blob: 1fd63febda8f9e704a07358d48c112b9211d2f2b [file] [log] [blame]
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001//
Geoff Langcec35902014-04-16 10:52:36 -04002// Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
Geoff Lange8ebe7f2013-08-05 15:03:13 -04003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// validationES2.cpp: Validation functions for OpenGL ES 2.0 entry point parameters
8
Jamie Madill778bf092018-11-14 09:54:36 -05009#include "libANGLE/validationES2_autogen.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030010
11#include <cstdint>
12
Geoff Lange8ebe7f2013-08-05 15:03:13 -040013#include "common/mathutil.h"
Sami Väisänen46eaa942016-06-29 10:26:37 +030014#include "common/string_utils.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040015#include "common/utilities.h"
Jamie Madillef300b12016-10-07 15:12:09 -040016#include "libANGLE/Context.h"
Brandon Jones6cad5662017-06-14 13:25:13 -070017#include "libANGLE/ErrorStrings.h"
Jamie Madill2b7bbc22017-12-21 17:30:38 -050018#include "libANGLE/Fence.h"
Jamie Madillef300b12016-10-07 15:12:09 -040019#include "libANGLE/Framebuffer.h"
20#include "libANGLE/FramebufferAttachment.h"
21#include "libANGLE/Renderbuffer.h"
22#include "libANGLE/Shader.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040023#include "libANGLE/Texture.h"
Jamie Madillef300b12016-10-07 15:12:09 -040024#include "libANGLE/Uniform.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040025#include "libANGLE/VertexArray.h"
Jamie Madillef300b12016-10-07 15:12:09 -040026#include "libANGLE/formatutils.h"
27#include "libANGLE/validationES.h"
Jamie Madill778bf092018-11-14 09:54:36 -050028#include "libANGLE/validationES2.h"
29#include "libANGLE/validationES3_autogen.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040030
31namespace gl
32{
Jamie Madille0472f32018-11-27 16:32:45 -050033using namespace err;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040034
Jamie Madillc29968b2016-01-20 11:17:23 -050035namespace
36{
37
38bool IsPartialBlit(gl::Context *context,
39 const FramebufferAttachment *readBuffer,
40 const FramebufferAttachment *writeBuffer,
41 GLint srcX0,
42 GLint srcY0,
43 GLint srcX1,
44 GLint srcY1,
45 GLint dstX0,
46 GLint dstY0,
47 GLint dstX1,
48 GLint dstY1)
49{
50 const Extents &writeSize = writeBuffer->getSize();
51 const Extents &readSize = readBuffer->getSize();
52
53 if (srcX0 != 0 || srcY0 != 0 || dstX0 != 0 || dstY0 != 0 || dstX1 != writeSize.width ||
54 dstY1 != writeSize.height || srcX1 != readSize.width || srcY1 != readSize.height)
55 {
56 return true;
57 }
58
Jamie Madilldfde6ab2016-06-09 07:07:18 -070059 if (context->getGLState().isScissorTestEnabled())
Jamie Madillc29968b2016-01-20 11:17:23 -050060 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -070061 const Rectangle &scissor = context->getGLState().getScissor();
Jamie Madillc29968b2016-01-20 11:17:23 -050062 return scissor.x > 0 || scissor.y > 0 || scissor.width < writeSize.width ||
63 scissor.height < writeSize.height;
64 }
65
66 return false;
67}
68
Sami Väisänend59ca052016-06-21 16:10:00 +030069template <typename T>
70bool ValidatePathInstances(gl::Context *context,
71 GLsizei numPaths,
72 const void *paths,
73 GLuint pathBase)
74{
75 const auto *array = static_cast<const T *>(paths);
76
77 for (GLsizei i = 0; i < numPaths; ++i)
78 {
79 const GLuint pathName = array[i] + pathBase;
Brandon Jones59770802018-04-02 13:18:42 -070080 if (context->isPathGenerated(pathName) && !context->isPath(pathName))
Sami Väisänend59ca052016-06-21 16:10:00 +030081 {
Jamie Madille0472f32018-11-27 16:32:45 -050082 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänend59ca052016-06-21 16:10:00 +030083 return false;
84 }
85 }
86 return true;
87}
88
89bool ValidateInstancedPathParameters(gl::Context *context,
90 GLsizei numPaths,
91 GLenum pathNameType,
92 const void *paths,
93 GLuint pathBase,
94 GLenum transformType,
95 const GLfloat *transformValues)
96{
97 if (!context->getExtensions().pathRendering)
98 {
Jamie Madillc3e37312018-11-30 15:25:39 -050099 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänend59ca052016-06-21 16:10:00 +0300100 return false;
101 }
102
103 if (paths == nullptr)
104 {
Jamie Madillc3e37312018-11-30 15:25:39 -0500105 context->validationError(GL_INVALID_VALUE, kInvalidPathNameArray);
Sami Väisänend59ca052016-06-21 16:10:00 +0300106 return false;
107 }
108
109 if (numPaths < 0)
110 {
Jamie Madillc3e37312018-11-30 15:25:39 -0500111 context->validationError(GL_INVALID_VALUE, kInvalidPathNumPaths);
Sami Väisänend59ca052016-06-21 16:10:00 +0300112 return false;
113 }
114
115 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(numPaths))
116 {
Jamie Madille0472f32018-11-27 16:32:45 -0500117 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300118 return false;
119 }
120
121 std::uint32_t pathNameTypeSize = 0;
122 std::uint32_t componentCount = 0;
123
124 switch (pathNameType)
125 {
126 case GL_UNSIGNED_BYTE:
127 pathNameTypeSize = sizeof(GLubyte);
128 if (!ValidatePathInstances<GLubyte>(context, numPaths, paths, pathBase))
129 return false;
130 break;
131
132 case GL_BYTE:
133 pathNameTypeSize = sizeof(GLbyte);
134 if (!ValidatePathInstances<GLbyte>(context, numPaths, paths, pathBase))
135 return false;
136 break;
137
138 case GL_UNSIGNED_SHORT:
139 pathNameTypeSize = sizeof(GLushort);
140 if (!ValidatePathInstances<GLushort>(context, numPaths, paths, pathBase))
141 return false;
142 break;
143
144 case GL_SHORT:
145 pathNameTypeSize = sizeof(GLshort);
146 if (!ValidatePathInstances<GLshort>(context, numPaths, paths, pathBase))
147 return false;
148 break;
149
150 case GL_UNSIGNED_INT:
151 pathNameTypeSize = sizeof(GLuint);
152 if (!ValidatePathInstances<GLuint>(context, numPaths, paths, pathBase))
153 return false;
154 break;
155
156 case GL_INT:
157 pathNameTypeSize = sizeof(GLint);
158 if (!ValidatePathInstances<GLint>(context, numPaths, paths, pathBase))
159 return false;
160 break;
161
162 default:
Jamie Madillc3e37312018-11-30 15:25:39 -0500163 context->validationError(GL_INVALID_ENUM, kInvalidPathNameType);
Sami Väisänend59ca052016-06-21 16:10:00 +0300164 return false;
165 }
166
167 switch (transformType)
168 {
169 case GL_NONE:
170 componentCount = 0;
171 break;
172 case GL_TRANSLATE_X_CHROMIUM:
173 case GL_TRANSLATE_Y_CHROMIUM:
174 componentCount = 1;
175 break;
176 case GL_TRANSLATE_2D_CHROMIUM:
177 componentCount = 2;
178 break;
179 case GL_TRANSLATE_3D_CHROMIUM:
180 componentCount = 3;
181 break;
182 case GL_AFFINE_2D_CHROMIUM:
183 case GL_TRANSPOSE_AFFINE_2D_CHROMIUM:
184 componentCount = 6;
185 break;
186 case GL_AFFINE_3D_CHROMIUM:
187 case GL_TRANSPOSE_AFFINE_3D_CHROMIUM:
188 componentCount = 12;
189 break;
190 default:
Jamie Madillc3e37312018-11-30 15:25:39 -0500191 context->validationError(GL_INVALID_ENUM, kInvalidTransformation);
Sami Väisänend59ca052016-06-21 16:10:00 +0300192 return false;
193 }
194 if (componentCount != 0 && transformValues == nullptr)
195 {
Jamie Madillc3e37312018-11-30 15:25:39 -0500196 context->validationError(GL_INVALID_VALUE, kNoTransformArray);
Sami Väisänend59ca052016-06-21 16:10:00 +0300197 return false;
198 }
199
200 angle::CheckedNumeric<std::uint32_t> checkedSize(0);
201 checkedSize += (numPaths * pathNameTypeSize);
202 checkedSize += (numPaths * sizeof(GLfloat) * componentCount);
203 if (!checkedSize.IsValid())
204 {
Jamie Madille0472f32018-11-27 16:32:45 -0500205 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300206 return false;
207 }
208
209 return true;
210}
211
Geoff Lang4f0e0032017-05-01 16:04:35 -0400212bool IsValidCopyTextureSourceInternalFormatEnum(GLenum internalFormat)
Geoff Lang97073d12016-04-20 10:42:34 -0700213{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400214 // Table 1.1 from the CHROMIUM_copy_texture spec
Geoff Langca271392017-04-05 12:30:00 -0400215 switch (GetUnsizedFormat(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700216 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400217 case GL_RED:
Geoff Lang97073d12016-04-20 10:42:34 -0700218 case GL_ALPHA:
219 case GL_LUMINANCE:
220 case GL_LUMINANCE_ALPHA:
221 case GL_RGB:
222 case GL_RGBA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400223 case GL_RGB8:
224 case GL_RGBA8:
225 case GL_BGRA_EXT:
226 case GL_BGRA8_EXT:
Geoff Lang97073d12016-04-20 10:42:34 -0700227 return true;
228
Geoff Lang4f0e0032017-05-01 16:04:35 -0400229 default:
230 return false;
231 }
232}
Geoff Lang97073d12016-04-20 10:42:34 -0700233
Geoff Lang4f0e0032017-05-01 16:04:35 -0400234bool IsValidCopySubTextureSourceInternalFormat(GLenum internalFormat)
235{
236 return IsValidCopyTextureSourceInternalFormatEnum(internalFormat);
237}
238
Geoff Lang4f0e0032017-05-01 16:04:35 -0400239bool IsValidCopyTextureDestinationInternalFormatEnum(GLint internalFormat)
240{
241 // Table 1.0 from the CHROMIUM_copy_texture spec
242 switch (internalFormat)
243 {
244 case GL_RGB:
245 case GL_RGBA:
246 case GL_RGB8:
247 case GL_RGBA8:
Geoff Lang97073d12016-04-20 10:42:34 -0700248 case GL_BGRA_EXT:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400249 case GL_BGRA8_EXT:
250 case GL_SRGB_EXT:
251 case GL_SRGB_ALPHA_EXT:
252 case GL_R8:
253 case GL_R8UI:
254 case GL_RG8:
255 case GL_RG8UI:
256 case GL_SRGB8:
257 case GL_RGB565:
258 case GL_RGB8UI:
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400259 case GL_RGB10_A2:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400260 case GL_SRGB8_ALPHA8:
261 case GL_RGB5_A1:
262 case GL_RGBA4:
263 case GL_RGBA8UI:
264 case GL_RGB9_E5:
265 case GL_R16F:
266 case GL_R32F:
267 case GL_RG16F:
268 case GL_RG32F:
269 case GL_RGB16F:
270 case GL_RGB32F:
271 case GL_RGBA16F:
272 case GL_RGBA32F:
273 case GL_R11F_G11F_B10F:
Brandon Jones340b7b82017-06-26 13:02:31 -0700274 case GL_LUMINANCE:
275 case GL_LUMINANCE_ALPHA:
276 case GL_ALPHA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400277 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700278
279 default:
280 return false;
281 }
282}
283
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400284bool IsValidCopySubTextureDestionationInternalFormat(GLenum internalFormat)
285{
286 return IsValidCopyTextureDestinationInternalFormatEnum(internalFormat);
287}
288
Geoff Lang97073d12016-04-20 10:42:34 -0700289bool IsValidCopyTextureDestinationFormatType(Context *context, GLint internalFormat, GLenum type)
290{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400291 if (!IsValidCopyTextureDestinationInternalFormatEnum(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700292 {
Jamie Madille0472f32018-11-27 16:32:45 -0500293 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400294 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700295 }
296
Geoff Langc0094ec2017-08-16 14:16:24 -0400297 if (!ValidES3FormatCombination(GetUnsizedFormat(internalFormat), type, internalFormat))
298 {
Jamie Madille0472f32018-11-27 16:32:45 -0500299 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Langc0094ec2017-08-16 14:16:24 -0400300 return false;
301 }
302
Geoff Lang4f0e0032017-05-01 16:04:35 -0400303 const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat, type);
304 if (!internalFormatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
Geoff Lang97073d12016-04-20 10:42:34 -0700305 {
Jamie Madille0472f32018-11-27 16:32:45 -0500306 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400307 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700308 }
309
310 return true;
311}
312
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800313bool IsValidCopyTextureDestinationTargetEnum(Context *context, TextureTarget target)
Geoff Lang97073d12016-04-20 10:42:34 -0700314{
315 switch (target)
316 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800317 case TextureTarget::_2D:
318 case TextureTarget::CubeMapNegativeX:
319 case TextureTarget::CubeMapNegativeY:
320 case TextureTarget::CubeMapNegativeZ:
321 case TextureTarget::CubeMapPositiveX:
322 case TextureTarget::CubeMapPositiveY:
323 case TextureTarget::CubeMapPositiveZ:
Geoff Lang63458a32017-10-30 15:16:53 -0400324 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700325
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800326 case TextureTarget::Rectangle:
Geoff Lang63458a32017-10-30 15:16:53 -0400327 return context->getExtensions().textureRectangle;
Geoff Lang97073d12016-04-20 10:42:34 -0700328
329 default:
330 return false;
331 }
332}
333
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800334bool IsValidCopyTextureDestinationTarget(Context *context,
335 TextureType textureType,
336 TextureTarget target)
Geoff Lang63458a32017-10-30 15:16:53 -0400337{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800338 return TextureTargetToType(target) == textureType;
Geoff Lang63458a32017-10-30 15:16:53 -0400339}
340
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800341bool IsValidCopyTextureSourceTarget(Context *context, TextureType type)
Geoff Lang97073d12016-04-20 10:42:34 -0700342{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800343 switch (type)
Geoff Lang97073d12016-04-20 10:42:34 -0700344 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800345 case TextureType::_2D:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400346 return true;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800347 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400348 return context->getExtensions().textureRectangle;
Geoff 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 Madille0472f32018-11-27 16:32:45 -0500476 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
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 Madillc3e37312018-11-30 15:25:39 -0500483 // Error is already handled.
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 Madille0472f32018-11-27 16:32:45 -0500510 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
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 Madille0472f32018-11-27 16:32:45 -0500521 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
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 Madille0472f32018-11-27 16:32:45 -0500534 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
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 Madille0472f32018-11-27 16:32:45 -0500546 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
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 Madille0472f32018-11-27 16:32:45 -0500557 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
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 Madille0472f32018-11-27 16:32:45 -0500567 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
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 Madille0472f32018-11-27 16:32:45 -0500585 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400586 return false;
587 case GL_DEPTH_COMPONENT:
588 case GL_DEPTH_STENCIL_OES:
Jamie Madille0472f32018-11-27 16:32:45 -0500589 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400590 return false;
591 default:
Jamie Madille0472f32018-11-27 16:32:45 -0500592 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400593 return false;
594 }
595
596 if (formatInfo.type == GL_FLOAT && !context->getExtensions().textureFloat)
597 {
Jamie Madille0472f32018-11-27 16:32:45 -0500598 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
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 Madille0472f32018-11-27 16:32:45 -0500611 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
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 Madille0472f32018-11-27 16:32:45 -0500622 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
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 Madille0472f32018-11-27 16:32:45 -0500633 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
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 Madille0472f32018-11-27 16:32:45 -0500643 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
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 Madille0472f32018-11-27 16:32:45 -0500653 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
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 Madille0472f32018-11-27 16:32:45 -0500663 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
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 Madille0472f32018-11-27 16:32:45 -0500671 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400672 return false;
673 }
674 else
675 {
Jamie Madille0472f32018-11-27 16:32:45 -0500676 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
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 Madille0472f32018-11-27 16:32:45 -0500683 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400684 return false;
685 }
686 else
687 {
Jamie Madille0472f32018-11-27 16:32:45 -0500688 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
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 Madille0472f32018-11-27 16:32:45 -0500695 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400696 return false;
697 }
698 else
699 {
Jamie Madille0472f32018-11-27 16:32:45 -0500700 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
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 Madille0472f32018-11-27 16:32:45 -0500707 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400708 return false;
709 }
710 else
711 {
Jamie Madille0472f32018-11-27 16:32:45 -0500712 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
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 Madillc3e37312018-11-30 15:25:39 -0500723 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400724 return false;
725 }
726 else
727 {
Jamie Madillc3e37312018-11-30 15:25:39 -0500728 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400729 return false;
730 }
731 break;
732 case GL_DEPTH_COMPONENT:
733 case GL_DEPTH_COMPONENT16:
734 case GL_DEPTH_COMPONENT32_OES:
735 case GL_DEPTH_STENCIL_OES:
736 case GL_DEPTH24_STENCIL8_OES:
737 if (context->getExtensions().depthTextures)
738 {
Jamie Madille0472f32018-11-27 16:32:45 -0500739 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400740 return false;
741 }
742 else
743 {
Jamie Madille0472f32018-11-27 16:32:45 -0500744 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400745 return false;
746 }
747 default:
Jamie Madille0472f32018-11-27 16:32:45 -0500748 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400749 return false;
750 }
751 }
752
753 // If width or height is zero, it is a no-op. Return false without setting an error.
754 return (width > 0 && height > 0);
755}
756
757bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
758{
759 switch (cap)
760 {
761 // EXT_multisample_compatibility
762 case GL_MULTISAMPLE_EXT:
763 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
764 return context->getExtensions().multisampleCompatibility;
765
766 case GL_CULL_FACE:
767 case GL_POLYGON_OFFSET_FILL:
768 case GL_SAMPLE_ALPHA_TO_COVERAGE:
769 case GL_SAMPLE_COVERAGE:
770 case GL_SCISSOR_TEST:
771 case GL_STENCIL_TEST:
772 case GL_DEPTH_TEST:
773 case GL_BLEND:
774 case GL_DITHER:
775 return true;
776
777 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
778 case GL_RASTERIZER_DISCARD:
779 return (context->getClientMajorVersion() >= 3);
780
781 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
782 case GL_DEBUG_OUTPUT:
783 return context->getExtensions().debug;
784
785 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
786 return queryOnly && context->getExtensions().bindGeneratesResource;
787
788 case GL_CLIENT_ARRAYS_ANGLE:
789 return queryOnly && context->getExtensions().clientArrays;
790
791 case GL_FRAMEBUFFER_SRGB_EXT:
792 return context->getExtensions().sRGBWriteControl;
793
794 case GL_SAMPLE_MASK:
795 return context->getClientVersion() >= Version(3, 1);
796
Geoff Langb433e872017-10-05 14:01:47 -0400797 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
Jamie Madillbe849e42017-05-02 15:49:00 -0400798 return queryOnly && context->getExtensions().robustResourceInitialization;
799
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700800 // GLES1 emulation: GLES1-specific caps
801 case GL_ALPHA_TEST:
Lingfeng Yang01074432018-04-16 10:19:51 -0700802 case GL_VERTEX_ARRAY:
803 case GL_NORMAL_ARRAY:
804 case GL_COLOR_ARRAY:
805 case GL_TEXTURE_COORD_ARRAY:
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700806 case GL_TEXTURE_2D:
Lingfeng Yangd0febe72018-05-17 22:36:52 -0700807 case GL_LIGHTING:
808 case GL_LIGHT0:
809 case GL_LIGHT1:
810 case GL_LIGHT2:
811 case GL_LIGHT3:
812 case GL_LIGHT4:
813 case GL_LIGHT5:
814 case GL_LIGHT6:
815 case GL_LIGHT7:
816 case GL_NORMALIZE:
817 case GL_RESCALE_NORMAL:
818 case GL_COLOR_MATERIAL:
Lingfeng Yang060088a2018-05-30 20:40:57 -0700819 case GL_CLIP_PLANE0:
820 case GL_CLIP_PLANE1:
821 case GL_CLIP_PLANE2:
822 case GL_CLIP_PLANE3:
823 case GL_CLIP_PLANE4:
824 case GL_CLIP_PLANE5:
Lingfeng Yang7ba3f422018-06-01 09:43:04 -0700825 case GL_FOG:
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700826 case GL_POINT_SMOOTH:
Lingfeng Yang6e5bf362018-08-15 09:53:17 -0700827 case GL_LINE_SMOOTH:
828 case GL_COLOR_LOGIC_OP:
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700829 return context->getClientVersion() < Version(2, 0);
Lingfeng Yang01074432018-04-16 10:19:51 -0700830 case GL_POINT_SIZE_ARRAY_OES:
831 return context->getClientVersion() < Version(2, 0) &&
832 context->getExtensions().pointSizeArray;
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700833 case GL_TEXTURE_CUBE_MAP:
834 return context->getClientVersion() < Version(2, 0) &&
835 context->getExtensions().textureCubeMap;
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700836 case GL_POINT_SPRITE_OES:
837 return context->getClientVersion() < Version(2, 0) &&
838 context->getExtensions().pointSprite;
Jamie Madillbe849e42017-05-02 15:49:00 -0400839 default:
840 return false;
841 }
842}
843
Geoff Langfc32e8b2017-05-31 14:16:59 -0400844// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
845// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400846bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400847{
848 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400849 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
850 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400851 {
852 return true;
853 }
854
855 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
856 if (c >= 9 && c <= 13)
857 {
858 return true;
859 }
860
861 return false;
862}
863
Geoff Langcab92ee2017-07-19 17:32:07 -0400864bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400865{
Geoff Langa71a98e2017-06-19 15:15:00 -0400866 for (size_t i = 0; i < len; i++)
867 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400868 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400869 {
870 return false;
871 }
872 }
873
874 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400875}
876
Geoff Langcab92ee2017-07-19 17:32:07 -0400877bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
878{
879 enum class ParseState
880 {
881 // Have not seen an ASCII non-whitespace character yet on
882 // this line. Possible that we might see a preprocessor
883 // directive.
884 BEGINING_OF_LINE,
885
886 // Have seen at least one ASCII non-whitespace character
887 // on this line.
888 MIDDLE_OF_LINE,
889
890 // Handling a preprocessor directive. Passes through all
891 // characters up to the end of the line. Disables comment
892 // processing.
893 IN_PREPROCESSOR_DIRECTIVE,
894
895 // Handling a single-line comment. The comment text is
896 // replaced with a single space.
897 IN_SINGLE_LINE_COMMENT,
898
899 // Handling a multi-line comment. Newlines are passed
900 // through to preserve line numbers.
901 IN_MULTI_LINE_COMMENT
902 };
903
904 ParseState state = ParseState::BEGINING_OF_LINE;
905 size_t pos = 0;
906
907 while (pos < len)
908 {
909 char c = str[pos];
910 char next = pos + 1 < len ? str[pos + 1] : 0;
911
912 // Check for newlines
913 if (c == '\n' || c == '\r')
914 {
915 if (state != ParseState::IN_MULTI_LINE_COMMENT)
916 {
917 state = ParseState::BEGINING_OF_LINE;
918 }
919
920 pos++;
921 continue;
922 }
923
924 switch (state)
925 {
926 case ParseState::BEGINING_OF_LINE:
927 if (c == ' ')
928 {
929 // Maintain the BEGINING_OF_LINE state until a non-space is seen
930 pos++;
931 }
932 else if (c == '#')
933 {
934 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
935 pos++;
936 }
937 else
938 {
939 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
940 state = ParseState::MIDDLE_OF_LINE;
941 }
942 break;
943
944 case ParseState::MIDDLE_OF_LINE:
945 if (c == '/' && next == '/')
946 {
947 state = ParseState::IN_SINGLE_LINE_COMMENT;
948 pos++;
949 }
950 else if (c == '/' && next == '*')
951 {
952 state = ParseState::IN_MULTI_LINE_COMMENT;
953 pos++;
954 }
955 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
956 {
957 // Skip line continuation characters
958 }
959 else if (!IsValidESSLCharacter(c))
960 {
961 return false;
962 }
963 pos++;
964 break;
965
966 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700967 // Line-continuation characters may not be permitted.
968 // Otherwise, just pass it through. Do not parse comments in this state.
969 if (!lineContinuationAllowed && c == '\\')
970 {
971 return false;
972 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400973 pos++;
974 break;
975
976 case ParseState::IN_SINGLE_LINE_COMMENT:
977 // Line-continuation characters are processed before comment processing.
978 // Advance string if a new line character is immediately behind
979 // line-continuation character.
980 if (c == '\\' && (next == '\n' || next == '\r'))
981 {
982 pos++;
983 }
984 pos++;
985 break;
986
987 case ParseState::IN_MULTI_LINE_COMMENT:
988 if (c == '*' && next == '/')
989 {
990 state = ParseState::MIDDLE_OF_LINE;
991 pos++;
992 }
993 pos++;
994 break;
995 }
996 }
997
998 return true;
999}
1000
Jamie Madill5b772312018-03-08 20:28:32 -05001001bool ValidateWebGLNamePrefix(Context *context, const GLchar *name)
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001002{
1003 ASSERT(context->isWebGL());
1004
1005 // WebGL 1.0 [Section 6.16] GLSL Constructs
1006 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
1007 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
1008 {
Jamie Madille0472f32018-11-27 16:32:45 -05001009 context->validationError(GL_INVALID_OPERATION, kWebglBindAttribLocationReservedPrefix);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001010 return false;
1011 }
1012
1013 return true;
1014}
1015
Jamie Madill5b772312018-03-08 20:28:32 -05001016bool ValidateWebGLNameLength(Context *context, size_t length)
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001017{
1018 ASSERT(context->isWebGL());
1019
1020 if (context->isWebGL1() && length > 256)
1021 {
1022 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
1023 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
1024 // locations.
Jamie Madille0472f32018-11-27 16:32:45 -05001025 context->validationError(GL_INVALID_VALUE, kWebglNameLengthLimitExceeded);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001026
1027 return false;
1028 }
1029 else if (length > 1024)
1030 {
1031 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
1032 // uniform and attribute locations.
Jamie Madille0472f32018-11-27 16:32:45 -05001033 context->validationError(GL_INVALID_VALUE, kWebgl2NameLengthLimitExceeded);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001034 return false;
1035 }
1036
1037 return true;
1038}
1039
Jamie Madill007530e2017-12-28 14:27:04 -05001040bool ValidateMatrixMode(Context *context, GLenum matrixMode)
1041{
1042 if (!context->getExtensions().pathRendering)
1043 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001044 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05001045 return false;
1046 }
1047
1048 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
1049 {
Jamie Madille0472f32018-11-27 16:32:45 -05001050 context->validationError(GL_INVALID_ENUM, kInvalidMatrixMode);
Jamie Madill007530e2017-12-28 14:27:04 -05001051 return false;
1052 }
1053 return true;
1054}
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03001055
1056bool ValidBlendFunc(const Context *context, GLenum val)
1057{
1058 const gl::Extensions &ext = context->getExtensions();
1059
1060 // these are always valid for src and dst.
1061 switch (val)
1062 {
1063 case GL_ZERO:
1064 case GL_ONE:
1065 case GL_SRC_COLOR:
1066 case GL_ONE_MINUS_SRC_COLOR:
1067 case GL_DST_COLOR:
1068 case GL_ONE_MINUS_DST_COLOR:
1069 case GL_SRC_ALPHA:
1070 case GL_ONE_MINUS_SRC_ALPHA:
1071 case GL_DST_ALPHA:
1072 case GL_ONE_MINUS_DST_ALPHA:
1073 case GL_CONSTANT_COLOR:
1074 case GL_ONE_MINUS_CONSTANT_COLOR:
1075 case GL_CONSTANT_ALPHA:
1076 case GL_ONE_MINUS_CONSTANT_ALPHA:
1077 return true;
1078
1079 // EXT_blend_func_extended.
1080 case GL_SRC1_COLOR_EXT:
1081 case GL_SRC1_ALPHA_EXT:
1082 case GL_ONE_MINUS_SRC1_COLOR_EXT:
1083 case GL_ONE_MINUS_SRC1_ALPHA_EXT:
1084 case GL_SRC_ALPHA_SATURATE_EXT:
1085 return ext.blendFuncExtended;
1086
1087 default:
1088 return false;
1089 }
1090}
1091
1092bool ValidSrcBlendFunc(const Context *context, GLenum val)
1093{
1094 if (ValidBlendFunc(context, val))
1095 return true;
1096
1097 if (val == GL_SRC_ALPHA_SATURATE)
1098 return true;
1099
1100 return false;
1101}
1102
1103bool ValidDstBlendFunc(const Context *context, GLenum val)
1104{
1105 if (ValidBlendFunc(context, val))
1106 return true;
1107
1108 if (val == GL_SRC_ALPHA_SATURATE)
1109 {
1110 if (context->getClientMajorVersion() >= 3)
1111 return true;
1112 }
1113
1114 return false;
1115}
1116
Jamie Madillac66f982018-10-09 18:30:01 -04001117void RecordBindTextureTypeError(Context *context, TextureType target)
1118{
1119 ASSERT(!context->getStateCache().isValidBindTextureType(target));
1120
1121 switch (target)
1122 {
1123 case TextureType::Rectangle:
1124 ASSERT(!context->getExtensions().textureRectangle);
Jamie Madillc3e37312018-11-30 15:25:39 -05001125 context->validationError(GL_INVALID_ENUM, kTextureRectangleNotSupported);
Jamie Madillac66f982018-10-09 18:30:01 -04001126 break;
1127
1128 case TextureType::_3D:
1129 case TextureType::_2DArray:
1130 ASSERT(context->getClientMajorVersion() < 3);
Jamie Madille0472f32018-11-27 16:32:45 -05001131 context->validationError(GL_INVALID_ENUM, kES3Required);
Jamie Madillac66f982018-10-09 18:30:01 -04001132 break;
1133
1134 case TextureType::_2DMultisample:
Yizhou Jiang7818a852018-09-06 15:02:04 +08001135 ASSERT(context->getClientVersion() < Version(3, 1) &&
1136 !context->getExtensions().textureMultisample);
Jamie Madille0472f32018-11-27 16:32:45 -05001137 context->validationError(GL_INVALID_ENUM, kMultisampleTextureExtensionOrES31Required);
Jamie Madillac66f982018-10-09 18:30:01 -04001138 break;
1139
1140 case TextureType::_2DMultisampleArray:
1141 ASSERT(!context->getExtensions().textureStorageMultisample2DArray);
Jamie Madille0472f32018-11-27 16:32:45 -05001142 context->validationError(GL_INVALID_ENUM, kMultisampleArrayExtensionRequired);
Jamie Madillac66f982018-10-09 18:30:01 -04001143 break;
1144
1145 case TextureType::External:
1146 ASSERT(!context->getExtensions().eglImageExternal &&
1147 !context->getExtensions().eglStreamConsumerExternal);
Jamie Madillc3e37312018-11-30 15:25:39 -05001148 context->validationError(GL_INVALID_ENUM, kExternalTextureNotSupported);
Jamie Madillac66f982018-10-09 18:30:01 -04001149 break;
1150
1151 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001152 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillac66f982018-10-09 18:30:01 -04001153 }
1154}
Jamie Madillc29968b2016-01-20 11:17:23 -05001155} // anonymous namespace
1156
Geoff Langff5b2d52016-09-07 11:32:23 -04001157bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001158 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001159 GLint level,
1160 GLenum internalformat,
1161 bool isCompressed,
1162 bool isSubImage,
1163 GLint xoffset,
1164 GLint yoffset,
1165 GLsizei width,
1166 GLsizei height,
1167 GLint border,
1168 GLenum format,
1169 GLenum type,
1170 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001171 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001172{
Jamie Madill6f38f822014-06-06 17:12:20 -04001173 if (!ValidTexture2DDestinationTarget(context, target))
1174 {
Jamie Madille0472f32018-11-27 16:32:45 -05001175 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001176 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001177 }
1178
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001179 TextureType texType = TextureTargetToType(target);
1180 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001181 {
Jamie Madill610640f2018-11-21 17:28:41 -05001182 // Error already handled.
Geoff Langb1196682014-07-23 13:47:29 -04001183 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001184 }
1185
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001186 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001187 {
Jamie Madille0472f32018-11-27 16:32:45 -05001188 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Brandon Jones6cad5662017-06-14 13:25:13 -07001189 return false;
1190 }
1191
1192 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001193 std::numeric_limits<GLsizei>::max() - yoffset < height)
1194 {
Jamie Madille0472f32018-11-27 16:32:45 -05001195 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001196 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001197 }
1198
Geoff Lang6e898aa2017-06-02 11:17:26 -04001199 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1200 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1201 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1202 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1203 // case.
1204 bool nonEqualFormatsAllowed =
1205 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
1206 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
1207
1208 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001209 {
Jamie Madille0472f32018-11-27 16:32:45 -05001210 context->validationError(GL_INVALID_OPERATION, kInvalidFormatCombination);
Geoff Langb1196682014-07-23 13:47:29 -04001211 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001212 }
1213
Geoff Langaae65a42014-05-26 12:43:44 -04001214 const gl::Caps &caps = context->getCaps();
1215
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001216 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001217 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001218 case TextureType::_2D:
1219 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1220 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1221 {
Jamie Madille0472f32018-11-27 16:32:45 -05001222 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001223 return false;
1224 }
1225 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001226
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001227 case TextureType::Rectangle:
1228 ASSERT(level == 0);
1229 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1230 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1231 {
Jamie Madille0472f32018-11-27 16:32:45 -05001232 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001233 return false;
1234 }
1235 if (isCompressed)
1236 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001237 context->validationError(GL_INVALID_ENUM, kRectangleTextureCompressed);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001238 return false;
1239 }
1240 break;
1241
1242 case TextureType::CubeMap:
1243 if (!isSubImage && width != height)
1244 {
Jamie Madille0472f32018-11-27 16:32:45 -05001245 context->validationError(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001246 return false;
1247 }
1248
1249 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1250 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1251 {
Jamie Madille0472f32018-11-27 16:32:45 -05001252 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001253 return false;
1254 }
1255 break;
1256
1257 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001258 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001259 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001260 }
1261
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001262 gl::Texture *texture = context->getTargetTexture(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001263 if (!texture)
1264 {
Jamie Madille0472f32018-11-27 16:32:45 -05001265 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001266 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001267 }
1268
Geoff Langa9be0dc2014-12-17 12:34:40 -05001269 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001270 {
Geoff Langca271392017-04-05 12:30:00 -04001271 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1272 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001273 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001274 context->validationError(GL_INVALID_OPERATION, kInvalidTextureLevel);
Geoff Langc51642b2016-11-14 16:18:26 -05001275 return false;
1276 }
1277
Geoff Langa9be0dc2014-12-17 12:34:40 -05001278 if (format != GL_NONE)
1279 {
Geoff Langca271392017-04-05 12:30:00 -04001280 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1281 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001282 {
Jamie Madille0472f32018-11-27 16:32:45 -05001283 context->validationError(GL_INVALID_OPERATION, kTypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001284 return false;
1285 }
1286 }
1287
1288 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1289 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1290 {
Jamie Madille0472f32018-11-27 16:32:45 -05001291 context->validationError(GL_INVALID_VALUE, kOffsetOverflow);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001292 return false;
1293 }
Geoff Langfb052642017-10-24 13:42:09 -04001294
1295 if (width > 0 && height > 0 && pixels == nullptr &&
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001296 context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
Geoff Langfb052642017-10-24 13:42:09 -04001297 {
Jamie Madille0472f32018-11-27 16:32:45 -05001298 context->validationError(GL_INVALID_VALUE, kPixelDataNull);
Geoff Langfb052642017-10-24 13:42:09 -04001299 return false;
1300 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001301 }
1302 else
1303 {
Geoff Lang69cce582015-09-17 13:20:36 -04001304 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001305 {
Jamie Madille0472f32018-11-27 16:32:45 -05001306 context->validationError(GL_INVALID_OPERATION, kTextureIsImmutable);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001307 return false;
1308 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001309 }
1310
1311 // Verify zero border
1312 if (border != 0)
1313 {
Jamie Madille0472f32018-11-27 16:32:45 -05001314 context->validationError(GL_INVALID_VALUE, kInvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001315 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001316 }
1317
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001318 if (isCompressed)
1319 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001320 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001321 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1322 : internalformat;
Geoff Lange88e4542018-05-03 15:05:57 -04001323
1324 const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(actualInternalFormat);
1325
1326 if (!internalFormatInfo.compressed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001327 {
Jamie Madille0472f32018-11-27 16:32:45 -05001328 context->validationError(GL_INVALID_ENUM, kInvalidInternalFormat);
Geoff Lange88e4542018-05-03 15:05:57 -04001329 return false;
1330 }
1331
1332 if (!internalFormatInfo.textureSupport(context->getClientVersion(),
1333 context->getExtensions()))
1334 {
Jamie Madille0472f32018-11-27 16:32:45 -05001335 context->validationError(GL_INVALID_ENUM, kInvalidInternalFormat);
Geoff Lange88e4542018-05-03 15:05:57 -04001336 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001337 }
Geoff Lang966c9402017-04-18 12:38:27 -04001338
1339 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001340 {
Geoff Lange88e4542018-05-03 15:05:57 -04001341 // From the OES_compressed_ETC1_RGB8_texture spec:
1342 // INVALID_OPERATION is generated by CompressedTexSubImage2D, TexSubImage2D, or
1343 // CopyTexSubImage2D if the texture image <level> bound to <target> has internal format
1344 // ETC1_RGB8_OES.
1345 if (actualInternalFormat == GL_ETC1_RGB8_OES)
1346 {
Jamie Madille0472f32018-11-27 16:32:45 -05001347 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lange88e4542018-05-03 15:05:57 -04001348 return false;
1349 }
1350
Geoff Lang966c9402017-04-18 12:38:27 -04001351 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1352 height, texture->getWidth(target, level),
1353 texture->getHeight(target, level)))
1354 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001355 context->validationError(GL_INVALID_OPERATION, kInvalidCompressedImageSize);
Geoff Lang966c9402017-04-18 12:38:27 -04001356 return false;
1357 }
1358
1359 if (format != actualInternalFormat)
1360 {
Jamie Madille0472f32018-11-27 16:32:45 -05001361 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001362 return false;
1363 }
1364 }
1365 else
1366 {
1367 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1368 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001369 context->validationError(GL_INVALID_OPERATION, kInvalidCompressedImageSize);
Geoff Lang966c9402017-04-18 12:38:27 -04001370 return false;
1371 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001372 }
1373 }
1374 else
1375 {
1376 // validate <type> by itself (used as secondary key below)
1377 switch (type)
1378 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001379 case GL_UNSIGNED_BYTE:
1380 case GL_UNSIGNED_SHORT_5_6_5:
1381 case GL_UNSIGNED_SHORT_4_4_4_4:
1382 case GL_UNSIGNED_SHORT_5_5_5_1:
1383 case GL_UNSIGNED_SHORT:
1384 case GL_UNSIGNED_INT:
1385 case GL_UNSIGNED_INT_24_8_OES:
1386 case GL_HALF_FLOAT_OES:
1387 case GL_FLOAT:
1388 break;
1389 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001390 context->validationError(GL_INVALID_ENUM, kInvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001391 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001392 }
1393
1394 // validate <format> + <type> combinations
1395 // - invalid <format> -> sets INVALID_ENUM
1396 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1397 switch (format)
1398 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001399 case GL_ALPHA:
1400 case GL_LUMINANCE:
1401 case GL_LUMINANCE_ALPHA:
1402 switch (type)
1403 {
1404 case GL_UNSIGNED_BYTE:
1405 case GL_FLOAT:
1406 case GL_HALF_FLOAT_OES:
1407 break;
1408 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001409 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001410 return false;
1411 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001412 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001413 case GL_RED:
1414 case GL_RG:
1415 if (!context->getExtensions().textureRG)
1416 {
Jamie Madille0472f32018-11-27 16:32:45 -05001417 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001418 return false;
1419 }
1420 switch (type)
1421 {
1422 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001423 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001424 case GL_FLOAT:
1425 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001426 if (!context->getExtensions().textureFloat)
1427 {
Jamie Madille0472f32018-11-27 16:32:45 -05001428 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001429 return false;
1430 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001431 break;
1432 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001433 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001434 return false;
1435 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001436 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001437 case GL_RGB:
1438 switch (type)
1439 {
1440 case GL_UNSIGNED_BYTE:
1441 case GL_UNSIGNED_SHORT_5_6_5:
1442 case GL_FLOAT:
1443 case GL_HALF_FLOAT_OES:
1444 break;
1445 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001446 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001447 return false;
1448 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001449 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001450 case GL_RGBA:
1451 switch (type)
1452 {
1453 case GL_UNSIGNED_BYTE:
1454 case GL_UNSIGNED_SHORT_4_4_4_4:
1455 case GL_UNSIGNED_SHORT_5_5_5_1:
1456 case GL_FLOAT:
1457 case GL_HALF_FLOAT_OES:
1458 break;
1459 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001460 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001461 return false;
1462 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001463 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001464 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001465 if (!context->getExtensions().textureFormatBGRA8888)
1466 {
Jamie Madille0472f32018-11-27 16:32:45 -05001467 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001468 return false;
1469 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001470 switch (type)
1471 {
1472 case GL_UNSIGNED_BYTE:
1473 break;
1474 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001475 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001476 return false;
1477 }
1478 break;
1479 case GL_SRGB_EXT:
1480 case GL_SRGB_ALPHA_EXT:
1481 if (!context->getExtensions().sRGB)
1482 {
Jamie Madille0472f32018-11-27 16:32:45 -05001483 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001484 return false;
1485 }
1486 switch (type)
1487 {
1488 case GL_UNSIGNED_BYTE:
1489 break;
1490 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001491 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001492 return false;
1493 }
1494 break;
1495 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1496 // handled below
1497 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1498 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1499 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1500 break;
1501 case GL_DEPTH_COMPONENT:
1502 switch (type)
1503 {
1504 case GL_UNSIGNED_SHORT:
1505 case GL_UNSIGNED_INT:
1506 break;
1507 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001508 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001509 return false;
1510 }
1511 break;
1512 case GL_DEPTH_STENCIL_OES:
1513 switch (type)
1514 {
1515 case GL_UNSIGNED_INT_24_8_OES:
1516 break;
1517 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001518 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001519 return false;
1520 }
1521 break;
1522 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001523 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001524 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001525 }
1526
1527 switch (format)
1528 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001529 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1530 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1531 if (context->getExtensions().textureCompressionDXT1)
1532 {
Jamie Madille0472f32018-11-27 16:32:45 -05001533 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001534 return false;
1535 }
1536 else
1537 {
Jamie Madille0472f32018-11-27 16:32:45 -05001538 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001539 return false;
1540 }
1541 break;
1542 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1543 if (context->getExtensions().textureCompressionDXT3)
1544 {
Jamie Madille0472f32018-11-27 16:32:45 -05001545 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001546 return false;
1547 }
1548 else
1549 {
Jamie Madille0472f32018-11-27 16:32:45 -05001550 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001551 return false;
1552 }
1553 break;
1554 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1555 if (context->getExtensions().textureCompressionDXT5)
1556 {
Jamie Madille0472f32018-11-27 16:32:45 -05001557 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001558 return false;
1559 }
1560 else
1561 {
Jamie Madille0472f32018-11-27 16:32:45 -05001562 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001563 return false;
1564 }
1565 break;
1566 case GL_ETC1_RGB8_OES:
1567 if (context->getExtensions().compressedETC1RGB8Texture)
1568 {
Jamie Madille0472f32018-11-27 16:32:45 -05001569 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001570 return false;
1571 }
1572 else
1573 {
Jamie Madille0472f32018-11-27 16:32:45 -05001574 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001575 return false;
1576 }
1577 break;
1578 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001579 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1580 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1581 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1582 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001583 if (context->getExtensions().lossyETCDecode)
1584 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001585 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001586 return false;
1587 }
1588 else
1589 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001590 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001591 return false;
1592 }
1593 break;
1594 case GL_DEPTH_COMPONENT:
1595 case GL_DEPTH_STENCIL_OES:
1596 if (!context->getExtensions().depthTextures)
1597 {
Jamie Madille0472f32018-11-27 16:32:45 -05001598 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001599 return false;
1600 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001601 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001602 {
Jamie Madille0472f32018-11-27 16:32:45 -05001603 context->validationError(GL_INVALID_OPERATION, kMismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001604 return false;
1605 }
1606 // OES_depth_texture supports loading depth data and multiple levels,
1607 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001608 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001609 {
Jamie Madille0472f32018-11-27 16:32:45 -05001610 context->validationError(GL_INVALID_OPERATION, kPixelDataNotNull);
Brandon Jonesafa75152017-07-21 13:11:29 -07001611 return false;
1612 }
1613 if (level != 0)
1614 {
Jamie Madille0472f32018-11-27 16:32:45 -05001615 context->validationError(GL_INVALID_OPERATION, kLevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001616 return false;
1617 }
1618 break;
1619 default:
1620 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001621 }
1622
Geoff Lang6e898aa2017-06-02 11:17:26 -04001623 if (!isSubImage)
1624 {
1625 switch (internalformat)
1626 {
1627 case GL_RGBA32F:
1628 if (!context->getExtensions().colorBufferFloatRGBA)
1629 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001630 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001631 return false;
1632 }
1633 if (type != GL_FLOAT)
1634 {
Jamie Madille0472f32018-11-27 16:32:45 -05001635 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001636 return false;
1637 }
1638 if (format != GL_RGBA)
1639 {
Jamie Madille0472f32018-11-27 16:32:45 -05001640 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001641 return false;
1642 }
1643 break;
1644
1645 case GL_RGB32F:
1646 if (!context->getExtensions().colorBufferFloatRGB)
1647 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001648 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001649 return false;
1650 }
1651 if (type != GL_FLOAT)
1652 {
Jamie Madille0472f32018-11-27 16:32:45 -05001653 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001654 return false;
1655 }
1656 if (format != GL_RGB)
1657 {
Jamie Madille0472f32018-11-27 16:32:45 -05001658 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001659 return false;
1660 }
1661 break;
1662
1663 default:
1664 break;
1665 }
1666 }
1667
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001668 if (type == GL_FLOAT)
1669 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001670 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001671 {
Jamie Madille0472f32018-11-27 16:32:45 -05001672 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001673 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001674 }
1675 }
1676 else if (type == GL_HALF_FLOAT_OES)
1677 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001678 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001679 {
Jamie Madille0472f32018-11-27 16:32:45 -05001680 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001681 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001682 }
1683 }
1684 }
1685
Geoff Langdbcced82017-06-06 15:55:54 -04001686 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001687 if (!ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001688 imageSize))
1689 {
1690 return false;
1691 }
1692
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001693 return true;
1694}
1695
He Yunchaoced53ae2016-11-29 15:00:51 +08001696bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001697 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001698 GLsizei levels,
1699 GLenum internalformat,
1700 GLsizei width,
1701 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001702{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001703 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1704 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001705 {
Jamie Madille0472f32018-11-27 16:32:45 -05001706 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001707 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001708 }
1709
1710 if (width < 1 || height < 1 || levels < 1)
1711 {
Jamie Madille0472f32018-11-27 16:32:45 -05001712 context->validationError(GL_INVALID_VALUE, kTextureSizeTooSmall);
Geoff Langb1196682014-07-23 13:47:29 -04001713 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001714 }
1715
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001716 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001717 {
Jamie Madille0472f32018-11-27 16:32:45 -05001718 context->validationError(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
Geoff Langb1196682014-07-23 13:47:29 -04001719 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001720 }
1721
1722 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1723 {
Jamie Madille0472f32018-11-27 16:32:45 -05001724 context->validationError(GL_INVALID_OPERATION, kInvalidMipLevels);
Geoff Langb1196682014-07-23 13:47:29 -04001725 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001726 }
1727
Geoff Langca271392017-04-05 12:30:00 -04001728 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001729 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001730 {
Jamie Madille0472f32018-11-27 16:32:45 -05001731 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001732 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001733 }
1734
Geoff Langaae65a42014-05-26 12:43:44 -04001735 const gl::Caps &caps = context->getCaps();
1736
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001737 switch (target)
1738 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001739 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001740 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1741 static_cast<GLuint>(height) > caps.max2DTextureSize)
1742 {
Jamie Madille0472f32018-11-27 16:32:45 -05001743 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
He Yunchaoced53ae2016-11-29 15:00:51 +08001744 return false;
1745 }
1746 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001747 case TextureType::Rectangle:
Jamie Madill610640f2018-11-21 17:28:41 -05001748 if (levels != 1)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001749 {
Jamie Madille0472f32018-11-27 16:32:45 -05001750 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madill610640f2018-11-21 17:28:41 -05001751 return false;
1752 }
1753
1754 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1755 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1756 {
Jamie Madille0472f32018-11-27 16:32:45 -05001757 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001758 return false;
1759 }
1760 if (formatInfo.compressed)
1761 {
Jamie Madille0472f32018-11-27 16:32:45 -05001762 context->validationError(GL_INVALID_ENUM, kRectangleTextureCompressed);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001763 return false;
1764 }
1765 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001766 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001767 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1768 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1769 {
Jamie Madille0472f32018-11-27 16:32:45 -05001770 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
He Yunchaoced53ae2016-11-29 15:00:51 +08001771 return false;
1772 }
1773 break;
1774 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001775 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001776 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001777 }
1778
Geoff Langc0b9ef42014-07-02 10:02:37 -04001779 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001780 {
1781 if (!gl::isPow2(width) || !gl::isPow2(height))
1782 {
Jamie Madille0472f32018-11-27 16:32:45 -05001783 context->validationError(GL_INVALID_OPERATION, kDimensionsMustBePow2);
Geoff Langb1196682014-07-23 13:47:29 -04001784 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001785 }
1786 }
1787
1788 switch (internalformat)
1789 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001790 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1791 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1792 if (!context->getExtensions().textureCompressionDXT1)
1793 {
Jamie Madille0472f32018-11-27 16:32:45 -05001794 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001795 return false;
1796 }
1797 break;
1798 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1799 if (!context->getExtensions().textureCompressionDXT3)
1800 {
Jamie Madille0472f32018-11-27 16:32:45 -05001801 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001802 return false;
1803 }
1804 break;
1805 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1806 if (!context->getExtensions().textureCompressionDXT5)
1807 {
Jamie Madille0472f32018-11-27 16:32:45 -05001808 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001809 return false;
1810 }
1811 break;
1812 case GL_ETC1_RGB8_OES:
1813 if (!context->getExtensions().compressedETC1RGB8Texture)
1814 {
Jamie Madille0472f32018-11-27 16:32:45 -05001815 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001816 return false;
1817 }
1818 break;
1819 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001820 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1821 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1822 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1823 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001824 if (!context->getExtensions().lossyETCDecode)
1825 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001826 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001827 return false;
1828 }
1829 break;
1830 case GL_RGBA32F_EXT:
1831 case GL_RGB32F_EXT:
1832 case GL_ALPHA32F_EXT:
1833 case GL_LUMINANCE32F_EXT:
1834 case GL_LUMINANCE_ALPHA32F_EXT:
1835 if (!context->getExtensions().textureFloat)
1836 {
Jamie Madille0472f32018-11-27 16:32:45 -05001837 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001838 return false;
1839 }
1840 break;
1841 case GL_RGBA16F_EXT:
1842 case GL_RGB16F_EXT:
1843 case GL_ALPHA16F_EXT:
1844 case GL_LUMINANCE16F_EXT:
1845 case GL_LUMINANCE_ALPHA16F_EXT:
1846 if (!context->getExtensions().textureHalfFloat)
1847 {
Jamie Madille0472f32018-11-27 16:32:45 -05001848 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001849 return false;
1850 }
1851 break;
1852 case GL_R8_EXT:
1853 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001854 if (!context->getExtensions().textureRG)
1855 {
Jamie Madille0472f32018-11-27 16:32:45 -05001856 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang677bb6f2017-04-05 12:40:40 -04001857 return false;
1858 }
1859 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001860 case GL_R16F_EXT:
1861 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001862 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1863 {
Jamie Madille0472f32018-11-27 16:32:45 -05001864 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang677bb6f2017-04-05 12:40:40 -04001865 return false;
1866 }
1867 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001868 case GL_R32F_EXT:
1869 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001870 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001871 {
Jamie Madille0472f32018-11-27 16:32:45 -05001872 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001873 return false;
1874 }
1875 break;
1876 case GL_DEPTH_COMPONENT16:
1877 case GL_DEPTH_COMPONENT32_OES:
1878 case GL_DEPTH24_STENCIL8_OES:
1879 if (!context->getExtensions().depthTextures)
1880 {
Jamie Madille0472f32018-11-27 16:32:45 -05001881 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001882 return false;
1883 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001884 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001885 {
Jamie Madille0472f32018-11-27 16:32:45 -05001886 context->validationError(GL_INVALID_OPERATION, kInvalidTextureTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001887 return false;
1888 }
1889 // ANGLE_depth_texture only supports 1-level textures
1890 if (levels != 1)
1891 {
Jamie Madille0472f32018-11-27 16:32:45 -05001892 context->validationError(GL_INVALID_OPERATION, kInvalidMipLevels);
He Yunchaoced53ae2016-11-29 15:00:51 +08001893 return false;
1894 }
1895 break;
1896 default:
1897 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001898 }
1899
Geoff Lang691e58c2014-12-19 17:03:25 -05001900 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001901 if (!texture || texture->id() == 0)
1902 {
Jamie Madille0472f32018-11-27 16:32:45 -05001903 context->validationError(GL_INVALID_OPERATION, kMissingTexture);
Geoff Langb1196682014-07-23 13:47:29 -04001904 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001905 }
1906
Geoff Lang69cce582015-09-17 13:20:36 -04001907 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001908 {
Jamie Madille0472f32018-11-27 16:32:45 -05001909 context->validationError(GL_INVALID_OPERATION, kTextureIsImmutable);
Geoff Langb1196682014-07-23 13:47:29 -04001910 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001911 }
1912
1913 return true;
1914}
1915
He Yunchaoced53ae2016-11-29 15:00:51 +08001916bool ValidateDiscardFramebufferEXT(Context *context,
1917 GLenum target,
1918 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001919 const GLenum *attachments)
1920{
Jamie Madillc29968b2016-01-20 11:17:23 -05001921 if (!context->getExtensions().discardFramebuffer)
1922 {
Jamie Madille0472f32018-11-27 16:32:45 -05001923 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001924 return false;
1925 }
1926
Austin Kinross08332632015-05-05 13:35:47 -07001927 bool defaultFramebuffer = false;
1928
1929 switch (target)
1930 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001931 case GL_FRAMEBUFFER:
1932 defaultFramebuffer =
1933 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1934 break;
1935 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001936 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001937 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001938 }
1939
He Yunchaoced53ae2016-11-29 15:00:51 +08001940 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1941 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001942}
1943
Austin Kinrossbc781f32015-10-26 09:27:38 -07001944bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1945{
1946 if (!context->getExtensions().vertexArrayObject)
1947 {
Jamie Madille0472f32018-11-27 16:32:45 -05001948 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001949 return false;
1950 }
1951
1952 return ValidateBindVertexArrayBase(context, array);
1953}
1954
Jamie Madilld7576732017-08-26 18:49:50 -04001955bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001956{
1957 if (!context->getExtensions().vertexArrayObject)
1958 {
Jamie Madille0472f32018-11-27 16:32:45 -05001959 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001960 return false;
1961 }
1962
Olli Etuaho41997e72016-03-10 13:38:39 +02001963 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001964}
1965
Jamie Madilld7576732017-08-26 18:49:50 -04001966bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001967{
1968 if (!context->getExtensions().vertexArrayObject)
1969 {
Jamie Madille0472f32018-11-27 16:32:45 -05001970 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001971 return false;
1972 }
1973
Olli Etuaho41997e72016-03-10 13:38:39 +02001974 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001975}
1976
Jamie Madilld7576732017-08-26 18:49:50 -04001977bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001978{
1979 if (!context->getExtensions().vertexArrayObject)
1980 {
Jamie Madille0472f32018-11-27 16:32:45 -05001981 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001982 return false;
1983 }
1984
1985 return true;
1986}
Geoff Langc5629752015-12-07 16:29:04 -05001987
1988bool ValidateProgramBinaryOES(Context *context,
1989 GLuint program,
1990 GLenum binaryFormat,
1991 const void *binary,
1992 GLint length)
1993{
1994 if (!context->getExtensions().getProgramBinary)
1995 {
Jamie Madille0472f32018-11-27 16:32:45 -05001996 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001997 return false;
1998 }
1999
2000 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
2001}
2002
2003bool ValidateGetProgramBinaryOES(Context *context,
2004 GLuint program,
2005 GLsizei bufSize,
2006 GLsizei *length,
2007 GLenum *binaryFormat,
2008 void *binary)
2009{
2010 if (!context->getExtensions().getProgramBinary)
2011 {
Jamie Madille0472f32018-11-27 16:32:45 -05002012 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05002013 return false;
2014 }
2015
2016 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
2017}
Geoff Lange102fee2015-12-10 11:23:30 -05002018
Geoff Lang70d0f492015-12-10 17:45:46 -05002019static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
2020{
2021 switch (source)
2022 {
2023 case GL_DEBUG_SOURCE_API:
2024 case GL_DEBUG_SOURCE_SHADER_COMPILER:
2025 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
2026 case GL_DEBUG_SOURCE_OTHER:
2027 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
2028 return !mustBeThirdPartyOrApplication;
2029
2030 case GL_DEBUG_SOURCE_THIRD_PARTY:
2031 case GL_DEBUG_SOURCE_APPLICATION:
2032 return true;
2033
2034 default:
2035 return false;
2036 }
2037}
2038
2039static bool ValidDebugType(GLenum type)
2040{
2041 switch (type)
2042 {
2043 case GL_DEBUG_TYPE_ERROR:
2044 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
2045 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
2046 case GL_DEBUG_TYPE_PERFORMANCE:
2047 case GL_DEBUG_TYPE_PORTABILITY:
2048 case GL_DEBUG_TYPE_OTHER:
2049 case GL_DEBUG_TYPE_MARKER:
2050 case GL_DEBUG_TYPE_PUSH_GROUP:
2051 case GL_DEBUG_TYPE_POP_GROUP:
2052 return true;
2053
2054 default:
2055 return false;
2056 }
2057}
2058
2059static bool ValidDebugSeverity(GLenum severity)
2060{
2061 switch (severity)
2062 {
2063 case GL_DEBUG_SEVERITY_HIGH:
2064 case GL_DEBUG_SEVERITY_MEDIUM:
2065 case GL_DEBUG_SEVERITY_LOW:
2066 case GL_DEBUG_SEVERITY_NOTIFICATION:
2067 return true;
2068
2069 default:
2070 return false;
2071 }
2072}
2073
Geoff Lange102fee2015-12-10 11:23:30 -05002074bool ValidateDebugMessageControlKHR(Context *context,
2075 GLenum source,
2076 GLenum type,
2077 GLenum severity,
2078 GLsizei count,
2079 const GLuint *ids,
2080 GLboolean enabled)
2081{
2082 if (!context->getExtensions().debug)
2083 {
Jamie Madille0472f32018-11-27 16:32:45 -05002084 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002085 return false;
2086 }
2087
Geoff Lang70d0f492015-12-10 17:45:46 -05002088 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
2089 {
Jamie Madille0472f32018-11-27 16:32:45 -05002090 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002091 return false;
2092 }
2093
2094 if (!ValidDebugType(type) && type != GL_DONT_CARE)
2095 {
Jamie Madille0472f32018-11-27 16:32:45 -05002096 context->validationError(GL_INVALID_ENUM, kInvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002097 return false;
2098 }
2099
2100 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
2101 {
Jamie Madille0472f32018-11-27 16:32:45 -05002102 context->validationError(GL_INVALID_ENUM, kInvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05002103 return false;
2104 }
2105
2106 if (count > 0)
2107 {
2108 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
2109 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002110 context->validationError(GL_INVALID_OPERATION, kInvalidDebugSourceType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002111 return false;
2112 }
2113
2114 if (severity != GL_DONT_CARE)
2115 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002116 context->validationError(GL_INVALID_OPERATION, kInvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05002117 return false;
2118 }
2119 }
2120
Geoff Lange102fee2015-12-10 11:23:30 -05002121 return true;
2122}
2123
2124bool ValidateDebugMessageInsertKHR(Context *context,
2125 GLenum source,
2126 GLenum type,
2127 GLuint id,
2128 GLenum severity,
2129 GLsizei length,
2130 const GLchar *buf)
2131{
2132 if (!context->getExtensions().debug)
2133 {
Jamie Madille0472f32018-11-27 16:32:45 -05002134 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002135 return false;
2136 }
2137
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002138 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002139 {
2140 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2141 // not generate an error.
2142 return false;
2143 }
2144
2145 if (!ValidDebugSeverity(severity))
2146 {
Jamie Madille0472f32018-11-27 16:32:45 -05002147 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002148 return false;
2149 }
2150
2151 if (!ValidDebugType(type))
2152 {
Jamie Madille0472f32018-11-27 16:32:45 -05002153 context->validationError(GL_INVALID_ENUM, kInvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002154 return false;
2155 }
2156
2157 if (!ValidDebugSource(source, true))
2158 {
Jamie Madille0472f32018-11-27 16:32:45 -05002159 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002160 return false;
2161 }
2162
2163 size_t messageLength = (length < 0) ? strlen(buf) : length;
2164 if (messageLength > context->getExtensions().maxDebugMessageLength)
2165 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002166 context->validationError(GL_INVALID_VALUE, kExceedsMaxDebugMessageLength);
Geoff Lang70d0f492015-12-10 17:45:46 -05002167 return false;
2168 }
2169
Geoff Lange102fee2015-12-10 11:23:30 -05002170 return true;
2171}
2172
2173bool ValidateDebugMessageCallbackKHR(Context *context,
2174 GLDEBUGPROCKHR callback,
2175 const void *userParam)
2176{
2177 if (!context->getExtensions().debug)
2178 {
Jamie Madille0472f32018-11-27 16:32:45 -05002179 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002180 return false;
2181 }
2182
Geoff Lange102fee2015-12-10 11:23:30 -05002183 return true;
2184}
2185
2186bool ValidateGetDebugMessageLogKHR(Context *context,
2187 GLuint count,
2188 GLsizei bufSize,
2189 GLenum *sources,
2190 GLenum *types,
2191 GLuint *ids,
2192 GLenum *severities,
2193 GLsizei *lengths,
2194 GLchar *messageLog)
2195{
2196 if (!context->getExtensions().debug)
2197 {
Jamie Madille0472f32018-11-27 16:32:45 -05002198 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002199 return false;
2200 }
2201
Geoff Lang70d0f492015-12-10 17:45:46 -05002202 if (bufSize < 0 && messageLog != nullptr)
2203 {
Jamie Madille0472f32018-11-27 16:32:45 -05002204 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002205 return false;
2206 }
2207
Geoff Lange102fee2015-12-10 11:23:30 -05002208 return true;
2209}
2210
2211bool ValidatePushDebugGroupKHR(Context *context,
2212 GLenum source,
2213 GLuint id,
2214 GLsizei length,
2215 const GLchar *message)
2216{
2217 if (!context->getExtensions().debug)
2218 {
Jamie Madille0472f32018-11-27 16:32:45 -05002219 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002220 return false;
2221 }
2222
Geoff Lang70d0f492015-12-10 17:45:46 -05002223 if (!ValidDebugSource(source, true))
2224 {
Jamie Madille0472f32018-11-27 16:32:45 -05002225 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002226 return false;
2227 }
2228
2229 size_t messageLength = (length < 0) ? strlen(message) : length;
2230 if (messageLength > context->getExtensions().maxDebugMessageLength)
2231 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002232 context->validationError(GL_INVALID_VALUE, kExceedsMaxDebugMessageLength);
Geoff Lang70d0f492015-12-10 17:45:46 -05002233 return false;
2234 }
2235
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002236 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002237 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2238 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002239 context->validationError(GL_STACK_OVERFLOW, kExceedsMaxDebugGroupStackDepth);
Geoff Lang70d0f492015-12-10 17:45:46 -05002240 return false;
2241 }
2242
Geoff Lange102fee2015-12-10 11:23:30 -05002243 return true;
2244}
2245
2246bool ValidatePopDebugGroupKHR(Context *context)
2247{
2248 if (!context->getExtensions().debug)
2249 {
Jamie Madille0472f32018-11-27 16:32:45 -05002250 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002251 return false;
2252 }
2253
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002254 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002255 if (currentStackSize <= 1)
2256 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002257 context->validationError(GL_STACK_UNDERFLOW, kCannotPopDefaultDebugGroup);
Geoff Lang70d0f492015-12-10 17:45:46 -05002258 return false;
2259 }
2260
2261 return true;
2262}
2263
2264static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2265{
2266 switch (identifier)
2267 {
2268 case GL_BUFFER:
2269 if (context->getBuffer(name) == nullptr)
2270 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002271 context->validationError(GL_INVALID_VALUE, kInvalidBufferName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002272 return false;
2273 }
2274 return true;
2275
2276 case GL_SHADER:
2277 if (context->getShader(name) == nullptr)
2278 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002279 context->validationError(GL_INVALID_VALUE, kInvalidShaderName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002280 return false;
2281 }
2282 return true;
2283
2284 case GL_PROGRAM:
Jamie Madill44a6fbf2018-10-02 13:38:56 -04002285 if (context->getProgramNoResolveLink(name) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002286 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002287 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002288 return false;
2289 }
2290 return true;
2291
2292 case GL_VERTEX_ARRAY:
2293 if (context->getVertexArray(name) == nullptr)
2294 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002295 context->validationError(GL_INVALID_VALUE, kInvalidVertexArrayName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002296 return false;
2297 }
2298 return true;
2299
2300 case GL_QUERY:
2301 if (context->getQuery(name) == nullptr)
2302 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002303 context->validationError(GL_INVALID_VALUE, kInvalidQueryName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002304 return false;
2305 }
2306 return true;
2307
2308 case GL_TRANSFORM_FEEDBACK:
2309 if (context->getTransformFeedback(name) == nullptr)
2310 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002311 context->validationError(GL_INVALID_VALUE, kInvalidTransformFeedbackName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002312 return false;
2313 }
2314 return true;
2315
2316 case GL_SAMPLER:
2317 if (context->getSampler(name) == nullptr)
2318 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002319 context->validationError(GL_INVALID_VALUE, kInvalidSamplerName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002320 return false;
2321 }
2322 return true;
2323
2324 case GL_TEXTURE:
2325 if (context->getTexture(name) == nullptr)
2326 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002327 context->validationError(GL_INVALID_VALUE, kInvalidTextureName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002328 return false;
2329 }
2330 return true;
2331
2332 case GL_RENDERBUFFER:
2333 if (context->getRenderbuffer(name) == nullptr)
2334 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002335 context->validationError(GL_INVALID_VALUE, kInvalidRenderbufferName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002336 return false;
2337 }
2338 return true;
2339
2340 case GL_FRAMEBUFFER:
2341 if (context->getFramebuffer(name) == nullptr)
2342 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002343 context->validationError(GL_INVALID_VALUE, kInvalidFramebufferName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002344 return false;
2345 }
2346 return true;
2347
2348 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05002349 context->validationError(GL_INVALID_ENUM, kInvalidIndentifier);
Geoff Lang70d0f492015-12-10 17:45:46 -05002350 return false;
2351 }
Geoff Lange102fee2015-12-10 11:23:30 -05002352}
2353
Martin Radev9d901792016-07-15 15:58:58 +03002354static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2355{
2356 size_t labelLength = 0;
2357
2358 if (length < 0)
2359 {
2360 if (label != nullptr)
2361 {
2362 labelLength = strlen(label);
2363 }
2364 }
2365 else
2366 {
2367 labelLength = static_cast<size_t>(length);
2368 }
2369
2370 if (labelLength > context->getExtensions().maxLabelLength)
2371 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002372 context->validationError(GL_INVALID_VALUE, kExceedsMaxLabelLength);
Martin Radev9d901792016-07-15 15:58:58 +03002373 return false;
2374 }
2375
2376 return true;
2377}
2378
Geoff Lange102fee2015-12-10 11:23:30 -05002379bool ValidateObjectLabelKHR(Context *context,
2380 GLenum identifier,
2381 GLuint name,
2382 GLsizei length,
2383 const GLchar *label)
2384{
2385 if (!context->getExtensions().debug)
2386 {
Jamie Madille0472f32018-11-27 16:32:45 -05002387 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002388 return false;
2389 }
2390
Geoff Lang70d0f492015-12-10 17:45:46 -05002391 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2392 {
2393 return false;
2394 }
2395
Martin Radev9d901792016-07-15 15:58:58 +03002396 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002397 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002398 return false;
2399 }
2400
Geoff Lange102fee2015-12-10 11:23:30 -05002401 return true;
2402}
2403
2404bool ValidateGetObjectLabelKHR(Context *context,
2405 GLenum identifier,
2406 GLuint name,
2407 GLsizei bufSize,
2408 GLsizei *length,
2409 GLchar *label)
2410{
2411 if (!context->getExtensions().debug)
2412 {
Jamie Madille0472f32018-11-27 16:32:45 -05002413 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002414 return false;
2415 }
2416
Geoff Lang70d0f492015-12-10 17:45:46 -05002417 if (bufSize < 0)
2418 {
Jamie Madille0472f32018-11-27 16:32:45 -05002419 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002420 return false;
2421 }
2422
2423 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2424 {
2425 return false;
2426 }
2427
Martin Radev9d901792016-07-15 15:58:58 +03002428 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002429}
2430
2431static bool ValidateObjectPtrName(Context *context, const void *ptr)
2432{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002433 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002434 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002435 context->validationError(GL_INVALID_VALUE, kInvalidSyncPointer);
Geoff Lang70d0f492015-12-10 17:45:46 -05002436 return false;
2437 }
2438
Geoff Lange102fee2015-12-10 11:23:30 -05002439 return true;
2440}
2441
2442bool ValidateObjectPtrLabelKHR(Context *context,
2443 const void *ptr,
2444 GLsizei length,
2445 const GLchar *label)
2446{
2447 if (!context->getExtensions().debug)
2448 {
Jamie Madille0472f32018-11-27 16:32:45 -05002449 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002450 return false;
2451 }
2452
Geoff Lang70d0f492015-12-10 17:45:46 -05002453 if (!ValidateObjectPtrName(context, ptr))
2454 {
2455 return false;
2456 }
2457
Martin Radev9d901792016-07-15 15:58:58 +03002458 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002459 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002460 return false;
2461 }
2462
Geoff Lange102fee2015-12-10 11:23:30 -05002463 return true;
2464}
2465
2466bool ValidateGetObjectPtrLabelKHR(Context *context,
2467 const void *ptr,
2468 GLsizei bufSize,
2469 GLsizei *length,
2470 GLchar *label)
2471{
2472 if (!context->getExtensions().debug)
2473 {
Jamie Madille0472f32018-11-27 16:32:45 -05002474 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002475 return false;
2476 }
2477
Geoff Lang70d0f492015-12-10 17:45:46 -05002478 if (bufSize < 0)
2479 {
Jamie Madille0472f32018-11-27 16:32:45 -05002480 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002481 return false;
2482 }
2483
2484 if (!ValidateObjectPtrName(context, ptr))
2485 {
2486 return false;
2487 }
2488
Martin Radev9d901792016-07-15 15:58:58 +03002489 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002490}
2491
2492bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2493{
2494 if (!context->getExtensions().debug)
2495 {
Jamie Madille0472f32018-11-27 16:32:45 -05002496 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002497 return false;
2498 }
2499
Geoff Lang70d0f492015-12-10 17:45:46 -05002500 // TODO: represent this in Context::getQueryParameterInfo.
2501 switch (pname)
2502 {
2503 case GL_DEBUG_CALLBACK_FUNCTION:
2504 case GL_DEBUG_CALLBACK_USER_PARAM:
2505 break;
2506
2507 default:
Jamie Madille0472f32018-11-27 16:32:45 -05002508 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002509 return false;
2510 }
2511
Geoff Lange102fee2015-12-10 11:23:30 -05002512 return true;
2513}
Jamie Madillc29968b2016-01-20 11:17:23 -05002514
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07002515bool ValidateGetPointervRobustANGLERobustANGLE(Context *context,
2516 GLenum pname,
2517 GLsizei bufSize,
2518 GLsizei *length,
2519 void **params)
2520{
2521 UNIMPLEMENTED();
2522 return false;
2523}
2524
Jamie Madillc29968b2016-01-20 11:17:23 -05002525bool ValidateBlitFramebufferANGLE(Context *context,
2526 GLint srcX0,
2527 GLint srcY0,
2528 GLint srcX1,
2529 GLint srcY1,
2530 GLint dstX0,
2531 GLint dstY0,
2532 GLint dstX1,
2533 GLint dstY1,
2534 GLbitfield mask,
2535 GLenum filter)
2536{
2537 if (!context->getExtensions().framebufferBlit)
2538 {
Jamie Madille0472f32018-11-27 16:32:45 -05002539 context->validationError(GL_INVALID_OPERATION, kBlitExtensionNotAvailable);
Jamie Madillc29968b2016-01-20 11:17:23 -05002540 return false;
2541 }
2542
2543 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2544 {
2545 // TODO(jmadill): Determine if this should be available on other implementations.
Jamie Madille0472f32018-11-27 16:32:45 -05002546 context->validationError(GL_INVALID_OPERATION, kBlitExtensionScaleOrFlip);
Jamie Madillc29968b2016-01-20 11:17:23 -05002547 return false;
2548 }
2549
2550 if (filter == GL_LINEAR)
2551 {
Jamie Madille0472f32018-11-27 16:32:45 -05002552 context->validationError(GL_INVALID_ENUM, kBlitExtensionLinear);
Jamie Madillc29968b2016-01-20 11:17:23 -05002553 return false;
2554 }
2555
Jamie Madill51f40ec2016-06-15 14:06:00 -04002556 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2557 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002558
2559 if (mask & GL_COLOR_BUFFER_BIT)
2560 {
2561 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2562 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2563
2564 if (readColorAttachment && drawColorAttachment)
2565 {
2566 if (!(readColorAttachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002567 readColorAttachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002568 readColorAttachment->type() != GL_RENDERBUFFER &&
2569 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2570 {
Jamie Madill610640f2018-11-21 17:28:41 -05002571 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002572 kBlitExtensionFromInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002573 return false;
2574 }
2575
Geoff Langa15472a2015-08-11 11:48:03 -04002576 for (size_t drawbufferIdx = 0;
2577 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002578 {
Geoff Langa15472a2015-08-11 11:48:03 -04002579 const FramebufferAttachment *attachment =
2580 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2581 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002582 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002583 if (!(attachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002584 attachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002585 attachment->type() != GL_RENDERBUFFER &&
2586 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2587 {
Jamie Madill610640f2018-11-21 17:28:41 -05002588 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002589 kBlitExtensionToInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002590 return false;
2591 }
2592
2593 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002594 if (!Format::EquivalentForBlit(attachment->getFormat(),
2595 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002596 {
Jamie Madill610640f2018-11-21 17:28:41 -05002597 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002598 kBlitExtensionFormatMismatch);
Jamie Madillc29968b2016-01-20 11:17:23 -05002599 return false;
2600 }
2601 }
2602 }
2603
Jamie Madill427064d2018-04-13 16:20:34 -04002604 GLint samples = readFramebuffer->getSamples(context);
Jamie Madille98b1b52018-03-08 09:47:23 -05002605 if (samples != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002606 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2607 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2608 {
Jamie Madill610640f2018-11-21 17:28:41 -05002609 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002610 kBlitExtensionMultisampledWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002611 return false;
2612 }
2613 }
2614 }
2615
2616 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2617 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2618 for (size_t i = 0; i < 2; i++)
2619 {
2620 if (mask & masks[i])
2621 {
2622 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002623 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002624 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002625 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002626
2627 if (readBuffer && drawBuffer)
2628 {
2629 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2630 dstX0, dstY0, dstX1, dstY1))
2631 {
2632 // only whole-buffer copies are permitted
Jamie Madill610640f2018-11-21 17:28:41 -05002633 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002634 kBlitExtensionDepthStencilWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002635 return false;
2636 }
2637
2638 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2639 {
Jamie Madill610640f2018-11-21 17:28:41 -05002640 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002641 kBlitExtensionMultisampledDepthOrStencil);
Jamie Madillc29968b2016-01-20 11:17:23 -05002642 return false;
2643 }
2644 }
2645 }
2646 }
2647
2648 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2649 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002650}
Jamie Madillc29968b2016-01-20 11:17:23 -05002651
Jamie Madill5b772312018-03-08 20:28:32 -05002652bool ValidateClear(Context *context, GLbitfield mask)
Jamie Madillc29968b2016-01-20 11:17:23 -05002653{
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07002654 Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
Olli Etuaho94c91a92018-07-19 15:10:24 +03002655 const Extensions &extensions = context->getExtensions();
Jamie Madille98b1b52018-03-08 09:47:23 -05002656
Jamie Madill427064d2018-04-13 16:20:34 -04002657 if (!ValidateFramebufferComplete(context, fbo))
Jamie Madillc29968b2016-01-20 11:17:23 -05002658 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002659 return false;
2660 }
2661
2662 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2663 {
Jamie Madille0472f32018-11-27 16:32:45 -05002664 context->validationError(GL_INVALID_VALUE, kInvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002665 return false;
2666 }
2667
Olli Etuaho94c91a92018-07-19 15:10:24 +03002668 if (extensions.webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
Geoff Lang76e65652017-03-27 14:58:02 -04002669 {
2670 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2671 GL_SIGNED_NORMALIZED};
2672
Corentin Wallez59c41592017-07-11 13:19:54 -04002673 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002674 drawBufferIdx++)
2675 {
2676 if (!ValidateWebGLFramebufferAttachmentClearType(
2677 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2678 {
2679 return false;
2680 }
2681 }
2682 }
2683
Olli Etuaho94c91a92018-07-19 15:10:24 +03002684 if (extensions.multiview && extensions.disjointTimerQuery)
2685 {
2686 const State &state = context->getGLState();
2687 Framebuffer *framebuffer = state.getDrawFramebuffer();
2688 if (framebuffer->getNumViews() > 1 && state.isQueryActive(QueryType::TimeElapsed))
2689 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002690 context->validationError(GL_INVALID_OPERATION, kMultiviewTimerQuery);
Olli Etuaho94c91a92018-07-19 15:10:24 +03002691 return false;
2692 }
2693 }
2694
Jamie Madillc29968b2016-01-20 11:17:23 -05002695 return true;
2696}
2697
Jamie Madill5b772312018-03-08 20:28:32 -05002698bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002699{
2700 if (!context->getExtensions().drawBuffers)
2701 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002702 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05002703 return false;
2704 }
2705
2706 return ValidateDrawBuffersBase(context, n, bufs);
2707}
2708
Jamie Madill73a84962016-02-12 09:27:23 -05002709bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002710 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002711 GLint level,
2712 GLint internalformat,
2713 GLsizei width,
2714 GLsizei height,
2715 GLint border,
2716 GLenum format,
2717 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002718 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002719{
Martin Radev1be913c2016-07-11 17:59:16 +03002720 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002721 {
2722 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002723 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002724 }
2725
Martin Radev1be913c2016-07-11 17:59:16 +03002726 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002727 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002728 0, 0, width, height, 1, border, format, type, -1,
2729 pixels);
2730}
2731
Brandon Jones416aaf92018-04-10 08:10:16 -07002732bool ValidateTexImage2DRobustANGLE(Context *context,
2733 TextureTarget target,
2734 GLint level,
2735 GLint internalformat,
2736 GLsizei width,
2737 GLsizei height,
2738 GLint border,
2739 GLenum format,
2740 GLenum type,
2741 GLsizei bufSize,
2742 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002743{
2744 if (!ValidateRobustEntryPoint(context, bufSize))
2745 {
2746 return false;
2747 }
2748
2749 if (context->getClientMajorVersion() < 3)
2750 {
2751 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2752 0, 0, width, height, border, format, type, bufSize,
2753 pixels);
2754 }
2755
2756 ASSERT(context->getClientMajorVersion() >= 3);
2757 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2758 0, 0, width, height, 1, border, format, type, bufSize,
2759 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002760}
2761
2762bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002763 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002764 GLint level,
2765 GLint xoffset,
2766 GLint yoffset,
2767 GLsizei width,
2768 GLsizei height,
2769 GLenum format,
2770 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002771 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002772{
2773
Martin Radev1be913c2016-07-11 17:59:16 +03002774 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002775 {
2776 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002777 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002778 }
2779
Martin Radev1be913c2016-07-11 17:59:16 +03002780 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002781 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002782 yoffset, 0, width, height, 1, 0, format, type, -1,
2783 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002784}
2785
Geoff Langc52f6f12016-10-14 10:18:00 -04002786bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002787 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002788 GLint level,
2789 GLint xoffset,
2790 GLint yoffset,
2791 GLsizei width,
2792 GLsizei height,
2793 GLenum format,
2794 GLenum type,
2795 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002796 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002797{
2798 if (!ValidateRobustEntryPoint(context, bufSize))
2799 {
2800 return false;
2801 }
2802
2803 if (context->getClientMajorVersion() < 3)
2804 {
2805 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2806 yoffset, width, height, 0, format, type, bufSize,
2807 pixels);
2808 }
2809
2810 ASSERT(context->getClientMajorVersion() >= 3);
2811 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2812 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2813 pixels);
2814}
2815
Jamie Madill73a84962016-02-12 09:27:23 -05002816bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002817 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002818 GLint level,
2819 GLenum internalformat,
2820 GLsizei width,
2821 GLsizei height,
2822 GLint border,
2823 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002824 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002825{
Martin Radev1be913c2016-07-11 17:59:16 +03002826 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002827 {
2828 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002829 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002830 {
2831 return false;
2832 }
2833 }
2834 else
2835 {
Martin Radev1be913c2016-07-11 17:59:16 +03002836 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002837 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002838 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002839 data))
2840 {
2841 return false;
2842 }
2843 }
2844
Geoff Langca271392017-04-05 12:30:00 -04002845 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jamie Madillca2ff382018-07-11 09:01:17 -04002846
2847 GLuint blockSize = 0;
2848 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002849 {
Jamie Madille0472f32018-11-27 16:32:45 -05002850 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002851 return false;
2852 }
2853
Jamie Madillca2ff382018-07-11 09:01:17 -04002854 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002855 {
Jamie Madille0472f32018-11-27 16:32:45 -05002856 context->validationError(GL_INVALID_VALUE, kCompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002857 return false;
2858 }
2859
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002860 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002861 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002862 context->validationError(GL_INVALID_ENUM, kRectangleTextureCompressed);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002863 return false;
2864 }
2865
Jamie Madill73a84962016-02-12 09:27:23 -05002866 return true;
2867}
2868
Corentin Wallezb2931602017-04-11 15:58:57 -04002869bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002870 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002871 GLint level,
2872 GLenum internalformat,
2873 GLsizei width,
2874 GLsizei height,
2875 GLint border,
2876 GLsizei imageSize,
2877 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002878 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002879{
2880 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2881 {
2882 return false;
2883 }
2884
2885 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2886 border, imageSize, data);
2887}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002888
Corentin Wallezb2931602017-04-11 15:58:57 -04002889bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002890 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002891 GLint level,
2892 GLint xoffset,
2893 GLint yoffset,
2894 GLsizei width,
2895 GLsizei height,
2896 GLenum format,
2897 GLsizei imageSize,
2898 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002899 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002900{
2901 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2902 {
2903 return false;
2904 }
2905
2906 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2907 format, imageSize, data);
2908}
2909
Jamie Madill73a84962016-02-12 09:27:23 -05002910bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002911 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002912 GLint level,
2913 GLint xoffset,
2914 GLint yoffset,
2915 GLsizei width,
2916 GLsizei height,
2917 GLenum format,
2918 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002919 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002920{
Martin Radev1be913c2016-07-11 17:59:16 +03002921 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002922 {
2923 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002924 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002925 {
2926 return false;
2927 }
2928 }
2929 else
2930 {
Martin Radev1be913c2016-07-11 17:59:16 +03002931 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002932 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002933 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002934 data))
2935 {
2936 return false;
2937 }
2938 }
2939
Geoff Langca271392017-04-05 12:30:00 -04002940 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jamie Madillca2ff382018-07-11 09:01:17 -04002941 GLuint blockSize = 0;
2942 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002943 {
Jamie Madille0472f32018-11-27 16:32:45 -05002944 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002945 return false;
2946 }
2947
Jamie Madillca2ff382018-07-11 09:01:17 -04002948 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002949 {
Jamie Madille0472f32018-11-27 16:32:45 -05002950 context->validationError(GL_INVALID_VALUE, kInvalidCompressedImageSize);
Jamie Madill73a84962016-02-12 09:27:23 -05002951 return false;
2952 }
2953
2954 return true;
2955}
2956
Corentin Wallez336129f2017-10-17 15:55:40 -04002957bool ValidateGetBufferPointervOES(Context *context,
2958 BufferBinding target,
2959 GLenum pname,
2960 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002961{
Jamie Madillc3e37312018-11-30 15:25:39 -05002962 if (!context->getExtensions().mapBuffer)
2963 {
2964 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
2965 return false;
2966 }
2967
Geoff Lang496c02d2016-10-20 11:38:11 -07002968 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002969}
2970
Corentin Wallez336129f2017-10-17 15:55:40 -04002971bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03002972{
2973 if (!context->getExtensions().mapBuffer)
2974 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002975 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03002976 return false;
2977 }
2978
Corentin Walleze4477002017-12-01 14:39:58 -05002979 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03002980 {
Jamie Madille0472f32018-11-27 16:32:45 -05002981 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002982 return false;
2983 }
2984
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002985 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002986
2987 if (buffer == nullptr)
2988 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002989 context->validationError(GL_INVALID_OPERATION, kBufferNotMappable);
Olli Etuaho4f667482016-03-30 15:56:35 +03002990 return false;
2991 }
2992
2993 if (access != GL_WRITE_ONLY_OES)
2994 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002995 context->validationError(GL_INVALID_ENUM, kInvalidAccessBits);
Olli Etuaho4f667482016-03-30 15:56:35 +03002996 return false;
2997 }
2998
2999 if (buffer->isMapped())
3000 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003001 context->validationError(GL_INVALID_OPERATION, kBufferAlreadyMapped);
Olli Etuaho4f667482016-03-30 15:56:35 +03003002 return false;
3003 }
3004
Geoff Lang79f71042017-08-14 16:43:43 -04003005 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003006}
3007
Corentin Wallez336129f2017-10-17 15:55:40 -04003008bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03003009{
3010 if (!context->getExtensions().mapBuffer)
3011 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003012 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03003013 return false;
3014 }
3015
3016 return ValidateUnmapBufferBase(context, target);
3017}
3018
3019bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003020 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003021 GLintptr offset,
3022 GLsizeiptr length,
3023 GLbitfield access)
3024{
3025 if (!context->getExtensions().mapBufferRange)
3026 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003027 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03003028 return false;
3029 }
3030
3031 return ValidateMapBufferRangeBase(context, target, offset, length, access);
3032}
3033
Corentin Wallez336129f2017-10-17 15:55:40 -04003034bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04003035{
3036 Buffer *buffer = context->getGLState().getTargetBuffer(target);
3037 ASSERT(buffer != nullptr);
3038
3039 // Check if this buffer is currently being used as a transform feedback output buffer
3040 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
3041 if (transformFeedback != nullptr && transformFeedback->isActive())
3042 {
3043 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
3044 {
3045 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
3046 if (transformFeedbackBuffer.get() == buffer)
3047 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003048 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
Geoff Lang79f71042017-08-14 16:43:43 -04003049 return false;
3050 }
3051 }
3052 }
3053
James Darpiniane8a93c62018-01-04 18:02:24 -08003054 if (context->getExtensions().webglCompatibility &&
3055 buffer->isBoundForTransformFeedbackAndOtherUse())
3056 {
Jamie Madille0472f32018-11-27 16:32:45 -05003057 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08003058 return false;
3059 }
3060
Geoff Lang79f71042017-08-14 16:43:43 -04003061 return true;
3062}
3063
Olli Etuaho4f667482016-03-30 15:56:35 +03003064bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003065 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003066 GLintptr offset,
3067 GLsizeiptr length)
3068{
3069 if (!context->getExtensions().mapBufferRange)
3070 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003071 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03003072 return false;
3073 }
3074
3075 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
3076}
3077
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003078bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
Ian Ewell54f87462016-03-10 13:47:21 -05003079{
Jamie Madillac66f982018-10-09 18:30:01 -04003080 if (!context->getStateCache().isValidBindTextureType(target))
Ian Ewell54f87462016-03-10 13:47:21 -05003081 {
Jamie Madillac66f982018-10-09 18:30:01 -04003082 RecordBindTextureTypeError(context, target);
3083 return false;
Ian Ewell54f87462016-03-10 13:47:21 -05003084 }
3085
Jamie Madill0fdb9562018-09-17 17:18:43 -04003086 if (texture == 0)
3087 {
3088 return true;
3089 }
3090
3091 Texture *textureObject = context->getTexture(texture);
3092 if (textureObject && textureObject->getType() != target)
3093 {
Jamie Madille0472f32018-11-27 16:32:45 -05003094 context->validationError(GL_INVALID_OPERATION, kTypeMismatch);
Jamie Madill0fdb9562018-09-17 17:18:43 -04003095 return false;
3096 }
3097
3098 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
3099 !context->isTextureGenerated(texture))
3100 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003101 context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
Jamie Madill0fdb9562018-09-17 17:18:43 -04003102 return false;
3103 }
3104
Ian Ewell54f87462016-03-10 13:47:21 -05003105 return true;
3106}
3107
Geoff Langd8605522016-04-13 10:19:12 -04003108bool ValidateBindUniformLocationCHROMIUM(Context *context,
3109 GLuint program,
3110 GLint location,
3111 const GLchar *name)
3112{
3113 if (!context->getExtensions().bindUniformLocation)
3114 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003115 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langd8605522016-04-13 10:19:12 -04003116 return false;
3117 }
3118
3119 Program *programObject = GetValidProgram(context, program);
3120 if (!programObject)
3121 {
3122 return false;
3123 }
3124
3125 if (location < 0)
3126 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003127 context->validationError(GL_INVALID_VALUE, kNegativeLocation);
Geoff Langd8605522016-04-13 10:19:12 -04003128 return false;
3129 }
3130
3131 const Caps &caps = context->getCaps();
3132 if (static_cast<size_t>(location) >=
3133 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3134 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003135 context->validationError(GL_INVALID_VALUE, kInvalidBindUniformLocation);
Geoff Langd8605522016-04-13 10:19:12 -04003136 return false;
3137 }
3138
Geoff Langfc32e8b2017-05-31 14:16:59 -04003139 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3140 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003141 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003142 {
Jamie Madille0472f32018-11-27 16:32:45 -05003143 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003144 return false;
3145 }
3146
Geoff Langd8605522016-04-13 10:19:12 -04003147 if (strncmp(name, "gl_", 3) == 0)
3148 {
Jamie Madille0472f32018-11-27 16:32:45 -05003149 context->validationError(GL_INVALID_VALUE, kNameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003150 return false;
3151 }
3152
3153 return true;
3154}
3155
Jamie Madille2e406c2016-06-02 13:04:10 -04003156bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003157{
3158 if (!context->getExtensions().framebufferMixedSamples)
3159 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003160 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänena797e062016-05-12 15:23:40 +03003161 return false;
3162 }
3163 switch (components)
3164 {
3165 case GL_RGB:
3166 case GL_RGBA:
3167 case GL_ALPHA:
3168 case GL_NONE:
3169 break;
3170 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003171 context->validationError(GL_INVALID_ENUM, kInvalidCoverageComponents);
Sami Väisänena797e062016-05-12 15:23:40 +03003172 return false;
3173 }
3174
3175 return true;
3176}
3177
Sami Väisänene45e53b2016-05-25 10:36:04 +03003178// CHROMIUM_path_rendering
3179
Jamie Madill007530e2017-12-28 14:27:04 -05003180bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003181{
Jamie Madill007530e2017-12-28 14:27:04 -05003182 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003183 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003184 return false;
3185 }
Jamie Madill007530e2017-12-28 14:27:04 -05003186
Sami Väisänene45e53b2016-05-25 10:36:04 +03003187 if (matrix == nullptr)
3188 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003189 context->validationError(GL_INVALID_OPERATION, kInvalidPathMatrix);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003190 return false;
3191 }
Jamie Madill007530e2017-12-28 14:27:04 -05003192
Sami Väisänene45e53b2016-05-25 10:36:04 +03003193 return true;
3194}
3195
Jamie Madill007530e2017-12-28 14:27:04 -05003196bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003197{
Jamie Madill007530e2017-12-28 14:27:04 -05003198 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003199}
3200
Jamie Madill007530e2017-12-28 14:27:04 -05003201bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003202{
3203 if (!context->getExtensions().pathRendering)
3204 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003205 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003206 return false;
3207 }
3208
3209 // range = 0 is undefined in NV_path_rendering.
3210 // we add stricter semantic check here and require a non zero positive range.
3211 if (range <= 0)
3212 {
Jamie Madille0472f32018-11-27 16:32:45 -05003213 context->validationError(GL_INVALID_VALUE, kInvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003214 return false;
3215 }
3216
3217 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3218 {
Jamie Madille0472f32018-11-27 16:32:45 -05003219 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003220 return false;
3221 }
3222
3223 return true;
3224}
3225
Jamie Madill007530e2017-12-28 14:27:04 -05003226bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003227{
3228 if (!context->getExtensions().pathRendering)
3229 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003230 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003231 return false;
3232 }
3233
3234 // range = 0 is undefined in NV_path_rendering.
3235 // we add stricter semantic check here and require a non zero positive range.
3236 if (range <= 0)
3237 {
Jamie Madille0472f32018-11-27 16:32:45 -05003238 context->validationError(GL_INVALID_VALUE, kInvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003239 return false;
3240 }
3241
3242 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3243 checkedRange += range;
3244
3245 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3246 {
Jamie Madille0472f32018-11-27 16:32:45 -05003247 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003248 return false;
3249 }
3250 return true;
3251}
3252
Jamie Madill007530e2017-12-28 14:27:04 -05003253bool ValidatePathCommandsCHROMIUM(Context *context,
3254 GLuint path,
3255 GLsizei numCommands,
3256 const GLubyte *commands,
3257 GLsizei numCoords,
3258 GLenum coordType,
3259 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003260{
3261 if (!context->getExtensions().pathRendering)
3262 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003263 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003264 return false;
3265 }
Brandon Jones59770802018-04-02 13:18:42 -07003266 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003267 {
Jamie Madille0472f32018-11-27 16:32:45 -05003268 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003269 return false;
3270 }
3271
3272 if (numCommands < 0)
3273 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003274 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCommands);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003275 return false;
3276 }
3277 else if (numCommands > 0)
3278 {
3279 if (!commands)
3280 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003281 context->validationError(GL_INVALID_VALUE, kInvalidPathCommandsArray);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003282 return false;
3283 }
3284 }
3285
3286 if (numCoords < 0)
3287 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003288 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCoords);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003289 return false;
3290 }
3291 else if (numCoords > 0)
3292 {
3293 if (!coords)
3294 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003295 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCoordsArray);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003296 return false;
3297 }
3298 }
3299
3300 std::uint32_t coordTypeSize = 0;
3301 switch (coordType)
3302 {
3303 case GL_BYTE:
3304 coordTypeSize = sizeof(GLbyte);
3305 break;
3306
3307 case GL_UNSIGNED_BYTE:
3308 coordTypeSize = sizeof(GLubyte);
3309 break;
3310
3311 case GL_SHORT:
3312 coordTypeSize = sizeof(GLshort);
3313 break;
3314
3315 case GL_UNSIGNED_SHORT:
3316 coordTypeSize = sizeof(GLushort);
3317 break;
3318
3319 case GL_FLOAT:
3320 coordTypeSize = sizeof(GLfloat);
3321 break;
3322
3323 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003324 context->validationError(GL_INVALID_ENUM, kInvalidPathCoordinateType);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003325 return false;
3326 }
3327
3328 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3329 checkedSize += (coordTypeSize * numCoords);
3330 if (!checkedSize.IsValid())
3331 {
Jamie Madille0472f32018-11-27 16:32:45 -05003332 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003333 return false;
3334 }
3335
3336 // early return skips command data validation when it doesn't exist.
3337 if (!commands)
3338 return true;
3339
3340 GLsizei expectedNumCoords = 0;
3341 for (GLsizei i = 0; i < numCommands; ++i)
3342 {
3343 switch (commands[i])
3344 {
3345 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3346 break;
3347 case GL_MOVE_TO_CHROMIUM:
3348 case GL_LINE_TO_CHROMIUM:
3349 expectedNumCoords += 2;
3350 break;
3351 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3352 expectedNumCoords += 4;
3353 break;
3354 case GL_CUBIC_CURVE_TO_CHROMIUM:
3355 expectedNumCoords += 6;
3356 break;
3357 case GL_CONIC_CURVE_TO_CHROMIUM:
3358 expectedNumCoords += 5;
3359 break;
3360 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003361 context->validationError(GL_INVALID_ENUM, kInvalidPathCommand);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003362 return false;
3363 }
3364 }
Jamie Madillc3e37312018-11-30 15:25:39 -05003365
Sami Väisänene45e53b2016-05-25 10:36:04 +03003366 if (expectedNumCoords != numCoords)
3367 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003368 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCoords);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003369 return false;
3370 }
3371
3372 return true;
3373}
3374
Jamie Madill007530e2017-12-28 14:27:04 -05003375bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003376{
3377 if (!context->getExtensions().pathRendering)
3378 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003379 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003380 return false;
3381 }
Brandon Jones59770802018-04-02 13:18:42 -07003382 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003383 {
Jamie Madille0472f32018-11-27 16:32:45 -05003384 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003385 return false;
3386 }
3387
3388 switch (pname)
3389 {
3390 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3391 if (value < 0.0f)
3392 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003393 context->validationError(GL_INVALID_VALUE, kInvalidPathStrokeWidth);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003394 return false;
3395 }
3396 break;
3397 case GL_PATH_END_CAPS_CHROMIUM:
3398 switch (static_cast<GLenum>(value))
3399 {
3400 case GL_FLAT_CHROMIUM:
3401 case GL_SQUARE_CHROMIUM:
3402 case GL_ROUND_CHROMIUM:
3403 break;
3404 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003405 context->validationError(GL_INVALID_ENUM, kInvalidPathEndCaps);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003406 return false;
3407 }
3408 break;
3409 case GL_PATH_JOIN_STYLE_CHROMIUM:
3410 switch (static_cast<GLenum>(value))
3411 {
3412 case GL_MITER_REVERT_CHROMIUM:
3413 case GL_BEVEL_CHROMIUM:
3414 case GL_ROUND_CHROMIUM:
3415 break;
3416 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003417 context->validationError(GL_INVALID_ENUM, kInvalidPathJoinStyle);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003418 return false;
3419 }
Nico Weber41b072b2018-02-09 10:01:32 -05003420 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003421 case GL_PATH_MITER_LIMIT_CHROMIUM:
3422 if (value < 0.0f)
3423 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003424 context->validationError(GL_INVALID_VALUE, kInvalidPathMiterLimit);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003425 return false;
3426 }
3427 break;
3428
3429 case GL_PATH_STROKE_BOUND_CHROMIUM:
3430 // no errors, only clamping.
3431 break;
3432
3433 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003434 context->validationError(GL_INVALID_ENUM, kInvalidPathParameter);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003435 return false;
3436 }
3437 return true;
3438}
3439
Jamie Madill007530e2017-12-28 14:27:04 -05003440bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3441{
3442 // TODO(jmadill): Use proper clamping cast.
3443 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3444}
3445
3446bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003447{
3448 if (!context->getExtensions().pathRendering)
3449 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003450 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003451 return false;
3452 }
3453
Brandon Jones59770802018-04-02 13:18:42 -07003454 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003455 {
Jamie Madille0472f32018-11-27 16:32:45 -05003456 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003457 return false;
3458 }
Jamie Madillc3e37312018-11-30 15:25:39 -05003459
Sami Väisänene45e53b2016-05-25 10:36:04 +03003460 if (!value)
3461 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003462 context->validationError(GL_INVALID_VALUE, kInvalidPathValueArray);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003463 return false;
3464 }
3465
3466 switch (pname)
3467 {
3468 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3469 case GL_PATH_END_CAPS_CHROMIUM:
3470 case GL_PATH_JOIN_STYLE_CHROMIUM:
3471 case GL_PATH_MITER_LIMIT_CHROMIUM:
3472 case GL_PATH_STROKE_BOUND_CHROMIUM:
3473 break;
3474
3475 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003476 context->validationError(GL_INVALID_ENUM, kInvalidPathParameter);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003477 return false;
3478 }
3479
3480 return true;
3481}
3482
Jamie Madill007530e2017-12-28 14:27:04 -05003483bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3484{
3485 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3486 reinterpret_cast<GLfloat *>(value));
3487}
3488
3489bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003490{
3491 if (!context->getExtensions().pathRendering)
3492 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003493 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003494 return false;
3495 }
3496
3497 switch (func)
3498 {
3499 case GL_NEVER:
3500 case GL_ALWAYS:
3501 case GL_LESS:
3502 case GL_LEQUAL:
3503 case GL_EQUAL:
3504 case GL_GEQUAL:
3505 case GL_GREATER:
3506 case GL_NOTEQUAL:
3507 break;
3508 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003509 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003510 return false;
3511 }
3512
3513 return true;
3514}
3515
3516// Note that the spec specifies that for the path drawing commands
3517// if the path object is not an existing path object the command
3518// does nothing and no error is generated.
3519// However if the path object exists but has not been specified any
3520// commands then an error is generated.
3521
Jamie Madill007530e2017-12-28 14:27:04 -05003522bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003523{
3524 if (!context->getExtensions().pathRendering)
3525 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003526 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003527 return false;
3528 }
Brandon Jones59770802018-04-02 13:18:42 -07003529 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003530 {
Jamie Madille0472f32018-11-27 16:32:45 -05003531 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003532 return false;
3533 }
3534
3535 switch (fillMode)
3536 {
3537 case GL_COUNT_UP_CHROMIUM:
3538 case GL_COUNT_DOWN_CHROMIUM:
3539 break;
3540 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003541 context->validationError(GL_INVALID_ENUM, kInvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003542 return false;
3543 }
3544
3545 if (!isPow2(mask + 1))
3546 {
Jamie Madille0472f32018-11-27 16:32:45 -05003547 context->validationError(GL_INVALID_VALUE, kInvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003548 return false;
3549 }
3550
3551 return true;
3552}
3553
Jamie Madill007530e2017-12-28 14:27:04 -05003554bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003555{
3556 if (!context->getExtensions().pathRendering)
3557 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003558 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003559 return false;
3560 }
Jamie Madillc3e37312018-11-30 15:25:39 -05003561
Brandon Jones59770802018-04-02 13:18:42 -07003562 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003563 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003564 context->validationError(GL_INVALID_OPERATION, kNoPathOrNoPathData);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003565 return false;
3566 }
3567
3568 return true;
3569}
3570
Jamie Madill007530e2017-12-28 14:27:04 -05003571bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003572{
3573 if (!context->getExtensions().pathRendering)
3574 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003575 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
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 Madille0472f32018-11-27 16:32:45 -05003580 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003581 return false;
3582 }
3583
3584 switch (coverMode)
3585 {
3586 case GL_CONVEX_HULL_CHROMIUM:
3587 case GL_BOUNDING_BOX_CHROMIUM:
3588 break;
3589 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003590 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003591 return false;
3592 }
3593 return true;
3594}
3595
Jamie Madill778bf092018-11-14 09:54:36 -05003596bool ValidateCoverFillPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3597{
3598 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3599}
3600
3601bool ValidateCoverStrokePathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3602{
3603 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3604}
3605
Jamie Madill007530e2017-12-28 14:27:04 -05003606bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3607 GLuint path,
3608 GLenum fillMode,
3609 GLuint mask,
3610 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003611{
Jamie Madill007530e2017-12-28 14:27:04 -05003612 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3613 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003614}
3615
Jamie Madill007530e2017-12-28 14:27:04 -05003616bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3617 GLuint path,
3618 GLint reference,
3619 GLuint mask,
3620 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003621{
Jamie Madill007530e2017-12-28 14:27:04 -05003622 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3623 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003624}
3625
Brandon Jonesd1049182018-03-28 10:02:20 -07003626bool ValidateIsPathCHROMIUM(Context *context, GLuint path)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003627{
3628 if (!context->getExtensions().pathRendering)
3629 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003630 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003631 return false;
3632 }
3633 return true;
3634}
3635
Jamie Madill007530e2017-12-28 14:27:04 -05003636bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3637 GLsizei numPaths,
3638 GLenum pathNameType,
3639 const void *paths,
3640 GLuint pathBase,
3641 GLenum coverMode,
3642 GLenum transformType,
3643 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003644{
3645 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3646 transformType, transformValues))
3647 return false;
3648
3649 switch (coverMode)
3650 {
3651 case GL_CONVEX_HULL_CHROMIUM:
3652 case GL_BOUNDING_BOX_CHROMIUM:
3653 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3654 break;
3655 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003656 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003657 return false;
3658 }
3659
3660 return true;
3661}
3662
Jamie Madill007530e2017-12-28 14:27:04 -05003663bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3664 GLsizei numPaths,
3665 GLenum pathNameType,
3666 const void *paths,
3667 GLuint pathBase,
3668 GLenum coverMode,
3669 GLenum transformType,
3670 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003671{
3672 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3673 transformType, transformValues))
3674 return false;
3675
3676 switch (coverMode)
3677 {
3678 case GL_CONVEX_HULL_CHROMIUM:
3679 case GL_BOUNDING_BOX_CHROMIUM:
3680 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3681 break;
3682 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003683 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003684 return false;
3685 }
3686
3687 return true;
3688}
3689
Jamie Madill007530e2017-12-28 14:27:04 -05003690bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3691 GLsizei numPaths,
3692 GLenum pathNameType,
3693 const void *paths,
3694 GLuint pathBase,
3695 GLenum fillMode,
3696 GLuint mask,
3697 GLenum transformType,
3698 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003699{
3700
3701 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3702 transformType, transformValues))
3703 return false;
3704
3705 switch (fillMode)
3706 {
3707 case GL_COUNT_UP_CHROMIUM:
3708 case GL_COUNT_DOWN_CHROMIUM:
3709 break;
3710 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003711 context->validationError(GL_INVALID_ENUM, kInvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003712 return false;
3713 }
3714 if (!isPow2(mask + 1))
3715 {
Jamie Madille0472f32018-11-27 16:32:45 -05003716 context->validationError(GL_INVALID_VALUE, kInvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003717 return false;
3718 }
3719 return true;
3720}
3721
Jamie Madill007530e2017-12-28 14:27:04 -05003722bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3723 GLsizei numPaths,
3724 GLenum pathNameType,
3725 const void *paths,
3726 GLuint pathBase,
3727 GLint reference,
3728 GLuint mask,
3729 GLenum transformType,
3730 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003731{
3732 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3733 transformType, transformValues))
3734 return false;
3735
3736 // no more validation here.
3737
3738 return true;
3739}
3740
Jamie Madill007530e2017-12-28 14:27:04 -05003741bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3742 GLsizei numPaths,
3743 GLenum pathNameType,
3744 const void *paths,
3745 GLuint pathBase,
3746 GLenum fillMode,
3747 GLuint mask,
3748 GLenum coverMode,
3749 GLenum transformType,
3750 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003751{
3752 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3753 transformType, transformValues))
3754 return false;
3755
3756 switch (coverMode)
3757 {
3758 case GL_CONVEX_HULL_CHROMIUM:
3759 case GL_BOUNDING_BOX_CHROMIUM:
3760 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3761 break;
3762 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003763 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003764 return false;
3765 }
3766
3767 switch (fillMode)
3768 {
3769 case GL_COUNT_UP_CHROMIUM:
3770 case GL_COUNT_DOWN_CHROMIUM:
3771 break;
3772 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003773 context->validationError(GL_INVALID_ENUM, kInvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003774 return false;
3775 }
3776 if (!isPow2(mask + 1))
3777 {
Jamie Madille0472f32018-11-27 16:32:45 -05003778 context->validationError(GL_INVALID_VALUE, kInvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003779 return false;
3780 }
3781
3782 return true;
3783}
3784
Jamie Madill007530e2017-12-28 14:27:04 -05003785bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
3786 GLsizei numPaths,
3787 GLenum pathNameType,
3788 const void *paths,
3789 GLuint pathBase,
3790 GLint reference,
3791 GLuint mask,
3792 GLenum coverMode,
3793 GLenum transformType,
3794 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003795{
3796 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3797 transformType, transformValues))
3798 return false;
3799
3800 switch (coverMode)
3801 {
3802 case GL_CONVEX_HULL_CHROMIUM:
3803 case GL_BOUNDING_BOX_CHROMIUM:
3804 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3805 break;
3806 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003807 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003808 return false;
3809 }
3810
3811 return true;
3812}
3813
Jamie Madill007530e2017-12-28 14:27:04 -05003814bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
3815 GLuint program,
3816 GLint location,
3817 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003818{
3819 if (!context->getExtensions().pathRendering)
3820 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003821 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003822 return false;
3823 }
3824
3825 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3826 if (location >= MaxLocation)
3827 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003828 context->validationError(GL_INVALID_VALUE, kInvalidVaryingLocation);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003829 return false;
3830 }
3831
Jamie Madill44a6fbf2018-10-02 13:38:56 -04003832 const auto *programObject = context->getProgramNoResolveLink(program);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003833 if (!programObject)
3834 {
Jamie Madille0472f32018-11-27 16:32:45 -05003835 context->validationError(GL_INVALID_OPERATION, kProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003836 return false;
3837 }
3838
3839 if (!name)
3840 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003841 context->validationError(GL_INVALID_VALUE, kMissingName);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003842 return false;
3843 }
3844
3845 if (angle::BeginsWith(name, "gl_"))
3846 {
Jamie Madille0472f32018-11-27 16:32:45 -05003847 context->validationError(GL_INVALID_OPERATION, kNameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003848 return false;
3849 }
3850
3851 return true;
3852}
3853
Jamie Madill007530e2017-12-28 14:27:04 -05003854bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
3855 GLuint program,
3856 GLint location,
3857 GLenum genMode,
3858 GLint components,
3859 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003860{
3861 if (!context->getExtensions().pathRendering)
3862 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003863 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003864 return false;
3865 }
3866
Jamie Madill44a6fbf2018-10-02 13:38:56 -04003867 const auto *programObject = context->getProgramResolveLink(program);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003868 if (!programObject || programObject->isFlaggedForDeletion())
3869 {
Jamie Madille0472f32018-11-27 16:32:45 -05003870 context->validationError(GL_INVALID_OPERATION, kProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003871 return false;
3872 }
3873
3874 if (!programObject->isLinked())
3875 {
Jamie Madille0472f32018-11-27 16:32:45 -05003876 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003877 return false;
3878 }
3879
3880 switch (genMode)
3881 {
3882 case GL_NONE:
3883 if (components != 0)
3884 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003885 context->validationError(GL_INVALID_VALUE, kInvalidComponents);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003886 return false;
3887 }
3888 break;
3889
3890 case GL_OBJECT_LINEAR_CHROMIUM:
3891 case GL_EYE_LINEAR_CHROMIUM:
3892 case GL_CONSTANT_CHROMIUM:
3893 if (components < 1 || components > 4)
3894 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003895 context->validationError(GL_INVALID_VALUE, kInvalidComponents);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003896 return false;
3897 }
3898 if (!coeffs)
3899 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003900 context->validationError(GL_INVALID_VALUE, kInvalidPathCoefficientsArray);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003901 return false;
3902 }
3903 break;
3904
3905 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003906 context->validationError(GL_INVALID_ENUM, kInvalidPathGenMode);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003907 return false;
3908 }
3909
3910 // If the location is -1 then the command is silently ignored
3911 // and no further validation is needed.
3912 if (location == -1)
3913 return true;
3914
jchen103fd614d2018-08-13 12:21:58 +08003915 const auto &binding = programObject->getFragmentInputBindingInfo(location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003916
3917 if (!binding.valid)
3918 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003919 context->validationError(GL_INVALID_OPERATION, kInvalidFragmentInputBinding);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003920 return false;
3921 }
3922
3923 if (binding.type != GL_NONE)
3924 {
3925 GLint expectedComponents = 0;
3926 switch (binding.type)
3927 {
3928 case GL_FLOAT:
3929 expectedComponents = 1;
3930 break;
3931 case GL_FLOAT_VEC2:
3932 expectedComponents = 2;
3933 break;
3934 case GL_FLOAT_VEC3:
3935 expectedComponents = 3;
3936 break;
3937 case GL_FLOAT_VEC4:
3938 expectedComponents = 4;
3939 break;
3940 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003941 context->validationError(GL_INVALID_OPERATION, kFragmentInputTypeNotFloatingPoint);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003942 return false;
3943 }
3944 if (expectedComponents != components && genMode != GL_NONE)
3945 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003946 context->validationError(GL_INVALID_OPERATION, kInvalidPathComponents);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003947 return false;
3948 }
3949 }
3950 return true;
3951}
3952
Geoff Lang97073d12016-04-20 10:42:34 -07003953bool ValidateCopyTextureCHROMIUM(Context *context,
3954 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003955 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003956 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003957 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003958 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003959 GLint internalFormat,
3960 GLenum destType,
3961 GLboolean unpackFlipY,
3962 GLboolean unpackPremultiplyAlpha,
3963 GLboolean unpackUnmultiplyAlpha)
3964{
3965 if (!context->getExtensions().copyTexture)
3966 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003967 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang97073d12016-04-20 10:42:34 -07003968 return false;
3969 }
3970
Geoff Lang4f0e0032017-05-01 16:04:35 -04003971 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003972 if (source == nullptr)
3973 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003974 context->validationError(GL_INVALID_VALUE, kInvalidSourceTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07003975 return false;
3976 }
3977
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003978 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003979 {
Jamie Madille0472f32018-11-27 16:32:45 -05003980 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003981 return false;
3982 }
3983
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003984 TextureType sourceType = source->getType();
3985 ASSERT(sourceType != TextureType::CubeMap);
3986 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003987
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003988 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07003989 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003990 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureLevel);
Geoff Lang97073d12016-04-20 10:42:34 -07003991 return false;
3992 }
3993
Geoff Lang4f0e0032017-05-01 16:04:35 -04003994 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
3995 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
3996 if (sourceWidth == 0 || sourceHeight == 0)
3997 {
Jamie Madille0472f32018-11-27 16:32:45 -05003998 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003999 return false;
4000 }
4001
4002 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
4003 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004004 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004005 context->validationError(GL_INVALID_OPERATION, kInvalidSourceTextureInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004006 return false;
4007 }
4008
Geoff Lang63458a32017-10-30 15:16:53 -04004009 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4010 {
Jamie Madille0472f32018-11-27 16:32:45 -05004011 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Lang63458a32017-10-30 15:16:53 -04004012 return false;
4013 }
4014
Geoff Lang4f0e0032017-05-01 16:04:35 -04004015 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004016 if (dest == nullptr)
4017 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004018 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07004019 return false;
4020 }
4021
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004022 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004023 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004024 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTextureType);
Geoff Lang97073d12016-04-20 10:42:34 -07004025 return false;
4026 }
4027
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004028 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08004029 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004030 {
Jamie Madille0472f32018-11-27 16:32:45 -05004031 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004032 return false;
4033 }
4034
Geoff Lang97073d12016-04-20 10:42:34 -07004035 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
4036 {
Geoff Lang97073d12016-04-20 10:42:34 -07004037 return false;
4038 }
4039
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004040 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04004041 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004042 context->validationError(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004043 return false;
4044 }
4045
Geoff Lang97073d12016-04-20 10:42:34 -07004046 if (dest->getImmutableFormat())
4047 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004048 context->validationError(GL_INVALID_OPERATION, kDestinationImmutable);
Geoff Lang97073d12016-04-20 10:42:34 -07004049 return false;
4050 }
4051
4052 return true;
4053}
4054
4055bool ValidateCopySubTextureCHROMIUM(Context *context,
4056 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04004057 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004058 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07004059 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04004060 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07004061 GLint xoffset,
4062 GLint yoffset,
4063 GLint x,
4064 GLint y,
4065 GLsizei width,
4066 GLsizei height,
4067 GLboolean unpackFlipY,
4068 GLboolean unpackPremultiplyAlpha,
4069 GLboolean unpackUnmultiplyAlpha)
4070{
4071 if (!context->getExtensions().copyTexture)
4072 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004073 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang97073d12016-04-20 10:42:34 -07004074 return false;
4075 }
4076
Geoff Lang4f0e0032017-05-01 16:04:35 -04004077 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004078 if (source == nullptr)
4079 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004080 context->validationError(GL_INVALID_VALUE, kInvalidSourceTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07004081 return false;
4082 }
4083
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004084 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004085 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004086 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureType);
Geoff Lang97073d12016-04-20 10:42:34 -07004087 return false;
4088 }
4089
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004090 TextureType sourceType = source->getType();
4091 ASSERT(sourceType != TextureType::CubeMap);
4092 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004093
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004094 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004095 {
Jamie Madille0472f32018-11-27 16:32:45 -05004096 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004097 return false;
4098 }
4099
4100 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4101 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004102 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004103 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureLevel);
Geoff Lang97073d12016-04-20 10:42:34 -07004104 return false;
4105 }
4106
4107 if (x < 0 || y < 0)
4108 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004109 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004110 return false;
4111 }
4112
4113 if (width < 0 || height < 0)
4114 {
Jamie Madille0472f32018-11-27 16:32:45 -05004115 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004116 return false;
4117 }
4118
Geoff Lang4f0e0032017-05-01 16:04:35 -04004119 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4120 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004121 {
Jamie Madille0472f32018-11-27 16:32:45 -05004122 context->validationError(GL_INVALID_VALUE, kSourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004123 return false;
4124 }
4125
Geoff Lang4f0e0032017-05-01 16:04:35 -04004126 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4127 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004128 {
Jamie Madille0472f32018-11-27 16:32:45 -05004129 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004130 return false;
4131 }
4132
Geoff Lang63458a32017-10-30 15:16:53 -04004133 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4134 {
Jamie Madille0472f32018-11-27 16:32:45 -05004135 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Lang63458a32017-10-30 15:16:53 -04004136 return false;
4137 }
4138
Geoff Lang4f0e0032017-05-01 16:04:35 -04004139 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004140 if (dest == nullptr)
4141 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004142 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07004143 return false;
4144 }
4145
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004146 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004147 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004148 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTextureType);
Geoff Lang97073d12016-04-20 10:42:34 -07004149 return false;
4150 }
4151
Brandon Jones28783792018-03-05 09:37:32 -08004152 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4153 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004154 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004155 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Lang97073d12016-04-20 10:42:34 -07004156 return false;
4157 }
4158
Geoff Lang4f0e0032017-05-01 16:04:35 -04004159 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4160 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004161 context->validationError(GL_INVALID_OPERATION, kDestinationLevelNotDefined);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004162 return false;
4163 }
4164
4165 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4166 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004167 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004168 context->validationError(GL_INVALID_OPERATION, kInvalidFormatCombination);
Geoff Lang97073d12016-04-20 10:42:34 -07004169 return false;
4170 }
4171
4172 if (xoffset < 0 || yoffset < 0)
4173 {
Jamie Madille0472f32018-11-27 16:32:45 -05004174 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004175 return false;
4176 }
4177
Geoff Lang4f0e0032017-05-01 16:04:35 -04004178 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4179 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004180 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004181 context->validationError(GL_INVALID_VALUE, kOffsetOverflow);
Geoff Lang97073d12016-04-20 10:42:34 -07004182 return false;
4183 }
4184
4185 return true;
4186}
4187
Geoff Lang47110bf2016-04-20 11:13:22 -07004188bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4189{
4190 if (!context->getExtensions().copyCompressedTexture)
4191 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004192 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang47110bf2016-04-20 11:13:22 -07004193 return false;
4194 }
4195
4196 const gl::Texture *source = context->getTexture(sourceId);
4197 if (source == nullptr)
4198 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004199 context->validationError(GL_INVALID_VALUE, kInvalidSourceTexture);
Geoff Lang47110bf2016-04-20 11:13:22 -07004200 return false;
4201 }
4202
Corentin Wallez99d492c2018-02-27 15:17:10 -05004203 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004204 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004205 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureType);
Geoff Lang47110bf2016-04-20 11:13:22 -07004206 return false;
4207 }
4208
Corentin Wallez99d492c2018-02-27 15:17:10 -05004209 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4210 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004211 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004212 context->validationError(GL_INVALID_VALUE, kSourceTextureLevelZeroDefined);
Geoff Lang47110bf2016-04-20 11:13:22 -07004213 return false;
4214 }
4215
Corentin Wallez99d492c2018-02-27 15:17:10 -05004216 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004217 if (!sourceFormat.info->compressed)
4218 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004219 context->validationError(GL_INVALID_OPERATION, kSourceTextureMustBeCompressed);
Geoff Lang47110bf2016-04-20 11:13:22 -07004220 return false;
4221 }
4222
4223 const gl::Texture *dest = context->getTexture(destId);
4224 if (dest == nullptr)
4225 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004226 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTexture);
Geoff Lang47110bf2016-04-20 11:13:22 -07004227 return false;
4228 }
4229
Corentin Wallez99d492c2018-02-27 15:17:10 -05004230 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004231 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004232 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTextureType);
Geoff Lang47110bf2016-04-20 11:13:22 -07004233 return false;
4234 }
4235
4236 if (dest->getImmutableFormat())
4237 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004238 context->validationError(GL_INVALID_OPERATION, kDestinationImmutable);
Geoff Lang47110bf2016-04-20 11:13:22 -07004239 return false;
4240 }
4241
4242 return true;
4243}
4244
Jiawei Shao385b3e02018-03-21 09:43:28 +08004245bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004246{
4247 switch (type)
4248 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004249 case ShaderType::Vertex:
4250 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004251 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004252
Jiawei Shao385b3e02018-03-21 09:43:28 +08004253 case ShaderType::Compute:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004254 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004255 {
Jamie Madille0472f32018-11-27 16:32:45 -05004256 context->validationError(GL_INVALID_ENUM, kES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004257 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004258 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004259 break;
4260
Jiawei Shao385b3e02018-03-21 09:43:28 +08004261 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004262 if (!context->getExtensions().geometryShader)
4263 {
Jamie Madille0472f32018-11-27 16:32:45 -05004264 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
Jiawei Shao89be29a2017-11-06 14:36:45 +08004265 return false;
4266 }
4267 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004268 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004269 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004270 return false;
4271 }
Jamie Madill29639852016-09-02 15:00:09 -04004272
4273 return true;
4274}
4275
Jamie Madill5b772312018-03-08 20:28:32 -05004276bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004277 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004278 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004279 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004280 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004281{
4282 if (size < 0)
4283 {
Jamie Madille0472f32018-11-27 16:32:45 -05004284 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004285 return false;
4286 }
4287
4288 switch (usage)
4289 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004290 case BufferUsage::StreamDraw:
4291 case BufferUsage::StaticDraw:
4292 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004293 break;
4294
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004295 case BufferUsage::StreamRead:
4296 case BufferUsage::StaticRead:
4297 case BufferUsage::DynamicRead:
4298 case BufferUsage::StreamCopy:
4299 case BufferUsage::StaticCopy:
4300 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004301 if (context->getClientMajorVersion() < 3)
4302 {
Jamie Madille0472f32018-11-27 16:32:45 -05004303 context->validationError(GL_INVALID_ENUM, kInvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004304 return false;
4305 }
4306 break;
4307
4308 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004309 context->validationError(GL_INVALID_ENUM, kInvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004310 return false;
4311 }
4312
Corentin Walleze4477002017-12-01 14:39:58 -05004313 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004314 {
Jamie Madille0472f32018-11-27 16:32:45 -05004315 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004316 return false;
4317 }
4318
4319 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4320
4321 if (!buffer)
4322 {
Jamie Madille0472f32018-11-27 16:32:45 -05004323 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004324 return false;
4325 }
4326
James Darpiniane8a93c62018-01-04 18:02:24 -08004327 if (context->getExtensions().webglCompatibility &&
4328 buffer->isBoundForTransformFeedbackAndOtherUse())
4329 {
Jamie Madille0472f32018-11-27 16:32:45 -05004330 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08004331 return false;
4332 }
4333
Jamie Madill29639852016-09-02 15:00:09 -04004334 return true;
4335}
4336
Jamie Madill5b772312018-03-08 20:28:32 -05004337bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004338 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004339 GLintptr offset,
4340 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004341 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004342{
Brandon Jones6cad5662017-06-14 13:25:13 -07004343 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004344 {
Jamie Madille0472f32018-11-27 16:32:45 -05004345 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Brandon Jones6cad5662017-06-14 13:25:13 -07004346 return false;
4347 }
4348
4349 if (offset < 0)
4350 {
Jamie Madille0472f32018-11-27 16:32:45 -05004351 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004352 return false;
4353 }
4354
Corentin Walleze4477002017-12-01 14:39:58 -05004355 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004356 {
Jamie Madille0472f32018-11-27 16:32:45 -05004357 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004358 return false;
4359 }
4360
4361 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4362
4363 if (!buffer)
4364 {
Jamie Madille0472f32018-11-27 16:32:45 -05004365 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004366 return false;
4367 }
4368
4369 if (buffer->isMapped())
4370 {
Jamie Madille0472f32018-11-27 16:32:45 -05004371 context->validationError(GL_INVALID_OPERATION, kBufferMapped);
Jamie Madill29639852016-09-02 15:00:09 -04004372 return false;
4373 }
4374
James Darpiniane8a93c62018-01-04 18:02:24 -08004375 if (context->getExtensions().webglCompatibility &&
4376 buffer->isBoundForTransformFeedbackAndOtherUse())
4377 {
Jamie Madille0472f32018-11-27 16:32:45 -05004378 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08004379 return false;
4380 }
4381
Jamie Madill29639852016-09-02 15:00:09 -04004382 // Check for possible overflow of size + offset
4383 angle::CheckedNumeric<size_t> checkedSize(size);
4384 checkedSize += offset;
4385 if (!checkedSize.IsValid())
4386 {
Jamie Madille0472f32018-11-27 16:32:45 -05004387 context->validationError(GL_INVALID_VALUE, kParamOverflow);
Jamie Madill29639852016-09-02 15:00:09 -04004388 return false;
4389 }
4390
4391 if (size + offset > buffer->getSize())
4392 {
Jamie Madille0472f32018-11-27 16:32:45 -05004393 context->validationError(GL_INVALID_VALUE, kInsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004394 return false;
4395 }
4396
Martin Radev4c4c8e72016-08-04 12:25:34 +03004397 return true;
4398}
4399
Geoff Lang111a99e2017-10-17 10:58:41 -04004400bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004401{
Geoff Langc339c4e2016-11-29 10:37:36 -05004402 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004403 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004404 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langc287ea62016-09-16 14:46:51 -04004405 return false;
4406 }
4407
Geoff Lang111a99e2017-10-17 10:58:41 -04004408 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004409 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004410 context->validationError(GL_INVALID_OPERATION, kExtensionNotRequestable);
Geoff Langc287ea62016-09-16 14:46:51 -04004411 return false;
4412 }
4413
4414 return true;
4415}
4416
Jamie Madill5b772312018-03-08 20:28:32 -05004417bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004418{
Lingfeng Yang038dd532018-03-29 17:31:52 -07004419 if (context->getClientMajorVersion() < 2)
4420 {
4421 return ValidateMultitextureUnit(context, texture);
4422 }
4423
Jamie Madillef300b12016-10-07 15:12:09 -04004424 if (texture < GL_TEXTURE0 ||
4425 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4426 {
Jamie Madille0472f32018-11-27 16:32:45 -05004427 context->validationError(GL_INVALID_ENUM, kInvalidCombinedImageUnit);
Jamie Madillef300b12016-10-07 15:12:09 -04004428 return false;
4429 }
4430
4431 return true;
4432}
4433
Jamie Madill5b772312018-03-08 20:28:32 -05004434bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004435{
4436 Program *programObject = GetValidProgram(context, program);
4437 if (!programObject)
4438 {
4439 return false;
4440 }
4441
4442 Shader *shaderObject = GetValidShader(context, shader);
4443 if (!shaderObject)
4444 {
4445 return false;
4446 }
4447
Jiawei Shao385b3e02018-03-21 09:43:28 +08004448 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04004449 {
Jamie Madille0472f32018-11-27 16:32:45 -05004450 context->validationError(GL_INVALID_OPERATION, kShaderAttachmentHasShader);
Jiawei Shao385b3e02018-03-21 09:43:28 +08004451 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04004452 }
4453
4454 return true;
4455}
4456
Jamie Madill5b772312018-03-08 20:28:32 -05004457bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004458{
4459 if (index >= MAX_VERTEX_ATTRIBS)
4460 {
Jamie Madille0472f32018-11-27 16:32:45 -05004461 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004462 return false;
4463 }
4464
4465 if (strncmp(name, "gl_", 3) == 0)
4466 {
Jamie Madille0472f32018-11-27 16:32:45 -05004467 context->validationError(GL_INVALID_OPERATION, kNameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004468 return false;
4469 }
4470
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004471 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004472 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004473 const size_t length = strlen(name);
4474
4475 if (!IsValidESSLString(name, length))
4476 {
4477 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4478 // for shader-related entry points
Jamie Madille0472f32018-11-27 16:32:45 -05004479 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004480 return false;
4481 }
4482
4483 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4484 {
4485 return false;
4486 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004487 }
4488
Jamie Madill01a80ee2016-11-07 12:06:18 -05004489 return GetValidProgram(context, program) != nullptr;
4490}
4491
Jamie Madill5b772312018-03-08 20:28:32 -05004492bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004493{
Geoff Lange8afa902017-09-27 15:00:43 -04004494 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004495 {
Jamie Madille0472f32018-11-27 16:32:45 -05004496 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004497 return false;
4498 }
4499
4500 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4501 !context->isFramebufferGenerated(framebuffer))
4502 {
Jamie Madille0472f32018-11-27 16:32:45 -05004503 context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004504 return false;
4505 }
4506
4507 return true;
4508}
4509
Jamie Madill5b772312018-03-08 20:28:32 -05004510bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004511{
4512 if (target != GL_RENDERBUFFER)
4513 {
Jamie Madille0472f32018-11-27 16:32:45 -05004514 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004515 return false;
4516 }
4517
4518 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4519 !context->isRenderbufferGenerated(renderbuffer))
4520 {
Jamie Madille0472f32018-11-27 16:32:45 -05004521 context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004522 return false;
4523 }
4524
4525 return true;
4526}
4527
Jamie Madill5b772312018-03-08 20:28:32 -05004528static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004529{
4530 switch (mode)
4531 {
4532 case GL_FUNC_ADD:
4533 case GL_FUNC_SUBTRACT:
4534 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004535 return true;
4536
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004537 case GL_MIN:
4538 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004539 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004540
4541 default:
4542 return false;
4543 }
4544}
4545
Jamie Madill5b772312018-03-08 20:28:32 -05004546bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004547{
4548 return true;
4549}
4550
Jamie Madill5b772312018-03-08 20:28:32 -05004551bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004552{
Geoff Lang50cac572017-09-26 17:37:43 -04004553 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004554 {
Jamie Madille0472f32018-11-27 16:32:45 -05004555 context->validationError(GL_INVALID_ENUM, kInvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004556 return false;
4557 }
4558
4559 return true;
4560}
4561
Jamie Madill5b772312018-03-08 20:28:32 -05004562bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004563{
Geoff Lang50cac572017-09-26 17:37:43 -04004564 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004565 {
Jamie Madille0472f32018-11-27 16:32:45 -05004566 context->validationError(GL_INVALID_ENUM, kInvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004567 return false;
4568 }
4569
Geoff Lang50cac572017-09-26 17:37:43 -04004570 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004571 {
Jamie Madille0472f32018-11-27 16:32:45 -05004572 context->validationError(GL_INVALID_ENUM, kInvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004573 return false;
4574 }
4575
4576 return true;
4577}
4578
Jamie Madill5b772312018-03-08 20:28:32 -05004579bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004580{
4581 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4582}
4583
Jamie Madill5b772312018-03-08 20:28:32 -05004584bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004585 GLenum srcRGB,
4586 GLenum dstRGB,
4587 GLenum srcAlpha,
4588 GLenum dstAlpha)
4589{
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004590 if (!ValidSrcBlendFunc(context, srcRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004591 {
Jamie Madille0472f32018-11-27 16:32:45 -05004592 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004593 return false;
4594 }
4595
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004596 if (!ValidDstBlendFunc(context, dstRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004597 {
Jamie Madille0472f32018-11-27 16:32:45 -05004598 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004599 return false;
4600 }
4601
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004602 if (!ValidSrcBlendFunc(context, srcAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004603 {
Jamie Madille0472f32018-11-27 16:32:45 -05004604 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004605 return false;
4606 }
4607
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004608 if (!ValidDstBlendFunc(context, dstAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004609 {
Jamie Madille0472f32018-11-27 16:32:45 -05004610 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004611 return false;
4612 }
4613
Frank Henigman146e8a12017-03-02 23:22:37 -05004614 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4615 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004616 {
4617 bool constantColorUsed =
4618 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4619 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4620
4621 bool constantAlphaUsed =
4622 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4623 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4624
4625 if (constantColorUsed && constantAlphaUsed)
4626 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004627 if (context->getExtensions().webglCompatibility)
4628 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004629 context->validationError(GL_INVALID_OPERATION, kInvalidConstantColor);
4630 return false;
Frank Henigman146e8a12017-03-02 23:22:37 -05004631 }
Jamie Madillc3e37312018-11-30 15:25:39 -05004632
4633 WARN() << kConstantColorAlphaLimitation;
4634 context->validationError(GL_INVALID_OPERATION, kConstantColorAlphaLimitation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004635 return false;
4636 }
4637 }
4638
4639 return true;
4640}
4641
Geoff Langc339c4e2016-11-29 10:37:36 -05004642bool ValidateGetString(Context *context, GLenum name)
4643{
4644 switch (name)
4645 {
4646 case GL_VENDOR:
4647 case GL_RENDERER:
4648 case GL_VERSION:
4649 case GL_SHADING_LANGUAGE_VERSION:
4650 case GL_EXTENSIONS:
4651 break;
4652
4653 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4654 if (!context->getExtensions().requestExtension)
4655 {
Jamie Madille0472f32018-11-27 16:32:45 -05004656 context->validationError(GL_INVALID_ENUM, kInvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004657 return false;
4658 }
4659 break;
4660
4661 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004662 context->validationError(GL_INVALID_ENUM, kInvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004663 return false;
4664 }
4665
4666 return true;
4667}
4668
Jamie Madill5b772312018-03-08 20:28:32 -05004669bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004670{
4671 if (width <= 0.0f || isNaN(width))
4672 {
Jamie Madille0472f32018-11-27 16:32:45 -05004673 context->validationError(GL_INVALID_VALUE, kInvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004674 return false;
4675 }
4676
4677 return true;
4678}
4679
Jamie Madill5b772312018-03-08 20:28:32 -05004680bool ValidateVertexAttribPointer(Context *context,
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004681 GLuint index,
4682 GLint size,
4683 GLenum type,
4684 GLboolean normalized,
4685 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004686 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004687{
Shao80957d92017-02-20 21:25:59 +08004688 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004689 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004690 return false;
4691 }
4692
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004693 if (stride < 0)
4694 {
Jamie Madille0472f32018-11-27 16:32:45 -05004695 context->validationError(GL_INVALID_VALUE, kNegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004696 return false;
4697 }
4698
Shao80957d92017-02-20 21:25:59 +08004699 const Caps &caps = context->getCaps();
4700 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004701 {
Shao80957d92017-02-20 21:25:59 +08004702 if (stride > caps.maxVertexAttribStride)
4703 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004704 context->validationError(GL_INVALID_VALUE, kExceedsMaxVertexAttribStride);
Shao80957d92017-02-20 21:25:59 +08004705 return false;
4706 }
4707
4708 if (index >= caps.maxVertexAttribBindings)
4709 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004710 context->validationError(GL_INVALID_VALUE, kExceedsMaxVertexAttribBindings);
Shao80957d92017-02-20 21:25:59 +08004711 return false;
4712 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004713 }
4714
4715 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4716 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4717 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4718 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004719 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4720 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004721 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4722 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004723 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004724 context->validationError(GL_INVALID_OPERATION, kClientDataInVertexArray);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004725 return false;
4726 }
4727
4728 if (context->getExtensions().webglCompatibility)
4729 {
4730 // WebGL 1.0 [Section 6.14] Fixed point support
4731 // The WebGL API does not support the GL_FIXED data type.
4732 if (type == GL_FIXED)
4733 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004734 context->validationError(GL_INVALID_ENUM, kFixedNotInWebGL);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004735 return false;
4736 }
4737
Geoff Lang2d62ab72017-03-23 16:54:40 -04004738 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004739 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004740 return false;
4741 }
4742 }
4743
4744 return true;
4745}
4746
Jamie Madill5b772312018-03-08 20:28:32 -05004747bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004748{
4749 if (context->getExtensions().webglCompatibility && zNear > zFar)
4750 {
Jamie Madille0472f32018-11-27 16:32:45 -05004751 context->validationError(GL_INVALID_OPERATION, kInvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004752 return false;
4753 }
4754
4755 return true;
4756}
4757
Jamie Madill5b772312018-03-08 20:28:32 -05004758bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004759 GLenum target,
4760 GLenum internalformat,
4761 GLsizei width,
4762 GLsizei height)
4763{
4764 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4765 height);
4766}
4767
Jamie Madill5b772312018-03-08 20:28:32 -05004768bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004769 GLenum target,
4770 GLsizei samples,
4771 GLenum internalformat,
4772 GLsizei width,
4773 GLsizei height)
4774{
4775 if (!context->getExtensions().framebufferMultisample)
4776 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004777 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madille8fb6402017-02-14 17:56:40 -05004778 return false;
4779 }
4780
4781 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
Jamie Madill610640f2018-11-21 17:28:41 -05004782 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_VALUE is
Jamie Madille8fb6402017-02-14 17:56:40 -05004783 // generated.
4784 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4785 {
Jamie Madille0472f32018-11-27 16:32:45 -05004786 context->validationError(GL_INVALID_VALUE, kSamplesOutOfRange);
Jamie Madille8fb6402017-02-14 17:56:40 -05004787 return false;
4788 }
4789
4790 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4791 // the specified storage. This is different than ES 3.0 in which a sample number higher
4792 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4793 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4794 if (context->getClientMajorVersion() >= 3)
4795 {
4796 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4797 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4798 {
Jamie Madille0472f32018-11-27 16:32:45 -05004799 context->validationError(GL_OUT_OF_MEMORY, kSamplesOutOfRange);
Jamie Madille8fb6402017-02-14 17:56:40 -05004800 return false;
4801 }
4802 }
4803
4804 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4805 width, height);
4806}
4807
Jamie Madill5b772312018-03-08 20:28:32 -05004808bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004809{
Geoff Lange8afa902017-09-27 15:00:43 -04004810 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004811 {
Jamie Madille0472f32018-11-27 16:32:45 -05004812 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004813 return false;
4814 }
4815
4816 return true;
4817}
4818
Jamie Madill5b772312018-03-08 20:28:32 -05004819bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004820{
4821 return true;
4822}
4823
Jamie Madill5b772312018-03-08 20:28:32 -05004824bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004825{
4826 return true;
4827}
4828
Jamie Madill5b772312018-03-08 20:28:32 -05004829bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004830{
4831 return true;
4832}
4833
Jamie Madill5b772312018-03-08 20:28:32 -05004834bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004835 GLboolean red,
4836 GLboolean green,
4837 GLboolean blue,
4838 GLboolean alpha)
4839{
4840 return true;
4841}
4842
Jamie Madill5b772312018-03-08 20:28:32 -05004843bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004844{
4845 return true;
4846}
4847
Jamie Madill5b772312018-03-08 20:28:32 -05004848bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004849{
4850 return true;
4851}
4852
Jamie Madill5b772312018-03-08 20:28:32 -05004853bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004854{
4855 switch (mode)
4856 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004857 case CullFaceMode::Front:
4858 case CullFaceMode::Back:
4859 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004860 break;
4861
4862 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004863 context->validationError(GL_INVALID_ENUM, kInvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004864 return false;
4865 }
4866
4867 return true;
4868}
4869
Jamie Madill5b772312018-03-08 20:28:32 -05004870bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004871{
4872 if (program == 0)
4873 {
4874 return false;
4875 }
4876
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004877 if (!context->getProgramResolveLink(program))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004878 {
4879 if (context->getShader(program))
4880 {
Jamie Madille0472f32018-11-27 16:32:45 -05004881 context->validationError(GL_INVALID_OPERATION, kExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004882 return false;
4883 }
4884 else
4885 {
Jamie Madille0472f32018-11-27 16:32:45 -05004886 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004887 return false;
4888 }
4889 }
4890
4891 return true;
4892}
4893
Jamie Madill5b772312018-03-08 20:28:32 -05004894bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004895{
4896 if (shader == 0)
4897 {
4898 return false;
4899 }
4900
4901 if (!context->getShader(shader))
4902 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004903 if (context->getProgramResolveLink(shader))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004904 {
Jamie Madille0472f32018-11-27 16:32:45 -05004905 context->validationError(GL_INVALID_OPERATION, kInvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004906 return false;
4907 }
4908 else
4909 {
Jamie Madille0472f32018-11-27 16:32:45 -05004910 context->validationError(GL_INVALID_VALUE, kExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004911 return false;
4912 }
4913 }
4914
4915 return true;
4916}
4917
Jamie Madill5b772312018-03-08 20:28:32 -05004918bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004919{
4920 switch (func)
4921 {
4922 case GL_NEVER:
4923 case GL_ALWAYS:
4924 case GL_LESS:
4925 case GL_LEQUAL:
4926 case GL_EQUAL:
4927 case GL_GREATER:
4928 case GL_GEQUAL:
4929 case GL_NOTEQUAL:
4930 break;
4931
4932 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004933 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004934 return false;
4935 }
4936
4937 return true;
4938}
4939
Jamie Madill5b772312018-03-08 20:28:32 -05004940bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004941{
4942 return true;
4943}
4944
Jamie Madill5b772312018-03-08 20:28:32 -05004945bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004946{
4947 Program *programObject = GetValidProgram(context, program);
4948 if (!programObject)
4949 {
4950 return false;
4951 }
4952
4953 Shader *shaderObject = GetValidShader(context, shader);
4954 if (!shaderObject)
4955 {
4956 return false;
4957 }
4958
Jiawei Shao385b3e02018-03-21 09:43:28 +08004959 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04004960 if (attachedShader != shaderObject)
4961 {
Jamie Madille0472f32018-11-27 16:32:45 -05004962 context->validationError(GL_INVALID_OPERATION, kShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004963 return false;
4964 }
4965
4966 return true;
4967}
4968
Jamie Madill5b772312018-03-08 20:28:32 -05004969bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004970{
4971 if (index >= MAX_VERTEX_ATTRIBS)
4972 {
Jamie Madille0472f32018-11-27 16:32:45 -05004973 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004974 return false;
4975 }
4976
4977 return true;
4978}
4979
Jamie Madill5b772312018-03-08 20:28:32 -05004980bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004981{
4982 if (index >= MAX_VERTEX_ATTRIBS)
4983 {
Jamie Madille0472f32018-11-27 16:32:45 -05004984 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004985 return false;
4986 }
4987
4988 return true;
4989}
4990
Jamie Madill5b772312018-03-08 20:28:32 -05004991bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004992{
4993 return true;
4994}
4995
Jamie Madill5b772312018-03-08 20:28:32 -05004996bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004997{
4998 return true;
4999}
5000
Jamie Madill5b772312018-03-08 20:28:32 -05005001bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005002{
5003 switch (mode)
5004 {
5005 case GL_CW:
5006 case GL_CCW:
5007 break;
5008 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005009 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005010 return false;
5011 }
5012
5013 return true;
5014}
5015
Jamie Madill5b772312018-03-08 20:28:32 -05005016bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005017 GLuint program,
5018 GLuint index,
5019 GLsizei bufsize,
5020 GLsizei *length,
5021 GLint *size,
5022 GLenum *type,
5023 GLchar *name)
5024{
5025 if (bufsize < 0)
5026 {
Jamie Madille0472f32018-11-27 16:32:45 -05005027 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005028 return false;
5029 }
5030
5031 Program *programObject = GetValidProgram(context, program);
5032
5033 if (!programObject)
5034 {
5035 return false;
5036 }
5037
5038 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5039 {
Jamie Madille0472f32018-11-27 16:32:45 -05005040 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005041 return false;
5042 }
5043
5044 return true;
5045}
5046
Jamie Madill5b772312018-03-08 20:28:32 -05005047bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005048 GLuint program,
5049 GLuint index,
5050 GLsizei bufsize,
5051 GLsizei *length,
5052 GLint *size,
5053 GLenum *type,
5054 GLchar *name)
5055{
5056 if (bufsize < 0)
5057 {
Jamie Madille0472f32018-11-27 16:32:45 -05005058 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005059 return false;
5060 }
5061
5062 Program *programObject = GetValidProgram(context, program);
5063
5064 if (!programObject)
5065 {
5066 return false;
5067 }
5068
5069 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5070 {
Jamie Madille0472f32018-11-27 16:32:45 -05005071 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005072 return false;
5073 }
5074
5075 return true;
5076}
5077
Jamie Madill5b772312018-03-08 20:28:32 -05005078bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005079 GLuint program,
5080 GLsizei maxcount,
5081 GLsizei *count,
5082 GLuint *shaders)
5083{
5084 if (maxcount < 0)
5085 {
Jamie Madille0472f32018-11-27 16:32:45 -05005086 context->validationError(GL_INVALID_VALUE, kNegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005087 return false;
5088 }
5089
5090 Program *programObject = GetValidProgram(context, program);
5091
5092 if (!programObject)
5093 {
5094 return false;
5095 }
5096
5097 return true;
5098}
5099
Jamie Madill5b772312018-03-08 20:28:32 -05005100bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005101{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005102 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5103 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005104 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005105 {
Jamie Madille0472f32018-11-27 16:32:45 -05005106 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005107 return false;
5108 }
5109
Jamie Madillc1d770e2017-04-13 17:31:24 -04005110 Program *programObject = GetValidProgram(context, program);
5111
5112 if (!programObject)
5113 {
Jamie Madille0472f32018-11-27 16:32:45 -05005114 context->validationError(GL_INVALID_OPERATION, kProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005115 return false;
5116 }
5117
5118 if (!programObject->isLinked())
5119 {
Jamie Madille0472f32018-11-27 16:32:45 -05005120 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005121 return false;
5122 }
5123
5124 return true;
5125}
5126
Jamie Madill5b772312018-03-08 20:28:32 -05005127bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005128{
5129 GLenum nativeType;
5130 unsigned int numParams = 0;
5131 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5132}
5133
Jamie Madill5b772312018-03-08 20:28:32 -05005134bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005135{
5136 return true;
5137}
5138
Jamie Madill5b772312018-03-08 20:28:32 -05005139bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005140{
5141 GLenum nativeType;
5142 unsigned int numParams = 0;
5143 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5144}
5145
Jamie Madill5b772312018-03-08 20:28:32 -05005146bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005147{
5148 GLenum nativeType;
5149 unsigned int numParams = 0;
5150 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5151}
5152
Jamie Madill5b772312018-03-08 20:28:32 -05005153bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005154 GLuint program,
5155 GLsizei bufsize,
5156 GLsizei *length,
5157 GLchar *infolog)
5158{
5159 if (bufsize < 0)
5160 {
Jamie Madille0472f32018-11-27 16:32:45 -05005161 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005162 return false;
5163 }
5164
5165 Program *programObject = GetValidProgram(context, program);
5166 if (!programObject)
5167 {
5168 return false;
5169 }
5170
5171 return true;
5172}
5173
Jamie Madill5b772312018-03-08 20:28:32 -05005174bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005175 GLuint shader,
5176 GLsizei bufsize,
5177 GLsizei *length,
5178 GLchar *infolog)
5179{
5180 if (bufsize < 0)
5181 {
Jamie Madille0472f32018-11-27 16:32:45 -05005182 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005183 return false;
5184 }
5185
5186 Shader *shaderObject = GetValidShader(context, shader);
5187 if (!shaderObject)
5188 {
5189 return false;
5190 }
5191
5192 return true;
5193}
5194
Jamie Madill5b772312018-03-08 20:28:32 -05005195bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005196 GLenum shadertype,
5197 GLenum precisiontype,
5198 GLint *range,
5199 GLint *precision)
5200{
5201 switch (shadertype)
5202 {
5203 case GL_VERTEX_SHADER:
5204 case GL_FRAGMENT_SHADER:
5205 break;
5206 case GL_COMPUTE_SHADER:
Jamie Madillc3e37312018-11-30 15:25:39 -05005207 context->validationError(GL_INVALID_OPERATION, kUnimplementedComputeShaderPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005208 return false;
5209 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005210 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005211 return false;
5212 }
5213
5214 switch (precisiontype)
5215 {
5216 case GL_LOW_FLOAT:
5217 case GL_MEDIUM_FLOAT:
5218 case GL_HIGH_FLOAT:
5219 case GL_LOW_INT:
5220 case GL_MEDIUM_INT:
5221 case GL_HIGH_INT:
5222 break;
5223
5224 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005225 context->validationError(GL_INVALID_ENUM, kInvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005226 return false;
5227 }
5228
5229 return true;
5230}
5231
Jamie Madill5b772312018-03-08 20:28:32 -05005232bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005233 GLuint shader,
5234 GLsizei bufsize,
5235 GLsizei *length,
5236 GLchar *source)
5237{
5238 if (bufsize < 0)
5239 {
Jamie Madille0472f32018-11-27 16:32:45 -05005240 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005241 return false;
5242 }
5243
5244 Shader *shaderObject = GetValidShader(context, shader);
5245 if (!shaderObject)
5246 {
5247 return false;
5248 }
5249
5250 return true;
5251}
5252
Jamie Madill5b772312018-03-08 20:28:32 -05005253bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005254{
5255 if (strstr(name, "gl_") == name)
5256 {
5257 return false;
5258 }
5259
Geoff Langfc32e8b2017-05-31 14:16:59 -04005260 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5261 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005262 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005263 {
Jamie Madille0472f32018-11-27 16:32:45 -05005264 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005265 return false;
5266 }
5267
Jamie Madillc1d770e2017-04-13 17:31:24 -04005268 Program *programObject = GetValidProgram(context, program);
5269
5270 if (!programObject)
5271 {
5272 return false;
5273 }
5274
5275 if (!programObject->isLinked())
5276 {
Jamie Madille0472f32018-11-27 16:32:45 -05005277 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005278 return false;
5279 }
5280
5281 return true;
5282}
5283
Jamie Madill5b772312018-03-08 20:28:32 -05005284bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005285{
5286 switch (mode)
5287 {
5288 case GL_FASTEST:
5289 case GL_NICEST:
5290 case GL_DONT_CARE:
5291 break;
5292
5293 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005294 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005295 return false;
5296 }
5297
5298 switch (target)
5299 {
5300 case GL_GENERATE_MIPMAP_HINT:
5301 break;
5302
Geoff Lange7bd2182017-06-16 16:13:13 -04005303 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5304 if (context->getClientVersion() < ES_3_0 &&
5305 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005306 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005307 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005308 return false;
5309 }
5310 break;
5311
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07005312 case GL_PERSPECTIVE_CORRECTION_HINT:
5313 case GL_POINT_SMOOTH_HINT:
5314 case GL_LINE_SMOOTH_HINT:
5315 case GL_FOG_HINT:
5316 if (context->getClientMajorVersion() >= 2)
5317 {
Jamie Madille0472f32018-11-27 16:32:45 -05005318 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07005319 return false;
5320 }
5321 break;
5322
Jamie Madillc1d770e2017-04-13 17:31:24 -04005323 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005324 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005325 return false;
5326 }
5327
5328 return true;
5329}
5330
Jamie Madill5b772312018-03-08 20:28:32 -05005331bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005332{
5333 return true;
5334}
5335
Jamie Madill5b772312018-03-08 20:28:32 -05005336bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005337{
5338 return true;
5339}
5340
Jamie Madill5b772312018-03-08 20:28:32 -05005341bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005342{
5343 return true;
5344}
5345
Jamie Madill5b772312018-03-08 20:28:32 -05005346bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005347{
5348 return true;
5349}
5350
Jamie Madill5b772312018-03-08 20:28:32 -05005351bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005352{
5353 return true;
5354}
5355
Jamie Madill5b772312018-03-08 20:28:32 -05005356bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005357{
5358 return true;
5359}
5360
Jamie Madill5b772312018-03-08 20:28:32 -05005361bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005362{
5363 if (context->getClientMajorVersion() < 3)
5364 {
5365 switch (pname)
5366 {
5367 case GL_UNPACK_IMAGE_HEIGHT:
5368 case GL_UNPACK_SKIP_IMAGES:
Jamie Madille0472f32018-11-27 16:32:45 -05005369 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005370 return false;
5371
5372 case GL_UNPACK_ROW_LENGTH:
5373 case GL_UNPACK_SKIP_ROWS:
5374 case GL_UNPACK_SKIP_PIXELS:
5375 if (!context->getExtensions().unpackSubimage)
5376 {
Jamie Madille0472f32018-11-27 16:32:45 -05005377 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005378 return false;
5379 }
5380 break;
5381
5382 case GL_PACK_ROW_LENGTH:
5383 case GL_PACK_SKIP_ROWS:
5384 case GL_PACK_SKIP_PIXELS:
5385 if (!context->getExtensions().packSubimage)
5386 {
Jamie Madille0472f32018-11-27 16:32:45 -05005387 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005388 return false;
5389 }
5390 break;
5391 }
5392 }
5393
5394 if (param < 0)
5395 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005396 context->validationError(GL_INVALID_VALUE, kNegativeParam);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005397 return false;
5398 }
5399
5400 switch (pname)
5401 {
5402 case GL_UNPACK_ALIGNMENT:
5403 if (param != 1 && param != 2 && param != 4 && param != 8)
5404 {
Jamie Madille0472f32018-11-27 16:32:45 -05005405 context->validationError(GL_INVALID_VALUE, kInvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005406 return false;
5407 }
5408 break;
5409
5410 case GL_PACK_ALIGNMENT:
5411 if (param != 1 && param != 2 && param != 4 && param != 8)
5412 {
Jamie Madille0472f32018-11-27 16:32:45 -05005413 context->validationError(GL_INVALID_VALUE, kInvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005414 return false;
5415 }
5416 break;
5417
5418 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005419 if (!context->getExtensions().packReverseRowOrder)
5420 {
Jamie Madille0472f32018-11-27 16:32:45 -05005421 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang000dab82017-09-27 14:27:07 -04005422 }
5423 break;
5424
Jamie Madillc1d770e2017-04-13 17:31:24 -04005425 case GL_UNPACK_ROW_LENGTH:
5426 case GL_UNPACK_IMAGE_HEIGHT:
5427 case GL_UNPACK_SKIP_IMAGES:
5428 case GL_UNPACK_SKIP_ROWS:
5429 case GL_UNPACK_SKIP_PIXELS:
5430 case GL_PACK_ROW_LENGTH:
5431 case GL_PACK_SKIP_ROWS:
5432 case GL_PACK_SKIP_PIXELS:
5433 break;
5434
5435 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005436 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005437 return false;
5438 }
5439
5440 return true;
5441}
5442
Jamie Madill5b772312018-03-08 20:28:32 -05005443bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005444{
5445 return true;
5446}
5447
Jamie Madill5b772312018-03-08 20:28:32 -05005448bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005449{
5450 return true;
5451}
5452
Jamie Madill5b772312018-03-08 20:28:32 -05005453bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005454{
5455 return true;
5456}
5457
Jamie Madill5b772312018-03-08 20:28:32 -05005458bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005459{
5460 if (width < 0 || height < 0)
5461 {
Jamie Madille0472f32018-11-27 16:32:45 -05005462 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005463 return false;
5464 }
5465
5466 return true;
5467}
5468
Jamie Madill5b772312018-03-08 20:28:32 -05005469bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005470 GLsizei n,
5471 const GLuint *shaders,
5472 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005473 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005474 GLsizei length)
5475{
5476 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5477 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5478 shaderBinaryFormats.end())
5479 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005480 context->validationError(GL_INVALID_ENUM, kInvalidShaderBinaryFormat);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005481 return false;
5482 }
5483
5484 return true;
5485}
5486
Jamie Madill5b772312018-03-08 20:28:32 -05005487bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005488 GLuint shader,
5489 GLsizei count,
5490 const GLchar *const *string,
5491 const GLint *length)
5492{
5493 if (count < 0)
5494 {
Jamie Madille0472f32018-11-27 16:32:45 -05005495 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005496 return false;
5497 }
5498
Geoff Langfc32e8b2017-05-31 14:16:59 -04005499 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5500 // shader-related entry points
5501 if (context->getExtensions().webglCompatibility)
5502 {
5503 for (GLsizei i = 0; i < count; i++)
5504 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005505 size_t len =
5506 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005507
5508 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005509 if (!IsValidESSLShaderSourceString(string[i], len,
5510 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005511 {
Jamie Madille0472f32018-11-27 16:32:45 -05005512 context->validationError(GL_INVALID_VALUE, kShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005513 return false;
5514 }
5515 }
5516 }
5517
Jamie Madillc1d770e2017-04-13 17:31:24 -04005518 Shader *shaderObject = GetValidShader(context, shader);
5519 if (!shaderObject)
5520 {
5521 return false;
5522 }
5523
5524 return true;
5525}
5526
Jamie Madill5b772312018-03-08 20:28:32 -05005527bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005528{
5529 if (!IsValidStencilFunc(func))
5530 {
Jamie Madille0472f32018-11-27 16:32:45 -05005531 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005532 return false;
5533 }
5534
5535 return true;
5536}
5537
Jamie Madill5b772312018-03-08 20:28:32 -05005538bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005539{
5540 if (!IsValidStencilFace(face))
5541 {
Jamie Madille0472f32018-11-27 16:32:45 -05005542 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005543 return false;
5544 }
5545
5546 if (!IsValidStencilFunc(func))
5547 {
Jamie Madille0472f32018-11-27 16:32:45 -05005548 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005549 return false;
5550 }
5551
5552 return true;
5553}
5554
Jamie Madill5b772312018-03-08 20:28:32 -05005555bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005556{
5557 return true;
5558}
5559
Jamie Madill5b772312018-03-08 20:28:32 -05005560bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005561{
5562 if (!IsValidStencilFace(face))
5563 {
Jamie Madille0472f32018-11-27 16:32:45 -05005564 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
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 ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005572{
5573 if (!IsValidStencilOp(fail))
5574 {
Jamie Madille0472f32018-11-27 16:32:45 -05005575 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005576 return false;
5577 }
5578
5579 if (!IsValidStencilOp(zfail))
5580 {
Jamie Madille0472f32018-11-27 16:32:45 -05005581 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005582 return false;
5583 }
5584
5585 if (!IsValidStencilOp(zpass))
5586 {
Jamie Madille0472f32018-11-27 16:32:45 -05005587 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005588 return false;
5589 }
5590
5591 return true;
5592}
5593
Jamie Madill5b772312018-03-08 20:28:32 -05005594bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005595 GLenum face,
5596 GLenum fail,
5597 GLenum zfail,
5598 GLenum zpass)
5599{
5600 if (!IsValidStencilFace(face))
5601 {
Jamie Madille0472f32018-11-27 16:32:45 -05005602 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005603 return false;
5604 }
5605
5606 return ValidateStencilOp(context, fail, zfail, zpass);
5607}
5608
Jamie Madill5b772312018-03-08 20:28:32 -05005609bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005610{
5611 return ValidateUniform(context, GL_FLOAT, location, 1);
5612}
5613
Jamie Madill5b772312018-03-08 20:28:32 -05005614bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005615{
5616 return ValidateUniform(context, GL_FLOAT, location, count);
5617}
5618
Jamie Madill5b772312018-03-08 20:28:32 -05005619bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005620{
5621 return ValidateUniform1iv(context, location, 1, &x);
5622}
5623
Jamie Madill5b772312018-03-08 20:28:32 -05005624bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005625{
5626 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5627}
5628
Jamie Madill5b772312018-03-08 20:28:32 -05005629bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005630{
5631 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5632}
5633
Jamie Madill5b772312018-03-08 20:28:32 -05005634bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005635{
5636 return ValidateUniform(context, GL_INT_VEC2, location, count);
5637}
5638
Jamie Madill5b772312018-03-08 20:28:32 -05005639bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005640{
5641 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5642}
5643
Jamie Madill5b772312018-03-08 20:28:32 -05005644bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005645{
5646 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5647}
5648
Jamie Madill5b772312018-03-08 20:28:32 -05005649bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005650{
5651 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5652}
5653
Jamie Madill5b772312018-03-08 20:28:32 -05005654bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005655{
5656 return ValidateUniform(context, GL_INT_VEC3, location, count);
5657}
5658
Jamie Madill5b772312018-03-08 20:28:32 -05005659bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005660{
5661 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5662}
5663
Jamie Madill5b772312018-03-08 20:28:32 -05005664bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005665{
5666 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5667}
5668
Jamie Madill5b772312018-03-08 20:28:32 -05005669bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005670{
5671 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5672}
5673
Jamie Madill5b772312018-03-08 20:28:32 -05005674bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005675{
5676 return ValidateUniform(context, GL_INT_VEC4, location, count);
5677}
5678
Jamie Madill5b772312018-03-08 20:28:32 -05005679bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005680 GLint location,
5681 GLsizei count,
5682 GLboolean transpose,
5683 const GLfloat *value)
5684{
5685 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5686}
5687
Jamie Madill5b772312018-03-08 20:28:32 -05005688bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005689 GLint location,
5690 GLsizei count,
5691 GLboolean transpose,
5692 const GLfloat *value)
5693{
5694 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5695}
5696
Jamie Madill5b772312018-03-08 20:28:32 -05005697bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005698 GLint location,
5699 GLsizei count,
5700 GLboolean transpose,
5701 const GLfloat *value)
5702{
5703 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5704}
5705
Jamie Madill5b772312018-03-08 20:28:32 -05005706bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005707{
5708 Program *programObject = GetValidProgram(context, program);
5709
5710 if (!programObject)
5711 {
5712 return false;
5713 }
5714
5715 return true;
5716}
5717
Jamie Madill5b772312018-03-08 20:28:32 -05005718bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005719{
5720 return ValidateVertexAttribIndex(context, index);
5721}
5722
Jamie Madill5b772312018-03-08 20:28:32 -05005723bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005724{
5725 return ValidateVertexAttribIndex(context, index);
5726}
5727
Jamie Madill5b772312018-03-08 20:28:32 -05005728bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005729{
5730 return ValidateVertexAttribIndex(context, index);
5731}
5732
Jamie Madill5b772312018-03-08 20:28:32 -05005733bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005734{
5735 return ValidateVertexAttribIndex(context, index);
5736}
5737
Jamie Madill5b772312018-03-08 20:28:32 -05005738bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005739{
5740 return ValidateVertexAttribIndex(context, index);
5741}
5742
Jamie Madill5b772312018-03-08 20:28:32 -05005743bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005744{
5745 return ValidateVertexAttribIndex(context, index);
5746}
5747
Jamie Madill5b772312018-03-08 20:28:32 -05005748bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005749 GLuint index,
5750 GLfloat x,
5751 GLfloat y,
5752 GLfloat z,
5753 GLfloat w)
5754{
5755 return ValidateVertexAttribIndex(context, index);
5756}
5757
Jamie Madill5b772312018-03-08 20:28:32 -05005758bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005759{
5760 return ValidateVertexAttribIndex(context, index);
5761}
5762
Jamie Madill5b772312018-03-08 20:28:32 -05005763bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005764{
5765 if (width < 0 || height < 0)
5766 {
Jamie Madille0472f32018-11-27 16:32:45 -05005767 context->validationError(GL_INVALID_VALUE, kViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005768 return false;
5769 }
5770
5771 return true;
5772}
5773
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005774bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005775 GLenum target,
5776 GLenum attachment,
5777 GLenum pname,
5778 GLint *params)
5779{
5780 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5781 nullptr);
5782}
5783
Jamie Madill5b772312018-03-08 20:28:32 -05005784bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04005785{
5786 return ValidateGetProgramivBase(context, program, pname, nullptr);
5787}
5788
Jamie Madill5b772312018-03-08 20:28:32 -05005789bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005790 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005791 GLint level,
5792 GLenum internalformat,
5793 GLint x,
5794 GLint y,
5795 GLsizei width,
5796 GLsizei height,
5797 GLint border)
5798{
5799 if (context->getClientMajorVersion() < 3)
5800 {
5801 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5802 0, x, y, width, height, border);
5803 }
5804
5805 ASSERT(context->getClientMajorVersion() == 3);
5806 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5807 0, x, y, width, height, border);
5808}
5809
5810bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005811 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005812 GLint level,
5813 GLint xoffset,
5814 GLint yoffset,
5815 GLint x,
5816 GLint y,
5817 GLsizei width,
5818 GLsizei height)
5819{
5820 if (context->getClientMajorVersion() < 3)
5821 {
5822 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5823 yoffset, x, y, width, height, 0);
5824 }
5825
5826 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5827 yoffset, 0, x, y, width, height, 0);
5828}
5829
5830bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5831{
5832 return ValidateGenOrDelete(context, n);
5833}
5834
5835bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5836{
5837 return ValidateGenOrDelete(context, n);
5838}
5839
5840bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5841{
5842 return ValidateGenOrDelete(context, n);
5843}
5844
5845bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5846{
5847 return ValidateGenOrDelete(context, n);
5848}
5849
5850bool ValidateDisable(Context *context, GLenum cap)
5851{
5852 if (!ValidCap(context, cap, false))
5853 {
Jamie Madille0472f32018-11-27 16:32:45 -05005854 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005855 return false;
5856 }
5857
5858 return true;
5859}
5860
5861bool ValidateEnable(Context *context, GLenum cap)
5862{
5863 if (!ValidCap(context, cap, false))
5864 {
Jamie Madille0472f32018-11-27 16:32:45 -05005865 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005866 return false;
5867 }
5868
5869 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5870 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5871 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005872 context->validationError(GL_INVALID_OPERATION, kNoSampleAlphaToCoveragesLimitation);
Jamie Madillbe849e42017-05-02 15:49:00 -04005873
5874 // We also output an error message to the debugger window if tracing is active, so that
5875 // developers can see the error message.
Jamie Madillc3e37312018-11-30 15:25:39 -05005876 ERR() << kNoSampleAlphaToCoveragesLimitation;
Jamie Madillbe849e42017-05-02 15:49:00 -04005877 return false;
5878 }
5879
5880 return true;
5881}
5882
5883bool ValidateFramebufferRenderbuffer(Context *context,
5884 GLenum target,
5885 GLenum attachment,
5886 GLenum renderbuffertarget,
5887 GLuint renderbuffer)
5888{
Geoff Lange8afa902017-09-27 15:00:43 -04005889 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005890 {
Jamie Madille0472f32018-11-27 16:32:45 -05005891 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Brandon Jones6cad5662017-06-14 13:25:13 -07005892 return false;
5893 }
5894
5895 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5896 {
Jamie Madille0472f32018-11-27 16:32:45 -05005897 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005898 return false;
5899 }
5900
5901 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5902 renderbuffertarget, renderbuffer);
5903}
5904
5905bool ValidateFramebufferTexture2D(Context *context,
5906 GLenum target,
5907 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005908 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04005909 GLuint texture,
5910 GLint level)
5911{
5912 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5913 // extension
5914 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5915 level != 0)
5916 {
Jamie Madille0472f32018-11-27 16:32:45 -05005917 context->validationError(GL_INVALID_VALUE, kInvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005918 return false;
5919 }
5920
5921 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5922 {
5923 return false;
5924 }
5925
5926 if (texture != 0)
5927 {
5928 gl::Texture *tex = context->getTexture(texture);
5929 ASSERT(tex);
5930
5931 const gl::Caps &caps = context->getCaps();
5932
5933 switch (textarget)
5934 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005935 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04005936 {
5937 if (level > gl::log2(caps.max2DTextureSize))
5938 {
Jamie Madille0472f32018-11-27 16:32:45 -05005939 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005940 return false;
5941 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005942 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04005943 {
Jamie Madille0472f32018-11-27 16:32:45 -05005944 context->validationError(GL_INVALID_OPERATION, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005945 return false;
5946 }
5947 }
5948 break;
5949
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005950 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005951 {
5952 if (level != 0)
5953 {
Jamie Madille0472f32018-11-27 16:32:45 -05005954 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005955 return false;
5956 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005957 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005958 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005959 context->validationError(GL_INVALID_OPERATION, kTextureTargetMismatch);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005960 return false;
5961 }
5962 }
5963 break;
5964
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005965 case TextureTarget::CubeMapNegativeX:
5966 case TextureTarget::CubeMapNegativeY:
5967 case TextureTarget::CubeMapNegativeZ:
5968 case TextureTarget::CubeMapPositiveX:
5969 case TextureTarget::CubeMapPositiveY:
5970 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04005971 {
5972 if (level > gl::log2(caps.maxCubeMapTextureSize))
5973 {
Jamie Madille0472f32018-11-27 16:32:45 -05005974 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005975 return false;
5976 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005977 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04005978 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005979 context->validationError(GL_INVALID_OPERATION, kTextureTargetMismatch);
Jamie Madillbe849e42017-05-02 15:49:00 -04005980 return false;
5981 }
5982 }
5983 break;
5984
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005985 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04005986 {
Yizhou Jiang7818a852018-09-06 15:02:04 +08005987 if (context->getClientVersion() < ES_3_1 &&
5988 !context->getExtensions().textureMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04005989 {
Jamie Madill610640f2018-11-21 17:28:41 -05005990 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05005991 kMultisampleTextureExtensionOrES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04005992 return false;
5993 }
5994
5995 if (level != 0)
5996 {
Jamie Madille0472f32018-11-27 16:32:45 -05005997 context->validationError(GL_INVALID_VALUE, kLevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04005998 return false;
5999 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006000 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006001 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006002 context->validationError(GL_INVALID_OPERATION, kTextureTargetMismatch);
Jamie Madillbe849e42017-05-02 15:49:00 -04006003 return false;
6004 }
6005 }
6006 break;
6007
6008 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006009 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006010 return false;
6011 }
Jamie Madillbe849e42017-05-02 15:49:00 -04006012 }
6013
6014 return true;
6015}
6016
6017bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6018{
6019 return ValidateGenOrDelete(context, n);
6020}
6021
6022bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6023{
6024 return ValidateGenOrDelete(context, n);
6025}
6026
6027bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6028{
6029 return ValidateGenOrDelete(context, n);
6030}
6031
6032bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6033{
6034 return ValidateGenOrDelete(context, n);
6035}
6036
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006037bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006038{
6039 if (!ValidTextureTarget(context, target))
6040 {
Jamie Madille0472f32018-11-27 16:32:45 -05006041 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006042 return false;
6043 }
6044
6045 Texture *texture = context->getTargetTexture(target);
6046
6047 if (texture == nullptr)
6048 {
Jamie Madille0472f32018-11-27 16:32:45 -05006049 context->validationError(GL_INVALID_OPERATION, kTextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006050 return false;
6051 }
6052
6053 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6054
6055 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6056 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6057 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6058 {
Jamie Madille0472f32018-11-27 16:32:45 -05006059 context->validationError(GL_INVALID_OPERATION, kBaseLevelOutOfRange);
Jamie Madillbe849e42017-05-02 15:49:00 -04006060 return false;
6061 }
6062
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006063 TextureTarget baseTarget = (target == TextureType::CubeMap)
6064 ? TextureTarget::CubeMapPositiveX
6065 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006066 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6067 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6068 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006069 {
Jamie Madille0472f32018-11-27 16:32:45 -05006070 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Brandon Jones6cad5662017-06-14 13:25:13 -07006071 return false;
6072 }
6073
Geoff Lang536eca12017-09-13 11:23:35 -04006074 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6075 bool formatUnsized = !format.sized;
6076 bool formatColorRenderableAndFilterable =
6077 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
Yuly Novikovf15f8862018-06-04 18:59:41 -04006078 format.textureAttachmentSupport(context->getClientVersion(), context->getExtensions());
Geoff Lang536eca12017-09-13 11:23:35 -04006079 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006080 {
Jamie Madille0472f32018-11-27 16:32:45 -05006081 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006082 return false;
6083 }
6084
Geoff Lang536eca12017-09-13 11:23:35 -04006085 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6086 // generation
6087 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6088 {
Jamie Madille0472f32018-11-27 16:32:45 -05006089 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Geoff Lang536eca12017-09-13 11:23:35 -04006090 return false;
6091 }
6092
Jiange2c00842018-07-13 16:50:49 +08006093 // According to the OpenGL extension spec EXT_sRGB.txt, EXT_SRGB is based on ES 2.0 and
6094 // generateMipmap is not allowed if texture format is SRGB_EXT or SRGB_ALPHA_EXT.
6095 if (context->getClientVersion() < Version(3, 0) && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006096 {
Jamie Madille0472f32018-11-27 16:32:45 -05006097 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006098 return false;
6099 }
6100
6101 // Non-power of 2 ES2 check
6102 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6103 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6104 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6105 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006106 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6107 target == TextureType::CubeMap);
Jamie Madille0472f32018-11-27 16:32:45 -05006108 context->validationError(GL_INVALID_OPERATION, kTextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006109 return false;
6110 }
6111
6112 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006113 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006114 {
Jamie Madille0472f32018-11-27 16:32:45 -05006115 context->validationError(GL_INVALID_OPERATION, kCubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006116 return false;
6117 }
6118
James Darpinian83b2f0e2018-11-27 15:56:01 -08006119 if (context->getExtensions().webglCompatibility &&
6120 (texture->getWidth(baseTarget, effectiveBaseLevel) == 0 ||
6121 texture->getHeight(baseTarget, effectiveBaseLevel) == 0))
6122 {
6123 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapZeroSize);
6124 return false;
6125 }
6126
Jamie Madillbe849e42017-05-02 15:49:00 -04006127 return true;
6128}
6129
Jamie Madill5b772312018-03-08 20:28:32 -05006130bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006131 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006132 GLenum pname,
6133 GLint *params)
6134{
6135 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6136}
6137
6138bool ValidateGetRenderbufferParameteriv(Context *context,
6139 GLenum target,
6140 GLenum pname,
6141 GLint *params)
6142{
6143 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6144}
6145
6146bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6147{
6148 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6149}
6150
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006151bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006152{
6153 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6154}
6155
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006156bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006157{
6158 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6159}
6160
Till Rathmannb8543632018-10-02 19:46:14 +02006161bool ValidateGetTexParameterIivOES(Context *context,
6162 TextureType target,
6163 GLenum pname,
6164 GLint *params)
6165{
6166 if (context->getClientMajorVersion() < 3)
6167 {
Jamie Madille0472f32018-11-27 16:32:45 -05006168 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006169 return false;
6170 }
6171 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6172}
6173
6174bool ValidateGetTexParameterIuivOES(Context *context,
6175 TextureType target,
6176 GLenum pname,
6177 GLuint *params)
6178{
6179 if (context->getClientMajorVersion() < 3)
6180 {
Jamie Madille0472f32018-11-27 16:32:45 -05006181 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006182 return false;
6183 }
6184 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6185}
6186
Jamie Madillbe849e42017-05-02 15:49:00 -04006187bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6188{
6189 return ValidateGetUniformBase(context, program, location);
6190}
6191
6192bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6193{
6194 return ValidateGetUniformBase(context, program, location);
6195}
6196
6197bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6198{
6199 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6200}
6201
6202bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6203{
6204 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6205}
6206
6207bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6208{
6209 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6210}
6211
6212bool ValidateIsEnabled(Context *context, GLenum cap)
6213{
6214 if (!ValidCap(context, cap, true))
6215 {
Jamie Madille0472f32018-11-27 16:32:45 -05006216 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006217 return false;
6218 }
6219
6220 return true;
6221}
6222
6223bool ValidateLinkProgram(Context *context, GLuint program)
6224{
6225 if (context->hasActiveTransformFeedback(program))
6226 {
6227 // ES 3.0.4 section 2.15 page 91
Jamie Madillc3e37312018-11-30 15:25:39 -05006228 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackActiveDuringLink);
Jamie Madillbe849e42017-05-02 15:49:00 -04006229 return false;
6230 }
6231
6232 Program *programObject = GetValidProgram(context, program);
6233 if (!programObject)
6234 {
6235 return false;
6236 }
6237
6238 return true;
6239}
6240
Jamie Madill4928b7c2017-06-20 12:57:39 -04006241bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006242 GLint x,
6243 GLint y,
6244 GLsizei width,
6245 GLsizei height,
6246 GLenum format,
6247 GLenum type,
6248 void *pixels)
6249{
6250 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6251 nullptr, pixels);
6252}
6253
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006254bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006255{
Till Rathmannb8543632018-10-02 19:46:14 +02006256 return ValidateTexParameterBase(context, target, pname, -1, false, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006257}
6258
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006259bool ValidateTexParameterfv(Context *context,
6260 TextureType target,
6261 GLenum pname,
6262 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006263{
Till Rathmannb8543632018-10-02 19:46:14 +02006264 return ValidateTexParameterBase(context, target, pname, -1, true, params);
Jamie Madillbe849e42017-05-02 15:49:00 -04006265}
6266
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006267bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006268{
Till Rathmannb8543632018-10-02 19:46:14 +02006269 return ValidateTexParameterBase(context, target, pname, -1, false, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006270}
6271
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006272bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006273{
Till Rathmannb8543632018-10-02 19:46:14 +02006274 return ValidateTexParameterBase(context, target, pname, -1, true, params);
6275}
6276
6277bool ValidateTexParameterIivOES(Context *context,
6278 TextureType target,
6279 GLenum pname,
6280 const GLint *params)
6281{
6282 if (context->getClientMajorVersion() < 3)
6283 {
Jamie Madille0472f32018-11-27 16:32:45 -05006284 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006285 return false;
6286 }
6287 return ValidateTexParameterBase(context, target, pname, -1, true, params);
6288}
6289
6290bool ValidateTexParameterIuivOES(Context *context,
6291 TextureType target,
6292 GLenum pname,
6293 const GLuint *params)
6294{
6295 if (context->getClientMajorVersion() < 3)
6296 {
Jamie Madille0472f32018-11-27 16:32:45 -05006297 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006298 return false;
6299 }
6300 return ValidateTexParameterBase(context, target, pname, -1, true, params);
Jamie Madillbe849e42017-05-02 15:49:00 -04006301}
6302
6303bool ValidateUseProgram(Context *context, GLuint program)
6304{
6305 if (program != 0)
6306 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04006307 Program *programObject = context->getProgramResolveLink(program);
Jamie Madillbe849e42017-05-02 15:49:00 -04006308 if (!programObject)
6309 {
6310 // ES 3.1.0 section 7.3 page 72
6311 if (context->getShader(program))
6312 {
Jamie Madille0472f32018-11-27 16:32:45 -05006313 context->validationError(GL_INVALID_OPERATION, kExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006314 return false;
6315 }
6316 else
6317 {
Jamie Madille0472f32018-11-27 16:32:45 -05006318 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006319 return false;
6320 }
6321 }
6322 if (!programObject->isLinked())
6323 {
Jamie Madille0472f32018-11-27 16:32:45 -05006324 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006325 return false;
6326 }
6327 }
6328 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6329 {
6330 // ES 3.0.4 section 2.15 page 91
Jamie Madillc3e37312018-11-30 15:25:39 -05006331 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackUseProgram);
Jamie Madillbe849e42017-05-02 15:49:00 -04006332 return false;
6333 }
6334
6335 return true;
6336}
6337
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006338bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6339{
6340 if (!context->getExtensions().fence)
6341 {
Jamie Madille0472f32018-11-27 16:32:45 -05006342 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006343 return false;
6344 }
6345
6346 if (n < 0)
6347 {
Jamie Madille0472f32018-11-27 16:32:45 -05006348 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006349 return false;
6350 }
6351
6352 return true;
6353}
6354
6355bool ValidateFinishFenceNV(Context *context, GLuint fence)
6356{
6357 if (!context->getExtensions().fence)
6358 {
Jamie Madille0472f32018-11-27 16:32:45 -05006359 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006360 return false;
6361 }
6362
6363 FenceNV *fenceObject = context->getFenceNV(fence);
6364
6365 if (fenceObject == nullptr)
6366 {
Jamie Madille0472f32018-11-27 16:32:45 -05006367 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006368 return false;
6369 }
6370
6371 if (!fenceObject->isSet())
6372 {
Jamie Madille0472f32018-11-27 16:32:45 -05006373 context->validationError(GL_INVALID_OPERATION, kInvalidFenceState);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006374 return false;
6375 }
6376
6377 return true;
6378}
6379
6380bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6381{
6382 if (!context->getExtensions().fence)
6383 {
Jamie Madille0472f32018-11-27 16:32:45 -05006384 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006385 return false;
6386 }
6387
6388 if (n < 0)
6389 {
Jamie Madille0472f32018-11-27 16:32:45 -05006390 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006391 return false;
6392 }
6393
6394 return true;
6395}
6396
6397bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6398{
6399 if (!context->getExtensions().fence)
6400 {
Jamie Madille0472f32018-11-27 16:32:45 -05006401 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006402 return false;
6403 }
6404
6405 FenceNV *fenceObject = context->getFenceNV(fence);
6406
6407 if (fenceObject == nullptr)
6408 {
Jamie Madille0472f32018-11-27 16:32:45 -05006409 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006410 return false;
6411 }
6412
6413 if (!fenceObject->isSet())
6414 {
Jamie Madille0472f32018-11-27 16:32:45 -05006415 context->validationError(GL_INVALID_OPERATION, kInvalidFenceState);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006416 return false;
6417 }
6418
6419 switch (pname)
6420 {
6421 case GL_FENCE_STATUS_NV:
6422 case GL_FENCE_CONDITION_NV:
6423 break;
6424
6425 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006426 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006427 return false;
6428 }
6429
6430 return true;
6431}
6432
6433bool ValidateGetGraphicsResetStatusEXT(Context *context)
6434{
6435 if (!context->getExtensions().robustness)
6436 {
Jamie Madille0472f32018-11-27 16:32:45 -05006437 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006438 return false;
6439 }
6440
6441 return true;
6442}
6443
6444bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6445 GLuint shader,
6446 GLsizei bufsize,
6447 GLsizei *length,
6448 GLchar *source)
6449{
6450 if (!context->getExtensions().translatedShaderSource)
6451 {
Jamie Madille0472f32018-11-27 16:32:45 -05006452 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006453 return false;
6454 }
6455
6456 if (bufsize < 0)
6457 {
Jamie Madille0472f32018-11-27 16:32:45 -05006458 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006459 return false;
6460 }
6461
6462 Shader *shaderObject = context->getShader(shader);
6463
6464 if (!shaderObject)
6465 {
Jamie Madille0472f32018-11-27 16:32:45 -05006466 context->validationError(GL_INVALID_OPERATION, kInvalidShaderName);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006467 return false;
6468 }
6469
6470 return true;
6471}
6472
6473bool ValidateIsFenceNV(Context *context, GLuint fence)
6474{
6475 if (!context->getExtensions().fence)
6476 {
Jamie Madille0472f32018-11-27 16:32:45 -05006477 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006478 return false;
6479 }
6480
6481 return true;
6482}
6483
Jamie Madill007530e2017-12-28 14:27:04 -05006484bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6485{
6486 if (!context->getExtensions().fence)
6487 {
Jamie Madille0472f32018-11-27 16:32:45 -05006488 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill007530e2017-12-28 14:27:04 -05006489 return false;
6490 }
6491
6492 if (condition != GL_ALL_COMPLETED_NV)
6493 {
Jamie Madille0472f32018-11-27 16:32:45 -05006494 context->validationError(GL_INVALID_ENUM, kInvalidFenceCondition);
Jamie Madill007530e2017-12-28 14:27:04 -05006495 return false;
6496 }
6497
6498 FenceNV *fenceObject = context->getFenceNV(fence);
6499
6500 if (fenceObject == nullptr)
6501 {
Jamie Madille0472f32018-11-27 16:32:45 -05006502 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill007530e2017-12-28 14:27:04 -05006503 return false;
6504 }
6505
6506 return true;
6507}
6508
6509bool ValidateTestFenceNV(Context *context, GLuint fence)
6510{
6511 if (!context->getExtensions().fence)
6512 {
Jamie Madille0472f32018-11-27 16:32:45 -05006513 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill007530e2017-12-28 14:27:04 -05006514 return false;
6515 }
6516
6517 FenceNV *fenceObject = context->getFenceNV(fence);
6518
6519 if (fenceObject == nullptr)
6520 {
Jamie Madille0472f32018-11-27 16:32:45 -05006521 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill007530e2017-12-28 14:27:04 -05006522 return false;
6523 }
6524
6525 if (fenceObject->isSet() != GL_TRUE)
6526 {
Jamie Madille0472f32018-11-27 16:32:45 -05006527 context->validationError(GL_INVALID_OPERATION, kInvalidFenceState);
Jamie Madill007530e2017-12-28 14:27:04 -05006528 return false;
6529 }
6530
6531 return true;
6532}
6533
6534bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006535 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006536 GLsizei levels,
6537 GLenum internalformat,
6538 GLsizei width,
6539 GLsizei height)
6540{
6541 if (!context->getExtensions().textureStorage)
6542 {
Jamie Madille0472f32018-11-27 16:32:45 -05006543 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05006544 return false;
6545 }
6546
6547 if (context->getClientMajorVersion() < 3)
6548 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006549 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006550 height);
6551 }
6552
6553 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006554 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006555 1);
6556}
6557
6558bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6559{
6560 if (!context->getExtensions().instancedArrays)
6561 {
Jamie Madille0472f32018-11-27 16:32:45 -05006562 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05006563 return false;
6564 }
6565
6566 if (index >= MAX_VERTEX_ATTRIBS)
6567 {
Jamie Madille0472f32018-11-27 16:32:45 -05006568 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madill007530e2017-12-28 14:27:04 -05006569 return false;
6570 }
6571
6572 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6573 {
6574 if (index == 0 && divisor != 0)
6575 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006576 context->validationError(GL_INVALID_OPERATION, kAttributeZeroRequiresDivisorLimitation);
Jamie Madill007530e2017-12-28 14:27:04 -05006577
6578 // We also output an error message to the debugger window if tracing is active, so
6579 // that developers can see the error message.
Jamie Madillc3e37312018-11-30 15:25:39 -05006580 ERR() << kAttributeZeroRequiresDivisorLimitation;
Jamie Madill007530e2017-12-28 14:27:04 -05006581 return false;
6582 }
6583 }
6584
6585 return true;
6586}
6587
6588bool ValidateTexImage3DOES(Context *context,
6589 GLenum target,
6590 GLint level,
6591 GLenum internalformat,
6592 GLsizei width,
6593 GLsizei height,
6594 GLsizei depth,
6595 GLint border,
6596 GLenum format,
6597 GLenum type,
6598 const void *pixels)
6599{
6600 UNIMPLEMENTED(); // FIXME
6601 return false;
6602}
6603
6604bool ValidatePopGroupMarkerEXT(Context *context)
6605{
6606 if (!context->getExtensions().debugMarker)
6607 {
6608 // The debug marker calls should not set error state
6609 // However, it seems reasonable to set an error state if the extension is not enabled
Jamie Madille0472f32018-11-27 16:32:45 -05006610 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05006611 return false;
6612 }
6613
6614 return true;
6615}
6616
Jamie Madillfa920eb2018-01-04 11:45:50 -05006617bool ValidateTexStorage1DEXT(Context *context,
6618 GLenum target,
6619 GLsizei levels,
6620 GLenum internalformat,
6621 GLsizei width)
6622{
6623 UNIMPLEMENTED();
Jamie Madille0472f32018-11-27 16:32:45 -05006624 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05006625 return false;
6626}
6627
6628bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006629 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006630 GLsizei levels,
6631 GLenum internalformat,
6632 GLsizei width,
6633 GLsizei height,
6634 GLsizei depth)
6635{
6636 if (!context->getExtensions().textureStorage)
6637 {
Jamie Madille0472f32018-11-27 16:32:45 -05006638 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05006639 return false;
6640 }
6641
6642 if (context->getClientMajorVersion() < 3)
6643 {
Jamie Madille0472f32018-11-27 16:32:45 -05006644 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05006645 return false;
6646 }
6647
6648 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6649 depth);
6650}
6651
jchen1082af6202018-06-22 10:59:52 +08006652bool ValidateMaxShaderCompilerThreadsKHR(Context *context, GLuint count)
6653{
6654 if (!context->getExtensions().parallelShaderCompile)
6655 {
Jamie Madille0472f32018-11-27 16:32:45 -05006656 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
jchen1082af6202018-06-22 10:59:52 +08006657 return false;
6658 }
6659 return true;
6660}
6661
Austin Eng1bf18ce2018-10-19 15:34:02 -07006662bool ValidateMultiDrawArraysANGLE(Context *context,
6663 PrimitiveMode mode,
6664 const GLint *firsts,
6665 const GLsizei *counts,
6666 GLsizei drawcount)
6667{
6668 if (!context->getExtensions().multiDraw)
6669 {
Jamie Madille0472f32018-11-27 16:32:45 -05006670 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07006671 return false;
6672 }
6673 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
6674 {
6675 if (!ValidateDrawArrays(context, mode, firsts[drawID], counts[drawID]))
6676 {
6677 return false;
6678 }
6679 }
6680 return true;
6681}
6682
6683bool ValidateMultiDrawElementsANGLE(Context *context,
6684 PrimitiveMode mode,
6685 const GLsizei *counts,
Jamie Madill8dc27f92018-11-29 11:45:44 -05006686 DrawElementsType type,
Austin Eng3b7c9d02018-11-21 18:09:05 -08006687 const GLvoid *const *indices,
Austin Eng1bf18ce2018-10-19 15:34:02 -07006688 GLsizei drawcount)
6689{
6690 if (!context->getExtensions().multiDraw)
6691 {
Jamie Madille0472f32018-11-27 16:32:45 -05006692 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07006693 return false;
6694 }
6695 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
6696 {
Austin Eng3b7c9d02018-11-21 18:09:05 -08006697 if (!ValidateDrawElements(context, mode, counts[drawID], type, indices[drawID]))
Austin Eng1bf18ce2018-10-19 15:34:02 -07006698 {
6699 return false;
6700 }
6701 }
6702 return true;
6703}
6704
Jamie Madillc29968b2016-01-20 11:17:23 -05006705} // namespace gl