blob: 7db8afd351351081b0d47589cc9ed859d934e429 [file] [log] [blame]
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001//
Geoff Langcec35902014-04-16 10:52:36 -04002// Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
Geoff Lange8ebe7f2013-08-05 15:03:13 -04003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// validationES2.cpp: Validation functions for OpenGL ES 2.0 entry point parameters
8
Jamie Madill778bf092018-11-14 09:54:36 -05009#include "libANGLE/validationES2_autogen.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030010
11#include <cstdint>
12
Geoff Lange8ebe7f2013-08-05 15:03:13 -040013#include "common/mathutil.h"
Sami Väisänen46eaa942016-06-29 10:26:37 +030014#include "common/string_utils.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040015#include "common/utilities.h"
Jamie Madillef300b12016-10-07 15:12:09 -040016#include "libANGLE/Context.h"
Brandon Jones6cad5662017-06-14 13:25:13 -070017#include "libANGLE/ErrorStrings.h"
Jamie Madill2b7bbc22017-12-21 17:30:38 -050018#include "libANGLE/Fence.h"
Jamie Madillef300b12016-10-07 15:12:09 -040019#include "libANGLE/Framebuffer.h"
20#include "libANGLE/FramebufferAttachment.h"
21#include "libANGLE/Renderbuffer.h"
22#include "libANGLE/Shader.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040023#include "libANGLE/Texture.h"
Jamie Madillef300b12016-10-07 15:12:09 -040024#include "libANGLE/Uniform.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040025#include "libANGLE/VertexArray.h"
Jamie Madillef300b12016-10-07 15:12:09 -040026#include "libANGLE/formatutils.h"
27#include "libANGLE/validationES.h"
Jamie Madill778bf092018-11-14 09:54:36 -050028#include "libANGLE/validationES2.h"
29#include "libANGLE/validationES3_autogen.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040030
31namespace gl
32{
Jamie Madille0472f32018-11-27 16:32:45 -050033using namespace err;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040034
Jamie Madillc29968b2016-01-20 11:17:23 -050035namespace
36{
37
38bool IsPartialBlit(gl::Context *context,
39 const FramebufferAttachment *readBuffer,
40 const FramebufferAttachment *writeBuffer,
41 GLint srcX0,
42 GLint srcY0,
43 GLint srcX1,
44 GLint srcY1,
45 GLint dstX0,
46 GLint dstY0,
47 GLint dstX1,
48 GLint dstY1)
49{
50 const Extents &writeSize = writeBuffer->getSize();
51 const Extents &readSize = readBuffer->getSize();
52
53 if (srcX0 != 0 || srcY0 != 0 || dstX0 != 0 || dstY0 != 0 || dstX1 != writeSize.width ||
54 dstY1 != writeSize.height || srcX1 != readSize.width || srcY1 != readSize.height)
55 {
56 return true;
57 }
58
Jamie Madillc3dc5d42018-12-30 12:12:04 -050059 if (context->getState().isScissorTestEnabled())
Jamie Madillc29968b2016-01-20 11:17:23 -050060 {
Jamie Madillc3dc5d42018-12-30 12:12:04 -050061 const Rectangle &scissor = context->getState().getScissor();
Jamie Madillc29968b2016-01-20 11:17:23 -050062 return scissor.x > 0 || scissor.y > 0 || scissor.width < writeSize.width ||
63 scissor.height < writeSize.height;
64 }
65
66 return false;
67}
68
Sami Väisänend59ca052016-06-21 16:10:00 +030069template <typename T>
70bool ValidatePathInstances(gl::Context *context,
71 GLsizei numPaths,
72 const void *paths,
73 GLuint pathBase)
74{
75 const auto *array = static_cast<const T *>(paths);
76
77 for (GLsizei i = 0; i < numPaths; ++i)
78 {
79 const GLuint pathName = array[i] + pathBase;
Brandon Jones59770802018-04-02 13:18:42 -070080 if (context->isPathGenerated(pathName) && !context->isPath(pathName))
Sami Väisänend59ca052016-06-21 16:10:00 +030081 {
Jamie Madille0472f32018-11-27 16:32:45 -050082 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänend59ca052016-06-21 16:10:00 +030083 return false;
84 }
85 }
86 return true;
87}
88
89bool ValidateInstancedPathParameters(gl::Context *context,
90 GLsizei numPaths,
91 GLenum pathNameType,
92 const void *paths,
93 GLuint pathBase,
94 GLenum transformType,
95 const GLfloat *transformValues)
96{
97 if (!context->getExtensions().pathRendering)
98 {
Jamie Madillc3e37312018-11-30 15:25:39 -050099 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänend59ca052016-06-21 16:10:00 +0300100 return false;
101 }
102
103 if (paths == nullptr)
104 {
Jamie Madillc3e37312018-11-30 15:25:39 -0500105 context->validationError(GL_INVALID_VALUE, kInvalidPathNameArray);
Sami Väisänend59ca052016-06-21 16:10:00 +0300106 return false;
107 }
108
109 if (numPaths < 0)
110 {
Jamie Madillc3e37312018-11-30 15:25:39 -0500111 context->validationError(GL_INVALID_VALUE, kInvalidPathNumPaths);
Sami Väisänend59ca052016-06-21 16:10:00 +0300112 return false;
113 }
114
115 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(numPaths))
116 {
Jamie Madille0472f32018-11-27 16:32:45 -0500117 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300118 return false;
119 }
120
121 std::uint32_t pathNameTypeSize = 0;
122 std::uint32_t componentCount = 0;
123
124 switch (pathNameType)
125 {
126 case GL_UNSIGNED_BYTE:
127 pathNameTypeSize = sizeof(GLubyte);
128 if (!ValidatePathInstances<GLubyte>(context, numPaths, paths, pathBase))
129 return false;
130 break;
131
132 case GL_BYTE:
133 pathNameTypeSize = sizeof(GLbyte);
134 if (!ValidatePathInstances<GLbyte>(context, numPaths, paths, pathBase))
135 return false;
136 break;
137
138 case GL_UNSIGNED_SHORT:
139 pathNameTypeSize = sizeof(GLushort);
140 if (!ValidatePathInstances<GLushort>(context, numPaths, paths, pathBase))
141 return false;
142 break;
143
144 case GL_SHORT:
145 pathNameTypeSize = sizeof(GLshort);
146 if (!ValidatePathInstances<GLshort>(context, numPaths, paths, pathBase))
147 return false;
148 break;
149
150 case GL_UNSIGNED_INT:
151 pathNameTypeSize = sizeof(GLuint);
152 if (!ValidatePathInstances<GLuint>(context, numPaths, paths, pathBase))
153 return false;
154 break;
155
156 case GL_INT:
157 pathNameTypeSize = sizeof(GLint);
158 if (!ValidatePathInstances<GLint>(context, numPaths, paths, pathBase))
159 return false;
160 break;
161
162 default:
Jamie Madillc3e37312018-11-30 15:25:39 -0500163 context->validationError(GL_INVALID_ENUM, kInvalidPathNameType);
Sami Väisänend59ca052016-06-21 16:10:00 +0300164 return false;
165 }
166
167 switch (transformType)
168 {
169 case GL_NONE:
170 componentCount = 0;
171 break;
172 case GL_TRANSLATE_X_CHROMIUM:
173 case GL_TRANSLATE_Y_CHROMIUM:
174 componentCount = 1;
175 break;
176 case GL_TRANSLATE_2D_CHROMIUM:
177 componentCount = 2;
178 break;
179 case GL_TRANSLATE_3D_CHROMIUM:
180 componentCount = 3;
181 break;
182 case GL_AFFINE_2D_CHROMIUM:
183 case GL_TRANSPOSE_AFFINE_2D_CHROMIUM:
184 componentCount = 6;
185 break;
186 case GL_AFFINE_3D_CHROMIUM:
187 case GL_TRANSPOSE_AFFINE_3D_CHROMIUM:
188 componentCount = 12;
189 break;
190 default:
Jamie Madillc3e37312018-11-30 15:25:39 -0500191 context->validationError(GL_INVALID_ENUM, kInvalidTransformation);
Sami Väisänend59ca052016-06-21 16:10:00 +0300192 return false;
193 }
194 if (componentCount != 0 && transformValues == nullptr)
195 {
Jamie Madillc3e37312018-11-30 15:25:39 -0500196 context->validationError(GL_INVALID_VALUE, kNoTransformArray);
Sami Väisänend59ca052016-06-21 16:10:00 +0300197 return false;
198 }
199
200 angle::CheckedNumeric<std::uint32_t> checkedSize(0);
201 checkedSize += (numPaths * pathNameTypeSize);
202 checkedSize += (numPaths * sizeof(GLfloat) * componentCount);
203 if (!checkedSize.IsValid())
204 {
Jamie Madille0472f32018-11-27 16:32:45 -0500205 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300206 return false;
207 }
208
209 return true;
210}
211
Geoff Lang4f0e0032017-05-01 16:04:35 -0400212bool IsValidCopyTextureSourceInternalFormatEnum(GLenum internalFormat)
Geoff Lang97073d12016-04-20 10:42:34 -0700213{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400214 // Table 1.1 from the CHROMIUM_copy_texture spec
Geoff Langca271392017-04-05 12:30:00 -0400215 switch (GetUnsizedFormat(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700216 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400217 case GL_RED:
Geoff Lang97073d12016-04-20 10:42:34 -0700218 case GL_ALPHA:
219 case GL_LUMINANCE:
220 case GL_LUMINANCE_ALPHA:
221 case GL_RGB:
222 case GL_RGBA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400223 case GL_RGB8:
224 case GL_RGBA8:
225 case GL_BGRA_EXT:
226 case GL_BGRA8_EXT:
Geoff Lang97073d12016-04-20 10:42:34 -0700227 return true;
228
Geoff Lang4f0e0032017-05-01 16:04:35 -0400229 default:
230 return false;
231 }
232}
Geoff Lang97073d12016-04-20 10:42:34 -0700233
Geoff Lang4f0e0032017-05-01 16:04:35 -0400234bool IsValidCopySubTextureSourceInternalFormat(GLenum internalFormat)
235{
236 return IsValidCopyTextureSourceInternalFormatEnum(internalFormat);
237}
238
Geoff Lang4f0e0032017-05-01 16:04:35 -0400239bool IsValidCopyTextureDestinationInternalFormatEnum(GLint internalFormat)
240{
241 // Table 1.0 from the CHROMIUM_copy_texture spec
242 switch (internalFormat)
243 {
244 case GL_RGB:
245 case GL_RGBA:
246 case GL_RGB8:
247 case GL_RGBA8:
Geoff Lang97073d12016-04-20 10:42:34 -0700248 case GL_BGRA_EXT:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400249 case GL_BGRA8_EXT:
250 case GL_SRGB_EXT:
251 case GL_SRGB_ALPHA_EXT:
252 case GL_R8:
253 case GL_R8UI:
254 case GL_RG8:
255 case GL_RG8UI:
256 case GL_SRGB8:
257 case GL_RGB565:
258 case GL_RGB8UI:
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400259 case GL_RGB10_A2:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400260 case GL_SRGB8_ALPHA8:
261 case GL_RGB5_A1:
262 case GL_RGBA4:
263 case GL_RGBA8UI:
264 case GL_RGB9_E5:
265 case GL_R16F:
266 case GL_R32F:
267 case GL_RG16F:
268 case GL_RG32F:
269 case GL_RGB16F:
270 case GL_RGB32F:
271 case GL_RGBA16F:
272 case GL_RGBA32F:
273 case GL_R11F_G11F_B10F:
Brandon Jones340b7b82017-06-26 13:02:31 -0700274 case GL_LUMINANCE:
275 case GL_LUMINANCE_ALPHA:
276 case GL_ALPHA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400277 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700278
279 default:
280 return false;
281 }
282}
283
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400284bool IsValidCopySubTextureDestionationInternalFormat(GLenum internalFormat)
285{
286 return IsValidCopyTextureDestinationInternalFormatEnum(internalFormat);
287}
288
Geoff Lang97073d12016-04-20 10:42:34 -0700289bool IsValidCopyTextureDestinationFormatType(Context *context, GLint internalFormat, GLenum type)
290{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400291 if (!IsValidCopyTextureDestinationInternalFormatEnum(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700292 {
Jamie Madille0472f32018-11-27 16:32:45 -0500293 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400294 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700295 }
296
Geoff Langc0094ec2017-08-16 14:16:24 -0400297 if (!ValidES3FormatCombination(GetUnsizedFormat(internalFormat), type, internalFormat))
298 {
Jamie Madille0472f32018-11-27 16:32:45 -0500299 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Langc0094ec2017-08-16 14:16:24 -0400300 return false;
301 }
302
Geoff Lang4f0e0032017-05-01 16:04:35 -0400303 const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat, type);
304 if (!internalFormatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
Geoff Lang97073d12016-04-20 10:42:34 -0700305 {
Jamie Madille0472f32018-11-27 16:32:45 -0500306 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400307 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700308 }
309
310 return true;
311}
312
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800313bool IsValidCopyTextureDestinationTargetEnum(Context *context, TextureTarget target)
Geoff Lang97073d12016-04-20 10:42:34 -0700314{
315 switch (target)
316 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800317 case TextureTarget::_2D:
318 case TextureTarget::CubeMapNegativeX:
319 case TextureTarget::CubeMapNegativeY:
320 case TextureTarget::CubeMapNegativeZ:
321 case TextureTarget::CubeMapPositiveX:
322 case TextureTarget::CubeMapPositiveY:
323 case TextureTarget::CubeMapPositiveZ:
Geoff Lang63458a32017-10-30 15:16:53 -0400324 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700325
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800326 case TextureTarget::Rectangle:
Geoff Lang63458a32017-10-30 15:16:53 -0400327 return context->getExtensions().textureRectangle;
Geoff Lang97073d12016-04-20 10:42:34 -0700328
329 default:
330 return false;
331 }
332}
333
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800334bool IsValidCopyTextureDestinationTarget(Context *context,
335 TextureType textureType,
336 TextureTarget target)
Geoff Lang63458a32017-10-30 15:16:53 -0400337{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800338 return TextureTargetToType(target) == textureType;
Geoff Lang63458a32017-10-30 15:16:53 -0400339}
340
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800341bool IsValidCopyTextureSourceTarget(Context *context, TextureType type)
Geoff Lang97073d12016-04-20 10:42:34 -0700342{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800343 switch (type)
Geoff Lang97073d12016-04-20 10:42:34 -0700344 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800345 case TextureType::_2D:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400346 return true;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800347 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400348 return context->getExtensions().textureRectangle;
Geoff Langbe607ad2018-11-29 10:14:22 -0500349 case TextureType::External:
350 return context->getExtensions().eglImageExternal;
Geoff Lang4f0e0032017-05-01 16:04:35 -0400351 default:
352 return false;
353 }
354}
355
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800356bool IsValidCopyTextureSourceLevel(Context *context, TextureType type, GLint level)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400357{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800358 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400359 {
360 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700361 }
362
Geoff Lang4f0e0032017-05-01 16:04:35 -0400363 if (level > 0 && context->getClientVersion() < ES_3_0)
364 {
365 return false;
366 }
Geoff Lang97073d12016-04-20 10:42:34 -0700367
Geoff Lang4f0e0032017-05-01 16:04:35 -0400368 return true;
369}
370
371bool IsValidCopyTextureDestinationLevel(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800372 TextureType type,
Geoff Lang4f0e0032017-05-01 16:04:35 -0400373 GLint level,
374 GLsizei width,
Brandon Jones28783792018-03-05 09:37:32 -0800375 GLsizei height,
376 bool isSubImage)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400377{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800378 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400379 {
380 return false;
381 }
382
Brandon Jones28783792018-03-05 09:37:32 -0800383 if (!ValidImageSizeParameters(context, type, level, width, height, 1, isSubImage))
384 {
385 return false;
386 }
387
Geoff Lang4f0e0032017-05-01 16:04:35 -0400388 const Caps &caps = context->getCaps();
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800389 switch (type)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400390 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800391 case TextureType::_2D:
392 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
393 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
394 case TextureType::Rectangle:
395 ASSERT(level == 0);
396 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
397 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400398
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800399 case TextureType::CubeMap:
400 return static_cast<GLuint>(width) <= (caps.maxCubeMapTextureSize >> level) &&
401 static_cast<GLuint>(height) <= (caps.maxCubeMapTextureSize >> level);
402 default:
403 return true;
404 }
Geoff Lang97073d12016-04-20 10:42:34 -0700405}
406
Jamie Madillc1d770e2017-04-13 17:31:24 -0400407bool IsValidStencilFunc(GLenum func)
408{
409 switch (func)
410 {
411 case GL_NEVER:
412 case GL_ALWAYS:
413 case GL_LESS:
414 case GL_LEQUAL:
415 case GL_EQUAL:
416 case GL_GEQUAL:
417 case GL_GREATER:
418 case GL_NOTEQUAL:
419 return true;
420
421 default:
422 return false;
423 }
424}
425
426bool IsValidStencilFace(GLenum face)
427{
428 switch (face)
429 {
430 case GL_FRONT:
431 case GL_BACK:
432 case GL_FRONT_AND_BACK:
433 return true;
434
435 default:
436 return false;
437 }
438}
439
440bool IsValidStencilOp(GLenum op)
441{
442 switch (op)
443 {
444 case GL_ZERO:
445 case GL_KEEP:
446 case GL_REPLACE:
447 case GL_INCR:
448 case GL_DECR:
449 case GL_INVERT:
450 case GL_INCR_WRAP:
451 case GL_DECR_WRAP:
452 return true;
453
454 default:
455 return false;
456 }
457}
458
Jamie Madill5b772312018-03-08 20:28:32 -0500459bool ValidateES2CopyTexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800460 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -0400461 GLint level,
462 GLenum internalformat,
463 bool isSubImage,
464 GLint xoffset,
465 GLint yoffset,
466 GLint x,
467 GLint y,
468 GLsizei width,
469 GLsizei height,
470 GLint border)
471{
472 if (!ValidTexture2DDestinationTarget(context, target))
473 {
Jamie Madille0472f32018-11-27 16:32:45 -0500474 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -0400475 return false;
476 }
477
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800478 TextureType texType = TextureTargetToType(target);
479 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Jamie Madillbe849e42017-05-02 15:49:00 -0400480 {
Jamie Madillc3e37312018-11-30 15:25:39 -0500481 // Error is already handled.
Jamie Madillbe849e42017-05-02 15:49:00 -0400482 return false;
483 }
484
485 Format textureFormat = Format::Invalid();
486 if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
487 xoffset, yoffset, 0, x, y, width, height, border,
488 &textureFormat))
489 {
490 return false;
491 }
492
Jamie Madillc3dc5d42018-12-30 12:12:04 -0500493 const gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer();
Jamie Madillbe849e42017-05-02 15:49:00 -0400494 GLenum colorbufferFormat =
495 framebuffer->getReadColorbuffer()->getFormat().info->sizedInternalFormat;
496 const auto &formatInfo = *textureFormat.info;
497
498 // [OpenGL ES 2.0.24] table 3.9
499 if (isSubImage)
500 {
501 switch (formatInfo.format)
502 {
503 case GL_ALPHA:
504 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400505 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
506 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400507 {
Jamie Madille0472f32018-11-27 16:32:45 -0500508 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400509 return false;
510 }
511 break;
512 case GL_LUMINANCE:
513 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
514 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
515 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400516 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGRA8_EXT &&
517 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400518 {
Jamie Madille0472f32018-11-27 16:32:45 -0500519 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400520 return false;
521 }
522 break;
523 case GL_RED_EXT:
524 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
525 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
526 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
527 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_R32F &&
528 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400529 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
530 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400531 {
Jamie Madille0472f32018-11-27 16:32:45 -0500532 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400533 return false;
534 }
535 break;
536 case GL_RG_EXT:
537 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
538 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
539 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
540 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400541 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
542 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400543 {
Jamie Madille0472f32018-11-27 16:32:45 -0500544 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400545 return false;
546 }
547 break;
548 case GL_RGB:
549 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
550 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
551 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400552 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
553 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400554 {
Jamie Madille0472f32018-11-27 16:32:45 -0500555 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400556 return false;
557 }
558 break;
559 case GL_LUMINANCE_ALPHA:
560 case GL_RGBA:
561 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400562 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGBA32F &&
563 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400564 {
Jamie Madille0472f32018-11-27 16:32:45 -0500565 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400566 return false;
567 }
568 break;
569 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
570 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
571 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
572 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
573 case GL_ETC1_RGB8_OES:
574 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
575 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
576 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
577 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
578 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
Olli Etuahof2ed2992018-10-04 13:54:42 +0300579 case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
580 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
581 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
582 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
Jamie Madille0472f32018-11-27 16:32:45 -0500583 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400584 return false;
585 case GL_DEPTH_COMPONENT:
586 case GL_DEPTH_STENCIL_OES:
Jamie Madille0472f32018-11-27 16:32:45 -0500587 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400588 return false;
589 default:
Jamie Madille0472f32018-11-27 16:32:45 -0500590 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400591 return false;
592 }
593
594 if (formatInfo.type == GL_FLOAT && !context->getExtensions().textureFloat)
595 {
Jamie Madille0472f32018-11-27 16:32:45 -0500596 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400597 return false;
598 }
599 }
600 else
601 {
602 switch (internalformat)
603 {
604 case GL_ALPHA:
605 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
606 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
607 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
608 {
Jamie Madille0472f32018-11-27 16:32:45 -0500609 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400610 return false;
611 }
612 break;
613 case GL_LUMINANCE:
614 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
615 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
616 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
617 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
618 colorbufferFormat != GL_BGR5_A1_ANGLEX)
619 {
Jamie Madille0472f32018-11-27 16:32:45 -0500620 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400621 return false;
622 }
623 break;
624 case GL_RED_EXT:
625 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
626 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
627 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
628 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
629 colorbufferFormat != GL_BGR5_A1_ANGLEX)
630 {
Jamie Madille0472f32018-11-27 16:32:45 -0500631 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400632 return false;
633 }
634 break;
635 case GL_RG_EXT:
636 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
637 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
638 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
639 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
640 {
Jamie Madille0472f32018-11-27 16:32:45 -0500641 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400642 return false;
643 }
644 break;
645 case GL_RGB:
646 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
647 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
648 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
649 colorbufferFormat != GL_BGR5_A1_ANGLEX)
650 {
Jamie Madille0472f32018-11-27 16:32:45 -0500651 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400652 return false;
653 }
654 break;
655 case GL_LUMINANCE_ALPHA:
656 case GL_RGBA:
657 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
658 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
659 colorbufferFormat != GL_BGR5_A1_ANGLEX)
660 {
Jamie Madille0472f32018-11-27 16:32:45 -0500661 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400662 return false;
663 }
664 break;
665 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
666 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
667 if (context->getExtensions().textureCompressionDXT1)
668 {
Jamie Madille0472f32018-11-27 16:32:45 -0500669 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400670 return false;
671 }
672 else
673 {
Jamie Madille0472f32018-11-27 16:32:45 -0500674 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400675 return false;
676 }
677 break;
678 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
679 if (context->getExtensions().textureCompressionDXT3)
680 {
Jamie Madille0472f32018-11-27 16:32:45 -0500681 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400682 return false;
683 }
684 else
685 {
Jamie Madille0472f32018-11-27 16:32:45 -0500686 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400687 return false;
688 }
689 break;
690 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
691 if (context->getExtensions().textureCompressionDXT5)
692 {
Jamie Madille0472f32018-11-27 16:32:45 -0500693 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400694 return false;
695 }
696 else
697 {
Jamie Madille0472f32018-11-27 16:32:45 -0500698 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400699 return false;
700 }
701 break;
702 case GL_ETC1_RGB8_OES:
703 if (context->getExtensions().compressedETC1RGB8Texture)
704 {
Jamie Madille0472f32018-11-27 16:32:45 -0500705 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400706 return false;
707 }
708 else
709 {
Jamie Madille0472f32018-11-27 16:32:45 -0500710 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400711 return false;
712 }
713 break;
714 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
715 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
716 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
717 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
718 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
719 if (context->getExtensions().lossyETCDecode)
720 {
Jamie Madillc3e37312018-11-30 15:25:39 -0500721 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400722 return false;
723 }
724 else
725 {
Jamie Madillc3e37312018-11-30 15:25:39 -0500726 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400727 return false;
728 }
729 break;
730 case GL_DEPTH_COMPONENT:
731 case GL_DEPTH_COMPONENT16:
732 case GL_DEPTH_COMPONENT32_OES:
733 case GL_DEPTH_STENCIL_OES:
734 case GL_DEPTH24_STENCIL8_OES:
735 if (context->getExtensions().depthTextures)
736 {
Jamie Madille0472f32018-11-27 16:32:45 -0500737 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400738 return false;
739 }
740 else
741 {
Jamie Madille0472f32018-11-27 16:32:45 -0500742 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400743 return false;
744 }
745 default:
Jamie Madille0472f32018-11-27 16:32:45 -0500746 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400747 return false;
748 }
749 }
750
751 // If width or height is zero, it is a no-op. Return false without setting an error.
752 return (width > 0 && height > 0);
753}
754
755bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
756{
757 switch (cap)
758 {
759 // EXT_multisample_compatibility
760 case GL_MULTISAMPLE_EXT:
761 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
762 return context->getExtensions().multisampleCompatibility;
763
764 case GL_CULL_FACE:
765 case GL_POLYGON_OFFSET_FILL:
766 case GL_SAMPLE_ALPHA_TO_COVERAGE:
767 case GL_SAMPLE_COVERAGE:
768 case GL_SCISSOR_TEST:
769 case GL_STENCIL_TEST:
770 case GL_DEPTH_TEST:
771 case GL_BLEND:
772 case GL_DITHER:
773 return true;
774
775 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
776 case GL_RASTERIZER_DISCARD:
777 return (context->getClientMajorVersion() >= 3);
778
779 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
780 case GL_DEBUG_OUTPUT:
781 return context->getExtensions().debug;
782
783 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
784 return queryOnly && context->getExtensions().bindGeneratesResource;
785
786 case GL_CLIENT_ARRAYS_ANGLE:
787 return queryOnly && context->getExtensions().clientArrays;
788
789 case GL_FRAMEBUFFER_SRGB_EXT:
790 return context->getExtensions().sRGBWriteControl;
791
792 case GL_SAMPLE_MASK:
793 return context->getClientVersion() >= Version(3, 1);
794
Geoff Langb433e872017-10-05 14:01:47 -0400795 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
Jamie Madillbe849e42017-05-02 15:49:00 -0400796 return queryOnly && context->getExtensions().robustResourceInitialization;
797
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700798 // GLES1 emulation: GLES1-specific caps
799 case GL_ALPHA_TEST:
Lingfeng Yang01074432018-04-16 10:19:51 -0700800 case GL_VERTEX_ARRAY:
801 case GL_NORMAL_ARRAY:
802 case GL_COLOR_ARRAY:
803 case GL_TEXTURE_COORD_ARRAY:
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700804 case GL_TEXTURE_2D:
Lingfeng Yangd0febe72018-05-17 22:36:52 -0700805 case GL_LIGHTING:
806 case GL_LIGHT0:
807 case GL_LIGHT1:
808 case GL_LIGHT2:
809 case GL_LIGHT3:
810 case GL_LIGHT4:
811 case GL_LIGHT5:
812 case GL_LIGHT6:
813 case GL_LIGHT7:
814 case GL_NORMALIZE:
815 case GL_RESCALE_NORMAL:
816 case GL_COLOR_MATERIAL:
Lingfeng Yang060088a2018-05-30 20:40:57 -0700817 case GL_CLIP_PLANE0:
818 case GL_CLIP_PLANE1:
819 case GL_CLIP_PLANE2:
820 case GL_CLIP_PLANE3:
821 case GL_CLIP_PLANE4:
822 case GL_CLIP_PLANE5:
Lingfeng Yang7ba3f422018-06-01 09:43:04 -0700823 case GL_FOG:
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700824 case GL_POINT_SMOOTH:
Lingfeng Yang6e5bf362018-08-15 09:53:17 -0700825 case GL_LINE_SMOOTH:
826 case GL_COLOR_LOGIC_OP:
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700827 return context->getClientVersion() < Version(2, 0);
Lingfeng Yang01074432018-04-16 10:19:51 -0700828 case GL_POINT_SIZE_ARRAY_OES:
829 return context->getClientVersion() < Version(2, 0) &&
830 context->getExtensions().pointSizeArray;
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700831 case GL_TEXTURE_CUBE_MAP:
832 return context->getClientVersion() < Version(2, 0) &&
833 context->getExtensions().textureCubeMap;
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700834 case GL_POINT_SPRITE_OES:
835 return context->getClientVersion() < Version(2, 0) &&
836 context->getExtensions().pointSprite;
Jamie Madillbe849e42017-05-02 15:49:00 -0400837 default:
838 return false;
839 }
840}
841
Geoff Langfc32e8b2017-05-31 14:16:59 -0400842// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
843// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400844bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400845{
846 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400847 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
848 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400849 {
850 return true;
851 }
852
853 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
854 if (c >= 9 && c <= 13)
855 {
856 return true;
857 }
858
859 return false;
860}
861
Geoff Langcab92ee2017-07-19 17:32:07 -0400862bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400863{
Geoff Langa71a98e2017-06-19 15:15:00 -0400864 for (size_t i = 0; i < len; i++)
865 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400866 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400867 {
868 return false;
869 }
870 }
871
872 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400873}
874
Geoff Langcab92ee2017-07-19 17:32:07 -0400875bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
876{
877 enum class ParseState
878 {
879 // Have not seen an ASCII non-whitespace character yet on
880 // this line. Possible that we might see a preprocessor
881 // directive.
882 BEGINING_OF_LINE,
883
884 // Have seen at least one ASCII non-whitespace character
885 // on this line.
886 MIDDLE_OF_LINE,
887
888 // Handling a preprocessor directive. Passes through all
889 // characters up to the end of the line. Disables comment
890 // processing.
891 IN_PREPROCESSOR_DIRECTIVE,
892
893 // Handling a single-line comment. The comment text is
894 // replaced with a single space.
895 IN_SINGLE_LINE_COMMENT,
896
897 // Handling a multi-line comment. Newlines are passed
898 // through to preserve line numbers.
899 IN_MULTI_LINE_COMMENT
900 };
901
902 ParseState state = ParseState::BEGINING_OF_LINE;
903 size_t pos = 0;
904
905 while (pos < len)
906 {
907 char c = str[pos];
908 char next = pos + 1 < len ? str[pos + 1] : 0;
909
910 // Check for newlines
911 if (c == '\n' || c == '\r')
912 {
913 if (state != ParseState::IN_MULTI_LINE_COMMENT)
914 {
915 state = ParseState::BEGINING_OF_LINE;
916 }
917
918 pos++;
919 continue;
920 }
921
922 switch (state)
923 {
924 case ParseState::BEGINING_OF_LINE:
925 if (c == ' ')
926 {
927 // Maintain the BEGINING_OF_LINE state until a non-space is seen
928 pos++;
929 }
930 else if (c == '#')
931 {
932 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
933 pos++;
934 }
935 else
936 {
937 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
938 state = ParseState::MIDDLE_OF_LINE;
939 }
940 break;
941
942 case ParseState::MIDDLE_OF_LINE:
943 if (c == '/' && next == '/')
944 {
945 state = ParseState::IN_SINGLE_LINE_COMMENT;
946 pos++;
947 }
948 else if (c == '/' && next == '*')
949 {
950 state = ParseState::IN_MULTI_LINE_COMMENT;
951 pos++;
952 }
953 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
954 {
955 // Skip line continuation characters
956 }
957 else if (!IsValidESSLCharacter(c))
958 {
959 return false;
960 }
961 pos++;
962 break;
963
964 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700965 // Line-continuation characters may not be permitted.
966 // Otherwise, just pass it through. Do not parse comments in this state.
967 if (!lineContinuationAllowed && c == '\\')
968 {
969 return false;
970 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400971 pos++;
972 break;
973
974 case ParseState::IN_SINGLE_LINE_COMMENT:
975 // Line-continuation characters are processed before comment processing.
976 // Advance string if a new line character is immediately behind
977 // line-continuation character.
978 if (c == '\\' && (next == '\n' || next == '\r'))
979 {
980 pos++;
981 }
982 pos++;
983 break;
984
985 case ParseState::IN_MULTI_LINE_COMMENT:
986 if (c == '*' && next == '/')
987 {
988 state = ParseState::MIDDLE_OF_LINE;
989 pos++;
990 }
991 pos++;
992 break;
993 }
994 }
995
996 return true;
997}
998
Jamie Madill5b772312018-03-08 20:28:32 -0500999bool ValidateWebGLNamePrefix(Context *context, const GLchar *name)
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001000{
1001 ASSERT(context->isWebGL());
1002
1003 // WebGL 1.0 [Section 6.16] GLSL Constructs
1004 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
1005 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
1006 {
Jamie Madille0472f32018-11-27 16:32:45 -05001007 context->validationError(GL_INVALID_OPERATION, kWebglBindAttribLocationReservedPrefix);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001008 return false;
1009 }
1010
1011 return true;
1012}
1013
Jamie Madill5b772312018-03-08 20:28:32 -05001014bool ValidateWebGLNameLength(Context *context, size_t length)
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001015{
1016 ASSERT(context->isWebGL());
1017
1018 if (context->isWebGL1() && length > 256)
1019 {
1020 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
1021 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
1022 // locations.
Jamie Madille0472f32018-11-27 16:32:45 -05001023 context->validationError(GL_INVALID_VALUE, kWebglNameLengthLimitExceeded);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001024
1025 return false;
1026 }
1027 else if (length > 1024)
1028 {
1029 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
1030 // uniform and attribute locations.
Jamie Madille0472f32018-11-27 16:32:45 -05001031 context->validationError(GL_INVALID_VALUE, kWebgl2NameLengthLimitExceeded);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001032 return false;
1033 }
1034
1035 return true;
1036}
1037
Jamie Madill007530e2017-12-28 14:27:04 -05001038bool ValidateMatrixMode(Context *context, GLenum matrixMode)
1039{
1040 if (!context->getExtensions().pathRendering)
1041 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001042 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05001043 return false;
1044 }
1045
1046 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
1047 {
Jamie Madille0472f32018-11-27 16:32:45 -05001048 context->validationError(GL_INVALID_ENUM, kInvalidMatrixMode);
Jamie Madill007530e2017-12-28 14:27:04 -05001049 return false;
1050 }
1051 return true;
1052}
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03001053
1054bool ValidBlendFunc(const Context *context, GLenum val)
1055{
1056 const gl::Extensions &ext = context->getExtensions();
1057
1058 // these are always valid for src and dst.
1059 switch (val)
1060 {
1061 case GL_ZERO:
1062 case GL_ONE:
1063 case GL_SRC_COLOR:
1064 case GL_ONE_MINUS_SRC_COLOR:
1065 case GL_DST_COLOR:
1066 case GL_ONE_MINUS_DST_COLOR:
1067 case GL_SRC_ALPHA:
1068 case GL_ONE_MINUS_SRC_ALPHA:
1069 case GL_DST_ALPHA:
1070 case GL_ONE_MINUS_DST_ALPHA:
1071 case GL_CONSTANT_COLOR:
1072 case GL_ONE_MINUS_CONSTANT_COLOR:
1073 case GL_CONSTANT_ALPHA:
1074 case GL_ONE_MINUS_CONSTANT_ALPHA:
1075 return true;
1076
1077 // EXT_blend_func_extended.
1078 case GL_SRC1_COLOR_EXT:
1079 case GL_SRC1_ALPHA_EXT:
1080 case GL_ONE_MINUS_SRC1_COLOR_EXT:
1081 case GL_ONE_MINUS_SRC1_ALPHA_EXT:
1082 case GL_SRC_ALPHA_SATURATE_EXT:
1083 return ext.blendFuncExtended;
1084
1085 default:
1086 return false;
1087 }
1088}
1089
1090bool ValidSrcBlendFunc(const Context *context, GLenum val)
1091{
1092 if (ValidBlendFunc(context, val))
1093 return true;
1094
1095 if (val == GL_SRC_ALPHA_SATURATE)
1096 return true;
1097
1098 return false;
1099}
1100
1101bool ValidDstBlendFunc(const Context *context, GLenum val)
1102{
1103 if (ValidBlendFunc(context, val))
1104 return true;
1105
1106 if (val == GL_SRC_ALPHA_SATURATE)
1107 {
1108 if (context->getClientMajorVersion() >= 3)
1109 return true;
1110 }
1111
1112 return false;
1113}
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 &&
Jamie Madillc3dc5d42018-12-30 12:12:04 -05001294 context->getState().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 =
Jamie Madillc3dc5d42018-12-30 12:12:04 -05001931 (context->getState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
He Yunchaoced53ae2016-11-29 15:00:51 +08001932 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 Madillc3dc5d42018-12-30 12:12:04 -05002136 if (!context->getState().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 Madillc3dc5d42018-12-30 12:12:04 -05002234 size_t currentStackSize = context->getState().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 Madillc3dc5d42018-12-30 12:12:04 -05002252 size_t currentStackSize = context->getState().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 Madillc3dc5d42018-12-30 12:12:04 -05002554 Framebuffer *readFramebuffer = context->getState().getReadFramebuffer();
2555 Framebuffer *drawFramebuffer = context->getState().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{
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002652 Framebuffer *fbo = context->getState().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 {
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002684 const State &state = context->getState();
Olli Etuaho94c91a92018-07-19 15:10:24 +03002685 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 Madillc3dc5d42018-12-30 12:12:04 -05002983 Buffer *buffer = context->getState().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{
Jamie Madillc3dc5d42018-12-30 12:12:04 -05003034 Buffer *buffer = context->getState().getTargetBuffer(target);
Geoff Lang79f71042017-08-14 16:43:43 -04003035 ASSERT(buffer != nullptr);
3036
3037 // Check if this buffer is currently being used as a transform feedback output buffer
Jamie Madillc3dc5d42018-12-30 12:12:04 -05003038 TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
Geoff Lang79f71042017-08-14 16:43:43 -04003039 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
Jamie Madillc3dc5d42018-12-30 12:12:04 -05003096 if (!context->getState().isBindGeneratesResourceEnabled() &&
Jamie Madill0fdb9562018-09-17 17:18:43 -04003097 !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
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004317 Buffer *buffer = context->getState().getTargetBuffer(target);
Jamie Madill29639852016-09-02 15:00:09 -04004318
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
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004359 Buffer *buffer = context->getState().getTargetBuffer(target);
Jamie Madill29639852016-09-02 15:00:09 -04004360
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
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004498 if (!context->getState().isBindGeneratesResourceEnabled() &&
Jamie Madill01a80ee2016-11-07 12:06:18 -05004499 !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
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004516 if (!context->getState().isBindGeneratesResourceEnabled() &&
Jamie Madill01a80ee2016-11-07 12:06:18 -05004517 !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 ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004679{
4680 if (context->getExtensions().webglCompatibility && zNear > zFar)
4681 {
Jamie Madille0472f32018-11-27 16:32:45 -05004682 context->validationError(GL_INVALID_OPERATION, kInvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004683 return false;
4684 }
4685
4686 return true;
4687}
4688
Jamie Madill5b772312018-03-08 20:28:32 -05004689bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004690 GLenum target,
4691 GLenum internalformat,
4692 GLsizei width,
4693 GLsizei height)
4694{
4695 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4696 height);
4697}
4698
Jamie Madill5b772312018-03-08 20:28:32 -05004699bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004700 GLenum target,
4701 GLsizei samples,
4702 GLenum internalformat,
4703 GLsizei width,
4704 GLsizei height)
4705{
4706 if (!context->getExtensions().framebufferMultisample)
4707 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004708 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madille8fb6402017-02-14 17:56:40 -05004709 return false;
4710 }
4711
4712 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
Jamie Madill610640f2018-11-21 17:28:41 -05004713 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_VALUE is
Jamie Madille8fb6402017-02-14 17:56:40 -05004714 // generated.
4715 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4716 {
Jamie Madille0472f32018-11-27 16:32:45 -05004717 context->validationError(GL_INVALID_VALUE, kSamplesOutOfRange);
Jamie Madille8fb6402017-02-14 17:56:40 -05004718 return false;
4719 }
4720
4721 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4722 // the specified storage. This is different than ES 3.0 in which a sample number higher
4723 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4724 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4725 if (context->getClientMajorVersion() >= 3)
4726 {
4727 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4728 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4729 {
Jamie Madille0472f32018-11-27 16:32:45 -05004730 context->validationError(GL_OUT_OF_MEMORY, kSamplesOutOfRange);
Jamie Madille8fb6402017-02-14 17:56:40 -05004731 return false;
4732 }
4733 }
4734
4735 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4736 width, height);
4737}
4738
Jamie Madill5b772312018-03-08 20:28:32 -05004739bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004740{
Geoff Lange8afa902017-09-27 15:00:43 -04004741 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004742 {
Jamie Madille0472f32018-11-27 16:32:45 -05004743 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004744 return false;
4745 }
4746
4747 return true;
4748}
4749
Jamie Madill5b772312018-03-08 20:28:32 -05004750bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004751{
4752 return true;
4753}
4754
Jamie Madill5b772312018-03-08 20:28:32 -05004755bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004756{
4757 return true;
4758}
4759
Jamie Madill5b772312018-03-08 20:28:32 -05004760bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004761{
4762 return true;
4763}
4764
Jamie Madill5b772312018-03-08 20:28:32 -05004765bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004766 GLboolean red,
4767 GLboolean green,
4768 GLboolean blue,
4769 GLboolean alpha)
4770{
4771 return true;
4772}
4773
Jamie Madill5b772312018-03-08 20:28:32 -05004774bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004775{
4776 return true;
4777}
4778
Jamie Madill5b772312018-03-08 20:28:32 -05004779bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004780{
4781 return true;
4782}
4783
Jamie Madill5b772312018-03-08 20:28:32 -05004784bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004785{
4786 switch (mode)
4787 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004788 case CullFaceMode::Front:
4789 case CullFaceMode::Back:
4790 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004791 break;
4792
4793 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004794 context->validationError(GL_INVALID_ENUM, kInvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004795 return false;
4796 }
4797
4798 return true;
4799}
4800
Jamie Madill5b772312018-03-08 20:28:32 -05004801bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004802{
4803 if (program == 0)
4804 {
4805 return false;
4806 }
4807
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004808 if (!context->getProgramResolveLink(program))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004809 {
4810 if (context->getShader(program))
4811 {
Jamie Madille0472f32018-11-27 16:32:45 -05004812 context->validationError(GL_INVALID_OPERATION, kExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004813 return false;
4814 }
4815 else
4816 {
Jamie Madille0472f32018-11-27 16:32:45 -05004817 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004818 return false;
4819 }
4820 }
4821
4822 return true;
4823}
4824
Jamie Madill5b772312018-03-08 20:28:32 -05004825bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004826{
4827 if (shader == 0)
4828 {
4829 return false;
4830 }
4831
4832 if (!context->getShader(shader))
4833 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004834 if (context->getProgramResolveLink(shader))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004835 {
Jamie Madille0472f32018-11-27 16:32:45 -05004836 context->validationError(GL_INVALID_OPERATION, kInvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004837 return false;
4838 }
4839 else
4840 {
Jamie Madille0472f32018-11-27 16:32:45 -05004841 context->validationError(GL_INVALID_VALUE, kExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004842 return false;
4843 }
4844 }
4845
4846 return true;
4847}
4848
Jamie Madill5b772312018-03-08 20:28:32 -05004849bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004850{
4851 switch (func)
4852 {
4853 case GL_NEVER:
4854 case GL_ALWAYS:
4855 case GL_LESS:
4856 case GL_LEQUAL:
4857 case GL_EQUAL:
4858 case GL_GREATER:
4859 case GL_GEQUAL:
4860 case GL_NOTEQUAL:
4861 break;
4862
4863 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004864 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004865 return false;
4866 }
4867
4868 return true;
4869}
4870
Jamie Madill5b772312018-03-08 20:28:32 -05004871bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004872{
4873 return true;
4874}
4875
Jamie Madill5b772312018-03-08 20:28:32 -05004876bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004877{
4878 Program *programObject = GetValidProgram(context, program);
4879 if (!programObject)
4880 {
4881 return false;
4882 }
4883
4884 Shader *shaderObject = GetValidShader(context, shader);
4885 if (!shaderObject)
4886 {
4887 return false;
4888 }
4889
Jiawei Shao385b3e02018-03-21 09:43:28 +08004890 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04004891 if (attachedShader != shaderObject)
4892 {
Jamie Madille0472f32018-11-27 16:32:45 -05004893 context->validationError(GL_INVALID_OPERATION, kShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004894 return false;
4895 }
4896
4897 return true;
4898}
4899
Jamie Madill5b772312018-03-08 20:28:32 -05004900bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004901{
4902 if (index >= MAX_VERTEX_ATTRIBS)
4903 {
Jamie Madille0472f32018-11-27 16:32:45 -05004904 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004905 return false;
4906 }
4907
4908 return true;
4909}
4910
Jamie Madill5b772312018-03-08 20:28:32 -05004911bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004912{
4913 if (index >= MAX_VERTEX_ATTRIBS)
4914 {
Jamie Madille0472f32018-11-27 16:32:45 -05004915 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004916 return false;
4917 }
4918
4919 return true;
4920}
4921
Jamie Madill5b772312018-03-08 20:28:32 -05004922bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004923{
4924 return true;
4925}
4926
Jamie Madill5b772312018-03-08 20:28:32 -05004927bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004928{
4929 return true;
4930}
4931
Jamie Madill5b772312018-03-08 20:28:32 -05004932bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004933{
4934 switch (mode)
4935 {
4936 case GL_CW:
4937 case GL_CCW:
4938 break;
4939 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004940 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004941 return false;
4942 }
4943
4944 return true;
4945}
4946
Jamie Madill5b772312018-03-08 20:28:32 -05004947bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004948 GLuint program,
4949 GLuint index,
4950 GLsizei bufsize,
4951 GLsizei *length,
4952 GLint *size,
4953 GLenum *type,
4954 GLchar *name)
4955{
4956 if (bufsize < 0)
4957 {
Jamie Madille0472f32018-11-27 16:32:45 -05004958 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004959 return false;
4960 }
4961
4962 Program *programObject = GetValidProgram(context, program);
4963
4964 if (!programObject)
4965 {
4966 return false;
4967 }
4968
4969 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
4970 {
Jamie Madille0472f32018-11-27 16:32:45 -05004971 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform);
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 ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004979 GLuint program,
4980 GLuint index,
4981 GLsizei bufsize,
4982 GLsizei *length,
4983 GLint *size,
4984 GLenum *type,
4985 GLchar *name)
4986{
4987 if (bufsize < 0)
4988 {
Jamie Madille0472f32018-11-27 16:32:45 -05004989 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004990 return false;
4991 }
4992
4993 Program *programObject = GetValidProgram(context, program);
4994
4995 if (!programObject)
4996 {
4997 return false;
4998 }
4999
5000 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5001 {
Jamie Madille0472f32018-11-27 16:32:45 -05005002 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005003 return false;
5004 }
5005
5006 return true;
5007}
5008
Jamie Madill5b772312018-03-08 20:28:32 -05005009bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005010 GLuint program,
5011 GLsizei maxcount,
5012 GLsizei *count,
5013 GLuint *shaders)
5014{
5015 if (maxcount < 0)
5016 {
Jamie Madille0472f32018-11-27 16:32:45 -05005017 context->validationError(GL_INVALID_VALUE, kNegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005018 return false;
5019 }
5020
5021 Program *programObject = GetValidProgram(context, program);
5022
5023 if (!programObject)
5024 {
5025 return false;
5026 }
5027
5028 return true;
5029}
5030
Jamie Madill5b772312018-03-08 20:28:32 -05005031bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005032{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005033 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5034 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005035 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005036 {
Jamie Madille0472f32018-11-27 16:32:45 -05005037 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005038 return false;
5039 }
5040
Jamie Madillc1d770e2017-04-13 17:31:24 -04005041 Program *programObject = GetValidProgram(context, program);
5042
5043 if (!programObject)
5044 {
Jamie Madille0472f32018-11-27 16:32:45 -05005045 context->validationError(GL_INVALID_OPERATION, kProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005046 return false;
5047 }
5048
5049 if (!programObject->isLinked())
5050 {
Jamie Madille0472f32018-11-27 16:32:45 -05005051 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005052 return false;
5053 }
5054
5055 return true;
5056}
5057
Jamie Madill5b772312018-03-08 20:28:32 -05005058bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005059{
5060 GLenum nativeType;
5061 unsigned int numParams = 0;
5062 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5063}
5064
Jamie Madill5b772312018-03-08 20:28:32 -05005065bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005066{
5067 return true;
5068}
5069
Jamie Madill5b772312018-03-08 20:28:32 -05005070bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005071{
5072 GLenum nativeType;
5073 unsigned int numParams = 0;
5074 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5075}
5076
Jamie Madill5b772312018-03-08 20:28:32 -05005077bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005078{
5079 GLenum nativeType;
5080 unsigned int numParams = 0;
5081 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5082}
5083
Jamie Madill5b772312018-03-08 20:28:32 -05005084bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005085 GLuint program,
5086 GLsizei bufsize,
5087 GLsizei *length,
5088 GLchar *infolog)
5089{
5090 if (bufsize < 0)
5091 {
Jamie Madille0472f32018-11-27 16:32:45 -05005092 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005093 return false;
5094 }
5095
5096 Program *programObject = GetValidProgram(context, program);
5097 if (!programObject)
5098 {
5099 return false;
5100 }
5101
5102 return true;
5103}
5104
Jamie Madill5b772312018-03-08 20:28:32 -05005105bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005106 GLuint shader,
5107 GLsizei bufsize,
5108 GLsizei *length,
5109 GLchar *infolog)
5110{
5111 if (bufsize < 0)
5112 {
Jamie Madille0472f32018-11-27 16:32:45 -05005113 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005114 return false;
5115 }
5116
5117 Shader *shaderObject = GetValidShader(context, shader);
5118 if (!shaderObject)
5119 {
5120 return false;
5121 }
5122
5123 return true;
5124}
5125
Jamie Madill5b772312018-03-08 20:28:32 -05005126bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005127 GLenum shadertype,
5128 GLenum precisiontype,
5129 GLint *range,
5130 GLint *precision)
5131{
5132 switch (shadertype)
5133 {
5134 case GL_VERTEX_SHADER:
5135 case GL_FRAGMENT_SHADER:
5136 break;
5137 case GL_COMPUTE_SHADER:
Jamie Madillc3e37312018-11-30 15:25:39 -05005138 context->validationError(GL_INVALID_OPERATION, kUnimplementedComputeShaderPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005139 return false;
5140 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005141 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005142 return false;
5143 }
5144
5145 switch (precisiontype)
5146 {
5147 case GL_LOW_FLOAT:
5148 case GL_MEDIUM_FLOAT:
5149 case GL_HIGH_FLOAT:
5150 case GL_LOW_INT:
5151 case GL_MEDIUM_INT:
5152 case GL_HIGH_INT:
5153 break;
5154
5155 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005156 context->validationError(GL_INVALID_ENUM, kInvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005157 return false;
5158 }
5159
5160 return true;
5161}
5162
Jamie Madill5b772312018-03-08 20:28:32 -05005163bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005164 GLuint shader,
5165 GLsizei bufsize,
5166 GLsizei *length,
5167 GLchar *source)
5168{
5169 if (bufsize < 0)
5170 {
Jamie Madille0472f32018-11-27 16:32:45 -05005171 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005172 return false;
5173 }
5174
5175 Shader *shaderObject = GetValidShader(context, shader);
5176 if (!shaderObject)
5177 {
5178 return false;
5179 }
5180
5181 return true;
5182}
5183
Jamie Madill5b772312018-03-08 20:28:32 -05005184bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005185{
5186 if (strstr(name, "gl_") == name)
5187 {
5188 return false;
5189 }
5190
Geoff Langfc32e8b2017-05-31 14:16:59 -04005191 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5192 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005193 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005194 {
Jamie Madille0472f32018-11-27 16:32:45 -05005195 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005196 return false;
5197 }
5198
Jamie Madillc1d770e2017-04-13 17:31:24 -04005199 Program *programObject = GetValidProgram(context, program);
5200
5201 if (!programObject)
5202 {
5203 return false;
5204 }
5205
5206 if (!programObject->isLinked())
5207 {
Jamie Madille0472f32018-11-27 16:32:45 -05005208 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005209 return false;
5210 }
5211
5212 return true;
5213}
5214
Jamie Madill5b772312018-03-08 20:28:32 -05005215bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005216{
5217 switch (mode)
5218 {
5219 case GL_FASTEST:
5220 case GL_NICEST:
5221 case GL_DONT_CARE:
5222 break;
5223
5224 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005225 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005226 return false;
5227 }
5228
5229 switch (target)
5230 {
5231 case GL_GENERATE_MIPMAP_HINT:
5232 break;
5233
Geoff Lange7bd2182017-06-16 16:13:13 -04005234 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5235 if (context->getClientVersion() < ES_3_0 &&
5236 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005237 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005238 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005239 return false;
5240 }
5241 break;
5242
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07005243 case GL_PERSPECTIVE_CORRECTION_HINT:
5244 case GL_POINT_SMOOTH_HINT:
5245 case GL_LINE_SMOOTH_HINT:
5246 case GL_FOG_HINT:
5247 if (context->getClientMajorVersion() >= 2)
5248 {
Jamie Madille0472f32018-11-27 16:32:45 -05005249 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07005250 return false;
5251 }
5252 break;
5253
Jamie Madillc1d770e2017-04-13 17:31:24 -04005254 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005255 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005256 return false;
5257 }
5258
5259 return true;
5260}
5261
Jamie Madill5b772312018-03-08 20:28:32 -05005262bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005263{
5264 return true;
5265}
5266
Jamie Madill5b772312018-03-08 20:28:32 -05005267bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005268{
5269 return true;
5270}
5271
Jamie Madill5b772312018-03-08 20:28:32 -05005272bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005273{
5274 return true;
5275}
5276
Jamie Madill5b772312018-03-08 20:28:32 -05005277bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005278{
5279 return true;
5280}
5281
Jamie Madill5b772312018-03-08 20:28:32 -05005282bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005283{
5284 return true;
5285}
5286
Jamie Madill5b772312018-03-08 20:28:32 -05005287bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005288{
5289 return true;
5290}
5291
Jamie Madill5b772312018-03-08 20:28:32 -05005292bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005293{
5294 if (context->getClientMajorVersion() < 3)
5295 {
5296 switch (pname)
5297 {
5298 case GL_UNPACK_IMAGE_HEIGHT:
5299 case GL_UNPACK_SKIP_IMAGES:
Jamie Madille0472f32018-11-27 16:32:45 -05005300 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005301 return false;
5302
5303 case GL_UNPACK_ROW_LENGTH:
5304 case GL_UNPACK_SKIP_ROWS:
5305 case GL_UNPACK_SKIP_PIXELS:
5306 if (!context->getExtensions().unpackSubimage)
5307 {
Jamie Madille0472f32018-11-27 16:32:45 -05005308 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005309 return false;
5310 }
5311 break;
5312
5313 case GL_PACK_ROW_LENGTH:
5314 case GL_PACK_SKIP_ROWS:
5315 case GL_PACK_SKIP_PIXELS:
5316 if (!context->getExtensions().packSubimage)
5317 {
Jamie Madille0472f32018-11-27 16:32:45 -05005318 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005319 return false;
5320 }
5321 break;
5322 }
5323 }
5324
5325 if (param < 0)
5326 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005327 context->validationError(GL_INVALID_VALUE, kNegativeParam);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005328 return false;
5329 }
5330
5331 switch (pname)
5332 {
5333 case GL_UNPACK_ALIGNMENT:
5334 if (param != 1 && param != 2 && param != 4 && param != 8)
5335 {
Jamie Madille0472f32018-11-27 16:32:45 -05005336 context->validationError(GL_INVALID_VALUE, kInvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005337 return false;
5338 }
5339 break;
5340
5341 case GL_PACK_ALIGNMENT:
5342 if (param != 1 && param != 2 && param != 4 && param != 8)
5343 {
Jamie Madille0472f32018-11-27 16:32:45 -05005344 context->validationError(GL_INVALID_VALUE, kInvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005345 return false;
5346 }
5347 break;
5348
5349 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005350 if (!context->getExtensions().packReverseRowOrder)
5351 {
Jamie Madille0472f32018-11-27 16:32:45 -05005352 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang000dab82017-09-27 14:27:07 -04005353 }
5354 break;
5355
Jamie Madillc1d770e2017-04-13 17:31:24 -04005356 case GL_UNPACK_ROW_LENGTH:
5357 case GL_UNPACK_IMAGE_HEIGHT:
5358 case GL_UNPACK_SKIP_IMAGES:
5359 case GL_UNPACK_SKIP_ROWS:
5360 case GL_UNPACK_SKIP_PIXELS:
5361 case GL_PACK_ROW_LENGTH:
5362 case GL_PACK_SKIP_ROWS:
5363 case GL_PACK_SKIP_PIXELS:
5364 break;
5365
5366 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005367 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005368 return false;
5369 }
5370
5371 return true;
5372}
5373
Jamie Madill5b772312018-03-08 20:28:32 -05005374bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005375{
5376 return true;
5377}
5378
Jamie Madill5b772312018-03-08 20:28:32 -05005379bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005380{
5381 return true;
5382}
5383
Jamie Madill5b772312018-03-08 20:28:32 -05005384bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005385{
5386 return true;
5387}
5388
Jamie Madill5b772312018-03-08 20:28:32 -05005389bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005390{
5391 if (width < 0 || height < 0)
5392 {
Jamie Madille0472f32018-11-27 16:32:45 -05005393 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005394 return false;
5395 }
5396
5397 return true;
5398}
5399
Jamie Madill5b772312018-03-08 20:28:32 -05005400bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005401 GLsizei n,
5402 const GLuint *shaders,
5403 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005404 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005405 GLsizei length)
5406{
5407 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5408 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5409 shaderBinaryFormats.end())
5410 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005411 context->validationError(GL_INVALID_ENUM, kInvalidShaderBinaryFormat);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005412 return false;
5413 }
5414
5415 return true;
5416}
5417
Jamie Madill5b772312018-03-08 20:28:32 -05005418bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005419 GLuint shader,
5420 GLsizei count,
5421 const GLchar *const *string,
5422 const GLint *length)
5423{
5424 if (count < 0)
5425 {
Jamie Madille0472f32018-11-27 16:32:45 -05005426 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005427 return false;
5428 }
5429
Geoff Langfc32e8b2017-05-31 14:16:59 -04005430 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5431 // shader-related entry points
5432 if (context->getExtensions().webglCompatibility)
5433 {
5434 for (GLsizei i = 0; i < count; i++)
5435 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005436 size_t len =
5437 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005438
5439 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005440 if (!IsValidESSLShaderSourceString(string[i], len,
5441 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005442 {
Jamie Madille0472f32018-11-27 16:32:45 -05005443 context->validationError(GL_INVALID_VALUE, kShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005444 return false;
5445 }
5446 }
5447 }
5448
Jamie Madillc1d770e2017-04-13 17:31:24 -04005449 Shader *shaderObject = GetValidShader(context, shader);
5450 if (!shaderObject)
5451 {
5452 return false;
5453 }
5454
5455 return true;
5456}
5457
Jamie Madill5b772312018-03-08 20:28:32 -05005458bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005459{
5460 if (!IsValidStencilFunc(func))
5461 {
Jamie Madille0472f32018-11-27 16:32:45 -05005462 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005463 return false;
5464 }
5465
5466 return true;
5467}
5468
Jamie Madill5b772312018-03-08 20:28:32 -05005469bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005470{
5471 if (!IsValidStencilFace(face))
5472 {
Jamie Madille0472f32018-11-27 16:32:45 -05005473 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005474 return false;
5475 }
5476
5477 if (!IsValidStencilFunc(func))
5478 {
Jamie Madille0472f32018-11-27 16:32:45 -05005479 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005480 return false;
5481 }
5482
5483 return true;
5484}
5485
Jamie Madill5b772312018-03-08 20:28:32 -05005486bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005487{
5488 return true;
5489}
5490
Jamie Madill5b772312018-03-08 20:28:32 -05005491bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005492{
5493 if (!IsValidStencilFace(face))
5494 {
Jamie Madille0472f32018-11-27 16:32:45 -05005495 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005496 return false;
5497 }
5498
5499 return true;
5500}
5501
Jamie Madill5b772312018-03-08 20:28:32 -05005502bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005503{
5504 if (!IsValidStencilOp(fail))
5505 {
Jamie Madille0472f32018-11-27 16:32:45 -05005506 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005507 return false;
5508 }
5509
5510 if (!IsValidStencilOp(zfail))
5511 {
Jamie Madille0472f32018-11-27 16:32:45 -05005512 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005513 return false;
5514 }
5515
5516 if (!IsValidStencilOp(zpass))
5517 {
Jamie Madille0472f32018-11-27 16:32:45 -05005518 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005519 return false;
5520 }
5521
5522 return true;
5523}
5524
Jamie Madill5b772312018-03-08 20:28:32 -05005525bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005526 GLenum face,
5527 GLenum fail,
5528 GLenum zfail,
5529 GLenum zpass)
5530{
5531 if (!IsValidStencilFace(face))
5532 {
Jamie Madille0472f32018-11-27 16:32:45 -05005533 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005534 return false;
5535 }
5536
5537 return ValidateStencilOp(context, fail, zfail, zpass);
5538}
5539
Jamie Madill5b772312018-03-08 20:28:32 -05005540bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005541{
5542 return ValidateUniform(context, GL_FLOAT, location, 1);
5543}
5544
Jamie Madill5b772312018-03-08 20:28:32 -05005545bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005546{
5547 return ValidateUniform(context, GL_FLOAT, location, count);
5548}
5549
Jamie Madill5b772312018-03-08 20:28:32 -05005550bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005551{
5552 return ValidateUniform1iv(context, location, 1, &x);
5553}
5554
Jamie Madill5b772312018-03-08 20:28:32 -05005555bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005556{
5557 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5558}
5559
Jamie Madill5b772312018-03-08 20:28:32 -05005560bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005561{
5562 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5563}
5564
Jamie Madill5b772312018-03-08 20:28:32 -05005565bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005566{
5567 return ValidateUniform(context, GL_INT_VEC2, location, count);
5568}
5569
Jamie Madill5b772312018-03-08 20:28:32 -05005570bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005571{
5572 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5573}
5574
Jamie Madill5b772312018-03-08 20:28:32 -05005575bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005576{
5577 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5578}
5579
Jamie Madill5b772312018-03-08 20:28:32 -05005580bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005581{
5582 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5583}
5584
Jamie Madill5b772312018-03-08 20:28:32 -05005585bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005586{
5587 return ValidateUniform(context, GL_INT_VEC3, location, count);
5588}
5589
Jamie Madill5b772312018-03-08 20:28:32 -05005590bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005591{
5592 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5593}
5594
Jamie Madill5b772312018-03-08 20:28:32 -05005595bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005596{
5597 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5598}
5599
Jamie Madill5b772312018-03-08 20:28:32 -05005600bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005601{
5602 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5603}
5604
Jamie Madill5b772312018-03-08 20:28:32 -05005605bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005606{
5607 return ValidateUniform(context, GL_INT_VEC4, location, count);
5608}
5609
Jamie Madill5b772312018-03-08 20:28:32 -05005610bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005611 GLint location,
5612 GLsizei count,
5613 GLboolean transpose,
5614 const GLfloat *value)
5615{
5616 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5617}
5618
Jamie Madill5b772312018-03-08 20:28:32 -05005619bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005620 GLint location,
5621 GLsizei count,
5622 GLboolean transpose,
5623 const GLfloat *value)
5624{
5625 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5626}
5627
Jamie Madill5b772312018-03-08 20:28:32 -05005628bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005629 GLint location,
5630 GLsizei count,
5631 GLboolean transpose,
5632 const GLfloat *value)
5633{
5634 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5635}
5636
Jamie Madill5b772312018-03-08 20:28:32 -05005637bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005638{
5639 Program *programObject = GetValidProgram(context, program);
5640
5641 if (!programObject)
5642 {
5643 return false;
5644 }
5645
5646 return true;
5647}
5648
Jamie Madill5b772312018-03-08 20:28:32 -05005649bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005650{
5651 return ValidateVertexAttribIndex(context, index);
5652}
5653
Jamie Madill5b772312018-03-08 20:28:32 -05005654bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005655{
5656 return ValidateVertexAttribIndex(context, index);
5657}
5658
Jamie Madill5b772312018-03-08 20:28:32 -05005659bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005660{
5661 return ValidateVertexAttribIndex(context, index);
5662}
5663
Jamie Madill5b772312018-03-08 20:28:32 -05005664bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005665{
5666 return ValidateVertexAttribIndex(context, index);
5667}
5668
Jamie Madill5b772312018-03-08 20:28:32 -05005669bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005670{
5671 return ValidateVertexAttribIndex(context, index);
5672}
5673
Jamie Madill5b772312018-03-08 20:28:32 -05005674bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005675{
5676 return ValidateVertexAttribIndex(context, index);
5677}
5678
Jamie Madill5b772312018-03-08 20:28:32 -05005679bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005680 GLuint index,
5681 GLfloat x,
5682 GLfloat y,
5683 GLfloat z,
5684 GLfloat w)
5685{
5686 return ValidateVertexAttribIndex(context, index);
5687}
5688
Jamie Madill5b772312018-03-08 20:28:32 -05005689bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005690{
5691 return ValidateVertexAttribIndex(context, index);
5692}
5693
Jamie Madill5b772312018-03-08 20:28:32 -05005694bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005695{
5696 if (width < 0 || height < 0)
5697 {
Jamie Madille0472f32018-11-27 16:32:45 -05005698 context->validationError(GL_INVALID_VALUE, kViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005699 return false;
5700 }
5701
5702 return true;
5703}
5704
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005705bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005706 GLenum target,
5707 GLenum attachment,
5708 GLenum pname,
5709 GLint *params)
5710{
5711 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5712 nullptr);
5713}
5714
Jamie Madill5b772312018-03-08 20:28:32 -05005715bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04005716{
5717 return ValidateGetProgramivBase(context, program, pname, nullptr);
5718}
5719
Jamie Madill5b772312018-03-08 20:28:32 -05005720bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005721 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005722 GLint level,
5723 GLenum internalformat,
5724 GLint x,
5725 GLint y,
5726 GLsizei width,
5727 GLsizei height,
5728 GLint border)
5729{
5730 if (context->getClientMajorVersion() < 3)
5731 {
5732 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5733 0, x, y, width, height, border);
5734 }
5735
5736 ASSERT(context->getClientMajorVersion() == 3);
5737 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5738 0, x, y, width, height, border);
5739}
5740
5741bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005742 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005743 GLint level,
5744 GLint xoffset,
5745 GLint yoffset,
5746 GLint x,
5747 GLint y,
5748 GLsizei width,
5749 GLsizei height)
5750{
5751 if (context->getClientMajorVersion() < 3)
5752 {
5753 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5754 yoffset, x, y, width, height, 0);
5755 }
5756
5757 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5758 yoffset, 0, x, y, width, height, 0);
5759}
5760
5761bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5762{
5763 return ValidateGenOrDelete(context, n);
5764}
5765
5766bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5767{
5768 return ValidateGenOrDelete(context, n);
5769}
5770
5771bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5772{
5773 return ValidateGenOrDelete(context, n);
5774}
5775
5776bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5777{
5778 return ValidateGenOrDelete(context, n);
5779}
5780
5781bool ValidateDisable(Context *context, GLenum cap)
5782{
5783 if (!ValidCap(context, cap, false))
5784 {
Jamie Madille0472f32018-11-27 16:32:45 -05005785 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005786 return false;
5787 }
5788
5789 return true;
5790}
5791
5792bool ValidateEnable(Context *context, GLenum cap)
5793{
5794 if (!ValidCap(context, cap, false))
5795 {
Jamie Madille0472f32018-11-27 16:32:45 -05005796 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005797 return false;
5798 }
5799
5800 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5801 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5802 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005803 context->validationError(GL_INVALID_OPERATION, kNoSampleAlphaToCoveragesLimitation);
Jamie Madillbe849e42017-05-02 15:49:00 -04005804
5805 // We also output an error message to the debugger window if tracing is active, so that
5806 // developers can see the error message.
Jamie Madillc3e37312018-11-30 15:25:39 -05005807 ERR() << kNoSampleAlphaToCoveragesLimitation;
Jamie Madillbe849e42017-05-02 15:49:00 -04005808 return false;
5809 }
5810
5811 return true;
5812}
5813
5814bool ValidateFramebufferRenderbuffer(Context *context,
5815 GLenum target,
5816 GLenum attachment,
5817 GLenum renderbuffertarget,
5818 GLuint renderbuffer)
5819{
Geoff Lange8afa902017-09-27 15:00:43 -04005820 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005821 {
Jamie Madille0472f32018-11-27 16:32:45 -05005822 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Brandon Jones6cad5662017-06-14 13:25:13 -07005823 return false;
5824 }
5825
5826 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5827 {
Jamie Madille0472f32018-11-27 16:32:45 -05005828 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005829 return false;
5830 }
5831
5832 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5833 renderbuffertarget, renderbuffer);
5834}
5835
5836bool ValidateFramebufferTexture2D(Context *context,
5837 GLenum target,
5838 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005839 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04005840 GLuint texture,
5841 GLint level)
5842{
5843 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5844 // extension
5845 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5846 level != 0)
5847 {
Jamie Madille0472f32018-11-27 16:32:45 -05005848 context->validationError(GL_INVALID_VALUE, kInvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005849 return false;
5850 }
5851
5852 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5853 {
5854 return false;
5855 }
5856
5857 if (texture != 0)
5858 {
5859 gl::Texture *tex = context->getTexture(texture);
5860 ASSERT(tex);
5861
5862 const gl::Caps &caps = context->getCaps();
5863
5864 switch (textarget)
5865 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005866 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04005867 {
5868 if (level > gl::log2(caps.max2DTextureSize))
5869 {
Jamie Madille0472f32018-11-27 16:32:45 -05005870 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005871 return false;
5872 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005873 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04005874 {
Jamie Madille0472f32018-11-27 16:32:45 -05005875 context->validationError(GL_INVALID_OPERATION, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005876 return false;
5877 }
5878 }
5879 break;
5880
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005881 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005882 {
5883 if (level != 0)
5884 {
Jamie Madille0472f32018-11-27 16:32:45 -05005885 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005886 return false;
5887 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005888 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005889 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005890 context->validationError(GL_INVALID_OPERATION, kTextureTargetMismatch);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005891 return false;
5892 }
5893 }
5894 break;
5895
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005896 case TextureTarget::CubeMapNegativeX:
5897 case TextureTarget::CubeMapNegativeY:
5898 case TextureTarget::CubeMapNegativeZ:
5899 case TextureTarget::CubeMapPositiveX:
5900 case TextureTarget::CubeMapPositiveY:
5901 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04005902 {
5903 if (level > gl::log2(caps.maxCubeMapTextureSize))
5904 {
Jamie Madille0472f32018-11-27 16:32:45 -05005905 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005906 return false;
5907 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005908 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04005909 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005910 context->validationError(GL_INVALID_OPERATION, kTextureTargetMismatch);
Jamie Madillbe849e42017-05-02 15:49:00 -04005911 return false;
5912 }
5913 }
5914 break;
5915
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005916 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04005917 {
Yizhou Jiang7818a852018-09-06 15:02:04 +08005918 if (context->getClientVersion() < ES_3_1 &&
5919 !context->getExtensions().textureMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04005920 {
Jamie Madill610640f2018-11-21 17:28:41 -05005921 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05005922 kMultisampleTextureExtensionOrES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04005923 return false;
5924 }
5925
5926 if (level != 0)
5927 {
Jamie Madille0472f32018-11-27 16:32:45 -05005928 context->validationError(GL_INVALID_VALUE, kLevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04005929 return false;
5930 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005931 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04005932 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005933 context->validationError(GL_INVALID_OPERATION, kTextureTargetMismatch);
Jamie Madillbe849e42017-05-02 15:49:00 -04005934 return false;
5935 }
5936 }
5937 break;
5938
5939 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005940 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005941 return false;
5942 }
Jamie Madillbe849e42017-05-02 15:49:00 -04005943 }
5944
5945 return true;
5946}
5947
5948bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
5949{
5950 return ValidateGenOrDelete(context, n);
5951}
5952
5953bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
5954{
5955 return ValidateGenOrDelete(context, n);
5956}
5957
5958bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
5959{
5960 return ValidateGenOrDelete(context, n);
5961}
5962
5963bool ValidateGenTextures(Context *context, GLint n, GLuint *)
5964{
5965 return ValidateGenOrDelete(context, n);
5966}
5967
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005968bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04005969{
5970 if (!ValidTextureTarget(context, target))
5971 {
Jamie Madille0472f32018-11-27 16:32:45 -05005972 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005973 return false;
5974 }
5975
5976 Texture *texture = context->getTargetTexture(target);
5977
5978 if (texture == nullptr)
5979 {
Jamie Madille0472f32018-11-27 16:32:45 -05005980 context->validationError(GL_INVALID_OPERATION, kTextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005981 return false;
5982 }
5983
5984 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
5985
5986 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
5987 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
5988 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
5989 {
Jamie Madille0472f32018-11-27 16:32:45 -05005990 context->validationError(GL_INVALID_OPERATION, kBaseLevelOutOfRange);
Jamie Madillbe849e42017-05-02 15:49:00 -04005991 return false;
5992 }
5993
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005994 TextureTarget baseTarget = (target == TextureType::CubeMap)
5995 ? TextureTarget::CubeMapPositiveX
5996 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04005997 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
5998 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
5999 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006000 {
Jamie Madille0472f32018-11-27 16:32:45 -05006001 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Brandon Jones6cad5662017-06-14 13:25:13 -07006002 return false;
6003 }
6004
Geoff Lang536eca12017-09-13 11:23:35 -04006005 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6006 bool formatUnsized = !format.sized;
6007 bool formatColorRenderableAndFilterable =
6008 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
Yuly Novikovf15f8862018-06-04 18:59:41 -04006009 format.textureAttachmentSupport(context->getClientVersion(), context->getExtensions());
Geoff Lang536eca12017-09-13 11:23:35 -04006010 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006011 {
Jamie Madille0472f32018-11-27 16:32:45 -05006012 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006013 return false;
6014 }
6015
Geoff Lang536eca12017-09-13 11:23:35 -04006016 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6017 // generation
6018 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6019 {
Jamie Madille0472f32018-11-27 16:32:45 -05006020 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Geoff Lang536eca12017-09-13 11:23:35 -04006021 return false;
6022 }
6023
Jiange2c00842018-07-13 16:50:49 +08006024 // According to the OpenGL extension spec EXT_sRGB.txt, EXT_SRGB is based on ES 2.0 and
6025 // generateMipmap is not allowed if texture format is SRGB_EXT or SRGB_ALPHA_EXT.
6026 if (context->getClientVersion() < Version(3, 0) && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006027 {
Jamie Madille0472f32018-11-27 16:32:45 -05006028 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006029 return false;
6030 }
6031
6032 // Non-power of 2 ES2 check
6033 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6034 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6035 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6036 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006037 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6038 target == TextureType::CubeMap);
Jamie Madille0472f32018-11-27 16:32:45 -05006039 context->validationError(GL_INVALID_OPERATION, kTextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006040 return false;
6041 }
6042
6043 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006044 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006045 {
Jamie Madille0472f32018-11-27 16:32:45 -05006046 context->validationError(GL_INVALID_OPERATION, kCubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006047 return false;
6048 }
6049
James Darpinian83b2f0e2018-11-27 15:56:01 -08006050 if (context->getExtensions().webglCompatibility &&
6051 (texture->getWidth(baseTarget, effectiveBaseLevel) == 0 ||
6052 texture->getHeight(baseTarget, effectiveBaseLevel) == 0))
6053 {
6054 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapZeroSize);
6055 return false;
6056 }
6057
Jamie Madillbe849e42017-05-02 15:49:00 -04006058 return true;
6059}
6060
Jamie Madill5b772312018-03-08 20:28:32 -05006061bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006062 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006063 GLenum pname,
6064 GLint *params)
6065{
6066 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6067}
6068
6069bool ValidateGetRenderbufferParameteriv(Context *context,
6070 GLenum target,
6071 GLenum pname,
6072 GLint *params)
6073{
6074 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6075}
6076
6077bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6078{
6079 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6080}
6081
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006082bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006083{
6084 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6085}
6086
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006087bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006088{
6089 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6090}
6091
Till Rathmannb8543632018-10-02 19:46:14 +02006092bool ValidateGetTexParameterIivOES(Context *context,
6093 TextureType target,
6094 GLenum pname,
6095 GLint *params)
6096{
6097 if (context->getClientMajorVersion() < 3)
6098 {
Jamie Madille0472f32018-11-27 16:32:45 -05006099 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006100 return false;
6101 }
6102 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6103}
6104
6105bool ValidateGetTexParameterIuivOES(Context *context,
6106 TextureType target,
6107 GLenum pname,
6108 GLuint *params)
6109{
6110 if (context->getClientMajorVersion() < 3)
6111 {
Jamie Madille0472f32018-11-27 16:32:45 -05006112 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006113 return false;
6114 }
6115 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6116}
6117
Jamie Madillbe849e42017-05-02 15:49:00 -04006118bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6119{
6120 return ValidateGetUniformBase(context, program, location);
6121}
6122
6123bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6124{
6125 return ValidateGetUniformBase(context, program, location);
6126}
6127
6128bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6129{
6130 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6131}
6132
6133bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6134{
6135 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6136}
6137
6138bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6139{
6140 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6141}
6142
6143bool ValidateIsEnabled(Context *context, GLenum cap)
6144{
6145 if (!ValidCap(context, cap, true))
6146 {
Jamie Madille0472f32018-11-27 16:32:45 -05006147 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006148 return false;
6149 }
6150
6151 return true;
6152}
6153
6154bool ValidateLinkProgram(Context *context, GLuint program)
6155{
6156 if (context->hasActiveTransformFeedback(program))
6157 {
6158 // ES 3.0.4 section 2.15 page 91
Jamie Madillc3e37312018-11-30 15:25:39 -05006159 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackActiveDuringLink);
Jamie Madillbe849e42017-05-02 15:49:00 -04006160 return false;
6161 }
6162
6163 Program *programObject = GetValidProgram(context, program);
6164 if (!programObject)
6165 {
6166 return false;
6167 }
6168
6169 return true;
6170}
6171
Jamie Madill4928b7c2017-06-20 12:57:39 -04006172bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006173 GLint x,
6174 GLint y,
6175 GLsizei width,
6176 GLsizei height,
6177 GLenum format,
6178 GLenum type,
6179 void *pixels)
6180{
6181 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6182 nullptr, pixels);
6183}
6184
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006185bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006186{
Till Rathmannb8543632018-10-02 19:46:14 +02006187 return ValidateTexParameterBase(context, target, pname, -1, false, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006188}
6189
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006190bool ValidateTexParameterfv(Context *context,
6191 TextureType target,
6192 GLenum pname,
6193 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006194{
Till Rathmannb8543632018-10-02 19:46:14 +02006195 return ValidateTexParameterBase(context, target, pname, -1, true, params);
Jamie Madillbe849e42017-05-02 15:49:00 -04006196}
6197
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006198bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006199{
Till Rathmannb8543632018-10-02 19:46:14 +02006200 return ValidateTexParameterBase(context, target, pname, -1, false, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006201}
6202
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006203bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006204{
Till Rathmannb8543632018-10-02 19:46:14 +02006205 return ValidateTexParameterBase(context, target, pname, -1, true, params);
6206}
6207
6208bool ValidateTexParameterIivOES(Context *context,
6209 TextureType target,
6210 GLenum pname,
6211 const GLint *params)
6212{
6213 if (context->getClientMajorVersion() < 3)
6214 {
Jamie Madille0472f32018-11-27 16:32:45 -05006215 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006216 return false;
6217 }
6218 return ValidateTexParameterBase(context, target, pname, -1, true, params);
6219}
6220
6221bool ValidateTexParameterIuivOES(Context *context,
6222 TextureType target,
6223 GLenum pname,
6224 const GLuint *params)
6225{
6226 if (context->getClientMajorVersion() < 3)
6227 {
Jamie Madille0472f32018-11-27 16:32:45 -05006228 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006229 return false;
6230 }
6231 return ValidateTexParameterBase(context, target, pname, -1, true, params);
Jamie Madillbe849e42017-05-02 15:49:00 -04006232}
6233
6234bool ValidateUseProgram(Context *context, GLuint program)
6235{
6236 if (program != 0)
6237 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04006238 Program *programObject = context->getProgramResolveLink(program);
Jamie Madillbe849e42017-05-02 15:49:00 -04006239 if (!programObject)
6240 {
6241 // ES 3.1.0 section 7.3 page 72
6242 if (context->getShader(program))
6243 {
Jamie Madille0472f32018-11-27 16:32:45 -05006244 context->validationError(GL_INVALID_OPERATION, kExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006245 return false;
6246 }
6247 else
6248 {
Jamie Madille0472f32018-11-27 16:32:45 -05006249 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006250 return false;
6251 }
6252 }
6253 if (!programObject->isLinked())
6254 {
Jamie Madille0472f32018-11-27 16:32:45 -05006255 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006256 return false;
6257 }
6258 }
Jamie Madillc3dc5d42018-12-30 12:12:04 -05006259 if (context->getState().isTransformFeedbackActiveUnpaused())
Jamie Madillbe849e42017-05-02 15:49:00 -04006260 {
6261 // ES 3.0.4 section 2.15 page 91
Jamie Madillc3e37312018-11-30 15:25:39 -05006262 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackUseProgram);
Jamie Madillbe849e42017-05-02 15:49:00 -04006263 return false;
6264 }
6265
6266 return true;
6267}
6268
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006269bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6270{
6271 if (!context->getExtensions().fence)
6272 {
Jamie Madille0472f32018-11-27 16:32:45 -05006273 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006274 return false;
6275 }
6276
6277 if (n < 0)
6278 {
Jamie Madille0472f32018-11-27 16:32:45 -05006279 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006280 return false;
6281 }
6282
6283 return true;
6284}
6285
6286bool ValidateFinishFenceNV(Context *context, GLuint fence)
6287{
6288 if (!context->getExtensions().fence)
6289 {
Jamie Madille0472f32018-11-27 16:32:45 -05006290 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006291 return false;
6292 }
6293
6294 FenceNV *fenceObject = context->getFenceNV(fence);
6295
6296 if (fenceObject == nullptr)
6297 {
Jamie Madille0472f32018-11-27 16:32:45 -05006298 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006299 return false;
6300 }
6301
6302 if (!fenceObject->isSet())
6303 {
Jamie Madille0472f32018-11-27 16:32:45 -05006304 context->validationError(GL_INVALID_OPERATION, kInvalidFenceState);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006305 return false;
6306 }
6307
6308 return true;
6309}
6310
6311bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6312{
6313 if (!context->getExtensions().fence)
6314 {
Jamie Madille0472f32018-11-27 16:32:45 -05006315 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006316 return false;
6317 }
6318
6319 if (n < 0)
6320 {
Jamie Madille0472f32018-11-27 16:32:45 -05006321 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006322 return false;
6323 }
6324
6325 return true;
6326}
6327
6328bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6329{
6330 if (!context->getExtensions().fence)
6331 {
Jamie Madille0472f32018-11-27 16:32:45 -05006332 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006333 return false;
6334 }
6335
6336 FenceNV *fenceObject = context->getFenceNV(fence);
6337
6338 if (fenceObject == nullptr)
6339 {
Jamie Madille0472f32018-11-27 16:32:45 -05006340 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006341 return false;
6342 }
6343
6344 if (!fenceObject->isSet())
6345 {
Jamie Madille0472f32018-11-27 16:32:45 -05006346 context->validationError(GL_INVALID_OPERATION, kInvalidFenceState);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006347 return false;
6348 }
6349
6350 switch (pname)
6351 {
6352 case GL_FENCE_STATUS_NV:
6353 case GL_FENCE_CONDITION_NV:
6354 break;
6355
6356 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006357 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006358 return false;
6359 }
6360
6361 return true;
6362}
6363
6364bool ValidateGetGraphicsResetStatusEXT(Context *context)
6365{
6366 if (!context->getExtensions().robustness)
6367 {
Jamie Madille0472f32018-11-27 16:32:45 -05006368 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006369 return false;
6370 }
6371
6372 return true;
6373}
6374
6375bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6376 GLuint shader,
6377 GLsizei bufsize,
6378 GLsizei *length,
6379 GLchar *source)
6380{
6381 if (!context->getExtensions().translatedShaderSource)
6382 {
Jamie Madille0472f32018-11-27 16:32:45 -05006383 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006384 return false;
6385 }
6386
6387 if (bufsize < 0)
6388 {
Jamie Madille0472f32018-11-27 16:32:45 -05006389 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006390 return false;
6391 }
6392
6393 Shader *shaderObject = context->getShader(shader);
6394
6395 if (!shaderObject)
6396 {
Jamie Madille0472f32018-11-27 16:32:45 -05006397 context->validationError(GL_INVALID_OPERATION, kInvalidShaderName);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006398 return false;
6399 }
6400
6401 return true;
6402}
6403
6404bool ValidateIsFenceNV(Context *context, GLuint fence)
6405{
6406 if (!context->getExtensions().fence)
6407 {
Jamie Madille0472f32018-11-27 16:32:45 -05006408 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006409 return false;
6410 }
6411
6412 return true;
6413}
6414
Jamie Madill007530e2017-12-28 14:27:04 -05006415bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6416{
6417 if (!context->getExtensions().fence)
6418 {
Jamie Madille0472f32018-11-27 16:32:45 -05006419 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill007530e2017-12-28 14:27:04 -05006420 return false;
6421 }
6422
6423 if (condition != GL_ALL_COMPLETED_NV)
6424 {
Jamie Madille0472f32018-11-27 16:32:45 -05006425 context->validationError(GL_INVALID_ENUM, kInvalidFenceCondition);
Jamie Madill007530e2017-12-28 14:27:04 -05006426 return false;
6427 }
6428
6429 FenceNV *fenceObject = context->getFenceNV(fence);
6430
6431 if (fenceObject == nullptr)
6432 {
Jamie Madille0472f32018-11-27 16:32:45 -05006433 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill007530e2017-12-28 14:27:04 -05006434 return false;
6435 }
6436
6437 return true;
6438}
6439
6440bool ValidateTestFenceNV(Context *context, GLuint fence)
6441{
6442 if (!context->getExtensions().fence)
6443 {
Jamie Madille0472f32018-11-27 16:32:45 -05006444 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill007530e2017-12-28 14:27:04 -05006445 return false;
6446 }
6447
6448 FenceNV *fenceObject = context->getFenceNV(fence);
6449
6450 if (fenceObject == nullptr)
6451 {
Jamie Madille0472f32018-11-27 16:32:45 -05006452 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill007530e2017-12-28 14:27:04 -05006453 return false;
6454 }
6455
6456 if (fenceObject->isSet() != GL_TRUE)
6457 {
Jamie Madille0472f32018-11-27 16:32:45 -05006458 context->validationError(GL_INVALID_OPERATION, kInvalidFenceState);
Jamie Madill007530e2017-12-28 14:27:04 -05006459 return false;
6460 }
6461
6462 return true;
6463}
6464
6465bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006466 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006467 GLsizei levels,
6468 GLenum internalformat,
6469 GLsizei width,
6470 GLsizei height)
6471{
6472 if (!context->getExtensions().textureStorage)
6473 {
Jamie Madille0472f32018-11-27 16:32:45 -05006474 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05006475 return false;
6476 }
6477
6478 if (context->getClientMajorVersion() < 3)
6479 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006480 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006481 height);
6482 }
6483
6484 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006485 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006486 1);
6487}
6488
6489bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6490{
6491 if (!context->getExtensions().instancedArrays)
6492 {
Jamie Madille0472f32018-11-27 16:32:45 -05006493 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05006494 return false;
6495 }
6496
6497 if (index >= MAX_VERTEX_ATTRIBS)
6498 {
Jamie Madille0472f32018-11-27 16:32:45 -05006499 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madill007530e2017-12-28 14:27:04 -05006500 return false;
6501 }
6502
6503 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6504 {
6505 if (index == 0 && divisor != 0)
6506 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006507 context->validationError(GL_INVALID_OPERATION, kAttributeZeroRequiresDivisorLimitation);
Jamie Madill007530e2017-12-28 14:27:04 -05006508
6509 // We also output an error message to the debugger window if tracing is active, so
6510 // that developers can see the error message.
Jamie Madillc3e37312018-11-30 15:25:39 -05006511 ERR() << kAttributeZeroRequiresDivisorLimitation;
Jamie Madill007530e2017-12-28 14:27:04 -05006512 return false;
6513 }
6514 }
6515
6516 return true;
6517}
6518
6519bool ValidateTexImage3DOES(Context *context,
6520 GLenum target,
6521 GLint level,
6522 GLenum internalformat,
6523 GLsizei width,
6524 GLsizei height,
6525 GLsizei depth,
6526 GLint border,
6527 GLenum format,
6528 GLenum type,
6529 const void *pixels)
6530{
6531 UNIMPLEMENTED(); // FIXME
6532 return false;
6533}
6534
6535bool ValidatePopGroupMarkerEXT(Context *context)
6536{
6537 if (!context->getExtensions().debugMarker)
6538 {
6539 // The debug marker calls should not set error state
6540 // However, it seems reasonable to set an error state if the extension is not enabled
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 return true;
6546}
6547
Jamie Madillfa920eb2018-01-04 11:45:50 -05006548bool ValidateTexStorage1DEXT(Context *context,
6549 GLenum target,
6550 GLsizei levels,
6551 GLenum internalformat,
6552 GLsizei width)
6553{
6554 UNIMPLEMENTED();
Jamie Madille0472f32018-11-27 16:32:45 -05006555 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05006556 return false;
6557}
6558
6559bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006560 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006561 GLsizei levels,
6562 GLenum internalformat,
6563 GLsizei width,
6564 GLsizei height,
6565 GLsizei depth)
6566{
6567 if (!context->getExtensions().textureStorage)
6568 {
Jamie Madille0472f32018-11-27 16:32:45 -05006569 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05006570 return false;
6571 }
6572
6573 if (context->getClientMajorVersion() < 3)
6574 {
Jamie Madille0472f32018-11-27 16:32:45 -05006575 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05006576 return false;
6577 }
6578
6579 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6580 depth);
6581}
6582
jchen1082af6202018-06-22 10:59:52 +08006583bool ValidateMaxShaderCompilerThreadsKHR(Context *context, GLuint count)
6584{
6585 if (!context->getExtensions().parallelShaderCompile)
6586 {
Jamie Madille0472f32018-11-27 16:32:45 -05006587 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
jchen1082af6202018-06-22 10:59:52 +08006588 return false;
6589 }
6590 return true;
6591}
6592
Austin Eng1bf18ce2018-10-19 15:34:02 -07006593bool ValidateMultiDrawArraysANGLE(Context *context,
6594 PrimitiveMode mode,
6595 const GLint *firsts,
6596 const GLsizei *counts,
6597 GLsizei drawcount)
6598{
6599 if (!context->getExtensions().multiDraw)
6600 {
Jamie Madille0472f32018-11-27 16:32:45 -05006601 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07006602 return false;
6603 }
6604 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
6605 {
6606 if (!ValidateDrawArrays(context, mode, firsts[drawID], counts[drawID]))
6607 {
6608 return false;
6609 }
6610 }
6611 return true;
6612}
6613
6614bool ValidateMultiDrawElementsANGLE(Context *context,
6615 PrimitiveMode mode,
6616 const GLsizei *counts,
Jamie Madill8dc27f92018-11-29 11:45:44 -05006617 DrawElementsType type,
Austin Eng3b7c9d02018-11-21 18:09:05 -08006618 const GLvoid *const *indices,
Austin Eng1bf18ce2018-10-19 15:34:02 -07006619 GLsizei drawcount)
6620{
6621 if (!context->getExtensions().multiDraw)
6622 {
Jamie Madille0472f32018-11-27 16:32:45 -05006623 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07006624 return false;
6625 }
6626 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
6627 {
Austin Eng3b7c9d02018-11-21 18:09:05 -08006628 if (!ValidateDrawElements(context, mode, counts[drawID], type, indices[drawID]))
Austin Eng1bf18ce2018-10-19 15:34:02 -07006629 {
6630 return false;
6631 }
6632 }
6633 return true;
6634}
6635
Jeff Gilbert465d6092019-01-02 16:21:18 -08006636bool ValidateProvokingVertexANGLE(Context *context, ProvokingVertex modePacked)
6637{
6638 if (!context->getExtensions().provokingVertex)
6639 {
6640 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
6641 return false;
6642 }
6643
6644 switch (modePacked)
6645 {
6646 case ProvokingVertex::FirstVertexConvention:
6647 case ProvokingVertex::LastVertexConvention:
6648 break;
6649 default:
6650 context->validationError(GL_INVALID_ENUM, kInvalidProvokingVertex);
6651 return false;
6652 }
6653
6654 return true;
6655}
6656
Jamie Madillc29968b2016-01-20 11:17:23 -05006657} // namespace gl