blob: f972fb302fe45d8a40b8382f5a80a0e1834370b2 [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}
Michael Spangab6a59b2019-05-21 21:26:26 -04001127
1128bool IsValidImageLayout(ImageLayout layout)
1129{
1130 switch (layout)
1131 {
1132 case ImageLayout::General:
1133 case ImageLayout::ColorAttachment:
1134 case ImageLayout::DepthStencilAttachment:
1135 case ImageLayout::DepthStencilReadOnlyAttachment:
1136 case ImageLayout::ShaderReadOnly:
1137 case ImageLayout::TransferSrc:
1138 case ImageLayout::TransferDst:
1139 case ImageLayout::DepthReadOnlyStencilAttachment:
1140 case ImageLayout::DepthAttachmentStencilReadOnly:
1141 return true;
1142
1143 default:
1144 return false;
1145 }
1146}
1147
Jamie Madillc29968b2016-01-20 11:17:23 -05001148} // anonymous namespace
1149
Geoff Langff5b2d52016-09-07 11:32:23 -04001150bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001151 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001152 GLint level,
1153 GLenum internalformat,
1154 bool isCompressed,
1155 bool isSubImage,
1156 GLint xoffset,
1157 GLint yoffset,
1158 GLsizei width,
1159 GLsizei height,
1160 GLint border,
1161 GLenum format,
1162 GLenum type,
1163 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001164 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001165{
Jamie Madill6f38f822014-06-06 17:12:20 -04001166 if (!ValidTexture2DDestinationTarget(context, target))
1167 {
Jamie Madille0472f32018-11-27 16:32:45 -05001168 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001169 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001170 }
1171
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001172 TextureType texType = TextureTargetToType(target);
1173 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001174 {
Jamie Madill610640f2018-11-21 17:28:41 -05001175 // Error already handled.
Geoff Langb1196682014-07-23 13:47:29 -04001176 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001177 }
1178
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001179 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001180 {
Jamie Madille0472f32018-11-27 16:32:45 -05001181 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Brandon Jones6cad5662017-06-14 13:25:13 -07001182 return false;
1183 }
1184
1185 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001186 std::numeric_limits<GLsizei>::max() - yoffset < height)
1187 {
Jamie Madille0472f32018-11-27 16:32:45 -05001188 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001189 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001190 }
1191
Geoff Langaae65a42014-05-26 12:43:44 -04001192 const gl::Caps &caps = context->getCaps();
1193
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001194 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001195 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001196 case TextureType::_2D:
1197 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1198 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1199 {
Jamie Madille0472f32018-11-27 16:32:45 -05001200 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001201 return false;
1202 }
1203 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001204
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001205 case TextureType::Rectangle:
1206 ASSERT(level == 0);
1207 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1208 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1209 {
Jamie Madille0472f32018-11-27 16:32:45 -05001210 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001211 return false;
1212 }
1213 if (isCompressed)
1214 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001215 context->validationError(GL_INVALID_ENUM, kRectangleTextureCompressed);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001216 return false;
1217 }
1218 break;
1219
1220 case TextureType::CubeMap:
1221 if (!isSubImage && width != height)
1222 {
Jamie Madille0472f32018-11-27 16:32:45 -05001223 context->validationError(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001224 return false;
1225 }
1226
1227 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1228 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1229 {
Jamie Madille0472f32018-11-27 16:32:45 -05001230 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001231 return false;
1232 }
1233 break;
1234
1235 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001236 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001237 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001238 }
1239
Jamie Madillcfc73cc2019-04-08 16:26:51 -04001240 gl::Texture *texture = context->getTextureByType(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001241 if (!texture)
1242 {
Jamie Madille0472f32018-11-27 16:32:45 -05001243 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001244 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001245 }
1246
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001247 // Verify zero border
1248 if (border != 0)
1249 {
Jamie Madille0472f32018-11-27 16:32:45 -05001250 context->validationError(GL_INVALID_VALUE, kInvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001251 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001252 }
1253
Tim Van Patten208af3e2019-03-19 09:15:55 -06001254 bool nonEqualFormatsAllowed = false;
1255
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001256 if (isCompressed)
1257 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001258 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001259 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1260 : internalformat;
Geoff Lange88e4542018-05-03 15:05:57 -04001261
1262 const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(actualInternalFormat);
1263
1264 if (!internalFormatInfo.compressed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001265 {
Jamie Madille0472f32018-11-27 16:32:45 -05001266 context->validationError(GL_INVALID_ENUM, kInvalidInternalFormat);
Geoff Lange88e4542018-05-03 15:05:57 -04001267 return false;
1268 }
1269
1270 if (!internalFormatInfo.textureSupport(context->getClientVersion(),
1271 context->getExtensions()))
1272 {
Jamie Madille0472f32018-11-27 16:32:45 -05001273 context->validationError(GL_INVALID_ENUM, kInvalidInternalFormat);
Geoff Lange88e4542018-05-03 15:05:57 -04001274 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001275 }
Geoff Lang966c9402017-04-18 12:38:27 -04001276
1277 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001278 {
Geoff Lange88e4542018-05-03 15:05:57 -04001279 // From the OES_compressed_ETC1_RGB8_texture spec:
1280 // INVALID_OPERATION is generated by CompressedTexSubImage2D, TexSubImage2D, or
1281 // CopyTexSubImage2D if the texture image <level> bound to <target> has internal format
1282 // ETC1_RGB8_OES.
1283 if (actualInternalFormat == GL_ETC1_RGB8_OES)
1284 {
Jamie Madille0472f32018-11-27 16:32:45 -05001285 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lange88e4542018-05-03 15:05:57 -04001286 return false;
1287 }
1288
Geoff Lang966c9402017-04-18 12:38:27 -04001289 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1290 height, texture->getWidth(target, level),
1291 texture->getHeight(target, level)))
1292 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001293 context->validationError(GL_INVALID_OPERATION, kInvalidCompressedImageSize);
Geoff Lang966c9402017-04-18 12:38:27 -04001294 return false;
1295 }
1296
1297 if (format != actualInternalFormat)
1298 {
Jamie Madille0472f32018-11-27 16:32:45 -05001299 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001300 return false;
1301 }
1302 }
1303 else
1304 {
1305 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1306 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001307 context->validationError(GL_INVALID_OPERATION, kInvalidCompressedImageSize);
Geoff Lang966c9402017-04-18 12:38:27 -04001308 return false;
1309 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001310 }
1311 }
1312 else
1313 {
1314 // validate <type> by itself (used as secondary key below)
1315 switch (type)
1316 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001317 case GL_UNSIGNED_BYTE:
1318 case GL_UNSIGNED_SHORT_5_6_5:
1319 case GL_UNSIGNED_SHORT_4_4_4_4:
1320 case GL_UNSIGNED_SHORT_5_5_5_1:
1321 case GL_UNSIGNED_SHORT:
1322 case GL_UNSIGNED_INT:
1323 case GL_UNSIGNED_INT_24_8_OES:
1324 case GL_HALF_FLOAT_OES:
1325 case GL_FLOAT:
1326 break;
1327 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001328 context->validationError(GL_INVALID_ENUM, kInvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001329 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001330 }
1331
1332 // validate <format> + <type> combinations
1333 // - invalid <format> -> sets INVALID_ENUM
1334 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1335 switch (format)
1336 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001337 case GL_ALPHA:
1338 case GL_LUMINANCE:
1339 case GL_LUMINANCE_ALPHA:
1340 switch (type)
1341 {
1342 case GL_UNSIGNED_BYTE:
1343 case GL_FLOAT:
1344 case GL_HALF_FLOAT_OES:
1345 break;
1346 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001347 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001348 return false;
1349 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001350 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001351 case GL_RED:
1352 case GL_RG:
1353 if (!context->getExtensions().textureRG)
1354 {
Jamie Madille0472f32018-11-27 16:32:45 -05001355 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001356 return false;
1357 }
1358 switch (type)
1359 {
1360 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001361 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001362 case GL_FLOAT:
1363 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001364 if (!context->getExtensions().textureFloat)
1365 {
Jamie Madille0472f32018-11-27 16:32:45 -05001366 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001367 return false;
1368 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001369 break;
1370 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001371 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001372 return false;
1373 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001374 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001375 case GL_RGB:
1376 switch (type)
1377 {
1378 case GL_UNSIGNED_BYTE:
1379 case GL_UNSIGNED_SHORT_5_6_5:
1380 case GL_FLOAT:
1381 case GL_HALF_FLOAT_OES:
1382 break;
1383 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001384 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001385 return false;
1386 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001387 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001388 case GL_RGBA:
1389 switch (type)
1390 {
1391 case GL_UNSIGNED_BYTE:
1392 case GL_UNSIGNED_SHORT_4_4_4_4:
1393 case GL_UNSIGNED_SHORT_5_5_5_1:
1394 case GL_FLOAT:
1395 case GL_HALF_FLOAT_OES:
1396 break;
1397 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001398 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001399 return false;
1400 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001401 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001402 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001403 if (!context->getExtensions().textureFormatBGRA8888)
1404 {
Jamie Madille0472f32018-11-27 16:32:45 -05001405 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001406 return false;
1407 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001408 switch (type)
1409 {
1410 case GL_UNSIGNED_BYTE:
1411 break;
1412 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001413 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001414 return false;
1415 }
1416 break;
1417 case GL_SRGB_EXT:
1418 case GL_SRGB_ALPHA_EXT:
1419 if (!context->getExtensions().sRGB)
1420 {
Jamie Madille0472f32018-11-27 16:32:45 -05001421 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001422 return false;
1423 }
1424 switch (type)
1425 {
1426 case GL_UNSIGNED_BYTE:
1427 break;
1428 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001429 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001430 return false;
1431 }
1432 break;
1433 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1434 // handled below
1435 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1436 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1437 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1438 break;
1439 case GL_DEPTH_COMPONENT:
1440 switch (type)
1441 {
1442 case GL_UNSIGNED_SHORT:
1443 case GL_UNSIGNED_INT:
1444 break;
1445 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001446 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001447 return false;
1448 }
1449 break;
1450 case GL_DEPTH_STENCIL_OES:
1451 switch (type)
1452 {
1453 case GL_UNSIGNED_INT_24_8_OES:
1454 break;
1455 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001456 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001457 return false;
1458 }
1459 break;
1460 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001461 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001462 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001463 }
1464
1465 switch (format)
1466 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001467 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1468 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1469 if (context->getExtensions().textureCompressionDXT1)
1470 {
Jamie Madille0472f32018-11-27 16:32:45 -05001471 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001472 return false;
1473 }
1474 else
1475 {
Jamie Madille0472f32018-11-27 16:32:45 -05001476 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001477 return false;
1478 }
1479 break;
1480 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1481 if (context->getExtensions().textureCompressionDXT3)
1482 {
Jamie Madille0472f32018-11-27 16:32:45 -05001483 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001484 return false;
1485 }
1486 else
1487 {
Jamie Madille0472f32018-11-27 16:32:45 -05001488 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001489 return false;
1490 }
1491 break;
1492 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1493 if (context->getExtensions().textureCompressionDXT5)
1494 {
Jamie Madille0472f32018-11-27 16:32:45 -05001495 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001496 return false;
1497 }
1498 else
1499 {
Jamie Madille0472f32018-11-27 16:32:45 -05001500 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001501 return false;
1502 }
1503 break;
1504 case GL_ETC1_RGB8_OES:
1505 if (context->getExtensions().compressedETC1RGB8Texture)
1506 {
Jamie Madille0472f32018-11-27 16:32:45 -05001507 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001508 return false;
1509 }
1510 else
1511 {
Jamie Madille0472f32018-11-27 16:32:45 -05001512 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001513 return false;
1514 }
1515 break;
1516 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001517 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1518 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1519 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1520 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001521 if (context->getExtensions().lossyETCDecode)
1522 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001523 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001524 return false;
1525 }
1526 else
1527 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001528 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001529 return false;
1530 }
1531 break;
1532 case GL_DEPTH_COMPONENT:
1533 case GL_DEPTH_STENCIL_OES:
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001534 if (!context->getExtensions().depthTextureANGLE &&
1535 !(context->getExtensions().packedDepthStencil &&
1536 context->getExtensions().depthTextureOES))
He Yunchaoced53ae2016-11-29 15:00:51 +08001537 {
Jamie Madille0472f32018-11-27 16:32:45 -05001538 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001539 return false;
1540 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001541 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001542 {
Jamie Madille0472f32018-11-27 16:32:45 -05001543 context->validationError(GL_INVALID_OPERATION, kMismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001544 return false;
1545 }
1546 // OES_depth_texture supports loading depth data and multiple levels,
1547 // but ANGLE_depth_texture does not
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001548 if (!context->getExtensions().depthTextureOES)
He Yunchaoced53ae2016-11-29 15:00:51 +08001549 {
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001550 if (pixels != nullptr)
1551 {
1552 context->validationError(GL_INVALID_OPERATION, kPixelDataNotNull);
1553 return false;
1554 }
1555 if (level != 0)
1556 {
1557 context->validationError(GL_INVALID_OPERATION, kLevelNotZero);
1558 return false;
1559 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001560 }
1561 break;
1562 default:
1563 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001564 }
1565
Geoff Lang6e898aa2017-06-02 11:17:26 -04001566 if (!isSubImage)
1567 {
1568 switch (internalformat)
1569 {
Tim Van Patten208af3e2019-03-19 09:15:55 -06001570 // Core ES 2.0 formats
1571 case GL_ALPHA:
1572 case GL_LUMINANCE:
1573 case GL_LUMINANCE_ALPHA:
1574 case GL_RGB:
1575 case GL_RGBA:
1576 break;
1577
Geoff Lang6e898aa2017-06-02 11:17:26 -04001578 case GL_RGBA32F:
1579 if (!context->getExtensions().colorBufferFloatRGBA)
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_RGBA)
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
1599 case GL_RGB32F:
1600 if (!context->getExtensions().colorBufferFloatRGB)
1601 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001602 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001603 return false;
1604 }
Tim Van Patten208af3e2019-03-19 09:15:55 -06001605
1606 nonEqualFormatsAllowed = true;
1607
Geoff Lang6e898aa2017-06-02 11:17:26 -04001608 if (type != GL_FLOAT)
1609 {
Jamie Madille0472f32018-11-27 16:32:45 -05001610 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001611 return false;
1612 }
1613 if (format != GL_RGB)
1614 {
Jamie Madille0472f32018-11-27 16:32:45 -05001615 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001616 return false;
1617 }
1618 break;
1619
Tim Van Patten208af3e2019-03-19 09:15:55 -06001620 case GL_BGRA_EXT:
1621 if (!context->getExtensions().textureFormatBGRA8888)
1622 {
1623 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
1624 return false;
1625 }
Geoff Lang6e898aa2017-06-02 11:17:26 -04001626 break;
Tim Van Patten208af3e2019-03-19 09:15:55 -06001627
1628 case GL_DEPTH_COMPONENT:
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001629 if (!(context->getExtensions().depthTextureAny()))
1630 {
1631 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
1632 return false;
1633 }
1634 break;
1635
Tim Van Patten208af3e2019-03-19 09:15:55 -06001636 case GL_DEPTH_STENCIL:
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001637 if (!(context->getExtensions().depthTextureANGLE ||
1638 context->getExtensions().packedDepthStencil))
Tim Van Patten208af3e2019-03-19 09:15:55 -06001639 {
1640 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
1641 return false;
1642 }
1643 break;
1644
1645 case GL_RED:
1646 case GL_RG:
1647 if (!context->getExtensions().textureRG)
1648 {
1649 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
1650 return false;
1651 }
1652 break;
1653
1654 case GL_SRGB_EXT:
1655 case GL_SRGB_ALPHA_EXT:
1656 if (!context->getExtensions().sRGB)
1657 {
1658 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
1659 return false;
1660 }
1661 break;
1662
1663 default:
1664 context->validationError(GL_INVALID_VALUE, kInvalidInternalFormat);
1665 return false;
Geoff Lang6e898aa2017-06-02 11:17:26 -04001666 }
1667 }
1668
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001669 if (type == GL_FLOAT)
1670 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001671 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001672 {
Jamie Madille0472f32018-11-27 16:32:45 -05001673 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001674 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001675 }
1676 }
1677 else if (type == GL_HALF_FLOAT_OES)
1678 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001679 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001680 {
Jamie Madille0472f32018-11-27 16:32:45 -05001681 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001682 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001683 }
1684 }
1685 }
1686
Tim Van Patten208af3e2019-03-19 09:15:55 -06001687 if (isSubImage)
Geoff Langff5b2d52016-09-07 11:32:23 -04001688 {
Tim Van Patten208af3e2019-03-19 09:15:55 -06001689 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1690 if (textureInternalFormat.internalFormat == GL_NONE)
1691 {
1692 context->validationError(GL_INVALID_OPERATION, kInvalidTextureLevel);
1693 return false;
1694 }
1695
Tim Van Patten5f388c22019-03-14 09:54:23 -06001696 if (format != textureInternalFormat.format)
1697 {
1698 context->validationError(GL_INVALID_OPERATION, err::kTextureFormatMismatch);
1699 return false;
1700 }
1701
1702 if (context->getExtensions().webglCompatibility)
Tim Van Patten208af3e2019-03-19 09:15:55 -06001703 {
1704 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1705 textureInternalFormat.sizedInternalFormat)
1706 {
Tim Van Patten5f388c22019-03-14 09:54:23 -06001707 context->validationError(GL_INVALID_OPERATION, kTextureTypeMismatch);
Tim Van Patten208af3e2019-03-19 09:15:55 -06001708 return false;
1709 }
1710 }
1711
1712 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1713 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1714 {
1715 context->validationError(GL_INVALID_VALUE, kOffsetOverflow);
1716 return false;
1717 }
1718
1719 if (width > 0 && height > 0 && pixels == nullptr &&
1720 context->getState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
1721 {
1722 context->validationError(GL_INVALID_VALUE, kPixelDataNull);
1723 return false;
1724 }
1725 }
1726 else
1727 {
1728 if (texture->getImmutableFormat())
1729 {
1730 context->validationError(GL_INVALID_OPERATION, kTextureIsImmutable);
1731 return false;
1732 }
1733 }
1734
1735 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1736 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1737 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1738 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1739 // case.
1740 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
1741 {
1742 context->validationError(GL_INVALID_OPERATION, kInvalidFormatCombination);
Geoff Langff5b2d52016-09-07 11:32:23 -04001743 return false;
1744 }
1745
Tim Van Patten208af3e2019-03-19 09:15:55 -06001746 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
1747 return ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
1748 imageSize);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001749}
1750
He Yunchaoced53ae2016-11-29 15:00:51 +08001751bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001752 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001753 GLsizei levels,
1754 GLenum internalformat,
1755 GLsizei width,
1756 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001757{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001758 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1759 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001760 {
Jamie Madille0472f32018-11-27 16:32:45 -05001761 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001762 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001763 }
1764
1765 if (width < 1 || height < 1 || levels < 1)
1766 {
Jamie Madille0472f32018-11-27 16:32:45 -05001767 context->validationError(GL_INVALID_VALUE, kTextureSizeTooSmall);
Geoff Langb1196682014-07-23 13:47:29 -04001768 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001769 }
1770
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001771 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001772 {
Jamie Madille0472f32018-11-27 16:32:45 -05001773 context->validationError(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
Geoff Langb1196682014-07-23 13:47:29 -04001774 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001775 }
1776
1777 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1778 {
Jamie Madille0472f32018-11-27 16:32:45 -05001779 context->validationError(GL_INVALID_OPERATION, kInvalidMipLevels);
Geoff Langb1196682014-07-23 13:47:29 -04001780 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001781 }
1782
Geoff Langca271392017-04-05 12:30:00 -04001783 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001784 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001785 {
Jamie Madille0472f32018-11-27 16:32:45 -05001786 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001787 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001788 }
1789
Geoff Langaae65a42014-05-26 12:43:44 -04001790 const gl::Caps &caps = context->getCaps();
1791
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001792 switch (target)
1793 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001794 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001795 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1796 static_cast<GLuint>(height) > caps.max2DTextureSize)
1797 {
Jamie Madille0472f32018-11-27 16:32:45 -05001798 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
He Yunchaoced53ae2016-11-29 15:00:51 +08001799 return false;
1800 }
1801 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001802 case TextureType::Rectangle:
Jamie Madill610640f2018-11-21 17:28:41 -05001803 if (levels != 1)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001804 {
Jamie Madille0472f32018-11-27 16:32:45 -05001805 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madill610640f2018-11-21 17:28:41 -05001806 return false;
1807 }
1808
1809 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1810 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1811 {
Jamie Madille0472f32018-11-27 16:32:45 -05001812 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001813 return false;
1814 }
1815 if (formatInfo.compressed)
1816 {
Jamie Madille0472f32018-11-27 16:32:45 -05001817 context->validationError(GL_INVALID_ENUM, kRectangleTextureCompressed);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001818 return false;
1819 }
1820 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001821 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001822 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1823 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1824 {
Jamie Madille0472f32018-11-27 16:32:45 -05001825 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
He Yunchaoced53ae2016-11-29 15:00:51 +08001826 return false;
1827 }
1828 break;
1829 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001830 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001831 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001832 }
1833
Geoff Langc0b9ef42014-07-02 10:02:37 -04001834 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001835 {
1836 if (!gl::isPow2(width) || !gl::isPow2(height))
1837 {
Jamie Madille0472f32018-11-27 16:32:45 -05001838 context->validationError(GL_INVALID_OPERATION, kDimensionsMustBePow2);
Geoff Langb1196682014-07-23 13:47:29 -04001839 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001840 }
1841 }
1842
1843 switch (internalformat)
1844 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001845 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1846 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1847 if (!context->getExtensions().textureCompressionDXT1)
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_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1854 if (!context->getExtensions().textureCompressionDXT3)
1855 {
Jamie Madille0472f32018-11-27 16:32:45 -05001856 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001857 return false;
1858 }
1859 break;
1860 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1861 if (!context->getExtensions().textureCompressionDXT5)
1862 {
Jamie Madille0472f32018-11-27 16:32:45 -05001863 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001864 return false;
1865 }
1866 break;
1867 case GL_ETC1_RGB8_OES:
1868 if (!context->getExtensions().compressedETC1RGB8Texture)
1869 {
Jamie Madille0472f32018-11-27 16:32:45 -05001870 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001871 return false;
1872 }
1873 break;
1874 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001875 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1876 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1877 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1878 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001879 if (!context->getExtensions().lossyETCDecode)
1880 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001881 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001882 return false;
1883 }
1884 break;
1885 case GL_RGBA32F_EXT:
1886 case GL_RGB32F_EXT:
1887 case GL_ALPHA32F_EXT:
1888 case GL_LUMINANCE32F_EXT:
1889 case GL_LUMINANCE_ALPHA32F_EXT:
1890 if (!context->getExtensions().textureFloat)
1891 {
Jamie Madille0472f32018-11-27 16:32:45 -05001892 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001893 return false;
1894 }
1895 break;
1896 case GL_RGBA16F_EXT:
1897 case GL_RGB16F_EXT:
1898 case GL_ALPHA16F_EXT:
1899 case GL_LUMINANCE16F_EXT:
1900 case GL_LUMINANCE_ALPHA16F_EXT:
1901 if (!context->getExtensions().textureHalfFloat)
1902 {
Jamie Madille0472f32018-11-27 16:32:45 -05001903 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001904 return false;
1905 }
1906 break;
1907 case GL_R8_EXT:
1908 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001909 if (!context->getExtensions().textureRG)
1910 {
Jamie Madille0472f32018-11-27 16:32:45 -05001911 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang677bb6f2017-04-05 12:40:40 -04001912 return false;
1913 }
1914 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001915 case GL_R16F_EXT:
1916 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001917 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1918 {
Jamie Madille0472f32018-11-27 16:32:45 -05001919 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang677bb6f2017-04-05 12:40:40 -04001920 return false;
1921 }
1922 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001923 case GL_R32F_EXT:
1924 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001925 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001926 {
Jamie Madille0472f32018-11-27 16:32:45 -05001927 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001928 return false;
1929 }
1930 break;
1931 case GL_DEPTH_COMPONENT16:
1932 case GL_DEPTH_COMPONENT32_OES:
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001933 if (!(context->getExtensions().depthTextureAny()))
He Yunchaoced53ae2016-11-29 15:00:51 +08001934 {
Jamie Madille0472f32018-11-27 16:32:45 -05001935 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001936 return false;
1937 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001938 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001939 {
Jamie Madille0472f32018-11-27 16:32:45 -05001940 context->validationError(GL_INVALID_OPERATION, kInvalidTextureTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001941 return false;
1942 }
1943 // ANGLE_depth_texture only supports 1-level textures
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001944 if (!context->getExtensions().depthTextureOES)
He Yunchaoced53ae2016-11-29 15:00:51 +08001945 {
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001946 if (levels != 1)
1947 {
1948 context->validationError(GL_INVALID_OPERATION, kInvalidMipLevels);
1949 return false;
1950 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001951 }
1952 break;
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001953 case GL_DEPTH24_STENCIL8_OES:
1954 if (!(context->getExtensions().depthTextureANGLE ||
1955 (context->getExtensions().packedDepthStencil &&
1956 context->getExtensions().textureStorage)))
1957 {
1958 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
1959 return false;
1960 }
1961 if (target != TextureType::_2D)
1962 {
1963 context->validationError(GL_INVALID_OPERATION, kInvalidTextureTarget);
1964 return false;
1965 }
1966 if (!context->getExtensions().packedDepthStencil)
1967 {
1968 // ANGLE_depth_texture only supports 1-level textures
1969 if (levels != 1)
1970 {
1971 context->validationError(GL_INVALID_OPERATION, kInvalidMipLevels);
1972 return false;
1973 }
1974 }
1975 break;
1976
He Yunchaoced53ae2016-11-29 15:00:51 +08001977 default:
1978 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001979 }
1980
Jamie Madillcfc73cc2019-04-08 16:26:51 -04001981 gl::Texture *texture = context->getTextureByType(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001982 if (!texture || texture->id() == 0)
1983 {
Jamie Madille0472f32018-11-27 16:32:45 -05001984 context->validationError(GL_INVALID_OPERATION, kMissingTexture);
Geoff Langb1196682014-07-23 13:47:29 -04001985 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001986 }
1987
Geoff Lang69cce582015-09-17 13:20:36 -04001988 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001989 {
Jamie Madille0472f32018-11-27 16:32:45 -05001990 context->validationError(GL_INVALID_OPERATION, kTextureIsImmutable);
Geoff Langb1196682014-07-23 13:47:29 -04001991 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001992 }
1993
1994 return true;
1995}
1996
He Yunchaoced53ae2016-11-29 15:00:51 +08001997bool ValidateDiscardFramebufferEXT(Context *context,
1998 GLenum target,
1999 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07002000 const GLenum *attachments)
2001{
Jamie Madillc29968b2016-01-20 11:17:23 -05002002 if (!context->getExtensions().discardFramebuffer)
2003 {
Jamie Madille0472f32018-11-27 16:32:45 -05002004 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05002005 return false;
2006 }
2007
Austin Kinross08332632015-05-05 13:35:47 -07002008 bool defaultFramebuffer = false;
2009
2010 switch (target)
2011 {
He Yunchaoced53ae2016-11-29 15:00:51 +08002012 case GL_FRAMEBUFFER:
2013 defaultFramebuffer =
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002014 (context->getState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
He Yunchaoced53ae2016-11-29 15:00:51 +08002015 break;
2016 default:
Jamie Madille0472f32018-11-27 16:32:45 -05002017 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08002018 return false;
Austin Kinross08332632015-05-05 13:35:47 -07002019 }
2020
He Yunchaoced53ae2016-11-29 15:00:51 +08002021 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
2022 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07002023}
2024
Austin Kinrossbc781f32015-10-26 09:27:38 -07002025bool ValidateBindVertexArrayOES(Context *context, GLuint array)
2026{
2027 if (!context->getExtensions().vertexArrayObject)
2028 {
Jamie Madille0472f32018-11-27 16:32:45 -05002029 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07002030 return false;
2031 }
2032
2033 return ValidateBindVertexArrayBase(context, array);
2034}
2035
Jamie Madilld7576732017-08-26 18:49:50 -04002036bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07002037{
2038 if (!context->getExtensions().vertexArrayObject)
2039 {
Jamie Madille0472f32018-11-27 16:32:45 -05002040 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07002041 return false;
2042 }
2043
Olli Etuaho41997e72016-03-10 13:38:39 +02002044 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07002045}
2046
Jamie Madilld7576732017-08-26 18:49:50 -04002047bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07002048{
2049 if (!context->getExtensions().vertexArrayObject)
2050 {
Jamie Madille0472f32018-11-27 16:32:45 -05002051 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07002052 return false;
2053 }
2054
Olli Etuaho41997e72016-03-10 13:38:39 +02002055 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07002056}
2057
Jamie Madilld7576732017-08-26 18:49:50 -04002058bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07002059{
2060 if (!context->getExtensions().vertexArrayObject)
2061 {
Jamie Madille0472f32018-11-27 16:32:45 -05002062 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07002063 return false;
2064 }
2065
2066 return true;
2067}
Geoff Langc5629752015-12-07 16:29:04 -05002068
2069bool ValidateProgramBinaryOES(Context *context,
2070 GLuint program,
2071 GLenum binaryFormat,
2072 const void *binary,
2073 GLint length)
2074{
2075 if (!context->getExtensions().getProgramBinary)
2076 {
Jamie Madille0472f32018-11-27 16:32:45 -05002077 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05002078 return false;
2079 }
2080
2081 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
2082}
2083
2084bool ValidateGetProgramBinaryOES(Context *context,
2085 GLuint program,
2086 GLsizei bufSize,
2087 GLsizei *length,
2088 GLenum *binaryFormat,
2089 void *binary)
2090{
2091 if (!context->getExtensions().getProgramBinary)
2092 {
Jamie Madille0472f32018-11-27 16:32:45 -05002093 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05002094 return false;
2095 }
2096
2097 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
2098}
Geoff Lange102fee2015-12-10 11:23:30 -05002099
Geoff Lang70d0f492015-12-10 17:45:46 -05002100static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
2101{
2102 switch (source)
2103 {
2104 case GL_DEBUG_SOURCE_API:
2105 case GL_DEBUG_SOURCE_SHADER_COMPILER:
2106 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
2107 case GL_DEBUG_SOURCE_OTHER:
2108 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
2109 return !mustBeThirdPartyOrApplication;
2110
2111 case GL_DEBUG_SOURCE_THIRD_PARTY:
2112 case GL_DEBUG_SOURCE_APPLICATION:
2113 return true;
2114
2115 default:
2116 return false;
2117 }
2118}
2119
2120static bool ValidDebugType(GLenum type)
2121{
2122 switch (type)
2123 {
2124 case GL_DEBUG_TYPE_ERROR:
2125 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
2126 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
2127 case GL_DEBUG_TYPE_PERFORMANCE:
2128 case GL_DEBUG_TYPE_PORTABILITY:
2129 case GL_DEBUG_TYPE_OTHER:
2130 case GL_DEBUG_TYPE_MARKER:
2131 case GL_DEBUG_TYPE_PUSH_GROUP:
2132 case GL_DEBUG_TYPE_POP_GROUP:
2133 return true;
2134
2135 default:
2136 return false;
2137 }
2138}
2139
2140static bool ValidDebugSeverity(GLenum severity)
2141{
2142 switch (severity)
2143 {
2144 case GL_DEBUG_SEVERITY_HIGH:
2145 case GL_DEBUG_SEVERITY_MEDIUM:
2146 case GL_DEBUG_SEVERITY_LOW:
2147 case GL_DEBUG_SEVERITY_NOTIFICATION:
2148 return true;
2149
2150 default:
2151 return false;
2152 }
2153}
2154
Geoff Lange102fee2015-12-10 11:23:30 -05002155bool ValidateDebugMessageControlKHR(Context *context,
2156 GLenum source,
2157 GLenum type,
2158 GLenum severity,
2159 GLsizei count,
2160 const GLuint *ids,
2161 GLboolean enabled)
2162{
2163 if (!context->getExtensions().debug)
2164 {
Jamie Madille0472f32018-11-27 16:32:45 -05002165 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002166 return false;
2167 }
2168
Geoff Lang70d0f492015-12-10 17:45:46 -05002169 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
2170 {
Jamie Madille0472f32018-11-27 16:32:45 -05002171 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002172 return false;
2173 }
2174
2175 if (!ValidDebugType(type) && type != GL_DONT_CARE)
2176 {
Jamie Madille0472f32018-11-27 16:32:45 -05002177 context->validationError(GL_INVALID_ENUM, kInvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002178 return false;
2179 }
2180
2181 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
2182 {
Jamie Madille0472f32018-11-27 16:32:45 -05002183 context->validationError(GL_INVALID_ENUM, kInvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05002184 return false;
2185 }
2186
2187 if (count > 0)
2188 {
2189 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
2190 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002191 context->validationError(GL_INVALID_OPERATION, kInvalidDebugSourceType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002192 return false;
2193 }
2194
2195 if (severity != GL_DONT_CARE)
2196 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002197 context->validationError(GL_INVALID_OPERATION, kInvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05002198 return false;
2199 }
2200 }
2201
Geoff Lange102fee2015-12-10 11:23:30 -05002202 return true;
2203}
2204
2205bool ValidateDebugMessageInsertKHR(Context *context,
2206 GLenum source,
2207 GLenum type,
2208 GLuint id,
2209 GLenum severity,
2210 GLsizei length,
2211 const GLchar *buf)
2212{
2213 if (!context->getExtensions().debug)
2214 {
Jamie Madille0472f32018-11-27 16:32:45 -05002215 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002216 return false;
2217 }
2218
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002219 if (!context->getState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002220 {
2221 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2222 // not generate an error.
2223 return false;
2224 }
2225
2226 if (!ValidDebugSeverity(severity))
2227 {
Jamie Madille0472f32018-11-27 16:32:45 -05002228 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002229 return false;
2230 }
2231
2232 if (!ValidDebugType(type))
2233 {
Jamie Madille0472f32018-11-27 16:32:45 -05002234 context->validationError(GL_INVALID_ENUM, kInvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002235 return false;
2236 }
2237
2238 if (!ValidDebugSource(source, true))
2239 {
Jamie Madille0472f32018-11-27 16:32:45 -05002240 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002241 return false;
2242 }
2243
2244 size_t messageLength = (length < 0) ? strlen(buf) : length;
2245 if (messageLength > context->getExtensions().maxDebugMessageLength)
2246 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002247 context->validationError(GL_INVALID_VALUE, kExceedsMaxDebugMessageLength);
Geoff Lang70d0f492015-12-10 17:45:46 -05002248 return false;
2249 }
2250
Geoff Lange102fee2015-12-10 11:23:30 -05002251 return true;
2252}
2253
2254bool ValidateDebugMessageCallbackKHR(Context *context,
2255 GLDEBUGPROCKHR callback,
2256 const void *userParam)
2257{
2258 if (!context->getExtensions().debug)
2259 {
Jamie Madille0472f32018-11-27 16:32:45 -05002260 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002261 return false;
2262 }
2263
Geoff Lange102fee2015-12-10 11:23:30 -05002264 return true;
2265}
2266
2267bool ValidateGetDebugMessageLogKHR(Context *context,
2268 GLuint count,
2269 GLsizei bufSize,
2270 GLenum *sources,
2271 GLenum *types,
2272 GLuint *ids,
2273 GLenum *severities,
2274 GLsizei *lengths,
2275 GLchar *messageLog)
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 (bufSize < 0 && messageLog != nullptr)
2284 {
Jamie Madille0472f32018-11-27 16:32:45 -05002285 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002286 return false;
2287 }
2288
Geoff Lange102fee2015-12-10 11:23:30 -05002289 return true;
2290}
2291
2292bool ValidatePushDebugGroupKHR(Context *context,
2293 GLenum source,
2294 GLuint id,
2295 GLsizei length,
2296 const GLchar *message)
2297{
2298 if (!context->getExtensions().debug)
2299 {
Jamie Madille0472f32018-11-27 16:32:45 -05002300 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002301 return false;
2302 }
2303
Geoff Lang70d0f492015-12-10 17:45:46 -05002304 if (!ValidDebugSource(source, true))
2305 {
Jamie Madille0472f32018-11-27 16:32:45 -05002306 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002307 return false;
2308 }
2309
2310 size_t messageLength = (length < 0) ? strlen(message) : length;
2311 if (messageLength > context->getExtensions().maxDebugMessageLength)
2312 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002313 context->validationError(GL_INVALID_VALUE, kExceedsMaxDebugMessageLength);
Geoff Lang70d0f492015-12-10 17:45:46 -05002314 return false;
2315 }
2316
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002317 size_t currentStackSize = context->getState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002318 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2319 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002320 context->validationError(GL_STACK_OVERFLOW, kExceedsMaxDebugGroupStackDepth);
Geoff Lang70d0f492015-12-10 17:45:46 -05002321 return false;
2322 }
2323
Geoff Lange102fee2015-12-10 11:23:30 -05002324 return true;
2325}
2326
2327bool ValidatePopDebugGroupKHR(Context *context)
2328{
2329 if (!context->getExtensions().debug)
2330 {
Jamie Madille0472f32018-11-27 16:32:45 -05002331 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002332 return false;
2333 }
2334
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002335 size_t currentStackSize = context->getState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002336 if (currentStackSize <= 1)
2337 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002338 context->validationError(GL_STACK_UNDERFLOW, kCannotPopDefaultDebugGroup);
Geoff Lang70d0f492015-12-10 17:45:46 -05002339 return false;
2340 }
2341
2342 return true;
2343}
2344
2345static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2346{
2347 switch (identifier)
2348 {
2349 case GL_BUFFER:
2350 if (context->getBuffer(name) == nullptr)
2351 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002352 context->validationError(GL_INVALID_VALUE, kInvalidBufferName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002353 return false;
2354 }
2355 return true;
2356
2357 case GL_SHADER:
2358 if (context->getShader(name) == nullptr)
2359 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002360 context->validationError(GL_INVALID_VALUE, kInvalidShaderName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002361 return false;
2362 }
2363 return true;
2364
2365 case GL_PROGRAM:
Jamie Madill44a6fbf2018-10-02 13:38:56 -04002366 if (context->getProgramNoResolveLink(name) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002367 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002368 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002369 return false;
2370 }
2371 return true;
2372
2373 case GL_VERTEX_ARRAY:
2374 if (context->getVertexArray(name) == nullptr)
2375 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002376 context->validationError(GL_INVALID_VALUE, kInvalidVertexArrayName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002377 return false;
2378 }
2379 return true;
2380
2381 case GL_QUERY:
2382 if (context->getQuery(name) == nullptr)
2383 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002384 context->validationError(GL_INVALID_VALUE, kInvalidQueryName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002385 return false;
2386 }
2387 return true;
2388
2389 case GL_TRANSFORM_FEEDBACK:
2390 if (context->getTransformFeedback(name) == nullptr)
2391 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002392 context->validationError(GL_INVALID_VALUE, kInvalidTransformFeedbackName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002393 return false;
2394 }
2395 return true;
2396
2397 case GL_SAMPLER:
2398 if (context->getSampler(name) == nullptr)
2399 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002400 context->validationError(GL_INVALID_VALUE, kInvalidSamplerName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002401 return false;
2402 }
2403 return true;
2404
2405 case GL_TEXTURE:
2406 if (context->getTexture(name) == nullptr)
2407 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002408 context->validationError(GL_INVALID_VALUE, kInvalidTextureName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002409 return false;
2410 }
2411 return true;
2412
2413 case GL_RENDERBUFFER:
2414 if (context->getRenderbuffer(name) == nullptr)
2415 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002416 context->validationError(GL_INVALID_VALUE, kInvalidRenderbufferName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002417 return false;
2418 }
2419 return true;
2420
2421 case GL_FRAMEBUFFER:
2422 if (context->getFramebuffer(name) == nullptr)
2423 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002424 context->validationError(GL_INVALID_VALUE, kInvalidFramebufferName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002425 return false;
2426 }
2427 return true;
2428
2429 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05002430 context->validationError(GL_INVALID_ENUM, kInvalidIndentifier);
Geoff Lang70d0f492015-12-10 17:45:46 -05002431 return false;
2432 }
Geoff Lange102fee2015-12-10 11:23:30 -05002433}
2434
Martin Radev9d901792016-07-15 15:58:58 +03002435static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2436{
2437 size_t labelLength = 0;
2438
2439 if (length < 0)
2440 {
2441 if (label != nullptr)
2442 {
2443 labelLength = strlen(label);
2444 }
2445 }
2446 else
2447 {
2448 labelLength = static_cast<size_t>(length);
2449 }
2450
2451 if (labelLength > context->getExtensions().maxLabelLength)
2452 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002453 context->validationError(GL_INVALID_VALUE, kExceedsMaxLabelLength);
Martin Radev9d901792016-07-15 15:58:58 +03002454 return false;
2455 }
2456
2457 return true;
2458}
2459
Geoff Lange102fee2015-12-10 11:23:30 -05002460bool ValidateObjectLabelKHR(Context *context,
2461 GLenum identifier,
2462 GLuint name,
2463 GLsizei length,
2464 const GLchar *label)
2465{
2466 if (!context->getExtensions().debug)
2467 {
Jamie Madille0472f32018-11-27 16:32:45 -05002468 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002469 return false;
2470 }
2471
Geoff Lang70d0f492015-12-10 17:45:46 -05002472 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2473 {
2474 return false;
2475 }
2476
Martin Radev9d901792016-07-15 15:58:58 +03002477 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002478 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002479 return false;
2480 }
2481
Geoff Lange102fee2015-12-10 11:23:30 -05002482 return true;
2483}
2484
2485bool ValidateGetObjectLabelKHR(Context *context,
2486 GLenum identifier,
2487 GLuint name,
2488 GLsizei bufSize,
2489 GLsizei *length,
2490 GLchar *label)
2491{
2492 if (!context->getExtensions().debug)
2493 {
Jamie Madille0472f32018-11-27 16:32:45 -05002494 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002495 return false;
2496 }
2497
Geoff Lang70d0f492015-12-10 17:45:46 -05002498 if (bufSize < 0)
2499 {
Jamie Madille0472f32018-11-27 16:32:45 -05002500 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002501 return false;
2502 }
2503
2504 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2505 {
2506 return false;
2507 }
2508
Martin Radev9d901792016-07-15 15:58:58 +03002509 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002510}
2511
2512static bool ValidateObjectPtrName(Context *context, const void *ptr)
2513{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002514 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002515 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002516 context->validationError(GL_INVALID_VALUE, kInvalidSyncPointer);
Geoff Lang70d0f492015-12-10 17:45:46 -05002517 return false;
2518 }
2519
Geoff Lange102fee2015-12-10 11:23:30 -05002520 return true;
2521}
2522
2523bool ValidateObjectPtrLabelKHR(Context *context,
2524 const void *ptr,
2525 GLsizei length,
2526 const GLchar *label)
2527{
2528 if (!context->getExtensions().debug)
2529 {
Jamie Madille0472f32018-11-27 16:32:45 -05002530 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002531 return false;
2532 }
2533
Geoff Lang70d0f492015-12-10 17:45:46 -05002534 if (!ValidateObjectPtrName(context, ptr))
2535 {
2536 return false;
2537 }
2538
Martin Radev9d901792016-07-15 15:58:58 +03002539 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002540 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002541 return false;
2542 }
2543
Geoff Lange102fee2015-12-10 11:23:30 -05002544 return true;
2545}
2546
2547bool ValidateGetObjectPtrLabelKHR(Context *context,
2548 const void *ptr,
2549 GLsizei bufSize,
2550 GLsizei *length,
2551 GLchar *label)
2552{
2553 if (!context->getExtensions().debug)
2554 {
Jamie Madille0472f32018-11-27 16:32:45 -05002555 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002556 return false;
2557 }
2558
Geoff Lang70d0f492015-12-10 17:45:46 -05002559 if (bufSize < 0)
2560 {
Jamie Madille0472f32018-11-27 16:32:45 -05002561 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002562 return false;
2563 }
2564
2565 if (!ValidateObjectPtrName(context, ptr))
2566 {
2567 return false;
2568 }
2569
Martin Radev9d901792016-07-15 15:58:58 +03002570 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002571}
2572
2573bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2574{
2575 if (!context->getExtensions().debug)
2576 {
Jamie Madille0472f32018-11-27 16:32:45 -05002577 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002578 return false;
2579 }
2580
Geoff Lang70d0f492015-12-10 17:45:46 -05002581 // TODO: represent this in Context::getQueryParameterInfo.
2582 switch (pname)
2583 {
2584 case GL_DEBUG_CALLBACK_FUNCTION:
2585 case GL_DEBUG_CALLBACK_USER_PARAM:
2586 break;
2587
2588 default:
Jamie Madille0472f32018-11-27 16:32:45 -05002589 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002590 return false;
2591 }
2592
Geoff Lange102fee2015-12-10 11:23:30 -05002593 return true;
2594}
Jamie Madillc29968b2016-01-20 11:17:23 -05002595
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07002596bool ValidateGetPointervRobustANGLERobustANGLE(Context *context,
2597 GLenum pname,
2598 GLsizei bufSize,
2599 GLsizei *length,
2600 void **params)
2601{
2602 UNIMPLEMENTED();
2603 return false;
2604}
2605
Jamie Madillc29968b2016-01-20 11:17:23 -05002606bool ValidateBlitFramebufferANGLE(Context *context,
2607 GLint srcX0,
2608 GLint srcY0,
2609 GLint srcX1,
2610 GLint srcY1,
2611 GLint dstX0,
2612 GLint dstY0,
2613 GLint dstX1,
2614 GLint dstY1,
2615 GLbitfield mask,
2616 GLenum filter)
2617{
2618 if (!context->getExtensions().framebufferBlit)
2619 {
Jamie Madille0472f32018-11-27 16:32:45 -05002620 context->validationError(GL_INVALID_OPERATION, kBlitExtensionNotAvailable);
Jamie Madillc29968b2016-01-20 11:17:23 -05002621 return false;
2622 }
2623
2624 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2625 {
2626 // TODO(jmadill): Determine if this should be available on other implementations.
Jamie Madille0472f32018-11-27 16:32:45 -05002627 context->validationError(GL_INVALID_OPERATION, kBlitExtensionScaleOrFlip);
Jamie Madillc29968b2016-01-20 11:17:23 -05002628 return false;
2629 }
2630
2631 if (filter == GL_LINEAR)
2632 {
Jamie Madille0472f32018-11-27 16:32:45 -05002633 context->validationError(GL_INVALID_ENUM, kBlitExtensionLinear);
Jamie Madillc29968b2016-01-20 11:17:23 -05002634 return false;
2635 }
2636
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002637 Framebuffer *readFramebuffer = context->getState().getReadFramebuffer();
2638 Framebuffer *drawFramebuffer = context->getState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002639
2640 if (mask & GL_COLOR_BUFFER_BIT)
2641 {
2642 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2643 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2644
2645 if (readColorAttachment && drawColorAttachment)
2646 {
2647 if (!(readColorAttachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002648 readColorAttachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002649 readColorAttachment->type() != GL_RENDERBUFFER &&
2650 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2651 {
Jamie Madill610640f2018-11-21 17:28:41 -05002652 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002653 kBlitExtensionFromInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002654 return false;
2655 }
2656
Geoff Langa15472a2015-08-11 11:48:03 -04002657 for (size_t drawbufferIdx = 0;
2658 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002659 {
Geoff Langa15472a2015-08-11 11:48:03 -04002660 const FramebufferAttachment *attachment =
2661 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2662 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002663 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002664 if (!(attachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002665 attachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002666 attachment->type() != GL_RENDERBUFFER &&
2667 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2668 {
Jamie Madill610640f2018-11-21 17:28:41 -05002669 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002670 kBlitExtensionToInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002671 return false;
2672 }
2673
2674 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002675 if (!Format::EquivalentForBlit(attachment->getFormat(),
2676 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002677 {
Jamie Madill610640f2018-11-21 17:28:41 -05002678 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002679 kBlitExtensionFormatMismatch);
Jamie Madillc29968b2016-01-20 11:17:23 -05002680 return false;
2681 }
2682 }
2683 }
2684
Jamie Madill427064d2018-04-13 16:20:34 -04002685 GLint samples = readFramebuffer->getSamples(context);
Jamie Madille98b1b52018-03-08 09:47:23 -05002686 if (samples != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002687 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2688 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2689 {
Jamie Madill610640f2018-11-21 17:28:41 -05002690 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002691 kBlitExtensionMultisampledWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002692 return false;
2693 }
2694 }
2695 }
2696
2697 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2698 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2699 for (size_t i = 0; i < 2; i++)
2700 {
2701 if (mask & masks[i])
2702 {
2703 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002704 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002705 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002706 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002707
2708 if (readBuffer && drawBuffer)
2709 {
2710 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2711 dstX0, dstY0, dstX1, dstY1))
2712 {
2713 // only whole-buffer copies are permitted
Jamie Madill610640f2018-11-21 17:28:41 -05002714 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002715 kBlitExtensionDepthStencilWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002716 return false;
2717 }
2718
2719 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2720 {
Jamie Madill610640f2018-11-21 17:28:41 -05002721 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002722 kBlitExtensionMultisampledDepthOrStencil);
Jamie Madillc29968b2016-01-20 11:17:23 -05002723 return false;
2724 }
2725 }
2726 }
2727 }
2728
2729 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2730 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002731}
Jamie Madillc29968b2016-01-20 11:17:23 -05002732
Jamie Madill5b772312018-03-08 20:28:32 -05002733bool ValidateClear(Context *context, GLbitfield mask)
Jamie Madillc29968b2016-01-20 11:17:23 -05002734{
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002735 Framebuffer *fbo = context->getState().getDrawFramebuffer();
Olli Etuaho94c91a92018-07-19 15:10:24 +03002736 const Extensions &extensions = context->getExtensions();
Jamie Madille98b1b52018-03-08 09:47:23 -05002737
Jamie Madill427064d2018-04-13 16:20:34 -04002738 if (!ValidateFramebufferComplete(context, fbo))
Jamie Madillc29968b2016-01-20 11:17:23 -05002739 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002740 return false;
2741 }
2742
2743 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2744 {
Jamie Madille0472f32018-11-27 16:32:45 -05002745 context->validationError(GL_INVALID_VALUE, kInvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002746 return false;
2747 }
2748
Olli Etuaho94c91a92018-07-19 15:10:24 +03002749 if (extensions.webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
Geoff Lang76e65652017-03-27 14:58:02 -04002750 {
2751 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2752 GL_SIGNED_NORMALIZED};
2753
Corentin Wallez59c41592017-07-11 13:19:54 -04002754 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002755 drawBufferIdx++)
2756 {
2757 if (!ValidateWebGLFramebufferAttachmentClearType(
2758 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2759 {
2760 return false;
2761 }
2762 }
2763 }
2764
Mingyu Huebab6702019-04-19 14:36:45 -07002765 if ((extensions.multiview || extensions.multiview2) && extensions.disjointTimerQuery)
Olli Etuaho94c91a92018-07-19 15:10:24 +03002766 {
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002767 const State &state = context->getState();
Olli Etuaho94c91a92018-07-19 15:10:24 +03002768 Framebuffer *framebuffer = state.getDrawFramebuffer();
2769 if (framebuffer->getNumViews() > 1 && state.isQueryActive(QueryType::TimeElapsed))
2770 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002771 context->validationError(GL_INVALID_OPERATION, kMultiviewTimerQuery);
Olli Etuaho94c91a92018-07-19 15:10:24 +03002772 return false;
2773 }
2774 }
2775
Jamie Madillc29968b2016-01-20 11:17:23 -05002776 return true;
2777}
2778
Jamie Madill5b772312018-03-08 20:28:32 -05002779bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002780{
2781 if (!context->getExtensions().drawBuffers)
2782 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002783 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05002784 return false;
2785 }
2786
2787 return ValidateDrawBuffersBase(context, n, bufs);
2788}
2789
Jamie Madill73a84962016-02-12 09:27:23 -05002790bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002791 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002792 GLint level,
2793 GLint internalformat,
2794 GLsizei width,
2795 GLsizei height,
2796 GLint border,
2797 GLenum format,
2798 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002799 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002800{
Martin Radev1be913c2016-07-11 17:59:16 +03002801 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002802 {
2803 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002804 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002805 }
2806
Martin Radev1be913c2016-07-11 17:59:16 +03002807 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002808 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002809 0, 0, width, height, 1, border, format, type, -1,
2810 pixels);
2811}
2812
Brandon Jones416aaf92018-04-10 08:10:16 -07002813bool ValidateTexImage2DRobustANGLE(Context *context,
2814 TextureTarget target,
2815 GLint level,
2816 GLint internalformat,
2817 GLsizei width,
2818 GLsizei height,
2819 GLint border,
2820 GLenum format,
2821 GLenum type,
2822 GLsizei bufSize,
2823 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002824{
2825 if (!ValidateRobustEntryPoint(context, bufSize))
2826 {
2827 return false;
2828 }
2829
2830 if (context->getClientMajorVersion() < 3)
2831 {
2832 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2833 0, 0, width, height, border, format, type, bufSize,
2834 pixels);
2835 }
2836
2837 ASSERT(context->getClientMajorVersion() >= 3);
2838 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2839 0, 0, width, height, 1, border, format, type, bufSize,
2840 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002841}
2842
2843bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002844 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002845 GLint level,
2846 GLint xoffset,
2847 GLint yoffset,
2848 GLsizei width,
2849 GLsizei height,
2850 GLenum format,
2851 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002852 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002853{
2854
Martin Radev1be913c2016-07-11 17:59:16 +03002855 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002856 {
2857 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002858 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002859 }
2860
Martin Radev1be913c2016-07-11 17:59:16 +03002861 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002862 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002863 yoffset, 0, width, height, 1, 0, format, type, -1,
2864 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002865}
2866
Geoff Langc52f6f12016-10-14 10:18:00 -04002867bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002868 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002869 GLint level,
2870 GLint xoffset,
2871 GLint yoffset,
2872 GLsizei width,
2873 GLsizei height,
2874 GLenum format,
2875 GLenum type,
2876 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002877 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002878{
2879 if (!ValidateRobustEntryPoint(context, bufSize))
2880 {
2881 return false;
2882 }
2883
2884 if (context->getClientMajorVersion() < 3)
2885 {
2886 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2887 yoffset, width, height, 0, format, type, bufSize,
2888 pixels);
2889 }
2890
2891 ASSERT(context->getClientMajorVersion() >= 3);
2892 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2893 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2894 pixels);
2895}
2896
Jamie Madill73a84962016-02-12 09:27:23 -05002897bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002898 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002899 GLint level,
2900 GLenum internalformat,
2901 GLsizei width,
2902 GLsizei height,
2903 GLint border,
2904 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002905 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002906{
Martin Radev1be913c2016-07-11 17:59:16 +03002907 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002908 {
2909 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002910 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002911 {
2912 return false;
2913 }
2914 }
2915 else
2916 {
Martin Radev1be913c2016-07-11 17:59:16 +03002917 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002918 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002919 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002920 data))
2921 {
2922 return false;
2923 }
2924 }
2925
Geoff Langca271392017-04-05 12:30:00 -04002926 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jamie Madillca2ff382018-07-11 09:01:17 -04002927
2928 GLuint blockSize = 0;
2929 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002930 {
Jamie Madille0472f32018-11-27 16:32:45 -05002931 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002932 return false;
2933 }
2934
Jamie Madillca2ff382018-07-11 09:01:17 -04002935 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002936 {
Jamie Madille0472f32018-11-27 16:32:45 -05002937 context->validationError(GL_INVALID_VALUE, kCompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002938 return false;
2939 }
2940
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002941 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002942 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002943 context->validationError(GL_INVALID_ENUM, kRectangleTextureCompressed);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002944 return false;
2945 }
2946
Jamie Madill73a84962016-02-12 09:27:23 -05002947 return true;
2948}
2949
Corentin Wallezb2931602017-04-11 15:58:57 -04002950bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002951 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002952 GLint level,
2953 GLenum internalformat,
2954 GLsizei width,
2955 GLsizei height,
2956 GLint border,
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 ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2967 border, imageSize, data);
2968}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002969
Corentin Wallezb2931602017-04-11 15:58:57 -04002970bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002971 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002972 GLint level,
2973 GLint xoffset,
2974 GLint yoffset,
2975 GLsizei width,
2976 GLsizei height,
2977 GLenum format,
2978 GLsizei imageSize,
2979 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002980 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002981{
2982 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2983 {
2984 return false;
2985 }
2986
2987 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2988 format, imageSize, data);
2989}
2990
Jamie Madill73a84962016-02-12 09:27:23 -05002991bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002992 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002993 GLint level,
2994 GLint xoffset,
2995 GLint yoffset,
2996 GLsizei width,
2997 GLsizei height,
2998 GLenum format,
2999 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003000 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003001{
Martin Radev1be913c2016-07-11 17:59:16 +03003002 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05003003 {
3004 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04003005 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05003006 {
3007 return false;
3008 }
3009 }
3010 else
3011 {
Martin Radev1be913c2016-07-11 17:59:16 +03003012 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05003013 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04003014 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05003015 data))
3016 {
3017 return false;
3018 }
3019 }
3020
Geoff Langca271392017-04-05 12:30:00 -04003021 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jamie Madillca2ff382018-07-11 09:01:17 -04003022 GLuint blockSize = 0;
3023 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04003024 {
Jamie Madille0472f32018-11-27 16:32:45 -05003025 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04003026 return false;
3027 }
3028
Jamie Madillca2ff382018-07-11 09:01:17 -04003029 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05003030 {
Jamie Madille0472f32018-11-27 16:32:45 -05003031 context->validationError(GL_INVALID_VALUE, kInvalidCompressedImageSize);
Jamie Madill73a84962016-02-12 09:27:23 -05003032 return false;
3033 }
3034
3035 return true;
3036}
3037
Corentin Wallez336129f2017-10-17 15:55:40 -04003038bool ValidateGetBufferPointervOES(Context *context,
3039 BufferBinding target,
3040 GLenum pname,
3041 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003042{
Jamie Madillc3e37312018-11-30 15:25:39 -05003043 if (!context->getExtensions().mapBuffer)
3044 {
3045 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3046 return false;
3047 }
3048
Geoff Lang496c02d2016-10-20 11:38:11 -07003049 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003050}
3051
Corentin Wallez336129f2017-10-17 15:55:40 -04003052bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003053{
3054 if (!context->getExtensions().mapBuffer)
3055 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003056 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03003057 return false;
3058 }
3059
Corentin Walleze4477002017-12-01 14:39:58 -05003060 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003061 {
Jamie Madille0472f32018-11-27 16:32:45 -05003062 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003063 return false;
3064 }
3065
Jamie Madillc3dc5d42018-12-30 12:12:04 -05003066 Buffer *buffer = context->getState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003067
3068 if (buffer == nullptr)
3069 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003070 context->validationError(GL_INVALID_OPERATION, kBufferNotMappable);
Olli Etuaho4f667482016-03-30 15:56:35 +03003071 return false;
3072 }
3073
3074 if (access != GL_WRITE_ONLY_OES)
3075 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003076 context->validationError(GL_INVALID_ENUM, kInvalidAccessBits);
Olli Etuaho4f667482016-03-30 15:56:35 +03003077 return false;
3078 }
3079
3080 if (buffer->isMapped())
3081 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003082 context->validationError(GL_INVALID_OPERATION, kBufferAlreadyMapped);
Olli Etuaho4f667482016-03-30 15:56:35 +03003083 return false;
3084 }
3085
Geoff Lang79f71042017-08-14 16:43:43 -04003086 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003087}
3088
Corentin Wallez336129f2017-10-17 15:55:40 -04003089bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03003090{
3091 if (!context->getExtensions().mapBuffer)
3092 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003093 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03003094 return false;
3095 }
3096
3097 return ValidateUnmapBufferBase(context, target);
3098}
3099
3100bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003101 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003102 GLintptr offset,
3103 GLsizeiptr length,
3104 GLbitfield access)
3105{
3106 if (!context->getExtensions().mapBufferRange)
3107 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003108 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03003109 return false;
3110 }
3111
3112 return ValidateMapBufferRangeBase(context, target, offset, length, access);
3113}
3114
Michael Spang7a8c3e52019-04-03 14:49:57 -04003115bool ValidateBufferStorageMemEXT(Context *context,
3116 TextureType target,
3117 GLsizeiptr size,
3118 GLuint memory,
3119 GLuint64 offset)
3120{
3121 if (!context->getExtensions().memoryObject)
3122 {
3123 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3124 return false;
3125 }
3126
3127 UNIMPLEMENTED();
3128 return false;
3129}
3130
3131bool ValidateCreateMemoryObjectsEXT(Context *context, GLsizei n, GLuint *memoryObjects)
3132{
3133 if (!context->getExtensions().memoryObject)
3134 {
3135 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3136 return false;
3137 }
3138
Michael Spangfb201c52019-04-03 14:57:35 -04003139 return ValidateGenOrDelete(context, n);
Michael Spang7a8c3e52019-04-03 14:49:57 -04003140}
3141
3142bool ValidateDeleteMemoryObjectsEXT(Context *context, GLsizei n, const GLuint *memoryObjects)
3143{
3144 if (!context->getExtensions().memoryObject)
3145 {
3146 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3147 return false;
3148 }
3149
Michael Spangfb201c52019-04-03 14:57:35 -04003150 return ValidateGenOrDelete(context, n);
Michael Spang7a8c3e52019-04-03 14:49:57 -04003151}
3152
3153bool ValidateGetMemoryObjectParameterivEXT(Context *context,
3154 GLuint memoryObject,
3155 GLenum pname,
3156 GLint *params)
3157{
3158 if (!context->getExtensions().memoryObject)
3159 {
3160 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3161 return false;
3162 }
3163
3164 UNIMPLEMENTED();
3165 return false;
3166}
3167
3168bool ValidateGetUnsignedBytevEXT(Context *context, GLenum pname, GLubyte *data)
3169{
3170 if (!context->getExtensions().memoryObject && !context->getExtensions().semaphore)
3171 {
3172 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3173 return false;
3174 }
3175
3176 UNIMPLEMENTED();
3177 return false;
3178}
3179
3180bool ValidateGetUnsignedBytei_vEXT(Context *context, GLenum target, GLuint index, GLubyte *data)
3181{
3182 if (!context->getExtensions().memoryObject && !context->getExtensions().semaphore)
3183 {
3184 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3185 return false;
3186 }
3187
3188 UNIMPLEMENTED();
3189 return false;
3190}
3191
3192bool ValidateIsMemoryObjectEXT(Context *context, GLuint memoryObject)
3193{
3194 if (!context->getExtensions().memoryObject)
3195 {
3196 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3197 return false;
3198 }
3199
Michael Spangfb201c52019-04-03 14:57:35 -04003200 return true;
Michael Spang7a8c3e52019-04-03 14:49:57 -04003201}
3202
3203bool ValidateMemoryObjectParameterivEXT(Context *context,
3204 GLuint memoryObject,
3205 GLenum pname,
3206 const GLint *params)
3207{
3208 if (!context->getExtensions().memoryObject)
3209 {
3210 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3211 return false;
3212 }
3213
3214 UNIMPLEMENTED();
3215 return false;
3216}
3217
3218bool ValidateTexStorageMem2DEXT(Context *context,
3219 TextureType target,
3220 GLsizei levels,
3221 GLenum internalFormat,
3222 GLsizei width,
3223 GLsizei height,
3224 GLuint memory,
3225 GLuint64 offset)
3226{
3227 if (!context->getExtensions().memoryObject)
3228 {
3229 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3230 return false;
3231 }
3232
Michael Spangf02a7672019-04-09 18:45:23 -04003233 if (context->getClientMajorVersion() < 3)
3234 {
3235 return ValidateES2TexStorageParameters(context, target, levels, internalFormat, width,
3236 height);
3237 }
3238
3239 ASSERT(context->getClientMajorVersion() >= 3);
3240 return ValidateES3TexStorage2DParameters(context, target, levels, internalFormat, width, height,
3241 1);
Michael Spang7a8c3e52019-04-03 14:49:57 -04003242}
3243
3244bool ValidateTexStorageMem3DEXT(Context *context,
3245 TextureType target,
3246 GLsizei levels,
3247 GLenum internalFormat,
3248 GLsizei width,
3249 GLsizei height,
3250 GLsizei depth,
3251 GLuint memory,
3252 GLuint64 offset)
3253{
3254 if (!context->getExtensions().memoryObject)
3255 {
3256 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3257 return false;
3258 }
3259
3260 UNIMPLEMENTED();
3261 return false;
3262}
3263
Michael Spang9de3ddb2019-04-03 16:23:40 -04003264bool ValidateImportMemoryFdEXT(Context *context,
3265 GLuint memory,
3266 GLuint64 size,
Michael Spange0da9ce2019-04-16 14:34:51 -04003267 HandleType handleType,
Michael Spang9de3ddb2019-04-03 16:23:40 -04003268 GLint fd)
3269{
3270 if (!context->getExtensions().memoryObjectFd)
3271 {
3272 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3273 return false;
3274 }
3275
Michael Spang3b2c6bf2019-04-16 17:19:50 -04003276 switch (handleType)
3277 {
3278 case HandleType::OpaqueFd:
3279 break;
3280 default:
3281 context->validationError(GL_INVALID_ENUM, kInvalidHandleType);
3282 return false;
3283 }
3284
3285 return true;
Michael Spang9de3ddb2019-04-03 16:23:40 -04003286}
3287
Michael Spang7a8c3e52019-04-03 14:49:57 -04003288bool ValidateDeleteSemaphoresEXT(Context *context, GLsizei n, const GLuint *semaphores)
3289{
3290 if (!context->getExtensions().semaphore)
3291 {
3292 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3293 return false;
3294 }
3295
Michael Spang5093ba62019-05-14 17:36:36 -04003296 return ValidateGenOrDelete(context, n);
Michael Spang7a8c3e52019-04-03 14:49:57 -04003297}
3298
3299bool ValidateGenSemaphoresEXT(Context *context, GLsizei n, GLuint *semaphores)
3300{
3301 if (!context->getExtensions().semaphore)
3302 {
3303 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3304 return false;
3305 }
3306
Michael Spang5093ba62019-05-14 17:36:36 -04003307 return ValidateGenOrDelete(context, n);
Michael Spang7a8c3e52019-04-03 14:49:57 -04003308}
3309
3310bool ValidateGetSemaphoreParameterui64vEXT(Context *context,
3311 GLuint semaphore,
3312 GLenum pname,
3313 GLuint64 *params)
3314{
3315 if (!context->getExtensions().semaphore)
3316 {
3317 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3318 return false;
3319 }
3320
3321 UNIMPLEMENTED();
3322 return false;
3323}
3324
3325bool ValidateIsSemaphoreEXT(Context *context, GLuint semaphore)
3326{
3327 if (!context->getExtensions().semaphore)
3328 {
3329 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3330 return false;
3331 }
3332
Michael Spang5093ba62019-05-14 17:36:36 -04003333 return true;
Michael Spang7a8c3e52019-04-03 14:49:57 -04003334}
3335
3336bool ValidateSemaphoreParameterui64vEXT(Context *context,
3337 GLuint semaphore,
3338 GLenum pname,
3339 const GLuint64 *params)
3340{
3341 if (!context->getExtensions().semaphore)
3342 {
3343 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3344 return false;
3345 }
3346
3347 UNIMPLEMENTED();
3348 return false;
3349}
3350
3351bool ValidateSignalSemaphoreEXT(Context *context,
3352 GLuint semaphore,
3353 GLuint numBufferBarriers,
3354 const GLuint *buffers,
3355 GLuint numTextureBarriers,
3356 const GLuint *textures,
3357 const GLenum *dstLayouts)
3358{
3359 if (!context->getExtensions().semaphore)
3360 {
3361 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3362 return false;
3363 }
3364
Michael Spangab6a59b2019-05-21 21:26:26 -04003365 for (GLuint i = 0; i < numTextureBarriers; ++i)
3366 {
3367 if (!IsValidImageLayout(FromGLenum<ImageLayout>(dstLayouts[i])))
3368 {
3369 context->validationError(GL_INVALID_ENUM, kInvalidImageLayout);
3370 return false;
3371 }
3372 }
3373
3374 return true;
Michael Spang7a8c3e52019-04-03 14:49:57 -04003375}
3376
3377bool ValidateWaitSemaphoreEXT(Context *context,
3378 GLuint semaphore,
3379 GLuint numBufferBarriers,
3380 const GLuint *buffers,
3381 GLuint numTextureBarriers,
3382 const GLuint *textures,
3383 const GLenum *srcLayouts)
3384{
3385 if (!context->getExtensions().semaphore)
3386 {
3387 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3388 return false;
3389 }
3390
Michael Spangab6a59b2019-05-21 21:26:26 -04003391 for (GLuint i = 0; i < numTextureBarriers; ++i)
3392 {
3393 if (!IsValidImageLayout(FromGLenum<ImageLayout>(srcLayouts[i])))
3394 {
3395 context->validationError(GL_INVALID_ENUM, kInvalidImageLayout);
3396 return false;
3397 }
3398 }
3399
3400 return true;
Michael Spang7a8c3e52019-04-03 14:49:57 -04003401}
3402
Michael Spange0da9ce2019-04-16 14:34:51 -04003403bool ValidateImportSemaphoreFdEXT(Context *context,
3404 GLuint semaphore,
3405 HandleType handleType,
3406 GLint fd)
Michael Spang9de3ddb2019-04-03 16:23:40 -04003407{
3408 if (!context->getExtensions().semaphoreFd)
3409 {
3410 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3411 return false;
3412 }
3413
Michael Spang6bb193c2019-05-22 16:32:21 -04003414 switch (handleType)
3415 {
3416 case HandleType::OpaqueFd:
3417 break;
3418 default:
3419 context->validationError(GL_INVALID_ENUM, kInvalidHandleType);
3420 return false;
3421 }
3422
3423 return true;
Michael Spang9de3ddb2019-04-03 16:23:40 -04003424}
3425
Corentin Wallez336129f2017-10-17 15:55:40 -04003426bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04003427{
Jamie Madillc3dc5d42018-12-30 12:12:04 -05003428 Buffer *buffer = context->getState().getTargetBuffer(target);
Geoff Lang79f71042017-08-14 16:43:43 -04003429 ASSERT(buffer != nullptr);
3430
3431 // Check if this buffer is currently being used as a transform feedback output buffer
Jamie Madillc3dc5d42018-12-30 12:12:04 -05003432 TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
Geoff Lang79f71042017-08-14 16:43:43 -04003433 if (transformFeedback != nullptr && transformFeedback->isActive())
3434 {
3435 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
3436 {
3437 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
3438 if (transformFeedbackBuffer.get() == buffer)
3439 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003440 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
Geoff Lang79f71042017-08-14 16:43:43 -04003441 return false;
3442 }
3443 }
3444 }
3445
James Darpiniane8a93c62018-01-04 18:02:24 -08003446 if (context->getExtensions().webglCompatibility &&
3447 buffer->isBoundForTransformFeedbackAndOtherUse())
3448 {
Jamie Madille0472f32018-11-27 16:32:45 -05003449 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08003450 return false;
3451 }
3452
Geoff Lang79f71042017-08-14 16:43:43 -04003453 return true;
3454}
3455
Olli Etuaho4f667482016-03-30 15:56:35 +03003456bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003457 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003458 GLintptr offset,
3459 GLsizeiptr length)
3460{
3461 if (!context->getExtensions().mapBufferRange)
3462 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003463 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03003464 return false;
3465 }
3466
3467 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
3468}
3469
Geoff Langd8605522016-04-13 10:19:12 -04003470bool ValidateBindUniformLocationCHROMIUM(Context *context,
3471 GLuint program,
3472 GLint location,
3473 const GLchar *name)
3474{
3475 if (!context->getExtensions().bindUniformLocation)
3476 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003477 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langd8605522016-04-13 10:19:12 -04003478 return false;
3479 }
3480
3481 Program *programObject = GetValidProgram(context, program);
3482 if (!programObject)
3483 {
3484 return false;
3485 }
3486
3487 if (location < 0)
3488 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003489 context->validationError(GL_INVALID_VALUE, kNegativeLocation);
Geoff Langd8605522016-04-13 10:19:12 -04003490 return false;
3491 }
3492
3493 const Caps &caps = context->getCaps();
3494 if (static_cast<size_t>(location) >=
3495 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3496 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003497 context->validationError(GL_INVALID_VALUE, kInvalidBindUniformLocation);
Geoff Langd8605522016-04-13 10:19:12 -04003498 return false;
3499 }
3500
Geoff Langfc32e8b2017-05-31 14:16:59 -04003501 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3502 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003503 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003504 {
Jamie Madille0472f32018-11-27 16:32:45 -05003505 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003506 return false;
3507 }
3508
Geoff Langd8605522016-04-13 10:19:12 -04003509 if (strncmp(name, "gl_", 3) == 0)
3510 {
Jamie Madille0472f32018-11-27 16:32:45 -05003511 context->validationError(GL_INVALID_VALUE, kNameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003512 return false;
3513 }
3514
3515 return true;
3516}
3517
Jamie Madille2e406c2016-06-02 13:04:10 -04003518bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003519{
3520 if (!context->getExtensions().framebufferMixedSamples)
3521 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003522 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänena797e062016-05-12 15:23:40 +03003523 return false;
3524 }
3525 switch (components)
3526 {
3527 case GL_RGB:
3528 case GL_RGBA:
3529 case GL_ALPHA:
3530 case GL_NONE:
3531 break;
3532 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003533 context->validationError(GL_INVALID_ENUM, kInvalidCoverageComponents);
Sami Väisänena797e062016-05-12 15:23:40 +03003534 return false;
3535 }
3536
3537 return true;
3538}
3539
Sami Väisänene45e53b2016-05-25 10:36:04 +03003540// CHROMIUM_path_rendering
3541
Jamie Madill007530e2017-12-28 14:27:04 -05003542bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003543{
Jamie Madill007530e2017-12-28 14:27:04 -05003544 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003545 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003546 return false;
3547 }
Jamie Madill007530e2017-12-28 14:27:04 -05003548
Sami Väisänene45e53b2016-05-25 10:36:04 +03003549 if (matrix == nullptr)
3550 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003551 context->validationError(GL_INVALID_OPERATION, kInvalidPathMatrix);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003552 return false;
3553 }
Jamie Madill007530e2017-12-28 14:27:04 -05003554
Sami Väisänene45e53b2016-05-25 10:36:04 +03003555 return true;
3556}
3557
Jamie Madill007530e2017-12-28 14:27:04 -05003558bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003559{
Jamie Madill007530e2017-12-28 14:27:04 -05003560 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003561}
3562
Jamie Madill007530e2017-12-28 14:27:04 -05003563bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003564{
3565 if (!context->getExtensions().pathRendering)
3566 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003567 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003568 return false;
3569 }
3570
3571 // range = 0 is undefined in NV_path_rendering.
3572 // we add stricter semantic check here and require a non zero positive range.
3573 if (range <= 0)
3574 {
Jamie Madille0472f32018-11-27 16:32:45 -05003575 context->validationError(GL_INVALID_VALUE, kInvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003576 return false;
3577 }
3578
3579 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3580 {
Jamie Madille0472f32018-11-27 16:32:45 -05003581 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003582 return false;
3583 }
3584
3585 return true;
3586}
3587
Jamie Madill007530e2017-12-28 14:27:04 -05003588bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003589{
3590 if (!context->getExtensions().pathRendering)
3591 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003592 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003593 return false;
3594 }
3595
3596 // range = 0 is undefined in NV_path_rendering.
3597 // we add stricter semantic check here and require a non zero positive range.
3598 if (range <= 0)
3599 {
Jamie Madille0472f32018-11-27 16:32:45 -05003600 context->validationError(GL_INVALID_VALUE, kInvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003601 return false;
3602 }
3603
3604 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3605 checkedRange += range;
3606
3607 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3608 {
Jamie Madille0472f32018-11-27 16:32:45 -05003609 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003610 return false;
3611 }
3612 return true;
3613}
3614
Jamie Madill007530e2017-12-28 14:27:04 -05003615bool ValidatePathCommandsCHROMIUM(Context *context,
3616 GLuint path,
3617 GLsizei numCommands,
3618 const GLubyte *commands,
3619 GLsizei numCoords,
3620 GLenum coordType,
3621 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003622{
3623 if (!context->getExtensions().pathRendering)
3624 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003625 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003626 return false;
3627 }
Brandon Jones59770802018-04-02 13:18:42 -07003628 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003629 {
Jamie Madille0472f32018-11-27 16:32:45 -05003630 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003631 return false;
3632 }
3633
3634 if (numCommands < 0)
3635 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003636 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCommands);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003637 return false;
3638 }
3639 else if (numCommands > 0)
3640 {
3641 if (!commands)
3642 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003643 context->validationError(GL_INVALID_VALUE, kInvalidPathCommandsArray);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003644 return false;
3645 }
3646 }
3647
3648 if (numCoords < 0)
3649 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003650 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCoords);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003651 return false;
3652 }
3653 else if (numCoords > 0)
3654 {
3655 if (!coords)
3656 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003657 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCoordsArray);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003658 return false;
3659 }
3660 }
3661
3662 std::uint32_t coordTypeSize = 0;
3663 switch (coordType)
3664 {
3665 case GL_BYTE:
3666 coordTypeSize = sizeof(GLbyte);
3667 break;
3668
3669 case GL_UNSIGNED_BYTE:
3670 coordTypeSize = sizeof(GLubyte);
3671 break;
3672
3673 case GL_SHORT:
3674 coordTypeSize = sizeof(GLshort);
3675 break;
3676
3677 case GL_UNSIGNED_SHORT:
3678 coordTypeSize = sizeof(GLushort);
3679 break;
3680
3681 case GL_FLOAT:
3682 coordTypeSize = sizeof(GLfloat);
3683 break;
3684
3685 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003686 context->validationError(GL_INVALID_ENUM, kInvalidPathCoordinateType);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003687 return false;
3688 }
3689
3690 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3691 checkedSize += (coordTypeSize * numCoords);
3692 if (!checkedSize.IsValid())
3693 {
Jamie Madille0472f32018-11-27 16:32:45 -05003694 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003695 return false;
3696 }
3697
3698 // early return skips command data validation when it doesn't exist.
3699 if (!commands)
3700 return true;
3701
3702 GLsizei expectedNumCoords = 0;
3703 for (GLsizei i = 0; i < numCommands; ++i)
3704 {
3705 switch (commands[i])
3706 {
3707 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3708 break;
3709 case GL_MOVE_TO_CHROMIUM:
3710 case GL_LINE_TO_CHROMIUM:
3711 expectedNumCoords += 2;
3712 break;
3713 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3714 expectedNumCoords += 4;
3715 break;
3716 case GL_CUBIC_CURVE_TO_CHROMIUM:
3717 expectedNumCoords += 6;
3718 break;
3719 case GL_CONIC_CURVE_TO_CHROMIUM:
3720 expectedNumCoords += 5;
3721 break;
3722 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003723 context->validationError(GL_INVALID_ENUM, kInvalidPathCommand);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003724 return false;
3725 }
3726 }
Jamie Madillc3e37312018-11-30 15:25:39 -05003727
Sami Väisänene45e53b2016-05-25 10:36:04 +03003728 if (expectedNumCoords != numCoords)
3729 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003730 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCoords);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003731 return false;
3732 }
3733
3734 return true;
3735}
3736
Jamie Madill007530e2017-12-28 14:27:04 -05003737bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003738{
3739 if (!context->getExtensions().pathRendering)
3740 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003741 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003742 return false;
3743 }
Brandon Jones59770802018-04-02 13:18:42 -07003744 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003745 {
Jamie Madille0472f32018-11-27 16:32:45 -05003746 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003747 return false;
3748 }
3749
3750 switch (pname)
3751 {
3752 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3753 if (value < 0.0f)
3754 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003755 context->validationError(GL_INVALID_VALUE, kInvalidPathStrokeWidth);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003756 return false;
3757 }
3758 break;
3759 case GL_PATH_END_CAPS_CHROMIUM:
3760 switch (static_cast<GLenum>(value))
3761 {
3762 case GL_FLAT_CHROMIUM:
3763 case GL_SQUARE_CHROMIUM:
3764 case GL_ROUND_CHROMIUM:
3765 break;
3766 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003767 context->validationError(GL_INVALID_ENUM, kInvalidPathEndCaps);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003768 return false;
3769 }
3770 break;
3771 case GL_PATH_JOIN_STYLE_CHROMIUM:
3772 switch (static_cast<GLenum>(value))
3773 {
3774 case GL_MITER_REVERT_CHROMIUM:
3775 case GL_BEVEL_CHROMIUM:
3776 case GL_ROUND_CHROMIUM:
3777 break;
3778 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003779 context->validationError(GL_INVALID_ENUM, kInvalidPathJoinStyle);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003780 return false;
3781 }
Nico Weber41b072b2018-02-09 10:01:32 -05003782 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003783 case GL_PATH_MITER_LIMIT_CHROMIUM:
3784 if (value < 0.0f)
3785 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003786 context->validationError(GL_INVALID_VALUE, kInvalidPathMiterLimit);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003787 return false;
3788 }
3789 break;
3790
3791 case GL_PATH_STROKE_BOUND_CHROMIUM:
3792 // no errors, only clamping.
3793 break;
3794
3795 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003796 context->validationError(GL_INVALID_ENUM, kInvalidPathParameter);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003797 return false;
3798 }
3799 return true;
3800}
3801
Jamie Madill007530e2017-12-28 14:27:04 -05003802bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3803{
3804 // TODO(jmadill): Use proper clamping cast.
3805 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3806}
3807
3808bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003809{
3810 if (!context->getExtensions().pathRendering)
3811 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003812 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003813 return false;
3814 }
3815
Brandon Jones59770802018-04-02 13:18:42 -07003816 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003817 {
Jamie Madille0472f32018-11-27 16:32:45 -05003818 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003819 return false;
3820 }
Jamie Madillc3e37312018-11-30 15:25:39 -05003821
Sami Väisänene45e53b2016-05-25 10:36:04 +03003822 if (!value)
3823 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003824 context->validationError(GL_INVALID_VALUE, kInvalidPathValueArray);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003825 return false;
3826 }
3827
3828 switch (pname)
3829 {
3830 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3831 case GL_PATH_END_CAPS_CHROMIUM:
3832 case GL_PATH_JOIN_STYLE_CHROMIUM:
3833 case GL_PATH_MITER_LIMIT_CHROMIUM:
3834 case GL_PATH_STROKE_BOUND_CHROMIUM:
3835 break;
3836
3837 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003838 context->validationError(GL_INVALID_ENUM, kInvalidPathParameter);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003839 return false;
3840 }
3841
3842 return true;
3843}
3844
Jamie Madill007530e2017-12-28 14:27:04 -05003845bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3846{
3847 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3848 reinterpret_cast<GLfloat *>(value));
3849}
3850
3851bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003852{
3853 if (!context->getExtensions().pathRendering)
3854 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003855 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003856 return false;
3857 }
3858
3859 switch (func)
3860 {
3861 case GL_NEVER:
3862 case GL_ALWAYS:
3863 case GL_LESS:
3864 case GL_LEQUAL:
3865 case GL_EQUAL:
3866 case GL_GEQUAL:
3867 case GL_GREATER:
3868 case GL_NOTEQUAL:
3869 break;
3870 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003871 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003872 return false;
3873 }
3874
3875 return true;
3876}
3877
3878// Note that the spec specifies that for the path drawing commands
3879// if the path object is not an existing path object the command
3880// does nothing and no error is generated.
3881// However if the path object exists but has not been specified any
3882// commands then an error is generated.
3883
Jamie Madill007530e2017-12-28 14:27:04 -05003884bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003885{
3886 if (!context->getExtensions().pathRendering)
3887 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003888 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003889 return false;
3890 }
Brandon Jones59770802018-04-02 13:18:42 -07003891 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003892 {
Jamie Madille0472f32018-11-27 16:32:45 -05003893 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003894 return false;
3895 }
3896
3897 switch (fillMode)
3898 {
3899 case GL_COUNT_UP_CHROMIUM:
3900 case GL_COUNT_DOWN_CHROMIUM:
3901 break;
3902 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003903 context->validationError(GL_INVALID_ENUM, kInvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003904 return false;
3905 }
3906
3907 if (!isPow2(mask + 1))
3908 {
Jamie Madille0472f32018-11-27 16:32:45 -05003909 context->validationError(GL_INVALID_VALUE, kInvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003910 return false;
3911 }
3912
3913 return true;
3914}
3915
Jamie Madill007530e2017-12-28 14:27:04 -05003916bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003917{
3918 if (!context->getExtensions().pathRendering)
3919 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003920 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003921 return false;
3922 }
Jamie Madillc3e37312018-11-30 15:25:39 -05003923
Brandon Jones59770802018-04-02 13:18:42 -07003924 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003925 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003926 context->validationError(GL_INVALID_OPERATION, kNoPathOrNoPathData);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003927 return false;
3928 }
3929
3930 return true;
3931}
3932
Jamie Madill007530e2017-12-28 14:27:04 -05003933bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003934{
3935 if (!context->getExtensions().pathRendering)
3936 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003937 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003938 return false;
3939 }
Brandon Jones59770802018-04-02 13:18:42 -07003940 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003941 {
Jamie Madille0472f32018-11-27 16:32:45 -05003942 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003943 return false;
3944 }
3945
3946 switch (coverMode)
3947 {
3948 case GL_CONVEX_HULL_CHROMIUM:
3949 case GL_BOUNDING_BOX_CHROMIUM:
3950 break;
3951 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003952 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003953 return false;
3954 }
3955 return true;
3956}
3957
Jamie Madill778bf092018-11-14 09:54:36 -05003958bool ValidateCoverFillPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3959{
3960 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3961}
3962
3963bool ValidateCoverStrokePathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3964{
3965 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3966}
3967
Jamie Madill007530e2017-12-28 14:27:04 -05003968bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3969 GLuint path,
3970 GLenum fillMode,
3971 GLuint mask,
3972 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003973{
Jamie Madill007530e2017-12-28 14:27:04 -05003974 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3975 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003976}
3977
Jamie Madill007530e2017-12-28 14:27:04 -05003978bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3979 GLuint path,
3980 GLint reference,
3981 GLuint mask,
3982 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003983{
Jamie Madill007530e2017-12-28 14:27:04 -05003984 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3985 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003986}
3987
Brandon Jonesd1049182018-03-28 10:02:20 -07003988bool ValidateIsPathCHROMIUM(Context *context, GLuint path)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003989{
3990 if (!context->getExtensions().pathRendering)
3991 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003992 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003993 return false;
3994 }
3995 return true;
3996}
3997
Jamie Madill007530e2017-12-28 14:27:04 -05003998bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3999 GLsizei numPaths,
4000 GLenum pathNameType,
4001 const void *paths,
4002 GLuint pathBase,
4003 GLenum coverMode,
4004 GLenum transformType,
4005 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03004006{
4007 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
4008 transformType, transformValues))
4009 return false;
4010
4011 switch (coverMode)
4012 {
4013 case GL_CONVEX_HULL_CHROMIUM:
4014 case GL_BOUNDING_BOX_CHROMIUM:
4015 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
4016 break;
4017 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004018 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03004019 return false;
4020 }
4021
4022 return true;
4023}
4024
Jamie Madill007530e2017-12-28 14:27:04 -05004025bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
4026 GLsizei numPaths,
4027 GLenum pathNameType,
4028 const void *paths,
4029 GLuint pathBase,
4030 GLenum coverMode,
4031 GLenum transformType,
4032 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03004033{
4034 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
4035 transformType, transformValues))
4036 return false;
4037
4038 switch (coverMode)
4039 {
4040 case GL_CONVEX_HULL_CHROMIUM:
4041 case GL_BOUNDING_BOX_CHROMIUM:
4042 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
4043 break;
4044 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004045 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03004046 return false;
4047 }
4048
4049 return true;
4050}
4051
Jamie Madill007530e2017-12-28 14:27:04 -05004052bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
4053 GLsizei numPaths,
4054 GLenum pathNameType,
4055 const void *paths,
4056 GLuint pathBase,
4057 GLenum fillMode,
4058 GLuint mask,
4059 GLenum transformType,
4060 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03004061{
4062
4063 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
4064 transformType, transformValues))
4065 return false;
4066
4067 switch (fillMode)
4068 {
4069 case GL_COUNT_UP_CHROMIUM:
4070 case GL_COUNT_DOWN_CHROMIUM:
4071 break;
4072 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004073 context->validationError(GL_INVALID_ENUM, kInvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03004074 return false;
4075 }
4076 if (!isPow2(mask + 1))
4077 {
Jamie Madille0472f32018-11-27 16:32:45 -05004078 context->validationError(GL_INVALID_VALUE, kInvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03004079 return false;
4080 }
4081 return true;
4082}
4083
Jamie Madill007530e2017-12-28 14:27:04 -05004084bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
4085 GLsizei numPaths,
4086 GLenum pathNameType,
4087 const void *paths,
4088 GLuint pathBase,
4089 GLint reference,
4090 GLuint mask,
4091 GLenum transformType,
4092 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03004093{
4094 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
4095 transformType, transformValues))
4096 return false;
4097
4098 // no more validation here.
4099
4100 return true;
4101}
4102
Jamie Madill007530e2017-12-28 14:27:04 -05004103bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
4104 GLsizei numPaths,
4105 GLenum pathNameType,
4106 const void *paths,
4107 GLuint pathBase,
4108 GLenum fillMode,
4109 GLuint mask,
4110 GLenum coverMode,
4111 GLenum transformType,
4112 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03004113{
4114 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
4115 transformType, transformValues))
4116 return false;
4117
4118 switch (coverMode)
4119 {
4120 case GL_CONVEX_HULL_CHROMIUM:
4121 case GL_BOUNDING_BOX_CHROMIUM:
4122 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
4123 break;
4124 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004125 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03004126 return false;
4127 }
4128
4129 switch (fillMode)
4130 {
4131 case GL_COUNT_UP_CHROMIUM:
4132 case GL_COUNT_DOWN_CHROMIUM:
4133 break;
4134 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004135 context->validationError(GL_INVALID_ENUM, kInvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03004136 return false;
4137 }
4138 if (!isPow2(mask + 1))
4139 {
Jamie Madille0472f32018-11-27 16:32:45 -05004140 context->validationError(GL_INVALID_VALUE, kInvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03004141 return false;
4142 }
4143
4144 return true;
4145}
4146
Jamie Madill007530e2017-12-28 14:27:04 -05004147bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
4148 GLsizei numPaths,
4149 GLenum pathNameType,
4150 const void *paths,
4151 GLuint pathBase,
4152 GLint reference,
4153 GLuint mask,
4154 GLenum coverMode,
4155 GLenum transformType,
4156 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03004157{
4158 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
4159 transformType, transformValues))
4160 return false;
4161
4162 switch (coverMode)
4163 {
4164 case GL_CONVEX_HULL_CHROMIUM:
4165 case GL_BOUNDING_BOX_CHROMIUM:
4166 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
4167 break;
4168 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004169 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03004170 return false;
4171 }
4172
4173 return true;
4174}
4175
Jamie Madill007530e2017-12-28 14:27:04 -05004176bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
4177 GLuint program,
4178 GLint location,
4179 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03004180{
4181 if (!context->getExtensions().pathRendering)
4182 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004183 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004184 return false;
4185 }
4186
4187 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
4188 if (location >= MaxLocation)
4189 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004190 context->validationError(GL_INVALID_VALUE, kInvalidVaryingLocation);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004191 return false;
4192 }
4193
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004194 const auto *programObject = context->getProgramNoResolveLink(program);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004195 if (!programObject)
4196 {
Jamie Madille0472f32018-11-27 16:32:45 -05004197 context->validationError(GL_INVALID_OPERATION, kProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004198 return false;
4199 }
4200
4201 if (!name)
4202 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004203 context->validationError(GL_INVALID_VALUE, kMissingName);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004204 return false;
4205 }
4206
4207 if (angle::BeginsWith(name, "gl_"))
4208 {
Jamie Madille0472f32018-11-27 16:32:45 -05004209 context->validationError(GL_INVALID_OPERATION, kNameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004210 return false;
4211 }
4212
4213 return true;
4214}
4215
Jamie Madill007530e2017-12-28 14:27:04 -05004216bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
4217 GLuint program,
4218 GLint location,
4219 GLenum genMode,
4220 GLint components,
4221 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03004222{
4223 if (!context->getExtensions().pathRendering)
4224 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004225 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004226 return false;
4227 }
4228
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004229 const auto *programObject = context->getProgramResolveLink(program);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004230 if (!programObject || programObject->isFlaggedForDeletion())
4231 {
Jamie Madille0472f32018-11-27 16:32:45 -05004232 context->validationError(GL_INVALID_OPERATION, kProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004233 return false;
4234 }
4235
4236 if (!programObject->isLinked())
4237 {
Jamie Madille0472f32018-11-27 16:32:45 -05004238 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004239 return false;
4240 }
4241
4242 switch (genMode)
4243 {
4244 case GL_NONE:
4245 if (components != 0)
4246 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004247 context->validationError(GL_INVALID_VALUE, kInvalidComponents);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004248 return false;
4249 }
4250 break;
4251
4252 case GL_OBJECT_LINEAR_CHROMIUM:
4253 case GL_EYE_LINEAR_CHROMIUM:
4254 case GL_CONSTANT_CHROMIUM:
4255 if (components < 1 || components > 4)
4256 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004257 context->validationError(GL_INVALID_VALUE, kInvalidComponents);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004258 return false;
4259 }
4260 if (!coeffs)
4261 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004262 context->validationError(GL_INVALID_VALUE, kInvalidPathCoefficientsArray);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004263 return false;
4264 }
4265 break;
4266
4267 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05004268 context->validationError(GL_INVALID_ENUM, kInvalidPathGenMode);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004269 return false;
4270 }
4271
4272 // If the location is -1 then the command is silently ignored
4273 // and no further validation is needed.
4274 if (location == -1)
4275 return true;
4276
jchen103fd614d2018-08-13 12:21:58 +08004277 const auto &binding = programObject->getFragmentInputBindingInfo(location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004278
4279 if (!binding.valid)
4280 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004281 context->validationError(GL_INVALID_OPERATION, kInvalidFragmentInputBinding);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004282 return false;
4283 }
4284
4285 if (binding.type != GL_NONE)
4286 {
4287 GLint expectedComponents = 0;
4288 switch (binding.type)
4289 {
4290 case GL_FLOAT:
4291 expectedComponents = 1;
4292 break;
4293 case GL_FLOAT_VEC2:
4294 expectedComponents = 2;
4295 break;
4296 case GL_FLOAT_VEC3:
4297 expectedComponents = 3;
4298 break;
4299 case GL_FLOAT_VEC4:
4300 expectedComponents = 4;
4301 break;
4302 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05004303 context->validationError(GL_INVALID_OPERATION, kFragmentInputTypeNotFloatingPoint);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004304 return false;
4305 }
4306 if (expectedComponents != components && genMode != GL_NONE)
4307 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004308 context->validationError(GL_INVALID_OPERATION, kInvalidPathComponents);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004309 return false;
4310 }
4311 }
4312 return true;
4313}
4314
Geoff Lang97073d12016-04-20 10:42:34 -07004315bool ValidateCopyTextureCHROMIUM(Context *context,
4316 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04004317 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004318 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07004319 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04004320 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07004321 GLint internalFormat,
4322 GLenum destType,
4323 GLboolean unpackFlipY,
4324 GLboolean unpackPremultiplyAlpha,
4325 GLboolean unpackUnmultiplyAlpha)
4326{
4327 if (!context->getExtensions().copyTexture)
4328 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004329 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang97073d12016-04-20 10:42:34 -07004330 return false;
4331 }
4332
Geoff Lang4f0e0032017-05-01 16:04:35 -04004333 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004334 if (source == nullptr)
4335 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004336 context->validationError(GL_INVALID_VALUE, kInvalidSourceTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07004337 return false;
4338 }
4339
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004340 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004341 {
Jamie Madille0472f32018-11-27 16:32:45 -05004342 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004343 return false;
4344 }
4345
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004346 TextureType sourceType = source->getType();
4347 ASSERT(sourceType != TextureType::CubeMap);
4348 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004349
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004350 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004351 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004352 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureLevel);
Geoff Lang97073d12016-04-20 10:42:34 -07004353 return false;
4354 }
4355
Geoff Lang4f0e0032017-05-01 16:04:35 -04004356 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
4357 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
4358 if (sourceWidth == 0 || sourceHeight == 0)
4359 {
Jamie Madille0472f32018-11-27 16:32:45 -05004360 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004361 return false;
4362 }
4363
4364 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
4365 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004366 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004367 context->validationError(GL_INVALID_OPERATION, kInvalidSourceTextureInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004368 return false;
4369 }
4370
Geoff Lang63458a32017-10-30 15:16:53 -04004371 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4372 {
Jamie Madille0472f32018-11-27 16:32:45 -05004373 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Lang63458a32017-10-30 15:16:53 -04004374 return false;
4375 }
4376
Geoff Lang4f0e0032017-05-01 16:04:35 -04004377 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004378 if (dest == nullptr)
4379 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004380 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07004381 return false;
4382 }
4383
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004384 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004385 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004386 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTextureType);
Geoff Lang97073d12016-04-20 10:42:34 -07004387 return false;
4388 }
4389
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004390 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08004391 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004392 {
Jamie Madille0472f32018-11-27 16:32:45 -05004393 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004394 return false;
4395 }
4396
Geoff Lang97073d12016-04-20 10:42:34 -07004397 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
4398 {
Geoff Lang97073d12016-04-20 10:42:34 -07004399 return false;
4400 }
4401
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004402 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04004403 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004404 context->validationError(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004405 return false;
4406 }
4407
Geoff Lang97073d12016-04-20 10:42:34 -07004408 if (dest->getImmutableFormat())
4409 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004410 context->validationError(GL_INVALID_OPERATION, kDestinationImmutable);
Geoff Lang97073d12016-04-20 10:42:34 -07004411 return false;
4412 }
4413
4414 return true;
4415}
4416
4417bool ValidateCopySubTextureCHROMIUM(Context *context,
4418 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04004419 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004420 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07004421 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04004422 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07004423 GLint xoffset,
4424 GLint yoffset,
4425 GLint x,
4426 GLint y,
4427 GLsizei width,
4428 GLsizei height,
4429 GLboolean unpackFlipY,
4430 GLboolean unpackPremultiplyAlpha,
4431 GLboolean unpackUnmultiplyAlpha)
4432{
4433 if (!context->getExtensions().copyTexture)
4434 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004435 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang97073d12016-04-20 10:42:34 -07004436 return false;
4437 }
4438
Geoff Lang4f0e0032017-05-01 16:04:35 -04004439 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004440 if (source == nullptr)
4441 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004442 context->validationError(GL_INVALID_VALUE, kInvalidSourceTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07004443 return false;
4444 }
4445
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004446 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004447 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004448 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureType);
Geoff Lang97073d12016-04-20 10:42:34 -07004449 return false;
4450 }
4451
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004452 TextureType sourceType = source->getType();
4453 ASSERT(sourceType != TextureType::CubeMap);
4454 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004455
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004456 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004457 {
Jamie Madille0472f32018-11-27 16:32:45 -05004458 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004459 return false;
4460 }
4461
4462 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4463 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004464 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004465 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureLevel);
Geoff Lang97073d12016-04-20 10:42:34 -07004466 return false;
4467 }
4468
4469 if (x < 0 || y < 0)
4470 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004471 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004472 return false;
4473 }
4474
4475 if (width < 0 || height < 0)
4476 {
Jamie Madille0472f32018-11-27 16:32:45 -05004477 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004478 return false;
4479 }
4480
Geoff Lang4f0e0032017-05-01 16:04:35 -04004481 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4482 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004483 {
Jamie Madille0472f32018-11-27 16:32:45 -05004484 context->validationError(GL_INVALID_VALUE, kSourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004485 return false;
4486 }
4487
Geoff Lang4f0e0032017-05-01 16:04:35 -04004488 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4489 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004490 {
Jamie Madille0472f32018-11-27 16:32:45 -05004491 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004492 return false;
4493 }
4494
Geoff Lang63458a32017-10-30 15:16:53 -04004495 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4496 {
Jamie Madille0472f32018-11-27 16:32:45 -05004497 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Lang63458a32017-10-30 15:16:53 -04004498 return false;
4499 }
4500
Geoff Lang4f0e0032017-05-01 16:04:35 -04004501 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004502 if (dest == nullptr)
4503 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004504 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07004505 return false;
4506 }
4507
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004508 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004509 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004510 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTextureType);
Geoff Lang97073d12016-04-20 10:42:34 -07004511 return false;
4512 }
4513
Brandon Jones28783792018-03-05 09:37:32 -08004514 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4515 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004516 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004517 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Lang97073d12016-04-20 10:42:34 -07004518 return false;
4519 }
4520
Geoff Lang4f0e0032017-05-01 16:04:35 -04004521 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4522 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004523 context->validationError(GL_INVALID_OPERATION, kDestinationLevelNotDefined);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004524 return false;
4525 }
4526
4527 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4528 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004529 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004530 context->validationError(GL_INVALID_OPERATION, kInvalidFormatCombination);
Geoff Lang97073d12016-04-20 10:42:34 -07004531 return false;
4532 }
4533
4534 if (xoffset < 0 || yoffset < 0)
4535 {
Jamie Madille0472f32018-11-27 16:32:45 -05004536 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004537 return false;
4538 }
4539
Geoff Lang4f0e0032017-05-01 16:04:35 -04004540 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4541 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004542 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004543 context->validationError(GL_INVALID_VALUE, kOffsetOverflow);
Geoff Lang97073d12016-04-20 10:42:34 -07004544 return false;
4545 }
4546
4547 return true;
4548}
4549
Geoff Lang47110bf2016-04-20 11:13:22 -07004550bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4551{
4552 if (!context->getExtensions().copyCompressedTexture)
4553 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004554 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang47110bf2016-04-20 11:13:22 -07004555 return false;
4556 }
4557
4558 const gl::Texture *source = context->getTexture(sourceId);
4559 if (source == nullptr)
4560 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004561 context->validationError(GL_INVALID_VALUE, kInvalidSourceTexture);
Geoff Lang47110bf2016-04-20 11:13:22 -07004562 return false;
4563 }
4564
Corentin Wallez99d492c2018-02-27 15:17:10 -05004565 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004566 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004567 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureType);
Geoff Lang47110bf2016-04-20 11:13:22 -07004568 return false;
4569 }
4570
Corentin Wallez99d492c2018-02-27 15:17:10 -05004571 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4572 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004573 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004574 context->validationError(GL_INVALID_VALUE, kSourceTextureLevelZeroDefined);
Geoff Lang47110bf2016-04-20 11:13:22 -07004575 return false;
4576 }
4577
Corentin Wallez99d492c2018-02-27 15:17:10 -05004578 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004579 if (!sourceFormat.info->compressed)
4580 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004581 context->validationError(GL_INVALID_OPERATION, kSourceTextureMustBeCompressed);
Geoff Lang47110bf2016-04-20 11:13:22 -07004582 return false;
4583 }
4584
4585 const gl::Texture *dest = context->getTexture(destId);
4586 if (dest == nullptr)
4587 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004588 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTexture);
Geoff Lang47110bf2016-04-20 11:13:22 -07004589 return false;
4590 }
4591
Corentin Wallez99d492c2018-02-27 15:17:10 -05004592 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004593 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004594 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTextureType);
Geoff Lang47110bf2016-04-20 11:13:22 -07004595 return false;
4596 }
4597
4598 if (dest->getImmutableFormat())
4599 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004600 context->validationError(GL_INVALID_OPERATION, kDestinationImmutable);
Geoff Lang47110bf2016-04-20 11:13:22 -07004601 return false;
4602 }
4603
4604 return true;
4605}
4606
Jiawei Shao385b3e02018-03-21 09:43:28 +08004607bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004608{
4609 switch (type)
4610 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004611 case ShaderType::Vertex:
4612 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004613 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004614
Jiawei Shao385b3e02018-03-21 09:43:28 +08004615 case ShaderType::Compute:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004616 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004617 {
Jamie Madille0472f32018-11-27 16:32:45 -05004618 context->validationError(GL_INVALID_ENUM, kES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004619 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004620 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004621 break;
4622
Jiawei Shao385b3e02018-03-21 09:43:28 +08004623 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004624 if (!context->getExtensions().geometryShader)
4625 {
Jamie Madille0472f32018-11-27 16:32:45 -05004626 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
Jiawei Shao89be29a2017-11-06 14:36:45 +08004627 return false;
4628 }
4629 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004630 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004631 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004632 return false;
4633 }
Jamie Madill29639852016-09-02 15:00:09 -04004634
4635 return true;
4636}
4637
Jamie Madill5b772312018-03-08 20:28:32 -05004638bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004639 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004640 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004641 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004642 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004643{
4644 if (size < 0)
4645 {
Jamie Madille0472f32018-11-27 16:32:45 -05004646 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004647 return false;
4648 }
4649
4650 switch (usage)
4651 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004652 case BufferUsage::StreamDraw:
4653 case BufferUsage::StaticDraw:
4654 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004655 break;
4656
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004657 case BufferUsage::StreamRead:
4658 case BufferUsage::StaticRead:
4659 case BufferUsage::DynamicRead:
4660 case BufferUsage::StreamCopy:
4661 case BufferUsage::StaticCopy:
4662 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004663 if (context->getClientMajorVersion() < 3)
4664 {
Jamie Madille0472f32018-11-27 16:32:45 -05004665 context->validationError(GL_INVALID_ENUM, kInvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004666 return false;
4667 }
4668 break;
4669
4670 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004671 context->validationError(GL_INVALID_ENUM, kInvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004672 return false;
4673 }
4674
Corentin Walleze4477002017-12-01 14:39:58 -05004675 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004676 {
Jamie Madille0472f32018-11-27 16:32:45 -05004677 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004678 return false;
4679 }
4680
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004681 Buffer *buffer = context->getState().getTargetBuffer(target);
Jamie Madill29639852016-09-02 15:00:09 -04004682
4683 if (!buffer)
4684 {
Jamie Madille0472f32018-11-27 16:32:45 -05004685 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004686 return false;
4687 }
4688
James Darpiniane8a93c62018-01-04 18:02:24 -08004689 if (context->getExtensions().webglCompatibility &&
4690 buffer->isBoundForTransformFeedbackAndOtherUse())
4691 {
Jamie Madille0472f32018-11-27 16:32:45 -05004692 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08004693 return false;
4694 }
4695
Jamie Madill29639852016-09-02 15:00:09 -04004696 return true;
4697}
4698
Jamie Madill5b772312018-03-08 20:28:32 -05004699bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004700 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004701 GLintptr offset,
4702 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004703 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004704{
Brandon Jones6cad5662017-06-14 13:25:13 -07004705 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004706 {
Jamie Madille0472f32018-11-27 16:32:45 -05004707 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Brandon Jones6cad5662017-06-14 13:25:13 -07004708 return false;
4709 }
4710
4711 if (offset < 0)
4712 {
Jamie Madille0472f32018-11-27 16:32:45 -05004713 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004714 return false;
4715 }
4716
Corentin Walleze4477002017-12-01 14:39:58 -05004717 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004718 {
Jamie Madille0472f32018-11-27 16:32:45 -05004719 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004720 return false;
4721 }
4722
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004723 Buffer *buffer = context->getState().getTargetBuffer(target);
Jamie Madill29639852016-09-02 15:00:09 -04004724
4725 if (!buffer)
4726 {
Jamie Madille0472f32018-11-27 16:32:45 -05004727 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004728 return false;
4729 }
4730
4731 if (buffer->isMapped())
4732 {
Jamie Madille0472f32018-11-27 16:32:45 -05004733 context->validationError(GL_INVALID_OPERATION, kBufferMapped);
Jamie Madill29639852016-09-02 15:00:09 -04004734 return false;
4735 }
4736
James Darpiniane8a93c62018-01-04 18:02:24 -08004737 if (context->getExtensions().webglCompatibility &&
4738 buffer->isBoundForTransformFeedbackAndOtherUse())
4739 {
Jamie Madille0472f32018-11-27 16:32:45 -05004740 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08004741 return false;
4742 }
4743
Jamie Madill29639852016-09-02 15:00:09 -04004744 // Check for possible overflow of size + offset
4745 angle::CheckedNumeric<size_t> checkedSize(size);
4746 checkedSize += offset;
4747 if (!checkedSize.IsValid())
4748 {
Jamie Madille0472f32018-11-27 16:32:45 -05004749 context->validationError(GL_INVALID_VALUE, kParamOverflow);
Jamie Madill29639852016-09-02 15:00:09 -04004750 return false;
4751 }
4752
4753 if (size + offset > buffer->getSize())
4754 {
Jamie Madille0472f32018-11-27 16:32:45 -05004755 context->validationError(GL_INVALID_VALUE, kInsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004756 return false;
4757 }
4758
Martin Radev4c4c8e72016-08-04 12:25:34 +03004759 return true;
4760}
4761
Geoff Lang111a99e2017-10-17 10:58:41 -04004762bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004763{
Geoff Langc339c4e2016-11-29 10:37:36 -05004764 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004765 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004766 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langc287ea62016-09-16 14:46:51 -04004767 return false;
4768 }
4769
Geoff Lang111a99e2017-10-17 10:58:41 -04004770 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004771 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004772 context->validationError(GL_INVALID_OPERATION, kExtensionNotRequestable);
Geoff Langc287ea62016-09-16 14:46:51 -04004773 return false;
4774 }
4775
4776 return true;
4777}
4778
Jamie Madill5b772312018-03-08 20:28:32 -05004779bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004780{
Lingfeng Yang038dd532018-03-29 17:31:52 -07004781 if (context->getClientMajorVersion() < 2)
4782 {
4783 return ValidateMultitextureUnit(context, texture);
4784 }
4785
Jamie Madillef300b12016-10-07 15:12:09 -04004786 if (texture < GL_TEXTURE0 ||
4787 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4788 {
Jamie Madille0472f32018-11-27 16:32:45 -05004789 context->validationError(GL_INVALID_ENUM, kInvalidCombinedImageUnit);
Jamie Madillef300b12016-10-07 15:12:09 -04004790 return false;
4791 }
4792
4793 return true;
4794}
4795
Jamie Madill5b772312018-03-08 20:28:32 -05004796bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004797{
4798 Program *programObject = GetValidProgram(context, program);
4799 if (!programObject)
4800 {
4801 return false;
4802 }
4803
4804 Shader *shaderObject = GetValidShader(context, shader);
4805 if (!shaderObject)
4806 {
4807 return false;
4808 }
4809
Jiawei Shao385b3e02018-03-21 09:43:28 +08004810 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04004811 {
Jamie Madille0472f32018-11-27 16:32:45 -05004812 context->validationError(GL_INVALID_OPERATION, kShaderAttachmentHasShader);
Jiawei Shao385b3e02018-03-21 09:43:28 +08004813 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04004814 }
4815
4816 return true;
4817}
4818
Jamie Madill5b772312018-03-08 20:28:32 -05004819bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004820{
4821 if (index >= MAX_VERTEX_ATTRIBS)
4822 {
Jamie Madille0472f32018-11-27 16:32:45 -05004823 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004824 return false;
4825 }
4826
4827 if (strncmp(name, "gl_", 3) == 0)
4828 {
Jamie Madille0472f32018-11-27 16:32:45 -05004829 context->validationError(GL_INVALID_OPERATION, kNameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004830 return false;
4831 }
4832
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004833 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004834 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004835 const size_t length = strlen(name);
4836
4837 if (!IsValidESSLString(name, length))
4838 {
4839 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4840 // for shader-related entry points
Jamie Madille0472f32018-11-27 16:32:45 -05004841 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004842 return false;
4843 }
4844
4845 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4846 {
4847 return false;
4848 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004849 }
4850
Jamie Madill01a80ee2016-11-07 12:06:18 -05004851 return GetValidProgram(context, program) != nullptr;
4852}
4853
Jamie Madill5b772312018-03-08 20:28:32 -05004854bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004855{
Geoff Lange8afa902017-09-27 15:00:43 -04004856 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004857 {
Jamie Madille0472f32018-11-27 16:32:45 -05004858 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004859 return false;
4860 }
4861
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004862 if (!context->getState().isBindGeneratesResourceEnabled() &&
Jamie Madill01a80ee2016-11-07 12:06:18 -05004863 !context->isFramebufferGenerated(framebuffer))
4864 {
Jamie Madille0472f32018-11-27 16:32:45 -05004865 context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004866 return false;
4867 }
4868
4869 return true;
4870}
4871
Jamie Madill5b772312018-03-08 20:28:32 -05004872bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004873{
4874 if (target != GL_RENDERBUFFER)
4875 {
Jamie Madille0472f32018-11-27 16:32:45 -05004876 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004877 return false;
4878 }
4879
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004880 if (!context->getState().isBindGeneratesResourceEnabled() &&
Jamie Madill01a80ee2016-11-07 12:06:18 -05004881 !context->isRenderbufferGenerated(renderbuffer))
4882 {
Jamie Madille0472f32018-11-27 16:32:45 -05004883 context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004884 return false;
4885 }
4886
4887 return true;
4888}
4889
Jamie Madill5b772312018-03-08 20:28:32 -05004890static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004891{
4892 switch (mode)
4893 {
4894 case GL_FUNC_ADD:
4895 case GL_FUNC_SUBTRACT:
4896 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004897 return true;
4898
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004899 case GL_MIN:
4900 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004901 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004902
4903 default:
4904 return false;
4905 }
4906}
4907
Jamie Madill5b772312018-03-08 20:28:32 -05004908bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004909{
4910 return true;
4911}
4912
Jamie Madill5b772312018-03-08 20:28:32 -05004913bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004914{
Geoff Lang50cac572017-09-26 17:37:43 -04004915 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004916 {
Jamie Madille0472f32018-11-27 16:32:45 -05004917 context->validationError(GL_INVALID_ENUM, kInvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004918 return false;
4919 }
4920
4921 return true;
4922}
4923
Jamie Madill5b772312018-03-08 20:28:32 -05004924bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004925{
Geoff Lang50cac572017-09-26 17:37:43 -04004926 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004927 {
Jamie Madille0472f32018-11-27 16:32:45 -05004928 context->validationError(GL_INVALID_ENUM, kInvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004929 return false;
4930 }
4931
Geoff Lang50cac572017-09-26 17:37:43 -04004932 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004933 {
Jamie Madille0472f32018-11-27 16:32:45 -05004934 context->validationError(GL_INVALID_ENUM, kInvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004935 return false;
4936 }
4937
4938 return true;
4939}
4940
Jamie Madill5b772312018-03-08 20:28:32 -05004941bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004942{
4943 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4944}
4945
Jamie Madill5b772312018-03-08 20:28:32 -05004946bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004947 GLenum srcRGB,
4948 GLenum dstRGB,
4949 GLenum srcAlpha,
4950 GLenum dstAlpha)
4951{
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004952 if (!ValidSrcBlendFunc(context, srcRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004953 {
Jamie Madille0472f32018-11-27 16:32:45 -05004954 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004955 return false;
4956 }
4957
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004958 if (!ValidDstBlendFunc(context, dstRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004959 {
Jamie Madille0472f32018-11-27 16:32:45 -05004960 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004961 return false;
4962 }
4963
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004964 if (!ValidSrcBlendFunc(context, srcAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004965 {
Jamie Madille0472f32018-11-27 16:32:45 -05004966 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004967 return false;
4968 }
4969
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004970 if (!ValidDstBlendFunc(context, dstAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004971 {
Jamie Madille0472f32018-11-27 16:32:45 -05004972 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004973 return false;
4974 }
4975
Frank Henigman146e8a12017-03-02 23:22:37 -05004976 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4977 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004978 {
4979 bool constantColorUsed =
4980 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4981 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4982
4983 bool constantAlphaUsed =
4984 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4985 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4986
4987 if (constantColorUsed && constantAlphaUsed)
4988 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004989 if (context->getExtensions().webglCompatibility)
4990 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004991 context->validationError(GL_INVALID_OPERATION, kInvalidConstantColor);
4992 return false;
Frank Henigman146e8a12017-03-02 23:22:37 -05004993 }
Jamie Madillc3e37312018-11-30 15:25:39 -05004994
4995 WARN() << kConstantColorAlphaLimitation;
4996 context->validationError(GL_INVALID_OPERATION, kConstantColorAlphaLimitation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004997 return false;
4998 }
4999 }
5000
5001 return true;
5002}
5003
Geoff Langc339c4e2016-11-29 10:37:36 -05005004bool ValidateGetString(Context *context, GLenum name)
5005{
5006 switch (name)
5007 {
5008 case GL_VENDOR:
5009 case GL_RENDERER:
5010 case GL_VERSION:
5011 case GL_SHADING_LANGUAGE_VERSION:
5012 case GL_EXTENSIONS:
5013 break;
5014
5015 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
5016 if (!context->getExtensions().requestExtension)
5017 {
Jamie Madille0472f32018-11-27 16:32:45 -05005018 context->validationError(GL_INVALID_ENUM, kInvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05005019 return false;
5020 }
5021 break;
5022
5023 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005024 context->validationError(GL_INVALID_ENUM, kInvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05005025 return false;
5026 }
5027
5028 return true;
5029}
5030
Jamie Madill5b772312018-03-08 20:28:32 -05005031bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05005032{
5033 if (width <= 0.0f || isNaN(width))
5034 {
Jamie Madille0472f32018-11-27 16:32:45 -05005035 context->validationError(GL_INVALID_VALUE, kInvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05005036 return false;
5037 }
5038
5039 return true;
5040}
5041
Jamie Madill5b772312018-03-08 20:28:32 -05005042bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05005043{
5044 if (context->getExtensions().webglCompatibility && zNear > zFar)
5045 {
Jamie Madille0472f32018-11-27 16:32:45 -05005046 context->validationError(GL_INVALID_OPERATION, kInvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05005047 return false;
5048 }
5049
5050 return true;
5051}
5052
Jamie Madill5b772312018-03-08 20:28:32 -05005053bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05005054 GLenum target,
5055 GLenum internalformat,
5056 GLsizei width,
5057 GLsizei height)
5058{
5059 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
5060 height);
5061}
5062
Jamie Madill5b772312018-03-08 20:28:32 -05005063bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05005064 GLenum target,
5065 GLsizei samples,
5066 GLenum internalformat,
5067 GLsizei width,
5068 GLsizei height)
5069{
5070 if (!context->getExtensions().framebufferMultisample)
5071 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005072 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madille8fb6402017-02-14 17:56:40 -05005073 return false;
5074 }
5075
5076 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
Jamie Madill610640f2018-11-21 17:28:41 -05005077 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_VALUE is
Jamie Madille8fb6402017-02-14 17:56:40 -05005078 // generated.
5079 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
5080 {
Jamie Madille0472f32018-11-27 16:32:45 -05005081 context->validationError(GL_INVALID_VALUE, kSamplesOutOfRange);
Jamie Madille8fb6402017-02-14 17:56:40 -05005082 return false;
5083 }
5084
5085 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
5086 // the specified storage. This is different than ES 3.0 in which a sample number higher
5087 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
5088 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
5089 if (context->getClientMajorVersion() >= 3)
5090 {
5091 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
5092 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
5093 {
Jamie Madille0472f32018-11-27 16:32:45 -05005094 context->validationError(GL_OUT_OF_MEMORY, kSamplesOutOfRange);
Jamie Madille8fb6402017-02-14 17:56:40 -05005095 return false;
5096 }
5097 }
5098
5099 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
5100 width, height);
5101}
5102
Jamie Madill5b772312018-03-08 20:28:32 -05005103bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005104{
Geoff Lange8afa902017-09-27 15:00:43 -04005105 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04005106 {
Jamie Madille0472f32018-11-27 16:32:45 -05005107 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005108 return false;
5109 }
5110
5111 return true;
5112}
5113
Jamie Madill5b772312018-03-08 20:28:32 -05005114bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005115{
5116 return true;
5117}
5118
Jamie Madill5b772312018-03-08 20:28:32 -05005119bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005120{
5121 return true;
5122}
5123
Jamie Madill5b772312018-03-08 20:28:32 -05005124bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005125{
5126 return true;
5127}
5128
Jamie Madill5b772312018-03-08 20:28:32 -05005129bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005130 GLboolean red,
5131 GLboolean green,
5132 GLboolean blue,
5133 GLboolean alpha)
5134{
5135 return true;
5136}
5137
Jamie Madill5b772312018-03-08 20:28:32 -05005138bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005139{
5140 return true;
5141}
5142
Jamie Madill5b772312018-03-08 20:28:32 -05005143bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005144{
5145 return true;
5146}
5147
Jamie Madill5b772312018-03-08 20:28:32 -05005148bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005149{
5150 switch (mode)
5151 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04005152 case CullFaceMode::Front:
5153 case CullFaceMode::Back:
5154 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04005155 break;
5156
5157 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005158 context->validationError(GL_INVALID_ENUM, kInvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005159 return false;
5160 }
5161
5162 return true;
5163}
5164
Jamie Madill5b772312018-03-08 20:28:32 -05005165bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005166{
5167 if (program == 0)
5168 {
5169 return false;
5170 }
5171
Jamie Madill44a6fbf2018-10-02 13:38:56 -04005172 if (!context->getProgramResolveLink(program))
Jamie Madillc1d770e2017-04-13 17:31:24 -04005173 {
5174 if (context->getShader(program))
5175 {
Jamie Madille0472f32018-11-27 16:32:45 -05005176 context->validationError(GL_INVALID_OPERATION, kExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005177 return false;
5178 }
5179 else
5180 {
Jamie Madille0472f32018-11-27 16:32:45 -05005181 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005182 return false;
5183 }
5184 }
5185
5186 return true;
5187}
5188
Jamie Madill5b772312018-03-08 20:28:32 -05005189bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005190{
5191 if (shader == 0)
5192 {
5193 return false;
5194 }
5195
5196 if (!context->getShader(shader))
5197 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04005198 if (context->getProgramResolveLink(shader))
Jamie Madillc1d770e2017-04-13 17:31:24 -04005199 {
Jamie Madille0472f32018-11-27 16:32:45 -05005200 context->validationError(GL_INVALID_OPERATION, kInvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005201 return false;
5202 }
5203 else
5204 {
Jamie Madille0472f32018-11-27 16:32:45 -05005205 context->validationError(GL_INVALID_VALUE, kExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005206 return false;
5207 }
5208 }
5209
5210 return true;
5211}
5212
Jamie Madill5b772312018-03-08 20:28:32 -05005213bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005214{
5215 switch (func)
5216 {
5217 case GL_NEVER:
5218 case GL_ALWAYS:
5219 case GL_LESS:
5220 case GL_LEQUAL:
5221 case GL_EQUAL:
5222 case GL_GREATER:
5223 case GL_GEQUAL:
5224 case GL_NOTEQUAL:
5225 break;
5226
5227 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005228 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005229 return false;
5230 }
5231
5232 return true;
5233}
5234
Jamie Madill5b772312018-03-08 20:28:32 -05005235bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005236{
5237 return true;
5238}
5239
Jamie Madill5b772312018-03-08 20:28:32 -05005240bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005241{
5242 Program *programObject = GetValidProgram(context, program);
5243 if (!programObject)
5244 {
5245 return false;
5246 }
5247
5248 Shader *shaderObject = GetValidShader(context, shader);
5249 if (!shaderObject)
5250 {
5251 return false;
5252 }
5253
Jiawei Shao385b3e02018-03-21 09:43:28 +08005254 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005255 if (attachedShader != shaderObject)
5256 {
Jamie Madille0472f32018-11-27 16:32:45 -05005257 context->validationError(GL_INVALID_OPERATION, kShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005258 return false;
5259 }
5260
5261 return true;
5262}
5263
Jamie Madill5b772312018-03-08 20:28:32 -05005264bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005265{
5266 if (index >= MAX_VERTEX_ATTRIBS)
5267 {
Jamie Madille0472f32018-11-27 16:32:45 -05005268 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005269 return false;
5270 }
5271
5272 return true;
5273}
5274
Jamie Madill5b772312018-03-08 20:28:32 -05005275bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005276{
5277 if (index >= MAX_VERTEX_ATTRIBS)
5278 {
Jamie Madille0472f32018-11-27 16:32:45 -05005279 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005280 return false;
5281 }
5282
5283 return true;
5284}
5285
Jamie Madill5b772312018-03-08 20:28:32 -05005286bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005287{
5288 return true;
5289}
5290
Jamie Madill5b772312018-03-08 20:28:32 -05005291bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005292{
5293 return true;
5294}
5295
Jamie Madill5b772312018-03-08 20:28:32 -05005296bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005297{
5298 switch (mode)
5299 {
5300 case GL_CW:
5301 case GL_CCW:
5302 break;
5303 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005304 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005305 return false;
5306 }
5307
5308 return true;
5309}
5310
Jamie Madill5b772312018-03-08 20:28:32 -05005311bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005312 GLuint program,
5313 GLuint index,
5314 GLsizei bufsize,
5315 GLsizei *length,
5316 GLint *size,
5317 GLenum *type,
5318 GLchar *name)
5319{
5320 if (bufsize < 0)
5321 {
Jamie Madille0472f32018-11-27 16:32:45 -05005322 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005323 return false;
5324 }
5325
5326 Program *programObject = GetValidProgram(context, program);
5327
5328 if (!programObject)
5329 {
5330 return false;
5331 }
5332
5333 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5334 {
Jamie Madille0472f32018-11-27 16:32:45 -05005335 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005336 return false;
5337 }
5338
5339 return true;
5340}
5341
Jamie Madill5b772312018-03-08 20:28:32 -05005342bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005343 GLuint program,
5344 GLuint index,
5345 GLsizei bufsize,
5346 GLsizei *length,
5347 GLint *size,
5348 GLenum *type,
5349 GLchar *name)
5350{
5351 if (bufsize < 0)
5352 {
Jamie Madille0472f32018-11-27 16:32:45 -05005353 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005354 return false;
5355 }
5356
5357 Program *programObject = GetValidProgram(context, program);
5358
5359 if (!programObject)
5360 {
5361 return false;
5362 }
5363
5364 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5365 {
Jamie Madille0472f32018-11-27 16:32:45 -05005366 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005367 return false;
5368 }
5369
5370 return true;
5371}
5372
Jamie Madill5b772312018-03-08 20:28:32 -05005373bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005374 GLuint program,
5375 GLsizei maxcount,
5376 GLsizei *count,
5377 GLuint *shaders)
5378{
5379 if (maxcount < 0)
5380 {
Jamie Madille0472f32018-11-27 16:32:45 -05005381 context->validationError(GL_INVALID_VALUE, kNegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005382 return false;
5383 }
5384
5385 Program *programObject = GetValidProgram(context, program);
5386
5387 if (!programObject)
5388 {
5389 return false;
5390 }
5391
5392 return true;
5393}
5394
Jamie Madill5b772312018-03-08 20:28:32 -05005395bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005396{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005397 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5398 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005399 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005400 {
Jamie Madille0472f32018-11-27 16:32:45 -05005401 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005402 return false;
5403 }
5404
Jamie Madillc1d770e2017-04-13 17:31:24 -04005405 Program *programObject = GetValidProgram(context, program);
5406
5407 if (!programObject)
5408 {
Jamie Madille0472f32018-11-27 16:32:45 -05005409 context->validationError(GL_INVALID_OPERATION, kProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005410 return false;
5411 }
5412
5413 if (!programObject->isLinked())
5414 {
Jamie Madille0472f32018-11-27 16:32:45 -05005415 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005416 return false;
5417 }
5418
5419 return true;
5420}
5421
Jamie Madill5b772312018-03-08 20:28:32 -05005422bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005423{
5424 GLenum nativeType;
5425 unsigned int numParams = 0;
5426 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5427}
5428
Jamie Madill5b772312018-03-08 20:28:32 -05005429bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005430{
5431 return true;
5432}
5433
Jamie Madill5b772312018-03-08 20:28:32 -05005434bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005435{
5436 GLenum nativeType;
5437 unsigned int numParams = 0;
5438 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5439}
5440
Jamie Madill5b772312018-03-08 20:28:32 -05005441bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005442{
5443 GLenum nativeType;
5444 unsigned int numParams = 0;
5445 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5446}
5447
Jamie Madill5b772312018-03-08 20:28:32 -05005448bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005449 GLuint program,
5450 GLsizei bufsize,
5451 GLsizei *length,
5452 GLchar *infolog)
5453{
5454 if (bufsize < 0)
5455 {
Jamie Madille0472f32018-11-27 16:32:45 -05005456 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005457 return false;
5458 }
5459
5460 Program *programObject = GetValidProgram(context, program);
5461 if (!programObject)
5462 {
5463 return false;
5464 }
5465
5466 return true;
5467}
5468
Jamie Madill5b772312018-03-08 20:28:32 -05005469bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005470 GLuint shader,
5471 GLsizei bufsize,
5472 GLsizei *length,
5473 GLchar *infolog)
5474{
5475 if (bufsize < 0)
5476 {
Jamie Madille0472f32018-11-27 16:32:45 -05005477 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005478 return false;
5479 }
5480
5481 Shader *shaderObject = GetValidShader(context, shader);
5482 if (!shaderObject)
5483 {
5484 return false;
5485 }
5486
5487 return true;
5488}
5489
Jamie Madill5b772312018-03-08 20:28:32 -05005490bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005491 GLenum shadertype,
5492 GLenum precisiontype,
5493 GLint *range,
5494 GLint *precision)
5495{
5496 switch (shadertype)
5497 {
5498 case GL_VERTEX_SHADER:
5499 case GL_FRAGMENT_SHADER:
5500 break;
5501 case GL_COMPUTE_SHADER:
Jamie Madillc3e37312018-11-30 15:25:39 -05005502 context->validationError(GL_INVALID_OPERATION, kUnimplementedComputeShaderPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005503 return false;
5504 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005505 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005506 return false;
5507 }
5508
5509 switch (precisiontype)
5510 {
5511 case GL_LOW_FLOAT:
5512 case GL_MEDIUM_FLOAT:
5513 case GL_HIGH_FLOAT:
5514 case GL_LOW_INT:
5515 case GL_MEDIUM_INT:
5516 case GL_HIGH_INT:
5517 break;
5518
5519 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005520 context->validationError(GL_INVALID_ENUM, kInvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005521 return false;
5522 }
5523
5524 return true;
5525}
5526
Jamie Madill5b772312018-03-08 20:28:32 -05005527bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005528 GLuint shader,
5529 GLsizei bufsize,
5530 GLsizei *length,
5531 GLchar *source)
5532{
5533 if (bufsize < 0)
5534 {
Jamie Madille0472f32018-11-27 16:32:45 -05005535 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005536 return false;
5537 }
5538
5539 Shader *shaderObject = GetValidShader(context, shader);
5540 if (!shaderObject)
5541 {
5542 return false;
5543 }
5544
5545 return true;
5546}
5547
Jamie Madill5b772312018-03-08 20:28:32 -05005548bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005549{
5550 if (strstr(name, "gl_") == name)
5551 {
5552 return false;
5553 }
5554
Geoff Langfc32e8b2017-05-31 14:16:59 -04005555 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5556 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005557 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005558 {
Jamie Madille0472f32018-11-27 16:32:45 -05005559 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005560 return false;
5561 }
5562
Jamie Madillc1d770e2017-04-13 17:31:24 -04005563 Program *programObject = GetValidProgram(context, program);
5564
5565 if (!programObject)
5566 {
5567 return false;
5568 }
5569
5570 if (!programObject->isLinked())
5571 {
Jamie Madille0472f32018-11-27 16:32:45 -05005572 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005573 return false;
5574 }
5575
5576 return true;
5577}
5578
Jamie Madill5b772312018-03-08 20:28:32 -05005579bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005580{
5581 switch (mode)
5582 {
5583 case GL_FASTEST:
5584 case GL_NICEST:
5585 case GL_DONT_CARE:
5586 break;
5587
5588 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005589 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005590 return false;
5591 }
5592
5593 switch (target)
5594 {
5595 case GL_GENERATE_MIPMAP_HINT:
5596 break;
5597
Geoff Lange7bd2182017-06-16 16:13:13 -04005598 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5599 if (context->getClientVersion() < ES_3_0 &&
5600 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005601 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005602 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005603 return false;
5604 }
5605 break;
5606
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07005607 case GL_PERSPECTIVE_CORRECTION_HINT:
5608 case GL_POINT_SMOOTH_HINT:
5609 case GL_LINE_SMOOTH_HINT:
5610 case GL_FOG_HINT:
5611 if (context->getClientMajorVersion() >= 2)
5612 {
Jamie Madille0472f32018-11-27 16:32:45 -05005613 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07005614 return false;
5615 }
5616 break;
5617
Jamie Madillc1d770e2017-04-13 17:31:24 -04005618 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005619 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005620 return false;
5621 }
5622
5623 return true;
5624}
5625
Jamie Madill5b772312018-03-08 20:28:32 -05005626bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005627{
5628 return true;
5629}
5630
Jamie Madill5b772312018-03-08 20:28:32 -05005631bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005632{
5633 return true;
5634}
5635
Jamie Madill5b772312018-03-08 20:28:32 -05005636bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005637{
5638 return true;
5639}
5640
Jamie Madill5b772312018-03-08 20:28:32 -05005641bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005642{
5643 return true;
5644}
5645
Jamie Madill5b772312018-03-08 20:28:32 -05005646bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005647{
5648 return true;
5649}
5650
Jamie Madill5b772312018-03-08 20:28:32 -05005651bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005652{
5653 return true;
5654}
5655
Jamie Madill5b772312018-03-08 20:28:32 -05005656bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005657{
5658 if (context->getClientMajorVersion() < 3)
5659 {
5660 switch (pname)
5661 {
5662 case GL_UNPACK_IMAGE_HEIGHT:
5663 case GL_UNPACK_SKIP_IMAGES:
Jamie Madille0472f32018-11-27 16:32:45 -05005664 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005665 return false;
5666
5667 case GL_UNPACK_ROW_LENGTH:
5668 case GL_UNPACK_SKIP_ROWS:
5669 case GL_UNPACK_SKIP_PIXELS:
5670 if (!context->getExtensions().unpackSubimage)
5671 {
Jamie Madille0472f32018-11-27 16:32:45 -05005672 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005673 return false;
5674 }
5675 break;
5676
5677 case GL_PACK_ROW_LENGTH:
5678 case GL_PACK_SKIP_ROWS:
5679 case GL_PACK_SKIP_PIXELS:
5680 if (!context->getExtensions().packSubimage)
5681 {
Jamie Madille0472f32018-11-27 16:32:45 -05005682 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005683 return false;
5684 }
5685 break;
5686 }
5687 }
5688
5689 if (param < 0)
5690 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005691 context->validationError(GL_INVALID_VALUE, kNegativeParam);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005692 return false;
5693 }
5694
5695 switch (pname)
5696 {
5697 case GL_UNPACK_ALIGNMENT:
5698 if (param != 1 && param != 2 && param != 4 && param != 8)
5699 {
Jamie Madille0472f32018-11-27 16:32:45 -05005700 context->validationError(GL_INVALID_VALUE, kInvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005701 return false;
5702 }
5703 break;
5704
5705 case GL_PACK_ALIGNMENT:
5706 if (param != 1 && param != 2 && param != 4 && param != 8)
5707 {
Jamie Madille0472f32018-11-27 16:32:45 -05005708 context->validationError(GL_INVALID_VALUE, kInvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005709 return false;
5710 }
5711 break;
5712
5713 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005714 if (!context->getExtensions().packReverseRowOrder)
5715 {
Jamie Madille0472f32018-11-27 16:32:45 -05005716 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang000dab82017-09-27 14:27:07 -04005717 }
5718 break;
5719
Jamie Madillc1d770e2017-04-13 17:31:24 -04005720 case GL_UNPACK_ROW_LENGTH:
5721 case GL_UNPACK_IMAGE_HEIGHT:
5722 case GL_UNPACK_SKIP_IMAGES:
5723 case GL_UNPACK_SKIP_ROWS:
5724 case GL_UNPACK_SKIP_PIXELS:
5725 case GL_PACK_ROW_LENGTH:
5726 case GL_PACK_SKIP_ROWS:
5727 case GL_PACK_SKIP_PIXELS:
5728 break;
5729
5730 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005731 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005732 return false;
5733 }
5734
5735 return true;
5736}
5737
Jamie Madill5b772312018-03-08 20:28:32 -05005738bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005739{
5740 return true;
5741}
5742
Jamie Madill5b772312018-03-08 20:28:32 -05005743bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005744{
5745 return true;
5746}
5747
Jamie Madill5b772312018-03-08 20:28:32 -05005748bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005749{
5750 return true;
5751}
5752
Jamie Madill5b772312018-03-08 20:28:32 -05005753bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005754{
5755 if (width < 0 || height < 0)
5756 {
Jamie Madille0472f32018-11-27 16:32:45 -05005757 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005758 return false;
5759 }
5760
5761 return true;
5762}
5763
Jamie Madill5b772312018-03-08 20:28:32 -05005764bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005765 GLsizei n,
5766 const GLuint *shaders,
5767 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005768 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005769 GLsizei length)
5770{
5771 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5772 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5773 shaderBinaryFormats.end())
5774 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005775 context->validationError(GL_INVALID_ENUM, kInvalidShaderBinaryFormat);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005776 return false;
5777 }
5778
5779 return true;
5780}
5781
Jamie Madill5b772312018-03-08 20:28:32 -05005782bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005783 GLuint shader,
5784 GLsizei count,
5785 const GLchar *const *string,
5786 const GLint *length)
5787{
5788 if (count < 0)
5789 {
Jamie Madille0472f32018-11-27 16:32:45 -05005790 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005791 return false;
5792 }
5793
Geoff Langfc32e8b2017-05-31 14:16:59 -04005794 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5795 // shader-related entry points
5796 if (context->getExtensions().webglCompatibility)
5797 {
5798 for (GLsizei i = 0; i < count; i++)
5799 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005800 size_t len =
5801 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005802
5803 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005804 if (!IsValidESSLShaderSourceString(string[i], len,
5805 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005806 {
Jamie Madille0472f32018-11-27 16:32:45 -05005807 context->validationError(GL_INVALID_VALUE, kShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005808 return false;
5809 }
5810 }
5811 }
5812
Jamie Madillc1d770e2017-04-13 17:31:24 -04005813 Shader *shaderObject = GetValidShader(context, shader);
5814 if (!shaderObject)
5815 {
5816 return false;
5817 }
5818
5819 return true;
5820}
5821
Jamie Madill5b772312018-03-08 20:28:32 -05005822bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005823{
5824 if (!IsValidStencilFunc(func))
5825 {
Jamie Madille0472f32018-11-27 16:32:45 -05005826 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005827 return false;
5828 }
5829
5830 return true;
5831}
5832
Jamie Madill5b772312018-03-08 20:28:32 -05005833bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005834{
5835 if (!IsValidStencilFace(face))
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 if (!IsValidStencilFunc(func))
5842 {
Jamie Madille0472f32018-11-27 16:32:45 -05005843 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005844 return false;
5845 }
5846
5847 return true;
5848}
5849
Jamie Madill5b772312018-03-08 20:28:32 -05005850bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005851{
5852 return true;
5853}
5854
Jamie Madill5b772312018-03-08 20:28:32 -05005855bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005856{
5857 if (!IsValidStencilFace(face))
5858 {
Jamie Madille0472f32018-11-27 16:32:45 -05005859 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005860 return false;
5861 }
5862
5863 return true;
5864}
5865
Jamie Madill5b772312018-03-08 20:28:32 -05005866bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005867{
5868 if (!IsValidStencilOp(fail))
5869 {
Jamie Madille0472f32018-11-27 16:32:45 -05005870 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005871 return false;
5872 }
5873
5874 if (!IsValidStencilOp(zfail))
5875 {
Jamie Madille0472f32018-11-27 16:32:45 -05005876 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005877 return false;
5878 }
5879
5880 if (!IsValidStencilOp(zpass))
5881 {
Jamie Madille0472f32018-11-27 16:32:45 -05005882 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005883 return false;
5884 }
5885
5886 return true;
5887}
5888
Jamie Madill5b772312018-03-08 20:28:32 -05005889bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005890 GLenum face,
5891 GLenum fail,
5892 GLenum zfail,
5893 GLenum zpass)
5894{
5895 if (!IsValidStencilFace(face))
5896 {
Jamie Madille0472f32018-11-27 16:32:45 -05005897 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005898 return false;
5899 }
5900
5901 return ValidateStencilOp(context, fail, zfail, zpass);
5902}
5903
Jamie Madill5b772312018-03-08 20:28:32 -05005904bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005905{
5906 return ValidateUniform(context, GL_FLOAT, location, 1);
5907}
5908
Jamie Madill5b772312018-03-08 20:28:32 -05005909bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005910{
5911 return ValidateUniform(context, GL_FLOAT, location, count);
5912}
5913
Jamie Madill5b772312018-03-08 20:28:32 -05005914bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005915{
5916 return ValidateUniform1iv(context, location, 1, &x);
5917}
5918
Jamie Madill5b772312018-03-08 20:28:32 -05005919bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005920{
5921 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5922}
5923
Jamie Madill5b772312018-03-08 20:28:32 -05005924bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005925{
5926 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5927}
5928
Jamie Madill5b772312018-03-08 20:28:32 -05005929bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005930{
5931 return ValidateUniform(context, GL_INT_VEC2, location, count);
5932}
5933
Jamie Madill5b772312018-03-08 20:28:32 -05005934bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005935{
5936 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5937}
5938
Jamie Madill5b772312018-03-08 20:28:32 -05005939bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005940{
5941 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5942}
5943
Jamie Madill5b772312018-03-08 20:28:32 -05005944bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005945{
5946 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5947}
5948
Jamie Madill5b772312018-03-08 20:28:32 -05005949bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005950{
5951 return ValidateUniform(context, GL_INT_VEC3, location, count);
5952}
5953
Jamie Madill5b772312018-03-08 20:28:32 -05005954bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005955{
5956 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5957}
5958
Jamie Madill5b772312018-03-08 20:28:32 -05005959bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005960{
5961 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5962}
5963
Jamie Madill5b772312018-03-08 20:28:32 -05005964bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005965{
5966 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5967}
5968
Jamie Madill5b772312018-03-08 20:28:32 -05005969bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005970{
5971 return ValidateUniform(context, GL_INT_VEC4, location, count);
5972}
5973
Jamie Madill5b772312018-03-08 20:28:32 -05005974bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005975 GLint location,
5976 GLsizei count,
5977 GLboolean transpose,
5978 const GLfloat *value)
5979{
5980 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5981}
5982
Jamie Madill5b772312018-03-08 20:28:32 -05005983bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005984 GLint location,
5985 GLsizei count,
5986 GLboolean transpose,
5987 const GLfloat *value)
5988{
5989 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5990}
5991
Jamie Madill5b772312018-03-08 20:28:32 -05005992bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005993 GLint location,
5994 GLsizei count,
5995 GLboolean transpose,
5996 const GLfloat *value)
5997{
5998 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5999}
6000
Jamie Madill5b772312018-03-08 20:28:32 -05006001bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006002{
6003 Program *programObject = GetValidProgram(context, program);
6004
6005 if (!programObject)
6006 {
6007 return false;
6008 }
6009
6010 return true;
6011}
6012
Jamie Madill5b772312018-03-08 20:28:32 -05006013bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006014{
6015 return ValidateVertexAttribIndex(context, index);
6016}
6017
Jamie Madill5b772312018-03-08 20:28:32 -05006018bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006019{
6020 return ValidateVertexAttribIndex(context, index);
6021}
6022
Jamie Madill5b772312018-03-08 20:28:32 -05006023bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006024{
6025 return ValidateVertexAttribIndex(context, index);
6026}
6027
Jamie Madill5b772312018-03-08 20:28:32 -05006028bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006029{
6030 return ValidateVertexAttribIndex(context, index);
6031}
6032
Jamie Madill5b772312018-03-08 20:28:32 -05006033bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006034{
6035 return ValidateVertexAttribIndex(context, index);
6036}
6037
Jamie Madill5b772312018-03-08 20:28:32 -05006038bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006039{
6040 return ValidateVertexAttribIndex(context, index);
6041}
6042
Jamie Madill5b772312018-03-08 20:28:32 -05006043bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04006044 GLuint index,
6045 GLfloat x,
6046 GLfloat y,
6047 GLfloat z,
6048 GLfloat w)
6049{
6050 return ValidateVertexAttribIndex(context, index);
6051}
6052
Jamie Madill5b772312018-03-08 20:28:32 -05006053bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006054{
6055 return ValidateVertexAttribIndex(context, index);
6056}
6057
Jamie Madill5b772312018-03-08 20:28:32 -05006058bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006059{
6060 if (width < 0 || height < 0)
6061 {
Jamie Madille0472f32018-11-27 16:32:45 -05006062 context->validationError(GL_INVALID_VALUE, kViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04006063 return false;
6064 }
6065
6066 return true;
6067}
6068
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08006069bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006070 GLenum target,
6071 GLenum attachment,
6072 GLenum pname,
6073 GLint *params)
6074{
6075 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
6076 nullptr);
6077}
6078
Jamie Madill5b772312018-03-08 20:28:32 -05006079bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006080{
6081 return ValidateGetProgramivBase(context, program, pname, nullptr);
6082}
6083
Jamie Madill5b772312018-03-08 20:28:32 -05006084bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006085 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006086 GLint level,
6087 GLenum internalformat,
6088 GLint x,
6089 GLint y,
6090 GLsizei width,
6091 GLsizei height,
6092 GLint border)
6093{
6094 if (context->getClientMajorVersion() < 3)
6095 {
6096 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
6097 0, x, y, width, height, border);
6098 }
6099
6100 ASSERT(context->getClientMajorVersion() == 3);
6101 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
6102 0, x, y, width, height, border);
6103}
6104
6105bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006106 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006107 GLint level,
6108 GLint xoffset,
6109 GLint yoffset,
6110 GLint x,
6111 GLint y,
6112 GLsizei width,
6113 GLsizei height)
6114{
6115 if (context->getClientMajorVersion() < 3)
6116 {
6117 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
6118 yoffset, x, y, width, height, 0);
6119 }
6120
6121 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
6122 yoffset, 0, x, y, width, height, 0);
6123}
6124
6125bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
6126{
6127 return ValidateGenOrDelete(context, n);
6128}
6129
6130bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
6131{
6132 return ValidateGenOrDelete(context, n);
6133}
6134
6135bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
6136{
6137 return ValidateGenOrDelete(context, n);
6138}
6139
6140bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
6141{
6142 return ValidateGenOrDelete(context, n);
6143}
6144
6145bool ValidateDisable(Context *context, GLenum cap)
6146{
6147 if (!ValidCap(context, cap, false))
6148 {
Jamie Madille0472f32018-11-27 16:32:45 -05006149 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006150 return false;
6151 }
6152
6153 return true;
6154}
6155
6156bool ValidateEnable(Context *context, GLenum cap)
6157{
6158 if (!ValidCap(context, cap, false))
6159 {
Jamie Madille0472f32018-11-27 16:32:45 -05006160 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006161 return false;
6162 }
6163
6164 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
6165 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
6166 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006167 context->validationError(GL_INVALID_OPERATION, kNoSampleAlphaToCoveragesLimitation);
Jamie Madillbe849e42017-05-02 15:49:00 -04006168
6169 // We also output an error message to the debugger window if tracing is active, so that
6170 // developers can see the error message.
Jamie Madillc3e37312018-11-30 15:25:39 -05006171 ERR() << kNoSampleAlphaToCoveragesLimitation;
Jamie Madillbe849e42017-05-02 15:49:00 -04006172 return false;
6173 }
6174
6175 return true;
6176}
6177
6178bool ValidateFramebufferRenderbuffer(Context *context,
6179 GLenum target,
6180 GLenum attachment,
6181 GLenum renderbuffertarget,
6182 GLuint renderbuffer)
6183{
Geoff Lange8afa902017-09-27 15:00:43 -04006184 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04006185 {
Jamie Madille0472f32018-11-27 16:32:45 -05006186 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Brandon Jones6cad5662017-06-14 13:25:13 -07006187 return false;
6188 }
6189
6190 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
6191 {
Jamie Madille0472f32018-11-27 16:32:45 -05006192 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006193 return false;
6194 }
6195
6196 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
6197 renderbuffertarget, renderbuffer);
6198}
6199
6200bool ValidateFramebufferTexture2D(Context *context,
6201 GLenum target,
6202 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006203 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04006204 GLuint texture,
6205 GLint level)
6206{
6207 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
6208 // extension
6209 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
6210 level != 0)
6211 {
Jamie Madille0472f32018-11-27 16:32:45 -05006212 context->validationError(GL_INVALID_VALUE, kInvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04006213 return false;
6214 }
6215
6216 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
6217 {
6218 return false;
6219 }
6220
6221 if (texture != 0)
6222 {
6223 gl::Texture *tex = context->getTexture(texture);
6224 ASSERT(tex);
6225
6226 const gl::Caps &caps = context->getCaps();
6227
6228 switch (textarget)
6229 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006230 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04006231 {
6232 if (level > gl::log2(caps.max2DTextureSize))
6233 {
Jamie Madille0472f32018-11-27 16:32:45 -05006234 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04006235 return false;
6236 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006237 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04006238 {
Jamie Madille0472f32018-11-27 16:32:45 -05006239 context->validationError(GL_INVALID_OPERATION, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006240 return false;
6241 }
6242 }
6243 break;
6244
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006245 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006246 {
6247 if (level != 0)
6248 {
Jamie Madille0472f32018-11-27 16:32:45 -05006249 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006250 return false;
6251 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006252 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006253 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006254 context->validationError(GL_INVALID_OPERATION, kTextureTargetMismatch);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006255 return false;
6256 }
6257 }
6258 break;
6259
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006260 case TextureTarget::CubeMapNegativeX:
6261 case TextureTarget::CubeMapNegativeY:
6262 case TextureTarget::CubeMapNegativeZ:
6263 case TextureTarget::CubeMapPositiveX:
6264 case TextureTarget::CubeMapPositiveY:
6265 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04006266 {
6267 if (level > gl::log2(caps.maxCubeMapTextureSize))
6268 {
Jamie Madille0472f32018-11-27 16:32:45 -05006269 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04006270 return false;
6271 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006272 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04006273 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006274 context->validationError(GL_INVALID_OPERATION, kTextureTargetMismatch);
Jamie Madillbe849e42017-05-02 15:49:00 -04006275 return false;
6276 }
6277 }
6278 break;
6279
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006280 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04006281 {
Yizhou Jiang7818a852018-09-06 15:02:04 +08006282 if (context->getClientVersion() < ES_3_1 &&
6283 !context->getExtensions().textureMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006284 {
Jamie Madill610640f2018-11-21 17:28:41 -05006285 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05006286 kMultisampleTextureExtensionOrES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006287 return false;
6288 }
6289
6290 if (level != 0)
6291 {
Jamie Madille0472f32018-11-27 16:32:45 -05006292 context->validationError(GL_INVALID_VALUE, kLevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006293 return false;
6294 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006295 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006296 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006297 context->validationError(GL_INVALID_OPERATION, kTextureTargetMismatch);
Jamie Madillbe849e42017-05-02 15:49:00 -04006298 return false;
6299 }
6300 }
6301 break;
6302
6303 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006304 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006305 return false;
6306 }
Jamie Madillbe849e42017-05-02 15:49:00 -04006307 }
6308
6309 return true;
6310}
6311
6312bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6313{
6314 return ValidateGenOrDelete(context, n);
6315}
6316
6317bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6318{
6319 return ValidateGenOrDelete(context, n);
6320}
6321
6322bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6323{
6324 return ValidateGenOrDelete(context, n);
6325}
6326
6327bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6328{
6329 return ValidateGenOrDelete(context, n);
6330}
6331
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006332bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006333{
6334 if (!ValidTextureTarget(context, target))
6335 {
Jamie Madille0472f32018-11-27 16:32:45 -05006336 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006337 return false;
6338 }
6339
Jamie Madillcfc73cc2019-04-08 16:26:51 -04006340 Texture *texture = context->getTextureByType(target);
Jamie Madillbe849e42017-05-02 15:49:00 -04006341
6342 if (texture == nullptr)
6343 {
Jamie Madille0472f32018-11-27 16:32:45 -05006344 context->validationError(GL_INVALID_OPERATION, kTextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006345 return false;
6346 }
6347
6348 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6349
6350 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6351 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6352 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6353 {
Jamie Madille0472f32018-11-27 16:32:45 -05006354 context->validationError(GL_INVALID_OPERATION, kBaseLevelOutOfRange);
Jamie Madillbe849e42017-05-02 15:49:00 -04006355 return false;
6356 }
6357
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006358 TextureTarget baseTarget = (target == TextureType::CubeMap)
6359 ? TextureTarget::CubeMapPositiveX
6360 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006361 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6362 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6363 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006364 {
Jamie Madille0472f32018-11-27 16:32:45 -05006365 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Brandon Jones6cad5662017-06-14 13:25:13 -07006366 return false;
6367 }
6368
Geoff Lang536eca12017-09-13 11:23:35 -04006369 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6370 bool formatUnsized = !format.sized;
6371 bool formatColorRenderableAndFilterable =
6372 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
Yuly Novikovf15f8862018-06-04 18:59:41 -04006373 format.textureAttachmentSupport(context->getClientVersion(), context->getExtensions());
Geoff Lang536eca12017-09-13 11:23:35 -04006374 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006375 {
Jamie Madille0472f32018-11-27 16:32:45 -05006376 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006377 return false;
6378 }
6379
Geoff Lang536eca12017-09-13 11:23:35 -04006380 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6381 // generation
6382 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6383 {
Jamie Madille0472f32018-11-27 16:32:45 -05006384 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Geoff Lang536eca12017-09-13 11:23:35 -04006385 return false;
6386 }
6387
Jiange2c00842018-07-13 16:50:49 +08006388 // According to the OpenGL extension spec EXT_sRGB.txt, EXT_SRGB is based on ES 2.0 and
6389 // generateMipmap is not allowed if texture format is SRGB_EXT or SRGB_ALPHA_EXT.
6390 if (context->getClientVersion() < Version(3, 0) && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006391 {
Jamie Madille0472f32018-11-27 16:32:45 -05006392 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006393 return false;
6394 }
6395
6396 // Non-power of 2 ES2 check
6397 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6398 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6399 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6400 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006401 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6402 target == TextureType::CubeMap);
Jamie Madille0472f32018-11-27 16:32:45 -05006403 context->validationError(GL_INVALID_OPERATION, kTextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006404 return false;
6405 }
6406
6407 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006408 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006409 {
Jamie Madille0472f32018-11-27 16:32:45 -05006410 context->validationError(GL_INVALID_OPERATION, kCubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006411 return false;
6412 }
6413
James Darpinian83b2f0e2018-11-27 15:56:01 -08006414 if (context->getExtensions().webglCompatibility &&
6415 (texture->getWidth(baseTarget, effectiveBaseLevel) == 0 ||
6416 texture->getHeight(baseTarget, effectiveBaseLevel) == 0))
6417 {
6418 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapZeroSize);
6419 return false;
6420 }
6421
Jamie Madillbe849e42017-05-02 15:49:00 -04006422 return true;
6423}
6424
Jamie Madill5b772312018-03-08 20:28:32 -05006425bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006426 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006427 GLenum pname,
6428 GLint *params)
6429{
6430 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6431}
6432
6433bool ValidateGetRenderbufferParameteriv(Context *context,
6434 GLenum target,
6435 GLenum pname,
6436 GLint *params)
6437{
6438 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6439}
6440
6441bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6442{
6443 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6444}
6445
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006446bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006447{
6448 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6449}
6450
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006451bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006452{
6453 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6454}
6455
Till Rathmannb8543632018-10-02 19:46:14 +02006456bool ValidateGetTexParameterIivOES(Context *context,
6457 TextureType target,
6458 GLenum pname,
6459 GLint *params)
6460{
6461 if (context->getClientMajorVersion() < 3)
6462 {
Jamie Madille0472f32018-11-27 16:32:45 -05006463 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006464 return false;
6465 }
6466 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6467}
6468
6469bool ValidateGetTexParameterIuivOES(Context *context,
6470 TextureType target,
6471 GLenum pname,
6472 GLuint *params)
6473{
6474 if (context->getClientMajorVersion() < 3)
6475 {
Jamie Madille0472f32018-11-27 16:32:45 -05006476 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006477 return false;
6478 }
6479 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6480}
6481
Jamie Madillbe849e42017-05-02 15:49:00 -04006482bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6483{
6484 return ValidateGetUniformBase(context, program, location);
6485}
6486
6487bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6488{
6489 return ValidateGetUniformBase(context, program, location);
6490}
6491
6492bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6493{
6494 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6495}
6496
6497bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6498{
6499 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6500}
6501
6502bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6503{
6504 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6505}
6506
6507bool ValidateIsEnabled(Context *context, GLenum cap)
6508{
6509 if (!ValidCap(context, cap, true))
6510 {
Jamie Madille0472f32018-11-27 16:32:45 -05006511 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006512 return false;
6513 }
6514
6515 return true;
6516}
6517
6518bool ValidateLinkProgram(Context *context, GLuint program)
6519{
6520 if (context->hasActiveTransformFeedback(program))
6521 {
6522 // ES 3.0.4 section 2.15 page 91
Jamie Madillc3e37312018-11-30 15:25:39 -05006523 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackActiveDuringLink);
Jamie Madillbe849e42017-05-02 15:49:00 -04006524 return false;
6525 }
6526
6527 Program *programObject = GetValidProgram(context, program);
6528 if (!programObject)
6529 {
6530 return false;
6531 }
6532
6533 return true;
6534}
6535
Jamie Madill4928b7c2017-06-20 12:57:39 -04006536bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006537 GLint x,
6538 GLint y,
6539 GLsizei width,
6540 GLsizei height,
6541 GLenum format,
6542 GLenum type,
6543 void *pixels)
6544{
6545 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6546 nullptr, pixels);
6547}
6548
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006549bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006550{
Till Rathmannb8543632018-10-02 19:46:14 +02006551 return ValidateTexParameterBase(context, target, pname, -1, false, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006552}
6553
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006554bool ValidateTexParameterfv(Context *context,
6555 TextureType target,
6556 GLenum pname,
6557 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006558{
Till Rathmannb8543632018-10-02 19:46:14 +02006559 return ValidateTexParameterBase(context, target, pname, -1, true, params);
Jamie Madillbe849e42017-05-02 15:49:00 -04006560}
6561
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006562bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006563{
Till Rathmannb8543632018-10-02 19:46:14 +02006564 return ValidateTexParameterBase(context, target, pname, -1, false, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006565}
6566
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006567bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006568{
Till Rathmannb8543632018-10-02 19:46:14 +02006569 return ValidateTexParameterBase(context, target, pname, -1, true, params);
6570}
6571
6572bool ValidateTexParameterIivOES(Context *context,
6573 TextureType target,
6574 GLenum pname,
6575 const GLint *params)
6576{
6577 if (context->getClientMajorVersion() < 3)
6578 {
Jamie Madille0472f32018-11-27 16:32:45 -05006579 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006580 return false;
6581 }
6582 return ValidateTexParameterBase(context, target, pname, -1, true, params);
6583}
6584
6585bool ValidateTexParameterIuivOES(Context *context,
6586 TextureType target,
6587 GLenum pname,
6588 const GLuint *params)
6589{
6590 if (context->getClientMajorVersion() < 3)
6591 {
Jamie Madille0472f32018-11-27 16:32:45 -05006592 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006593 return false;
6594 }
6595 return ValidateTexParameterBase(context, target, pname, -1, true, params);
Jamie Madillbe849e42017-05-02 15:49:00 -04006596}
6597
6598bool ValidateUseProgram(Context *context, GLuint program)
6599{
6600 if (program != 0)
6601 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04006602 Program *programObject = context->getProgramResolveLink(program);
Jamie Madillbe849e42017-05-02 15:49:00 -04006603 if (!programObject)
6604 {
6605 // ES 3.1.0 section 7.3 page 72
6606 if (context->getShader(program))
6607 {
Jamie Madille0472f32018-11-27 16:32:45 -05006608 context->validationError(GL_INVALID_OPERATION, kExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006609 return false;
6610 }
6611 else
6612 {
Jamie Madille0472f32018-11-27 16:32:45 -05006613 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006614 return false;
6615 }
6616 }
6617 if (!programObject->isLinked())
6618 {
Jamie Madille0472f32018-11-27 16:32:45 -05006619 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006620 return false;
6621 }
6622 }
Jamie Madillc3dc5d42018-12-30 12:12:04 -05006623 if (context->getState().isTransformFeedbackActiveUnpaused())
Jamie Madillbe849e42017-05-02 15:49:00 -04006624 {
6625 // ES 3.0.4 section 2.15 page 91
Jamie Madillc3e37312018-11-30 15:25:39 -05006626 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackUseProgram);
Jamie Madillbe849e42017-05-02 15:49:00 -04006627 return false;
6628 }
6629
6630 return true;
6631}
6632
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006633bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6634{
6635 if (!context->getExtensions().fence)
6636 {
Jamie Madille0472f32018-11-27 16:32:45 -05006637 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006638 return false;
6639 }
6640
6641 if (n < 0)
6642 {
Jamie Madille0472f32018-11-27 16:32:45 -05006643 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006644 return false;
6645 }
6646
6647 return true;
6648}
6649
6650bool ValidateFinishFenceNV(Context *context, GLuint fence)
6651{
6652 if (!context->getExtensions().fence)
6653 {
Jamie Madille0472f32018-11-27 16:32:45 -05006654 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006655 return false;
6656 }
6657
6658 FenceNV *fenceObject = context->getFenceNV(fence);
6659
6660 if (fenceObject == nullptr)
6661 {
Jamie Madille0472f32018-11-27 16:32:45 -05006662 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006663 return false;
6664 }
6665
6666 if (!fenceObject->isSet())
6667 {
Jamie Madille0472f32018-11-27 16:32:45 -05006668 context->validationError(GL_INVALID_OPERATION, kInvalidFenceState);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006669 return false;
6670 }
6671
6672 return true;
6673}
6674
6675bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6676{
6677 if (!context->getExtensions().fence)
6678 {
Jamie Madille0472f32018-11-27 16:32:45 -05006679 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006680 return false;
6681 }
6682
6683 if (n < 0)
6684 {
Jamie Madille0472f32018-11-27 16:32:45 -05006685 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006686 return false;
6687 }
6688
6689 return true;
6690}
6691
6692bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6693{
6694 if (!context->getExtensions().fence)
6695 {
Jamie Madille0472f32018-11-27 16:32:45 -05006696 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006697 return false;
6698 }
6699
6700 FenceNV *fenceObject = context->getFenceNV(fence);
6701
6702 if (fenceObject == nullptr)
6703 {
Jamie Madille0472f32018-11-27 16:32:45 -05006704 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006705 return false;
6706 }
6707
6708 if (!fenceObject->isSet())
6709 {
Jamie Madille0472f32018-11-27 16:32:45 -05006710 context->validationError(GL_INVALID_OPERATION, kInvalidFenceState);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006711 return false;
6712 }
6713
6714 switch (pname)
6715 {
6716 case GL_FENCE_STATUS_NV:
6717 case GL_FENCE_CONDITION_NV:
6718 break;
6719
6720 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006721 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006722 return false;
6723 }
6724
6725 return true;
6726}
6727
6728bool ValidateGetGraphicsResetStatusEXT(Context *context)
6729{
6730 if (!context->getExtensions().robustness)
6731 {
Jamie Madille0472f32018-11-27 16:32:45 -05006732 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006733 return false;
6734 }
6735
6736 return true;
6737}
6738
6739bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6740 GLuint shader,
6741 GLsizei bufsize,
6742 GLsizei *length,
6743 GLchar *source)
6744{
6745 if (!context->getExtensions().translatedShaderSource)
6746 {
Jamie Madille0472f32018-11-27 16:32:45 -05006747 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006748 return false;
6749 }
6750
6751 if (bufsize < 0)
6752 {
Jamie Madille0472f32018-11-27 16:32:45 -05006753 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006754 return false;
6755 }
6756
6757 Shader *shaderObject = context->getShader(shader);
6758
6759 if (!shaderObject)
6760 {
Jamie Madille0472f32018-11-27 16:32:45 -05006761 context->validationError(GL_INVALID_OPERATION, kInvalidShaderName);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006762 return false;
6763 }
6764
6765 return true;
6766}
6767
6768bool ValidateIsFenceNV(Context *context, GLuint fence)
6769{
6770 if (!context->getExtensions().fence)
6771 {
Jamie Madille0472f32018-11-27 16:32:45 -05006772 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006773 return false;
6774 }
6775
6776 return true;
6777}
6778
Jamie Madill007530e2017-12-28 14:27:04 -05006779bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6780{
6781 if (!context->getExtensions().fence)
6782 {
Jamie Madille0472f32018-11-27 16:32:45 -05006783 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill007530e2017-12-28 14:27:04 -05006784 return false;
6785 }
6786
6787 if (condition != GL_ALL_COMPLETED_NV)
6788 {
Jamie Madille0472f32018-11-27 16:32:45 -05006789 context->validationError(GL_INVALID_ENUM, kInvalidFenceCondition);
Jamie Madill007530e2017-12-28 14:27:04 -05006790 return false;
6791 }
6792
6793 FenceNV *fenceObject = context->getFenceNV(fence);
6794
6795 if (fenceObject == nullptr)
6796 {
Jamie Madille0472f32018-11-27 16:32:45 -05006797 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill007530e2017-12-28 14:27:04 -05006798 return false;
6799 }
6800
6801 return true;
6802}
6803
6804bool ValidateTestFenceNV(Context *context, GLuint fence)
6805{
6806 if (!context->getExtensions().fence)
6807 {
Jamie Madille0472f32018-11-27 16:32:45 -05006808 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill007530e2017-12-28 14:27:04 -05006809 return false;
6810 }
6811
6812 FenceNV *fenceObject = context->getFenceNV(fence);
6813
6814 if (fenceObject == nullptr)
6815 {
Jamie Madille0472f32018-11-27 16:32:45 -05006816 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill007530e2017-12-28 14:27:04 -05006817 return false;
6818 }
6819
6820 if (fenceObject->isSet() != GL_TRUE)
6821 {
Jamie Madille0472f32018-11-27 16:32:45 -05006822 context->validationError(GL_INVALID_OPERATION, kInvalidFenceState);
Jamie Madill007530e2017-12-28 14:27:04 -05006823 return false;
6824 }
6825
6826 return true;
6827}
6828
6829bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006830 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006831 GLsizei levels,
6832 GLenum internalformat,
6833 GLsizei width,
6834 GLsizei height)
6835{
6836 if (!context->getExtensions().textureStorage)
6837 {
Jamie Madille0472f32018-11-27 16:32:45 -05006838 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05006839 return false;
6840 }
6841
6842 if (context->getClientMajorVersion() < 3)
6843 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006844 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006845 height);
6846 }
6847
6848 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006849 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006850 1);
6851}
6852
6853bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6854{
Jonah Ryan-Davis2b0553c2019-02-08 10:07:21 -05006855 if (!context->getExtensions().instancedArraysANGLE)
Jamie Madill007530e2017-12-28 14:27:04 -05006856 {
Jamie Madille0472f32018-11-27 16:32:45 -05006857 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05006858 return false;
6859 }
6860
6861 if (index >= MAX_VERTEX_ATTRIBS)
6862 {
Jamie Madille0472f32018-11-27 16:32:45 -05006863 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madill007530e2017-12-28 14:27:04 -05006864 return false;
6865 }
6866
6867 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6868 {
6869 if (index == 0 && divisor != 0)
6870 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006871 context->validationError(GL_INVALID_OPERATION, kAttributeZeroRequiresDivisorLimitation);
Jamie Madill007530e2017-12-28 14:27:04 -05006872
6873 // We also output an error message to the debugger window if tracing is active, so
6874 // that developers can see the error message.
Jamie Madillc3e37312018-11-30 15:25:39 -05006875 ERR() << kAttributeZeroRequiresDivisorLimitation;
Jamie Madill007530e2017-12-28 14:27:04 -05006876 return false;
6877 }
6878 }
6879
6880 return true;
6881}
6882
Jonah Ryan-Davis2b0553c2019-02-08 10:07:21 -05006883bool ValidateVertexAttribDivisorEXT(Context *context, GLuint index, GLuint divisor)
6884{
6885 if (!context->getExtensions().instancedArraysEXT)
6886 {
6887 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
6888 return false;
6889 }
6890
6891 if (index >= MAX_VERTEX_ATTRIBS)
6892 {
6893 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
6894 return false;
6895 }
6896
6897 return true;
6898}
6899
Jamie Madill007530e2017-12-28 14:27:04 -05006900bool ValidateTexImage3DOES(Context *context,
6901 GLenum target,
6902 GLint level,
6903 GLenum internalformat,
6904 GLsizei width,
6905 GLsizei height,
6906 GLsizei depth,
6907 GLint border,
6908 GLenum format,
6909 GLenum type,
6910 const void *pixels)
6911{
6912 UNIMPLEMENTED(); // FIXME
6913 return false;
6914}
6915
6916bool ValidatePopGroupMarkerEXT(Context *context)
6917{
6918 if (!context->getExtensions().debugMarker)
6919 {
6920 // The debug marker calls should not set error state
6921 // However, it seems reasonable to set an error state if the extension is not enabled
Jamie Madille0472f32018-11-27 16:32:45 -05006922 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05006923 return false;
6924 }
6925
6926 return true;
6927}
6928
Jamie Madillfa920eb2018-01-04 11:45:50 -05006929bool ValidateTexStorage1DEXT(Context *context,
6930 GLenum target,
6931 GLsizei levels,
6932 GLenum internalformat,
6933 GLsizei width)
6934{
6935 UNIMPLEMENTED();
Jamie Madille0472f32018-11-27 16:32:45 -05006936 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05006937 return false;
6938}
6939
6940bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006941 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006942 GLsizei levels,
6943 GLenum internalformat,
6944 GLsizei width,
6945 GLsizei height,
6946 GLsizei depth)
6947{
6948 if (!context->getExtensions().textureStorage)
6949 {
Jamie Madille0472f32018-11-27 16:32:45 -05006950 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05006951 return false;
6952 }
6953
6954 if (context->getClientMajorVersion() < 3)
6955 {
Jamie Madille0472f32018-11-27 16:32:45 -05006956 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05006957 return false;
6958 }
6959
6960 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6961 depth);
6962}
6963
jchen1082af6202018-06-22 10:59:52 +08006964bool ValidateMaxShaderCompilerThreadsKHR(Context *context, GLuint count)
6965{
6966 if (!context->getExtensions().parallelShaderCompile)
6967 {
Jamie Madille0472f32018-11-27 16:32:45 -05006968 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
jchen1082af6202018-06-22 10:59:52 +08006969 return false;
6970 }
6971 return true;
6972}
6973
Austin Eng1bf18ce2018-10-19 15:34:02 -07006974bool ValidateMultiDrawArraysANGLE(Context *context,
6975 PrimitiveMode mode,
6976 const GLint *firsts,
6977 const GLsizei *counts,
6978 GLsizei drawcount)
6979{
6980 if (!context->getExtensions().multiDraw)
6981 {
Jamie Madille0472f32018-11-27 16:32:45 -05006982 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07006983 return false;
6984 }
6985 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
6986 {
6987 if (!ValidateDrawArrays(context, mode, firsts[drawID], counts[drawID]))
6988 {
6989 return false;
6990 }
6991 }
6992 return true;
6993}
6994
6995bool ValidateMultiDrawElementsANGLE(Context *context,
6996 PrimitiveMode mode,
6997 const GLsizei *counts,
Jamie Madill8dc27f92018-11-29 11:45:44 -05006998 DrawElementsType type,
Austin Eng3b7c9d02018-11-21 18:09:05 -08006999 const GLvoid *const *indices,
Austin Eng1bf18ce2018-10-19 15:34:02 -07007000 GLsizei drawcount)
7001{
7002 if (!context->getExtensions().multiDraw)
7003 {
Jamie Madille0472f32018-11-27 16:32:45 -05007004 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07007005 return false;
7006 }
7007 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
7008 {
Austin Eng3b7c9d02018-11-21 18:09:05 -08007009 if (!ValidateDrawElements(context, mode, counts[drawID], type, indices[drawID]))
Austin Eng1bf18ce2018-10-19 15:34:02 -07007010 {
7011 return false;
7012 }
7013 }
7014 return true;
7015}
7016
Jeff Gilbert465d6092019-01-02 16:21:18 -08007017bool ValidateProvokingVertexANGLE(Context *context, ProvokingVertex modePacked)
7018{
7019 if (!context->getExtensions().provokingVertex)
7020 {
7021 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
7022 return false;
7023 }
7024
7025 switch (modePacked)
7026 {
7027 case ProvokingVertex::FirstVertexConvention:
7028 case ProvokingVertex::LastVertexConvention:
7029 break;
7030 default:
7031 context->validationError(GL_INVALID_ENUM, kInvalidProvokingVertex);
7032 return false;
7033 }
7034
7035 return true;
7036}
7037
Jamie Madilla5410482019-01-31 19:55:55 -05007038void RecordBindTextureTypeError(Context *context, TextureType target)
7039{
7040 ASSERT(!context->getStateCache().isValidBindTextureType(target));
7041
7042 switch (target)
7043 {
7044 case TextureType::Rectangle:
7045 ASSERT(!context->getExtensions().textureRectangle);
7046 context->validationError(GL_INVALID_ENUM, kTextureRectangleNotSupported);
7047 break;
7048
7049 case TextureType::_3D:
7050 case TextureType::_2DArray:
7051 ASSERT(context->getClientMajorVersion() < 3);
7052 context->validationError(GL_INVALID_ENUM, kES3Required);
7053 break;
7054
7055 case TextureType::_2DMultisample:
7056 ASSERT(context->getClientVersion() < Version(3, 1) &&
7057 !context->getExtensions().textureMultisample);
7058 context->validationError(GL_INVALID_ENUM, kMultisampleTextureExtensionOrES31Required);
7059 break;
7060
7061 case TextureType::_2DMultisampleArray:
7062 ASSERT(!context->getExtensions().textureStorageMultisample2DArray);
7063 context->validationError(GL_INVALID_ENUM, kMultisampleArrayExtensionRequired);
7064 break;
7065
7066 case TextureType::External:
7067 ASSERT(!context->getExtensions().eglImageExternal &&
7068 !context->getExtensions().eglStreamConsumerExternal);
7069 context->validationError(GL_INVALID_ENUM, kExternalTextureNotSupported);
7070 break;
7071
7072 default:
7073 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
7074 }
7075}
7076
Jamie Madillc29968b2016-01-20 11:17:23 -05007077} // namespace gl