blob: 82c8347c48a7ab8fa35d658c098da67f2a8bceea [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:
733 case GL_DEPTH_STENCIL_OES:
734 case GL_DEPTH24_STENCIL8_OES:
735 if (context->getExtensions().depthTextures)
736 {
Jamie Madille0472f32018-11-27 16:32:45 -0500737 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400738 return false;
739 }
740 else
741 {
Jamie Madille0472f32018-11-27 16:32:45 -0500742 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400743 return false;
744 }
745 default:
Jamie Madille0472f32018-11-27 16:32:45 -0500746 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400747 return false;
748 }
749 }
750
751 // If width or height is zero, it is a no-op. Return false without setting an error.
752 return (width > 0 && height > 0);
753}
754
755bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
756{
757 switch (cap)
758 {
759 // EXT_multisample_compatibility
760 case GL_MULTISAMPLE_EXT:
761 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
762 return context->getExtensions().multisampleCompatibility;
763
764 case GL_CULL_FACE:
765 case GL_POLYGON_OFFSET_FILL:
766 case GL_SAMPLE_ALPHA_TO_COVERAGE:
767 case GL_SAMPLE_COVERAGE:
768 case GL_SCISSOR_TEST:
769 case GL_STENCIL_TEST:
770 case GL_DEPTH_TEST:
771 case GL_BLEND:
772 case GL_DITHER:
773 return true;
774
775 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
776 case GL_RASTERIZER_DISCARD:
777 return (context->getClientMajorVersion() >= 3);
778
779 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
780 case GL_DEBUG_OUTPUT:
781 return context->getExtensions().debug;
782
783 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
784 return queryOnly && context->getExtensions().bindGeneratesResource;
785
786 case GL_CLIENT_ARRAYS_ANGLE:
787 return queryOnly && context->getExtensions().clientArrays;
788
789 case GL_FRAMEBUFFER_SRGB_EXT:
790 return context->getExtensions().sRGBWriteControl;
791
792 case GL_SAMPLE_MASK:
793 return context->getClientVersion() >= Version(3, 1);
794
Geoff Langb433e872017-10-05 14:01:47 -0400795 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
Jamie Madillbe849e42017-05-02 15:49:00 -0400796 return queryOnly && context->getExtensions().robustResourceInitialization;
797
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700798 // GLES1 emulation: GLES1-specific caps
799 case GL_ALPHA_TEST:
Lingfeng Yang01074432018-04-16 10:19:51 -0700800 case GL_VERTEX_ARRAY:
801 case GL_NORMAL_ARRAY:
802 case GL_COLOR_ARRAY:
803 case GL_TEXTURE_COORD_ARRAY:
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700804 case GL_TEXTURE_2D:
Lingfeng Yangd0febe72018-05-17 22:36:52 -0700805 case GL_LIGHTING:
806 case GL_LIGHT0:
807 case GL_LIGHT1:
808 case GL_LIGHT2:
809 case GL_LIGHT3:
810 case GL_LIGHT4:
811 case GL_LIGHT5:
812 case GL_LIGHT6:
813 case GL_LIGHT7:
814 case GL_NORMALIZE:
815 case GL_RESCALE_NORMAL:
816 case GL_COLOR_MATERIAL:
Lingfeng Yang060088a2018-05-30 20:40:57 -0700817 case GL_CLIP_PLANE0:
818 case GL_CLIP_PLANE1:
819 case GL_CLIP_PLANE2:
820 case GL_CLIP_PLANE3:
821 case GL_CLIP_PLANE4:
822 case GL_CLIP_PLANE5:
Lingfeng Yang7ba3f422018-06-01 09:43:04 -0700823 case GL_FOG:
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700824 case GL_POINT_SMOOTH:
Lingfeng Yang6e5bf362018-08-15 09:53:17 -0700825 case GL_LINE_SMOOTH:
826 case GL_COLOR_LOGIC_OP:
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700827 return context->getClientVersion() < Version(2, 0);
Lingfeng Yang01074432018-04-16 10:19:51 -0700828 case GL_POINT_SIZE_ARRAY_OES:
829 return context->getClientVersion() < Version(2, 0) &&
830 context->getExtensions().pointSizeArray;
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700831 case GL_TEXTURE_CUBE_MAP:
832 return context->getClientVersion() < Version(2, 0) &&
833 context->getExtensions().textureCubeMap;
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700834 case GL_POINT_SPRITE_OES:
835 return context->getClientVersion() < Version(2, 0) &&
836 context->getExtensions().pointSprite;
Jamie Madillbe849e42017-05-02 15:49:00 -0400837 default:
838 return false;
839 }
840}
841
Geoff Langfc32e8b2017-05-31 14:16:59 -0400842// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
843// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400844bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400845{
846 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400847 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
848 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400849 {
850 return true;
851 }
852
853 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
854 if (c >= 9 && c <= 13)
855 {
856 return true;
857 }
858
859 return false;
860}
861
Geoff Langcab92ee2017-07-19 17:32:07 -0400862bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400863{
Geoff Langa71a98e2017-06-19 15:15:00 -0400864 for (size_t i = 0; i < len; i++)
865 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400866 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400867 {
868 return false;
869 }
870 }
871
872 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400873}
874
Geoff Langcab92ee2017-07-19 17:32:07 -0400875bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
876{
877 enum class ParseState
878 {
879 // Have not seen an ASCII non-whitespace character yet on
880 // this line. Possible that we might see a preprocessor
881 // directive.
882 BEGINING_OF_LINE,
883
884 // Have seen at least one ASCII non-whitespace character
885 // on this line.
886 MIDDLE_OF_LINE,
887
888 // Handling a preprocessor directive. Passes through all
889 // characters up to the end of the line. Disables comment
890 // processing.
891 IN_PREPROCESSOR_DIRECTIVE,
892
893 // Handling a single-line comment. The comment text is
894 // replaced with a single space.
895 IN_SINGLE_LINE_COMMENT,
896
897 // Handling a multi-line comment. Newlines are passed
898 // through to preserve line numbers.
899 IN_MULTI_LINE_COMMENT
900 };
901
902 ParseState state = ParseState::BEGINING_OF_LINE;
903 size_t pos = 0;
904
905 while (pos < len)
906 {
907 char c = str[pos];
908 char next = pos + 1 < len ? str[pos + 1] : 0;
909
910 // Check for newlines
911 if (c == '\n' || c == '\r')
912 {
913 if (state != ParseState::IN_MULTI_LINE_COMMENT)
914 {
915 state = ParseState::BEGINING_OF_LINE;
916 }
917
918 pos++;
919 continue;
920 }
921
922 switch (state)
923 {
924 case ParseState::BEGINING_OF_LINE:
925 if (c == ' ')
926 {
927 // Maintain the BEGINING_OF_LINE state until a non-space is seen
928 pos++;
929 }
930 else if (c == '#')
931 {
932 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
933 pos++;
934 }
935 else
936 {
937 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
938 state = ParseState::MIDDLE_OF_LINE;
939 }
940 break;
941
942 case ParseState::MIDDLE_OF_LINE:
943 if (c == '/' && next == '/')
944 {
945 state = ParseState::IN_SINGLE_LINE_COMMENT;
946 pos++;
947 }
948 else if (c == '/' && next == '*')
949 {
950 state = ParseState::IN_MULTI_LINE_COMMENT;
951 pos++;
952 }
953 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
954 {
955 // Skip line continuation characters
956 }
957 else if (!IsValidESSLCharacter(c))
958 {
959 return false;
960 }
961 pos++;
962 break;
963
964 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700965 // Line-continuation characters may not be permitted.
966 // Otherwise, just pass it through. Do not parse comments in this state.
967 if (!lineContinuationAllowed && c == '\\')
968 {
969 return false;
970 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400971 pos++;
972 break;
973
974 case ParseState::IN_SINGLE_LINE_COMMENT:
975 // Line-continuation characters are processed before comment processing.
976 // Advance string if a new line character is immediately behind
977 // line-continuation character.
978 if (c == '\\' && (next == '\n' || next == '\r'))
979 {
980 pos++;
981 }
982 pos++;
983 break;
984
985 case ParseState::IN_MULTI_LINE_COMMENT:
986 if (c == '*' && next == '/')
987 {
988 state = ParseState::MIDDLE_OF_LINE;
989 pos++;
990 }
991 pos++;
992 break;
993 }
994 }
995
996 return true;
997}
998
Jamie Madill5b772312018-03-08 20:28:32 -0500999bool ValidateWebGLNamePrefix(Context *context, const GLchar *name)
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001000{
1001 ASSERT(context->isWebGL());
1002
1003 // WebGL 1.0 [Section 6.16] GLSL Constructs
1004 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
1005 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
1006 {
Jamie Madille0472f32018-11-27 16:32:45 -05001007 context->validationError(GL_INVALID_OPERATION, kWebglBindAttribLocationReservedPrefix);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001008 return false;
1009 }
1010
1011 return true;
1012}
1013
Jamie Madill5b772312018-03-08 20:28:32 -05001014bool ValidateWebGLNameLength(Context *context, size_t length)
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001015{
1016 ASSERT(context->isWebGL());
1017
1018 if (context->isWebGL1() && length > 256)
1019 {
1020 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
1021 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
1022 // locations.
Jamie Madille0472f32018-11-27 16:32:45 -05001023 context->validationError(GL_INVALID_VALUE, kWebglNameLengthLimitExceeded);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001024
1025 return false;
1026 }
1027 else if (length > 1024)
1028 {
1029 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
1030 // uniform and attribute locations.
Jamie Madille0472f32018-11-27 16:32:45 -05001031 context->validationError(GL_INVALID_VALUE, kWebgl2NameLengthLimitExceeded);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001032 return false;
1033 }
1034
1035 return true;
1036}
1037
Jamie Madill007530e2017-12-28 14:27:04 -05001038bool ValidateMatrixMode(Context *context, GLenum matrixMode)
1039{
1040 if (!context->getExtensions().pathRendering)
1041 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001042 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05001043 return false;
1044 }
1045
1046 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
1047 {
Jamie Madille0472f32018-11-27 16:32:45 -05001048 context->validationError(GL_INVALID_ENUM, kInvalidMatrixMode);
Jamie Madill007530e2017-12-28 14:27:04 -05001049 return false;
1050 }
1051 return true;
1052}
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03001053
1054bool ValidBlendFunc(const Context *context, GLenum val)
1055{
1056 const gl::Extensions &ext = context->getExtensions();
1057
1058 // these are always valid for src and dst.
1059 switch (val)
1060 {
1061 case GL_ZERO:
1062 case GL_ONE:
1063 case GL_SRC_COLOR:
1064 case GL_ONE_MINUS_SRC_COLOR:
1065 case GL_DST_COLOR:
1066 case GL_ONE_MINUS_DST_COLOR:
1067 case GL_SRC_ALPHA:
1068 case GL_ONE_MINUS_SRC_ALPHA:
1069 case GL_DST_ALPHA:
1070 case GL_ONE_MINUS_DST_ALPHA:
1071 case GL_CONSTANT_COLOR:
1072 case GL_ONE_MINUS_CONSTANT_COLOR:
1073 case GL_CONSTANT_ALPHA:
1074 case GL_ONE_MINUS_CONSTANT_ALPHA:
1075 return true;
1076
1077 // EXT_blend_func_extended.
1078 case GL_SRC1_COLOR_EXT:
1079 case GL_SRC1_ALPHA_EXT:
1080 case GL_ONE_MINUS_SRC1_COLOR_EXT:
1081 case GL_ONE_MINUS_SRC1_ALPHA_EXT:
1082 case GL_SRC_ALPHA_SATURATE_EXT:
1083 return ext.blendFuncExtended;
1084
1085 default:
1086 return false;
1087 }
1088}
1089
1090bool ValidSrcBlendFunc(const Context *context, GLenum val)
1091{
1092 if (ValidBlendFunc(context, val))
1093 return true;
1094
1095 if (val == GL_SRC_ALPHA_SATURATE)
1096 return true;
1097
1098 return false;
1099}
1100
1101bool ValidDstBlendFunc(const Context *context, GLenum val)
1102{
1103 if (ValidBlendFunc(context, val))
1104 return true;
1105
1106 if (val == GL_SRC_ALPHA_SATURATE)
1107 {
1108 if (context->getClientMajorVersion() >= 3)
1109 return true;
1110 }
1111
1112 return false;
1113}
Jamie Madillc29968b2016-01-20 11:17:23 -05001114} // anonymous namespace
1115
Geoff Langff5b2d52016-09-07 11:32:23 -04001116bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001117 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001118 GLint level,
1119 GLenum internalformat,
1120 bool isCompressed,
1121 bool isSubImage,
1122 GLint xoffset,
1123 GLint yoffset,
1124 GLsizei width,
1125 GLsizei height,
1126 GLint border,
1127 GLenum format,
1128 GLenum type,
1129 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001130 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001131{
Jamie Madill6f38f822014-06-06 17:12:20 -04001132 if (!ValidTexture2DDestinationTarget(context, target))
1133 {
Jamie Madille0472f32018-11-27 16:32:45 -05001134 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001135 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001136 }
1137
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001138 TextureType texType = TextureTargetToType(target);
1139 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001140 {
Jamie Madill610640f2018-11-21 17:28:41 -05001141 // Error already handled.
Geoff Langb1196682014-07-23 13:47:29 -04001142 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001143 }
1144
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001145 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001146 {
Jamie Madille0472f32018-11-27 16:32:45 -05001147 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Brandon Jones6cad5662017-06-14 13:25:13 -07001148 return false;
1149 }
1150
1151 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001152 std::numeric_limits<GLsizei>::max() - yoffset < height)
1153 {
Jamie Madille0472f32018-11-27 16:32:45 -05001154 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001155 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001156 }
1157
Geoff Langaae65a42014-05-26 12:43:44 -04001158 const gl::Caps &caps = context->getCaps();
1159
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001160 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001161 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001162 case TextureType::_2D:
1163 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1164 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1165 {
Jamie Madille0472f32018-11-27 16:32:45 -05001166 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001167 return false;
1168 }
1169 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001170
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001171 case TextureType::Rectangle:
1172 ASSERT(level == 0);
1173 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1174 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1175 {
Jamie Madille0472f32018-11-27 16:32:45 -05001176 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001177 return false;
1178 }
1179 if (isCompressed)
1180 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001181 context->validationError(GL_INVALID_ENUM, kRectangleTextureCompressed);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001182 return false;
1183 }
1184 break;
1185
1186 case TextureType::CubeMap:
1187 if (!isSubImage && width != height)
1188 {
Jamie Madille0472f32018-11-27 16:32:45 -05001189 context->validationError(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001190 return false;
1191 }
1192
1193 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1194 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1195 {
Jamie Madille0472f32018-11-27 16:32:45 -05001196 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001197 return false;
1198 }
1199 break;
1200
1201 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001202 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001203 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001204 }
1205
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001206 gl::Texture *texture = context->getTargetTexture(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001207 if (!texture)
1208 {
Jamie Madille0472f32018-11-27 16:32:45 -05001209 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001210 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001211 }
1212
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001213 // Verify zero border
1214 if (border != 0)
1215 {
Jamie Madille0472f32018-11-27 16:32:45 -05001216 context->validationError(GL_INVALID_VALUE, kInvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001217 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001218 }
1219
Tim Van Patten208af3e2019-03-19 09:15:55 -06001220 bool nonEqualFormatsAllowed = false;
1221
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001222 if (isCompressed)
1223 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001224 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001225 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1226 : internalformat;
Geoff Lange88e4542018-05-03 15:05:57 -04001227
1228 const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(actualInternalFormat);
1229
1230 if (!internalFormatInfo.compressed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001231 {
Jamie Madille0472f32018-11-27 16:32:45 -05001232 context->validationError(GL_INVALID_ENUM, kInvalidInternalFormat);
Geoff Lange88e4542018-05-03 15:05:57 -04001233 return false;
1234 }
1235
1236 if (!internalFormatInfo.textureSupport(context->getClientVersion(),
1237 context->getExtensions()))
1238 {
Jamie Madille0472f32018-11-27 16:32:45 -05001239 context->validationError(GL_INVALID_ENUM, kInvalidInternalFormat);
Geoff Lange88e4542018-05-03 15:05:57 -04001240 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001241 }
Geoff Lang966c9402017-04-18 12:38:27 -04001242
1243 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001244 {
Geoff Lange88e4542018-05-03 15:05:57 -04001245 // From the OES_compressed_ETC1_RGB8_texture spec:
1246 // INVALID_OPERATION is generated by CompressedTexSubImage2D, TexSubImage2D, or
1247 // CopyTexSubImage2D if the texture image <level> bound to <target> has internal format
1248 // ETC1_RGB8_OES.
1249 if (actualInternalFormat == GL_ETC1_RGB8_OES)
1250 {
Jamie Madille0472f32018-11-27 16:32:45 -05001251 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lange88e4542018-05-03 15:05:57 -04001252 return false;
1253 }
1254
Geoff Lang966c9402017-04-18 12:38:27 -04001255 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1256 height, texture->getWidth(target, level),
1257 texture->getHeight(target, level)))
1258 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001259 context->validationError(GL_INVALID_OPERATION, kInvalidCompressedImageSize);
Geoff Lang966c9402017-04-18 12:38:27 -04001260 return false;
1261 }
1262
1263 if (format != actualInternalFormat)
1264 {
Jamie Madille0472f32018-11-27 16:32:45 -05001265 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001266 return false;
1267 }
1268 }
1269 else
1270 {
1271 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1272 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001273 context->validationError(GL_INVALID_OPERATION, kInvalidCompressedImageSize);
Geoff Lang966c9402017-04-18 12:38:27 -04001274 return false;
1275 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001276 }
1277 }
1278 else
1279 {
1280 // validate <type> by itself (used as secondary key below)
1281 switch (type)
1282 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001283 case GL_UNSIGNED_BYTE:
1284 case GL_UNSIGNED_SHORT_5_6_5:
1285 case GL_UNSIGNED_SHORT_4_4_4_4:
1286 case GL_UNSIGNED_SHORT_5_5_5_1:
1287 case GL_UNSIGNED_SHORT:
1288 case GL_UNSIGNED_INT:
1289 case GL_UNSIGNED_INT_24_8_OES:
1290 case GL_HALF_FLOAT_OES:
1291 case GL_FLOAT:
1292 break;
1293 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001294 context->validationError(GL_INVALID_ENUM, kInvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001295 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001296 }
1297
1298 // validate <format> + <type> combinations
1299 // - invalid <format> -> sets INVALID_ENUM
1300 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1301 switch (format)
1302 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001303 case GL_ALPHA:
1304 case GL_LUMINANCE:
1305 case GL_LUMINANCE_ALPHA:
1306 switch (type)
1307 {
1308 case GL_UNSIGNED_BYTE:
1309 case GL_FLOAT:
1310 case GL_HALF_FLOAT_OES:
1311 break;
1312 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001313 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001314 return false;
1315 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001316 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001317 case GL_RED:
1318 case GL_RG:
1319 if (!context->getExtensions().textureRG)
1320 {
Jamie Madille0472f32018-11-27 16:32:45 -05001321 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001322 return false;
1323 }
1324 switch (type)
1325 {
1326 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001327 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001328 case GL_FLOAT:
1329 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001330 if (!context->getExtensions().textureFloat)
1331 {
Jamie Madille0472f32018-11-27 16:32:45 -05001332 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001333 return false;
1334 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001335 break;
1336 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001337 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001338 return false;
1339 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001340 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001341 case GL_RGB:
1342 switch (type)
1343 {
1344 case GL_UNSIGNED_BYTE:
1345 case GL_UNSIGNED_SHORT_5_6_5:
1346 case GL_FLOAT:
1347 case GL_HALF_FLOAT_OES:
1348 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_RGBA:
1355 switch (type)
1356 {
1357 case GL_UNSIGNED_BYTE:
1358 case GL_UNSIGNED_SHORT_4_4_4_4:
1359 case GL_UNSIGNED_SHORT_5_5_5_1:
1360 case GL_FLOAT:
1361 case GL_HALF_FLOAT_OES:
1362 break;
1363 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001364 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001365 return false;
1366 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001367 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001368 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001369 if (!context->getExtensions().textureFormatBGRA8888)
1370 {
Jamie Madille0472f32018-11-27 16:32:45 -05001371 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001372 return false;
1373 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001374 switch (type)
1375 {
1376 case GL_UNSIGNED_BYTE:
1377 break;
1378 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001379 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001380 return false;
1381 }
1382 break;
1383 case GL_SRGB_EXT:
1384 case GL_SRGB_ALPHA_EXT:
1385 if (!context->getExtensions().sRGB)
1386 {
Jamie Madille0472f32018-11-27 16:32:45 -05001387 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001388 return false;
1389 }
1390 switch (type)
1391 {
1392 case GL_UNSIGNED_BYTE:
1393 break;
1394 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001395 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001396 return false;
1397 }
1398 break;
1399 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1400 // handled below
1401 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1402 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1403 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1404 break;
1405 case GL_DEPTH_COMPONENT:
1406 switch (type)
1407 {
1408 case GL_UNSIGNED_SHORT:
1409 case GL_UNSIGNED_INT:
1410 break;
1411 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001412 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001413 return false;
1414 }
1415 break;
1416 case GL_DEPTH_STENCIL_OES:
1417 switch (type)
1418 {
1419 case GL_UNSIGNED_INT_24_8_OES:
1420 break;
1421 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001422 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001423 return false;
1424 }
1425 break;
1426 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001427 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001428 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001429 }
1430
1431 switch (format)
1432 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001433 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1434 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1435 if (context->getExtensions().textureCompressionDXT1)
1436 {
Jamie Madille0472f32018-11-27 16:32:45 -05001437 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001438 return false;
1439 }
1440 else
1441 {
Jamie Madille0472f32018-11-27 16:32:45 -05001442 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001443 return false;
1444 }
1445 break;
1446 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1447 if (context->getExtensions().textureCompressionDXT3)
1448 {
Jamie Madille0472f32018-11-27 16:32:45 -05001449 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001450 return false;
1451 }
1452 else
1453 {
Jamie Madille0472f32018-11-27 16:32:45 -05001454 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001455 return false;
1456 }
1457 break;
1458 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1459 if (context->getExtensions().textureCompressionDXT5)
1460 {
Jamie Madille0472f32018-11-27 16:32:45 -05001461 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001462 return false;
1463 }
1464 else
1465 {
Jamie Madille0472f32018-11-27 16:32:45 -05001466 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001467 return false;
1468 }
1469 break;
1470 case GL_ETC1_RGB8_OES:
1471 if (context->getExtensions().compressedETC1RGB8Texture)
1472 {
Jamie Madille0472f32018-11-27 16:32:45 -05001473 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001474 return false;
1475 }
1476 else
1477 {
Jamie Madille0472f32018-11-27 16:32:45 -05001478 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001479 return false;
1480 }
1481 break;
1482 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001483 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1484 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1485 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1486 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001487 if (context->getExtensions().lossyETCDecode)
1488 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001489 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001490 return false;
1491 }
1492 else
1493 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001494 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001495 return false;
1496 }
1497 break;
1498 case GL_DEPTH_COMPONENT:
1499 case GL_DEPTH_STENCIL_OES:
1500 if (!context->getExtensions().depthTextures)
1501 {
Jamie Madille0472f32018-11-27 16:32:45 -05001502 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001503 return false;
1504 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001505 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001506 {
Jamie Madille0472f32018-11-27 16:32:45 -05001507 context->validationError(GL_INVALID_OPERATION, kMismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001508 return false;
1509 }
1510 // OES_depth_texture supports loading depth data and multiple levels,
1511 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001512 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001513 {
Jamie Madille0472f32018-11-27 16:32:45 -05001514 context->validationError(GL_INVALID_OPERATION, kPixelDataNotNull);
Brandon Jonesafa75152017-07-21 13:11:29 -07001515 return false;
1516 }
1517 if (level != 0)
1518 {
Jamie Madille0472f32018-11-27 16:32:45 -05001519 context->validationError(GL_INVALID_OPERATION, kLevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001520 return false;
1521 }
1522 break;
1523 default:
1524 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001525 }
1526
Geoff Lang6e898aa2017-06-02 11:17:26 -04001527 if (!isSubImage)
1528 {
1529 switch (internalformat)
1530 {
Tim Van Patten208af3e2019-03-19 09:15:55 -06001531 // Core ES 2.0 formats
1532 case GL_ALPHA:
1533 case GL_LUMINANCE:
1534 case GL_LUMINANCE_ALPHA:
1535 case GL_RGB:
1536 case GL_RGBA:
1537 break;
1538
Geoff Lang6e898aa2017-06-02 11:17:26 -04001539 case GL_RGBA32F:
1540 if (!context->getExtensions().colorBufferFloatRGBA)
1541 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001542 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001543 return false;
1544 }
Tim Van Patten208af3e2019-03-19 09:15:55 -06001545
1546 nonEqualFormatsAllowed = true;
1547
Geoff Lang6e898aa2017-06-02 11:17:26 -04001548 if (type != GL_FLOAT)
1549 {
Jamie Madille0472f32018-11-27 16:32:45 -05001550 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001551 return false;
1552 }
1553 if (format != GL_RGBA)
1554 {
Jamie Madille0472f32018-11-27 16:32:45 -05001555 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001556 return false;
1557 }
1558 break;
1559
1560 case GL_RGB32F:
1561 if (!context->getExtensions().colorBufferFloatRGB)
1562 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001563 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001564 return false;
1565 }
Tim Van Patten208af3e2019-03-19 09:15:55 -06001566
1567 nonEqualFormatsAllowed = true;
1568
Geoff Lang6e898aa2017-06-02 11:17:26 -04001569 if (type != GL_FLOAT)
1570 {
Jamie Madille0472f32018-11-27 16:32:45 -05001571 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001572 return false;
1573 }
1574 if (format != GL_RGB)
1575 {
Jamie Madille0472f32018-11-27 16:32:45 -05001576 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001577 return false;
1578 }
1579 break;
1580
Tim Van Patten208af3e2019-03-19 09:15:55 -06001581 case GL_BGRA_EXT:
1582 if (!context->getExtensions().textureFormatBGRA8888)
1583 {
1584 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
1585 return false;
1586 }
Geoff Lang6e898aa2017-06-02 11:17:26 -04001587 break;
Tim Van Patten208af3e2019-03-19 09:15:55 -06001588
1589 case GL_DEPTH_COMPONENT:
1590 case GL_DEPTH_STENCIL:
1591 if (!context->getExtensions().depthTextures)
1592 {
1593 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
1594 return false;
1595 }
1596 break;
1597
1598 case GL_RED:
1599 case GL_RG:
1600 if (!context->getExtensions().textureRG)
1601 {
1602 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
1603 return false;
1604 }
1605 break;
1606
1607 case GL_SRGB_EXT:
1608 case GL_SRGB_ALPHA_EXT:
1609 if (!context->getExtensions().sRGB)
1610 {
1611 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
1612 return false;
1613 }
1614 break;
1615
1616 default:
1617 context->validationError(GL_INVALID_VALUE, kInvalidInternalFormat);
1618 return false;
Geoff Lang6e898aa2017-06-02 11:17:26 -04001619 }
1620 }
1621
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001622 if (type == GL_FLOAT)
1623 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001624 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001625 {
Jamie Madille0472f32018-11-27 16:32:45 -05001626 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001627 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001628 }
1629 }
1630 else if (type == GL_HALF_FLOAT_OES)
1631 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001632 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001633 {
Jamie Madille0472f32018-11-27 16:32:45 -05001634 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001635 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001636 }
1637 }
1638 }
1639
Tim Van Patten208af3e2019-03-19 09:15:55 -06001640 if (isSubImage)
Geoff Langff5b2d52016-09-07 11:32:23 -04001641 {
Tim Van Patten208af3e2019-03-19 09:15:55 -06001642 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1643 if (textureInternalFormat.internalFormat == GL_NONE)
1644 {
1645 context->validationError(GL_INVALID_OPERATION, kInvalidTextureLevel);
1646 return false;
1647 }
1648
1649 if (format != GL_NONE)
1650 {
1651 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1652 textureInternalFormat.sizedInternalFormat)
1653 {
1654 context->validationError(GL_INVALID_OPERATION, kTypeMismatch);
1655 return false;
1656 }
1657 }
1658
1659 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1660 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1661 {
1662 context->validationError(GL_INVALID_VALUE, kOffsetOverflow);
1663 return false;
1664 }
1665
1666 if (width > 0 && height > 0 && pixels == nullptr &&
1667 context->getState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
1668 {
1669 context->validationError(GL_INVALID_VALUE, kPixelDataNull);
1670 return false;
1671 }
1672 }
1673 else
1674 {
1675 if (texture->getImmutableFormat())
1676 {
1677 context->validationError(GL_INVALID_OPERATION, kTextureIsImmutable);
1678 return false;
1679 }
1680 }
1681
1682 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1683 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1684 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1685 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1686 // case.
1687 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
1688 {
1689 context->validationError(GL_INVALID_OPERATION, kInvalidFormatCombination);
Geoff Langff5b2d52016-09-07 11:32:23 -04001690 return false;
1691 }
1692
Tim Van Patten208af3e2019-03-19 09:15:55 -06001693 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
1694 return ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
1695 imageSize);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001696}
1697
He Yunchaoced53ae2016-11-29 15:00:51 +08001698bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001699 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001700 GLsizei levels,
1701 GLenum internalformat,
1702 GLsizei width,
1703 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001704{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001705 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1706 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001707 {
Jamie Madille0472f32018-11-27 16:32:45 -05001708 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001709 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001710 }
1711
1712 if (width < 1 || height < 1 || levels < 1)
1713 {
Jamie Madille0472f32018-11-27 16:32:45 -05001714 context->validationError(GL_INVALID_VALUE, kTextureSizeTooSmall);
Geoff Langb1196682014-07-23 13:47:29 -04001715 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001716 }
1717
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001718 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001719 {
Jamie Madille0472f32018-11-27 16:32:45 -05001720 context->validationError(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
Geoff Langb1196682014-07-23 13:47:29 -04001721 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001722 }
1723
1724 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1725 {
Jamie Madille0472f32018-11-27 16:32:45 -05001726 context->validationError(GL_INVALID_OPERATION, kInvalidMipLevels);
Geoff Langb1196682014-07-23 13:47:29 -04001727 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001728 }
1729
Geoff Langca271392017-04-05 12:30:00 -04001730 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001731 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001732 {
Jamie Madille0472f32018-11-27 16:32:45 -05001733 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001734 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001735 }
1736
Geoff Langaae65a42014-05-26 12:43:44 -04001737 const gl::Caps &caps = context->getCaps();
1738
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001739 switch (target)
1740 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001741 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001742 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1743 static_cast<GLuint>(height) > caps.max2DTextureSize)
1744 {
Jamie Madille0472f32018-11-27 16:32:45 -05001745 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
He Yunchaoced53ae2016-11-29 15:00:51 +08001746 return false;
1747 }
1748 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001749 case TextureType::Rectangle:
Jamie Madill610640f2018-11-21 17:28:41 -05001750 if (levels != 1)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001751 {
Jamie Madille0472f32018-11-27 16:32:45 -05001752 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madill610640f2018-11-21 17:28:41 -05001753 return false;
1754 }
1755
1756 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1757 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1758 {
Jamie Madille0472f32018-11-27 16:32:45 -05001759 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001760 return false;
1761 }
1762 if (formatInfo.compressed)
1763 {
Jamie Madille0472f32018-11-27 16:32:45 -05001764 context->validationError(GL_INVALID_ENUM, kRectangleTextureCompressed);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001765 return false;
1766 }
1767 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001768 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001769 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1770 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1771 {
Jamie Madille0472f32018-11-27 16:32:45 -05001772 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
He Yunchaoced53ae2016-11-29 15:00:51 +08001773 return false;
1774 }
1775 break;
1776 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001777 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001778 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001779 }
1780
Geoff Langc0b9ef42014-07-02 10:02:37 -04001781 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001782 {
1783 if (!gl::isPow2(width) || !gl::isPow2(height))
1784 {
Jamie Madille0472f32018-11-27 16:32:45 -05001785 context->validationError(GL_INVALID_OPERATION, kDimensionsMustBePow2);
Geoff Langb1196682014-07-23 13:47:29 -04001786 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001787 }
1788 }
1789
1790 switch (internalformat)
1791 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001792 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1793 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1794 if (!context->getExtensions().textureCompressionDXT1)
1795 {
Jamie Madille0472f32018-11-27 16:32:45 -05001796 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001797 return false;
1798 }
1799 break;
1800 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1801 if (!context->getExtensions().textureCompressionDXT3)
1802 {
Jamie Madille0472f32018-11-27 16:32:45 -05001803 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001804 return false;
1805 }
1806 break;
1807 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1808 if (!context->getExtensions().textureCompressionDXT5)
1809 {
Jamie Madille0472f32018-11-27 16:32:45 -05001810 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001811 return false;
1812 }
1813 break;
1814 case GL_ETC1_RGB8_OES:
1815 if (!context->getExtensions().compressedETC1RGB8Texture)
1816 {
Jamie Madille0472f32018-11-27 16:32:45 -05001817 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001818 return false;
1819 }
1820 break;
1821 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001822 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1823 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1824 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1825 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001826 if (!context->getExtensions().lossyETCDecode)
1827 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001828 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001829 return false;
1830 }
1831 break;
1832 case GL_RGBA32F_EXT:
1833 case GL_RGB32F_EXT:
1834 case GL_ALPHA32F_EXT:
1835 case GL_LUMINANCE32F_EXT:
1836 case GL_LUMINANCE_ALPHA32F_EXT:
1837 if (!context->getExtensions().textureFloat)
1838 {
Jamie Madille0472f32018-11-27 16:32:45 -05001839 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001840 return false;
1841 }
1842 break;
1843 case GL_RGBA16F_EXT:
1844 case GL_RGB16F_EXT:
1845 case GL_ALPHA16F_EXT:
1846 case GL_LUMINANCE16F_EXT:
1847 case GL_LUMINANCE_ALPHA16F_EXT:
1848 if (!context->getExtensions().textureHalfFloat)
1849 {
Jamie Madille0472f32018-11-27 16:32:45 -05001850 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001851 return false;
1852 }
1853 break;
1854 case GL_R8_EXT:
1855 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001856 if (!context->getExtensions().textureRG)
1857 {
Jamie Madille0472f32018-11-27 16:32:45 -05001858 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang677bb6f2017-04-05 12:40:40 -04001859 return false;
1860 }
1861 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001862 case GL_R16F_EXT:
1863 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001864 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1865 {
Jamie Madille0472f32018-11-27 16:32:45 -05001866 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang677bb6f2017-04-05 12:40:40 -04001867 return false;
1868 }
1869 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001870 case GL_R32F_EXT:
1871 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001872 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001873 {
Jamie Madille0472f32018-11-27 16:32:45 -05001874 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001875 return false;
1876 }
1877 break;
1878 case GL_DEPTH_COMPONENT16:
1879 case GL_DEPTH_COMPONENT32_OES:
1880 case GL_DEPTH24_STENCIL8_OES:
1881 if (!context->getExtensions().depthTextures)
1882 {
Jamie Madille0472f32018-11-27 16:32:45 -05001883 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001884 return false;
1885 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001886 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001887 {
Jamie Madille0472f32018-11-27 16:32:45 -05001888 context->validationError(GL_INVALID_OPERATION, kInvalidTextureTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001889 return false;
1890 }
1891 // ANGLE_depth_texture only supports 1-level textures
1892 if (levels != 1)
1893 {
Jamie Madille0472f32018-11-27 16:32:45 -05001894 context->validationError(GL_INVALID_OPERATION, kInvalidMipLevels);
He Yunchaoced53ae2016-11-29 15:00:51 +08001895 return false;
1896 }
1897 break;
1898 default:
1899 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001900 }
1901
Geoff Lang691e58c2014-12-19 17:03:25 -05001902 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001903 if (!texture || texture->id() == 0)
1904 {
Jamie Madille0472f32018-11-27 16:32:45 -05001905 context->validationError(GL_INVALID_OPERATION, kMissingTexture);
Geoff Langb1196682014-07-23 13:47:29 -04001906 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001907 }
1908
Geoff Lang69cce582015-09-17 13:20:36 -04001909 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001910 {
Jamie Madille0472f32018-11-27 16:32:45 -05001911 context->validationError(GL_INVALID_OPERATION, kTextureIsImmutable);
Geoff Langb1196682014-07-23 13:47:29 -04001912 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001913 }
1914
1915 return true;
1916}
1917
He Yunchaoced53ae2016-11-29 15:00:51 +08001918bool ValidateDiscardFramebufferEXT(Context *context,
1919 GLenum target,
1920 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001921 const GLenum *attachments)
1922{
Jamie Madillc29968b2016-01-20 11:17:23 -05001923 if (!context->getExtensions().discardFramebuffer)
1924 {
Jamie Madille0472f32018-11-27 16:32:45 -05001925 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001926 return false;
1927 }
1928
Austin Kinross08332632015-05-05 13:35:47 -07001929 bool defaultFramebuffer = false;
1930
1931 switch (target)
1932 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001933 case GL_FRAMEBUFFER:
1934 defaultFramebuffer =
Jamie Madillc3dc5d42018-12-30 12:12:04 -05001935 (context->getState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
He Yunchaoced53ae2016-11-29 15:00:51 +08001936 break;
1937 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001938 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001939 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001940 }
1941
He Yunchaoced53ae2016-11-29 15:00:51 +08001942 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1943 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001944}
1945
Austin Kinrossbc781f32015-10-26 09:27:38 -07001946bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1947{
1948 if (!context->getExtensions().vertexArrayObject)
1949 {
Jamie Madille0472f32018-11-27 16:32:45 -05001950 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001951 return false;
1952 }
1953
1954 return ValidateBindVertexArrayBase(context, array);
1955}
1956
Jamie Madilld7576732017-08-26 18:49:50 -04001957bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001958{
1959 if (!context->getExtensions().vertexArrayObject)
1960 {
Jamie Madille0472f32018-11-27 16:32:45 -05001961 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001962 return false;
1963 }
1964
Olli Etuaho41997e72016-03-10 13:38:39 +02001965 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001966}
1967
Jamie Madilld7576732017-08-26 18:49:50 -04001968bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001969{
1970 if (!context->getExtensions().vertexArrayObject)
1971 {
Jamie Madille0472f32018-11-27 16:32:45 -05001972 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001973 return false;
1974 }
1975
Olli Etuaho41997e72016-03-10 13:38:39 +02001976 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001977}
1978
Jamie Madilld7576732017-08-26 18:49:50 -04001979bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001980{
1981 if (!context->getExtensions().vertexArrayObject)
1982 {
Jamie Madille0472f32018-11-27 16:32:45 -05001983 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001984 return false;
1985 }
1986
1987 return true;
1988}
Geoff Langc5629752015-12-07 16:29:04 -05001989
1990bool ValidateProgramBinaryOES(Context *context,
1991 GLuint program,
1992 GLenum binaryFormat,
1993 const void *binary,
1994 GLint length)
1995{
1996 if (!context->getExtensions().getProgramBinary)
1997 {
Jamie Madille0472f32018-11-27 16:32:45 -05001998 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001999 return false;
2000 }
2001
2002 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
2003}
2004
2005bool ValidateGetProgramBinaryOES(Context *context,
2006 GLuint program,
2007 GLsizei bufSize,
2008 GLsizei *length,
2009 GLenum *binaryFormat,
2010 void *binary)
2011{
2012 if (!context->getExtensions().getProgramBinary)
2013 {
Jamie Madille0472f32018-11-27 16:32:45 -05002014 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05002015 return false;
2016 }
2017
2018 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
2019}
Geoff Lange102fee2015-12-10 11:23:30 -05002020
Geoff Lang70d0f492015-12-10 17:45:46 -05002021static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
2022{
2023 switch (source)
2024 {
2025 case GL_DEBUG_SOURCE_API:
2026 case GL_DEBUG_SOURCE_SHADER_COMPILER:
2027 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
2028 case GL_DEBUG_SOURCE_OTHER:
2029 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
2030 return !mustBeThirdPartyOrApplication;
2031
2032 case GL_DEBUG_SOURCE_THIRD_PARTY:
2033 case GL_DEBUG_SOURCE_APPLICATION:
2034 return true;
2035
2036 default:
2037 return false;
2038 }
2039}
2040
2041static bool ValidDebugType(GLenum type)
2042{
2043 switch (type)
2044 {
2045 case GL_DEBUG_TYPE_ERROR:
2046 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
2047 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
2048 case GL_DEBUG_TYPE_PERFORMANCE:
2049 case GL_DEBUG_TYPE_PORTABILITY:
2050 case GL_DEBUG_TYPE_OTHER:
2051 case GL_DEBUG_TYPE_MARKER:
2052 case GL_DEBUG_TYPE_PUSH_GROUP:
2053 case GL_DEBUG_TYPE_POP_GROUP:
2054 return true;
2055
2056 default:
2057 return false;
2058 }
2059}
2060
2061static bool ValidDebugSeverity(GLenum severity)
2062{
2063 switch (severity)
2064 {
2065 case GL_DEBUG_SEVERITY_HIGH:
2066 case GL_DEBUG_SEVERITY_MEDIUM:
2067 case GL_DEBUG_SEVERITY_LOW:
2068 case GL_DEBUG_SEVERITY_NOTIFICATION:
2069 return true;
2070
2071 default:
2072 return false;
2073 }
2074}
2075
Geoff Lange102fee2015-12-10 11:23:30 -05002076bool ValidateDebugMessageControlKHR(Context *context,
2077 GLenum source,
2078 GLenum type,
2079 GLenum severity,
2080 GLsizei count,
2081 const GLuint *ids,
2082 GLboolean enabled)
2083{
2084 if (!context->getExtensions().debug)
2085 {
Jamie Madille0472f32018-11-27 16:32:45 -05002086 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002087 return false;
2088 }
2089
Geoff Lang70d0f492015-12-10 17:45:46 -05002090 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
2091 {
Jamie Madille0472f32018-11-27 16:32:45 -05002092 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002093 return false;
2094 }
2095
2096 if (!ValidDebugType(type) && type != GL_DONT_CARE)
2097 {
Jamie Madille0472f32018-11-27 16:32:45 -05002098 context->validationError(GL_INVALID_ENUM, kInvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002099 return false;
2100 }
2101
2102 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
2103 {
Jamie Madille0472f32018-11-27 16:32:45 -05002104 context->validationError(GL_INVALID_ENUM, kInvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05002105 return false;
2106 }
2107
2108 if (count > 0)
2109 {
2110 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
2111 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002112 context->validationError(GL_INVALID_OPERATION, kInvalidDebugSourceType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002113 return false;
2114 }
2115
2116 if (severity != GL_DONT_CARE)
2117 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002118 context->validationError(GL_INVALID_OPERATION, kInvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05002119 return false;
2120 }
2121 }
2122
Geoff Lange102fee2015-12-10 11:23:30 -05002123 return true;
2124}
2125
2126bool ValidateDebugMessageInsertKHR(Context *context,
2127 GLenum source,
2128 GLenum type,
2129 GLuint id,
2130 GLenum severity,
2131 GLsizei length,
2132 const GLchar *buf)
2133{
2134 if (!context->getExtensions().debug)
2135 {
Jamie Madille0472f32018-11-27 16:32:45 -05002136 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002137 return false;
2138 }
2139
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002140 if (!context->getState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002141 {
2142 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2143 // not generate an error.
2144 return false;
2145 }
2146
2147 if (!ValidDebugSeverity(severity))
2148 {
Jamie Madille0472f32018-11-27 16:32:45 -05002149 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002150 return false;
2151 }
2152
2153 if (!ValidDebugType(type))
2154 {
Jamie Madille0472f32018-11-27 16:32:45 -05002155 context->validationError(GL_INVALID_ENUM, kInvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002156 return false;
2157 }
2158
2159 if (!ValidDebugSource(source, true))
2160 {
Jamie Madille0472f32018-11-27 16:32:45 -05002161 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002162 return false;
2163 }
2164
2165 size_t messageLength = (length < 0) ? strlen(buf) : length;
2166 if (messageLength > context->getExtensions().maxDebugMessageLength)
2167 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002168 context->validationError(GL_INVALID_VALUE, kExceedsMaxDebugMessageLength);
Geoff Lang70d0f492015-12-10 17:45:46 -05002169 return false;
2170 }
2171
Geoff Lange102fee2015-12-10 11:23:30 -05002172 return true;
2173}
2174
2175bool ValidateDebugMessageCallbackKHR(Context *context,
2176 GLDEBUGPROCKHR callback,
2177 const void *userParam)
2178{
2179 if (!context->getExtensions().debug)
2180 {
Jamie Madille0472f32018-11-27 16:32:45 -05002181 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002182 return false;
2183 }
2184
Geoff Lange102fee2015-12-10 11:23:30 -05002185 return true;
2186}
2187
2188bool ValidateGetDebugMessageLogKHR(Context *context,
2189 GLuint count,
2190 GLsizei bufSize,
2191 GLenum *sources,
2192 GLenum *types,
2193 GLuint *ids,
2194 GLenum *severities,
2195 GLsizei *lengths,
2196 GLchar *messageLog)
2197{
2198 if (!context->getExtensions().debug)
2199 {
Jamie Madille0472f32018-11-27 16:32:45 -05002200 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002201 return false;
2202 }
2203
Geoff Lang70d0f492015-12-10 17:45:46 -05002204 if (bufSize < 0 && messageLog != nullptr)
2205 {
Jamie Madille0472f32018-11-27 16:32:45 -05002206 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002207 return false;
2208 }
2209
Geoff Lange102fee2015-12-10 11:23:30 -05002210 return true;
2211}
2212
2213bool ValidatePushDebugGroupKHR(Context *context,
2214 GLenum source,
2215 GLuint id,
2216 GLsizei length,
2217 const GLchar *message)
2218{
2219 if (!context->getExtensions().debug)
2220 {
Jamie Madille0472f32018-11-27 16:32:45 -05002221 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002222 return false;
2223 }
2224
Geoff Lang70d0f492015-12-10 17:45:46 -05002225 if (!ValidDebugSource(source, true))
2226 {
Jamie Madille0472f32018-11-27 16:32:45 -05002227 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002228 return false;
2229 }
2230
2231 size_t messageLength = (length < 0) ? strlen(message) : length;
2232 if (messageLength > context->getExtensions().maxDebugMessageLength)
2233 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002234 context->validationError(GL_INVALID_VALUE, kExceedsMaxDebugMessageLength);
Geoff Lang70d0f492015-12-10 17:45:46 -05002235 return false;
2236 }
2237
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002238 size_t currentStackSize = context->getState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002239 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2240 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002241 context->validationError(GL_STACK_OVERFLOW, kExceedsMaxDebugGroupStackDepth);
Geoff Lang70d0f492015-12-10 17:45:46 -05002242 return false;
2243 }
2244
Geoff Lange102fee2015-12-10 11:23:30 -05002245 return true;
2246}
2247
2248bool ValidatePopDebugGroupKHR(Context *context)
2249{
2250 if (!context->getExtensions().debug)
2251 {
Jamie Madille0472f32018-11-27 16:32:45 -05002252 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002253 return false;
2254 }
2255
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002256 size_t currentStackSize = context->getState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002257 if (currentStackSize <= 1)
2258 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002259 context->validationError(GL_STACK_UNDERFLOW, kCannotPopDefaultDebugGroup);
Geoff Lang70d0f492015-12-10 17:45:46 -05002260 return false;
2261 }
2262
2263 return true;
2264}
2265
2266static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2267{
2268 switch (identifier)
2269 {
2270 case GL_BUFFER:
2271 if (context->getBuffer(name) == nullptr)
2272 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002273 context->validationError(GL_INVALID_VALUE, kInvalidBufferName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002274 return false;
2275 }
2276 return true;
2277
2278 case GL_SHADER:
2279 if (context->getShader(name) == nullptr)
2280 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002281 context->validationError(GL_INVALID_VALUE, kInvalidShaderName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002282 return false;
2283 }
2284 return true;
2285
2286 case GL_PROGRAM:
Jamie Madill44a6fbf2018-10-02 13:38:56 -04002287 if (context->getProgramNoResolveLink(name) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002288 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002289 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002290 return false;
2291 }
2292 return true;
2293
2294 case GL_VERTEX_ARRAY:
2295 if (context->getVertexArray(name) == nullptr)
2296 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002297 context->validationError(GL_INVALID_VALUE, kInvalidVertexArrayName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002298 return false;
2299 }
2300 return true;
2301
2302 case GL_QUERY:
2303 if (context->getQuery(name) == nullptr)
2304 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002305 context->validationError(GL_INVALID_VALUE, kInvalidQueryName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002306 return false;
2307 }
2308 return true;
2309
2310 case GL_TRANSFORM_FEEDBACK:
2311 if (context->getTransformFeedback(name) == nullptr)
2312 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002313 context->validationError(GL_INVALID_VALUE, kInvalidTransformFeedbackName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002314 return false;
2315 }
2316 return true;
2317
2318 case GL_SAMPLER:
2319 if (context->getSampler(name) == nullptr)
2320 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002321 context->validationError(GL_INVALID_VALUE, kInvalidSamplerName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002322 return false;
2323 }
2324 return true;
2325
2326 case GL_TEXTURE:
2327 if (context->getTexture(name) == nullptr)
2328 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002329 context->validationError(GL_INVALID_VALUE, kInvalidTextureName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002330 return false;
2331 }
2332 return true;
2333
2334 case GL_RENDERBUFFER:
2335 if (context->getRenderbuffer(name) == nullptr)
2336 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002337 context->validationError(GL_INVALID_VALUE, kInvalidRenderbufferName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002338 return false;
2339 }
2340 return true;
2341
2342 case GL_FRAMEBUFFER:
2343 if (context->getFramebuffer(name) == nullptr)
2344 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002345 context->validationError(GL_INVALID_VALUE, kInvalidFramebufferName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002346 return false;
2347 }
2348 return true;
2349
2350 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05002351 context->validationError(GL_INVALID_ENUM, kInvalidIndentifier);
Geoff Lang70d0f492015-12-10 17:45:46 -05002352 return false;
2353 }
Geoff Lange102fee2015-12-10 11:23:30 -05002354}
2355
Martin Radev9d901792016-07-15 15:58:58 +03002356static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2357{
2358 size_t labelLength = 0;
2359
2360 if (length < 0)
2361 {
2362 if (label != nullptr)
2363 {
2364 labelLength = strlen(label);
2365 }
2366 }
2367 else
2368 {
2369 labelLength = static_cast<size_t>(length);
2370 }
2371
2372 if (labelLength > context->getExtensions().maxLabelLength)
2373 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002374 context->validationError(GL_INVALID_VALUE, kExceedsMaxLabelLength);
Martin Radev9d901792016-07-15 15:58:58 +03002375 return false;
2376 }
2377
2378 return true;
2379}
2380
Geoff Lange102fee2015-12-10 11:23:30 -05002381bool ValidateObjectLabelKHR(Context *context,
2382 GLenum identifier,
2383 GLuint name,
2384 GLsizei length,
2385 const GLchar *label)
2386{
2387 if (!context->getExtensions().debug)
2388 {
Jamie Madille0472f32018-11-27 16:32:45 -05002389 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002390 return false;
2391 }
2392
Geoff Lang70d0f492015-12-10 17:45:46 -05002393 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2394 {
2395 return false;
2396 }
2397
Martin Radev9d901792016-07-15 15:58:58 +03002398 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002399 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002400 return false;
2401 }
2402
Geoff Lange102fee2015-12-10 11:23:30 -05002403 return true;
2404}
2405
2406bool ValidateGetObjectLabelKHR(Context *context,
2407 GLenum identifier,
2408 GLuint name,
2409 GLsizei bufSize,
2410 GLsizei *length,
2411 GLchar *label)
2412{
2413 if (!context->getExtensions().debug)
2414 {
Jamie Madille0472f32018-11-27 16:32:45 -05002415 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002416 return false;
2417 }
2418
Geoff Lang70d0f492015-12-10 17:45:46 -05002419 if (bufSize < 0)
2420 {
Jamie Madille0472f32018-11-27 16:32:45 -05002421 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002422 return false;
2423 }
2424
2425 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2426 {
2427 return false;
2428 }
2429
Martin Radev9d901792016-07-15 15:58:58 +03002430 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002431}
2432
2433static bool ValidateObjectPtrName(Context *context, const void *ptr)
2434{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002435 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002436 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002437 context->validationError(GL_INVALID_VALUE, kInvalidSyncPointer);
Geoff Lang70d0f492015-12-10 17:45:46 -05002438 return false;
2439 }
2440
Geoff Lange102fee2015-12-10 11:23:30 -05002441 return true;
2442}
2443
2444bool ValidateObjectPtrLabelKHR(Context *context,
2445 const void *ptr,
2446 GLsizei length,
2447 const GLchar *label)
2448{
2449 if (!context->getExtensions().debug)
2450 {
Jamie Madille0472f32018-11-27 16:32:45 -05002451 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002452 return false;
2453 }
2454
Geoff Lang70d0f492015-12-10 17:45:46 -05002455 if (!ValidateObjectPtrName(context, ptr))
2456 {
2457 return false;
2458 }
2459
Martin Radev9d901792016-07-15 15:58:58 +03002460 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002461 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002462 return false;
2463 }
2464
Geoff Lange102fee2015-12-10 11:23:30 -05002465 return true;
2466}
2467
2468bool ValidateGetObjectPtrLabelKHR(Context *context,
2469 const void *ptr,
2470 GLsizei bufSize,
2471 GLsizei *length,
2472 GLchar *label)
2473{
2474 if (!context->getExtensions().debug)
2475 {
Jamie Madille0472f32018-11-27 16:32:45 -05002476 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002477 return false;
2478 }
2479
Geoff Lang70d0f492015-12-10 17:45:46 -05002480 if (bufSize < 0)
2481 {
Jamie Madille0472f32018-11-27 16:32:45 -05002482 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002483 return false;
2484 }
2485
2486 if (!ValidateObjectPtrName(context, ptr))
2487 {
2488 return false;
2489 }
2490
Martin Radev9d901792016-07-15 15:58:58 +03002491 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002492}
2493
2494bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2495{
2496 if (!context->getExtensions().debug)
2497 {
Jamie Madille0472f32018-11-27 16:32:45 -05002498 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002499 return false;
2500 }
2501
Geoff Lang70d0f492015-12-10 17:45:46 -05002502 // TODO: represent this in Context::getQueryParameterInfo.
2503 switch (pname)
2504 {
2505 case GL_DEBUG_CALLBACK_FUNCTION:
2506 case GL_DEBUG_CALLBACK_USER_PARAM:
2507 break;
2508
2509 default:
Jamie Madille0472f32018-11-27 16:32:45 -05002510 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002511 return false;
2512 }
2513
Geoff Lange102fee2015-12-10 11:23:30 -05002514 return true;
2515}
Jamie Madillc29968b2016-01-20 11:17:23 -05002516
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07002517bool ValidateGetPointervRobustANGLERobustANGLE(Context *context,
2518 GLenum pname,
2519 GLsizei bufSize,
2520 GLsizei *length,
2521 void **params)
2522{
2523 UNIMPLEMENTED();
2524 return false;
2525}
2526
Jamie Madillc29968b2016-01-20 11:17:23 -05002527bool ValidateBlitFramebufferANGLE(Context *context,
2528 GLint srcX0,
2529 GLint srcY0,
2530 GLint srcX1,
2531 GLint srcY1,
2532 GLint dstX0,
2533 GLint dstY0,
2534 GLint dstX1,
2535 GLint dstY1,
2536 GLbitfield mask,
2537 GLenum filter)
2538{
2539 if (!context->getExtensions().framebufferBlit)
2540 {
Jamie Madille0472f32018-11-27 16:32:45 -05002541 context->validationError(GL_INVALID_OPERATION, kBlitExtensionNotAvailable);
Jamie Madillc29968b2016-01-20 11:17:23 -05002542 return false;
2543 }
2544
2545 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2546 {
2547 // TODO(jmadill): Determine if this should be available on other implementations.
Jamie Madille0472f32018-11-27 16:32:45 -05002548 context->validationError(GL_INVALID_OPERATION, kBlitExtensionScaleOrFlip);
Jamie Madillc29968b2016-01-20 11:17:23 -05002549 return false;
2550 }
2551
2552 if (filter == GL_LINEAR)
2553 {
Jamie Madille0472f32018-11-27 16:32:45 -05002554 context->validationError(GL_INVALID_ENUM, kBlitExtensionLinear);
Jamie Madillc29968b2016-01-20 11:17:23 -05002555 return false;
2556 }
2557
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002558 Framebuffer *readFramebuffer = context->getState().getReadFramebuffer();
2559 Framebuffer *drawFramebuffer = context->getState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002560
2561 if (mask & GL_COLOR_BUFFER_BIT)
2562 {
2563 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2564 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2565
2566 if (readColorAttachment && drawColorAttachment)
2567 {
2568 if (!(readColorAttachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002569 readColorAttachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002570 readColorAttachment->type() != GL_RENDERBUFFER &&
2571 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2572 {
Jamie Madill610640f2018-11-21 17:28:41 -05002573 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002574 kBlitExtensionFromInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002575 return false;
2576 }
2577
Geoff Langa15472a2015-08-11 11:48:03 -04002578 for (size_t drawbufferIdx = 0;
2579 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002580 {
Geoff Langa15472a2015-08-11 11:48:03 -04002581 const FramebufferAttachment *attachment =
2582 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2583 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002584 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002585 if (!(attachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002586 attachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002587 attachment->type() != GL_RENDERBUFFER &&
2588 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2589 {
Jamie Madill610640f2018-11-21 17:28:41 -05002590 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002591 kBlitExtensionToInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002592 return false;
2593 }
2594
2595 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002596 if (!Format::EquivalentForBlit(attachment->getFormat(),
2597 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002598 {
Jamie Madill610640f2018-11-21 17:28:41 -05002599 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002600 kBlitExtensionFormatMismatch);
Jamie Madillc29968b2016-01-20 11:17:23 -05002601 return false;
2602 }
2603 }
2604 }
2605
Jamie Madill427064d2018-04-13 16:20:34 -04002606 GLint samples = readFramebuffer->getSamples(context);
Jamie Madille98b1b52018-03-08 09:47:23 -05002607 if (samples != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002608 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2609 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2610 {
Jamie Madill610640f2018-11-21 17:28:41 -05002611 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002612 kBlitExtensionMultisampledWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002613 return false;
2614 }
2615 }
2616 }
2617
2618 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2619 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2620 for (size_t i = 0; i < 2; i++)
2621 {
2622 if (mask & masks[i])
2623 {
2624 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002625 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002626 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002627 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002628
2629 if (readBuffer && drawBuffer)
2630 {
2631 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2632 dstX0, dstY0, dstX1, dstY1))
2633 {
2634 // only whole-buffer copies are permitted
Jamie Madill610640f2018-11-21 17:28:41 -05002635 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002636 kBlitExtensionDepthStencilWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002637 return false;
2638 }
2639
2640 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2641 {
Jamie Madill610640f2018-11-21 17:28:41 -05002642 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002643 kBlitExtensionMultisampledDepthOrStencil);
Jamie Madillc29968b2016-01-20 11:17:23 -05002644 return false;
2645 }
2646 }
2647 }
2648 }
2649
2650 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2651 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002652}
Jamie Madillc29968b2016-01-20 11:17:23 -05002653
Jamie Madill5b772312018-03-08 20:28:32 -05002654bool ValidateClear(Context *context, GLbitfield mask)
Jamie Madillc29968b2016-01-20 11:17:23 -05002655{
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002656 Framebuffer *fbo = context->getState().getDrawFramebuffer();
Olli Etuaho94c91a92018-07-19 15:10:24 +03002657 const Extensions &extensions = context->getExtensions();
Jamie Madille98b1b52018-03-08 09:47:23 -05002658
Jamie Madill427064d2018-04-13 16:20:34 -04002659 if (!ValidateFramebufferComplete(context, fbo))
Jamie Madillc29968b2016-01-20 11:17:23 -05002660 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002661 return false;
2662 }
2663
2664 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2665 {
Jamie Madille0472f32018-11-27 16:32:45 -05002666 context->validationError(GL_INVALID_VALUE, kInvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002667 return false;
2668 }
2669
Olli Etuaho94c91a92018-07-19 15:10:24 +03002670 if (extensions.webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
Geoff Lang76e65652017-03-27 14:58:02 -04002671 {
2672 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2673 GL_SIGNED_NORMALIZED};
2674
Corentin Wallez59c41592017-07-11 13:19:54 -04002675 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002676 drawBufferIdx++)
2677 {
2678 if (!ValidateWebGLFramebufferAttachmentClearType(
2679 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2680 {
2681 return false;
2682 }
2683 }
2684 }
2685
Olli Etuaho94c91a92018-07-19 15:10:24 +03002686 if (extensions.multiview && extensions.disjointTimerQuery)
2687 {
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002688 const State &state = context->getState();
Olli Etuaho94c91a92018-07-19 15:10:24 +03002689 Framebuffer *framebuffer = state.getDrawFramebuffer();
2690 if (framebuffer->getNumViews() > 1 && state.isQueryActive(QueryType::TimeElapsed))
2691 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002692 context->validationError(GL_INVALID_OPERATION, kMultiviewTimerQuery);
Olli Etuaho94c91a92018-07-19 15:10:24 +03002693 return false;
2694 }
2695 }
2696
Jamie Madillc29968b2016-01-20 11:17:23 -05002697 return true;
2698}
2699
Jamie Madill5b772312018-03-08 20:28:32 -05002700bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002701{
2702 if (!context->getExtensions().drawBuffers)
2703 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002704 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05002705 return false;
2706 }
2707
2708 return ValidateDrawBuffersBase(context, n, bufs);
2709}
2710
Jamie Madill73a84962016-02-12 09:27:23 -05002711bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002712 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002713 GLint level,
2714 GLint internalformat,
2715 GLsizei width,
2716 GLsizei height,
2717 GLint border,
2718 GLenum format,
2719 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002720 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002721{
Martin Radev1be913c2016-07-11 17:59:16 +03002722 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002723 {
2724 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002725 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002726 }
2727
Martin Radev1be913c2016-07-11 17:59:16 +03002728 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002729 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002730 0, 0, width, height, 1, border, format, type, -1,
2731 pixels);
2732}
2733
Brandon Jones416aaf92018-04-10 08:10:16 -07002734bool ValidateTexImage2DRobustANGLE(Context *context,
2735 TextureTarget target,
2736 GLint level,
2737 GLint internalformat,
2738 GLsizei width,
2739 GLsizei height,
2740 GLint border,
2741 GLenum format,
2742 GLenum type,
2743 GLsizei bufSize,
2744 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002745{
2746 if (!ValidateRobustEntryPoint(context, bufSize))
2747 {
2748 return false;
2749 }
2750
2751 if (context->getClientMajorVersion() < 3)
2752 {
2753 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2754 0, 0, width, height, border, format, type, bufSize,
2755 pixels);
2756 }
2757
2758 ASSERT(context->getClientMajorVersion() >= 3);
2759 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2760 0, 0, width, height, 1, border, format, type, bufSize,
2761 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002762}
2763
2764bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002765 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002766 GLint level,
2767 GLint xoffset,
2768 GLint yoffset,
2769 GLsizei width,
2770 GLsizei height,
2771 GLenum format,
2772 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002773 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002774{
2775
Martin Radev1be913c2016-07-11 17:59:16 +03002776 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002777 {
2778 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002779 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002780 }
2781
Martin Radev1be913c2016-07-11 17:59:16 +03002782 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002783 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002784 yoffset, 0, width, height, 1, 0, format, type, -1,
2785 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002786}
2787
Geoff Langc52f6f12016-10-14 10:18:00 -04002788bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002789 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002790 GLint level,
2791 GLint xoffset,
2792 GLint yoffset,
2793 GLsizei width,
2794 GLsizei height,
2795 GLenum format,
2796 GLenum type,
2797 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002798 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002799{
2800 if (!ValidateRobustEntryPoint(context, bufSize))
2801 {
2802 return false;
2803 }
2804
2805 if (context->getClientMajorVersion() < 3)
2806 {
2807 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2808 yoffset, width, height, 0, format, type, bufSize,
2809 pixels);
2810 }
2811
2812 ASSERT(context->getClientMajorVersion() >= 3);
2813 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2814 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2815 pixels);
2816}
2817
Jamie Madill73a84962016-02-12 09:27:23 -05002818bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002819 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002820 GLint level,
2821 GLenum internalformat,
2822 GLsizei width,
2823 GLsizei height,
2824 GLint border,
2825 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002826 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002827{
Martin Radev1be913c2016-07-11 17:59:16 +03002828 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002829 {
2830 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002831 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002832 {
2833 return false;
2834 }
2835 }
2836 else
2837 {
Martin Radev1be913c2016-07-11 17:59:16 +03002838 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002839 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002840 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002841 data))
2842 {
2843 return false;
2844 }
2845 }
2846
Geoff Langca271392017-04-05 12:30:00 -04002847 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jamie Madillca2ff382018-07-11 09:01:17 -04002848
2849 GLuint blockSize = 0;
2850 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002851 {
Jamie Madille0472f32018-11-27 16:32:45 -05002852 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002853 return false;
2854 }
2855
Jamie Madillca2ff382018-07-11 09:01:17 -04002856 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002857 {
Jamie Madille0472f32018-11-27 16:32:45 -05002858 context->validationError(GL_INVALID_VALUE, kCompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002859 return false;
2860 }
2861
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002862 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002863 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002864 context->validationError(GL_INVALID_ENUM, kRectangleTextureCompressed);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002865 return false;
2866 }
2867
Jamie Madill73a84962016-02-12 09:27:23 -05002868 return true;
2869}
2870
Corentin Wallezb2931602017-04-11 15:58:57 -04002871bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002872 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002873 GLint level,
2874 GLenum internalformat,
2875 GLsizei width,
2876 GLsizei height,
2877 GLint border,
2878 GLsizei imageSize,
2879 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002880 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002881{
2882 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2883 {
2884 return false;
2885 }
2886
2887 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2888 border, imageSize, data);
2889}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002890
Corentin Wallezb2931602017-04-11 15:58:57 -04002891bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002892 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002893 GLint level,
2894 GLint xoffset,
2895 GLint yoffset,
2896 GLsizei width,
2897 GLsizei height,
2898 GLenum format,
2899 GLsizei imageSize,
2900 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002901 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002902{
2903 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2904 {
2905 return false;
2906 }
2907
2908 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2909 format, imageSize, data);
2910}
2911
Jamie Madill73a84962016-02-12 09:27:23 -05002912bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002913 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002914 GLint level,
2915 GLint xoffset,
2916 GLint yoffset,
2917 GLsizei width,
2918 GLsizei height,
2919 GLenum format,
2920 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002921 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002922{
Martin Radev1be913c2016-07-11 17:59:16 +03002923 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002924 {
2925 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002926 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002927 {
2928 return false;
2929 }
2930 }
2931 else
2932 {
Martin Radev1be913c2016-07-11 17:59:16 +03002933 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002934 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002935 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002936 data))
2937 {
2938 return false;
2939 }
2940 }
2941
Geoff Langca271392017-04-05 12:30:00 -04002942 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jamie Madillca2ff382018-07-11 09:01:17 -04002943 GLuint blockSize = 0;
2944 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002945 {
Jamie Madille0472f32018-11-27 16:32:45 -05002946 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002947 return false;
2948 }
2949
Jamie Madillca2ff382018-07-11 09:01:17 -04002950 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002951 {
Jamie Madille0472f32018-11-27 16:32:45 -05002952 context->validationError(GL_INVALID_VALUE, kInvalidCompressedImageSize);
Jamie Madill73a84962016-02-12 09:27:23 -05002953 return false;
2954 }
2955
2956 return true;
2957}
2958
Corentin Wallez336129f2017-10-17 15:55:40 -04002959bool ValidateGetBufferPointervOES(Context *context,
2960 BufferBinding target,
2961 GLenum pname,
2962 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002963{
Jamie Madillc3e37312018-11-30 15:25:39 -05002964 if (!context->getExtensions().mapBuffer)
2965 {
2966 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
2967 return false;
2968 }
2969
Geoff Lang496c02d2016-10-20 11:38:11 -07002970 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002971}
2972
Corentin Wallez336129f2017-10-17 15:55:40 -04002973bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03002974{
2975 if (!context->getExtensions().mapBuffer)
2976 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002977 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03002978 return false;
2979 }
2980
Corentin Walleze4477002017-12-01 14:39:58 -05002981 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03002982 {
Jamie Madille0472f32018-11-27 16:32:45 -05002983 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002984 return false;
2985 }
2986
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002987 Buffer *buffer = context->getState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002988
2989 if (buffer == nullptr)
2990 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002991 context->validationError(GL_INVALID_OPERATION, kBufferNotMappable);
Olli Etuaho4f667482016-03-30 15:56:35 +03002992 return false;
2993 }
2994
2995 if (access != GL_WRITE_ONLY_OES)
2996 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002997 context->validationError(GL_INVALID_ENUM, kInvalidAccessBits);
Olli Etuaho4f667482016-03-30 15:56:35 +03002998 return false;
2999 }
3000
3001 if (buffer->isMapped())
3002 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003003 context->validationError(GL_INVALID_OPERATION, kBufferAlreadyMapped);
Olli Etuaho4f667482016-03-30 15:56:35 +03003004 return false;
3005 }
3006
Geoff Lang79f71042017-08-14 16:43:43 -04003007 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003008}
3009
Corentin Wallez336129f2017-10-17 15:55:40 -04003010bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03003011{
3012 if (!context->getExtensions().mapBuffer)
3013 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003014 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03003015 return false;
3016 }
3017
3018 return ValidateUnmapBufferBase(context, target);
3019}
3020
3021bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003022 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003023 GLintptr offset,
3024 GLsizeiptr length,
3025 GLbitfield access)
3026{
3027 if (!context->getExtensions().mapBufferRange)
3028 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003029 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03003030 return false;
3031 }
3032
3033 return ValidateMapBufferRangeBase(context, target, offset, length, access);
3034}
3035
Corentin Wallez336129f2017-10-17 15:55:40 -04003036bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04003037{
Jamie Madillc3dc5d42018-12-30 12:12:04 -05003038 Buffer *buffer = context->getState().getTargetBuffer(target);
Geoff Lang79f71042017-08-14 16:43:43 -04003039 ASSERT(buffer != nullptr);
3040
3041 // Check if this buffer is currently being used as a transform feedback output buffer
Jamie Madillc3dc5d42018-12-30 12:12:04 -05003042 TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
Geoff Lang79f71042017-08-14 16:43:43 -04003043 if (transformFeedback != nullptr && transformFeedback->isActive())
3044 {
3045 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
3046 {
3047 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
3048 if (transformFeedbackBuffer.get() == buffer)
3049 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003050 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
Geoff Lang79f71042017-08-14 16:43:43 -04003051 return false;
3052 }
3053 }
3054 }
3055
James Darpiniane8a93c62018-01-04 18:02:24 -08003056 if (context->getExtensions().webglCompatibility &&
3057 buffer->isBoundForTransformFeedbackAndOtherUse())
3058 {
Jamie Madille0472f32018-11-27 16:32:45 -05003059 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08003060 return false;
3061 }
3062
Geoff Lang79f71042017-08-14 16:43:43 -04003063 return true;
3064}
3065
Olli Etuaho4f667482016-03-30 15:56:35 +03003066bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003067 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003068 GLintptr offset,
3069 GLsizeiptr length)
3070{
3071 if (!context->getExtensions().mapBufferRange)
3072 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003073 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03003074 return false;
3075 }
3076
3077 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
3078}
3079
Geoff Langd8605522016-04-13 10:19:12 -04003080bool ValidateBindUniformLocationCHROMIUM(Context *context,
3081 GLuint program,
3082 GLint location,
3083 const GLchar *name)
3084{
3085 if (!context->getExtensions().bindUniformLocation)
3086 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003087 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langd8605522016-04-13 10:19:12 -04003088 return false;
3089 }
3090
3091 Program *programObject = GetValidProgram(context, program);
3092 if (!programObject)
3093 {
3094 return false;
3095 }
3096
3097 if (location < 0)
3098 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003099 context->validationError(GL_INVALID_VALUE, kNegativeLocation);
Geoff Langd8605522016-04-13 10:19:12 -04003100 return false;
3101 }
3102
3103 const Caps &caps = context->getCaps();
3104 if (static_cast<size_t>(location) >=
3105 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3106 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003107 context->validationError(GL_INVALID_VALUE, kInvalidBindUniformLocation);
Geoff Langd8605522016-04-13 10:19:12 -04003108 return false;
3109 }
3110
Geoff Langfc32e8b2017-05-31 14:16:59 -04003111 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3112 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003113 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003114 {
Jamie Madille0472f32018-11-27 16:32:45 -05003115 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003116 return false;
3117 }
3118
Geoff Langd8605522016-04-13 10:19:12 -04003119 if (strncmp(name, "gl_", 3) == 0)
3120 {
Jamie Madille0472f32018-11-27 16:32:45 -05003121 context->validationError(GL_INVALID_VALUE, kNameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003122 return false;
3123 }
3124
3125 return true;
3126}
3127
Jamie Madille2e406c2016-06-02 13:04:10 -04003128bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003129{
3130 if (!context->getExtensions().framebufferMixedSamples)
3131 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003132 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänena797e062016-05-12 15:23:40 +03003133 return false;
3134 }
3135 switch (components)
3136 {
3137 case GL_RGB:
3138 case GL_RGBA:
3139 case GL_ALPHA:
3140 case GL_NONE:
3141 break;
3142 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003143 context->validationError(GL_INVALID_ENUM, kInvalidCoverageComponents);
Sami Väisänena797e062016-05-12 15:23:40 +03003144 return false;
3145 }
3146
3147 return true;
3148}
3149
Sami Väisänene45e53b2016-05-25 10:36:04 +03003150// CHROMIUM_path_rendering
3151
Jamie Madill007530e2017-12-28 14:27:04 -05003152bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003153{
Jamie Madill007530e2017-12-28 14:27:04 -05003154 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003155 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003156 return false;
3157 }
Jamie Madill007530e2017-12-28 14:27:04 -05003158
Sami Väisänene45e53b2016-05-25 10:36:04 +03003159 if (matrix == nullptr)
3160 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003161 context->validationError(GL_INVALID_OPERATION, kInvalidPathMatrix);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003162 return false;
3163 }
Jamie Madill007530e2017-12-28 14:27:04 -05003164
Sami Väisänene45e53b2016-05-25 10:36:04 +03003165 return true;
3166}
3167
Jamie Madill007530e2017-12-28 14:27:04 -05003168bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003169{
Jamie Madill007530e2017-12-28 14:27:04 -05003170 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003171}
3172
Jamie Madill007530e2017-12-28 14:27:04 -05003173bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003174{
3175 if (!context->getExtensions().pathRendering)
3176 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003177 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003178 return false;
3179 }
3180
3181 // range = 0 is undefined in NV_path_rendering.
3182 // we add stricter semantic check here and require a non zero positive range.
3183 if (range <= 0)
3184 {
Jamie Madille0472f32018-11-27 16:32:45 -05003185 context->validationError(GL_INVALID_VALUE, kInvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003186 return false;
3187 }
3188
3189 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3190 {
Jamie Madille0472f32018-11-27 16:32:45 -05003191 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003192 return false;
3193 }
3194
3195 return true;
3196}
3197
Jamie Madill007530e2017-12-28 14:27:04 -05003198bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003199{
3200 if (!context->getExtensions().pathRendering)
3201 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003202 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003203 return false;
3204 }
3205
3206 // range = 0 is undefined in NV_path_rendering.
3207 // we add stricter semantic check here and require a non zero positive range.
3208 if (range <= 0)
3209 {
Jamie Madille0472f32018-11-27 16:32:45 -05003210 context->validationError(GL_INVALID_VALUE, kInvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003211 return false;
3212 }
3213
3214 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3215 checkedRange += range;
3216
3217 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3218 {
Jamie Madille0472f32018-11-27 16:32:45 -05003219 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003220 return false;
3221 }
3222 return true;
3223}
3224
Jamie Madill007530e2017-12-28 14:27:04 -05003225bool ValidatePathCommandsCHROMIUM(Context *context,
3226 GLuint path,
3227 GLsizei numCommands,
3228 const GLubyte *commands,
3229 GLsizei numCoords,
3230 GLenum coordType,
3231 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003232{
3233 if (!context->getExtensions().pathRendering)
3234 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003235 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003236 return false;
3237 }
Brandon Jones59770802018-04-02 13:18:42 -07003238 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003239 {
Jamie Madille0472f32018-11-27 16:32:45 -05003240 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003241 return false;
3242 }
3243
3244 if (numCommands < 0)
3245 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003246 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCommands);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003247 return false;
3248 }
3249 else if (numCommands > 0)
3250 {
3251 if (!commands)
3252 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003253 context->validationError(GL_INVALID_VALUE, kInvalidPathCommandsArray);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003254 return false;
3255 }
3256 }
3257
3258 if (numCoords < 0)
3259 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003260 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCoords);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003261 return false;
3262 }
3263 else if (numCoords > 0)
3264 {
3265 if (!coords)
3266 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003267 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCoordsArray);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003268 return false;
3269 }
3270 }
3271
3272 std::uint32_t coordTypeSize = 0;
3273 switch (coordType)
3274 {
3275 case GL_BYTE:
3276 coordTypeSize = sizeof(GLbyte);
3277 break;
3278
3279 case GL_UNSIGNED_BYTE:
3280 coordTypeSize = sizeof(GLubyte);
3281 break;
3282
3283 case GL_SHORT:
3284 coordTypeSize = sizeof(GLshort);
3285 break;
3286
3287 case GL_UNSIGNED_SHORT:
3288 coordTypeSize = sizeof(GLushort);
3289 break;
3290
3291 case GL_FLOAT:
3292 coordTypeSize = sizeof(GLfloat);
3293 break;
3294
3295 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003296 context->validationError(GL_INVALID_ENUM, kInvalidPathCoordinateType);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003297 return false;
3298 }
3299
3300 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3301 checkedSize += (coordTypeSize * numCoords);
3302 if (!checkedSize.IsValid())
3303 {
Jamie Madille0472f32018-11-27 16:32:45 -05003304 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003305 return false;
3306 }
3307
3308 // early return skips command data validation when it doesn't exist.
3309 if (!commands)
3310 return true;
3311
3312 GLsizei expectedNumCoords = 0;
3313 for (GLsizei i = 0; i < numCommands; ++i)
3314 {
3315 switch (commands[i])
3316 {
3317 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3318 break;
3319 case GL_MOVE_TO_CHROMIUM:
3320 case GL_LINE_TO_CHROMIUM:
3321 expectedNumCoords += 2;
3322 break;
3323 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3324 expectedNumCoords += 4;
3325 break;
3326 case GL_CUBIC_CURVE_TO_CHROMIUM:
3327 expectedNumCoords += 6;
3328 break;
3329 case GL_CONIC_CURVE_TO_CHROMIUM:
3330 expectedNumCoords += 5;
3331 break;
3332 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003333 context->validationError(GL_INVALID_ENUM, kInvalidPathCommand);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003334 return false;
3335 }
3336 }
Jamie Madillc3e37312018-11-30 15:25:39 -05003337
Sami Väisänene45e53b2016-05-25 10:36:04 +03003338 if (expectedNumCoords != numCoords)
3339 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003340 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCoords);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003341 return false;
3342 }
3343
3344 return true;
3345}
3346
Jamie Madill007530e2017-12-28 14:27:04 -05003347bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003348{
3349 if (!context->getExtensions().pathRendering)
3350 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003351 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003352 return false;
3353 }
Brandon Jones59770802018-04-02 13:18:42 -07003354 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003355 {
Jamie Madille0472f32018-11-27 16:32:45 -05003356 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003357 return false;
3358 }
3359
3360 switch (pname)
3361 {
3362 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3363 if (value < 0.0f)
3364 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003365 context->validationError(GL_INVALID_VALUE, kInvalidPathStrokeWidth);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003366 return false;
3367 }
3368 break;
3369 case GL_PATH_END_CAPS_CHROMIUM:
3370 switch (static_cast<GLenum>(value))
3371 {
3372 case GL_FLAT_CHROMIUM:
3373 case GL_SQUARE_CHROMIUM:
3374 case GL_ROUND_CHROMIUM:
3375 break;
3376 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003377 context->validationError(GL_INVALID_ENUM, kInvalidPathEndCaps);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003378 return false;
3379 }
3380 break;
3381 case GL_PATH_JOIN_STYLE_CHROMIUM:
3382 switch (static_cast<GLenum>(value))
3383 {
3384 case GL_MITER_REVERT_CHROMIUM:
3385 case GL_BEVEL_CHROMIUM:
3386 case GL_ROUND_CHROMIUM:
3387 break;
3388 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003389 context->validationError(GL_INVALID_ENUM, kInvalidPathJoinStyle);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003390 return false;
3391 }
Nico Weber41b072b2018-02-09 10:01:32 -05003392 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003393 case GL_PATH_MITER_LIMIT_CHROMIUM:
3394 if (value < 0.0f)
3395 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003396 context->validationError(GL_INVALID_VALUE, kInvalidPathMiterLimit);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003397 return false;
3398 }
3399 break;
3400
3401 case GL_PATH_STROKE_BOUND_CHROMIUM:
3402 // no errors, only clamping.
3403 break;
3404
3405 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003406 context->validationError(GL_INVALID_ENUM, kInvalidPathParameter);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003407 return false;
3408 }
3409 return true;
3410}
3411
Jamie Madill007530e2017-12-28 14:27:04 -05003412bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3413{
3414 // TODO(jmadill): Use proper clamping cast.
3415 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3416}
3417
3418bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003419{
3420 if (!context->getExtensions().pathRendering)
3421 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003422 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003423 return false;
3424 }
3425
Brandon Jones59770802018-04-02 13:18:42 -07003426 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003427 {
Jamie Madille0472f32018-11-27 16:32:45 -05003428 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003429 return false;
3430 }
Jamie Madillc3e37312018-11-30 15:25:39 -05003431
Sami Väisänene45e53b2016-05-25 10:36:04 +03003432 if (!value)
3433 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003434 context->validationError(GL_INVALID_VALUE, kInvalidPathValueArray);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003435 return false;
3436 }
3437
3438 switch (pname)
3439 {
3440 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3441 case GL_PATH_END_CAPS_CHROMIUM:
3442 case GL_PATH_JOIN_STYLE_CHROMIUM:
3443 case GL_PATH_MITER_LIMIT_CHROMIUM:
3444 case GL_PATH_STROKE_BOUND_CHROMIUM:
3445 break;
3446
3447 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003448 context->validationError(GL_INVALID_ENUM, kInvalidPathParameter);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003449 return false;
3450 }
3451
3452 return true;
3453}
3454
Jamie Madill007530e2017-12-28 14:27:04 -05003455bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3456{
3457 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3458 reinterpret_cast<GLfloat *>(value));
3459}
3460
3461bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003462{
3463 if (!context->getExtensions().pathRendering)
3464 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003465 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003466 return false;
3467 }
3468
3469 switch (func)
3470 {
3471 case GL_NEVER:
3472 case GL_ALWAYS:
3473 case GL_LESS:
3474 case GL_LEQUAL:
3475 case GL_EQUAL:
3476 case GL_GEQUAL:
3477 case GL_GREATER:
3478 case GL_NOTEQUAL:
3479 break;
3480 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003481 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003482 return false;
3483 }
3484
3485 return true;
3486}
3487
3488// Note that the spec specifies that for the path drawing commands
3489// if the path object is not an existing path object the command
3490// does nothing and no error is generated.
3491// However if the path object exists but has not been specified any
3492// commands then an error is generated.
3493
Jamie Madill007530e2017-12-28 14:27:04 -05003494bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003495{
3496 if (!context->getExtensions().pathRendering)
3497 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003498 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003499 return false;
3500 }
Brandon Jones59770802018-04-02 13:18:42 -07003501 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003502 {
Jamie Madille0472f32018-11-27 16:32:45 -05003503 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003504 return false;
3505 }
3506
3507 switch (fillMode)
3508 {
3509 case GL_COUNT_UP_CHROMIUM:
3510 case GL_COUNT_DOWN_CHROMIUM:
3511 break;
3512 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003513 context->validationError(GL_INVALID_ENUM, kInvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003514 return false;
3515 }
3516
3517 if (!isPow2(mask + 1))
3518 {
Jamie Madille0472f32018-11-27 16:32:45 -05003519 context->validationError(GL_INVALID_VALUE, kInvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003520 return false;
3521 }
3522
3523 return true;
3524}
3525
Jamie Madill007530e2017-12-28 14:27:04 -05003526bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003527{
3528 if (!context->getExtensions().pathRendering)
3529 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003530 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003531 return false;
3532 }
Jamie Madillc3e37312018-11-30 15:25:39 -05003533
Brandon Jones59770802018-04-02 13:18:42 -07003534 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003535 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003536 context->validationError(GL_INVALID_OPERATION, kNoPathOrNoPathData);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003537 return false;
3538 }
3539
3540 return true;
3541}
3542
Jamie Madill007530e2017-12-28 14:27:04 -05003543bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003544{
3545 if (!context->getExtensions().pathRendering)
3546 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003547 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003548 return false;
3549 }
Brandon Jones59770802018-04-02 13:18:42 -07003550 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003551 {
Jamie Madille0472f32018-11-27 16:32:45 -05003552 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003553 return false;
3554 }
3555
3556 switch (coverMode)
3557 {
3558 case GL_CONVEX_HULL_CHROMIUM:
3559 case GL_BOUNDING_BOX_CHROMIUM:
3560 break;
3561 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003562 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003563 return false;
3564 }
3565 return true;
3566}
3567
Jamie Madill778bf092018-11-14 09:54:36 -05003568bool ValidateCoverFillPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3569{
3570 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3571}
3572
3573bool ValidateCoverStrokePathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3574{
3575 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3576}
3577
Jamie Madill007530e2017-12-28 14:27:04 -05003578bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3579 GLuint path,
3580 GLenum fillMode,
3581 GLuint mask,
3582 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003583{
Jamie Madill007530e2017-12-28 14:27:04 -05003584 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3585 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003586}
3587
Jamie Madill007530e2017-12-28 14:27:04 -05003588bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3589 GLuint path,
3590 GLint reference,
3591 GLuint mask,
3592 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003593{
Jamie Madill007530e2017-12-28 14:27:04 -05003594 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3595 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003596}
3597
Brandon Jonesd1049182018-03-28 10:02:20 -07003598bool ValidateIsPathCHROMIUM(Context *context, GLuint path)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003599{
3600 if (!context->getExtensions().pathRendering)
3601 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003602 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003603 return false;
3604 }
3605 return true;
3606}
3607
Jamie Madill007530e2017-12-28 14:27:04 -05003608bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3609 GLsizei numPaths,
3610 GLenum pathNameType,
3611 const void *paths,
3612 GLuint pathBase,
3613 GLenum coverMode,
3614 GLenum transformType,
3615 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003616{
3617 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3618 transformType, transformValues))
3619 return false;
3620
3621 switch (coverMode)
3622 {
3623 case GL_CONVEX_HULL_CHROMIUM:
3624 case GL_BOUNDING_BOX_CHROMIUM:
3625 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3626 break;
3627 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003628 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003629 return false;
3630 }
3631
3632 return true;
3633}
3634
Jamie Madill007530e2017-12-28 14:27:04 -05003635bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3636 GLsizei numPaths,
3637 GLenum pathNameType,
3638 const void *paths,
3639 GLuint pathBase,
3640 GLenum coverMode,
3641 GLenum transformType,
3642 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003643{
3644 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3645 transformType, transformValues))
3646 return false;
3647
3648 switch (coverMode)
3649 {
3650 case GL_CONVEX_HULL_CHROMIUM:
3651 case GL_BOUNDING_BOX_CHROMIUM:
3652 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3653 break;
3654 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003655 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003656 return false;
3657 }
3658
3659 return true;
3660}
3661
Jamie Madill007530e2017-12-28 14:27:04 -05003662bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3663 GLsizei numPaths,
3664 GLenum pathNameType,
3665 const void *paths,
3666 GLuint pathBase,
3667 GLenum fillMode,
3668 GLuint mask,
3669 GLenum transformType,
3670 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003671{
3672
3673 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3674 transformType, transformValues))
3675 return false;
3676
3677 switch (fillMode)
3678 {
3679 case GL_COUNT_UP_CHROMIUM:
3680 case GL_COUNT_DOWN_CHROMIUM:
3681 break;
3682 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003683 context->validationError(GL_INVALID_ENUM, kInvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003684 return false;
3685 }
3686 if (!isPow2(mask + 1))
3687 {
Jamie Madille0472f32018-11-27 16:32:45 -05003688 context->validationError(GL_INVALID_VALUE, kInvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003689 return false;
3690 }
3691 return true;
3692}
3693
Jamie Madill007530e2017-12-28 14:27:04 -05003694bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3695 GLsizei numPaths,
3696 GLenum pathNameType,
3697 const void *paths,
3698 GLuint pathBase,
3699 GLint reference,
3700 GLuint mask,
3701 GLenum transformType,
3702 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003703{
3704 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3705 transformType, transformValues))
3706 return false;
3707
3708 // no more validation here.
3709
3710 return true;
3711}
3712
Jamie Madill007530e2017-12-28 14:27:04 -05003713bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3714 GLsizei numPaths,
3715 GLenum pathNameType,
3716 const void *paths,
3717 GLuint pathBase,
3718 GLenum fillMode,
3719 GLuint mask,
3720 GLenum coverMode,
3721 GLenum transformType,
3722 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003723{
3724 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3725 transformType, transformValues))
3726 return false;
3727
3728 switch (coverMode)
3729 {
3730 case GL_CONVEX_HULL_CHROMIUM:
3731 case GL_BOUNDING_BOX_CHROMIUM:
3732 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3733 break;
3734 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003735 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003736 return false;
3737 }
3738
3739 switch (fillMode)
3740 {
3741 case GL_COUNT_UP_CHROMIUM:
3742 case GL_COUNT_DOWN_CHROMIUM:
3743 break;
3744 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003745 context->validationError(GL_INVALID_ENUM, kInvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003746 return false;
3747 }
3748 if (!isPow2(mask + 1))
3749 {
Jamie Madille0472f32018-11-27 16:32:45 -05003750 context->validationError(GL_INVALID_VALUE, kInvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003751 return false;
3752 }
3753
3754 return true;
3755}
3756
Jamie Madill007530e2017-12-28 14:27:04 -05003757bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
3758 GLsizei numPaths,
3759 GLenum pathNameType,
3760 const void *paths,
3761 GLuint pathBase,
3762 GLint reference,
3763 GLuint mask,
3764 GLenum coverMode,
3765 GLenum transformType,
3766 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003767{
3768 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3769 transformType, transformValues))
3770 return false;
3771
3772 switch (coverMode)
3773 {
3774 case GL_CONVEX_HULL_CHROMIUM:
3775 case GL_BOUNDING_BOX_CHROMIUM:
3776 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3777 break;
3778 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003779 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003780 return false;
3781 }
3782
3783 return true;
3784}
3785
Jamie Madill007530e2017-12-28 14:27:04 -05003786bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
3787 GLuint program,
3788 GLint location,
3789 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003790{
3791 if (!context->getExtensions().pathRendering)
3792 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003793 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003794 return false;
3795 }
3796
3797 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3798 if (location >= MaxLocation)
3799 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003800 context->validationError(GL_INVALID_VALUE, kInvalidVaryingLocation);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003801 return false;
3802 }
3803
Jamie Madill44a6fbf2018-10-02 13:38:56 -04003804 const auto *programObject = context->getProgramNoResolveLink(program);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003805 if (!programObject)
3806 {
Jamie Madille0472f32018-11-27 16:32:45 -05003807 context->validationError(GL_INVALID_OPERATION, kProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003808 return false;
3809 }
3810
3811 if (!name)
3812 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003813 context->validationError(GL_INVALID_VALUE, kMissingName);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003814 return false;
3815 }
3816
3817 if (angle::BeginsWith(name, "gl_"))
3818 {
Jamie Madille0472f32018-11-27 16:32:45 -05003819 context->validationError(GL_INVALID_OPERATION, kNameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003820 return false;
3821 }
3822
3823 return true;
3824}
3825
Jamie Madill007530e2017-12-28 14:27:04 -05003826bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
3827 GLuint program,
3828 GLint location,
3829 GLenum genMode,
3830 GLint components,
3831 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003832{
3833 if (!context->getExtensions().pathRendering)
3834 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003835 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003836 return false;
3837 }
3838
Jamie Madill44a6fbf2018-10-02 13:38:56 -04003839 const auto *programObject = context->getProgramResolveLink(program);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003840 if (!programObject || programObject->isFlaggedForDeletion())
3841 {
Jamie Madille0472f32018-11-27 16:32:45 -05003842 context->validationError(GL_INVALID_OPERATION, kProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003843 return false;
3844 }
3845
3846 if (!programObject->isLinked())
3847 {
Jamie Madille0472f32018-11-27 16:32:45 -05003848 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003849 return false;
3850 }
3851
3852 switch (genMode)
3853 {
3854 case GL_NONE:
3855 if (components != 0)
3856 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003857 context->validationError(GL_INVALID_VALUE, kInvalidComponents);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003858 return false;
3859 }
3860 break;
3861
3862 case GL_OBJECT_LINEAR_CHROMIUM:
3863 case GL_EYE_LINEAR_CHROMIUM:
3864 case GL_CONSTANT_CHROMIUM:
3865 if (components < 1 || components > 4)
3866 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003867 context->validationError(GL_INVALID_VALUE, kInvalidComponents);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003868 return false;
3869 }
3870 if (!coeffs)
3871 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003872 context->validationError(GL_INVALID_VALUE, kInvalidPathCoefficientsArray);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003873 return false;
3874 }
3875 break;
3876
3877 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003878 context->validationError(GL_INVALID_ENUM, kInvalidPathGenMode);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003879 return false;
3880 }
3881
3882 // If the location is -1 then the command is silently ignored
3883 // and no further validation is needed.
3884 if (location == -1)
3885 return true;
3886
jchen103fd614d2018-08-13 12:21:58 +08003887 const auto &binding = programObject->getFragmentInputBindingInfo(location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003888
3889 if (!binding.valid)
3890 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003891 context->validationError(GL_INVALID_OPERATION, kInvalidFragmentInputBinding);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003892 return false;
3893 }
3894
3895 if (binding.type != GL_NONE)
3896 {
3897 GLint expectedComponents = 0;
3898 switch (binding.type)
3899 {
3900 case GL_FLOAT:
3901 expectedComponents = 1;
3902 break;
3903 case GL_FLOAT_VEC2:
3904 expectedComponents = 2;
3905 break;
3906 case GL_FLOAT_VEC3:
3907 expectedComponents = 3;
3908 break;
3909 case GL_FLOAT_VEC4:
3910 expectedComponents = 4;
3911 break;
3912 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003913 context->validationError(GL_INVALID_OPERATION, kFragmentInputTypeNotFloatingPoint);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003914 return false;
3915 }
3916 if (expectedComponents != components && genMode != GL_NONE)
3917 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003918 context->validationError(GL_INVALID_OPERATION, kInvalidPathComponents);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003919 return false;
3920 }
3921 }
3922 return true;
3923}
3924
Geoff Lang97073d12016-04-20 10:42:34 -07003925bool ValidateCopyTextureCHROMIUM(Context *context,
3926 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003927 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003928 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003929 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003930 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003931 GLint internalFormat,
3932 GLenum destType,
3933 GLboolean unpackFlipY,
3934 GLboolean unpackPremultiplyAlpha,
3935 GLboolean unpackUnmultiplyAlpha)
3936{
3937 if (!context->getExtensions().copyTexture)
3938 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003939 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang97073d12016-04-20 10:42:34 -07003940 return false;
3941 }
3942
Geoff Lang4f0e0032017-05-01 16:04:35 -04003943 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003944 if (source == nullptr)
3945 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003946 context->validationError(GL_INVALID_VALUE, kInvalidSourceTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07003947 return false;
3948 }
3949
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003950 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003951 {
Jamie Madille0472f32018-11-27 16:32:45 -05003952 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003953 return false;
3954 }
3955
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003956 TextureType sourceType = source->getType();
3957 ASSERT(sourceType != TextureType::CubeMap);
3958 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003959
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003960 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07003961 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003962 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureLevel);
Geoff Lang97073d12016-04-20 10:42:34 -07003963 return false;
3964 }
3965
Geoff Lang4f0e0032017-05-01 16:04:35 -04003966 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
3967 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
3968 if (sourceWidth == 0 || sourceHeight == 0)
3969 {
Jamie Madille0472f32018-11-27 16:32:45 -05003970 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003971 return false;
3972 }
3973
3974 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
3975 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07003976 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003977 context->validationError(GL_INVALID_OPERATION, kInvalidSourceTextureInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003978 return false;
3979 }
3980
Geoff Lang63458a32017-10-30 15:16:53 -04003981 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
3982 {
Jamie Madille0472f32018-11-27 16:32:45 -05003983 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Lang63458a32017-10-30 15:16:53 -04003984 return false;
3985 }
3986
Geoff Lang4f0e0032017-05-01 16:04:35 -04003987 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07003988 if (dest == nullptr)
3989 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003990 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07003991 return false;
3992 }
3993
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003994 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07003995 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003996 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTextureType);
Geoff Lang97073d12016-04-20 10:42:34 -07003997 return false;
3998 }
3999
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004000 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08004001 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004002 {
Jamie Madille0472f32018-11-27 16:32:45 -05004003 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004004 return false;
4005 }
4006
Geoff Lang97073d12016-04-20 10:42:34 -07004007 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
4008 {
Geoff Lang97073d12016-04-20 10:42:34 -07004009 return false;
4010 }
4011
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004012 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04004013 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004014 context->validationError(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004015 return false;
4016 }
4017
Geoff Lang97073d12016-04-20 10:42:34 -07004018 if (dest->getImmutableFormat())
4019 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004020 context->validationError(GL_INVALID_OPERATION, kDestinationImmutable);
Geoff Lang97073d12016-04-20 10:42:34 -07004021 return false;
4022 }
4023
4024 return true;
4025}
4026
4027bool ValidateCopySubTextureCHROMIUM(Context *context,
4028 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04004029 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004030 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07004031 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04004032 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07004033 GLint xoffset,
4034 GLint yoffset,
4035 GLint x,
4036 GLint y,
4037 GLsizei width,
4038 GLsizei height,
4039 GLboolean unpackFlipY,
4040 GLboolean unpackPremultiplyAlpha,
4041 GLboolean unpackUnmultiplyAlpha)
4042{
4043 if (!context->getExtensions().copyTexture)
4044 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004045 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang97073d12016-04-20 10:42:34 -07004046 return false;
4047 }
4048
Geoff Lang4f0e0032017-05-01 16:04:35 -04004049 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004050 if (source == nullptr)
4051 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004052 context->validationError(GL_INVALID_VALUE, kInvalidSourceTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07004053 return false;
4054 }
4055
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004056 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004057 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004058 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureType);
Geoff Lang97073d12016-04-20 10:42:34 -07004059 return false;
4060 }
4061
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004062 TextureType sourceType = source->getType();
4063 ASSERT(sourceType != TextureType::CubeMap);
4064 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004065
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004066 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004067 {
Jamie Madille0472f32018-11-27 16:32:45 -05004068 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004069 return false;
4070 }
4071
4072 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4073 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004074 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004075 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureLevel);
Geoff Lang97073d12016-04-20 10:42:34 -07004076 return false;
4077 }
4078
4079 if (x < 0 || y < 0)
4080 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004081 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004082 return false;
4083 }
4084
4085 if (width < 0 || height < 0)
4086 {
Jamie Madille0472f32018-11-27 16:32:45 -05004087 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004088 return false;
4089 }
4090
Geoff Lang4f0e0032017-05-01 16:04:35 -04004091 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4092 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004093 {
Jamie Madille0472f32018-11-27 16:32:45 -05004094 context->validationError(GL_INVALID_VALUE, kSourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004095 return false;
4096 }
4097
Geoff Lang4f0e0032017-05-01 16:04:35 -04004098 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4099 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004100 {
Jamie Madille0472f32018-11-27 16:32:45 -05004101 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004102 return false;
4103 }
4104
Geoff Lang63458a32017-10-30 15:16:53 -04004105 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4106 {
Jamie Madille0472f32018-11-27 16:32:45 -05004107 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Lang63458a32017-10-30 15:16:53 -04004108 return false;
4109 }
4110
Geoff Lang4f0e0032017-05-01 16:04:35 -04004111 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004112 if (dest == nullptr)
4113 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004114 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07004115 return false;
4116 }
4117
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004118 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004119 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004120 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTextureType);
Geoff Lang97073d12016-04-20 10:42:34 -07004121 return false;
4122 }
4123
Brandon Jones28783792018-03-05 09:37:32 -08004124 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4125 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004126 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004127 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Lang97073d12016-04-20 10:42:34 -07004128 return false;
4129 }
4130
Geoff Lang4f0e0032017-05-01 16:04:35 -04004131 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4132 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004133 context->validationError(GL_INVALID_OPERATION, kDestinationLevelNotDefined);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004134 return false;
4135 }
4136
4137 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4138 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004139 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004140 context->validationError(GL_INVALID_OPERATION, kInvalidFormatCombination);
Geoff Lang97073d12016-04-20 10:42:34 -07004141 return false;
4142 }
4143
4144 if (xoffset < 0 || yoffset < 0)
4145 {
Jamie Madille0472f32018-11-27 16:32:45 -05004146 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004147 return false;
4148 }
4149
Geoff Lang4f0e0032017-05-01 16:04:35 -04004150 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4151 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004152 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004153 context->validationError(GL_INVALID_VALUE, kOffsetOverflow);
Geoff Lang97073d12016-04-20 10:42:34 -07004154 return false;
4155 }
4156
4157 return true;
4158}
4159
Geoff Lang47110bf2016-04-20 11:13:22 -07004160bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4161{
4162 if (!context->getExtensions().copyCompressedTexture)
4163 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004164 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang47110bf2016-04-20 11:13:22 -07004165 return false;
4166 }
4167
4168 const gl::Texture *source = context->getTexture(sourceId);
4169 if (source == nullptr)
4170 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004171 context->validationError(GL_INVALID_VALUE, kInvalidSourceTexture);
Geoff Lang47110bf2016-04-20 11:13:22 -07004172 return false;
4173 }
4174
Corentin Wallez99d492c2018-02-27 15:17:10 -05004175 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004176 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004177 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureType);
Geoff Lang47110bf2016-04-20 11:13:22 -07004178 return false;
4179 }
4180
Corentin Wallez99d492c2018-02-27 15:17:10 -05004181 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4182 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004183 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004184 context->validationError(GL_INVALID_VALUE, kSourceTextureLevelZeroDefined);
Geoff Lang47110bf2016-04-20 11:13:22 -07004185 return false;
4186 }
4187
Corentin Wallez99d492c2018-02-27 15:17:10 -05004188 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004189 if (!sourceFormat.info->compressed)
4190 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004191 context->validationError(GL_INVALID_OPERATION, kSourceTextureMustBeCompressed);
Geoff Lang47110bf2016-04-20 11:13:22 -07004192 return false;
4193 }
4194
4195 const gl::Texture *dest = context->getTexture(destId);
4196 if (dest == nullptr)
4197 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004198 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTexture);
Geoff Lang47110bf2016-04-20 11:13:22 -07004199 return false;
4200 }
4201
Corentin Wallez99d492c2018-02-27 15:17:10 -05004202 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004203 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004204 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTextureType);
Geoff Lang47110bf2016-04-20 11:13:22 -07004205 return false;
4206 }
4207
4208 if (dest->getImmutableFormat())
4209 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004210 context->validationError(GL_INVALID_OPERATION, kDestinationImmutable);
Geoff Lang47110bf2016-04-20 11:13:22 -07004211 return false;
4212 }
4213
4214 return true;
4215}
4216
Jiawei Shao385b3e02018-03-21 09:43:28 +08004217bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004218{
4219 switch (type)
4220 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004221 case ShaderType::Vertex:
4222 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004223 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004224
Jiawei Shao385b3e02018-03-21 09:43:28 +08004225 case ShaderType::Compute:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004226 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004227 {
Jamie Madille0472f32018-11-27 16:32:45 -05004228 context->validationError(GL_INVALID_ENUM, kES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004229 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004230 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004231 break;
4232
Jiawei Shao385b3e02018-03-21 09:43:28 +08004233 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004234 if (!context->getExtensions().geometryShader)
4235 {
Jamie Madille0472f32018-11-27 16:32:45 -05004236 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
Jiawei Shao89be29a2017-11-06 14:36:45 +08004237 return false;
4238 }
4239 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004240 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004241 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004242 return false;
4243 }
Jamie Madill29639852016-09-02 15:00:09 -04004244
4245 return true;
4246}
4247
Jamie Madill5b772312018-03-08 20:28:32 -05004248bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004249 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004250 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004251 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004252 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004253{
4254 if (size < 0)
4255 {
Jamie Madille0472f32018-11-27 16:32:45 -05004256 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004257 return false;
4258 }
4259
4260 switch (usage)
4261 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004262 case BufferUsage::StreamDraw:
4263 case BufferUsage::StaticDraw:
4264 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004265 break;
4266
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004267 case BufferUsage::StreamRead:
4268 case BufferUsage::StaticRead:
4269 case BufferUsage::DynamicRead:
4270 case BufferUsage::StreamCopy:
4271 case BufferUsage::StaticCopy:
4272 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004273 if (context->getClientMajorVersion() < 3)
4274 {
Jamie Madille0472f32018-11-27 16:32:45 -05004275 context->validationError(GL_INVALID_ENUM, kInvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004276 return false;
4277 }
4278 break;
4279
4280 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004281 context->validationError(GL_INVALID_ENUM, kInvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004282 return false;
4283 }
4284
Corentin Walleze4477002017-12-01 14:39:58 -05004285 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004286 {
Jamie Madille0472f32018-11-27 16:32:45 -05004287 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004288 return false;
4289 }
4290
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004291 Buffer *buffer = context->getState().getTargetBuffer(target);
Jamie Madill29639852016-09-02 15:00:09 -04004292
4293 if (!buffer)
4294 {
Jamie Madille0472f32018-11-27 16:32:45 -05004295 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004296 return false;
4297 }
4298
James Darpiniane8a93c62018-01-04 18:02:24 -08004299 if (context->getExtensions().webglCompatibility &&
4300 buffer->isBoundForTransformFeedbackAndOtherUse())
4301 {
Jamie Madille0472f32018-11-27 16:32:45 -05004302 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08004303 return false;
4304 }
4305
Jamie Madill29639852016-09-02 15:00:09 -04004306 return true;
4307}
4308
Jamie Madill5b772312018-03-08 20:28:32 -05004309bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004310 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004311 GLintptr offset,
4312 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004313 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004314{
Brandon Jones6cad5662017-06-14 13:25:13 -07004315 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004316 {
Jamie Madille0472f32018-11-27 16:32:45 -05004317 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Brandon Jones6cad5662017-06-14 13:25:13 -07004318 return false;
4319 }
4320
4321 if (offset < 0)
4322 {
Jamie Madille0472f32018-11-27 16:32:45 -05004323 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004324 return false;
4325 }
4326
Corentin Walleze4477002017-12-01 14:39:58 -05004327 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004328 {
Jamie Madille0472f32018-11-27 16:32:45 -05004329 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004330 return false;
4331 }
4332
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004333 Buffer *buffer = context->getState().getTargetBuffer(target);
Jamie Madill29639852016-09-02 15:00:09 -04004334
4335 if (!buffer)
4336 {
Jamie Madille0472f32018-11-27 16:32:45 -05004337 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004338 return false;
4339 }
4340
4341 if (buffer->isMapped())
4342 {
Jamie Madille0472f32018-11-27 16:32:45 -05004343 context->validationError(GL_INVALID_OPERATION, kBufferMapped);
Jamie Madill29639852016-09-02 15:00:09 -04004344 return false;
4345 }
4346
James Darpiniane8a93c62018-01-04 18:02:24 -08004347 if (context->getExtensions().webglCompatibility &&
4348 buffer->isBoundForTransformFeedbackAndOtherUse())
4349 {
Jamie Madille0472f32018-11-27 16:32:45 -05004350 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08004351 return false;
4352 }
4353
Jamie Madill29639852016-09-02 15:00:09 -04004354 // Check for possible overflow of size + offset
4355 angle::CheckedNumeric<size_t> checkedSize(size);
4356 checkedSize += offset;
4357 if (!checkedSize.IsValid())
4358 {
Jamie Madille0472f32018-11-27 16:32:45 -05004359 context->validationError(GL_INVALID_VALUE, kParamOverflow);
Jamie Madill29639852016-09-02 15:00:09 -04004360 return false;
4361 }
4362
4363 if (size + offset > buffer->getSize())
4364 {
Jamie Madille0472f32018-11-27 16:32:45 -05004365 context->validationError(GL_INVALID_VALUE, kInsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004366 return false;
4367 }
4368
Martin Radev4c4c8e72016-08-04 12:25:34 +03004369 return true;
4370}
4371
Geoff Lang111a99e2017-10-17 10:58:41 -04004372bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004373{
Geoff Langc339c4e2016-11-29 10:37:36 -05004374 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004375 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004376 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langc287ea62016-09-16 14:46:51 -04004377 return false;
4378 }
4379
Geoff Lang111a99e2017-10-17 10:58:41 -04004380 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004381 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004382 context->validationError(GL_INVALID_OPERATION, kExtensionNotRequestable);
Geoff Langc287ea62016-09-16 14:46:51 -04004383 return false;
4384 }
4385
4386 return true;
4387}
4388
Jamie Madill5b772312018-03-08 20:28:32 -05004389bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004390{
Lingfeng Yang038dd532018-03-29 17:31:52 -07004391 if (context->getClientMajorVersion() < 2)
4392 {
4393 return ValidateMultitextureUnit(context, texture);
4394 }
4395
Jamie Madillef300b12016-10-07 15:12:09 -04004396 if (texture < GL_TEXTURE0 ||
4397 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4398 {
Jamie Madille0472f32018-11-27 16:32:45 -05004399 context->validationError(GL_INVALID_ENUM, kInvalidCombinedImageUnit);
Jamie Madillef300b12016-10-07 15:12:09 -04004400 return false;
4401 }
4402
4403 return true;
4404}
4405
Jamie Madill5b772312018-03-08 20:28:32 -05004406bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004407{
4408 Program *programObject = GetValidProgram(context, program);
4409 if (!programObject)
4410 {
4411 return false;
4412 }
4413
4414 Shader *shaderObject = GetValidShader(context, shader);
4415 if (!shaderObject)
4416 {
4417 return false;
4418 }
4419
Jiawei Shao385b3e02018-03-21 09:43:28 +08004420 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04004421 {
Jamie Madille0472f32018-11-27 16:32:45 -05004422 context->validationError(GL_INVALID_OPERATION, kShaderAttachmentHasShader);
Jiawei Shao385b3e02018-03-21 09:43:28 +08004423 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04004424 }
4425
4426 return true;
4427}
4428
Jamie Madill5b772312018-03-08 20:28:32 -05004429bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004430{
4431 if (index >= MAX_VERTEX_ATTRIBS)
4432 {
Jamie Madille0472f32018-11-27 16:32:45 -05004433 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004434 return false;
4435 }
4436
4437 if (strncmp(name, "gl_", 3) == 0)
4438 {
Jamie Madille0472f32018-11-27 16:32:45 -05004439 context->validationError(GL_INVALID_OPERATION, kNameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004440 return false;
4441 }
4442
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004443 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004444 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004445 const size_t length = strlen(name);
4446
4447 if (!IsValidESSLString(name, length))
4448 {
4449 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4450 // for shader-related entry points
Jamie Madille0472f32018-11-27 16:32:45 -05004451 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004452 return false;
4453 }
4454
4455 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4456 {
4457 return false;
4458 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004459 }
4460
Jamie Madill01a80ee2016-11-07 12:06:18 -05004461 return GetValidProgram(context, program) != nullptr;
4462}
4463
Jamie Madill5b772312018-03-08 20:28:32 -05004464bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004465{
Geoff Lange8afa902017-09-27 15:00:43 -04004466 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004467 {
Jamie Madille0472f32018-11-27 16:32:45 -05004468 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004469 return false;
4470 }
4471
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004472 if (!context->getState().isBindGeneratesResourceEnabled() &&
Jamie Madill01a80ee2016-11-07 12:06:18 -05004473 !context->isFramebufferGenerated(framebuffer))
4474 {
Jamie Madille0472f32018-11-27 16:32:45 -05004475 context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004476 return false;
4477 }
4478
4479 return true;
4480}
4481
Jamie Madill5b772312018-03-08 20:28:32 -05004482bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004483{
4484 if (target != GL_RENDERBUFFER)
4485 {
Jamie Madille0472f32018-11-27 16:32:45 -05004486 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004487 return false;
4488 }
4489
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004490 if (!context->getState().isBindGeneratesResourceEnabled() &&
Jamie Madill01a80ee2016-11-07 12:06:18 -05004491 !context->isRenderbufferGenerated(renderbuffer))
4492 {
Jamie Madille0472f32018-11-27 16:32:45 -05004493 context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004494 return false;
4495 }
4496
4497 return true;
4498}
4499
Jamie Madill5b772312018-03-08 20:28:32 -05004500static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004501{
4502 switch (mode)
4503 {
4504 case GL_FUNC_ADD:
4505 case GL_FUNC_SUBTRACT:
4506 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004507 return true;
4508
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004509 case GL_MIN:
4510 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004511 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004512
4513 default:
4514 return false;
4515 }
4516}
4517
Jamie Madill5b772312018-03-08 20:28:32 -05004518bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004519{
4520 return true;
4521}
4522
Jamie Madill5b772312018-03-08 20:28:32 -05004523bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004524{
Geoff Lang50cac572017-09-26 17:37:43 -04004525 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004526 {
Jamie Madille0472f32018-11-27 16:32:45 -05004527 context->validationError(GL_INVALID_ENUM, kInvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004528 return false;
4529 }
4530
4531 return true;
4532}
4533
Jamie Madill5b772312018-03-08 20:28:32 -05004534bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004535{
Geoff Lang50cac572017-09-26 17:37:43 -04004536 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004537 {
Jamie Madille0472f32018-11-27 16:32:45 -05004538 context->validationError(GL_INVALID_ENUM, kInvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004539 return false;
4540 }
4541
Geoff Lang50cac572017-09-26 17:37:43 -04004542 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004543 {
Jamie Madille0472f32018-11-27 16:32:45 -05004544 context->validationError(GL_INVALID_ENUM, kInvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004545 return false;
4546 }
4547
4548 return true;
4549}
4550
Jamie Madill5b772312018-03-08 20:28:32 -05004551bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004552{
4553 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4554}
4555
Jamie Madill5b772312018-03-08 20:28:32 -05004556bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004557 GLenum srcRGB,
4558 GLenum dstRGB,
4559 GLenum srcAlpha,
4560 GLenum dstAlpha)
4561{
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004562 if (!ValidSrcBlendFunc(context, srcRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004563 {
Jamie Madille0472f32018-11-27 16:32:45 -05004564 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004565 return false;
4566 }
4567
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004568 if (!ValidDstBlendFunc(context, dstRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004569 {
Jamie Madille0472f32018-11-27 16:32:45 -05004570 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004571 return false;
4572 }
4573
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004574 if (!ValidSrcBlendFunc(context, srcAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004575 {
Jamie Madille0472f32018-11-27 16:32:45 -05004576 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004577 return false;
4578 }
4579
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004580 if (!ValidDstBlendFunc(context, dstAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004581 {
Jamie Madille0472f32018-11-27 16:32:45 -05004582 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004583 return false;
4584 }
4585
Frank Henigman146e8a12017-03-02 23:22:37 -05004586 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4587 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004588 {
4589 bool constantColorUsed =
4590 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4591 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4592
4593 bool constantAlphaUsed =
4594 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4595 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4596
4597 if (constantColorUsed && constantAlphaUsed)
4598 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004599 if (context->getExtensions().webglCompatibility)
4600 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004601 context->validationError(GL_INVALID_OPERATION, kInvalidConstantColor);
4602 return false;
Frank Henigman146e8a12017-03-02 23:22:37 -05004603 }
Jamie Madillc3e37312018-11-30 15:25:39 -05004604
4605 WARN() << kConstantColorAlphaLimitation;
4606 context->validationError(GL_INVALID_OPERATION, kConstantColorAlphaLimitation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004607 return false;
4608 }
4609 }
4610
4611 return true;
4612}
4613
Geoff Langc339c4e2016-11-29 10:37:36 -05004614bool ValidateGetString(Context *context, GLenum name)
4615{
4616 switch (name)
4617 {
4618 case GL_VENDOR:
4619 case GL_RENDERER:
4620 case GL_VERSION:
4621 case GL_SHADING_LANGUAGE_VERSION:
4622 case GL_EXTENSIONS:
4623 break;
4624
4625 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4626 if (!context->getExtensions().requestExtension)
4627 {
Jamie Madille0472f32018-11-27 16:32:45 -05004628 context->validationError(GL_INVALID_ENUM, kInvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004629 return false;
4630 }
4631 break;
4632
4633 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004634 context->validationError(GL_INVALID_ENUM, kInvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004635 return false;
4636 }
4637
4638 return true;
4639}
4640
Jamie Madill5b772312018-03-08 20:28:32 -05004641bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004642{
4643 if (width <= 0.0f || isNaN(width))
4644 {
Jamie Madille0472f32018-11-27 16:32:45 -05004645 context->validationError(GL_INVALID_VALUE, kInvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004646 return false;
4647 }
4648
4649 return true;
4650}
4651
Jamie Madill5b772312018-03-08 20:28:32 -05004652bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004653{
4654 if (context->getExtensions().webglCompatibility && zNear > zFar)
4655 {
Jamie Madille0472f32018-11-27 16:32:45 -05004656 context->validationError(GL_INVALID_OPERATION, kInvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004657 return false;
4658 }
4659
4660 return true;
4661}
4662
Jamie Madill5b772312018-03-08 20:28:32 -05004663bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004664 GLenum target,
4665 GLenum internalformat,
4666 GLsizei width,
4667 GLsizei height)
4668{
4669 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4670 height);
4671}
4672
Jamie Madill5b772312018-03-08 20:28:32 -05004673bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004674 GLenum target,
4675 GLsizei samples,
4676 GLenum internalformat,
4677 GLsizei width,
4678 GLsizei height)
4679{
4680 if (!context->getExtensions().framebufferMultisample)
4681 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004682 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madille8fb6402017-02-14 17:56:40 -05004683 return false;
4684 }
4685
4686 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
Jamie Madill610640f2018-11-21 17:28:41 -05004687 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_VALUE is
Jamie Madille8fb6402017-02-14 17:56:40 -05004688 // generated.
4689 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4690 {
Jamie Madille0472f32018-11-27 16:32:45 -05004691 context->validationError(GL_INVALID_VALUE, kSamplesOutOfRange);
Jamie Madille8fb6402017-02-14 17:56:40 -05004692 return false;
4693 }
4694
4695 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4696 // the specified storage. This is different than ES 3.0 in which a sample number higher
4697 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4698 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4699 if (context->getClientMajorVersion() >= 3)
4700 {
4701 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4702 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4703 {
Jamie Madille0472f32018-11-27 16:32:45 -05004704 context->validationError(GL_OUT_OF_MEMORY, kSamplesOutOfRange);
Jamie Madille8fb6402017-02-14 17:56:40 -05004705 return false;
4706 }
4707 }
4708
4709 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4710 width, height);
4711}
4712
Jamie Madill5b772312018-03-08 20:28:32 -05004713bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004714{
Geoff Lange8afa902017-09-27 15:00:43 -04004715 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004716 {
Jamie Madille0472f32018-11-27 16:32:45 -05004717 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004718 return false;
4719 }
4720
4721 return true;
4722}
4723
Jamie Madill5b772312018-03-08 20:28:32 -05004724bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004725{
4726 return true;
4727}
4728
Jamie Madill5b772312018-03-08 20:28:32 -05004729bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004730{
4731 return true;
4732}
4733
Jamie Madill5b772312018-03-08 20:28:32 -05004734bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004735{
4736 return true;
4737}
4738
Jamie Madill5b772312018-03-08 20:28:32 -05004739bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004740 GLboolean red,
4741 GLboolean green,
4742 GLboolean blue,
4743 GLboolean alpha)
4744{
4745 return true;
4746}
4747
Jamie Madill5b772312018-03-08 20:28:32 -05004748bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004749{
4750 return true;
4751}
4752
Jamie Madill5b772312018-03-08 20:28:32 -05004753bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004754{
4755 return true;
4756}
4757
Jamie Madill5b772312018-03-08 20:28:32 -05004758bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004759{
4760 switch (mode)
4761 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004762 case CullFaceMode::Front:
4763 case CullFaceMode::Back:
4764 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004765 break;
4766
4767 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004768 context->validationError(GL_INVALID_ENUM, kInvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004769 return false;
4770 }
4771
4772 return true;
4773}
4774
Jamie Madill5b772312018-03-08 20:28:32 -05004775bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004776{
4777 if (program == 0)
4778 {
4779 return false;
4780 }
4781
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004782 if (!context->getProgramResolveLink(program))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004783 {
4784 if (context->getShader(program))
4785 {
Jamie Madille0472f32018-11-27 16:32:45 -05004786 context->validationError(GL_INVALID_OPERATION, kExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004787 return false;
4788 }
4789 else
4790 {
Jamie Madille0472f32018-11-27 16:32:45 -05004791 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004792 return false;
4793 }
4794 }
4795
4796 return true;
4797}
4798
Jamie Madill5b772312018-03-08 20:28:32 -05004799bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004800{
4801 if (shader == 0)
4802 {
4803 return false;
4804 }
4805
4806 if (!context->getShader(shader))
4807 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004808 if (context->getProgramResolveLink(shader))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004809 {
Jamie Madille0472f32018-11-27 16:32:45 -05004810 context->validationError(GL_INVALID_OPERATION, kInvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004811 return false;
4812 }
4813 else
4814 {
Jamie Madille0472f32018-11-27 16:32:45 -05004815 context->validationError(GL_INVALID_VALUE, kExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004816 return false;
4817 }
4818 }
4819
4820 return true;
4821}
4822
Jamie Madill5b772312018-03-08 20:28:32 -05004823bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004824{
4825 switch (func)
4826 {
4827 case GL_NEVER:
4828 case GL_ALWAYS:
4829 case GL_LESS:
4830 case GL_LEQUAL:
4831 case GL_EQUAL:
4832 case GL_GREATER:
4833 case GL_GEQUAL:
4834 case GL_NOTEQUAL:
4835 break;
4836
4837 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004838 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004839 return false;
4840 }
4841
4842 return true;
4843}
4844
Jamie Madill5b772312018-03-08 20:28:32 -05004845bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004846{
4847 return true;
4848}
4849
Jamie Madill5b772312018-03-08 20:28:32 -05004850bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004851{
4852 Program *programObject = GetValidProgram(context, program);
4853 if (!programObject)
4854 {
4855 return false;
4856 }
4857
4858 Shader *shaderObject = GetValidShader(context, shader);
4859 if (!shaderObject)
4860 {
4861 return false;
4862 }
4863
Jiawei Shao385b3e02018-03-21 09:43:28 +08004864 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04004865 if (attachedShader != shaderObject)
4866 {
Jamie Madille0472f32018-11-27 16:32:45 -05004867 context->validationError(GL_INVALID_OPERATION, kShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004868 return false;
4869 }
4870
4871 return true;
4872}
4873
Jamie Madill5b772312018-03-08 20:28:32 -05004874bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004875{
4876 if (index >= MAX_VERTEX_ATTRIBS)
4877 {
Jamie Madille0472f32018-11-27 16:32:45 -05004878 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004879 return false;
4880 }
4881
4882 return true;
4883}
4884
Jamie Madill5b772312018-03-08 20:28:32 -05004885bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004886{
4887 if (index >= MAX_VERTEX_ATTRIBS)
4888 {
Jamie Madille0472f32018-11-27 16:32:45 -05004889 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004890 return false;
4891 }
4892
4893 return true;
4894}
4895
Jamie Madill5b772312018-03-08 20:28:32 -05004896bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004897{
4898 return true;
4899}
4900
Jamie Madill5b772312018-03-08 20:28:32 -05004901bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004902{
4903 return true;
4904}
4905
Jamie Madill5b772312018-03-08 20:28:32 -05004906bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004907{
4908 switch (mode)
4909 {
4910 case GL_CW:
4911 case GL_CCW:
4912 break;
4913 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004914 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004915 return false;
4916 }
4917
4918 return true;
4919}
4920
Jamie Madill5b772312018-03-08 20:28:32 -05004921bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004922 GLuint program,
4923 GLuint index,
4924 GLsizei bufsize,
4925 GLsizei *length,
4926 GLint *size,
4927 GLenum *type,
4928 GLchar *name)
4929{
4930 if (bufsize < 0)
4931 {
Jamie Madille0472f32018-11-27 16:32:45 -05004932 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004933 return false;
4934 }
4935
4936 Program *programObject = GetValidProgram(context, program);
4937
4938 if (!programObject)
4939 {
4940 return false;
4941 }
4942
4943 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
4944 {
Jamie Madille0472f32018-11-27 16:32:45 -05004945 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004946 return false;
4947 }
4948
4949 return true;
4950}
4951
Jamie Madill5b772312018-03-08 20:28:32 -05004952bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004953 GLuint program,
4954 GLuint index,
4955 GLsizei bufsize,
4956 GLsizei *length,
4957 GLint *size,
4958 GLenum *type,
4959 GLchar *name)
4960{
4961 if (bufsize < 0)
4962 {
Jamie Madille0472f32018-11-27 16:32:45 -05004963 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004964 return false;
4965 }
4966
4967 Program *programObject = GetValidProgram(context, program);
4968
4969 if (!programObject)
4970 {
4971 return false;
4972 }
4973
4974 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
4975 {
Jamie Madille0472f32018-11-27 16:32:45 -05004976 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004977 return false;
4978 }
4979
4980 return true;
4981}
4982
Jamie Madill5b772312018-03-08 20:28:32 -05004983bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004984 GLuint program,
4985 GLsizei maxcount,
4986 GLsizei *count,
4987 GLuint *shaders)
4988{
4989 if (maxcount < 0)
4990 {
Jamie Madille0472f32018-11-27 16:32:45 -05004991 context->validationError(GL_INVALID_VALUE, kNegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004992 return false;
4993 }
4994
4995 Program *programObject = GetValidProgram(context, program);
4996
4997 if (!programObject)
4998 {
4999 return false;
5000 }
5001
5002 return true;
5003}
5004
Jamie Madill5b772312018-03-08 20:28:32 -05005005bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005006{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005007 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5008 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005009 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005010 {
Jamie Madille0472f32018-11-27 16:32:45 -05005011 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005012 return false;
5013 }
5014
Jamie Madillc1d770e2017-04-13 17:31:24 -04005015 Program *programObject = GetValidProgram(context, program);
5016
5017 if (!programObject)
5018 {
Jamie Madille0472f32018-11-27 16:32:45 -05005019 context->validationError(GL_INVALID_OPERATION, kProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005020 return false;
5021 }
5022
5023 if (!programObject->isLinked())
5024 {
Jamie Madille0472f32018-11-27 16:32:45 -05005025 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005026 return false;
5027 }
5028
5029 return true;
5030}
5031
Jamie Madill5b772312018-03-08 20:28:32 -05005032bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005033{
5034 GLenum nativeType;
5035 unsigned int numParams = 0;
5036 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5037}
5038
Jamie Madill5b772312018-03-08 20:28:32 -05005039bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005040{
5041 return true;
5042}
5043
Jamie Madill5b772312018-03-08 20:28:32 -05005044bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005045{
5046 GLenum nativeType;
5047 unsigned int numParams = 0;
5048 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5049}
5050
Jamie Madill5b772312018-03-08 20:28:32 -05005051bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005052{
5053 GLenum nativeType;
5054 unsigned int numParams = 0;
5055 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5056}
5057
Jamie Madill5b772312018-03-08 20:28:32 -05005058bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005059 GLuint program,
5060 GLsizei bufsize,
5061 GLsizei *length,
5062 GLchar *infolog)
5063{
5064 if (bufsize < 0)
5065 {
Jamie Madille0472f32018-11-27 16:32:45 -05005066 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005067 return false;
5068 }
5069
5070 Program *programObject = GetValidProgram(context, program);
5071 if (!programObject)
5072 {
5073 return false;
5074 }
5075
5076 return true;
5077}
5078
Jamie Madill5b772312018-03-08 20:28:32 -05005079bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005080 GLuint shader,
5081 GLsizei bufsize,
5082 GLsizei *length,
5083 GLchar *infolog)
5084{
5085 if (bufsize < 0)
5086 {
Jamie Madille0472f32018-11-27 16:32:45 -05005087 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005088 return false;
5089 }
5090
5091 Shader *shaderObject = GetValidShader(context, shader);
5092 if (!shaderObject)
5093 {
5094 return false;
5095 }
5096
5097 return true;
5098}
5099
Jamie Madill5b772312018-03-08 20:28:32 -05005100bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005101 GLenum shadertype,
5102 GLenum precisiontype,
5103 GLint *range,
5104 GLint *precision)
5105{
5106 switch (shadertype)
5107 {
5108 case GL_VERTEX_SHADER:
5109 case GL_FRAGMENT_SHADER:
5110 break;
5111 case GL_COMPUTE_SHADER:
Jamie Madillc3e37312018-11-30 15:25:39 -05005112 context->validationError(GL_INVALID_OPERATION, kUnimplementedComputeShaderPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005113 return false;
5114 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005115 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005116 return false;
5117 }
5118
5119 switch (precisiontype)
5120 {
5121 case GL_LOW_FLOAT:
5122 case GL_MEDIUM_FLOAT:
5123 case GL_HIGH_FLOAT:
5124 case GL_LOW_INT:
5125 case GL_MEDIUM_INT:
5126 case GL_HIGH_INT:
5127 break;
5128
5129 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005130 context->validationError(GL_INVALID_ENUM, kInvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005131 return false;
5132 }
5133
5134 return true;
5135}
5136
Jamie Madill5b772312018-03-08 20:28:32 -05005137bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005138 GLuint shader,
5139 GLsizei bufsize,
5140 GLsizei *length,
5141 GLchar *source)
5142{
5143 if (bufsize < 0)
5144 {
Jamie Madille0472f32018-11-27 16:32:45 -05005145 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005146 return false;
5147 }
5148
5149 Shader *shaderObject = GetValidShader(context, shader);
5150 if (!shaderObject)
5151 {
5152 return false;
5153 }
5154
5155 return true;
5156}
5157
Jamie Madill5b772312018-03-08 20:28:32 -05005158bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005159{
5160 if (strstr(name, "gl_") == name)
5161 {
5162 return false;
5163 }
5164
Geoff Langfc32e8b2017-05-31 14:16:59 -04005165 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5166 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005167 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005168 {
Jamie Madille0472f32018-11-27 16:32:45 -05005169 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005170 return false;
5171 }
5172
Jamie Madillc1d770e2017-04-13 17:31:24 -04005173 Program *programObject = GetValidProgram(context, program);
5174
5175 if (!programObject)
5176 {
5177 return false;
5178 }
5179
5180 if (!programObject->isLinked())
5181 {
Jamie Madille0472f32018-11-27 16:32:45 -05005182 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005183 return false;
5184 }
5185
5186 return true;
5187}
5188
Jamie Madill5b772312018-03-08 20:28:32 -05005189bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005190{
5191 switch (mode)
5192 {
5193 case GL_FASTEST:
5194 case GL_NICEST:
5195 case GL_DONT_CARE:
5196 break;
5197
5198 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005199 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005200 return false;
5201 }
5202
5203 switch (target)
5204 {
5205 case GL_GENERATE_MIPMAP_HINT:
5206 break;
5207
Geoff Lange7bd2182017-06-16 16:13:13 -04005208 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5209 if (context->getClientVersion() < ES_3_0 &&
5210 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005211 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005212 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005213 return false;
5214 }
5215 break;
5216
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07005217 case GL_PERSPECTIVE_CORRECTION_HINT:
5218 case GL_POINT_SMOOTH_HINT:
5219 case GL_LINE_SMOOTH_HINT:
5220 case GL_FOG_HINT:
5221 if (context->getClientMajorVersion() >= 2)
5222 {
Jamie Madille0472f32018-11-27 16:32:45 -05005223 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07005224 return false;
5225 }
5226 break;
5227
Jamie Madillc1d770e2017-04-13 17:31:24 -04005228 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005229 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005230 return false;
5231 }
5232
5233 return true;
5234}
5235
Jamie Madill5b772312018-03-08 20:28:32 -05005236bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005237{
5238 return true;
5239}
5240
Jamie Madill5b772312018-03-08 20:28:32 -05005241bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005242{
5243 return true;
5244}
5245
Jamie Madill5b772312018-03-08 20:28:32 -05005246bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005247{
5248 return true;
5249}
5250
Jamie Madill5b772312018-03-08 20:28:32 -05005251bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005252{
5253 return true;
5254}
5255
Jamie Madill5b772312018-03-08 20:28:32 -05005256bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005257{
5258 return true;
5259}
5260
Jamie Madill5b772312018-03-08 20:28:32 -05005261bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005262{
5263 return true;
5264}
5265
Jamie Madill5b772312018-03-08 20:28:32 -05005266bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005267{
5268 if (context->getClientMajorVersion() < 3)
5269 {
5270 switch (pname)
5271 {
5272 case GL_UNPACK_IMAGE_HEIGHT:
5273 case GL_UNPACK_SKIP_IMAGES:
Jamie Madille0472f32018-11-27 16:32:45 -05005274 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005275 return false;
5276
5277 case GL_UNPACK_ROW_LENGTH:
5278 case GL_UNPACK_SKIP_ROWS:
5279 case GL_UNPACK_SKIP_PIXELS:
5280 if (!context->getExtensions().unpackSubimage)
5281 {
Jamie Madille0472f32018-11-27 16:32:45 -05005282 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005283 return false;
5284 }
5285 break;
5286
5287 case GL_PACK_ROW_LENGTH:
5288 case GL_PACK_SKIP_ROWS:
5289 case GL_PACK_SKIP_PIXELS:
5290 if (!context->getExtensions().packSubimage)
5291 {
Jamie Madille0472f32018-11-27 16:32:45 -05005292 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005293 return false;
5294 }
5295 break;
5296 }
5297 }
5298
5299 if (param < 0)
5300 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005301 context->validationError(GL_INVALID_VALUE, kNegativeParam);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005302 return false;
5303 }
5304
5305 switch (pname)
5306 {
5307 case GL_UNPACK_ALIGNMENT:
5308 if (param != 1 && param != 2 && param != 4 && param != 8)
5309 {
Jamie Madille0472f32018-11-27 16:32:45 -05005310 context->validationError(GL_INVALID_VALUE, kInvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005311 return false;
5312 }
5313 break;
5314
5315 case GL_PACK_ALIGNMENT:
5316 if (param != 1 && param != 2 && param != 4 && param != 8)
5317 {
Jamie Madille0472f32018-11-27 16:32:45 -05005318 context->validationError(GL_INVALID_VALUE, kInvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005319 return false;
5320 }
5321 break;
5322
5323 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005324 if (!context->getExtensions().packReverseRowOrder)
5325 {
Jamie Madille0472f32018-11-27 16:32:45 -05005326 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang000dab82017-09-27 14:27:07 -04005327 }
5328 break;
5329
Jamie Madillc1d770e2017-04-13 17:31:24 -04005330 case GL_UNPACK_ROW_LENGTH:
5331 case GL_UNPACK_IMAGE_HEIGHT:
5332 case GL_UNPACK_SKIP_IMAGES:
5333 case GL_UNPACK_SKIP_ROWS:
5334 case GL_UNPACK_SKIP_PIXELS:
5335 case GL_PACK_ROW_LENGTH:
5336 case GL_PACK_SKIP_ROWS:
5337 case GL_PACK_SKIP_PIXELS:
5338 break;
5339
5340 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005341 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005342 return false;
5343 }
5344
5345 return true;
5346}
5347
Jamie Madill5b772312018-03-08 20:28:32 -05005348bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005349{
5350 return true;
5351}
5352
Jamie Madill5b772312018-03-08 20:28:32 -05005353bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005354{
5355 return true;
5356}
5357
Jamie Madill5b772312018-03-08 20:28:32 -05005358bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005359{
5360 return true;
5361}
5362
Jamie Madill5b772312018-03-08 20:28:32 -05005363bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005364{
5365 if (width < 0 || height < 0)
5366 {
Jamie Madille0472f32018-11-27 16:32:45 -05005367 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005368 return false;
5369 }
5370
5371 return true;
5372}
5373
Jamie Madill5b772312018-03-08 20:28:32 -05005374bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005375 GLsizei n,
5376 const GLuint *shaders,
5377 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005378 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005379 GLsizei length)
5380{
5381 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5382 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5383 shaderBinaryFormats.end())
5384 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005385 context->validationError(GL_INVALID_ENUM, kInvalidShaderBinaryFormat);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005386 return false;
5387 }
5388
5389 return true;
5390}
5391
Jamie Madill5b772312018-03-08 20:28:32 -05005392bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005393 GLuint shader,
5394 GLsizei count,
5395 const GLchar *const *string,
5396 const GLint *length)
5397{
5398 if (count < 0)
5399 {
Jamie Madille0472f32018-11-27 16:32:45 -05005400 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005401 return false;
5402 }
5403
Geoff Langfc32e8b2017-05-31 14:16:59 -04005404 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5405 // shader-related entry points
5406 if (context->getExtensions().webglCompatibility)
5407 {
5408 for (GLsizei i = 0; i < count; i++)
5409 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005410 size_t len =
5411 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005412
5413 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005414 if (!IsValidESSLShaderSourceString(string[i], len,
5415 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005416 {
Jamie Madille0472f32018-11-27 16:32:45 -05005417 context->validationError(GL_INVALID_VALUE, kShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005418 return false;
5419 }
5420 }
5421 }
5422
Jamie Madillc1d770e2017-04-13 17:31:24 -04005423 Shader *shaderObject = GetValidShader(context, shader);
5424 if (!shaderObject)
5425 {
5426 return false;
5427 }
5428
5429 return true;
5430}
5431
Jamie Madill5b772312018-03-08 20:28:32 -05005432bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005433{
5434 if (!IsValidStencilFunc(func))
5435 {
Jamie Madille0472f32018-11-27 16:32:45 -05005436 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005437 return false;
5438 }
5439
5440 return true;
5441}
5442
Jamie Madill5b772312018-03-08 20:28:32 -05005443bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005444{
5445 if (!IsValidStencilFace(face))
5446 {
Jamie Madille0472f32018-11-27 16:32:45 -05005447 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005448 return false;
5449 }
5450
5451 if (!IsValidStencilFunc(func))
5452 {
Jamie Madille0472f32018-11-27 16:32:45 -05005453 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005454 return false;
5455 }
5456
5457 return true;
5458}
5459
Jamie Madill5b772312018-03-08 20:28:32 -05005460bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005461{
5462 return true;
5463}
5464
Jamie Madill5b772312018-03-08 20:28:32 -05005465bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005466{
5467 if (!IsValidStencilFace(face))
5468 {
Jamie Madille0472f32018-11-27 16:32:45 -05005469 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005470 return false;
5471 }
5472
5473 return true;
5474}
5475
Jamie Madill5b772312018-03-08 20:28:32 -05005476bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005477{
5478 if (!IsValidStencilOp(fail))
5479 {
Jamie Madille0472f32018-11-27 16:32:45 -05005480 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005481 return false;
5482 }
5483
5484 if (!IsValidStencilOp(zfail))
5485 {
Jamie Madille0472f32018-11-27 16:32:45 -05005486 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005487 return false;
5488 }
5489
5490 if (!IsValidStencilOp(zpass))
5491 {
Jamie Madille0472f32018-11-27 16:32:45 -05005492 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005493 return false;
5494 }
5495
5496 return true;
5497}
5498
Jamie Madill5b772312018-03-08 20:28:32 -05005499bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005500 GLenum face,
5501 GLenum fail,
5502 GLenum zfail,
5503 GLenum zpass)
5504{
5505 if (!IsValidStencilFace(face))
5506 {
Jamie Madille0472f32018-11-27 16:32:45 -05005507 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005508 return false;
5509 }
5510
5511 return ValidateStencilOp(context, fail, zfail, zpass);
5512}
5513
Jamie Madill5b772312018-03-08 20:28:32 -05005514bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005515{
5516 return ValidateUniform(context, GL_FLOAT, location, 1);
5517}
5518
Jamie Madill5b772312018-03-08 20:28:32 -05005519bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005520{
5521 return ValidateUniform(context, GL_FLOAT, location, count);
5522}
5523
Jamie Madill5b772312018-03-08 20:28:32 -05005524bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005525{
5526 return ValidateUniform1iv(context, location, 1, &x);
5527}
5528
Jamie Madill5b772312018-03-08 20:28:32 -05005529bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005530{
5531 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5532}
5533
Jamie Madill5b772312018-03-08 20:28:32 -05005534bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005535{
5536 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5537}
5538
Jamie Madill5b772312018-03-08 20:28:32 -05005539bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005540{
5541 return ValidateUniform(context, GL_INT_VEC2, location, count);
5542}
5543
Jamie Madill5b772312018-03-08 20:28:32 -05005544bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005545{
5546 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5547}
5548
Jamie Madill5b772312018-03-08 20:28:32 -05005549bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005550{
5551 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5552}
5553
Jamie Madill5b772312018-03-08 20:28:32 -05005554bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005555{
5556 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5557}
5558
Jamie Madill5b772312018-03-08 20:28:32 -05005559bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005560{
5561 return ValidateUniform(context, GL_INT_VEC3, location, count);
5562}
5563
Jamie Madill5b772312018-03-08 20:28:32 -05005564bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005565{
5566 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5567}
5568
Jamie Madill5b772312018-03-08 20:28:32 -05005569bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005570{
5571 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5572}
5573
Jamie Madill5b772312018-03-08 20:28:32 -05005574bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005575{
5576 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5577}
5578
Jamie Madill5b772312018-03-08 20:28:32 -05005579bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005580{
5581 return ValidateUniform(context, GL_INT_VEC4, location, count);
5582}
5583
Jamie Madill5b772312018-03-08 20:28:32 -05005584bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005585 GLint location,
5586 GLsizei count,
5587 GLboolean transpose,
5588 const GLfloat *value)
5589{
5590 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5591}
5592
Jamie Madill5b772312018-03-08 20:28:32 -05005593bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005594 GLint location,
5595 GLsizei count,
5596 GLboolean transpose,
5597 const GLfloat *value)
5598{
5599 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5600}
5601
Jamie Madill5b772312018-03-08 20:28:32 -05005602bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005603 GLint location,
5604 GLsizei count,
5605 GLboolean transpose,
5606 const GLfloat *value)
5607{
5608 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5609}
5610
Jamie Madill5b772312018-03-08 20:28:32 -05005611bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005612{
5613 Program *programObject = GetValidProgram(context, program);
5614
5615 if (!programObject)
5616 {
5617 return false;
5618 }
5619
5620 return true;
5621}
5622
Jamie Madill5b772312018-03-08 20:28:32 -05005623bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005624{
5625 return ValidateVertexAttribIndex(context, index);
5626}
5627
Jamie Madill5b772312018-03-08 20:28:32 -05005628bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005629{
5630 return ValidateVertexAttribIndex(context, index);
5631}
5632
Jamie Madill5b772312018-03-08 20:28:32 -05005633bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005634{
5635 return ValidateVertexAttribIndex(context, index);
5636}
5637
Jamie Madill5b772312018-03-08 20:28:32 -05005638bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005639{
5640 return ValidateVertexAttribIndex(context, index);
5641}
5642
Jamie Madill5b772312018-03-08 20:28:32 -05005643bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005644{
5645 return ValidateVertexAttribIndex(context, index);
5646}
5647
Jamie Madill5b772312018-03-08 20:28:32 -05005648bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005649{
5650 return ValidateVertexAttribIndex(context, index);
5651}
5652
Jamie Madill5b772312018-03-08 20:28:32 -05005653bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005654 GLuint index,
5655 GLfloat x,
5656 GLfloat y,
5657 GLfloat z,
5658 GLfloat w)
5659{
5660 return ValidateVertexAttribIndex(context, index);
5661}
5662
Jamie Madill5b772312018-03-08 20:28:32 -05005663bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005664{
5665 return ValidateVertexAttribIndex(context, index);
5666}
5667
Jamie Madill5b772312018-03-08 20:28:32 -05005668bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005669{
5670 if (width < 0 || height < 0)
5671 {
Jamie Madille0472f32018-11-27 16:32:45 -05005672 context->validationError(GL_INVALID_VALUE, kViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005673 return false;
5674 }
5675
5676 return true;
5677}
5678
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005679bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005680 GLenum target,
5681 GLenum attachment,
5682 GLenum pname,
5683 GLint *params)
5684{
5685 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5686 nullptr);
5687}
5688
Jamie Madill5b772312018-03-08 20:28:32 -05005689bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04005690{
5691 return ValidateGetProgramivBase(context, program, pname, nullptr);
5692}
5693
Jamie Madill5b772312018-03-08 20:28:32 -05005694bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005695 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005696 GLint level,
5697 GLenum internalformat,
5698 GLint x,
5699 GLint y,
5700 GLsizei width,
5701 GLsizei height,
5702 GLint border)
5703{
5704 if (context->getClientMajorVersion() < 3)
5705 {
5706 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5707 0, x, y, width, height, border);
5708 }
5709
5710 ASSERT(context->getClientMajorVersion() == 3);
5711 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5712 0, x, y, width, height, border);
5713}
5714
5715bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005716 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005717 GLint level,
5718 GLint xoffset,
5719 GLint yoffset,
5720 GLint x,
5721 GLint y,
5722 GLsizei width,
5723 GLsizei height)
5724{
5725 if (context->getClientMajorVersion() < 3)
5726 {
5727 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5728 yoffset, x, y, width, height, 0);
5729 }
5730
5731 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5732 yoffset, 0, x, y, width, height, 0);
5733}
5734
5735bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5736{
5737 return ValidateGenOrDelete(context, n);
5738}
5739
5740bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5741{
5742 return ValidateGenOrDelete(context, n);
5743}
5744
5745bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5746{
5747 return ValidateGenOrDelete(context, n);
5748}
5749
5750bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5751{
5752 return ValidateGenOrDelete(context, n);
5753}
5754
5755bool ValidateDisable(Context *context, GLenum cap)
5756{
5757 if (!ValidCap(context, cap, false))
5758 {
Jamie Madille0472f32018-11-27 16:32:45 -05005759 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005760 return false;
5761 }
5762
5763 return true;
5764}
5765
5766bool ValidateEnable(Context *context, GLenum cap)
5767{
5768 if (!ValidCap(context, cap, false))
5769 {
Jamie Madille0472f32018-11-27 16:32:45 -05005770 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005771 return false;
5772 }
5773
5774 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5775 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5776 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005777 context->validationError(GL_INVALID_OPERATION, kNoSampleAlphaToCoveragesLimitation);
Jamie Madillbe849e42017-05-02 15:49:00 -04005778
5779 // We also output an error message to the debugger window if tracing is active, so that
5780 // developers can see the error message.
Jamie Madillc3e37312018-11-30 15:25:39 -05005781 ERR() << kNoSampleAlphaToCoveragesLimitation;
Jamie Madillbe849e42017-05-02 15:49:00 -04005782 return false;
5783 }
5784
5785 return true;
5786}
5787
5788bool ValidateFramebufferRenderbuffer(Context *context,
5789 GLenum target,
5790 GLenum attachment,
5791 GLenum renderbuffertarget,
5792 GLuint renderbuffer)
5793{
Geoff Lange8afa902017-09-27 15:00:43 -04005794 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005795 {
Jamie Madille0472f32018-11-27 16:32:45 -05005796 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Brandon Jones6cad5662017-06-14 13:25:13 -07005797 return false;
5798 }
5799
5800 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5801 {
Jamie Madille0472f32018-11-27 16:32:45 -05005802 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005803 return false;
5804 }
5805
5806 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5807 renderbuffertarget, renderbuffer);
5808}
5809
5810bool ValidateFramebufferTexture2D(Context *context,
5811 GLenum target,
5812 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005813 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04005814 GLuint texture,
5815 GLint level)
5816{
5817 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5818 // extension
5819 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5820 level != 0)
5821 {
Jamie Madille0472f32018-11-27 16:32:45 -05005822 context->validationError(GL_INVALID_VALUE, kInvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005823 return false;
5824 }
5825
5826 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5827 {
5828 return false;
5829 }
5830
5831 if (texture != 0)
5832 {
5833 gl::Texture *tex = context->getTexture(texture);
5834 ASSERT(tex);
5835
5836 const gl::Caps &caps = context->getCaps();
5837
5838 switch (textarget)
5839 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005840 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04005841 {
5842 if (level > gl::log2(caps.max2DTextureSize))
5843 {
Jamie Madille0472f32018-11-27 16:32:45 -05005844 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005845 return false;
5846 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005847 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04005848 {
Jamie Madille0472f32018-11-27 16:32:45 -05005849 context->validationError(GL_INVALID_OPERATION, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005850 return false;
5851 }
5852 }
5853 break;
5854
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005855 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005856 {
5857 if (level != 0)
5858 {
Jamie Madille0472f32018-11-27 16:32:45 -05005859 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005860 return false;
5861 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005862 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005863 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005864 context->validationError(GL_INVALID_OPERATION, kTextureTargetMismatch);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005865 return false;
5866 }
5867 }
5868 break;
5869
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005870 case TextureTarget::CubeMapNegativeX:
5871 case TextureTarget::CubeMapNegativeY:
5872 case TextureTarget::CubeMapNegativeZ:
5873 case TextureTarget::CubeMapPositiveX:
5874 case TextureTarget::CubeMapPositiveY:
5875 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04005876 {
5877 if (level > gl::log2(caps.maxCubeMapTextureSize))
5878 {
Jamie Madille0472f32018-11-27 16:32:45 -05005879 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005880 return false;
5881 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005882 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04005883 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005884 context->validationError(GL_INVALID_OPERATION, kTextureTargetMismatch);
Jamie Madillbe849e42017-05-02 15:49:00 -04005885 return false;
5886 }
5887 }
5888 break;
5889
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005890 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04005891 {
Yizhou Jiang7818a852018-09-06 15:02:04 +08005892 if (context->getClientVersion() < ES_3_1 &&
5893 !context->getExtensions().textureMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04005894 {
Jamie Madill610640f2018-11-21 17:28:41 -05005895 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05005896 kMultisampleTextureExtensionOrES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04005897 return false;
5898 }
5899
5900 if (level != 0)
5901 {
Jamie Madille0472f32018-11-27 16:32:45 -05005902 context->validationError(GL_INVALID_VALUE, kLevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04005903 return false;
5904 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005905 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04005906 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005907 context->validationError(GL_INVALID_OPERATION, kTextureTargetMismatch);
Jamie Madillbe849e42017-05-02 15:49:00 -04005908 return false;
5909 }
5910 }
5911 break;
5912
5913 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005914 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005915 return false;
5916 }
Jamie Madillbe849e42017-05-02 15:49:00 -04005917 }
5918
5919 return true;
5920}
5921
5922bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
5923{
5924 return ValidateGenOrDelete(context, n);
5925}
5926
5927bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
5928{
5929 return ValidateGenOrDelete(context, n);
5930}
5931
5932bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
5933{
5934 return ValidateGenOrDelete(context, n);
5935}
5936
5937bool ValidateGenTextures(Context *context, GLint n, GLuint *)
5938{
5939 return ValidateGenOrDelete(context, n);
5940}
5941
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005942bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04005943{
5944 if (!ValidTextureTarget(context, target))
5945 {
Jamie Madille0472f32018-11-27 16:32:45 -05005946 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005947 return false;
5948 }
5949
5950 Texture *texture = context->getTargetTexture(target);
5951
5952 if (texture == nullptr)
5953 {
Jamie Madille0472f32018-11-27 16:32:45 -05005954 context->validationError(GL_INVALID_OPERATION, kTextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005955 return false;
5956 }
5957
5958 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
5959
5960 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
5961 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
5962 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
5963 {
Jamie Madille0472f32018-11-27 16:32:45 -05005964 context->validationError(GL_INVALID_OPERATION, kBaseLevelOutOfRange);
Jamie Madillbe849e42017-05-02 15:49:00 -04005965 return false;
5966 }
5967
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005968 TextureTarget baseTarget = (target == TextureType::CubeMap)
5969 ? TextureTarget::CubeMapPositiveX
5970 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04005971 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
5972 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
5973 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07005974 {
Jamie Madille0472f32018-11-27 16:32:45 -05005975 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Brandon Jones6cad5662017-06-14 13:25:13 -07005976 return false;
5977 }
5978
Geoff Lang536eca12017-09-13 11:23:35 -04005979 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
5980 bool formatUnsized = !format.sized;
5981 bool formatColorRenderableAndFilterable =
5982 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
Yuly Novikovf15f8862018-06-04 18:59:41 -04005983 format.textureAttachmentSupport(context->getClientVersion(), context->getExtensions());
Geoff Lang536eca12017-09-13 11:23:35 -04005984 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04005985 {
Jamie Madille0472f32018-11-27 16:32:45 -05005986 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04005987 return false;
5988 }
5989
Geoff Lang536eca12017-09-13 11:23:35 -04005990 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
5991 // generation
5992 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
5993 {
Jamie Madille0472f32018-11-27 16:32:45 -05005994 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Geoff Lang536eca12017-09-13 11:23:35 -04005995 return false;
5996 }
5997
Jiange2c00842018-07-13 16:50:49 +08005998 // According to the OpenGL extension spec EXT_sRGB.txt, EXT_SRGB is based on ES 2.0 and
5999 // generateMipmap is not allowed if texture format is SRGB_EXT or SRGB_ALPHA_EXT.
6000 if (context->getClientVersion() < Version(3, 0) && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006001 {
Jamie Madille0472f32018-11-27 16:32:45 -05006002 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006003 return false;
6004 }
6005
6006 // Non-power of 2 ES2 check
6007 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6008 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6009 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6010 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006011 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6012 target == TextureType::CubeMap);
Jamie Madille0472f32018-11-27 16:32:45 -05006013 context->validationError(GL_INVALID_OPERATION, kTextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006014 return false;
6015 }
6016
6017 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006018 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006019 {
Jamie Madille0472f32018-11-27 16:32:45 -05006020 context->validationError(GL_INVALID_OPERATION, kCubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006021 return false;
6022 }
6023
James Darpinian83b2f0e2018-11-27 15:56:01 -08006024 if (context->getExtensions().webglCompatibility &&
6025 (texture->getWidth(baseTarget, effectiveBaseLevel) == 0 ||
6026 texture->getHeight(baseTarget, effectiveBaseLevel) == 0))
6027 {
6028 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapZeroSize);
6029 return false;
6030 }
6031
Jamie Madillbe849e42017-05-02 15:49:00 -04006032 return true;
6033}
6034
Jamie Madill5b772312018-03-08 20:28:32 -05006035bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006036 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006037 GLenum pname,
6038 GLint *params)
6039{
6040 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6041}
6042
6043bool ValidateGetRenderbufferParameteriv(Context *context,
6044 GLenum target,
6045 GLenum pname,
6046 GLint *params)
6047{
6048 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6049}
6050
6051bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6052{
6053 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6054}
6055
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006056bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006057{
6058 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6059}
6060
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006061bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006062{
6063 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6064}
6065
Till Rathmannb8543632018-10-02 19:46:14 +02006066bool ValidateGetTexParameterIivOES(Context *context,
6067 TextureType target,
6068 GLenum pname,
6069 GLint *params)
6070{
6071 if (context->getClientMajorVersion() < 3)
6072 {
Jamie Madille0472f32018-11-27 16:32:45 -05006073 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006074 return false;
6075 }
6076 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6077}
6078
6079bool ValidateGetTexParameterIuivOES(Context *context,
6080 TextureType target,
6081 GLenum pname,
6082 GLuint *params)
6083{
6084 if (context->getClientMajorVersion() < 3)
6085 {
Jamie Madille0472f32018-11-27 16:32:45 -05006086 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006087 return false;
6088 }
6089 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6090}
6091
Jamie Madillbe849e42017-05-02 15:49:00 -04006092bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6093{
6094 return ValidateGetUniformBase(context, program, location);
6095}
6096
6097bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6098{
6099 return ValidateGetUniformBase(context, program, location);
6100}
6101
6102bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6103{
6104 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6105}
6106
6107bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6108{
6109 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6110}
6111
6112bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6113{
6114 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6115}
6116
6117bool ValidateIsEnabled(Context *context, GLenum cap)
6118{
6119 if (!ValidCap(context, cap, true))
6120 {
Jamie Madille0472f32018-11-27 16:32:45 -05006121 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006122 return false;
6123 }
6124
6125 return true;
6126}
6127
6128bool ValidateLinkProgram(Context *context, GLuint program)
6129{
6130 if (context->hasActiveTransformFeedback(program))
6131 {
6132 // ES 3.0.4 section 2.15 page 91
Jamie Madillc3e37312018-11-30 15:25:39 -05006133 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackActiveDuringLink);
Jamie Madillbe849e42017-05-02 15:49:00 -04006134 return false;
6135 }
6136
6137 Program *programObject = GetValidProgram(context, program);
6138 if (!programObject)
6139 {
6140 return false;
6141 }
6142
6143 return true;
6144}
6145
Jamie Madill4928b7c2017-06-20 12:57:39 -04006146bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006147 GLint x,
6148 GLint y,
6149 GLsizei width,
6150 GLsizei height,
6151 GLenum format,
6152 GLenum type,
6153 void *pixels)
6154{
6155 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6156 nullptr, pixels);
6157}
6158
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006159bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006160{
Till Rathmannb8543632018-10-02 19:46:14 +02006161 return ValidateTexParameterBase(context, target, pname, -1, false, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006162}
6163
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006164bool ValidateTexParameterfv(Context *context,
6165 TextureType target,
6166 GLenum pname,
6167 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006168{
Till Rathmannb8543632018-10-02 19:46:14 +02006169 return ValidateTexParameterBase(context, target, pname, -1, true, params);
Jamie Madillbe849e42017-05-02 15:49:00 -04006170}
6171
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006172bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006173{
Till Rathmannb8543632018-10-02 19:46:14 +02006174 return ValidateTexParameterBase(context, target, pname, -1, false, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006175}
6176
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006177bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006178{
Till Rathmannb8543632018-10-02 19:46:14 +02006179 return ValidateTexParameterBase(context, target, pname, -1, true, params);
6180}
6181
6182bool ValidateTexParameterIivOES(Context *context,
6183 TextureType target,
6184 GLenum pname,
6185 const GLint *params)
6186{
6187 if (context->getClientMajorVersion() < 3)
6188 {
Jamie Madille0472f32018-11-27 16:32:45 -05006189 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006190 return false;
6191 }
6192 return ValidateTexParameterBase(context, target, pname, -1, true, params);
6193}
6194
6195bool ValidateTexParameterIuivOES(Context *context,
6196 TextureType target,
6197 GLenum pname,
6198 const GLuint *params)
6199{
6200 if (context->getClientMajorVersion() < 3)
6201 {
Jamie Madille0472f32018-11-27 16:32:45 -05006202 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006203 return false;
6204 }
6205 return ValidateTexParameterBase(context, target, pname, -1, true, params);
Jamie Madillbe849e42017-05-02 15:49:00 -04006206}
6207
6208bool ValidateUseProgram(Context *context, GLuint program)
6209{
6210 if (program != 0)
6211 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04006212 Program *programObject = context->getProgramResolveLink(program);
Jamie Madillbe849e42017-05-02 15:49:00 -04006213 if (!programObject)
6214 {
6215 // ES 3.1.0 section 7.3 page 72
6216 if (context->getShader(program))
6217 {
Jamie Madille0472f32018-11-27 16:32:45 -05006218 context->validationError(GL_INVALID_OPERATION, kExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006219 return false;
6220 }
6221 else
6222 {
Jamie Madille0472f32018-11-27 16:32:45 -05006223 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006224 return false;
6225 }
6226 }
6227 if (!programObject->isLinked())
6228 {
Jamie Madille0472f32018-11-27 16:32:45 -05006229 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006230 return false;
6231 }
6232 }
Jamie Madillc3dc5d42018-12-30 12:12:04 -05006233 if (context->getState().isTransformFeedbackActiveUnpaused())
Jamie Madillbe849e42017-05-02 15:49:00 -04006234 {
6235 // ES 3.0.4 section 2.15 page 91
Jamie Madillc3e37312018-11-30 15:25:39 -05006236 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackUseProgram);
Jamie Madillbe849e42017-05-02 15:49:00 -04006237 return false;
6238 }
6239
6240 return true;
6241}
6242
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006243bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6244{
6245 if (!context->getExtensions().fence)
6246 {
Jamie Madille0472f32018-11-27 16:32:45 -05006247 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006248 return false;
6249 }
6250
6251 if (n < 0)
6252 {
Jamie Madille0472f32018-11-27 16:32:45 -05006253 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006254 return false;
6255 }
6256
6257 return true;
6258}
6259
6260bool ValidateFinishFenceNV(Context *context, GLuint fence)
6261{
6262 if (!context->getExtensions().fence)
6263 {
Jamie Madille0472f32018-11-27 16:32:45 -05006264 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006265 return false;
6266 }
6267
6268 FenceNV *fenceObject = context->getFenceNV(fence);
6269
6270 if (fenceObject == nullptr)
6271 {
Jamie Madille0472f32018-11-27 16:32:45 -05006272 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006273 return false;
6274 }
6275
6276 if (!fenceObject->isSet())
6277 {
Jamie Madille0472f32018-11-27 16:32:45 -05006278 context->validationError(GL_INVALID_OPERATION, kInvalidFenceState);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006279 return false;
6280 }
6281
6282 return true;
6283}
6284
6285bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6286{
6287 if (!context->getExtensions().fence)
6288 {
Jamie Madille0472f32018-11-27 16:32:45 -05006289 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006290 return false;
6291 }
6292
6293 if (n < 0)
6294 {
Jamie Madille0472f32018-11-27 16:32:45 -05006295 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006296 return false;
6297 }
6298
6299 return true;
6300}
6301
6302bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6303{
6304 if (!context->getExtensions().fence)
6305 {
Jamie Madille0472f32018-11-27 16:32:45 -05006306 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006307 return false;
6308 }
6309
6310 FenceNV *fenceObject = context->getFenceNV(fence);
6311
6312 if (fenceObject == nullptr)
6313 {
Jamie Madille0472f32018-11-27 16:32:45 -05006314 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006315 return false;
6316 }
6317
6318 if (!fenceObject->isSet())
6319 {
Jamie Madille0472f32018-11-27 16:32:45 -05006320 context->validationError(GL_INVALID_OPERATION, kInvalidFenceState);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006321 return false;
6322 }
6323
6324 switch (pname)
6325 {
6326 case GL_FENCE_STATUS_NV:
6327 case GL_FENCE_CONDITION_NV:
6328 break;
6329
6330 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006331 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006332 return false;
6333 }
6334
6335 return true;
6336}
6337
6338bool ValidateGetGraphicsResetStatusEXT(Context *context)
6339{
6340 if (!context->getExtensions().robustness)
6341 {
Jamie Madille0472f32018-11-27 16:32:45 -05006342 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006343 return false;
6344 }
6345
6346 return true;
6347}
6348
6349bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6350 GLuint shader,
6351 GLsizei bufsize,
6352 GLsizei *length,
6353 GLchar *source)
6354{
6355 if (!context->getExtensions().translatedShaderSource)
6356 {
Jamie Madille0472f32018-11-27 16:32:45 -05006357 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006358 return false;
6359 }
6360
6361 if (bufsize < 0)
6362 {
Jamie Madille0472f32018-11-27 16:32:45 -05006363 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006364 return false;
6365 }
6366
6367 Shader *shaderObject = context->getShader(shader);
6368
6369 if (!shaderObject)
6370 {
Jamie Madille0472f32018-11-27 16:32:45 -05006371 context->validationError(GL_INVALID_OPERATION, kInvalidShaderName);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006372 return false;
6373 }
6374
6375 return true;
6376}
6377
6378bool ValidateIsFenceNV(Context *context, GLuint fence)
6379{
6380 if (!context->getExtensions().fence)
6381 {
Jamie Madille0472f32018-11-27 16:32:45 -05006382 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006383 return false;
6384 }
6385
6386 return true;
6387}
6388
Jamie Madill007530e2017-12-28 14:27:04 -05006389bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6390{
6391 if (!context->getExtensions().fence)
6392 {
Jamie Madille0472f32018-11-27 16:32:45 -05006393 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill007530e2017-12-28 14:27:04 -05006394 return false;
6395 }
6396
6397 if (condition != GL_ALL_COMPLETED_NV)
6398 {
Jamie Madille0472f32018-11-27 16:32:45 -05006399 context->validationError(GL_INVALID_ENUM, kInvalidFenceCondition);
Jamie Madill007530e2017-12-28 14:27:04 -05006400 return false;
6401 }
6402
6403 FenceNV *fenceObject = context->getFenceNV(fence);
6404
6405 if (fenceObject == nullptr)
6406 {
Jamie Madille0472f32018-11-27 16:32:45 -05006407 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill007530e2017-12-28 14:27:04 -05006408 return false;
6409 }
6410
6411 return true;
6412}
6413
6414bool ValidateTestFenceNV(Context *context, GLuint fence)
6415{
6416 if (!context->getExtensions().fence)
6417 {
Jamie Madille0472f32018-11-27 16:32:45 -05006418 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill007530e2017-12-28 14:27:04 -05006419 return false;
6420 }
6421
6422 FenceNV *fenceObject = context->getFenceNV(fence);
6423
6424 if (fenceObject == nullptr)
6425 {
Jamie Madille0472f32018-11-27 16:32:45 -05006426 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill007530e2017-12-28 14:27:04 -05006427 return false;
6428 }
6429
6430 if (fenceObject->isSet() != GL_TRUE)
6431 {
Jamie Madille0472f32018-11-27 16:32:45 -05006432 context->validationError(GL_INVALID_OPERATION, kInvalidFenceState);
Jamie Madill007530e2017-12-28 14:27:04 -05006433 return false;
6434 }
6435
6436 return true;
6437}
6438
6439bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006440 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006441 GLsizei levels,
6442 GLenum internalformat,
6443 GLsizei width,
6444 GLsizei height)
6445{
6446 if (!context->getExtensions().textureStorage)
6447 {
Jamie Madille0472f32018-11-27 16:32:45 -05006448 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05006449 return false;
6450 }
6451
6452 if (context->getClientMajorVersion() < 3)
6453 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006454 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006455 height);
6456 }
6457
6458 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006459 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006460 1);
6461}
6462
6463bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6464{
Jonah Ryan-Davis2b0553c2019-02-08 10:07:21 -05006465 if (!context->getExtensions().instancedArraysANGLE)
Jamie Madill007530e2017-12-28 14:27:04 -05006466 {
Jamie Madille0472f32018-11-27 16:32:45 -05006467 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05006468 return false;
6469 }
6470
6471 if (index >= MAX_VERTEX_ATTRIBS)
6472 {
Jamie Madille0472f32018-11-27 16:32:45 -05006473 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madill007530e2017-12-28 14:27:04 -05006474 return false;
6475 }
6476
6477 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6478 {
6479 if (index == 0 && divisor != 0)
6480 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006481 context->validationError(GL_INVALID_OPERATION, kAttributeZeroRequiresDivisorLimitation);
Jamie Madill007530e2017-12-28 14:27:04 -05006482
6483 // We also output an error message to the debugger window if tracing is active, so
6484 // that developers can see the error message.
Jamie Madillc3e37312018-11-30 15:25:39 -05006485 ERR() << kAttributeZeroRequiresDivisorLimitation;
Jamie Madill007530e2017-12-28 14:27:04 -05006486 return false;
6487 }
6488 }
6489
6490 return true;
6491}
6492
Jonah Ryan-Davis2b0553c2019-02-08 10:07:21 -05006493bool ValidateVertexAttribDivisorEXT(Context *context, GLuint index, GLuint divisor)
6494{
6495 if (!context->getExtensions().instancedArraysEXT)
6496 {
6497 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
6498 return false;
6499 }
6500
6501 if (index >= MAX_VERTEX_ATTRIBS)
6502 {
6503 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
6504 return false;
6505 }
6506
6507 return true;
6508}
6509
Jamie Madill007530e2017-12-28 14:27:04 -05006510bool ValidateTexImage3DOES(Context *context,
6511 GLenum target,
6512 GLint level,
6513 GLenum internalformat,
6514 GLsizei width,
6515 GLsizei height,
6516 GLsizei depth,
6517 GLint border,
6518 GLenum format,
6519 GLenum type,
6520 const void *pixels)
6521{
6522 UNIMPLEMENTED(); // FIXME
6523 return false;
6524}
6525
6526bool ValidatePopGroupMarkerEXT(Context *context)
6527{
6528 if (!context->getExtensions().debugMarker)
6529 {
6530 // The debug marker calls should not set error state
6531 // However, it seems reasonable to set an error state if the extension is not enabled
Jamie Madille0472f32018-11-27 16:32:45 -05006532 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05006533 return false;
6534 }
6535
6536 return true;
6537}
6538
Jamie Madillfa920eb2018-01-04 11:45:50 -05006539bool ValidateTexStorage1DEXT(Context *context,
6540 GLenum target,
6541 GLsizei levels,
6542 GLenum internalformat,
6543 GLsizei width)
6544{
6545 UNIMPLEMENTED();
Jamie Madille0472f32018-11-27 16:32:45 -05006546 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05006547 return false;
6548}
6549
6550bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006551 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006552 GLsizei levels,
6553 GLenum internalformat,
6554 GLsizei width,
6555 GLsizei height,
6556 GLsizei depth)
6557{
6558 if (!context->getExtensions().textureStorage)
6559 {
Jamie Madille0472f32018-11-27 16:32:45 -05006560 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05006561 return false;
6562 }
6563
6564 if (context->getClientMajorVersion() < 3)
6565 {
Jamie Madille0472f32018-11-27 16:32:45 -05006566 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05006567 return false;
6568 }
6569
6570 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6571 depth);
6572}
6573
jchen1082af6202018-06-22 10:59:52 +08006574bool ValidateMaxShaderCompilerThreadsKHR(Context *context, GLuint count)
6575{
6576 if (!context->getExtensions().parallelShaderCompile)
6577 {
Jamie Madille0472f32018-11-27 16:32:45 -05006578 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
jchen1082af6202018-06-22 10:59:52 +08006579 return false;
6580 }
6581 return true;
6582}
6583
Austin Eng1bf18ce2018-10-19 15:34:02 -07006584bool ValidateMultiDrawArraysANGLE(Context *context,
6585 PrimitiveMode mode,
6586 const GLint *firsts,
6587 const GLsizei *counts,
6588 GLsizei drawcount)
6589{
6590 if (!context->getExtensions().multiDraw)
6591 {
Jamie Madille0472f32018-11-27 16:32:45 -05006592 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07006593 return false;
6594 }
6595 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
6596 {
6597 if (!ValidateDrawArrays(context, mode, firsts[drawID], counts[drawID]))
6598 {
6599 return false;
6600 }
6601 }
6602 return true;
6603}
6604
6605bool ValidateMultiDrawElementsANGLE(Context *context,
6606 PrimitiveMode mode,
6607 const GLsizei *counts,
Jamie Madill8dc27f92018-11-29 11:45:44 -05006608 DrawElementsType type,
Austin Eng3b7c9d02018-11-21 18:09:05 -08006609 const GLvoid *const *indices,
Austin Eng1bf18ce2018-10-19 15:34:02 -07006610 GLsizei drawcount)
6611{
6612 if (!context->getExtensions().multiDraw)
6613 {
Jamie Madille0472f32018-11-27 16:32:45 -05006614 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07006615 return false;
6616 }
6617 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
6618 {
Austin Eng3b7c9d02018-11-21 18:09:05 -08006619 if (!ValidateDrawElements(context, mode, counts[drawID], type, indices[drawID]))
Austin Eng1bf18ce2018-10-19 15:34:02 -07006620 {
6621 return false;
6622 }
6623 }
6624 return true;
6625}
6626
Jeff Gilbert465d6092019-01-02 16:21:18 -08006627bool ValidateProvokingVertexANGLE(Context *context, ProvokingVertex modePacked)
6628{
6629 if (!context->getExtensions().provokingVertex)
6630 {
6631 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
6632 return false;
6633 }
6634
6635 switch (modePacked)
6636 {
6637 case ProvokingVertex::FirstVertexConvention:
6638 case ProvokingVertex::LastVertexConvention:
6639 break;
6640 default:
6641 context->validationError(GL_INVALID_ENUM, kInvalidProvokingVertex);
6642 return false;
6643 }
6644
6645 return true;
6646}
6647
Jamie Madilla5410482019-01-31 19:55:55 -05006648void RecordBindTextureTypeError(Context *context, TextureType target)
6649{
6650 ASSERT(!context->getStateCache().isValidBindTextureType(target));
6651
6652 switch (target)
6653 {
6654 case TextureType::Rectangle:
6655 ASSERT(!context->getExtensions().textureRectangle);
6656 context->validationError(GL_INVALID_ENUM, kTextureRectangleNotSupported);
6657 break;
6658
6659 case TextureType::_3D:
6660 case TextureType::_2DArray:
6661 ASSERT(context->getClientMajorVersion() < 3);
6662 context->validationError(GL_INVALID_ENUM, kES3Required);
6663 break;
6664
6665 case TextureType::_2DMultisample:
6666 ASSERT(context->getClientVersion() < Version(3, 1) &&
6667 !context->getExtensions().textureMultisample);
6668 context->validationError(GL_INVALID_ENUM, kMultisampleTextureExtensionOrES31Required);
6669 break;
6670
6671 case TextureType::_2DMultisampleArray:
6672 ASSERT(!context->getExtensions().textureStorageMultisample2DArray);
6673 context->validationError(GL_INVALID_ENUM, kMultisampleArrayExtensionRequired);
6674 break;
6675
6676 case TextureType::External:
6677 ASSERT(!context->getExtensions().eglImageExternal &&
6678 !context->getExtensions().eglStreamConsumerExternal);
6679 context->validationError(GL_INVALID_ENUM, kExternalTextureNotSupported);
6680 break;
6681
6682 default:
6683 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
6684 }
6685}
6686
Jamie Madillc29968b2016-01-20 11:17:23 -05006687} // namespace gl