blob: 61c26238332df22ba93b64262a6e187e111d9eca [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
Michael Spang7a8c3e52019-04-03 14:49:57 -04003036bool ValidateBufferStorageMemEXT(Context *context,
3037 TextureType target,
3038 GLsizeiptr size,
3039 GLuint memory,
3040 GLuint64 offset)
3041{
3042 if (!context->getExtensions().memoryObject)
3043 {
3044 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3045 return false;
3046 }
3047
3048 UNIMPLEMENTED();
3049 return false;
3050}
3051
3052bool ValidateCreateMemoryObjectsEXT(Context *context, GLsizei n, GLuint *memoryObjects)
3053{
3054 if (!context->getExtensions().memoryObject)
3055 {
3056 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3057 return false;
3058 }
3059
3060 UNIMPLEMENTED();
3061 return false;
3062}
3063
3064bool ValidateDeleteMemoryObjectsEXT(Context *context, GLsizei n, const GLuint *memoryObjects)
3065{
3066 if (!context->getExtensions().memoryObject)
3067 {
3068 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3069 return false;
3070 }
3071
3072 UNIMPLEMENTED();
3073 return false;
3074}
3075
3076bool ValidateGetMemoryObjectParameterivEXT(Context *context,
3077 GLuint memoryObject,
3078 GLenum pname,
3079 GLint *params)
3080{
3081 if (!context->getExtensions().memoryObject)
3082 {
3083 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3084 return false;
3085 }
3086
3087 UNIMPLEMENTED();
3088 return false;
3089}
3090
3091bool ValidateGetUnsignedBytevEXT(Context *context, GLenum pname, GLubyte *data)
3092{
3093 if (!context->getExtensions().memoryObject && !context->getExtensions().semaphore)
3094 {
3095 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3096 return false;
3097 }
3098
3099 UNIMPLEMENTED();
3100 return false;
3101}
3102
3103bool ValidateGetUnsignedBytei_vEXT(Context *context, GLenum target, GLuint index, GLubyte *data)
3104{
3105 if (!context->getExtensions().memoryObject && !context->getExtensions().semaphore)
3106 {
3107 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3108 return false;
3109 }
3110
3111 UNIMPLEMENTED();
3112 return false;
3113}
3114
3115bool ValidateIsMemoryObjectEXT(Context *context, GLuint memoryObject)
3116{
3117 if (!context->getExtensions().memoryObject)
3118 {
3119 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3120 return false;
3121 }
3122
3123 UNIMPLEMENTED();
3124 return false;
3125}
3126
3127bool ValidateMemoryObjectParameterivEXT(Context *context,
3128 GLuint memoryObject,
3129 GLenum pname,
3130 const GLint *params)
3131{
3132 if (!context->getExtensions().memoryObject)
3133 {
3134 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3135 return false;
3136 }
3137
3138 UNIMPLEMENTED();
3139 return false;
3140}
3141
3142bool ValidateTexStorageMem2DEXT(Context *context,
3143 TextureType target,
3144 GLsizei levels,
3145 GLenum internalFormat,
3146 GLsizei width,
3147 GLsizei height,
3148 GLuint memory,
3149 GLuint64 offset)
3150{
3151 if (!context->getExtensions().memoryObject)
3152 {
3153 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3154 return false;
3155 }
3156
3157 UNIMPLEMENTED();
3158 return false;
3159}
3160
3161bool ValidateTexStorageMem3DEXT(Context *context,
3162 TextureType target,
3163 GLsizei levels,
3164 GLenum internalFormat,
3165 GLsizei width,
3166 GLsizei height,
3167 GLsizei depth,
3168 GLuint memory,
3169 GLuint64 offset)
3170{
3171 if (!context->getExtensions().memoryObject)
3172 {
3173 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3174 return false;
3175 }
3176
3177 UNIMPLEMENTED();
3178 return false;
3179}
3180
3181bool ValidateDeleteSemaphoresEXT(Context *context, GLsizei n, const GLuint *semaphores)
3182{
3183 if (!context->getExtensions().semaphore)
3184 {
3185 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3186 return false;
3187 }
3188
3189 UNIMPLEMENTED();
3190 return false;
3191}
3192
3193bool ValidateGenSemaphoresEXT(Context *context, GLsizei n, GLuint *semaphores)
3194{
3195 if (!context->getExtensions().semaphore)
3196 {
3197 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3198 return false;
3199 }
3200
3201 UNIMPLEMENTED();
3202 return false;
3203}
3204
3205bool ValidateGetSemaphoreParameterui64vEXT(Context *context,
3206 GLuint semaphore,
3207 GLenum pname,
3208 GLuint64 *params)
3209{
3210 if (!context->getExtensions().semaphore)
3211 {
3212 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3213 return false;
3214 }
3215
3216 UNIMPLEMENTED();
3217 return false;
3218}
3219
3220bool ValidateIsSemaphoreEXT(Context *context, GLuint semaphore)
3221{
3222 if (!context->getExtensions().semaphore)
3223 {
3224 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3225 return false;
3226 }
3227
3228 UNIMPLEMENTED();
3229 return false;
3230}
3231
3232bool ValidateSemaphoreParameterui64vEXT(Context *context,
3233 GLuint semaphore,
3234 GLenum pname,
3235 const GLuint64 *params)
3236{
3237 if (!context->getExtensions().semaphore)
3238 {
3239 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3240 return false;
3241 }
3242
3243 UNIMPLEMENTED();
3244 return false;
3245}
3246
3247bool ValidateSignalSemaphoreEXT(Context *context,
3248 GLuint semaphore,
3249 GLuint numBufferBarriers,
3250 const GLuint *buffers,
3251 GLuint numTextureBarriers,
3252 const GLuint *textures,
3253 const GLenum *dstLayouts)
3254{
3255 if (!context->getExtensions().semaphore)
3256 {
3257 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3258 return false;
3259 }
3260
3261 UNIMPLEMENTED();
3262 return false;
3263}
3264
3265bool ValidateWaitSemaphoreEXT(Context *context,
3266 GLuint semaphore,
3267 GLuint numBufferBarriers,
3268 const GLuint *buffers,
3269 GLuint numTextureBarriers,
3270 const GLuint *textures,
3271 const GLenum *srcLayouts)
3272{
3273 if (!context->getExtensions().semaphore)
3274 {
3275 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3276 return false;
3277 }
3278
3279 UNIMPLEMENTED();
3280 return false;
3281}
3282
Corentin Wallez336129f2017-10-17 15:55:40 -04003283bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04003284{
Jamie Madillc3dc5d42018-12-30 12:12:04 -05003285 Buffer *buffer = context->getState().getTargetBuffer(target);
Geoff Lang79f71042017-08-14 16:43:43 -04003286 ASSERT(buffer != nullptr);
3287
3288 // Check if this buffer is currently being used as a transform feedback output buffer
Jamie Madillc3dc5d42018-12-30 12:12:04 -05003289 TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
Geoff Lang79f71042017-08-14 16:43:43 -04003290 if (transformFeedback != nullptr && transformFeedback->isActive())
3291 {
3292 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
3293 {
3294 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
3295 if (transformFeedbackBuffer.get() == buffer)
3296 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003297 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
Geoff Lang79f71042017-08-14 16:43:43 -04003298 return false;
3299 }
3300 }
3301 }
3302
James Darpiniane8a93c62018-01-04 18:02:24 -08003303 if (context->getExtensions().webglCompatibility &&
3304 buffer->isBoundForTransformFeedbackAndOtherUse())
3305 {
Jamie Madille0472f32018-11-27 16:32:45 -05003306 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08003307 return false;
3308 }
3309
Geoff Lang79f71042017-08-14 16:43:43 -04003310 return true;
3311}
3312
Olli Etuaho4f667482016-03-30 15:56:35 +03003313bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003314 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003315 GLintptr offset,
3316 GLsizeiptr length)
3317{
3318 if (!context->getExtensions().mapBufferRange)
3319 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003320 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03003321 return false;
3322 }
3323
3324 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
3325}
3326
Geoff Langd8605522016-04-13 10:19:12 -04003327bool ValidateBindUniformLocationCHROMIUM(Context *context,
3328 GLuint program,
3329 GLint location,
3330 const GLchar *name)
3331{
3332 if (!context->getExtensions().bindUniformLocation)
3333 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003334 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langd8605522016-04-13 10:19:12 -04003335 return false;
3336 }
3337
3338 Program *programObject = GetValidProgram(context, program);
3339 if (!programObject)
3340 {
3341 return false;
3342 }
3343
3344 if (location < 0)
3345 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003346 context->validationError(GL_INVALID_VALUE, kNegativeLocation);
Geoff Langd8605522016-04-13 10:19:12 -04003347 return false;
3348 }
3349
3350 const Caps &caps = context->getCaps();
3351 if (static_cast<size_t>(location) >=
3352 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3353 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003354 context->validationError(GL_INVALID_VALUE, kInvalidBindUniformLocation);
Geoff Langd8605522016-04-13 10:19:12 -04003355 return false;
3356 }
3357
Geoff Langfc32e8b2017-05-31 14:16:59 -04003358 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3359 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003360 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003361 {
Jamie Madille0472f32018-11-27 16:32:45 -05003362 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003363 return false;
3364 }
3365
Geoff Langd8605522016-04-13 10:19:12 -04003366 if (strncmp(name, "gl_", 3) == 0)
3367 {
Jamie Madille0472f32018-11-27 16:32:45 -05003368 context->validationError(GL_INVALID_VALUE, kNameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003369 return false;
3370 }
3371
3372 return true;
3373}
3374
Jamie Madille2e406c2016-06-02 13:04:10 -04003375bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003376{
3377 if (!context->getExtensions().framebufferMixedSamples)
3378 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003379 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänena797e062016-05-12 15:23:40 +03003380 return false;
3381 }
3382 switch (components)
3383 {
3384 case GL_RGB:
3385 case GL_RGBA:
3386 case GL_ALPHA:
3387 case GL_NONE:
3388 break;
3389 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003390 context->validationError(GL_INVALID_ENUM, kInvalidCoverageComponents);
Sami Väisänena797e062016-05-12 15:23:40 +03003391 return false;
3392 }
3393
3394 return true;
3395}
3396
Sami Väisänene45e53b2016-05-25 10:36:04 +03003397// CHROMIUM_path_rendering
3398
Jamie Madill007530e2017-12-28 14:27:04 -05003399bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003400{
Jamie Madill007530e2017-12-28 14:27:04 -05003401 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003402 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003403 return false;
3404 }
Jamie Madill007530e2017-12-28 14:27:04 -05003405
Sami Väisänene45e53b2016-05-25 10:36:04 +03003406 if (matrix == nullptr)
3407 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003408 context->validationError(GL_INVALID_OPERATION, kInvalidPathMatrix);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003409 return false;
3410 }
Jamie Madill007530e2017-12-28 14:27:04 -05003411
Sami Väisänene45e53b2016-05-25 10:36:04 +03003412 return true;
3413}
3414
Jamie Madill007530e2017-12-28 14:27:04 -05003415bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003416{
Jamie Madill007530e2017-12-28 14:27:04 -05003417 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003418}
3419
Jamie Madill007530e2017-12-28 14:27:04 -05003420bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003421{
3422 if (!context->getExtensions().pathRendering)
3423 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003424 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003425 return false;
3426 }
3427
3428 // range = 0 is undefined in NV_path_rendering.
3429 // we add stricter semantic check here and require a non zero positive range.
3430 if (range <= 0)
3431 {
Jamie Madille0472f32018-11-27 16:32:45 -05003432 context->validationError(GL_INVALID_VALUE, kInvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003433 return false;
3434 }
3435
3436 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3437 {
Jamie Madille0472f32018-11-27 16:32:45 -05003438 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003439 return false;
3440 }
3441
3442 return true;
3443}
3444
Jamie Madill007530e2017-12-28 14:27:04 -05003445bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003446{
3447 if (!context->getExtensions().pathRendering)
3448 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003449 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003450 return false;
3451 }
3452
3453 // range = 0 is undefined in NV_path_rendering.
3454 // we add stricter semantic check here and require a non zero positive range.
3455 if (range <= 0)
3456 {
Jamie Madille0472f32018-11-27 16:32:45 -05003457 context->validationError(GL_INVALID_VALUE, kInvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003458 return false;
3459 }
3460
3461 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3462 checkedRange += range;
3463
3464 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3465 {
Jamie Madille0472f32018-11-27 16:32:45 -05003466 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003467 return false;
3468 }
3469 return true;
3470}
3471
Jamie Madill007530e2017-12-28 14:27:04 -05003472bool ValidatePathCommandsCHROMIUM(Context *context,
3473 GLuint path,
3474 GLsizei numCommands,
3475 const GLubyte *commands,
3476 GLsizei numCoords,
3477 GLenum coordType,
3478 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003479{
3480 if (!context->getExtensions().pathRendering)
3481 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003482 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003483 return false;
3484 }
Brandon Jones59770802018-04-02 13:18:42 -07003485 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003486 {
Jamie Madille0472f32018-11-27 16:32:45 -05003487 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003488 return false;
3489 }
3490
3491 if (numCommands < 0)
3492 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003493 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCommands);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003494 return false;
3495 }
3496 else if (numCommands > 0)
3497 {
3498 if (!commands)
3499 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003500 context->validationError(GL_INVALID_VALUE, kInvalidPathCommandsArray);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003501 return false;
3502 }
3503 }
3504
3505 if (numCoords < 0)
3506 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003507 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCoords);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003508 return false;
3509 }
3510 else if (numCoords > 0)
3511 {
3512 if (!coords)
3513 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003514 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCoordsArray);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003515 return false;
3516 }
3517 }
3518
3519 std::uint32_t coordTypeSize = 0;
3520 switch (coordType)
3521 {
3522 case GL_BYTE:
3523 coordTypeSize = sizeof(GLbyte);
3524 break;
3525
3526 case GL_UNSIGNED_BYTE:
3527 coordTypeSize = sizeof(GLubyte);
3528 break;
3529
3530 case GL_SHORT:
3531 coordTypeSize = sizeof(GLshort);
3532 break;
3533
3534 case GL_UNSIGNED_SHORT:
3535 coordTypeSize = sizeof(GLushort);
3536 break;
3537
3538 case GL_FLOAT:
3539 coordTypeSize = sizeof(GLfloat);
3540 break;
3541
3542 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003543 context->validationError(GL_INVALID_ENUM, kInvalidPathCoordinateType);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003544 return false;
3545 }
3546
3547 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3548 checkedSize += (coordTypeSize * numCoords);
3549 if (!checkedSize.IsValid())
3550 {
Jamie Madille0472f32018-11-27 16:32:45 -05003551 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003552 return false;
3553 }
3554
3555 // early return skips command data validation when it doesn't exist.
3556 if (!commands)
3557 return true;
3558
3559 GLsizei expectedNumCoords = 0;
3560 for (GLsizei i = 0; i < numCommands; ++i)
3561 {
3562 switch (commands[i])
3563 {
3564 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3565 break;
3566 case GL_MOVE_TO_CHROMIUM:
3567 case GL_LINE_TO_CHROMIUM:
3568 expectedNumCoords += 2;
3569 break;
3570 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3571 expectedNumCoords += 4;
3572 break;
3573 case GL_CUBIC_CURVE_TO_CHROMIUM:
3574 expectedNumCoords += 6;
3575 break;
3576 case GL_CONIC_CURVE_TO_CHROMIUM:
3577 expectedNumCoords += 5;
3578 break;
3579 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003580 context->validationError(GL_INVALID_ENUM, kInvalidPathCommand);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003581 return false;
3582 }
3583 }
Jamie Madillc3e37312018-11-30 15:25:39 -05003584
Sami Väisänene45e53b2016-05-25 10:36:04 +03003585 if (expectedNumCoords != numCoords)
3586 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003587 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCoords);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003588 return false;
3589 }
3590
3591 return true;
3592}
3593
Jamie Madill007530e2017-12-28 14:27:04 -05003594bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003595{
3596 if (!context->getExtensions().pathRendering)
3597 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003598 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003599 return false;
3600 }
Brandon Jones59770802018-04-02 13:18:42 -07003601 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003602 {
Jamie Madille0472f32018-11-27 16:32:45 -05003603 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003604 return false;
3605 }
3606
3607 switch (pname)
3608 {
3609 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3610 if (value < 0.0f)
3611 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003612 context->validationError(GL_INVALID_VALUE, kInvalidPathStrokeWidth);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003613 return false;
3614 }
3615 break;
3616 case GL_PATH_END_CAPS_CHROMIUM:
3617 switch (static_cast<GLenum>(value))
3618 {
3619 case GL_FLAT_CHROMIUM:
3620 case GL_SQUARE_CHROMIUM:
3621 case GL_ROUND_CHROMIUM:
3622 break;
3623 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003624 context->validationError(GL_INVALID_ENUM, kInvalidPathEndCaps);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003625 return false;
3626 }
3627 break;
3628 case GL_PATH_JOIN_STYLE_CHROMIUM:
3629 switch (static_cast<GLenum>(value))
3630 {
3631 case GL_MITER_REVERT_CHROMIUM:
3632 case GL_BEVEL_CHROMIUM:
3633 case GL_ROUND_CHROMIUM:
3634 break;
3635 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003636 context->validationError(GL_INVALID_ENUM, kInvalidPathJoinStyle);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003637 return false;
3638 }
Nico Weber41b072b2018-02-09 10:01:32 -05003639 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003640 case GL_PATH_MITER_LIMIT_CHROMIUM:
3641 if (value < 0.0f)
3642 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003643 context->validationError(GL_INVALID_VALUE, kInvalidPathMiterLimit);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003644 return false;
3645 }
3646 break;
3647
3648 case GL_PATH_STROKE_BOUND_CHROMIUM:
3649 // no errors, only clamping.
3650 break;
3651
3652 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003653 context->validationError(GL_INVALID_ENUM, kInvalidPathParameter);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003654 return false;
3655 }
3656 return true;
3657}
3658
Jamie Madill007530e2017-12-28 14:27:04 -05003659bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3660{
3661 // TODO(jmadill): Use proper clamping cast.
3662 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3663}
3664
3665bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003666{
3667 if (!context->getExtensions().pathRendering)
3668 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003669 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003670 return false;
3671 }
3672
Brandon Jones59770802018-04-02 13:18:42 -07003673 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003674 {
Jamie Madille0472f32018-11-27 16:32:45 -05003675 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003676 return false;
3677 }
Jamie Madillc3e37312018-11-30 15:25:39 -05003678
Sami Väisänene45e53b2016-05-25 10:36:04 +03003679 if (!value)
3680 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003681 context->validationError(GL_INVALID_VALUE, kInvalidPathValueArray);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003682 return false;
3683 }
3684
3685 switch (pname)
3686 {
3687 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3688 case GL_PATH_END_CAPS_CHROMIUM:
3689 case GL_PATH_JOIN_STYLE_CHROMIUM:
3690 case GL_PATH_MITER_LIMIT_CHROMIUM:
3691 case GL_PATH_STROKE_BOUND_CHROMIUM:
3692 break;
3693
3694 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003695 context->validationError(GL_INVALID_ENUM, kInvalidPathParameter);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003696 return false;
3697 }
3698
3699 return true;
3700}
3701
Jamie Madill007530e2017-12-28 14:27:04 -05003702bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3703{
3704 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3705 reinterpret_cast<GLfloat *>(value));
3706}
3707
3708bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003709{
3710 if (!context->getExtensions().pathRendering)
3711 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003712 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003713 return false;
3714 }
3715
3716 switch (func)
3717 {
3718 case GL_NEVER:
3719 case GL_ALWAYS:
3720 case GL_LESS:
3721 case GL_LEQUAL:
3722 case GL_EQUAL:
3723 case GL_GEQUAL:
3724 case GL_GREATER:
3725 case GL_NOTEQUAL:
3726 break;
3727 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003728 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003729 return false;
3730 }
3731
3732 return true;
3733}
3734
3735// Note that the spec specifies that for the path drawing commands
3736// if the path object is not an existing path object the command
3737// does nothing and no error is generated.
3738// However if the path object exists but has not been specified any
3739// commands then an error is generated.
3740
Jamie Madill007530e2017-12-28 14:27:04 -05003741bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003742{
3743 if (!context->getExtensions().pathRendering)
3744 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003745 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003746 return false;
3747 }
Brandon Jones59770802018-04-02 13:18:42 -07003748 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003749 {
Jamie Madille0472f32018-11-27 16:32:45 -05003750 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003751 return false;
3752 }
3753
3754 switch (fillMode)
3755 {
3756 case GL_COUNT_UP_CHROMIUM:
3757 case GL_COUNT_DOWN_CHROMIUM:
3758 break;
3759 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003760 context->validationError(GL_INVALID_ENUM, kInvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003761 return false;
3762 }
3763
3764 if (!isPow2(mask + 1))
3765 {
Jamie Madille0472f32018-11-27 16:32:45 -05003766 context->validationError(GL_INVALID_VALUE, kInvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003767 return false;
3768 }
3769
3770 return true;
3771}
3772
Jamie Madill007530e2017-12-28 14:27:04 -05003773bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003774{
3775 if (!context->getExtensions().pathRendering)
3776 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003777 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003778 return false;
3779 }
Jamie Madillc3e37312018-11-30 15:25:39 -05003780
Brandon Jones59770802018-04-02 13:18:42 -07003781 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003782 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003783 context->validationError(GL_INVALID_OPERATION, kNoPathOrNoPathData);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003784 return false;
3785 }
3786
3787 return true;
3788}
3789
Jamie Madill007530e2017-12-28 14:27:04 -05003790bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003791{
3792 if (!context->getExtensions().pathRendering)
3793 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003794 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003795 return false;
3796 }
Brandon Jones59770802018-04-02 13:18:42 -07003797 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003798 {
Jamie Madille0472f32018-11-27 16:32:45 -05003799 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003800 return false;
3801 }
3802
3803 switch (coverMode)
3804 {
3805 case GL_CONVEX_HULL_CHROMIUM:
3806 case GL_BOUNDING_BOX_CHROMIUM:
3807 break;
3808 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003809 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003810 return false;
3811 }
3812 return true;
3813}
3814
Jamie Madill778bf092018-11-14 09:54:36 -05003815bool ValidateCoverFillPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3816{
3817 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3818}
3819
3820bool ValidateCoverStrokePathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3821{
3822 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3823}
3824
Jamie Madill007530e2017-12-28 14:27:04 -05003825bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3826 GLuint path,
3827 GLenum fillMode,
3828 GLuint mask,
3829 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003830{
Jamie Madill007530e2017-12-28 14:27:04 -05003831 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3832 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003833}
3834
Jamie Madill007530e2017-12-28 14:27:04 -05003835bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3836 GLuint path,
3837 GLint reference,
3838 GLuint mask,
3839 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003840{
Jamie Madill007530e2017-12-28 14:27:04 -05003841 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3842 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003843}
3844
Brandon Jonesd1049182018-03-28 10:02:20 -07003845bool ValidateIsPathCHROMIUM(Context *context, GLuint path)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003846{
3847 if (!context->getExtensions().pathRendering)
3848 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003849 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003850 return false;
3851 }
3852 return true;
3853}
3854
Jamie Madill007530e2017-12-28 14:27:04 -05003855bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3856 GLsizei numPaths,
3857 GLenum pathNameType,
3858 const void *paths,
3859 GLuint pathBase,
3860 GLenum coverMode,
3861 GLenum transformType,
3862 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003863{
3864 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3865 transformType, transformValues))
3866 return false;
3867
3868 switch (coverMode)
3869 {
3870 case GL_CONVEX_HULL_CHROMIUM:
3871 case GL_BOUNDING_BOX_CHROMIUM:
3872 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3873 break;
3874 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003875 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003876 return false;
3877 }
3878
3879 return true;
3880}
3881
Jamie Madill007530e2017-12-28 14:27:04 -05003882bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3883 GLsizei numPaths,
3884 GLenum pathNameType,
3885 const void *paths,
3886 GLuint pathBase,
3887 GLenum coverMode,
3888 GLenum transformType,
3889 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003890{
3891 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3892 transformType, transformValues))
3893 return false;
3894
3895 switch (coverMode)
3896 {
3897 case GL_CONVEX_HULL_CHROMIUM:
3898 case GL_BOUNDING_BOX_CHROMIUM:
3899 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3900 break;
3901 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003902 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003903 return false;
3904 }
3905
3906 return true;
3907}
3908
Jamie Madill007530e2017-12-28 14:27:04 -05003909bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3910 GLsizei numPaths,
3911 GLenum pathNameType,
3912 const void *paths,
3913 GLuint pathBase,
3914 GLenum fillMode,
3915 GLuint mask,
3916 GLenum transformType,
3917 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003918{
3919
3920 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3921 transformType, transformValues))
3922 return false;
3923
3924 switch (fillMode)
3925 {
3926 case GL_COUNT_UP_CHROMIUM:
3927 case GL_COUNT_DOWN_CHROMIUM:
3928 break;
3929 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003930 context->validationError(GL_INVALID_ENUM, kInvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003931 return false;
3932 }
3933 if (!isPow2(mask + 1))
3934 {
Jamie Madille0472f32018-11-27 16:32:45 -05003935 context->validationError(GL_INVALID_VALUE, kInvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003936 return false;
3937 }
3938 return true;
3939}
3940
Jamie Madill007530e2017-12-28 14:27:04 -05003941bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3942 GLsizei numPaths,
3943 GLenum pathNameType,
3944 const void *paths,
3945 GLuint pathBase,
3946 GLint reference,
3947 GLuint mask,
3948 GLenum transformType,
3949 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003950{
3951 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3952 transformType, transformValues))
3953 return false;
3954
3955 // no more validation here.
3956
3957 return true;
3958}
3959
Jamie Madill007530e2017-12-28 14:27:04 -05003960bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3961 GLsizei numPaths,
3962 GLenum pathNameType,
3963 const void *paths,
3964 GLuint pathBase,
3965 GLenum fillMode,
3966 GLuint mask,
3967 GLenum coverMode,
3968 GLenum transformType,
3969 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003970{
3971 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3972 transformType, transformValues))
3973 return false;
3974
3975 switch (coverMode)
3976 {
3977 case GL_CONVEX_HULL_CHROMIUM:
3978 case GL_BOUNDING_BOX_CHROMIUM:
3979 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3980 break;
3981 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003982 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003983 return false;
3984 }
3985
3986 switch (fillMode)
3987 {
3988 case GL_COUNT_UP_CHROMIUM:
3989 case GL_COUNT_DOWN_CHROMIUM:
3990 break;
3991 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003992 context->validationError(GL_INVALID_ENUM, kInvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003993 return false;
3994 }
3995 if (!isPow2(mask + 1))
3996 {
Jamie Madille0472f32018-11-27 16:32:45 -05003997 context->validationError(GL_INVALID_VALUE, kInvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003998 return false;
3999 }
4000
4001 return true;
4002}
4003
Jamie Madill007530e2017-12-28 14:27:04 -05004004bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
4005 GLsizei numPaths,
4006 GLenum pathNameType,
4007 const void *paths,
4008 GLuint pathBase,
4009 GLint reference,
4010 GLuint mask,
4011 GLenum coverMode,
4012 GLenum transformType,
4013 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03004014{
4015 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
4016 transformType, transformValues))
4017 return false;
4018
4019 switch (coverMode)
4020 {
4021 case GL_CONVEX_HULL_CHROMIUM:
4022 case GL_BOUNDING_BOX_CHROMIUM:
4023 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
4024 break;
4025 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004026 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03004027 return false;
4028 }
4029
4030 return true;
4031}
4032
Jamie Madill007530e2017-12-28 14:27:04 -05004033bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
4034 GLuint program,
4035 GLint location,
4036 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03004037{
4038 if (!context->getExtensions().pathRendering)
4039 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004040 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004041 return false;
4042 }
4043
4044 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
4045 if (location >= MaxLocation)
4046 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004047 context->validationError(GL_INVALID_VALUE, kInvalidVaryingLocation);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004048 return false;
4049 }
4050
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004051 const auto *programObject = context->getProgramNoResolveLink(program);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004052 if (!programObject)
4053 {
Jamie Madille0472f32018-11-27 16:32:45 -05004054 context->validationError(GL_INVALID_OPERATION, kProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004055 return false;
4056 }
4057
4058 if (!name)
4059 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004060 context->validationError(GL_INVALID_VALUE, kMissingName);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004061 return false;
4062 }
4063
4064 if (angle::BeginsWith(name, "gl_"))
4065 {
Jamie Madille0472f32018-11-27 16:32:45 -05004066 context->validationError(GL_INVALID_OPERATION, kNameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004067 return false;
4068 }
4069
4070 return true;
4071}
4072
Jamie Madill007530e2017-12-28 14:27:04 -05004073bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
4074 GLuint program,
4075 GLint location,
4076 GLenum genMode,
4077 GLint components,
4078 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03004079{
4080 if (!context->getExtensions().pathRendering)
4081 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004082 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004083 return false;
4084 }
4085
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004086 const auto *programObject = context->getProgramResolveLink(program);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004087 if (!programObject || programObject->isFlaggedForDeletion())
4088 {
Jamie Madille0472f32018-11-27 16:32:45 -05004089 context->validationError(GL_INVALID_OPERATION, kProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004090 return false;
4091 }
4092
4093 if (!programObject->isLinked())
4094 {
Jamie Madille0472f32018-11-27 16:32:45 -05004095 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004096 return false;
4097 }
4098
4099 switch (genMode)
4100 {
4101 case GL_NONE:
4102 if (components != 0)
4103 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004104 context->validationError(GL_INVALID_VALUE, kInvalidComponents);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004105 return false;
4106 }
4107 break;
4108
4109 case GL_OBJECT_LINEAR_CHROMIUM:
4110 case GL_EYE_LINEAR_CHROMIUM:
4111 case GL_CONSTANT_CHROMIUM:
4112 if (components < 1 || components > 4)
4113 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004114 context->validationError(GL_INVALID_VALUE, kInvalidComponents);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004115 return false;
4116 }
4117 if (!coeffs)
4118 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004119 context->validationError(GL_INVALID_VALUE, kInvalidPathCoefficientsArray);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004120 return false;
4121 }
4122 break;
4123
4124 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05004125 context->validationError(GL_INVALID_ENUM, kInvalidPathGenMode);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004126 return false;
4127 }
4128
4129 // If the location is -1 then the command is silently ignored
4130 // and no further validation is needed.
4131 if (location == -1)
4132 return true;
4133
jchen103fd614d2018-08-13 12:21:58 +08004134 const auto &binding = programObject->getFragmentInputBindingInfo(location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004135
4136 if (!binding.valid)
4137 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004138 context->validationError(GL_INVALID_OPERATION, kInvalidFragmentInputBinding);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004139 return false;
4140 }
4141
4142 if (binding.type != GL_NONE)
4143 {
4144 GLint expectedComponents = 0;
4145 switch (binding.type)
4146 {
4147 case GL_FLOAT:
4148 expectedComponents = 1;
4149 break;
4150 case GL_FLOAT_VEC2:
4151 expectedComponents = 2;
4152 break;
4153 case GL_FLOAT_VEC3:
4154 expectedComponents = 3;
4155 break;
4156 case GL_FLOAT_VEC4:
4157 expectedComponents = 4;
4158 break;
4159 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05004160 context->validationError(GL_INVALID_OPERATION, kFragmentInputTypeNotFloatingPoint);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004161 return false;
4162 }
4163 if (expectedComponents != components && genMode != GL_NONE)
4164 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004165 context->validationError(GL_INVALID_OPERATION, kInvalidPathComponents);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004166 return false;
4167 }
4168 }
4169 return true;
4170}
4171
Geoff Lang97073d12016-04-20 10:42:34 -07004172bool ValidateCopyTextureCHROMIUM(Context *context,
4173 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04004174 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004175 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07004176 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04004177 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07004178 GLint internalFormat,
4179 GLenum destType,
4180 GLboolean unpackFlipY,
4181 GLboolean unpackPremultiplyAlpha,
4182 GLboolean unpackUnmultiplyAlpha)
4183{
4184 if (!context->getExtensions().copyTexture)
4185 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004186 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang97073d12016-04-20 10:42:34 -07004187 return false;
4188 }
4189
Geoff Lang4f0e0032017-05-01 16:04:35 -04004190 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004191 if (source == nullptr)
4192 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004193 context->validationError(GL_INVALID_VALUE, kInvalidSourceTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07004194 return false;
4195 }
4196
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004197 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004198 {
Jamie Madille0472f32018-11-27 16:32:45 -05004199 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004200 return false;
4201 }
4202
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004203 TextureType sourceType = source->getType();
4204 ASSERT(sourceType != TextureType::CubeMap);
4205 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004206
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004207 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004208 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004209 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureLevel);
Geoff Lang97073d12016-04-20 10:42:34 -07004210 return false;
4211 }
4212
Geoff Lang4f0e0032017-05-01 16:04:35 -04004213 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
4214 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
4215 if (sourceWidth == 0 || sourceHeight == 0)
4216 {
Jamie Madille0472f32018-11-27 16:32:45 -05004217 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004218 return false;
4219 }
4220
4221 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
4222 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004223 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004224 context->validationError(GL_INVALID_OPERATION, kInvalidSourceTextureInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004225 return false;
4226 }
4227
Geoff Lang63458a32017-10-30 15:16:53 -04004228 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4229 {
Jamie Madille0472f32018-11-27 16:32:45 -05004230 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Lang63458a32017-10-30 15:16:53 -04004231 return false;
4232 }
4233
Geoff Lang4f0e0032017-05-01 16:04:35 -04004234 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004235 if (dest == nullptr)
4236 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004237 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07004238 return false;
4239 }
4240
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004241 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004242 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004243 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTextureType);
Geoff Lang97073d12016-04-20 10:42:34 -07004244 return false;
4245 }
4246
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004247 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08004248 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004249 {
Jamie Madille0472f32018-11-27 16:32:45 -05004250 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004251 return false;
4252 }
4253
Geoff Lang97073d12016-04-20 10:42:34 -07004254 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
4255 {
Geoff Lang97073d12016-04-20 10:42:34 -07004256 return false;
4257 }
4258
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004259 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04004260 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004261 context->validationError(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004262 return false;
4263 }
4264
Geoff Lang97073d12016-04-20 10:42:34 -07004265 if (dest->getImmutableFormat())
4266 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004267 context->validationError(GL_INVALID_OPERATION, kDestinationImmutable);
Geoff Lang97073d12016-04-20 10:42:34 -07004268 return false;
4269 }
4270
4271 return true;
4272}
4273
4274bool ValidateCopySubTextureCHROMIUM(Context *context,
4275 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04004276 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004277 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07004278 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04004279 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07004280 GLint xoffset,
4281 GLint yoffset,
4282 GLint x,
4283 GLint y,
4284 GLsizei width,
4285 GLsizei height,
4286 GLboolean unpackFlipY,
4287 GLboolean unpackPremultiplyAlpha,
4288 GLboolean unpackUnmultiplyAlpha)
4289{
4290 if (!context->getExtensions().copyTexture)
4291 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004292 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang97073d12016-04-20 10:42:34 -07004293 return false;
4294 }
4295
Geoff Lang4f0e0032017-05-01 16:04:35 -04004296 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004297 if (source == nullptr)
4298 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004299 context->validationError(GL_INVALID_VALUE, kInvalidSourceTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07004300 return false;
4301 }
4302
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004303 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004304 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004305 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureType);
Geoff Lang97073d12016-04-20 10:42:34 -07004306 return false;
4307 }
4308
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004309 TextureType sourceType = source->getType();
4310 ASSERT(sourceType != TextureType::CubeMap);
4311 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004312
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004313 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004314 {
Jamie Madille0472f32018-11-27 16:32:45 -05004315 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004316 return false;
4317 }
4318
4319 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4320 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004321 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004322 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureLevel);
Geoff Lang97073d12016-04-20 10:42:34 -07004323 return false;
4324 }
4325
4326 if (x < 0 || y < 0)
4327 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004328 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004329 return false;
4330 }
4331
4332 if (width < 0 || height < 0)
4333 {
Jamie Madille0472f32018-11-27 16:32:45 -05004334 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004335 return false;
4336 }
4337
Geoff Lang4f0e0032017-05-01 16:04:35 -04004338 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4339 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004340 {
Jamie Madille0472f32018-11-27 16:32:45 -05004341 context->validationError(GL_INVALID_VALUE, kSourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004342 return false;
4343 }
4344
Geoff Lang4f0e0032017-05-01 16:04:35 -04004345 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4346 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004347 {
Jamie Madille0472f32018-11-27 16:32:45 -05004348 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004349 return false;
4350 }
4351
Geoff Lang63458a32017-10-30 15:16:53 -04004352 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4353 {
Jamie Madille0472f32018-11-27 16:32:45 -05004354 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Lang63458a32017-10-30 15:16:53 -04004355 return false;
4356 }
4357
Geoff Lang4f0e0032017-05-01 16:04:35 -04004358 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004359 if (dest == nullptr)
4360 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004361 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07004362 return false;
4363 }
4364
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004365 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004366 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004367 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTextureType);
Geoff Lang97073d12016-04-20 10:42:34 -07004368 return false;
4369 }
4370
Brandon Jones28783792018-03-05 09:37:32 -08004371 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4372 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004373 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004374 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Lang97073d12016-04-20 10:42:34 -07004375 return false;
4376 }
4377
Geoff Lang4f0e0032017-05-01 16:04:35 -04004378 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4379 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004380 context->validationError(GL_INVALID_OPERATION, kDestinationLevelNotDefined);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004381 return false;
4382 }
4383
4384 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4385 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004386 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004387 context->validationError(GL_INVALID_OPERATION, kInvalidFormatCombination);
Geoff Lang97073d12016-04-20 10:42:34 -07004388 return false;
4389 }
4390
4391 if (xoffset < 0 || yoffset < 0)
4392 {
Jamie Madille0472f32018-11-27 16:32:45 -05004393 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004394 return false;
4395 }
4396
Geoff Lang4f0e0032017-05-01 16:04:35 -04004397 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4398 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004399 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004400 context->validationError(GL_INVALID_VALUE, kOffsetOverflow);
Geoff Lang97073d12016-04-20 10:42:34 -07004401 return false;
4402 }
4403
4404 return true;
4405}
4406
Geoff Lang47110bf2016-04-20 11:13:22 -07004407bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4408{
4409 if (!context->getExtensions().copyCompressedTexture)
4410 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004411 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang47110bf2016-04-20 11:13:22 -07004412 return false;
4413 }
4414
4415 const gl::Texture *source = context->getTexture(sourceId);
4416 if (source == nullptr)
4417 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004418 context->validationError(GL_INVALID_VALUE, kInvalidSourceTexture);
Geoff Lang47110bf2016-04-20 11:13:22 -07004419 return false;
4420 }
4421
Corentin Wallez99d492c2018-02-27 15:17:10 -05004422 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004423 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004424 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureType);
Geoff Lang47110bf2016-04-20 11:13:22 -07004425 return false;
4426 }
4427
Corentin Wallez99d492c2018-02-27 15:17:10 -05004428 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4429 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004430 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004431 context->validationError(GL_INVALID_VALUE, kSourceTextureLevelZeroDefined);
Geoff Lang47110bf2016-04-20 11:13:22 -07004432 return false;
4433 }
4434
Corentin Wallez99d492c2018-02-27 15:17:10 -05004435 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004436 if (!sourceFormat.info->compressed)
4437 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004438 context->validationError(GL_INVALID_OPERATION, kSourceTextureMustBeCompressed);
Geoff Lang47110bf2016-04-20 11:13:22 -07004439 return false;
4440 }
4441
4442 const gl::Texture *dest = context->getTexture(destId);
4443 if (dest == nullptr)
4444 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004445 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTexture);
Geoff Lang47110bf2016-04-20 11:13:22 -07004446 return false;
4447 }
4448
Corentin Wallez99d492c2018-02-27 15:17:10 -05004449 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004450 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004451 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTextureType);
Geoff Lang47110bf2016-04-20 11:13:22 -07004452 return false;
4453 }
4454
4455 if (dest->getImmutableFormat())
4456 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004457 context->validationError(GL_INVALID_OPERATION, kDestinationImmutable);
Geoff Lang47110bf2016-04-20 11:13:22 -07004458 return false;
4459 }
4460
4461 return true;
4462}
4463
Jiawei Shao385b3e02018-03-21 09:43:28 +08004464bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004465{
4466 switch (type)
4467 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004468 case ShaderType::Vertex:
4469 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004470 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004471
Jiawei Shao385b3e02018-03-21 09:43:28 +08004472 case ShaderType::Compute:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004473 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004474 {
Jamie Madille0472f32018-11-27 16:32:45 -05004475 context->validationError(GL_INVALID_ENUM, kES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004476 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004477 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004478 break;
4479
Jiawei Shao385b3e02018-03-21 09:43:28 +08004480 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004481 if (!context->getExtensions().geometryShader)
4482 {
Jamie Madille0472f32018-11-27 16:32:45 -05004483 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
Jiawei Shao89be29a2017-11-06 14:36:45 +08004484 return false;
4485 }
4486 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004487 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004488 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004489 return false;
4490 }
Jamie Madill29639852016-09-02 15:00:09 -04004491
4492 return true;
4493}
4494
Jamie Madill5b772312018-03-08 20:28:32 -05004495bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004496 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004497 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004498 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004499 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004500{
4501 if (size < 0)
4502 {
Jamie Madille0472f32018-11-27 16:32:45 -05004503 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004504 return false;
4505 }
4506
4507 switch (usage)
4508 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004509 case BufferUsage::StreamDraw:
4510 case BufferUsage::StaticDraw:
4511 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004512 break;
4513
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004514 case BufferUsage::StreamRead:
4515 case BufferUsage::StaticRead:
4516 case BufferUsage::DynamicRead:
4517 case BufferUsage::StreamCopy:
4518 case BufferUsage::StaticCopy:
4519 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004520 if (context->getClientMajorVersion() < 3)
4521 {
Jamie Madille0472f32018-11-27 16:32:45 -05004522 context->validationError(GL_INVALID_ENUM, kInvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004523 return false;
4524 }
4525 break;
4526
4527 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004528 context->validationError(GL_INVALID_ENUM, kInvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004529 return false;
4530 }
4531
Corentin Walleze4477002017-12-01 14:39:58 -05004532 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004533 {
Jamie Madille0472f32018-11-27 16:32:45 -05004534 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004535 return false;
4536 }
4537
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004538 Buffer *buffer = context->getState().getTargetBuffer(target);
Jamie Madill29639852016-09-02 15:00:09 -04004539
4540 if (!buffer)
4541 {
Jamie Madille0472f32018-11-27 16:32:45 -05004542 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004543 return false;
4544 }
4545
James Darpiniane8a93c62018-01-04 18:02:24 -08004546 if (context->getExtensions().webglCompatibility &&
4547 buffer->isBoundForTransformFeedbackAndOtherUse())
4548 {
Jamie Madille0472f32018-11-27 16:32:45 -05004549 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08004550 return false;
4551 }
4552
Jamie Madill29639852016-09-02 15:00:09 -04004553 return true;
4554}
4555
Jamie Madill5b772312018-03-08 20:28:32 -05004556bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004557 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004558 GLintptr offset,
4559 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004560 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004561{
Brandon Jones6cad5662017-06-14 13:25:13 -07004562 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004563 {
Jamie Madille0472f32018-11-27 16:32:45 -05004564 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Brandon Jones6cad5662017-06-14 13:25:13 -07004565 return false;
4566 }
4567
4568 if (offset < 0)
4569 {
Jamie Madille0472f32018-11-27 16:32:45 -05004570 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004571 return false;
4572 }
4573
Corentin Walleze4477002017-12-01 14:39:58 -05004574 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004575 {
Jamie Madille0472f32018-11-27 16:32:45 -05004576 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004577 return false;
4578 }
4579
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004580 Buffer *buffer = context->getState().getTargetBuffer(target);
Jamie Madill29639852016-09-02 15:00:09 -04004581
4582 if (!buffer)
4583 {
Jamie Madille0472f32018-11-27 16:32:45 -05004584 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004585 return false;
4586 }
4587
4588 if (buffer->isMapped())
4589 {
Jamie Madille0472f32018-11-27 16:32:45 -05004590 context->validationError(GL_INVALID_OPERATION, kBufferMapped);
Jamie Madill29639852016-09-02 15:00:09 -04004591 return false;
4592 }
4593
James Darpiniane8a93c62018-01-04 18:02:24 -08004594 if (context->getExtensions().webglCompatibility &&
4595 buffer->isBoundForTransformFeedbackAndOtherUse())
4596 {
Jamie Madille0472f32018-11-27 16:32:45 -05004597 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08004598 return false;
4599 }
4600
Jamie Madill29639852016-09-02 15:00:09 -04004601 // Check for possible overflow of size + offset
4602 angle::CheckedNumeric<size_t> checkedSize(size);
4603 checkedSize += offset;
4604 if (!checkedSize.IsValid())
4605 {
Jamie Madille0472f32018-11-27 16:32:45 -05004606 context->validationError(GL_INVALID_VALUE, kParamOverflow);
Jamie Madill29639852016-09-02 15:00:09 -04004607 return false;
4608 }
4609
4610 if (size + offset > buffer->getSize())
4611 {
Jamie Madille0472f32018-11-27 16:32:45 -05004612 context->validationError(GL_INVALID_VALUE, kInsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004613 return false;
4614 }
4615
Martin Radev4c4c8e72016-08-04 12:25:34 +03004616 return true;
4617}
4618
Geoff Lang111a99e2017-10-17 10:58:41 -04004619bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004620{
Geoff Langc339c4e2016-11-29 10:37:36 -05004621 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004622 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004623 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langc287ea62016-09-16 14:46:51 -04004624 return false;
4625 }
4626
Geoff Lang111a99e2017-10-17 10:58:41 -04004627 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004628 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004629 context->validationError(GL_INVALID_OPERATION, kExtensionNotRequestable);
Geoff Langc287ea62016-09-16 14:46:51 -04004630 return false;
4631 }
4632
4633 return true;
4634}
4635
Jamie Madill5b772312018-03-08 20:28:32 -05004636bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004637{
Lingfeng Yang038dd532018-03-29 17:31:52 -07004638 if (context->getClientMajorVersion() < 2)
4639 {
4640 return ValidateMultitextureUnit(context, texture);
4641 }
4642
Jamie Madillef300b12016-10-07 15:12:09 -04004643 if (texture < GL_TEXTURE0 ||
4644 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4645 {
Jamie Madille0472f32018-11-27 16:32:45 -05004646 context->validationError(GL_INVALID_ENUM, kInvalidCombinedImageUnit);
Jamie Madillef300b12016-10-07 15:12:09 -04004647 return false;
4648 }
4649
4650 return true;
4651}
4652
Jamie Madill5b772312018-03-08 20:28:32 -05004653bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004654{
4655 Program *programObject = GetValidProgram(context, program);
4656 if (!programObject)
4657 {
4658 return false;
4659 }
4660
4661 Shader *shaderObject = GetValidShader(context, shader);
4662 if (!shaderObject)
4663 {
4664 return false;
4665 }
4666
Jiawei Shao385b3e02018-03-21 09:43:28 +08004667 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04004668 {
Jamie Madille0472f32018-11-27 16:32:45 -05004669 context->validationError(GL_INVALID_OPERATION, kShaderAttachmentHasShader);
Jiawei Shao385b3e02018-03-21 09:43:28 +08004670 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04004671 }
4672
4673 return true;
4674}
4675
Jamie Madill5b772312018-03-08 20:28:32 -05004676bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004677{
4678 if (index >= MAX_VERTEX_ATTRIBS)
4679 {
Jamie Madille0472f32018-11-27 16:32:45 -05004680 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004681 return false;
4682 }
4683
4684 if (strncmp(name, "gl_", 3) == 0)
4685 {
Jamie Madille0472f32018-11-27 16:32:45 -05004686 context->validationError(GL_INVALID_OPERATION, kNameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004687 return false;
4688 }
4689
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004690 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004691 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004692 const size_t length = strlen(name);
4693
4694 if (!IsValidESSLString(name, length))
4695 {
4696 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4697 // for shader-related entry points
Jamie Madille0472f32018-11-27 16:32:45 -05004698 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004699 return false;
4700 }
4701
4702 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4703 {
4704 return false;
4705 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004706 }
4707
Jamie Madill01a80ee2016-11-07 12:06:18 -05004708 return GetValidProgram(context, program) != nullptr;
4709}
4710
Jamie Madill5b772312018-03-08 20:28:32 -05004711bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004712{
Geoff Lange8afa902017-09-27 15:00:43 -04004713 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004714 {
Jamie Madille0472f32018-11-27 16:32:45 -05004715 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004716 return false;
4717 }
4718
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004719 if (!context->getState().isBindGeneratesResourceEnabled() &&
Jamie Madill01a80ee2016-11-07 12:06:18 -05004720 !context->isFramebufferGenerated(framebuffer))
4721 {
Jamie Madille0472f32018-11-27 16:32:45 -05004722 context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004723 return false;
4724 }
4725
4726 return true;
4727}
4728
Jamie Madill5b772312018-03-08 20:28:32 -05004729bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004730{
4731 if (target != GL_RENDERBUFFER)
4732 {
Jamie Madille0472f32018-11-27 16:32:45 -05004733 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004734 return false;
4735 }
4736
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004737 if (!context->getState().isBindGeneratesResourceEnabled() &&
Jamie Madill01a80ee2016-11-07 12:06:18 -05004738 !context->isRenderbufferGenerated(renderbuffer))
4739 {
Jamie Madille0472f32018-11-27 16:32:45 -05004740 context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004741 return false;
4742 }
4743
4744 return true;
4745}
4746
Jamie Madill5b772312018-03-08 20:28:32 -05004747static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004748{
4749 switch (mode)
4750 {
4751 case GL_FUNC_ADD:
4752 case GL_FUNC_SUBTRACT:
4753 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004754 return true;
4755
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004756 case GL_MIN:
4757 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004758 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004759
4760 default:
4761 return false;
4762 }
4763}
4764
Jamie Madill5b772312018-03-08 20:28:32 -05004765bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004766{
4767 return true;
4768}
4769
Jamie Madill5b772312018-03-08 20:28:32 -05004770bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004771{
Geoff Lang50cac572017-09-26 17:37:43 -04004772 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004773 {
Jamie Madille0472f32018-11-27 16:32:45 -05004774 context->validationError(GL_INVALID_ENUM, kInvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004775 return false;
4776 }
4777
4778 return true;
4779}
4780
Jamie Madill5b772312018-03-08 20:28:32 -05004781bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004782{
Geoff Lang50cac572017-09-26 17:37:43 -04004783 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004784 {
Jamie Madille0472f32018-11-27 16:32:45 -05004785 context->validationError(GL_INVALID_ENUM, kInvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004786 return false;
4787 }
4788
Geoff Lang50cac572017-09-26 17:37:43 -04004789 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004790 {
Jamie Madille0472f32018-11-27 16:32:45 -05004791 context->validationError(GL_INVALID_ENUM, kInvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004792 return false;
4793 }
4794
4795 return true;
4796}
4797
Jamie Madill5b772312018-03-08 20:28:32 -05004798bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004799{
4800 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4801}
4802
Jamie Madill5b772312018-03-08 20:28:32 -05004803bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004804 GLenum srcRGB,
4805 GLenum dstRGB,
4806 GLenum srcAlpha,
4807 GLenum dstAlpha)
4808{
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004809 if (!ValidSrcBlendFunc(context, srcRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004810 {
Jamie Madille0472f32018-11-27 16:32:45 -05004811 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004812 return false;
4813 }
4814
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004815 if (!ValidDstBlendFunc(context, dstRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004816 {
Jamie Madille0472f32018-11-27 16:32:45 -05004817 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004818 return false;
4819 }
4820
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004821 if (!ValidSrcBlendFunc(context, srcAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004822 {
Jamie Madille0472f32018-11-27 16:32:45 -05004823 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004824 return false;
4825 }
4826
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004827 if (!ValidDstBlendFunc(context, dstAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004828 {
Jamie Madille0472f32018-11-27 16:32:45 -05004829 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004830 return false;
4831 }
4832
Frank Henigman146e8a12017-03-02 23:22:37 -05004833 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4834 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004835 {
4836 bool constantColorUsed =
4837 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4838 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4839
4840 bool constantAlphaUsed =
4841 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4842 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4843
4844 if (constantColorUsed && constantAlphaUsed)
4845 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004846 if (context->getExtensions().webglCompatibility)
4847 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004848 context->validationError(GL_INVALID_OPERATION, kInvalidConstantColor);
4849 return false;
Frank Henigman146e8a12017-03-02 23:22:37 -05004850 }
Jamie Madillc3e37312018-11-30 15:25:39 -05004851
4852 WARN() << kConstantColorAlphaLimitation;
4853 context->validationError(GL_INVALID_OPERATION, kConstantColorAlphaLimitation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004854 return false;
4855 }
4856 }
4857
4858 return true;
4859}
4860
Geoff Langc339c4e2016-11-29 10:37:36 -05004861bool ValidateGetString(Context *context, GLenum name)
4862{
4863 switch (name)
4864 {
4865 case GL_VENDOR:
4866 case GL_RENDERER:
4867 case GL_VERSION:
4868 case GL_SHADING_LANGUAGE_VERSION:
4869 case GL_EXTENSIONS:
4870 break;
4871
4872 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4873 if (!context->getExtensions().requestExtension)
4874 {
Jamie Madille0472f32018-11-27 16:32:45 -05004875 context->validationError(GL_INVALID_ENUM, kInvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004876 return false;
4877 }
4878 break;
4879
4880 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004881 context->validationError(GL_INVALID_ENUM, kInvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004882 return false;
4883 }
4884
4885 return true;
4886}
4887
Jamie Madill5b772312018-03-08 20:28:32 -05004888bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004889{
4890 if (width <= 0.0f || isNaN(width))
4891 {
Jamie Madille0472f32018-11-27 16:32:45 -05004892 context->validationError(GL_INVALID_VALUE, kInvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004893 return false;
4894 }
4895
4896 return true;
4897}
4898
Jamie Madill5b772312018-03-08 20:28:32 -05004899bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004900{
4901 if (context->getExtensions().webglCompatibility && zNear > zFar)
4902 {
Jamie Madille0472f32018-11-27 16:32:45 -05004903 context->validationError(GL_INVALID_OPERATION, kInvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004904 return false;
4905 }
4906
4907 return true;
4908}
4909
Jamie Madill5b772312018-03-08 20:28:32 -05004910bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004911 GLenum target,
4912 GLenum internalformat,
4913 GLsizei width,
4914 GLsizei height)
4915{
4916 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4917 height);
4918}
4919
Jamie Madill5b772312018-03-08 20:28:32 -05004920bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004921 GLenum target,
4922 GLsizei samples,
4923 GLenum internalformat,
4924 GLsizei width,
4925 GLsizei height)
4926{
4927 if (!context->getExtensions().framebufferMultisample)
4928 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004929 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madille8fb6402017-02-14 17:56:40 -05004930 return false;
4931 }
4932
4933 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
Jamie Madill610640f2018-11-21 17:28:41 -05004934 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_VALUE is
Jamie Madille8fb6402017-02-14 17:56:40 -05004935 // generated.
4936 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4937 {
Jamie Madille0472f32018-11-27 16:32:45 -05004938 context->validationError(GL_INVALID_VALUE, kSamplesOutOfRange);
Jamie Madille8fb6402017-02-14 17:56:40 -05004939 return false;
4940 }
4941
4942 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4943 // the specified storage. This is different than ES 3.0 in which a sample number higher
4944 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4945 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4946 if (context->getClientMajorVersion() >= 3)
4947 {
4948 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4949 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4950 {
Jamie Madille0472f32018-11-27 16:32:45 -05004951 context->validationError(GL_OUT_OF_MEMORY, kSamplesOutOfRange);
Jamie Madille8fb6402017-02-14 17:56:40 -05004952 return false;
4953 }
4954 }
4955
4956 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4957 width, height);
4958}
4959
Jamie Madill5b772312018-03-08 20:28:32 -05004960bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004961{
Geoff Lange8afa902017-09-27 15:00:43 -04004962 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004963 {
Jamie Madille0472f32018-11-27 16:32:45 -05004964 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004965 return false;
4966 }
4967
4968 return true;
4969}
4970
Jamie Madill5b772312018-03-08 20:28:32 -05004971bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004972{
4973 return true;
4974}
4975
Jamie Madill5b772312018-03-08 20:28:32 -05004976bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004977{
4978 return true;
4979}
4980
Jamie Madill5b772312018-03-08 20:28:32 -05004981bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004982{
4983 return true;
4984}
4985
Jamie Madill5b772312018-03-08 20:28:32 -05004986bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004987 GLboolean red,
4988 GLboolean green,
4989 GLboolean blue,
4990 GLboolean alpha)
4991{
4992 return true;
4993}
4994
Jamie Madill5b772312018-03-08 20:28:32 -05004995bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004996{
4997 return true;
4998}
4999
Jamie Madill5b772312018-03-08 20:28:32 -05005000bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005001{
5002 return true;
5003}
5004
Jamie Madill5b772312018-03-08 20:28:32 -05005005bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005006{
5007 switch (mode)
5008 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04005009 case CullFaceMode::Front:
5010 case CullFaceMode::Back:
5011 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04005012 break;
5013
5014 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005015 context->validationError(GL_INVALID_ENUM, kInvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005016 return false;
5017 }
5018
5019 return true;
5020}
5021
Jamie Madill5b772312018-03-08 20:28:32 -05005022bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005023{
5024 if (program == 0)
5025 {
5026 return false;
5027 }
5028
Jamie Madill44a6fbf2018-10-02 13:38:56 -04005029 if (!context->getProgramResolveLink(program))
Jamie Madillc1d770e2017-04-13 17:31:24 -04005030 {
5031 if (context->getShader(program))
5032 {
Jamie Madille0472f32018-11-27 16:32:45 -05005033 context->validationError(GL_INVALID_OPERATION, kExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005034 return false;
5035 }
5036 else
5037 {
Jamie Madille0472f32018-11-27 16:32:45 -05005038 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005039 return false;
5040 }
5041 }
5042
5043 return true;
5044}
5045
Jamie Madill5b772312018-03-08 20:28:32 -05005046bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005047{
5048 if (shader == 0)
5049 {
5050 return false;
5051 }
5052
5053 if (!context->getShader(shader))
5054 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04005055 if (context->getProgramResolveLink(shader))
Jamie Madillc1d770e2017-04-13 17:31:24 -04005056 {
Jamie Madille0472f32018-11-27 16:32:45 -05005057 context->validationError(GL_INVALID_OPERATION, kInvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005058 return false;
5059 }
5060 else
5061 {
Jamie Madille0472f32018-11-27 16:32:45 -05005062 context->validationError(GL_INVALID_VALUE, kExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005063 return false;
5064 }
5065 }
5066
5067 return true;
5068}
5069
Jamie Madill5b772312018-03-08 20:28:32 -05005070bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005071{
5072 switch (func)
5073 {
5074 case GL_NEVER:
5075 case GL_ALWAYS:
5076 case GL_LESS:
5077 case GL_LEQUAL:
5078 case GL_EQUAL:
5079 case GL_GREATER:
5080 case GL_GEQUAL:
5081 case GL_NOTEQUAL:
5082 break;
5083
5084 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005085 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005086 return false;
5087 }
5088
5089 return true;
5090}
5091
Jamie Madill5b772312018-03-08 20:28:32 -05005092bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005093{
5094 return true;
5095}
5096
Jamie Madill5b772312018-03-08 20:28:32 -05005097bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005098{
5099 Program *programObject = GetValidProgram(context, program);
5100 if (!programObject)
5101 {
5102 return false;
5103 }
5104
5105 Shader *shaderObject = GetValidShader(context, shader);
5106 if (!shaderObject)
5107 {
5108 return false;
5109 }
5110
Jiawei Shao385b3e02018-03-21 09:43:28 +08005111 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005112 if (attachedShader != shaderObject)
5113 {
Jamie Madille0472f32018-11-27 16:32:45 -05005114 context->validationError(GL_INVALID_OPERATION, kShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005115 return false;
5116 }
5117
5118 return true;
5119}
5120
Jamie Madill5b772312018-03-08 20:28:32 -05005121bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005122{
5123 if (index >= MAX_VERTEX_ATTRIBS)
5124 {
Jamie Madille0472f32018-11-27 16:32:45 -05005125 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005126 return false;
5127 }
5128
5129 return true;
5130}
5131
Jamie Madill5b772312018-03-08 20:28:32 -05005132bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005133{
5134 if (index >= MAX_VERTEX_ATTRIBS)
5135 {
Jamie Madille0472f32018-11-27 16:32:45 -05005136 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005137 return false;
5138 }
5139
5140 return true;
5141}
5142
Jamie Madill5b772312018-03-08 20:28:32 -05005143bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005144{
5145 return true;
5146}
5147
Jamie Madill5b772312018-03-08 20:28:32 -05005148bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005149{
5150 return true;
5151}
5152
Jamie Madill5b772312018-03-08 20:28:32 -05005153bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005154{
5155 switch (mode)
5156 {
5157 case GL_CW:
5158 case GL_CCW:
5159 break;
5160 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005161 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005162 return false;
5163 }
5164
5165 return true;
5166}
5167
Jamie Madill5b772312018-03-08 20:28:32 -05005168bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005169 GLuint program,
5170 GLuint index,
5171 GLsizei bufsize,
5172 GLsizei *length,
5173 GLint *size,
5174 GLenum *type,
5175 GLchar *name)
5176{
5177 if (bufsize < 0)
5178 {
Jamie Madille0472f32018-11-27 16:32:45 -05005179 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005180 return false;
5181 }
5182
5183 Program *programObject = GetValidProgram(context, program);
5184
5185 if (!programObject)
5186 {
5187 return false;
5188 }
5189
5190 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5191 {
Jamie Madille0472f32018-11-27 16:32:45 -05005192 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005193 return false;
5194 }
5195
5196 return true;
5197}
5198
Jamie Madill5b772312018-03-08 20:28:32 -05005199bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005200 GLuint program,
5201 GLuint index,
5202 GLsizei bufsize,
5203 GLsizei *length,
5204 GLint *size,
5205 GLenum *type,
5206 GLchar *name)
5207{
5208 if (bufsize < 0)
5209 {
Jamie Madille0472f32018-11-27 16:32:45 -05005210 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005211 return false;
5212 }
5213
5214 Program *programObject = GetValidProgram(context, program);
5215
5216 if (!programObject)
5217 {
5218 return false;
5219 }
5220
5221 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5222 {
Jamie Madille0472f32018-11-27 16:32:45 -05005223 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005224 return false;
5225 }
5226
5227 return true;
5228}
5229
Jamie Madill5b772312018-03-08 20:28:32 -05005230bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005231 GLuint program,
5232 GLsizei maxcount,
5233 GLsizei *count,
5234 GLuint *shaders)
5235{
5236 if (maxcount < 0)
5237 {
Jamie Madille0472f32018-11-27 16:32:45 -05005238 context->validationError(GL_INVALID_VALUE, kNegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005239 return false;
5240 }
5241
5242 Program *programObject = GetValidProgram(context, program);
5243
5244 if (!programObject)
5245 {
5246 return false;
5247 }
5248
5249 return true;
5250}
5251
Jamie Madill5b772312018-03-08 20:28:32 -05005252bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005253{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005254 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5255 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005256 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005257 {
Jamie Madille0472f32018-11-27 16:32:45 -05005258 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005259 return false;
5260 }
5261
Jamie Madillc1d770e2017-04-13 17:31:24 -04005262 Program *programObject = GetValidProgram(context, program);
5263
5264 if (!programObject)
5265 {
Jamie Madille0472f32018-11-27 16:32:45 -05005266 context->validationError(GL_INVALID_OPERATION, kProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005267 return false;
5268 }
5269
5270 if (!programObject->isLinked())
5271 {
Jamie Madille0472f32018-11-27 16:32:45 -05005272 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005273 return false;
5274 }
5275
5276 return true;
5277}
5278
Jamie Madill5b772312018-03-08 20:28:32 -05005279bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005280{
5281 GLenum nativeType;
5282 unsigned int numParams = 0;
5283 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5284}
5285
Jamie Madill5b772312018-03-08 20:28:32 -05005286bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005287{
5288 return true;
5289}
5290
Jamie Madill5b772312018-03-08 20:28:32 -05005291bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005292{
5293 GLenum nativeType;
5294 unsigned int numParams = 0;
5295 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5296}
5297
Jamie Madill5b772312018-03-08 20:28:32 -05005298bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005299{
5300 GLenum nativeType;
5301 unsigned int numParams = 0;
5302 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5303}
5304
Jamie Madill5b772312018-03-08 20:28:32 -05005305bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005306 GLuint program,
5307 GLsizei bufsize,
5308 GLsizei *length,
5309 GLchar *infolog)
5310{
5311 if (bufsize < 0)
5312 {
Jamie Madille0472f32018-11-27 16:32:45 -05005313 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005314 return false;
5315 }
5316
5317 Program *programObject = GetValidProgram(context, program);
5318 if (!programObject)
5319 {
5320 return false;
5321 }
5322
5323 return true;
5324}
5325
Jamie Madill5b772312018-03-08 20:28:32 -05005326bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005327 GLuint shader,
5328 GLsizei bufsize,
5329 GLsizei *length,
5330 GLchar *infolog)
5331{
5332 if (bufsize < 0)
5333 {
Jamie Madille0472f32018-11-27 16:32:45 -05005334 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005335 return false;
5336 }
5337
5338 Shader *shaderObject = GetValidShader(context, shader);
5339 if (!shaderObject)
5340 {
5341 return false;
5342 }
5343
5344 return true;
5345}
5346
Jamie Madill5b772312018-03-08 20:28:32 -05005347bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005348 GLenum shadertype,
5349 GLenum precisiontype,
5350 GLint *range,
5351 GLint *precision)
5352{
5353 switch (shadertype)
5354 {
5355 case GL_VERTEX_SHADER:
5356 case GL_FRAGMENT_SHADER:
5357 break;
5358 case GL_COMPUTE_SHADER:
Jamie Madillc3e37312018-11-30 15:25:39 -05005359 context->validationError(GL_INVALID_OPERATION, kUnimplementedComputeShaderPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005360 return false;
5361 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005362 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005363 return false;
5364 }
5365
5366 switch (precisiontype)
5367 {
5368 case GL_LOW_FLOAT:
5369 case GL_MEDIUM_FLOAT:
5370 case GL_HIGH_FLOAT:
5371 case GL_LOW_INT:
5372 case GL_MEDIUM_INT:
5373 case GL_HIGH_INT:
5374 break;
5375
5376 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005377 context->validationError(GL_INVALID_ENUM, kInvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005378 return false;
5379 }
5380
5381 return true;
5382}
5383
Jamie Madill5b772312018-03-08 20:28:32 -05005384bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005385 GLuint shader,
5386 GLsizei bufsize,
5387 GLsizei *length,
5388 GLchar *source)
5389{
5390 if (bufsize < 0)
5391 {
Jamie Madille0472f32018-11-27 16:32:45 -05005392 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005393 return false;
5394 }
5395
5396 Shader *shaderObject = GetValidShader(context, shader);
5397 if (!shaderObject)
5398 {
5399 return false;
5400 }
5401
5402 return true;
5403}
5404
Jamie Madill5b772312018-03-08 20:28:32 -05005405bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005406{
5407 if (strstr(name, "gl_") == name)
5408 {
5409 return false;
5410 }
5411
Geoff Langfc32e8b2017-05-31 14:16:59 -04005412 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5413 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005414 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005415 {
Jamie Madille0472f32018-11-27 16:32:45 -05005416 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005417 return false;
5418 }
5419
Jamie Madillc1d770e2017-04-13 17:31:24 -04005420 Program *programObject = GetValidProgram(context, program);
5421
5422 if (!programObject)
5423 {
5424 return false;
5425 }
5426
5427 if (!programObject->isLinked())
5428 {
Jamie Madille0472f32018-11-27 16:32:45 -05005429 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005430 return false;
5431 }
5432
5433 return true;
5434}
5435
Jamie Madill5b772312018-03-08 20:28:32 -05005436bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005437{
5438 switch (mode)
5439 {
5440 case GL_FASTEST:
5441 case GL_NICEST:
5442 case GL_DONT_CARE:
5443 break;
5444
5445 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005446 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005447 return false;
5448 }
5449
5450 switch (target)
5451 {
5452 case GL_GENERATE_MIPMAP_HINT:
5453 break;
5454
Geoff Lange7bd2182017-06-16 16:13:13 -04005455 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5456 if (context->getClientVersion() < ES_3_0 &&
5457 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005458 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005459 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005460 return false;
5461 }
5462 break;
5463
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07005464 case GL_PERSPECTIVE_CORRECTION_HINT:
5465 case GL_POINT_SMOOTH_HINT:
5466 case GL_LINE_SMOOTH_HINT:
5467 case GL_FOG_HINT:
5468 if (context->getClientMajorVersion() >= 2)
5469 {
Jamie Madille0472f32018-11-27 16:32:45 -05005470 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07005471 return false;
5472 }
5473 break;
5474
Jamie Madillc1d770e2017-04-13 17:31:24 -04005475 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005476 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005477 return false;
5478 }
5479
5480 return true;
5481}
5482
Jamie Madill5b772312018-03-08 20:28:32 -05005483bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005484{
5485 return true;
5486}
5487
Jamie Madill5b772312018-03-08 20:28:32 -05005488bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005489{
5490 return true;
5491}
5492
Jamie Madill5b772312018-03-08 20:28:32 -05005493bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005494{
5495 return true;
5496}
5497
Jamie Madill5b772312018-03-08 20:28:32 -05005498bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005499{
5500 return true;
5501}
5502
Jamie Madill5b772312018-03-08 20:28:32 -05005503bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005504{
5505 return true;
5506}
5507
Jamie Madill5b772312018-03-08 20:28:32 -05005508bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005509{
5510 return true;
5511}
5512
Jamie Madill5b772312018-03-08 20:28:32 -05005513bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005514{
5515 if (context->getClientMajorVersion() < 3)
5516 {
5517 switch (pname)
5518 {
5519 case GL_UNPACK_IMAGE_HEIGHT:
5520 case GL_UNPACK_SKIP_IMAGES:
Jamie Madille0472f32018-11-27 16:32:45 -05005521 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005522 return false;
5523
5524 case GL_UNPACK_ROW_LENGTH:
5525 case GL_UNPACK_SKIP_ROWS:
5526 case GL_UNPACK_SKIP_PIXELS:
5527 if (!context->getExtensions().unpackSubimage)
5528 {
Jamie Madille0472f32018-11-27 16:32:45 -05005529 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005530 return false;
5531 }
5532 break;
5533
5534 case GL_PACK_ROW_LENGTH:
5535 case GL_PACK_SKIP_ROWS:
5536 case GL_PACK_SKIP_PIXELS:
5537 if (!context->getExtensions().packSubimage)
5538 {
Jamie Madille0472f32018-11-27 16:32:45 -05005539 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005540 return false;
5541 }
5542 break;
5543 }
5544 }
5545
5546 if (param < 0)
5547 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005548 context->validationError(GL_INVALID_VALUE, kNegativeParam);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005549 return false;
5550 }
5551
5552 switch (pname)
5553 {
5554 case GL_UNPACK_ALIGNMENT:
5555 if (param != 1 && param != 2 && param != 4 && param != 8)
5556 {
Jamie Madille0472f32018-11-27 16:32:45 -05005557 context->validationError(GL_INVALID_VALUE, kInvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005558 return false;
5559 }
5560 break;
5561
5562 case GL_PACK_ALIGNMENT:
5563 if (param != 1 && param != 2 && param != 4 && param != 8)
5564 {
Jamie Madille0472f32018-11-27 16:32:45 -05005565 context->validationError(GL_INVALID_VALUE, kInvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005566 return false;
5567 }
5568 break;
5569
5570 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005571 if (!context->getExtensions().packReverseRowOrder)
5572 {
Jamie Madille0472f32018-11-27 16:32:45 -05005573 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang000dab82017-09-27 14:27:07 -04005574 }
5575 break;
5576
Jamie Madillc1d770e2017-04-13 17:31:24 -04005577 case GL_UNPACK_ROW_LENGTH:
5578 case GL_UNPACK_IMAGE_HEIGHT:
5579 case GL_UNPACK_SKIP_IMAGES:
5580 case GL_UNPACK_SKIP_ROWS:
5581 case GL_UNPACK_SKIP_PIXELS:
5582 case GL_PACK_ROW_LENGTH:
5583 case GL_PACK_SKIP_ROWS:
5584 case GL_PACK_SKIP_PIXELS:
5585 break;
5586
5587 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005588 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005589 return false;
5590 }
5591
5592 return true;
5593}
5594
Jamie Madill5b772312018-03-08 20:28:32 -05005595bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005596{
5597 return true;
5598}
5599
Jamie Madill5b772312018-03-08 20:28:32 -05005600bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005601{
5602 return true;
5603}
5604
Jamie Madill5b772312018-03-08 20:28:32 -05005605bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005606{
5607 return true;
5608}
5609
Jamie Madill5b772312018-03-08 20:28:32 -05005610bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005611{
5612 if (width < 0 || height < 0)
5613 {
Jamie Madille0472f32018-11-27 16:32:45 -05005614 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005615 return false;
5616 }
5617
5618 return true;
5619}
5620
Jamie Madill5b772312018-03-08 20:28:32 -05005621bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005622 GLsizei n,
5623 const GLuint *shaders,
5624 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005625 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005626 GLsizei length)
5627{
5628 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5629 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5630 shaderBinaryFormats.end())
5631 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005632 context->validationError(GL_INVALID_ENUM, kInvalidShaderBinaryFormat);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005633 return false;
5634 }
5635
5636 return true;
5637}
5638
Jamie Madill5b772312018-03-08 20:28:32 -05005639bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005640 GLuint shader,
5641 GLsizei count,
5642 const GLchar *const *string,
5643 const GLint *length)
5644{
5645 if (count < 0)
5646 {
Jamie Madille0472f32018-11-27 16:32:45 -05005647 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005648 return false;
5649 }
5650
Geoff Langfc32e8b2017-05-31 14:16:59 -04005651 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5652 // shader-related entry points
5653 if (context->getExtensions().webglCompatibility)
5654 {
5655 for (GLsizei i = 0; i < count; i++)
5656 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005657 size_t len =
5658 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005659
5660 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005661 if (!IsValidESSLShaderSourceString(string[i], len,
5662 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005663 {
Jamie Madille0472f32018-11-27 16:32:45 -05005664 context->validationError(GL_INVALID_VALUE, kShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005665 return false;
5666 }
5667 }
5668 }
5669
Jamie Madillc1d770e2017-04-13 17:31:24 -04005670 Shader *shaderObject = GetValidShader(context, shader);
5671 if (!shaderObject)
5672 {
5673 return false;
5674 }
5675
5676 return true;
5677}
5678
Jamie Madill5b772312018-03-08 20:28:32 -05005679bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005680{
5681 if (!IsValidStencilFunc(func))
5682 {
Jamie Madille0472f32018-11-27 16:32:45 -05005683 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005684 return false;
5685 }
5686
5687 return true;
5688}
5689
Jamie Madill5b772312018-03-08 20:28:32 -05005690bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005691{
5692 if (!IsValidStencilFace(face))
5693 {
Jamie Madille0472f32018-11-27 16:32:45 -05005694 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005695 return false;
5696 }
5697
5698 if (!IsValidStencilFunc(func))
5699 {
Jamie Madille0472f32018-11-27 16:32:45 -05005700 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005701 return false;
5702 }
5703
5704 return true;
5705}
5706
Jamie Madill5b772312018-03-08 20:28:32 -05005707bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005708{
5709 return true;
5710}
5711
Jamie Madill5b772312018-03-08 20:28:32 -05005712bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005713{
5714 if (!IsValidStencilFace(face))
5715 {
Jamie Madille0472f32018-11-27 16:32:45 -05005716 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005717 return false;
5718 }
5719
5720 return true;
5721}
5722
Jamie Madill5b772312018-03-08 20:28:32 -05005723bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005724{
5725 if (!IsValidStencilOp(fail))
5726 {
Jamie Madille0472f32018-11-27 16:32:45 -05005727 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005728 return false;
5729 }
5730
5731 if (!IsValidStencilOp(zfail))
5732 {
Jamie Madille0472f32018-11-27 16:32:45 -05005733 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005734 return false;
5735 }
5736
5737 if (!IsValidStencilOp(zpass))
5738 {
Jamie Madille0472f32018-11-27 16:32:45 -05005739 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005740 return false;
5741 }
5742
5743 return true;
5744}
5745
Jamie Madill5b772312018-03-08 20:28:32 -05005746bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005747 GLenum face,
5748 GLenum fail,
5749 GLenum zfail,
5750 GLenum zpass)
5751{
5752 if (!IsValidStencilFace(face))
5753 {
Jamie Madille0472f32018-11-27 16:32:45 -05005754 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005755 return false;
5756 }
5757
5758 return ValidateStencilOp(context, fail, zfail, zpass);
5759}
5760
Jamie Madill5b772312018-03-08 20:28:32 -05005761bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005762{
5763 return ValidateUniform(context, GL_FLOAT, location, 1);
5764}
5765
Jamie Madill5b772312018-03-08 20:28:32 -05005766bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005767{
5768 return ValidateUniform(context, GL_FLOAT, location, count);
5769}
5770
Jamie Madill5b772312018-03-08 20:28:32 -05005771bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005772{
5773 return ValidateUniform1iv(context, location, 1, &x);
5774}
5775
Jamie Madill5b772312018-03-08 20:28:32 -05005776bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005777{
5778 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5779}
5780
Jamie Madill5b772312018-03-08 20:28:32 -05005781bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005782{
5783 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5784}
5785
Jamie Madill5b772312018-03-08 20:28:32 -05005786bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005787{
5788 return ValidateUniform(context, GL_INT_VEC2, location, count);
5789}
5790
Jamie Madill5b772312018-03-08 20:28:32 -05005791bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005792{
5793 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5794}
5795
Jamie Madill5b772312018-03-08 20:28:32 -05005796bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005797{
5798 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5799}
5800
Jamie Madill5b772312018-03-08 20:28:32 -05005801bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005802{
5803 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5804}
5805
Jamie Madill5b772312018-03-08 20:28:32 -05005806bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005807{
5808 return ValidateUniform(context, GL_INT_VEC3, location, count);
5809}
5810
Jamie Madill5b772312018-03-08 20:28:32 -05005811bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005812{
5813 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5814}
5815
Jamie Madill5b772312018-03-08 20:28:32 -05005816bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005817{
5818 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5819}
5820
Jamie Madill5b772312018-03-08 20:28:32 -05005821bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005822{
5823 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5824}
5825
Jamie Madill5b772312018-03-08 20:28:32 -05005826bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005827{
5828 return ValidateUniform(context, GL_INT_VEC4, location, count);
5829}
5830
Jamie Madill5b772312018-03-08 20:28:32 -05005831bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005832 GLint location,
5833 GLsizei count,
5834 GLboolean transpose,
5835 const GLfloat *value)
5836{
5837 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5838}
5839
Jamie Madill5b772312018-03-08 20:28:32 -05005840bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005841 GLint location,
5842 GLsizei count,
5843 GLboolean transpose,
5844 const GLfloat *value)
5845{
5846 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5847}
5848
Jamie Madill5b772312018-03-08 20:28:32 -05005849bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005850 GLint location,
5851 GLsizei count,
5852 GLboolean transpose,
5853 const GLfloat *value)
5854{
5855 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5856}
5857
Jamie Madill5b772312018-03-08 20:28:32 -05005858bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005859{
5860 Program *programObject = GetValidProgram(context, program);
5861
5862 if (!programObject)
5863 {
5864 return false;
5865 }
5866
5867 return true;
5868}
5869
Jamie Madill5b772312018-03-08 20:28:32 -05005870bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005871{
5872 return ValidateVertexAttribIndex(context, index);
5873}
5874
Jamie Madill5b772312018-03-08 20:28:32 -05005875bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005876{
5877 return ValidateVertexAttribIndex(context, index);
5878}
5879
Jamie Madill5b772312018-03-08 20:28:32 -05005880bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005881{
5882 return ValidateVertexAttribIndex(context, index);
5883}
5884
Jamie Madill5b772312018-03-08 20:28:32 -05005885bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005886{
5887 return ValidateVertexAttribIndex(context, index);
5888}
5889
Jamie Madill5b772312018-03-08 20:28:32 -05005890bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005891{
5892 return ValidateVertexAttribIndex(context, index);
5893}
5894
Jamie Madill5b772312018-03-08 20:28:32 -05005895bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005896{
5897 return ValidateVertexAttribIndex(context, index);
5898}
5899
Jamie Madill5b772312018-03-08 20:28:32 -05005900bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005901 GLuint index,
5902 GLfloat x,
5903 GLfloat y,
5904 GLfloat z,
5905 GLfloat w)
5906{
5907 return ValidateVertexAttribIndex(context, index);
5908}
5909
Jamie Madill5b772312018-03-08 20:28:32 -05005910bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005911{
5912 return ValidateVertexAttribIndex(context, index);
5913}
5914
Jamie Madill5b772312018-03-08 20:28:32 -05005915bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005916{
5917 if (width < 0 || height < 0)
5918 {
Jamie Madille0472f32018-11-27 16:32:45 -05005919 context->validationError(GL_INVALID_VALUE, kViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005920 return false;
5921 }
5922
5923 return true;
5924}
5925
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005926bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005927 GLenum target,
5928 GLenum attachment,
5929 GLenum pname,
5930 GLint *params)
5931{
5932 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5933 nullptr);
5934}
5935
Jamie Madill5b772312018-03-08 20:28:32 -05005936bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04005937{
5938 return ValidateGetProgramivBase(context, program, pname, nullptr);
5939}
5940
Jamie Madill5b772312018-03-08 20:28:32 -05005941bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005942 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005943 GLint level,
5944 GLenum internalformat,
5945 GLint x,
5946 GLint y,
5947 GLsizei width,
5948 GLsizei height,
5949 GLint border)
5950{
5951 if (context->getClientMajorVersion() < 3)
5952 {
5953 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5954 0, x, y, width, height, border);
5955 }
5956
5957 ASSERT(context->getClientMajorVersion() == 3);
5958 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5959 0, x, y, width, height, border);
5960}
5961
5962bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005963 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005964 GLint level,
5965 GLint xoffset,
5966 GLint yoffset,
5967 GLint x,
5968 GLint y,
5969 GLsizei width,
5970 GLsizei height)
5971{
5972 if (context->getClientMajorVersion() < 3)
5973 {
5974 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5975 yoffset, x, y, width, height, 0);
5976 }
5977
5978 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5979 yoffset, 0, x, y, width, height, 0);
5980}
5981
5982bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5983{
5984 return ValidateGenOrDelete(context, n);
5985}
5986
5987bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5988{
5989 return ValidateGenOrDelete(context, n);
5990}
5991
5992bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5993{
5994 return ValidateGenOrDelete(context, n);
5995}
5996
5997bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5998{
5999 return ValidateGenOrDelete(context, n);
6000}
6001
6002bool ValidateDisable(Context *context, GLenum cap)
6003{
6004 if (!ValidCap(context, cap, false))
6005 {
Jamie Madille0472f32018-11-27 16:32:45 -05006006 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006007 return false;
6008 }
6009
6010 return true;
6011}
6012
6013bool ValidateEnable(Context *context, GLenum cap)
6014{
6015 if (!ValidCap(context, cap, false))
6016 {
Jamie Madille0472f32018-11-27 16:32:45 -05006017 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006018 return false;
6019 }
6020
6021 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
6022 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
6023 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006024 context->validationError(GL_INVALID_OPERATION, kNoSampleAlphaToCoveragesLimitation);
Jamie Madillbe849e42017-05-02 15:49:00 -04006025
6026 // We also output an error message to the debugger window if tracing is active, so that
6027 // developers can see the error message.
Jamie Madillc3e37312018-11-30 15:25:39 -05006028 ERR() << kNoSampleAlphaToCoveragesLimitation;
Jamie Madillbe849e42017-05-02 15:49:00 -04006029 return false;
6030 }
6031
6032 return true;
6033}
6034
6035bool ValidateFramebufferRenderbuffer(Context *context,
6036 GLenum target,
6037 GLenum attachment,
6038 GLenum renderbuffertarget,
6039 GLuint renderbuffer)
6040{
Geoff Lange8afa902017-09-27 15:00:43 -04006041 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04006042 {
Jamie Madille0472f32018-11-27 16:32:45 -05006043 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Brandon Jones6cad5662017-06-14 13:25:13 -07006044 return false;
6045 }
6046
6047 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
6048 {
Jamie Madille0472f32018-11-27 16:32:45 -05006049 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006050 return false;
6051 }
6052
6053 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
6054 renderbuffertarget, renderbuffer);
6055}
6056
6057bool ValidateFramebufferTexture2D(Context *context,
6058 GLenum target,
6059 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006060 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04006061 GLuint texture,
6062 GLint level)
6063{
6064 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
6065 // extension
6066 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
6067 level != 0)
6068 {
Jamie Madille0472f32018-11-27 16:32:45 -05006069 context->validationError(GL_INVALID_VALUE, kInvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04006070 return false;
6071 }
6072
6073 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
6074 {
6075 return false;
6076 }
6077
6078 if (texture != 0)
6079 {
6080 gl::Texture *tex = context->getTexture(texture);
6081 ASSERT(tex);
6082
6083 const gl::Caps &caps = context->getCaps();
6084
6085 switch (textarget)
6086 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006087 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04006088 {
6089 if (level > gl::log2(caps.max2DTextureSize))
6090 {
Jamie Madille0472f32018-11-27 16:32:45 -05006091 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04006092 return false;
6093 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006094 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04006095 {
Jamie Madille0472f32018-11-27 16:32:45 -05006096 context->validationError(GL_INVALID_OPERATION, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006097 return false;
6098 }
6099 }
6100 break;
6101
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006102 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006103 {
6104 if (level != 0)
6105 {
Jamie Madille0472f32018-11-27 16:32:45 -05006106 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006107 return false;
6108 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006109 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006110 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006111 context->validationError(GL_INVALID_OPERATION, kTextureTargetMismatch);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006112 return false;
6113 }
6114 }
6115 break;
6116
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006117 case TextureTarget::CubeMapNegativeX:
6118 case TextureTarget::CubeMapNegativeY:
6119 case TextureTarget::CubeMapNegativeZ:
6120 case TextureTarget::CubeMapPositiveX:
6121 case TextureTarget::CubeMapPositiveY:
6122 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04006123 {
6124 if (level > gl::log2(caps.maxCubeMapTextureSize))
6125 {
Jamie Madille0472f32018-11-27 16:32:45 -05006126 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04006127 return false;
6128 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006129 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04006130 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006131 context->validationError(GL_INVALID_OPERATION, kTextureTargetMismatch);
Jamie Madillbe849e42017-05-02 15:49:00 -04006132 return false;
6133 }
6134 }
6135 break;
6136
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006137 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04006138 {
Yizhou Jiang7818a852018-09-06 15:02:04 +08006139 if (context->getClientVersion() < ES_3_1 &&
6140 !context->getExtensions().textureMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006141 {
Jamie Madill610640f2018-11-21 17:28:41 -05006142 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05006143 kMultisampleTextureExtensionOrES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006144 return false;
6145 }
6146
6147 if (level != 0)
6148 {
Jamie Madille0472f32018-11-27 16:32:45 -05006149 context->validationError(GL_INVALID_VALUE, kLevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006150 return false;
6151 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006152 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006153 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006154 context->validationError(GL_INVALID_OPERATION, kTextureTargetMismatch);
Jamie Madillbe849e42017-05-02 15:49:00 -04006155 return false;
6156 }
6157 }
6158 break;
6159
6160 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006161 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006162 return false;
6163 }
Jamie Madillbe849e42017-05-02 15:49:00 -04006164 }
6165
6166 return true;
6167}
6168
6169bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6170{
6171 return ValidateGenOrDelete(context, n);
6172}
6173
6174bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6175{
6176 return ValidateGenOrDelete(context, n);
6177}
6178
6179bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6180{
6181 return ValidateGenOrDelete(context, n);
6182}
6183
6184bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6185{
6186 return ValidateGenOrDelete(context, n);
6187}
6188
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006189bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006190{
6191 if (!ValidTextureTarget(context, target))
6192 {
Jamie Madille0472f32018-11-27 16:32:45 -05006193 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006194 return false;
6195 }
6196
6197 Texture *texture = context->getTargetTexture(target);
6198
6199 if (texture == nullptr)
6200 {
Jamie Madille0472f32018-11-27 16:32:45 -05006201 context->validationError(GL_INVALID_OPERATION, kTextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006202 return false;
6203 }
6204
6205 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6206
6207 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6208 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6209 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6210 {
Jamie Madille0472f32018-11-27 16:32:45 -05006211 context->validationError(GL_INVALID_OPERATION, kBaseLevelOutOfRange);
Jamie Madillbe849e42017-05-02 15:49:00 -04006212 return false;
6213 }
6214
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006215 TextureTarget baseTarget = (target == TextureType::CubeMap)
6216 ? TextureTarget::CubeMapPositiveX
6217 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006218 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6219 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6220 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006221 {
Jamie Madille0472f32018-11-27 16:32:45 -05006222 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Brandon Jones6cad5662017-06-14 13:25:13 -07006223 return false;
6224 }
6225
Geoff Lang536eca12017-09-13 11:23:35 -04006226 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6227 bool formatUnsized = !format.sized;
6228 bool formatColorRenderableAndFilterable =
6229 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
Yuly Novikovf15f8862018-06-04 18:59:41 -04006230 format.textureAttachmentSupport(context->getClientVersion(), context->getExtensions());
Geoff Lang536eca12017-09-13 11:23:35 -04006231 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006232 {
Jamie Madille0472f32018-11-27 16:32:45 -05006233 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006234 return false;
6235 }
6236
Geoff Lang536eca12017-09-13 11:23:35 -04006237 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6238 // generation
6239 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6240 {
Jamie Madille0472f32018-11-27 16:32:45 -05006241 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Geoff Lang536eca12017-09-13 11:23:35 -04006242 return false;
6243 }
6244
Jiange2c00842018-07-13 16:50:49 +08006245 // According to the OpenGL extension spec EXT_sRGB.txt, EXT_SRGB is based on ES 2.0 and
6246 // generateMipmap is not allowed if texture format is SRGB_EXT or SRGB_ALPHA_EXT.
6247 if (context->getClientVersion() < Version(3, 0) && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006248 {
Jamie Madille0472f32018-11-27 16:32:45 -05006249 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006250 return false;
6251 }
6252
6253 // Non-power of 2 ES2 check
6254 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6255 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6256 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6257 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006258 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6259 target == TextureType::CubeMap);
Jamie Madille0472f32018-11-27 16:32:45 -05006260 context->validationError(GL_INVALID_OPERATION, kTextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006261 return false;
6262 }
6263
6264 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006265 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006266 {
Jamie Madille0472f32018-11-27 16:32:45 -05006267 context->validationError(GL_INVALID_OPERATION, kCubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006268 return false;
6269 }
6270
James Darpinian83b2f0e2018-11-27 15:56:01 -08006271 if (context->getExtensions().webglCompatibility &&
6272 (texture->getWidth(baseTarget, effectiveBaseLevel) == 0 ||
6273 texture->getHeight(baseTarget, effectiveBaseLevel) == 0))
6274 {
6275 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapZeroSize);
6276 return false;
6277 }
6278
Jamie Madillbe849e42017-05-02 15:49:00 -04006279 return true;
6280}
6281
Jamie Madill5b772312018-03-08 20:28:32 -05006282bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006283 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006284 GLenum pname,
6285 GLint *params)
6286{
6287 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6288}
6289
6290bool ValidateGetRenderbufferParameteriv(Context *context,
6291 GLenum target,
6292 GLenum pname,
6293 GLint *params)
6294{
6295 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6296}
6297
6298bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6299{
6300 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6301}
6302
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006303bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006304{
6305 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6306}
6307
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006308bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006309{
6310 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6311}
6312
Till Rathmannb8543632018-10-02 19:46:14 +02006313bool ValidateGetTexParameterIivOES(Context *context,
6314 TextureType target,
6315 GLenum pname,
6316 GLint *params)
6317{
6318 if (context->getClientMajorVersion() < 3)
6319 {
Jamie Madille0472f32018-11-27 16:32:45 -05006320 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006321 return false;
6322 }
6323 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6324}
6325
6326bool ValidateGetTexParameterIuivOES(Context *context,
6327 TextureType target,
6328 GLenum pname,
6329 GLuint *params)
6330{
6331 if (context->getClientMajorVersion() < 3)
6332 {
Jamie Madille0472f32018-11-27 16:32:45 -05006333 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006334 return false;
6335 }
6336 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6337}
6338
Jamie Madillbe849e42017-05-02 15:49:00 -04006339bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6340{
6341 return ValidateGetUniformBase(context, program, location);
6342}
6343
6344bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6345{
6346 return ValidateGetUniformBase(context, program, location);
6347}
6348
6349bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6350{
6351 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6352}
6353
6354bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6355{
6356 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6357}
6358
6359bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6360{
6361 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6362}
6363
6364bool ValidateIsEnabled(Context *context, GLenum cap)
6365{
6366 if (!ValidCap(context, cap, true))
6367 {
Jamie Madille0472f32018-11-27 16:32:45 -05006368 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006369 return false;
6370 }
6371
6372 return true;
6373}
6374
6375bool ValidateLinkProgram(Context *context, GLuint program)
6376{
6377 if (context->hasActiveTransformFeedback(program))
6378 {
6379 // ES 3.0.4 section 2.15 page 91
Jamie Madillc3e37312018-11-30 15:25:39 -05006380 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackActiveDuringLink);
Jamie Madillbe849e42017-05-02 15:49:00 -04006381 return false;
6382 }
6383
6384 Program *programObject = GetValidProgram(context, program);
6385 if (!programObject)
6386 {
6387 return false;
6388 }
6389
6390 return true;
6391}
6392
Jamie Madill4928b7c2017-06-20 12:57:39 -04006393bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006394 GLint x,
6395 GLint y,
6396 GLsizei width,
6397 GLsizei height,
6398 GLenum format,
6399 GLenum type,
6400 void *pixels)
6401{
6402 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6403 nullptr, pixels);
6404}
6405
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006406bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006407{
Till Rathmannb8543632018-10-02 19:46:14 +02006408 return ValidateTexParameterBase(context, target, pname, -1, false, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006409}
6410
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006411bool ValidateTexParameterfv(Context *context,
6412 TextureType target,
6413 GLenum pname,
6414 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006415{
Till Rathmannb8543632018-10-02 19:46:14 +02006416 return ValidateTexParameterBase(context, target, pname, -1, true, params);
Jamie Madillbe849e42017-05-02 15:49:00 -04006417}
6418
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006419bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006420{
Till Rathmannb8543632018-10-02 19:46:14 +02006421 return ValidateTexParameterBase(context, target, pname, -1, false, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006422}
6423
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006424bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006425{
Till Rathmannb8543632018-10-02 19:46:14 +02006426 return ValidateTexParameterBase(context, target, pname, -1, true, params);
6427}
6428
6429bool ValidateTexParameterIivOES(Context *context,
6430 TextureType target,
6431 GLenum pname,
6432 const GLint *params)
6433{
6434 if (context->getClientMajorVersion() < 3)
6435 {
Jamie Madille0472f32018-11-27 16:32:45 -05006436 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006437 return false;
6438 }
6439 return ValidateTexParameterBase(context, target, pname, -1, true, params);
6440}
6441
6442bool ValidateTexParameterIuivOES(Context *context,
6443 TextureType target,
6444 GLenum pname,
6445 const GLuint *params)
6446{
6447 if (context->getClientMajorVersion() < 3)
6448 {
Jamie Madille0472f32018-11-27 16:32:45 -05006449 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006450 return false;
6451 }
6452 return ValidateTexParameterBase(context, target, pname, -1, true, params);
Jamie Madillbe849e42017-05-02 15:49:00 -04006453}
6454
6455bool ValidateUseProgram(Context *context, GLuint program)
6456{
6457 if (program != 0)
6458 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04006459 Program *programObject = context->getProgramResolveLink(program);
Jamie Madillbe849e42017-05-02 15:49:00 -04006460 if (!programObject)
6461 {
6462 // ES 3.1.0 section 7.3 page 72
6463 if (context->getShader(program))
6464 {
Jamie Madille0472f32018-11-27 16:32:45 -05006465 context->validationError(GL_INVALID_OPERATION, kExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006466 return false;
6467 }
6468 else
6469 {
Jamie Madille0472f32018-11-27 16:32:45 -05006470 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006471 return false;
6472 }
6473 }
6474 if (!programObject->isLinked())
6475 {
Jamie Madille0472f32018-11-27 16:32:45 -05006476 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006477 return false;
6478 }
6479 }
Jamie Madillc3dc5d42018-12-30 12:12:04 -05006480 if (context->getState().isTransformFeedbackActiveUnpaused())
Jamie Madillbe849e42017-05-02 15:49:00 -04006481 {
6482 // ES 3.0.4 section 2.15 page 91
Jamie Madillc3e37312018-11-30 15:25:39 -05006483 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackUseProgram);
Jamie Madillbe849e42017-05-02 15:49:00 -04006484 return false;
6485 }
6486
6487 return true;
6488}
6489
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006490bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6491{
6492 if (!context->getExtensions().fence)
6493 {
Jamie Madille0472f32018-11-27 16:32:45 -05006494 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006495 return false;
6496 }
6497
6498 if (n < 0)
6499 {
Jamie Madille0472f32018-11-27 16:32:45 -05006500 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006501 return false;
6502 }
6503
6504 return true;
6505}
6506
6507bool ValidateFinishFenceNV(Context *context, GLuint fence)
6508{
6509 if (!context->getExtensions().fence)
6510 {
Jamie Madille0472f32018-11-27 16:32:45 -05006511 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006512 return false;
6513 }
6514
6515 FenceNV *fenceObject = context->getFenceNV(fence);
6516
6517 if (fenceObject == nullptr)
6518 {
Jamie Madille0472f32018-11-27 16:32:45 -05006519 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006520 return false;
6521 }
6522
6523 if (!fenceObject->isSet())
6524 {
Jamie Madille0472f32018-11-27 16:32:45 -05006525 context->validationError(GL_INVALID_OPERATION, kInvalidFenceState);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006526 return false;
6527 }
6528
6529 return true;
6530}
6531
6532bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6533{
6534 if (!context->getExtensions().fence)
6535 {
Jamie Madille0472f32018-11-27 16:32:45 -05006536 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006537 return false;
6538 }
6539
6540 if (n < 0)
6541 {
Jamie Madille0472f32018-11-27 16:32:45 -05006542 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006543 return false;
6544 }
6545
6546 return true;
6547}
6548
6549bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6550{
6551 if (!context->getExtensions().fence)
6552 {
Jamie Madille0472f32018-11-27 16:32:45 -05006553 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006554 return false;
6555 }
6556
6557 FenceNV *fenceObject = context->getFenceNV(fence);
6558
6559 if (fenceObject == nullptr)
6560 {
Jamie Madille0472f32018-11-27 16:32:45 -05006561 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006562 return false;
6563 }
6564
6565 if (!fenceObject->isSet())
6566 {
Jamie Madille0472f32018-11-27 16:32:45 -05006567 context->validationError(GL_INVALID_OPERATION, kInvalidFenceState);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006568 return false;
6569 }
6570
6571 switch (pname)
6572 {
6573 case GL_FENCE_STATUS_NV:
6574 case GL_FENCE_CONDITION_NV:
6575 break;
6576
6577 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006578 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006579 return false;
6580 }
6581
6582 return true;
6583}
6584
6585bool ValidateGetGraphicsResetStatusEXT(Context *context)
6586{
6587 if (!context->getExtensions().robustness)
6588 {
Jamie Madille0472f32018-11-27 16:32:45 -05006589 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006590 return false;
6591 }
6592
6593 return true;
6594}
6595
6596bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6597 GLuint shader,
6598 GLsizei bufsize,
6599 GLsizei *length,
6600 GLchar *source)
6601{
6602 if (!context->getExtensions().translatedShaderSource)
6603 {
Jamie Madille0472f32018-11-27 16:32:45 -05006604 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006605 return false;
6606 }
6607
6608 if (bufsize < 0)
6609 {
Jamie Madille0472f32018-11-27 16:32:45 -05006610 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006611 return false;
6612 }
6613
6614 Shader *shaderObject = context->getShader(shader);
6615
6616 if (!shaderObject)
6617 {
Jamie Madille0472f32018-11-27 16:32:45 -05006618 context->validationError(GL_INVALID_OPERATION, kInvalidShaderName);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006619 return false;
6620 }
6621
6622 return true;
6623}
6624
6625bool ValidateIsFenceNV(Context *context, GLuint fence)
6626{
6627 if (!context->getExtensions().fence)
6628 {
Jamie Madille0472f32018-11-27 16:32:45 -05006629 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006630 return false;
6631 }
6632
6633 return true;
6634}
6635
Jamie Madill007530e2017-12-28 14:27:04 -05006636bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6637{
6638 if (!context->getExtensions().fence)
6639 {
Jamie Madille0472f32018-11-27 16:32:45 -05006640 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill007530e2017-12-28 14:27:04 -05006641 return false;
6642 }
6643
6644 if (condition != GL_ALL_COMPLETED_NV)
6645 {
Jamie Madille0472f32018-11-27 16:32:45 -05006646 context->validationError(GL_INVALID_ENUM, kInvalidFenceCondition);
Jamie Madill007530e2017-12-28 14:27:04 -05006647 return false;
6648 }
6649
6650 FenceNV *fenceObject = context->getFenceNV(fence);
6651
6652 if (fenceObject == nullptr)
6653 {
Jamie Madille0472f32018-11-27 16:32:45 -05006654 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill007530e2017-12-28 14:27:04 -05006655 return false;
6656 }
6657
6658 return true;
6659}
6660
6661bool ValidateTestFenceNV(Context *context, GLuint fence)
6662{
6663 if (!context->getExtensions().fence)
6664 {
Jamie Madille0472f32018-11-27 16:32:45 -05006665 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill007530e2017-12-28 14:27:04 -05006666 return false;
6667 }
6668
6669 FenceNV *fenceObject = context->getFenceNV(fence);
6670
6671 if (fenceObject == nullptr)
6672 {
Jamie Madille0472f32018-11-27 16:32:45 -05006673 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill007530e2017-12-28 14:27:04 -05006674 return false;
6675 }
6676
6677 if (fenceObject->isSet() != GL_TRUE)
6678 {
Jamie Madille0472f32018-11-27 16:32:45 -05006679 context->validationError(GL_INVALID_OPERATION, kInvalidFenceState);
Jamie Madill007530e2017-12-28 14:27:04 -05006680 return false;
6681 }
6682
6683 return true;
6684}
6685
6686bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006687 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006688 GLsizei levels,
6689 GLenum internalformat,
6690 GLsizei width,
6691 GLsizei height)
6692{
6693 if (!context->getExtensions().textureStorage)
6694 {
Jamie Madille0472f32018-11-27 16:32:45 -05006695 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05006696 return false;
6697 }
6698
6699 if (context->getClientMajorVersion() < 3)
6700 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006701 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006702 height);
6703 }
6704
6705 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006706 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006707 1);
6708}
6709
6710bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6711{
Jonah Ryan-Davis2b0553c2019-02-08 10:07:21 -05006712 if (!context->getExtensions().instancedArraysANGLE)
Jamie Madill007530e2017-12-28 14:27:04 -05006713 {
Jamie Madille0472f32018-11-27 16:32:45 -05006714 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05006715 return false;
6716 }
6717
6718 if (index >= MAX_VERTEX_ATTRIBS)
6719 {
Jamie Madille0472f32018-11-27 16:32:45 -05006720 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madill007530e2017-12-28 14:27:04 -05006721 return false;
6722 }
6723
6724 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6725 {
6726 if (index == 0 && divisor != 0)
6727 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006728 context->validationError(GL_INVALID_OPERATION, kAttributeZeroRequiresDivisorLimitation);
Jamie Madill007530e2017-12-28 14:27:04 -05006729
6730 // We also output an error message to the debugger window if tracing is active, so
6731 // that developers can see the error message.
Jamie Madillc3e37312018-11-30 15:25:39 -05006732 ERR() << kAttributeZeroRequiresDivisorLimitation;
Jamie Madill007530e2017-12-28 14:27:04 -05006733 return false;
6734 }
6735 }
6736
6737 return true;
6738}
6739
Jonah Ryan-Davis2b0553c2019-02-08 10:07:21 -05006740bool ValidateVertexAttribDivisorEXT(Context *context, GLuint index, GLuint divisor)
6741{
6742 if (!context->getExtensions().instancedArraysEXT)
6743 {
6744 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
6745 return false;
6746 }
6747
6748 if (index >= MAX_VERTEX_ATTRIBS)
6749 {
6750 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
6751 return false;
6752 }
6753
6754 return true;
6755}
6756
Jamie Madill007530e2017-12-28 14:27:04 -05006757bool ValidateTexImage3DOES(Context *context,
6758 GLenum target,
6759 GLint level,
6760 GLenum internalformat,
6761 GLsizei width,
6762 GLsizei height,
6763 GLsizei depth,
6764 GLint border,
6765 GLenum format,
6766 GLenum type,
6767 const void *pixels)
6768{
6769 UNIMPLEMENTED(); // FIXME
6770 return false;
6771}
6772
6773bool ValidatePopGroupMarkerEXT(Context *context)
6774{
6775 if (!context->getExtensions().debugMarker)
6776 {
6777 // The debug marker calls should not set error state
6778 // However, it seems reasonable to set an error state if the extension is not enabled
Jamie Madille0472f32018-11-27 16:32:45 -05006779 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05006780 return false;
6781 }
6782
6783 return true;
6784}
6785
Jamie Madillfa920eb2018-01-04 11:45:50 -05006786bool ValidateTexStorage1DEXT(Context *context,
6787 GLenum target,
6788 GLsizei levels,
6789 GLenum internalformat,
6790 GLsizei width)
6791{
6792 UNIMPLEMENTED();
Jamie Madille0472f32018-11-27 16:32:45 -05006793 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05006794 return false;
6795}
6796
6797bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006798 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006799 GLsizei levels,
6800 GLenum internalformat,
6801 GLsizei width,
6802 GLsizei height,
6803 GLsizei depth)
6804{
6805 if (!context->getExtensions().textureStorage)
6806 {
Jamie Madille0472f32018-11-27 16:32:45 -05006807 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05006808 return false;
6809 }
6810
6811 if (context->getClientMajorVersion() < 3)
6812 {
Jamie Madille0472f32018-11-27 16:32:45 -05006813 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05006814 return false;
6815 }
6816
6817 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6818 depth);
6819}
6820
jchen1082af6202018-06-22 10:59:52 +08006821bool ValidateMaxShaderCompilerThreadsKHR(Context *context, GLuint count)
6822{
6823 if (!context->getExtensions().parallelShaderCompile)
6824 {
Jamie Madille0472f32018-11-27 16:32:45 -05006825 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
jchen1082af6202018-06-22 10:59:52 +08006826 return false;
6827 }
6828 return true;
6829}
6830
Austin Eng1bf18ce2018-10-19 15:34:02 -07006831bool ValidateMultiDrawArraysANGLE(Context *context,
6832 PrimitiveMode mode,
6833 const GLint *firsts,
6834 const GLsizei *counts,
6835 GLsizei drawcount)
6836{
6837 if (!context->getExtensions().multiDraw)
6838 {
Jamie Madille0472f32018-11-27 16:32:45 -05006839 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07006840 return false;
6841 }
6842 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
6843 {
6844 if (!ValidateDrawArrays(context, mode, firsts[drawID], counts[drawID]))
6845 {
6846 return false;
6847 }
6848 }
6849 return true;
6850}
6851
6852bool ValidateMultiDrawElementsANGLE(Context *context,
6853 PrimitiveMode mode,
6854 const GLsizei *counts,
Jamie Madill8dc27f92018-11-29 11:45:44 -05006855 DrawElementsType type,
Austin Eng3b7c9d02018-11-21 18:09:05 -08006856 const GLvoid *const *indices,
Austin Eng1bf18ce2018-10-19 15:34:02 -07006857 GLsizei drawcount)
6858{
6859 if (!context->getExtensions().multiDraw)
6860 {
Jamie Madille0472f32018-11-27 16:32:45 -05006861 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07006862 return false;
6863 }
6864 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
6865 {
Austin Eng3b7c9d02018-11-21 18:09:05 -08006866 if (!ValidateDrawElements(context, mode, counts[drawID], type, indices[drawID]))
Austin Eng1bf18ce2018-10-19 15:34:02 -07006867 {
6868 return false;
6869 }
6870 }
6871 return true;
6872}
6873
Jeff Gilbert465d6092019-01-02 16:21:18 -08006874bool ValidateProvokingVertexANGLE(Context *context, ProvokingVertex modePacked)
6875{
6876 if (!context->getExtensions().provokingVertex)
6877 {
6878 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
6879 return false;
6880 }
6881
6882 switch (modePacked)
6883 {
6884 case ProvokingVertex::FirstVertexConvention:
6885 case ProvokingVertex::LastVertexConvention:
6886 break;
6887 default:
6888 context->validationError(GL_INVALID_ENUM, kInvalidProvokingVertex);
6889 return false;
6890 }
6891
6892 return true;
6893}
6894
Jamie Madilla5410482019-01-31 19:55:55 -05006895void RecordBindTextureTypeError(Context *context, TextureType target)
6896{
6897 ASSERT(!context->getStateCache().isValidBindTextureType(target));
6898
6899 switch (target)
6900 {
6901 case TextureType::Rectangle:
6902 ASSERT(!context->getExtensions().textureRectangle);
6903 context->validationError(GL_INVALID_ENUM, kTextureRectangleNotSupported);
6904 break;
6905
6906 case TextureType::_3D:
6907 case TextureType::_2DArray:
6908 ASSERT(context->getClientMajorVersion() < 3);
6909 context->validationError(GL_INVALID_ENUM, kES3Required);
6910 break;
6911
6912 case TextureType::_2DMultisample:
6913 ASSERT(context->getClientVersion() < Version(3, 1) &&
6914 !context->getExtensions().textureMultisample);
6915 context->validationError(GL_INVALID_ENUM, kMultisampleTextureExtensionOrES31Required);
6916 break;
6917
6918 case TextureType::_2DMultisampleArray:
6919 ASSERT(!context->getExtensions().textureStorageMultisample2DArray);
6920 context->validationError(GL_INVALID_ENUM, kMultisampleArrayExtensionRequired);
6921 break;
6922
6923 case TextureType::External:
6924 ASSERT(!context->getExtensions().eglImageExternal &&
6925 !context->getExtensions().eglStreamConsumerExternal);
6926 context->validationError(GL_INVALID_ENUM, kExternalTextureNotSupported);
6927 break;
6928
6929 default:
6930 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
6931 }
6932}
6933
Jamie Madillc29968b2016-01-20 11:17:23 -05006934} // namespace gl