blob: 81dcf688d54bc254aeaad534230b78c90b1660bd [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 Madilldfde6ab2016-06-09 07:07:18 -070059 if (context->getGLState().isScissorTestEnabled())
Jamie Madillc29968b2016-01-20 11:17:23 -050060 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -070061 const Rectangle &scissor = context->getGLState().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
493 const gl::Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
494 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}
1114
Jamie Madillac66f982018-10-09 18:30:01 -04001115void RecordBindTextureTypeError(Context *context, TextureType target)
1116{
1117 ASSERT(!context->getStateCache().isValidBindTextureType(target));
1118
1119 switch (target)
1120 {
1121 case TextureType::Rectangle:
1122 ASSERT(!context->getExtensions().textureRectangle);
Jamie Madillc3e37312018-11-30 15:25:39 -05001123 context->validationError(GL_INVALID_ENUM, kTextureRectangleNotSupported);
Jamie Madillac66f982018-10-09 18:30:01 -04001124 break;
1125
1126 case TextureType::_3D:
1127 case TextureType::_2DArray:
1128 ASSERT(context->getClientMajorVersion() < 3);
Jamie Madille0472f32018-11-27 16:32:45 -05001129 context->validationError(GL_INVALID_ENUM, kES3Required);
Jamie Madillac66f982018-10-09 18:30:01 -04001130 break;
1131
1132 case TextureType::_2DMultisample:
Yizhou Jiang7818a852018-09-06 15:02:04 +08001133 ASSERT(context->getClientVersion() < Version(3, 1) &&
1134 !context->getExtensions().textureMultisample);
Jamie Madille0472f32018-11-27 16:32:45 -05001135 context->validationError(GL_INVALID_ENUM, kMultisampleTextureExtensionOrES31Required);
Jamie Madillac66f982018-10-09 18:30:01 -04001136 break;
1137
1138 case TextureType::_2DMultisampleArray:
1139 ASSERT(!context->getExtensions().textureStorageMultisample2DArray);
Jamie Madille0472f32018-11-27 16:32:45 -05001140 context->validationError(GL_INVALID_ENUM, kMultisampleArrayExtensionRequired);
Jamie Madillac66f982018-10-09 18:30:01 -04001141 break;
1142
1143 case TextureType::External:
1144 ASSERT(!context->getExtensions().eglImageExternal &&
1145 !context->getExtensions().eglStreamConsumerExternal);
Jamie Madillc3e37312018-11-30 15:25:39 -05001146 context->validationError(GL_INVALID_ENUM, kExternalTextureNotSupported);
Jamie Madillac66f982018-10-09 18:30:01 -04001147 break;
1148
1149 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001150 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillac66f982018-10-09 18:30:01 -04001151 }
1152}
Jamie Madillc29968b2016-01-20 11:17:23 -05001153} // anonymous namespace
1154
Geoff Langff5b2d52016-09-07 11:32:23 -04001155bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001156 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001157 GLint level,
1158 GLenum internalformat,
1159 bool isCompressed,
1160 bool isSubImage,
1161 GLint xoffset,
1162 GLint yoffset,
1163 GLsizei width,
1164 GLsizei height,
1165 GLint border,
1166 GLenum format,
1167 GLenum type,
1168 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001169 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001170{
Jamie Madill6f38f822014-06-06 17:12:20 -04001171 if (!ValidTexture2DDestinationTarget(context, target))
1172 {
Jamie Madille0472f32018-11-27 16:32:45 -05001173 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001174 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001175 }
1176
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001177 TextureType texType = TextureTargetToType(target);
1178 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001179 {
Jamie Madill610640f2018-11-21 17:28:41 -05001180 // Error already handled.
Geoff Langb1196682014-07-23 13:47:29 -04001181 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001182 }
1183
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001184 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001185 {
Jamie Madille0472f32018-11-27 16:32:45 -05001186 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Brandon Jones6cad5662017-06-14 13:25:13 -07001187 return false;
1188 }
1189
1190 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001191 std::numeric_limits<GLsizei>::max() - yoffset < height)
1192 {
Jamie Madille0472f32018-11-27 16:32:45 -05001193 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001194 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001195 }
1196
Geoff Lang6e898aa2017-06-02 11:17:26 -04001197 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1198 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1199 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1200 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1201 // case.
1202 bool nonEqualFormatsAllowed =
1203 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
1204 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
1205
1206 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001207 {
Jamie Madille0472f32018-11-27 16:32:45 -05001208 context->validationError(GL_INVALID_OPERATION, kInvalidFormatCombination);
Geoff Langb1196682014-07-23 13:47:29 -04001209 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001210 }
1211
Geoff Langaae65a42014-05-26 12:43:44 -04001212 const gl::Caps &caps = context->getCaps();
1213
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001214 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001215 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001216 case TextureType::_2D:
1217 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1218 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1219 {
Jamie Madille0472f32018-11-27 16:32:45 -05001220 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001221 return false;
1222 }
1223 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001224
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001225 case TextureType::Rectangle:
1226 ASSERT(level == 0);
1227 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1228 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1229 {
Jamie Madille0472f32018-11-27 16:32:45 -05001230 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001231 return false;
1232 }
1233 if (isCompressed)
1234 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001235 context->validationError(GL_INVALID_ENUM, kRectangleTextureCompressed);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001236 return false;
1237 }
1238 break;
1239
1240 case TextureType::CubeMap:
1241 if (!isSubImage && width != height)
1242 {
Jamie Madille0472f32018-11-27 16:32:45 -05001243 context->validationError(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001244 return false;
1245 }
1246
1247 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1248 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1249 {
Jamie Madille0472f32018-11-27 16:32:45 -05001250 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001251 return false;
1252 }
1253 break;
1254
1255 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001256 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001257 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001258 }
1259
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001260 gl::Texture *texture = context->getTargetTexture(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001261 if (!texture)
1262 {
Jamie Madille0472f32018-11-27 16:32:45 -05001263 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001264 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001265 }
1266
Geoff Langa9be0dc2014-12-17 12:34:40 -05001267 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001268 {
Geoff Langca271392017-04-05 12:30:00 -04001269 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1270 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001271 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001272 context->validationError(GL_INVALID_OPERATION, kInvalidTextureLevel);
Geoff Langc51642b2016-11-14 16:18:26 -05001273 return false;
1274 }
1275
Geoff Langa9be0dc2014-12-17 12:34:40 -05001276 if (format != GL_NONE)
1277 {
Geoff Langca271392017-04-05 12:30:00 -04001278 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1279 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001280 {
Jamie Madille0472f32018-11-27 16:32:45 -05001281 context->validationError(GL_INVALID_OPERATION, kTypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001282 return false;
1283 }
1284 }
1285
1286 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1287 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1288 {
Jamie Madille0472f32018-11-27 16:32:45 -05001289 context->validationError(GL_INVALID_VALUE, kOffsetOverflow);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001290 return false;
1291 }
Geoff Langfb052642017-10-24 13:42:09 -04001292
1293 if (width > 0 && height > 0 && pixels == nullptr &&
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001294 context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
Geoff Langfb052642017-10-24 13:42:09 -04001295 {
Jamie Madille0472f32018-11-27 16:32:45 -05001296 context->validationError(GL_INVALID_VALUE, kPixelDataNull);
Geoff Langfb052642017-10-24 13:42:09 -04001297 return false;
1298 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001299 }
1300 else
1301 {
Geoff Lang69cce582015-09-17 13:20:36 -04001302 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001303 {
Jamie Madille0472f32018-11-27 16:32:45 -05001304 context->validationError(GL_INVALID_OPERATION, kTextureIsImmutable);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001305 return false;
1306 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001307 }
1308
1309 // Verify zero border
1310 if (border != 0)
1311 {
Jamie Madille0472f32018-11-27 16:32:45 -05001312 context->validationError(GL_INVALID_VALUE, kInvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001313 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001314 }
1315
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001316 if (isCompressed)
1317 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001318 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001319 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1320 : internalformat;
Geoff Lange88e4542018-05-03 15:05:57 -04001321
1322 const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(actualInternalFormat);
1323
1324 if (!internalFormatInfo.compressed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001325 {
Jamie Madille0472f32018-11-27 16:32:45 -05001326 context->validationError(GL_INVALID_ENUM, kInvalidInternalFormat);
Geoff Lange88e4542018-05-03 15:05:57 -04001327 return false;
1328 }
1329
1330 if (!internalFormatInfo.textureSupport(context->getClientVersion(),
1331 context->getExtensions()))
1332 {
Jamie Madille0472f32018-11-27 16:32:45 -05001333 context->validationError(GL_INVALID_ENUM, kInvalidInternalFormat);
Geoff Lange88e4542018-05-03 15:05:57 -04001334 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001335 }
Geoff Lang966c9402017-04-18 12:38:27 -04001336
1337 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001338 {
Geoff Lange88e4542018-05-03 15:05:57 -04001339 // From the OES_compressed_ETC1_RGB8_texture spec:
1340 // INVALID_OPERATION is generated by CompressedTexSubImage2D, TexSubImage2D, or
1341 // CopyTexSubImage2D if the texture image <level> bound to <target> has internal format
1342 // ETC1_RGB8_OES.
1343 if (actualInternalFormat == GL_ETC1_RGB8_OES)
1344 {
Jamie Madille0472f32018-11-27 16:32:45 -05001345 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lange88e4542018-05-03 15:05:57 -04001346 return false;
1347 }
1348
Geoff Lang966c9402017-04-18 12:38:27 -04001349 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1350 height, texture->getWidth(target, level),
1351 texture->getHeight(target, level)))
1352 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001353 context->validationError(GL_INVALID_OPERATION, kInvalidCompressedImageSize);
Geoff Lang966c9402017-04-18 12:38:27 -04001354 return false;
1355 }
1356
1357 if (format != actualInternalFormat)
1358 {
Jamie Madille0472f32018-11-27 16:32:45 -05001359 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001360 return false;
1361 }
1362 }
1363 else
1364 {
1365 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1366 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001367 context->validationError(GL_INVALID_OPERATION, kInvalidCompressedImageSize);
Geoff Lang966c9402017-04-18 12:38:27 -04001368 return false;
1369 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001370 }
1371 }
1372 else
1373 {
1374 // validate <type> by itself (used as secondary key below)
1375 switch (type)
1376 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001377 case GL_UNSIGNED_BYTE:
1378 case GL_UNSIGNED_SHORT_5_6_5:
1379 case GL_UNSIGNED_SHORT_4_4_4_4:
1380 case GL_UNSIGNED_SHORT_5_5_5_1:
1381 case GL_UNSIGNED_SHORT:
1382 case GL_UNSIGNED_INT:
1383 case GL_UNSIGNED_INT_24_8_OES:
1384 case GL_HALF_FLOAT_OES:
1385 case GL_FLOAT:
1386 break;
1387 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001388 context->validationError(GL_INVALID_ENUM, kInvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001389 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001390 }
1391
1392 // validate <format> + <type> combinations
1393 // - invalid <format> -> sets INVALID_ENUM
1394 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1395 switch (format)
1396 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001397 case GL_ALPHA:
1398 case GL_LUMINANCE:
1399 case GL_LUMINANCE_ALPHA:
1400 switch (type)
1401 {
1402 case GL_UNSIGNED_BYTE:
1403 case GL_FLOAT:
1404 case GL_HALF_FLOAT_OES:
1405 break;
1406 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001407 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001408 return false;
1409 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001410 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001411 case GL_RED:
1412 case GL_RG:
1413 if (!context->getExtensions().textureRG)
1414 {
Jamie Madille0472f32018-11-27 16:32:45 -05001415 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001416 return false;
1417 }
1418 switch (type)
1419 {
1420 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001421 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001422 case GL_FLOAT:
1423 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001424 if (!context->getExtensions().textureFloat)
1425 {
Jamie Madille0472f32018-11-27 16:32:45 -05001426 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001427 return false;
1428 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001429 break;
1430 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001431 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001432 return false;
1433 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001434 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001435 case GL_RGB:
1436 switch (type)
1437 {
1438 case GL_UNSIGNED_BYTE:
1439 case GL_UNSIGNED_SHORT_5_6_5:
1440 case GL_FLOAT:
1441 case GL_HALF_FLOAT_OES:
1442 break;
1443 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001444 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001445 return false;
1446 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001447 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001448 case GL_RGBA:
1449 switch (type)
1450 {
1451 case GL_UNSIGNED_BYTE:
1452 case GL_UNSIGNED_SHORT_4_4_4_4:
1453 case GL_UNSIGNED_SHORT_5_5_5_1:
1454 case GL_FLOAT:
1455 case GL_HALF_FLOAT_OES:
1456 break;
1457 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001458 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001459 return false;
1460 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001461 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001462 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001463 if (!context->getExtensions().textureFormatBGRA8888)
1464 {
Jamie Madille0472f32018-11-27 16:32:45 -05001465 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001466 return false;
1467 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001468 switch (type)
1469 {
1470 case GL_UNSIGNED_BYTE:
1471 break;
1472 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001473 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001474 return false;
1475 }
1476 break;
1477 case GL_SRGB_EXT:
1478 case GL_SRGB_ALPHA_EXT:
1479 if (!context->getExtensions().sRGB)
1480 {
Jamie Madille0472f32018-11-27 16:32:45 -05001481 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001482 return false;
1483 }
1484 switch (type)
1485 {
1486 case GL_UNSIGNED_BYTE:
1487 break;
1488 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001489 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001490 return false;
1491 }
1492 break;
1493 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1494 // handled below
1495 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1496 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1497 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1498 break;
1499 case GL_DEPTH_COMPONENT:
1500 switch (type)
1501 {
1502 case GL_UNSIGNED_SHORT:
1503 case GL_UNSIGNED_INT:
1504 break;
1505 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001506 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001507 return false;
1508 }
1509 break;
1510 case GL_DEPTH_STENCIL_OES:
1511 switch (type)
1512 {
1513 case GL_UNSIGNED_INT_24_8_OES:
1514 break;
1515 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001516 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001517 return false;
1518 }
1519 break;
1520 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001521 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001522 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001523 }
1524
1525 switch (format)
1526 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001527 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1528 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1529 if (context->getExtensions().textureCompressionDXT1)
1530 {
Jamie Madille0472f32018-11-27 16:32:45 -05001531 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001532 return false;
1533 }
1534 else
1535 {
Jamie Madille0472f32018-11-27 16:32:45 -05001536 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001537 return false;
1538 }
1539 break;
1540 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1541 if (context->getExtensions().textureCompressionDXT3)
1542 {
Jamie Madille0472f32018-11-27 16:32:45 -05001543 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001544 return false;
1545 }
1546 else
1547 {
Jamie Madille0472f32018-11-27 16:32:45 -05001548 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001549 return false;
1550 }
1551 break;
1552 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1553 if (context->getExtensions().textureCompressionDXT5)
1554 {
Jamie Madille0472f32018-11-27 16:32:45 -05001555 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001556 return false;
1557 }
1558 else
1559 {
Jamie Madille0472f32018-11-27 16:32:45 -05001560 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001561 return false;
1562 }
1563 break;
1564 case GL_ETC1_RGB8_OES:
1565 if (context->getExtensions().compressedETC1RGB8Texture)
1566 {
Jamie Madille0472f32018-11-27 16:32:45 -05001567 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001568 return false;
1569 }
1570 else
1571 {
Jamie Madille0472f32018-11-27 16:32:45 -05001572 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001573 return false;
1574 }
1575 break;
1576 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001577 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1578 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1579 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1580 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001581 if (context->getExtensions().lossyETCDecode)
1582 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001583 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001584 return false;
1585 }
1586 else
1587 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001588 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001589 return false;
1590 }
1591 break;
1592 case GL_DEPTH_COMPONENT:
1593 case GL_DEPTH_STENCIL_OES:
1594 if (!context->getExtensions().depthTextures)
1595 {
Jamie Madille0472f32018-11-27 16:32:45 -05001596 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001597 return false;
1598 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001599 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001600 {
Jamie Madille0472f32018-11-27 16:32:45 -05001601 context->validationError(GL_INVALID_OPERATION, kMismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001602 return false;
1603 }
1604 // OES_depth_texture supports loading depth data and multiple levels,
1605 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001606 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001607 {
Jamie Madille0472f32018-11-27 16:32:45 -05001608 context->validationError(GL_INVALID_OPERATION, kPixelDataNotNull);
Brandon Jonesafa75152017-07-21 13:11:29 -07001609 return false;
1610 }
1611 if (level != 0)
1612 {
Jamie Madille0472f32018-11-27 16:32:45 -05001613 context->validationError(GL_INVALID_OPERATION, kLevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001614 return false;
1615 }
1616 break;
1617 default:
1618 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001619 }
1620
Geoff Lang6e898aa2017-06-02 11:17:26 -04001621 if (!isSubImage)
1622 {
1623 switch (internalformat)
1624 {
1625 case GL_RGBA32F:
1626 if (!context->getExtensions().colorBufferFloatRGBA)
1627 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001628 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001629 return false;
1630 }
1631 if (type != GL_FLOAT)
1632 {
Jamie Madille0472f32018-11-27 16:32:45 -05001633 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001634 return false;
1635 }
1636 if (format != GL_RGBA)
1637 {
Jamie Madille0472f32018-11-27 16:32:45 -05001638 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001639 return false;
1640 }
1641 break;
1642
1643 case GL_RGB32F:
1644 if (!context->getExtensions().colorBufferFloatRGB)
1645 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001646 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001647 return false;
1648 }
1649 if (type != GL_FLOAT)
1650 {
Jamie Madille0472f32018-11-27 16:32:45 -05001651 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001652 return false;
1653 }
1654 if (format != GL_RGB)
1655 {
Jamie Madille0472f32018-11-27 16:32:45 -05001656 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001657 return false;
1658 }
1659 break;
1660
1661 default:
1662 break;
1663 }
1664 }
1665
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001666 if (type == GL_FLOAT)
1667 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001668 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001669 {
Jamie Madille0472f32018-11-27 16:32:45 -05001670 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001671 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001672 }
1673 }
1674 else if (type == GL_HALF_FLOAT_OES)
1675 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001676 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001677 {
Jamie Madille0472f32018-11-27 16:32:45 -05001678 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001679 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001680 }
1681 }
1682 }
1683
Geoff Langdbcced82017-06-06 15:55:54 -04001684 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001685 if (!ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001686 imageSize))
1687 {
1688 return false;
1689 }
1690
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001691 return true;
1692}
1693
He Yunchaoced53ae2016-11-29 15:00:51 +08001694bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001695 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001696 GLsizei levels,
1697 GLenum internalformat,
1698 GLsizei width,
1699 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001700{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001701 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1702 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001703 {
Jamie Madille0472f32018-11-27 16:32:45 -05001704 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001705 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001706 }
1707
1708 if (width < 1 || height < 1 || levels < 1)
1709 {
Jamie Madille0472f32018-11-27 16:32:45 -05001710 context->validationError(GL_INVALID_VALUE, kTextureSizeTooSmall);
Geoff Langb1196682014-07-23 13:47:29 -04001711 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001712 }
1713
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001714 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001715 {
Jamie Madille0472f32018-11-27 16:32:45 -05001716 context->validationError(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
Geoff Langb1196682014-07-23 13:47:29 -04001717 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001718 }
1719
1720 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1721 {
Jamie Madille0472f32018-11-27 16:32:45 -05001722 context->validationError(GL_INVALID_OPERATION, kInvalidMipLevels);
Geoff Langb1196682014-07-23 13:47:29 -04001723 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001724 }
1725
Geoff Langca271392017-04-05 12:30:00 -04001726 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001727 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001728 {
Jamie Madille0472f32018-11-27 16:32:45 -05001729 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001730 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001731 }
1732
Geoff Langaae65a42014-05-26 12:43:44 -04001733 const gl::Caps &caps = context->getCaps();
1734
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001735 switch (target)
1736 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001737 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001738 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1739 static_cast<GLuint>(height) > caps.max2DTextureSize)
1740 {
Jamie Madille0472f32018-11-27 16:32:45 -05001741 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
He Yunchaoced53ae2016-11-29 15:00:51 +08001742 return false;
1743 }
1744 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001745 case TextureType::Rectangle:
Jamie Madill610640f2018-11-21 17:28:41 -05001746 if (levels != 1)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001747 {
Jamie Madille0472f32018-11-27 16:32:45 -05001748 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madill610640f2018-11-21 17:28:41 -05001749 return false;
1750 }
1751
1752 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1753 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1754 {
Jamie Madille0472f32018-11-27 16:32:45 -05001755 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001756 return false;
1757 }
1758 if (formatInfo.compressed)
1759 {
Jamie Madille0472f32018-11-27 16:32:45 -05001760 context->validationError(GL_INVALID_ENUM, kRectangleTextureCompressed);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001761 return false;
1762 }
1763 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001764 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001765 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1766 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1767 {
Jamie Madille0472f32018-11-27 16:32:45 -05001768 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
He Yunchaoced53ae2016-11-29 15:00:51 +08001769 return false;
1770 }
1771 break;
1772 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001773 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001774 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001775 }
1776
Geoff Langc0b9ef42014-07-02 10:02:37 -04001777 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001778 {
1779 if (!gl::isPow2(width) || !gl::isPow2(height))
1780 {
Jamie Madille0472f32018-11-27 16:32:45 -05001781 context->validationError(GL_INVALID_OPERATION, kDimensionsMustBePow2);
Geoff Langb1196682014-07-23 13:47:29 -04001782 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001783 }
1784 }
1785
1786 switch (internalformat)
1787 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001788 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1789 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1790 if (!context->getExtensions().textureCompressionDXT1)
1791 {
Jamie Madille0472f32018-11-27 16:32:45 -05001792 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001793 return false;
1794 }
1795 break;
1796 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1797 if (!context->getExtensions().textureCompressionDXT3)
1798 {
Jamie Madille0472f32018-11-27 16:32:45 -05001799 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001800 return false;
1801 }
1802 break;
1803 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1804 if (!context->getExtensions().textureCompressionDXT5)
1805 {
Jamie Madille0472f32018-11-27 16:32:45 -05001806 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001807 return false;
1808 }
1809 break;
1810 case GL_ETC1_RGB8_OES:
1811 if (!context->getExtensions().compressedETC1RGB8Texture)
1812 {
Jamie Madille0472f32018-11-27 16:32:45 -05001813 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001814 return false;
1815 }
1816 break;
1817 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001818 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1819 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1820 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1821 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001822 if (!context->getExtensions().lossyETCDecode)
1823 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001824 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001825 return false;
1826 }
1827 break;
1828 case GL_RGBA32F_EXT:
1829 case GL_RGB32F_EXT:
1830 case GL_ALPHA32F_EXT:
1831 case GL_LUMINANCE32F_EXT:
1832 case GL_LUMINANCE_ALPHA32F_EXT:
1833 if (!context->getExtensions().textureFloat)
1834 {
Jamie Madille0472f32018-11-27 16:32:45 -05001835 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001836 return false;
1837 }
1838 break;
1839 case GL_RGBA16F_EXT:
1840 case GL_RGB16F_EXT:
1841 case GL_ALPHA16F_EXT:
1842 case GL_LUMINANCE16F_EXT:
1843 case GL_LUMINANCE_ALPHA16F_EXT:
1844 if (!context->getExtensions().textureHalfFloat)
1845 {
Jamie Madille0472f32018-11-27 16:32:45 -05001846 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001847 return false;
1848 }
1849 break;
1850 case GL_R8_EXT:
1851 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001852 if (!context->getExtensions().textureRG)
1853 {
Jamie Madille0472f32018-11-27 16:32:45 -05001854 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang677bb6f2017-04-05 12:40:40 -04001855 return false;
1856 }
1857 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001858 case GL_R16F_EXT:
1859 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001860 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1861 {
Jamie Madille0472f32018-11-27 16:32:45 -05001862 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang677bb6f2017-04-05 12:40:40 -04001863 return false;
1864 }
1865 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001866 case GL_R32F_EXT:
1867 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001868 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001869 {
Jamie Madille0472f32018-11-27 16:32:45 -05001870 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001871 return false;
1872 }
1873 break;
1874 case GL_DEPTH_COMPONENT16:
1875 case GL_DEPTH_COMPONENT32_OES:
1876 case GL_DEPTH24_STENCIL8_OES:
1877 if (!context->getExtensions().depthTextures)
1878 {
Jamie Madille0472f32018-11-27 16:32:45 -05001879 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001880 return false;
1881 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001882 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001883 {
Jamie Madille0472f32018-11-27 16:32:45 -05001884 context->validationError(GL_INVALID_OPERATION, kInvalidTextureTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001885 return false;
1886 }
1887 // ANGLE_depth_texture only supports 1-level textures
1888 if (levels != 1)
1889 {
Jamie Madille0472f32018-11-27 16:32:45 -05001890 context->validationError(GL_INVALID_OPERATION, kInvalidMipLevels);
He Yunchaoced53ae2016-11-29 15:00:51 +08001891 return false;
1892 }
1893 break;
1894 default:
1895 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001896 }
1897
Geoff Lang691e58c2014-12-19 17:03:25 -05001898 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001899 if (!texture || texture->id() == 0)
1900 {
Jamie Madille0472f32018-11-27 16:32:45 -05001901 context->validationError(GL_INVALID_OPERATION, kMissingTexture);
Geoff Langb1196682014-07-23 13:47:29 -04001902 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001903 }
1904
Geoff Lang69cce582015-09-17 13:20:36 -04001905 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001906 {
Jamie Madille0472f32018-11-27 16:32:45 -05001907 context->validationError(GL_INVALID_OPERATION, kTextureIsImmutable);
Geoff Langb1196682014-07-23 13:47:29 -04001908 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001909 }
1910
1911 return true;
1912}
1913
He Yunchaoced53ae2016-11-29 15:00:51 +08001914bool ValidateDiscardFramebufferEXT(Context *context,
1915 GLenum target,
1916 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001917 const GLenum *attachments)
1918{
Jamie Madillc29968b2016-01-20 11:17:23 -05001919 if (!context->getExtensions().discardFramebuffer)
1920 {
Jamie Madille0472f32018-11-27 16:32:45 -05001921 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001922 return false;
1923 }
1924
Austin Kinross08332632015-05-05 13:35:47 -07001925 bool defaultFramebuffer = false;
1926
1927 switch (target)
1928 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001929 case GL_FRAMEBUFFER:
1930 defaultFramebuffer =
1931 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1932 break;
1933 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001934 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001935 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001936 }
1937
He Yunchaoced53ae2016-11-29 15:00:51 +08001938 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1939 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001940}
1941
Austin Kinrossbc781f32015-10-26 09:27:38 -07001942bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1943{
1944 if (!context->getExtensions().vertexArrayObject)
1945 {
Jamie Madille0472f32018-11-27 16:32:45 -05001946 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001947 return false;
1948 }
1949
1950 return ValidateBindVertexArrayBase(context, array);
1951}
1952
Jamie Madilld7576732017-08-26 18:49:50 -04001953bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001954{
1955 if (!context->getExtensions().vertexArrayObject)
1956 {
Jamie Madille0472f32018-11-27 16:32:45 -05001957 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001958 return false;
1959 }
1960
Olli Etuaho41997e72016-03-10 13:38:39 +02001961 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001962}
1963
Jamie Madilld7576732017-08-26 18:49:50 -04001964bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001965{
1966 if (!context->getExtensions().vertexArrayObject)
1967 {
Jamie Madille0472f32018-11-27 16:32:45 -05001968 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001969 return false;
1970 }
1971
Olli Etuaho41997e72016-03-10 13:38:39 +02001972 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001973}
1974
Jamie Madilld7576732017-08-26 18:49:50 -04001975bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001976{
1977 if (!context->getExtensions().vertexArrayObject)
1978 {
Jamie Madille0472f32018-11-27 16:32:45 -05001979 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001980 return false;
1981 }
1982
1983 return true;
1984}
Geoff Langc5629752015-12-07 16:29:04 -05001985
1986bool ValidateProgramBinaryOES(Context *context,
1987 GLuint program,
1988 GLenum binaryFormat,
1989 const void *binary,
1990 GLint length)
1991{
1992 if (!context->getExtensions().getProgramBinary)
1993 {
Jamie Madille0472f32018-11-27 16:32:45 -05001994 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001995 return false;
1996 }
1997
1998 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
1999}
2000
2001bool ValidateGetProgramBinaryOES(Context *context,
2002 GLuint program,
2003 GLsizei bufSize,
2004 GLsizei *length,
2005 GLenum *binaryFormat,
2006 void *binary)
2007{
2008 if (!context->getExtensions().getProgramBinary)
2009 {
Jamie Madille0472f32018-11-27 16:32:45 -05002010 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05002011 return false;
2012 }
2013
2014 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
2015}
Geoff Lange102fee2015-12-10 11:23:30 -05002016
Geoff Lang70d0f492015-12-10 17:45:46 -05002017static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
2018{
2019 switch (source)
2020 {
2021 case GL_DEBUG_SOURCE_API:
2022 case GL_DEBUG_SOURCE_SHADER_COMPILER:
2023 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
2024 case GL_DEBUG_SOURCE_OTHER:
2025 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
2026 return !mustBeThirdPartyOrApplication;
2027
2028 case GL_DEBUG_SOURCE_THIRD_PARTY:
2029 case GL_DEBUG_SOURCE_APPLICATION:
2030 return true;
2031
2032 default:
2033 return false;
2034 }
2035}
2036
2037static bool ValidDebugType(GLenum type)
2038{
2039 switch (type)
2040 {
2041 case GL_DEBUG_TYPE_ERROR:
2042 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
2043 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
2044 case GL_DEBUG_TYPE_PERFORMANCE:
2045 case GL_DEBUG_TYPE_PORTABILITY:
2046 case GL_DEBUG_TYPE_OTHER:
2047 case GL_DEBUG_TYPE_MARKER:
2048 case GL_DEBUG_TYPE_PUSH_GROUP:
2049 case GL_DEBUG_TYPE_POP_GROUP:
2050 return true;
2051
2052 default:
2053 return false;
2054 }
2055}
2056
2057static bool ValidDebugSeverity(GLenum severity)
2058{
2059 switch (severity)
2060 {
2061 case GL_DEBUG_SEVERITY_HIGH:
2062 case GL_DEBUG_SEVERITY_MEDIUM:
2063 case GL_DEBUG_SEVERITY_LOW:
2064 case GL_DEBUG_SEVERITY_NOTIFICATION:
2065 return true;
2066
2067 default:
2068 return false;
2069 }
2070}
2071
Geoff Lange102fee2015-12-10 11:23:30 -05002072bool ValidateDebugMessageControlKHR(Context *context,
2073 GLenum source,
2074 GLenum type,
2075 GLenum severity,
2076 GLsizei count,
2077 const GLuint *ids,
2078 GLboolean enabled)
2079{
2080 if (!context->getExtensions().debug)
2081 {
Jamie Madille0472f32018-11-27 16:32:45 -05002082 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002083 return false;
2084 }
2085
Geoff Lang70d0f492015-12-10 17:45:46 -05002086 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
2087 {
Jamie Madille0472f32018-11-27 16:32:45 -05002088 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002089 return false;
2090 }
2091
2092 if (!ValidDebugType(type) && type != GL_DONT_CARE)
2093 {
Jamie Madille0472f32018-11-27 16:32:45 -05002094 context->validationError(GL_INVALID_ENUM, kInvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002095 return false;
2096 }
2097
2098 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
2099 {
Jamie Madille0472f32018-11-27 16:32:45 -05002100 context->validationError(GL_INVALID_ENUM, kInvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05002101 return false;
2102 }
2103
2104 if (count > 0)
2105 {
2106 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
2107 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002108 context->validationError(GL_INVALID_OPERATION, kInvalidDebugSourceType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002109 return false;
2110 }
2111
2112 if (severity != GL_DONT_CARE)
2113 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002114 context->validationError(GL_INVALID_OPERATION, kInvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05002115 return false;
2116 }
2117 }
2118
Geoff Lange102fee2015-12-10 11:23:30 -05002119 return true;
2120}
2121
2122bool ValidateDebugMessageInsertKHR(Context *context,
2123 GLenum source,
2124 GLenum type,
2125 GLuint id,
2126 GLenum severity,
2127 GLsizei length,
2128 const GLchar *buf)
2129{
2130 if (!context->getExtensions().debug)
2131 {
Jamie Madille0472f32018-11-27 16:32:45 -05002132 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002133 return false;
2134 }
2135
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002136 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002137 {
2138 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2139 // not generate an error.
2140 return false;
2141 }
2142
2143 if (!ValidDebugSeverity(severity))
2144 {
Jamie Madille0472f32018-11-27 16:32:45 -05002145 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002146 return false;
2147 }
2148
2149 if (!ValidDebugType(type))
2150 {
Jamie Madille0472f32018-11-27 16:32:45 -05002151 context->validationError(GL_INVALID_ENUM, kInvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002152 return false;
2153 }
2154
2155 if (!ValidDebugSource(source, true))
2156 {
Jamie Madille0472f32018-11-27 16:32:45 -05002157 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002158 return false;
2159 }
2160
2161 size_t messageLength = (length < 0) ? strlen(buf) : length;
2162 if (messageLength > context->getExtensions().maxDebugMessageLength)
2163 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002164 context->validationError(GL_INVALID_VALUE, kExceedsMaxDebugMessageLength);
Geoff Lang70d0f492015-12-10 17:45:46 -05002165 return false;
2166 }
2167
Geoff Lange102fee2015-12-10 11:23:30 -05002168 return true;
2169}
2170
2171bool ValidateDebugMessageCallbackKHR(Context *context,
2172 GLDEBUGPROCKHR callback,
2173 const void *userParam)
2174{
2175 if (!context->getExtensions().debug)
2176 {
Jamie Madille0472f32018-11-27 16:32:45 -05002177 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002178 return false;
2179 }
2180
Geoff Lange102fee2015-12-10 11:23:30 -05002181 return true;
2182}
2183
2184bool ValidateGetDebugMessageLogKHR(Context *context,
2185 GLuint count,
2186 GLsizei bufSize,
2187 GLenum *sources,
2188 GLenum *types,
2189 GLuint *ids,
2190 GLenum *severities,
2191 GLsizei *lengths,
2192 GLchar *messageLog)
2193{
2194 if (!context->getExtensions().debug)
2195 {
Jamie Madille0472f32018-11-27 16:32:45 -05002196 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002197 return false;
2198 }
2199
Geoff Lang70d0f492015-12-10 17:45:46 -05002200 if (bufSize < 0 && messageLog != nullptr)
2201 {
Jamie Madille0472f32018-11-27 16:32:45 -05002202 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002203 return false;
2204 }
2205
Geoff Lange102fee2015-12-10 11:23:30 -05002206 return true;
2207}
2208
2209bool ValidatePushDebugGroupKHR(Context *context,
2210 GLenum source,
2211 GLuint id,
2212 GLsizei length,
2213 const GLchar *message)
2214{
2215 if (!context->getExtensions().debug)
2216 {
Jamie Madille0472f32018-11-27 16:32:45 -05002217 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002218 return false;
2219 }
2220
Geoff Lang70d0f492015-12-10 17:45:46 -05002221 if (!ValidDebugSource(source, true))
2222 {
Jamie Madille0472f32018-11-27 16:32:45 -05002223 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002224 return false;
2225 }
2226
2227 size_t messageLength = (length < 0) ? strlen(message) : length;
2228 if (messageLength > context->getExtensions().maxDebugMessageLength)
2229 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002230 context->validationError(GL_INVALID_VALUE, kExceedsMaxDebugMessageLength);
Geoff Lang70d0f492015-12-10 17:45:46 -05002231 return false;
2232 }
2233
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002234 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002235 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2236 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002237 context->validationError(GL_STACK_OVERFLOW, kExceedsMaxDebugGroupStackDepth);
Geoff Lang70d0f492015-12-10 17:45:46 -05002238 return false;
2239 }
2240
Geoff Lange102fee2015-12-10 11:23:30 -05002241 return true;
2242}
2243
2244bool ValidatePopDebugGroupKHR(Context *context)
2245{
2246 if (!context->getExtensions().debug)
2247 {
Jamie Madille0472f32018-11-27 16:32:45 -05002248 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002249 return false;
2250 }
2251
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002252 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002253 if (currentStackSize <= 1)
2254 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002255 context->validationError(GL_STACK_UNDERFLOW, kCannotPopDefaultDebugGroup);
Geoff Lang70d0f492015-12-10 17:45:46 -05002256 return false;
2257 }
2258
2259 return true;
2260}
2261
2262static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2263{
2264 switch (identifier)
2265 {
2266 case GL_BUFFER:
2267 if (context->getBuffer(name) == nullptr)
2268 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002269 context->validationError(GL_INVALID_VALUE, kInvalidBufferName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002270 return false;
2271 }
2272 return true;
2273
2274 case GL_SHADER:
2275 if (context->getShader(name) == nullptr)
2276 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002277 context->validationError(GL_INVALID_VALUE, kInvalidShaderName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002278 return false;
2279 }
2280 return true;
2281
2282 case GL_PROGRAM:
Jamie Madill44a6fbf2018-10-02 13:38:56 -04002283 if (context->getProgramNoResolveLink(name) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002284 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002285 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002286 return false;
2287 }
2288 return true;
2289
2290 case GL_VERTEX_ARRAY:
2291 if (context->getVertexArray(name) == nullptr)
2292 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002293 context->validationError(GL_INVALID_VALUE, kInvalidVertexArrayName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002294 return false;
2295 }
2296 return true;
2297
2298 case GL_QUERY:
2299 if (context->getQuery(name) == nullptr)
2300 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002301 context->validationError(GL_INVALID_VALUE, kInvalidQueryName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002302 return false;
2303 }
2304 return true;
2305
2306 case GL_TRANSFORM_FEEDBACK:
2307 if (context->getTransformFeedback(name) == nullptr)
2308 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002309 context->validationError(GL_INVALID_VALUE, kInvalidTransformFeedbackName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002310 return false;
2311 }
2312 return true;
2313
2314 case GL_SAMPLER:
2315 if (context->getSampler(name) == nullptr)
2316 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002317 context->validationError(GL_INVALID_VALUE, kInvalidSamplerName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002318 return false;
2319 }
2320 return true;
2321
2322 case GL_TEXTURE:
2323 if (context->getTexture(name) == nullptr)
2324 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002325 context->validationError(GL_INVALID_VALUE, kInvalidTextureName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002326 return false;
2327 }
2328 return true;
2329
2330 case GL_RENDERBUFFER:
2331 if (context->getRenderbuffer(name) == nullptr)
2332 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002333 context->validationError(GL_INVALID_VALUE, kInvalidRenderbufferName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002334 return false;
2335 }
2336 return true;
2337
2338 case GL_FRAMEBUFFER:
2339 if (context->getFramebuffer(name) == nullptr)
2340 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002341 context->validationError(GL_INVALID_VALUE, kInvalidFramebufferName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002342 return false;
2343 }
2344 return true;
2345
2346 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05002347 context->validationError(GL_INVALID_ENUM, kInvalidIndentifier);
Geoff Lang70d0f492015-12-10 17:45:46 -05002348 return false;
2349 }
Geoff Lange102fee2015-12-10 11:23:30 -05002350}
2351
Martin Radev9d901792016-07-15 15:58:58 +03002352static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2353{
2354 size_t labelLength = 0;
2355
2356 if (length < 0)
2357 {
2358 if (label != nullptr)
2359 {
2360 labelLength = strlen(label);
2361 }
2362 }
2363 else
2364 {
2365 labelLength = static_cast<size_t>(length);
2366 }
2367
2368 if (labelLength > context->getExtensions().maxLabelLength)
2369 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002370 context->validationError(GL_INVALID_VALUE, kExceedsMaxLabelLength);
Martin Radev9d901792016-07-15 15:58:58 +03002371 return false;
2372 }
2373
2374 return true;
2375}
2376
Geoff Lange102fee2015-12-10 11:23:30 -05002377bool ValidateObjectLabelKHR(Context *context,
2378 GLenum identifier,
2379 GLuint name,
2380 GLsizei length,
2381 const GLchar *label)
2382{
2383 if (!context->getExtensions().debug)
2384 {
Jamie Madille0472f32018-11-27 16:32:45 -05002385 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002386 return false;
2387 }
2388
Geoff Lang70d0f492015-12-10 17:45:46 -05002389 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2390 {
2391 return false;
2392 }
2393
Martin Radev9d901792016-07-15 15:58:58 +03002394 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002395 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002396 return false;
2397 }
2398
Geoff Lange102fee2015-12-10 11:23:30 -05002399 return true;
2400}
2401
2402bool ValidateGetObjectLabelKHR(Context *context,
2403 GLenum identifier,
2404 GLuint name,
2405 GLsizei bufSize,
2406 GLsizei *length,
2407 GLchar *label)
2408{
2409 if (!context->getExtensions().debug)
2410 {
Jamie Madille0472f32018-11-27 16:32:45 -05002411 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002412 return false;
2413 }
2414
Geoff Lang70d0f492015-12-10 17:45:46 -05002415 if (bufSize < 0)
2416 {
Jamie Madille0472f32018-11-27 16:32:45 -05002417 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002418 return false;
2419 }
2420
2421 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2422 {
2423 return false;
2424 }
2425
Martin Radev9d901792016-07-15 15:58:58 +03002426 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002427}
2428
2429static bool ValidateObjectPtrName(Context *context, const void *ptr)
2430{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002431 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002432 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002433 context->validationError(GL_INVALID_VALUE, kInvalidSyncPointer);
Geoff Lang70d0f492015-12-10 17:45:46 -05002434 return false;
2435 }
2436
Geoff Lange102fee2015-12-10 11:23:30 -05002437 return true;
2438}
2439
2440bool ValidateObjectPtrLabelKHR(Context *context,
2441 const void *ptr,
2442 GLsizei length,
2443 const GLchar *label)
2444{
2445 if (!context->getExtensions().debug)
2446 {
Jamie Madille0472f32018-11-27 16:32:45 -05002447 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002448 return false;
2449 }
2450
Geoff Lang70d0f492015-12-10 17:45:46 -05002451 if (!ValidateObjectPtrName(context, ptr))
2452 {
2453 return false;
2454 }
2455
Martin Radev9d901792016-07-15 15:58:58 +03002456 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002457 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002458 return false;
2459 }
2460
Geoff Lange102fee2015-12-10 11:23:30 -05002461 return true;
2462}
2463
2464bool ValidateGetObjectPtrLabelKHR(Context *context,
2465 const void *ptr,
2466 GLsizei bufSize,
2467 GLsizei *length,
2468 GLchar *label)
2469{
2470 if (!context->getExtensions().debug)
2471 {
Jamie Madille0472f32018-11-27 16:32:45 -05002472 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002473 return false;
2474 }
2475
Geoff Lang70d0f492015-12-10 17:45:46 -05002476 if (bufSize < 0)
2477 {
Jamie Madille0472f32018-11-27 16:32:45 -05002478 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002479 return false;
2480 }
2481
2482 if (!ValidateObjectPtrName(context, ptr))
2483 {
2484 return false;
2485 }
2486
Martin Radev9d901792016-07-15 15:58:58 +03002487 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002488}
2489
2490bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2491{
2492 if (!context->getExtensions().debug)
2493 {
Jamie Madille0472f32018-11-27 16:32:45 -05002494 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002495 return false;
2496 }
2497
Geoff Lang70d0f492015-12-10 17:45:46 -05002498 // TODO: represent this in Context::getQueryParameterInfo.
2499 switch (pname)
2500 {
2501 case GL_DEBUG_CALLBACK_FUNCTION:
2502 case GL_DEBUG_CALLBACK_USER_PARAM:
2503 break;
2504
2505 default:
Jamie Madille0472f32018-11-27 16:32:45 -05002506 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002507 return false;
2508 }
2509
Geoff Lange102fee2015-12-10 11:23:30 -05002510 return true;
2511}
Jamie Madillc29968b2016-01-20 11:17:23 -05002512
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07002513bool ValidateGetPointervRobustANGLERobustANGLE(Context *context,
2514 GLenum pname,
2515 GLsizei bufSize,
2516 GLsizei *length,
2517 void **params)
2518{
2519 UNIMPLEMENTED();
2520 return false;
2521}
2522
Jamie Madillc29968b2016-01-20 11:17:23 -05002523bool ValidateBlitFramebufferANGLE(Context *context,
2524 GLint srcX0,
2525 GLint srcY0,
2526 GLint srcX1,
2527 GLint srcY1,
2528 GLint dstX0,
2529 GLint dstY0,
2530 GLint dstX1,
2531 GLint dstY1,
2532 GLbitfield mask,
2533 GLenum filter)
2534{
2535 if (!context->getExtensions().framebufferBlit)
2536 {
Jamie Madille0472f32018-11-27 16:32:45 -05002537 context->validationError(GL_INVALID_OPERATION, kBlitExtensionNotAvailable);
Jamie Madillc29968b2016-01-20 11:17:23 -05002538 return false;
2539 }
2540
2541 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2542 {
2543 // TODO(jmadill): Determine if this should be available on other implementations.
Jamie Madille0472f32018-11-27 16:32:45 -05002544 context->validationError(GL_INVALID_OPERATION, kBlitExtensionScaleOrFlip);
Jamie Madillc29968b2016-01-20 11:17:23 -05002545 return false;
2546 }
2547
2548 if (filter == GL_LINEAR)
2549 {
Jamie Madille0472f32018-11-27 16:32:45 -05002550 context->validationError(GL_INVALID_ENUM, kBlitExtensionLinear);
Jamie Madillc29968b2016-01-20 11:17:23 -05002551 return false;
2552 }
2553
Jamie Madill51f40ec2016-06-15 14:06:00 -04002554 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2555 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002556
2557 if (mask & GL_COLOR_BUFFER_BIT)
2558 {
2559 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2560 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2561
2562 if (readColorAttachment && drawColorAttachment)
2563 {
2564 if (!(readColorAttachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002565 readColorAttachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002566 readColorAttachment->type() != GL_RENDERBUFFER &&
2567 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2568 {
Jamie Madill610640f2018-11-21 17:28:41 -05002569 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002570 kBlitExtensionFromInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002571 return false;
2572 }
2573
Geoff Langa15472a2015-08-11 11:48:03 -04002574 for (size_t drawbufferIdx = 0;
2575 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002576 {
Geoff Langa15472a2015-08-11 11:48:03 -04002577 const FramebufferAttachment *attachment =
2578 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2579 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002580 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002581 if (!(attachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002582 attachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002583 attachment->type() != GL_RENDERBUFFER &&
2584 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2585 {
Jamie Madill610640f2018-11-21 17:28:41 -05002586 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002587 kBlitExtensionToInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002588 return false;
2589 }
2590
2591 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002592 if (!Format::EquivalentForBlit(attachment->getFormat(),
2593 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002594 {
Jamie Madill610640f2018-11-21 17:28:41 -05002595 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002596 kBlitExtensionFormatMismatch);
Jamie Madillc29968b2016-01-20 11:17:23 -05002597 return false;
2598 }
2599 }
2600 }
2601
Jamie Madill427064d2018-04-13 16:20:34 -04002602 GLint samples = readFramebuffer->getSamples(context);
Jamie Madille98b1b52018-03-08 09:47:23 -05002603 if (samples != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002604 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2605 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2606 {
Jamie Madill610640f2018-11-21 17:28:41 -05002607 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002608 kBlitExtensionMultisampledWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002609 return false;
2610 }
2611 }
2612 }
2613
2614 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2615 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2616 for (size_t i = 0; i < 2; i++)
2617 {
2618 if (mask & masks[i])
2619 {
2620 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002621 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002622 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002623 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002624
2625 if (readBuffer && drawBuffer)
2626 {
2627 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2628 dstX0, dstY0, dstX1, dstY1))
2629 {
2630 // only whole-buffer copies are permitted
Jamie Madill610640f2018-11-21 17:28:41 -05002631 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002632 kBlitExtensionDepthStencilWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002633 return false;
2634 }
2635
2636 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2637 {
Jamie Madill610640f2018-11-21 17:28:41 -05002638 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002639 kBlitExtensionMultisampledDepthOrStencil);
Jamie Madillc29968b2016-01-20 11:17:23 -05002640 return false;
2641 }
2642 }
2643 }
2644 }
2645
2646 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2647 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002648}
Jamie Madillc29968b2016-01-20 11:17:23 -05002649
Jamie Madill5b772312018-03-08 20:28:32 -05002650bool ValidateClear(Context *context, GLbitfield mask)
Jamie Madillc29968b2016-01-20 11:17:23 -05002651{
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07002652 Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
Olli Etuaho94c91a92018-07-19 15:10:24 +03002653 const Extensions &extensions = context->getExtensions();
Jamie Madille98b1b52018-03-08 09:47:23 -05002654
Jamie Madill427064d2018-04-13 16:20:34 -04002655 if (!ValidateFramebufferComplete(context, fbo))
Jamie Madillc29968b2016-01-20 11:17:23 -05002656 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002657 return false;
2658 }
2659
2660 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2661 {
Jamie Madille0472f32018-11-27 16:32:45 -05002662 context->validationError(GL_INVALID_VALUE, kInvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002663 return false;
2664 }
2665
Olli Etuaho94c91a92018-07-19 15:10:24 +03002666 if (extensions.webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
Geoff Lang76e65652017-03-27 14:58:02 -04002667 {
2668 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2669 GL_SIGNED_NORMALIZED};
2670
Corentin Wallez59c41592017-07-11 13:19:54 -04002671 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002672 drawBufferIdx++)
2673 {
2674 if (!ValidateWebGLFramebufferAttachmentClearType(
2675 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2676 {
2677 return false;
2678 }
2679 }
2680 }
2681
Olli Etuaho94c91a92018-07-19 15:10:24 +03002682 if (extensions.multiview && extensions.disjointTimerQuery)
2683 {
2684 const State &state = context->getGLState();
2685 Framebuffer *framebuffer = state.getDrawFramebuffer();
2686 if (framebuffer->getNumViews() > 1 && state.isQueryActive(QueryType::TimeElapsed))
2687 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002688 context->validationError(GL_INVALID_OPERATION, kMultiviewTimerQuery);
Olli Etuaho94c91a92018-07-19 15:10:24 +03002689 return false;
2690 }
2691 }
2692
Jamie Madillc29968b2016-01-20 11:17:23 -05002693 return true;
2694}
2695
Jamie Madill5b772312018-03-08 20:28:32 -05002696bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002697{
2698 if (!context->getExtensions().drawBuffers)
2699 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002700 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05002701 return false;
2702 }
2703
2704 return ValidateDrawBuffersBase(context, n, bufs);
2705}
2706
Jamie Madill73a84962016-02-12 09:27:23 -05002707bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002708 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002709 GLint level,
2710 GLint internalformat,
2711 GLsizei width,
2712 GLsizei height,
2713 GLint border,
2714 GLenum format,
2715 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002716 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002717{
Martin Radev1be913c2016-07-11 17:59:16 +03002718 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002719 {
2720 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002721 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002722 }
2723
Martin Radev1be913c2016-07-11 17:59:16 +03002724 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002725 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002726 0, 0, width, height, 1, border, format, type, -1,
2727 pixels);
2728}
2729
Brandon Jones416aaf92018-04-10 08:10:16 -07002730bool ValidateTexImage2DRobustANGLE(Context *context,
2731 TextureTarget target,
2732 GLint level,
2733 GLint internalformat,
2734 GLsizei width,
2735 GLsizei height,
2736 GLint border,
2737 GLenum format,
2738 GLenum type,
2739 GLsizei bufSize,
2740 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002741{
2742 if (!ValidateRobustEntryPoint(context, bufSize))
2743 {
2744 return false;
2745 }
2746
2747 if (context->getClientMajorVersion() < 3)
2748 {
2749 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2750 0, 0, width, height, border, format, type, bufSize,
2751 pixels);
2752 }
2753
2754 ASSERT(context->getClientMajorVersion() >= 3);
2755 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2756 0, 0, width, height, 1, border, format, type, bufSize,
2757 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002758}
2759
2760bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002761 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002762 GLint level,
2763 GLint xoffset,
2764 GLint yoffset,
2765 GLsizei width,
2766 GLsizei height,
2767 GLenum format,
2768 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002769 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002770{
2771
Martin Radev1be913c2016-07-11 17:59:16 +03002772 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002773 {
2774 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002775 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002776 }
2777
Martin Radev1be913c2016-07-11 17:59:16 +03002778 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002779 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002780 yoffset, 0, width, height, 1, 0, format, type, -1,
2781 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002782}
2783
Geoff Langc52f6f12016-10-14 10:18:00 -04002784bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002785 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002786 GLint level,
2787 GLint xoffset,
2788 GLint yoffset,
2789 GLsizei width,
2790 GLsizei height,
2791 GLenum format,
2792 GLenum type,
2793 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002794 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002795{
2796 if (!ValidateRobustEntryPoint(context, bufSize))
2797 {
2798 return false;
2799 }
2800
2801 if (context->getClientMajorVersion() < 3)
2802 {
2803 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2804 yoffset, width, height, 0, format, type, bufSize,
2805 pixels);
2806 }
2807
2808 ASSERT(context->getClientMajorVersion() >= 3);
2809 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2810 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2811 pixels);
2812}
2813
Jamie Madill73a84962016-02-12 09:27:23 -05002814bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002815 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002816 GLint level,
2817 GLenum internalformat,
2818 GLsizei width,
2819 GLsizei height,
2820 GLint border,
2821 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002822 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002823{
Martin Radev1be913c2016-07-11 17:59:16 +03002824 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002825 {
2826 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002827 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002828 {
2829 return false;
2830 }
2831 }
2832 else
2833 {
Martin Radev1be913c2016-07-11 17:59:16 +03002834 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002835 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002836 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002837 data))
2838 {
2839 return false;
2840 }
2841 }
2842
Geoff Langca271392017-04-05 12:30:00 -04002843 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jamie Madillca2ff382018-07-11 09:01:17 -04002844
2845 GLuint blockSize = 0;
2846 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002847 {
Jamie Madille0472f32018-11-27 16:32:45 -05002848 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002849 return false;
2850 }
2851
Jamie Madillca2ff382018-07-11 09:01:17 -04002852 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002853 {
Jamie Madille0472f32018-11-27 16:32:45 -05002854 context->validationError(GL_INVALID_VALUE, kCompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002855 return false;
2856 }
2857
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002858 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002859 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002860 context->validationError(GL_INVALID_ENUM, kRectangleTextureCompressed);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002861 return false;
2862 }
2863
Jamie Madill73a84962016-02-12 09:27:23 -05002864 return true;
2865}
2866
Corentin Wallezb2931602017-04-11 15:58:57 -04002867bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002868 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002869 GLint level,
2870 GLenum internalformat,
2871 GLsizei width,
2872 GLsizei height,
2873 GLint border,
2874 GLsizei imageSize,
2875 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002876 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002877{
2878 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2879 {
2880 return false;
2881 }
2882
2883 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2884 border, imageSize, data);
2885}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002886
Corentin Wallezb2931602017-04-11 15:58:57 -04002887bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002888 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002889 GLint level,
2890 GLint xoffset,
2891 GLint yoffset,
2892 GLsizei width,
2893 GLsizei height,
2894 GLenum format,
2895 GLsizei imageSize,
2896 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002897 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002898{
2899 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2900 {
2901 return false;
2902 }
2903
2904 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2905 format, imageSize, data);
2906}
2907
Jamie Madill73a84962016-02-12 09:27:23 -05002908bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002909 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002910 GLint level,
2911 GLint xoffset,
2912 GLint yoffset,
2913 GLsizei width,
2914 GLsizei height,
2915 GLenum format,
2916 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002917 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002918{
Martin Radev1be913c2016-07-11 17:59:16 +03002919 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002920 {
2921 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002922 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002923 {
2924 return false;
2925 }
2926 }
2927 else
2928 {
Martin Radev1be913c2016-07-11 17:59:16 +03002929 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002930 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002931 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002932 data))
2933 {
2934 return false;
2935 }
2936 }
2937
Geoff Langca271392017-04-05 12:30:00 -04002938 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jamie Madillca2ff382018-07-11 09:01:17 -04002939 GLuint blockSize = 0;
2940 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002941 {
Jamie Madille0472f32018-11-27 16:32:45 -05002942 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002943 return false;
2944 }
2945
Jamie Madillca2ff382018-07-11 09:01:17 -04002946 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002947 {
Jamie Madille0472f32018-11-27 16:32:45 -05002948 context->validationError(GL_INVALID_VALUE, kInvalidCompressedImageSize);
Jamie Madill73a84962016-02-12 09:27:23 -05002949 return false;
2950 }
2951
2952 return true;
2953}
2954
Corentin Wallez336129f2017-10-17 15:55:40 -04002955bool ValidateGetBufferPointervOES(Context *context,
2956 BufferBinding target,
2957 GLenum pname,
2958 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002959{
Jamie Madillc3e37312018-11-30 15:25:39 -05002960 if (!context->getExtensions().mapBuffer)
2961 {
2962 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
2963 return false;
2964 }
2965
Geoff Lang496c02d2016-10-20 11:38:11 -07002966 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002967}
2968
Corentin Wallez336129f2017-10-17 15:55:40 -04002969bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03002970{
2971 if (!context->getExtensions().mapBuffer)
2972 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002973 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03002974 return false;
2975 }
2976
Corentin Walleze4477002017-12-01 14:39:58 -05002977 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03002978 {
Jamie Madille0472f32018-11-27 16:32:45 -05002979 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002980 return false;
2981 }
2982
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002983 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002984
2985 if (buffer == nullptr)
2986 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002987 context->validationError(GL_INVALID_OPERATION, kBufferNotMappable);
Olli Etuaho4f667482016-03-30 15:56:35 +03002988 return false;
2989 }
2990
2991 if (access != GL_WRITE_ONLY_OES)
2992 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002993 context->validationError(GL_INVALID_ENUM, kInvalidAccessBits);
Olli Etuaho4f667482016-03-30 15:56:35 +03002994 return false;
2995 }
2996
2997 if (buffer->isMapped())
2998 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002999 context->validationError(GL_INVALID_OPERATION, kBufferAlreadyMapped);
Olli Etuaho4f667482016-03-30 15:56:35 +03003000 return false;
3001 }
3002
Geoff Lang79f71042017-08-14 16:43:43 -04003003 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003004}
3005
Corentin Wallez336129f2017-10-17 15:55:40 -04003006bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03003007{
3008 if (!context->getExtensions().mapBuffer)
3009 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003010 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03003011 return false;
3012 }
3013
3014 return ValidateUnmapBufferBase(context, target);
3015}
3016
3017bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003018 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003019 GLintptr offset,
3020 GLsizeiptr length,
3021 GLbitfield access)
3022{
3023 if (!context->getExtensions().mapBufferRange)
3024 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003025 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03003026 return false;
3027 }
3028
3029 return ValidateMapBufferRangeBase(context, target, offset, length, access);
3030}
3031
Corentin Wallez336129f2017-10-17 15:55:40 -04003032bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04003033{
3034 Buffer *buffer = context->getGLState().getTargetBuffer(target);
3035 ASSERT(buffer != nullptr);
3036
3037 // Check if this buffer is currently being used as a transform feedback output buffer
3038 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
3039 if (transformFeedback != nullptr && transformFeedback->isActive())
3040 {
3041 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
3042 {
3043 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
3044 if (transformFeedbackBuffer.get() == buffer)
3045 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003046 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
Geoff Lang79f71042017-08-14 16:43:43 -04003047 return false;
3048 }
3049 }
3050 }
3051
James Darpiniane8a93c62018-01-04 18:02:24 -08003052 if (context->getExtensions().webglCompatibility &&
3053 buffer->isBoundForTransformFeedbackAndOtherUse())
3054 {
Jamie Madille0472f32018-11-27 16:32:45 -05003055 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08003056 return false;
3057 }
3058
Geoff Lang79f71042017-08-14 16:43:43 -04003059 return true;
3060}
3061
Olli Etuaho4f667482016-03-30 15:56:35 +03003062bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003063 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003064 GLintptr offset,
3065 GLsizeiptr length)
3066{
3067 if (!context->getExtensions().mapBufferRange)
3068 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003069 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03003070 return false;
3071 }
3072
3073 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
3074}
3075
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003076bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
Ian Ewell54f87462016-03-10 13:47:21 -05003077{
Jamie Madillac66f982018-10-09 18:30:01 -04003078 if (!context->getStateCache().isValidBindTextureType(target))
Ian Ewell54f87462016-03-10 13:47:21 -05003079 {
Jamie Madillac66f982018-10-09 18:30:01 -04003080 RecordBindTextureTypeError(context, target);
3081 return false;
Ian Ewell54f87462016-03-10 13:47:21 -05003082 }
3083
Jamie Madill0fdb9562018-09-17 17:18:43 -04003084 if (texture == 0)
3085 {
3086 return true;
3087 }
3088
3089 Texture *textureObject = context->getTexture(texture);
3090 if (textureObject && textureObject->getType() != target)
3091 {
Jamie Madille0472f32018-11-27 16:32:45 -05003092 context->validationError(GL_INVALID_OPERATION, kTypeMismatch);
Jamie Madill0fdb9562018-09-17 17:18:43 -04003093 return false;
3094 }
3095
3096 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
3097 !context->isTextureGenerated(texture))
3098 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003099 context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
Jamie Madill0fdb9562018-09-17 17:18:43 -04003100 return false;
3101 }
3102
Ian Ewell54f87462016-03-10 13:47:21 -05003103 return true;
3104}
3105
Geoff Langd8605522016-04-13 10:19:12 -04003106bool ValidateBindUniformLocationCHROMIUM(Context *context,
3107 GLuint program,
3108 GLint location,
3109 const GLchar *name)
3110{
3111 if (!context->getExtensions().bindUniformLocation)
3112 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003113 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langd8605522016-04-13 10:19:12 -04003114 return false;
3115 }
3116
3117 Program *programObject = GetValidProgram(context, program);
3118 if (!programObject)
3119 {
3120 return false;
3121 }
3122
3123 if (location < 0)
3124 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003125 context->validationError(GL_INVALID_VALUE, kNegativeLocation);
Geoff Langd8605522016-04-13 10:19:12 -04003126 return false;
3127 }
3128
3129 const Caps &caps = context->getCaps();
3130 if (static_cast<size_t>(location) >=
3131 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3132 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003133 context->validationError(GL_INVALID_VALUE, kInvalidBindUniformLocation);
Geoff Langd8605522016-04-13 10:19:12 -04003134 return false;
3135 }
3136
Geoff Langfc32e8b2017-05-31 14:16:59 -04003137 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3138 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003139 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003140 {
Jamie Madille0472f32018-11-27 16:32:45 -05003141 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003142 return false;
3143 }
3144
Geoff Langd8605522016-04-13 10:19:12 -04003145 if (strncmp(name, "gl_", 3) == 0)
3146 {
Jamie Madille0472f32018-11-27 16:32:45 -05003147 context->validationError(GL_INVALID_VALUE, kNameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003148 return false;
3149 }
3150
3151 return true;
3152}
3153
Jamie Madille2e406c2016-06-02 13:04:10 -04003154bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003155{
3156 if (!context->getExtensions().framebufferMixedSamples)
3157 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003158 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänena797e062016-05-12 15:23:40 +03003159 return false;
3160 }
3161 switch (components)
3162 {
3163 case GL_RGB:
3164 case GL_RGBA:
3165 case GL_ALPHA:
3166 case GL_NONE:
3167 break;
3168 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003169 context->validationError(GL_INVALID_ENUM, kInvalidCoverageComponents);
Sami Väisänena797e062016-05-12 15:23:40 +03003170 return false;
3171 }
3172
3173 return true;
3174}
3175
Sami Väisänene45e53b2016-05-25 10:36:04 +03003176// CHROMIUM_path_rendering
3177
Jamie Madill007530e2017-12-28 14:27:04 -05003178bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003179{
Jamie Madill007530e2017-12-28 14:27:04 -05003180 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003181 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003182 return false;
3183 }
Jamie Madill007530e2017-12-28 14:27:04 -05003184
Sami Väisänene45e53b2016-05-25 10:36:04 +03003185 if (matrix == nullptr)
3186 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003187 context->validationError(GL_INVALID_OPERATION, kInvalidPathMatrix);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003188 return false;
3189 }
Jamie Madill007530e2017-12-28 14:27:04 -05003190
Sami Väisänene45e53b2016-05-25 10:36:04 +03003191 return true;
3192}
3193
Jamie Madill007530e2017-12-28 14:27:04 -05003194bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003195{
Jamie Madill007530e2017-12-28 14:27:04 -05003196 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003197}
3198
Jamie Madill007530e2017-12-28 14:27:04 -05003199bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003200{
3201 if (!context->getExtensions().pathRendering)
3202 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003203 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003204 return false;
3205 }
3206
3207 // range = 0 is undefined in NV_path_rendering.
3208 // we add stricter semantic check here and require a non zero positive range.
3209 if (range <= 0)
3210 {
Jamie Madille0472f32018-11-27 16:32:45 -05003211 context->validationError(GL_INVALID_VALUE, kInvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003212 return false;
3213 }
3214
3215 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3216 {
Jamie Madille0472f32018-11-27 16:32:45 -05003217 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003218 return false;
3219 }
3220
3221 return true;
3222}
3223
Jamie Madill007530e2017-12-28 14:27:04 -05003224bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003225{
3226 if (!context->getExtensions().pathRendering)
3227 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003228 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003229 return false;
3230 }
3231
3232 // range = 0 is undefined in NV_path_rendering.
3233 // we add stricter semantic check here and require a non zero positive range.
3234 if (range <= 0)
3235 {
Jamie Madille0472f32018-11-27 16:32:45 -05003236 context->validationError(GL_INVALID_VALUE, kInvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003237 return false;
3238 }
3239
3240 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3241 checkedRange += range;
3242
3243 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3244 {
Jamie Madille0472f32018-11-27 16:32:45 -05003245 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003246 return false;
3247 }
3248 return true;
3249}
3250
Jamie Madill007530e2017-12-28 14:27:04 -05003251bool ValidatePathCommandsCHROMIUM(Context *context,
3252 GLuint path,
3253 GLsizei numCommands,
3254 const GLubyte *commands,
3255 GLsizei numCoords,
3256 GLenum coordType,
3257 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003258{
3259 if (!context->getExtensions().pathRendering)
3260 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003261 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003262 return false;
3263 }
Brandon Jones59770802018-04-02 13:18:42 -07003264 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003265 {
Jamie Madille0472f32018-11-27 16:32:45 -05003266 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003267 return false;
3268 }
3269
3270 if (numCommands < 0)
3271 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003272 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCommands);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003273 return false;
3274 }
3275 else if (numCommands > 0)
3276 {
3277 if (!commands)
3278 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003279 context->validationError(GL_INVALID_VALUE, kInvalidPathCommandsArray);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003280 return false;
3281 }
3282 }
3283
3284 if (numCoords < 0)
3285 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003286 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCoords);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003287 return false;
3288 }
3289 else if (numCoords > 0)
3290 {
3291 if (!coords)
3292 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003293 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCoordsArray);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003294 return false;
3295 }
3296 }
3297
3298 std::uint32_t coordTypeSize = 0;
3299 switch (coordType)
3300 {
3301 case GL_BYTE:
3302 coordTypeSize = sizeof(GLbyte);
3303 break;
3304
3305 case GL_UNSIGNED_BYTE:
3306 coordTypeSize = sizeof(GLubyte);
3307 break;
3308
3309 case GL_SHORT:
3310 coordTypeSize = sizeof(GLshort);
3311 break;
3312
3313 case GL_UNSIGNED_SHORT:
3314 coordTypeSize = sizeof(GLushort);
3315 break;
3316
3317 case GL_FLOAT:
3318 coordTypeSize = sizeof(GLfloat);
3319 break;
3320
3321 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003322 context->validationError(GL_INVALID_ENUM, kInvalidPathCoordinateType);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003323 return false;
3324 }
3325
3326 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3327 checkedSize += (coordTypeSize * numCoords);
3328 if (!checkedSize.IsValid())
3329 {
Jamie Madille0472f32018-11-27 16:32:45 -05003330 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003331 return false;
3332 }
3333
3334 // early return skips command data validation when it doesn't exist.
3335 if (!commands)
3336 return true;
3337
3338 GLsizei expectedNumCoords = 0;
3339 for (GLsizei i = 0; i < numCommands; ++i)
3340 {
3341 switch (commands[i])
3342 {
3343 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3344 break;
3345 case GL_MOVE_TO_CHROMIUM:
3346 case GL_LINE_TO_CHROMIUM:
3347 expectedNumCoords += 2;
3348 break;
3349 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3350 expectedNumCoords += 4;
3351 break;
3352 case GL_CUBIC_CURVE_TO_CHROMIUM:
3353 expectedNumCoords += 6;
3354 break;
3355 case GL_CONIC_CURVE_TO_CHROMIUM:
3356 expectedNumCoords += 5;
3357 break;
3358 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003359 context->validationError(GL_INVALID_ENUM, kInvalidPathCommand);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003360 return false;
3361 }
3362 }
Jamie Madillc3e37312018-11-30 15:25:39 -05003363
Sami Väisänene45e53b2016-05-25 10:36:04 +03003364 if (expectedNumCoords != numCoords)
3365 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003366 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCoords);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003367 return false;
3368 }
3369
3370 return true;
3371}
3372
Jamie Madill007530e2017-12-28 14:27:04 -05003373bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003374{
3375 if (!context->getExtensions().pathRendering)
3376 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003377 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003378 return false;
3379 }
Brandon Jones59770802018-04-02 13:18:42 -07003380 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003381 {
Jamie Madille0472f32018-11-27 16:32:45 -05003382 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003383 return false;
3384 }
3385
3386 switch (pname)
3387 {
3388 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3389 if (value < 0.0f)
3390 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003391 context->validationError(GL_INVALID_VALUE, kInvalidPathStrokeWidth);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003392 return false;
3393 }
3394 break;
3395 case GL_PATH_END_CAPS_CHROMIUM:
3396 switch (static_cast<GLenum>(value))
3397 {
3398 case GL_FLAT_CHROMIUM:
3399 case GL_SQUARE_CHROMIUM:
3400 case GL_ROUND_CHROMIUM:
3401 break;
3402 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003403 context->validationError(GL_INVALID_ENUM, kInvalidPathEndCaps);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003404 return false;
3405 }
3406 break;
3407 case GL_PATH_JOIN_STYLE_CHROMIUM:
3408 switch (static_cast<GLenum>(value))
3409 {
3410 case GL_MITER_REVERT_CHROMIUM:
3411 case GL_BEVEL_CHROMIUM:
3412 case GL_ROUND_CHROMIUM:
3413 break;
3414 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003415 context->validationError(GL_INVALID_ENUM, kInvalidPathJoinStyle);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003416 return false;
3417 }
Nico Weber41b072b2018-02-09 10:01:32 -05003418 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003419 case GL_PATH_MITER_LIMIT_CHROMIUM:
3420 if (value < 0.0f)
3421 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003422 context->validationError(GL_INVALID_VALUE, kInvalidPathMiterLimit);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003423 return false;
3424 }
3425 break;
3426
3427 case GL_PATH_STROKE_BOUND_CHROMIUM:
3428 // no errors, only clamping.
3429 break;
3430
3431 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003432 context->validationError(GL_INVALID_ENUM, kInvalidPathParameter);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003433 return false;
3434 }
3435 return true;
3436}
3437
Jamie Madill007530e2017-12-28 14:27:04 -05003438bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3439{
3440 // TODO(jmadill): Use proper clamping cast.
3441 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3442}
3443
3444bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003445{
3446 if (!context->getExtensions().pathRendering)
3447 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003448 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003449 return false;
3450 }
3451
Brandon Jones59770802018-04-02 13:18:42 -07003452 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003453 {
Jamie Madille0472f32018-11-27 16:32:45 -05003454 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003455 return false;
3456 }
Jamie Madillc3e37312018-11-30 15:25:39 -05003457
Sami Väisänene45e53b2016-05-25 10:36:04 +03003458 if (!value)
3459 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003460 context->validationError(GL_INVALID_VALUE, kInvalidPathValueArray);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003461 return false;
3462 }
3463
3464 switch (pname)
3465 {
3466 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3467 case GL_PATH_END_CAPS_CHROMIUM:
3468 case GL_PATH_JOIN_STYLE_CHROMIUM:
3469 case GL_PATH_MITER_LIMIT_CHROMIUM:
3470 case GL_PATH_STROKE_BOUND_CHROMIUM:
3471 break;
3472
3473 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003474 context->validationError(GL_INVALID_ENUM, kInvalidPathParameter);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003475 return false;
3476 }
3477
3478 return true;
3479}
3480
Jamie Madill007530e2017-12-28 14:27:04 -05003481bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3482{
3483 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3484 reinterpret_cast<GLfloat *>(value));
3485}
3486
3487bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003488{
3489 if (!context->getExtensions().pathRendering)
3490 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003491 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003492 return false;
3493 }
3494
3495 switch (func)
3496 {
3497 case GL_NEVER:
3498 case GL_ALWAYS:
3499 case GL_LESS:
3500 case GL_LEQUAL:
3501 case GL_EQUAL:
3502 case GL_GEQUAL:
3503 case GL_GREATER:
3504 case GL_NOTEQUAL:
3505 break;
3506 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003507 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003508 return false;
3509 }
3510
3511 return true;
3512}
3513
3514// Note that the spec specifies that for the path drawing commands
3515// if the path object is not an existing path object the command
3516// does nothing and no error is generated.
3517// However if the path object exists but has not been specified any
3518// commands then an error is generated.
3519
Jamie Madill007530e2017-12-28 14:27:04 -05003520bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003521{
3522 if (!context->getExtensions().pathRendering)
3523 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003524 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003525 return false;
3526 }
Brandon Jones59770802018-04-02 13:18:42 -07003527 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003528 {
Jamie Madille0472f32018-11-27 16:32:45 -05003529 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003530 return false;
3531 }
3532
3533 switch (fillMode)
3534 {
3535 case GL_COUNT_UP_CHROMIUM:
3536 case GL_COUNT_DOWN_CHROMIUM:
3537 break;
3538 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003539 context->validationError(GL_INVALID_ENUM, kInvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003540 return false;
3541 }
3542
3543 if (!isPow2(mask + 1))
3544 {
Jamie Madille0472f32018-11-27 16:32:45 -05003545 context->validationError(GL_INVALID_VALUE, kInvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003546 return false;
3547 }
3548
3549 return true;
3550}
3551
Jamie Madill007530e2017-12-28 14:27:04 -05003552bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003553{
3554 if (!context->getExtensions().pathRendering)
3555 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003556 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003557 return false;
3558 }
Jamie Madillc3e37312018-11-30 15:25:39 -05003559
Brandon Jones59770802018-04-02 13:18:42 -07003560 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003561 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003562 context->validationError(GL_INVALID_OPERATION, kNoPathOrNoPathData);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003563 return false;
3564 }
3565
3566 return true;
3567}
3568
Jamie Madill007530e2017-12-28 14:27:04 -05003569bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003570{
3571 if (!context->getExtensions().pathRendering)
3572 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003573 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003574 return false;
3575 }
Brandon Jones59770802018-04-02 13:18:42 -07003576 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003577 {
Jamie Madille0472f32018-11-27 16:32:45 -05003578 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003579 return false;
3580 }
3581
3582 switch (coverMode)
3583 {
3584 case GL_CONVEX_HULL_CHROMIUM:
3585 case GL_BOUNDING_BOX_CHROMIUM:
3586 break;
3587 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003588 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003589 return false;
3590 }
3591 return true;
3592}
3593
Jamie Madill778bf092018-11-14 09:54:36 -05003594bool ValidateCoverFillPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3595{
3596 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3597}
3598
3599bool ValidateCoverStrokePathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3600{
3601 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3602}
3603
Jamie Madill007530e2017-12-28 14:27:04 -05003604bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3605 GLuint path,
3606 GLenum fillMode,
3607 GLuint mask,
3608 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003609{
Jamie Madill007530e2017-12-28 14:27:04 -05003610 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3611 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003612}
3613
Jamie Madill007530e2017-12-28 14:27:04 -05003614bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3615 GLuint path,
3616 GLint reference,
3617 GLuint mask,
3618 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003619{
Jamie Madill007530e2017-12-28 14:27:04 -05003620 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3621 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003622}
3623
Brandon Jonesd1049182018-03-28 10:02:20 -07003624bool ValidateIsPathCHROMIUM(Context *context, GLuint path)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003625{
3626 if (!context->getExtensions().pathRendering)
3627 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003628 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003629 return false;
3630 }
3631 return true;
3632}
3633
Jamie Madill007530e2017-12-28 14:27:04 -05003634bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3635 GLsizei numPaths,
3636 GLenum pathNameType,
3637 const void *paths,
3638 GLuint pathBase,
3639 GLenum coverMode,
3640 GLenum transformType,
3641 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003642{
3643 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3644 transformType, transformValues))
3645 return false;
3646
3647 switch (coverMode)
3648 {
3649 case GL_CONVEX_HULL_CHROMIUM:
3650 case GL_BOUNDING_BOX_CHROMIUM:
3651 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3652 break;
3653 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003654 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003655 return false;
3656 }
3657
3658 return true;
3659}
3660
Jamie Madill007530e2017-12-28 14:27:04 -05003661bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3662 GLsizei numPaths,
3663 GLenum pathNameType,
3664 const void *paths,
3665 GLuint pathBase,
3666 GLenum coverMode,
3667 GLenum transformType,
3668 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003669{
3670 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3671 transformType, transformValues))
3672 return false;
3673
3674 switch (coverMode)
3675 {
3676 case GL_CONVEX_HULL_CHROMIUM:
3677 case GL_BOUNDING_BOX_CHROMIUM:
3678 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3679 break;
3680 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003681 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003682 return false;
3683 }
3684
3685 return true;
3686}
3687
Jamie Madill007530e2017-12-28 14:27:04 -05003688bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3689 GLsizei numPaths,
3690 GLenum pathNameType,
3691 const void *paths,
3692 GLuint pathBase,
3693 GLenum fillMode,
3694 GLuint mask,
3695 GLenum transformType,
3696 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003697{
3698
3699 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3700 transformType, transformValues))
3701 return false;
3702
3703 switch (fillMode)
3704 {
3705 case GL_COUNT_UP_CHROMIUM:
3706 case GL_COUNT_DOWN_CHROMIUM:
3707 break;
3708 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003709 context->validationError(GL_INVALID_ENUM, kInvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003710 return false;
3711 }
3712 if (!isPow2(mask + 1))
3713 {
Jamie Madille0472f32018-11-27 16:32:45 -05003714 context->validationError(GL_INVALID_VALUE, kInvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003715 return false;
3716 }
3717 return true;
3718}
3719
Jamie Madill007530e2017-12-28 14:27:04 -05003720bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3721 GLsizei numPaths,
3722 GLenum pathNameType,
3723 const void *paths,
3724 GLuint pathBase,
3725 GLint reference,
3726 GLuint mask,
3727 GLenum transformType,
3728 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003729{
3730 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3731 transformType, transformValues))
3732 return false;
3733
3734 // no more validation here.
3735
3736 return true;
3737}
3738
Jamie Madill007530e2017-12-28 14:27:04 -05003739bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3740 GLsizei numPaths,
3741 GLenum pathNameType,
3742 const void *paths,
3743 GLuint pathBase,
3744 GLenum fillMode,
3745 GLuint mask,
3746 GLenum coverMode,
3747 GLenum transformType,
3748 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003749{
3750 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3751 transformType, transformValues))
3752 return false;
3753
3754 switch (coverMode)
3755 {
3756 case GL_CONVEX_HULL_CHROMIUM:
3757 case GL_BOUNDING_BOX_CHROMIUM:
3758 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3759 break;
3760 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003761 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003762 return false;
3763 }
3764
3765 switch (fillMode)
3766 {
3767 case GL_COUNT_UP_CHROMIUM:
3768 case GL_COUNT_DOWN_CHROMIUM:
3769 break;
3770 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003771 context->validationError(GL_INVALID_ENUM, kInvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003772 return false;
3773 }
3774 if (!isPow2(mask + 1))
3775 {
Jamie Madille0472f32018-11-27 16:32:45 -05003776 context->validationError(GL_INVALID_VALUE, kInvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003777 return false;
3778 }
3779
3780 return true;
3781}
3782
Jamie Madill007530e2017-12-28 14:27:04 -05003783bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
3784 GLsizei numPaths,
3785 GLenum pathNameType,
3786 const void *paths,
3787 GLuint pathBase,
3788 GLint reference,
3789 GLuint mask,
3790 GLenum coverMode,
3791 GLenum transformType,
3792 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003793{
3794 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3795 transformType, transformValues))
3796 return false;
3797
3798 switch (coverMode)
3799 {
3800 case GL_CONVEX_HULL_CHROMIUM:
3801 case GL_BOUNDING_BOX_CHROMIUM:
3802 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3803 break;
3804 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003805 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003806 return false;
3807 }
3808
3809 return true;
3810}
3811
Jamie Madill007530e2017-12-28 14:27:04 -05003812bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
3813 GLuint program,
3814 GLint location,
3815 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003816{
3817 if (!context->getExtensions().pathRendering)
3818 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003819 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003820 return false;
3821 }
3822
3823 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3824 if (location >= MaxLocation)
3825 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003826 context->validationError(GL_INVALID_VALUE, kInvalidVaryingLocation);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003827 return false;
3828 }
3829
Jamie Madill44a6fbf2018-10-02 13:38:56 -04003830 const auto *programObject = context->getProgramNoResolveLink(program);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003831 if (!programObject)
3832 {
Jamie Madille0472f32018-11-27 16:32:45 -05003833 context->validationError(GL_INVALID_OPERATION, kProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003834 return false;
3835 }
3836
3837 if (!name)
3838 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003839 context->validationError(GL_INVALID_VALUE, kMissingName);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003840 return false;
3841 }
3842
3843 if (angle::BeginsWith(name, "gl_"))
3844 {
Jamie Madille0472f32018-11-27 16:32:45 -05003845 context->validationError(GL_INVALID_OPERATION, kNameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003846 return false;
3847 }
3848
3849 return true;
3850}
3851
Jamie Madill007530e2017-12-28 14:27:04 -05003852bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
3853 GLuint program,
3854 GLint location,
3855 GLenum genMode,
3856 GLint components,
3857 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003858{
3859 if (!context->getExtensions().pathRendering)
3860 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003861 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003862 return false;
3863 }
3864
Jamie Madill44a6fbf2018-10-02 13:38:56 -04003865 const auto *programObject = context->getProgramResolveLink(program);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003866 if (!programObject || programObject->isFlaggedForDeletion())
3867 {
Jamie Madille0472f32018-11-27 16:32:45 -05003868 context->validationError(GL_INVALID_OPERATION, kProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003869 return false;
3870 }
3871
3872 if (!programObject->isLinked())
3873 {
Jamie Madille0472f32018-11-27 16:32:45 -05003874 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003875 return false;
3876 }
3877
3878 switch (genMode)
3879 {
3880 case GL_NONE:
3881 if (components != 0)
3882 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003883 context->validationError(GL_INVALID_VALUE, kInvalidComponents);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003884 return false;
3885 }
3886 break;
3887
3888 case GL_OBJECT_LINEAR_CHROMIUM:
3889 case GL_EYE_LINEAR_CHROMIUM:
3890 case GL_CONSTANT_CHROMIUM:
3891 if (components < 1 || components > 4)
3892 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003893 context->validationError(GL_INVALID_VALUE, kInvalidComponents);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003894 return false;
3895 }
3896 if (!coeffs)
3897 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003898 context->validationError(GL_INVALID_VALUE, kInvalidPathCoefficientsArray);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003899 return false;
3900 }
3901 break;
3902
3903 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003904 context->validationError(GL_INVALID_ENUM, kInvalidPathGenMode);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003905 return false;
3906 }
3907
3908 // If the location is -1 then the command is silently ignored
3909 // and no further validation is needed.
3910 if (location == -1)
3911 return true;
3912
jchen103fd614d2018-08-13 12:21:58 +08003913 const auto &binding = programObject->getFragmentInputBindingInfo(location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003914
3915 if (!binding.valid)
3916 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003917 context->validationError(GL_INVALID_OPERATION, kInvalidFragmentInputBinding);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003918 return false;
3919 }
3920
3921 if (binding.type != GL_NONE)
3922 {
3923 GLint expectedComponents = 0;
3924 switch (binding.type)
3925 {
3926 case GL_FLOAT:
3927 expectedComponents = 1;
3928 break;
3929 case GL_FLOAT_VEC2:
3930 expectedComponents = 2;
3931 break;
3932 case GL_FLOAT_VEC3:
3933 expectedComponents = 3;
3934 break;
3935 case GL_FLOAT_VEC4:
3936 expectedComponents = 4;
3937 break;
3938 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003939 context->validationError(GL_INVALID_OPERATION, kFragmentInputTypeNotFloatingPoint);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003940 return false;
3941 }
3942 if (expectedComponents != components && genMode != GL_NONE)
3943 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003944 context->validationError(GL_INVALID_OPERATION, kInvalidPathComponents);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003945 return false;
3946 }
3947 }
3948 return true;
3949}
3950
Geoff Lang97073d12016-04-20 10:42:34 -07003951bool ValidateCopyTextureCHROMIUM(Context *context,
3952 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003953 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003954 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003955 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003956 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003957 GLint internalFormat,
3958 GLenum destType,
3959 GLboolean unpackFlipY,
3960 GLboolean unpackPremultiplyAlpha,
3961 GLboolean unpackUnmultiplyAlpha)
3962{
3963 if (!context->getExtensions().copyTexture)
3964 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003965 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang97073d12016-04-20 10:42:34 -07003966 return false;
3967 }
3968
Geoff Lang4f0e0032017-05-01 16:04:35 -04003969 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003970 if (source == nullptr)
3971 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003972 context->validationError(GL_INVALID_VALUE, kInvalidSourceTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07003973 return false;
3974 }
3975
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003976 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003977 {
Jamie Madille0472f32018-11-27 16:32:45 -05003978 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003979 return false;
3980 }
3981
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003982 TextureType sourceType = source->getType();
3983 ASSERT(sourceType != TextureType::CubeMap);
3984 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003985
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003986 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07003987 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003988 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureLevel);
Geoff Lang97073d12016-04-20 10:42:34 -07003989 return false;
3990 }
3991
Geoff Lang4f0e0032017-05-01 16:04:35 -04003992 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
3993 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
3994 if (sourceWidth == 0 || sourceHeight == 0)
3995 {
Jamie Madille0472f32018-11-27 16:32:45 -05003996 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003997 return false;
3998 }
3999
4000 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
4001 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004002 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004003 context->validationError(GL_INVALID_OPERATION, kInvalidSourceTextureInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004004 return false;
4005 }
4006
Geoff Lang63458a32017-10-30 15:16:53 -04004007 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4008 {
Jamie Madille0472f32018-11-27 16:32:45 -05004009 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Lang63458a32017-10-30 15:16:53 -04004010 return false;
4011 }
4012
Geoff Lang4f0e0032017-05-01 16:04:35 -04004013 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004014 if (dest == nullptr)
4015 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004016 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07004017 return false;
4018 }
4019
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004020 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004021 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004022 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTextureType);
Geoff Lang97073d12016-04-20 10:42:34 -07004023 return false;
4024 }
4025
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004026 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08004027 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004028 {
Jamie Madille0472f32018-11-27 16:32:45 -05004029 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004030 return false;
4031 }
4032
Geoff Lang97073d12016-04-20 10:42:34 -07004033 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
4034 {
Geoff Lang97073d12016-04-20 10:42:34 -07004035 return false;
4036 }
4037
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004038 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04004039 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004040 context->validationError(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004041 return false;
4042 }
4043
Geoff Lang97073d12016-04-20 10:42:34 -07004044 if (dest->getImmutableFormat())
4045 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004046 context->validationError(GL_INVALID_OPERATION, kDestinationImmutable);
Geoff Lang97073d12016-04-20 10:42:34 -07004047 return false;
4048 }
4049
4050 return true;
4051}
4052
4053bool ValidateCopySubTextureCHROMIUM(Context *context,
4054 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04004055 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004056 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07004057 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04004058 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07004059 GLint xoffset,
4060 GLint yoffset,
4061 GLint x,
4062 GLint y,
4063 GLsizei width,
4064 GLsizei height,
4065 GLboolean unpackFlipY,
4066 GLboolean unpackPremultiplyAlpha,
4067 GLboolean unpackUnmultiplyAlpha)
4068{
4069 if (!context->getExtensions().copyTexture)
4070 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004071 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang97073d12016-04-20 10:42:34 -07004072 return false;
4073 }
4074
Geoff Lang4f0e0032017-05-01 16:04:35 -04004075 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004076 if (source == nullptr)
4077 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004078 context->validationError(GL_INVALID_VALUE, kInvalidSourceTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07004079 return false;
4080 }
4081
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004082 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004083 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004084 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureType);
Geoff Lang97073d12016-04-20 10:42:34 -07004085 return false;
4086 }
4087
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004088 TextureType sourceType = source->getType();
4089 ASSERT(sourceType != TextureType::CubeMap);
4090 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004091
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004092 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004093 {
Jamie Madille0472f32018-11-27 16:32:45 -05004094 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004095 return false;
4096 }
4097
4098 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4099 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004100 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004101 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureLevel);
Geoff Lang97073d12016-04-20 10:42:34 -07004102 return false;
4103 }
4104
4105 if (x < 0 || y < 0)
4106 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004107 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004108 return false;
4109 }
4110
4111 if (width < 0 || height < 0)
4112 {
Jamie Madille0472f32018-11-27 16:32:45 -05004113 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004114 return false;
4115 }
4116
Geoff Lang4f0e0032017-05-01 16:04:35 -04004117 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4118 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004119 {
Jamie Madille0472f32018-11-27 16:32:45 -05004120 context->validationError(GL_INVALID_VALUE, kSourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004121 return false;
4122 }
4123
Geoff Lang4f0e0032017-05-01 16:04:35 -04004124 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4125 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004126 {
Jamie Madille0472f32018-11-27 16:32:45 -05004127 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004128 return false;
4129 }
4130
Geoff Lang63458a32017-10-30 15:16:53 -04004131 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4132 {
Jamie Madille0472f32018-11-27 16:32:45 -05004133 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Lang63458a32017-10-30 15:16:53 -04004134 return false;
4135 }
4136
Geoff Lang4f0e0032017-05-01 16:04:35 -04004137 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004138 if (dest == nullptr)
4139 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004140 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07004141 return false;
4142 }
4143
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004144 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004145 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004146 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTextureType);
Geoff Lang97073d12016-04-20 10:42:34 -07004147 return false;
4148 }
4149
Brandon Jones28783792018-03-05 09:37:32 -08004150 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4151 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004152 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004153 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Lang97073d12016-04-20 10:42:34 -07004154 return false;
4155 }
4156
Geoff Lang4f0e0032017-05-01 16:04:35 -04004157 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4158 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004159 context->validationError(GL_INVALID_OPERATION, kDestinationLevelNotDefined);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004160 return false;
4161 }
4162
4163 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4164 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004165 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004166 context->validationError(GL_INVALID_OPERATION, kInvalidFormatCombination);
Geoff Lang97073d12016-04-20 10:42:34 -07004167 return false;
4168 }
4169
4170 if (xoffset < 0 || yoffset < 0)
4171 {
Jamie Madille0472f32018-11-27 16:32:45 -05004172 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004173 return false;
4174 }
4175
Geoff Lang4f0e0032017-05-01 16:04:35 -04004176 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4177 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004178 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004179 context->validationError(GL_INVALID_VALUE, kOffsetOverflow);
Geoff Lang97073d12016-04-20 10:42:34 -07004180 return false;
4181 }
4182
4183 return true;
4184}
4185
Geoff Lang47110bf2016-04-20 11:13:22 -07004186bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4187{
4188 if (!context->getExtensions().copyCompressedTexture)
4189 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004190 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang47110bf2016-04-20 11:13:22 -07004191 return false;
4192 }
4193
4194 const gl::Texture *source = context->getTexture(sourceId);
4195 if (source == nullptr)
4196 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004197 context->validationError(GL_INVALID_VALUE, kInvalidSourceTexture);
Geoff Lang47110bf2016-04-20 11:13:22 -07004198 return false;
4199 }
4200
Corentin Wallez99d492c2018-02-27 15:17:10 -05004201 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004202 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004203 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureType);
Geoff Lang47110bf2016-04-20 11:13:22 -07004204 return false;
4205 }
4206
Corentin Wallez99d492c2018-02-27 15:17:10 -05004207 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4208 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004209 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004210 context->validationError(GL_INVALID_VALUE, kSourceTextureLevelZeroDefined);
Geoff Lang47110bf2016-04-20 11:13:22 -07004211 return false;
4212 }
4213
Corentin Wallez99d492c2018-02-27 15:17:10 -05004214 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004215 if (!sourceFormat.info->compressed)
4216 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004217 context->validationError(GL_INVALID_OPERATION, kSourceTextureMustBeCompressed);
Geoff Lang47110bf2016-04-20 11:13:22 -07004218 return false;
4219 }
4220
4221 const gl::Texture *dest = context->getTexture(destId);
4222 if (dest == nullptr)
4223 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004224 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTexture);
Geoff Lang47110bf2016-04-20 11:13:22 -07004225 return false;
4226 }
4227
Corentin Wallez99d492c2018-02-27 15:17:10 -05004228 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004229 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004230 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTextureType);
Geoff Lang47110bf2016-04-20 11:13:22 -07004231 return false;
4232 }
4233
4234 if (dest->getImmutableFormat())
4235 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004236 context->validationError(GL_INVALID_OPERATION, kDestinationImmutable);
Geoff Lang47110bf2016-04-20 11:13:22 -07004237 return false;
4238 }
4239
4240 return true;
4241}
4242
Jiawei Shao385b3e02018-03-21 09:43:28 +08004243bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004244{
4245 switch (type)
4246 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004247 case ShaderType::Vertex:
4248 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004249 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004250
Jiawei Shao385b3e02018-03-21 09:43:28 +08004251 case ShaderType::Compute:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004252 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004253 {
Jamie Madille0472f32018-11-27 16:32:45 -05004254 context->validationError(GL_INVALID_ENUM, kES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004255 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004256 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004257 break;
4258
Jiawei Shao385b3e02018-03-21 09:43:28 +08004259 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004260 if (!context->getExtensions().geometryShader)
4261 {
Jamie Madille0472f32018-11-27 16:32:45 -05004262 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
Jiawei Shao89be29a2017-11-06 14:36:45 +08004263 return false;
4264 }
4265 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004266 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004267 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004268 return false;
4269 }
Jamie Madill29639852016-09-02 15:00:09 -04004270
4271 return true;
4272}
4273
Jamie Madill5b772312018-03-08 20:28:32 -05004274bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004275 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004276 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004277 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004278 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004279{
4280 if (size < 0)
4281 {
Jamie Madille0472f32018-11-27 16:32:45 -05004282 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004283 return false;
4284 }
4285
4286 switch (usage)
4287 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004288 case BufferUsage::StreamDraw:
4289 case BufferUsage::StaticDraw:
4290 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004291 break;
4292
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004293 case BufferUsage::StreamRead:
4294 case BufferUsage::StaticRead:
4295 case BufferUsage::DynamicRead:
4296 case BufferUsage::StreamCopy:
4297 case BufferUsage::StaticCopy:
4298 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004299 if (context->getClientMajorVersion() < 3)
4300 {
Jamie Madille0472f32018-11-27 16:32:45 -05004301 context->validationError(GL_INVALID_ENUM, kInvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004302 return false;
4303 }
4304 break;
4305
4306 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004307 context->validationError(GL_INVALID_ENUM, kInvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004308 return false;
4309 }
4310
Corentin Walleze4477002017-12-01 14:39:58 -05004311 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004312 {
Jamie Madille0472f32018-11-27 16:32:45 -05004313 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004314 return false;
4315 }
4316
4317 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4318
4319 if (!buffer)
4320 {
Jamie Madille0472f32018-11-27 16:32:45 -05004321 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004322 return false;
4323 }
4324
James Darpiniane8a93c62018-01-04 18:02:24 -08004325 if (context->getExtensions().webglCompatibility &&
4326 buffer->isBoundForTransformFeedbackAndOtherUse())
4327 {
Jamie Madille0472f32018-11-27 16:32:45 -05004328 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08004329 return false;
4330 }
4331
Jamie Madill29639852016-09-02 15:00:09 -04004332 return true;
4333}
4334
Jamie Madill5b772312018-03-08 20:28:32 -05004335bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004336 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004337 GLintptr offset,
4338 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004339 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004340{
Brandon Jones6cad5662017-06-14 13:25:13 -07004341 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004342 {
Jamie Madille0472f32018-11-27 16:32:45 -05004343 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Brandon Jones6cad5662017-06-14 13:25:13 -07004344 return false;
4345 }
4346
4347 if (offset < 0)
4348 {
Jamie Madille0472f32018-11-27 16:32:45 -05004349 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004350 return false;
4351 }
4352
Corentin Walleze4477002017-12-01 14:39:58 -05004353 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004354 {
Jamie Madille0472f32018-11-27 16:32:45 -05004355 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004356 return false;
4357 }
4358
4359 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4360
4361 if (!buffer)
4362 {
Jamie Madille0472f32018-11-27 16:32:45 -05004363 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004364 return false;
4365 }
4366
4367 if (buffer->isMapped())
4368 {
Jamie Madille0472f32018-11-27 16:32:45 -05004369 context->validationError(GL_INVALID_OPERATION, kBufferMapped);
Jamie Madill29639852016-09-02 15:00:09 -04004370 return false;
4371 }
4372
James Darpiniane8a93c62018-01-04 18:02:24 -08004373 if (context->getExtensions().webglCompatibility &&
4374 buffer->isBoundForTransformFeedbackAndOtherUse())
4375 {
Jamie Madille0472f32018-11-27 16:32:45 -05004376 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08004377 return false;
4378 }
4379
Jamie Madill29639852016-09-02 15:00:09 -04004380 // Check for possible overflow of size + offset
4381 angle::CheckedNumeric<size_t> checkedSize(size);
4382 checkedSize += offset;
4383 if (!checkedSize.IsValid())
4384 {
Jamie Madille0472f32018-11-27 16:32:45 -05004385 context->validationError(GL_INVALID_VALUE, kParamOverflow);
Jamie Madill29639852016-09-02 15:00:09 -04004386 return false;
4387 }
4388
4389 if (size + offset > buffer->getSize())
4390 {
Jamie Madille0472f32018-11-27 16:32:45 -05004391 context->validationError(GL_INVALID_VALUE, kInsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004392 return false;
4393 }
4394
Martin Radev4c4c8e72016-08-04 12:25:34 +03004395 return true;
4396}
4397
Geoff Lang111a99e2017-10-17 10:58:41 -04004398bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004399{
Geoff Langc339c4e2016-11-29 10:37:36 -05004400 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004401 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004402 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langc287ea62016-09-16 14:46:51 -04004403 return false;
4404 }
4405
Geoff Lang111a99e2017-10-17 10:58:41 -04004406 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004407 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004408 context->validationError(GL_INVALID_OPERATION, kExtensionNotRequestable);
Geoff Langc287ea62016-09-16 14:46:51 -04004409 return false;
4410 }
4411
4412 return true;
4413}
4414
Jamie Madill5b772312018-03-08 20:28:32 -05004415bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004416{
Lingfeng Yang038dd532018-03-29 17:31:52 -07004417 if (context->getClientMajorVersion() < 2)
4418 {
4419 return ValidateMultitextureUnit(context, texture);
4420 }
4421
Jamie Madillef300b12016-10-07 15:12:09 -04004422 if (texture < GL_TEXTURE0 ||
4423 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4424 {
Jamie Madille0472f32018-11-27 16:32:45 -05004425 context->validationError(GL_INVALID_ENUM, kInvalidCombinedImageUnit);
Jamie Madillef300b12016-10-07 15:12:09 -04004426 return false;
4427 }
4428
4429 return true;
4430}
4431
Jamie Madill5b772312018-03-08 20:28:32 -05004432bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004433{
4434 Program *programObject = GetValidProgram(context, program);
4435 if (!programObject)
4436 {
4437 return false;
4438 }
4439
4440 Shader *shaderObject = GetValidShader(context, shader);
4441 if (!shaderObject)
4442 {
4443 return false;
4444 }
4445
Jiawei Shao385b3e02018-03-21 09:43:28 +08004446 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04004447 {
Jamie Madille0472f32018-11-27 16:32:45 -05004448 context->validationError(GL_INVALID_OPERATION, kShaderAttachmentHasShader);
Jiawei Shao385b3e02018-03-21 09:43:28 +08004449 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04004450 }
4451
4452 return true;
4453}
4454
Jamie Madill5b772312018-03-08 20:28:32 -05004455bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004456{
4457 if (index >= MAX_VERTEX_ATTRIBS)
4458 {
Jamie Madille0472f32018-11-27 16:32:45 -05004459 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004460 return false;
4461 }
4462
4463 if (strncmp(name, "gl_", 3) == 0)
4464 {
Jamie Madille0472f32018-11-27 16:32:45 -05004465 context->validationError(GL_INVALID_OPERATION, kNameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004466 return false;
4467 }
4468
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004469 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004470 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004471 const size_t length = strlen(name);
4472
4473 if (!IsValidESSLString(name, length))
4474 {
4475 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4476 // for shader-related entry points
Jamie Madille0472f32018-11-27 16:32:45 -05004477 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004478 return false;
4479 }
4480
4481 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4482 {
4483 return false;
4484 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004485 }
4486
Jamie Madill01a80ee2016-11-07 12:06:18 -05004487 return GetValidProgram(context, program) != nullptr;
4488}
4489
Jamie Madill5b772312018-03-08 20:28:32 -05004490bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004491{
Geoff Lange8afa902017-09-27 15:00:43 -04004492 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004493 {
Jamie Madille0472f32018-11-27 16:32:45 -05004494 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004495 return false;
4496 }
4497
4498 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4499 !context->isFramebufferGenerated(framebuffer))
4500 {
Jamie Madille0472f32018-11-27 16:32:45 -05004501 context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004502 return false;
4503 }
4504
4505 return true;
4506}
4507
Jamie Madill5b772312018-03-08 20:28:32 -05004508bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004509{
4510 if (target != GL_RENDERBUFFER)
4511 {
Jamie Madille0472f32018-11-27 16:32:45 -05004512 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004513 return false;
4514 }
4515
4516 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4517 !context->isRenderbufferGenerated(renderbuffer))
4518 {
Jamie Madille0472f32018-11-27 16:32:45 -05004519 context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004520 return false;
4521 }
4522
4523 return true;
4524}
4525
Jamie Madill5b772312018-03-08 20:28:32 -05004526static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004527{
4528 switch (mode)
4529 {
4530 case GL_FUNC_ADD:
4531 case GL_FUNC_SUBTRACT:
4532 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004533 return true;
4534
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004535 case GL_MIN:
4536 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004537 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004538
4539 default:
4540 return false;
4541 }
4542}
4543
Jamie Madill5b772312018-03-08 20:28:32 -05004544bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004545{
4546 return true;
4547}
4548
Jamie Madill5b772312018-03-08 20:28:32 -05004549bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004550{
Geoff Lang50cac572017-09-26 17:37:43 -04004551 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004552 {
Jamie Madille0472f32018-11-27 16:32:45 -05004553 context->validationError(GL_INVALID_ENUM, kInvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004554 return false;
4555 }
4556
4557 return true;
4558}
4559
Jamie Madill5b772312018-03-08 20:28:32 -05004560bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004561{
Geoff Lang50cac572017-09-26 17:37:43 -04004562 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004563 {
Jamie Madille0472f32018-11-27 16:32:45 -05004564 context->validationError(GL_INVALID_ENUM, kInvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004565 return false;
4566 }
4567
Geoff Lang50cac572017-09-26 17:37:43 -04004568 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004569 {
Jamie Madille0472f32018-11-27 16:32:45 -05004570 context->validationError(GL_INVALID_ENUM, kInvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004571 return false;
4572 }
4573
4574 return true;
4575}
4576
Jamie Madill5b772312018-03-08 20:28:32 -05004577bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004578{
4579 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4580}
4581
Jamie Madill5b772312018-03-08 20:28:32 -05004582bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004583 GLenum srcRGB,
4584 GLenum dstRGB,
4585 GLenum srcAlpha,
4586 GLenum dstAlpha)
4587{
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004588 if (!ValidSrcBlendFunc(context, srcRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004589 {
Jamie Madille0472f32018-11-27 16:32:45 -05004590 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004591 return false;
4592 }
4593
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004594 if (!ValidDstBlendFunc(context, dstRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004595 {
Jamie Madille0472f32018-11-27 16:32:45 -05004596 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004597 return false;
4598 }
4599
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004600 if (!ValidSrcBlendFunc(context, srcAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004601 {
Jamie Madille0472f32018-11-27 16:32:45 -05004602 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004603 return false;
4604 }
4605
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004606 if (!ValidDstBlendFunc(context, dstAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004607 {
Jamie Madille0472f32018-11-27 16:32:45 -05004608 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004609 return false;
4610 }
4611
Frank Henigman146e8a12017-03-02 23:22:37 -05004612 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4613 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004614 {
4615 bool constantColorUsed =
4616 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4617 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4618
4619 bool constantAlphaUsed =
4620 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4621 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4622
4623 if (constantColorUsed && constantAlphaUsed)
4624 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004625 if (context->getExtensions().webglCompatibility)
4626 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004627 context->validationError(GL_INVALID_OPERATION, kInvalidConstantColor);
4628 return false;
Frank Henigman146e8a12017-03-02 23:22:37 -05004629 }
Jamie Madillc3e37312018-11-30 15:25:39 -05004630
4631 WARN() << kConstantColorAlphaLimitation;
4632 context->validationError(GL_INVALID_OPERATION, kConstantColorAlphaLimitation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004633 return false;
4634 }
4635 }
4636
4637 return true;
4638}
4639
Geoff Langc339c4e2016-11-29 10:37:36 -05004640bool ValidateGetString(Context *context, GLenum name)
4641{
4642 switch (name)
4643 {
4644 case GL_VENDOR:
4645 case GL_RENDERER:
4646 case GL_VERSION:
4647 case GL_SHADING_LANGUAGE_VERSION:
4648 case GL_EXTENSIONS:
4649 break;
4650
4651 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4652 if (!context->getExtensions().requestExtension)
4653 {
Jamie Madille0472f32018-11-27 16:32:45 -05004654 context->validationError(GL_INVALID_ENUM, kInvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004655 return false;
4656 }
4657 break;
4658
4659 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004660 context->validationError(GL_INVALID_ENUM, kInvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004661 return false;
4662 }
4663
4664 return true;
4665}
4666
Jamie Madill5b772312018-03-08 20:28:32 -05004667bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004668{
4669 if (width <= 0.0f || isNaN(width))
4670 {
Jamie Madille0472f32018-11-27 16:32:45 -05004671 context->validationError(GL_INVALID_VALUE, kInvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004672 return false;
4673 }
4674
4675 return true;
4676}
4677
Jamie Madill5b772312018-03-08 20:28:32 -05004678bool ValidateVertexAttribPointer(Context *context,
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004679 GLuint index,
4680 GLint size,
4681 GLenum type,
4682 GLboolean normalized,
4683 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004684 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004685{
Shao80957d92017-02-20 21:25:59 +08004686 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004687 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004688 return false;
4689 }
4690
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004691 if (stride < 0)
4692 {
Jamie Madille0472f32018-11-27 16:32:45 -05004693 context->validationError(GL_INVALID_VALUE, kNegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004694 return false;
4695 }
4696
Shao80957d92017-02-20 21:25:59 +08004697 const Caps &caps = context->getCaps();
4698 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004699 {
Shao80957d92017-02-20 21:25:59 +08004700 if (stride > caps.maxVertexAttribStride)
4701 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004702 context->validationError(GL_INVALID_VALUE, kExceedsMaxVertexAttribStride);
Shao80957d92017-02-20 21:25:59 +08004703 return false;
4704 }
4705
4706 if (index >= caps.maxVertexAttribBindings)
4707 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004708 context->validationError(GL_INVALID_VALUE, kExceedsMaxVertexAttribBindings);
Shao80957d92017-02-20 21:25:59 +08004709 return false;
4710 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004711 }
4712
4713 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4714 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4715 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4716 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004717 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4718 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004719 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4720 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004721 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004722 context->validationError(GL_INVALID_OPERATION, kClientDataInVertexArray);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004723 return false;
4724 }
4725
4726 if (context->getExtensions().webglCompatibility)
4727 {
4728 // WebGL 1.0 [Section 6.14] Fixed point support
4729 // The WebGL API does not support the GL_FIXED data type.
4730 if (type == GL_FIXED)
4731 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004732 context->validationError(GL_INVALID_ENUM, kFixedNotInWebGL);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004733 return false;
4734 }
4735
Geoff Lang2d62ab72017-03-23 16:54:40 -04004736 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004737 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004738 return false;
4739 }
4740 }
4741
4742 return true;
4743}
4744
Jamie Madill5b772312018-03-08 20:28:32 -05004745bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004746{
4747 if (context->getExtensions().webglCompatibility && zNear > zFar)
4748 {
Jamie Madille0472f32018-11-27 16:32:45 -05004749 context->validationError(GL_INVALID_OPERATION, kInvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004750 return false;
4751 }
4752
4753 return true;
4754}
4755
Jamie Madill5b772312018-03-08 20:28:32 -05004756bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004757 GLenum target,
4758 GLenum internalformat,
4759 GLsizei width,
4760 GLsizei height)
4761{
4762 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4763 height);
4764}
4765
Jamie Madill5b772312018-03-08 20:28:32 -05004766bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004767 GLenum target,
4768 GLsizei samples,
4769 GLenum internalformat,
4770 GLsizei width,
4771 GLsizei height)
4772{
4773 if (!context->getExtensions().framebufferMultisample)
4774 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004775 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madille8fb6402017-02-14 17:56:40 -05004776 return false;
4777 }
4778
4779 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
Jamie Madill610640f2018-11-21 17:28:41 -05004780 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_VALUE is
Jamie Madille8fb6402017-02-14 17:56:40 -05004781 // generated.
4782 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4783 {
Jamie Madille0472f32018-11-27 16:32:45 -05004784 context->validationError(GL_INVALID_VALUE, kSamplesOutOfRange);
Jamie Madille8fb6402017-02-14 17:56:40 -05004785 return false;
4786 }
4787
4788 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4789 // the specified storage. This is different than ES 3.0 in which a sample number higher
4790 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4791 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4792 if (context->getClientMajorVersion() >= 3)
4793 {
4794 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4795 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4796 {
Jamie Madille0472f32018-11-27 16:32:45 -05004797 context->validationError(GL_OUT_OF_MEMORY, kSamplesOutOfRange);
Jamie Madille8fb6402017-02-14 17:56:40 -05004798 return false;
4799 }
4800 }
4801
4802 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4803 width, height);
4804}
4805
Jamie Madill5b772312018-03-08 20:28:32 -05004806bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004807{
Geoff Lange8afa902017-09-27 15:00:43 -04004808 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004809 {
Jamie Madille0472f32018-11-27 16:32:45 -05004810 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004811 return false;
4812 }
4813
4814 return true;
4815}
4816
Jamie Madill5b772312018-03-08 20:28:32 -05004817bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004818{
4819 return true;
4820}
4821
Jamie Madill5b772312018-03-08 20:28:32 -05004822bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004823{
4824 return true;
4825}
4826
Jamie Madill5b772312018-03-08 20:28:32 -05004827bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004828{
4829 return true;
4830}
4831
Jamie Madill5b772312018-03-08 20:28:32 -05004832bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004833 GLboolean red,
4834 GLboolean green,
4835 GLboolean blue,
4836 GLboolean alpha)
4837{
4838 return true;
4839}
4840
Jamie Madill5b772312018-03-08 20:28:32 -05004841bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004842{
4843 return true;
4844}
4845
Jamie Madill5b772312018-03-08 20:28:32 -05004846bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004847{
4848 return true;
4849}
4850
Jamie Madill5b772312018-03-08 20:28:32 -05004851bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004852{
4853 switch (mode)
4854 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004855 case CullFaceMode::Front:
4856 case CullFaceMode::Back:
4857 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004858 break;
4859
4860 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004861 context->validationError(GL_INVALID_ENUM, kInvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004862 return false;
4863 }
4864
4865 return true;
4866}
4867
Jamie Madill5b772312018-03-08 20:28:32 -05004868bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004869{
4870 if (program == 0)
4871 {
4872 return false;
4873 }
4874
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004875 if (!context->getProgramResolveLink(program))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004876 {
4877 if (context->getShader(program))
4878 {
Jamie Madille0472f32018-11-27 16:32:45 -05004879 context->validationError(GL_INVALID_OPERATION, kExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004880 return false;
4881 }
4882 else
4883 {
Jamie Madille0472f32018-11-27 16:32:45 -05004884 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004885 return false;
4886 }
4887 }
4888
4889 return true;
4890}
4891
Jamie Madill5b772312018-03-08 20:28:32 -05004892bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004893{
4894 if (shader == 0)
4895 {
4896 return false;
4897 }
4898
4899 if (!context->getShader(shader))
4900 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004901 if (context->getProgramResolveLink(shader))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004902 {
Jamie Madille0472f32018-11-27 16:32:45 -05004903 context->validationError(GL_INVALID_OPERATION, kInvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004904 return false;
4905 }
4906 else
4907 {
Jamie Madille0472f32018-11-27 16:32:45 -05004908 context->validationError(GL_INVALID_VALUE, kExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004909 return false;
4910 }
4911 }
4912
4913 return true;
4914}
4915
Jamie Madill5b772312018-03-08 20:28:32 -05004916bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004917{
4918 switch (func)
4919 {
4920 case GL_NEVER:
4921 case GL_ALWAYS:
4922 case GL_LESS:
4923 case GL_LEQUAL:
4924 case GL_EQUAL:
4925 case GL_GREATER:
4926 case GL_GEQUAL:
4927 case GL_NOTEQUAL:
4928 break;
4929
4930 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004931 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004932 return false;
4933 }
4934
4935 return true;
4936}
4937
Jamie Madill5b772312018-03-08 20:28:32 -05004938bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004939{
4940 return true;
4941}
4942
Jamie Madill5b772312018-03-08 20:28:32 -05004943bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004944{
4945 Program *programObject = GetValidProgram(context, program);
4946 if (!programObject)
4947 {
4948 return false;
4949 }
4950
4951 Shader *shaderObject = GetValidShader(context, shader);
4952 if (!shaderObject)
4953 {
4954 return false;
4955 }
4956
Jiawei Shao385b3e02018-03-21 09:43:28 +08004957 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04004958 if (attachedShader != shaderObject)
4959 {
Jamie Madille0472f32018-11-27 16:32:45 -05004960 context->validationError(GL_INVALID_OPERATION, kShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004961 return false;
4962 }
4963
4964 return true;
4965}
4966
Jamie Madill5b772312018-03-08 20:28:32 -05004967bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004968{
4969 if (index >= MAX_VERTEX_ATTRIBS)
4970 {
Jamie Madille0472f32018-11-27 16:32:45 -05004971 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004972 return false;
4973 }
4974
4975 return true;
4976}
4977
Jamie Madill5b772312018-03-08 20:28:32 -05004978bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004979{
4980 if (index >= MAX_VERTEX_ATTRIBS)
4981 {
Jamie Madille0472f32018-11-27 16:32:45 -05004982 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004983 return false;
4984 }
4985
4986 return true;
4987}
4988
Jamie Madill5b772312018-03-08 20:28:32 -05004989bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004990{
4991 return true;
4992}
4993
Jamie Madill5b772312018-03-08 20:28:32 -05004994bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004995{
4996 return true;
4997}
4998
Jamie Madill5b772312018-03-08 20:28:32 -05004999bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005000{
5001 switch (mode)
5002 {
5003 case GL_CW:
5004 case GL_CCW:
5005 break;
5006 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005007 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005008 return false;
5009 }
5010
5011 return true;
5012}
5013
Jamie Madill5b772312018-03-08 20:28:32 -05005014bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005015 GLuint program,
5016 GLuint index,
5017 GLsizei bufsize,
5018 GLsizei *length,
5019 GLint *size,
5020 GLenum *type,
5021 GLchar *name)
5022{
5023 if (bufsize < 0)
5024 {
Jamie Madille0472f32018-11-27 16:32:45 -05005025 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005026 return false;
5027 }
5028
5029 Program *programObject = GetValidProgram(context, program);
5030
5031 if (!programObject)
5032 {
5033 return false;
5034 }
5035
5036 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5037 {
Jamie Madille0472f32018-11-27 16:32:45 -05005038 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005039 return false;
5040 }
5041
5042 return true;
5043}
5044
Jamie Madill5b772312018-03-08 20:28:32 -05005045bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005046 GLuint program,
5047 GLuint index,
5048 GLsizei bufsize,
5049 GLsizei *length,
5050 GLint *size,
5051 GLenum *type,
5052 GLchar *name)
5053{
5054 if (bufsize < 0)
5055 {
Jamie Madille0472f32018-11-27 16:32:45 -05005056 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005057 return false;
5058 }
5059
5060 Program *programObject = GetValidProgram(context, program);
5061
5062 if (!programObject)
5063 {
5064 return false;
5065 }
5066
5067 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5068 {
Jamie Madille0472f32018-11-27 16:32:45 -05005069 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005070 return false;
5071 }
5072
5073 return true;
5074}
5075
Jamie Madill5b772312018-03-08 20:28:32 -05005076bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005077 GLuint program,
5078 GLsizei maxcount,
5079 GLsizei *count,
5080 GLuint *shaders)
5081{
5082 if (maxcount < 0)
5083 {
Jamie Madille0472f32018-11-27 16:32:45 -05005084 context->validationError(GL_INVALID_VALUE, kNegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005085 return false;
5086 }
5087
5088 Program *programObject = GetValidProgram(context, program);
5089
5090 if (!programObject)
5091 {
5092 return false;
5093 }
5094
5095 return true;
5096}
5097
Jamie Madill5b772312018-03-08 20:28:32 -05005098bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005099{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005100 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5101 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005102 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005103 {
Jamie Madille0472f32018-11-27 16:32:45 -05005104 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005105 return false;
5106 }
5107
Jamie Madillc1d770e2017-04-13 17:31:24 -04005108 Program *programObject = GetValidProgram(context, program);
5109
5110 if (!programObject)
5111 {
Jamie Madille0472f32018-11-27 16:32:45 -05005112 context->validationError(GL_INVALID_OPERATION, kProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005113 return false;
5114 }
5115
5116 if (!programObject->isLinked())
5117 {
Jamie Madille0472f32018-11-27 16:32:45 -05005118 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005119 return false;
5120 }
5121
5122 return true;
5123}
5124
Jamie Madill5b772312018-03-08 20:28:32 -05005125bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005126{
5127 GLenum nativeType;
5128 unsigned int numParams = 0;
5129 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5130}
5131
Jamie Madill5b772312018-03-08 20:28:32 -05005132bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005133{
5134 return true;
5135}
5136
Jamie Madill5b772312018-03-08 20:28:32 -05005137bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005138{
5139 GLenum nativeType;
5140 unsigned int numParams = 0;
5141 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5142}
5143
Jamie Madill5b772312018-03-08 20:28:32 -05005144bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005145{
5146 GLenum nativeType;
5147 unsigned int numParams = 0;
5148 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5149}
5150
Jamie Madill5b772312018-03-08 20:28:32 -05005151bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005152 GLuint program,
5153 GLsizei bufsize,
5154 GLsizei *length,
5155 GLchar *infolog)
5156{
5157 if (bufsize < 0)
5158 {
Jamie Madille0472f32018-11-27 16:32:45 -05005159 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005160 return false;
5161 }
5162
5163 Program *programObject = GetValidProgram(context, program);
5164 if (!programObject)
5165 {
5166 return false;
5167 }
5168
5169 return true;
5170}
5171
Jamie Madill5b772312018-03-08 20:28:32 -05005172bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005173 GLuint shader,
5174 GLsizei bufsize,
5175 GLsizei *length,
5176 GLchar *infolog)
5177{
5178 if (bufsize < 0)
5179 {
Jamie Madille0472f32018-11-27 16:32:45 -05005180 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005181 return false;
5182 }
5183
5184 Shader *shaderObject = GetValidShader(context, shader);
5185 if (!shaderObject)
5186 {
5187 return false;
5188 }
5189
5190 return true;
5191}
5192
Jamie Madill5b772312018-03-08 20:28:32 -05005193bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005194 GLenum shadertype,
5195 GLenum precisiontype,
5196 GLint *range,
5197 GLint *precision)
5198{
5199 switch (shadertype)
5200 {
5201 case GL_VERTEX_SHADER:
5202 case GL_FRAGMENT_SHADER:
5203 break;
5204 case GL_COMPUTE_SHADER:
Jamie Madillc3e37312018-11-30 15:25:39 -05005205 context->validationError(GL_INVALID_OPERATION, kUnimplementedComputeShaderPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005206 return false;
5207 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005208 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005209 return false;
5210 }
5211
5212 switch (precisiontype)
5213 {
5214 case GL_LOW_FLOAT:
5215 case GL_MEDIUM_FLOAT:
5216 case GL_HIGH_FLOAT:
5217 case GL_LOW_INT:
5218 case GL_MEDIUM_INT:
5219 case GL_HIGH_INT:
5220 break;
5221
5222 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005223 context->validationError(GL_INVALID_ENUM, kInvalidPrecision);
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 ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005231 GLuint shader,
5232 GLsizei bufsize,
5233 GLsizei *length,
5234 GLchar *source)
5235{
5236 if (bufsize < 0)
5237 {
Jamie Madille0472f32018-11-27 16:32:45 -05005238 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005239 return false;
5240 }
5241
5242 Shader *shaderObject = GetValidShader(context, shader);
5243 if (!shaderObject)
5244 {
5245 return false;
5246 }
5247
5248 return true;
5249}
5250
Jamie Madill5b772312018-03-08 20:28:32 -05005251bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005252{
5253 if (strstr(name, "gl_") == name)
5254 {
5255 return false;
5256 }
5257
Geoff Langfc32e8b2017-05-31 14:16:59 -04005258 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5259 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005260 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005261 {
Jamie Madille0472f32018-11-27 16:32:45 -05005262 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005263 return false;
5264 }
5265
Jamie Madillc1d770e2017-04-13 17:31:24 -04005266 Program *programObject = GetValidProgram(context, program);
5267
5268 if (!programObject)
5269 {
5270 return false;
5271 }
5272
5273 if (!programObject->isLinked())
5274 {
Jamie Madille0472f32018-11-27 16:32:45 -05005275 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005276 return false;
5277 }
5278
5279 return true;
5280}
5281
Jamie Madill5b772312018-03-08 20:28:32 -05005282bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005283{
5284 switch (mode)
5285 {
5286 case GL_FASTEST:
5287 case GL_NICEST:
5288 case GL_DONT_CARE:
5289 break;
5290
5291 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005292 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005293 return false;
5294 }
5295
5296 switch (target)
5297 {
5298 case GL_GENERATE_MIPMAP_HINT:
5299 break;
5300
Geoff Lange7bd2182017-06-16 16:13:13 -04005301 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5302 if (context->getClientVersion() < ES_3_0 &&
5303 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005304 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005305 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005306 return false;
5307 }
5308 break;
5309
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07005310 case GL_PERSPECTIVE_CORRECTION_HINT:
5311 case GL_POINT_SMOOTH_HINT:
5312 case GL_LINE_SMOOTH_HINT:
5313 case GL_FOG_HINT:
5314 if (context->getClientMajorVersion() >= 2)
5315 {
Jamie Madille0472f32018-11-27 16:32:45 -05005316 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07005317 return false;
5318 }
5319 break;
5320
Jamie Madillc1d770e2017-04-13 17:31:24 -04005321 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005322 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005323 return false;
5324 }
5325
5326 return true;
5327}
5328
Jamie Madill5b772312018-03-08 20:28:32 -05005329bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005330{
5331 return true;
5332}
5333
Jamie Madill5b772312018-03-08 20:28:32 -05005334bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005335{
5336 return true;
5337}
5338
Jamie Madill5b772312018-03-08 20:28:32 -05005339bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005340{
5341 return true;
5342}
5343
Jamie Madill5b772312018-03-08 20:28:32 -05005344bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005345{
5346 return true;
5347}
5348
Jamie Madill5b772312018-03-08 20:28:32 -05005349bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005350{
5351 return true;
5352}
5353
Jamie Madill5b772312018-03-08 20:28:32 -05005354bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005355{
5356 return true;
5357}
5358
Jamie Madill5b772312018-03-08 20:28:32 -05005359bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005360{
5361 if (context->getClientMajorVersion() < 3)
5362 {
5363 switch (pname)
5364 {
5365 case GL_UNPACK_IMAGE_HEIGHT:
5366 case GL_UNPACK_SKIP_IMAGES:
Jamie Madille0472f32018-11-27 16:32:45 -05005367 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005368 return false;
5369
5370 case GL_UNPACK_ROW_LENGTH:
5371 case GL_UNPACK_SKIP_ROWS:
5372 case GL_UNPACK_SKIP_PIXELS:
5373 if (!context->getExtensions().unpackSubimage)
5374 {
Jamie Madille0472f32018-11-27 16:32:45 -05005375 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005376 return false;
5377 }
5378 break;
5379
5380 case GL_PACK_ROW_LENGTH:
5381 case GL_PACK_SKIP_ROWS:
5382 case GL_PACK_SKIP_PIXELS:
5383 if (!context->getExtensions().packSubimage)
5384 {
Jamie Madille0472f32018-11-27 16:32:45 -05005385 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005386 return false;
5387 }
5388 break;
5389 }
5390 }
5391
5392 if (param < 0)
5393 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005394 context->validationError(GL_INVALID_VALUE, kNegativeParam);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005395 return false;
5396 }
5397
5398 switch (pname)
5399 {
5400 case GL_UNPACK_ALIGNMENT:
5401 if (param != 1 && param != 2 && param != 4 && param != 8)
5402 {
Jamie Madille0472f32018-11-27 16:32:45 -05005403 context->validationError(GL_INVALID_VALUE, kInvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005404 return false;
5405 }
5406 break;
5407
5408 case GL_PACK_ALIGNMENT:
5409 if (param != 1 && param != 2 && param != 4 && param != 8)
5410 {
Jamie Madille0472f32018-11-27 16:32:45 -05005411 context->validationError(GL_INVALID_VALUE, kInvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005412 return false;
5413 }
5414 break;
5415
5416 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005417 if (!context->getExtensions().packReverseRowOrder)
5418 {
Jamie Madille0472f32018-11-27 16:32:45 -05005419 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang000dab82017-09-27 14:27:07 -04005420 }
5421 break;
5422
Jamie Madillc1d770e2017-04-13 17:31:24 -04005423 case GL_UNPACK_ROW_LENGTH:
5424 case GL_UNPACK_IMAGE_HEIGHT:
5425 case GL_UNPACK_SKIP_IMAGES:
5426 case GL_UNPACK_SKIP_ROWS:
5427 case GL_UNPACK_SKIP_PIXELS:
5428 case GL_PACK_ROW_LENGTH:
5429 case GL_PACK_SKIP_ROWS:
5430 case GL_PACK_SKIP_PIXELS:
5431 break;
5432
5433 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005434 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005435 return false;
5436 }
5437
5438 return true;
5439}
5440
Jamie Madill5b772312018-03-08 20:28:32 -05005441bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005442{
5443 return true;
5444}
5445
Jamie Madill5b772312018-03-08 20:28:32 -05005446bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005447{
5448 return true;
5449}
5450
Jamie Madill5b772312018-03-08 20:28:32 -05005451bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005452{
5453 return true;
5454}
5455
Jamie Madill5b772312018-03-08 20:28:32 -05005456bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005457{
5458 if (width < 0 || height < 0)
5459 {
Jamie Madille0472f32018-11-27 16:32:45 -05005460 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005461 return false;
5462 }
5463
5464 return true;
5465}
5466
Jamie Madill5b772312018-03-08 20:28:32 -05005467bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005468 GLsizei n,
5469 const GLuint *shaders,
5470 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005471 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005472 GLsizei length)
5473{
5474 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5475 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5476 shaderBinaryFormats.end())
5477 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005478 context->validationError(GL_INVALID_ENUM, kInvalidShaderBinaryFormat);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005479 return false;
5480 }
5481
5482 return true;
5483}
5484
Jamie Madill5b772312018-03-08 20:28:32 -05005485bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005486 GLuint shader,
5487 GLsizei count,
5488 const GLchar *const *string,
5489 const GLint *length)
5490{
5491 if (count < 0)
5492 {
Jamie Madille0472f32018-11-27 16:32:45 -05005493 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005494 return false;
5495 }
5496
Geoff Langfc32e8b2017-05-31 14:16:59 -04005497 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5498 // shader-related entry points
5499 if (context->getExtensions().webglCompatibility)
5500 {
5501 for (GLsizei i = 0; i < count; i++)
5502 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005503 size_t len =
5504 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005505
5506 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005507 if (!IsValidESSLShaderSourceString(string[i], len,
5508 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005509 {
Jamie Madille0472f32018-11-27 16:32:45 -05005510 context->validationError(GL_INVALID_VALUE, kShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005511 return false;
5512 }
5513 }
5514 }
5515
Jamie Madillc1d770e2017-04-13 17:31:24 -04005516 Shader *shaderObject = GetValidShader(context, shader);
5517 if (!shaderObject)
5518 {
5519 return false;
5520 }
5521
5522 return true;
5523}
5524
Jamie Madill5b772312018-03-08 20:28:32 -05005525bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005526{
5527 if (!IsValidStencilFunc(func))
5528 {
Jamie Madille0472f32018-11-27 16:32:45 -05005529 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005530 return false;
5531 }
5532
5533 return true;
5534}
5535
Jamie Madill5b772312018-03-08 20:28:32 -05005536bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005537{
5538 if (!IsValidStencilFace(face))
5539 {
Jamie Madille0472f32018-11-27 16:32:45 -05005540 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005541 return false;
5542 }
5543
5544 if (!IsValidStencilFunc(func))
5545 {
Jamie Madille0472f32018-11-27 16:32:45 -05005546 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005547 return false;
5548 }
5549
5550 return true;
5551}
5552
Jamie Madill5b772312018-03-08 20:28:32 -05005553bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005554{
5555 return true;
5556}
5557
Jamie Madill5b772312018-03-08 20:28:32 -05005558bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005559{
5560 if (!IsValidStencilFace(face))
5561 {
Jamie Madille0472f32018-11-27 16:32:45 -05005562 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005563 return false;
5564 }
5565
5566 return true;
5567}
5568
Jamie Madill5b772312018-03-08 20:28:32 -05005569bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005570{
5571 if (!IsValidStencilOp(fail))
5572 {
Jamie Madille0472f32018-11-27 16:32:45 -05005573 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005574 return false;
5575 }
5576
5577 if (!IsValidStencilOp(zfail))
5578 {
Jamie Madille0472f32018-11-27 16:32:45 -05005579 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005580 return false;
5581 }
5582
5583 if (!IsValidStencilOp(zpass))
5584 {
Jamie Madille0472f32018-11-27 16:32:45 -05005585 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005586 return false;
5587 }
5588
5589 return true;
5590}
5591
Jamie Madill5b772312018-03-08 20:28:32 -05005592bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005593 GLenum face,
5594 GLenum fail,
5595 GLenum zfail,
5596 GLenum zpass)
5597{
5598 if (!IsValidStencilFace(face))
5599 {
Jamie Madille0472f32018-11-27 16:32:45 -05005600 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005601 return false;
5602 }
5603
5604 return ValidateStencilOp(context, fail, zfail, zpass);
5605}
5606
Jamie Madill5b772312018-03-08 20:28:32 -05005607bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005608{
5609 return ValidateUniform(context, GL_FLOAT, location, 1);
5610}
5611
Jamie Madill5b772312018-03-08 20:28:32 -05005612bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005613{
5614 return ValidateUniform(context, GL_FLOAT, location, count);
5615}
5616
Jamie Madill5b772312018-03-08 20:28:32 -05005617bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005618{
5619 return ValidateUniform1iv(context, location, 1, &x);
5620}
5621
Jamie Madill5b772312018-03-08 20:28:32 -05005622bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005623{
5624 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5625}
5626
Jamie Madill5b772312018-03-08 20:28:32 -05005627bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005628{
5629 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5630}
5631
Jamie Madill5b772312018-03-08 20:28:32 -05005632bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005633{
5634 return ValidateUniform(context, GL_INT_VEC2, location, count);
5635}
5636
Jamie Madill5b772312018-03-08 20:28:32 -05005637bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005638{
5639 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5640}
5641
Jamie Madill5b772312018-03-08 20:28:32 -05005642bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005643{
5644 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5645}
5646
Jamie Madill5b772312018-03-08 20:28:32 -05005647bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005648{
5649 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5650}
5651
Jamie Madill5b772312018-03-08 20:28:32 -05005652bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005653{
5654 return ValidateUniform(context, GL_INT_VEC3, location, count);
5655}
5656
Jamie Madill5b772312018-03-08 20:28:32 -05005657bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005658{
5659 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5660}
5661
Jamie Madill5b772312018-03-08 20:28:32 -05005662bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005663{
5664 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5665}
5666
Jamie Madill5b772312018-03-08 20:28:32 -05005667bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005668{
5669 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5670}
5671
Jamie Madill5b772312018-03-08 20:28:32 -05005672bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005673{
5674 return ValidateUniform(context, GL_INT_VEC4, location, count);
5675}
5676
Jamie Madill5b772312018-03-08 20:28:32 -05005677bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005678 GLint location,
5679 GLsizei count,
5680 GLboolean transpose,
5681 const GLfloat *value)
5682{
5683 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5684}
5685
Jamie Madill5b772312018-03-08 20:28:32 -05005686bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005687 GLint location,
5688 GLsizei count,
5689 GLboolean transpose,
5690 const GLfloat *value)
5691{
5692 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5693}
5694
Jamie Madill5b772312018-03-08 20:28:32 -05005695bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005696 GLint location,
5697 GLsizei count,
5698 GLboolean transpose,
5699 const GLfloat *value)
5700{
5701 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5702}
5703
Jamie Madill5b772312018-03-08 20:28:32 -05005704bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005705{
5706 Program *programObject = GetValidProgram(context, program);
5707
5708 if (!programObject)
5709 {
5710 return false;
5711 }
5712
5713 return true;
5714}
5715
Jamie Madill5b772312018-03-08 20:28:32 -05005716bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005717{
5718 return ValidateVertexAttribIndex(context, index);
5719}
5720
Jamie Madill5b772312018-03-08 20:28:32 -05005721bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005722{
5723 return ValidateVertexAttribIndex(context, index);
5724}
5725
Jamie Madill5b772312018-03-08 20:28:32 -05005726bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005727{
5728 return ValidateVertexAttribIndex(context, index);
5729}
5730
Jamie Madill5b772312018-03-08 20:28:32 -05005731bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005732{
5733 return ValidateVertexAttribIndex(context, index);
5734}
5735
Jamie Madill5b772312018-03-08 20:28:32 -05005736bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005737{
5738 return ValidateVertexAttribIndex(context, index);
5739}
5740
Jamie Madill5b772312018-03-08 20:28:32 -05005741bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005742{
5743 return ValidateVertexAttribIndex(context, index);
5744}
5745
Jamie Madill5b772312018-03-08 20:28:32 -05005746bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005747 GLuint index,
5748 GLfloat x,
5749 GLfloat y,
5750 GLfloat z,
5751 GLfloat w)
5752{
5753 return ValidateVertexAttribIndex(context, index);
5754}
5755
Jamie Madill5b772312018-03-08 20:28:32 -05005756bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005757{
5758 return ValidateVertexAttribIndex(context, index);
5759}
5760
Jamie Madill5b772312018-03-08 20:28:32 -05005761bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005762{
5763 if (width < 0 || height < 0)
5764 {
Jamie Madille0472f32018-11-27 16:32:45 -05005765 context->validationError(GL_INVALID_VALUE, kViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005766 return false;
5767 }
5768
5769 return true;
5770}
5771
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005772bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005773 GLenum target,
5774 GLenum attachment,
5775 GLenum pname,
5776 GLint *params)
5777{
5778 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5779 nullptr);
5780}
5781
Jamie Madill5b772312018-03-08 20:28:32 -05005782bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04005783{
5784 return ValidateGetProgramivBase(context, program, pname, nullptr);
5785}
5786
Jamie Madill5b772312018-03-08 20:28:32 -05005787bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005788 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005789 GLint level,
5790 GLenum internalformat,
5791 GLint x,
5792 GLint y,
5793 GLsizei width,
5794 GLsizei height,
5795 GLint border)
5796{
5797 if (context->getClientMajorVersion() < 3)
5798 {
5799 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5800 0, x, y, width, height, border);
5801 }
5802
5803 ASSERT(context->getClientMajorVersion() == 3);
5804 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5805 0, x, y, width, height, border);
5806}
5807
5808bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005809 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005810 GLint level,
5811 GLint xoffset,
5812 GLint yoffset,
5813 GLint x,
5814 GLint y,
5815 GLsizei width,
5816 GLsizei height)
5817{
5818 if (context->getClientMajorVersion() < 3)
5819 {
5820 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5821 yoffset, x, y, width, height, 0);
5822 }
5823
5824 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5825 yoffset, 0, x, y, width, height, 0);
5826}
5827
5828bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5829{
5830 return ValidateGenOrDelete(context, n);
5831}
5832
5833bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5834{
5835 return ValidateGenOrDelete(context, n);
5836}
5837
5838bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5839{
5840 return ValidateGenOrDelete(context, n);
5841}
5842
5843bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5844{
5845 return ValidateGenOrDelete(context, n);
5846}
5847
5848bool ValidateDisable(Context *context, GLenum cap)
5849{
5850 if (!ValidCap(context, cap, false))
5851 {
Jamie Madille0472f32018-11-27 16:32:45 -05005852 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005853 return false;
5854 }
5855
5856 return true;
5857}
5858
5859bool ValidateEnable(Context *context, GLenum cap)
5860{
5861 if (!ValidCap(context, cap, false))
5862 {
Jamie Madille0472f32018-11-27 16:32:45 -05005863 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005864 return false;
5865 }
5866
5867 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5868 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5869 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005870 context->validationError(GL_INVALID_OPERATION, kNoSampleAlphaToCoveragesLimitation);
Jamie Madillbe849e42017-05-02 15:49:00 -04005871
5872 // We also output an error message to the debugger window if tracing is active, so that
5873 // developers can see the error message.
Jamie Madillc3e37312018-11-30 15:25:39 -05005874 ERR() << kNoSampleAlphaToCoveragesLimitation;
Jamie Madillbe849e42017-05-02 15:49:00 -04005875 return false;
5876 }
5877
5878 return true;
5879}
5880
5881bool ValidateFramebufferRenderbuffer(Context *context,
5882 GLenum target,
5883 GLenum attachment,
5884 GLenum renderbuffertarget,
5885 GLuint renderbuffer)
5886{
Geoff Lange8afa902017-09-27 15:00:43 -04005887 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005888 {
Jamie Madille0472f32018-11-27 16:32:45 -05005889 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Brandon Jones6cad5662017-06-14 13:25:13 -07005890 return false;
5891 }
5892
5893 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5894 {
Jamie Madille0472f32018-11-27 16:32:45 -05005895 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005896 return false;
5897 }
5898
5899 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5900 renderbuffertarget, renderbuffer);
5901}
5902
5903bool ValidateFramebufferTexture2D(Context *context,
5904 GLenum target,
5905 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005906 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04005907 GLuint texture,
5908 GLint level)
5909{
5910 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5911 // extension
5912 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5913 level != 0)
5914 {
Jamie Madille0472f32018-11-27 16:32:45 -05005915 context->validationError(GL_INVALID_VALUE, kInvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005916 return false;
5917 }
5918
5919 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5920 {
5921 return false;
5922 }
5923
5924 if (texture != 0)
5925 {
5926 gl::Texture *tex = context->getTexture(texture);
5927 ASSERT(tex);
5928
5929 const gl::Caps &caps = context->getCaps();
5930
5931 switch (textarget)
5932 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005933 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04005934 {
5935 if (level > gl::log2(caps.max2DTextureSize))
5936 {
Jamie Madille0472f32018-11-27 16:32:45 -05005937 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005938 return false;
5939 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005940 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04005941 {
Jamie Madille0472f32018-11-27 16:32:45 -05005942 context->validationError(GL_INVALID_OPERATION, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005943 return false;
5944 }
5945 }
5946 break;
5947
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005948 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005949 {
5950 if (level != 0)
5951 {
Jamie Madille0472f32018-11-27 16:32:45 -05005952 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005953 return false;
5954 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005955 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005956 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005957 context->validationError(GL_INVALID_OPERATION, kTextureTargetMismatch);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005958 return false;
5959 }
5960 }
5961 break;
5962
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005963 case TextureTarget::CubeMapNegativeX:
5964 case TextureTarget::CubeMapNegativeY:
5965 case TextureTarget::CubeMapNegativeZ:
5966 case TextureTarget::CubeMapPositiveX:
5967 case TextureTarget::CubeMapPositiveY:
5968 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04005969 {
5970 if (level > gl::log2(caps.maxCubeMapTextureSize))
5971 {
Jamie Madille0472f32018-11-27 16:32:45 -05005972 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005973 return false;
5974 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005975 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04005976 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005977 context->validationError(GL_INVALID_OPERATION, kTextureTargetMismatch);
Jamie Madillbe849e42017-05-02 15:49:00 -04005978 return false;
5979 }
5980 }
5981 break;
5982
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005983 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04005984 {
Yizhou Jiang7818a852018-09-06 15:02:04 +08005985 if (context->getClientVersion() < ES_3_1 &&
5986 !context->getExtensions().textureMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04005987 {
Jamie Madill610640f2018-11-21 17:28:41 -05005988 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05005989 kMultisampleTextureExtensionOrES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04005990 return false;
5991 }
5992
5993 if (level != 0)
5994 {
Jamie Madille0472f32018-11-27 16:32:45 -05005995 context->validationError(GL_INVALID_VALUE, kLevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04005996 return false;
5997 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005998 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04005999 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006000 context->validationError(GL_INVALID_OPERATION, kTextureTargetMismatch);
Jamie Madillbe849e42017-05-02 15:49:00 -04006001 return false;
6002 }
6003 }
6004 break;
6005
6006 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006007 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006008 return false;
6009 }
Jamie Madillbe849e42017-05-02 15:49:00 -04006010 }
6011
6012 return true;
6013}
6014
6015bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6016{
6017 return ValidateGenOrDelete(context, n);
6018}
6019
6020bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6021{
6022 return ValidateGenOrDelete(context, n);
6023}
6024
6025bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6026{
6027 return ValidateGenOrDelete(context, n);
6028}
6029
6030bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6031{
6032 return ValidateGenOrDelete(context, n);
6033}
6034
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006035bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006036{
6037 if (!ValidTextureTarget(context, target))
6038 {
Jamie Madille0472f32018-11-27 16:32:45 -05006039 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006040 return false;
6041 }
6042
6043 Texture *texture = context->getTargetTexture(target);
6044
6045 if (texture == nullptr)
6046 {
Jamie Madille0472f32018-11-27 16:32:45 -05006047 context->validationError(GL_INVALID_OPERATION, kTextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006048 return false;
6049 }
6050
6051 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6052
6053 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6054 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6055 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6056 {
Jamie Madille0472f32018-11-27 16:32:45 -05006057 context->validationError(GL_INVALID_OPERATION, kBaseLevelOutOfRange);
Jamie Madillbe849e42017-05-02 15:49:00 -04006058 return false;
6059 }
6060
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006061 TextureTarget baseTarget = (target == TextureType::CubeMap)
6062 ? TextureTarget::CubeMapPositiveX
6063 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006064 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6065 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6066 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006067 {
Jamie Madille0472f32018-11-27 16:32:45 -05006068 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Brandon Jones6cad5662017-06-14 13:25:13 -07006069 return false;
6070 }
6071
Geoff Lang536eca12017-09-13 11:23:35 -04006072 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6073 bool formatUnsized = !format.sized;
6074 bool formatColorRenderableAndFilterable =
6075 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
Yuly Novikovf15f8862018-06-04 18:59:41 -04006076 format.textureAttachmentSupport(context->getClientVersion(), context->getExtensions());
Geoff Lang536eca12017-09-13 11:23:35 -04006077 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006078 {
Jamie Madille0472f32018-11-27 16:32:45 -05006079 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006080 return false;
6081 }
6082
Geoff Lang536eca12017-09-13 11:23:35 -04006083 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6084 // generation
6085 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6086 {
Jamie Madille0472f32018-11-27 16:32:45 -05006087 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Geoff Lang536eca12017-09-13 11:23:35 -04006088 return false;
6089 }
6090
Jiange2c00842018-07-13 16:50:49 +08006091 // According to the OpenGL extension spec EXT_sRGB.txt, EXT_SRGB is based on ES 2.0 and
6092 // generateMipmap is not allowed if texture format is SRGB_EXT or SRGB_ALPHA_EXT.
6093 if (context->getClientVersion() < Version(3, 0) && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006094 {
Jamie Madille0472f32018-11-27 16:32:45 -05006095 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006096 return false;
6097 }
6098
6099 // Non-power of 2 ES2 check
6100 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6101 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6102 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6103 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006104 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6105 target == TextureType::CubeMap);
Jamie Madille0472f32018-11-27 16:32:45 -05006106 context->validationError(GL_INVALID_OPERATION, kTextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006107 return false;
6108 }
6109
6110 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006111 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006112 {
Jamie Madille0472f32018-11-27 16:32:45 -05006113 context->validationError(GL_INVALID_OPERATION, kCubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006114 return false;
6115 }
6116
James Darpinian83b2f0e2018-11-27 15:56:01 -08006117 if (context->getExtensions().webglCompatibility &&
6118 (texture->getWidth(baseTarget, effectiveBaseLevel) == 0 ||
6119 texture->getHeight(baseTarget, effectiveBaseLevel) == 0))
6120 {
6121 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapZeroSize);
6122 return false;
6123 }
6124
Jamie Madillbe849e42017-05-02 15:49:00 -04006125 return true;
6126}
6127
Jamie Madill5b772312018-03-08 20:28:32 -05006128bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006129 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006130 GLenum pname,
6131 GLint *params)
6132{
6133 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6134}
6135
6136bool ValidateGetRenderbufferParameteriv(Context *context,
6137 GLenum target,
6138 GLenum pname,
6139 GLint *params)
6140{
6141 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6142}
6143
6144bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6145{
6146 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6147}
6148
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006149bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006150{
6151 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6152}
6153
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006154bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006155{
6156 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6157}
6158
Till Rathmannb8543632018-10-02 19:46:14 +02006159bool ValidateGetTexParameterIivOES(Context *context,
6160 TextureType target,
6161 GLenum pname,
6162 GLint *params)
6163{
6164 if (context->getClientMajorVersion() < 3)
6165 {
Jamie Madille0472f32018-11-27 16:32:45 -05006166 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006167 return false;
6168 }
6169 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6170}
6171
6172bool ValidateGetTexParameterIuivOES(Context *context,
6173 TextureType target,
6174 GLenum pname,
6175 GLuint *params)
6176{
6177 if (context->getClientMajorVersion() < 3)
6178 {
Jamie Madille0472f32018-11-27 16:32:45 -05006179 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006180 return false;
6181 }
6182 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6183}
6184
Jamie Madillbe849e42017-05-02 15:49:00 -04006185bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6186{
6187 return ValidateGetUniformBase(context, program, location);
6188}
6189
6190bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6191{
6192 return ValidateGetUniformBase(context, program, location);
6193}
6194
6195bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6196{
6197 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6198}
6199
6200bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6201{
6202 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6203}
6204
6205bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6206{
6207 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6208}
6209
6210bool ValidateIsEnabled(Context *context, GLenum cap)
6211{
6212 if (!ValidCap(context, cap, true))
6213 {
Jamie Madille0472f32018-11-27 16:32:45 -05006214 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006215 return false;
6216 }
6217
6218 return true;
6219}
6220
6221bool ValidateLinkProgram(Context *context, GLuint program)
6222{
6223 if (context->hasActiveTransformFeedback(program))
6224 {
6225 // ES 3.0.4 section 2.15 page 91
Jamie Madillc3e37312018-11-30 15:25:39 -05006226 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackActiveDuringLink);
Jamie Madillbe849e42017-05-02 15:49:00 -04006227 return false;
6228 }
6229
6230 Program *programObject = GetValidProgram(context, program);
6231 if (!programObject)
6232 {
6233 return false;
6234 }
6235
6236 return true;
6237}
6238
Jamie Madill4928b7c2017-06-20 12:57:39 -04006239bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006240 GLint x,
6241 GLint y,
6242 GLsizei width,
6243 GLsizei height,
6244 GLenum format,
6245 GLenum type,
6246 void *pixels)
6247{
6248 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6249 nullptr, pixels);
6250}
6251
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006252bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006253{
Till Rathmannb8543632018-10-02 19:46:14 +02006254 return ValidateTexParameterBase(context, target, pname, -1, false, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006255}
6256
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006257bool ValidateTexParameterfv(Context *context,
6258 TextureType target,
6259 GLenum pname,
6260 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006261{
Till Rathmannb8543632018-10-02 19:46:14 +02006262 return ValidateTexParameterBase(context, target, pname, -1, true, params);
Jamie Madillbe849e42017-05-02 15:49:00 -04006263}
6264
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006265bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006266{
Till Rathmannb8543632018-10-02 19:46:14 +02006267 return ValidateTexParameterBase(context, target, pname, -1, false, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006268}
6269
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006270bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006271{
Till Rathmannb8543632018-10-02 19:46:14 +02006272 return ValidateTexParameterBase(context, target, pname, -1, true, params);
6273}
6274
6275bool ValidateTexParameterIivOES(Context *context,
6276 TextureType target,
6277 GLenum pname,
6278 const GLint *params)
6279{
6280 if (context->getClientMajorVersion() < 3)
6281 {
Jamie Madille0472f32018-11-27 16:32:45 -05006282 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006283 return false;
6284 }
6285 return ValidateTexParameterBase(context, target, pname, -1, true, params);
6286}
6287
6288bool ValidateTexParameterIuivOES(Context *context,
6289 TextureType target,
6290 GLenum pname,
6291 const GLuint *params)
6292{
6293 if (context->getClientMajorVersion() < 3)
6294 {
Jamie Madille0472f32018-11-27 16:32:45 -05006295 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006296 return false;
6297 }
6298 return ValidateTexParameterBase(context, target, pname, -1, true, params);
Jamie Madillbe849e42017-05-02 15:49:00 -04006299}
6300
6301bool ValidateUseProgram(Context *context, GLuint program)
6302{
6303 if (program != 0)
6304 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04006305 Program *programObject = context->getProgramResolveLink(program);
Jamie Madillbe849e42017-05-02 15:49:00 -04006306 if (!programObject)
6307 {
6308 // ES 3.1.0 section 7.3 page 72
6309 if (context->getShader(program))
6310 {
Jamie Madille0472f32018-11-27 16:32:45 -05006311 context->validationError(GL_INVALID_OPERATION, kExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006312 return false;
6313 }
6314 else
6315 {
Jamie Madille0472f32018-11-27 16:32:45 -05006316 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006317 return false;
6318 }
6319 }
6320 if (!programObject->isLinked())
6321 {
Jamie Madille0472f32018-11-27 16:32:45 -05006322 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006323 return false;
6324 }
6325 }
6326 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6327 {
6328 // ES 3.0.4 section 2.15 page 91
Jamie Madillc3e37312018-11-30 15:25:39 -05006329 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackUseProgram);
Jamie Madillbe849e42017-05-02 15:49:00 -04006330 return false;
6331 }
6332
6333 return true;
6334}
6335
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006336bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6337{
6338 if (!context->getExtensions().fence)
6339 {
Jamie Madille0472f32018-11-27 16:32:45 -05006340 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006341 return false;
6342 }
6343
6344 if (n < 0)
6345 {
Jamie Madille0472f32018-11-27 16:32:45 -05006346 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006347 return false;
6348 }
6349
6350 return true;
6351}
6352
6353bool ValidateFinishFenceNV(Context *context, GLuint fence)
6354{
6355 if (!context->getExtensions().fence)
6356 {
Jamie Madille0472f32018-11-27 16:32:45 -05006357 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006358 return false;
6359 }
6360
6361 FenceNV *fenceObject = context->getFenceNV(fence);
6362
6363 if (fenceObject == nullptr)
6364 {
Jamie Madille0472f32018-11-27 16:32:45 -05006365 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006366 return false;
6367 }
6368
6369 if (!fenceObject->isSet())
6370 {
Jamie Madille0472f32018-11-27 16:32:45 -05006371 context->validationError(GL_INVALID_OPERATION, kInvalidFenceState);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006372 return false;
6373 }
6374
6375 return true;
6376}
6377
6378bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6379{
6380 if (!context->getExtensions().fence)
6381 {
Jamie Madille0472f32018-11-27 16:32:45 -05006382 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006383 return false;
6384 }
6385
6386 if (n < 0)
6387 {
Jamie Madille0472f32018-11-27 16:32:45 -05006388 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006389 return false;
6390 }
6391
6392 return true;
6393}
6394
6395bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6396{
6397 if (!context->getExtensions().fence)
6398 {
Jamie Madille0472f32018-11-27 16:32:45 -05006399 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006400 return false;
6401 }
6402
6403 FenceNV *fenceObject = context->getFenceNV(fence);
6404
6405 if (fenceObject == nullptr)
6406 {
Jamie Madille0472f32018-11-27 16:32:45 -05006407 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006408 return false;
6409 }
6410
6411 if (!fenceObject->isSet())
6412 {
Jamie Madille0472f32018-11-27 16:32:45 -05006413 context->validationError(GL_INVALID_OPERATION, kInvalidFenceState);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006414 return false;
6415 }
6416
6417 switch (pname)
6418 {
6419 case GL_FENCE_STATUS_NV:
6420 case GL_FENCE_CONDITION_NV:
6421 break;
6422
6423 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006424 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006425 return false;
6426 }
6427
6428 return true;
6429}
6430
6431bool ValidateGetGraphicsResetStatusEXT(Context *context)
6432{
6433 if (!context->getExtensions().robustness)
6434 {
Jamie Madille0472f32018-11-27 16:32:45 -05006435 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006436 return false;
6437 }
6438
6439 return true;
6440}
6441
6442bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6443 GLuint shader,
6444 GLsizei bufsize,
6445 GLsizei *length,
6446 GLchar *source)
6447{
6448 if (!context->getExtensions().translatedShaderSource)
6449 {
Jamie Madille0472f32018-11-27 16:32:45 -05006450 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006451 return false;
6452 }
6453
6454 if (bufsize < 0)
6455 {
Jamie Madille0472f32018-11-27 16:32:45 -05006456 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006457 return false;
6458 }
6459
6460 Shader *shaderObject = context->getShader(shader);
6461
6462 if (!shaderObject)
6463 {
Jamie Madille0472f32018-11-27 16:32:45 -05006464 context->validationError(GL_INVALID_OPERATION, kInvalidShaderName);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006465 return false;
6466 }
6467
6468 return true;
6469}
6470
6471bool ValidateIsFenceNV(Context *context, GLuint fence)
6472{
6473 if (!context->getExtensions().fence)
6474 {
Jamie Madille0472f32018-11-27 16:32:45 -05006475 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006476 return false;
6477 }
6478
6479 return true;
6480}
6481
Jamie Madill007530e2017-12-28 14:27:04 -05006482bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6483{
6484 if (!context->getExtensions().fence)
6485 {
Jamie Madille0472f32018-11-27 16:32:45 -05006486 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill007530e2017-12-28 14:27:04 -05006487 return false;
6488 }
6489
6490 if (condition != GL_ALL_COMPLETED_NV)
6491 {
Jamie Madille0472f32018-11-27 16:32:45 -05006492 context->validationError(GL_INVALID_ENUM, kInvalidFenceCondition);
Jamie Madill007530e2017-12-28 14:27:04 -05006493 return false;
6494 }
6495
6496 FenceNV *fenceObject = context->getFenceNV(fence);
6497
6498 if (fenceObject == nullptr)
6499 {
Jamie Madille0472f32018-11-27 16:32:45 -05006500 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill007530e2017-12-28 14:27:04 -05006501 return false;
6502 }
6503
6504 return true;
6505}
6506
6507bool ValidateTestFenceNV(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 Madill007530e2017-12-28 14:27:04 -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 Madill007530e2017-12-28 14:27:04 -05006520 return false;
6521 }
6522
6523 if (fenceObject->isSet() != GL_TRUE)
6524 {
Jamie Madille0472f32018-11-27 16:32:45 -05006525 context->validationError(GL_INVALID_OPERATION, kInvalidFenceState);
Jamie Madill007530e2017-12-28 14:27:04 -05006526 return false;
6527 }
6528
6529 return true;
6530}
6531
6532bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006533 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006534 GLsizei levels,
6535 GLenum internalformat,
6536 GLsizei width,
6537 GLsizei height)
6538{
6539 if (!context->getExtensions().textureStorage)
6540 {
Jamie Madille0472f32018-11-27 16:32:45 -05006541 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05006542 return false;
6543 }
6544
6545 if (context->getClientMajorVersion() < 3)
6546 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006547 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006548 height);
6549 }
6550
6551 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006552 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006553 1);
6554}
6555
6556bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6557{
6558 if (!context->getExtensions().instancedArrays)
6559 {
Jamie Madille0472f32018-11-27 16:32:45 -05006560 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05006561 return false;
6562 }
6563
6564 if (index >= MAX_VERTEX_ATTRIBS)
6565 {
Jamie Madille0472f32018-11-27 16:32:45 -05006566 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madill007530e2017-12-28 14:27:04 -05006567 return false;
6568 }
6569
6570 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6571 {
6572 if (index == 0 && divisor != 0)
6573 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006574 context->validationError(GL_INVALID_OPERATION, kAttributeZeroRequiresDivisorLimitation);
Jamie Madill007530e2017-12-28 14:27:04 -05006575
6576 // We also output an error message to the debugger window if tracing is active, so
6577 // that developers can see the error message.
Jamie Madillc3e37312018-11-30 15:25:39 -05006578 ERR() << kAttributeZeroRequiresDivisorLimitation;
Jamie Madill007530e2017-12-28 14:27:04 -05006579 return false;
6580 }
6581 }
6582
6583 return true;
6584}
6585
6586bool ValidateTexImage3DOES(Context *context,
6587 GLenum target,
6588 GLint level,
6589 GLenum internalformat,
6590 GLsizei width,
6591 GLsizei height,
6592 GLsizei depth,
6593 GLint border,
6594 GLenum format,
6595 GLenum type,
6596 const void *pixels)
6597{
6598 UNIMPLEMENTED(); // FIXME
6599 return false;
6600}
6601
6602bool ValidatePopGroupMarkerEXT(Context *context)
6603{
6604 if (!context->getExtensions().debugMarker)
6605 {
6606 // The debug marker calls should not set error state
6607 // However, it seems reasonable to set an error state if the extension is not enabled
Jamie Madille0472f32018-11-27 16:32:45 -05006608 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05006609 return false;
6610 }
6611
6612 return true;
6613}
6614
Jamie Madillfa920eb2018-01-04 11:45:50 -05006615bool ValidateTexStorage1DEXT(Context *context,
6616 GLenum target,
6617 GLsizei levels,
6618 GLenum internalformat,
6619 GLsizei width)
6620{
6621 UNIMPLEMENTED();
Jamie Madille0472f32018-11-27 16:32:45 -05006622 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05006623 return false;
6624}
6625
6626bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006627 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006628 GLsizei levels,
6629 GLenum internalformat,
6630 GLsizei width,
6631 GLsizei height,
6632 GLsizei depth)
6633{
6634 if (!context->getExtensions().textureStorage)
6635 {
Jamie Madille0472f32018-11-27 16:32:45 -05006636 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05006637 return false;
6638 }
6639
6640 if (context->getClientMajorVersion() < 3)
6641 {
Jamie Madille0472f32018-11-27 16:32:45 -05006642 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05006643 return false;
6644 }
6645
6646 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6647 depth);
6648}
6649
jchen1082af6202018-06-22 10:59:52 +08006650bool ValidateMaxShaderCompilerThreadsKHR(Context *context, GLuint count)
6651{
6652 if (!context->getExtensions().parallelShaderCompile)
6653 {
Jamie Madille0472f32018-11-27 16:32:45 -05006654 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
jchen1082af6202018-06-22 10:59:52 +08006655 return false;
6656 }
6657 return true;
6658}
6659
Austin Eng1bf18ce2018-10-19 15:34:02 -07006660bool ValidateMultiDrawArraysANGLE(Context *context,
6661 PrimitiveMode mode,
6662 const GLint *firsts,
6663 const GLsizei *counts,
6664 GLsizei drawcount)
6665{
6666 if (!context->getExtensions().multiDraw)
6667 {
Jamie Madille0472f32018-11-27 16:32:45 -05006668 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07006669 return false;
6670 }
6671 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
6672 {
6673 if (!ValidateDrawArrays(context, mode, firsts[drawID], counts[drawID]))
6674 {
6675 return false;
6676 }
6677 }
6678 return true;
6679}
6680
6681bool ValidateMultiDrawElementsANGLE(Context *context,
6682 PrimitiveMode mode,
6683 const GLsizei *counts,
Jamie Madill8dc27f92018-11-29 11:45:44 -05006684 DrawElementsType type,
Austin Eng3b7c9d02018-11-21 18:09:05 -08006685 const GLvoid *const *indices,
Austin Eng1bf18ce2018-10-19 15:34:02 -07006686 GLsizei drawcount)
6687{
6688 if (!context->getExtensions().multiDraw)
6689 {
Jamie Madille0472f32018-11-27 16:32:45 -05006690 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07006691 return false;
6692 }
6693 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
6694 {
Austin Eng3b7c9d02018-11-21 18:09:05 -08006695 if (!ValidateDrawElements(context, mode, counts[drawID], type, indices[drawID]))
Austin Eng1bf18ce2018-10-19 15:34:02 -07006696 {
6697 return false;
6698 }
6699 }
6700 return true;
6701}
6702
Jamie Madillc29968b2016-01-20 11:17:23 -05006703} // namespace gl