blob: 2b1afed7187cf293d3b43d7fec935f67fed5d896 [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{
33
Jamie Madillc29968b2016-01-20 11:17:23 -050034namespace
35{
36
37bool IsPartialBlit(gl::Context *context,
38 const FramebufferAttachment *readBuffer,
39 const FramebufferAttachment *writeBuffer,
40 GLint srcX0,
41 GLint srcY0,
42 GLint srcX1,
43 GLint srcY1,
44 GLint dstX0,
45 GLint dstY0,
46 GLint dstX1,
47 GLint dstY1)
48{
49 const Extents &writeSize = writeBuffer->getSize();
50 const Extents &readSize = readBuffer->getSize();
51
52 if (srcX0 != 0 || srcY0 != 0 || dstX0 != 0 || dstY0 != 0 || dstX1 != writeSize.width ||
53 dstY1 != writeSize.height || srcX1 != readSize.width || srcY1 != readSize.height)
54 {
55 return true;
56 }
57
Jamie Madilldfde6ab2016-06-09 07:07:18 -070058 if (context->getGLState().isScissorTestEnabled())
Jamie Madillc29968b2016-01-20 11:17:23 -050059 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -070060 const Rectangle &scissor = context->getGLState().getScissor();
Jamie Madillc29968b2016-01-20 11:17:23 -050061 return scissor.x > 0 || scissor.y > 0 || scissor.width < writeSize.width ||
62 scissor.height < writeSize.height;
63 }
64
65 return false;
66}
67
Sami Väisänend59ca052016-06-21 16:10:00 +030068template <typename T>
69bool ValidatePathInstances(gl::Context *context,
70 GLsizei numPaths,
71 const void *paths,
72 GLuint pathBase)
73{
74 const auto *array = static_cast<const T *>(paths);
75
76 for (GLsizei i = 0; i < numPaths; ++i)
77 {
78 const GLuint pathName = array[i] + pathBase;
Brandon Jones59770802018-04-02 13:18:42 -070079 if (context->isPathGenerated(pathName) && !context->isPath(pathName))
Sami Väisänend59ca052016-06-21 16:10:00 +030080 {
Jamie Madill610640f2018-11-21 17:28:41 -050081 context->validationError(GL_INVALID_OPERATION, kErrorNoSuchPath);
Sami Väisänend59ca052016-06-21 16:10:00 +030082 return false;
83 }
84 }
85 return true;
86}
87
88bool ValidateInstancedPathParameters(gl::Context *context,
89 GLsizei numPaths,
90 GLenum pathNameType,
91 const void *paths,
92 GLuint pathBase,
93 GLenum transformType,
94 const GLfloat *transformValues)
95{
96 if (!context->getExtensions().pathRendering)
97 {
Jamie Madill610640f2018-11-21 17:28:41 -050098 context->validationError(GL_INVALID_OPERATION,
99 "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300100 return false;
101 }
102
103 if (paths == nullptr)
104 {
Jamie Madill610640f2018-11-21 17:28:41 -0500105 context->validationError(GL_INVALID_VALUE, "No path name array.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300106 return false;
107 }
108
109 if (numPaths < 0)
110 {
Jamie Madill610640f2018-11-21 17:28:41 -0500111 context->validationError(GL_INVALID_VALUE, "Invalid (negative) numPaths.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300112 return false;
113 }
114
115 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(numPaths))
116 {
Jamie Madill610640f2018-11-21 17:28:41 -0500117 context->validationError(GL_INVALID_OPERATION, kErrorIntegerOverflow);
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 Madill610640f2018-11-21 17:28:41 -0500163 context->validationError(GL_INVALID_ENUM, "Invalid path name type.");
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 Madill610640f2018-11-21 17:28:41 -0500191 context->validationError(GL_INVALID_ENUM, "Invalid transformation.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300192 return false;
193 }
194 if (componentCount != 0 && transformValues == nullptr)
195 {
Jamie Madill610640f2018-11-21 17:28:41 -0500196 context->validationError(GL_INVALID_VALUE, "No transform array given.");
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 Madill610640f2018-11-21 17:28:41 -0500205 context->validationError(GL_INVALID_OPERATION, kErrorIntegerOverflow);
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 Madill610640f2018-11-21 17:28:41 -0500293 context->validationError(GL_INVALID_OPERATION, kErrorInvalidInternalFormat);
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 Madill610640f2018-11-21 17:28:41 -0500299 context->validationError(GL_INVALID_OPERATION, kErrorMismatchedTypeAndFormat);
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 Madill610640f2018-11-21 17:28:41 -0500306 context->validationError(GL_INVALID_OPERATION, kErrorInvalidInternalFormat);
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 Lang4f0e0032017-05-01 16:04:35 -0400349
Jamie Madillb980c562018-11-27 11:34:27 -0500350 // TODO(geofflang): accept GL_TEXTURE_EXTERNAL_OES if the texture_external extension is
351 // supported
Geoff Lang4f0e0032017-05-01 16:04:35 -0400352
353 default:
354 return false;
355 }
356}
357
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800358bool IsValidCopyTextureSourceLevel(Context *context, TextureType type, GLint level)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400359{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800360 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400361 {
362 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700363 }
364
Geoff Lang4f0e0032017-05-01 16:04:35 -0400365 if (level > 0 && context->getClientVersion() < ES_3_0)
366 {
367 return false;
368 }
Geoff Lang97073d12016-04-20 10:42:34 -0700369
Geoff Lang4f0e0032017-05-01 16:04:35 -0400370 return true;
371}
372
373bool IsValidCopyTextureDestinationLevel(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800374 TextureType type,
Geoff Lang4f0e0032017-05-01 16:04:35 -0400375 GLint level,
376 GLsizei width,
Brandon Jones28783792018-03-05 09:37:32 -0800377 GLsizei height,
378 bool isSubImage)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400379{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800380 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400381 {
382 return false;
383 }
384
Brandon Jones28783792018-03-05 09:37:32 -0800385 if (!ValidImageSizeParameters(context, type, level, width, height, 1, isSubImage))
386 {
387 return false;
388 }
389
Geoff Lang4f0e0032017-05-01 16:04:35 -0400390 const Caps &caps = context->getCaps();
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800391 switch (type)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400392 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800393 case TextureType::_2D:
394 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
395 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
396 case TextureType::Rectangle:
397 ASSERT(level == 0);
398 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
399 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400400
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800401 case TextureType::CubeMap:
402 return static_cast<GLuint>(width) <= (caps.maxCubeMapTextureSize >> level) &&
403 static_cast<GLuint>(height) <= (caps.maxCubeMapTextureSize >> level);
404 default:
405 return true;
406 }
Geoff Lang97073d12016-04-20 10:42:34 -0700407}
408
Jamie Madillc1d770e2017-04-13 17:31:24 -0400409bool IsValidStencilFunc(GLenum func)
410{
411 switch (func)
412 {
413 case GL_NEVER:
414 case GL_ALWAYS:
415 case GL_LESS:
416 case GL_LEQUAL:
417 case GL_EQUAL:
418 case GL_GEQUAL:
419 case GL_GREATER:
420 case GL_NOTEQUAL:
421 return true;
422
423 default:
424 return false;
425 }
426}
427
428bool IsValidStencilFace(GLenum face)
429{
430 switch (face)
431 {
432 case GL_FRONT:
433 case GL_BACK:
434 case GL_FRONT_AND_BACK:
435 return true;
436
437 default:
438 return false;
439 }
440}
441
442bool IsValidStencilOp(GLenum op)
443{
444 switch (op)
445 {
446 case GL_ZERO:
447 case GL_KEEP:
448 case GL_REPLACE:
449 case GL_INCR:
450 case GL_DECR:
451 case GL_INVERT:
452 case GL_INCR_WRAP:
453 case GL_DECR_WRAP:
454 return true;
455
456 default:
457 return false;
458 }
459}
460
Jamie Madill5b772312018-03-08 20:28:32 -0500461bool ValidateES2CopyTexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800462 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -0400463 GLint level,
464 GLenum internalformat,
465 bool isSubImage,
466 GLint xoffset,
467 GLint yoffset,
468 GLint x,
469 GLint y,
470 GLsizei width,
471 GLsizei height,
472 GLint border)
473{
474 if (!ValidTexture2DDestinationTarget(context, target))
475 {
Jamie Madill610640f2018-11-21 17:28:41 -0500476 context->validationError(GL_INVALID_ENUM, kErrorInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -0400477 return false;
478 }
479
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800480 TextureType texType = TextureTargetToType(target);
481 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Jamie Madillbe849e42017-05-02 15:49:00 -0400482 {
Jamie Madill610640f2018-11-21 17:28:41 -0500483 context->validationError(GL_INVALID_VALUE, "Invalid texture dimensions.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400484 return false;
485 }
486
487 Format textureFormat = Format::Invalid();
488 if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
489 xoffset, yoffset, 0, x, y, width, height, border,
490 &textureFormat))
491 {
492 return false;
493 }
494
495 const gl::Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
496 GLenum colorbufferFormat =
497 framebuffer->getReadColorbuffer()->getFormat().info->sizedInternalFormat;
498 const auto &formatInfo = *textureFormat.info;
499
500 // [OpenGL ES 2.0.24] table 3.9
501 if (isSubImage)
502 {
503 switch (formatInfo.format)
504 {
505 case GL_ALPHA:
506 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400507 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
508 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400509 {
Jamie Madill610640f2018-11-21 17:28:41 -0500510 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400511 return false;
512 }
513 break;
514 case GL_LUMINANCE:
515 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
516 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
517 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400518 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGRA8_EXT &&
519 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400520 {
Jamie Madill610640f2018-11-21 17:28:41 -0500521 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400522 return false;
523 }
524 break;
525 case GL_RED_EXT:
526 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
527 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
528 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
529 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_R32F &&
530 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400531 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
532 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400533 {
Jamie Madill610640f2018-11-21 17:28:41 -0500534 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400535 return false;
536 }
537 break;
538 case GL_RG_EXT:
539 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
540 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
541 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
542 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400543 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
544 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400545 {
Jamie Madill610640f2018-11-21 17:28:41 -0500546 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400547 return false;
548 }
549 break;
550 case GL_RGB:
551 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
552 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
553 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400554 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
555 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400556 {
Jamie Madill610640f2018-11-21 17:28:41 -0500557 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400558 return false;
559 }
560 break;
561 case GL_LUMINANCE_ALPHA:
562 case GL_RGBA:
563 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400564 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGBA32F &&
565 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400566 {
Jamie Madill610640f2018-11-21 17:28:41 -0500567 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400568 return false;
569 }
570 break;
571 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
572 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
573 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
574 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
575 case GL_ETC1_RGB8_OES:
576 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
577 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
578 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
579 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
580 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
Olli Etuahof2ed2992018-10-04 13:54:42 +0300581 case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
582 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
583 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
584 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
Jamie Madill610640f2018-11-21 17:28:41 -0500585 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400586 return false;
587 case GL_DEPTH_COMPONENT:
588 case GL_DEPTH_STENCIL_OES:
Jamie Madill610640f2018-11-21 17:28:41 -0500589 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400590 return false;
591 default:
Jamie Madill610640f2018-11-21 17:28:41 -0500592 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400593 return false;
594 }
595
596 if (formatInfo.type == GL_FLOAT && !context->getExtensions().textureFloat)
597 {
Jamie Madill610640f2018-11-21 17:28:41 -0500598 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400599 return false;
600 }
601 }
602 else
603 {
604 switch (internalformat)
605 {
606 case GL_ALPHA:
607 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
608 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
609 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
610 {
Jamie Madill610640f2018-11-21 17:28:41 -0500611 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400612 return false;
613 }
614 break;
615 case GL_LUMINANCE:
616 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
617 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
618 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
619 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
620 colorbufferFormat != GL_BGR5_A1_ANGLEX)
621 {
Jamie Madill610640f2018-11-21 17:28:41 -0500622 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400623 return false;
624 }
625 break;
626 case GL_RED_EXT:
627 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
628 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
629 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
630 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
631 colorbufferFormat != GL_BGR5_A1_ANGLEX)
632 {
Jamie Madill610640f2018-11-21 17:28:41 -0500633 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400634 return false;
635 }
636 break;
637 case GL_RG_EXT:
638 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
639 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
640 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
641 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
642 {
Jamie Madill610640f2018-11-21 17:28:41 -0500643 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400644 return false;
645 }
646 break;
647 case GL_RGB:
648 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
649 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
650 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
651 colorbufferFormat != GL_BGR5_A1_ANGLEX)
652 {
Jamie Madill610640f2018-11-21 17:28:41 -0500653 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400654 return false;
655 }
656 break;
657 case GL_LUMINANCE_ALPHA:
658 case GL_RGBA:
659 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
660 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
661 colorbufferFormat != GL_BGR5_A1_ANGLEX)
662 {
Jamie Madill610640f2018-11-21 17:28:41 -0500663 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400664 return false;
665 }
666 break;
667 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
668 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
669 if (context->getExtensions().textureCompressionDXT1)
670 {
Jamie Madill610640f2018-11-21 17:28:41 -0500671 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400672 return false;
673 }
674 else
675 {
Jamie Madill610640f2018-11-21 17:28:41 -0500676 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400677 return false;
678 }
679 break;
680 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
681 if (context->getExtensions().textureCompressionDXT3)
682 {
Jamie Madill610640f2018-11-21 17:28:41 -0500683 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400684 return false;
685 }
686 else
687 {
Jamie Madill610640f2018-11-21 17:28:41 -0500688 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400689 return false;
690 }
691 break;
692 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
693 if (context->getExtensions().textureCompressionDXT5)
694 {
Jamie Madill610640f2018-11-21 17:28:41 -0500695 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400696 return false;
697 }
698 else
699 {
Jamie Madill610640f2018-11-21 17:28:41 -0500700 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400701 return false;
702 }
703 break;
704 case GL_ETC1_RGB8_OES:
705 if (context->getExtensions().compressedETC1RGB8Texture)
706 {
Jamie Madill610640f2018-11-21 17:28:41 -0500707 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400708 return false;
709 }
710 else
711 {
Jamie Madill610640f2018-11-21 17:28:41 -0500712 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400713 return false;
714 }
715 break;
716 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
717 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
718 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
719 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
720 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
721 if (context->getExtensions().lossyETCDecode)
722 {
Jamie Madill610640f2018-11-21 17:28:41 -0500723 context->validationError(GL_INVALID_OPERATION,
724 "ETC lossy decode formats can't be copied to.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400725 return false;
726 }
727 else
728 {
Jamie Madill610640f2018-11-21 17:28:41 -0500729 context->validationError(GL_INVALID_ENUM,
730 "ANGLE_lossy_etc_decode extension is not supported.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400731 return false;
732 }
733 break;
734 case GL_DEPTH_COMPONENT:
735 case GL_DEPTH_COMPONENT16:
736 case GL_DEPTH_COMPONENT32_OES:
737 case GL_DEPTH_STENCIL_OES:
738 case GL_DEPTH24_STENCIL8_OES:
739 if (context->getExtensions().depthTextures)
740 {
Jamie Madill610640f2018-11-21 17:28:41 -0500741 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400742 return false;
743 }
744 else
745 {
Jamie Madill610640f2018-11-21 17:28:41 -0500746 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400747 return false;
748 }
749 default:
Jamie Madill610640f2018-11-21 17:28:41 -0500750 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400751 return false;
752 }
753 }
754
755 // If width or height is zero, it is a no-op. Return false without setting an error.
756 return (width > 0 && height > 0);
757}
758
759bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
760{
761 switch (cap)
762 {
763 // EXT_multisample_compatibility
764 case GL_MULTISAMPLE_EXT:
765 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
766 return context->getExtensions().multisampleCompatibility;
767
768 case GL_CULL_FACE:
769 case GL_POLYGON_OFFSET_FILL:
770 case GL_SAMPLE_ALPHA_TO_COVERAGE:
771 case GL_SAMPLE_COVERAGE:
772 case GL_SCISSOR_TEST:
773 case GL_STENCIL_TEST:
774 case GL_DEPTH_TEST:
775 case GL_BLEND:
776 case GL_DITHER:
777 return true;
778
779 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
780 case GL_RASTERIZER_DISCARD:
781 return (context->getClientMajorVersion() >= 3);
782
783 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
784 case GL_DEBUG_OUTPUT:
785 return context->getExtensions().debug;
786
787 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
788 return queryOnly && context->getExtensions().bindGeneratesResource;
789
790 case GL_CLIENT_ARRAYS_ANGLE:
791 return queryOnly && context->getExtensions().clientArrays;
792
793 case GL_FRAMEBUFFER_SRGB_EXT:
794 return context->getExtensions().sRGBWriteControl;
795
796 case GL_SAMPLE_MASK:
797 return context->getClientVersion() >= Version(3, 1);
798
Geoff Langb433e872017-10-05 14:01:47 -0400799 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
Jamie Madillbe849e42017-05-02 15:49:00 -0400800 return queryOnly && context->getExtensions().robustResourceInitialization;
801
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700802 // GLES1 emulation: GLES1-specific caps
803 case GL_ALPHA_TEST:
Lingfeng Yang01074432018-04-16 10:19:51 -0700804 case GL_VERTEX_ARRAY:
805 case GL_NORMAL_ARRAY:
806 case GL_COLOR_ARRAY:
807 case GL_TEXTURE_COORD_ARRAY:
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700808 case GL_TEXTURE_2D:
Lingfeng Yangd0febe72018-05-17 22:36:52 -0700809 case GL_LIGHTING:
810 case GL_LIGHT0:
811 case GL_LIGHT1:
812 case GL_LIGHT2:
813 case GL_LIGHT3:
814 case GL_LIGHT4:
815 case GL_LIGHT5:
816 case GL_LIGHT6:
817 case GL_LIGHT7:
818 case GL_NORMALIZE:
819 case GL_RESCALE_NORMAL:
820 case GL_COLOR_MATERIAL:
Lingfeng Yang060088a2018-05-30 20:40:57 -0700821 case GL_CLIP_PLANE0:
822 case GL_CLIP_PLANE1:
823 case GL_CLIP_PLANE2:
824 case GL_CLIP_PLANE3:
825 case GL_CLIP_PLANE4:
826 case GL_CLIP_PLANE5:
Lingfeng Yang7ba3f422018-06-01 09:43:04 -0700827 case GL_FOG:
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700828 case GL_POINT_SMOOTH:
Lingfeng Yang6e5bf362018-08-15 09:53:17 -0700829 case GL_LINE_SMOOTH:
830 case GL_COLOR_LOGIC_OP:
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700831 return context->getClientVersion() < Version(2, 0);
Lingfeng Yang01074432018-04-16 10:19:51 -0700832 case GL_POINT_SIZE_ARRAY_OES:
833 return context->getClientVersion() < Version(2, 0) &&
834 context->getExtensions().pointSizeArray;
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700835 case GL_TEXTURE_CUBE_MAP:
836 return context->getClientVersion() < Version(2, 0) &&
837 context->getExtensions().textureCubeMap;
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700838 case GL_POINT_SPRITE_OES:
839 return context->getClientVersion() < Version(2, 0) &&
840 context->getExtensions().pointSprite;
Jamie Madillbe849e42017-05-02 15:49:00 -0400841 default:
842 return false;
843 }
844}
845
Geoff Langfc32e8b2017-05-31 14:16:59 -0400846// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
847// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400848bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400849{
850 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400851 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
852 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400853 {
854 return true;
855 }
856
857 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
858 if (c >= 9 && c <= 13)
859 {
860 return true;
861 }
862
863 return false;
864}
865
Geoff Langcab92ee2017-07-19 17:32:07 -0400866bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400867{
Geoff Langa71a98e2017-06-19 15:15:00 -0400868 for (size_t i = 0; i < len; i++)
869 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400870 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400871 {
872 return false;
873 }
874 }
875
876 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400877}
878
Geoff Langcab92ee2017-07-19 17:32:07 -0400879bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
880{
881 enum class ParseState
882 {
883 // Have not seen an ASCII non-whitespace character yet on
884 // this line. Possible that we might see a preprocessor
885 // directive.
886 BEGINING_OF_LINE,
887
888 // Have seen at least one ASCII non-whitespace character
889 // on this line.
890 MIDDLE_OF_LINE,
891
892 // Handling a preprocessor directive. Passes through all
893 // characters up to the end of the line. Disables comment
894 // processing.
895 IN_PREPROCESSOR_DIRECTIVE,
896
897 // Handling a single-line comment. The comment text is
898 // replaced with a single space.
899 IN_SINGLE_LINE_COMMENT,
900
901 // Handling a multi-line comment. Newlines are passed
902 // through to preserve line numbers.
903 IN_MULTI_LINE_COMMENT
904 };
905
906 ParseState state = ParseState::BEGINING_OF_LINE;
907 size_t pos = 0;
908
909 while (pos < len)
910 {
911 char c = str[pos];
912 char next = pos + 1 < len ? str[pos + 1] : 0;
913
914 // Check for newlines
915 if (c == '\n' || c == '\r')
916 {
917 if (state != ParseState::IN_MULTI_LINE_COMMENT)
918 {
919 state = ParseState::BEGINING_OF_LINE;
920 }
921
922 pos++;
923 continue;
924 }
925
926 switch (state)
927 {
928 case ParseState::BEGINING_OF_LINE:
929 if (c == ' ')
930 {
931 // Maintain the BEGINING_OF_LINE state until a non-space is seen
932 pos++;
933 }
934 else if (c == '#')
935 {
936 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
937 pos++;
938 }
939 else
940 {
941 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
942 state = ParseState::MIDDLE_OF_LINE;
943 }
944 break;
945
946 case ParseState::MIDDLE_OF_LINE:
947 if (c == '/' && next == '/')
948 {
949 state = ParseState::IN_SINGLE_LINE_COMMENT;
950 pos++;
951 }
952 else if (c == '/' && next == '*')
953 {
954 state = ParseState::IN_MULTI_LINE_COMMENT;
955 pos++;
956 }
957 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
958 {
959 // Skip line continuation characters
960 }
961 else if (!IsValidESSLCharacter(c))
962 {
963 return false;
964 }
965 pos++;
966 break;
967
968 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700969 // Line-continuation characters may not be permitted.
970 // Otherwise, just pass it through. Do not parse comments in this state.
971 if (!lineContinuationAllowed && c == '\\')
972 {
973 return false;
974 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400975 pos++;
976 break;
977
978 case ParseState::IN_SINGLE_LINE_COMMENT:
979 // Line-continuation characters are processed before comment processing.
980 // Advance string if a new line character is immediately behind
981 // line-continuation character.
982 if (c == '\\' && (next == '\n' || next == '\r'))
983 {
984 pos++;
985 }
986 pos++;
987 break;
988
989 case ParseState::IN_MULTI_LINE_COMMENT:
990 if (c == '*' && next == '/')
991 {
992 state = ParseState::MIDDLE_OF_LINE;
993 pos++;
994 }
995 pos++;
996 break;
997 }
998 }
999
1000 return true;
1001}
1002
Jamie Madill5b772312018-03-08 20:28:32 -05001003bool ValidateWebGLNamePrefix(Context *context, const GLchar *name)
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001004{
1005 ASSERT(context->isWebGL());
1006
1007 // WebGL 1.0 [Section 6.16] GLSL Constructs
1008 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
1009 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
1010 {
Jamie Madill610640f2018-11-21 17:28:41 -05001011 context->validationError(GL_INVALID_OPERATION, kErrorWebglBindAttribLocationReservedPrefix);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001012 return false;
1013 }
1014
1015 return true;
1016}
1017
Jamie Madill5b772312018-03-08 20:28:32 -05001018bool ValidateWebGLNameLength(Context *context, size_t length)
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001019{
1020 ASSERT(context->isWebGL());
1021
1022 if (context->isWebGL1() && length > 256)
1023 {
1024 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
1025 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
1026 // locations.
Jamie Madill610640f2018-11-21 17:28:41 -05001027 context->validationError(GL_INVALID_VALUE, kErrorWebglNameLengthLimitExceeded);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001028
1029 return false;
1030 }
1031 else if (length > 1024)
1032 {
1033 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
1034 // uniform and attribute locations.
Jamie Madill610640f2018-11-21 17:28:41 -05001035 context->validationError(GL_INVALID_VALUE, kErrorWebgl2NameLengthLimitExceeded);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001036 return false;
1037 }
1038
1039 return true;
1040}
1041
Jamie Madill007530e2017-12-28 14:27:04 -05001042bool ValidateMatrixMode(Context *context, GLenum matrixMode)
1043{
1044 if (!context->getExtensions().pathRendering)
1045 {
Jamie Madill610640f2018-11-21 17:28:41 -05001046 context->validationError(GL_INVALID_OPERATION,
1047 "GL_CHROMIUM_path_rendering is not available.");
Jamie Madill007530e2017-12-28 14:27:04 -05001048 return false;
1049 }
1050
1051 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
1052 {
Jamie Madill610640f2018-11-21 17:28:41 -05001053 context->validationError(GL_INVALID_ENUM, kErrorInvalidMatrixMode);
Jamie Madill007530e2017-12-28 14:27:04 -05001054 return false;
1055 }
1056 return true;
1057}
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03001058
1059bool ValidBlendFunc(const Context *context, GLenum val)
1060{
1061 const gl::Extensions &ext = context->getExtensions();
1062
1063 // these are always valid for src and dst.
1064 switch (val)
1065 {
1066 case GL_ZERO:
1067 case GL_ONE:
1068 case GL_SRC_COLOR:
1069 case GL_ONE_MINUS_SRC_COLOR:
1070 case GL_DST_COLOR:
1071 case GL_ONE_MINUS_DST_COLOR:
1072 case GL_SRC_ALPHA:
1073 case GL_ONE_MINUS_SRC_ALPHA:
1074 case GL_DST_ALPHA:
1075 case GL_ONE_MINUS_DST_ALPHA:
1076 case GL_CONSTANT_COLOR:
1077 case GL_ONE_MINUS_CONSTANT_COLOR:
1078 case GL_CONSTANT_ALPHA:
1079 case GL_ONE_MINUS_CONSTANT_ALPHA:
1080 return true;
1081
1082 // EXT_blend_func_extended.
1083 case GL_SRC1_COLOR_EXT:
1084 case GL_SRC1_ALPHA_EXT:
1085 case GL_ONE_MINUS_SRC1_COLOR_EXT:
1086 case GL_ONE_MINUS_SRC1_ALPHA_EXT:
1087 case GL_SRC_ALPHA_SATURATE_EXT:
1088 return ext.blendFuncExtended;
1089
1090 default:
1091 return false;
1092 }
1093}
1094
1095bool ValidSrcBlendFunc(const Context *context, GLenum val)
1096{
1097 if (ValidBlendFunc(context, val))
1098 return true;
1099
1100 if (val == GL_SRC_ALPHA_SATURATE)
1101 return true;
1102
1103 return false;
1104}
1105
1106bool ValidDstBlendFunc(const Context *context, GLenum val)
1107{
1108 if (ValidBlendFunc(context, val))
1109 return true;
1110
1111 if (val == GL_SRC_ALPHA_SATURATE)
1112 {
1113 if (context->getClientMajorVersion() >= 3)
1114 return true;
1115 }
1116
1117 return false;
1118}
1119
Jamie Madillac66f982018-10-09 18:30:01 -04001120void RecordBindTextureTypeError(Context *context, TextureType target)
1121{
1122 ASSERT(!context->getStateCache().isValidBindTextureType(target));
1123
1124 switch (target)
1125 {
1126 case TextureType::Rectangle:
1127 ASSERT(!context->getExtensions().textureRectangle);
Jamie Madill610640f2018-11-21 17:28:41 -05001128 context->validationError(GL_INVALID_ENUM,
1129 "Context does not support GL_ANGLE_texture_rectangle");
Jamie Madillac66f982018-10-09 18:30:01 -04001130 break;
1131
1132 case TextureType::_3D:
1133 case TextureType::_2DArray:
1134 ASSERT(context->getClientMajorVersion() < 3);
Jamie Madill610640f2018-11-21 17:28:41 -05001135 context->validationError(GL_INVALID_ENUM, kErrorES3Required);
Jamie Madillac66f982018-10-09 18:30:01 -04001136 break;
1137
1138 case TextureType::_2DMultisample:
Yizhou Jiang7818a852018-09-06 15:02:04 +08001139 ASSERT(context->getClientVersion() < Version(3, 1) &&
1140 !context->getExtensions().textureMultisample);
Jamie Madill610640f2018-11-21 17:28:41 -05001141 context->validationError(GL_INVALID_ENUM,
1142 kErrorMultisampleTextureExtensionOrES31Required);
Jamie Madillac66f982018-10-09 18:30:01 -04001143 break;
1144
1145 case TextureType::_2DMultisampleArray:
1146 ASSERT(!context->getExtensions().textureStorageMultisample2DArray);
Jamie Madill610640f2018-11-21 17:28:41 -05001147 context->validationError(GL_INVALID_ENUM, kErrorMultisampleArrayExtensionRequired);
Jamie Madillac66f982018-10-09 18:30:01 -04001148 break;
1149
1150 case TextureType::External:
1151 ASSERT(!context->getExtensions().eglImageExternal &&
1152 !context->getExtensions().eglStreamConsumerExternal);
Jamie Madill610640f2018-11-21 17:28:41 -05001153 context->validationError(GL_INVALID_ENUM, "External texture extension not enabled");
Jamie Madillac66f982018-10-09 18:30:01 -04001154 break;
1155
1156 default:
Jamie Madill610640f2018-11-21 17:28:41 -05001157 context->validationError(GL_INVALID_ENUM, kErrorInvalidTextureTarget);
Jamie Madillac66f982018-10-09 18:30:01 -04001158 }
1159}
Jamie Madillc29968b2016-01-20 11:17:23 -05001160} // anonymous namespace
1161
Geoff Langff5b2d52016-09-07 11:32:23 -04001162bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001163 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001164 GLint level,
1165 GLenum internalformat,
1166 bool isCompressed,
1167 bool isSubImage,
1168 GLint xoffset,
1169 GLint yoffset,
1170 GLsizei width,
1171 GLsizei height,
1172 GLint border,
1173 GLenum format,
1174 GLenum type,
1175 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001176 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001177{
Jamie Madill6f38f822014-06-06 17:12:20 -04001178 if (!ValidTexture2DDestinationTarget(context, target))
1179 {
Jamie Madill610640f2018-11-21 17:28:41 -05001180 context->validationError(GL_INVALID_ENUM, kErrorInvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001181 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001182 }
1183
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001184 TextureType texType = TextureTargetToType(target);
1185 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001186 {
Jamie Madill610640f2018-11-21 17:28:41 -05001187 // Error already handled.
Geoff Langb1196682014-07-23 13:47:29 -04001188 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001189 }
1190
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001191 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001192 {
Jamie Madill610640f2018-11-21 17:28:41 -05001193 context->validationError(GL_INVALID_VALUE, kErrorInvalidMipLevel);
Brandon Jones6cad5662017-06-14 13:25:13 -07001194 return false;
1195 }
1196
1197 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001198 std::numeric_limits<GLsizei>::max() - yoffset < height)
1199 {
Jamie Madill610640f2018-11-21 17:28:41 -05001200 context->validationError(GL_INVALID_VALUE, kErrorResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001201 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001202 }
1203
Geoff Lang6e898aa2017-06-02 11:17:26 -04001204 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1205 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1206 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1207 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1208 // case.
1209 bool nonEqualFormatsAllowed =
1210 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
1211 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
1212
1213 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001214 {
Jamie Madill610640f2018-11-21 17:28:41 -05001215 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFormatCombination);
Geoff Langb1196682014-07-23 13:47:29 -04001216 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001217 }
1218
Geoff Langaae65a42014-05-26 12:43:44 -04001219 const gl::Caps &caps = context->getCaps();
1220
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001221 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001222 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001223 case TextureType::_2D:
1224 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1225 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1226 {
Jamie Madill610640f2018-11-21 17:28:41 -05001227 context->validationError(GL_INVALID_VALUE, kErrorResourceMaxTextureSize);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001228 return false;
1229 }
1230 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001231
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001232 case TextureType::Rectangle:
1233 ASSERT(level == 0);
1234 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1235 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1236 {
Jamie Madill610640f2018-11-21 17:28:41 -05001237 context->validationError(GL_INVALID_VALUE, kErrorResourceMaxTextureSize);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001238 return false;
1239 }
1240 if (isCompressed)
1241 {
Jamie Madill610640f2018-11-21 17:28:41 -05001242 context->validationError(GL_INVALID_ENUM,
1243 "Rectangle texture cannot have a compressed format.");
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001244 return false;
1245 }
1246 break;
1247
1248 case TextureType::CubeMap:
1249 if (!isSubImage && width != height)
1250 {
Jamie Madill610640f2018-11-21 17:28:41 -05001251 context->validationError(GL_INVALID_VALUE, kErrorCubemapFacesEqualDimensions);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001252 return false;
1253 }
1254
1255 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1256 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1257 {
Jamie Madill610640f2018-11-21 17:28:41 -05001258 context->validationError(GL_INVALID_VALUE, kErrorResourceMaxTextureSize);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001259 return false;
1260 }
1261 break;
1262
1263 default:
Jamie Madill610640f2018-11-21 17:28:41 -05001264 context->validationError(GL_INVALID_ENUM, kErrorInvalidTextureTarget);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001265 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001266 }
1267
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001268 gl::Texture *texture = context->getTargetTexture(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001269 if (!texture)
1270 {
Jamie Madill610640f2018-11-21 17:28:41 -05001271 context->validationError(GL_INVALID_OPERATION, kErrorBufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001272 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001273 }
1274
Geoff Langa9be0dc2014-12-17 12:34:40 -05001275 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001276 {
Geoff Langca271392017-04-05 12:30:00 -04001277 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1278 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001279 {
Jamie Madill610640f2018-11-21 17:28:41 -05001280 context->validationError(GL_INVALID_OPERATION, "Texture level does not exist.");
Geoff Langc51642b2016-11-14 16:18:26 -05001281 return false;
1282 }
1283
Geoff Langa9be0dc2014-12-17 12:34:40 -05001284 if (format != GL_NONE)
1285 {
Geoff Langca271392017-04-05 12:30:00 -04001286 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1287 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001288 {
Jamie Madill610640f2018-11-21 17:28:41 -05001289 context->validationError(GL_INVALID_OPERATION, kErrorTypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001290 return false;
1291 }
1292 }
1293
1294 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1295 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1296 {
Jamie Madill610640f2018-11-21 17:28:41 -05001297 context->validationError(GL_INVALID_VALUE, kErrorOffsetOverflow);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001298 return false;
1299 }
Geoff Langfb052642017-10-24 13:42:09 -04001300
1301 if (width > 0 && height > 0 && pixels == nullptr &&
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001302 context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
Geoff Langfb052642017-10-24 13:42:09 -04001303 {
Jamie Madill610640f2018-11-21 17:28:41 -05001304 context->validationError(GL_INVALID_VALUE, kErrorPixelDataNull);
Geoff Langfb052642017-10-24 13:42:09 -04001305 return false;
1306 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001307 }
1308 else
1309 {
Geoff Lang69cce582015-09-17 13:20:36 -04001310 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001311 {
Jamie Madill610640f2018-11-21 17:28:41 -05001312 context->validationError(GL_INVALID_OPERATION, kErrorTextureIsImmutable);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001313 return false;
1314 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001315 }
1316
1317 // Verify zero border
1318 if (border != 0)
1319 {
Jamie Madill610640f2018-11-21 17:28:41 -05001320 context->validationError(GL_INVALID_VALUE, kErrorInvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001321 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001322 }
1323
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001324 if (isCompressed)
1325 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001326 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001327 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1328 : internalformat;
Geoff Lange88e4542018-05-03 15:05:57 -04001329
1330 const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(actualInternalFormat);
1331
1332 if (!internalFormatInfo.compressed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001333 {
Jamie Madill610640f2018-11-21 17:28:41 -05001334 context->validationError(GL_INVALID_ENUM, kErrorInvalidInternalFormat);
Geoff Lange88e4542018-05-03 15:05:57 -04001335 return false;
1336 }
1337
1338 if (!internalFormatInfo.textureSupport(context->getClientVersion(),
1339 context->getExtensions()))
1340 {
Jamie Madill610640f2018-11-21 17:28:41 -05001341 context->validationError(GL_INVALID_ENUM, kErrorInvalidInternalFormat);
Geoff Lange88e4542018-05-03 15:05:57 -04001342 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001343 }
Geoff Lang966c9402017-04-18 12:38:27 -04001344
1345 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001346 {
Geoff Lange88e4542018-05-03 15:05:57 -04001347 // From the OES_compressed_ETC1_RGB8_texture spec:
1348 // INVALID_OPERATION is generated by CompressedTexSubImage2D, TexSubImage2D, or
1349 // CopyTexSubImage2D if the texture image <level> bound to <target> has internal format
1350 // ETC1_RGB8_OES.
1351 if (actualInternalFormat == GL_ETC1_RGB8_OES)
1352 {
Jamie Madill610640f2018-11-21 17:28:41 -05001353 context->validationError(GL_INVALID_OPERATION, kErrorInvalidInternalFormat);
Geoff Lange88e4542018-05-03 15:05:57 -04001354 return false;
1355 }
1356
Geoff Lang966c9402017-04-18 12:38:27 -04001357 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1358 height, texture->getWidth(target, level),
1359 texture->getHeight(target, level)))
1360 {
Jamie Madill610640f2018-11-21 17:28:41 -05001361 context->validationError(GL_INVALID_OPERATION,
1362 "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001363 return false;
1364 }
1365
1366 if (format != actualInternalFormat)
1367 {
Jamie Madill610640f2018-11-21 17:28:41 -05001368 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001369 return false;
1370 }
1371 }
1372 else
1373 {
1374 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1375 {
Jamie Madill610640f2018-11-21 17:28:41 -05001376 context->validationError(GL_INVALID_OPERATION,
1377 "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001378 return false;
1379 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001380 }
1381 }
1382 else
1383 {
1384 // validate <type> by itself (used as secondary key below)
1385 switch (type)
1386 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001387 case GL_UNSIGNED_BYTE:
1388 case GL_UNSIGNED_SHORT_5_6_5:
1389 case GL_UNSIGNED_SHORT_4_4_4_4:
1390 case GL_UNSIGNED_SHORT_5_5_5_1:
1391 case GL_UNSIGNED_SHORT:
1392 case GL_UNSIGNED_INT:
1393 case GL_UNSIGNED_INT_24_8_OES:
1394 case GL_HALF_FLOAT_OES:
1395 case GL_FLOAT:
1396 break;
1397 default:
Jamie Madill610640f2018-11-21 17:28:41 -05001398 context->validationError(GL_INVALID_ENUM, kErrorInvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001399 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001400 }
1401
1402 // validate <format> + <type> combinations
1403 // - invalid <format> -> sets INVALID_ENUM
1404 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1405 switch (format)
1406 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001407 case GL_ALPHA:
1408 case GL_LUMINANCE:
1409 case GL_LUMINANCE_ALPHA:
1410 switch (type)
1411 {
1412 case GL_UNSIGNED_BYTE:
1413 case GL_FLOAT:
1414 case GL_HALF_FLOAT_OES:
1415 break;
1416 default:
Jamie Madill610640f2018-11-21 17:28:41 -05001417 context->validationError(GL_INVALID_OPERATION,
1418 kErrorMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001419 return false;
1420 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001421 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001422 case GL_RED:
1423 case GL_RG:
1424 if (!context->getExtensions().textureRG)
1425 {
Jamie Madill610640f2018-11-21 17:28:41 -05001426 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001427 return false;
1428 }
1429 switch (type)
1430 {
1431 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001432 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001433 case GL_FLOAT:
1434 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001435 if (!context->getExtensions().textureFloat)
1436 {
Jamie Madill610640f2018-11-21 17:28:41 -05001437 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001438 return false;
1439 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001440 break;
1441 default:
Jamie Madill610640f2018-11-21 17:28:41 -05001442 context->validationError(GL_INVALID_OPERATION,
1443 kErrorMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001444 return false;
1445 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001446 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001447 case GL_RGB:
1448 switch (type)
1449 {
1450 case GL_UNSIGNED_BYTE:
1451 case GL_UNSIGNED_SHORT_5_6_5:
1452 case GL_FLOAT:
1453 case GL_HALF_FLOAT_OES:
1454 break;
1455 default:
Jamie Madill610640f2018-11-21 17:28:41 -05001456 context->validationError(GL_INVALID_OPERATION,
1457 kErrorMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001458 return false;
1459 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001460 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001461 case GL_RGBA:
1462 switch (type)
1463 {
1464 case GL_UNSIGNED_BYTE:
1465 case GL_UNSIGNED_SHORT_4_4_4_4:
1466 case GL_UNSIGNED_SHORT_5_5_5_1:
1467 case GL_FLOAT:
1468 case GL_HALF_FLOAT_OES:
1469 break;
1470 default:
Jamie Madill610640f2018-11-21 17:28:41 -05001471 context->validationError(GL_INVALID_OPERATION,
1472 kErrorMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001473 return false;
1474 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001475 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001476 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001477 if (!context->getExtensions().textureFormatBGRA8888)
1478 {
Jamie Madill610640f2018-11-21 17:28:41 -05001479 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001480 return false;
1481 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001482 switch (type)
1483 {
1484 case GL_UNSIGNED_BYTE:
1485 break;
1486 default:
Jamie Madill610640f2018-11-21 17:28:41 -05001487 context->validationError(GL_INVALID_OPERATION,
1488 kErrorMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001489 return false;
1490 }
1491 break;
1492 case GL_SRGB_EXT:
1493 case GL_SRGB_ALPHA_EXT:
1494 if (!context->getExtensions().sRGB)
1495 {
Jamie Madill610640f2018-11-21 17:28:41 -05001496 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001497 return false;
1498 }
1499 switch (type)
1500 {
1501 case GL_UNSIGNED_BYTE:
1502 break;
1503 default:
Jamie Madill610640f2018-11-21 17:28:41 -05001504 context->validationError(GL_INVALID_OPERATION,
1505 kErrorMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001506 return false;
1507 }
1508 break;
1509 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1510 // handled below
1511 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1512 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1513 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1514 break;
1515 case GL_DEPTH_COMPONENT:
1516 switch (type)
1517 {
1518 case GL_UNSIGNED_SHORT:
1519 case GL_UNSIGNED_INT:
1520 break;
1521 default:
Jamie Madill610640f2018-11-21 17:28:41 -05001522 context->validationError(GL_INVALID_OPERATION,
1523 kErrorMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001524 return false;
1525 }
1526 break;
1527 case GL_DEPTH_STENCIL_OES:
1528 switch (type)
1529 {
1530 case GL_UNSIGNED_INT_24_8_OES:
1531 break;
1532 default:
Jamie Madill610640f2018-11-21 17:28:41 -05001533 context->validationError(GL_INVALID_OPERATION,
1534 kErrorMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001535 return false;
1536 }
1537 break;
1538 default:
Jamie Madill610640f2018-11-21 17:28:41 -05001539 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001540 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001541 }
1542
1543 switch (format)
1544 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001545 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1546 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1547 if (context->getExtensions().textureCompressionDXT1)
1548 {
Jamie Madill610640f2018-11-21 17:28:41 -05001549 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001550 return false;
1551 }
1552 else
1553 {
Jamie Madill610640f2018-11-21 17:28:41 -05001554 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001555 return false;
1556 }
1557 break;
1558 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1559 if (context->getExtensions().textureCompressionDXT3)
1560 {
Jamie Madill610640f2018-11-21 17:28:41 -05001561 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001562 return false;
1563 }
1564 else
1565 {
Jamie Madill610640f2018-11-21 17:28:41 -05001566 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001567 return false;
1568 }
1569 break;
1570 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1571 if (context->getExtensions().textureCompressionDXT5)
1572 {
Jamie Madill610640f2018-11-21 17:28:41 -05001573 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001574 return false;
1575 }
1576 else
1577 {
Jamie Madill610640f2018-11-21 17:28:41 -05001578 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001579 return false;
1580 }
1581 break;
1582 case GL_ETC1_RGB8_OES:
1583 if (context->getExtensions().compressedETC1RGB8Texture)
1584 {
Jamie Madill610640f2018-11-21 17:28:41 -05001585 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001586 return false;
1587 }
1588 else
1589 {
Jamie Madill610640f2018-11-21 17:28:41 -05001590 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001591 return false;
1592 }
1593 break;
1594 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001595 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1596 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1597 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1598 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001599 if (context->getExtensions().lossyETCDecode)
1600 {
Jamie Madill610640f2018-11-21 17:28:41 -05001601 context->validationError(GL_INVALID_OPERATION,
1602 "ETC lossy decode formats can't work with this type.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001603 return false;
1604 }
1605 else
1606 {
Jamie Madill610640f2018-11-21 17:28:41 -05001607 context->validationError(GL_INVALID_ENUM,
1608 "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001609 return false;
1610 }
1611 break;
1612 case GL_DEPTH_COMPONENT:
1613 case GL_DEPTH_STENCIL_OES:
1614 if (!context->getExtensions().depthTextures)
1615 {
Jamie Madill610640f2018-11-21 17:28:41 -05001616 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001617 return false;
1618 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001619 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001620 {
Jamie Madill610640f2018-11-21 17:28:41 -05001621 context->validationError(GL_INVALID_OPERATION, kErrorMismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001622 return false;
1623 }
1624 // OES_depth_texture supports loading depth data and multiple levels,
1625 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001626 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001627 {
Jamie Madill610640f2018-11-21 17:28:41 -05001628 context->validationError(GL_INVALID_OPERATION, kErrorPixelDataNotNull);
Brandon Jonesafa75152017-07-21 13:11:29 -07001629 return false;
1630 }
1631 if (level != 0)
1632 {
Jamie Madill610640f2018-11-21 17:28:41 -05001633 context->validationError(GL_INVALID_OPERATION, kErrorLevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001634 return false;
1635 }
1636 break;
1637 default:
1638 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001639 }
1640
Geoff Lang6e898aa2017-06-02 11:17:26 -04001641 if (!isSubImage)
1642 {
1643 switch (internalformat)
1644 {
1645 case GL_RGBA32F:
1646 if (!context->getExtensions().colorBufferFloatRGBA)
1647 {
Jamie Madill610640f2018-11-21 17:28:41 -05001648 context->validationError(GL_INVALID_ENUM,
1649 "Sized GL_RGBA32F internal format requires "
1650 "GL_CHROMIUM_color_buffer_float_rgba");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001651 return false;
1652 }
1653 if (type != GL_FLOAT)
1654 {
Jamie Madill610640f2018-11-21 17:28:41 -05001655 context->validationError(GL_INVALID_OPERATION,
1656 kErrorMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001657 return false;
1658 }
1659 if (format != GL_RGBA)
1660 {
Jamie Madill610640f2018-11-21 17:28:41 -05001661 context->validationError(GL_INVALID_OPERATION,
1662 kErrorMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001663 return false;
1664 }
1665 break;
1666
1667 case GL_RGB32F:
1668 if (!context->getExtensions().colorBufferFloatRGB)
1669 {
Jamie Madill610640f2018-11-21 17:28:41 -05001670 context->validationError(GL_INVALID_ENUM,
1671 "Sized GL_RGB32F internal format requires "
1672 "GL_CHROMIUM_color_buffer_float_rgb");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001673 return false;
1674 }
1675 if (type != GL_FLOAT)
1676 {
Jamie Madill610640f2018-11-21 17:28:41 -05001677 context->validationError(GL_INVALID_OPERATION,
1678 kErrorMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001679 return false;
1680 }
1681 if (format != GL_RGB)
1682 {
Jamie Madill610640f2018-11-21 17:28:41 -05001683 context->validationError(GL_INVALID_OPERATION,
1684 kErrorMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001685 return false;
1686 }
1687 break;
1688
1689 default:
1690 break;
1691 }
1692 }
1693
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001694 if (type == GL_FLOAT)
1695 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001696 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001697 {
Jamie Madill610640f2018-11-21 17:28:41 -05001698 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001699 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001700 }
1701 }
1702 else if (type == GL_HALF_FLOAT_OES)
1703 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001704 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001705 {
Jamie Madill610640f2018-11-21 17:28:41 -05001706 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001707 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001708 }
1709 }
1710 }
1711
Geoff Langdbcced82017-06-06 15:55:54 -04001712 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001713 if (!ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001714 imageSize))
1715 {
1716 return false;
1717 }
1718
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001719 return true;
1720}
1721
He Yunchaoced53ae2016-11-29 15:00:51 +08001722bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001723 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001724 GLsizei levels,
1725 GLenum internalformat,
1726 GLsizei width,
1727 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001728{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001729 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1730 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001731 {
Jamie Madill610640f2018-11-21 17:28:41 -05001732 context->validationError(GL_INVALID_ENUM, kErrorInvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001733 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001734 }
1735
1736 if (width < 1 || height < 1 || levels < 1)
1737 {
Jamie Madill610640f2018-11-21 17:28:41 -05001738 context->validationError(GL_INVALID_VALUE, kErrorTextureSizeTooSmall);
Geoff Langb1196682014-07-23 13:47:29 -04001739 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001740 }
1741
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001742 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001743 {
Jamie Madill610640f2018-11-21 17:28:41 -05001744 context->validationError(GL_INVALID_VALUE, kErrorCubemapFacesEqualDimensions);
Geoff Langb1196682014-07-23 13:47:29 -04001745 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001746 }
1747
1748 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1749 {
Jamie Madill610640f2018-11-21 17:28:41 -05001750 context->validationError(GL_INVALID_OPERATION, kErrorInvalidMipLevels);
Geoff Langb1196682014-07-23 13:47:29 -04001751 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001752 }
1753
Geoff Langca271392017-04-05 12:30:00 -04001754 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001755 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001756 {
Jamie Madill610640f2018-11-21 17:28:41 -05001757 context->validationError(GL_INVALID_ENUM, kErrorInvalidFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001758 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001759 }
1760
Geoff Langaae65a42014-05-26 12:43:44 -04001761 const gl::Caps &caps = context->getCaps();
1762
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001763 switch (target)
1764 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001765 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001766 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1767 static_cast<GLuint>(height) > caps.max2DTextureSize)
1768 {
Jamie Madill610640f2018-11-21 17:28:41 -05001769 context->validationError(GL_INVALID_VALUE, kErrorResourceMaxTextureSize);
He Yunchaoced53ae2016-11-29 15:00:51 +08001770 return false;
1771 }
1772 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001773 case TextureType::Rectangle:
Jamie Madill610640f2018-11-21 17:28:41 -05001774 if (levels != 1)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001775 {
Jamie Madill610640f2018-11-21 17:28:41 -05001776 context->validationError(GL_INVALID_VALUE, kErrorInvalidMipLevel);
1777 return false;
1778 }
1779
1780 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1781 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1782 {
1783 context->validationError(GL_INVALID_VALUE, kErrorResourceMaxTextureSize);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001784 return false;
1785 }
1786 if (formatInfo.compressed)
1787 {
Jamie Madill610640f2018-11-21 17:28:41 -05001788 context->validationError(GL_INVALID_ENUM, kErrorRectangleTextureCompressed);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001789 return false;
1790 }
1791 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001792 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001793 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1794 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1795 {
Jamie Madill610640f2018-11-21 17:28:41 -05001796 context->validationError(GL_INVALID_VALUE, kErrorResourceMaxTextureSize);
He Yunchaoced53ae2016-11-29 15:00:51 +08001797 return false;
1798 }
1799 break;
1800 default:
Jamie Madill610640f2018-11-21 17:28:41 -05001801 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001802 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001803 }
1804
Geoff Langc0b9ef42014-07-02 10:02:37 -04001805 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001806 {
1807 if (!gl::isPow2(width) || !gl::isPow2(height))
1808 {
Jamie Madill610640f2018-11-21 17:28:41 -05001809 context->validationError(GL_INVALID_OPERATION, kErrorDimensionsMustBePow2);
Geoff Langb1196682014-07-23 13:47:29 -04001810 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001811 }
1812 }
1813
1814 switch (internalformat)
1815 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001816 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1817 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1818 if (!context->getExtensions().textureCompressionDXT1)
1819 {
Jamie Madill610640f2018-11-21 17:28:41 -05001820 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001821 return false;
1822 }
1823 break;
1824 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1825 if (!context->getExtensions().textureCompressionDXT3)
1826 {
Jamie Madill610640f2018-11-21 17:28:41 -05001827 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001828 return false;
1829 }
1830 break;
1831 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1832 if (!context->getExtensions().textureCompressionDXT5)
1833 {
Jamie Madill610640f2018-11-21 17:28:41 -05001834 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001835 return false;
1836 }
1837 break;
1838 case GL_ETC1_RGB8_OES:
1839 if (!context->getExtensions().compressedETC1RGB8Texture)
1840 {
Jamie Madill610640f2018-11-21 17:28:41 -05001841 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001842 return false;
1843 }
1844 break;
1845 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001846 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1847 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1848 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1849 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001850 if (!context->getExtensions().lossyETCDecode)
1851 {
Jamie Madill610640f2018-11-21 17:28:41 -05001852 context->validationError(GL_INVALID_ENUM,
1853 "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001854 return false;
1855 }
1856 break;
1857 case GL_RGBA32F_EXT:
1858 case GL_RGB32F_EXT:
1859 case GL_ALPHA32F_EXT:
1860 case GL_LUMINANCE32F_EXT:
1861 case GL_LUMINANCE_ALPHA32F_EXT:
1862 if (!context->getExtensions().textureFloat)
1863 {
Jamie Madill610640f2018-11-21 17:28:41 -05001864 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001865 return false;
1866 }
1867 break;
1868 case GL_RGBA16F_EXT:
1869 case GL_RGB16F_EXT:
1870 case GL_ALPHA16F_EXT:
1871 case GL_LUMINANCE16F_EXT:
1872 case GL_LUMINANCE_ALPHA16F_EXT:
1873 if (!context->getExtensions().textureHalfFloat)
1874 {
Jamie Madill610640f2018-11-21 17:28:41 -05001875 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001876 return false;
1877 }
1878 break;
1879 case GL_R8_EXT:
1880 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001881 if (!context->getExtensions().textureRG)
1882 {
Jamie Madill610640f2018-11-21 17:28:41 -05001883 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Geoff Lang677bb6f2017-04-05 12:40:40 -04001884 return false;
1885 }
1886 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001887 case GL_R16F_EXT:
1888 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001889 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1890 {
Jamie Madill610640f2018-11-21 17:28:41 -05001891 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Geoff Lang677bb6f2017-04-05 12:40:40 -04001892 return false;
1893 }
1894 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001895 case GL_R32F_EXT:
1896 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001897 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001898 {
Jamie Madill610640f2018-11-21 17:28:41 -05001899 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001900 return false;
1901 }
1902 break;
1903 case GL_DEPTH_COMPONENT16:
1904 case GL_DEPTH_COMPONENT32_OES:
1905 case GL_DEPTH24_STENCIL8_OES:
1906 if (!context->getExtensions().depthTextures)
1907 {
Jamie Madill610640f2018-11-21 17:28:41 -05001908 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001909 return false;
1910 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001911 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001912 {
Jamie Madill610640f2018-11-21 17:28:41 -05001913 context->validationError(GL_INVALID_OPERATION, kErrorInvalidTextureTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001914 return false;
1915 }
1916 // ANGLE_depth_texture only supports 1-level textures
1917 if (levels != 1)
1918 {
Jamie Madill610640f2018-11-21 17:28:41 -05001919 context->validationError(GL_INVALID_OPERATION, kErrorInvalidMipLevels);
He Yunchaoced53ae2016-11-29 15:00:51 +08001920 return false;
1921 }
1922 break;
1923 default:
1924 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001925 }
1926
Geoff Lang691e58c2014-12-19 17:03:25 -05001927 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001928 if (!texture || texture->id() == 0)
1929 {
Jamie Madill610640f2018-11-21 17:28:41 -05001930 context->validationError(GL_INVALID_OPERATION, kErrorMissingTexture);
Geoff Langb1196682014-07-23 13:47:29 -04001931 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001932 }
1933
Geoff Lang69cce582015-09-17 13:20:36 -04001934 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001935 {
Jamie Madill610640f2018-11-21 17:28:41 -05001936 context->validationError(GL_INVALID_OPERATION, kErrorTextureIsImmutable);
Geoff Langb1196682014-07-23 13:47:29 -04001937 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001938 }
1939
1940 return true;
1941}
1942
He Yunchaoced53ae2016-11-29 15:00:51 +08001943bool ValidateDiscardFramebufferEXT(Context *context,
1944 GLenum target,
1945 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001946 const GLenum *attachments)
1947{
Jamie Madillc29968b2016-01-20 11:17:23 -05001948 if (!context->getExtensions().discardFramebuffer)
1949 {
Jamie Madill610640f2018-11-21 17:28:41 -05001950 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001951 return false;
1952 }
1953
Austin Kinross08332632015-05-05 13:35:47 -07001954 bool defaultFramebuffer = false;
1955
1956 switch (target)
1957 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001958 case GL_FRAMEBUFFER:
1959 defaultFramebuffer =
1960 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1961 break;
1962 default:
Jamie Madill610640f2018-11-21 17:28:41 -05001963 context->validationError(GL_INVALID_ENUM, kErrorInvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001964 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001965 }
1966
He Yunchaoced53ae2016-11-29 15:00:51 +08001967 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1968 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001969}
1970
Austin Kinrossbc781f32015-10-26 09:27:38 -07001971bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1972{
1973 if (!context->getExtensions().vertexArrayObject)
1974 {
Jamie Madill610640f2018-11-21 17:28:41 -05001975 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001976 return false;
1977 }
1978
1979 return ValidateBindVertexArrayBase(context, array);
1980}
1981
Jamie Madilld7576732017-08-26 18:49:50 -04001982bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001983{
1984 if (!context->getExtensions().vertexArrayObject)
1985 {
Jamie Madill610640f2018-11-21 17:28:41 -05001986 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001987 return false;
1988 }
1989
Olli Etuaho41997e72016-03-10 13:38:39 +02001990 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001991}
1992
Jamie Madilld7576732017-08-26 18:49:50 -04001993bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001994{
1995 if (!context->getExtensions().vertexArrayObject)
1996 {
Jamie Madill610640f2018-11-21 17:28:41 -05001997 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001998 return false;
1999 }
2000
Olli Etuaho41997e72016-03-10 13:38:39 +02002001 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07002002}
2003
Jamie Madilld7576732017-08-26 18:49:50 -04002004bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07002005{
2006 if (!context->getExtensions().vertexArrayObject)
2007 {
Jamie Madill610640f2018-11-21 17:28:41 -05002008 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07002009 return false;
2010 }
2011
2012 return true;
2013}
Geoff Langc5629752015-12-07 16:29:04 -05002014
2015bool ValidateProgramBinaryOES(Context *context,
2016 GLuint program,
2017 GLenum binaryFormat,
2018 const void *binary,
2019 GLint length)
2020{
2021 if (!context->getExtensions().getProgramBinary)
2022 {
Jamie Madill610640f2018-11-21 17:28:41 -05002023 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05002024 return false;
2025 }
2026
2027 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
2028}
2029
2030bool ValidateGetProgramBinaryOES(Context *context,
2031 GLuint program,
2032 GLsizei bufSize,
2033 GLsizei *length,
2034 GLenum *binaryFormat,
2035 void *binary)
2036{
2037 if (!context->getExtensions().getProgramBinary)
2038 {
Jamie Madill610640f2018-11-21 17:28:41 -05002039 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05002040 return false;
2041 }
2042
2043 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
2044}
Geoff Lange102fee2015-12-10 11:23:30 -05002045
Geoff Lang70d0f492015-12-10 17:45:46 -05002046static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
2047{
2048 switch (source)
2049 {
2050 case GL_DEBUG_SOURCE_API:
2051 case GL_DEBUG_SOURCE_SHADER_COMPILER:
2052 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
2053 case GL_DEBUG_SOURCE_OTHER:
2054 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
2055 return !mustBeThirdPartyOrApplication;
2056
2057 case GL_DEBUG_SOURCE_THIRD_PARTY:
2058 case GL_DEBUG_SOURCE_APPLICATION:
2059 return true;
2060
2061 default:
2062 return false;
2063 }
2064}
2065
2066static bool ValidDebugType(GLenum type)
2067{
2068 switch (type)
2069 {
2070 case GL_DEBUG_TYPE_ERROR:
2071 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
2072 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
2073 case GL_DEBUG_TYPE_PERFORMANCE:
2074 case GL_DEBUG_TYPE_PORTABILITY:
2075 case GL_DEBUG_TYPE_OTHER:
2076 case GL_DEBUG_TYPE_MARKER:
2077 case GL_DEBUG_TYPE_PUSH_GROUP:
2078 case GL_DEBUG_TYPE_POP_GROUP:
2079 return true;
2080
2081 default:
2082 return false;
2083 }
2084}
2085
2086static bool ValidDebugSeverity(GLenum severity)
2087{
2088 switch (severity)
2089 {
2090 case GL_DEBUG_SEVERITY_HIGH:
2091 case GL_DEBUG_SEVERITY_MEDIUM:
2092 case GL_DEBUG_SEVERITY_LOW:
2093 case GL_DEBUG_SEVERITY_NOTIFICATION:
2094 return true;
2095
2096 default:
2097 return false;
2098 }
2099}
2100
Geoff Lange102fee2015-12-10 11:23:30 -05002101bool ValidateDebugMessageControlKHR(Context *context,
2102 GLenum source,
2103 GLenum type,
2104 GLenum severity,
2105 GLsizei count,
2106 const GLuint *ids,
2107 GLboolean enabled)
2108{
2109 if (!context->getExtensions().debug)
2110 {
Jamie Madill610640f2018-11-21 17:28:41 -05002111 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002112 return false;
2113 }
2114
Geoff Lang70d0f492015-12-10 17:45:46 -05002115 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
2116 {
Jamie Madill610640f2018-11-21 17:28:41 -05002117 context->validationError(GL_INVALID_ENUM, kErrorInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002118 return false;
2119 }
2120
2121 if (!ValidDebugType(type) && type != GL_DONT_CARE)
2122 {
Jamie Madill610640f2018-11-21 17:28:41 -05002123 context->validationError(GL_INVALID_ENUM, kErrorInvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002124 return false;
2125 }
2126
2127 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
2128 {
Jamie Madill610640f2018-11-21 17:28:41 -05002129 context->validationError(GL_INVALID_ENUM, kErrorInvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05002130 return false;
2131 }
2132
2133 if (count > 0)
2134 {
2135 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
2136 {
Jamie Madill610640f2018-11-21 17:28:41 -05002137 context->validationError(
2138 GL_INVALID_OPERATION,
2139 "If count is greater than zero, source and severity cannot be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002140 return false;
2141 }
2142
2143 if (severity != GL_DONT_CARE)
2144 {
Jamie Madill610640f2018-11-21 17:28:41 -05002145 context->validationError(
2146 GL_INVALID_OPERATION,
2147 "If count is greater than zero, severity must be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002148 return false;
2149 }
2150 }
2151
Geoff Lange102fee2015-12-10 11:23:30 -05002152 return true;
2153}
2154
2155bool ValidateDebugMessageInsertKHR(Context *context,
2156 GLenum source,
2157 GLenum type,
2158 GLuint id,
2159 GLenum severity,
2160 GLsizei length,
2161 const GLchar *buf)
2162{
2163 if (!context->getExtensions().debug)
2164 {
Jamie Madill610640f2018-11-21 17:28:41 -05002165 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002166 return false;
2167 }
2168
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002169 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002170 {
2171 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2172 // not generate an error.
2173 return false;
2174 }
2175
2176 if (!ValidDebugSeverity(severity))
2177 {
Jamie Madill610640f2018-11-21 17:28:41 -05002178 context->validationError(GL_INVALID_ENUM, kErrorInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002179 return false;
2180 }
2181
2182 if (!ValidDebugType(type))
2183 {
Jamie Madill610640f2018-11-21 17:28:41 -05002184 context->validationError(GL_INVALID_ENUM, kErrorInvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002185 return false;
2186 }
2187
2188 if (!ValidDebugSource(source, true))
2189 {
Jamie Madill610640f2018-11-21 17:28:41 -05002190 context->validationError(GL_INVALID_ENUM, kErrorInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002191 return false;
2192 }
2193
2194 size_t messageLength = (length < 0) ? strlen(buf) : length;
2195 if (messageLength > context->getExtensions().maxDebugMessageLength)
2196 {
Jamie Madill610640f2018-11-21 17:28:41 -05002197 context->validationError(GL_INVALID_VALUE,
2198 "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002199 return false;
2200 }
2201
Geoff Lange102fee2015-12-10 11:23:30 -05002202 return true;
2203}
2204
2205bool ValidateDebugMessageCallbackKHR(Context *context,
2206 GLDEBUGPROCKHR callback,
2207 const void *userParam)
2208{
2209 if (!context->getExtensions().debug)
2210 {
Jamie Madill610640f2018-11-21 17:28:41 -05002211 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002212 return false;
2213 }
2214
Geoff Lange102fee2015-12-10 11:23:30 -05002215 return true;
2216}
2217
2218bool ValidateGetDebugMessageLogKHR(Context *context,
2219 GLuint count,
2220 GLsizei bufSize,
2221 GLenum *sources,
2222 GLenum *types,
2223 GLuint *ids,
2224 GLenum *severities,
2225 GLsizei *lengths,
2226 GLchar *messageLog)
2227{
2228 if (!context->getExtensions().debug)
2229 {
Jamie Madill610640f2018-11-21 17:28:41 -05002230 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002231 return false;
2232 }
2233
Geoff Lang70d0f492015-12-10 17:45:46 -05002234 if (bufSize < 0 && messageLog != nullptr)
2235 {
Jamie Madill610640f2018-11-21 17:28:41 -05002236 context->validationError(GL_INVALID_VALUE, kErrorNegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002237 return false;
2238 }
2239
Geoff Lange102fee2015-12-10 11:23:30 -05002240 return true;
2241}
2242
2243bool ValidatePushDebugGroupKHR(Context *context,
2244 GLenum source,
2245 GLuint id,
2246 GLsizei length,
2247 const GLchar *message)
2248{
2249 if (!context->getExtensions().debug)
2250 {
Jamie Madill610640f2018-11-21 17:28:41 -05002251 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002252 return false;
2253 }
2254
Geoff Lang70d0f492015-12-10 17:45:46 -05002255 if (!ValidDebugSource(source, true))
2256 {
Jamie Madill610640f2018-11-21 17:28:41 -05002257 context->validationError(GL_INVALID_ENUM, kErrorInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002258 return false;
2259 }
2260
2261 size_t messageLength = (length < 0) ? strlen(message) : length;
2262 if (messageLength > context->getExtensions().maxDebugMessageLength)
2263 {
Jamie Madill610640f2018-11-21 17:28:41 -05002264 context->validationError(GL_INVALID_VALUE,
2265 "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002266 return false;
2267 }
2268
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002269 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002270 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2271 {
Jamie Madill610640f2018-11-21 17:28:41 -05002272 context->validationError(
2273 GL_STACK_OVERFLOW,
2274 "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002275 return false;
2276 }
2277
Geoff Lange102fee2015-12-10 11:23:30 -05002278 return true;
2279}
2280
2281bool ValidatePopDebugGroupKHR(Context *context)
2282{
2283 if (!context->getExtensions().debug)
2284 {
Jamie Madill610640f2018-11-21 17:28:41 -05002285 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002286 return false;
2287 }
2288
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002289 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002290 if (currentStackSize <= 1)
2291 {
Jamie Madill610640f2018-11-21 17:28:41 -05002292 context->validationError(GL_STACK_UNDERFLOW, "Cannot pop the default debug group.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002293 return false;
2294 }
2295
2296 return true;
2297}
2298
2299static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2300{
2301 switch (identifier)
2302 {
2303 case GL_BUFFER:
2304 if (context->getBuffer(name) == nullptr)
2305 {
Jamie Madill610640f2018-11-21 17:28:41 -05002306 context->validationError(GL_INVALID_VALUE, "name is not a valid buffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002307 return false;
2308 }
2309 return true;
2310
2311 case GL_SHADER:
2312 if (context->getShader(name) == nullptr)
2313 {
Jamie Madill610640f2018-11-21 17:28:41 -05002314 context->validationError(GL_INVALID_VALUE, "name is not a valid shader.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002315 return false;
2316 }
2317 return true;
2318
2319 case GL_PROGRAM:
Jamie Madill44a6fbf2018-10-02 13:38:56 -04002320 if (context->getProgramNoResolveLink(name) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002321 {
Jamie Madill610640f2018-11-21 17:28:41 -05002322 context->validationError(GL_INVALID_VALUE, "name is not a valid program.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002323 return false;
2324 }
2325 return true;
2326
2327 case GL_VERTEX_ARRAY:
2328 if (context->getVertexArray(name) == nullptr)
2329 {
Jamie Madill610640f2018-11-21 17:28:41 -05002330 context->validationError(GL_INVALID_VALUE, "name is not a valid vertex array.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002331 return false;
2332 }
2333 return true;
2334
2335 case GL_QUERY:
2336 if (context->getQuery(name) == nullptr)
2337 {
Jamie Madill610640f2018-11-21 17:28:41 -05002338 context->validationError(GL_INVALID_VALUE, "name is not a valid query.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002339 return false;
2340 }
2341 return true;
2342
2343 case GL_TRANSFORM_FEEDBACK:
2344 if (context->getTransformFeedback(name) == nullptr)
2345 {
Jamie Madill610640f2018-11-21 17:28:41 -05002346 context->validationError(GL_INVALID_VALUE,
2347 "name is not a valid transform feedback.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002348 return false;
2349 }
2350 return true;
2351
2352 case GL_SAMPLER:
2353 if (context->getSampler(name) == nullptr)
2354 {
Jamie Madill610640f2018-11-21 17:28:41 -05002355 context->validationError(GL_INVALID_VALUE, "name is not a valid sampler.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002356 return false;
2357 }
2358 return true;
2359
2360 case GL_TEXTURE:
2361 if (context->getTexture(name) == nullptr)
2362 {
Jamie Madill610640f2018-11-21 17:28:41 -05002363 context->validationError(GL_INVALID_VALUE, "name is not a valid texture.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002364 return false;
2365 }
2366 return true;
2367
2368 case GL_RENDERBUFFER:
2369 if (context->getRenderbuffer(name) == nullptr)
2370 {
Jamie Madill610640f2018-11-21 17:28:41 -05002371 context->validationError(GL_INVALID_VALUE, "name is not a valid renderbuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002372 return false;
2373 }
2374 return true;
2375
2376 case GL_FRAMEBUFFER:
2377 if (context->getFramebuffer(name) == nullptr)
2378 {
Jamie Madill610640f2018-11-21 17:28:41 -05002379 context->validationError(GL_INVALID_VALUE, "name is not a valid framebuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002380 return false;
2381 }
2382 return true;
2383
2384 default:
Jamie Madill610640f2018-11-21 17:28:41 -05002385 context->validationError(GL_INVALID_ENUM, "Invalid identifier.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002386 return false;
2387 }
Geoff Lange102fee2015-12-10 11:23:30 -05002388}
2389
Martin Radev9d901792016-07-15 15:58:58 +03002390static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2391{
2392 size_t labelLength = 0;
2393
2394 if (length < 0)
2395 {
2396 if (label != nullptr)
2397 {
2398 labelLength = strlen(label);
2399 }
2400 }
2401 else
2402 {
2403 labelLength = static_cast<size_t>(length);
2404 }
2405
2406 if (labelLength > context->getExtensions().maxLabelLength)
2407 {
Jamie Madill610640f2018-11-21 17:28:41 -05002408 context->validationError(GL_INVALID_VALUE,
2409 "Label length is larger than GL_MAX_LABEL_LENGTH.");
Martin Radev9d901792016-07-15 15:58:58 +03002410 return false;
2411 }
2412
2413 return true;
2414}
2415
Geoff Lange102fee2015-12-10 11:23:30 -05002416bool ValidateObjectLabelKHR(Context *context,
2417 GLenum identifier,
2418 GLuint name,
2419 GLsizei length,
2420 const GLchar *label)
2421{
2422 if (!context->getExtensions().debug)
2423 {
Jamie Madill610640f2018-11-21 17:28:41 -05002424 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002425 return false;
2426 }
2427
Geoff Lang70d0f492015-12-10 17:45:46 -05002428 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2429 {
2430 return false;
2431 }
2432
Martin Radev9d901792016-07-15 15:58:58 +03002433 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002434 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002435 return false;
2436 }
2437
Geoff Lange102fee2015-12-10 11:23:30 -05002438 return true;
2439}
2440
2441bool ValidateGetObjectLabelKHR(Context *context,
2442 GLenum identifier,
2443 GLuint name,
2444 GLsizei bufSize,
2445 GLsizei *length,
2446 GLchar *label)
2447{
2448 if (!context->getExtensions().debug)
2449 {
Jamie Madill610640f2018-11-21 17:28:41 -05002450 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002451 return false;
2452 }
2453
Geoff Lang70d0f492015-12-10 17:45:46 -05002454 if (bufSize < 0)
2455 {
Jamie Madill610640f2018-11-21 17:28:41 -05002456 context->validationError(GL_INVALID_VALUE, kErrorNegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002457 return false;
2458 }
2459
2460 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2461 {
2462 return false;
2463 }
2464
Martin Radev9d901792016-07-15 15:58:58 +03002465 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002466}
2467
2468static bool ValidateObjectPtrName(Context *context, const void *ptr)
2469{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002470 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002471 {
Jamie Madill610640f2018-11-21 17:28:41 -05002472 context->validationError(GL_INVALID_VALUE, "name is not a valid sync.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002473 return false;
2474 }
2475
Geoff Lange102fee2015-12-10 11:23:30 -05002476 return true;
2477}
2478
2479bool ValidateObjectPtrLabelKHR(Context *context,
2480 const void *ptr,
2481 GLsizei length,
2482 const GLchar *label)
2483{
2484 if (!context->getExtensions().debug)
2485 {
Jamie Madill610640f2018-11-21 17:28:41 -05002486 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002487 return false;
2488 }
2489
Geoff Lang70d0f492015-12-10 17:45:46 -05002490 if (!ValidateObjectPtrName(context, ptr))
2491 {
2492 return false;
2493 }
2494
Martin Radev9d901792016-07-15 15:58:58 +03002495 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002496 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002497 return false;
2498 }
2499
Geoff Lange102fee2015-12-10 11:23:30 -05002500 return true;
2501}
2502
2503bool ValidateGetObjectPtrLabelKHR(Context *context,
2504 const void *ptr,
2505 GLsizei bufSize,
2506 GLsizei *length,
2507 GLchar *label)
2508{
2509 if (!context->getExtensions().debug)
2510 {
Jamie Madill610640f2018-11-21 17:28:41 -05002511 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002512 return false;
2513 }
2514
Geoff Lang70d0f492015-12-10 17:45:46 -05002515 if (bufSize < 0)
2516 {
Jamie Madill610640f2018-11-21 17:28:41 -05002517 context->validationError(GL_INVALID_VALUE, kErrorNegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002518 return false;
2519 }
2520
2521 if (!ValidateObjectPtrName(context, ptr))
2522 {
2523 return false;
2524 }
2525
Martin Radev9d901792016-07-15 15:58:58 +03002526 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002527}
2528
2529bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2530{
2531 if (!context->getExtensions().debug)
2532 {
Jamie Madill610640f2018-11-21 17:28:41 -05002533 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002534 return false;
2535 }
2536
Geoff Lang70d0f492015-12-10 17:45:46 -05002537 // TODO: represent this in Context::getQueryParameterInfo.
2538 switch (pname)
2539 {
2540 case GL_DEBUG_CALLBACK_FUNCTION:
2541 case GL_DEBUG_CALLBACK_USER_PARAM:
2542 break;
2543
2544 default:
Jamie Madill610640f2018-11-21 17:28:41 -05002545 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002546 return false;
2547 }
2548
Geoff Lange102fee2015-12-10 11:23:30 -05002549 return true;
2550}
Jamie Madillc29968b2016-01-20 11:17:23 -05002551
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07002552bool ValidateGetPointervRobustANGLERobustANGLE(Context *context,
2553 GLenum pname,
2554 GLsizei bufSize,
2555 GLsizei *length,
2556 void **params)
2557{
2558 UNIMPLEMENTED();
2559 return false;
2560}
2561
Jamie Madillc29968b2016-01-20 11:17:23 -05002562bool ValidateBlitFramebufferANGLE(Context *context,
2563 GLint srcX0,
2564 GLint srcY0,
2565 GLint srcX1,
2566 GLint srcY1,
2567 GLint dstX0,
2568 GLint dstY0,
2569 GLint dstX1,
2570 GLint dstY1,
2571 GLbitfield mask,
2572 GLenum filter)
2573{
2574 if (!context->getExtensions().framebufferBlit)
2575 {
Jamie Madill610640f2018-11-21 17:28:41 -05002576 context->validationError(GL_INVALID_OPERATION, kErrorBlitExtensionNotAvailable);
Jamie Madillc29968b2016-01-20 11:17:23 -05002577 return false;
2578 }
2579
2580 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2581 {
2582 // TODO(jmadill): Determine if this should be available on other implementations.
Jamie Madill610640f2018-11-21 17:28:41 -05002583 context->validationError(GL_INVALID_OPERATION, kErrorBlitExtensionScaleOrFlip);
Jamie Madillc29968b2016-01-20 11:17:23 -05002584 return false;
2585 }
2586
2587 if (filter == GL_LINEAR)
2588 {
Jamie Madill610640f2018-11-21 17:28:41 -05002589 context->validationError(GL_INVALID_ENUM, kErrorBlitExtensionLinear);
Jamie Madillc29968b2016-01-20 11:17:23 -05002590 return false;
2591 }
2592
Jamie Madill51f40ec2016-06-15 14:06:00 -04002593 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2594 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002595
2596 if (mask & GL_COLOR_BUFFER_BIT)
2597 {
2598 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2599 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2600
2601 if (readColorAttachment && drawColorAttachment)
2602 {
2603 if (!(readColorAttachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002604 readColorAttachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002605 readColorAttachment->type() != GL_RENDERBUFFER &&
2606 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2607 {
Jamie Madill610640f2018-11-21 17:28:41 -05002608 context->validationError(GL_INVALID_OPERATION,
2609 kErrorBlitExtensionFromInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002610 return false;
2611 }
2612
Geoff Langa15472a2015-08-11 11:48:03 -04002613 for (size_t drawbufferIdx = 0;
2614 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002615 {
Geoff Langa15472a2015-08-11 11:48:03 -04002616 const FramebufferAttachment *attachment =
2617 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2618 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002619 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002620 if (!(attachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002621 attachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002622 attachment->type() != GL_RENDERBUFFER &&
2623 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2624 {
Jamie Madill610640f2018-11-21 17:28:41 -05002625 context->validationError(GL_INVALID_OPERATION,
2626 kErrorBlitExtensionToInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002627 return false;
2628 }
2629
2630 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002631 if (!Format::EquivalentForBlit(attachment->getFormat(),
2632 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002633 {
Jamie Madill610640f2018-11-21 17:28:41 -05002634 context->validationError(GL_INVALID_OPERATION,
2635 kErrorBlitExtensionFormatMismatch);
Jamie Madillc29968b2016-01-20 11:17:23 -05002636 return false;
2637 }
2638 }
2639 }
2640
Jamie Madill427064d2018-04-13 16:20:34 -04002641 GLint samples = readFramebuffer->getSamples(context);
Jamie Madille98b1b52018-03-08 09:47:23 -05002642 if (samples != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002643 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2644 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2645 {
Jamie Madill610640f2018-11-21 17:28:41 -05002646 context->validationError(GL_INVALID_OPERATION,
2647 kErrorBlitExtensionMultisampledWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002648 return false;
2649 }
2650 }
2651 }
2652
2653 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2654 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2655 for (size_t i = 0; i < 2; i++)
2656 {
2657 if (mask & masks[i])
2658 {
2659 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002660 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002661 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002662 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002663
2664 if (readBuffer && drawBuffer)
2665 {
2666 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2667 dstX0, dstY0, dstX1, dstY1))
2668 {
2669 // only whole-buffer copies are permitted
Jamie Madill610640f2018-11-21 17:28:41 -05002670 context->validationError(GL_INVALID_OPERATION,
2671 kErrorBlitExtensionDepthStencilWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002672 return false;
2673 }
2674
2675 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2676 {
Jamie Madill610640f2018-11-21 17:28:41 -05002677 context->validationError(GL_INVALID_OPERATION,
2678 kErrorBlitExtensionMultisampledDepthOrStencil);
Jamie Madillc29968b2016-01-20 11:17:23 -05002679 return false;
2680 }
2681 }
2682 }
2683 }
2684
2685 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2686 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002687}
Jamie Madillc29968b2016-01-20 11:17:23 -05002688
Jamie Madill5b772312018-03-08 20:28:32 -05002689bool ValidateClear(Context *context, GLbitfield mask)
Jamie Madillc29968b2016-01-20 11:17:23 -05002690{
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07002691 Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
Olli Etuaho94c91a92018-07-19 15:10:24 +03002692 const Extensions &extensions = context->getExtensions();
Jamie Madille98b1b52018-03-08 09:47:23 -05002693
Jamie Madill427064d2018-04-13 16:20:34 -04002694 if (!ValidateFramebufferComplete(context, fbo))
Jamie Madillc29968b2016-01-20 11:17:23 -05002695 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002696 return false;
2697 }
2698
2699 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2700 {
Jamie Madill610640f2018-11-21 17:28:41 -05002701 context->validationError(GL_INVALID_VALUE, kErrorInvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002702 return false;
2703 }
2704
Olli Etuaho94c91a92018-07-19 15:10:24 +03002705 if (extensions.webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
Geoff Lang76e65652017-03-27 14:58:02 -04002706 {
2707 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2708 GL_SIGNED_NORMALIZED};
2709
Corentin Wallez59c41592017-07-11 13:19:54 -04002710 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002711 drawBufferIdx++)
2712 {
2713 if (!ValidateWebGLFramebufferAttachmentClearType(
2714 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2715 {
2716 return false;
2717 }
2718 }
2719 }
2720
Olli Etuaho94c91a92018-07-19 15:10:24 +03002721 if (extensions.multiview && extensions.disjointTimerQuery)
2722 {
2723 const State &state = context->getGLState();
2724 Framebuffer *framebuffer = state.getDrawFramebuffer();
2725 if (framebuffer->getNumViews() > 1 && state.isQueryActive(QueryType::TimeElapsed))
2726 {
Jamie Madill610640f2018-11-21 17:28:41 -05002727 context->validationError(GL_INVALID_OPERATION,
2728 "There is an active query for target "
2729 "GL_TIME_ELAPSED_EXT when the number of "
2730 "views in the active draw framebuffer is "
2731 "greater than 1.");
Olli Etuaho94c91a92018-07-19 15:10:24 +03002732 return false;
2733 }
2734 }
2735
Jamie Madillc29968b2016-01-20 11:17:23 -05002736 return true;
2737}
2738
Jamie Madill5b772312018-03-08 20:28:32 -05002739bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002740{
2741 if (!context->getExtensions().drawBuffers)
2742 {
Jamie Madill610640f2018-11-21 17:28:41 -05002743 context->validationError(GL_INVALID_OPERATION, "Extension not supported.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002744 return false;
2745 }
2746
2747 return ValidateDrawBuffersBase(context, n, bufs);
2748}
2749
Jamie Madill73a84962016-02-12 09:27:23 -05002750bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002751 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002752 GLint level,
2753 GLint internalformat,
2754 GLsizei width,
2755 GLsizei height,
2756 GLint border,
2757 GLenum format,
2758 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002759 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002760{
Martin Radev1be913c2016-07-11 17:59:16 +03002761 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002762 {
2763 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002764 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002765 }
2766
Martin Radev1be913c2016-07-11 17:59:16 +03002767 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002768 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002769 0, 0, width, height, 1, border, format, type, -1,
2770 pixels);
2771}
2772
Brandon Jones416aaf92018-04-10 08:10:16 -07002773bool ValidateTexImage2DRobustANGLE(Context *context,
2774 TextureTarget target,
2775 GLint level,
2776 GLint internalformat,
2777 GLsizei width,
2778 GLsizei height,
2779 GLint border,
2780 GLenum format,
2781 GLenum type,
2782 GLsizei bufSize,
2783 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002784{
2785 if (!ValidateRobustEntryPoint(context, bufSize))
2786 {
2787 return false;
2788 }
2789
2790 if (context->getClientMajorVersion() < 3)
2791 {
2792 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2793 0, 0, width, height, border, format, type, bufSize,
2794 pixels);
2795 }
2796
2797 ASSERT(context->getClientMajorVersion() >= 3);
2798 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2799 0, 0, width, height, 1, border, format, type, bufSize,
2800 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002801}
2802
2803bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002804 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002805 GLint level,
2806 GLint xoffset,
2807 GLint yoffset,
2808 GLsizei width,
2809 GLsizei height,
2810 GLenum format,
2811 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002812 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002813{
2814
Martin Radev1be913c2016-07-11 17:59:16 +03002815 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002816 {
2817 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002818 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002819 }
2820
Martin Radev1be913c2016-07-11 17:59:16 +03002821 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002822 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002823 yoffset, 0, width, height, 1, 0, format, type, -1,
2824 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002825}
2826
Geoff Langc52f6f12016-10-14 10:18:00 -04002827bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002828 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002829 GLint level,
2830 GLint xoffset,
2831 GLint yoffset,
2832 GLsizei width,
2833 GLsizei height,
2834 GLenum format,
2835 GLenum type,
2836 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002837 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002838{
2839 if (!ValidateRobustEntryPoint(context, bufSize))
2840 {
2841 return false;
2842 }
2843
2844 if (context->getClientMajorVersion() < 3)
2845 {
2846 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2847 yoffset, width, height, 0, format, type, bufSize,
2848 pixels);
2849 }
2850
2851 ASSERT(context->getClientMajorVersion() >= 3);
2852 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2853 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2854 pixels);
2855}
2856
Jamie Madill73a84962016-02-12 09:27:23 -05002857bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002858 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002859 GLint level,
2860 GLenum internalformat,
2861 GLsizei width,
2862 GLsizei height,
2863 GLint border,
2864 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002865 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002866{
Martin Radev1be913c2016-07-11 17:59:16 +03002867 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002868 {
2869 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002870 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002871 {
2872 return false;
2873 }
2874 }
2875 else
2876 {
Martin Radev1be913c2016-07-11 17:59:16 +03002877 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002878 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002879 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002880 data))
2881 {
2882 return false;
2883 }
2884 }
2885
Geoff Langca271392017-04-05 12:30:00 -04002886 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jamie Madillca2ff382018-07-11 09:01:17 -04002887
2888 GLuint blockSize = 0;
2889 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002890 {
Jamie Madill610640f2018-11-21 17:28:41 -05002891 context->validationError(GL_INVALID_OPERATION, kErrorIntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002892 return false;
2893 }
2894
Jamie Madillca2ff382018-07-11 09:01:17 -04002895 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002896 {
Jamie Madill610640f2018-11-21 17:28:41 -05002897 context->validationError(GL_INVALID_VALUE, kErrorCompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002898 return false;
2899 }
2900
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002901 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002902 {
Jamie Madill610640f2018-11-21 17:28:41 -05002903 context->validationError(GL_INVALID_ENUM,
2904 "Rectangle texture cannot have a compressed format.");
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002905 return false;
2906 }
2907
Jamie Madill73a84962016-02-12 09:27:23 -05002908 return true;
2909}
2910
Corentin Wallezb2931602017-04-11 15:58:57 -04002911bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002912 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002913 GLint level,
2914 GLenum internalformat,
2915 GLsizei width,
2916 GLsizei height,
2917 GLint border,
2918 GLsizei imageSize,
2919 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002920 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002921{
2922 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2923 {
2924 return false;
2925 }
2926
2927 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2928 border, imageSize, data);
2929}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002930
Corentin Wallezb2931602017-04-11 15:58:57 -04002931bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002932 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002933 GLint level,
2934 GLint xoffset,
2935 GLint yoffset,
2936 GLsizei width,
2937 GLsizei height,
2938 GLenum format,
2939 GLsizei imageSize,
2940 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002941 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002942{
2943 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2944 {
2945 return false;
2946 }
2947
2948 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2949 format, imageSize, data);
2950}
2951
Jamie Madill73a84962016-02-12 09:27:23 -05002952bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002953 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002954 GLint level,
2955 GLint xoffset,
2956 GLint yoffset,
2957 GLsizei width,
2958 GLsizei height,
2959 GLenum format,
2960 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002961 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002962{
Martin Radev1be913c2016-07-11 17:59:16 +03002963 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002964 {
2965 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002966 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002967 {
2968 return false;
2969 }
2970 }
2971 else
2972 {
Martin Radev1be913c2016-07-11 17:59:16 +03002973 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002974 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002975 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002976 data))
2977 {
2978 return false;
2979 }
2980 }
2981
Geoff Langca271392017-04-05 12:30:00 -04002982 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jamie Madillca2ff382018-07-11 09:01:17 -04002983 GLuint blockSize = 0;
2984 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002985 {
Jamie Madill610640f2018-11-21 17:28:41 -05002986 context->validationError(GL_INVALID_OPERATION, kErrorIntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002987 return false;
2988 }
2989
Jamie Madillca2ff382018-07-11 09:01:17 -04002990 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002991 {
Jamie Madill610640f2018-11-21 17:28:41 -05002992 context->validationError(GL_INVALID_VALUE, kErrorInvalidCompressedImageSize);
Jamie Madill73a84962016-02-12 09:27:23 -05002993 return false;
2994 }
2995
2996 return true;
2997}
2998
Corentin Wallez336129f2017-10-17 15:55:40 -04002999bool ValidateGetBufferPointervOES(Context *context,
3000 BufferBinding target,
3001 GLenum pname,
3002 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003003{
Geoff Lang496c02d2016-10-20 11:38:11 -07003004 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003005}
3006
Corentin Wallez336129f2017-10-17 15:55:40 -04003007bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003008{
3009 if (!context->getExtensions().mapBuffer)
3010 {
Jamie Madill610640f2018-11-21 17:28:41 -05003011 context->validationError(GL_INVALID_OPERATION, "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003012 return false;
3013 }
3014
Corentin Walleze4477002017-12-01 14:39:58 -05003015 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003016 {
Jamie Madill610640f2018-11-21 17:28:41 -05003017 context->validationError(GL_INVALID_ENUM, kErrorInvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003018 return false;
3019 }
3020
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003021 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003022
3023 if (buffer == nullptr)
3024 {
Jamie Madill610640f2018-11-21 17:28:41 -05003025 context->validationError(GL_INVALID_OPERATION, "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003026 return false;
3027 }
3028
3029 if (access != GL_WRITE_ONLY_OES)
3030 {
Jamie Madill610640f2018-11-21 17:28:41 -05003031 context->validationError(GL_INVALID_ENUM, "Non-write buffer mapping not supported.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003032 return false;
3033 }
3034
3035 if (buffer->isMapped())
3036 {
Jamie Madill610640f2018-11-21 17:28:41 -05003037 context->validationError(GL_INVALID_OPERATION, "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003038 return false;
3039 }
3040
Geoff Lang79f71042017-08-14 16:43:43 -04003041 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003042}
3043
Corentin Wallez336129f2017-10-17 15:55:40 -04003044bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03003045{
3046 if (!context->getExtensions().mapBuffer)
3047 {
Jamie Madill610640f2018-11-21 17:28:41 -05003048 context->validationError(GL_INVALID_OPERATION, "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003049 return false;
3050 }
3051
3052 return ValidateUnmapBufferBase(context, target);
3053}
3054
3055bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003056 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003057 GLintptr offset,
3058 GLsizeiptr length,
3059 GLbitfield access)
3060{
3061 if (!context->getExtensions().mapBufferRange)
3062 {
Jamie Madill610640f2018-11-21 17:28:41 -05003063 context->validationError(GL_INVALID_OPERATION, "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003064 return false;
3065 }
3066
3067 return ValidateMapBufferRangeBase(context, target, offset, length, access);
3068}
3069
Corentin Wallez336129f2017-10-17 15:55:40 -04003070bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04003071{
3072 Buffer *buffer = context->getGLState().getTargetBuffer(target);
3073 ASSERT(buffer != nullptr);
3074
3075 // Check if this buffer is currently being used as a transform feedback output buffer
3076 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
3077 if (transformFeedback != nullptr && transformFeedback->isActive())
3078 {
3079 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
3080 {
3081 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
3082 if (transformFeedbackBuffer.get() == buffer)
3083 {
Jamie Madill610640f2018-11-21 17:28:41 -05003084 context->validationError(GL_INVALID_OPERATION,
3085 "Buffer is currently bound for transform feedback.");
Geoff Lang79f71042017-08-14 16:43:43 -04003086 return false;
3087 }
3088 }
3089 }
3090
James Darpiniane8a93c62018-01-04 18:02:24 -08003091 if (context->getExtensions().webglCompatibility &&
3092 buffer->isBoundForTransformFeedbackAndOtherUse())
3093 {
Jamie Madill610640f2018-11-21 17:28:41 -05003094 context->validationError(GL_INVALID_OPERATION, kErrorBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08003095 return false;
3096 }
3097
Geoff Lang79f71042017-08-14 16:43:43 -04003098 return true;
3099}
3100
Olli Etuaho4f667482016-03-30 15:56:35 +03003101bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003102 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003103 GLintptr offset,
3104 GLsizeiptr length)
3105{
3106 if (!context->getExtensions().mapBufferRange)
3107 {
Jamie Madill610640f2018-11-21 17:28:41 -05003108 context->validationError(GL_INVALID_OPERATION, "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003109 return false;
3110 }
3111
3112 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
3113}
3114
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003115bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
Ian Ewell54f87462016-03-10 13:47:21 -05003116{
Jamie Madillac66f982018-10-09 18:30:01 -04003117 if (!context->getStateCache().isValidBindTextureType(target))
Ian Ewell54f87462016-03-10 13:47:21 -05003118 {
Jamie Madillac66f982018-10-09 18:30:01 -04003119 RecordBindTextureTypeError(context, target);
3120 return false;
Ian Ewell54f87462016-03-10 13:47:21 -05003121 }
3122
Jamie Madill0fdb9562018-09-17 17:18:43 -04003123 if (texture == 0)
3124 {
3125 return true;
3126 }
3127
3128 Texture *textureObject = context->getTexture(texture);
3129 if (textureObject && textureObject->getType() != target)
3130 {
Jamie Madill610640f2018-11-21 17:28:41 -05003131 context->validationError(GL_INVALID_OPERATION, kErrorTypeMismatch);
Jamie Madill0fdb9562018-09-17 17:18:43 -04003132 return false;
3133 }
3134
3135 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
3136 !context->isTextureGenerated(texture))
3137 {
Jamie Madill610640f2018-11-21 17:28:41 -05003138 context->validationError(GL_INVALID_OPERATION, "Texture was not generated");
Jamie Madill0fdb9562018-09-17 17:18:43 -04003139 return false;
3140 }
3141
Ian Ewell54f87462016-03-10 13:47:21 -05003142 return true;
3143}
3144
Geoff Langd8605522016-04-13 10:19:12 -04003145bool ValidateBindUniformLocationCHROMIUM(Context *context,
3146 GLuint program,
3147 GLint location,
3148 const GLchar *name)
3149{
3150 if (!context->getExtensions().bindUniformLocation)
3151 {
Jamie Madill610640f2018-11-21 17:28:41 -05003152 context->validationError(GL_INVALID_OPERATION,
3153 "GL_CHROMIUM_bind_uniform_location is not available.");
Geoff Langd8605522016-04-13 10:19:12 -04003154 return false;
3155 }
3156
3157 Program *programObject = GetValidProgram(context, program);
3158 if (!programObject)
3159 {
3160 return false;
3161 }
3162
3163 if (location < 0)
3164 {
Jamie Madill610640f2018-11-21 17:28:41 -05003165 context->validationError(GL_INVALID_VALUE, "Location cannot be less than 0.");
Geoff Langd8605522016-04-13 10:19:12 -04003166 return false;
3167 }
3168
3169 const Caps &caps = context->getCaps();
3170 if (static_cast<size_t>(location) >=
3171 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3172 {
Jamie Madill610640f2018-11-21 17:28:41 -05003173 context->validationError(GL_INVALID_VALUE,
3174 "Location must be less than "
3175 "(MAX_VERTEX_UNIFORM_VECTORS + "
3176 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4");
Geoff Langd8605522016-04-13 10:19:12 -04003177 return false;
3178 }
3179
Geoff Langfc32e8b2017-05-31 14:16:59 -04003180 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3181 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003182 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003183 {
Jamie Madill610640f2018-11-21 17:28:41 -05003184 context->validationError(GL_INVALID_VALUE, kErrorInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003185 return false;
3186 }
3187
Geoff Langd8605522016-04-13 10:19:12 -04003188 if (strncmp(name, "gl_", 3) == 0)
3189 {
Jamie Madill610640f2018-11-21 17:28:41 -05003190 context->validationError(GL_INVALID_VALUE, kErrorNameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003191 return false;
3192 }
3193
3194 return true;
3195}
3196
Jamie Madille2e406c2016-06-02 13:04:10 -04003197bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003198{
3199 if (!context->getExtensions().framebufferMixedSamples)
3200 {
Jamie Madill610640f2018-11-21 17:28:41 -05003201 context->validationError(GL_INVALID_OPERATION,
3202 "GL_CHROMIUM_framebuffer_mixed_samples is not available.");
Sami Väisänena797e062016-05-12 15:23:40 +03003203 return false;
3204 }
3205 switch (components)
3206 {
3207 case GL_RGB:
3208 case GL_RGBA:
3209 case GL_ALPHA:
3210 case GL_NONE:
3211 break;
3212 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003213 context->validationError(
3214 GL_INVALID_ENUM,
3215 "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.");
Sami Väisänena797e062016-05-12 15:23:40 +03003216 return false;
3217 }
3218
3219 return true;
3220}
3221
Sami Väisänene45e53b2016-05-25 10:36:04 +03003222// CHROMIUM_path_rendering
3223
Jamie Madill007530e2017-12-28 14:27:04 -05003224bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003225{
Jamie Madill007530e2017-12-28 14:27:04 -05003226 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003227 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003228 return false;
3229 }
Jamie Madill007530e2017-12-28 14:27:04 -05003230
Sami Väisänene45e53b2016-05-25 10:36:04 +03003231 if (matrix == nullptr)
3232 {
Jamie Madill610640f2018-11-21 17:28:41 -05003233 context->validationError(GL_INVALID_OPERATION, "Invalid matrix.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003234 return false;
3235 }
Jamie Madill007530e2017-12-28 14:27:04 -05003236
Sami Väisänene45e53b2016-05-25 10:36:04 +03003237 return true;
3238}
3239
Jamie Madill007530e2017-12-28 14:27:04 -05003240bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003241{
Jamie Madill007530e2017-12-28 14:27:04 -05003242 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003243}
3244
Jamie Madill007530e2017-12-28 14:27:04 -05003245bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003246{
3247 if (!context->getExtensions().pathRendering)
3248 {
Jamie Madill610640f2018-11-21 17:28:41 -05003249 context->validationError(GL_INVALID_OPERATION,
3250 "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003251 return false;
3252 }
3253
3254 // range = 0 is undefined in NV_path_rendering.
3255 // we add stricter semantic check here and require a non zero positive range.
3256 if (range <= 0)
3257 {
Jamie Madill610640f2018-11-21 17:28:41 -05003258 context->validationError(GL_INVALID_VALUE, kErrorInvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003259 return false;
3260 }
3261
3262 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3263 {
Jamie Madill610640f2018-11-21 17:28:41 -05003264 context->validationError(GL_INVALID_OPERATION, kErrorIntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003265 return false;
3266 }
3267
3268 return true;
3269}
3270
Jamie Madill007530e2017-12-28 14:27:04 -05003271bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003272{
3273 if (!context->getExtensions().pathRendering)
3274 {
Jamie Madill610640f2018-11-21 17:28:41 -05003275 context->validationError(GL_INVALID_OPERATION,
3276 "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003277 return false;
3278 }
3279
3280 // range = 0 is undefined in NV_path_rendering.
3281 // we add stricter semantic check here and require a non zero positive range.
3282 if (range <= 0)
3283 {
Jamie Madill610640f2018-11-21 17:28:41 -05003284 context->validationError(GL_INVALID_VALUE, kErrorInvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003285 return false;
3286 }
3287
3288 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3289 checkedRange += range;
3290
3291 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3292 {
Jamie Madill610640f2018-11-21 17:28:41 -05003293 context->validationError(GL_INVALID_OPERATION, kErrorIntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003294 return false;
3295 }
3296 return true;
3297}
3298
Jamie Madill007530e2017-12-28 14:27:04 -05003299bool ValidatePathCommandsCHROMIUM(Context *context,
3300 GLuint path,
3301 GLsizei numCommands,
3302 const GLubyte *commands,
3303 GLsizei numCoords,
3304 GLenum coordType,
3305 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003306{
3307 if (!context->getExtensions().pathRendering)
3308 {
Jamie Madill610640f2018-11-21 17:28:41 -05003309 context->validationError(GL_INVALID_OPERATION,
3310 "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003311 return false;
3312 }
Brandon Jones59770802018-04-02 13:18:42 -07003313 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003314 {
Jamie Madill610640f2018-11-21 17:28:41 -05003315 context->validationError(GL_INVALID_OPERATION, kErrorNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003316 return false;
3317 }
3318
3319 if (numCommands < 0)
3320 {
Jamie Madill610640f2018-11-21 17:28:41 -05003321 context->validationError(GL_INVALID_VALUE, "Invalid number of commands.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003322 return false;
3323 }
3324 else if (numCommands > 0)
3325 {
3326 if (!commands)
3327 {
Jamie Madill610640f2018-11-21 17:28:41 -05003328 context->validationError(GL_INVALID_VALUE, "No commands array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003329 return false;
3330 }
3331 }
3332
3333 if (numCoords < 0)
3334 {
Jamie Madill610640f2018-11-21 17:28:41 -05003335 context->validationError(GL_INVALID_VALUE, "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003336 return false;
3337 }
3338 else if (numCoords > 0)
3339 {
3340 if (!coords)
3341 {
Jamie Madill610640f2018-11-21 17:28:41 -05003342 context->validationError(GL_INVALID_VALUE, "No coordinate array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003343 return false;
3344 }
3345 }
3346
3347 std::uint32_t coordTypeSize = 0;
3348 switch (coordType)
3349 {
3350 case GL_BYTE:
3351 coordTypeSize = sizeof(GLbyte);
3352 break;
3353
3354 case GL_UNSIGNED_BYTE:
3355 coordTypeSize = sizeof(GLubyte);
3356 break;
3357
3358 case GL_SHORT:
3359 coordTypeSize = sizeof(GLshort);
3360 break;
3361
3362 case GL_UNSIGNED_SHORT:
3363 coordTypeSize = sizeof(GLushort);
3364 break;
3365
3366 case GL_FLOAT:
3367 coordTypeSize = sizeof(GLfloat);
3368 break;
3369
3370 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003371 context->validationError(GL_INVALID_ENUM, "Invalid coordinate type.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003372 return false;
3373 }
3374
3375 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3376 checkedSize += (coordTypeSize * numCoords);
3377 if (!checkedSize.IsValid())
3378 {
Jamie Madill610640f2018-11-21 17:28:41 -05003379 context->validationError(GL_INVALID_OPERATION, kErrorIntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003380 return false;
3381 }
3382
3383 // early return skips command data validation when it doesn't exist.
3384 if (!commands)
3385 return true;
3386
3387 GLsizei expectedNumCoords = 0;
3388 for (GLsizei i = 0; i < numCommands; ++i)
3389 {
3390 switch (commands[i])
3391 {
3392 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3393 break;
3394 case GL_MOVE_TO_CHROMIUM:
3395 case GL_LINE_TO_CHROMIUM:
3396 expectedNumCoords += 2;
3397 break;
3398 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3399 expectedNumCoords += 4;
3400 break;
3401 case GL_CUBIC_CURVE_TO_CHROMIUM:
3402 expectedNumCoords += 6;
3403 break;
3404 case GL_CONIC_CURVE_TO_CHROMIUM:
3405 expectedNumCoords += 5;
3406 break;
3407 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003408 context->validationError(GL_INVALID_ENUM, "Invalid command.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003409 return false;
3410 }
3411 }
3412 if (expectedNumCoords != numCoords)
3413 {
Jamie Madill610640f2018-11-21 17:28:41 -05003414 context->validationError(GL_INVALID_VALUE, "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003415 return false;
3416 }
3417
3418 return true;
3419}
3420
Jamie Madill007530e2017-12-28 14:27:04 -05003421bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003422{
3423 if (!context->getExtensions().pathRendering)
3424 {
Jamie Madill610640f2018-11-21 17:28:41 -05003425 context->validationError(GL_INVALID_OPERATION,
3426 "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003427 return false;
3428 }
Brandon Jones59770802018-04-02 13:18:42 -07003429 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003430 {
Jamie Madill610640f2018-11-21 17:28:41 -05003431 context->validationError(GL_INVALID_OPERATION, kErrorNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003432 return false;
3433 }
3434
3435 switch (pname)
3436 {
3437 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3438 if (value < 0.0f)
3439 {
Jamie Madill610640f2018-11-21 17:28:41 -05003440 context->validationError(GL_INVALID_VALUE, "Invalid stroke width.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003441 return false;
3442 }
3443 break;
3444 case GL_PATH_END_CAPS_CHROMIUM:
3445 switch (static_cast<GLenum>(value))
3446 {
3447 case GL_FLAT_CHROMIUM:
3448 case GL_SQUARE_CHROMIUM:
3449 case GL_ROUND_CHROMIUM:
3450 break;
3451 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003452 context->validationError(GL_INVALID_ENUM, "Invalid end caps.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003453 return false;
3454 }
3455 break;
3456 case GL_PATH_JOIN_STYLE_CHROMIUM:
3457 switch (static_cast<GLenum>(value))
3458 {
3459 case GL_MITER_REVERT_CHROMIUM:
3460 case GL_BEVEL_CHROMIUM:
3461 case GL_ROUND_CHROMIUM:
3462 break;
3463 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003464 context->validationError(GL_INVALID_ENUM, "Invalid join style.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003465 return false;
3466 }
Nico Weber41b072b2018-02-09 10:01:32 -05003467 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003468 case GL_PATH_MITER_LIMIT_CHROMIUM:
3469 if (value < 0.0f)
3470 {
Jamie Madill610640f2018-11-21 17:28:41 -05003471 context->validationError(GL_INVALID_VALUE, "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003472 return false;
3473 }
3474 break;
3475
3476 case GL_PATH_STROKE_BOUND_CHROMIUM:
3477 // no errors, only clamping.
3478 break;
3479
3480 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003481 context->validationError(GL_INVALID_ENUM, "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003482 return false;
3483 }
3484 return true;
3485}
3486
Jamie Madill007530e2017-12-28 14:27:04 -05003487bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3488{
3489 // TODO(jmadill): Use proper clamping cast.
3490 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3491}
3492
3493bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003494{
3495 if (!context->getExtensions().pathRendering)
3496 {
Jamie Madill610640f2018-11-21 17:28:41 -05003497 context->validationError(GL_INVALID_OPERATION,
3498 "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003499 return false;
3500 }
3501
Brandon Jones59770802018-04-02 13:18:42 -07003502 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003503 {
Jamie Madill610640f2018-11-21 17:28:41 -05003504 context->validationError(GL_INVALID_OPERATION, kErrorNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003505 return false;
3506 }
3507 if (!value)
3508 {
Jamie Madill610640f2018-11-21 17:28:41 -05003509 context->validationError(GL_INVALID_VALUE, "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003510 return false;
3511 }
3512
3513 switch (pname)
3514 {
3515 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3516 case GL_PATH_END_CAPS_CHROMIUM:
3517 case GL_PATH_JOIN_STYLE_CHROMIUM:
3518 case GL_PATH_MITER_LIMIT_CHROMIUM:
3519 case GL_PATH_STROKE_BOUND_CHROMIUM:
3520 break;
3521
3522 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003523 context->validationError(GL_INVALID_ENUM, "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003524 return false;
3525 }
3526
3527 return true;
3528}
3529
Jamie Madill007530e2017-12-28 14:27:04 -05003530bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3531{
3532 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3533 reinterpret_cast<GLfloat *>(value));
3534}
3535
3536bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003537{
3538 if (!context->getExtensions().pathRendering)
3539 {
Jamie Madill610640f2018-11-21 17:28:41 -05003540 context->validationError(GL_INVALID_OPERATION,
3541 "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003542 return false;
3543 }
3544
3545 switch (func)
3546 {
3547 case GL_NEVER:
3548 case GL_ALWAYS:
3549 case GL_LESS:
3550 case GL_LEQUAL:
3551 case GL_EQUAL:
3552 case GL_GEQUAL:
3553 case GL_GREATER:
3554 case GL_NOTEQUAL:
3555 break;
3556 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003557 context->validationError(GL_INVALID_ENUM, kErrorInvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003558 return false;
3559 }
3560
3561 return true;
3562}
3563
3564// Note that the spec specifies that for the path drawing commands
3565// if the path object is not an existing path object the command
3566// does nothing and no error is generated.
3567// However if the path object exists but has not been specified any
3568// commands then an error is generated.
3569
Jamie Madill007530e2017-12-28 14:27:04 -05003570bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003571{
3572 if (!context->getExtensions().pathRendering)
3573 {
Jamie Madill610640f2018-11-21 17:28:41 -05003574 context->validationError(GL_INVALID_OPERATION,
3575 "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003576 return false;
3577 }
Brandon Jones59770802018-04-02 13:18:42 -07003578 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003579 {
Jamie Madill610640f2018-11-21 17:28:41 -05003580 context->validationError(GL_INVALID_OPERATION, kErrorNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003581 return false;
3582 }
3583
3584 switch (fillMode)
3585 {
3586 case GL_COUNT_UP_CHROMIUM:
3587 case GL_COUNT_DOWN_CHROMIUM:
3588 break;
3589 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003590 context->validationError(GL_INVALID_ENUM, kErrorInvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003591 return false;
3592 }
3593
3594 if (!isPow2(mask + 1))
3595 {
Jamie Madill610640f2018-11-21 17:28:41 -05003596 context->validationError(GL_INVALID_VALUE, kErrorInvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003597 return false;
3598 }
3599
3600 return true;
3601}
3602
Jamie Madill007530e2017-12-28 14:27:04 -05003603bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003604{
3605 if (!context->getExtensions().pathRendering)
3606 {
Jamie Madill610640f2018-11-21 17:28:41 -05003607 context->validationError(GL_INVALID_OPERATION,
3608 "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003609 return false;
3610 }
Brandon Jones59770802018-04-02 13:18:42 -07003611 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003612 {
Jamie Madill610640f2018-11-21 17:28:41 -05003613 context->validationError(GL_INVALID_OPERATION, "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003614 return false;
3615 }
3616
3617 return true;
3618}
3619
Jamie Madill007530e2017-12-28 14:27:04 -05003620bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003621{
3622 if (!context->getExtensions().pathRendering)
3623 {
Jamie Madill610640f2018-11-21 17:28:41 -05003624 context->validationError(GL_INVALID_OPERATION,
3625 "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003626 return false;
3627 }
Brandon Jones59770802018-04-02 13:18:42 -07003628 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003629 {
Jamie Madill610640f2018-11-21 17:28:41 -05003630 context->validationError(GL_INVALID_OPERATION, kErrorNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003631 return false;
3632 }
3633
3634 switch (coverMode)
3635 {
3636 case GL_CONVEX_HULL_CHROMIUM:
3637 case GL_BOUNDING_BOX_CHROMIUM:
3638 break;
3639 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003640 context->validationError(GL_INVALID_ENUM, kErrorInvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003641 return false;
3642 }
3643 return true;
3644}
3645
Jamie Madill778bf092018-11-14 09:54:36 -05003646bool ValidateCoverFillPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3647{
3648 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3649}
3650
3651bool ValidateCoverStrokePathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3652{
3653 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3654}
3655
Jamie Madill007530e2017-12-28 14:27:04 -05003656bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3657 GLuint path,
3658 GLenum fillMode,
3659 GLuint mask,
3660 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003661{
Jamie Madill007530e2017-12-28 14:27:04 -05003662 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3663 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003664}
3665
Jamie Madill007530e2017-12-28 14:27:04 -05003666bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3667 GLuint path,
3668 GLint reference,
3669 GLuint mask,
3670 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003671{
Jamie Madill007530e2017-12-28 14:27:04 -05003672 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3673 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003674}
3675
Brandon Jonesd1049182018-03-28 10:02:20 -07003676bool ValidateIsPathCHROMIUM(Context *context, GLuint path)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003677{
3678 if (!context->getExtensions().pathRendering)
3679 {
Jamie Madill610640f2018-11-21 17:28:41 -05003680 context->validationError(GL_INVALID_OPERATION,
3681 "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003682 return false;
3683 }
3684 return true;
3685}
3686
Jamie Madill007530e2017-12-28 14:27:04 -05003687bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3688 GLsizei numPaths,
3689 GLenum pathNameType,
3690 const void *paths,
3691 GLuint pathBase,
3692 GLenum coverMode,
3693 GLenum transformType,
3694 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003695{
3696 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3697 transformType, transformValues))
3698 return false;
3699
3700 switch (coverMode)
3701 {
3702 case GL_CONVEX_HULL_CHROMIUM:
3703 case GL_BOUNDING_BOX_CHROMIUM:
3704 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3705 break;
3706 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003707 context->validationError(GL_INVALID_ENUM, kErrorInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003708 return false;
3709 }
3710
3711 return true;
3712}
3713
Jamie Madill007530e2017-12-28 14:27:04 -05003714bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3715 GLsizei numPaths,
3716 GLenum pathNameType,
3717 const void *paths,
3718 GLuint pathBase,
3719 GLenum coverMode,
3720 GLenum transformType,
3721 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003722{
3723 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3724 transformType, transformValues))
3725 return false;
3726
3727 switch (coverMode)
3728 {
3729 case GL_CONVEX_HULL_CHROMIUM:
3730 case GL_BOUNDING_BOX_CHROMIUM:
3731 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3732 break;
3733 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003734 context->validationError(GL_INVALID_ENUM, kErrorInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003735 return false;
3736 }
3737
3738 return true;
3739}
3740
Jamie Madill007530e2017-12-28 14:27:04 -05003741bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3742 GLsizei numPaths,
3743 GLenum pathNameType,
3744 const void *paths,
3745 GLuint pathBase,
3746 GLenum fillMode,
3747 GLuint mask,
3748 GLenum transformType,
3749 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003750{
3751
3752 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3753 transformType, transformValues))
3754 return false;
3755
3756 switch (fillMode)
3757 {
3758 case GL_COUNT_UP_CHROMIUM:
3759 case GL_COUNT_DOWN_CHROMIUM:
3760 break;
3761 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003762 context->validationError(GL_INVALID_ENUM, kErrorInvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003763 return false;
3764 }
3765 if (!isPow2(mask + 1))
3766 {
Jamie Madill610640f2018-11-21 17:28:41 -05003767 context->validationError(GL_INVALID_VALUE, kErrorInvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003768 return false;
3769 }
3770 return true;
3771}
3772
Jamie Madill007530e2017-12-28 14:27:04 -05003773bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3774 GLsizei numPaths,
3775 GLenum pathNameType,
3776 const void *paths,
3777 GLuint pathBase,
3778 GLint reference,
3779 GLuint mask,
3780 GLenum transformType,
3781 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003782{
3783 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3784 transformType, transformValues))
3785 return false;
3786
3787 // no more validation here.
3788
3789 return true;
3790}
3791
Jamie Madill007530e2017-12-28 14:27:04 -05003792bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3793 GLsizei numPaths,
3794 GLenum pathNameType,
3795 const void *paths,
3796 GLuint pathBase,
3797 GLenum fillMode,
3798 GLuint mask,
3799 GLenum coverMode,
3800 GLenum transformType,
3801 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003802{
3803 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3804 transformType, transformValues))
3805 return false;
3806
3807 switch (coverMode)
3808 {
3809 case GL_CONVEX_HULL_CHROMIUM:
3810 case GL_BOUNDING_BOX_CHROMIUM:
3811 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3812 break;
3813 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003814 context->validationError(GL_INVALID_ENUM, kErrorInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003815 return false;
3816 }
3817
3818 switch (fillMode)
3819 {
3820 case GL_COUNT_UP_CHROMIUM:
3821 case GL_COUNT_DOWN_CHROMIUM:
3822 break;
3823 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003824 context->validationError(GL_INVALID_ENUM, kErrorInvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003825 return false;
3826 }
3827 if (!isPow2(mask + 1))
3828 {
Jamie Madill610640f2018-11-21 17:28:41 -05003829 context->validationError(GL_INVALID_VALUE, kErrorInvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003830 return false;
3831 }
3832
3833 return true;
3834}
3835
Jamie Madill007530e2017-12-28 14:27:04 -05003836bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
3837 GLsizei numPaths,
3838 GLenum pathNameType,
3839 const void *paths,
3840 GLuint pathBase,
3841 GLint reference,
3842 GLuint mask,
3843 GLenum coverMode,
3844 GLenum transformType,
3845 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003846{
3847 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3848 transformType, transformValues))
3849 return false;
3850
3851 switch (coverMode)
3852 {
3853 case GL_CONVEX_HULL_CHROMIUM:
3854 case GL_BOUNDING_BOX_CHROMIUM:
3855 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3856 break;
3857 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003858 context->validationError(GL_INVALID_ENUM, kErrorInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003859 return false;
3860 }
3861
3862 return true;
3863}
3864
Jamie Madill007530e2017-12-28 14:27:04 -05003865bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
3866 GLuint program,
3867 GLint location,
3868 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003869{
3870 if (!context->getExtensions().pathRendering)
3871 {
Jamie Madill610640f2018-11-21 17:28:41 -05003872 context->validationError(GL_INVALID_OPERATION,
3873 "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003874 return false;
3875 }
3876
3877 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3878 if (location >= MaxLocation)
3879 {
Jamie Madill610640f2018-11-21 17:28:41 -05003880 context->validationError(GL_INVALID_VALUE, "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003881 return false;
3882 }
3883
Jamie Madill44a6fbf2018-10-02 13:38:56 -04003884 const auto *programObject = context->getProgramNoResolveLink(program);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003885 if (!programObject)
3886 {
Jamie Madill610640f2018-11-21 17:28:41 -05003887 context->validationError(GL_INVALID_OPERATION, kErrorProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003888 return false;
3889 }
3890
3891 if (!name)
3892 {
Jamie Madill610640f2018-11-21 17:28:41 -05003893 context->validationError(GL_INVALID_VALUE, "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003894 return false;
3895 }
3896
3897 if (angle::BeginsWith(name, "gl_"))
3898 {
Jamie Madill610640f2018-11-21 17:28:41 -05003899 context->validationError(GL_INVALID_OPERATION, kErrorNameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003900 return false;
3901 }
3902
3903 return true;
3904}
3905
Jamie Madill007530e2017-12-28 14:27:04 -05003906bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
3907 GLuint program,
3908 GLint location,
3909 GLenum genMode,
3910 GLint components,
3911 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003912{
3913 if (!context->getExtensions().pathRendering)
3914 {
Jamie Madill610640f2018-11-21 17:28:41 -05003915 context->validationError(GL_INVALID_OPERATION,
3916 "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003917 return false;
3918 }
3919
Jamie Madill44a6fbf2018-10-02 13:38:56 -04003920 const auto *programObject = context->getProgramResolveLink(program);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003921 if (!programObject || programObject->isFlaggedForDeletion())
3922 {
Jamie Madill610640f2018-11-21 17:28:41 -05003923 context->validationError(GL_INVALID_OPERATION, kErrorProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003924 return false;
3925 }
3926
3927 if (!programObject->isLinked())
3928 {
Jamie Madill610640f2018-11-21 17:28:41 -05003929 context->validationError(GL_INVALID_OPERATION, kErrorProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003930 return false;
3931 }
3932
3933 switch (genMode)
3934 {
3935 case GL_NONE:
3936 if (components != 0)
3937 {
Jamie Madill610640f2018-11-21 17:28:41 -05003938 context->validationError(GL_INVALID_VALUE, "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003939 return false;
3940 }
3941 break;
3942
3943 case GL_OBJECT_LINEAR_CHROMIUM:
3944 case GL_EYE_LINEAR_CHROMIUM:
3945 case GL_CONSTANT_CHROMIUM:
3946 if (components < 1 || components > 4)
3947 {
Jamie Madill610640f2018-11-21 17:28:41 -05003948 context->validationError(GL_INVALID_VALUE, "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003949 return false;
3950 }
3951 if (!coeffs)
3952 {
Jamie Madill610640f2018-11-21 17:28:41 -05003953 context->validationError(GL_INVALID_VALUE, "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003954 return false;
3955 }
3956 break;
3957
3958 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003959 context->validationError(GL_INVALID_ENUM, "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003960 return false;
3961 }
3962
3963 // If the location is -1 then the command is silently ignored
3964 // and no further validation is needed.
3965 if (location == -1)
3966 return true;
3967
jchen103fd614d2018-08-13 12:21:58 +08003968 const auto &binding = programObject->getFragmentInputBindingInfo(location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003969
3970 if (!binding.valid)
3971 {
Jamie Madill610640f2018-11-21 17:28:41 -05003972 context->validationError(GL_INVALID_OPERATION, "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003973 return false;
3974 }
3975
3976 if (binding.type != GL_NONE)
3977 {
3978 GLint expectedComponents = 0;
3979 switch (binding.type)
3980 {
3981 case GL_FLOAT:
3982 expectedComponents = 1;
3983 break;
3984 case GL_FLOAT_VEC2:
3985 expectedComponents = 2;
3986 break;
3987 case GL_FLOAT_VEC3:
3988 expectedComponents = 3;
3989 break;
3990 case GL_FLOAT_VEC4:
3991 expectedComponents = 4;
3992 break;
3993 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003994 context->validationError(
3995 GL_INVALID_OPERATION,
3996 "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003997 return false;
3998 }
3999 if (expectedComponents != components && genMode != GL_NONE)
4000 {
Jamie Madill610640f2018-11-21 17:28:41 -05004001 context->validationError(GL_INVALID_OPERATION, "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03004002 return false;
4003 }
4004 }
4005 return true;
4006}
4007
Geoff Lang97073d12016-04-20 10:42:34 -07004008bool ValidateCopyTextureCHROMIUM(Context *context,
4009 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04004010 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004011 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07004012 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04004013 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07004014 GLint internalFormat,
4015 GLenum destType,
4016 GLboolean unpackFlipY,
4017 GLboolean unpackPremultiplyAlpha,
4018 GLboolean unpackUnmultiplyAlpha)
4019{
4020 if (!context->getExtensions().copyTexture)
4021 {
Jamie Madill610640f2018-11-21 17:28:41 -05004022 context->validationError(GL_INVALID_OPERATION,
4023 "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07004024 return false;
4025 }
4026
Geoff Lang4f0e0032017-05-01 16:04:35 -04004027 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004028 if (source == nullptr)
4029 {
Jamie Madill610640f2018-11-21 17:28:41 -05004030 context->validationError(GL_INVALID_VALUE, "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004031 return false;
4032 }
4033
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004034 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004035 {
Jamie Madill610640f2018-11-21 17:28:41 -05004036 context->validationError(GL_INVALID_OPERATION, kErrorInvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004037 return false;
4038 }
4039
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004040 TextureType sourceType = source->getType();
4041 ASSERT(sourceType != TextureType::CubeMap);
4042 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004043
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004044 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004045 {
Jamie Madill610640f2018-11-21 17:28:41 -05004046 context->validationError(GL_INVALID_VALUE, "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004047 return false;
4048 }
4049
Geoff Lang4f0e0032017-05-01 16:04:35 -04004050 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
4051 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
4052 if (sourceWidth == 0 || sourceHeight == 0)
4053 {
Jamie Madill610640f2018-11-21 17:28:41 -05004054 context->validationError(GL_INVALID_OPERATION, kErrorInvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004055 return false;
4056 }
4057
4058 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
4059 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004060 {
Jamie Madill610640f2018-11-21 17:28:41 -05004061 context->validationError(GL_INVALID_OPERATION,
4062 "Source texture internal format is invalid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004063 return false;
4064 }
4065
Geoff Lang63458a32017-10-30 15:16:53 -04004066 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4067 {
Jamie Madill610640f2018-11-21 17:28:41 -05004068 context->validationError(GL_INVALID_ENUM, kErrorInvalidTextureTarget);
Geoff Lang63458a32017-10-30 15:16:53 -04004069 return false;
4070 }
4071
Geoff Lang4f0e0032017-05-01 16:04:35 -04004072 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004073 if (dest == nullptr)
4074 {
Jamie Madill610640f2018-11-21 17:28:41 -05004075 context->validationError(GL_INVALID_VALUE,
4076 "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004077 return false;
4078 }
4079
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004080 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004081 {
Jamie Madill610640f2018-11-21 17:28:41 -05004082 context->validationError(GL_INVALID_VALUE, "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004083 return false;
4084 }
4085
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004086 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08004087 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004088 {
Jamie Madill610640f2018-11-21 17:28:41 -05004089 context->validationError(GL_INVALID_VALUE, kErrorInvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004090 return false;
4091 }
4092
Geoff Lang97073d12016-04-20 10:42:34 -07004093 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
4094 {
Geoff Lang97073d12016-04-20 10:42:34 -07004095 return false;
4096 }
4097
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004098 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04004099 {
Jamie Madill610640f2018-11-21 17:28:41 -05004100 context->validationError(
4101 GL_INVALID_VALUE, "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004102 return false;
4103 }
4104
Geoff Lang97073d12016-04-20 10:42:34 -07004105 if (dest->getImmutableFormat())
4106 {
Jamie Madill610640f2018-11-21 17:28:41 -05004107 context->validationError(GL_INVALID_OPERATION, "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07004108 return false;
4109 }
4110
4111 return true;
4112}
4113
4114bool ValidateCopySubTextureCHROMIUM(Context *context,
4115 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04004116 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004117 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07004118 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04004119 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07004120 GLint xoffset,
4121 GLint yoffset,
4122 GLint x,
4123 GLint y,
4124 GLsizei width,
4125 GLsizei height,
4126 GLboolean unpackFlipY,
4127 GLboolean unpackPremultiplyAlpha,
4128 GLboolean unpackUnmultiplyAlpha)
4129{
4130 if (!context->getExtensions().copyTexture)
4131 {
Jamie Madill610640f2018-11-21 17:28:41 -05004132 context->validationError(GL_INVALID_OPERATION,
4133 "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07004134 return false;
4135 }
4136
Geoff Lang4f0e0032017-05-01 16:04:35 -04004137 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004138 if (source == nullptr)
4139 {
Jamie Madill610640f2018-11-21 17:28:41 -05004140 context->validationError(GL_INVALID_VALUE, "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004141 return false;
4142 }
4143
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004144 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004145 {
Jamie Madill610640f2018-11-21 17:28:41 -05004146 context->validationError(GL_INVALID_VALUE, "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004147 return false;
4148 }
4149
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004150 TextureType sourceType = source->getType();
4151 ASSERT(sourceType != TextureType::CubeMap);
4152 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004153
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004154 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004155 {
Jamie Madill610640f2018-11-21 17:28:41 -05004156 context->validationError(GL_INVALID_VALUE, kErrorInvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004157 return false;
4158 }
4159
4160 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4161 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004162 {
Jamie Madill610640f2018-11-21 17:28:41 -05004163 context->validationError(GL_INVALID_VALUE,
4164 "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07004165 return false;
4166 }
4167
4168 if (x < 0 || y < 0)
4169 {
Jamie Madill610640f2018-11-21 17:28:41 -05004170 context->validationError(GL_INVALID_VALUE, "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07004171 return false;
4172 }
4173
4174 if (width < 0 || height < 0)
4175 {
Jamie Madill610640f2018-11-21 17:28:41 -05004176 context->validationError(GL_INVALID_VALUE, kErrorNegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004177 return false;
4178 }
4179
Geoff Lang4f0e0032017-05-01 16:04:35 -04004180 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4181 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004182 {
Jamie Madill610640f2018-11-21 17:28:41 -05004183 context->validationError(GL_INVALID_VALUE, kErrorSourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004184 return false;
4185 }
4186
Geoff Lang4f0e0032017-05-01 16:04:35 -04004187 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4188 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004189 {
Jamie Madill610640f2018-11-21 17:28:41 -05004190 context->validationError(GL_INVALID_OPERATION, kErrorInvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004191 return false;
4192 }
4193
Geoff Lang63458a32017-10-30 15:16:53 -04004194 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4195 {
Jamie Madill610640f2018-11-21 17:28:41 -05004196 context->validationError(GL_INVALID_ENUM, kErrorInvalidTextureTarget);
Geoff Lang63458a32017-10-30 15:16:53 -04004197 return false;
4198 }
4199
Geoff Lang4f0e0032017-05-01 16:04:35 -04004200 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004201 if (dest == nullptr)
4202 {
Jamie Madill610640f2018-11-21 17:28:41 -05004203 context->validationError(GL_INVALID_VALUE,
4204 "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004205 return false;
4206 }
4207
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004208 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004209 {
Jamie Madill610640f2018-11-21 17:28:41 -05004210 context->validationError(GL_INVALID_VALUE, "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004211 return false;
4212 }
4213
Brandon Jones28783792018-03-05 09:37:32 -08004214 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4215 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004216 {
Jamie Madill610640f2018-11-21 17:28:41 -05004217 context->validationError(GL_INVALID_VALUE, "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004218 return false;
4219 }
4220
Geoff Lang4f0e0032017-05-01 16:04:35 -04004221 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4222 {
Jamie Madill610640f2018-11-21 17:28:41 -05004223 context->validationError(
4224 GL_INVALID_OPERATION,
4225 "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004226 return false;
4227 }
4228
4229 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4230 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004231 {
Jamie Madill610640f2018-11-21 17:28:41 -05004232 context->validationError(GL_INVALID_OPERATION,
4233 "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004234 return false;
4235 }
4236
4237 if (xoffset < 0 || yoffset < 0)
4238 {
Jamie Madill610640f2018-11-21 17:28:41 -05004239 context->validationError(GL_INVALID_VALUE, kErrorNegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004240 return false;
4241 }
4242
Geoff Lang4f0e0032017-05-01 16:04:35 -04004243 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4244 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004245 {
Jamie Madill610640f2018-11-21 17:28:41 -05004246 context->validationError(GL_INVALID_VALUE,
4247 "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07004248 return false;
4249 }
4250
4251 return true;
4252}
4253
Geoff Lang47110bf2016-04-20 11:13:22 -07004254bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4255{
4256 if (!context->getExtensions().copyCompressedTexture)
4257 {
Jamie Madill610640f2018-11-21 17:28:41 -05004258 context->validationError(GL_INVALID_OPERATION,
4259 "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004260 return false;
4261 }
4262
4263 const gl::Texture *source = context->getTexture(sourceId);
4264 if (source == nullptr)
4265 {
Jamie Madill610640f2018-11-21 17:28:41 -05004266 context->validationError(GL_INVALID_VALUE, "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004267 return false;
4268 }
4269
Corentin Wallez99d492c2018-02-27 15:17:10 -05004270 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004271 {
Jamie Madill610640f2018-11-21 17:28:41 -05004272 context->validationError(GL_INVALID_VALUE, "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004273 return false;
4274 }
4275
Corentin Wallez99d492c2018-02-27 15:17:10 -05004276 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4277 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004278 {
Jamie Madill610640f2018-11-21 17:28:41 -05004279 context->validationError(GL_INVALID_VALUE, "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004280 return false;
4281 }
4282
Corentin Wallez99d492c2018-02-27 15:17:10 -05004283 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004284 if (!sourceFormat.info->compressed)
4285 {
Jamie Madill610640f2018-11-21 17:28:41 -05004286 context->validationError(GL_INVALID_OPERATION,
4287 "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004288 return false;
4289 }
4290
4291 const gl::Texture *dest = context->getTexture(destId);
4292 if (dest == nullptr)
4293 {
Jamie Madill610640f2018-11-21 17:28:41 -05004294 context->validationError(GL_INVALID_VALUE,
4295 "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004296 return false;
4297 }
4298
Corentin Wallez99d492c2018-02-27 15:17:10 -05004299 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004300 {
Jamie Madill610640f2018-11-21 17:28:41 -05004301 context->validationError(GL_INVALID_VALUE,
4302 "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004303 return false;
4304 }
4305
4306 if (dest->getImmutableFormat())
4307 {
Jamie Madill610640f2018-11-21 17:28:41 -05004308 context->validationError(GL_INVALID_OPERATION, "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004309 return false;
4310 }
4311
4312 return true;
4313}
4314
Jiawei Shao385b3e02018-03-21 09:43:28 +08004315bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004316{
4317 switch (type)
4318 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004319 case ShaderType::Vertex:
4320 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004321 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004322
Jiawei Shao385b3e02018-03-21 09:43:28 +08004323 case ShaderType::Compute:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004324 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004325 {
Jamie Madill610640f2018-11-21 17:28:41 -05004326 context->validationError(GL_INVALID_ENUM, kErrorES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004327 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004328 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004329 break;
4330
Jiawei Shao385b3e02018-03-21 09:43:28 +08004331 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004332 if (!context->getExtensions().geometryShader)
4333 {
Jamie Madill610640f2018-11-21 17:28:41 -05004334 context->validationError(GL_INVALID_ENUM, kErrorInvalidShaderType);
Jiawei Shao89be29a2017-11-06 14:36:45 +08004335 return false;
4336 }
4337 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004338 default:
Jamie Madill610640f2018-11-21 17:28:41 -05004339 context->validationError(GL_INVALID_ENUM, kErrorInvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004340 return false;
4341 }
Jamie Madill29639852016-09-02 15:00:09 -04004342
4343 return true;
4344}
4345
Jamie Madill5b772312018-03-08 20:28:32 -05004346bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004347 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004348 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004349 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004350 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004351{
4352 if (size < 0)
4353 {
Jamie Madill610640f2018-11-21 17:28:41 -05004354 context->validationError(GL_INVALID_VALUE, kErrorNegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004355 return false;
4356 }
4357
4358 switch (usage)
4359 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004360 case BufferUsage::StreamDraw:
4361 case BufferUsage::StaticDraw:
4362 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004363 break;
4364
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004365 case BufferUsage::StreamRead:
4366 case BufferUsage::StaticRead:
4367 case BufferUsage::DynamicRead:
4368 case BufferUsage::StreamCopy:
4369 case BufferUsage::StaticCopy:
4370 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004371 if (context->getClientMajorVersion() < 3)
4372 {
Jamie Madill610640f2018-11-21 17:28:41 -05004373 context->validationError(GL_INVALID_ENUM, kErrorInvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004374 return false;
4375 }
4376 break;
4377
4378 default:
Jamie Madill610640f2018-11-21 17:28:41 -05004379 context->validationError(GL_INVALID_ENUM, kErrorInvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004380 return false;
4381 }
4382
Corentin Walleze4477002017-12-01 14:39:58 -05004383 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004384 {
Jamie Madill610640f2018-11-21 17:28:41 -05004385 context->validationError(GL_INVALID_ENUM, kErrorInvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004386 return false;
4387 }
4388
4389 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4390
4391 if (!buffer)
4392 {
Jamie Madill610640f2018-11-21 17:28:41 -05004393 context->validationError(GL_INVALID_OPERATION, kErrorBufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004394 return false;
4395 }
4396
James Darpiniane8a93c62018-01-04 18:02:24 -08004397 if (context->getExtensions().webglCompatibility &&
4398 buffer->isBoundForTransformFeedbackAndOtherUse())
4399 {
Jamie Madill610640f2018-11-21 17:28:41 -05004400 context->validationError(GL_INVALID_OPERATION, kErrorBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08004401 return false;
4402 }
4403
Jamie Madill29639852016-09-02 15:00:09 -04004404 return true;
4405}
4406
Jamie Madill5b772312018-03-08 20:28:32 -05004407bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004408 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004409 GLintptr offset,
4410 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004411 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004412{
Brandon Jones6cad5662017-06-14 13:25:13 -07004413 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004414 {
Jamie Madill610640f2018-11-21 17:28:41 -05004415 context->validationError(GL_INVALID_VALUE, kErrorNegativeSize);
Brandon Jones6cad5662017-06-14 13:25:13 -07004416 return false;
4417 }
4418
4419 if (offset < 0)
4420 {
Jamie Madill610640f2018-11-21 17:28:41 -05004421 context->validationError(GL_INVALID_VALUE, kErrorNegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004422 return false;
4423 }
4424
Corentin Walleze4477002017-12-01 14:39:58 -05004425 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004426 {
Jamie Madill610640f2018-11-21 17:28:41 -05004427 context->validationError(GL_INVALID_ENUM, kErrorInvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004428 return false;
4429 }
4430
4431 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4432
4433 if (!buffer)
4434 {
Jamie Madill610640f2018-11-21 17:28:41 -05004435 context->validationError(GL_INVALID_OPERATION, kErrorBufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004436 return false;
4437 }
4438
4439 if (buffer->isMapped())
4440 {
Jamie Madill610640f2018-11-21 17:28:41 -05004441 context->validationError(GL_INVALID_OPERATION, kErrorBufferMapped);
Jamie Madill29639852016-09-02 15:00:09 -04004442 return false;
4443 }
4444
James Darpiniane8a93c62018-01-04 18:02:24 -08004445 if (context->getExtensions().webglCompatibility &&
4446 buffer->isBoundForTransformFeedbackAndOtherUse())
4447 {
Jamie Madill610640f2018-11-21 17:28:41 -05004448 context->validationError(GL_INVALID_OPERATION, kErrorBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08004449 return false;
4450 }
4451
Jamie Madill29639852016-09-02 15:00:09 -04004452 // Check for possible overflow of size + offset
4453 angle::CheckedNumeric<size_t> checkedSize(size);
4454 checkedSize += offset;
4455 if (!checkedSize.IsValid())
4456 {
Jamie Madill610640f2018-11-21 17:28:41 -05004457 context->validationError(GL_INVALID_VALUE, kErrorParamOverflow);
Jamie Madill29639852016-09-02 15:00:09 -04004458 return false;
4459 }
4460
4461 if (size + offset > buffer->getSize())
4462 {
Jamie Madill610640f2018-11-21 17:28:41 -05004463 context->validationError(GL_INVALID_VALUE, kErrorInsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004464 return false;
4465 }
4466
Martin Radev4c4c8e72016-08-04 12:25:34 +03004467 return true;
4468}
4469
Geoff Lang111a99e2017-10-17 10:58:41 -04004470bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004471{
Geoff Langc339c4e2016-11-29 10:37:36 -05004472 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004473 {
Jamie Madill610640f2018-11-21 17:28:41 -05004474 context->validationError(GL_INVALID_OPERATION,
4475 "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004476 return false;
4477 }
4478
Geoff Lang111a99e2017-10-17 10:58:41 -04004479 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004480 {
Jamie Madill610640f2018-11-21 17:28:41 -05004481 context->validationError(GL_INVALID_OPERATION, "Extension is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004482 return false;
4483 }
4484
4485 return true;
4486}
4487
Jamie Madill5b772312018-03-08 20:28:32 -05004488bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004489{
Lingfeng Yang038dd532018-03-29 17:31:52 -07004490 if (context->getClientMajorVersion() < 2)
4491 {
4492 return ValidateMultitextureUnit(context, texture);
4493 }
4494
Jamie Madillef300b12016-10-07 15:12:09 -04004495 if (texture < GL_TEXTURE0 ||
4496 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4497 {
Jamie Madill610640f2018-11-21 17:28:41 -05004498 context->validationError(GL_INVALID_ENUM, kErrorInvalidCombinedImageUnit);
Jamie Madillef300b12016-10-07 15:12:09 -04004499 return false;
4500 }
4501
4502 return true;
4503}
4504
Jamie Madill5b772312018-03-08 20:28:32 -05004505bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004506{
4507 Program *programObject = GetValidProgram(context, program);
4508 if (!programObject)
4509 {
4510 return false;
4511 }
4512
4513 Shader *shaderObject = GetValidShader(context, shader);
4514 if (!shaderObject)
4515 {
4516 return false;
4517 }
4518
Jiawei Shao385b3e02018-03-21 09:43:28 +08004519 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04004520 {
Jamie Madill610640f2018-11-21 17:28:41 -05004521 context->validationError(GL_INVALID_OPERATION, kErrorShaderAttachmentHasShader);
Jiawei Shao385b3e02018-03-21 09:43:28 +08004522 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04004523 }
4524
4525 return true;
4526}
4527
Jamie Madill5b772312018-03-08 20:28:32 -05004528bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004529{
4530 if (index >= MAX_VERTEX_ATTRIBS)
4531 {
Jamie Madill610640f2018-11-21 17:28:41 -05004532 context->validationError(GL_INVALID_VALUE, kErrorIndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004533 return false;
4534 }
4535
4536 if (strncmp(name, "gl_", 3) == 0)
4537 {
Jamie Madill610640f2018-11-21 17:28:41 -05004538 context->validationError(GL_INVALID_OPERATION, kErrorNameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004539 return false;
4540 }
4541
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004542 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004543 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004544 const size_t length = strlen(name);
4545
4546 if (!IsValidESSLString(name, length))
4547 {
4548 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4549 // for shader-related entry points
Jamie Madill610640f2018-11-21 17:28:41 -05004550 context->validationError(GL_INVALID_VALUE, kErrorInvalidNameCharacters);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004551 return false;
4552 }
4553
4554 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4555 {
4556 return false;
4557 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004558 }
4559
Jamie Madill01a80ee2016-11-07 12:06:18 -05004560 return GetValidProgram(context, program) != nullptr;
4561}
4562
Jamie Madill5b772312018-03-08 20:28:32 -05004563bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004564{
Geoff Lange8afa902017-09-27 15:00:43 -04004565 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004566 {
Jamie Madilla139f012018-10-10 16:13:03 -04004567 context->validationError(GL_INVALID_ENUM, kErrorInvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004568 return false;
4569 }
4570
4571 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4572 !context->isFramebufferGenerated(framebuffer))
4573 {
Jamie Madilla139f012018-10-10 16:13:03 -04004574 context->validationError(GL_INVALID_OPERATION, kErrorObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004575 return false;
4576 }
4577
4578 return true;
4579}
4580
Jamie Madill5b772312018-03-08 20:28:32 -05004581bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004582{
4583 if (target != GL_RENDERBUFFER)
4584 {
Jamie Madill610640f2018-11-21 17:28:41 -05004585 context->validationError(GL_INVALID_ENUM, kErrorInvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004586 return false;
4587 }
4588
4589 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4590 !context->isRenderbufferGenerated(renderbuffer))
4591 {
Jamie Madill610640f2018-11-21 17:28:41 -05004592 context->validationError(GL_INVALID_OPERATION, kErrorObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004593 return false;
4594 }
4595
4596 return true;
4597}
4598
Jamie Madill5b772312018-03-08 20:28:32 -05004599static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004600{
4601 switch (mode)
4602 {
4603 case GL_FUNC_ADD:
4604 case GL_FUNC_SUBTRACT:
4605 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004606 return true;
4607
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004608 case GL_MIN:
4609 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004610 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004611
4612 default:
4613 return false;
4614 }
4615}
4616
Jamie Madill5b772312018-03-08 20:28:32 -05004617bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004618{
4619 return true;
4620}
4621
Jamie Madill5b772312018-03-08 20:28:32 -05004622bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004623{
Geoff Lang50cac572017-09-26 17:37:43 -04004624 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004625 {
Jamie Madill610640f2018-11-21 17:28:41 -05004626 context->validationError(GL_INVALID_ENUM, kErrorInvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004627 return false;
4628 }
4629
4630 return true;
4631}
4632
Jamie Madill5b772312018-03-08 20:28:32 -05004633bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004634{
Geoff Lang50cac572017-09-26 17:37:43 -04004635 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004636 {
Jamie Madill610640f2018-11-21 17:28:41 -05004637 context->validationError(GL_INVALID_ENUM, kErrorInvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004638 return false;
4639 }
4640
Geoff Lang50cac572017-09-26 17:37:43 -04004641 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004642 {
Jamie Madill610640f2018-11-21 17:28:41 -05004643 context->validationError(GL_INVALID_ENUM, kErrorInvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004644 return false;
4645 }
4646
4647 return true;
4648}
4649
Jamie Madill5b772312018-03-08 20:28:32 -05004650bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004651{
4652 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4653}
4654
Jamie Madill5b772312018-03-08 20:28:32 -05004655bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004656 GLenum srcRGB,
4657 GLenum dstRGB,
4658 GLenum srcAlpha,
4659 GLenum dstAlpha)
4660{
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004661 if (!ValidSrcBlendFunc(context, srcRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004662 {
Jamie Madill610640f2018-11-21 17:28:41 -05004663 context->validationError(GL_INVALID_ENUM, kErrorInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004664 return false;
4665 }
4666
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004667 if (!ValidDstBlendFunc(context, dstRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004668 {
Jamie Madill610640f2018-11-21 17:28:41 -05004669 context->validationError(GL_INVALID_ENUM, kErrorInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004670 return false;
4671 }
4672
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004673 if (!ValidSrcBlendFunc(context, srcAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004674 {
Jamie Madill610640f2018-11-21 17:28:41 -05004675 context->validationError(GL_INVALID_ENUM, kErrorInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004676 return false;
4677 }
4678
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004679 if (!ValidDstBlendFunc(context, dstAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004680 {
Jamie Madill610640f2018-11-21 17:28:41 -05004681 context->validationError(GL_INVALID_ENUM, kErrorInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004682 return false;
4683 }
4684
Frank Henigman146e8a12017-03-02 23:22:37 -05004685 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4686 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004687 {
4688 bool constantColorUsed =
4689 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4690 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4691
4692 bool constantAlphaUsed =
4693 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4694 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4695
4696 if (constantColorUsed && constantAlphaUsed)
4697 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004698 const char *msg;
4699 if (context->getExtensions().webglCompatibility)
4700 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004701 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004702 }
4703 else
4704 {
4705 msg =
4706 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4707 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4708 "implementation.";
Jamie Madilla2f043d2018-07-10 17:21:20 -04004709 WARN() << msg;
Frank Henigman146e8a12017-03-02 23:22:37 -05004710 }
Jamie Madill610640f2018-11-21 17:28:41 -05004711 context->validationError(GL_INVALID_OPERATION, msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004712 return false;
4713 }
4714 }
4715
4716 return true;
4717}
4718
Geoff Langc339c4e2016-11-29 10:37:36 -05004719bool ValidateGetString(Context *context, GLenum name)
4720{
4721 switch (name)
4722 {
4723 case GL_VENDOR:
4724 case GL_RENDERER:
4725 case GL_VERSION:
4726 case GL_SHADING_LANGUAGE_VERSION:
4727 case GL_EXTENSIONS:
4728 break;
4729
4730 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4731 if (!context->getExtensions().requestExtension)
4732 {
Jamie Madill610640f2018-11-21 17:28:41 -05004733 context->validationError(GL_INVALID_ENUM, kErrorInvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004734 return false;
4735 }
4736 break;
4737
4738 default:
Jamie Madill610640f2018-11-21 17:28:41 -05004739 context->validationError(GL_INVALID_ENUM, kErrorInvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004740 return false;
4741 }
4742
4743 return true;
4744}
4745
Jamie Madill5b772312018-03-08 20:28:32 -05004746bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004747{
4748 if (width <= 0.0f || isNaN(width))
4749 {
Jamie Madill610640f2018-11-21 17:28:41 -05004750 context->validationError(GL_INVALID_VALUE, kErrorInvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004751 return false;
4752 }
4753
4754 return true;
4755}
4756
Jamie Madill5b772312018-03-08 20:28:32 -05004757bool ValidateVertexAttribPointer(Context *context,
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004758 GLuint index,
4759 GLint size,
4760 GLenum type,
4761 GLboolean normalized,
4762 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004763 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004764{
Shao80957d92017-02-20 21:25:59 +08004765 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004766 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004767 return false;
4768 }
4769
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004770 if (stride < 0)
4771 {
Jamie Madill610640f2018-11-21 17:28:41 -05004772 context->validationError(GL_INVALID_VALUE, kErrorNegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004773 return false;
4774 }
4775
Shao80957d92017-02-20 21:25:59 +08004776 const Caps &caps = context->getCaps();
4777 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004778 {
Shao80957d92017-02-20 21:25:59 +08004779 if (stride > caps.maxVertexAttribStride)
4780 {
Jamie Madill610640f2018-11-21 17:28:41 -05004781 context->validationError(GL_INVALID_VALUE,
4782 "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004783 return false;
4784 }
4785
4786 if (index >= caps.maxVertexAttribBindings)
4787 {
Jamie Madill610640f2018-11-21 17:28:41 -05004788 context->validationError(GL_INVALID_VALUE,
4789 "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004790 return false;
4791 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004792 }
4793
4794 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4795 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4796 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4797 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004798 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4799 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004800 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4801 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004802 {
Jamie Madill610640f2018-11-21 17:28:41 -05004803 context->validationError(
4804 GL_INVALID_OPERATION,
4805 "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004806 return false;
4807 }
4808
4809 if (context->getExtensions().webglCompatibility)
4810 {
4811 // WebGL 1.0 [Section 6.14] Fixed point support
4812 // The WebGL API does not support the GL_FIXED data type.
4813 if (type == GL_FIXED)
4814 {
Jamie Madill610640f2018-11-21 17:28:41 -05004815 context->validationError(GL_INVALID_ENUM, "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004816 return false;
4817 }
4818
Geoff Lang2d62ab72017-03-23 16:54:40 -04004819 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004820 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004821 return false;
4822 }
4823 }
4824
4825 return true;
4826}
4827
Jamie Madill5b772312018-03-08 20:28:32 -05004828bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004829{
4830 if (context->getExtensions().webglCompatibility && zNear > zFar)
4831 {
Jamie Madill610640f2018-11-21 17:28:41 -05004832 context->validationError(GL_INVALID_OPERATION, kErrorInvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004833 return false;
4834 }
4835
4836 return true;
4837}
4838
Jamie Madill5b772312018-03-08 20:28:32 -05004839bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004840 GLenum target,
4841 GLenum internalformat,
4842 GLsizei width,
4843 GLsizei height)
4844{
4845 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4846 height);
4847}
4848
Jamie Madill5b772312018-03-08 20:28:32 -05004849bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004850 GLenum target,
4851 GLsizei samples,
4852 GLenum internalformat,
4853 GLsizei width,
4854 GLsizei height)
4855{
4856 if (!context->getExtensions().framebufferMultisample)
4857 {
Jamie Madill610640f2018-11-21 17:28:41 -05004858 context->validationError(GL_INVALID_OPERATION,
4859 "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004860 return false;
4861 }
4862
4863 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
Jamie Madill610640f2018-11-21 17:28:41 -05004864 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_VALUE is
Jamie Madille8fb6402017-02-14 17:56:40 -05004865 // generated.
4866 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4867 {
Jamie Madill610640f2018-11-21 17:28:41 -05004868 context->validationError(GL_INVALID_VALUE, kErrorSamplesOutOfRange);
Jamie Madille8fb6402017-02-14 17:56:40 -05004869 return false;
4870 }
4871
4872 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4873 // the specified storage. This is different than ES 3.0 in which a sample number higher
4874 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4875 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4876 if (context->getClientMajorVersion() >= 3)
4877 {
4878 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4879 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4880 {
Jamie Madill610640f2018-11-21 17:28:41 -05004881 context->validationError(GL_OUT_OF_MEMORY, kErrorSamplesOutOfRange);
Jamie Madille8fb6402017-02-14 17:56:40 -05004882 return false;
4883 }
4884 }
4885
4886 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4887 width, height);
4888}
4889
Jamie Madill5b772312018-03-08 20:28:32 -05004890bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004891{
Geoff Lange8afa902017-09-27 15:00:43 -04004892 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004893 {
Jamie Madill610640f2018-11-21 17:28:41 -05004894 context->validationError(GL_INVALID_ENUM, kErrorInvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004895 return false;
4896 }
4897
4898 return true;
4899}
4900
Jamie Madill5b772312018-03-08 20:28:32 -05004901bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004902{
4903 return true;
4904}
4905
Jamie Madill5b772312018-03-08 20:28:32 -05004906bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004907{
4908 return true;
4909}
4910
Jamie Madill5b772312018-03-08 20:28:32 -05004911bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004912{
4913 return true;
4914}
4915
Jamie Madill5b772312018-03-08 20:28:32 -05004916bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004917 GLboolean red,
4918 GLboolean green,
4919 GLboolean blue,
4920 GLboolean alpha)
4921{
4922 return true;
4923}
4924
Jamie Madill5b772312018-03-08 20:28:32 -05004925bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004926{
4927 return true;
4928}
4929
Jamie Madill5b772312018-03-08 20:28:32 -05004930bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004931{
4932 return true;
4933}
4934
Jamie Madill5b772312018-03-08 20:28:32 -05004935bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004936{
4937 switch (mode)
4938 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004939 case CullFaceMode::Front:
4940 case CullFaceMode::Back:
4941 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004942 break;
4943
4944 default:
Jamie Madill610640f2018-11-21 17:28:41 -05004945 context->validationError(GL_INVALID_ENUM, kErrorInvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004946 return false;
4947 }
4948
4949 return true;
4950}
4951
Jamie Madill5b772312018-03-08 20:28:32 -05004952bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004953{
4954 if (program == 0)
4955 {
4956 return false;
4957 }
4958
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004959 if (!context->getProgramResolveLink(program))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004960 {
4961 if (context->getShader(program))
4962 {
Jamie Madill610640f2018-11-21 17:28:41 -05004963 context->validationError(GL_INVALID_OPERATION, kErrorExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004964 return false;
4965 }
4966 else
4967 {
Jamie Madill610640f2018-11-21 17:28:41 -05004968 context->validationError(GL_INVALID_VALUE, kErrorInvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004969 return false;
4970 }
4971 }
4972
4973 return true;
4974}
4975
Jamie Madill5b772312018-03-08 20:28:32 -05004976bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004977{
4978 if (shader == 0)
4979 {
4980 return false;
4981 }
4982
4983 if (!context->getShader(shader))
4984 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004985 if (context->getProgramResolveLink(shader))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004986 {
Jamie Madill610640f2018-11-21 17:28:41 -05004987 context->validationError(GL_INVALID_OPERATION, kErrorInvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004988 return false;
4989 }
4990 else
4991 {
Jamie Madill610640f2018-11-21 17:28:41 -05004992 context->validationError(GL_INVALID_VALUE, kErrorExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004993 return false;
4994 }
4995 }
4996
4997 return true;
4998}
4999
Jamie Madill5b772312018-03-08 20:28:32 -05005000bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005001{
5002 switch (func)
5003 {
5004 case GL_NEVER:
5005 case GL_ALWAYS:
5006 case GL_LESS:
5007 case GL_LEQUAL:
5008 case GL_EQUAL:
5009 case GL_GREATER:
5010 case GL_GEQUAL:
5011 case GL_NOTEQUAL:
5012 break;
5013
5014 default:
Jamie Madill610640f2018-11-21 17:28:41 -05005015 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005016 return false;
5017 }
5018
5019 return true;
5020}
5021
Jamie Madill5b772312018-03-08 20:28:32 -05005022bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005023{
5024 return true;
5025}
5026
Jamie Madill5b772312018-03-08 20:28:32 -05005027bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005028{
5029 Program *programObject = GetValidProgram(context, program);
5030 if (!programObject)
5031 {
5032 return false;
5033 }
5034
5035 Shader *shaderObject = GetValidShader(context, shader);
5036 if (!shaderObject)
5037 {
5038 return false;
5039 }
5040
Jiawei Shao385b3e02018-03-21 09:43:28 +08005041 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005042 if (attachedShader != shaderObject)
5043 {
Jamie Madill610640f2018-11-21 17:28:41 -05005044 context->validationError(GL_INVALID_OPERATION, kErrorShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005045 return false;
5046 }
5047
5048 return true;
5049}
5050
Jamie Madill5b772312018-03-08 20:28:32 -05005051bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005052{
5053 if (index >= MAX_VERTEX_ATTRIBS)
5054 {
Jamie Madill610640f2018-11-21 17:28:41 -05005055 context->validationError(GL_INVALID_VALUE, kErrorIndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005056 return false;
5057 }
5058
5059 return true;
5060}
5061
Jamie Madill5b772312018-03-08 20:28:32 -05005062bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005063{
5064 if (index >= MAX_VERTEX_ATTRIBS)
5065 {
Jamie Madill610640f2018-11-21 17:28:41 -05005066 context->validationError(GL_INVALID_VALUE, kErrorIndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005067 return false;
5068 }
5069
5070 return true;
5071}
5072
Jamie Madill5b772312018-03-08 20:28:32 -05005073bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005074{
5075 return true;
5076}
5077
Jamie Madill5b772312018-03-08 20:28:32 -05005078bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005079{
5080 return true;
5081}
5082
Jamie Madill5b772312018-03-08 20:28:32 -05005083bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005084{
5085 switch (mode)
5086 {
5087 case GL_CW:
5088 case GL_CCW:
5089 break;
5090 default:
Jamie Madill610640f2018-11-21 17:28:41 -05005091 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005092 return false;
5093 }
5094
5095 return true;
5096}
5097
Jamie Madill5b772312018-03-08 20:28:32 -05005098bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005099 GLuint program,
5100 GLuint index,
5101 GLsizei bufsize,
5102 GLsizei *length,
5103 GLint *size,
5104 GLenum *type,
5105 GLchar *name)
5106{
5107 if (bufsize < 0)
5108 {
Jamie Madill610640f2018-11-21 17:28:41 -05005109 context->validationError(GL_INVALID_VALUE, kErrorNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005110 return false;
5111 }
5112
5113 Program *programObject = GetValidProgram(context, program);
5114
5115 if (!programObject)
5116 {
5117 return false;
5118 }
5119
5120 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5121 {
Jamie Madill610640f2018-11-21 17:28:41 -05005122 context->validationError(GL_INVALID_VALUE, kErrorIndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005123 return false;
5124 }
5125
5126 return true;
5127}
5128
Jamie Madill5b772312018-03-08 20:28:32 -05005129bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005130 GLuint program,
5131 GLuint index,
5132 GLsizei bufsize,
5133 GLsizei *length,
5134 GLint *size,
5135 GLenum *type,
5136 GLchar *name)
5137{
5138 if (bufsize < 0)
5139 {
Jamie Madill610640f2018-11-21 17:28:41 -05005140 context->validationError(GL_INVALID_VALUE, kErrorNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005141 return false;
5142 }
5143
5144 Program *programObject = GetValidProgram(context, program);
5145
5146 if (!programObject)
5147 {
5148 return false;
5149 }
5150
5151 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5152 {
Jamie Madill610640f2018-11-21 17:28:41 -05005153 context->validationError(GL_INVALID_VALUE, kErrorIndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005154 return false;
5155 }
5156
5157 return true;
5158}
5159
Jamie Madill5b772312018-03-08 20:28:32 -05005160bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005161 GLuint program,
5162 GLsizei maxcount,
5163 GLsizei *count,
5164 GLuint *shaders)
5165{
5166 if (maxcount < 0)
5167 {
Jamie Madill610640f2018-11-21 17:28:41 -05005168 context->validationError(GL_INVALID_VALUE, kErrorNegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005169 return false;
5170 }
5171
5172 Program *programObject = GetValidProgram(context, program);
5173
5174 if (!programObject)
5175 {
5176 return false;
5177 }
5178
5179 return true;
5180}
5181
Jamie Madill5b772312018-03-08 20:28:32 -05005182bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005183{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005184 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5185 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005186 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005187 {
Jamie Madill610640f2018-11-21 17:28:41 -05005188 context->validationError(GL_INVALID_VALUE, kErrorInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005189 return false;
5190 }
5191
Jamie Madillc1d770e2017-04-13 17:31:24 -04005192 Program *programObject = GetValidProgram(context, program);
5193
5194 if (!programObject)
5195 {
Jamie Madill610640f2018-11-21 17:28:41 -05005196 context->validationError(GL_INVALID_OPERATION, kErrorProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005197 return false;
5198 }
5199
5200 if (!programObject->isLinked())
5201 {
Jamie Madill610640f2018-11-21 17:28:41 -05005202 context->validationError(GL_INVALID_OPERATION, kErrorProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005203 return false;
5204 }
5205
5206 return true;
5207}
5208
Jamie Madill5b772312018-03-08 20:28:32 -05005209bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005210{
5211 GLenum nativeType;
5212 unsigned int numParams = 0;
5213 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5214}
5215
Jamie Madill5b772312018-03-08 20:28:32 -05005216bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005217{
5218 return true;
5219}
5220
Jamie Madill5b772312018-03-08 20:28:32 -05005221bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005222{
5223 GLenum nativeType;
5224 unsigned int numParams = 0;
5225 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5226}
5227
Jamie Madill5b772312018-03-08 20:28:32 -05005228bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005229{
5230 GLenum nativeType;
5231 unsigned int numParams = 0;
5232 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5233}
5234
Jamie Madill5b772312018-03-08 20:28:32 -05005235bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005236 GLuint program,
5237 GLsizei bufsize,
5238 GLsizei *length,
5239 GLchar *infolog)
5240{
5241 if (bufsize < 0)
5242 {
Jamie Madill610640f2018-11-21 17:28:41 -05005243 context->validationError(GL_INVALID_VALUE, kErrorNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005244 return false;
5245 }
5246
5247 Program *programObject = GetValidProgram(context, program);
5248 if (!programObject)
5249 {
5250 return false;
5251 }
5252
5253 return true;
5254}
5255
Jamie Madill5b772312018-03-08 20:28:32 -05005256bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005257 GLuint shader,
5258 GLsizei bufsize,
5259 GLsizei *length,
5260 GLchar *infolog)
5261{
5262 if (bufsize < 0)
5263 {
Jamie Madill610640f2018-11-21 17:28:41 -05005264 context->validationError(GL_INVALID_VALUE, kErrorNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005265 return false;
5266 }
5267
5268 Shader *shaderObject = GetValidShader(context, shader);
5269 if (!shaderObject)
5270 {
5271 return false;
5272 }
5273
5274 return true;
5275}
5276
Jamie Madill5b772312018-03-08 20:28:32 -05005277bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005278 GLenum shadertype,
5279 GLenum precisiontype,
5280 GLint *range,
5281 GLint *precision)
5282{
5283 switch (shadertype)
5284 {
5285 case GL_VERTEX_SHADER:
5286 case GL_FRAGMENT_SHADER:
5287 break;
5288 case GL_COMPUTE_SHADER:
Jamie Madill610640f2018-11-21 17:28:41 -05005289 context->validationError(GL_INVALID_OPERATION,
5290 "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005291 return false;
5292 default:
Jamie Madill610640f2018-11-21 17:28:41 -05005293 context->validationError(GL_INVALID_ENUM, kErrorInvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005294 return false;
5295 }
5296
5297 switch (precisiontype)
5298 {
5299 case GL_LOW_FLOAT:
5300 case GL_MEDIUM_FLOAT:
5301 case GL_HIGH_FLOAT:
5302 case GL_LOW_INT:
5303 case GL_MEDIUM_INT:
5304 case GL_HIGH_INT:
5305 break;
5306
5307 default:
Jamie Madill610640f2018-11-21 17:28:41 -05005308 context->validationError(GL_INVALID_ENUM, kErrorInvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005309 return false;
5310 }
5311
5312 return true;
5313}
5314
Jamie Madill5b772312018-03-08 20:28:32 -05005315bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005316 GLuint shader,
5317 GLsizei bufsize,
5318 GLsizei *length,
5319 GLchar *source)
5320{
5321 if (bufsize < 0)
5322 {
Jamie Madill610640f2018-11-21 17:28:41 -05005323 context->validationError(GL_INVALID_VALUE, kErrorNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005324 return false;
5325 }
5326
5327 Shader *shaderObject = GetValidShader(context, shader);
5328 if (!shaderObject)
5329 {
5330 return false;
5331 }
5332
5333 return true;
5334}
5335
Jamie Madill5b772312018-03-08 20:28:32 -05005336bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005337{
5338 if (strstr(name, "gl_") == name)
5339 {
5340 return false;
5341 }
5342
Geoff Langfc32e8b2017-05-31 14:16:59 -04005343 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5344 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005345 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005346 {
Jamie Madill610640f2018-11-21 17:28:41 -05005347 context->validationError(GL_INVALID_VALUE, kErrorInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005348 return false;
5349 }
5350
Jamie Madillc1d770e2017-04-13 17:31:24 -04005351 Program *programObject = GetValidProgram(context, program);
5352
5353 if (!programObject)
5354 {
5355 return false;
5356 }
5357
5358 if (!programObject->isLinked())
5359 {
Jamie Madill610640f2018-11-21 17:28:41 -05005360 context->validationError(GL_INVALID_OPERATION, kErrorProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005361 return false;
5362 }
5363
5364 return true;
5365}
5366
Jamie Madill5b772312018-03-08 20:28:32 -05005367bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005368{
5369 switch (mode)
5370 {
5371 case GL_FASTEST:
5372 case GL_NICEST:
5373 case GL_DONT_CARE:
5374 break;
5375
5376 default:
Jamie Madill610640f2018-11-21 17:28:41 -05005377 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005378 return false;
5379 }
5380
5381 switch (target)
5382 {
5383 case GL_GENERATE_MIPMAP_HINT:
5384 break;
5385
Geoff Lange7bd2182017-06-16 16:13:13 -04005386 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5387 if (context->getClientVersion() < ES_3_0 &&
5388 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005389 {
Jamie Madill610640f2018-11-21 17:28:41 -05005390 context->validationError(GL_INVALID_ENUM,
5391 "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005392 return false;
5393 }
5394 break;
5395
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07005396 case GL_PERSPECTIVE_CORRECTION_HINT:
5397 case GL_POINT_SMOOTH_HINT:
5398 case GL_LINE_SMOOTH_HINT:
5399 case GL_FOG_HINT:
5400 if (context->getClientMajorVersion() >= 2)
5401 {
Jamie Madill610640f2018-11-21 17:28:41 -05005402 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07005403 return false;
5404 }
5405 break;
5406
Jamie Madillc1d770e2017-04-13 17:31:24 -04005407 default:
Jamie Madill610640f2018-11-21 17:28:41 -05005408 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005409 return false;
5410 }
5411
5412 return true;
5413}
5414
Jamie Madill5b772312018-03-08 20:28:32 -05005415bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005416{
5417 return true;
5418}
5419
Jamie Madill5b772312018-03-08 20:28:32 -05005420bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005421{
5422 return true;
5423}
5424
Jamie Madill5b772312018-03-08 20:28:32 -05005425bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005426{
5427 return true;
5428}
5429
Jamie Madill5b772312018-03-08 20:28:32 -05005430bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005431{
5432 return true;
5433}
5434
Jamie Madill5b772312018-03-08 20:28:32 -05005435bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005436{
5437 return true;
5438}
5439
Jamie Madill5b772312018-03-08 20:28:32 -05005440bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005441{
5442 return true;
5443}
5444
Jamie Madill5b772312018-03-08 20:28:32 -05005445bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005446{
5447 if (context->getClientMajorVersion() < 3)
5448 {
5449 switch (pname)
5450 {
5451 case GL_UNPACK_IMAGE_HEIGHT:
5452 case GL_UNPACK_SKIP_IMAGES:
Jamie Madill610640f2018-11-21 17:28:41 -05005453 context->validationError(GL_INVALID_ENUM, kErrorInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005454 return false;
5455
5456 case GL_UNPACK_ROW_LENGTH:
5457 case GL_UNPACK_SKIP_ROWS:
5458 case GL_UNPACK_SKIP_PIXELS:
5459 if (!context->getExtensions().unpackSubimage)
5460 {
Jamie Madill610640f2018-11-21 17:28:41 -05005461 context->validationError(GL_INVALID_ENUM, kErrorInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005462 return false;
5463 }
5464 break;
5465
5466 case GL_PACK_ROW_LENGTH:
5467 case GL_PACK_SKIP_ROWS:
5468 case GL_PACK_SKIP_PIXELS:
5469 if (!context->getExtensions().packSubimage)
5470 {
Jamie Madill610640f2018-11-21 17:28:41 -05005471 context->validationError(GL_INVALID_ENUM, kErrorInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005472 return false;
5473 }
5474 break;
5475 }
5476 }
5477
5478 if (param < 0)
5479 {
Jamie Madill610640f2018-11-21 17:28:41 -05005480 context->validationError(GL_INVALID_VALUE, "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005481 return false;
5482 }
5483
5484 switch (pname)
5485 {
5486 case GL_UNPACK_ALIGNMENT:
5487 if (param != 1 && param != 2 && param != 4 && param != 8)
5488 {
Jamie Madill610640f2018-11-21 17:28:41 -05005489 context->validationError(GL_INVALID_VALUE, kErrorInvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005490 return false;
5491 }
5492 break;
5493
5494 case GL_PACK_ALIGNMENT:
5495 if (param != 1 && param != 2 && param != 4 && param != 8)
5496 {
Jamie Madill610640f2018-11-21 17:28:41 -05005497 context->validationError(GL_INVALID_VALUE, kErrorInvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005498 return false;
5499 }
5500 break;
5501
5502 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005503 if (!context->getExtensions().packReverseRowOrder)
5504 {
Jamie Madill610640f2018-11-21 17:28:41 -05005505 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Geoff Lang000dab82017-09-27 14:27:07 -04005506 }
5507 break;
5508
Jamie Madillc1d770e2017-04-13 17:31:24 -04005509 case GL_UNPACK_ROW_LENGTH:
5510 case GL_UNPACK_IMAGE_HEIGHT:
5511 case GL_UNPACK_SKIP_IMAGES:
5512 case GL_UNPACK_SKIP_ROWS:
5513 case GL_UNPACK_SKIP_PIXELS:
5514 case GL_PACK_ROW_LENGTH:
5515 case GL_PACK_SKIP_ROWS:
5516 case GL_PACK_SKIP_PIXELS:
5517 break;
5518
5519 default:
Jamie Madill610640f2018-11-21 17:28:41 -05005520 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005521 return false;
5522 }
5523
5524 return true;
5525}
5526
Jamie Madill5b772312018-03-08 20:28:32 -05005527bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005528{
5529 return true;
5530}
5531
Jamie Madill5b772312018-03-08 20:28:32 -05005532bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005533{
5534 return true;
5535}
5536
Jamie Madill5b772312018-03-08 20:28:32 -05005537bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005538{
5539 return true;
5540}
5541
Jamie Madill5b772312018-03-08 20:28:32 -05005542bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005543{
5544 if (width < 0 || height < 0)
5545 {
Jamie Madill610640f2018-11-21 17:28:41 -05005546 context->validationError(GL_INVALID_VALUE, kErrorNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005547 return false;
5548 }
5549
5550 return true;
5551}
5552
Jamie Madill5b772312018-03-08 20:28:32 -05005553bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005554 GLsizei n,
5555 const GLuint *shaders,
5556 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005557 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005558 GLsizei length)
5559{
5560 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5561 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5562 shaderBinaryFormats.end())
5563 {
Jamie Madill610640f2018-11-21 17:28:41 -05005564 context->validationError(GL_INVALID_ENUM, "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005565 return false;
5566 }
5567
5568 return true;
5569}
5570
Jamie Madill5b772312018-03-08 20:28:32 -05005571bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005572 GLuint shader,
5573 GLsizei count,
5574 const GLchar *const *string,
5575 const GLint *length)
5576{
5577 if (count < 0)
5578 {
Jamie Madill610640f2018-11-21 17:28:41 -05005579 context->validationError(GL_INVALID_VALUE, kErrorNegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005580 return false;
5581 }
5582
Geoff Langfc32e8b2017-05-31 14:16:59 -04005583 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5584 // shader-related entry points
5585 if (context->getExtensions().webglCompatibility)
5586 {
5587 for (GLsizei i = 0; i < count; i++)
5588 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005589 size_t len =
5590 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005591
5592 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005593 if (!IsValidESSLShaderSourceString(string[i], len,
5594 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005595 {
Jamie Madill610640f2018-11-21 17:28:41 -05005596 context->validationError(GL_INVALID_VALUE, kErrorShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005597 return false;
5598 }
5599 }
5600 }
5601
Jamie Madillc1d770e2017-04-13 17:31:24 -04005602 Shader *shaderObject = GetValidShader(context, shader);
5603 if (!shaderObject)
5604 {
5605 return false;
5606 }
5607
5608 return true;
5609}
5610
Jamie Madill5b772312018-03-08 20:28:32 -05005611bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005612{
5613 if (!IsValidStencilFunc(func))
5614 {
Jamie Madill610640f2018-11-21 17:28:41 -05005615 context->validationError(GL_INVALID_ENUM, kErrorInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005616 return false;
5617 }
5618
5619 return true;
5620}
5621
Jamie Madill5b772312018-03-08 20:28:32 -05005622bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005623{
5624 if (!IsValidStencilFace(face))
5625 {
Jamie Madill610640f2018-11-21 17:28:41 -05005626 context->validationError(GL_INVALID_ENUM, kErrorInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005627 return false;
5628 }
5629
5630 if (!IsValidStencilFunc(func))
5631 {
Jamie Madill610640f2018-11-21 17:28:41 -05005632 context->validationError(GL_INVALID_ENUM, kErrorInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005633 return false;
5634 }
5635
5636 return true;
5637}
5638
Jamie Madill5b772312018-03-08 20:28:32 -05005639bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005640{
5641 return true;
5642}
5643
Jamie Madill5b772312018-03-08 20:28:32 -05005644bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005645{
5646 if (!IsValidStencilFace(face))
5647 {
Jamie Madill610640f2018-11-21 17:28:41 -05005648 context->validationError(GL_INVALID_ENUM, kErrorInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005649 return false;
5650 }
5651
5652 return true;
5653}
5654
Jamie Madill5b772312018-03-08 20:28:32 -05005655bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005656{
5657 if (!IsValidStencilOp(fail))
5658 {
Jamie Madill610640f2018-11-21 17:28:41 -05005659 context->validationError(GL_INVALID_ENUM, kErrorInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005660 return false;
5661 }
5662
5663 if (!IsValidStencilOp(zfail))
5664 {
Jamie Madill610640f2018-11-21 17:28:41 -05005665 context->validationError(GL_INVALID_ENUM, kErrorInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005666 return false;
5667 }
5668
5669 if (!IsValidStencilOp(zpass))
5670 {
Jamie Madill610640f2018-11-21 17:28:41 -05005671 context->validationError(GL_INVALID_ENUM, kErrorInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005672 return false;
5673 }
5674
5675 return true;
5676}
5677
Jamie Madill5b772312018-03-08 20:28:32 -05005678bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005679 GLenum face,
5680 GLenum fail,
5681 GLenum zfail,
5682 GLenum zpass)
5683{
5684 if (!IsValidStencilFace(face))
5685 {
Jamie Madill610640f2018-11-21 17:28:41 -05005686 context->validationError(GL_INVALID_ENUM, kErrorInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005687 return false;
5688 }
5689
5690 return ValidateStencilOp(context, fail, zfail, zpass);
5691}
5692
Jamie Madill5b772312018-03-08 20:28:32 -05005693bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005694{
5695 return ValidateUniform(context, GL_FLOAT, location, 1);
5696}
5697
Jamie Madill5b772312018-03-08 20:28:32 -05005698bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005699{
5700 return ValidateUniform(context, GL_FLOAT, location, count);
5701}
5702
Jamie Madill5b772312018-03-08 20:28:32 -05005703bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005704{
5705 return ValidateUniform1iv(context, location, 1, &x);
5706}
5707
Jamie Madill5b772312018-03-08 20:28:32 -05005708bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005709{
5710 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5711}
5712
Jamie Madill5b772312018-03-08 20:28:32 -05005713bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005714{
5715 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5716}
5717
Jamie Madill5b772312018-03-08 20:28:32 -05005718bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005719{
5720 return ValidateUniform(context, GL_INT_VEC2, location, count);
5721}
5722
Jamie Madill5b772312018-03-08 20:28:32 -05005723bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005724{
5725 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5726}
5727
Jamie Madill5b772312018-03-08 20:28:32 -05005728bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005729{
5730 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5731}
5732
Jamie Madill5b772312018-03-08 20:28:32 -05005733bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005734{
5735 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5736}
5737
Jamie Madill5b772312018-03-08 20:28:32 -05005738bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005739{
5740 return ValidateUniform(context, GL_INT_VEC3, location, count);
5741}
5742
Jamie Madill5b772312018-03-08 20:28:32 -05005743bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005744{
5745 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5746}
5747
Jamie Madill5b772312018-03-08 20:28:32 -05005748bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005749{
5750 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5751}
5752
Jamie Madill5b772312018-03-08 20:28:32 -05005753bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005754{
5755 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5756}
5757
Jamie Madill5b772312018-03-08 20:28:32 -05005758bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005759{
5760 return ValidateUniform(context, GL_INT_VEC4, location, count);
5761}
5762
Jamie Madill5b772312018-03-08 20:28:32 -05005763bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005764 GLint location,
5765 GLsizei count,
5766 GLboolean transpose,
5767 const GLfloat *value)
5768{
5769 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5770}
5771
Jamie Madill5b772312018-03-08 20:28:32 -05005772bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005773 GLint location,
5774 GLsizei count,
5775 GLboolean transpose,
5776 const GLfloat *value)
5777{
5778 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5779}
5780
Jamie Madill5b772312018-03-08 20:28:32 -05005781bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005782 GLint location,
5783 GLsizei count,
5784 GLboolean transpose,
5785 const GLfloat *value)
5786{
5787 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5788}
5789
Jamie Madill5b772312018-03-08 20:28:32 -05005790bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005791{
5792 Program *programObject = GetValidProgram(context, program);
5793
5794 if (!programObject)
5795 {
5796 return false;
5797 }
5798
5799 return true;
5800}
5801
Jamie Madill5b772312018-03-08 20:28:32 -05005802bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005803{
5804 return ValidateVertexAttribIndex(context, index);
5805}
5806
Jamie Madill5b772312018-03-08 20:28:32 -05005807bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005808{
5809 return ValidateVertexAttribIndex(context, index);
5810}
5811
Jamie Madill5b772312018-03-08 20:28:32 -05005812bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005813{
5814 return ValidateVertexAttribIndex(context, index);
5815}
5816
Jamie Madill5b772312018-03-08 20:28:32 -05005817bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005818{
5819 return ValidateVertexAttribIndex(context, index);
5820}
5821
Jamie Madill5b772312018-03-08 20:28:32 -05005822bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005823{
5824 return ValidateVertexAttribIndex(context, index);
5825}
5826
Jamie Madill5b772312018-03-08 20:28:32 -05005827bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005828{
5829 return ValidateVertexAttribIndex(context, index);
5830}
5831
Jamie Madill5b772312018-03-08 20:28:32 -05005832bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005833 GLuint index,
5834 GLfloat x,
5835 GLfloat y,
5836 GLfloat z,
5837 GLfloat w)
5838{
5839 return ValidateVertexAttribIndex(context, index);
5840}
5841
Jamie Madill5b772312018-03-08 20:28:32 -05005842bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005843{
5844 return ValidateVertexAttribIndex(context, index);
5845}
5846
Jamie Madill5b772312018-03-08 20:28:32 -05005847bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005848{
5849 if (width < 0 || height < 0)
5850 {
Jamie Madill610640f2018-11-21 17:28:41 -05005851 context->validationError(GL_INVALID_VALUE, kErrorViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005852 return false;
5853 }
5854
5855 return true;
5856}
5857
Jamie Madill5b772312018-03-08 20:28:32 -05005858bool ValidateDrawElements(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04005859 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005860 GLsizei count,
5861 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005862 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005863{
5864 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5865}
5866
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005867bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005868 GLenum target,
5869 GLenum attachment,
5870 GLenum pname,
5871 GLint *params)
5872{
5873 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5874 nullptr);
5875}
5876
Jamie Madill5b772312018-03-08 20:28:32 -05005877bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04005878{
5879 return ValidateGetProgramivBase(context, program, pname, nullptr);
5880}
5881
Jamie Madill5b772312018-03-08 20:28:32 -05005882bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005883 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005884 GLint level,
5885 GLenum internalformat,
5886 GLint x,
5887 GLint y,
5888 GLsizei width,
5889 GLsizei height,
5890 GLint border)
5891{
5892 if (context->getClientMajorVersion() < 3)
5893 {
5894 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5895 0, x, y, width, height, border);
5896 }
5897
5898 ASSERT(context->getClientMajorVersion() == 3);
5899 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5900 0, x, y, width, height, border);
5901}
5902
5903bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005904 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005905 GLint level,
5906 GLint xoffset,
5907 GLint yoffset,
5908 GLint x,
5909 GLint y,
5910 GLsizei width,
5911 GLsizei height)
5912{
5913 if (context->getClientMajorVersion() < 3)
5914 {
5915 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5916 yoffset, x, y, width, height, 0);
5917 }
5918
5919 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5920 yoffset, 0, x, y, width, height, 0);
5921}
5922
5923bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5924{
5925 return ValidateGenOrDelete(context, n);
5926}
5927
5928bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5929{
5930 return ValidateGenOrDelete(context, n);
5931}
5932
5933bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5934{
5935 return ValidateGenOrDelete(context, n);
5936}
5937
5938bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5939{
5940 return ValidateGenOrDelete(context, n);
5941}
5942
5943bool ValidateDisable(Context *context, GLenum cap)
5944{
5945 if (!ValidCap(context, cap, false))
5946 {
Jamie Madill610640f2018-11-21 17:28:41 -05005947 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005948 return false;
5949 }
5950
5951 return true;
5952}
5953
5954bool ValidateEnable(Context *context, GLenum cap)
5955{
5956 if (!ValidCap(context, cap, false))
5957 {
Jamie Madill610640f2018-11-21 17:28:41 -05005958 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005959 return false;
5960 }
5961
5962 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5963 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5964 {
5965 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Jamie Madill610640f2018-11-21 17:28:41 -05005966 context->validationError(GL_INVALID_OPERATION, errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005967
5968 // We also output an error message to the debugger window if tracing is active, so that
5969 // developers can see the error message.
5970 ERR() << errorMessage;
5971 return false;
5972 }
5973
5974 return true;
5975}
5976
5977bool ValidateFramebufferRenderbuffer(Context *context,
5978 GLenum target,
5979 GLenum attachment,
5980 GLenum renderbuffertarget,
5981 GLuint renderbuffer)
5982{
Geoff Lange8afa902017-09-27 15:00:43 -04005983 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005984 {
Jamie Madill610640f2018-11-21 17:28:41 -05005985 context->validationError(GL_INVALID_ENUM, kErrorInvalidFramebufferTarget);
Brandon Jones6cad5662017-06-14 13:25:13 -07005986 return false;
5987 }
5988
5989 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5990 {
Jamie Madill610640f2018-11-21 17:28:41 -05005991 context->validationError(GL_INVALID_ENUM, kErrorInvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005992 return false;
5993 }
5994
5995 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5996 renderbuffertarget, renderbuffer);
5997}
5998
5999bool ValidateFramebufferTexture2D(Context *context,
6000 GLenum target,
6001 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006002 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04006003 GLuint texture,
6004 GLint level)
6005{
6006 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
6007 // extension
6008 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
6009 level != 0)
6010 {
Jamie Madill610640f2018-11-21 17:28:41 -05006011 context->validationError(GL_INVALID_VALUE, kErrorInvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04006012 return false;
6013 }
6014
6015 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
6016 {
6017 return false;
6018 }
6019
6020 if (texture != 0)
6021 {
6022 gl::Texture *tex = context->getTexture(texture);
6023 ASSERT(tex);
6024
6025 const gl::Caps &caps = context->getCaps();
6026
6027 switch (textarget)
6028 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006029 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04006030 {
6031 if (level > gl::log2(caps.max2DTextureSize))
6032 {
Jamie Madill610640f2018-11-21 17:28:41 -05006033 context->validationError(GL_INVALID_VALUE, kErrorInvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04006034 return false;
6035 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006036 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04006037 {
Jamie Madill610640f2018-11-21 17:28:41 -05006038 context->validationError(GL_INVALID_OPERATION, kErrorInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006039 return false;
6040 }
6041 }
6042 break;
6043
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006044 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006045 {
6046 if (level != 0)
6047 {
Jamie Madill610640f2018-11-21 17:28:41 -05006048 context->validationError(GL_INVALID_VALUE, kErrorInvalidMipLevel);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006049 return false;
6050 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006051 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006052 {
Jamie Madill610640f2018-11-21 17:28:41 -05006053 context->validationError(GL_INVALID_OPERATION,
6054 "Textarget must match the texture target type.");
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006055 return false;
6056 }
6057 }
6058 break;
6059
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006060 case TextureTarget::CubeMapNegativeX:
6061 case TextureTarget::CubeMapNegativeY:
6062 case TextureTarget::CubeMapNegativeZ:
6063 case TextureTarget::CubeMapPositiveX:
6064 case TextureTarget::CubeMapPositiveY:
6065 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04006066 {
6067 if (level > gl::log2(caps.maxCubeMapTextureSize))
6068 {
Jamie Madill610640f2018-11-21 17:28:41 -05006069 context->validationError(GL_INVALID_VALUE, kErrorInvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04006070 return false;
6071 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006072 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04006073 {
Jamie Madill610640f2018-11-21 17:28:41 -05006074 context->validationError(GL_INVALID_OPERATION,
6075 "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006076 return false;
6077 }
6078 }
6079 break;
6080
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006081 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04006082 {
Yizhou Jiang7818a852018-09-06 15:02:04 +08006083 if (context->getClientVersion() < ES_3_1 &&
6084 !context->getExtensions().textureMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006085 {
Jamie Madill610640f2018-11-21 17:28:41 -05006086 context->validationError(GL_INVALID_OPERATION,
6087 kErrorMultisampleTextureExtensionOrES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006088 return false;
6089 }
6090
6091 if (level != 0)
6092 {
Jamie Madill610640f2018-11-21 17:28:41 -05006093 context->validationError(GL_INVALID_VALUE, kErrorLevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006094 return false;
6095 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006096 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006097 {
Jamie Madill610640f2018-11-21 17:28:41 -05006098 context->validationError(GL_INVALID_OPERATION,
6099 "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006100 return false;
6101 }
6102 }
6103 break;
6104
6105 default:
Jamie Madill610640f2018-11-21 17:28:41 -05006106 context->validationError(GL_INVALID_ENUM, kErrorInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006107 return false;
6108 }
Jamie Madillbe849e42017-05-02 15:49:00 -04006109 }
6110
6111 return true;
6112}
6113
6114bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6115{
6116 return ValidateGenOrDelete(context, n);
6117}
6118
6119bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6120{
6121 return ValidateGenOrDelete(context, n);
6122}
6123
6124bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6125{
6126 return ValidateGenOrDelete(context, n);
6127}
6128
6129bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6130{
6131 return ValidateGenOrDelete(context, n);
6132}
6133
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006134bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006135{
6136 if (!ValidTextureTarget(context, target))
6137 {
Jamie Madill610640f2018-11-21 17:28:41 -05006138 context->validationError(GL_INVALID_ENUM, kErrorInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006139 return false;
6140 }
6141
6142 Texture *texture = context->getTargetTexture(target);
6143
6144 if (texture == nullptr)
6145 {
Jamie Madill610640f2018-11-21 17:28:41 -05006146 context->validationError(GL_INVALID_OPERATION, kErrorTextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006147 return false;
6148 }
6149
6150 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6151
6152 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6153 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6154 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6155 {
Jamie Madill610640f2018-11-21 17:28:41 -05006156 context->validationError(GL_INVALID_OPERATION, kErrorBaseLevelOutOfRange);
Jamie Madillbe849e42017-05-02 15:49:00 -04006157 return false;
6158 }
6159
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006160 TextureTarget baseTarget = (target == TextureType::CubeMap)
6161 ? TextureTarget::CubeMapPositiveX
6162 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006163 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6164 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6165 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006166 {
Jamie Madill610640f2018-11-21 17:28:41 -05006167 context->validationError(GL_INVALID_OPERATION, kErrorGenerateMipmapNotAllowed);
Brandon Jones6cad5662017-06-14 13:25:13 -07006168 return false;
6169 }
6170
Geoff Lang536eca12017-09-13 11:23:35 -04006171 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6172 bool formatUnsized = !format.sized;
6173 bool formatColorRenderableAndFilterable =
6174 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
Yuly Novikovf15f8862018-06-04 18:59:41 -04006175 format.textureAttachmentSupport(context->getClientVersion(), context->getExtensions());
Geoff Lang536eca12017-09-13 11:23:35 -04006176 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006177 {
Jamie Madill610640f2018-11-21 17:28:41 -05006178 context->validationError(GL_INVALID_OPERATION, kErrorGenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006179 return false;
6180 }
6181
Geoff Lang536eca12017-09-13 11:23:35 -04006182 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6183 // generation
6184 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6185 {
Jamie Madill610640f2018-11-21 17:28:41 -05006186 context->validationError(GL_INVALID_OPERATION, kErrorGenerateMipmapNotAllowed);
Geoff Lang536eca12017-09-13 11:23:35 -04006187 return false;
6188 }
6189
Jiange2c00842018-07-13 16:50:49 +08006190 // According to the OpenGL extension spec EXT_sRGB.txt, EXT_SRGB is based on ES 2.0 and
6191 // generateMipmap is not allowed if texture format is SRGB_EXT or SRGB_ALPHA_EXT.
6192 if (context->getClientVersion() < Version(3, 0) && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006193 {
Jamie Madill610640f2018-11-21 17:28:41 -05006194 context->validationError(GL_INVALID_OPERATION, kErrorGenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006195 return false;
6196 }
6197
6198 // Non-power of 2 ES2 check
6199 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6200 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6201 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6202 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006203 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6204 target == TextureType::CubeMap);
Jamie Madill610640f2018-11-21 17:28:41 -05006205 context->validationError(GL_INVALID_OPERATION, kErrorTextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006206 return false;
6207 }
6208
6209 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006210 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006211 {
Jamie Madill610640f2018-11-21 17:28:41 -05006212 context->validationError(GL_INVALID_OPERATION, kErrorCubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006213 return false;
6214 }
6215
6216 return true;
6217}
6218
Jamie Madill5b772312018-03-08 20:28:32 -05006219bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006220 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006221 GLenum pname,
6222 GLint *params)
6223{
6224 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6225}
6226
6227bool ValidateGetRenderbufferParameteriv(Context *context,
6228 GLenum target,
6229 GLenum pname,
6230 GLint *params)
6231{
6232 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6233}
6234
6235bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6236{
6237 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6238}
6239
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006240bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006241{
6242 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6243}
6244
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006245bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006246{
6247 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6248}
6249
Till Rathmannb8543632018-10-02 19:46:14 +02006250bool ValidateGetTexParameterIivOES(Context *context,
6251 TextureType target,
6252 GLenum pname,
6253 GLint *params)
6254{
6255 if (context->getClientMajorVersion() < 3)
6256 {
Jamie Madill610640f2018-11-21 17:28:41 -05006257 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006258 return false;
6259 }
6260 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6261}
6262
6263bool ValidateGetTexParameterIuivOES(Context *context,
6264 TextureType target,
6265 GLenum pname,
6266 GLuint *params)
6267{
6268 if (context->getClientMajorVersion() < 3)
6269 {
Jamie Madill610640f2018-11-21 17:28:41 -05006270 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006271 return false;
6272 }
6273 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6274}
6275
Jamie Madillbe849e42017-05-02 15:49:00 -04006276bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6277{
6278 return ValidateGetUniformBase(context, program, location);
6279}
6280
6281bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6282{
6283 return ValidateGetUniformBase(context, program, location);
6284}
6285
6286bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6287{
6288 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6289}
6290
6291bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6292{
6293 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6294}
6295
6296bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6297{
6298 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6299}
6300
6301bool ValidateIsEnabled(Context *context, GLenum cap)
6302{
6303 if (!ValidCap(context, cap, true))
6304 {
Jamie Madill610640f2018-11-21 17:28:41 -05006305 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006306 return false;
6307 }
6308
6309 return true;
6310}
6311
6312bool ValidateLinkProgram(Context *context, GLuint program)
6313{
6314 if (context->hasActiveTransformFeedback(program))
6315 {
6316 // ES 3.0.4 section 2.15 page 91
Jamie Madill610640f2018-11-21 17:28:41 -05006317 context->validationError(GL_INVALID_OPERATION,
6318 "Cannot link program while program is "
6319 "associated with an active transform "
6320 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006321 return false;
6322 }
6323
6324 Program *programObject = GetValidProgram(context, program);
6325 if (!programObject)
6326 {
6327 return false;
6328 }
6329
6330 return true;
6331}
6332
Jamie Madill4928b7c2017-06-20 12:57:39 -04006333bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006334 GLint x,
6335 GLint y,
6336 GLsizei width,
6337 GLsizei height,
6338 GLenum format,
6339 GLenum type,
6340 void *pixels)
6341{
6342 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6343 nullptr, pixels);
6344}
6345
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006346bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006347{
Till Rathmannb8543632018-10-02 19:46:14 +02006348 return ValidateTexParameterBase(context, target, pname, -1, false, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006349}
6350
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006351bool ValidateTexParameterfv(Context *context,
6352 TextureType target,
6353 GLenum pname,
6354 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006355{
Till Rathmannb8543632018-10-02 19:46:14 +02006356 return ValidateTexParameterBase(context, target, pname, -1, true, params);
Jamie Madillbe849e42017-05-02 15:49:00 -04006357}
6358
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006359bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006360{
Till Rathmannb8543632018-10-02 19:46:14 +02006361 return ValidateTexParameterBase(context, target, pname, -1, false, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006362}
6363
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006364bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006365{
Till Rathmannb8543632018-10-02 19:46:14 +02006366 return ValidateTexParameterBase(context, target, pname, -1, true, params);
6367}
6368
6369bool ValidateTexParameterIivOES(Context *context,
6370 TextureType target,
6371 GLenum pname,
6372 const GLint *params)
6373{
6374 if (context->getClientMajorVersion() < 3)
6375 {
Jamie Madill610640f2018-11-21 17:28:41 -05006376 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006377 return false;
6378 }
6379 return ValidateTexParameterBase(context, target, pname, -1, true, params);
6380}
6381
6382bool ValidateTexParameterIuivOES(Context *context,
6383 TextureType target,
6384 GLenum pname,
6385 const GLuint *params)
6386{
6387 if (context->getClientMajorVersion() < 3)
6388 {
Jamie Madill610640f2018-11-21 17:28:41 -05006389 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006390 return false;
6391 }
6392 return ValidateTexParameterBase(context, target, pname, -1, true, params);
Jamie Madillbe849e42017-05-02 15:49:00 -04006393}
6394
6395bool ValidateUseProgram(Context *context, GLuint program)
6396{
6397 if (program != 0)
6398 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04006399 Program *programObject = context->getProgramResolveLink(program);
Jamie Madillbe849e42017-05-02 15:49:00 -04006400 if (!programObject)
6401 {
6402 // ES 3.1.0 section 7.3 page 72
6403 if (context->getShader(program))
6404 {
Jamie Madill610640f2018-11-21 17:28:41 -05006405 context->validationError(GL_INVALID_OPERATION, kErrorExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006406 return false;
6407 }
6408 else
6409 {
Jamie Madill610640f2018-11-21 17:28:41 -05006410 context->validationError(GL_INVALID_VALUE, kErrorInvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006411 return false;
6412 }
6413 }
6414 if (!programObject->isLinked())
6415 {
Jamie Madill610640f2018-11-21 17:28:41 -05006416 context->validationError(GL_INVALID_OPERATION, kErrorProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006417 return false;
6418 }
6419 }
6420 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6421 {
6422 // ES 3.0.4 section 2.15 page 91
Jamie Madill610640f2018-11-21 17:28:41 -05006423 context->validationError(
6424 GL_INVALID_OPERATION,
6425 "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006426 return false;
6427 }
6428
6429 return true;
6430}
6431
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006432bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6433{
6434 if (!context->getExtensions().fence)
6435 {
Jamie Madill610640f2018-11-21 17:28:41 -05006436 context->validationError(GL_INVALID_OPERATION, kErrorNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006437 return false;
6438 }
6439
6440 if (n < 0)
6441 {
Jamie Madill610640f2018-11-21 17:28:41 -05006442 context->validationError(GL_INVALID_VALUE, kErrorNegativeCount);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006443 return false;
6444 }
6445
6446 return true;
6447}
6448
6449bool ValidateFinishFenceNV(Context *context, GLuint fence)
6450{
6451 if (!context->getExtensions().fence)
6452 {
Jamie Madill610640f2018-11-21 17:28:41 -05006453 context->validationError(GL_INVALID_OPERATION, kErrorNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006454 return false;
6455 }
6456
6457 FenceNV *fenceObject = context->getFenceNV(fence);
6458
6459 if (fenceObject == nullptr)
6460 {
Jamie Madill610640f2018-11-21 17:28:41 -05006461 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFence);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006462 return false;
6463 }
6464
6465 if (!fenceObject->isSet())
6466 {
Jamie Madill610640f2018-11-21 17:28:41 -05006467 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFenceState);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006468 return false;
6469 }
6470
6471 return true;
6472}
6473
6474bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6475{
6476 if (!context->getExtensions().fence)
6477 {
Jamie Madill610640f2018-11-21 17:28:41 -05006478 context->validationError(GL_INVALID_OPERATION, kErrorNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006479 return false;
6480 }
6481
6482 if (n < 0)
6483 {
Jamie Madill610640f2018-11-21 17:28:41 -05006484 context->validationError(GL_INVALID_VALUE, kErrorNegativeCount);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006485 return false;
6486 }
6487
6488 return true;
6489}
6490
6491bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6492{
6493 if (!context->getExtensions().fence)
6494 {
Jamie Madill610640f2018-11-21 17:28:41 -05006495 context->validationError(GL_INVALID_OPERATION, kErrorNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006496 return false;
6497 }
6498
6499 FenceNV *fenceObject = context->getFenceNV(fence);
6500
6501 if (fenceObject == nullptr)
6502 {
Jamie Madill610640f2018-11-21 17:28:41 -05006503 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFence);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006504 return false;
6505 }
6506
6507 if (!fenceObject->isSet())
6508 {
Jamie Madill610640f2018-11-21 17:28:41 -05006509 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFenceState);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006510 return false;
6511 }
6512
6513 switch (pname)
6514 {
6515 case GL_FENCE_STATUS_NV:
6516 case GL_FENCE_CONDITION_NV:
6517 break;
6518
6519 default:
Jamie Madill610640f2018-11-21 17:28:41 -05006520 context->validationError(GL_INVALID_ENUM, kErrorInvalidPname);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006521 return false;
6522 }
6523
6524 return true;
6525}
6526
6527bool ValidateGetGraphicsResetStatusEXT(Context *context)
6528{
6529 if (!context->getExtensions().robustness)
6530 {
Jamie Madill610640f2018-11-21 17:28:41 -05006531 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006532 return false;
6533 }
6534
6535 return true;
6536}
6537
6538bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6539 GLuint shader,
6540 GLsizei bufsize,
6541 GLsizei *length,
6542 GLchar *source)
6543{
6544 if (!context->getExtensions().translatedShaderSource)
6545 {
Jamie Madill610640f2018-11-21 17:28:41 -05006546 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006547 return false;
6548 }
6549
6550 if (bufsize < 0)
6551 {
Jamie Madill610640f2018-11-21 17:28:41 -05006552 context->validationError(GL_INVALID_VALUE, kErrorNegativeBufferSize);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006553 return false;
6554 }
6555
6556 Shader *shaderObject = context->getShader(shader);
6557
6558 if (!shaderObject)
6559 {
Jamie Madill610640f2018-11-21 17:28:41 -05006560 context->validationError(GL_INVALID_OPERATION, kErrorInvalidShaderName);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006561 return false;
6562 }
6563
6564 return true;
6565}
6566
6567bool ValidateIsFenceNV(Context *context, GLuint fence)
6568{
6569 if (!context->getExtensions().fence)
6570 {
Jamie Madill610640f2018-11-21 17:28:41 -05006571 context->validationError(GL_INVALID_OPERATION, kErrorNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006572 return false;
6573 }
6574
6575 return true;
6576}
6577
Jamie Madill007530e2017-12-28 14:27:04 -05006578bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6579{
6580 if (!context->getExtensions().fence)
6581 {
Jamie Madill610640f2018-11-21 17:28:41 -05006582 context->validationError(GL_INVALID_OPERATION, kErrorNVFenceNotSupported);
Jamie Madill007530e2017-12-28 14:27:04 -05006583 return false;
6584 }
6585
6586 if (condition != GL_ALL_COMPLETED_NV)
6587 {
Jamie Madill610640f2018-11-21 17:28:41 -05006588 context->validationError(GL_INVALID_ENUM, kErrorInvalidFenceCondition);
Jamie Madill007530e2017-12-28 14:27:04 -05006589 return false;
6590 }
6591
6592 FenceNV *fenceObject = context->getFenceNV(fence);
6593
6594 if (fenceObject == nullptr)
6595 {
Jamie Madill610640f2018-11-21 17:28:41 -05006596 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFence);
Jamie Madill007530e2017-12-28 14:27:04 -05006597 return false;
6598 }
6599
6600 return true;
6601}
6602
6603bool ValidateTestFenceNV(Context *context, GLuint fence)
6604{
6605 if (!context->getExtensions().fence)
6606 {
Jamie Madill610640f2018-11-21 17:28:41 -05006607 context->validationError(GL_INVALID_OPERATION, kErrorNVFenceNotSupported);
Jamie Madill007530e2017-12-28 14:27:04 -05006608 return false;
6609 }
6610
6611 FenceNV *fenceObject = context->getFenceNV(fence);
6612
6613 if (fenceObject == nullptr)
6614 {
Jamie Madill610640f2018-11-21 17:28:41 -05006615 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFence);
Jamie Madill007530e2017-12-28 14:27:04 -05006616 return false;
6617 }
6618
6619 if (fenceObject->isSet() != GL_TRUE)
6620 {
Jamie Madill610640f2018-11-21 17:28:41 -05006621 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFenceState);
Jamie Madill007530e2017-12-28 14:27:04 -05006622 return false;
6623 }
6624
6625 return true;
6626}
6627
6628bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006629 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006630 GLsizei levels,
6631 GLenum internalformat,
6632 GLsizei width,
6633 GLsizei height)
6634{
6635 if (!context->getExtensions().textureStorage)
6636 {
Jamie Madill610640f2018-11-21 17:28:41 -05006637 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05006638 return false;
6639 }
6640
6641 if (context->getClientMajorVersion() < 3)
6642 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006643 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006644 height);
6645 }
6646
6647 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006648 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006649 1);
6650}
6651
6652bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6653{
6654 if (!context->getExtensions().instancedArrays)
6655 {
Jamie Madill610640f2018-11-21 17:28:41 -05006656 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05006657 return false;
6658 }
6659
6660 if (index >= MAX_VERTEX_ATTRIBS)
6661 {
Jamie Madill610640f2018-11-21 17:28:41 -05006662 context->validationError(GL_INVALID_VALUE, kErrorIndexExceedsMaxVertexAttribute);
Jamie Madill007530e2017-12-28 14:27:04 -05006663 return false;
6664 }
6665
6666 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6667 {
6668 if (index == 0 && divisor != 0)
6669 {
6670 const char *errorMessage =
6671 "The current context doesn't support setting a non-zero divisor on the "
6672 "attribute with index zero. "
6673 "Please reorder the attributes in your vertex shader so that attribute zero "
6674 "can have a zero divisor.";
Jamie Madill610640f2018-11-21 17:28:41 -05006675 context->validationError(GL_INVALID_OPERATION, errorMessage);
Jamie Madill007530e2017-12-28 14:27:04 -05006676
6677 // We also output an error message to the debugger window if tracing is active, so
6678 // that developers can see the error message.
6679 ERR() << errorMessage;
6680 return false;
6681 }
6682 }
6683
6684 return true;
6685}
6686
6687bool ValidateTexImage3DOES(Context *context,
6688 GLenum target,
6689 GLint level,
6690 GLenum internalformat,
6691 GLsizei width,
6692 GLsizei height,
6693 GLsizei depth,
6694 GLint border,
6695 GLenum format,
6696 GLenum type,
6697 const void *pixels)
6698{
6699 UNIMPLEMENTED(); // FIXME
6700 return false;
6701}
6702
6703bool ValidatePopGroupMarkerEXT(Context *context)
6704{
6705 if (!context->getExtensions().debugMarker)
6706 {
6707 // The debug marker calls should not set error state
6708 // However, it seems reasonable to set an error state if the extension is not enabled
Jamie Madill610640f2018-11-21 17:28:41 -05006709 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05006710 return false;
6711 }
6712
6713 return true;
6714}
6715
Jamie Madillfa920eb2018-01-04 11:45:50 -05006716bool ValidateTexStorage1DEXT(Context *context,
6717 GLenum target,
6718 GLsizei levels,
6719 GLenum internalformat,
6720 GLsizei width)
6721{
6722 UNIMPLEMENTED();
Jamie Madill610640f2018-11-21 17:28:41 -05006723 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05006724 return false;
6725}
6726
6727bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006728 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006729 GLsizei levels,
6730 GLenum internalformat,
6731 GLsizei width,
6732 GLsizei height,
6733 GLsizei depth)
6734{
6735 if (!context->getExtensions().textureStorage)
6736 {
Jamie Madill610640f2018-11-21 17:28:41 -05006737 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05006738 return false;
6739 }
6740
6741 if (context->getClientMajorVersion() < 3)
6742 {
Jamie Madill610640f2018-11-21 17:28:41 -05006743 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05006744 return false;
6745 }
6746
6747 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6748 depth);
6749}
6750
jchen1082af6202018-06-22 10:59:52 +08006751bool ValidateMaxShaderCompilerThreadsKHR(Context *context, GLuint count)
6752{
6753 if (!context->getExtensions().parallelShaderCompile)
6754 {
Jamie Madill610640f2018-11-21 17:28:41 -05006755 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
jchen1082af6202018-06-22 10:59:52 +08006756 return false;
6757 }
6758 return true;
6759}
6760
Austin Eng1bf18ce2018-10-19 15:34:02 -07006761bool ValidateMultiDrawArraysANGLE(Context *context,
6762 PrimitiveMode mode,
6763 const GLint *firsts,
6764 const GLsizei *counts,
6765 GLsizei drawcount)
6766{
6767 if (!context->getExtensions().multiDraw)
6768 {
Jamie Madill610640f2018-11-21 17:28:41 -05006769 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07006770 return false;
6771 }
6772 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
6773 {
6774 if (!ValidateDrawArrays(context, mode, firsts[drawID], counts[drawID]))
6775 {
6776 return false;
6777 }
6778 }
6779 return true;
6780}
6781
6782bool ValidateMultiDrawElementsANGLE(Context *context,
6783 PrimitiveMode mode,
6784 const GLsizei *counts,
6785 GLenum type,
6786 const GLsizei *offsets,
6787 GLsizei drawcount)
6788{
6789 if (!context->getExtensions().multiDraw)
6790 {
Jamie Madill610640f2018-11-21 17:28:41 -05006791 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07006792 return false;
6793 }
6794 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
6795 {
6796 const void *indices = reinterpret_cast<void *>(static_cast<long>(offsets[drawID]));
6797 if (!ValidateDrawElements(context, mode, counts[drawID], type, indices))
6798 {
6799 return false;
6800 }
6801 }
6802 return true;
6803}
6804
Jamie Madillc29968b2016-01-20 11:17:23 -05006805} // namespace gl