blob: a6caffc328b13a452e9085635d48d9f32fc29fc9 [file] [log] [blame]
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001//
Geoff Langcec35902014-04-16 10:52:36 -04002// Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
Geoff Lange8ebe7f2013-08-05 15:03:13 -04003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// validationES2.cpp: Validation functions for OpenGL ES 2.0 entry point parameters
8
Jamie Madill778bf092018-11-14 09:54:36 -05009#include "libANGLE/validationES2_autogen.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030010
11#include <cstdint>
12
Geoff Lange8ebe7f2013-08-05 15:03:13 -040013#include "common/mathutil.h"
Sami Väisänen46eaa942016-06-29 10:26:37 +030014#include "common/string_utils.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040015#include "common/utilities.h"
Jamie Madillef300b12016-10-07 15:12:09 -040016#include "libANGLE/Context.h"
Brandon Jones6cad5662017-06-14 13:25:13 -070017#include "libANGLE/ErrorStrings.h"
Jamie Madill2b7bbc22017-12-21 17:30:38 -050018#include "libANGLE/Fence.h"
Jamie Madillef300b12016-10-07 15:12:09 -040019#include "libANGLE/Framebuffer.h"
20#include "libANGLE/FramebufferAttachment.h"
21#include "libANGLE/Renderbuffer.h"
22#include "libANGLE/Shader.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040023#include "libANGLE/Texture.h"
Jamie Madillef300b12016-10-07 15:12:09 -040024#include "libANGLE/Uniform.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040025#include "libANGLE/VertexArray.h"
Jamie Madillef300b12016-10-07 15:12:09 -040026#include "libANGLE/formatutils.h"
27#include "libANGLE/validationES.h"
Jamie Madill778bf092018-11-14 09:54:36 -050028#include "libANGLE/validationES2.h"
29#include "libANGLE/validationES3_autogen.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040030
31namespace gl
32{
Jamie Madille0472f32018-11-27 16:32:45 -050033using namespace err;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040034
Jamie Madillc29968b2016-01-20 11:17:23 -050035namespace
36{
37
38bool IsPartialBlit(gl::Context *context,
39 const FramebufferAttachment *readBuffer,
40 const FramebufferAttachment *writeBuffer,
41 GLint srcX0,
42 GLint srcY0,
43 GLint srcX1,
44 GLint srcY1,
45 GLint dstX0,
46 GLint dstY0,
47 GLint dstX1,
48 GLint dstY1)
49{
50 const Extents &writeSize = writeBuffer->getSize();
51 const Extents &readSize = readBuffer->getSize();
52
53 if (srcX0 != 0 || srcY0 != 0 || dstX0 != 0 || dstY0 != 0 || dstX1 != writeSize.width ||
54 dstY1 != writeSize.height || srcX1 != readSize.width || srcY1 != readSize.height)
55 {
56 return true;
57 }
58
Jamie Madillc3dc5d42018-12-30 12:12:04 -050059 if (context->getState().isScissorTestEnabled())
Jamie Madillc29968b2016-01-20 11:17:23 -050060 {
Jamie Madillc3dc5d42018-12-30 12:12:04 -050061 const Rectangle &scissor = context->getState().getScissor();
Jamie Madillc29968b2016-01-20 11:17:23 -050062 return scissor.x > 0 || scissor.y > 0 || scissor.width < writeSize.width ||
63 scissor.height < writeSize.height;
64 }
65
66 return false;
67}
68
Sami Väisänend59ca052016-06-21 16:10:00 +030069template <typename T>
70bool ValidatePathInstances(gl::Context *context,
71 GLsizei numPaths,
72 const void *paths,
73 GLuint pathBase)
74{
75 const auto *array = static_cast<const T *>(paths);
76
77 for (GLsizei i = 0; i < numPaths; ++i)
78 {
79 const GLuint pathName = array[i] + pathBase;
Brandon Jones59770802018-04-02 13:18:42 -070080 if (context->isPathGenerated(pathName) && !context->isPath(pathName))
Sami Väisänend59ca052016-06-21 16:10:00 +030081 {
Jamie Madille0472f32018-11-27 16:32:45 -050082 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänend59ca052016-06-21 16:10:00 +030083 return false;
84 }
85 }
86 return true;
87}
88
89bool ValidateInstancedPathParameters(gl::Context *context,
90 GLsizei numPaths,
91 GLenum pathNameType,
92 const void *paths,
93 GLuint pathBase,
94 GLenum transformType,
95 const GLfloat *transformValues)
96{
97 if (!context->getExtensions().pathRendering)
98 {
Jamie Madillc3e37312018-11-30 15:25:39 -050099 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänend59ca052016-06-21 16:10:00 +0300100 return false;
101 }
102
103 if (paths == nullptr)
104 {
Jamie Madillc3e37312018-11-30 15:25:39 -0500105 context->validationError(GL_INVALID_VALUE, kInvalidPathNameArray);
Sami Väisänend59ca052016-06-21 16:10:00 +0300106 return false;
107 }
108
109 if (numPaths < 0)
110 {
Jamie Madillc3e37312018-11-30 15:25:39 -0500111 context->validationError(GL_INVALID_VALUE, kInvalidPathNumPaths);
Sami Väisänend59ca052016-06-21 16:10:00 +0300112 return false;
113 }
114
115 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(numPaths))
116 {
Jamie Madille0472f32018-11-27 16:32:45 -0500117 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300118 return false;
119 }
120
121 std::uint32_t pathNameTypeSize = 0;
122 std::uint32_t componentCount = 0;
123
124 switch (pathNameType)
125 {
126 case GL_UNSIGNED_BYTE:
127 pathNameTypeSize = sizeof(GLubyte);
128 if (!ValidatePathInstances<GLubyte>(context, numPaths, paths, pathBase))
129 return false;
130 break;
131
132 case GL_BYTE:
133 pathNameTypeSize = sizeof(GLbyte);
134 if (!ValidatePathInstances<GLbyte>(context, numPaths, paths, pathBase))
135 return false;
136 break;
137
138 case GL_UNSIGNED_SHORT:
139 pathNameTypeSize = sizeof(GLushort);
140 if (!ValidatePathInstances<GLushort>(context, numPaths, paths, pathBase))
141 return false;
142 break;
143
144 case GL_SHORT:
145 pathNameTypeSize = sizeof(GLshort);
146 if (!ValidatePathInstances<GLshort>(context, numPaths, paths, pathBase))
147 return false;
148 break;
149
150 case GL_UNSIGNED_INT:
151 pathNameTypeSize = sizeof(GLuint);
152 if (!ValidatePathInstances<GLuint>(context, numPaths, paths, pathBase))
153 return false;
154 break;
155
156 case GL_INT:
157 pathNameTypeSize = sizeof(GLint);
158 if (!ValidatePathInstances<GLint>(context, numPaths, paths, pathBase))
159 return false;
160 break;
161
162 default:
Jamie Madillc3e37312018-11-30 15:25:39 -0500163 context->validationError(GL_INVALID_ENUM, kInvalidPathNameType);
Sami Väisänend59ca052016-06-21 16:10:00 +0300164 return false;
165 }
166
167 switch (transformType)
168 {
169 case GL_NONE:
170 componentCount = 0;
171 break;
172 case GL_TRANSLATE_X_CHROMIUM:
173 case GL_TRANSLATE_Y_CHROMIUM:
174 componentCount = 1;
175 break;
176 case GL_TRANSLATE_2D_CHROMIUM:
177 componentCount = 2;
178 break;
179 case GL_TRANSLATE_3D_CHROMIUM:
180 componentCount = 3;
181 break;
182 case GL_AFFINE_2D_CHROMIUM:
183 case GL_TRANSPOSE_AFFINE_2D_CHROMIUM:
184 componentCount = 6;
185 break;
186 case GL_AFFINE_3D_CHROMIUM:
187 case GL_TRANSPOSE_AFFINE_3D_CHROMIUM:
188 componentCount = 12;
189 break;
190 default:
Jamie Madillc3e37312018-11-30 15:25:39 -0500191 context->validationError(GL_INVALID_ENUM, kInvalidTransformation);
Sami Väisänend59ca052016-06-21 16:10:00 +0300192 return false;
193 }
194 if (componentCount != 0 && transformValues == nullptr)
195 {
Jamie Madillc3e37312018-11-30 15:25:39 -0500196 context->validationError(GL_INVALID_VALUE, kNoTransformArray);
Sami Väisänend59ca052016-06-21 16:10:00 +0300197 return false;
198 }
199
200 angle::CheckedNumeric<std::uint32_t> checkedSize(0);
201 checkedSize += (numPaths * pathNameTypeSize);
202 checkedSize += (numPaths * sizeof(GLfloat) * componentCount);
203 if (!checkedSize.IsValid())
204 {
Jamie Madille0472f32018-11-27 16:32:45 -0500205 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300206 return false;
207 }
208
209 return true;
210}
211
Geoff Lang4f0e0032017-05-01 16:04:35 -0400212bool IsValidCopyTextureSourceInternalFormatEnum(GLenum internalFormat)
Geoff Lang97073d12016-04-20 10:42:34 -0700213{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400214 // Table 1.1 from the CHROMIUM_copy_texture spec
Geoff Langca271392017-04-05 12:30:00 -0400215 switch (GetUnsizedFormat(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700216 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400217 case GL_RED:
Geoff Lang97073d12016-04-20 10:42:34 -0700218 case GL_ALPHA:
219 case GL_LUMINANCE:
220 case GL_LUMINANCE_ALPHA:
221 case GL_RGB:
222 case GL_RGBA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400223 case GL_RGB8:
224 case GL_RGBA8:
225 case GL_BGRA_EXT:
226 case GL_BGRA8_EXT:
Geoff Lang97073d12016-04-20 10:42:34 -0700227 return true;
228
Geoff Lang4f0e0032017-05-01 16:04:35 -0400229 default:
230 return false;
231 }
232}
Geoff Lang97073d12016-04-20 10:42:34 -0700233
Geoff Lang4f0e0032017-05-01 16:04:35 -0400234bool IsValidCopySubTextureSourceInternalFormat(GLenum internalFormat)
235{
236 return IsValidCopyTextureSourceInternalFormatEnum(internalFormat);
237}
238
Geoff Lang4f0e0032017-05-01 16:04:35 -0400239bool IsValidCopyTextureDestinationInternalFormatEnum(GLint internalFormat)
240{
241 // Table 1.0 from the CHROMIUM_copy_texture spec
242 switch (internalFormat)
243 {
244 case GL_RGB:
245 case GL_RGBA:
246 case GL_RGB8:
247 case GL_RGBA8:
Geoff Lang97073d12016-04-20 10:42:34 -0700248 case GL_BGRA_EXT:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400249 case GL_BGRA8_EXT:
250 case GL_SRGB_EXT:
251 case GL_SRGB_ALPHA_EXT:
252 case GL_R8:
253 case GL_R8UI:
254 case GL_RG8:
255 case GL_RG8UI:
256 case GL_SRGB8:
257 case GL_RGB565:
258 case GL_RGB8UI:
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400259 case GL_RGB10_A2:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400260 case GL_SRGB8_ALPHA8:
261 case GL_RGB5_A1:
262 case GL_RGBA4:
263 case GL_RGBA8UI:
264 case GL_RGB9_E5:
265 case GL_R16F:
266 case GL_R32F:
267 case GL_RG16F:
268 case GL_RG32F:
269 case GL_RGB16F:
270 case GL_RGB32F:
271 case GL_RGBA16F:
272 case GL_RGBA32F:
273 case GL_R11F_G11F_B10F:
Brandon Jones340b7b82017-06-26 13:02:31 -0700274 case GL_LUMINANCE:
275 case GL_LUMINANCE_ALPHA:
276 case GL_ALPHA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400277 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700278
279 default:
280 return false;
281 }
282}
283
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400284bool IsValidCopySubTextureDestionationInternalFormat(GLenum internalFormat)
285{
286 return IsValidCopyTextureDestinationInternalFormatEnum(internalFormat);
287}
288
Geoff Lang97073d12016-04-20 10:42:34 -0700289bool IsValidCopyTextureDestinationFormatType(Context *context, GLint internalFormat, GLenum type)
290{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400291 if (!IsValidCopyTextureDestinationInternalFormatEnum(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700292 {
Jamie Madille0472f32018-11-27 16:32:45 -0500293 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400294 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700295 }
296
Geoff Langc0094ec2017-08-16 14:16:24 -0400297 if (!ValidES3FormatCombination(GetUnsizedFormat(internalFormat), type, internalFormat))
298 {
Jamie Madille0472f32018-11-27 16:32:45 -0500299 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Langc0094ec2017-08-16 14:16:24 -0400300 return false;
301 }
302
Geoff Lang4f0e0032017-05-01 16:04:35 -0400303 const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat, type);
304 if (!internalFormatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
Geoff Lang97073d12016-04-20 10:42:34 -0700305 {
Jamie Madille0472f32018-11-27 16:32:45 -0500306 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400307 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700308 }
309
310 return true;
311}
312
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800313bool IsValidCopyTextureDestinationTargetEnum(Context *context, TextureTarget target)
Geoff Lang97073d12016-04-20 10:42:34 -0700314{
315 switch (target)
316 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800317 case TextureTarget::_2D:
318 case TextureTarget::CubeMapNegativeX:
319 case TextureTarget::CubeMapNegativeY:
320 case TextureTarget::CubeMapNegativeZ:
321 case TextureTarget::CubeMapPositiveX:
322 case TextureTarget::CubeMapPositiveY:
323 case TextureTarget::CubeMapPositiveZ:
Geoff Lang63458a32017-10-30 15:16:53 -0400324 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700325
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800326 case TextureTarget::Rectangle:
Geoff Lang63458a32017-10-30 15:16:53 -0400327 return context->getExtensions().textureRectangle;
Geoff Lang97073d12016-04-20 10:42:34 -0700328
329 default:
330 return false;
331 }
332}
333
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800334bool IsValidCopyTextureDestinationTarget(Context *context,
335 TextureType textureType,
336 TextureTarget target)
Geoff Lang63458a32017-10-30 15:16:53 -0400337{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800338 return TextureTargetToType(target) == textureType;
Geoff Lang63458a32017-10-30 15:16:53 -0400339}
340
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800341bool IsValidCopyTextureSourceTarget(Context *context, TextureType type)
Geoff Lang97073d12016-04-20 10:42:34 -0700342{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800343 switch (type)
Geoff Lang97073d12016-04-20 10:42:34 -0700344 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800345 case TextureType::_2D:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400346 return true;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800347 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400348 return context->getExtensions().textureRectangle;
Geoff Langbe607ad2018-11-29 10:14:22 -0500349 case TextureType::External:
350 return context->getExtensions().eglImageExternal;
Geoff Lang4f0e0032017-05-01 16:04:35 -0400351 default:
352 return false;
353 }
354}
355
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800356bool IsValidCopyTextureSourceLevel(Context *context, TextureType type, GLint level)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400357{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800358 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400359 {
360 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700361 }
362
Geoff Lang4f0e0032017-05-01 16:04:35 -0400363 if (level > 0 && context->getClientVersion() < ES_3_0)
364 {
365 return false;
366 }
Geoff Lang97073d12016-04-20 10:42:34 -0700367
Geoff Lang4f0e0032017-05-01 16:04:35 -0400368 return true;
369}
370
371bool IsValidCopyTextureDestinationLevel(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800372 TextureType type,
Geoff Lang4f0e0032017-05-01 16:04:35 -0400373 GLint level,
374 GLsizei width,
Brandon Jones28783792018-03-05 09:37:32 -0800375 GLsizei height,
376 bool isSubImage)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400377{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800378 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400379 {
380 return false;
381 }
382
Brandon Jones28783792018-03-05 09:37:32 -0800383 if (!ValidImageSizeParameters(context, type, level, width, height, 1, isSubImage))
384 {
385 return false;
386 }
387
Geoff Lang4f0e0032017-05-01 16:04:35 -0400388 const Caps &caps = context->getCaps();
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800389 switch (type)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400390 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800391 case TextureType::_2D:
392 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
393 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
394 case TextureType::Rectangle:
395 ASSERT(level == 0);
396 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
397 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400398
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800399 case TextureType::CubeMap:
400 return static_cast<GLuint>(width) <= (caps.maxCubeMapTextureSize >> level) &&
401 static_cast<GLuint>(height) <= (caps.maxCubeMapTextureSize >> level);
402 default:
403 return true;
404 }
Geoff Lang97073d12016-04-20 10:42:34 -0700405}
406
Jamie Madillc1d770e2017-04-13 17:31:24 -0400407bool IsValidStencilFunc(GLenum func)
408{
409 switch (func)
410 {
411 case GL_NEVER:
412 case GL_ALWAYS:
413 case GL_LESS:
414 case GL_LEQUAL:
415 case GL_EQUAL:
416 case GL_GEQUAL:
417 case GL_GREATER:
418 case GL_NOTEQUAL:
419 return true;
420
421 default:
422 return false;
423 }
424}
425
426bool IsValidStencilFace(GLenum face)
427{
428 switch (face)
429 {
430 case GL_FRONT:
431 case GL_BACK:
432 case GL_FRONT_AND_BACK:
433 return true;
434
435 default:
436 return false;
437 }
438}
439
440bool IsValidStencilOp(GLenum op)
441{
442 switch (op)
443 {
444 case GL_ZERO:
445 case GL_KEEP:
446 case GL_REPLACE:
447 case GL_INCR:
448 case GL_DECR:
449 case GL_INVERT:
450 case GL_INCR_WRAP:
451 case GL_DECR_WRAP:
452 return true;
453
454 default:
455 return false;
456 }
457}
458
Jamie Madill5b772312018-03-08 20:28:32 -0500459bool ValidateES2CopyTexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800460 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -0400461 GLint level,
462 GLenum internalformat,
463 bool isSubImage,
464 GLint xoffset,
465 GLint yoffset,
466 GLint x,
467 GLint y,
468 GLsizei width,
469 GLsizei height,
470 GLint border)
471{
472 if (!ValidTexture2DDestinationTarget(context, target))
473 {
Jamie Madille0472f32018-11-27 16:32:45 -0500474 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -0400475 return false;
476 }
477
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800478 TextureType texType = TextureTargetToType(target);
479 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Jamie Madillbe849e42017-05-02 15:49:00 -0400480 {
Jamie Madillc3e37312018-11-30 15:25:39 -0500481 // Error is already handled.
Jamie Madillbe849e42017-05-02 15:49:00 -0400482 return false;
483 }
484
485 Format textureFormat = Format::Invalid();
486 if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
487 xoffset, yoffset, 0, x, y, width, height, border,
488 &textureFormat))
489 {
490 return false;
491 }
492
Jamie Madillc3dc5d42018-12-30 12:12:04 -0500493 const gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer();
Jamie Madillbe849e42017-05-02 15:49:00 -0400494 GLenum colorbufferFormat =
495 framebuffer->getReadColorbuffer()->getFormat().info->sizedInternalFormat;
496 const auto &formatInfo = *textureFormat.info;
497
498 // [OpenGL ES 2.0.24] table 3.9
499 if (isSubImage)
500 {
501 switch (formatInfo.format)
502 {
503 case GL_ALPHA:
504 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400505 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
506 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400507 {
Jamie Madille0472f32018-11-27 16:32:45 -0500508 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400509 return false;
510 }
511 break;
512 case GL_LUMINANCE:
513 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
514 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
515 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400516 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGRA8_EXT &&
517 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400518 {
Jamie Madille0472f32018-11-27 16:32:45 -0500519 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400520 return false;
521 }
522 break;
523 case GL_RED_EXT:
524 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
525 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
526 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
527 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_R32F &&
528 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400529 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
530 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400531 {
Jamie Madille0472f32018-11-27 16:32:45 -0500532 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400533 return false;
534 }
535 break;
536 case GL_RG_EXT:
537 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
538 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
539 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
540 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400541 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
542 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400543 {
Jamie Madille0472f32018-11-27 16:32:45 -0500544 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400545 return false;
546 }
547 break;
548 case GL_RGB:
549 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
550 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
551 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400552 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
553 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400554 {
Jamie Madille0472f32018-11-27 16:32:45 -0500555 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400556 return false;
557 }
558 break;
559 case GL_LUMINANCE_ALPHA:
560 case GL_RGBA:
561 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400562 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGBA32F &&
563 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400564 {
Jamie Madille0472f32018-11-27 16:32:45 -0500565 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400566 return false;
567 }
568 break;
569 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
570 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
571 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
572 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
573 case GL_ETC1_RGB8_OES:
574 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
575 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
576 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
577 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
578 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
Olli Etuahof2ed2992018-10-04 13:54:42 +0300579 case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
580 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
581 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
582 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
Jamie Madille0472f32018-11-27 16:32:45 -0500583 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400584 return false;
585 case GL_DEPTH_COMPONENT:
586 case GL_DEPTH_STENCIL_OES:
Jamie Madille0472f32018-11-27 16:32:45 -0500587 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400588 return false;
589 default:
Jamie Madille0472f32018-11-27 16:32:45 -0500590 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400591 return false;
592 }
593
594 if (formatInfo.type == GL_FLOAT && !context->getExtensions().textureFloat)
595 {
Jamie Madille0472f32018-11-27 16:32:45 -0500596 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400597 return false;
598 }
599 }
600 else
601 {
602 switch (internalformat)
603 {
604 case GL_ALPHA:
605 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
606 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
607 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
608 {
Jamie Madille0472f32018-11-27 16:32:45 -0500609 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400610 return false;
611 }
612 break;
613 case GL_LUMINANCE:
614 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
615 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
616 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
617 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
618 colorbufferFormat != GL_BGR5_A1_ANGLEX)
619 {
Jamie Madille0472f32018-11-27 16:32:45 -0500620 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400621 return false;
622 }
623 break;
624 case GL_RED_EXT:
625 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
626 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
627 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
628 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
629 colorbufferFormat != GL_BGR5_A1_ANGLEX)
630 {
Jamie Madille0472f32018-11-27 16:32:45 -0500631 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400632 return false;
633 }
634 break;
635 case GL_RG_EXT:
636 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
637 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
638 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
639 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
640 {
Jamie Madille0472f32018-11-27 16:32:45 -0500641 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400642 return false;
643 }
644 break;
645 case GL_RGB:
646 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
647 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
648 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
649 colorbufferFormat != GL_BGR5_A1_ANGLEX)
650 {
Jamie Madille0472f32018-11-27 16:32:45 -0500651 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400652 return false;
653 }
654 break;
655 case GL_LUMINANCE_ALPHA:
656 case GL_RGBA:
657 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
658 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
659 colorbufferFormat != GL_BGR5_A1_ANGLEX)
660 {
Jamie Madille0472f32018-11-27 16:32:45 -0500661 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400662 return false;
663 }
664 break;
665 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
666 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
667 if (context->getExtensions().textureCompressionDXT1)
668 {
Jamie Madille0472f32018-11-27 16:32:45 -0500669 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400670 return false;
671 }
672 else
673 {
Jamie Madille0472f32018-11-27 16:32:45 -0500674 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400675 return false;
676 }
677 break;
678 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
679 if (context->getExtensions().textureCompressionDXT3)
680 {
Jamie Madille0472f32018-11-27 16:32:45 -0500681 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400682 return false;
683 }
684 else
685 {
Jamie Madille0472f32018-11-27 16:32:45 -0500686 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400687 return false;
688 }
689 break;
690 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
691 if (context->getExtensions().textureCompressionDXT5)
692 {
Jamie Madille0472f32018-11-27 16:32:45 -0500693 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400694 return false;
695 }
696 else
697 {
Jamie Madille0472f32018-11-27 16:32:45 -0500698 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400699 return false;
700 }
701 break;
702 case GL_ETC1_RGB8_OES:
703 if (context->getExtensions().compressedETC1RGB8Texture)
704 {
Jamie Madille0472f32018-11-27 16:32:45 -0500705 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400706 return false;
707 }
708 else
709 {
Jamie Madille0472f32018-11-27 16:32:45 -0500710 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400711 return false;
712 }
713 break;
714 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
715 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
716 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
717 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
718 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
719 if (context->getExtensions().lossyETCDecode)
720 {
Jamie Madillc3e37312018-11-30 15:25:39 -0500721 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400722 return false;
723 }
724 else
725 {
Jamie Madillc3e37312018-11-30 15:25:39 -0500726 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400727 return false;
728 }
729 break;
730 case GL_DEPTH_COMPONENT:
731 case GL_DEPTH_COMPONENT16:
732 case GL_DEPTH_COMPONENT32_OES:
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -0600733 if (context->getExtensions().depthTextureAny())
Jamie Madillbe849e42017-05-02 15:49:00 -0400734 {
Jamie Madille0472f32018-11-27 16:32:45 -0500735 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400736 return false;
737 }
738 else
739 {
Jamie Madille0472f32018-11-27 16:32:45 -0500740 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400741 return false;
742 }
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -0600743 break;
744 case GL_DEPTH_STENCIL_OES:
745 case GL_DEPTH24_STENCIL8_OES:
746 if (context->getExtensions().depthTextureAny() ||
747 context->getExtensions().packedDepthStencil)
748 {
749 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
750 return false;
751 }
752 else
753 {
754 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
755 return false;
756 }
757 break;
Jamie Madillbe849e42017-05-02 15:49:00 -0400758 default:
Jamie Madille0472f32018-11-27 16:32:45 -0500759 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400760 return false;
761 }
762 }
763
764 // If width or height is zero, it is a no-op. Return false without setting an error.
765 return (width > 0 && height > 0);
766}
767
768bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
769{
770 switch (cap)
771 {
772 // EXT_multisample_compatibility
773 case GL_MULTISAMPLE_EXT:
774 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
775 return context->getExtensions().multisampleCompatibility;
776
777 case GL_CULL_FACE:
778 case GL_POLYGON_OFFSET_FILL:
779 case GL_SAMPLE_ALPHA_TO_COVERAGE:
780 case GL_SAMPLE_COVERAGE:
781 case GL_SCISSOR_TEST:
782 case GL_STENCIL_TEST:
783 case GL_DEPTH_TEST:
784 case GL_BLEND:
785 case GL_DITHER:
786 return true;
787
788 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
789 case GL_RASTERIZER_DISCARD:
790 return (context->getClientMajorVersion() >= 3);
791
792 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
793 case GL_DEBUG_OUTPUT:
794 return context->getExtensions().debug;
795
796 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
797 return queryOnly && context->getExtensions().bindGeneratesResource;
798
799 case GL_CLIENT_ARRAYS_ANGLE:
800 return queryOnly && context->getExtensions().clientArrays;
801
802 case GL_FRAMEBUFFER_SRGB_EXT:
803 return context->getExtensions().sRGBWriteControl;
804
805 case GL_SAMPLE_MASK:
806 return context->getClientVersion() >= Version(3, 1);
807
Geoff Langb433e872017-10-05 14:01:47 -0400808 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
Jamie Madillbe849e42017-05-02 15:49:00 -0400809 return queryOnly && context->getExtensions().robustResourceInitialization;
810
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700811 // GLES1 emulation: GLES1-specific caps
812 case GL_ALPHA_TEST:
Lingfeng Yang01074432018-04-16 10:19:51 -0700813 case GL_VERTEX_ARRAY:
814 case GL_NORMAL_ARRAY:
815 case GL_COLOR_ARRAY:
816 case GL_TEXTURE_COORD_ARRAY:
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700817 case GL_TEXTURE_2D:
Lingfeng Yangd0febe72018-05-17 22:36:52 -0700818 case GL_LIGHTING:
819 case GL_LIGHT0:
820 case GL_LIGHT1:
821 case GL_LIGHT2:
822 case GL_LIGHT3:
823 case GL_LIGHT4:
824 case GL_LIGHT5:
825 case GL_LIGHT6:
826 case GL_LIGHT7:
827 case GL_NORMALIZE:
828 case GL_RESCALE_NORMAL:
829 case GL_COLOR_MATERIAL:
Lingfeng Yang060088a2018-05-30 20:40:57 -0700830 case GL_CLIP_PLANE0:
831 case GL_CLIP_PLANE1:
832 case GL_CLIP_PLANE2:
833 case GL_CLIP_PLANE3:
834 case GL_CLIP_PLANE4:
835 case GL_CLIP_PLANE5:
Lingfeng Yang7ba3f422018-06-01 09:43:04 -0700836 case GL_FOG:
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700837 case GL_POINT_SMOOTH:
Lingfeng Yang6e5bf362018-08-15 09:53:17 -0700838 case GL_LINE_SMOOTH:
839 case GL_COLOR_LOGIC_OP:
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700840 return context->getClientVersion() < Version(2, 0);
Lingfeng Yang01074432018-04-16 10:19:51 -0700841 case GL_POINT_SIZE_ARRAY_OES:
842 return context->getClientVersion() < Version(2, 0) &&
843 context->getExtensions().pointSizeArray;
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700844 case GL_TEXTURE_CUBE_MAP:
845 return context->getClientVersion() < Version(2, 0) &&
846 context->getExtensions().textureCubeMap;
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700847 case GL_POINT_SPRITE_OES:
848 return context->getClientVersion() < Version(2, 0) &&
849 context->getExtensions().pointSprite;
Jamie Madillbe849e42017-05-02 15:49:00 -0400850 default:
851 return false;
852 }
853}
854
Geoff Langfc32e8b2017-05-31 14:16:59 -0400855// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
856// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400857bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400858{
859 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400860 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
861 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400862 {
863 return true;
864 }
865
866 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
867 if (c >= 9 && c <= 13)
868 {
869 return true;
870 }
871
872 return false;
873}
874
Geoff Langcab92ee2017-07-19 17:32:07 -0400875bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400876{
Geoff Langa71a98e2017-06-19 15:15:00 -0400877 for (size_t i = 0; i < len; i++)
878 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400879 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400880 {
881 return false;
882 }
883 }
884
885 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400886}
887
Geoff Langcab92ee2017-07-19 17:32:07 -0400888bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
889{
890 enum class ParseState
891 {
892 // Have not seen an ASCII non-whitespace character yet on
893 // this line. Possible that we might see a preprocessor
894 // directive.
895 BEGINING_OF_LINE,
896
897 // Have seen at least one ASCII non-whitespace character
898 // on this line.
899 MIDDLE_OF_LINE,
900
901 // Handling a preprocessor directive. Passes through all
902 // characters up to the end of the line. Disables comment
903 // processing.
904 IN_PREPROCESSOR_DIRECTIVE,
905
906 // Handling a single-line comment. The comment text is
907 // replaced with a single space.
908 IN_SINGLE_LINE_COMMENT,
909
910 // Handling a multi-line comment. Newlines are passed
911 // through to preserve line numbers.
912 IN_MULTI_LINE_COMMENT
913 };
914
915 ParseState state = ParseState::BEGINING_OF_LINE;
916 size_t pos = 0;
917
918 while (pos < len)
919 {
920 char c = str[pos];
921 char next = pos + 1 < len ? str[pos + 1] : 0;
922
923 // Check for newlines
924 if (c == '\n' || c == '\r')
925 {
926 if (state != ParseState::IN_MULTI_LINE_COMMENT)
927 {
928 state = ParseState::BEGINING_OF_LINE;
929 }
930
931 pos++;
932 continue;
933 }
934
935 switch (state)
936 {
937 case ParseState::BEGINING_OF_LINE:
938 if (c == ' ')
939 {
940 // Maintain the BEGINING_OF_LINE state until a non-space is seen
941 pos++;
942 }
943 else if (c == '#')
944 {
945 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
946 pos++;
947 }
948 else
949 {
950 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
951 state = ParseState::MIDDLE_OF_LINE;
952 }
953 break;
954
955 case ParseState::MIDDLE_OF_LINE:
956 if (c == '/' && next == '/')
957 {
958 state = ParseState::IN_SINGLE_LINE_COMMENT;
959 pos++;
960 }
961 else if (c == '/' && next == '*')
962 {
963 state = ParseState::IN_MULTI_LINE_COMMENT;
964 pos++;
965 }
966 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
967 {
968 // Skip line continuation characters
969 }
970 else if (!IsValidESSLCharacter(c))
971 {
972 return false;
973 }
974 pos++;
975 break;
976
977 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700978 // Line-continuation characters may not be permitted.
979 // Otherwise, just pass it through. Do not parse comments in this state.
980 if (!lineContinuationAllowed && c == '\\')
981 {
982 return false;
983 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400984 pos++;
985 break;
986
987 case ParseState::IN_SINGLE_LINE_COMMENT:
988 // Line-continuation characters are processed before comment processing.
989 // Advance string if a new line character is immediately behind
990 // line-continuation character.
991 if (c == '\\' && (next == '\n' || next == '\r'))
992 {
993 pos++;
994 }
995 pos++;
996 break;
997
998 case ParseState::IN_MULTI_LINE_COMMENT:
999 if (c == '*' && next == '/')
1000 {
1001 state = ParseState::MIDDLE_OF_LINE;
1002 pos++;
1003 }
1004 pos++;
1005 break;
1006 }
1007 }
1008
1009 return true;
1010}
1011
Jamie Madill5b772312018-03-08 20:28:32 -05001012bool ValidateWebGLNamePrefix(Context *context, const GLchar *name)
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001013{
1014 ASSERT(context->isWebGL());
1015
1016 // WebGL 1.0 [Section 6.16] GLSL Constructs
1017 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
1018 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
1019 {
Jamie Madille0472f32018-11-27 16:32:45 -05001020 context->validationError(GL_INVALID_OPERATION, kWebglBindAttribLocationReservedPrefix);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001021 return false;
1022 }
1023
1024 return true;
1025}
1026
Jamie Madill5b772312018-03-08 20:28:32 -05001027bool ValidateWebGLNameLength(Context *context, size_t length)
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001028{
1029 ASSERT(context->isWebGL());
1030
1031 if (context->isWebGL1() && length > 256)
1032 {
1033 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
1034 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
1035 // locations.
Jamie Madille0472f32018-11-27 16:32:45 -05001036 context->validationError(GL_INVALID_VALUE, kWebglNameLengthLimitExceeded);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001037
1038 return false;
1039 }
1040 else if (length > 1024)
1041 {
1042 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
1043 // uniform and attribute locations.
Jamie Madille0472f32018-11-27 16:32:45 -05001044 context->validationError(GL_INVALID_VALUE, kWebgl2NameLengthLimitExceeded);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001045 return false;
1046 }
1047
1048 return true;
1049}
1050
Jamie Madill007530e2017-12-28 14:27:04 -05001051bool ValidateMatrixMode(Context *context, GLenum matrixMode)
1052{
1053 if (!context->getExtensions().pathRendering)
1054 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001055 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05001056 return false;
1057 }
1058
1059 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
1060 {
Jamie Madille0472f32018-11-27 16:32:45 -05001061 context->validationError(GL_INVALID_ENUM, kInvalidMatrixMode);
Jamie Madill007530e2017-12-28 14:27:04 -05001062 return false;
1063 }
1064 return true;
1065}
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03001066
1067bool ValidBlendFunc(const Context *context, GLenum val)
1068{
1069 const gl::Extensions &ext = context->getExtensions();
1070
1071 // these are always valid for src and dst.
1072 switch (val)
1073 {
1074 case GL_ZERO:
1075 case GL_ONE:
1076 case GL_SRC_COLOR:
1077 case GL_ONE_MINUS_SRC_COLOR:
1078 case GL_DST_COLOR:
1079 case GL_ONE_MINUS_DST_COLOR:
1080 case GL_SRC_ALPHA:
1081 case GL_ONE_MINUS_SRC_ALPHA:
1082 case GL_DST_ALPHA:
1083 case GL_ONE_MINUS_DST_ALPHA:
1084 case GL_CONSTANT_COLOR:
1085 case GL_ONE_MINUS_CONSTANT_COLOR:
1086 case GL_CONSTANT_ALPHA:
1087 case GL_ONE_MINUS_CONSTANT_ALPHA:
1088 return true;
1089
1090 // EXT_blend_func_extended.
1091 case GL_SRC1_COLOR_EXT:
1092 case GL_SRC1_ALPHA_EXT:
1093 case GL_ONE_MINUS_SRC1_COLOR_EXT:
1094 case GL_ONE_MINUS_SRC1_ALPHA_EXT:
1095 case GL_SRC_ALPHA_SATURATE_EXT:
1096 return ext.blendFuncExtended;
1097
1098 default:
1099 return false;
1100 }
1101}
1102
1103bool ValidSrcBlendFunc(const Context *context, GLenum val)
1104{
1105 if (ValidBlendFunc(context, val))
1106 return true;
1107
1108 if (val == GL_SRC_ALPHA_SATURATE)
1109 return true;
1110
1111 return false;
1112}
1113
1114bool ValidDstBlendFunc(const Context *context, GLenum val)
1115{
1116 if (ValidBlendFunc(context, val))
1117 return true;
1118
1119 if (val == GL_SRC_ALPHA_SATURATE)
1120 {
1121 if (context->getClientMajorVersion() >= 3)
1122 return true;
1123 }
1124
1125 return false;
1126}
Jamie Madillc29968b2016-01-20 11:17:23 -05001127} // anonymous namespace
1128
Geoff Langff5b2d52016-09-07 11:32:23 -04001129bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001130 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001131 GLint level,
1132 GLenum internalformat,
1133 bool isCompressed,
1134 bool isSubImage,
1135 GLint xoffset,
1136 GLint yoffset,
1137 GLsizei width,
1138 GLsizei height,
1139 GLint border,
1140 GLenum format,
1141 GLenum type,
1142 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001143 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001144{
Jamie Madill6f38f822014-06-06 17:12:20 -04001145 if (!ValidTexture2DDestinationTarget(context, target))
1146 {
Jamie Madille0472f32018-11-27 16:32:45 -05001147 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001148 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001149 }
1150
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001151 TextureType texType = TextureTargetToType(target);
1152 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001153 {
Jamie Madill610640f2018-11-21 17:28:41 -05001154 // Error already handled.
Geoff Langb1196682014-07-23 13:47:29 -04001155 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001156 }
1157
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001158 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001159 {
Jamie Madille0472f32018-11-27 16:32:45 -05001160 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Brandon Jones6cad5662017-06-14 13:25:13 -07001161 return false;
1162 }
1163
1164 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001165 std::numeric_limits<GLsizei>::max() - yoffset < height)
1166 {
Jamie Madille0472f32018-11-27 16:32:45 -05001167 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001168 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001169 }
1170
Geoff Langaae65a42014-05-26 12:43:44 -04001171 const gl::Caps &caps = context->getCaps();
1172
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001173 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001174 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001175 case TextureType::_2D:
1176 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1177 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1178 {
Jamie Madille0472f32018-11-27 16:32:45 -05001179 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001180 return false;
1181 }
1182 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001183
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001184 case TextureType::Rectangle:
1185 ASSERT(level == 0);
1186 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1187 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1188 {
Jamie Madille0472f32018-11-27 16:32:45 -05001189 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001190 return false;
1191 }
1192 if (isCompressed)
1193 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001194 context->validationError(GL_INVALID_ENUM, kRectangleTextureCompressed);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001195 return false;
1196 }
1197 break;
1198
1199 case TextureType::CubeMap:
1200 if (!isSubImage && width != height)
1201 {
Jamie Madille0472f32018-11-27 16:32:45 -05001202 context->validationError(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001203 return false;
1204 }
1205
1206 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1207 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1208 {
Jamie Madille0472f32018-11-27 16:32:45 -05001209 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001210 return false;
1211 }
1212 break;
1213
1214 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001215 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001216 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001217 }
1218
Jamie Madillcfc73cc2019-04-08 16:26:51 -04001219 gl::Texture *texture = context->getTextureByType(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001220 if (!texture)
1221 {
Jamie Madille0472f32018-11-27 16:32:45 -05001222 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001223 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001224 }
1225
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001226 // Verify zero border
1227 if (border != 0)
1228 {
Jamie Madille0472f32018-11-27 16:32:45 -05001229 context->validationError(GL_INVALID_VALUE, kInvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001230 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001231 }
1232
Tim Van Patten208af3e2019-03-19 09:15:55 -06001233 bool nonEqualFormatsAllowed = false;
1234
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001235 if (isCompressed)
1236 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001237 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001238 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1239 : internalformat;
Geoff Lange88e4542018-05-03 15:05:57 -04001240
1241 const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(actualInternalFormat);
1242
1243 if (!internalFormatInfo.compressed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001244 {
Jamie Madille0472f32018-11-27 16:32:45 -05001245 context->validationError(GL_INVALID_ENUM, kInvalidInternalFormat);
Geoff Lange88e4542018-05-03 15:05:57 -04001246 return false;
1247 }
1248
1249 if (!internalFormatInfo.textureSupport(context->getClientVersion(),
1250 context->getExtensions()))
1251 {
Jamie Madille0472f32018-11-27 16:32:45 -05001252 context->validationError(GL_INVALID_ENUM, kInvalidInternalFormat);
Geoff Lange88e4542018-05-03 15:05:57 -04001253 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001254 }
Geoff Lang966c9402017-04-18 12:38:27 -04001255
1256 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001257 {
Geoff Lange88e4542018-05-03 15:05:57 -04001258 // From the OES_compressed_ETC1_RGB8_texture spec:
1259 // INVALID_OPERATION is generated by CompressedTexSubImage2D, TexSubImage2D, or
1260 // CopyTexSubImage2D if the texture image <level> bound to <target> has internal format
1261 // ETC1_RGB8_OES.
1262 if (actualInternalFormat == GL_ETC1_RGB8_OES)
1263 {
Jamie Madille0472f32018-11-27 16:32:45 -05001264 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lange88e4542018-05-03 15:05:57 -04001265 return false;
1266 }
1267
Geoff Lang966c9402017-04-18 12:38:27 -04001268 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1269 height, texture->getWidth(target, level),
1270 texture->getHeight(target, level)))
1271 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001272 context->validationError(GL_INVALID_OPERATION, kInvalidCompressedImageSize);
Geoff Lang966c9402017-04-18 12:38:27 -04001273 return false;
1274 }
1275
1276 if (format != actualInternalFormat)
1277 {
Jamie Madille0472f32018-11-27 16:32:45 -05001278 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001279 return false;
1280 }
1281 }
1282 else
1283 {
1284 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1285 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001286 context->validationError(GL_INVALID_OPERATION, kInvalidCompressedImageSize);
Geoff Lang966c9402017-04-18 12:38:27 -04001287 return false;
1288 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001289 }
1290 }
1291 else
1292 {
1293 // validate <type> by itself (used as secondary key below)
1294 switch (type)
1295 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001296 case GL_UNSIGNED_BYTE:
1297 case GL_UNSIGNED_SHORT_5_6_5:
1298 case GL_UNSIGNED_SHORT_4_4_4_4:
1299 case GL_UNSIGNED_SHORT_5_5_5_1:
1300 case GL_UNSIGNED_SHORT:
1301 case GL_UNSIGNED_INT:
1302 case GL_UNSIGNED_INT_24_8_OES:
1303 case GL_HALF_FLOAT_OES:
1304 case GL_FLOAT:
1305 break;
1306 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001307 context->validationError(GL_INVALID_ENUM, kInvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001308 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001309 }
1310
1311 // validate <format> + <type> combinations
1312 // - invalid <format> -> sets INVALID_ENUM
1313 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1314 switch (format)
1315 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001316 case GL_ALPHA:
1317 case GL_LUMINANCE:
1318 case GL_LUMINANCE_ALPHA:
1319 switch (type)
1320 {
1321 case GL_UNSIGNED_BYTE:
1322 case GL_FLOAT:
1323 case GL_HALF_FLOAT_OES:
1324 break;
1325 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001326 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001327 return false;
1328 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001329 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001330 case GL_RED:
1331 case GL_RG:
1332 if (!context->getExtensions().textureRG)
1333 {
Jamie Madille0472f32018-11-27 16:32:45 -05001334 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001335 return false;
1336 }
1337 switch (type)
1338 {
1339 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001340 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001341 case GL_FLOAT:
1342 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001343 if (!context->getExtensions().textureFloat)
1344 {
Jamie Madille0472f32018-11-27 16:32:45 -05001345 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001346 return false;
1347 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001348 break;
1349 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001350 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001351 return false;
1352 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001353 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001354 case GL_RGB:
1355 switch (type)
1356 {
1357 case GL_UNSIGNED_BYTE:
1358 case GL_UNSIGNED_SHORT_5_6_5:
1359 case GL_FLOAT:
1360 case GL_HALF_FLOAT_OES:
1361 break;
1362 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001363 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001364 return false;
1365 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001366 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001367 case GL_RGBA:
1368 switch (type)
1369 {
1370 case GL_UNSIGNED_BYTE:
1371 case GL_UNSIGNED_SHORT_4_4_4_4:
1372 case GL_UNSIGNED_SHORT_5_5_5_1:
1373 case GL_FLOAT:
1374 case GL_HALF_FLOAT_OES:
1375 break;
1376 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001377 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001378 return false;
1379 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001380 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001381 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001382 if (!context->getExtensions().textureFormatBGRA8888)
1383 {
Jamie Madille0472f32018-11-27 16:32:45 -05001384 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001385 return false;
1386 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001387 switch (type)
1388 {
1389 case GL_UNSIGNED_BYTE:
1390 break;
1391 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001392 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001393 return false;
1394 }
1395 break;
1396 case GL_SRGB_EXT:
1397 case GL_SRGB_ALPHA_EXT:
1398 if (!context->getExtensions().sRGB)
1399 {
Jamie Madille0472f32018-11-27 16:32:45 -05001400 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001401 return false;
1402 }
1403 switch (type)
1404 {
1405 case GL_UNSIGNED_BYTE:
1406 break;
1407 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001408 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001409 return false;
1410 }
1411 break;
1412 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1413 // handled below
1414 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1415 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1416 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1417 break;
1418 case GL_DEPTH_COMPONENT:
1419 switch (type)
1420 {
1421 case GL_UNSIGNED_SHORT:
1422 case GL_UNSIGNED_INT:
1423 break;
1424 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001425 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001426 return false;
1427 }
1428 break;
1429 case GL_DEPTH_STENCIL_OES:
1430 switch (type)
1431 {
1432 case GL_UNSIGNED_INT_24_8_OES:
1433 break;
1434 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001435 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001436 return false;
1437 }
1438 break;
1439 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001440 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001441 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001442 }
1443
1444 switch (format)
1445 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001446 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1447 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1448 if (context->getExtensions().textureCompressionDXT1)
1449 {
Jamie Madille0472f32018-11-27 16:32:45 -05001450 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001451 return false;
1452 }
1453 else
1454 {
Jamie Madille0472f32018-11-27 16:32:45 -05001455 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001456 return false;
1457 }
1458 break;
1459 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1460 if (context->getExtensions().textureCompressionDXT3)
1461 {
Jamie Madille0472f32018-11-27 16:32:45 -05001462 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001463 return false;
1464 }
1465 else
1466 {
Jamie Madille0472f32018-11-27 16:32:45 -05001467 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001468 return false;
1469 }
1470 break;
1471 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1472 if (context->getExtensions().textureCompressionDXT5)
1473 {
Jamie Madille0472f32018-11-27 16:32:45 -05001474 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001475 return false;
1476 }
1477 else
1478 {
Jamie Madille0472f32018-11-27 16:32:45 -05001479 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001480 return false;
1481 }
1482 break;
1483 case GL_ETC1_RGB8_OES:
1484 if (context->getExtensions().compressedETC1RGB8Texture)
1485 {
Jamie Madille0472f32018-11-27 16:32:45 -05001486 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001487 return false;
1488 }
1489 else
1490 {
Jamie Madille0472f32018-11-27 16:32:45 -05001491 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001492 return false;
1493 }
1494 break;
1495 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001496 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1497 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1498 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1499 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001500 if (context->getExtensions().lossyETCDecode)
1501 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001502 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001503 return false;
1504 }
1505 else
1506 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001507 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001508 return false;
1509 }
1510 break;
1511 case GL_DEPTH_COMPONENT:
1512 case GL_DEPTH_STENCIL_OES:
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001513 if (!context->getExtensions().depthTextureANGLE &&
1514 !(context->getExtensions().packedDepthStencil &&
1515 context->getExtensions().depthTextureOES))
He Yunchaoced53ae2016-11-29 15:00:51 +08001516 {
Jamie Madille0472f32018-11-27 16:32:45 -05001517 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001518 return false;
1519 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001520 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001521 {
Jamie Madille0472f32018-11-27 16:32:45 -05001522 context->validationError(GL_INVALID_OPERATION, kMismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001523 return false;
1524 }
1525 // OES_depth_texture supports loading depth data and multiple levels,
1526 // but ANGLE_depth_texture does not
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001527 if (!context->getExtensions().depthTextureOES)
He Yunchaoced53ae2016-11-29 15:00:51 +08001528 {
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001529 if (pixels != nullptr)
1530 {
1531 context->validationError(GL_INVALID_OPERATION, kPixelDataNotNull);
1532 return false;
1533 }
1534 if (level != 0)
1535 {
1536 context->validationError(GL_INVALID_OPERATION, kLevelNotZero);
1537 return false;
1538 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001539 }
1540 break;
1541 default:
1542 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001543 }
1544
Geoff Lang6e898aa2017-06-02 11:17:26 -04001545 if (!isSubImage)
1546 {
1547 switch (internalformat)
1548 {
Tim Van Patten208af3e2019-03-19 09:15:55 -06001549 // Core ES 2.0 formats
1550 case GL_ALPHA:
1551 case GL_LUMINANCE:
1552 case GL_LUMINANCE_ALPHA:
1553 case GL_RGB:
1554 case GL_RGBA:
1555 break;
1556
Geoff Lang6e898aa2017-06-02 11:17:26 -04001557 case GL_RGBA32F:
1558 if (!context->getExtensions().colorBufferFloatRGBA)
1559 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001560 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001561 return false;
1562 }
Tim Van Patten208af3e2019-03-19 09:15:55 -06001563
1564 nonEqualFormatsAllowed = true;
1565
Geoff Lang6e898aa2017-06-02 11:17:26 -04001566 if (type != GL_FLOAT)
1567 {
Jamie Madille0472f32018-11-27 16:32:45 -05001568 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001569 return false;
1570 }
1571 if (format != GL_RGBA)
1572 {
Jamie Madille0472f32018-11-27 16:32:45 -05001573 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001574 return false;
1575 }
1576 break;
1577
1578 case GL_RGB32F:
1579 if (!context->getExtensions().colorBufferFloatRGB)
1580 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001581 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001582 return false;
1583 }
Tim Van Patten208af3e2019-03-19 09:15:55 -06001584
1585 nonEqualFormatsAllowed = true;
1586
Geoff Lang6e898aa2017-06-02 11:17:26 -04001587 if (type != GL_FLOAT)
1588 {
Jamie Madille0472f32018-11-27 16:32:45 -05001589 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001590 return false;
1591 }
1592 if (format != GL_RGB)
1593 {
Jamie Madille0472f32018-11-27 16:32:45 -05001594 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001595 return false;
1596 }
1597 break;
1598
Tim Van Patten208af3e2019-03-19 09:15:55 -06001599 case GL_BGRA_EXT:
1600 if (!context->getExtensions().textureFormatBGRA8888)
1601 {
1602 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
1603 return false;
1604 }
Geoff Lang6e898aa2017-06-02 11:17:26 -04001605 break;
Tim Van Patten208af3e2019-03-19 09:15:55 -06001606
1607 case GL_DEPTH_COMPONENT:
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001608 if (!(context->getExtensions().depthTextureAny()))
1609 {
1610 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
1611 return false;
1612 }
1613 break;
1614
Tim Van Patten208af3e2019-03-19 09:15:55 -06001615 case GL_DEPTH_STENCIL:
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001616 if (!(context->getExtensions().depthTextureANGLE ||
1617 context->getExtensions().packedDepthStencil))
Tim Van Patten208af3e2019-03-19 09:15:55 -06001618 {
1619 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
1620 return false;
1621 }
1622 break;
1623
1624 case GL_RED:
1625 case GL_RG:
1626 if (!context->getExtensions().textureRG)
1627 {
1628 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
1629 return false;
1630 }
1631 break;
1632
1633 case GL_SRGB_EXT:
1634 case GL_SRGB_ALPHA_EXT:
1635 if (!context->getExtensions().sRGB)
1636 {
1637 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
1638 return false;
1639 }
1640 break;
1641
1642 default:
1643 context->validationError(GL_INVALID_VALUE, kInvalidInternalFormat);
1644 return false;
Geoff Lang6e898aa2017-06-02 11:17:26 -04001645 }
1646 }
1647
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001648 if (type == GL_FLOAT)
1649 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001650 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001651 {
Jamie Madille0472f32018-11-27 16:32:45 -05001652 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001653 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001654 }
1655 }
1656 else if (type == GL_HALF_FLOAT_OES)
1657 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001658 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001659 {
Jamie Madille0472f32018-11-27 16:32:45 -05001660 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001661 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001662 }
1663 }
1664 }
1665
Tim Van Patten208af3e2019-03-19 09:15:55 -06001666 if (isSubImage)
Geoff Langff5b2d52016-09-07 11:32:23 -04001667 {
Tim Van Patten208af3e2019-03-19 09:15:55 -06001668 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1669 if (textureInternalFormat.internalFormat == GL_NONE)
1670 {
1671 context->validationError(GL_INVALID_OPERATION, kInvalidTextureLevel);
1672 return false;
1673 }
1674
Tim Van Patten5f388c22019-03-14 09:54:23 -06001675 if (format != textureInternalFormat.format)
1676 {
1677 context->validationError(GL_INVALID_OPERATION, err::kTextureFormatMismatch);
1678 return false;
1679 }
1680
1681 if (context->getExtensions().webglCompatibility)
Tim Van Patten208af3e2019-03-19 09:15:55 -06001682 {
1683 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1684 textureInternalFormat.sizedInternalFormat)
1685 {
Tim Van Patten5f388c22019-03-14 09:54:23 -06001686 context->validationError(GL_INVALID_OPERATION, kTextureTypeMismatch);
Tim Van Patten208af3e2019-03-19 09:15:55 -06001687 return false;
1688 }
1689 }
1690
1691 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1692 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1693 {
1694 context->validationError(GL_INVALID_VALUE, kOffsetOverflow);
1695 return false;
1696 }
1697
1698 if (width > 0 && height > 0 && pixels == nullptr &&
1699 context->getState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
1700 {
1701 context->validationError(GL_INVALID_VALUE, kPixelDataNull);
1702 return false;
1703 }
1704 }
1705 else
1706 {
1707 if (texture->getImmutableFormat())
1708 {
1709 context->validationError(GL_INVALID_OPERATION, kTextureIsImmutable);
1710 return false;
1711 }
1712 }
1713
1714 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1715 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1716 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1717 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1718 // case.
1719 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
1720 {
1721 context->validationError(GL_INVALID_OPERATION, kInvalidFormatCombination);
Geoff Langff5b2d52016-09-07 11:32:23 -04001722 return false;
1723 }
1724
Tim Van Patten208af3e2019-03-19 09:15:55 -06001725 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
1726 return ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
1727 imageSize);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001728}
1729
He Yunchaoced53ae2016-11-29 15:00:51 +08001730bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001731 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001732 GLsizei levels,
1733 GLenum internalformat,
1734 GLsizei width,
1735 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001736{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001737 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1738 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001739 {
Jamie Madille0472f32018-11-27 16:32:45 -05001740 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001741 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001742 }
1743
1744 if (width < 1 || height < 1 || levels < 1)
1745 {
Jamie Madille0472f32018-11-27 16:32:45 -05001746 context->validationError(GL_INVALID_VALUE, kTextureSizeTooSmall);
Geoff Langb1196682014-07-23 13:47:29 -04001747 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001748 }
1749
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001750 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001751 {
Jamie Madille0472f32018-11-27 16:32:45 -05001752 context->validationError(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
Geoff Langb1196682014-07-23 13:47:29 -04001753 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001754 }
1755
1756 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1757 {
Jamie Madille0472f32018-11-27 16:32:45 -05001758 context->validationError(GL_INVALID_OPERATION, kInvalidMipLevels);
Geoff Langb1196682014-07-23 13:47:29 -04001759 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001760 }
1761
Geoff Langca271392017-04-05 12:30:00 -04001762 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001763 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001764 {
Jamie Madille0472f32018-11-27 16:32:45 -05001765 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001766 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001767 }
1768
Geoff Langaae65a42014-05-26 12:43:44 -04001769 const gl::Caps &caps = context->getCaps();
1770
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001771 switch (target)
1772 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001773 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001774 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1775 static_cast<GLuint>(height) > caps.max2DTextureSize)
1776 {
Jamie Madille0472f32018-11-27 16:32:45 -05001777 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
He Yunchaoced53ae2016-11-29 15:00:51 +08001778 return false;
1779 }
1780 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001781 case TextureType::Rectangle:
Jamie Madill610640f2018-11-21 17:28:41 -05001782 if (levels != 1)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001783 {
Jamie Madille0472f32018-11-27 16:32:45 -05001784 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madill610640f2018-11-21 17:28:41 -05001785 return false;
1786 }
1787
1788 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1789 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1790 {
Jamie Madille0472f32018-11-27 16:32:45 -05001791 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001792 return false;
1793 }
1794 if (formatInfo.compressed)
1795 {
Jamie Madille0472f32018-11-27 16:32:45 -05001796 context->validationError(GL_INVALID_ENUM, kRectangleTextureCompressed);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001797 return false;
1798 }
1799 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001800 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001801 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1802 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1803 {
Jamie Madille0472f32018-11-27 16:32:45 -05001804 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
He Yunchaoced53ae2016-11-29 15:00:51 +08001805 return false;
1806 }
1807 break;
1808 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001809 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001810 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001811 }
1812
Geoff Langc0b9ef42014-07-02 10:02:37 -04001813 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001814 {
1815 if (!gl::isPow2(width) || !gl::isPow2(height))
1816 {
Jamie Madille0472f32018-11-27 16:32:45 -05001817 context->validationError(GL_INVALID_OPERATION, kDimensionsMustBePow2);
Geoff Langb1196682014-07-23 13:47:29 -04001818 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001819 }
1820 }
1821
1822 switch (internalformat)
1823 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001824 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1825 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1826 if (!context->getExtensions().textureCompressionDXT1)
1827 {
Jamie Madille0472f32018-11-27 16:32:45 -05001828 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001829 return false;
1830 }
1831 break;
1832 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1833 if (!context->getExtensions().textureCompressionDXT3)
1834 {
Jamie Madille0472f32018-11-27 16:32:45 -05001835 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001836 return false;
1837 }
1838 break;
1839 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1840 if (!context->getExtensions().textureCompressionDXT5)
1841 {
Jamie Madille0472f32018-11-27 16:32:45 -05001842 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001843 return false;
1844 }
1845 break;
1846 case GL_ETC1_RGB8_OES:
1847 if (!context->getExtensions().compressedETC1RGB8Texture)
1848 {
Jamie Madille0472f32018-11-27 16:32:45 -05001849 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001850 return false;
1851 }
1852 break;
1853 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001854 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1855 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1856 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1857 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001858 if (!context->getExtensions().lossyETCDecode)
1859 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001860 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001861 return false;
1862 }
1863 break;
1864 case GL_RGBA32F_EXT:
1865 case GL_RGB32F_EXT:
1866 case GL_ALPHA32F_EXT:
1867 case GL_LUMINANCE32F_EXT:
1868 case GL_LUMINANCE_ALPHA32F_EXT:
1869 if (!context->getExtensions().textureFloat)
1870 {
Jamie Madille0472f32018-11-27 16:32:45 -05001871 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001872 return false;
1873 }
1874 break;
1875 case GL_RGBA16F_EXT:
1876 case GL_RGB16F_EXT:
1877 case GL_ALPHA16F_EXT:
1878 case GL_LUMINANCE16F_EXT:
1879 case GL_LUMINANCE_ALPHA16F_EXT:
1880 if (!context->getExtensions().textureHalfFloat)
1881 {
Jamie Madille0472f32018-11-27 16:32:45 -05001882 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001883 return false;
1884 }
1885 break;
1886 case GL_R8_EXT:
1887 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001888 if (!context->getExtensions().textureRG)
1889 {
Jamie Madille0472f32018-11-27 16:32:45 -05001890 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang677bb6f2017-04-05 12:40:40 -04001891 return false;
1892 }
1893 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001894 case GL_R16F_EXT:
1895 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001896 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1897 {
Jamie Madille0472f32018-11-27 16:32:45 -05001898 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang677bb6f2017-04-05 12:40:40 -04001899 return false;
1900 }
1901 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001902 case GL_R32F_EXT:
1903 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001904 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001905 {
Jamie Madille0472f32018-11-27 16:32:45 -05001906 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001907 return false;
1908 }
1909 break;
1910 case GL_DEPTH_COMPONENT16:
1911 case GL_DEPTH_COMPONENT32_OES:
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001912 if (!(context->getExtensions().depthTextureAny()))
He Yunchaoced53ae2016-11-29 15:00:51 +08001913 {
Jamie Madille0472f32018-11-27 16:32:45 -05001914 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001915 return false;
1916 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001917 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001918 {
Jamie Madille0472f32018-11-27 16:32:45 -05001919 context->validationError(GL_INVALID_OPERATION, kInvalidTextureTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001920 return false;
1921 }
1922 // ANGLE_depth_texture only supports 1-level textures
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001923 if (!context->getExtensions().depthTextureOES)
He Yunchaoced53ae2016-11-29 15:00:51 +08001924 {
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001925 if (levels != 1)
1926 {
1927 context->validationError(GL_INVALID_OPERATION, kInvalidMipLevels);
1928 return false;
1929 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001930 }
1931 break;
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001932 case GL_DEPTH24_STENCIL8_OES:
1933 if (!(context->getExtensions().depthTextureANGLE ||
1934 (context->getExtensions().packedDepthStencil &&
1935 context->getExtensions().textureStorage)))
1936 {
1937 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
1938 return false;
1939 }
1940 if (target != TextureType::_2D)
1941 {
1942 context->validationError(GL_INVALID_OPERATION, kInvalidTextureTarget);
1943 return false;
1944 }
1945 if (!context->getExtensions().packedDepthStencil)
1946 {
1947 // ANGLE_depth_texture only supports 1-level textures
1948 if (levels != 1)
1949 {
1950 context->validationError(GL_INVALID_OPERATION, kInvalidMipLevels);
1951 return false;
1952 }
1953 }
1954 break;
1955
He Yunchaoced53ae2016-11-29 15:00:51 +08001956 default:
1957 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001958 }
1959
Jamie Madillcfc73cc2019-04-08 16:26:51 -04001960 gl::Texture *texture = context->getTextureByType(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001961 if (!texture || texture->id() == 0)
1962 {
Jamie Madille0472f32018-11-27 16:32:45 -05001963 context->validationError(GL_INVALID_OPERATION, kMissingTexture);
Geoff Langb1196682014-07-23 13:47:29 -04001964 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001965 }
1966
Geoff Lang69cce582015-09-17 13:20:36 -04001967 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001968 {
Jamie Madille0472f32018-11-27 16:32:45 -05001969 context->validationError(GL_INVALID_OPERATION, kTextureIsImmutable);
Geoff Langb1196682014-07-23 13:47:29 -04001970 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001971 }
1972
1973 return true;
1974}
1975
He Yunchaoced53ae2016-11-29 15:00:51 +08001976bool ValidateDiscardFramebufferEXT(Context *context,
1977 GLenum target,
1978 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001979 const GLenum *attachments)
1980{
Jamie Madillc29968b2016-01-20 11:17:23 -05001981 if (!context->getExtensions().discardFramebuffer)
1982 {
Jamie Madille0472f32018-11-27 16:32:45 -05001983 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001984 return false;
1985 }
1986
Austin Kinross08332632015-05-05 13:35:47 -07001987 bool defaultFramebuffer = false;
1988
1989 switch (target)
1990 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001991 case GL_FRAMEBUFFER:
1992 defaultFramebuffer =
Jamie Madillc3dc5d42018-12-30 12:12:04 -05001993 (context->getState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
He Yunchaoced53ae2016-11-29 15:00:51 +08001994 break;
1995 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001996 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001997 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001998 }
1999
He Yunchaoced53ae2016-11-29 15:00:51 +08002000 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
2001 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07002002}
2003
Austin Kinrossbc781f32015-10-26 09:27:38 -07002004bool ValidateBindVertexArrayOES(Context *context, GLuint array)
2005{
2006 if (!context->getExtensions().vertexArrayObject)
2007 {
Jamie Madille0472f32018-11-27 16:32:45 -05002008 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07002009 return false;
2010 }
2011
2012 return ValidateBindVertexArrayBase(context, array);
2013}
2014
Jamie Madilld7576732017-08-26 18:49:50 -04002015bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07002016{
2017 if (!context->getExtensions().vertexArrayObject)
2018 {
Jamie Madille0472f32018-11-27 16:32:45 -05002019 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07002020 return false;
2021 }
2022
Olli Etuaho41997e72016-03-10 13:38:39 +02002023 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07002024}
2025
Jamie Madilld7576732017-08-26 18:49:50 -04002026bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07002027{
2028 if (!context->getExtensions().vertexArrayObject)
2029 {
Jamie Madille0472f32018-11-27 16:32:45 -05002030 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07002031 return false;
2032 }
2033
Olli Etuaho41997e72016-03-10 13:38:39 +02002034 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07002035}
2036
Jamie Madilld7576732017-08-26 18:49:50 -04002037bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07002038{
2039 if (!context->getExtensions().vertexArrayObject)
2040 {
Jamie Madille0472f32018-11-27 16:32:45 -05002041 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07002042 return false;
2043 }
2044
2045 return true;
2046}
Geoff Langc5629752015-12-07 16:29:04 -05002047
2048bool ValidateProgramBinaryOES(Context *context,
2049 GLuint program,
2050 GLenum binaryFormat,
2051 const void *binary,
2052 GLint length)
2053{
2054 if (!context->getExtensions().getProgramBinary)
2055 {
Jamie Madille0472f32018-11-27 16:32:45 -05002056 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05002057 return false;
2058 }
2059
2060 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
2061}
2062
2063bool ValidateGetProgramBinaryOES(Context *context,
2064 GLuint program,
2065 GLsizei bufSize,
2066 GLsizei *length,
2067 GLenum *binaryFormat,
2068 void *binary)
2069{
2070 if (!context->getExtensions().getProgramBinary)
2071 {
Jamie Madille0472f32018-11-27 16:32:45 -05002072 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05002073 return false;
2074 }
2075
2076 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
2077}
Geoff Lange102fee2015-12-10 11:23:30 -05002078
Geoff Lang70d0f492015-12-10 17:45:46 -05002079static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
2080{
2081 switch (source)
2082 {
2083 case GL_DEBUG_SOURCE_API:
2084 case GL_DEBUG_SOURCE_SHADER_COMPILER:
2085 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
2086 case GL_DEBUG_SOURCE_OTHER:
2087 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
2088 return !mustBeThirdPartyOrApplication;
2089
2090 case GL_DEBUG_SOURCE_THIRD_PARTY:
2091 case GL_DEBUG_SOURCE_APPLICATION:
2092 return true;
2093
2094 default:
2095 return false;
2096 }
2097}
2098
2099static bool ValidDebugType(GLenum type)
2100{
2101 switch (type)
2102 {
2103 case GL_DEBUG_TYPE_ERROR:
2104 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
2105 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
2106 case GL_DEBUG_TYPE_PERFORMANCE:
2107 case GL_DEBUG_TYPE_PORTABILITY:
2108 case GL_DEBUG_TYPE_OTHER:
2109 case GL_DEBUG_TYPE_MARKER:
2110 case GL_DEBUG_TYPE_PUSH_GROUP:
2111 case GL_DEBUG_TYPE_POP_GROUP:
2112 return true;
2113
2114 default:
2115 return false;
2116 }
2117}
2118
2119static bool ValidDebugSeverity(GLenum severity)
2120{
2121 switch (severity)
2122 {
2123 case GL_DEBUG_SEVERITY_HIGH:
2124 case GL_DEBUG_SEVERITY_MEDIUM:
2125 case GL_DEBUG_SEVERITY_LOW:
2126 case GL_DEBUG_SEVERITY_NOTIFICATION:
2127 return true;
2128
2129 default:
2130 return false;
2131 }
2132}
2133
Geoff Lange102fee2015-12-10 11:23:30 -05002134bool ValidateDebugMessageControlKHR(Context *context,
2135 GLenum source,
2136 GLenum type,
2137 GLenum severity,
2138 GLsizei count,
2139 const GLuint *ids,
2140 GLboolean enabled)
2141{
2142 if (!context->getExtensions().debug)
2143 {
Jamie Madille0472f32018-11-27 16:32:45 -05002144 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002145 return false;
2146 }
2147
Geoff Lang70d0f492015-12-10 17:45:46 -05002148 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
2149 {
Jamie Madille0472f32018-11-27 16:32:45 -05002150 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002151 return false;
2152 }
2153
2154 if (!ValidDebugType(type) && type != GL_DONT_CARE)
2155 {
Jamie Madille0472f32018-11-27 16:32:45 -05002156 context->validationError(GL_INVALID_ENUM, kInvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002157 return false;
2158 }
2159
2160 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
2161 {
Jamie Madille0472f32018-11-27 16:32:45 -05002162 context->validationError(GL_INVALID_ENUM, kInvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05002163 return false;
2164 }
2165
2166 if (count > 0)
2167 {
2168 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
2169 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002170 context->validationError(GL_INVALID_OPERATION, kInvalidDebugSourceType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002171 return false;
2172 }
2173
2174 if (severity != GL_DONT_CARE)
2175 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002176 context->validationError(GL_INVALID_OPERATION, kInvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05002177 return false;
2178 }
2179 }
2180
Geoff Lange102fee2015-12-10 11:23:30 -05002181 return true;
2182}
2183
2184bool ValidateDebugMessageInsertKHR(Context *context,
2185 GLenum source,
2186 GLenum type,
2187 GLuint id,
2188 GLenum severity,
2189 GLsizei length,
2190 const GLchar *buf)
2191{
2192 if (!context->getExtensions().debug)
2193 {
Jamie Madille0472f32018-11-27 16:32:45 -05002194 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002195 return false;
2196 }
2197
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002198 if (!context->getState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002199 {
2200 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2201 // not generate an error.
2202 return false;
2203 }
2204
2205 if (!ValidDebugSeverity(severity))
2206 {
Jamie Madille0472f32018-11-27 16:32:45 -05002207 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002208 return false;
2209 }
2210
2211 if (!ValidDebugType(type))
2212 {
Jamie Madille0472f32018-11-27 16:32:45 -05002213 context->validationError(GL_INVALID_ENUM, kInvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002214 return false;
2215 }
2216
2217 if (!ValidDebugSource(source, true))
2218 {
Jamie Madille0472f32018-11-27 16:32:45 -05002219 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002220 return false;
2221 }
2222
2223 size_t messageLength = (length < 0) ? strlen(buf) : length;
2224 if (messageLength > context->getExtensions().maxDebugMessageLength)
2225 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002226 context->validationError(GL_INVALID_VALUE, kExceedsMaxDebugMessageLength);
Geoff Lang70d0f492015-12-10 17:45:46 -05002227 return false;
2228 }
2229
Geoff Lange102fee2015-12-10 11:23:30 -05002230 return true;
2231}
2232
2233bool ValidateDebugMessageCallbackKHR(Context *context,
2234 GLDEBUGPROCKHR callback,
2235 const void *userParam)
2236{
2237 if (!context->getExtensions().debug)
2238 {
Jamie Madille0472f32018-11-27 16:32:45 -05002239 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002240 return false;
2241 }
2242
Geoff Lange102fee2015-12-10 11:23:30 -05002243 return true;
2244}
2245
2246bool ValidateGetDebugMessageLogKHR(Context *context,
2247 GLuint count,
2248 GLsizei bufSize,
2249 GLenum *sources,
2250 GLenum *types,
2251 GLuint *ids,
2252 GLenum *severities,
2253 GLsizei *lengths,
2254 GLchar *messageLog)
2255{
2256 if (!context->getExtensions().debug)
2257 {
Jamie Madille0472f32018-11-27 16:32:45 -05002258 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002259 return false;
2260 }
2261
Geoff Lang70d0f492015-12-10 17:45:46 -05002262 if (bufSize < 0 && messageLog != nullptr)
2263 {
Jamie Madille0472f32018-11-27 16:32:45 -05002264 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002265 return false;
2266 }
2267
Geoff Lange102fee2015-12-10 11:23:30 -05002268 return true;
2269}
2270
2271bool ValidatePushDebugGroupKHR(Context *context,
2272 GLenum source,
2273 GLuint id,
2274 GLsizei length,
2275 const GLchar *message)
2276{
2277 if (!context->getExtensions().debug)
2278 {
Jamie Madille0472f32018-11-27 16:32:45 -05002279 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002280 return false;
2281 }
2282
Geoff Lang70d0f492015-12-10 17:45:46 -05002283 if (!ValidDebugSource(source, true))
2284 {
Jamie Madille0472f32018-11-27 16:32:45 -05002285 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002286 return false;
2287 }
2288
2289 size_t messageLength = (length < 0) ? strlen(message) : length;
2290 if (messageLength > context->getExtensions().maxDebugMessageLength)
2291 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002292 context->validationError(GL_INVALID_VALUE, kExceedsMaxDebugMessageLength);
Geoff Lang70d0f492015-12-10 17:45:46 -05002293 return false;
2294 }
2295
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002296 size_t currentStackSize = context->getState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002297 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2298 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002299 context->validationError(GL_STACK_OVERFLOW, kExceedsMaxDebugGroupStackDepth);
Geoff Lang70d0f492015-12-10 17:45:46 -05002300 return false;
2301 }
2302
Geoff Lange102fee2015-12-10 11:23:30 -05002303 return true;
2304}
2305
2306bool ValidatePopDebugGroupKHR(Context *context)
2307{
2308 if (!context->getExtensions().debug)
2309 {
Jamie Madille0472f32018-11-27 16:32:45 -05002310 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002311 return false;
2312 }
2313
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002314 size_t currentStackSize = context->getState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002315 if (currentStackSize <= 1)
2316 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002317 context->validationError(GL_STACK_UNDERFLOW, kCannotPopDefaultDebugGroup);
Geoff Lang70d0f492015-12-10 17:45:46 -05002318 return false;
2319 }
2320
2321 return true;
2322}
2323
2324static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2325{
2326 switch (identifier)
2327 {
2328 case GL_BUFFER:
2329 if (context->getBuffer(name) == nullptr)
2330 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002331 context->validationError(GL_INVALID_VALUE, kInvalidBufferName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002332 return false;
2333 }
2334 return true;
2335
2336 case GL_SHADER:
2337 if (context->getShader(name) == nullptr)
2338 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002339 context->validationError(GL_INVALID_VALUE, kInvalidShaderName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002340 return false;
2341 }
2342 return true;
2343
2344 case GL_PROGRAM:
Jamie Madill44a6fbf2018-10-02 13:38:56 -04002345 if (context->getProgramNoResolveLink(name) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002346 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002347 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002348 return false;
2349 }
2350 return true;
2351
2352 case GL_VERTEX_ARRAY:
2353 if (context->getVertexArray(name) == nullptr)
2354 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002355 context->validationError(GL_INVALID_VALUE, kInvalidVertexArrayName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002356 return false;
2357 }
2358 return true;
2359
2360 case GL_QUERY:
2361 if (context->getQuery(name) == nullptr)
2362 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002363 context->validationError(GL_INVALID_VALUE, kInvalidQueryName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002364 return false;
2365 }
2366 return true;
2367
2368 case GL_TRANSFORM_FEEDBACK:
2369 if (context->getTransformFeedback(name) == nullptr)
2370 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002371 context->validationError(GL_INVALID_VALUE, kInvalidTransformFeedbackName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002372 return false;
2373 }
2374 return true;
2375
2376 case GL_SAMPLER:
2377 if (context->getSampler(name) == nullptr)
2378 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002379 context->validationError(GL_INVALID_VALUE, kInvalidSamplerName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002380 return false;
2381 }
2382 return true;
2383
2384 case GL_TEXTURE:
2385 if (context->getTexture(name) == nullptr)
2386 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002387 context->validationError(GL_INVALID_VALUE, kInvalidTextureName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002388 return false;
2389 }
2390 return true;
2391
2392 case GL_RENDERBUFFER:
2393 if (context->getRenderbuffer(name) == nullptr)
2394 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002395 context->validationError(GL_INVALID_VALUE, kInvalidRenderbufferName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002396 return false;
2397 }
2398 return true;
2399
2400 case GL_FRAMEBUFFER:
2401 if (context->getFramebuffer(name) == nullptr)
2402 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002403 context->validationError(GL_INVALID_VALUE, kInvalidFramebufferName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002404 return false;
2405 }
2406 return true;
2407
2408 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05002409 context->validationError(GL_INVALID_ENUM, kInvalidIndentifier);
Geoff Lang70d0f492015-12-10 17:45:46 -05002410 return false;
2411 }
Geoff Lange102fee2015-12-10 11:23:30 -05002412}
2413
Martin Radev9d901792016-07-15 15:58:58 +03002414static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2415{
2416 size_t labelLength = 0;
2417
2418 if (length < 0)
2419 {
2420 if (label != nullptr)
2421 {
2422 labelLength = strlen(label);
2423 }
2424 }
2425 else
2426 {
2427 labelLength = static_cast<size_t>(length);
2428 }
2429
2430 if (labelLength > context->getExtensions().maxLabelLength)
2431 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002432 context->validationError(GL_INVALID_VALUE, kExceedsMaxLabelLength);
Martin Radev9d901792016-07-15 15:58:58 +03002433 return false;
2434 }
2435
2436 return true;
2437}
2438
Geoff Lange102fee2015-12-10 11:23:30 -05002439bool ValidateObjectLabelKHR(Context *context,
2440 GLenum identifier,
2441 GLuint name,
2442 GLsizei length,
2443 const GLchar *label)
2444{
2445 if (!context->getExtensions().debug)
2446 {
Jamie Madille0472f32018-11-27 16:32:45 -05002447 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002448 return false;
2449 }
2450
Geoff Lang70d0f492015-12-10 17:45:46 -05002451 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2452 {
2453 return false;
2454 }
2455
Martin Radev9d901792016-07-15 15:58:58 +03002456 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002457 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002458 return false;
2459 }
2460
Geoff Lange102fee2015-12-10 11:23:30 -05002461 return true;
2462}
2463
2464bool ValidateGetObjectLabelKHR(Context *context,
2465 GLenum identifier,
2466 GLuint name,
2467 GLsizei bufSize,
2468 GLsizei *length,
2469 GLchar *label)
2470{
2471 if (!context->getExtensions().debug)
2472 {
Jamie Madille0472f32018-11-27 16:32:45 -05002473 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002474 return false;
2475 }
2476
Geoff Lang70d0f492015-12-10 17:45:46 -05002477 if (bufSize < 0)
2478 {
Jamie Madille0472f32018-11-27 16:32:45 -05002479 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002480 return false;
2481 }
2482
2483 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2484 {
2485 return false;
2486 }
2487
Martin Radev9d901792016-07-15 15:58:58 +03002488 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002489}
2490
2491static bool ValidateObjectPtrName(Context *context, const void *ptr)
2492{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002493 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002494 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002495 context->validationError(GL_INVALID_VALUE, kInvalidSyncPointer);
Geoff Lang70d0f492015-12-10 17:45:46 -05002496 return false;
2497 }
2498
Geoff Lange102fee2015-12-10 11:23:30 -05002499 return true;
2500}
2501
2502bool ValidateObjectPtrLabelKHR(Context *context,
2503 const void *ptr,
2504 GLsizei length,
2505 const GLchar *label)
2506{
2507 if (!context->getExtensions().debug)
2508 {
Jamie Madille0472f32018-11-27 16:32:45 -05002509 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002510 return false;
2511 }
2512
Geoff Lang70d0f492015-12-10 17:45:46 -05002513 if (!ValidateObjectPtrName(context, ptr))
2514 {
2515 return false;
2516 }
2517
Martin Radev9d901792016-07-15 15:58:58 +03002518 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002519 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002520 return false;
2521 }
2522
Geoff Lange102fee2015-12-10 11:23:30 -05002523 return true;
2524}
2525
2526bool ValidateGetObjectPtrLabelKHR(Context *context,
2527 const void *ptr,
2528 GLsizei bufSize,
2529 GLsizei *length,
2530 GLchar *label)
2531{
2532 if (!context->getExtensions().debug)
2533 {
Jamie Madille0472f32018-11-27 16:32:45 -05002534 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002535 return false;
2536 }
2537
Geoff Lang70d0f492015-12-10 17:45:46 -05002538 if (bufSize < 0)
2539 {
Jamie Madille0472f32018-11-27 16:32:45 -05002540 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002541 return false;
2542 }
2543
2544 if (!ValidateObjectPtrName(context, ptr))
2545 {
2546 return false;
2547 }
2548
Martin Radev9d901792016-07-15 15:58:58 +03002549 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002550}
2551
2552bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2553{
2554 if (!context->getExtensions().debug)
2555 {
Jamie Madille0472f32018-11-27 16:32:45 -05002556 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002557 return false;
2558 }
2559
Geoff Lang70d0f492015-12-10 17:45:46 -05002560 // TODO: represent this in Context::getQueryParameterInfo.
2561 switch (pname)
2562 {
2563 case GL_DEBUG_CALLBACK_FUNCTION:
2564 case GL_DEBUG_CALLBACK_USER_PARAM:
2565 break;
2566
2567 default:
Jamie Madille0472f32018-11-27 16:32:45 -05002568 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002569 return false;
2570 }
2571
Geoff Lange102fee2015-12-10 11:23:30 -05002572 return true;
2573}
Jamie Madillc29968b2016-01-20 11:17:23 -05002574
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07002575bool ValidateGetPointervRobustANGLERobustANGLE(Context *context,
2576 GLenum pname,
2577 GLsizei bufSize,
2578 GLsizei *length,
2579 void **params)
2580{
2581 UNIMPLEMENTED();
2582 return false;
2583}
2584
Jamie Madillc29968b2016-01-20 11:17:23 -05002585bool ValidateBlitFramebufferANGLE(Context *context,
2586 GLint srcX0,
2587 GLint srcY0,
2588 GLint srcX1,
2589 GLint srcY1,
2590 GLint dstX0,
2591 GLint dstY0,
2592 GLint dstX1,
2593 GLint dstY1,
2594 GLbitfield mask,
2595 GLenum filter)
2596{
2597 if (!context->getExtensions().framebufferBlit)
2598 {
Jamie Madille0472f32018-11-27 16:32:45 -05002599 context->validationError(GL_INVALID_OPERATION, kBlitExtensionNotAvailable);
Jamie Madillc29968b2016-01-20 11:17:23 -05002600 return false;
2601 }
2602
2603 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2604 {
2605 // TODO(jmadill): Determine if this should be available on other implementations.
Jamie Madille0472f32018-11-27 16:32:45 -05002606 context->validationError(GL_INVALID_OPERATION, kBlitExtensionScaleOrFlip);
Jamie Madillc29968b2016-01-20 11:17:23 -05002607 return false;
2608 }
2609
2610 if (filter == GL_LINEAR)
2611 {
Jamie Madille0472f32018-11-27 16:32:45 -05002612 context->validationError(GL_INVALID_ENUM, kBlitExtensionLinear);
Jamie Madillc29968b2016-01-20 11:17:23 -05002613 return false;
2614 }
2615
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002616 Framebuffer *readFramebuffer = context->getState().getReadFramebuffer();
2617 Framebuffer *drawFramebuffer = context->getState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002618
2619 if (mask & GL_COLOR_BUFFER_BIT)
2620 {
2621 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2622 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2623
2624 if (readColorAttachment && drawColorAttachment)
2625 {
2626 if (!(readColorAttachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002627 readColorAttachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002628 readColorAttachment->type() != GL_RENDERBUFFER &&
2629 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2630 {
Jamie Madill610640f2018-11-21 17:28:41 -05002631 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002632 kBlitExtensionFromInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002633 return false;
2634 }
2635
Geoff Langa15472a2015-08-11 11:48:03 -04002636 for (size_t drawbufferIdx = 0;
2637 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002638 {
Geoff Langa15472a2015-08-11 11:48:03 -04002639 const FramebufferAttachment *attachment =
2640 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2641 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002642 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002643 if (!(attachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002644 attachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002645 attachment->type() != GL_RENDERBUFFER &&
2646 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2647 {
Jamie Madill610640f2018-11-21 17:28:41 -05002648 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002649 kBlitExtensionToInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002650 return false;
2651 }
2652
2653 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002654 if (!Format::EquivalentForBlit(attachment->getFormat(),
2655 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002656 {
Jamie Madill610640f2018-11-21 17:28:41 -05002657 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002658 kBlitExtensionFormatMismatch);
Jamie Madillc29968b2016-01-20 11:17:23 -05002659 return false;
2660 }
2661 }
2662 }
2663
Jamie Madill427064d2018-04-13 16:20:34 -04002664 GLint samples = readFramebuffer->getSamples(context);
Jamie Madille98b1b52018-03-08 09:47:23 -05002665 if (samples != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002666 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2667 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2668 {
Jamie Madill610640f2018-11-21 17:28:41 -05002669 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002670 kBlitExtensionMultisampledWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002671 return false;
2672 }
2673 }
2674 }
2675
2676 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2677 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2678 for (size_t i = 0; i < 2; i++)
2679 {
2680 if (mask & masks[i])
2681 {
2682 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002683 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002684 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002685 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002686
2687 if (readBuffer && drawBuffer)
2688 {
2689 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2690 dstX0, dstY0, dstX1, dstY1))
2691 {
2692 // only whole-buffer copies are permitted
Jamie Madill610640f2018-11-21 17:28:41 -05002693 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002694 kBlitExtensionDepthStencilWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002695 return false;
2696 }
2697
2698 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2699 {
Jamie Madill610640f2018-11-21 17:28:41 -05002700 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002701 kBlitExtensionMultisampledDepthOrStencil);
Jamie Madillc29968b2016-01-20 11:17:23 -05002702 return false;
2703 }
2704 }
2705 }
2706 }
2707
2708 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2709 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002710}
Jamie Madillc29968b2016-01-20 11:17:23 -05002711
Jamie Madill5b772312018-03-08 20:28:32 -05002712bool ValidateClear(Context *context, GLbitfield mask)
Jamie Madillc29968b2016-01-20 11:17:23 -05002713{
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002714 Framebuffer *fbo = context->getState().getDrawFramebuffer();
Olli Etuaho94c91a92018-07-19 15:10:24 +03002715 const Extensions &extensions = context->getExtensions();
Jamie Madille98b1b52018-03-08 09:47:23 -05002716
Jamie Madill427064d2018-04-13 16:20:34 -04002717 if (!ValidateFramebufferComplete(context, fbo))
Jamie Madillc29968b2016-01-20 11:17:23 -05002718 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002719 return false;
2720 }
2721
2722 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2723 {
Jamie Madille0472f32018-11-27 16:32:45 -05002724 context->validationError(GL_INVALID_VALUE, kInvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002725 return false;
2726 }
2727
Olli Etuaho94c91a92018-07-19 15:10:24 +03002728 if (extensions.webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
Geoff Lang76e65652017-03-27 14:58:02 -04002729 {
2730 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2731 GL_SIGNED_NORMALIZED};
2732
Corentin Wallez59c41592017-07-11 13:19:54 -04002733 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002734 drawBufferIdx++)
2735 {
2736 if (!ValidateWebGLFramebufferAttachmentClearType(
2737 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2738 {
2739 return false;
2740 }
2741 }
2742 }
2743
Mingyu Huebab6702019-04-19 14:36:45 -07002744 if ((extensions.multiview || extensions.multiview2) && extensions.disjointTimerQuery)
Olli Etuaho94c91a92018-07-19 15:10:24 +03002745 {
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002746 const State &state = context->getState();
Olli Etuaho94c91a92018-07-19 15:10:24 +03002747 Framebuffer *framebuffer = state.getDrawFramebuffer();
2748 if (framebuffer->getNumViews() > 1 && state.isQueryActive(QueryType::TimeElapsed))
2749 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002750 context->validationError(GL_INVALID_OPERATION, kMultiviewTimerQuery);
Olli Etuaho94c91a92018-07-19 15:10:24 +03002751 return false;
2752 }
2753 }
2754
Jamie Madillc29968b2016-01-20 11:17:23 -05002755 return true;
2756}
2757
Jamie Madill5b772312018-03-08 20:28:32 -05002758bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002759{
2760 if (!context->getExtensions().drawBuffers)
2761 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002762 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05002763 return false;
2764 }
2765
2766 return ValidateDrawBuffersBase(context, n, bufs);
2767}
2768
Jamie Madill73a84962016-02-12 09:27:23 -05002769bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002770 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002771 GLint level,
2772 GLint internalformat,
2773 GLsizei width,
2774 GLsizei height,
2775 GLint border,
2776 GLenum format,
2777 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002778 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002779{
Martin Radev1be913c2016-07-11 17:59:16 +03002780 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002781 {
2782 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002783 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002784 }
2785
Martin Radev1be913c2016-07-11 17:59:16 +03002786 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002787 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002788 0, 0, width, height, 1, border, format, type, -1,
2789 pixels);
2790}
2791
Brandon Jones416aaf92018-04-10 08:10:16 -07002792bool ValidateTexImage2DRobustANGLE(Context *context,
2793 TextureTarget target,
2794 GLint level,
2795 GLint internalformat,
2796 GLsizei width,
2797 GLsizei height,
2798 GLint border,
2799 GLenum format,
2800 GLenum type,
2801 GLsizei bufSize,
2802 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002803{
2804 if (!ValidateRobustEntryPoint(context, bufSize))
2805 {
2806 return false;
2807 }
2808
2809 if (context->getClientMajorVersion() < 3)
2810 {
2811 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2812 0, 0, width, height, border, format, type, bufSize,
2813 pixels);
2814 }
2815
2816 ASSERT(context->getClientMajorVersion() >= 3);
2817 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2818 0, 0, width, height, 1, border, format, type, bufSize,
2819 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002820}
2821
2822bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002823 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002824 GLint level,
2825 GLint xoffset,
2826 GLint yoffset,
2827 GLsizei width,
2828 GLsizei height,
2829 GLenum format,
2830 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002831 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002832{
2833
Martin Radev1be913c2016-07-11 17:59:16 +03002834 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002835 {
2836 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002837 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002838 }
2839
Martin Radev1be913c2016-07-11 17:59:16 +03002840 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002841 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002842 yoffset, 0, width, height, 1, 0, format, type, -1,
2843 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002844}
2845
Geoff Langc52f6f12016-10-14 10:18:00 -04002846bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002847 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002848 GLint level,
2849 GLint xoffset,
2850 GLint yoffset,
2851 GLsizei width,
2852 GLsizei height,
2853 GLenum format,
2854 GLenum type,
2855 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002856 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002857{
2858 if (!ValidateRobustEntryPoint(context, bufSize))
2859 {
2860 return false;
2861 }
2862
2863 if (context->getClientMajorVersion() < 3)
2864 {
2865 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2866 yoffset, width, height, 0, format, type, bufSize,
2867 pixels);
2868 }
2869
2870 ASSERT(context->getClientMajorVersion() >= 3);
2871 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2872 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2873 pixels);
2874}
2875
Jamie Madill73a84962016-02-12 09:27:23 -05002876bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002877 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002878 GLint level,
2879 GLenum internalformat,
2880 GLsizei width,
2881 GLsizei height,
2882 GLint border,
2883 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002884 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002885{
Martin Radev1be913c2016-07-11 17:59:16 +03002886 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002887 {
2888 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002889 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002890 {
2891 return false;
2892 }
2893 }
2894 else
2895 {
Martin Radev1be913c2016-07-11 17:59:16 +03002896 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002897 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002898 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002899 data))
2900 {
2901 return false;
2902 }
2903 }
2904
Geoff Langca271392017-04-05 12:30:00 -04002905 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jamie Madillca2ff382018-07-11 09:01:17 -04002906
2907 GLuint blockSize = 0;
2908 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002909 {
Jamie Madille0472f32018-11-27 16:32:45 -05002910 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002911 return false;
2912 }
2913
Jamie Madillca2ff382018-07-11 09:01:17 -04002914 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002915 {
Jamie Madille0472f32018-11-27 16:32:45 -05002916 context->validationError(GL_INVALID_VALUE, kCompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002917 return false;
2918 }
2919
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002920 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002921 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002922 context->validationError(GL_INVALID_ENUM, kRectangleTextureCompressed);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002923 return false;
2924 }
2925
Jamie Madill73a84962016-02-12 09:27:23 -05002926 return true;
2927}
2928
Corentin Wallezb2931602017-04-11 15:58:57 -04002929bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002930 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002931 GLint level,
2932 GLenum internalformat,
2933 GLsizei width,
2934 GLsizei height,
2935 GLint border,
2936 GLsizei imageSize,
2937 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002938 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002939{
2940 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2941 {
2942 return false;
2943 }
2944
2945 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2946 border, imageSize, data);
2947}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002948
Corentin Wallezb2931602017-04-11 15:58:57 -04002949bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002950 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002951 GLint level,
2952 GLint xoffset,
2953 GLint yoffset,
2954 GLsizei width,
2955 GLsizei height,
2956 GLenum format,
2957 GLsizei imageSize,
2958 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002959 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002960{
2961 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2962 {
2963 return false;
2964 }
2965
2966 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2967 format, imageSize, data);
2968}
2969
Jamie Madill73a84962016-02-12 09:27:23 -05002970bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002971 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002972 GLint level,
2973 GLint xoffset,
2974 GLint yoffset,
2975 GLsizei width,
2976 GLsizei height,
2977 GLenum format,
2978 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002979 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002980{
Martin Radev1be913c2016-07-11 17:59:16 +03002981 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002982 {
2983 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002984 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002985 {
2986 return false;
2987 }
2988 }
2989 else
2990 {
Martin Radev1be913c2016-07-11 17:59:16 +03002991 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002992 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002993 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002994 data))
2995 {
2996 return false;
2997 }
2998 }
2999
Geoff Langca271392017-04-05 12:30:00 -04003000 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jamie Madillca2ff382018-07-11 09:01:17 -04003001 GLuint blockSize = 0;
3002 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04003003 {
Jamie Madille0472f32018-11-27 16:32:45 -05003004 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04003005 return false;
3006 }
3007
Jamie Madillca2ff382018-07-11 09:01:17 -04003008 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05003009 {
Jamie Madille0472f32018-11-27 16:32:45 -05003010 context->validationError(GL_INVALID_VALUE, kInvalidCompressedImageSize);
Jamie Madill73a84962016-02-12 09:27:23 -05003011 return false;
3012 }
3013
3014 return true;
3015}
3016
Corentin Wallez336129f2017-10-17 15:55:40 -04003017bool ValidateGetBufferPointervOES(Context *context,
3018 BufferBinding target,
3019 GLenum pname,
3020 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003021{
Jamie Madillc3e37312018-11-30 15:25:39 -05003022 if (!context->getExtensions().mapBuffer)
3023 {
3024 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3025 return false;
3026 }
3027
Geoff Lang496c02d2016-10-20 11:38:11 -07003028 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003029}
3030
Corentin Wallez336129f2017-10-17 15:55:40 -04003031bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003032{
3033 if (!context->getExtensions().mapBuffer)
3034 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003035 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03003036 return false;
3037 }
3038
Corentin Walleze4477002017-12-01 14:39:58 -05003039 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003040 {
Jamie Madille0472f32018-11-27 16:32:45 -05003041 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003042 return false;
3043 }
3044
Jamie Madillc3dc5d42018-12-30 12:12:04 -05003045 Buffer *buffer = context->getState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003046
3047 if (buffer == nullptr)
3048 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003049 context->validationError(GL_INVALID_OPERATION, kBufferNotMappable);
Olli Etuaho4f667482016-03-30 15:56:35 +03003050 return false;
3051 }
3052
3053 if (access != GL_WRITE_ONLY_OES)
3054 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003055 context->validationError(GL_INVALID_ENUM, kInvalidAccessBits);
Olli Etuaho4f667482016-03-30 15:56:35 +03003056 return false;
3057 }
3058
3059 if (buffer->isMapped())
3060 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003061 context->validationError(GL_INVALID_OPERATION, kBufferAlreadyMapped);
Olli Etuaho4f667482016-03-30 15:56:35 +03003062 return false;
3063 }
3064
Geoff Lang79f71042017-08-14 16:43:43 -04003065 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003066}
3067
Corentin Wallez336129f2017-10-17 15:55:40 -04003068bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03003069{
3070 if (!context->getExtensions().mapBuffer)
3071 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003072 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03003073 return false;
3074 }
3075
3076 return ValidateUnmapBufferBase(context, target);
3077}
3078
3079bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003080 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003081 GLintptr offset,
3082 GLsizeiptr length,
3083 GLbitfield access)
3084{
3085 if (!context->getExtensions().mapBufferRange)
3086 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003087 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03003088 return false;
3089 }
3090
3091 return ValidateMapBufferRangeBase(context, target, offset, length, access);
3092}
3093
Michael Spang7a8c3e52019-04-03 14:49:57 -04003094bool ValidateBufferStorageMemEXT(Context *context,
3095 TextureType target,
3096 GLsizeiptr size,
3097 GLuint memory,
3098 GLuint64 offset)
3099{
3100 if (!context->getExtensions().memoryObject)
3101 {
3102 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3103 return false;
3104 }
3105
3106 UNIMPLEMENTED();
3107 return false;
3108}
3109
3110bool ValidateCreateMemoryObjectsEXT(Context *context, GLsizei n, GLuint *memoryObjects)
3111{
3112 if (!context->getExtensions().memoryObject)
3113 {
3114 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3115 return false;
3116 }
3117
Michael Spangfb201c52019-04-03 14:57:35 -04003118 return ValidateGenOrDelete(context, n);
Michael Spang7a8c3e52019-04-03 14:49:57 -04003119}
3120
3121bool ValidateDeleteMemoryObjectsEXT(Context *context, GLsizei n, const GLuint *memoryObjects)
3122{
3123 if (!context->getExtensions().memoryObject)
3124 {
3125 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3126 return false;
3127 }
3128
Michael Spangfb201c52019-04-03 14:57:35 -04003129 return ValidateGenOrDelete(context, n);
Michael Spang7a8c3e52019-04-03 14:49:57 -04003130}
3131
3132bool ValidateGetMemoryObjectParameterivEXT(Context *context,
3133 GLuint memoryObject,
3134 GLenum pname,
3135 GLint *params)
3136{
3137 if (!context->getExtensions().memoryObject)
3138 {
3139 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3140 return false;
3141 }
3142
3143 UNIMPLEMENTED();
3144 return false;
3145}
3146
3147bool ValidateGetUnsignedBytevEXT(Context *context, GLenum pname, GLubyte *data)
3148{
3149 if (!context->getExtensions().memoryObject && !context->getExtensions().semaphore)
3150 {
3151 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3152 return false;
3153 }
3154
3155 UNIMPLEMENTED();
3156 return false;
3157}
3158
3159bool ValidateGetUnsignedBytei_vEXT(Context *context, GLenum target, GLuint index, GLubyte *data)
3160{
3161 if (!context->getExtensions().memoryObject && !context->getExtensions().semaphore)
3162 {
3163 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3164 return false;
3165 }
3166
3167 UNIMPLEMENTED();
3168 return false;
3169}
3170
3171bool ValidateIsMemoryObjectEXT(Context *context, GLuint memoryObject)
3172{
3173 if (!context->getExtensions().memoryObject)
3174 {
3175 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3176 return false;
3177 }
3178
Michael Spangfb201c52019-04-03 14:57:35 -04003179 return true;
Michael Spang7a8c3e52019-04-03 14:49:57 -04003180}
3181
3182bool ValidateMemoryObjectParameterivEXT(Context *context,
3183 GLuint memoryObject,
3184 GLenum pname,
3185 const GLint *params)
3186{
3187 if (!context->getExtensions().memoryObject)
3188 {
3189 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3190 return false;
3191 }
3192
3193 UNIMPLEMENTED();
3194 return false;
3195}
3196
3197bool ValidateTexStorageMem2DEXT(Context *context,
3198 TextureType target,
3199 GLsizei levels,
3200 GLenum internalFormat,
3201 GLsizei width,
3202 GLsizei height,
3203 GLuint memory,
3204 GLuint64 offset)
3205{
3206 if (!context->getExtensions().memoryObject)
3207 {
3208 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3209 return false;
3210 }
3211
Michael Spangf02a7672019-04-09 18:45:23 -04003212 if (context->getClientMajorVersion() < 3)
3213 {
3214 return ValidateES2TexStorageParameters(context, target, levels, internalFormat, width,
3215 height);
3216 }
3217
3218 ASSERT(context->getClientMajorVersion() >= 3);
3219 return ValidateES3TexStorage2DParameters(context, target, levels, internalFormat, width, height,
3220 1);
Michael Spang7a8c3e52019-04-03 14:49:57 -04003221}
3222
3223bool ValidateTexStorageMem3DEXT(Context *context,
3224 TextureType target,
3225 GLsizei levels,
3226 GLenum internalFormat,
3227 GLsizei width,
3228 GLsizei height,
3229 GLsizei depth,
3230 GLuint memory,
3231 GLuint64 offset)
3232{
3233 if (!context->getExtensions().memoryObject)
3234 {
3235 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3236 return false;
3237 }
3238
3239 UNIMPLEMENTED();
3240 return false;
3241}
3242
Michael Spang9de3ddb2019-04-03 16:23:40 -04003243bool ValidateImportMemoryFdEXT(Context *context,
3244 GLuint memory,
3245 GLuint64 size,
Michael Spange0da9ce2019-04-16 14:34:51 -04003246 HandleType handleType,
Michael Spang9de3ddb2019-04-03 16:23:40 -04003247 GLint fd)
3248{
3249 if (!context->getExtensions().memoryObjectFd)
3250 {
3251 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3252 return false;
3253 }
3254
Michael Spang3b2c6bf2019-04-16 17:19:50 -04003255 switch (handleType)
3256 {
3257 case HandleType::OpaqueFd:
3258 break;
3259 default:
3260 context->validationError(GL_INVALID_ENUM, kInvalidHandleType);
3261 return false;
3262 }
3263
3264 return true;
Michael Spang9de3ddb2019-04-03 16:23:40 -04003265}
3266
Michael Spang7a8c3e52019-04-03 14:49:57 -04003267bool ValidateDeleteSemaphoresEXT(Context *context, GLsizei n, const GLuint *semaphores)
3268{
3269 if (!context->getExtensions().semaphore)
3270 {
3271 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3272 return false;
3273 }
3274
3275 UNIMPLEMENTED();
3276 return false;
3277}
3278
3279bool ValidateGenSemaphoresEXT(Context *context, GLsizei n, GLuint *semaphores)
3280{
3281 if (!context->getExtensions().semaphore)
3282 {
3283 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3284 return false;
3285 }
3286
3287 UNIMPLEMENTED();
3288 return false;
3289}
3290
3291bool ValidateGetSemaphoreParameterui64vEXT(Context *context,
3292 GLuint semaphore,
3293 GLenum pname,
3294 GLuint64 *params)
3295{
3296 if (!context->getExtensions().semaphore)
3297 {
3298 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3299 return false;
3300 }
3301
3302 UNIMPLEMENTED();
3303 return false;
3304}
3305
3306bool ValidateIsSemaphoreEXT(Context *context, GLuint semaphore)
3307{
3308 if (!context->getExtensions().semaphore)
3309 {
3310 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3311 return false;
3312 }
3313
3314 UNIMPLEMENTED();
3315 return false;
3316}
3317
3318bool ValidateSemaphoreParameterui64vEXT(Context *context,
3319 GLuint semaphore,
3320 GLenum pname,
3321 const GLuint64 *params)
3322{
3323 if (!context->getExtensions().semaphore)
3324 {
3325 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3326 return false;
3327 }
3328
3329 UNIMPLEMENTED();
3330 return false;
3331}
3332
3333bool ValidateSignalSemaphoreEXT(Context *context,
3334 GLuint semaphore,
3335 GLuint numBufferBarriers,
3336 const GLuint *buffers,
3337 GLuint numTextureBarriers,
3338 const GLuint *textures,
3339 const GLenum *dstLayouts)
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 ValidateWaitSemaphoreEXT(Context *context,
3352 GLuint semaphore,
3353 GLuint numBufferBarriers,
3354 const GLuint *buffers,
3355 GLuint numTextureBarriers,
3356 const GLuint *textures,
3357 const GLenum *srcLayouts)
3358{
3359 if (!context->getExtensions().semaphore)
3360 {
3361 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3362 return false;
3363 }
3364
3365 UNIMPLEMENTED();
3366 return false;
3367}
3368
Michael Spange0da9ce2019-04-16 14:34:51 -04003369bool ValidateImportSemaphoreFdEXT(Context *context,
3370 GLuint semaphore,
3371 HandleType handleType,
3372 GLint fd)
Michael Spang9de3ddb2019-04-03 16:23:40 -04003373{
3374 if (!context->getExtensions().semaphoreFd)
3375 {
3376 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3377 return false;
3378 }
3379
3380 UNIMPLEMENTED();
3381 return false;
3382}
3383
Corentin Wallez336129f2017-10-17 15:55:40 -04003384bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04003385{
Jamie Madillc3dc5d42018-12-30 12:12:04 -05003386 Buffer *buffer = context->getState().getTargetBuffer(target);
Geoff Lang79f71042017-08-14 16:43:43 -04003387 ASSERT(buffer != nullptr);
3388
3389 // Check if this buffer is currently being used as a transform feedback output buffer
Jamie Madillc3dc5d42018-12-30 12:12:04 -05003390 TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
Geoff Lang79f71042017-08-14 16:43:43 -04003391 if (transformFeedback != nullptr && transformFeedback->isActive())
3392 {
3393 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
3394 {
3395 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
3396 if (transformFeedbackBuffer.get() == buffer)
3397 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003398 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
Geoff Lang79f71042017-08-14 16:43:43 -04003399 return false;
3400 }
3401 }
3402 }
3403
James Darpiniane8a93c62018-01-04 18:02:24 -08003404 if (context->getExtensions().webglCompatibility &&
3405 buffer->isBoundForTransformFeedbackAndOtherUse())
3406 {
Jamie Madille0472f32018-11-27 16:32:45 -05003407 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08003408 return false;
3409 }
3410
Geoff Lang79f71042017-08-14 16:43:43 -04003411 return true;
3412}
3413
Olli Etuaho4f667482016-03-30 15:56:35 +03003414bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003415 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003416 GLintptr offset,
3417 GLsizeiptr length)
3418{
3419 if (!context->getExtensions().mapBufferRange)
3420 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003421 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03003422 return false;
3423 }
3424
3425 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
3426}
3427
Geoff Langd8605522016-04-13 10:19:12 -04003428bool ValidateBindUniformLocationCHROMIUM(Context *context,
3429 GLuint program,
3430 GLint location,
3431 const GLchar *name)
3432{
3433 if (!context->getExtensions().bindUniformLocation)
3434 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003435 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langd8605522016-04-13 10:19:12 -04003436 return false;
3437 }
3438
3439 Program *programObject = GetValidProgram(context, program);
3440 if (!programObject)
3441 {
3442 return false;
3443 }
3444
3445 if (location < 0)
3446 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003447 context->validationError(GL_INVALID_VALUE, kNegativeLocation);
Geoff Langd8605522016-04-13 10:19:12 -04003448 return false;
3449 }
3450
3451 const Caps &caps = context->getCaps();
3452 if (static_cast<size_t>(location) >=
3453 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3454 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003455 context->validationError(GL_INVALID_VALUE, kInvalidBindUniformLocation);
Geoff Langd8605522016-04-13 10:19:12 -04003456 return false;
3457 }
3458
Geoff Langfc32e8b2017-05-31 14:16:59 -04003459 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3460 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003461 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003462 {
Jamie Madille0472f32018-11-27 16:32:45 -05003463 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003464 return false;
3465 }
3466
Geoff Langd8605522016-04-13 10:19:12 -04003467 if (strncmp(name, "gl_", 3) == 0)
3468 {
Jamie Madille0472f32018-11-27 16:32:45 -05003469 context->validationError(GL_INVALID_VALUE, kNameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003470 return false;
3471 }
3472
3473 return true;
3474}
3475
Jamie Madille2e406c2016-06-02 13:04:10 -04003476bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003477{
3478 if (!context->getExtensions().framebufferMixedSamples)
3479 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003480 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänena797e062016-05-12 15:23:40 +03003481 return false;
3482 }
3483 switch (components)
3484 {
3485 case GL_RGB:
3486 case GL_RGBA:
3487 case GL_ALPHA:
3488 case GL_NONE:
3489 break;
3490 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003491 context->validationError(GL_INVALID_ENUM, kInvalidCoverageComponents);
Sami Väisänena797e062016-05-12 15:23:40 +03003492 return false;
3493 }
3494
3495 return true;
3496}
3497
Sami Väisänene45e53b2016-05-25 10:36:04 +03003498// CHROMIUM_path_rendering
3499
Jamie Madill007530e2017-12-28 14:27:04 -05003500bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003501{
Jamie Madill007530e2017-12-28 14:27:04 -05003502 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003503 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003504 return false;
3505 }
Jamie Madill007530e2017-12-28 14:27:04 -05003506
Sami Väisänene45e53b2016-05-25 10:36:04 +03003507 if (matrix == nullptr)
3508 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003509 context->validationError(GL_INVALID_OPERATION, kInvalidPathMatrix);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003510 return false;
3511 }
Jamie Madill007530e2017-12-28 14:27:04 -05003512
Sami Väisänene45e53b2016-05-25 10:36:04 +03003513 return true;
3514}
3515
Jamie Madill007530e2017-12-28 14:27:04 -05003516bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003517{
Jamie Madill007530e2017-12-28 14:27:04 -05003518 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003519}
3520
Jamie Madill007530e2017-12-28 14:27:04 -05003521bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003522{
3523 if (!context->getExtensions().pathRendering)
3524 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003525 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003526 return false;
3527 }
3528
3529 // range = 0 is undefined in NV_path_rendering.
3530 // we add stricter semantic check here and require a non zero positive range.
3531 if (range <= 0)
3532 {
Jamie Madille0472f32018-11-27 16:32:45 -05003533 context->validationError(GL_INVALID_VALUE, kInvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003534 return false;
3535 }
3536
3537 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3538 {
Jamie Madille0472f32018-11-27 16:32:45 -05003539 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003540 return false;
3541 }
3542
3543 return true;
3544}
3545
Jamie Madill007530e2017-12-28 14:27:04 -05003546bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003547{
3548 if (!context->getExtensions().pathRendering)
3549 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003550 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003551 return false;
3552 }
3553
3554 // range = 0 is undefined in NV_path_rendering.
3555 // we add stricter semantic check here and require a non zero positive range.
3556 if (range <= 0)
3557 {
Jamie Madille0472f32018-11-27 16:32:45 -05003558 context->validationError(GL_INVALID_VALUE, kInvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003559 return false;
3560 }
3561
3562 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3563 checkedRange += range;
3564
3565 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3566 {
Jamie Madille0472f32018-11-27 16:32:45 -05003567 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003568 return false;
3569 }
3570 return true;
3571}
3572
Jamie Madill007530e2017-12-28 14:27:04 -05003573bool ValidatePathCommandsCHROMIUM(Context *context,
3574 GLuint path,
3575 GLsizei numCommands,
3576 const GLubyte *commands,
3577 GLsizei numCoords,
3578 GLenum coordType,
3579 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003580{
3581 if (!context->getExtensions().pathRendering)
3582 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003583 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003584 return false;
3585 }
Brandon Jones59770802018-04-02 13:18:42 -07003586 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003587 {
Jamie Madille0472f32018-11-27 16:32:45 -05003588 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003589 return false;
3590 }
3591
3592 if (numCommands < 0)
3593 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003594 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCommands);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003595 return false;
3596 }
3597 else if (numCommands > 0)
3598 {
3599 if (!commands)
3600 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003601 context->validationError(GL_INVALID_VALUE, kInvalidPathCommandsArray);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003602 return false;
3603 }
3604 }
3605
3606 if (numCoords < 0)
3607 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003608 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCoords);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003609 return false;
3610 }
3611 else if (numCoords > 0)
3612 {
3613 if (!coords)
3614 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003615 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCoordsArray);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003616 return false;
3617 }
3618 }
3619
3620 std::uint32_t coordTypeSize = 0;
3621 switch (coordType)
3622 {
3623 case GL_BYTE:
3624 coordTypeSize = sizeof(GLbyte);
3625 break;
3626
3627 case GL_UNSIGNED_BYTE:
3628 coordTypeSize = sizeof(GLubyte);
3629 break;
3630
3631 case GL_SHORT:
3632 coordTypeSize = sizeof(GLshort);
3633 break;
3634
3635 case GL_UNSIGNED_SHORT:
3636 coordTypeSize = sizeof(GLushort);
3637 break;
3638
3639 case GL_FLOAT:
3640 coordTypeSize = sizeof(GLfloat);
3641 break;
3642
3643 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003644 context->validationError(GL_INVALID_ENUM, kInvalidPathCoordinateType);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003645 return false;
3646 }
3647
3648 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3649 checkedSize += (coordTypeSize * numCoords);
3650 if (!checkedSize.IsValid())
3651 {
Jamie Madille0472f32018-11-27 16:32:45 -05003652 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003653 return false;
3654 }
3655
3656 // early return skips command data validation when it doesn't exist.
3657 if (!commands)
3658 return true;
3659
3660 GLsizei expectedNumCoords = 0;
3661 for (GLsizei i = 0; i < numCommands; ++i)
3662 {
3663 switch (commands[i])
3664 {
3665 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3666 break;
3667 case GL_MOVE_TO_CHROMIUM:
3668 case GL_LINE_TO_CHROMIUM:
3669 expectedNumCoords += 2;
3670 break;
3671 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3672 expectedNumCoords += 4;
3673 break;
3674 case GL_CUBIC_CURVE_TO_CHROMIUM:
3675 expectedNumCoords += 6;
3676 break;
3677 case GL_CONIC_CURVE_TO_CHROMIUM:
3678 expectedNumCoords += 5;
3679 break;
3680 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003681 context->validationError(GL_INVALID_ENUM, kInvalidPathCommand);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003682 return false;
3683 }
3684 }
Jamie Madillc3e37312018-11-30 15:25:39 -05003685
Sami Väisänene45e53b2016-05-25 10:36:04 +03003686 if (expectedNumCoords != numCoords)
3687 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003688 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCoords);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003689 return false;
3690 }
3691
3692 return true;
3693}
3694
Jamie Madill007530e2017-12-28 14:27:04 -05003695bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003696{
3697 if (!context->getExtensions().pathRendering)
3698 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003699 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003700 return false;
3701 }
Brandon Jones59770802018-04-02 13:18:42 -07003702 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003703 {
Jamie Madille0472f32018-11-27 16:32:45 -05003704 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003705 return false;
3706 }
3707
3708 switch (pname)
3709 {
3710 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3711 if (value < 0.0f)
3712 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003713 context->validationError(GL_INVALID_VALUE, kInvalidPathStrokeWidth);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003714 return false;
3715 }
3716 break;
3717 case GL_PATH_END_CAPS_CHROMIUM:
3718 switch (static_cast<GLenum>(value))
3719 {
3720 case GL_FLAT_CHROMIUM:
3721 case GL_SQUARE_CHROMIUM:
3722 case GL_ROUND_CHROMIUM:
3723 break;
3724 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003725 context->validationError(GL_INVALID_ENUM, kInvalidPathEndCaps);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003726 return false;
3727 }
3728 break;
3729 case GL_PATH_JOIN_STYLE_CHROMIUM:
3730 switch (static_cast<GLenum>(value))
3731 {
3732 case GL_MITER_REVERT_CHROMIUM:
3733 case GL_BEVEL_CHROMIUM:
3734 case GL_ROUND_CHROMIUM:
3735 break;
3736 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003737 context->validationError(GL_INVALID_ENUM, kInvalidPathJoinStyle);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003738 return false;
3739 }
Nico Weber41b072b2018-02-09 10:01:32 -05003740 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003741 case GL_PATH_MITER_LIMIT_CHROMIUM:
3742 if (value < 0.0f)
3743 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003744 context->validationError(GL_INVALID_VALUE, kInvalidPathMiterLimit);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003745 return false;
3746 }
3747 break;
3748
3749 case GL_PATH_STROKE_BOUND_CHROMIUM:
3750 // no errors, only clamping.
3751 break;
3752
3753 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003754 context->validationError(GL_INVALID_ENUM, kInvalidPathParameter);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003755 return false;
3756 }
3757 return true;
3758}
3759
Jamie Madill007530e2017-12-28 14:27:04 -05003760bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3761{
3762 // TODO(jmadill): Use proper clamping cast.
3763 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3764}
3765
3766bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003767{
3768 if (!context->getExtensions().pathRendering)
3769 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003770 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003771 return false;
3772 }
3773
Brandon Jones59770802018-04-02 13:18:42 -07003774 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003775 {
Jamie Madille0472f32018-11-27 16:32:45 -05003776 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003777 return false;
3778 }
Jamie Madillc3e37312018-11-30 15:25:39 -05003779
Sami Väisänene45e53b2016-05-25 10:36:04 +03003780 if (!value)
3781 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003782 context->validationError(GL_INVALID_VALUE, kInvalidPathValueArray);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003783 return false;
3784 }
3785
3786 switch (pname)
3787 {
3788 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3789 case GL_PATH_END_CAPS_CHROMIUM:
3790 case GL_PATH_JOIN_STYLE_CHROMIUM:
3791 case GL_PATH_MITER_LIMIT_CHROMIUM:
3792 case GL_PATH_STROKE_BOUND_CHROMIUM:
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
3800 return true;
3801}
3802
Jamie Madill007530e2017-12-28 14:27:04 -05003803bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3804{
3805 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3806 reinterpret_cast<GLfloat *>(value));
3807}
3808
3809bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003810{
3811 if (!context->getExtensions().pathRendering)
3812 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003813 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003814 return false;
3815 }
3816
3817 switch (func)
3818 {
3819 case GL_NEVER:
3820 case GL_ALWAYS:
3821 case GL_LESS:
3822 case GL_LEQUAL:
3823 case GL_EQUAL:
3824 case GL_GEQUAL:
3825 case GL_GREATER:
3826 case GL_NOTEQUAL:
3827 break;
3828 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003829 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003830 return false;
3831 }
3832
3833 return true;
3834}
3835
3836// Note that the spec specifies that for the path drawing commands
3837// if the path object is not an existing path object the command
3838// does nothing and no error is generated.
3839// However if the path object exists but has not been specified any
3840// commands then an error is generated.
3841
Jamie Madill007530e2017-12-28 14:27:04 -05003842bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003843{
3844 if (!context->getExtensions().pathRendering)
3845 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003846 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003847 return false;
3848 }
Brandon Jones59770802018-04-02 13:18:42 -07003849 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003850 {
Jamie Madille0472f32018-11-27 16:32:45 -05003851 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003852 return false;
3853 }
3854
3855 switch (fillMode)
3856 {
3857 case GL_COUNT_UP_CHROMIUM:
3858 case GL_COUNT_DOWN_CHROMIUM:
3859 break;
3860 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003861 context->validationError(GL_INVALID_ENUM, kInvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003862 return false;
3863 }
3864
3865 if (!isPow2(mask + 1))
3866 {
Jamie Madille0472f32018-11-27 16:32:45 -05003867 context->validationError(GL_INVALID_VALUE, kInvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003868 return false;
3869 }
3870
3871 return true;
3872}
3873
Jamie Madill007530e2017-12-28 14:27:04 -05003874bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003875{
3876 if (!context->getExtensions().pathRendering)
3877 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003878 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003879 return false;
3880 }
Jamie Madillc3e37312018-11-30 15:25:39 -05003881
Brandon Jones59770802018-04-02 13:18:42 -07003882 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003883 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003884 context->validationError(GL_INVALID_OPERATION, kNoPathOrNoPathData);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003885 return false;
3886 }
3887
3888 return true;
3889}
3890
Jamie Madill007530e2017-12-28 14:27:04 -05003891bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003892{
3893 if (!context->getExtensions().pathRendering)
3894 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003895 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003896 return false;
3897 }
Brandon Jones59770802018-04-02 13:18:42 -07003898 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003899 {
Jamie Madille0472f32018-11-27 16:32:45 -05003900 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003901 return false;
3902 }
3903
3904 switch (coverMode)
3905 {
3906 case GL_CONVEX_HULL_CHROMIUM:
3907 case GL_BOUNDING_BOX_CHROMIUM:
3908 break;
3909 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003910 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003911 return false;
3912 }
3913 return true;
3914}
3915
Jamie Madill778bf092018-11-14 09:54:36 -05003916bool ValidateCoverFillPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3917{
3918 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3919}
3920
3921bool ValidateCoverStrokePathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3922{
3923 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3924}
3925
Jamie Madill007530e2017-12-28 14:27:04 -05003926bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3927 GLuint path,
3928 GLenum fillMode,
3929 GLuint mask,
3930 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003931{
Jamie Madill007530e2017-12-28 14:27:04 -05003932 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3933 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003934}
3935
Jamie Madill007530e2017-12-28 14:27:04 -05003936bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3937 GLuint path,
3938 GLint reference,
3939 GLuint mask,
3940 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003941{
Jamie Madill007530e2017-12-28 14:27:04 -05003942 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3943 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003944}
3945
Brandon Jonesd1049182018-03-28 10:02:20 -07003946bool ValidateIsPathCHROMIUM(Context *context, GLuint path)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003947{
3948 if (!context->getExtensions().pathRendering)
3949 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003950 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003951 return false;
3952 }
3953 return true;
3954}
3955
Jamie Madill007530e2017-12-28 14:27:04 -05003956bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3957 GLsizei numPaths,
3958 GLenum pathNameType,
3959 const void *paths,
3960 GLuint pathBase,
3961 GLenum coverMode,
3962 GLenum transformType,
3963 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003964{
3965 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3966 transformType, transformValues))
3967 return false;
3968
3969 switch (coverMode)
3970 {
3971 case GL_CONVEX_HULL_CHROMIUM:
3972 case GL_BOUNDING_BOX_CHROMIUM:
3973 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3974 break;
3975 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003976 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003977 return false;
3978 }
3979
3980 return true;
3981}
3982
Jamie Madill007530e2017-12-28 14:27:04 -05003983bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3984 GLsizei numPaths,
3985 GLenum pathNameType,
3986 const void *paths,
3987 GLuint pathBase,
3988 GLenum coverMode,
3989 GLenum transformType,
3990 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003991{
3992 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3993 transformType, transformValues))
3994 return false;
3995
3996 switch (coverMode)
3997 {
3998 case GL_CONVEX_HULL_CHROMIUM:
3999 case GL_BOUNDING_BOX_CHROMIUM:
4000 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
4001 break;
4002 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004003 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03004004 return false;
4005 }
4006
4007 return true;
4008}
4009
Jamie Madill007530e2017-12-28 14:27:04 -05004010bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
4011 GLsizei numPaths,
4012 GLenum pathNameType,
4013 const void *paths,
4014 GLuint pathBase,
4015 GLenum fillMode,
4016 GLuint mask,
4017 GLenum transformType,
4018 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03004019{
4020
4021 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
4022 transformType, transformValues))
4023 return false;
4024
4025 switch (fillMode)
4026 {
4027 case GL_COUNT_UP_CHROMIUM:
4028 case GL_COUNT_DOWN_CHROMIUM:
4029 break;
4030 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004031 context->validationError(GL_INVALID_ENUM, kInvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03004032 return false;
4033 }
4034 if (!isPow2(mask + 1))
4035 {
Jamie Madille0472f32018-11-27 16:32:45 -05004036 context->validationError(GL_INVALID_VALUE, kInvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03004037 return false;
4038 }
4039 return true;
4040}
4041
Jamie Madill007530e2017-12-28 14:27:04 -05004042bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
4043 GLsizei numPaths,
4044 GLenum pathNameType,
4045 const void *paths,
4046 GLuint pathBase,
4047 GLint reference,
4048 GLuint mask,
4049 GLenum transformType,
4050 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03004051{
4052 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
4053 transformType, transformValues))
4054 return false;
4055
4056 // no more validation here.
4057
4058 return true;
4059}
4060
Jamie Madill007530e2017-12-28 14:27:04 -05004061bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
4062 GLsizei numPaths,
4063 GLenum pathNameType,
4064 const void *paths,
4065 GLuint pathBase,
4066 GLenum fillMode,
4067 GLuint mask,
4068 GLenum coverMode,
4069 GLenum transformType,
4070 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03004071{
4072 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
4073 transformType, transformValues))
4074 return false;
4075
4076 switch (coverMode)
4077 {
4078 case GL_CONVEX_HULL_CHROMIUM:
4079 case GL_BOUNDING_BOX_CHROMIUM:
4080 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
4081 break;
4082 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004083 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03004084 return false;
4085 }
4086
4087 switch (fillMode)
4088 {
4089 case GL_COUNT_UP_CHROMIUM:
4090 case GL_COUNT_DOWN_CHROMIUM:
4091 break;
4092 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004093 context->validationError(GL_INVALID_ENUM, kInvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03004094 return false;
4095 }
4096 if (!isPow2(mask + 1))
4097 {
Jamie Madille0472f32018-11-27 16:32:45 -05004098 context->validationError(GL_INVALID_VALUE, kInvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03004099 return false;
4100 }
4101
4102 return true;
4103}
4104
Jamie Madill007530e2017-12-28 14:27:04 -05004105bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
4106 GLsizei numPaths,
4107 GLenum pathNameType,
4108 const void *paths,
4109 GLuint pathBase,
4110 GLint reference,
4111 GLuint mask,
4112 GLenum coverMode,
4113 GLenum transformType,
4114 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03004115{
4116 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
4117 transformType, transformValues))
4118 return false;
4119
4120 switch (coverMode)
4121 {
4122 case GL_CONVEX_HULL_CHROMIUM:
4123 case GL_BOUNDING_BOX_CHROMIUM:
4124 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
4125 break;
4126 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004127 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03004128 return false;
4129 }
4130
4131 return true;
4132}
4133
Jamie Madill007530e2017-12-28 14:27:04 -05004134bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
4135 GLuint program,
4136 GLint location,
4137 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03004138{
4139 if (!context->getExtensions().pathRendering)
4140 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004141 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004142 return false;
4143 }
4144
4145 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
4146 if (location >= MaxLocation)
4147 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004148 context->validationError(GL_INVALID_VALUE, kInvalidVaryingLocation);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004149 return false;
4150 }
4151
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004152 const auto *programObject = context->getProgramNoResolveLink(program);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004153 if (!programObject)
4154 {
Jamie Madille0472f32018-11-27 16:32:45 -05004155 context->validationError(GL_INVALID_OPERATION, kProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004156 return false;
4157 }
4158
4159 if (!name)
4160 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004161 context->validationError(GL_INVALID_VALUE, kMissingName);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004162 return false;
4163 }
4164
4165 if (angle::BeginsWith(name, "gl_"))
4166 {
Jamie Madille0472f32018-11-27 16:32:45 -05004167 context->validationError(GL_INVALID_OPERATION, kNameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004168 return false;
4169 }
4170
4171 return true;
4172}
4173
Jamie Madill007530e2017-12-28 14:27:04 -05004174bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
4175 GLuint program,
4176 GLint location,
4177 GLenum genMode,
4178 GLint components,
4179 const GLfloat *coeffs)
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
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004187 const auto *programObject = context->getProgramResolveLink(program);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004188 if (!programObject || programObject->isFlaggedForDeletion())
4189 {
Jamie Madille0472f32018-11-27 16:32:45 -05004190 context->validationError(GL_INVALID_OPERATION, kProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004191 return false;
4192 }
4193
4194 if (!programObject->isLinked())
4195 {
Jamie Madille0472f32018-11-27 16:32:45 -05004196 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004197 return false;
4198 }
4199
4200 switch (genMode)
4201 {
4202 case GL_NONE:
4203 if (components != 0)
4204 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004205 context->validationError(GL_INVALID_VALUE, kInvalidComponents);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004206 return false;
4207 }
4208 break;
4209
4210 case GL_OBJECT_LINEAR_CHROMIUM:
4211 case GL_EYE_LINEAR_CHROMIUM:
4212 case GL_CONSTANT_CHROMIUM:
4213 if (components < 1 || components > 4)
4214 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004215 context->validationError(GL_INVALID_VALUE, kInvalidComponents);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004216 return false;
4217 }
4218 if (!coeffs)
4219 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004220 context->validationError(GL_INVALID_VALUE, kInvalidPathCoefficientsArray);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004221 return false;
4222 }
4223 break;
4224
4225 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05004226 context->validationError(GL_INVALID_ENUM, kInvalidPathGenMode);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004227 return false;
4228 }
4229
4230 // If the location is -1 then the command is silently ignored
4231 // and no further validation is needed.
4232 if (location == -1)
4233 return true;
4234
jchen103fd614d2018-08-13 12:21:58 +08004235 const auto &binding = programObject->getFragmentInputBindingInfo(location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004236
4237 if (!binding.valid)
4238 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004239 context->validationError(GL_INVALID_OPERATION, kInvalidFragmentInputBinding);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004240 return false;
4241 }
4242
4243 if (binding.type != GL_NONE)
4244 {
4245 GLint expectedComponents = 0;
4246 switch (binding.type)
4247 {
4248 case GL_FLOAT:
4249 expectedComponents = 1;
4250 break;
4251 case GL_FLOAT_VEC2:
4252 expectedComponents = 2;
4253 break;
4254 case GL_FLOAT_VEC3:
4255 expectedComponents = 3;
4256 break;
4257 case GL_FLOAT_VEC4:
4258 expectedComponents = 4;
4259 break;
4260 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05004261 context->validationError(GL_INVALID_OPERATION, kFragmentInputTypeNotFloatingPoint);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004262 return false;
4263 }
4264 if (expectedComponents != components && genMode != GL_NONE)
4265 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004266 context->validationError(GL_INVALID_OPERATION, kInvalidPathComponents);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004267 return false;
4268 }
4269 }
4270 return true;
4271}
4272
Geoff Lang97073d12016-04-20 10:42:34 -07004273bool ValidateCopyTextureCHROMIUM(Context *context,
4274 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04004275 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004276 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07004277 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04004278 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07004279 GLint internalFormat,
4280 GLenum destType,
4281 GLboolean unpackFlipY,
4282 GLboolean unpackPremultiplyAlpha,
4283 GLboolean unpackUnmultiplyAlpha)
4284{
4285 if (!context->getExtensions().copyTexture)
4286 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004287 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang97073d12016-04-20 10:42:34 -07004288 return false;
4289 }
4290
Geoff Lang4f0e0032017-05-01 16:04:35 -04004291 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004292 if (source == nullptr)
4293 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004294 context->validationError(GL_INVALID_VALUE, kInvalidSourceTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07004295 return false;
4296 }
4297
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004298 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004299 {
Jamie Madille0472f32018-11-27 16:32:45 -05004300 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004301 return false;
4302 }
4303
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004304 TextureType sourceType = source->getType();
4305 ASSERT(sourceType != TextureType::CubeMap);
4306 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004307
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004308 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004309 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004310 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureLevel);
Geoff Lang97073d12016-04-20 10:42:34 -07004311 return false;
4312 }
4313
Geoff Lang4f0e0032017-05-01 16:04:35 -04004314 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
4315 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
4316 if (sourceWidth == 0 || sourceHeight == 0)
4317 {
Jamie Madille0472f32018-11-27 16:32:45 -05004318 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004319 return false;
4320 }
4321
4322 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
4323 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004324 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004325 context->validationError(GL_INVALID_OPERATION, kInvalidSourceTextureInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004326 return false;
4327 }
4328
Geoff Lang63458a32017-10-30 15:16:53 -04004329 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4330 {
Jamie Madille0472f32018-11-27 16:32:45 -05004331 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Lang63458a32017-10-30 15:16:53 -04004332 return false;
4333 }
4334
Geoff Lang4f0e0032017-05-01 16:04:35 -04004335 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004336 if (dest == nullptr)
4337 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004338 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07004339 return false;
4340 }
4341
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004342 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004343 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004344 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTextureType);
Geoff Lang97073d12016-04-20 10:42:34 -07004345 return false;
4346 }
4347
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004348 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08004349 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004350 {
Jamie Madille0472f32018-11-27 16:32:45 -05004351 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004352 return false;
4353 }
4354
Geoff Lang97073d12016-04-20 10:42:34 -07004355 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
4356 {
Geoff Lang97073d12016-04-20 10:42:34 -07004357 return false;
4358 }
4359
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004360 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04004361 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004362 context->validationError(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004363 return false;
4364 }
4365
Geoff Lang97073d12016-04-20 10:42:34 -07004366 if (dest->getImmutableFormat())
4367 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004368 context->validationError(GL_INVALID_OPERATION, kDestinationImmutable);
Geoff Lang97073d12016-04-20 10:42:34 -07004369 return false;
4370 }
4371
4372 return true;
4373}
4374
4375bool ValidateCopySubTextureCHROMIUM(Context *context,
4376 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04004377 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004378 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07004379 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04004380 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07004381 GLint xoffset,
4382 GLint yoffset,
4383 GLint x,
4384 GLint y,
4385 GLsizei width,
4386 GLsizei height,
4387 GLboolean unpackFlipY,
4388 GLboolean unpackPremultiplyAlpha,
4389 GLboolean unpackUnmultiplyAlpha)
4390{
4391 if (!context->getExtensions().copyTexture)
4392 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004393 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang97073d12016-04-20 10:42:34 -07004394 return false;
4395 }
4396
Geoff Lang4f0e0032017-05-01 16:04:35 -04004397 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004398 if (source == nullptr)
4399 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004400 context->validationError(GL_INVALID_VALUE, kInvalidSourceTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07004401 return false;
4402 }
4403
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004404 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004405 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004406 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureType);
Geoff Lang97073d12016-04-20 10:42:34 -07004407 return false;
4408 }
4409
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004410 TextureType sourceType = source->getType();
4411 ASSERT(sourceType != TextureType::CubeMap);
4412 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004413
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004414 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004415 {
Jamie Madille0472f32018-11-27 16:32:45 -05004416 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004417 return false;
4418 }
4419
4420 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4421 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004422 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004423 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureLevel);
Geoff Lang97073d12016-04-20 10:42:34 -07004424 return false;
4425 }
4426
4427 if (x < 0 || y < 0)
4428 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004429 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004430 return false;
4431 }
4432
4433 if (width < 0 || height < 0)
4434 {
Jamie Madille0472f32018-11-27 16:32:45 -05004435 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004436 return false;
4437 }
4438
Geoff Lang4f0e0032017-05-01 16:04:35 -04004439 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4440 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004441 {
Jamie Madille0472f32018-11-27 16:32:45 -05004442 context->validationError(GL_INVALID_VALUE, kSourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004443 return false;
4444 }
4445
Geoff Lang4f0e0032017-05-01 16:04:35 -04004446 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4447 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004448 {
Jamie Madille0472f32018-11-27 16:32:45 -05004449 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004450 return false;
4451 }
4452
Geoff Lang63458a32017-10-30 15:16:53 -04004453 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4454 {
Jamie Madille0472f32018-11-27 16:32:45 -05004455 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Lang63458a32017-10-30 15:16:53 -04004456 return false;
4457 }
4458
Geoff Lang4f0e0032017-05-01 16:04:35 -04004459 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004460 if (dest == nullptr)
4461 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004462 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07004463 return false;
4464 }
4465
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004466 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004467 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004468 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTextureType);
Geoff Lang97073d12016-04-20 10:42:34 -07004469 return false;
4470 }
4471
Brandon Jones28783792018-03-05 09:37:32 -08004472 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4473 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004474 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004475 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Lang97073d12016-04-20 10:42:34 -07004476 return false;
4477 }
4478
Geoff Lang4f0e0032017-05-01 16:04:35 -04004479 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4480 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004481 context->validationError(GL_INVALID_OPERATION, kDestinationLevelNotDefined);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004482 return false;
4483 }
4484
4485 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4486 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004487 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004488 context->validationError(GL_INVALID_OPERATION, kInvalidFormatCombination);
Geoff Lang97073d12016-04-20 10:42:34 -07004489 return false;
4490 }
4491
4492 if (xoffset < 0 || yoffset < 0)
4493 {
Jamie Madille0472f32018-11-27 16:32:45 -05004494 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004495 return false;
4496 }
4497
Geoff Lang4f0e0032017-05-01 16:04:35 -04004498 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4499 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004500 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004501 context->validationError(GL_INVALID_VALUE, kOffsetOverflow);
Geoff Lang97073d12016-04-20 10:42:34 -07004502 return false;
4503 }
4504
4505 return true;
4506}
4507
Geoff Lang47110bf2016-04-20 11:13:22 -07004508bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4509{
4510 if (!context->getExtensions().copyCompressedTexture)
4511 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004512 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang47110bf2016-04-20 11:13:22 -07004513 return false;
4514 }
4515
4516 const gl::Texture *source = context->getTexture(sourceId);
4517 if (source == nullptr)
4518 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004519 context->validationError(GL_INVALID_VALUE, kInvalidSourceTexture);
Geoff Lang47110bf2016-04-20 11:13:22 -07004520 return false;
4521 }
4522
Corentin Wallez99d492c2018-02-27 15:17:10 -05004523 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004524 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004525 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureType);
Geoff Lang47110bf2016-04-20 11:13:22 -07004526 return false;
4527 }
4528
Corentin Wallez99d492c2018-02-27 15:17:10 -05004529 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4530 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004531 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004532 context->validationError(GL_INVALID_VALUE, kSourceTextureLevelZeroDefined);
Geoff Lang47110bf2016-04-20 11:13:22 -07004533 return false;
4534 }
4535
Corentin Wallez99d492c2018-02-27 15:17:10 -05004536 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004537 if (!sourceFormat.info->compressed)
4538 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004539 context->validationError(GL_INVALID_OPERATION, kSourceTextureMustBeCompressed);
Geoff Lang47110bf2016-04-20 11:13:22 -07004540 return false;
4541 }
4542
4543 const gl::Texture *dest = context->getTexture(destId);
4544 if (dest == nullptr)
4545 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004546 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTexture);
Geoff Lang47110bf2016-04-20 11:13:22 -07004547 return false;
4548 }
4549
Corentin Wallez99d492c2018-02-27 15:17:10 -05004550 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004551 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004552 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTextureType);
Geoff Lang47110bf2016-04-20 11:13:22 -07004553 return false;
4554 }
4555
4556 if (dest->getImmutableFormat())
4557 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004558 context->validationError(GL_INVALID_OPERATION, kDestinationImmutable);
Geoff Lang47110bf2016-04-20 11:13:22 -07004559 return false;
4560 }
4561
4562 return true;
4563}
4564
Jiawei Shao385b3e02018-03-21 09:43:28 +08004565bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004566{
4567 switch (type)
4568 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004569 case ShaderType::Vertex:
4570 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004571 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004572
Jiawei Shao385b3e02018-03-21 09:43:28 +08004573 case ShaderType::Compute:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004574 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004575 {
Jamie Madille0472f32018-11-27 16:32:45 -05004576 context->validationError(GL_INVALID_ENUM, kES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004577 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004578 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004579 break;
4580
Jiawei Shao385b3e02018-03-21 09:43:28 +08004581 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004582 if (!context->getExtensions().geometryShader)
4583 {
Jamie Madille0472f32018-11-27 16:32:45 -05004584 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
Jiawei Shao89be29a2017-11-06 14:36:45 +08004585 return false;
4586 }
4587 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004588 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004589 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004590 return false;
4591 }
Jamie Madill29639852016-09-02 15:00:09 -04004592
4593 return true;
4594}
4595
Jamie Madill5b772312018-03-08 20:28:32 -05004596bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004597 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004598 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004599 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004600 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004601{
4602 if (size < 0)
4603 {
Jamie Madille0472f32018-11-27 16:32:45 -05004604 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004605 return false;
4606 }
4607
4608 switch (usage)
4609 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004610 case BufferUsage::StreamDraw:
4611 case BufferUsage::StaticDraw:
4612 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004613 break;
4614
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004615 case BufferUsage::StreamRead:
4616 case BufferUsage::StaticRead:
4617 case BufferUsage::DynamicRead:
4618 case BufferUsage::StreamCopy:
4619 case BufferUsage::StaticCopy:
4620 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004621 if (context->getClientMajorVersion() < 3)
4622 {
Jamie Madille0472f32018-11-27 16:32:45 -05004623 context->validationError(GL_INVALID_ENUM, kInvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004624 return false;
4625 }
4626 break;
4627
4628 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004629 context->validationError(GL_INVALID_ENUM, kInvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004630 return false;
4631 }
4632
Corentin Walleze4477002017-12-01 14:39:58 -05004633 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004634 {
Jamie Madille0472f32018-11-27 16:32:45 -05004635 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004636 return false;
4637 }
4638
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004639 Buffer *buffer = context->getState().getTargetBuffer(target);
Jamie Madill29639852016-09-02 15:00:09 -04004640
4641 if (!buffer)
4642 {
Jamie Madille0472f32018-11-27 16:32:45 -05004643 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004644 return false;
4645 }
4646
James Darpiniane8a93c62018-01-04 18:02:24 -08004647 if (context->getExtensions().webglCompatibility &&
4648 buffer->isBoundForTransformFeedbackAndOtherUse())
4649 {
Jamie Madille0472f32018-11-27 16:32:45 -05004650 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08004651 return false;
4652 }
4653
Jamie Madill29639852016-09-02 15:00:09 -04004654 return true;
4655}
4656
Jamie Madill5b772312018-03-08 20:28:32 -05004657bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004658 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004659 GLintptr offset,
4660 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004661 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004662{
Brandon Jones6cad5662017-06-14 13:25:13 -07004663 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004664 {
Jamie Madille0472f32018-11-27 16:32:45 -05004665 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Brandon Jones6cad5662017-06-14 13:25:13 -07004666 return false;
4667 }
4668
4669 if (offset < 0)
4670 {
Jamie Madille0472f32018-11-27 16:32:45 -05004671 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
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
4689 if (buffer->isMapped())
4690 {
Jamie Madille0472f32018-11-27 16:32:45 -05004691 context->validationError(GL_INVALID_OPERATION, kBufferMapped);
Jamie Madill29639852016-09-02 15:00:09 -04004692 return false;
4693 }
4694
James Darpiniane8a93c62018-01-04 18:02:24 -08004695 if (context->getExtensions().webglCompatibility &&
4696 buffer->isBoundForTransformFeedbackAndOtherUse())
4697 {
Jamie Madille0472f32018-11-27 16:32:45 -05004698 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08004699 return false;
4700 }
4701
Jamie Madill29639852016-09-02 15:00:09 -04004702 // Check for possible overflow of size + offset
4703 angle::CheckedNumeric<size_t> checkedSize(size);
4704 checkedSize += offset;
4705 if (!checkedSize.IsValid())
4706 {
Jamie Madille0472f32018-11-27 16:32:45 -05004707 context->validationError(GL_INVALID_VALUE, kParamOverflow);
Jamie Madill29639852016-09-02 15:00:09 -04004708 return false;
4709 }
4710
4711 if (size + offset > buffer->getSize())
4712 {
Jamie Madille0472f32018-11-27 16:32:45 -05004713 context->validationError(GL_INVALID_VALUE, kInsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004714 return false;
4715 }
4716
Martin Radev4c4c8e72016-08-04 12:25:34 +03004717 return true;
4718}
4719
Geoff Lang111a99e2017-10-17 10:58:41 -04004720bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004721{
Geoff Langc339c4e2016-11-29 10:37:36 -05004722 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004723 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004724 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langc287ea62016-09-16 14:46:51 -04004725 return false;
4726 }
4727
Geoff Lang111a99e2017-10-17 10:58:41 -04004728 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004729 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004730 context->validationError(GL_INVALID_OPERATION, kExtensionNotRequestable);
Geoff Langc287ea62016-09-16 14:46:51 -04004731 return false;
4732 }
4733
4734 return true;
4735}
4736
Jamie Madill5b772312018-03-08 20:28:32 -05004737bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004738{
Lingfeng Yang038dd532018-03-29 17:31:52 -07004739 if (context->getClientMajorVersion() < 2)
4740 {
4741 return ValidateMultitextureUnit(context, texture);
4742 }
4743
Jamie Madillef300b12016-10-07 15:12:09 -04004744 if (texture < GL_TEXTURE0 ||
4745 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4746 {
Jamie Madille0472f32018-11-27 16:32:45 -05004747 context->validationError(GL_INVALID_ENUM, kInvalidCombinedImageUnit);
Jamie Madillef300b12016-10-07 15:12:09 -04004748 return false;
4749 }
4750
4751 return true;
4752}
4753
Jamie Madill5b772312018-03-08 20:28:32 -05004754bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004755{
4756 Program *programObject = GetValidProgram(context, program);
4757 if (!programObject)
4758 {
4759 return false;
4760 }
4761
4762 Shader *shaderObject = GetValidShader(context, shader);
4763 if (!shaderObject)
4764 {
4765 return false;
4766 }
4767
Jiawei Shao385b3e02018-03-21 09:43:28 +08004768 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04004769 {
Jamie Madille0472f32018-11-27 16:32:45 -05004770 context->validationError(GL_INVALID_OPERATION, kShaderAttachmentHasShader);
Jiawei Shao385b3e02018-03-21 09:43:28 +08004771 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04004772 }
4773
4774 return true;
4775}
4776
Jamie Madill5b772312018-03-08 20:28:32 -05004777bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004778{
4779 if (index >= MAX_VERTEX_ATTRIBS)
4780 {
Jamie Madille0472f32018-11-27 16:32:45 -05004781 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004782 return false;
4783 }
4784
4785 if (strncmp(name, "gl_", 3) == 0)
4786 {
Jamie Madille0472f32018-11-27 16:32:45 -05004787 context->validationError(GL_INVALID_OPERATION, kNameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004788 return false;
4789 }
4790
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004791 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004792 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004793 const size_t length = strlen(name);
4794
4795 if (!IsValidESSLString(name, length))
4796 {
4797 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4798 // for shader-related entry points
Jamie Madille0472f32018-11-27 16:32:45 -05004799 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004800 return false;
4801 }
4802
4803 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4804 {
4805 return false;
4806 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004807 }
4808
Jamie Madill01a80ee2016-11-07 12:06:18 -05004809 return GetValidProgram(context, program) != nullptr;
4810}
4811
Jamie Madill5b772312018-03-08 20:28:32 -05004812bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004813{
Geoff Lange8afa902017-09-27 15:00:43 -04004814 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004815 {
Jamie Madille0472f32018-11-27 16:32:45 -05004816 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004817 return false;
4818 }
4819
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004820 if (!context->getState().isBindGeneratesResourceEnabled() &&
Jamie Madill01a80ee2016-11-07 12:06:18 -05004821 !context->isFramebufferGenerated(framebuffer))
4822 {
Jamie Madille0472f32018-11-27 16:32:45 -05004823 context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004824 return false;
4825 }
4826
4827 return true;
4828}
4829
Jamie Madill5b772312018-03-08 20:28:32 -05004830bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004831{
4832 if (target != GL_RENDERBUFFER)
4833 {
Jamie Madille0472f32018-11-27 16:32:45 -05004834 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004835 return false;
4836 }
4837
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004838 if (!context->getState().isBindGeneratesResourceEnabled() &&
Jamie Madill01a80ee2016-11-07 12:06:18 -05004839 !context->isRenderbufferGenerated(renderbuffer))
4840 {
Jamie Madille0472f32018-11-27 16:32:45 -05004841 context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004842 return false;
4843 }
4844
4845 return true;
4846}
4847
Jamie Madill5b772312018-03-08 20:28:32 -05004848static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004849{
4850 switch (mode)
4851 {
4852 case GL_FUNC_ADD:
4853 case GL_FUNC_SUBTRACT:
4854 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004855 return true;
4856
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004857 case GL_MIN:
4858 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004859 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004860
4861 default:
4862 return false;
4863 }
4864}
4865
Jamie Madill5b772312018-03-08 20:28:32 -05004866bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004867{
4868 return true;
4869}
4870
Jamie Madill5b772312018-03-08 20:28:32 -05004871bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004872{
Geoff Lang50cac572017-09-26 17:37:43 -04004873 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004874 {
Jamie Madille0472f32018-11-27 16:32:45 -05004875 context->validationError(GL_INVALID_ENUM, kInvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004876 return false;
4877 }
4878
4879 return true;
4880}
4881
Jamie Madill5b772312018-03-08 20:28:32 -05004882bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004883{
Geoff Lang50cac572017-09-26 17:37:43 -04004884 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004885 {
Jamie Madille0472f32018-11-27 16:32:45 -05004886 context->validationError(GL_INVALID_ENUM, kInvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004887 return false;
4888 }
4889
Geoff Lang50cac572017-09-26 17:37:43 -04004890 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004891 {
Jamie Madille0472f32018-11-27 16:32:45 -05004892 context->validationError(GL_INVALID_ENUM, kInvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004893 return false;
4894 }
4895
4896 return true;
4897}
4898
Jamie Madill5b772312018-03-08 20:28:32 -05004899bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004900{
4901 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4902}
4903
Jamie Madill5b772312018-03-08 20:28:32 -05004904bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004905 GLenum srcRGB,
4906 GLenum dstRGB,
4907 GLenum srcAlpha,
4908 GLenum dstAlpha)
4909{
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004910 if (!ValidSrcBlendFunc(context, srcRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004911 {
Jamie Madille0472f32018-11-27 16:32:45 -05004912 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004913 return false;
4914 }
4915
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004916 if (!ValidDstBlendFunc(context, dstRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004917 {
Jamie Madille0472f32018-11-27 16:32:45 -05004918 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004919 return false;
4920 }
4921
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004922 if (!ValidSrcBlendFunc(context, srcAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004923 {
Jamie Madille0472f32018-11-27 16:32:45 -05004924 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004925 return false;
4926 }
4927
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004928 if (!ValidDstBlendFunc(context, dstAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004929 {
Jamie Madille0472f32018-11-27 16:32:45 -05004930 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004931 return false;
4932 }
4933
Frank Henigman146e8a12017-03-02 23:22:37 -05004934 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4935 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004936 {
4937 bool constantColorUsed =
4938 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4939 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4940
4941 bool constantAlphaUsed =
4942 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4943 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4944
4945 if (constantColorUsed && constantAlphaUsed)
4946 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004947 if (context->getExtensions().webglCompatibility)
4948 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004949 context->validationError(GL_INVALID_OPERATION, kInvalidConstantColor);
4950 return false;
Frank Henigman146e8a12017-03-02 23:22:37 -05004951 }
Jamie Madillc3e37312018-11-30 15:25:39 -05004952
4953 WARN() << kConstantColorAlphaLimitation;
4954 context->validationError(GL_INVALID_OPERATION, kConstantColorAlphaLimitation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004955 return false;
4956 }
4957 }
4958
4959 return true;
4960}
4961
Geoff Langc339c4e2016-11-29 10:37:36 -05004962bool ValidateGetString(Context *context, GLenum name)
4963{
4964 switch (name)
4965 {
4966 case GL_VENDOR:
4967 case GL_RENDERER:
4968 case GL_VERSION:
4969 case GL_SHADING_LANGUAGE_VERSION:
4970 case GL_EXTENSIONS:
4971 break;
4972
4973 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4974 if (!context->getExtensions().requestExtension)
4975 {
Jamie Madille0472f32018-11-27 16:32:45 -05004976 context->validationError(GL_INVALID_ENUM, kInvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004977 return false;
4978 }
4979 break;
4980
4981 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004982 context->validationError(GL_INVALID_ENUM, kInvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004983 return false;
4984 }
4985
4986 return true;
4987}
4988
Jamie Madill5b772312018-03-08 20:28:32 -05004989bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004990{
4991 if (width <= 0.0f || isNaN(width))
4992 {
Jamie Madille0472f32018-11-27 16:32:45 -05004993 context->validationError(GL_INVALID_VALUE, kInvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004994 return false;
4995 }
4996
4997 return true;
4998}
4999
Jamie Madill5b772312018-03-08 20:28:32 -05005000bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05005001{
5002 if (context->getExtensions().webglCompatibility && zNear > zFar)
5003 {
Jamie Madille0472f32018-11-27 16:32:45 -05005004 context->validationError(GL_INVALID_OPERATION, kInvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05005005 return false;
5006 }
5007
5008 return true;
5009}
5010
Jamie Madill5b772312018-03-08 20:28:32 -05005011bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05005012 GLenum target,
5013 GLenum internalformat,
5014 GLsizei width,
5015 GLsizei height)
5016{
5017 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
5018 height);
5019}
5020
Jamie Madill5b772312018-03-08 20:28:32 -05005021bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05005022 GLenum target,
5023 GLsizei samples,
5024 GLenum internalformat,
5025 GLsizei width,
5026 GLsizei height)
5027{
5028 if (!context->getExtensions().framebufferMultisample)
5029 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005030 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madille8fb6402017-02-14 17:56:40 -05005031 return false;
5032 }
5033
5034 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
Jamie Madill610640f2018-11-21 17:28:41 -05005035 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_VALUE is
Jamie Madille8fb6402017-02-14 17:56:40 -05005036 // generated.
5037 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
5038 {
Jamie Madille0472f32018-11-27 16:32:45 -05005039 context->validationError(GL_INVALID_VALUE, kSamplesOutOfRange);
Jamie Madille8fb6402017-02-14 17:56:40 -05005040 return false;
5041 }
5042
5043 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
5044 // the specified storage. This is different than ES 3.0 in which a sample number higher
5045 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
5046 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
5047 if (context->getClientMajorVersion() >= 3)
5048 {
5049 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
5050 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
5051 {
Jamie Madille0472f32018-11-27 16:32:45 -05005052 context->validationError(GL_OUT_OF_MEMORY, kSamplesOutOfRange);
Jamie Madille8fb6402017-02-14 17:56:40 -05005053 return false;
5054 }
5055 }
5056
5057 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
5058 width, height);
5059}
5060
Jamie Madill5b772312018-03-08 20:28:32 -05005061bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005062{
Geoff Lange8afa902017-09-27 15:00:43 -04005063 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04005064 {
Jamie Madille0472f32018-11-27 16:32:45 -05005065 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005066 return false;
5067 }
5068
5069 return true;
5070}
5071
Jamie Madill5b772312018-03-08 20:28:32 -05005072bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005073{
5074 return true;
5075}
5076
Jamie Madill5b772312018-03-08 20:28:32 -05005077bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005078{
5079 return true;
5080}
5081
Jamie Madill5b772312018-03-08 20:28:32 -05005082bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005083{
5084 return true;
5085}
5086
Jamie Madill5b772312018-03-08 20:28:32 -05005087bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005088 GLboolean red,
5089 GLboolean green,
5090 GLboolean blue,
5091 GLboolean alpha)
5092{
5093 return true;
5094}
5095
Jamie Madill5b772312018-03-08 20:28:32 -05005096bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005097{
5098 return true;
5099}
5100
Jamie Madill5b772312018-03-08 20:28:32 -05005101bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005102{
5103 return true;
5104}
5105
Jamie Madill5b772312018-03-08 20:28:32 -05005106bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005107{
5108 switch (mode)
5109 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04005110 case CullFaceMode::Front:
5111 case CullFaceMode::Back:
5112 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04005113 break;
5114
5115 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005116 context->validationError(GL_INVALID_ENUM, kInvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005117 return false;
5118 }
5119
5120 return true;
5121}
5122
Jamie Madill5b772312018-03-08 20:28:32 -05005123bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005124{
5125 if (program == 0)
5126 {
5127 return false;
5128 }
5129
Jamie Madill44a6fbf2018-10-02 13:38:56 -04005130 if (!context->getProgramResolveLink(program))
Jamie Madillc1d770e2017-04-13 17:31:24 -04005131 {
5132 if (context->getShader(program))
5133 {
Jamie Madille0472f32018-11-27 16:32:45 -05005134 context->validationError(GL_INVALID_OPERATION, kExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005135 return false;
5136 }
5137 else
5138 {
Jamie Madille0472f32018-11-27 16:32:45 -05005139 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005140 return false;
5141 }
5142 }
5143
5144 return true;
5145}
5146
Jamie Madill5b772312018-03-08 20:28:32 -05005147bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005148{
5149 if (shader == 0)
5150 {
5151 return false;
5152 }
5153
5154 if (!context->getShader(shader))
5155 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04005156 if (context->getProgramResolveLink(shader))
Jamie Madillc1d770e2017-04-13 17:31:24 -04005157 {
Jamie Madille0472f32018-11-27 16:32:45 -05005158 context->validationError(GL_INVALID_OPERATION, kInvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005159 return false;
5160 }
5161 else
5162 {
Jamie Madille0472f32018-11-27 16:32:45 -05005163 context->validationError(GL_INVALID_VALUE, kExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005164 return false;
5165 }
5166 }
5167
5168 return true;
5169}
5170
Jamie Madill5b772312018-03-08 20:28:32 -05005171bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005172{
5173 switch (func)
5174 {
5175 case GL_NEVER:
5176 case GL_ALWAYS:
5177 case GL_LESS:
5178 case GL_LEQUAL:
5179 case GL_EQUAL:
5180 case GL_GREATER:
5181 case GL_GEQUAL:
5182 case GL_NOTEQUAL:
5183 break;
5184
5185 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005186 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005187 return false;
5188 }
5189
5190 return true;
5191}
5192
Jamie Madill5b772312018-03-08 20:28:32 -05005193bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005194{
5195 return true;
5196}
5197
Jamie Madill5b772312018-03-08 20:28:32 -05005198bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005199{
5200 Program *programObject = GetValidProgram(context, program);
5201 if (!programObject)
5202 {
5203 return false;
5204 }
5205
5206 Shader *shaderObject = GetValidShader(context, shader);
5207 if (!shaderObject)
5208 {
5209 return false;
5210 }
5211
Jiawei Shao385b3e02018-03-21 09:43:28 +08005212 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005213 if (attachedShader != shaderObject)
5214 {
Jamie Madille0472f32018-11-27 16:32:45 -05005215 context->validationError(GL_INVALID_OPERATION, kShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005216 return false;
5217 }
5218
5219 return true;
5220}
5221
Jamie Madill5b772312018-03-08 20:28:32 -05005222bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005223{
5224 if (index >= MAX_VERTEX_ATTRIBS)
5225 {
Jamie Madille0472f32018-11-27 16:32:45 -05005226 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005227 return false;
5228 }
5229
5230 return true;
5231}
5232
Jamie Madill5b772312018-03-08 20:28:32 -05005233bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005234{
5235 if (index >= MAX_VERTEX_ATTRIBS)
5236 {
Jamie Madille0472f32018-11-27 16:32:45 -05005237 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005238 return false;
5239 }
5240
5241 return true;
5242}
5243
Jamie Madill5b772312018-03-08 20:28:32 -05005244bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005245{
5246 return true;
5247}
5248
Jamie Madill5b772312018-03-08 20:28:32 -05005249bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005250{
5251 return true;
5252}
5253
Jamie Madill5b772312018-03-08 20:28:32 -05005254bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005255{
5256 switch (mode)
5257 {
5258 case GL_CW:
5259 case GL_CCW:
5260 break;
5261 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005262 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005263 return false;
5264 }
5265
5266 return true;
5267}
5268
Jamie Madill5b772312018-03-08 20:28:32 -05005269bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005270 GLuint program,
5271 GLuint index,
5272 GLsizei bufsize,
5273 GLsizei *length,
5274 GLint *size,
5275 GLenum *type,
5276 GLchar *name)
5277{
5278 if (bufsize < 0)
5279 {
Jamie Madille0472f32018-11-27 16:32:45 -05005280 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005281 return false;
5282 }
5283
5284 Program *programObject = GetValidProgram(context, program);
5285
5286 if (!programObject)
5287 {
5288 return false;
5289 }
5290
5291 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5292 {
Jamie Madille0472f32018-11-27 16:32:45 -05005293 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005294 return false;
5295 }
5296
5297 return true;
5298}
5299
Jamie Madill5b772312018-03-08 20:28:32 -05005300bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005301 GLuint program,
5302 GLuint index,
5303 GLsizei bufsize,
5304 GLsizei *length,
5305 GLint *size,
5306 GLenum *type,
5307 GLchar *name)
5308{
5309 if (bufsize < 0)
5310 {
Jamie Madille0472f32018-11-27 16:32:45 -05005311 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005312 return false;
5313 }
5314
5315 Program *programObject = GetValidProgram(context, program);
5316
5317 if (!programObject)
5318 {
5319 return false;
5320 }
5321
5322 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5323 {
Jamie Madille0472f32018-11-27 16:32:45 -05005324 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005325 return false;
5326 }
5327
5328 return true;
5329}
5330
Jamie Madill5b772312018-03-08 20:28:32 -05005331bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005332 GLuint program,
5333 GLsizei maxcount,
5334 GLsizei *count,
5335 GLuint *shaders)
5336{
5337 if (maxcount < 0)
5338 {
Jamie Madille0472f32018-11-27 16:32:45 -05005339 context->validationError(GL_INVALID_VALUE, kNegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005340 return false;
5341 }
5342
5343 Program *programObject = GetValidProgram(context, program);
5344
5345 if (!programObject)
5346 {
5347 return false;
5348 }
5349
5350 return true;
5351}
5352
Jamie Madill5b772312018-03-08 20:28:32 -05005353bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005354{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005355 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5356 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005357 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005358 {
Jamie Madille0472f32018-11-27 16:32:45 -05005359 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005360 return false;
5361 }
5362
Jamie Madillc1d770e2017-04-13 17:31:24 -04005363 Program *programObject = GetValidProgram(context, program);
5364
5365 if (!programObject)
5366 {
Jamie Madille0472f32018-11-27 16:32:45 -05005367 context->validationError(GL_INVALID_OPERATION, kProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005368 return false;
5369 }
5370
5371 if (!programObject->isLinked())
5372 {
Jamie Madille0472f32018-11-27 16:32:45 -05005373 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005374 return false;
5375 }
5376
5377 return true;
5378}
5379
Jamie Madill5b772312018-03-08 20:28:32 -05005380bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005381{
5382 GLenum nativeType;
5383 unsigned int numParams = 0;
5384 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5385}
5386
Jamie Madill5b772312018-03-08 20:28:32 -05005387bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005388{
5389 return true;
5390}
5391
Jamie Madill5b772312018-03-08 20:28:32 -05005392bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005393{
5394 GLenum nativeType;
5395 unsigned int numParams = 0;
5396 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5397}
5398
Jamie Madill5b772312018-03-08 20:28:32 -05005399bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005400{
5401 GLenum nativeType;
5402 unsigned int numParams = 0;
5403 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5404}
5405
Jamie Madill5b772312018-03-08 20:28:32 -05005406bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005407 GLuint program,
5408 GLsizei bufsize,
5409 GLsizei *length,
5410 GLchar *infolog)
5411{
5412 if (bufsize < 0)
5413 {
Jamie Madille0472f32018-11-27 16:32:45 -05005414 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005415 return false;
5416 }
5417
5418 Program *programObject = GetValidProgram(context, program);
5419 if (!programObject)
5420 {
5421 return false;
5422 }
5423
5424 return true;
5425}
5426
Jamie Madill5b772312018-03-08 20:28:32 -05005427bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005428 GLuint shader,
5429 GLsizei bufsize,
5430 GLsizei *length,
5431 GLchar *infolog)
5432{
5433 if (bufsize < 0)
5434 {
Jamie Madille0472f32018-11-27 16:32:45 -05005435 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005436 return false;
5437 }
5438
5439 Shader *shaderObject = GetValidShader(context, shader);
5440 if (!shaderObject)
5441 {
5442 return false;
5443 }
5444
5445 return true;
5446}
5447
Jamie Madill5b772312018-03-08 20:28:32 -05005448bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005449 GLenum shadertype,
5450 GLenum precisiontype,
5451 GLint *range,
5452 GLint *precision)
5453{
5454 switch (shadertype)
5455 {
5456 case GL_VERTEX_SHADER:
5457 case GL_FRAGMENT_SHADER:
5458 break;
5459 case GL_COMPUTE_SHADER:
Jamie Madillc3e37312018-11-30 15:25:39 -05005460 context->validationError(GL_INVALID_OPERATION, kUnimplementedComputeShaderPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005461 return false;
5462 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005463 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005464 return false;
5465 }
5466
5467 switch (precisiontype)
5468 {
5469 case GL_LOW_FLOAT:
5470 case GL_MEDIUM_FLOAT:
5471 case GL_HIGH_FLOAT:
5472 case GL_LOW_INT:
5473 case GL_MEDIUM_INT:
5474 case GL_HIGH_INT:
5475 break;
5476
5477 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005478 context->validationError(GL_INVALID_ENUM, kInvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005479 return false;
5480 }
5481
5482 return true;
5483}
5484
Jamie Madill5b772312018-03-08 20:28:32 -05005485bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005486 GLuint shader,
5487 GLsizei bufsize,
5488 GLsizei *length,
5489 GLchar *source)
5490{
5491 if (bufsize < 0)
5492 {
Jamie Madille0472f32018-11-27 16:32:45 -05005493 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005494 return false;
5495 }
5496
5497 Shader *shaderObject = GetValidShader(context, shader);
5498 if (!shaderObject)
5499 {
5500 return false;
5501 }
5502
5503 return true;
5504}
5505
Jamie Madill5b772312018-03-08 20:28:32 -05005506bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005507{
5508 if (strstr(name, "gl_") == name)
5509 {
5510 return false;
5511 }
5512
Geoff Langfc32e8b2017-05-31 14:16:59 -04005513 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5514 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005515 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005516 {
Jamie Madille0472f32018-11-27 16:32:45 -05005517 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005518 return false;
5519 }
5520
Jamie Madillc1d770e2017-04-13 17:31:24 -04005521 Program *programObject = GetValidProgram(context, program);
5522
5523 if (!programObject)
5524 {
5525 return false;
5526 }
5527
5528 if (!programObject->isLinked())
5529 {
Jamie Madille0472f32018-11-27 16:32:45 -05005530 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005531 return false;
5532 }
5533
5534 return true;
5535}
5536
Jamie Madill5b772312018-03-08 20:28:32 -05005537bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005538{
5539 switch (mode)
5540 {
5541 case GL_FASTEST:
5542 case GL_NICEST:
5543 case GL_DONT_CARE:
5544 break;
5545
5546 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005547 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005548 return false;
5549 }
5550
5551 switch (target)
5552 {
5553 case GL_GENERATE_MIPMAP_HINT:
5554 break;
5555
Geoff Lange7bd2182017-06-16 16:13:13 -04005556 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5557 if (context->getClientVersion() < ES_3_0 &&
5558 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005559 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005560 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005561 return false;
5562 }
5563 break;
5564
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07005565 case GL_PERSPECTIVE_CORRECTION_HINT:
5566 case GL_POINT_SMOOTH_HINT:
5567 case GL_LINE_SMOOTH_HINT:
5568 case GL_FOG_HINT:
5569 if (context->getClientMajorVersion() >= 2)
5570 {
Jamie Madille0472f32018-11-27 16:32:45 -05005571 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07005572 return false;
5573 }
5574 break;
5575
Jamie Madillc1d770e2017-04-13 17:31:24 -04005576 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005577 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005578 return false;
5579 }
5580
5581 return true;
5582}
5583
Jamie Madill5b772312018-03-08 20:28:32 -05005584bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005585{
5586 return true;
5587}
5588
Jamie Madill5b772312018-03-08 20:28:32 -05005589bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005590{
5591 return true;
5592}
5593
Jamie Madill5b772312018-03-08 20:28:32 -05005594bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005595{
5596 return true;
5597}
5598
Jamie Madill5b772312018-03-08 20:28:32 -05005599bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005600{
5601 return true;
5602}
5603
Jamie Madill5b772312018-03-08 20:28:32 -05005604bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005605{
5606 return true;
5607}
5608
Jamie Madill5b772312018-03-08 20:28:32 -05005609bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005610{
5611 return true;
5612}
5613
Jamie Madill5b772312018-03-08 20:28:32 -05005614bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005615{
5616 if (context->getClientMajorVersion() < 3)
5617 {
5618 switch (pname)
5619 {
5620 case GL_UNPACK_IMAGE_HEIGHT:
5621 case GL_UNPACK_SKIP_IMAGES:
Jamie Madille0472f32018-11-27 16:32:45 -05005622 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005623 return false;
5624
5625 case GL_UNPACK_ROW_LENGTH:
5626 case GL_UNPACK_SKIP_ROWS:
5627 case GL_UNPACK_SKIP_PIXELS:
5628 if (!context->getExtensions().unpackSubimage)
5629 {
Jamie Madille0472f32018-11-27 16:32:45 -05005630 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005631 return false;
5632 }
5633 break;
5634
5635 case GL_PACK_ROW_LENGTH:
5636 case GL_PACK_SKIP_ROWS:
5637 case GL_PACK_SKIP_PIXELS:
5638 if (!context->getExtensions().packSubimage)
5639 {
Jamie Madille0472f32018-11-27 16:32:45 -05005640 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005641 return false;
5642 }
5643 break;
5644 }
5645 }
5646
5647 if (param < 0)
5648 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005649 context->validationError(GL_INVALID_VALUE, kNegativeParam);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005650 return false;
5651 }
5652
5653 switch (pname)
5654 {
5655 case GL_UNPACK_ALIGNMENT:
5656 if (param != 1 && param != 2 && param != 4 && param != 8)
5657 {
Jamie Madille0472f32018-11-27 16:32:45 -05005658 context->validationError(GL_INVALID_VALUE, kInvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005659 return false;
5660 }
5661 break;
5662
5663 case GL_PACK_ALIGNMENT:
5664 if (param != 1 && param != 2 && param != 4 && param != 8)
5665 {
Jamie Madille0472f32018-11-27 16:32:45 -05005666 context->validationError(GL_INVALID_VALUE, kInvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005667 return false;
5668 }
5669 break;
5670
5671 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005672 if (!context->getExtensions().packReverseRowOrder)
5673 {
Jamie Madille0472f32018-11-27 16:32:45 -05005674 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang000dab82017-09-27 14:27:07 -04005675 }
5676 break;
5677
Jamie Madillc1d770e2017-04-13 17:31:24 -04005678 case GL_UNPACK_ROW_LENGTH:
5679 case GL_UNPACK_IMAGE_HEIGHT:
5680 case GL_UNPACK_SKIP_IMAGES:
5681 case GL_UNPACK_SKIP_ROWS:
5682 case GL_UNPACK_SKIP_PIXELS:
5683 case GL_PACK_ROW_LENGTH:
5684 case GL_PACK_SKIP_ROWS:
5685 case GL_PACK_SKIP_PIXELS:
5686 break;
5687
5688 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005689 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005690 return false;
5691 }
5692
5693 return true;
5694}
5695
Jamie Madill5b772312018-03-08 20:28:32 -05005696bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005697{
5698 return true;
5699}
5700
Jamie Madill5b772312018-03-08 20:28:32 -05005701bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005702{
5703 return true;
5704}
5705
Jamie Madill5b772312018-03-08 20:28:32 -05005706bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005707{
5708 return true;
5709}
5710
Jamie Madill5b772312018-03-08 20:28:32 -05005711bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005712{
5713 if (width < 0 || height < 0)
5714 {
Jamie Madille0472f32018-11-27 16:32:45 -05005715 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005716 return false;
5717 }
5718
5719 return true;
5720}
5721
Jamie Madill5b772312018-03-08 20:28:32 -05005722bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005723 GLsizei n,
5724 const GLuint *shaders,
5725 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005726 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005727 GLsizei length)
5728{
5729 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5730 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5731 shaderBinaryFormats.end())
5732 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005733 context->validationError(GL_INVALID_ENUM, kInvalidShaderBinaryFormat);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005734 return false;
5735 }
5736
5737 return true;
5738}
5739
Jamie Madill5b772312018-03-08 20:28:32 -05005740bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005741 GLuint shader,
5742 GLsizei count,
5743 const GLchar *const *string,
5744 const GLint *length)
5745{
5746 if (count < 0)
5747 {
Jamie Madille0472f32018-11-27 16:32:45 -05005748 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005749 return false;
5750 }
5751
Geoff Langfc32e8b2017-05-31 14:16:59 -04005752 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5753 // shader-related entry points
5754 if (context->getExtensions().webglCompatibility)
5755 {
5756 for (GLsizei i = 0; i < count; i++)
5757 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005758 size_t len =
5759 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005760
5761 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005762 if (!IsValidESSLShaderSourceString(string[i], len,
5763 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005764 {
Jamie Madille0472f32018-11-27 16:32:45 -05005765 context->validationError(GL_INVALID_VALUE, kShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005766 return false;
5767 }
5768 }
5769 }
5770
Jamie Madillc1d770e2017-04-13 17:31:24 -04005771 Shader *shaderObject = GetValidShader(context, shader);
5772 if (!shaderObject)
5773 {
5774 return false;
5775 }
5776
5777 return true;
5778}
5779
Jamie Madill5b772312018-03-08 20:28:32 -05005780bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005781{
5782 if (!IsValidStencilFunc(func))
5783 {
Jamie Madille0472f32018-11-27 16:32:45 -05005784 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005785 return false;
5786 }
5787
5788 return true;
5789}
5790
Jamie Madill5b772312018-03-08 20:28:32 -05005791bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005792{
5793 if (!IsValidStencilFace(face))
5794 {
Jamie Madille0472f32018-11-27 16:32:45 -05005795 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005796 return false;
5797 }
5798
5799 if (!IsValidStencilFunc(func))
5800 {
Jamie Madille0472f32018-11-27 16:32:45 -05005801 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005802 return false;
5803 }
5804
5805 return true;
5806}
5807
Jamie Madill5b772312018-03-08 20:28:32 -05005808bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005809{
5810 return true;
5811}
5812
Jamie Madill5b772312018-03-08 20:28:32 -05005813bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005814{
5815 if (!IsValidStencilFace(face))
5816 {
Jamie Madille0472f32018-11-27 16:32:45 -05005817 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005818 return false;
5819 }
5820
5821 return true;
5822}
5823
Jamie Madill5b772312018-03-08 20:28:32 -05005824bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005825{
5826 if (!IsValidStencilOp(fail))
5827 {
Jamie Madille0472f32018-11-27 16:32:45 -05005828 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005829 return false;
5830 }
5831
5832 if (!IsValidStencilOp(zfail))
5833 {
Jamie Madille0472f32018-11-27 16:32:45 -05005834 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005835 return false;
5836 }
5837
5838 if (!IsValidStencilOp(zpass))
5839 {
Jamie Madille0472f32018-11-27 16:32:45 -05005840 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005841 return false;
5842 }
5843
5844 return true;
5845}
5846
Jamie Madill5b772312018-03-08 20:28:32 -05005847bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005848 GLenum face,
5849 GLenum fail,
5850 GLenum zfail,
5851 GLenum zpass)
5852{
5853 if (!IsValidStencilFace(face))
5854 {
Jamie Madille0472f32018-11-27 16:32:45 -05005855 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005856 return false;
5857 }
5858
5859 return ValidateStencilOp(context, fail, zfail, zpass);
5860}
5861
Jamie Madill5b772312018-03-08 20:28:32 -05005862bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005863{
5864 return ValidateUniform(context, GL_FLOAT, location, 1);
5865}
5866
Jamie Madill5b772312018-03-08 20:28:32 -05005867bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005868{
5869 return ValidateUniform(context, GL_FLOAT, location, count);
5870}
5871
Jamie Madill5b772312018-03-08 20:28:32 -05005872bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005873{
5874 return ValidateUniform1iv(context, location, 1, &x);
5875}
5876
Jamie Madill5b772312018-03-08 20:28:32 -05005877bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005878{
5879 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5880}
5881
Jamie Madill5b772312018-03-08 20:28:32 -05005882bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005883{
5884 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5885}
5886
Jamie Madill5b772312018-03-08 20:28:32 -05005887bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005888{
5889 return ValidateUniform(context, GL_INT_VEC2, location, count);
5890}
5891
Jamie Madill5b772312018-03-08 20:28:32 -05005892bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005893{
5894 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5895}
5896
Jamie Madill5b772312018-03-08 20:28:32 -05005897bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005898{
5899 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5900}
5901
Jamie Madill5b772312018-03-08 20:28:32 -05005902bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005903{
5904 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5905}
5906
Jamie Madill5b772312018-03-08 20:28:32 -05005907bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005908{
5909 return ValidateUniform(context, GL_INT_VEC3, location, count);
5910}
5911
Jamie Madill5b772312018-03-08 20:28:32 -05005912bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005913{
5914 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5915}
5916
Jamie Madill5b772312018-03-08 20:28:32 -05005917bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005918{
5919 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5920}
5921
Jamie Madill5b772312018-03-08 20:28:32 -05005922bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005923{
5924 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5925}
5926
Jamie Madill5b772312018-03-08 20:28:32 -05005927bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005928{
5929 return ValidateUniform(context, GL_INT_VEC4, location, count);
5930}
5931
Jamie Madill5b772312018-03-08 20:28:32 -05005932bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005933 GLint location,
5934 GLsizei count,
5935 GLboolean transpose,
5936 const GLfloat *value)
5937{
5938 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5939}
5940
Jamie Madill5b772312018-03-08 20:28:32 -05005941bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005942 GLint location,
5943 GLsizei count,
5944 GLboolean transpose,
5945 const GLfloat *value)
5946{
5947 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5948}
5949
Jamie Madill5b772312018-03-08 20:28:32 -05005950bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005951 GLint location,
5952 GLsizei count,
5953 GLboolean transpose,
5954 const GLfloat *value)
5955{
5956 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5957}
5958
Jamie Madill5b772312018-03-08 20:28:32 -05005959bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005960{
5961 Program *programObject = GetValidProgram(context, program);
5962
5963 if (!programObject)
5964 {
5965 return false;
5966 }
5967
5968 return true;
5969}
5970
Jamie Madill5b772312018-03-08 20:28:32 -05005971bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005972{
5973 return ValidateVertexAttribIndex(context, index);
5974}
5975
Jamie Madill5b772312018-03-08 20:28:32 -05005976bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005977{
5978 return ValidateVertexAttribIndex(context, index);
5979}
5980
Jamie Madill5b772312018-03-08 20:28:32 -05005981bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005982{
5983 return ValidateVertexAttribIndex(context, index);
5984}
5985
Jamie Madill5b772312018-03-08 20:28:32 -05005986bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005987{
5988 return ValidateVertexAttribIndex(context, index);
5989}
5990
Jamie Madill5b772312018-03-08 20:28:32 -05005991bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005992{
5993 return ValidateVertexAttribIndex(context, index);
5994}
5995
Jamie Madill5b772312018-03-08 20:28:32 -05005996bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005997{
5998 return ValidateVertexAttribIndex(context, index);
5999}
6000
Jamie Madill5b772312018-03-08 20:28:32 -05006001bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04006002 GLuint index,
6003 GLfloat x,
6004 GLfloat y,
6005 GLfloat z,
6006 GLfloat w)
6007{
6008 return ValidateVertexAttribIndex(context, index);
6009}
6010
Jamie Madill5b772312018-03-08 20:28:32 -05006011bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006012{
6013 return ValidateVertexAttribIndex(context, index);
6014}
6015
Jamie Madill5b772312018-03-08 20:28:32 -05006016bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006017{
6018 if (width < 0 || height < 0)
6019 {
Jamie Madille0472f32018-11-27 16:32:45 -05006020 context->validationError(GL_INVALID_VALUE, kViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04006021 return false;
6022 }
6023
6024 return true;
6025}
6026
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08006027bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006028 GLenum target,
6029 GLenum attachment,
6030 GLenum pname,
6031 GLint *params)
6032{
6033 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
6034 nullptr);
6035}
6036
Jamie Madill5b772312018-03-08 20:28:32 -05006037bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006038{
6039 return ValidateGetProgramivBase(context, program, pname, nullptr);
6040}
6041
Jamie Madill5b772312018-03-08 20:28:32 -05006042bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006043 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006044 GLint level,
6045 GLenum internalformat,
6046 GLint x,
6047 GLint y,
6048 GLsizei width,
6049 GLsizei height,
6050 GLint border)
6051{
6052 if (context->getClientMajorVersion() < 3)
6053 {
6054 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
6055 0, x, y, width, height, border);
6056 }
6057
6058 ASSERT(context->getClientMajorVersion() == 3);
6059 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
6060 0, x, y, width, height, border);
6061}
6062
6063bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006064 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006065 GLint level,
6066 GLint xoffset,
6067 GLint yoffset,
6068 GLint x,
6069 GLint y,
6070 GLsizei width,
6071 GLsizei height)
6072{
6073 if (context->getClientMajorVersion() < 3)
6074 {
6075 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
6076 yoffset, x, y, width, height, 0);
6077 }
6078
6079 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
6080 yoffset, 0, x, y, width, height, 0);
6081}
6082
6083bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
6084{
6085 return ValidateGenOrDelete(context, n);
6086}
6087
6088bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
6089{
6090 return ValidateGenOrDelete(context, n);
6091}
6092
6093bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
6094{
6095 return ValidateGenOrDelete(context, n);
6096}
6097
6098bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
6099{
6100 return ValidateGenOrDelete(context, n);
6101}
6102
6103bool ValidateDisable(Context *context, GLenum cap)
6104{
6105 if (!ValidCap(context, cap, false))
6106 {
Jamie Madille0472f32018-11-27 16:32:45 -05006107 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006108 return false;
6109 }
6110
6111 return true;
6112}
6113
6114bool ValidateEnable(Context *context, GLenum cap)
6115{
6116 if (!ValidCap(context, cap, false))
6117 {
Jamie Madille0472f32018-11-27 16:32:45 -05006118 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006119 return false;
6120 }
6121
6122 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
6123 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
6124 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006125 context->validationError(GL_INVALID_OPERATION, kNoSampleAlphaToCoveragesLimitation);
Jamie Madillbe849e42017-05-02 15:49:00 -04006126
6127 // We also output an error message to the debugger window if tracing is active, so that
6128 // developers can see the error message.
Jamie Madillc3e37312018-11-30 15:25:39 -05006129 ERR() << kNoSampleAlphaToCoveragesLimitation;
Jamie Madillbe849e42017-05-02 15:49:00 -04006130 return false;
6131 }
6132
6133 return true;
6134}
6135
6136bool ValidateFramebufferRenderbuffer(Context *context,
6137 GLenum target,
6138 GLenum attachment,
6139 GLenum renderbuffertarget,
6140 GLuint renderbuffer)
6141{
Geoff Lange8afa902017-09-27 15:00:43 -04006142 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04006143 {
Jamie Madille0472f32018-11-27 16:32:45 -05006144 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Brandon Jones6cad5662017-06-14 13:25:13 -07006145 return false;
6146 }
6147
6148 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
6149 {
Jamie Madille0472f32018-11-27 16:32:45 -05006150 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006151 return false;
6152 }
6153
6154 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
6155 renderbuffertarget, renderbuffer);
6156}
6157
6158bool ValidateFramebufferTexture2D(Context *context,
6159 GLenum target,
6160 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006161 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04006162 GLuint texture,
6163 GLint level)
6164{
6165 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
6166 // extension
6167 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
6168 level != 0)
6169 {
Jamie Madille0472f32018-11-27 16:32:45 -05006170 context->validationError(GL_INVALID_VALUE, kInvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04006171 return false;
6172 }
6173
6174 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
6175 {
6176 return false;
6177 }
6178
6179 if (texture != 0)
6180 {
6181 gl::Texture *tex = context->getTexture(texture);
6182 ASSERT(tex);
6183
6184 const gl::Caps &caps = context->getCaps();
6185
6186 switch (textarget)
6187 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006188 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04006189 {
6190 if (level > gl::log2(caps.max2DTextureSize))
6191 {
Jamie Madille0472f32018-11-27 16:32:45 -05006192 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04006193 return false;
6194 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006195 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04006196 {
Jamie Madille0472f32018-11-27 16:32:45 -05006197 context->validationError(GL_INVALID_OPERATION, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006198 return false;
6199 }
6200 }
6201 break;
6202
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006203 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006204 {
6205 if (level != 0)
6206 {
Jamie Madille0472f32018-11-27 16:32:45 -05006207 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006208 return false;
6209 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006210 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006211 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006212 context->validationError(GL_INVALID_OPERATION, kTextureTargetMismatch);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006213 return false;
6214 }
6215 }
6216 break;
6217
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006218 case TextureTarget::CubeMapNegativeX:
6219 case TextureTarget::CubeMapNegativeY:
6220 case TextureTarget::CubeMapNegativeZ:
6221 case TextureTarget::CubeMapPositiveX:
6222 case TextureTarget::CubeMapPositiveY:
6223 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04006224 {
6225 if (level > gl::log2(caps.maxCubeMapTextureSize))
6226 {
Jamie Madille0472f32018-11-27 16:32:45 -05006227 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04006228 return false;
6229 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006230 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04006231 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006232 context->validationError(GL_INVALID_OPERATION, kTextureTargetMismatch);
Jamie Madillbe849e42017-05-02 15:49:00 -04006233 return false;
6234 }
6235 }
6236 break;
6237
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006238 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04006239 {
Yizhou Jiang7818a852018-09-06 15:02:04 +08006240 if (context->getClientVersion() < ES_3_1 &&
6241 !context->getExtensions().textureMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006242 {
Jamie Madill610640f2018-11-21 17:28:41 -05006243 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05006244 kMultisampleTextureExtensionOrES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006245 return false;
6246 }
6247
6248 if (level != 0)
6249 {
Jamie Madille0472f32018-11-27 16:32:45 -05006250 context->validationError(GL_INVALID_VALUE, kLevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006251 return false;
6252 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006253 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006254 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006255 context->validationError(GL_INVALID_OPERATION, kTextureTargetMismatch);
Jamie Madillbe849e42017-05-02 15:49:00 -04006256 return false;
6257 }
6258 }
6259 break;
6260
6261 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006262 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006263 return false;
6264 }
Jamie Madillbe849e42017-05-02 15:49:00 -04006265 }
6266
6267 return true;
6268}
6269
6270bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6271{
6272 return ValidateGenOrDelete(context, n);
6273}
6274
6275bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6276{
6277 return ValidateGenOrDelete(context, n);
6278}
6279
6280bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6281{
6282 return ValidateGenOrDelete(context, n);
6283}
6284
6285bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6286{
6287 return ValidateGenOrDelete(context, n);
6288}
6289
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006290bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006291{
6292 if (!ValidTextureTarget(context, target))
6293 {
Jamie Madille0472f32018-11-27 16:32:45 -05006294 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006295 return false;
6296 }
6297
Jamie Madillcfc73cc2019-04-08 16:26:51 -04006298 Texture *texture = context->getTextureByType(target);
Jamie Madillbe849e42017-05-02 15:49:00 -04006299
6300 if (texture == nullptr)
6301 {
Jamie Madille0472f32018-11-27 16:32:45 -05006302 context->validationError(GL_INVALID_OPERATION, kTextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006303 return false;
6304 }
6305
6306 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6307
6308 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6309 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6310 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6311 {
Jamie Madille0472f32018-11-27 16:32:45 -05006312 context->validationError(GL_INVALID_OPERATION, kBaseLevelOutOfRange);
Jamie Madillbe849e42017-05-02 15:49:00 -04006313 return false;
6314 }
6315
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006316 TextureTarget baseTarget = (target == TextureType::CubeMap)
6317 ? TextureTarget::CubeMapPositiveX
6318 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006319 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6320 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6321 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006322 {
Jamie Madille0472f32018-11-27 16:32:45 -05006323 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Brandon Jones6cad5662017-06-14 13:25:13 -07006324 return false;
6325 }
6326
Geoff Lang536eca12017-09-13 11:23:35 -04006327 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6328 bool formatUnsized = !format.sized;
6329 bool formatColorRenderableAndFilterable =
6330 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
Yuly Novikovf15f8862018-06-04 18:59:41 -04006331 format.textureAttachmentSupport(context->getClientVersion(), context->getExtensions());
Geoff Lang536eca12017-09-13 11:23:35 -04006332 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006333 {
Jamie Madille0472f32018-11-27 16:32:45 -05006334 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006335 return false;
6336 }
6337
Geoff Lang536eca12017-09-13 11:23:35 -04006338 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6339 // generation
6340 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6341 {
Jamie Madille0472f32018-11-27 16:32:45 -05006342 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Geoff Lang536eca12017-09-13 11:23:35 -04006343 return false;
6344 }
6345
Jiange2c00842018-07-13 16:50:49 +08006346 // According to the OpenGL extension spec EXT_sRGB.txt, EXT_SRGB is based on ES 2.0 and
6347 // generateMipmap is not allowed if texture format is SRGB_EXT or SRGB_ALPHA_EXT.
6348 if (context->getClientVersion() < Version(3, 0) && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006349 {
Jamie Madille0472f32018-11-27 16:32:45 -05006350 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006351 return false;
6352 }
6353
6354 // Non-power of 2 ES2 check
6355 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6356 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6357 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6358 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006359 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6360 target == TextureType::CubeMap);
Jamie Madille0472f32018-11-27 16:32:45 -05006361 context->validationError(GL_INVALID_OPERATION, kTextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006362 return false;
6363 }
6364
6365 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006366 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006367 {
Jamie Madille0472f32018-11-27 16:32:45 -05006368 context->validationError(GL_INVALID_OPERATION, kCubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006369 return false;
6370 }
6371
James Darpinian83b2f0e2018-11-27 15:56:01 -08006372 if (context->getExtensions().webglCompatibility &&
6373 (texture->getWidth(baseTarget, effectiveBaseLevel) == 0 ||
6374 texture->getHeight(baseTarget, effectiveBaseLevel) == 0))
6375 {
6376 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapZeroSize);
6377 return false;
6378 }
6379
Jamie Madillbe849e42017-05-02 15:49:00 -04006380 return true;
6381}
6382
Jamie Madill5b772312018-03-08 20:28:32 -05006383bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006384 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006385 GLenum pname,
6386 GLint *params)
6387{
6388 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6389}
6390
6391bool ValidateGetRenderbufferParameteriv(Context *context,
6392 GLenum target,
6393 GLenum pname,
6394 GLint *params)
6395{
6396 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6397}
6398
6399bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6400{
6401 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6402}
6403
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006404bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006405{
6406 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6407}
6408
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006409bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006410{
6411 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6412}
6413
Till Rathmannb8543632018-10-02 19:46:14 +02006414bool ValidateGetTexParameterIivOES(Context *context,
6415 TextureType target,
6416 GLenum pname,
6417 GLint *params)
6418{
6419 if (context->getClientMajorVersion() < 3)
6420 {
Jamie Madille0472f32018-11-27 16:32:45 -05006421 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006422 return false;
6423 }
6424 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6425}
6426
6427bool ValidateGetTexParameterIuivOES(Context *context,
6428 TextureType target,
6429 GLenum pname,
6430 GLuint *params)
6431{
6432 if (context->getClientMajorVersion() < 3)
6433 {
Jamie Madille0472f32018-11-27 16:32:45 -05006434 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006435 return false;
6436 }
6437 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6438}
6439
Jamie Madillbe849e42017-05-02 15:49:00 -04006440bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6441{
6442 return ValidateGetUniformBase(context, program, location);
6443}
6444
6445bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6446{
6447 return ValidateGetUniformBase(context, program, location);
6448}
6449
6450bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6451{
6452 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6453}
6454
6455bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6456{
6457 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6458}
6459
6460bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6461{
6462 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6463}
6464
6465bool ValidateIsEnabled(Context *context, GLenum cap)
6466{
6467 if (!ValidCap(context, cap, true))
6468 {
Jamie Madille0472f32018-11-27 16:32:45 -05006469 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006470 return false;
6471 }
6472
6473 return true;
6474}
6475
6476bool ValidateLinkProgram(Context *context, GLuint program)
6477{
6478 if (context->hasActiveTransformFeedback(program))
6479 {
6480 // ES 3.0.4 section 2.15 page 91
Jamie Madillc3e37312018-11-30 15:25:39 -05006481 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackActiveDuringLink);
Jamie Madillbe849e42017-05-02 15:49:00 -04006482 return false;
6483 }
6484
6485 Program *programObject = GetValidProgram(context, program);
6486 if (!programObject)
6487 {
6488 return false;
6489 }
6490
6491 return true;
6492}
6493
Jamie Madill4928b7c2017-06-20 12:57:39 -04006494bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006495 GLint x,
6496 GLint y,
6497 GLsizei width,
6498 GLsizei height,
6499 GLenum format,
6500 GLenum type,
6501 void *pixels)
6502{
6503 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6504 nullptr, pixels);
6505}
6506
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006507bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006508{
Till Rathmannb8543632018-10-02 19:46:14 +02006509 return ValidateTexParameterBase(context, target, pname, -1, false, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006510}
6511
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006512bool ValidateTexParameterfv(Context *context,
6513 TextureType target,
6514 GLenum pname,
6515 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006516{
Till Rathmannb8543632018-10-02 19:46:14 +02006517 return ValidateTexParameterBase(context, target, pname, -1, true, params);
Jamie Madillbe849e42017-05-02 15:49:00 -04006518}
6519
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006520bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006521{
Till Rathmannb8543632018-10-02 19:46:14 +02006522 return ValidateTexParameterBase(context, target, pname, -1, false, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006523}
6524
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006525bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006526{
Till Rathmannb8543632018-10-02 19:46:14 +02006527 return ValidateTexParameterBase(context, target, pname, -1, true, params);
6528}
6529
6530bool ValidateTexParameterIivOES(Context *context,
6531 TextureType target,
6532 GLenum pname,
6533 const GLint *params)
6534{
6535 if (context->getClientMajorVersion() < 3)
6536 {
Jamie Madille0472f32018-11-27 16:32:45 -05006537 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006538 return false;
6539 }
6540 return ValidateTexParameterBase(context, target, pname, -1, true, params);
6541}
6542
6543bool ValidateTexParameterIuivOES(Context *context,
6544 TextureType target,
6545 GLenum pname,
6546 const GLuint *params)
6547{
6548 if (context->getClientMajorVersion() < 3)
6549 {
Jamie Madille0472f32018-11-27 16:32:45 -05006550 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006551 return false;
6552 }
6553 return ValidateTexParameterBase(context, target, pname, -1, true, params);
Jamie Madillbe849e42017-05-02 15:49:00 -04006554}
6555
6556bool ValidateUseProgram(Context *context, GLuint program)
6557{
6558 if (program != 0)
6559 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04006560 Program *programObject = context->getProgramResolveLink(program);
Jamie Madillbe849e42017-05-02 15:49:00 -04006561 if (!programObject)
6562 {
6563 // ES 3.1.0 section 7.3 page 72
6564 if (context->getShader(program))
6565 {
Jamie Madille0472f32018-11-27 16:32:45 -05006566 context->validationError(GL_INVALID_OPERATION, kExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006567 return false;
6568 }
6569 else
6570 {
Jamie Madille0472f32018-11-27 16:32:45 -05006571 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006572 return false;
6573 }
6574 }
6575 if (!programObject->isLinked())
6576 {
Jamie Madille0472f32018-11-27 16:32:45 -05006577 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006578 return false;
6579 }
6580 }
Jamie Madillc3dc5d42018-12-30 12:12:04 -05006581 if (context->getState().isTransformFeedbackActiveUnpaused())
Jamie Madillbe849e42017-05-02 15:49:00 -04006582 {
6583 // ES 3.0.4 section 2.15 page 91
Jamie Madillc3e37312018-11-30 15:25:39 -05006584 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackUseProgram);
Jamie Madillbe849e42017-05-02 15:49:00 -04006585 return false;
6586 }
6587
6588 return true;
6589}
6590
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006591bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6592{
6593 if (!context->getExtensions().fence)
6594 {
Jamie Madille0472f32018-11-27 16:32:45 -05006595 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006596 return false;
6597 }
6598
6599 if (n < 0)
6600 {
Jamie Madille0472f32018-11-27 16:32:45 -05006601 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006602 return false;
6603 }
6604
6605 return true;
6606}
6607
6608bool ValidateFinishFenceNV(Context *context, GLuint fence)
6609{
6610 if (!context->getExtensions().fence)
6611 {
Jamie Madille0472f32018-11-27 16:32:45 -05006612 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006613 return false;
6614 }
6615
6616 FenceNV *fenceObject = context->getFenceNV(fence);
6617
6618 if (fenceObject == nullptr)
6619 {
Jamie Madille0472f32018-11-27 16:32:45 -05006620 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006621 return false;
6622 }
6623
6624 if (!fenceObject->isSet())
6625 {
Jamie Madille0472f32018-11-27 16:32:45 -05006626 context->validationError(GL_INVALID_OPERATION, kInvalidFenceState);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006627 return false;
6628 }
6629
6630 return true;
6631}
6632
6633bool ValidateGenFencesNV(Context *context, GLsizei n, 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 ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
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 switch (pname)
6673 {
6674 case GL_FENCE_STATUS_NV:
6675 case GL_FENCE_CONDITION_NV:
6676 break;
6677
6678 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006679 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006680 return false;
6681 }
6682
6683 return true;
6684}
6685
6686bool ValidateGetGraphicsResetStatusEXT(Context *context)
6687{
6688 if (!context->getExtensions().robustness)
6689 {
Jamie Madille0472f32018-11-27 16:32:45 -05006690 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006691 return false;
6692 }
6693
6694 return true;
6695}
6696
6697bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6698 GLuint shader,
6699 GLsizei bufsize,
6700 GLsizei *length,
6701 GLchar *source)
6702{
6703 if (!context->getExtensions().translatedShaderSource)
6704 {
Jamie Madille0472f32018-11-27 16:32:45 -05006705 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006706 return false;
6707 }
6708
6709 if (bufsize < 0)
6710 {
Jamie Madille0472f32018-11-27 16:32:45 -05006711 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006712 return false;
6713 }
6714
6715 Shader *shaderObject = context->getShader(shader);
6716
6717 if (!shaderObject)
6718 {
Jamie Madille0472f32018-11-27 16:32:45 -05006719 context->validationError(GL_INVALID_OPERATION, kInvalidShaderName);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006720 return false;
6721 }
6722
6723 return true;
6724}
6725
6726bool ValidateIsFenceNV(Context *context, GLuint fence)
6727{
6728 if (!context->getExtensions().fence)
6729 {
Jamie Madille0472f32018-11-27 16:32:45 -05006730 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006731 return false;
6732 }
6733
6734 return true;
6735}
6736
Jamie Madill007530e2017-12-28 14:27:04 -05006737bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6738{
6739 if (!context->getExtensions().fence)
6740 {
Jamie Madille0472f32018-11-27 16:32:45 -05006741 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill007530e2017-12-28 14:27:04 -05006742 return false;
6743 }
6744
6745 if (condition != GL_ALL_COMPLETED_NV)
6746 {
Jamie Madille0472f32018-11-27 16:32:45 -05006747 context->validationError(GL_INVALID_ENUM, kInvalidFenceCondition);
Jamie Madill007530e2017-12-28 14:27:04 -05006748 return false;
6749 }
6750
6751 FenceNV *fenceObject = context->getFenceNV(fence);
6752
6753 if (fenceObject == nullptr)
6754 {
Jamie Madille0472f32018-11-27 16:32:45 -05006755 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill007530e2017-12-28 14:27:04 -05006756 return false;
6757 }
6758
6759 return true;
6760}
6761
6762bool ValidateTestFenceNV(Context *context, GLuint fence)
6763{
6764 if (!context->getExtensions().fence)
6765 {
Jamie Madille0472f32018-11-27 16:32:45 -05006766 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill007530e2017-12-28 14:27:04 -05006767 return false;
6768 }
6769
6770 FenceNV *fenceObject = context->getFenceNV(fence);
6771
6772 if (fenceObject == nullptr)
6773 {
Jamie Madille0472f32018-11-27 16:32:45 -05006774 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill007530e2017-12-28 14:27:04 -05006775 return false;
6776 }
6777
6778 if (fenceObject->isSet() != GL_TRUE)
6779 {
Jamie Madille0472f32018-11-27 16:32:45 -05006780 context->validationError(GL_INVALID_OPERATION, kInvalidFenceState);
Jamie Madill007530e2017-12-28 14:27:04 -05006781 return false;
6782 }
6783
6784 return true;
6785}
6786
6787bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006788 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006789 GLsizei levels,
6790 GLenum internalformat,
6791 GLsizei width,
6792 GLsizei height)
6793{
6794 if (!context->getExtensions().textureStorage)
6795 {
Jamie Madille0472f32018-11-27 16:32:45 -05006796 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05006797 return false;
6798 }
6799
6800 if (context->getClientMajorVersion() < 3)
6801 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006802 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006803 height);
6804 }
6805
6806 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006807 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006808 1);
6809}
6810
6811bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6812{
Jonah Ryan-Davis2b0553c2019-02-08 10:07:21 -05006813 if (!context->getExtensions().instancedArraysANGLE)
Jamie Madill007530e2017-12-28 14:27:04 -05006814 {
Jamie Madille0472f32018-11-27 16:32:45 -05006815 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05006816 return false;
6817 }
6818
6819 if (index >= MAX_VERTEX_ATTRIBS)
6820 {
Jamie Madille0472f32018-11-27 16:32:45 -05006821 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madill007530e2017-12-28 14:27:04 -05006822 return false;
6823 }
6824
6825 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6826 {
6827 if (index == 0 && divisor != 0)
6828 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006829 context->validationError(GL_INVALID_OPERATION, kAttributeZeroRequiresDivisorLimitation);
Jamie Madill007530e2017-12-28 14:27:04 -05006830
6831 // We also output an error message to the debugger window if tracing is active, so
6832 // that developers can see the error message.
Jamie Madillc3e37312018-11-30 15:25:39 -05006833 ERR() << kAttributeZeroRequiresDivisorLimitation;
Jamie Madill007530e2017-12-28 14:27:04 -05006834 return false;
6835 }
6836 }
6837
6838 return true;
6839}
6840
Jonah Ryan-Davis2b0553c2019-02-08 10:07:21 -05006841bool ValidateVertexAttribDivisorEXT(Context *context, GLuint index, GLuint divisor)
6842{
6843 if (!context->getExtensions().instancedArraysEXT)
6844 {
6845 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
6846 return false;
6847 }
6848
6849 if (index >= MAX_VERTEX_ATTRIBS)
6850 {
6851 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
6852 return false;
6853 }
6854
6855 return true;
6856}
6857
Jamie Madill007530e2017-12-28 14:27:04 -05006858bool ValidateTexImage3DOES(Context *context,
6859 GLenum target,
6860 GLint level,
6861 GLenum internalformat,
6862 GLsizei width,
6863 GLsizei height,
6864 GLsizei depth,
6865 GLint border,
6866 GLenum format,
6867 GLenum type,
6868 const void *pixels)
6869{
6870 UNIMPLEMENTED(); // FIXME
6871 return false;
6872}
6873
6874bool ValidatePopGroupMarkerEXT(Context *context)
6875{
6876 if (!context->getExtensions().debugMarker)
6877 {
6878 // The debug marker calls should not set error state
6879 // However, it seems reasonable to set an error state if the extension is not enabled
Jamie Madille0472f32018-11-27 16:32:45 -05006880 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05006881 return false;
6882 }
6883
6884 return true;
6885}
6886
Jamie Madillfa920eb2018-01-04 11:45:50 -05006887bool ValidateTexStorage1DEXT(Context *context,
6888 GLenum target,
6889 GLsizei levels,
6890 GLenum internalformat,
6891 GLsizei width)
6892{
6893 UNIMPLEMENTED();
Jamie Madille0472f32018-11-27 16:32:45 -05006894 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05006895 return false;
6896}
6897
6898bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006899 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006900 GLsizei levels,
6901 GLenum internalformat,
6902 GLsizei width,
6903 GLsizei height,
6904 GLsizei depth)
6905{
6906 if (!context->getExtensions().textureStorage)
6907 {
Jamie Madille0472f32018-11-27 16:32:45 -05006908 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05006909 return false;
6910 }
6911
6912 if (context->getClientMajorVersion() < 3)
6913 {
Jamie Madille0472f32018-11-27 16:32:45 -05006914 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05006915 return false;
6916 }
6917
6918 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6919 depth);
6920}
6921
jchen1082af6202018-06-22 10:59:52 +08006922bool ValidateMaxShaderCompilerThreadsKHR(Context *context, GLuint count)
6923{
6924 if (!context->getExtensions().parallelShaderCompile)
6925 {
Jamie Madille0472f32018-11-27 16:32:45 -05006926 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
jchen1082af6202018-06-22 10:59:52 +08006927 return false;
6928 }
6929 return true;
6930}
6931
Austin Eng1bf18ce2018-10-19 15:34:02 -07006932bool ValidateMultiDrawArraysANGLE(Context *context,
6933 PrimitiveMode mode,
6934 const GLint *firsts,
6935 const GLsizei *counts,
6936 GLsizei drawcount)
6937{
6938 if (!context->getExtensions().multiDraw)
6939 {
Jamie Madille0472f32018-11-27 16:32:45 -05006940 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07006941 return false;
6942 }
6943 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
6944 {
6945 if (!ValidateDrawArrays(context, mode, firsts[drawID], counts[drawID]))
6946 {
6947 return false;
6948 }
6949 }
6950 return true;
6951}
6952
6953bool ValidateMultiDrawElementsANGLE(Context *context,
6954 PrimitiveMode mode,
6955 const GLsizei *counts,
Jamie Madill8dc27f92018-11-29 11:45:44 -05006956 DrawElementsType type,
Austin Eng3b7c9d02018-11-21 18:09:05 -08006957 const GLvoid *const *indices,
Austin Eng1bf18ce2018-10-19 15:34:02 -07006958 GLsizei drawcount)
6959{
6960 if (!context->getExtensions().multiDraw)
6961 {
Jamie Madille0472f32018-11-27 16:32:45 -05006962 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07006963 return false;
6964 }
6965 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
6966 {
Austin Eng3b7c9d02018-11-21 18:09:05 -08006967 if (!ValidateDrawElements(context, mode, counts[drawID], type, indices[drawID]))
Austin Eng1bf18ce2018-10-19 15:34:02 -07006968 {
6969 return false;
6970 }
6971 }
6972 return true;
6973}
6974
Jeff Gilbert465d6092019-01-02 16:21:18 -08006975bool ValidateProvokingVertexANGLE(Context *context, ProvokingVertex modePacked)
6976{
6977 if (!context->getExtensions().provokingVertex)
6978 {
6979 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
6980 return false;
6981 }
6982
6983 switch (modePacked)
6984 {
6985 case ProvokingVertex::FirstVertexConvention:
6986 case ProvokingVertex::LastVertexConvention:
6987 break;
6988 default:
6989 context->validationError(GL_INVALID_ENUM, kInvalidProvokingVertex);
6990 return false;
6991 }
6992
6993 return true;
6994}
6995
Jamie Madilla5410482019-01-31 19:55:55 -05006996void RecordBindTextureTypeError(Context *context, TextureType target)
6997{
6998 ASSERT(!context->getStateCache().isValidBindTextureType(target));
6999
7000 switch (target)
7001 {
7002 case TextureType::Rectangle:
7003 ASSERT(!context->getExtensions().textureRectangle);
7004 context->validationError(GL_INVALID_ENUM, kTextureRectangleNotSupported);
7005 break;
7006
7007 case TextureType::_3D:
7008 case TextureType::_2DArray:
7009 ASSERT(context->getClientMajorVersion() < 3);
7010 context->validationError(GL_INVALID_ENUM, kES3Required);
7011 break;
7012
7013 case TextureType::_2DMultisample:
7014 ASSERT(context->getClientVersion() < Version(3, 1) &&
7015 !context->getExtensions().textureMultisample);
7016 context->validationError(GL_INVALID_ENUM, kMultisampleTextureExtensionOrES31Required);
7017 break;
7018
7019 case TextureType::_2DMultisampleArray:
7020 ASSERT(!context->getExtensions().textureStorageMultisample2DArray);
7021 context->validationError(GL_INVALID_ENUM, kMultisampleArrayExtensionRequired);
7022 break;
7023
7024 case TextureType::External:
7025 ASSERT(!context->getExtensions().eglImageExternal &&
7026 !context->getExtensions().eglStreamConsumerExternal);
7027 context->validationError(GL_INVALID_ENUM, kExternalTextureNotSupported);
7028 break;
7029
7030 default:
7031 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
7032 }
7033}
7034
Jamie Madillc29968b2016-01-20 11:17:23 -05007035} // namespace gl