blob: c6fdbaf59e11d5e11338144dc62f7035ee2eb7d9 [file] [log] [blame]
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001//
Geoff Langcec35902014-04-16 10:52:36 -04002// Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
Geoff Lange8ebe7f2013-08-05 15:03:13 -04003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// validationES2.cpp: Validation functions for OpenGL ES 2.0 entry point parameters
8
Jamie Madill778bf092018-11-14 09:54:36 -05009#include "libANGLE/validationES2_autogen.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030010
11#include <cstdint>
12
Geoff Lange8ebe7f2013-08-05 15:03:13 -040013#include "common/mathutil.h"
Sami Väisänen46eaa942016-06-29 10:26:37 +030014#include "common/string_utils.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040015#include "common/utilities.h"
Jamie Madillef300b12016-10-07 15:12:09 -040016#include "libANGLE/Context.h"
Brandon Jones6cad5662017-06-14 13:25:13 -070017#include "libANGLE/ErrorStrings.h"
Jamie Madill2b7bbc22017-12-21 17:30:38 -050018#include "libANGLE/Fence.h"
Jamie Madillef300b12016-10-07 15:12:09 -040019#include "libANGLE/Framebuffer.h"
20#include "libANGLE/FramebufferAttachment.h"
21#include "libANGLE/Renderbuffer.h"
22#include "libANGLE/Shader.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040023#include "libANGLE/Texture.h"
Jamie Madillef300b12016-10-07 15:12:09 -040024#include "libANGLE/Uniform.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040025#include "libANGLE/VertexArray.h"
Jamie Madillef300b12016-10-07 15:12:09 -040026#include "libANGLE/formatutils.h"
27#include "libANGLE/validationES.h"
Jamie Madill778bf092018-11-14 09:54:36 -050028#include "libANGLE/validationES2.h"
29#include "libANGLE/validationES3_autogen.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040030
31namespace gl
32{
Jamie Madille0472f32018-11-27 16:32:45 -050033using namespace err;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040034
Jamie Madillc29968b2016-01-20 11:17:23 -050035namespace
36{
37
38bool IsPartialBlit(gl::Context *context,
39 const FramebufferAttachment *readBuffer,
40 const FramebufferAttachment *writeBuffer,
41 GLint srcX0,
42 GLint srcY0,
43 GLint srcX1,
44 GLint srcY1,
45 GLint dstX0,
46 GLint dstY0,
47 GLint dstX1,
48 GLint dstY1)
49{
50 const Extents &writeSize = writeBuffer->getSize();
51 const Extents &readSize = readBuffer->getSize();
52
53 if (srcX0 != 0 || srcY0 != 0 || dstX0 != 0 || dstY0 != 0 || dstX1 != writeSize.width ||
54 dstY1 != writeSize.height || srcX1 != readSize.width || srcY1 != readSize.height)
55 {
56 return true;
57 }
58
Jamie Madillc3dc5d42018-12-30 12:12:04 -050059 if (context->getState().isScissorTestEnabled())
Jamie Madillc29968b2016-01-20 11:17:23 -050060 {
Jamie Madillc3dc5d42018-12-30 12:12:04 -050061 const Rectangle &scissor = context->getState().getScissor();
Jamie Madillc29968b2016-01-20 11:17:23 -050062 return scissor.x > 0 || scissor.y > 0 || scissor.width < writeSize.width ||
63 scissor.height < writeSize.height;
64 }
65
66 return false;
67}
68
Sami Väisänend59ca052016-06-21 16:10:00 +030069template <typename T>
70bool ValidatePathInstances(gl::Context *context,
71 GLsizei numPaths,
72 const void *paths,
73 GLuint pathBase)
74{
75 const auto *array = static_cast<const T *>(paths);
76
77 for (GLsizei i = 0; i < numPaths; ++i)
78 {
79 const GLuint pathName = array[i] + pathBase;
Brandon Jones59770802018-04-02 13:18:42 -070080 if (context->isPathGenerated(pathName) && !context->isPath(pathName))
Sami Väisänend59ca052016-06-21 16:10:00 +030081 {
Jamie Madille0472f32018-11-27 16:32:45 -050082 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänend59ca052016-06-21 16:10:00 +030083 return false;
84 }
85 }
86 return true;
87}
88
89bool ValidateInstancedPathParameters(gl::Context *context,
90 GLsizei numPaths,
91 GLenum pathNameType,
92 const void *paths,
93 GLuint pathBase,
94 GLenum transformType,
95 const GLfloat *transformValues)
96{
97 if (!context->getExtensions().pathRendering)
98 {
Jamie Madillc3e37312018-11-30 15:25:39 -050099 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänend59ca052016-06-21 16:10:00 +0300100 return false;
101 }
102
103 if (paths == nullptr)
104 {
Jamie Madillc3e37312018-11-30 15:25:39 -0500105 context->validationError(GL_INVALID_VALUE, kInvalidPathNameArray);
Sami Väisänend59ca052016-06-21 16:10:00 +0300106 return false;
107 }
108
109 if (numPaths < 0)
110 {
Jamie Madillc3e37312018-11-30 15:25:39 -0500111 context->validationError(GL_INVALID_VALUE, kInvalidPathNumPaths);
Sami Väisänend59ca052016-06-21 16:10:00 +0300112 return false;
113 }
114
115 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(numPaths))
116 {
Jamie Madille0472f32018-11-27 16:32:45 -0500117 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300118 return false;
119 }
120
121 std::uint32_t pathNameTypeSize = 0;
122 std::uint32_t componentCount = 0;
123
124 switch (pathNameType)
125 {
126 case GL_UNSIGNED_BYTE:
127 pathNameTypeSize = sizeof(GLubyte);
128 if (!ValidatePathInstances<GLubyte>(context, numPaths, paths, pathBase))
129 return false;
130 break;
131
132 case GL_BYTE:
133 pathNameTypeSize = sizeof(GLbyte);
134 if (!ValidatePathInstances<GLbyte>(context, numPaths, paths, pathBase))
135 return false;
136 break;
137
138 case GL_UNSIGNED_SHORT:
139 pathNameTypeSize = sizeof(GLushort);
140 if (!ValidatePathInstances<GLushort>(context, numPaths, paths, pathBase))
141 return false;
142 break;
143
144 case GL_SHORT:
145 pathNameTypeSize = sizeof(GLshort);
146 if (!ValidatePathInstances<GLshort>(context, numPaths, paths, pathBase))
147 return false;
148 break;
149
150 case GL_UNSIGNED_INT:
151 pathNameTypeSize = sizeof(GLuint);
152 if (!ValidatePathInstances<GLuint>(context, numPaths, paths, pathBase))
153 return false;
154 break;
155
156 case GL_INT:
157 pathNameTypeSize = sizeof(GLint);
158 if (!ValidatePathInstances<GLint>(context, numPaths, paths, pathBase))
159 return false;
160 break;
161
162 default:
Jamie Madillc3e37312018-11-30 15:25:39 -0500163 context->validationError(GL_INVALID_ENUM, kInvalidPathNameType);
Sami Väisänend59ca052016-06-21 16:10:00 +0300164 return false;
165 }
166
167 switch (transformType)
168 {
169 case GL_NONE:
170 componentCount = 0;
171 break;
172 case GL_TRANSLATE_X_CHROMIUM:
173 case GL_TRANSLATE_Y_CHROMIUM:
174 componentCount = 1;
175 break;
176 case GL_TRANSLATE_2D_CHROMIUM:
177 componentCount = 2;
178 break;
179 case GL_TRANSLATE_3D_CHROMIUM:
180 componentCount = 3;
181 break;
182 case GL_AFFINE_2D_CHROMIUM:
183 case GL_TRANSPOSE_AFFINE_2D_CHROMIUM:
184 componentCount = 6;
185 break;
186 case GL_AFFINE_3D_CHROMIUM:
187 case GL_TRANSPOSE_AFFINE_3D_CHROMIUM:
188 componentCount = 12;
189 break;
190 default:
Jamie Madillc3e37312018-11-30 15:25:39 -0500191 context->validationError(GL_INVALID_ENUM, kInvalidTransformation);
Sami Väisänend59ca052016-06-21 16:10:00 +0300192 return false;
193 }
194 if (componentCount != 0 && transformValues == nullptr)
195 {
Jamie Madillc3e37312018-11-30 15:25:39 -0500196 context->validationError(GL_INVALID_VALUE, kNoTransformArray);
Sami Väisänend59ca052016-06-21 16:10:00 +0300197 return false;
198 }
199
200 angle::CheckedNumeric<std::uint32_t> checkedSize(0);
201 checkedSize += (numPaths * pathNameTypeSize);
202 checkedSize += (numPaths * sizeof(GLfloat) * componentCount);
203 if (!checkedSize.IsValid())
204 {
Jamie Madille0472f32018-11-27 16:32:45 -0500205 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300206 return false;
207 }
208
209 return true;
210}
211
Geoff Lang4f0e0032017-05-01 16:04:35 -0400212bool IsValidCopyTextureSourceInternalFormatEnum(GLenum internalFormat)
Geoff Lang97073d12016-04-20 10:42:34 -0700213{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400214 // Table 1.1 from the CHROMIUM_copy_texture spec
Geoff Langca271392017-04-05 12:30:00 -0400215 switch (GetUnsizedFormat(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700216 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400217 case GL_RED:
Geoff Lang97073d12016-04-20 10:42:34 -0700218 case GL_ALPHA:
219 case GL_LUMINANCE:
220 case GL_LUMINANCE_ALPHA:
221 case GL_RGB:
222 case GL_RGBA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400223 case GL_RGB8:
224 case GL_RGBA8:
225 case GL_BGRA_EXT:
226 case GL_BGRA8_EXT:
Geoff Lang97073d12016-04-20 10:42:34 -0700227 return true;
228
Geoff Lang4f0e0032017-05-01 16:04:35 -0400229 default:
230 return false;
231 }
232}
Geoff Lang97073d12016-04-20 10:42:34 -0700233
Geoff Lang4f0e0032017-05-01 16:04:35 -0400234bool IsValidCopySubTextureSourceInternalFormat(GLenum internalFormat)
235{
236 return IsValidCopyTextureSourceInternalFormatEnum(internalFormat);
237}
238
Geoff Lang4f0e0032017-05-01 16:04:35 -0400239bool IsValidCopyTextureDestinationInternalFormatEnum(GLint internalFormat)
240{
241 // Table 1.0 from the CHROMIUM_copy_texture spec
242 switch (internalFormat)
243 {
244 case GL_RGB:
245 case GL_RGBA:
246 case GL_RGB8:
247 case GL_RGBA8:
Geoff Lang97073d12016-04-20 10:42:34 -0700248 case GL_BGRA_EXT:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400249 case GL_BGRA8_EXT:
250 case GL_SRGB_EXT:
251 case GL_SRGB_ALPHA_EXT:
252 case GL_R8:
253 case GL_R8UI:
254 case GL_RG8:
255 case GL_RG8UI:
256 case GL_SRGB8:
257 case GL_RGB565:
258 case GL_RGB8UI:
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400259 case GL_RGB10_A2:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400260 case GL_SRGB8_ALPHA8:
261 case GL_RGB5_A1:
262 case GL_RGBA4:
263 case GL_RGBA8UI:
264 case GL_RGB9_E5:
265 case GL_R16F:
266 case GL_R32F:
267 case GL_RG16F:
268 case GL_RG32F:
269 case GL_RGB16F:
270 case GL_RGB32F:
271 case GL_RGBA16F:
272 case GL_RGBA32F:
273 case GL_R11F_G11F_B10F:
Brandon Jones340b7b82017-06-26 13:02:31 -0700274 case GL_LUMINANCE:
275 case GL_LUMINANCE_ALPHA:
276 case GL_ALPHA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400277 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700278
279 default:
280 return false;
281 }
282}
283
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400284bool IsValidCopySubTextureDestionationInternalFormat(GLenum internalFormat)
285{
286 return IsValidCopyTextureDestinationInternalFormatEnum(internalFormat);
287}
288
Geoff Lang97073d12016-04-20 10:42:34 -0700289bool IsValidCopyTextureDestinationFormatType(Context *context, GLint internalFormat, GLenum type)
290{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400291 if (!IsValidCopyTextureDestinationInternalFormatEnum(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700292 {
Jamie Madille0472f32018-11-27 16:32:45 -0500293 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400294 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700295 }
296
Geoff Langc0094ec2017-08-16 14:16:24 -0400297 if (!ValidES3FormatCombination(GetUnsizedFormat(internalFormat), type, internalFormat))
298 {
Jamie Madille0472f32018-11-27 16:32:45 -0500299 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Langc0094ec2017-08-16 14:16:24 -0400300 return false;
301 }
302
Geoff Lang4f0e0032017-05-01 16:04:35 -0400303 const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat, type);
304 if (!internalFormatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
Geoff Lang97073d12016-04-20 10:42:34 -0700305 {
Jamie Madille0472f32018-11-27 16:32:45 -0500306 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400307 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700308 }
309
310 return true;
311}
312
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800313bool IsValidCopyTextureDestinationTargetEnum(Context *context, TextureTarget target)
Geoff Lang97073d12016-04-20 10:42:34 -0700314{
315 switch (target)
316 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800317 case TextureTarget::_2D:
318 case TextureTarget::CubeMapNegativeX:
319 case TextureTarget::CubeMapNegativeY:
320 case TextureTarget::CubeMapNegativeZ:
321 case TextureTarget::CubeMapPositiveX:
322 case TextureTarget::CubeMapPositiveY:
323 case TextureTarget::CubeMapPositiveZ:
Geoff Lang63458a32017-10-30 15:16:53 -0400324 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700325
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800326 case TextureTarget::Rectangle:
Geoff Lang63458a32017-10-30 15:16:53 -0400327 return context->getExtensions().textureRectangle;
Geoff Lang97073d12016-04-20 10:42:34 -0700328
329 default:
330 return false;
331 }
332}
333
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800334bool IsValidCopyTextureDestinationTarget(Context *context,
335 TextureType textureType,
336 TextureTarget target)
Geoff Lang63458a32017-10-30 15:16:53 -0400337{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800338 return TextureTargetToType(target) == textureType;
Geoff Lang63458a32017-10-30 15:16:53 -0400339}
340
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800341bool IsValidCopyTextureSourceTarget(Context *context, TextureType type)
Geoff Lang97073d12016-04-20 10:42:34 -0700342{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800343 switch (type)
Geoff Lang97073d12016-04-20 10:42:34 -0700344 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800345 case TextureType::_2D:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400346 return true;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800347 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400348 return context->getExtensions().textureRectangle;
Geoff Langbe607ad2018-11-29 10:14:22 -0500349 case TextureType::External:
350 return context->getExtensions().eglImageExternal;
Geoff Lang4f0e0032017-05-01 16:04:35 -0400351 default:
352 return false;
353 }
354}
355
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800356bool IsValidCopyTextureSourceLevel(Context *context, TextureType type, GLint level)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400357{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800358 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400359 {
360 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700361 }
362
Geoff Lang4f0e0032017-05-01 16:04:35 -0400363 if (level > 0 && context->getClientVersion() < ES_3_0)
364 {
365 return false;
366 }
Geoff Lang97073d12016-04-20 10:42:34 -0700367
Geoff Lang4f0e0032017-05-01 16:04:35 -0400368 return true;
369}
370
371bool IsValidCopyTextureDestinationLevel(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800372 TextureType type,
Geoff Lang4f0e0032017-05-01 16:04:35 -0400373 GLint level,
374 GLsizei width,
Brandon Jones28783792018-03-05 09:37:32 -0800375 GLsizei height,
376 bool isSubImage)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400377{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800378 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400379 {
380 return false;
381 }
382
Brandon Jones28783792018-03-05 09:37:32 -0800383 if (!ValidImageSizeParameters(context, type, level, width, height, 1, isSubImage))
384 {
385 return false;
386 }
387
Geoff Lang4f0e0032017-05-01 16:04:35 -0400388 const Caps &caps = context->getCaps();
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800389 switch (type)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400390 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800391 case TextureType::_2D:
392 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
393 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
394 case TextureType::Rectangle:
395 ASSERT(level == 0);
396 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
397 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400398
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800399 case TextureType::CubeMap:
400 return static_cast<GLuint>(width) <= (caps.maxCubeMapTextureSize >> level) &&
401 static_cast<GLuint>(height) <= (caps.maxCubeMapTextureSize >> level);
402 default:
403 return true;
404 }
Geoff Lang97073d12016-04-20 10:42:34 -0700405}
406
Jamie Madillc1d770e2017-04-13 17:31:24 -0400407bool IsValidStencilFunc(GLenum func)
408{
409 switch (func)
410 {
411 case GL_NEVER:
412 case GL_ALWAYS:
413 case GL_LESS:
414 case GL_LEQUAL:
415 case GL_EQUAL:
416 case GL_GEQUAL:
417 case GL_GREATER:
418 case GL_NOTEQUAL:
419 return true;
420
421 default:
422 return false;
423 }
424}
425
426bool IsValidStencilFace(GLenum face)
427{
428 switch (face)
429 {
430 case GL_FRONT:
431 case GL_BACK:
432 case GL_FRONT_AND_BACK:
433 return true;
434
435 default:
436 return false;
437 }
438}
439
440bool IsValidStencilOp(GLenum op)
441{
442 switch (op)
443 {
444 case GL_ZERO:
445 case GL_KEEP:
446 case GL_REPLACE:
447 case GL_INCR:
448 case GL_DECR:
449 case GL_INVERT:
450 case GL_INCR_WRAP:
451 case GL_DECR_WRAP:
452 return true;
453
454 default:
455 return false;
456 }
457}
458
Jamie Madill5b772312018-03-08 20:28:32 -0500459bool ValidateES2CopyTexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800460 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -0400461 GLint level,
462 GLenum internalformat,
463 bool isSubImage,
464 GLint xoffset,
465 GLint yoffset,
466 GLint x,
467 GLint y,
468 GLsizei width,
469 GLsizei height,
470 GLint border)
471{
472 if (!ValidTexture2DDestinationTarget(context, target))
473 {
Jamie Madille0472f32018-11-27 16:32:45 -0500474 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -0400475 return false;
476 }
477
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800478 TextureType texType = TextureTargetToType(target);
479 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Jamie Madillbe849e42017-05-02 15:49:00 -0400480 {
Jamie Madillc3e37312018-11-30 15:25:39 -0500481 // Error is already handled.
Jamie Madillbe849e42017-05-02 15:49:00 -0400482 return false;
483 }
484
485 Format textureFormat = Format::Invalid();
486 if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
487 xoffset, yoffset, 0, x, y, width, height, border,
488 &textureFormat))
489 {
490 return false;
491 }
492
Jamie Madillc3dc5d42018-12-30 12:12:04 -0500493 const gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer();
Jamie Madillbe849e42017-05-02 15:49:00 -0400494 GLenum colorbufferFormat =
495 framebuffer->getReadColorbuffer()->getFormat().info->sizedInternalFormat;
496 const auto &formatInfo = *textureFormat.info;
497
498 // [OpenGL ES 2.0.24] table 3.9
499 if (isSubImage)
500 {
501 switch (formatInfo.format)
502 {
503 case GL_ALPHA:
504 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400505 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
506 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400507 {
Jamie Madille0472f32018-11-27 16:32:45 -0500508 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400509 return false;
510 }
511 break;
512 case GL_LUMINANCE:
513 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
514 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
515 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400516 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGRA8_EXT &&
517 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400518 {
Jamie Madille0472f32018-11-27 16:32:45 -0500519 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400520 return false;
521 }
522 break;
523 case GL_RED_EXT:
524 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
525 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
526 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
527 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_R32F &&
528 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400529 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
530 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400531 {
Jamie Madille0472f32018-11-27 16:32:45 -0500532 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400533 return false;
534 }
535 break;
536 case GL_RG_EXT:
537 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
538 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
539 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
540 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400541 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
542 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400543 {
Jamie Madille0472f32018-11-27 16:32:45 -0500544 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400545 return false;
546 }
547 break;
548 case GL_RGB:
549 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
550 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
551 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400552 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
553 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400554 {
Jamie Madille0472f32018-11-27 16:32:45 -0500555 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400556 return false;
557 }
558 break;
559 case GL_LUMINANCE_ALPHA:
560 case GL_RGBA:
561 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400562 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGBA32F &&
563 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400564 {
Jamie Madille0472f32018-11-27 16:32:45 -0500565 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400566 return false;
567 }
568 break;
569 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
570 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
571 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
572 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
573 case GL_ETC1_RGB8_OES:
574 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
575 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
576 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
577 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
578 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
Olli Etuahof2ed2992018-10-04 13:54:42 +0300579 case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
580 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
581 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
582 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
Jamie Madille0472f32018-11-27 16:32:45 -0500583 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400584 return false;
585 case GL_DEPTH_COMPONENT:
586 case GL_DEPTH_STENCIL_OES:
Jamie Madille0472f32018-11-27 16:32:45 -0500587 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400588 return false;
589 default:
Jamie Madille0472f32018-11-27 16:32:45 -0500590 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400591 return false;
592 }
593
594 if (formatInfo.type == GL_FLOAT && !context->getExtensions().textureFloat)
595 {
Jamie Madille0472f32018-11-27 16:32:45 -0500596 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400597 return false;
598 }
599 }
600 else
601 {
602 switch (internalformat)
603 {
604 case GL_ALPHA:
605 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
606 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
607 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
608 {
Jamie Madille0472f32018-11-27 16:32:45 -0500609 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400610 return false;
611 }
612 break;
613 case GL_LUMINANCE:
614 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
615 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
616 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
617 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
618 colorbufferFormat != GL_BGR5_A1_ANGLEX)
619 {
Jamie Madille0472f32018-11-27 16:32:45 -0500620 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400621 return false;
622 }
623 break;
624 case GL_RED_EXT:
625 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
626 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
627 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
628 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
629 colorbufferFormat != GL_BGR5_A1_ANGLEX)
630 {
Jamie Madille0472f32018-11-27 16:32:45 -0500631 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400632 return false;
633 }
634 break;
635 case GL_RG_EXT:
636 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
637 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
638 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
639 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
640 {
Jamie Madille0472f32018-11-27 16:32:45 -0500641 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400642 return false;
643 }
644 break;
645 case GL_RGB:
646 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
647 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
648 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
649 colorbufferFormat != GL_BGR5_A1_ANGLEX)
650 {
Jamie Madille0472f32018-11-27 16:32:45 -0500651 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400652 return false;
653 }
654 break;
655 case GL_LUMINANCE_ALPHA:
656 case GL_RGBA:
657 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
658 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
659 colorbufferFormat != GL_BGR5_A1_ANGLEX)
660 {
Jamie Madille0472f32018-11-27 16:32:45 -0500661 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400662 return false;
663 }
664 break;
665 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
666 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
667 if (context->getExtensions().textureCompressionDXT1)
668 {
Jamie Madille0472f32018-11-27 16:32:45 -0500669 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400670 return false;
671 }
672 else
673 {
Jamie Madille0472f32018-11-27 16:32:45 -0500674 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400675 return false;
676 }
677 break;
678 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
679 if (context->getExtensions().textureCompressionDXT3)
680 {
Jamie Madille0472f32018-11-27 16:32:45 -0500681 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400682 return false;
683 }
684 else
685 {
Jamie Madille0472f32018-11-27 16:32:45 -0500686 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400687 return false;
688 }
689 break;
690 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
691 if (context->getExtensions().textureCompressionDXT5)
692 {
Jamie Madille0472f32018-11-27 16:32:45 -0500693 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400694 return false;
695 }
696 else
697 {
Jamie Madille0472f32018-11-27 16:32:45 -0500698 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400699 return false;
700 }
701 break;
702 case GL_ETC1_RGB8_OES:
703 if (context->getExtensions().compressedETC1RGB8Texture)
704 {
Jamie Madille0472f32018-11-27 16:32:45 -0500705 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400706 return false;
707 }
708 else
709 {
Jamie Madille0472f32018-11-27 16:32:45 -0500710 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400711 return false;
712 }
713 break;
714 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
715 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
716 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
717 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
718 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
719 if (context->getExtensions().lossyETCDecode)
720 {
Jamie Madillc3e37312018-11-30 15:25:39 -0500721 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400722 return false;
723 }
724 else
725 {
Jamie Madillc3e37312018-11-30 15:25:39 -0500726 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400727 return false;
728 }
729 break;
730 case GL_DEPTH_COMPONENT:
731 case GL_DEPTH_COMPONENT16:
732 case GL_DEPTH_COMPONENT32_OES:
733 case GL_DEPTH_STENCIL_OES:
734 case GL_DEPTH24_STENCIL8_OES:
735 if (context->getExtensions().depthTextures)
736 {
Jamie Madille0472f32018-11-27 16:32:45 -0500737 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400738 return false;
739 }
740 else
741 {
Jamie Madille0472f32018-11-27 16:32:45 -0500742 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400743 return false;
744 }
745 default:
Jamie Madille0472f32018-11-27 16:32:45 -0500746 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400747 return false;
748 }
749 }
750
751 // If width or height is zero, it is a no-op. Return false without setting an error.
752 return (width > 0 && height > 0);
753}
754
755bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
756{
757 switch (cap)
758 {
759 // EXT_multisample_compatibility
760 case GL_MULTISAMPLE_EXT:
761 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
762 return context->getExtensions().multisampleCompatibility;
763
764 case GL_CULL_FACE:
765 case GL_POLYGON_OFFSET_FILL:
766 case GL_SAMPLE_ALPHA_TO_COVERAGE:
767 case GL_SAMPLE_COVERAGE:
768 case GL_SCISSOR_TEST:
769 case GL_STENCIL_TEST:
770 case GL_DEPTH_TEST:
771 case GL_BLEND:
772 case GL_DITHER:
773 return true;
774
775 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
776 case GL_RASTERIZER_DISCARD:
777 return (context->getClientMajorVersion() >= 3);
778
779 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
780 case GL_DEBUG_OUTPUT:
781 return context->getExtensions().debug;
782
783 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
784 return queryOnly && context->getExtensions().bindGeneratesResource;
785
786 case GL_CLIENT_ARRAYS_ANGLE:
787 return queryOnly && context->getExtensions().clientArrays;
788
789 case GL_FRAMEBUFFER_SRGB_EXT:
790 return context->getExtensions().sRGBWriteControl;
791
792 case GL_SAMPLE_MASK:
793 return context->getClientVersion() >= Version(3, 1);
794
Geoff Langb433e872017-10-05 14:01:47 -0400795 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
Jamie Madillbe849e42017-05-02 15:49:00 -0400796 return queryOnly && context->getExtensions().robustResourceInitialization;
797
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700798 // GLES1 emulation: GLES1-specific caps
799 case GL_ALPHA_TEST:
Lingfeng Yang01074432018-04-16 10:19:51 -0700800 case GL_VERTEX_ARRAY:
801 case GL_NORMAL_ARRAY:
802 case GL_COLOR_ARRAY:
803 case GL_TEXTURE_COORD_ARRAY:
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700804 case GL_TEXTURE_2D:
Lingfeng Yangd0febe72018-05-17 22:36:52 -0700805 case GL_LIGHTING:
806 case GL_LIGHT0:
807 case GL_LIGHT1:
808 case GL_LIGHT2:
809 case GL_LIGHT3:
810 case GL_LIGHT4:
811 case GL_LIGHT5:
812 case GL_LIGHT6:
813 case GL_LIGHT7:
814 case GL_NORMALIZE:
815 case GL_RESCALE_NORMAL:
816 case GL_COLOR_MATERIAL:
Lingfeng Yang060088a2018-05-30 20:40:57 -0700817 case GL_CLIP_PLANE0:
818 case GL_CLIP_PLANE1:
819 case GL_CLIP_PLANE2:
820 case GL_CLIP_PLANE3:
821 case GL_CLIP_PLANE4:
822 case GL_CLIP_PLANE5:
Lingfeng Yang7ba3f422018-06-01 09:43:04 -0700823 case GL_FOG:
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700824 case GL_POINT_SMOOTH:
Lingfeng Yang6e5bf362018-08-15 09:53:17 -0700825 case GL_LINE_SMOOTH:
826 case GL_COLOR_LOGIC_OP:
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700827 return context->getClientVersion() < Version(2, 0);
Lingfeng Yang01074432018-04-16 10:19:51 -0700828 case GL_POINT_SIZE_ARRAY_OES:
829 return context->getClientVersion() < Version(2, 0) &&
830 context->getExtensions().pointSizeArray;
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700831 case GL_TEXTURE_CUBE_MAP:
832 return context->getClientVersion() < Version(2, 0) &&
833 context->getExtensions().textureCubeMap;
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700834 case GL_POINT_SPRITE_OES:
835 return context->getClientVersion() < Version(2, 0) &&
836 context->getExtensions().pointSprite;
Jamie Madillbe849e42017-05-02 15:49:00 -0400837 default:
838 return false;
839 }
840}
841
Geoff Langfc32e8b2017-05-31 14:16:59 -0400842// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
843// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400844bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400845{
846 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400847 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
848 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400849 {
850 return true;
851 }
852
853 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
854 if (c >= 9 && c <= 13)
855 {
856 return true;
857 }
858
859 return false;
860}
861
Geoff Langcab92ee2017-07-19 17:32:07 -0400862bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400863{
Geoff Langa71a98e2017-06-19 15:15:00 -0400864 for (size_t i = 0; i < len; i++)
865 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400866 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400867 {
868 return false;
869 }
870 }
871
872 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400873}
874
Geoff Langcab92ee2017-07-19 17:32:07 -0400875bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
876{
877 enum class ParseState
878 {
879 // Have not seen an ASCII non-whitespace character yet on
880 // this line. Possible that we might see a preprocessor
881 // directive.
882 BEGINING_OF_LINE,
883
884 // Have seen at least one ASCII non-whitespace character
885 // on this line.
886 MIDDLE_OF_LINE,
887
888 // Handling a preprocessor directive. Passes through all
889 // characters up to the end of the line. Disables comment
890 // processing.
891 IN_PREPROCESSOR_DIRECTIVE,
892
893 // Handling a single-line comment. The comment text is
894 // replaced with a single space.
895 IN_SINGLE_LINE_COMMENT,
896
897 // Handling a multi-line comment. Newlines are passed
898 // through to preserve line numbers.
899 IN_MULTI_LINE_COMMENT
900 };
901
902 ParseState state = ParseState::BEGINING_OF_LINE;
903 size_t pos = 0;
904
905 while (pos < len)
906 {
907 char c = str[pos];
908 char next = pos + 1 < len ? str[pos + 1] : 0;
909
910 // Check for newlines
911 if (c == '\n' || c == '\r')
912 {
913 if (state != ParseState::IN_MULTI_LINE_COMMENT)
914 {
915 state = ParseState::BEGINING_OF_LINE;
916 }
917
918 pos++;
919 continue;
920 }
921
922 switch (state)
923 {
924 case ParseState::BEGINING_OF_LINE:
925 if (c == ' ')
926 {
927 // Maintain the BEGINING_OF_LINE state until a non-space is seen
928 pos++;
929 }
930 else if (c == '#')
931 {
932 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
933 pos++;
934 }
935 else
936 {
937 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
938 state = ParseState::MIDDLE_OF_LINE;
939 }
940 break;
941
942 case ParseState::MIDDLE_OF_LINE:
943 if (c == '/' && next == '/')
944 {
945 state = ParseState::IN_SINGLE_LINE_COMMENT;
946 pos++;
947 }
948 else if (c == '/' && next == '*')
949 {
950 state = ParseState::IN_MULTI_LINE_COMMENT;
951 pos++;
952 }
953 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
954 {
955 // Skip line continuation characters
956 }
957 else if (!IsValidESSLCharacter(c))
958 {
959 return false;
960 }
961 pos++;
962 break;
963
964 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700965 // Line-continuation characters may not be permitted.
966 // Otherwise, just pass it through. Do not parse comments in this state.
967 if (!lineContinuationAllowed && c == '\\')
968 {
969 return false;
970 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400971 pos++;
972 break;
973
974 case ParseState::IN_SINGLE_LINE_COMMENT:
975 // Line-continuation characters are processed before comment processing.
976 // Advance string if a new line character is immediately behind
977 // line-continuation character.
978 if (c == '\\' && (next == '\n' || next == '\r'))
979 {
980 pos++;
981 }
982 pos++;
983 break;
984
985 case ParseState::IN_MULTI_LINE_COMMENT:
986 if (c == '*' && next == '/')
987 {
988 state = ParseState::MIDDLE_OF_LINE;
989 pos++;
990 }
991 pos++;
992 break;
993 }
994 }
995
996 return true;
997}
998
Jamie Madill5b772312018-03-08 20:28:32 -0500999bool ValidateWebGLNamePrefix(Context *context, const GLchar *name)
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001000{
1001 ASSERT(context->isWebGL());
1002
1003 // WebGL 1.0 [Section 6.16] GLSL Constructs
1004 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
1005 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
1006 {
Jamie Madille0472f32018-11-27 16:32:45 -05001007 context->validationError(GL_INVALID_OPERATION, kWebglBindAttribLocationReservedPrefix);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001008 return false;
1009 }
1010
1011 return true;
1012}
1013
Jamie Madill5b772312018-03-08 20:28:32 -05001014bool ValidateWebGLNameLength(Context *context, size_t length)
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001015{
1016 ASSERT(context->isWebGL());
1017
1018 if (context->isWebGL1() && length > 256)
1019 {
1020 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
1021 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
1022 // locations.
Jamie Madille0472f32018-11-27 16:32:45 -05001023 context->validationError(GL_INVALID_VALUE, kWebglNameLengthLimitExceeded);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001024
1025 return false;
1026 }
1027 else if (length > 1024)
1028 {
1029 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
1030 // uniform and attribute locations.
Jamie Madille0472f32018-11-27 16:32:45 -05001031 context->validationError(GL_INVALID_VALUE, kWebgl2NameLengthLimitExceeded);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001032 return false;
1033 }
1034
1035 return true;
1036}
1037
Jamie Madill007530e2017-12-28 14:27:04 -05001038bool ValidateMatrixMode(Context *context, GLenum matrixMode)
1039{
1040 if (!context->getExtensions().pathRendering)
1041 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001042 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05001043 return false;
1044 }
1045
1046 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
1047 {
Jamie Madille0472f32018-11-27 16:32:45 -05001048 context->validationError(GL_INVALID_ENUM, kInvalidMatrixMode);
Jamie Madill007530e2017-12-28 14:27:04 -05001049 return false;
1050 }
1051 return true;
1052}
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03001053
1054bool ValidBlendFunc(const Context *context, GLenum val)
1055{
1056 const gl::Extensions &ext = context->getExtensions();
1057
1058 // these are always valid for src and dst.
1059 switch (val)
1060 {
1061 case GL_ZERO:
1062 case GL_ONE:
1063 case GL_SRC_COLOR:
1064 case GL_ONE_MINUS_SRC_COLOR:
1065 case GL_DST_COLOR:
1066 case GL_ONE_MINUS_DST_COLOR:
1067 case GL_SRC_ALPHA:
1068 case GL_ONE_MINUS_SRC_ALPHA:
1069 case GL_DST_ALPHA:
1070 case GL_ONE_MINUS_DST_ALPHA:
1071 case GL_CONSTANT_COLOR:
1072 case GL_ONE_MINUS_CONSTANT_COLOR:
1073 case GL_CONSTANT_ALPHA:
1074 case GL_ONE_MINUS_CONSTANT_ALPHA:
1075 return true;
1076
1077 // EXT_blend_func_extended.
1078 case GL_SRC1_COLOR_EXT:
1079 case GL_SRC1_ALPHA_EXT:
1080 case GL_ONE_MINUS_SRC1_COLOR_EXT:
1081 case GL_ONE_MINUS_SRC1_ALPHA_EXT:
1082 case GL_SRC_ALPHA_SATURATE_EXT:
1083 return ext.blendFuncExtended;
1084
1085 default:
1086 return false;
1087 }
1088}
1089
1090bool ValidSrcBlendFunc(const Context *context, GLenum val)
1091{
1092 if (ValidBlendFunc(context, val))
1093 return true;
1094
1095 if (val == GL_SRC_ALPHA_SATURATE)
1096 return true;
1097
1098 return false;
1099}
1100
1101bool ValidDstBlendFunc(const Context *context, GLenum val)
1102{
1103 if (ValidBlendFunc(context, val))
1104 return true;
1105
1106 if (val == GL_SRC_ALPHA_SATURATE)
1107 {
1108 if (context->getClientMajorVersion() >= 3)
1109 return true;
1110 }
1111
1112 return false;
1113}
Jamie Madillc29968b2016-01-20 11:17:23 -05001114} // anonymous namespace
1115
Geoff Langff5b2d52016-09-07 11:32:23 -04001116bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001117 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001118 GLint level,
1119 GLenum internalformat,
1120 bool isCompressed,
1121 bool isSubImage,
1122 GLint xoffset,
1123 GLint yoffset,
1124 GLsizei width,
1125 GLsizei height,
1126 GLint border,
1127 GLenum format,
1128 GLenum type,
1129 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001130 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001131{
Jamie Madill6f38f822014-06-06 17:12:20 -04001132 if (!ValidTexture2DDestinationTarget(context, target))
1133 {
Jamie Madille0472f32018-11-27 16:32:45 -05001134 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001135 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001136 }
1137
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001138 TextureType texType = TextureTargetToType(target);
1139 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001140 {
Jamie Madill610640f2018-11-21 17:28:41 -05001141 // Error already handled.
Geoff Langb1196682014-07-23 13:47:29 -04001142 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001143 }
1144
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001145 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001146 {
Jamie Madille0472f32018-11-27 16:32:45 -05001147 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Brandon Jones6cad5662017-06-14 13:25:13 -07001148 return false;
1149 }
1150
1151 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001152 std::numeric_limits<GLsizei>::max() - yoffset < height)
1153 {
Jamie Madille0472f32018-11-27 16:32:45 -05001154 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001155 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001156 }
1157
Geoff Lang6e898aa2017-06-02 11:17:26 -04001158 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1159 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1160 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1161 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1162 // case.
1163 bool nonEqualFormatsAllowed =
1164 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
1165 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
1166
1167 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001168 {
Jamie Madille0472f32018-11-27 16:32:45 -05001169 context->validationError(GL_INVALID_OPERATION, kInvalidFormatCombination);
Geoff Langb1196682014-07-23 13:47:29 -04001170 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001171 }
1172
Geoff Langaae65a42014-05-26 12:43:44 -04001173 const gl::Caps &caps = context->getCaps();
1174
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001175 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001176 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001177 case TextureType::_2D:
1178 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1179 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1180 {
Jamie Madille0472f32018-11-27 16:32:45 -05001181 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001182 return false;
1183 }
1184 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001185
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001186 case TextureType::Rectangle:
1187 ASSERT(level == 0);
1188 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1189 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1190 {
Jamie Madille0472f32018-11-27 16:32:45 -05001191 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001192 return false;
1193 }
1194 if (isCompressed)
1195 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001196 context->validationError(GL_INVALID_ENUM, kRectangleTextureCompressed);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001197 return false;
1198 }
1199 break;
1200
1201 case TextureType::CubeMap:
1202 if (!isSubImage && width != height)
1203 {
Jamie Madille0472f32018-11-27 16:32:45 -05001204 context->validationError(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001205 return false;
1206 }
1207
1208 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1209 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1210 {
Jamie Madille0472f32018-11-27 16:32:45 -05001211 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001212 return false;
1213 }
1214 break;
1215
1216 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001217 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001218 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001219 }
1220
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001221 gl::Texture *texture = context->getTargetTexture(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001222 if (!texture)
1223 {
Jamie Madille0472f32018-11-27 16:32:45 -05001224 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001225 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001226 }
1227
Geoff Langa9be0dc2014-12-17 12:34:40 -05001228 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001229 {
Geoff Langca271392017-04-05 12:30:00 -04001230 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1231 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001232 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001233 context->validationError(GL_INVALID_OPERATION, kInvalidTextureLevel);
Geoff Langc51642b2016-11-14 16:18:26 -05001234 return false;
1235 }
1236
Geoff Langa9be0dc2014-12-17 12:34:40 -05001237 if (format != GL_NONE)
1238 {
Geoff Langca271392017-04-05 12:30:00 -04001239 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1240 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001241 {
Jamie Madille0472f32018-11-27 16:32:45 -05001242 context->validationError(GL_INVALID_OPERATION, kTypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001243 return false;
1244 }
1245 }
1246
1247 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1248 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1249 {
Jamie Madille0472f32018-11-27 16:32:45 -05001250 context->validationError(GL_INVALID_VALUE, kOffsetOverflow);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001251 return false;
1252 }
Geoff Langfb052642017-10-24 13:42:09 -04001253
1254 if (width > 0 && height > 0 && pixels == nullptr &&
Jamie Madillc3dc5d42018-12-30 12:12:04 -05001255 context->getState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
Geoff Langfb052642017-10-24 13:42:09 -04001256 {
Jamie Madille0472f32018-11-27 16:32:45 -05001257 context->validationError(GL_INVALID_VALUE, kPixelDataNull);
Geoff Langfb052642017-10-24 13:42:09 -04001258 return false;
1259 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001260 }
1261 else
1262 {
Geoff Lang69cce582015-09-17 13:20:36 -04001263 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001264 {
Jamie Madille0472f32018-11-27 16:32:45 -05001265 context->validationError(GL_INVALID_OPERATION, kTextureIsImmutable);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001266 return false;
1267 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001268 }
1269
1270 // Verify zero border
1271 if (border != 0)
1272 {
Jamie Madille0472f32018-11-27 16:32:45 -05001273 context->validationError(GL_INVALID_VALUE, kInvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001274 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001275 }
1276
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001277 if (isCompressed)
1278 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001279 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001280 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1281 : internalformat;
Geoff Lange88e4542018-05-03 15:05:57 -04001282
1283 const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(actualInternalFormat);
1284
1285 if (!internalFormatInfo.compressed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001286 {
Jamie Madille0472f32018-11-27 16:32:45 -05001287 context->validationError(GL_INVALID_ENUM, kInvalidInternalFormat);
Geoff Lange88e4542018-05-03 15:05:57 -04001288 return false;
1289 }
1290
1291 if (!internalFormatInfo.textureSupport(context->getClientVersion(),
1292 context->getExtensions()))
1293 {
Jamie Madille0472f32018-11-27 16:32:45 -05001294 context->validationError(GL_INVALID_ENUM, kInvalidInternalFormat);
Geoff Lange88e4542018-05-03 15:05:57 -04001295 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001296 }
Geoff Lang966c9402017-04-18 12:38:27 -04001297
1298 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001299 {
Geoff Lange88e4542018-05-03 15:05:57 -04001300 // From the OES_compressed_ETC1_RGB8_texture spec:
1301 // INVALID_OPERATION is generated by CompressedTexSubImage2D, TexSubImage2D, or
1302 // CopyTexSubImage2D if the texture image <level> bound to <target> has internal format
1303 // ETC1_RGB8_OES.
1304 if (actualInternalFormat == GL_ETC1_RGB8_OES)
1305 {
Jamie Madille0472f32018-11-27 16:32:45 -05001306 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lange88e4542018-05-03 15:05:57 -04001307 return false;
1308 }
1309
Geoff Lang966c9402017-04-18 12:38:27 -04001310 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1311 height, texture->getWidth(target, level),
1312 texture->getHeight(target, level)))
1313 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001314 context->validationError(GL_INVALID_OPERATION, kInvalidCompressedImageSize);
Geoff Lang966c9402017-04-18 12:38:27 -04001315 return false;
1316 }
1317
1318 if (format != actualInternalFormat)
1319 {
Jamie Madille0472f32018-11-27 16:32:45 -05001320 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001321 return false;
1322 }
1323 }
1324 else
1325 {
1326 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1327 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001328 context->validationError(GL_INVALID_OPERATION, kInvalidCompressedImageSize);
Geoff Lang966c9402017-04-18 12:38:27 -04001329 return false;
1330 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001331 }
1332 }
1333 else
1334 {
1335 // validate <type> by itself (used as secondary key below)
1336 switch (type)
1337 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001338 case GL_UNSIGNED_BYTE:
1339 case GL_UNSIGNED_SHORT_5_6_5:
1340 case GL_UNSIGNED_SHORT_4_4_4_4:
1341 case GL_UNSIGNED_SHORT_5_5_5_1:
1342 case GL_UNSIGNED_SHORT:
1343 case GL_UNSIGNED_INT:
1344 case GL_UNSIGNED_INT_24_8_OES:
1345 case GL_HALF_FLOAT_OES:
1346 case GL_FLOAT:
1347 break;
1348 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001349 context->validationError(GL_INVALID_ENUM, kInvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001350 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001351 }
1352
1353 // validate <format> + <type> combinations
1354 // - invalid <format> -> sets INVALID_ENUM
1355 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1356 switch (format)
1357 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001358 case GL_ALPHA:
1359 case GL_LUMINANCE:
1360 case GL_LUMINANCE_ALPHA:
1361 switch (type)
1362 {
1363 case GL_UNSIGNED_BYTE:
1364 case GL_FLOAT:
1365 case GL_HALF_FLOAT_OES:
1366 break;
1367 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001368 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001369 return false;
1370 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001371 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001372 case GL_RED:
1373 case GL_RG:
1374 if (!context->getExtensions().textureRG)
1375 {
Jamie Madille0472f32018-11-27 16:32:45 -05001376 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001377 return false;
1378 }
1379 switch (type)
1380 {
1381 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001382 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001383 case GL_FLOAT:
1384 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001385 if (!context->getExtensions().textureFloat)
1386 {
Jamie Madille0472f32018-11-27 16:32:45 -05001387 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001388 return false;
1389 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001390 break;
1391 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001392 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001393 return false;
1394 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001395 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001396 case GL_RGB:
1397 switch (type)
1398 {
1399 case GL_UNSIGNED_BYTE:
1400 case GL_UNSIGNED_SHORT_5_6_5:
1401 case GL_FLOAT:
1402 case GL_HALF_FLOAT_OES:
1403 break;
1404 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001405 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001406 return false;
1407 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001408 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001409 case GL_RGBA:
1410 switch (type)
1411 {
1412 case GL_UNSIGNED_BYTE:
1413 case GL_UNSIGNED_SHORT_4_4_4_4:
1414 case GL_UNSIGNED_SHORT_5_5_5_1:
1415 case GL_FLOAT:
1416 case GL_HALF_FLOAT_OES:
1417 break;
1418 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001419 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001420 return false;
1421 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001422 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001423 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001424 if (!context->getExtensions().textureFormatBGRA8888)
1425 {
Jamie Madille0472f32018-11-27 16:32:45 -05001426 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001427 return false;
1428 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001429 switch (type)
1430 {
1431 case GL_UNSIGNED_BYTE:
1432 break;
1433 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001434 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001435 return false;
1436 }
1437 break;
1438 case GL_SRGB_EXT:
1439 case GL_SRGB_ALPHA_EXT:
1440 if (!context->getExtensions().sRGB)
1441 {
Jamie Madille0472f32018-11-27 16:32:45 -05001442 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001443 return false;
1444 }
1445 switch (type)
1446 {
1447 case GL_UNSIGNED_BYTE:
1448 break;
1449 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001450 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001451 return false;
1452 }
1453 break;
1454 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1455 // handled below
1456 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1457 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1458 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1459 break;
1460 case GL_DEPTH_COMPONENT:
1461 switch (type)
1462 {
1463 case GL_UNSIGNED_SHORT:
1464 case GL_UNSIGNED_INT:
1465 break;
1466 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001467 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001468 return false;
1469 }
1470 break;
1471 case GL_DEPTH_STENCIL_OES:
1472 switch (type)
1473 {
1474 case GL_UNSIGNED_INT_24_8_OES:
1475 break;
1476 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001477 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001478 return false;
1479 }
1480 break;
1481 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001482 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001483 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001484 }
1485
1486 switch (format)
1487 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001488 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1489 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1490 if (context->getExtensions().textureCompressionDXT1)
1491 {
Jamie Madille0472f32018-11-27 16:32:45 -05001492 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001493 return false;
1494 }
1495 else
1496 {
Jamie Madille0472f32018-11-27 16:32:45 -05001497 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001498 return false;
1499 }
1500 break;
1501 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1502 if (context->getExtensions().textureCompressionDXT3)
1503 {
Jamie Madille0472f32018-11-27 16:32:45 -05001504 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001505 return false;
1506 }
1507 else
1508 {
Jamie Madille0472f32018-11-27 16:32:45 -05001509 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001510 return false;
1511 }
1512 break;
1513 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1514 if (context->getExtensions().textureCompressionDXT5)
1515 {
Jamie Madille0472f32018-11-27 16:32:45 -05001516 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001517 return false;
1518 }
1519 else
1520 {
Jamie Madille0472f32018-11-27 16:32:45 -05001521 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001522 return false;
1523 }
1524 break;
1525 case GL_ETC1_RGB8_OES:
1526 if (context->getExtensions().compressedETC1RGB8Texture)
1527 {
Jamie Madille0472f32018-11-27 16:32:45 -05001528 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001529 return false;
1530 }
1531 else
1532 {
Jamie Madille0472f32018-11-27 16:32:45 -05001533 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001534 return false;
1535 }
1536 break;
1537 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001538 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1539 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1540 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1541 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001542 if (context->getExtensions().lossyETCDecode)
1543 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001544 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001545 return false;
1546 }
1547 else
1548 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001549 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001550 return false;
1551 }
1552 break;
1553 case GL_DEPTH_COMPONENT:
1554 case GL_DEPTH_STENCIL_OES:
1555 if (!context->getExtensions().depthTextures)
1556 {
Jamie Madille0472f32018-11-27 16:32:45 -05001557 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001558 return false;
1559 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001560 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001561 {
Jamie Madille0472f32018-11-27 16:32:45 -05001562 context->validationError(GL_INVALID_OPERATION, kMismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001563 return false;
1564 }
1565 // OES_depth_texture supports loading depth data and multiple levels,
1566 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001567 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001568 {
Jamie Madille0472f32018-11-27 16:32:45 -05001569 context->validationError(GL_INVALID_OPERATION, kPixelDataNotNull);
Brandon Jonesafa75152017-07-21 13:11:29 -07001570 return false;
1571 }
1572 if (level != 0)
1573 {
Jamie Madille0472f32018-11-27 16:32:45 -05001574 context->validationError(GL_INVALID_OPERATION, kLevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001575 return false;
1576 }
1577 break;
1578 default:
1579 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001580 }
1581
Geoff Lang6e898aa2017-06-02 11:17:26 -04001582 if (!isSubImage)
1583 {
1584 switch (internalformat)
1585 {
1586 case GL_RGBA32F:
1587 if (!context->getExtensions().colorBufferFloatRGBA)
1588 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001589 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001590 return false;
1591 }
1592 if (type != GL_FLOAT)
1593 {
Jamie Madille0472f32018-11-27 16:32:45 -05001594 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001595 return false;
1596 }
1597 if (format != GL_RGBA)
1598 {
Jamie Madille0472f32018-11-27 16:32:45 -05001599 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001600 return false;
1601 }
1602 break;
1603
1604 case GL_RGB32F:
1605 if (!context->getExtensions().colorBufferFloatRGB)
1606 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001607 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001608 return false;
1609 }
1610 if (type != GL_FLOAT)
1611 {
Jamie Madille0472f32018-11-27 16:32:45 -05001612 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001613 return false;
1614 }
1615 if (format != GL_RGB)
1616 {
Jamie Madille0472f32018-11-27 16:32:45 -05001617 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001618 return false;
1619 }
1620 break;
1621
1622 default:
1623 break;
1624 }
1625 }
1626
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001627 if (type == GL_FLOAT)
1628 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001629 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001630 {
Jamie Madille0472f32018-11-27 16:32:45 -05001631 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001632 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001633 }
1634 }
1635 else if (type == GL_HALF_FLOAT_OES)
1636 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001637 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001638 {
Jamie Madille0472f32018-11-27 16:32:45 -05001639 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001640 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001641 }
1642 }
1643 }
1644
Geoff Langdbcced82017-06-06 15:55:54 -04001645 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001646 if (!ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001647 imageSize))
1648 {
1649 return false;
1650 }
1651
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001652 return true;
1653}
1654
He Yunchaoced53ae2016-11-29 15:00:51 +08001655bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001656 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001657 GLsizei levels,
1658 GLenum internalformat,
1659 GLsizei width,
1660 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001661{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001662 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1663 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001664 {
Jamie Madille0472f32018-11-27 16:32:45 -05001665 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001666 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001667 }
1668
1669 if (width < 1 || height < 1 || levels < 1)
1670 {
Jamie Madille0472f32018-11-27 16:32:45 -05001671 context->validationError(GL_INVALID_VALUE, kTextureSizeTooSmall);
Geoff Langb1196682014-07-23 13:47:29 -04001672 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001673 }
1674
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001675 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001676 {
Jamie Madille0472f32018-11-27 16:32:45 -05001677 context->validationError(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
Geoff Langb1196682014-07-23 13:47:29 -04001678 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001679 }
1680
1681 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1682 {
Jamie Madille0472f32018-11-27 16:32:45 -05001683 context->validationError(GL_INVALID_OPERATION, kInvalidMipLevels);
Geoff Langb1196682014-07-23 13:47:29 -04001684 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001685 }
1686
Geoff Langca271392017-04-05 12:30:00 -04001687 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001688 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001689 {
Jamie Madille0472f32018-11-27 16:32:45 -05001690 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001691 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001692 }
1693
Geoff Langaae65a42014-05-26 12:43:44 -04001694 const gl::Caps &caps = context->getCaps();
1695
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001696 switch (target)
1697 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001698 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001699 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1700 static_cast<GLuint>(height) > caps.max2DTextureSize)
1701 {
Jamie Madille0472f32018-11-27 16:32:45 -05001702 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
He Yunchaoced53ae2016-11-29 15:00:51 +08001703 return false;
1704 }
1705 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001706 case TextureType::Rectangle:
Jamie Madill610640f2018-11-21 17:28:41 -05001707 if (levels != 1)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001708 {
Jamie Madille0472f32018-11-27 16:32:45 -05001709 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madill610640f2018-11-21 17:28:41 -05001710 return false;
1711 }
1712
1713 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1714 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1715 {
Jamie Madille0472f32018-11-27 16:32:45 -05001716 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001717 return false;
1718 }
1719 if (formatInfo.compressed)
1720 {
Jamie Madille0472f32018-11-27 16:32:45 -05001721 context->validationError(GL_INVALID_ENUM, kRectangleTextureCompressed);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001722 return false;
1723 }
1724 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001725 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001726 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1727 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1728 {
Jamie Madille0472f32018-11-27 16:32:45 -05001729 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
He Yunchaoced53ae2016-11-29 15:00:51 +08001730 return false;
1731 }
1732 break;
1733 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001734 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001735 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001736 }
1737
Geoff Langc0b9ef42014-07-02 10:02:37 -04001738 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001739 {
1740 if (!gl::isPow2(width) || !gl::isPow2(height))
1741 {
Jamie Madille0472f32018-11-27 16:32:45 -05001742 context->validationError(GL_INVALID_OPERATION, kDimensionsMustBePow2);
Geoff Langb1196682014-07-23 13:47:29 -04001743 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001744 }
1745 }
1746
1747 switch (internalformat)
1748 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001749 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1750 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1751 if (!context->getExtensions().textureCompressionDXT1)
1752 {
Jamie Madille0472f32018-11-27 16:32:45 -05001753 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001754 return false;
1755 }
1756 break;
1757 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1758 if (!context->getExtensions().textureCompressionDXT3)
1759 {
Jamie Madille0472f32018-11-27 16:32:45 -05001760 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001761 return false;
1762 }
1763 break;
1764 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1765 if (!context->getExtensions().textureCompressionDXT5)
1766 {
Jamie Madille0472f32018-11-27 16:32:45 -05001767 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001768 return false;
1769 }
1770 break;
1771 case GL_ETC1_RGB8_OES:
1772 if (!context->getExtensions().compressedETC1RGB8Texture)
1773 {
Jamie Madille0472f32018-11-27 16:32:45 -05001774 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001775 return false;
1776 }
1777 break;
1778 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001779 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1780 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1781 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1782 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001783 if (!context->getExtensions().lossyETCDecode)
1784 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001785 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001786 return false;
1787 }
1788 break;
1789 case GL_RGBA32F_EXT:
1790 case GL_RGB32F_EXT:
1791 case GL_ALPHA32F_EXT:
1792 case GL_LUMINANCE32F_EXT:
1793 case GL_LUMINANCE_ALPHA32F_EXT:
1794 if (!context->getExtensions().textureFloat)
1795 {
Jamie Madille0472f32018-11-27 16:32:45 -05001796 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001797 return false;
1798 }
1799 break;
1800 case GL_RGBA16F_EXT:
1801 case GL_RGB16F_EXT:
1802 case GL_ALPHA16F_EXT:
1803 case GL_LUMINANCE16F_EXT:
1804 case GL_LUMINANCE_ALPHA16F_EXT:
1805 if (!context->getExtensions().textureHalfFloat)
1806 {
Jamie Madille0472f32018-11-27 16:32:45 -05001807 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001808 return false;
1809 }
1810 break;
1811 case GL_R8_EXT:
1812 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001813 if (!context->getExtensions().textureRG)
1814 {
Jamie Madille0472f32018-11-27 16:32:45 -05001815 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang677bb6f2017-04-05 12:40:40 -04001816 return false;
1817 }
1818 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001819 case GL_R16F_EXT:
1820 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001821 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1822 {
Jamie Madille0472f32018-11-27 16:32:45 -05001823 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang677bb6f2017-04-05 12:40:40 -04001824 return false;
1825 }
1826 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001827 case GL_R32F_EXT:
1828 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001829 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001830 {
Jamie Madille0472f32018-11-27 16:32:45 -05001831 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001832 return false;
1833 }
1834 break;
1835 case GL_DEPTH_COMPONENT16:
1836 case GL_DEPTH_COMPONENT32_OES:
1837 case GL_DEPTH24_STENCIL8_OES:
1838 if (!context->getExtensions().depthTextures)
1839 {
Jamie Madille0472f32018-11-27 16:32:45 -05001840 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001841 return false;
1842 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001843 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001844 {
Jamie Madille0472f32018-11-27 16:32:45 -05001845 context->validationError(GL_INVALID_OPERATION, kInvalidTextureTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001846 return false;
1847 }
1848 // ANGLE_depth_texture only supports 1-level textures
1849 if (levels != 1)
1850 {
Jamie Madille0472f32018-11-27 16:32:45 -05001851 context->validationError(GL_INVALID_OPERATION, kInvalidMipLevels);
He Yunchaoced53ae2016-11-29 15:00:51 +08001852 return false;
1853 }
1854 break;
1855 default:
1856 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001857 }
1858
Geoff Lang691e58c2014-12-19 17:03:25 -05001859 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001860 if (!texture || texture->id() == 0)
1861 {
Jamie Madille0472f32018-11-27 16:32:45 -05001862 context->validationError(GL_INVALID_OPERATION, kMissingTexture);
Geoff Langb1196682014-07-23 13:47:29 -04001863 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001864 }
1865
Geoff Lang69cce582015-09-17 13:20:36 -04001866 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001867 {
Jamie Madille0472f32018-11-27 16:32:45 -05001868 context->validationError(GL_INVALID_OPERATION, kTextureIsImmutable);
Geoff Langb1196682014-07-23 13:47:29 -04001869 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001870 }
1871
1872 return true;
1873}
1874
He Yunchaoced53ae2016-11-29 15:00:51 +08001875bool ValidateDiscardFramebufferEXT(Context *context,
1876 GLenum target,
1877 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001878 const GLenum *attachments)
1879{
Jamie Madillc29968b2016-01-20 11:17:23 -05001880 if (!context->getExtensions().discardFramebuffer)
1881 {
Jamie Madille0472f32018-11-27 16:32:45 -05001882 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001883 return false;
1884 }
1885
Austin Kinross08332632015-05-05 13:35:47 -07001886 bool defaultFramebuffer = false;
1887
1888 switch (target)
1889 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001890 case GL_FRAMEBUFFER:
1891 defaultFramebuffer =
Jamie Madillc3dc5d42018-12-30 12:12:04 -05001892 (context->getState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
He Yunchaoced53ae2016-11-29 15:00:51 +08001893 break;
1894 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001895 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001896 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001897 }
1898
He Yunchaoced53ae2016-11-29 15:00:51 +08001899 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1900 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001901}
1902
Austin Kinrossbc781f32015-10-26 09:27:38 -07001903bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1904{
1905 if (!context->getExtensions().vertexArrayObject)
1906 {
Jamie Madille0472f32018-11-27 16:32:45 -05001907 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001908 return false;
1909 }
1910
1911 return ValidateBindVertexArrayBase(context, array);
1912}
1913
Jamie Madilld7576732017-08-26 18:49:50 -04001914bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001915{
1916 if (!context->getExtensions().vertexArrayObject)
1917 {
Jamie Madille0472f32018-11-27 16:32:45 -05001918 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001919 return false;
1920 }
1921
Olli Etuaho41997e72016-03-10 13:38:39 +02001922 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001923}
1924
Jamie Madilld7576732017-08-26 18:49:50 -04001925bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001926{
1927 if (!context->getExtensions().vertexArrayObject)
1928 {
Jamie Madille0472f32018-11-27 16:32:45 -05001929 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001930 return false;
1931 }
1932
Olli Etuaho41997e72016-03-10 13:38:39 +02001933 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001934}
1935
Jamie Madilld7576732017-08-26 18:49:50 -04001936bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001937{
1938 if (!context->getExtensions().vertexArrayObject)
1939 {
Jamie Madille0472f32018-11-27 16:32:45 -05001940 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001941 return false;
1942 }
1943
1944 return true;
1945}
Geoff Langc5629752015-12-07 16:29:04 -05001946
1947bool ValidateProgramBinaryOES(Context *context,
1948 GLuint program,
1949 GLenum binaryFormat,
1950 const void *binary,
1951 GLint length)
1952{
1953 if (!context->getExtensions().getProgramBinary)
1954 {
Jamie Madille0472f32018-11-27 16:32:45 -05001955 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001956 return false;
1957 }
1958
1959 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
1960}
1961
1962bool ValidateGetProgramBinaryOES(Context *context,
1963 GLuint program,
1964 GLsizei bufSize,
1965 GLsizei *length,
1966 GLenum *binaryFormat,
1967 void *binary)
1968{
1969 if (!context->getExtensions().getProgramBinary)
1970 {
Jamie Madille0472f32018-11-27 16:32:45 -05001971 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001972 return false;
1973 }
1974
1975 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
1976}
Geoff Lange102fee2015-12-10 11:23:30 -05001977
Geoff Lang70d0f492015-12-10 17:45:46 -05001978static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
1979{
1980 switch (source)
1981 {
1982 case GL_DEBUG_SOURCE_API:
1983 case GL_DEBUG_SOURCE_SHADER_COMPILER:
1984 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1985 case GL_DEBUG_SOURCE_OTHER:
1986 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
1987 return !mustBeThirdPartyOrApplication;
1988
1989 case GL_DEBUG_SOURCE_THIRD_PARTY:
1990 case GL_DEBUG_SOURCE_APPLICATION:
1991 return true;
1992
1993 default:
1994 return false;
1995 }
1996}
1997
1998static bool ValidDebugType(GLenum type)
1999{
2000 switch (type)
2001 {
2002 case GL_DEBUG_TYPE_ERROR:
2003 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
2004 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
2005 case GL_DEBUG_TYPE_PERFORMANCE:
2006 case GL_DEBUG_TYPE_PORTABILITY:
2007 case GL_DEBUG_TYPE_OTHER:
2008 case GL_DEBUG_TYPE_MARKER:
2009 case GL_DEBUG_TYPE_PUSH_GROUP:
2010 case GL_DEBUG_TYPE_POP_GROUP:
2011 return true;
2012
2013 default:
2014 return false;
2015 }
2016}
2017
2018static bool ValidDebugSeverity(GLenum severity)
2019{
2020 switch (severity)
2021 {
2022 case GL_DEBUG_SEVERITY_HIGH:
2023 case GL_DEBUG_SEVERITY_MEDIUM:
2024 case GL_DEBUG_SEVERITY_LOW:
2025 case GL_DEBUG_SEVERITY_NOTIFICATION:
2026 return true;
2027
2028 default:
2029 return false;
2030 }
2031}
2032
Geoff Lange102fee2015-12-10 11:23:30 -05002033bool ValidateDebugMessageControlKHR(Context *context,
2034 GLenum source,
2035 GLenum type,
2036 GLenum severity,
2037 GLsizei count,
2038 const GLuint *ids,
2039 GLboolean enabled)
2040{
2041 if (!context->getExtensions().debug)
2042 {
Jamie Madille0472f32018-11-27 16:32:45 -05002043 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002044 return false;
2045 }
2046
Geoff Lang70d0f492015-12-10 17:45:46 -05002047 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
2048 {
Jamie Madille0472f32018-11-27 16:32:45 -05002049 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002050 return false;
2051 }
2052
2053 if (!ValidDebugType(type) && type != GL_DONT_CARE)
2054 {
Jamie Madille0472f32018-11-27 16:32:45 -05002055 context->validationError(GL_INVALID_ENUM, kInvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002056 return false;
2057 }
2058
2059 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
2060 {
Jamie Madille0472f32018-11-27 16:32:45 -05002061 context->validationError(GL_INVALID_ENUM, kInvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05002062 return false;
2063 }
2064
2065 if (count > 0)
2066 {
2067 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
2068 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002069 context->validationError(GL_INVALID_OPERATION, kInvalidDebugSourceType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002070 return false;
2071 }
2072
2073 if (severity != GL_DONT_CARE)
2074 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002075 context->validationError(GL_INVALID_OPERATION, kInvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05002076 return false;
2077 }
2078 }
2079
Geoff Lange102fee2015-12-10 11:23:30 -05002080 return true;
2081}
2082
2083bool ValidateDebugMessageInsertKHR(Context *context,
2084 GLenum source,
2085 GLenum type,
2086 GLuint id,
2087 GLenum severity,
2088 GLsizei length,
2089 const GLchar *buf)
2090{
2091 if (!context->getExtensions().debug)
2092 {
Jamie Madille0472f32018-11-27 16:32:45 -05002093 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002094 return false;
2095 }
2096
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002097 if (!context->getState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002098 {
2099 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2100 // not generate an error.
2101 return false;
2102 }
2103
2104 if (!ValidDebugSeverity(severity))
2105 {
Jamie Madille0472f32018-11-27 16:32:45 -05002106 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002107 return false;
2108 }
2109
2110 if (!ValidDebugType(type))
2111 {
Jamie Madille0472f32018-11-27 16:32:45 -05002112 context->validationError(GL_INVALID_ENUM, kInvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002113 return false;
2114 }
2115
2116 if (!ValidDebugSource(source, true))
2117 {
Jamie Madille0472f32018-11-27 16:32:45 -05002118 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002119 return false;
2120 }
2121
2122 size_t messageLength = (length < 0) ? strlen(buf) : length;
2123 if (messageLength > context->getExtensions().maxDebugMessageLength)
2124 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002125 context->validationError(GL_INVALID_VALUE, kExceedsMaxDebugMessageLength);
Geoff Lang70d0f492015-12-10 17:45:46 -05002126 return false;
2127 }
2128
Geoff Lange102fee2015-12-10 11:23:30 -05002129 return true;
2130}
2131
2132bool ValidateDebugMessageCallbackKHR(Context *context,
2133 GLDEBUGPROCKHR callback,
2134 const void *userParam)
2135{
2136 if (!context->getExtensions().debug)
2137 {
Jamie Madille0472f32018-11-27 16:32:45 -05002138 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002139 return false;
2140 }
2141
Geoff Lange102fee2015-12-10 11:23:30 -05002142 return true;
2143}
2144
2145bool ValidateGetDebugMessageLogKHR(Context *context,
2146 GLuint count,
2147 GLsizei bufSize,
2148 GLenum *sources,
2149 GLenum *types,
2150 GLuint *ids,
2151 GLenum *severities,
2152 GLsizei *lengths,
2153 GLchar *messageLog)
2154{
2155 if (!context->getExtensions().debug)
2156 {
Jamie Madille0472f32018-11-27 16:32:45 -05002157 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002158 return false;
2159 }
2160
Geoff Lang70d0f492015-12-10 17:45:46 -05002161 if (bufSize < 0 && messageLog != nullptr)
2162 {
Jamie Madille0472f32018-11-27 16:32:45 -05002163 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002164 return false;
2165 }
2166
Geoff Lange102fee2015-12-10 11:23:30 -05002167 return true;
2168}
2169
2170bool ValidatePushDebugGroupKHR(Context *context,
2171 GLenum source,
2172 GLuint id,
2173 GLsizei length,
2174 const GLchar *message)
2175{
2176 if (!context->getExtensions().debug)
2177 {
Jamie Madille0472f32018-11-27 16:32:45 -05002178 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002179 return false;
2180 }
2181
Geoff Lang70d0f492015-12-10 17:45:46 -05002182 if (!ValidDebugSource(source, true))
2183 {
Jamie Madille0472f32018-11-27 16:32:45 -05002184 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002185 return false;
2186 }
2187
2188 size_t messageLength = (length < 0) ? strlen(message) : length;
2189 if (messageLength > context->getExtensions().maxDebugMessageLength)
2190 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002191 context->validationError(GL_INVALID_VALUE, kExceedsMaxDebugMessageLength);
Geoff Lang70d0f492015-12-10 17:45:46 -05002192 return false;
2193 }
2194
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002195 size_t currentStackSize = context->getState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002196 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2197 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002198 context->validationError(GL_STACK_OVERFLOW, kExceedsMaxDebugGroupStackDepth);
Geoff Lang70d0f492015-12-10 17:45:46 -05002199 return false;
2200 }
2201
Geoff Lange102fee2015-12-10 11:23:30 -05002202 return true;
2203}
2204
2205bool ValidatePopDebugGroupKHR(Context *context)
2206{
2207 if (!context->getExtensions().debug)
2208 {
Jamie Madille0472f32018-11-27 16:32:45 -05002209 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002210 return false;
2211 }
2212
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002213 size_t currentStackSize = context->getState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002214 if (currentStackSize <= 1)
2215 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002216 context->validationError(GL_STACK_UNDERFLOW, kCannotPopDefaultDebugGroup);
Geoff Lang70d0f492015-12-10 17:45:46 -05002217 return false;
2218 }
2219
2220 return true;
2221}
2222
2223static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2224{
2225 switch (identifier)
2226 {
2227 case GL_BUFFER:
2228 if (context->getBuffer(name) == nullptr)
2229 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002230 context->validationError(GL_INVALID_VALUE, kInvalidBufferName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002231 return false;
2232 }
2233 return true;
2234
2235 case GL_SHADER:
2236 if (context->getShader(name) == nullptr)
2237 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002238 context->validationError(GL_INVALID_VALUE, kInvalidShaderName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002239 return false;
2240 }
2241 return true;
2242
2243 case GL_PROGRAM:
Jamie Madill44a6fbf2018-10-02 13:38:56 -04002244 if (context->getProgramNoResolveLink(name) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002245 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002246 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002247 return false;
2248 }
2249 return true;
2250
2251 case GL_VERTEX_ARRAY:
2252 if (context->getVertexArray(name) == nullptr)
2253 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002254 context->validationError(GL_INVALID_VALUE, kInvalidVertexArrayName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002255 return false;
2256 }
2257 return true;
2258
2259 case GL_QUERY:
2260 if (context->getQuery(name) == nullptr)
2261 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002262 context->validationError(GL_INVALID_VALUE, kInvalidQueryName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002263 return false;
2264 }
2265 return true;
2266
2267 case GL_TRANSFORM_FEEDBACK:
2268 if (context->getTransformFeedback(name) == nullptr)
2269 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002270 context->validationError(GL_INVALID_VALUE, kInvalidTransformFeedbackName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002271 return false;
2272 }
2273 return true;
2274
2275 case GL_SAMPLER:
2276 if (context->getSampler(name) == nullptr)
2277 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002278 context->validationError(GL_INVALID_VALUE, kInvalidSamplerName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002279 return false;
2280 }
2281 return true;
2282
2283 case GL_TEXTURE:
2284 if (context->getTexture(name) == nullptr)
2285 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002286 context->validationError(GL_INVALID_VALUE, kInvalidTextureName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002287 return false;
2288 }
2289 return true;
2290
2291 case GL_RENDERBUFFER:
2292 if (context->getRenderbuffer(name) == nullptr)
2293 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002294 context->validationError(GL_INVALID_VALUE, kInvalidRenderbufferName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002295 return false;
2296 }
2297 return true;
2298
2299 case GL_FRAMEBUFFER:
2300 if (context->getFramebuffer(name) == nullptr)
2301 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002302 context->validationError(GL_INVALID_VALUE, kInvalidFramebufferName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002303 return false;
2304 }
2305 return true;
2306
2307 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05002308 context->validationError(GL_INVALID_ENUM, kInvalidIndentifier);
Geoff Lang70d0f492015-12-10 17:45:46 -05002309 return false;
2310 }
Geoff Lange102fee2015-12-10 11:23:30 -05002311}
2312
Martin Radev9d901792016-07-15 15:58:58 +03002313static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2314{
2315 size_t labelLength = 0;
2316
2317 if (length < 0)
2318 {
2319 if (label != nullptr)
2320 {
2321 labelLength = strlen(label);
2322 }
2323 }
2324 else
2325 {
2326 labelLength = static_cast<size_t>(length);
2327 }
2328
2329 if (labelLength > context->getExtensions().maxLabelLength)
2330 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002331 context->validationError(GL_INVALID_VALUE, kExceedsMaxLabelLength);
Martin Radev9d901792016-07-15 15:58:58 +03002332 return false;
2333 }
2334
2335 return true;
2336}
2337
Geoff Lange102fee2015-12-10 11:23:30 -05002338bool ValidateObjectLabelKHR(Context *context,
2339 GLenum identifier,
2340 GLuint name,
2341 GLsizei length,
2342 const GLchar *label)
2343{
2344 if (!context->getExtensions().debug)
2345 {
Jamie Madille0472f32018-11-27 16:32:45 -05002346 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002347 return false;
2348 }
2349
Geoff Lang70d0f492015-12-10 17:45:46 -05002350 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2351 {
2352 return false;
2353 }
2354
Martin Radev9d901792016-07-15 15:58:58 +03002355 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002356 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002357 return false;
2358 }
2359
Geoff Lange102fee2015-12-10 11:23:30 -05002360 return true;
2361}
2362
2363bool ValidateGetObjectLabelKHR(Context *context,
2364 GLenum identifier,
2365 GLuint name,
2366 GLsizei bufSize,
2367 GLsizei *length,
2368 GLchar *label)
2369{
2370 if (!context->getExtensions().debug)
2371 {
Jamie Madille0472f32018-11-27 16:32:45 -05002372 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002373 return false;
2374 }
2375
Geoff Lang70d0f492015-12-10 17:45:46 -05002376 if (bufSize < 0)
2377 {
Jamie Madille0472f32018-11-27 16:32:45 -05002378 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002379 return false;
2380 }
2381
2382 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2383 {
2384 return false;
2385 }
2386
Martin Radev9d901792016-07-15 15:58:58 +03002387 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002388}
2389
2390static bool ValidateObjectPtrName(Context *context, const void *ptr)
2391{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002392 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002393 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002394 context->validationError(GL_INVALID_VALUE, kInvalidSyncPointer);
Geoff Lang70d0f492015-12-10 17:45:46 -05002395 return false;
2396 }
2397
Geoff Lange102fee2015-12-10 11:23:30 -05002398 return true;
2399}
2400
2401bool ValidateObjectPtrLabelKHR(Context *context,
2402 const void *ptr,
2403 GLsizei length,
2404 const GLchar *label)
2405{
2406 if (!context->getExtensions().debug)
2407 {
Jamie Madille0472f32018-11-27 16:32:45 -05002408 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002409 return false;
2410 }
2411
Geoff Lang70d0f492015-12-10 17:45:46 -05002412 if (!ValidateObjectPtrName(context, ptr))
2413 {
2414 return false;
2415 }
2416
Martin Radev9d901792016-07-15 15:58:58 +03002417 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002418 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002419 return false;
2420 }
2421
Geoff Lange102fee2015-12-10 11:23:30 -05002422 return true;
2423}
2424
2425bool ValidateGetObjectPtrLabelKHR(Context *context,
2426 const void *ptr,
2427 GLsizei bufSize,
2428 GLsizei *length,
2429 GLchar *label)
2430{
2431 if (!context->getExtensions().debug)
2432 {
Jamie Madille0472f32018-11-27 16:32:45 -05002433 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002434 return false;
2435 }
2436
Geoff Lang70d0f492015-12-10 17:45:46 -05002437 if (bufSize < 0)
2438 {
Jamie Madille0472f32018-11-27 16:32:45 -05002439 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002440 return false;
2441 }
2442
2443 if (!ValidateObjectPtrName(context, ptr))
2444 {
2445 return false;
2446 }
2447
Martin Radev9d901792016-07-15 15:58:58 +03002448 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002449}
2450
2451bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2452{
2453 if (!context->getExtensions().debug)
2454 {
Jamie Madille0472f32018-11-27 16:32:45 -05002455 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002456 return false;
2457 }
2458
Geoff Lang70d0f492015-12-10 17:45:46 -05002459 // TODO: represent this in Context::getQueryParameterInfo.
2460 switch (pname)
2461 {
2462 case GL_DEBUG_CALLBACK_FUNCTION:
2463 case GL_DEBUG_CALLBACK_USER_PARAM:
2464 break;
2465
2466 default:
Jamie Madille0472f32018-11-27 16:32:45 -05002467 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002468 return false;
2469 }
2470
Geoff Lange102fee2015-12-10 11:23:30 -05002471 return true;
2472}
Jamie Madillc29968b2016-01-20 11:17:23 -05002473
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07002474bool ValidateGetPointervRobustANGLERobustANGLE(Context *context,
2475 GLenum pname,
2476 GLsizei bufSize,
2477 GLsizei *length,
2478 void **params)
2479{
2480 UNIMPLEMENTED();
2481 return false;
2482}
2483
Jamie Madillc29968b2016-01-20 11:17:23 -05002484bool ValidateBlitFramebufferANGLE(Context *context,
2485 GLint srcX0,
2486 GLint srcY0,
2487 GLint srcX1,
2488 GLint srcY1,
2489 GLint dstX0,
2490 GLint dstY0,
2491 GLint dstX1,
2492 GLint dstY1,
2493 GLbitfield mask,
2494 GLenum filter)
2495{
2496 if (!context->getExtensions().framebufferBlit)
2497 {
Jamie Madille0472f32018-11-27 16:32:45 -05002498 context->validationError(GL_INVALID_OPERATION, kBlitExtensionNotAvailable);
Jamie Madillc29968b2016-01-20 11:17:23 -05002499 return false;
2500 }
2501
2502 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2503 {
2504 // TODO(jmadill): Determine if this should be available on other implementations.
Jamie Madille0472f32018-11-27 16:32:45 -05002505 context->validationError(GL_INVALID_OPERATION, kBlitExtensionScaleOrFlip);
Jamie Madillc29968b2016-01-20 11:17:23 -05002506 return false;
2507 }
2508
2509 if (filter == GL_LINEAR)
2510 {
Jamie Madille0472f32018-11-27 16:32:45 -05002511 context->validationError(GL_INVALID_ENUM, kBlitExtensionLinear);
Jamie Madillc29968b2016-01-20 11:17:23 -05002512 return false;
2513 }
2514
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002515 Framebuffer *readFramebuffer = context->getState().getReadFramebuffer();
2516 Framebuffer *drawFramebuffer = context->getState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002517
2518 if (mask & GL_COLOR_BUFFER_BIT)
2519 {
2520 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2521 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2522
2523 if (readColorAttachment && drawColorAttachment)
2524 {
2525 if (!(readColorAttachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002526 readColorAttachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002527 readColorAttachment->type() != GL_RENDERBUFFER &&
2528 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2529 {
Jamie Madill610640f2018-11-21 17:28:41 -05002530 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002531 kBlitExtensionFromInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002532 return false;
2533 }
2534
Geoff Langa15472a2015-08-11 11:48:03 -04002535 for (size_t drawbufferIdx = 0;
2536 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002537 {
Geoff Langa15472a2015-08-11 11:48:03 -04002538 const FramebufferAttachment *attachment =
2539 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2540 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002541 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002542 if (!(attachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002543 attachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002544 attachment->type() != GL_RENDERBUFFER &&
2545 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2546 {
Jamie Madill610640f2018-11-21 17:28:41 -05002547 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002548 kBlitExtensionToInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002549 return false;
2550 }
2551
2552 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002553 if (!Format::EquivalentForBlit(attachment->getFormat(),
2554 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002555 {
Jamie Madill610640f2018-11-21 17:28:41 -05002556 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002557 kBlitExtensionFormatMismatch);
Jamie Madillc29968b2016-01-20 11:17:23 -05002558 return false;
2559 }
2560 }
2561 }
2562
Jamie Madill427064d2018-04-13 16:20:34 -04002563 GLint samples = readFramebuffer->getSamples(context);
Jamie Madille98b1b52018-03-08 09:47:23 -05002564 if (samples != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002565 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2566 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2567 {
Jamie Madill610640f2018-11-21 17:28:41 -05002568 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002569 kBlitExtensionMultisampledWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002570 return false;
2571 }
2572 }
2573 }
2574
2575 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2576 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2577 for (size_t i = 0; i < 2; i++)
2578 {
2579 if (mask & masks[i])
2580 {
2581 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002582 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002583 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002584 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002585
2586 if (readBuffer && drawBuffer)
2587 {
2588 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2589 dstX0, dstY0, dstX1, dstY1))
2590 {
2591 // only whole-buffer copies are permitted
Jamie Madill610640f2018-11-21 17:28:41 -05002592 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002593 kBlitExtensionDepthStencilWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002594 return false;
2595 }
2596
2597 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2598 {
Jamie Madill610640f2018-11-21 17:28:41 -05002599 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002600 kBlitExtensionMultisampledDepthOrStencil);
Jamie Madillc29968b2016-01-20 11:17:23 -05002601 return false;
2602 }
2603 }
2604 }
2605 }
2606
2607 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2608 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002609}
Jamie Madillc29968b2016-01-20 11:17:23 -05002610
Jamie Madill5b772312018-03-08 20:28:32 -05002611bool ValidateClear(Context *context, GLbitfield mask)
Jamie Madillc29968b2016-01-20 11:17:23 -05002612{
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002613 Framebuffer *fbo = context->getState().getDrawFramebuffer();
Olli Etuaho94c91a92018-07-19 15:10:24 +03002614 const Extensions &extensions = context->getExtensions();
Jamie Madille98b1b52018-03-08 09:47:23 -05002615
Jamie Madill427064d2018-04-13 16:20:34 -04002616 if (!ValidateFramebufferComplete(context, fbo))
Jamie Madillc29968b2016-01-20 11:17:23 -05002617 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002618 return false;
2619 }
2620
2621 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2622 {
Jamie Madille0472f32018-11-27 16:32:45 -05002623 context->validationError(GL_INVALID_VALUE, kInvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002624 return false;
2625 }
2626
Olli Etuaho94c91a92018-07-19 15:10:24 +03002627 if (extensions.webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
Geoff Lang76e65652017-03-27 14:58:02 -04002628 {
2629 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2630 GL_SIGNED_NORMALIZED};
2631
Corentin Wallez59c41592017-07-11 13:19:54 -04002632 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002633 drawBufferIdx++)
2634 {
2635 if (!ValidateWebGLFramebufferAttachmentClearType(
2636 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2637 {
2638 return false;
2639 }
2640 }
2641 }
2642
Olli Etuaho94c91a92018-07-19 15:10:24 +03002643 if (extensions.multiview && extensions.disjointTimerQuery)
2644 {
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002645 const State &state = context->getState();
Olli Etuaho94c91a92018-07-19 15:10:24 +03002646 Framebuffer *framebuffer = state.getDrawFramebuffer();
2647 if (framebuffer->getNumViews() > 1 && state.isQueryActive(QueryType::TimeElapsed))
2648 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002649 context->validationError(GL_INVALID_OPERATION, kMultiviewTimerQuery);
Olli Etuaho94c91a92018-07-19 15:10:24 +03002650 return false;
2651 }
2652 }
2653
Jamie Madillc29968b2016-01-20 11:17:23 -05002654 return true;
2655}
2656
Jamie Madill5b772312018-03-08 20:28:32 -05002657bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002658{
2659 if (!context->getExtensions().drawBuffers)
2660 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002661 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05002662 return false;
2663 }
2664
2665 return ValidateDrawBuffersBase(context, n, bufs);
2666}
2667
Jamie Madill73a84962016-02-12 09:27:23 -05002668bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002669 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002670 GLint level,
2671 GLint internalformat,
2672 GLsizei width,
2673 GLsizei height,
2674 GLint border,
2675 GLenum format,
2676 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002677 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002678{
Martin Radev1be913c2016-07-11 17:59:16 +03002679 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002680 {
2681 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002682 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002683 }
2684
Martin Radev1be913c2016-07-11 17:59:16 +03002685 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002686 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002687 0, 0, width, height, 1, border, format, type, -1,
2688 pixels);
2689}
2690
Brandon Jones416aaf92018-04-10 08:10:16 -07002691bool ValidateTexImage2DRobustANGLE(Context *context,
2692 TextureTarget target,
2693 GLint level,
2694 GLint internalformat,
2695 GLsizei width,
2696 GLsizei height,
2697 GLint border,
2698 GLenum format,
2699 GLenum type,
2700 GLsizei bufSize,
2701 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002702{
2703 if (!ValidateRobustEntryPoint(context, bufSize))
2704 {
2705 return false;
2706 }
2707
2708 if (context->getClientMajorVersion() < 3)
2709 {
2710 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2711 0, 0, width, height, border, format, type, bufSize,
2712 pixels);
2713 }
2714
2715 ASSERT(context->getClientMajorVersion() >= 3);
2716 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2717 0, 0, width, height, 1, border, format, type, bufSize,
2718 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002719}
2720
2721bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002722 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002723 GLint level,
2724 GLint xoffset,
2725 GLint yoffset,
2726 GLsizei width,
2727 GLsizei height,
2728 GLenum format,
2729 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002730 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002731{
2732
Martin Radev1be913c2016-07-11 17:59:16 +03002733 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002734 {
2735 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002736 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002737 }
2738
Martin Radev1be913c2016-07-11 17:59:16 +03002739 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002740 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002741 yoffset, 0, width, height, 1, 0, format, type, -1,
2742 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002743}
2744
Geoff Langc52f6f12016-10-14 10:18:00 -04002745bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002746 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002747 GLint level,
2748 GLint xoffset,
2749 GLint yoffset,
2750 GLsizei width,
2751 GLsizei height,
2752 GLenum format,
2753 GLenum type,
2754 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002755 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002756{
2757 if (!ValidateRobustEntryPoint(context, bufSize))
2758 {
2759 return false;
2760 }
2761
2762 if (context->getClientMajorVersion() < 3)
2763 {
2764 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2765 yoffset, width, height, 0, format, type, bufSize,
2766 pixels);
2767 }
2768
2769 ASSERT(context->getClientMajorVersion() >= 3);
2770 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2771 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2772 pixels);
2773}
2774
Jamie Madill73a84962016-02-12 09:27:23 -05002775bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002776 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002777 GLint level,
2778 GLenum internalformat,
2779 GLsizei width,
2780 GLsizei height,
2781 GLint border,
2782 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002783 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002784{
Martin Radev1be913c2016-07-11 17:59:16 +03002785 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002786 {
2787 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002788 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002789 {
2790 return false;
2791 }
2792 }
2793 else
2794 {
Martin Radev1be913c2016-07-11 17:59:16 +03002795 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002796 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002797 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002798 data))
2799 {
2800 return false;
2801 }
2802 }
2803
Geoff Langca271392017-04-05 12:30:00 -04002804 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jamie Madillca2ff382018-07-11 09:01:17 -04002805
2806 GLuint blockSize = 0;
2807 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002808 {
Jamie Madille0472f32018-11-27 16:32:45 -05002809 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002810 return false;
2811 }
2812
Jamie Madillca2ff382018-07-11 09:01:17 -04002813 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002814 {
Jamie Madille0472f32018-11-27 16:32:45 -05002815 context->validationError(GL_INVALID_VALUE, kCompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002816 return false;
2817 }
2818
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002819 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002820 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002821 context->validationError(GL_INVALID_ENUM, kRectangleTextureCompressed);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002822 return false;
2823 }
2824
Jamie Madill73a84962016-02-12 09:27:23 -05002825 return true;
2826}
2827
Corentin Wallezb2931602017-04-11 15:58:57 -04002828bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002829 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002830 GLint level,
2831 GLenum internalformat,
2832 GLsizei width,
2833 GLsizei height,
2834 GLint border,
2835 GLsizei imageSize,
2836 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002837 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002838{
2839 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2840 {
2841 return false;
2842 }
2843
2844 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2845 border, imageSize, data);
2846}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002847
Corentin Wallezb2931602017-04-11 15:58:57 -04002848bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002849 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002850 GLint level,
2851 GLint xoffset,
2852 GLint yoffset,
2853 GLsizei width,
2854 GLsizei height,
2855 GLenum format,
2856 GLsizei imageSize,
2857 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002858 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002859{
2860 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2861 {
2862 return false;
2863 }
2864
2865 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2866 format, imageSize, data);
2867}
2868
Jamie Madill73a84962016-02-12 09:27:23 -05002869bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002870 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002871 GLint level,
2872 GLint xoffset,
2873 GLint yoffset,
2874 GLsizei width,
2875 GLsizei height,
2876 GLenum format,
2877 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002878 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002879{
Martin Radev1be913c2016-07-11 17:59:16 +03002880 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002881 {
2882 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002883 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002884 {
2885 return false;
2886 }
2887 }
2888 else
2889 {
Martin Radev1be913c2016-07-11 17:59:16 +03002890 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002891 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002892 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002893 data))
2894 {
2895 return false;
2896 }
2897 }
2898
Geoff Langca271392017-04-05 12:30:00 -04002899 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jamie Madillca2ff382018-07-11 09:01:17 -04002900 GLuint blockSize = 0;
2901 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002902 {
Jamie Madille0472f32018-11-27 16:32:45 -05002903 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002904 return false;
2905 }
2906
Jamie Madillca2ff382018-07-11 09:01:17 -04002907 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002908 {
Jamie Madille0472f32018-11-27 16:32:45 -05002909 context->validationError(GL_INVALID_VALUE, kInvalidCompressedImageSize);
Jamie Madill73a84962016-02-12 09:27:23 -05002910 return false;
2911 }
2912
2913 return true;
2914}
2915
Corentin Wallez336129f2017-10-17 15:55:40 -04002916bool ValidateGetBufferPointervOES(Context *context,
2917 BufferBinding target,
2918 GLenum pname,
2919 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002920{
Jamie Madillc3e37312018-11-30 15:25:39 -05002921 if (!context->getExtensions().mapBuffer)
2922 {
2923 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
2924 return false;
2925 }
2926
Geoff Lang496c02d2016-10-20 11:38:11 -07002927 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002928}
2929
Corentin Wallez336129f2017-10-17 15:55:40 -04002930bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03002931{
2932 if (!context->getExtensions().mapBuffer)
2933 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002934 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03002935 return false;
2936 }
2937
Corentin Walleze4477002017-12-01 14:39:58 -05002938 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03002939 {
Jamie Madille0472f32018-11-27 16:32:45 -05002940 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002941 return false;
2942 }
2943
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002944 Buffer *buffer = context->getState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002945
2946 if (buffer == nullptr)
2947 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002948 context->validationError(GL_INVALID_OPERATION, kBufferNotMappable);
Olli Etuaho4f667482016-03-30 15:56:35 +03002949 return false;
2950 }
2951
2952 if (access != GL_WRITE_ONLY_OES)
2953 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002954 context->validationError(GL_INVALID_ENUM, kInvalidAccessBits);
Olli Etuaho4f667482016-03-30 15:56:35 +03002955 return false;
2956 }
2957
2958 if (buffer->isMapped())
2959 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002960 context->validationError(GL_INVALID_OPERATION, kBufferAlreadyMapped);
Olli Etuaho4f667482016-03-30 15:56:35 +03002961 return false;
2962 }
2963
Geoff Lang79f71042017-08-14 16:43:43 -04002964 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002965}
2966
Corentin Wallez336129f2017-10-17 15:55:40 -04002967bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03002968{
2969 if (!context->getExtensions().mapBuffer)
2970 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002971 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03002972 return false;
2973 }
2974
2975 return ValidateUnmapBufferBase(context, target);
2976}
2977
2978bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002979 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002980 GLintptr offset,
2981 GLsizeiptr length,
2982 GLbitfield access)
2983{
2984 if (!context->getExtensions().mapBufferRange)
2985 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002986 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03002987 return false;
2988 }
2989
2990 return ValidateMapBufferRangeBase(context, target, offset, length, access);
2991}
2992
Corentin Wallez336129f2017-10-17 15:55:40 -04002993bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04002994{
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002995 Buffer *buffer = context->getState().getTargetBuffer(target);
Geoff Lang79f71042017-08-14 16:43:43 -04002996 ASSERT(buffer != nullptr);
2997
2998 // Check if this buffer is currently being used as a transform feedback output buffer
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002999 TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
Geoff Lang79f71042017-08-14 16:43:43 -04003000 if (transformFeedback != nullptr && transformFeedback->isActive())
3001 {
3002 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
3003 {
3004 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
3005 if (transformFeedbackBuffer.get() == buffer)
3006 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003007 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
Geoff Lang79f71042017-08-14 16:43:43 -04003008 return false;
3009 }
3010 }
3011 }
3012
James Darpiniane8a93c62018-01-04 18:02:24 -08003013 if (context->getExtensions().webglCompatibility &&
3014 buffer->isBoundForTransformFeedbackAndOtherUse())
3015 {
Jamie Madille0472f32018-11-27 16:32:45 -05003016 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08003017 return false;
3018 }
3019
Geoff Lang79f71042017-08-14 16:43:43 -04003020 return true;
3021}
3022
Olli Etuaho4f667482016-03-30 15:56:35 +03003023bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003024 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003025 GLintptr offset,
3026 GLsizeiptr length)
3027{
3028 if (!context->getExtensions().mapBufferRange)
3029 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003030 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03003031 return false;
3032 }
3033
3034 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
3035}
3036
Geoff Langd8605522016-04-13 10:19:12 -04003037bool ValidateBindUniformLocationCHROMIUM(Context *context,
3038 GLuint program,
3039 GLint location,
3040 const GLchar *name)
3041{
3042 if (!context->getExtensions().bindUniformLocation)
3043 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003044 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langd8605522016-04-13 10:19:12 -04003045 return false;
3046 }
3047
3048 Program *programObject = GetValidProgram(context, program);
3049 if (!programObject)
3050 {
3051 return false;
3052 }
3053
3054 if (location < 0)
3055 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003056 context->validationError(GL_INVALID_VALUE, kNegativeLocation);
Geoff Langd8605522016-04-13 10:19:12 -04003057 return false;
3058 }
3059
3060 const Caps &caps = context->getCaps();
3061 if (static_cast<size_t>(location) >=
3062 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3063 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003064 context->validationError(GL_INVALID_VALUE, kInvalidBindUniformLocation);
Geoff Langd8605522016-04-13 10:19:12 -04003065 return false;
3066 }
3067
Geoff Langfc32e8b2017-05-31 14:16:59 -04003068 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3069 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003070 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003071 {
Jamie Madille0472f32018-11-27 16:32:45 -05003072 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003073 return false;
3074 }
3075
Geoff Langd8605522016-04-13 10:19:12 -04003076 if (strncmp(name, "gl_", 3) == 0)
3077 {
Jamie Madille0472f32018-11-27 16:32:45 -05003078 context->validationError(GL_INVALID_VALUE, kNameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003079 return false;
3080 }
3081
3082 return true;
3083}
3084
Jamie Madille2e406c2016-06-02 13:04:10 -04003085bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003086{
3087 if (!context->getExtensions().framebufferMixedSamples)
3088 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003089 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänena797e062016-05-12 15:23:40 +03003090 return false;
3091 }
3092 switch (components)
3093 {
3094 case GL_RGB:
3095 case GL_RGBA:
3096 case GL_ALPHA:
3097 case GL_NONE:
3098 break;
3099 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003100 context->validationError(GL_INVALID_ENUM, kInvalidCoverageComponents);
Sami Väisänena797e062016-05-12 15:23:40 +03003101 return false;
3102 }
3103
3104 return true;
3105}
3106
Sami Väisänene45e53b2016-05-25 10:36:04 +03003107// CHROMIUM_path_rendering
3108
Jamie Madill007530e2017-12-28 14:27:04 -05003109bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003110{
Jamie Madill007530e2017-12-28 14:27:04 -05003111 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003112 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003113 return false;
3114 }
Jamie Madill007530e2017-12-28 14:27:04 -05003115
Sami Väisänene45e53b2016-05-25 10:36:04 +03003116 if (matrix == nullptr)
3117 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003118 context->validationError(GL_INVALID_OPERATION, kInvalidPathMatrix);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003119 return false;
3120 }
Jamie Madill007530e2017-12-28 14:27:04 -05003121
Sami Väisänene45e53b2016-05-25 10:36:04 +03003122 return true;
3123}
3124
Jamie Madill007530e2017-12-28 14:27:04 -05003125bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003126{
Jamie Madill007530e2017-12-28 14:27:04 -05003127 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003128}
3129
Jamie Madill007530e2017-12-28 14:27:04 -05003130bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003131{
3132 if (!context->getExtensions().pathRendering)
3133 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003134 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003135 return false;
3136 }
3137
3138 // range = 0 is undefined in NV_path_rendering.
3139 // we add stricter semantic check here and require a non zero positive range.
3140 if (range <= 0)
3141 {
Jamie Madille0472f32018-11-27 16:32:45 -05003142 context->validationError(GL_INVALID_VALUE, kInvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003143 return false;
3144 }
3145
3146 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3147 {
Jamie Madille0472f32018-11-27 16:32:45 -05003148 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003149 return false;
3150 }
3151
3152 return true;
3153}
3154
Jamie Madill007530e2017-12-28 14:27:04 -05003155bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003156{
3157 if (!context->getExtensions().pathRendering)
3158 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003159 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003160 return false;
3161 }
3162
3163 // range = 0 is undefined in NV_path_rendering.
3164 // we add stricter semantic check here and require a non zero positive range.
3165 if (range <= 0)
3166 {
Jamie Madille0472f32018-11-27 16:32:45 -05003167 context->validationError(GL_INVALID_VALUE, kInvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003168 return false;
3169 }
3170
3171 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3172 checkedRange += range;
3173
3174 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3175 {
Jamie Madille0472f32018-11-27 16:32:45 -05003176 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003177 return false;
3178 }
3179 return true;
3180}
3181
Jamie Madill007530e2017-12-28 14:27:04 -05003182bool ValidatePathCommandsCHROMIUM(Context *context,
3183 GLuint path,
3184 GLsizei numCommands,
3185 const GLubyte *commands,
3186 GLsizei numCoords,
3187 GLenum coordType,
3188 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003189{
3190 if (!context->getExtensions().pathRendering)
3191 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003192 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003193 return false;
3194 }
Brandon Jones59770802018-04-02 13:18:42 -07003195 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003196 {
Jamie Madille0472f32018-11-27 16:32:45 -05003197 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003198 return false;
3199 }
3200
3201 if (numCommands < 0)
3202 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003203 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCommands);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003204 return false;
3205 }
3206 else if (numCommands > 0)
3207 {
3208 if (!commands)
3209 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003210 context->validationError(GL_INVALID_VALUE, kInvalidPathCommandsArray);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003211 return false;
3212 }
3213 }
3214
3215 if (numCoords < 0)
3216 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003217 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCoords);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003218 return false;
3219 }
3220 else if (numCoords > 0)
3221 {
3222 if (!coords)
3223 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003224 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCoordsArray);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003225 return false;
3226 }
3227 }
3228
3229 std::uint32_t coordTypeSize = 0;
3230 switch (coordType)
3231 {
3232 case GL_BYTE:
3233 coordTypeSize = sizeof(GLbyte);
3234 break;
3235
3236 case GL_UNSIGNED_BYTE:
3237 coordTypeSize = sizeof(GLubyte);
3238 break;
3239
3240 case GL_SHORT:
3241 coordTypeSize = sizeof(GLshort);
3242 break;
3243
3244 case GL_UNSIGNED_SHORT:
3245 coordTypeSize = sizeof(GLushort);
3246 break;
3247
3248 case GL_FLOAT:
3249 coordTypeSize = sizeof(GLfloat);
3250 break;
3251
3252 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003253 context->validationError(GL_INVALID_ENUM, kInvalidPathCoordinateType);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003254 return false;
3255 }
3256
3257 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3258 checkedSize += (coordTypeSize * numCoords);
3259 if (!checkedSize.IsValid())
3260 {
Jamie Madille0472f32018-11-27 16:32:45 -05003261 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003262 return false;
3263 }
3264
3265 // early return skips command data validation when it doesn't exist.
3266 if (!commands)
3267 return true;
3268
3269 GLsizei expectedNumCoords = 0;
3270 for (GLsizei i = 0; i < numCommands; ++i)
3271 {
3272 switch (commands[i])
3273 {
3274 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3275 break;
3276 case GL_MOVE_TO_CHROMIUM:
3277 case GL_LINE_TO_CHROMIUM:
3278 expectedNumCoords += 2;
3279 break;
3280 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3281 expectedNumCoords += 4;
3282 break;
3283 case GL_CUBIC_CURVE_TO_CHROMIUM:
3284 expectedNumCoords += 6;
3285 break;
3286 case GL_CONIC_CURVE_TO_CHROMIUM:
3287 expectedNumCoords += 5;
3288 break;
3289 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003290 context->validationError(GL_INVALID_ENUM, kInvalidPathCommand);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003291 return false;
3292 }
3293 }
Jamie Madillc3e37312018-11-30 15:25:39 -05003294
Sami Väisänene45e53b2016-05-25 10:36:04 +03003295 if (expectedNumCoords != numCoords)
3296 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003297 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCoords);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003298 return false;
3299 }
3300
3301 return true;
3302}
3303
Jamie Madill007530e2017-12-28 14:27:04 -05003304bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003305{
3306 if (!context->getExtensions().pathRendering)
3307 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003308 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003309 return false;
3310 }
Brandon Jones59770802018-04-02 13:18:42 -07003311 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003312 {
Jamie Madille0472f32018-11-27 16:32:45 -05003313 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003314 return false;
3315 }
3316
3317 switch (pname)
3318 {
3319 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3320 if (value < 0.0f)
3321 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003322 context->validationError(GL_INVALID_VALUE, kInvalidPathStrokeWidth);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003323 return false;
3324 }
3325 break;
3326 case GL_PATH_END_CAPS_CHROMIUM:
3327 switch (static_cast<GLenum>(value))
3328 {
3329 case GL_FLAT_CHROMIUM:
3330 case GL_SQUARE_CHROMIUM:
3331 case GL_ROUND_CHROMIUM:
3332 break;
3333 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003334 context->validationError(GL_INVALID_ENUM, kInvalidPathEndCaps);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003335 return false;
3336 }
3337 break;
3338 case GL_PATH_JOIN_STYLE_CHROMIUM:
3339 switch (static_cast<GLenum>(value))
3340 {
3341 case GL_MITER_REVERT_CHROMIUM:
3342 case GL_BEVEL_CHROMIUM:
3343 case GL_ROUND_CHROMIUM:
3344 break;
3345 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003346 context->validationError(GL_INVALID_ENUM, kInvalidPathJoinStyle);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003347 return false;
3348 }
Nico Weber41b072b2018-02-09 10:01:32 -05003349 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003350 case GL_PATH_MITER_LIMIT_CHROMIUM:
3351 if (value < 0.0f)
3352 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003353 context->validationError(GL_INVALID_VALUE, kInvalidPathMiterLimit);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003354 return false;
3355 }
3356 break;
3357
3358 case GL_PATH_STROKE_BOUND_CHROMIUM:
3359 // no errors, only clamping.
3360 break;
3361
3362 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003363 context->validationError(GL_INVALID_ENUM, kInvalidPathParameter);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003364 return false;
3365 }
3366 return true;
3367}
3368
Jamie Madill007530e2017-12-28 14:27:04 -05003369bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3370{
3371 // TODO(jmadill): Use proper clamping cast.
3372 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3373}
3374
3375bool ValidateGetPathParameterfvCHROMIUM(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 }
3382
Brandon Jones59770802018-04-02 13:18:42 -07003383 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003384 {
Jamie Madille0472f32018-11-27 16:32:45 -05003385 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003386 return false;
3387 }
Jamie Madillc3e37312018-11-30 15:25:39 -05003388
Sami Väisänene45e53b2016-05-25 10:36:04 +03003389 if (!value)
3390 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003391 context->validationError(GL_INVALID_VALUE, kInvalidPathValueArray);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003392 return false;
3393 }
3394
3395 switch (pname)
3396 {
3397 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3398 case GL_PATH_END_CAPS_CHROMIUM:
3399 case GL_PATH_JOIN_STYLE_CHROMIUM:
3400 case GL_PATH_MITER_LIMIT_CHROMIUM:
3401 case GL_PATH_STROKE_BOUND_CHROMIUM:
3402 break;
3403
3404 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003405 context->validationError(GL_INVALID_ENUM, kInvalidPathParameter);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003406 return false;
3407 }
3408
3409 return true;
3410}
3411
Jamie Madill007530e2017-12-28 14:27:04 -05003412bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3413{
3414 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3415 reinterpret_cast<GLfloat *>(value));
3416}
3417
3418bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003419{
3420 if (!context->getExtensions().pathRendering)
3421 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003422 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003423 return false;
3424 }
3425
3426 switch (func)
3427 {
3428 case GL_NEVER:
3429 case GL_ALWAYS:
3430 case GL_LESS:
3431 case GL_LEQUAL:
3432 case GL_EQUAL:
3433 case GL_GEQUAL:
3434 case GL_GREATER:
3435 case GL_NOTEQUAL:
3436 break;
3437 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003438 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003439 return false;
3440 }
3441
3442 return true;
3443}
3444
3445// Note that the spec specifies that for the path drawing commands
3446// if the path object is not an existing path object the command
3447// does nothing and no error is generated.
3448// However if the path object exists but has not been specified any
3449// commands then an error is generated.
3450
Jamie Madill007530e2017-12-28 14:27:04 -05003451bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003452{
3453 if (!context->getExtensions().pathRendering)
3454 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003455 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003456 return false;
3457 }
Brandon Jones59770802018-04-02 13:18:42 -07003458 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003459 {
Jamie Madille0472f32018-11-27 16:32:45 -05003460 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003461 return false;
3462 }
3463
3464 switch (fillMode)
3465 {
3466 case GL_COUNT_UP_CHROMIUM:
3467 case GL_COUNT_DOWN_CHROMIUM:
3468 break;
3469 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003470 context->validationError(GL_INVALID_ENUM, kInvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003471 return false;
3472 }
3473
3474 if (!isPow2(mask + 1))
3475 {
Jamie Madille0472f32018-11-27 16:32:45 -05003476 context->validationError(GL_INVALID_VALUE, kInvalidStencilBitMask);
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 ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003484{
3485 if (!context->getExtensions().pathRendering)
3486 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003487 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003488 return false;
3489 }
Jamie Madillc3e37312018-11-30 15:25:39 -05003490
Brandon Jones59770802018-04-02 13:18:42 -07003491 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003492 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003493 context->validationError(GL_INVALID_OPERATION, kNoPathOrNoPathData);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003494 return false;
3495 }
3496
3497 return true;
3498}
3499
Jamie Madill007530e2017-12-28 14:27:04 -05003500bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003501{
3502 if (!context->getExtensions().pathRendering)
3503 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003504 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003505 return false;
3506 }
Brandon Jones59770802018-04-02 13:18:42 -07003507 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003508 {
Jamie Madille0472f32018-11-27 16:32:45 -05003509 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003510 return false;
3511 }
3512
3513 switch (coverMode)
3514 {
3515 case GL_CONVEX_HULL_CHROMIUM:
3516 case GL_BOUNDING_BOX_CHROMIUM:
3517 break;
3518 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003519 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003520 return false;
3521 }
3522 return true;
3523}
3524
Jamie Madill778bf092018-11-14 09:54:36 -05003525bool ValidateCoverFillPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3526{
3527 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3528}
3529
3530bool ValidateCoverStrokePathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3531{
3532 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3533}
3534
Jamie Madill007530e2017-12-28 14:27:04 -05003535bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3536 GLuint path,
3537 GLenum fillMode,
3538 GLuint mask,
3539 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003540{
Jamie Madill007530e2017-12-28 14:27:04 -05003541 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3542 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003543}
3544
Jamie Madill007530e2017-12-28 14:27:04 -05003545bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3546 GLuint path,
3547 GLint reference,
3548 GLuint mask,
3549 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003550{
Jamie Madill007530e2017-12-28 14:27:04 -05003551 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3552 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003553}
3554
Brandon Jonesd1049182018-03-28 10:02:20 -07003555bool ValidateIsPathCHROMIUM(Context *context, GLuint path)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003556{
3557 if (!context->getExtensions().pathRendering)
3558 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003559 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003560 return false;
3561 }
3562 return true;
3563}
3564
Jamie Madill007530e2017-12-28 14:27:04 -05003565bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3566 GLsizei numPaths,
3567 GLenum pathNameType,
3568 const void *paths,
3569 GLuint pathBase,
3570 GLenum coverMode,
3571 GLenum transformType,
3572 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003573{
3574 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3575 transformType, transformValues))
3576 return false;
3577
3578 switch (coverMode)
3579 {
3580 case GL_CONVEX_HULL_CHROMIUM:
3581 case GL_BOUNDING_BOX_CHROMIUM:
3582 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3583 break;
3584 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003585 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003586 return false;
3587 }
3588
3589 return true;
3590}
3591
Jamie Madill007530e2017-12-28 14:27:04 -05003592bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3593 GLsizei numPaths,
3594 GLenum pathNameType,
3595 const void *paths,
3596 GLuint pathBase,
3597 GLenum coverMode,
3598 GLenum transformType,
3599 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003600{
3601 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3602 transformType, transformValues))
3603 return false;
3604
3605 switch (coverMode)
3606 {
3607 case GL_CONVEX_HULL_CHROMIUM:
3608 case GL_BOUNDING_BOX_CHROMIUM:
3609 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3610 break;
3611 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003612 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003613 return false;
3614 }
3615
3616 return true;
3617}
3618
Jamie Madill007530e2017-12-28 14:27:04 -05003619bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3620 GLsizei numPaths,
3621 GLenum pathNameType,
3622 const void *paths,
3623 GLuint pathBase,
3624 GLenum fillMode,
3625 GLuint mask,
3626 GLenum transformType,
3627 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003628{
3629
3630 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3631 transformType, transformValues))
3632 return false;
3633
3634 switch (fillMode)
3635 {
3636 case GL_COUNT_UP_CHROMIUM:
3637 case GL_COUNT_DOWN_CHROMIUM:
3638 break;
3639 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003640 context->validationError(GL_INVALID_ENUM, kInvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003641 return false;
3642 }
3643 if (!isPow2(mask + 1))
3644 {
Jamie Madille0472f32018-11-27 16:32:45 -05003645 context->validationError(GL_INVALID_VALUE, kInvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003646 return false;
3647 }
3648 return true;
3649}
3650
Jamie Madill007530e2017-12-28 14:27:04 -05003651bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3652 GLsizei numPaths,
3653 GLenum pathNameType,
3654 const void *paths,
3655 GLuint pathBase,
3656 GLint reference,
3657 GLuint mask,
3658 GLenum transformType,
3659 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003660{
3661 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3662 transformType, transformValues))
3663 return false;
3664
3665 // no more validation here.
3666
3667 return true;
3668}
3669
Jamie Madill007530e2017-12-28 14:27:04 -05003670bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3671 GLsizei numPaths,
3672 GLenum pathNameType,
3673 const void *paths,
3674 GLuint pathBase,
3675 GLenum fillMode,
3676 GLuint mask,
3677 GLenum coverMode,
3678 GLenum transformType,
3679 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003680{
3681 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3682 transformType, transformValues))
3683 return false;
3684
3685 switch (coverMode)
3686 {
3687 case GL_CONVEX_HULL_CHROMIUM:
3688 case GL_BOUNDING_BOX_CHROMIUM:
3689 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3690 break;
3691 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003692 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003693 return false;
3694 }
3695
3696 switch (fillMode)
3697 {
3698 case GL_COUNT_UP_CHROMIUM:
3699 case GL_COUNT_DOWN_CHROMIUM:
3700 break;
3701 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003702 context->validationError(GL_INVALID_ENUM, kInvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003703 return false;
3704 }
3705 if (!isPow2(mask + 1))
3706 {
Jamie Madille0472f32018-11-27 16:32:45 -05003707 context->validationError(GL_INVALID_VALUE, kInvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003708 return false;
3709 }
3710
3711 return true;
3712}
3713
Jamie Madill007530e2017-12-28 14:27:04 -05003714bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
3715 GLsizei numPaths,
3716 GLenum pathNameType,
3717 const void *paths,
3718 GLuint pathBase,
3719 GLint reference,
3720 GLuint mask,
3721 GLenum coverMode,
3722 GLenum transformType,
3723 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003724{
3725 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3726 transformType, transformValues))
3727 return false;
3728
3729 switch (coverMode)
3730 {
3731 case GL_CONVEX_HULL_CHROMIUM:
3732 case GL_BOUNDING_BOX_CHROMIUM:
3733 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3734 break;
3735 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003736 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003737 return false;
3738 }
3739
3740 return true;
3741}
3742
Jamie Madill007530e2017-12-28 14:27:04 -05003743bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
3744 GLuint program,
3745 GLint location,
3746 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003747{
3748 if (!context->getExtensions().pathRendering)
3749 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003750 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003751 return false;
3752 }
3753
3754 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3755 if (location >= MaxLocation)
3756 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003757 context->validationError(GL_INVALID_VALUE, kInvalidVaryingLocation);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003758 return false;
3759 }
3760
Jamie Madill44a6fbf2018-10-02 13:38:56 -04003761 const auto *programObject = context->getProgramNoResolveLink(program);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003762 if (!programObject)
3763 {
Jamie Madille0472f32018-11-27 16:32:45 -05003764 context->validationError(GL_INVALID_OPERATION, kProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003765 return false;
3766 }
3767
3768 if (!name)
3769 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003770 context->validationError(GL_INVALID_VALUE, kMissingName);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003771 return false;
3772 }
3773
3774 if (angle::BeginsWith(name, "gl_"))
3775 {
Jamie Madille0472f32018-11-27 16:32:45 -05003776 context->validationError(GL_INVALID_OPERATION, kNameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003777 return false;
3778 }
3779
3780 return true;
3781}
3782
Jamie Madill007530e2017-12-28 14:27:04 -05003783bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
3784 GLuint program,
3785 GLint location,
3786 GLenum genMode,
3787 GLint components,
3788 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003789{
3790 if (!context->getExtensions().pathRendering)
3791 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003792 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003793 return false;
3794 }
3795
Jamie Madill44a6fbf2018-10-02 13:38:56 -04003796 const auto *programObject = context->getProgramResolveLink(program);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003797 if (!programObject || programObject->isFlaggedForDeletion())
3798 {
Jamie Madille0472f32018-11-27 16:32:45 -05003799 context->validationError(GL_INVALID_OPERATION, kProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003800 return false;
3801 }
3802
3803 if (!programObject->isLinked())
3804 {
Jamie Madille0472f32018-11-27 16:32:45 -05003805 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003806 return false;
3807 }
3808
3809 switch (genMode)
3810 {
3811 case GL_NONE:
3812 if (components != 0)
3813 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003814 context->validationError(GL_INVALID_VALUE, kInvalidComponents);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003815 return false;
3816 }
3817 break;
3818
3819 case GL_OBJECT_LINEAR_CHROMIUM:
3820 case GL_EYE_LINEAR_CHROMIUM:
3821 case GL_CONSTANT_CHROMIUM:
3822 if (components < 1 || components > 4)
3823 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003824 context->validationError(GL_INVALID_VALUE, kInvalidComponents);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003825 return false;
3826 }
3827 if (!coeffs)
3828 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003829 context->validationError(GL_INVALID_VALUE, kInvalidPathCoefficientsArray);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003830 return false;
3831 }
3832 break;
3833
3834 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003835 context->validationError(GL_INVALID_ENUM, kInvalidPathGenMode);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003836 return false;
3837 }
3838
3839 // If the location is -1 then the command is silently ignored
3840 // and no further validation is needed.
3841 if (location == -1)
3842 return true;
3843
jchen103fd614d2018-08-13 12:21:58 +08003844 const auto &binding = programObject->getFragmentInputBindingInfo(location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003845
3846 if (!binding.valid)
3847 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003848 context->validationError(GL_INVALID_OPERATION, kInvalidFragmentInputBinding);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003849 return false;
3850 }
3851
3852 if (binding.type != GL_NONE)
3853 {
3854 GLint expectedComponents = 0;
3855 switch (binding.type)
3856 {
3857 case GL_FLOAT:
3858 expectedComponents = 1;
3859 break;
3860 case GL_FLOAT_VEC2:
3861 expectedComponents = 2;
3862 break;
3863 case GL_FLOAT_VEC3:
3864 expectedComponents = 3;
3865 break;
3866 case GL_FLOAT_VEC4:
3867 expectedComponents = 4;
3868 break;
3869 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003870 context->validationError(GL_INVALID_OPERATION, kFragmentInputTypeNotFloatingPoint);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003871 return false;
3872 }
3873 if (expectedComponents != components && genMode != GL_NONE)
3874 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003875 context->validationError(GL_INVALID_OPERATION, kInvalidPathComponents);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003876 return false;
3877 }
3878 }
3879 return true;
3880}
3881
Geoff Lang97073d12016-04-20 10:42:34 -07003882bool ValidateCopyTextureCHROMIUM(Context *context,
3883 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003884 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003885 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003886 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003887 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003888 GLint internalFormat,
3889 GLenum destType,
3890 GLboolean unpackFlipY,
3891 GLboolean unpackPremultiplyAlpha,
3892 GLboolean unpackUnmultiplyAlpha)
3893{
3894 if (!context->getExtensions().copyTexture)
3895 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003896 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang97073d12016-04-20 10:42:34 -07003897 return false;
3898 }
3899
Geoff Lang4f0e0032017-05-01 16:04:35 -04003900 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003901 if (source == nullptr)
3902 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003903 context->validationError(GL_INVALID_VALUE, kInvalidSourceTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07003904 return false;
3905 }
3906
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003907 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003908 {
Jamie Madille0472f32018-11-27 16:32:45 -05003909 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003910 return false;
3911 }
3912
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003913 TextureType sourceType = source->getType();
3914 ASSERT(sourceType != TextureType::CubeMap);
3915 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003916
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003917 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07003918 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003919 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureLevel);
Geoff Lang97073d12016-04-20 10:42:34 -07003920 return false;
3921 }
3922
Geoff Lang4f0e0032017-05-01 16:04:35 -04003923 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
3924 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
3925 if (sourceWidth == 0 || sourceHeight == 0)
3926 {
Jamie Madille0472f32018-11-27 16:32:45 -05003927 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003928 return false;
3929 }
3930
3931 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
3932 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07003933 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003934 context->validationError(GL_INVALID_OPERATION, kInvalidSourceTextureInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003935 return false;
3936 }
3937
Geoff Lang63458a32017-10-30 15:16:53 -04003938 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
3939 {
Jamie Madille0472f32018-11-27 16:32:45 -05003940 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Lang63458a32017-10-30 15:16:53 -04003941 return false;
3942 }
3943
Geoff Lang4f0e0032017-05-01 16:04:35 -04003944 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07003945 if (dest == nullptr)
3946 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003947 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07003948 return false;
3949 }
3950
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003951 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07003952 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003953 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTextureType);
Geoff Lang97073d12016-04-20 10:42:34 -07003954 return false;
3955 }
3956
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003957 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08003958 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04003959 {
Jamie Madille0472f32018-11-27 16:32:45 -05003960 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003961 return false;
3962 }
3963
Geoff Lang97073d12016-04-20 10:42:34 -07003964 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
3965 {
Geoff Lang97073d12016-04-20 10:42:34 -07003966 return false;
3967 }
3968
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003969 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04003970 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003971 context->validationError(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003972 return false;
3973 }
3974
Geoff Lang97073d12016-04-20 10:42:34 -07003975 if (dest->getImmutableFormat())
3976 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003977 context->validationError(GL_INVALID_OPERATION, kDestinationImmutable);
Geoff Lang97073d12016-04-20 10:42:34 -07003978 return false;
3979 }
3980
3981 return true;
3982}
3983
3984bool ValidateCopySubTextureCHROMIUM(Context *context,
3985 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003986 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003987 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003988 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003989 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003990 GLint xoffset,
3991 GLint yoffset,
3992 GLint x,
3993 GLint y,
3994 GLsizei width,
3995 GLsizei height,
3996 GLboolean unpackFlipY,
3997 GLboolean unpackPremultiplyAlpha,
3998 GLboolean unpackUnmultiplyAlpha)
3999{
4000 if (!context->getExtensions().copyTexture)
4001 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004002 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang97073d12016-04-20 10:42:34 -07004003 return false;
4004 }
4005
Geoff Lang4f0e0032017-05-01 16:04:35 -04004006 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004007 if (source == nullptr)
4008 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004009 context->validationError(GL_INVALID_VALUE, kInvalidSourceTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07004010 return false;
4011 }
4012
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004013 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004014 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004015 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureType);
Geoff Lang97073d12016-04-20 10:42:34 -07004016 return false;
4017 }
4018
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004019 TextureType sourceType = source->getType();
4020 ASSERT(sourceType != TextureType::CubeMap);
4021 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004022
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004023 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004024 {
Jamie Madille0472f32018-11-27 16:32:45 -05004025 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004026 return false;
4027 }
4028
4029 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4030 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004031 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004032 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureLevel);
Geoff Lang97073d12016-04-20 10:42:34 -07004033 return false;
4034 }
4035
4036 if (x < 0 || y < 0)
4037 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004038 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004039 return false;
4040 }
4041
4042 if (width < 0 || height < 0)
4043 {
Jamie Madille0472f32018-11-27 16:32:45 -05004044 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004045 return false;
4046 }
4047
Geoff Lang4f0e0032017-05-01 16:04:35 -04004048 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4049 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004050 {
Jamie Madille0472f32018-11-27 16:32:45 -05004051 context->validationError(GL_INVALID_VALUE, kSourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004052 return false;
4053 }
4054
Geoff Lang4f0e0032017-05-01 16:04:35 -04004055 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4056 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004057 {
Jamie Madille0472f32018-11-27 16:32:45 -05004058 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004059 return false;
4060 }
4061
Geoff Lang63458a32017-10-30 15:16:53 -04004062 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4063 {
Jamie Madille0472f32018-11-27 16:32:45 -05004064 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Lang63458a32017-10-30 15:16:53 -04004065 return false;
4066 }
4067
Geoff Lang4f0e0032017-05-01 16:04:35 -04004068 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004069 if (dest == nullptr)
4070 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004071 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07004072 return false;
4073 }
4074
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004075 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004076 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004077 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTextureType);
Geoff Lang97073d12016-04-20 10:42:34 -07004078 return false;
4079 }
4080
Brandon Jones28783792018-03-05 09:37:32 -08004081 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4082 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004083 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004084 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Lang97073d12016-04-20 10:42:34 -07004085 return false;
4086 }
4087
Geoff Lang4f0e0032017-05-01 16:04:35 -04004088 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4089 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004090 context->validationError(GL_INVALID_OPERATION, kDestinationLevelNotDefined);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004091 return false;
4092 }
4093
4094 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4095 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004096 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004097 context->validationError(GL_INVALID_OPERATION, kInvalidFormatCombination);
Geoff Lang97073d12016-04-20 10:42:34 -07004098 return false;
4099 }
4100
4101 if (xoffset < 0 || yoffset < 0)
4102 {
Jamie Madille0472f32018-11-27 16:32:45 -05004103 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004104 return false;
4105 }
4106
Geoff Lang4f0e0032017-05-01 16:04:35 -04004107 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4108 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004109 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004110 context->validationError(GL_INVALID_VALUE, kOffsetOverflow);
Geoff Lang97073d12016-04-20 10:42:34 -07004111 return false;
4112 }
4113
4114 return true;
4115}
4116
Geoff Lang47110bf2016-04-20 11:13:22 -07004117bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4118{
4119 if (!context->getExtensions().copyCompressedTexture)
4120 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004121 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang47110bf2016-04-20 11:13:22 -07004122 return false;
4123 }
4124
4125 const gl::Texture *source = context->getTexture(sourceId);
4126 if (source == nullptr)
4127 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004128 context->validationError(GL_INVALID_VALUE, kInvalidSourceTexture);
Geoff Lang47110bf2016-04-20 11:13:22 -07004129 return false;
4130 }
4131
Corentin Wallez99d492c2018-02-27 15:17:10 -05004132 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004133 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004134 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureType);
Geoff Lang47110bf2016-04-20 11:13:22 -07004135 return false;
4136 }
4137
Corentin Wallez99d492c2018-02-27 15:17:10 -05004138 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4139 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004140 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004141 context->validationError(GL_INVALID_VALUE, kSourceTextureLevelZeroDefined);
Geoff Lang47110bf2016-04-20 11:13:22 -07004142 return false;
4143 }
4144
Corentin Wallez99d492c2018-02-27 15:17:10 -05004145 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004146 if (!sourceFormat.info->compressed)
4147 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004148 context->validationError(GL_INVALID_OPERATION, kSourceTextureMustBeCompressed);
Geoff Lang47110bf2016-04-20 11:13:22 -07004149 return false;
4150 }
4151
4152 const gl::Texture *dest = context->getTexture(destId);
4153 if (dest == nullptr)
4154 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004155 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTexture);
Geoff Lang47110bf2016-04-20 11:13:22 -07004156 return false;
4157 }
4158
Corentin Wallez99d492c2018-02-27 15:17:10 -05004159 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004160 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004161 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTextureType);
Geoff Lang47110bf2016-04-20 11:13:22 -07004162 return false;
4163 }
4164
4165 if (dest->getImmutableFormat())
4166 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004167 context->validationError(GL_INVALID_OPERATION, kDestinationImmutable);
Geoff Lang47110bf2016-04-20 11:13:22 -07004168 return false;
4169 }
4170
4171 return true;
4172}
4173
Jiawei Shao385b3e02018-03-21 09:43:28 +08004174bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004175{
4176 switch (type)
4177 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004178 case ShaderType::Vertex:
4179 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004180 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004181
Jiawei Shao385b3e02018-03-21 09:43:28 +08004182 case ShaderType::Compute:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004183 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004184 {
Jamie Madille0472f32018-11-27 16:32:45 -05004185 context->validationError(GL_INVALID_ENUM, kES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004186 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004187 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004188 break;
4189
Jiawei Shao385b3e02018-03-21 09:43:28 +08004190 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004191 if (!context->getExtensions().geometryShader)
4192 {
Jamie Madille0472f32018-11-27 16:32:45 -05004193 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
Jiawei Shao89be29a2017-11-06 14:36:45 +08004194 return false;
4195 }
4196 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004197 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004198 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004199 return false;
4200 }
Jamie Madill29639852016-09-02 15:00:09 -04004201
4202 return true;
4203}
4204
Jamie Madill5b772312018-03-08 20:28:32 -05004205bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004206 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004207 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004208 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004209 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004210{
4211 if (size < 0)
4212 {
Jamie Madille0472f32018-11-27 16:32:45 -05004213 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004214 return false;
4215 }
4216
4217 switch (usage)
4218 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004219 case BufferUsage::StreamDraw:
4220 case BufferUsage::StaticDraw:
4221 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004222 break;
4223
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004224 case BufferUsage::StreamRead:
4225 case BufferUsage::StaticRead:
4226 case BufferUsage::DynamicRead:
4227 case BufferUsage::StreamCopy:
4228 case BufferUsage::StaticCopy:
4229 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004230 if (context->getClientMajorVersion() < 3)
4231 {
Jamie Madille0472f32018-11-27 16:32:45 -05004232 context->validationError(GL_INVALID_ENUM, kInvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004233 return false;
4234 }
4235 break;
4236
4237 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004238 context->validationError(GL_INVALID_ENUM, kInvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004239 return false;
4240 }
4241
Corentin Walleze4477002017-12-01 14:39:58 -05004242 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004243 {
Jamie Madille0472f32018-11-27 16:32:45 -05004244 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004245 return false;
4246 }
4247
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004248 Buffer *buffer = context->getState().getTargetBuffer(target);
Jamie Madill29639852016-09-02 15:00:09 -04004249
4250 if (!buffer)
4251 {
Jamie Madille0472f32018-11-27 16:32:45 -05004252 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004253 return false;
4254 }
4255
James Darpiniane8a93c62018-01-04 18:02:24 -08004256 if (context->getExtensions().webglCompatibility &&
4257 buffer->isBoundForTransformFeedbackAndOtherUse())
4258 {
Jamie Madille0472f32018-11-27 16:32:45 -05004259 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08004260 return false;
4261 }
4262
Jamie Madill29639852016-09-02 15:00:09 -04004263 return true;
4264}
4265
Jamie Madill5b772312018-03-08 20:28:32 -05004266bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004267 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004268 GLintptr offset,
4269 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004270 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004271{
Brandon Jones6cad5662017-06-14 13:25:13 -07004272 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004273 {
Jamie Madille0472f32018-11-27 16:32:45 -05004274 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Brandon Jones6cad5662017-06-14 13:25:13 -07004275 return false;
4276 }
4277
4278 if (offset < 0)
4279 {
Jamie Madille0472f32018-11-27 16:32:45 -05004280 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004281 return false;
4282 }
4283
Corentin Walleze4477002017-12-01 14:39:58 -05004284 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004285 {
Jamie Madille0472f32018-11-27 16:32:45 -05004286 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004287 return false;
4288 }
4289
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004290 Buffer *buffer = context->getState().getTargetBuffer(target);
Jamie Madill29639852016-09-02 15:00:09 -04004291
4292 if (!buffer)
4293 {
Jamie Madille0472f32018-11-27 16:32:45 -05004294 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004295 return false;
4296 }
4297
4298 if (buffer->isMapped())
4299 {
Jamie Madille0472f32018-11-27 16:32:45 -05004300 context->validationError(GL_INVALID_OPERATION, kBufferMapped);
Jamie Madill29639852016-09-02 15:00:09 -04004301 return false;
4302 }
4303
James Darpiniane8a93c62018-01-04 18:02:24 -08004304 if (context->getExtensions().webglCompatibility &&
4305 buffer->isBoundForTransformFeedbackAndOtherUse())
4306 {
Jamie Madille0472f32018-11-27 16:32:45 -05004307 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08004308 return false;
4309 }
4310
Jamie Madill29639852016-09-02 15:00:09 -04004311 // Check for possible overflow of size + offset
4312 angle::CheckedNumeric<size_t> checkedSize(size);
4313 checkedSize += offset;
4314 if (!checkedSize.IsValid())
4315 {
Jamie Madille0472f32018-11-27 16:32:45 -05004316 context->validationError(GL_INVALID_VALUE, kParamOverflow);
Jamie Madill29639852016-09-02 15:00:09 -04004317 return false;
4318 }
4319
4320 if (size + offset > buffer->getSize())
4321 {
Jamie Madille0472f32018-11-27 16:32:45 -05004322 context->validationError(GL_INVALID_VALUE, kInsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004323 return false;
4324 }
4325
Martin Radev4c4c8e72016-08-04 12:25:34 +03004326 return true;
4327}
4328
Geoff Lang111a99e2017-10-17 10:58:41 -04004329bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004330{
Geoff Langc339c4e2016-11-29 10:37:36 -05004331 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004332 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004333 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langc287ea62016-09-16 14:46:51 -04004334 return false;
4335 }
4336
Geoff Lang111a99e2017-10-17 10:58:41 -04004337 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004338 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004339 context->validationError(GL_INVALID_OPERATION, kExtensionNotRequestable);
Geoff Langc287ea62016-09-16 14:46:51 -04004340 return false;
4341 }
4342
4343 return true;
4344}
4345
Jamie Madill5b772312018-03-08 20:28:32 -05004346bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004347{
Lingfeng Yang038dd532018-03-29 17:31:52 -07004348 if (context->getClientMajorVersion() < 2)
4349 {
4350 return ValidateMultitextureUnit(context, texture);
4351 }
4352
Jamie Madillef300b12016-10-07 15:12:09 -04004353 if (texture < GL_TEXTURE0 ||
4354 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4355 {
Jamie Madille0472f32018-11-27 16:32:45 -05004356 context->validationError(GL_INVALID_ENUM, kInvalidCombinedImageUnit);
Jamie Madillef300b12016-10-07 15:12:09 -04004357 return false;
4358 }
4359
4360 return true;
4361}
4362
Jamie Madill5b772312018-03-08 20:28:32 -05004363bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004364{
4365 Program *programObject = GetValidProgram(context, program);
4366 if (!programObject)
4367 {
4368 return false;
4369 }
4370
4371 Shader *shaderObject = GetValidShader(context, shader);
4372 if (!shaderObject)
4373 {
4374 return false;
4375 }
4376
Jiawei Shao385b3e02018-03-21 09:43:28 +08004377 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04004378 {
Jamie Madille0472f32018-11-27 16:32:45 -05004379 context->validationError(GL_INVALID_OPERATION, kShaderAttachmentHasShader);
Jiawei Shao385b3e02018-03-21 09:43:28 +08004380 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04004381 }
4382
4383 return true;
4384}
4385
Jamie Madill5b772312018-03-08 20:28:32 -05004386bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004387{
4388 if (index >= MAX_VERTEX_ATTRIBS)
4389 {
Jamie Madille0472f32018-11-27 16:32:45 -05004390 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004391 return false;
4392 }
4393
4394 if (strncmp(name, "gl_", 3) == 0)
4395 {
Jamie Madille0472f32018-11-27 16:32:45 -05004396 context->validationError(GL_INVALID_OPERATION, kNameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004397 return false;
4398 }
4399
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004400 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004401 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004402 const size_t length = strlen(name);
4403
4404 if (!IsValidESSLString(name, length))
4405 {
4406 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4407 // for shader-related entry points
Jamie Madille0472f32018-11-27 16:32:45 -05004408 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004409 return false;
4410 }
4411
4412 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4413 {
4414 return false;
4415 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004416 }
4417
Jamie Madill01a80ee2016-11-07 12:06:18 -05004418 return GetValidProgram(context, program) != nullptr;
4419}
4420
Jamie Madill5b772312018-03-08 20:28:32 -05004421bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004422{
Geoff Lange8afa902017-09-27 15:00:43 -04004423 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004424 {
Jamie Madille0472f32018-11-27 16:32:45 -05004425 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004426 return false;
4427 }
4428
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004429 if (!context->getState().isBindGeneratesResourceEnabled() &&
Jamie Madill01a80ee2016-11-07 12:06:18 -05004430 !context->isFramebufferGenerated(framebuffer))
4431 {
Jamie Madille0472f32018-11-27 16:32:45 -05004432 context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004433 return false;
4434 }
4435
4436 return true;
4437}
4438
Jamie Madill5b772312018-03-08 20:28:32 -05004439bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004440{
4441 if (target != GL_RENDERBUFFER)
4442 {
Jamie Madille0472f32018-11-27 16:32:45 -05004443 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004444 return false;
4445 }
4446
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004447 if (!context->getState().isBindGeneratesResourceEnabled() &&
Jamie Madill01a80ee2016-11-07 12:06:18 -05004448 !context->isRenderbufferGenerated(renderbuffer))
4449 {
Jamie Madille0472f32018-11-27 16:32:45 -05004450 context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004451 return false;
4452 }
4453
4454 return true;
4455}
4456
Jamie Madill5b772312018-03-08 20:28:32 -05004457static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004458{
4459 switch (mode)
4460 {
4461 case GL_FUNC_ADD:
4462 case GL_FUNC_SUBTRACT:
4463 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004464 return true;
4465
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004466 case GL_MIN:
4467 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004468 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004469
4470 default:
4471 return false;
4472 }
4473}
4474
Jamie Madill5b772312018-03-08 20:28:32 -05004475bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004476{
4477 return true;
4478}
4479
Jamie Madill5b772312018-03-08 20:28:32 -05004480bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004481{
Geoff Lang50cac572017-09-26 17:37:43 -04004482 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004483 {
Jamie Madille0472f32018-11-27 16:32:45 -05004484 context->validationError(GL_INVALID_ENUM, kInvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004485 return false;
4486 }
4487
4488 return true;
4489}
4490
Jamie Madill5b772312018-03-08 20:28:32 -05004491bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004492{
Geoff Lang50cac572017-09-26 17:37:43 -04004493 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004494 {
Jamie Madille0472f32018-11-27 16:32:45 -05004495 context->validationError(GL_INVALID_ENUM, kInvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004496 return false;
4497 }
4498
Geoff Lang50cac572017-09-26 17:37:43 -04004499 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004500 {
Jamie Madille0472f32018-11-27 16:32:45 -05004501 context->validationError(GL_INVALID_ENUM, kInvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004502 return false;
4503 }
4504
4505 return true;
4506}
4507
Jamie Madill5b772312018-03-08 20:28:32 -05004508bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004509{
4510 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4511}
4512
Jamie Madill5b772312018-03-08 20:28:32 -05004513bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004514 GLenum srcRGB,
4515 GLenum dstRGB,
4516 GLenum srcAlpha,
4517 GLenum dstAlpha)
4518{
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004519 if (!ValidSrcBlendFunc(context, srcRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004520 {
Jamie Madille0472f32018-11-27 16:32:45 -05004521 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004522 return false;
4523 }
4524
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004525 if (!ValidDstBlendFunc(context, dstRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004526 {
Jamie Madille0472f32018-11-27 16:32:45 -05004527 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004528 return false;
4529 }
4530
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004531 if (!ValidSrcBlendFunc(context, srcAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004532 {
Jamie Madille0472f32018-11-27 16:32:45 -05004533 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004534 return false;
4535 }
4536
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004537 if (!ValidDstBlendFunc(context, dstAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004538 {
Jamie Madille0472f32018-11-27 16:32:45 -05004539 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004540 return false;
4541 }
4542
Frank Henigman146e8a12017-03-02 23:22:37 -05004543 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4544 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004545 {
4546 bool constantColorUsed =
4547 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4548 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4549
4550 bool constantAlphaUsed =
4551 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4552 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4553
4554 if (constantColorUsed && constantAlphaUsed)
4555 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004556 if (context->getExtensions().webglCompatibility)
4557 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004558 context->validationError(GL_INVALID_OPERATION, kInvalidConstantColor);
4559 return false;
Frank Henigman146e8a12017-03-02 23:22:37 -05004560 }
Jamie Madillc3e37312018-11-30 15:25:39 -05004561
4562 WARN() << kConstantColorAlphaLimitation;
4563 context->validationError(GL_INVALID_OPERATION, kConstantColorAlphaLimitation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004564 return false;
4565 }
4566 }
4567
4568 return true;
4569}
4570
Geoff Langc339c4e2016-11-29 10:37:36 -05004571bool ValidateGetString(Context *context, GLenum name)
4572{
4573 switch (name)
4574 {
4575 case GL_VENDOR:
4576 case GL_RENDERER:
4577 case GL_VERSION:
4578 case GL_SHADING_LANGUAGE_VERSION:
4579 case GL_EXTENSIONS:
4580 break;
4581
4582 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4583 if (!context->getExtensions().requestExtension)
4584 {
Jamie Madille0472f32018-11-27 16:32:45 -05004585 context->validationError(GL_INVALID_ENUM, kInvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004586 return false;
4587 }
4588 break;
4589
4590 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004591 context->validationError(GL_INVALID_ENUM, kInvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004592 return false;
4593 }
4594
4595 return true;
4596}
4597
Jamie Madill5b772312018-03-08 20:28:32 -05004598bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004599{
4600 if (width <= 0.0f || isNaN(width))
4601 {
Jamie Madille0472f32018-11-27 16:32:45 -05004602 context->validationError(GL_INVALID_VALUE, kInvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004603 return false;
4604 }
4605
4606 return true;
4607}
4608
Jamie Madill5b772312018-03-08 20:28:32 -05004609bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004610{
4611 if (context->getExtensions().webglCompatibility && zNear > zFar)
4612 {
Jamie Madille0472f32018-11-27 16:32:45 -05004613 context->validationError(GL_INVALID_OPERATION, kInvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004614 return false;
4615 }
4616
4617 return true;
4618}
4619
Jamie Madill5b772312018-03-08 20:28:32 -05004620bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004621 GLenum target,
4622 GLenum internalformat,
4623 GLsizei width,
4624 GLsizei height)
4625{
4626 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4627 height);
4628}
4629
Jamie Madill5b772312018-03-08 20:28:32 -05004630bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004631 GLenum target,
4632 GLsizei samples,
4633 GLenum internalformat,
4634 GLsizei width,
4635 GLsizei height)
4636{
4637 if (!context->getExtensions().framebufferMultisample)
4638 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004639 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madille8fb6402017-02-14 17:56:40 -05004640 return false;
4641 }
4642
4643 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
Jamie Madill610640f2018-11-21 17:28:41 -05004644 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_VALUE is
Jamie Madille8fb6402017-02-14 17:56:40 -05004645 // generated.
4646 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4647 {
Jamie Madille0472f32018-11-27 16:32:45 -05004648 context->validationError(GL_INVALID_VALUE, kSamplesOutOfRange);
Jamie Madille8fb6402017-02-14 17:56:40 -05004649 return false;
4650 }
4651
4652 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4653 // the specified storage. This is different than ES 3.0 in which a sample number higher
4654 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4655 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4656 if (context->getClientMajorVersion() >= 3)
4657 {
4658 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4659 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4660 {
Jamie Madille0472f32018-11-27 16:32:45 -05004661 context->validationError(GL_OUT_OF_MEMORY, kSamplesOutOfRange);
Jamie Madille8fb6402017-02-14 17:56:40 -05004662 return false;
4663 }
4664 }
4665
4666 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4667 width, height);
4668}
4669
Jamie Madill5b772312018-03-08 20:28:32 -05004670bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004671{
Geoff Lange8afa902017-09-27 15:00:43 -04004672 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004673 {
Jamie Madille0472f32018-11-27 16:32:45 -05004674 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004675 return false;
4676 }
4677
4678 return true;
4679}
4680
Jamie Madill5b772312018-03-08 20:28:32 -05004681bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004682{
4683 return true;
4684}
4685
Jamie Madill5b772312018-03-08 20:28:32 -05004686bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004687{
4688 return true;
4689}
4690
Jamie Madill5b772312018-03-08 20:28:32 -05004691bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004692{
4693 return true;
4694}
4695
Jamie Madill5b772312018-03-08 20:28:32 -05004696bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004697 GLboolean red,
4698 GLboolean green,
4699 GLboolean blue,
4700 GLboolean alpha)
4701{
4702 return true;
4703}
4704
Jamie Madill5b772312018-03-08 20:28:32 -05004705bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004706{
4707 return true;
4708}
4709
Jamie Madill5b772312018-03-08 20:28:32 -05004710bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004711{
4712 return true;
4713}
4714
Jamie Madill5b772312018-03-08 20:28:32 -05004715bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004716{
4717 switch (mode)
4718 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004719 case CullFaceMode::Front:
4720 case CullFaceMode::Back:
4721 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004722 break;
4723
4724 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004725 context->validationError(GL_INVALID_ENUM, kInvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004726 return false;
4727 }
4728
4729 return true;
4730}
4731
Jamie Madill5b772312018-03-08 20:28:32 -05004732bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004733{
4734 if (program == 0)
4735 {
4736 return false;
4737 }
4738
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004739 if (!context->getProgramResolveLink(program))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004740 {
4741 if (context->getShader(program))
4742 {
Jamie Madille0472f32018-11-27 16:32:45 -05004743 context->validationError(GL_INVALID_OPERATION, kExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004744 return false;
4745 }
4746 else
4747 {
Jamie Madille0472f32018-11-27 16:32:45 -05004748 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004749 return false;
4750 }
4751 }
4752
4753 return true;
4754}
4755
Jamie Madill5b772312018-03-08 20:28:32 -05004756bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004757{
4758 if (shader == 0)
4759 {
4760 return false;
4761 }
4762
4763 if (!context->getShader(shader))
4764 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004765 if (context->getProgramResolveLink(shader))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004766 {
Jamie Madille0472f32018-11-27 16:32:45 -05004767 context->validationError(GL_INVALID_OPERATION, kInvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004768 return false;
4769 }
4770 else
4771 {
Jamie Madille0472f32018-11-27 16:32:45 -05004772 context->validationError(GL_INVALID_VALUE, kExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004773 return false;
4774 }
4775 }
4776
4777 return true;
4778}
4779
Jamie Madill5b772312018-03-08 20:28:32 -05004780bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004781{
4782 switch (func)
4783 {
4784 case GL_NEVER:
4785 case GL_ALWAYS:
4786 case GL_LESS:
4787 case GL_LEQUAL:
4788 case GL_EQUAL:
4789 case GL_GREATER:
4790 case GL_GEQUAL:
4791 case GL_NOTEQUAL:
4792 break;
4793
4794 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004795 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004796 return false;
4797 }
4798
4799 return true;
4800}
4801
Jamie Madill5b772312018-03-08 20:28:32 -05004802bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004803{
4804 return true;
4805}
4806
Jamie Madill5b772312018-03-08 20:28:32 -05004807bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004808{
4809 Program *programObject = GetValidProgram(context, program);
4810 if (!programObject)
4811 {
4812 return false;
4813 }
4814
4815 Shader *shaderObject = GetValidShader(context, shader);
4816 if (!shaderObject)
4817 {
4818 return false;
4819 }
4820
Jiawei Shao385b3e02018-03-21 09:43:28 +08004821 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04004822 if (attachedShader != shaderObject)
4823 {
Jamie Madille0472f32018-11-27 16:32:45 -05004824 context->validationError(GL_INVALID_OPERATION, kShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004825 return false;
4826 }
4827
4828 return true;
4829}
4830
Jamie Madill5b772312018-03-08 20:28:32 -05004831bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004832{
4833 if (index >= MAX_VERTEX_ATTRIBS)
4834 {
Jamie Madille0472f32018-11-27 16:32:45 -05004835 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004836 return false;
4837 }
4838
4839 return true;
4840}
4841
Jamie Madill5b772312018-03-08 20:28:32 -05004842bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004843{
4844 if (index >= MAX_VERTEX_ATTRIBS)
4845 {
Jamie Madille0472f32018-11-27 16:32:45 -05004846 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004847 return false;
4848 }
4849
4850 return true;
4851}
4852
Jamie Madill5b772312018-03-08 20:28:32 -05004853bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004854{
4855 return true;
4856}
4857
Jamie Madill5b772312018-03-08 20:28:32 -05004858bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004859{
4860 return true;
4861}
4862
Jamie Madill5b772312018-03-08 20:28:32 -05004863bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004864{
4865 switch (mode)
4866 {
4867 case GL_CW:
4868 case GL_CCW:
4869 break;
4870 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004871 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004872 return false;
4873 }
4874
4875 return true;
4876}
4877
Jamie Madill5b772312018-03-08 20:28:32 -05004878bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004879 GLuint program,
4880 GLuint index,
4881 GLsizei bufsize,
4882 GLsizei *length,
4883 GLint *size,
4884 GLenum *type,
4885 GLchar *name)
4886{
4887 if (bufsize < 0)
4888 {
Jamie Madille0472f32018-11-27 16:32:45 -05004889 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004890 return false;
4891 }
4892
4893 Program *programObject = GetValidProgram(context, program);
4894
4895 if (!programObject)
4896 {
4897 return false;
4898 }
4899
4900 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
4901 {
Jamie Madille0472f32018-11-27 16:32:45 -05004902 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004903 return false;
4904 }
4905
4906 return true;
4907}
4908
Jamie Madill5b772312018-03-08 20:28:32 -05004909bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004910 GLuint program,
4911 GLuint index,
4912 GLsizei bufsize,
4913 GLsizei *length,
4914 GLint *size,
4915 GLenum *type,
4916 GLchar *name)
4917{
4918 if (bufsize < 0)
4919 {
Jamie Madille0472f32018-11-27 16:32:45 -05004920 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004921 return false;
4922 }
4923
4924 Program *programObject = GetValidProgram(context, program);
4925
4926 if (!programObject)
4927 {
4928 return false;
4929 }
4930
4931 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
4932 {
Jamie Madille0472f32018-11-27 16:32:45 -05004933 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform);
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 ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004941 GLuint program,
4942 GLsizei maxcount,
4943 GLsizei *count,
4944 GLuint *shaders)
4945{
4946 if (maxcount < 0)
4947 {
Jamie Madille0472f32018-11-27 16:32:45 -05004948 context->validationError(GL_INVALID_VALUE, kNegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004949 return false;
4950 }
4951
4952 Program *programObject = GetValidProgram(context, program);
4953
4954 if (!programObject)
4955 {
4956 return false;
4957 }
4958
4959 return true;
4960}
4961
Jamie Madill5b772312018-03-08 20:28:32 -05004962bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004963{
Geoff Langfc32e8b2017-05-31 14:16:59 -04004964 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
4965 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04004966 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04004967 {
Jamie Madille0472f32018-11-27 16:32:45 -05004968 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04004969 return false;
4970 }
4971
Jamie Madillc1d770e2017-04-13 17:31:24 -04004972 Program *programObject = GetValidProgram(context, program);
4973
4974 if (!programObject)
4975 {
Jamie Madille0472f32018-11-27 16:32:45 -05004976 context->validationError(GL_INVALID_OPERATION, kProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004977 return false;
4978 }
4979
4980 if (!programObject->isLinked())
4981 {
Jamie Madille0472f32018-11-27 16:32:45 -05004982 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004983 return false;
4984 }
4985
4986 return true;
4987}
4988
Jamie Madill5b772312018-03-08 20:28:32 -05004989bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004990{
4991 GLenum nativeType;
4992 unsigned int numParams = 0;
4993 return ValidateStateQuery(context, pname, &nativeType, &numParams);
4994}
4995
Jamie Madill5b772312018-03-08 20:28:32 -05004996bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004997{
4998 return true;
4999}
5000
Jamie Madill5b772312018-03-08 20:28:32 -05005001bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005002{
5003 GLenum nativeType;
5004 unsigned int numParams = 0;
5005 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5006}
5007
Jamie Madill5b772312018-03-08 20:28:32 -05005008bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005009{
5010 GLenum nativeType;
5011 unsigned int numParams = 0;
5012 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5013}
5014
Jamie Madill5b772312018-03-08 20:28:32 -05005015bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005016 GLuint program,
5017 GLsizei bufsize,
5018 GLsizei *length,
5019 GLchar *infolog)
5020{
5021 if (bufsize < 0)
5022 {
Jamie Madille0472f32018-11-27 16:32:45 -05005023 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005024 return false;
5025 }
5026
5027 Program *programObject = GetValidProgram(context, program);
5028 if (!programObject)
5029 {
5030 return false;
5031 }
5032
5033 return true;
5034}
5035
Jamie Madill5b772312018-03-08 20:28:32 -05005036bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005037 GLuint shader,
5038 GLsizei bufsize,
5039 GLsizei *length,
5040 GLchar *infolog)
5041{
5042 if (bufsize < 0)
5043 {
Jamie Madille0472f32018-11-27 16:32:45 -05005044 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005045 return false;
5046 }
5047
5048 Shader *shaderObject = GetValidShader(context, shader);
5049 if (!shaderObject)
5050 {
5051 return false;
5052 }
5053
5054 return true;
5055}
5056
Jamie Madill5b772312018-03-08 20:28:32 -05005057bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005058 GLenum shadertype,
5059 GLenum precisiontype,
5060 GLint *range,
5061 GLint *precision)
5062{
5063 switch (shadertype)
5064 {
5065 case GL_VERTEX_SHADER:
5066 case GL_FRAGMENT_SHADER:
5067 break;
5068 case GL_COMPUTE_SHADER:
Jamie Madillc3e37312018-11-30 15:25:39 -05005069 context->validationError(GL_INVALID_OPERATION, kUnimplementedComputeShaderPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005070 return false;
5071 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005072 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005073 return false;
5074 }
5075
5076 switch (precisiontype)
5077 {
5078 case GL_LOW_FLOAT:
5079 case GL_MEDIUM_FLOAT:
5080 case GL_HIGH_FLOAT:
5081 case GL_LOW_INT:
5082 case GL_MEDIUM_INT:
5083 case GL_HIGH_INT:
5084 break;
5085
5086 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005087 context->validationError(GL_INVALID_ENUM, kInvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005088 return false;
5089 }
5090
5091 return true;
5092}
5093
Jamie Madill5b772312018-03-08 20:28:32 -05005094bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005095 GLuint shader,
5096 GLsizei bufsize,
5097 GLsizei *length,
5098 GLchar *source)
5099{
5100 if (bufsize < 0)
5101 {
Jamie Madille0472f32018-11-27 16:32:45 -05005102 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005103 return false;
5104 }
5105
5106 Shader *shaderObject = GetValidShader(context, shader);
5107 if (!shaderObject)
5108 {
5109 return false;
5110 }
5111
5112 return true;
5113}
5114
Jamie Madill5b772312018-03-08 20:28:32 -05005115bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005116{
5117 if (strstr(name, "gl_") == name)
5118 {
5119 return false;
5120 }
5121
Geoff Langfc32e8b2017-05-31 14:16:59 -04005122 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5123 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005124 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005125 {
Jamie Madille0472f32018-11-27 16:32:45 -05005126 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005127 return false;
5128 }
5129
Jamie Madillc1d770e2017-04-13 17:31:24 -04005130 Program *programObject = GetValidProgram(context, program);
5131
5132 if (!programObject)
5133 {
5134 return false;
5135 }
5136
5137 if (!programObject->isLinked())
5138 {
Jamie Madille0472f32018-11-27 16:32:45 -05005139 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005140 return false;
5141 }
5142
5143 return true;
5144}
5145
Jamie Madill5b772312018-03-08 20:28:32 -05005146bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005147{
5148 switch (mode)
5149 {
5150 case GL_FASTEST:
5151 case GL_NICEST:
5152 case GL_DONT_CARE:
5153 break;
5154
5155 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005156 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005157 return false;
5158 }
5159
5160 switch (target)
5161 {
5162 case GL_GENERATE_MIPMAP_HINT:
5163 break;
5164
Geoff Lange7bd2182017-06-16 16:13:13 -04005165 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5166 if (context->getClientVersion() < ES_3_0 &&
5167 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005168 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005169 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005170 return false;
5171 }
5172 break;
5173
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07005174 case GL_PERSPECTIVE_CORRECTION_HINT:
5175 case GL_POINT_SMOOTH_HINT:
5176 case GL_LINE_SMOOTH_HINT:
5177 case GL_FOG_HINT:
5178 if (context->getClientMajorVersion() >= 2)
5179 {
Jamie Madille0472f32018-11-27 16:32:45 -05005180 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07005181 return false;
5182 }
5183 break;
5184
Jamie Madillc1d770e2017-04-13 17:31:24 -04005185 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005186 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005187 return false;
5188 }
5189
5190 return true;
5191}
5192
Jamie Madill5b772312018-03-08 20:28:32 -05005193bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005194{
5195 return true;
5196}
5197
Jamie Madill5b772312018-03-08 20:28:32 -05005198bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005199{
5200 return true;
5201}
5202
Jamie Madill5b772312018-03-08 20:28:32 -05005203bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005204{
5205 return true;
5206}
5207
Jamie Madill5b772312018-03-08 20:28:32 -05005208bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005209{
5210 return true;
5211}
5212
Jamie Madill5b772312018-03-08 20:28:32 -05005213bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005214{
5215 return true;
5216}
5217
Jamie Madill5b772312018-03-08 20:28:32 -05005218bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005219{
5220 return true;
5221}
5222
Jamie Madill5b772312018-03-08 20:28:32 -05005223bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005224{
5225 if (context->getClientMajorVersion() < 3)
5226 {
5227 switch (pname)
5228 {
5229 case GL_UNPACK_IMAGE_HEIGHT:
5230 case GL_UNPACK_SKIP_IMAGES:
Jamie Madille0472f32018-11-27 16:32:45 -05005231 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005232 return false;
5233
5234 case GL_UNPACK_ROW_LENGTH:
5235 case GL_UNPACK_SKIP_ROWS:
5236 case GL_UNPACK_SKIP_PIXELS:
5237 if (!context->getExtensions().unpackSubimage)
5238 {
Jamie Madille0472f32018-11-27 16:32:45 -05005239 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005240 return false;
5241 }
5242 break;
5243
5244 case GL_PACK_ROW_LENGTH:
5245 case GL_PACK_SKIP_ROWS:
5246 case GL_PACK_SKIP_PIXELS:
5247 if (!context->getExtensions().packSubimage)
5248 {
Jamie Madille0472f32018-11-27 16:32:45 -05005249 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005250 return false;
5251 }
5252 break;
5253 }
5254 }
5255
5256 if (param < 0)
5257 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005258 context->validationError(GL_INVALID_VALUE, kNegativeParam);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005259 return false;
5260 }
5261
5262 switch (pname)
5263 {
5264 case GL_UNPACK_ALIGNMENT:
5265 if (param != 1 && param != 2 && param != 4 && param != 8)
5266 {
Jamie Madille0472f32018-11-27 16:32:45 -05005267 context->validationError(GL_INVALID_VALUE, kInvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005268 return false;
5269 }
5270 break;
5271
5272 case GL_PACK_ALIGNMENT:
5273 if (param != 1 && param != 2 && param != 4 && param != 8)
5274 {
Jamie Madille0472f32018-11-27 16:32:45 -05005275 context->validationError(GL_INVALID_VALUE, kInvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005276 return false;
5277 }
5278 break;
5279
5280 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005281 if (!context->getExtensions().packReverseRowOrder)
5282 {
Jamie Madille0472f32018-11-27 16:32:45 -05005283 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang000dab82017-09-27 14:27:07 -04005284 }
5285 break;
5286
Jamie Madillc1d770e2017-04-13 17:31:24 -04005287 case GL_UNPACK_ROW_LENGTH:
5288 case GL_UNPACK_IMAGE_HEIGHT:
5289 case GL_UNPACK_SKIP_IMAGES:
5290 case GL_UNPACK_SKIP_ROWS:
5291 case GL_UNPACK_SKIP_PIXELS:
5292 case GL_PACK_ROW_LENGTH:
5293 case GL_PACK_SKIP_ROWS:
5294 case GL_PACK_SKIP_PIXELS:
5295 break;
5296
5297 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005298 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005299 return false;
5300 }
5301
5302 return true;
5303}
5304
Jamie Madill5b772312018-03-08 20:28:32 -05005305bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005306{
5307 return true;
5308}
5309
Jamie Madill5b772312018-03-08 20:28:32 -05005310bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005311{
5312 return true;
5313}
5314
Jamie Madill5b772312018-03-08 20:28:32 -05005315bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005316{
5317 return true;
5318}
5319
Jamie Madill5b772312018-03-08 20:28:32 -05005320bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005321{
5322 if (width < 0 || height < 0)
5323 {
Jamie Madille0472f32018-11-27 16:32:45 -05005324 context->validationError(GL_INVALID_VALUE, kNegativeSize);
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 ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005332 GLsizei n,
5333 const GLuint *shaders,
5334 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005335 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005336 GLsizei length)
5337{
5338 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5339 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5340 shaderBinaryFormats.end())
5341 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005342 context->validationError(GL_INVALID_ENUM, kInvalidShaderBinaryFormat);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005343 return false;
5344 }
5345
5346 return true;
5347}
5348
Jamie Madill5b772312018-03-08 20:28:32 -05005349bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005350 GLuint shader,
5351 GLsizei count,
5352 const GLchar *const *string,
5353 const GLint *length)
5354{
5355 if (count < 0)
5356 {
Jamie Madille0472f32018-11-27 16:32:45 -05005357 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005358 return false;
5359 }
5360
Geoff Langfc32e8b2017-05-31 14:16:59 -04005361 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5362 // shader-related entry points
5363 if (context->getExtensions().webglCompatibility)
5364 {
5365 for (GLsizei i = 0; i < count; i++)
5366 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005367 size_t len =
5368 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005369
5370 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005371 if (!IsValidESSLShaderSourceString(string[i], len,
5372 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005373 {
Jamie Madille0472f32018-11-27 16:32:45 -05005374 context->validationError(GL_INVALID_VALUE, kShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005375 return false;
5376 }
5377 }
5378 }
5379
Jamie Madillc1d770e2017-04-13 17:31:24 -04005380 Shader *shaderObject = GetValidShader(context, shader);
5381 if (!shaderObject)
5382 {
5383 return false;
5384 }
5385
5386 return true;
5387}
5388
Jamie Madill5b772312018-03-08 20:28:32 -05005389bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005390{
5391 if (!IsValidStencilFunc(func))
5392 {
Jamie Madille0472f32018-11-27 16:32:45 -05005393 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005394 return false;
5395 }
5396
5397 return true;
5398}
5399
Jamie Madill5b772312018-03-08 20:28:32 -05005400bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005401{
5402 if (!IsValidStencilFace(face))
5403 {
Jamie Madille0472f32018-11-27 16:32:45 -05005404 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005405 return false;
5406 }
5407
5408 if (!IsValidStencilFunc(func))
5409 {
Jamie Madille0472f32018-11-27 16:32:45 -05005410 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005411 return false;
5412 }
5413
5414 return true;
5415}
5416
Jamie Madill5b772312018-03-08 20:28:32 -05005417bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005418{
5419 return true;
5420}
5421
Jamie Madill5b772312018-03-08 20:28:32 -05005422bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005423{
5424 if (!IsValidStencilFace(face))
5425 {
Jamie Madille0472f32018-11-27 16:32:45 -05005426 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005427 return false;
5428 }
5429
5430 return true;
5431}
5432
Jamie Madill5b772312018-03-08 20:28:32 -05005433bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005434{
5435 if (!IsValidStencilOp(fail))
5436 {
Jamie Madille0472f32018-11-27 16:32:45 -05005437 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005438 return false;
5439 }
5440
5441 if (!IsValidStencilOp(zfail))
5442 {
Jamie Madille0472f32018-11-27 16:32:45 -05005443 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005444 return false;
5445 }
5446
5447 if (!IsValidStencilOp(zpass))
5448 {
Jamie Madille0472f32018-11-27 16:32:45 -05005449 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005450 return false;
5451 }
5452
5453 return true;
5454}
5455
Jamie Madill5b772312018-03-08 20:28:32 -05005456bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005457 GLenum face,
5458 GLenum fail,
5459 GLenum zfail,
5460 GLenum zpass)
5461{
5462 if (!IsValidStencilFace(face))
5463 {
Jamie Madille0472f32018-11-27 16:32:45 -05005464 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005465 return false;
5466 }
5467
5468 return ValidateStencilOp(context, fail, zfail, zpass);
5469}
5470
Jamie Madill5b772312018-03-08 20:28:32 -05005471bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005472{
5473 return ValidateUniform(context, GL_FLOAT, location, 1);
5474}
5475
Jamie Madill5b772312018-03-08 20:28:32 -05005476bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005477{
5478 return ValidateUniform(context, GL_FLOAT, location, count);
5479}
5480
Jamie Madill5b772312018-03-08 20:28:32 -05005481bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005482{
5483 return ValidateUniform1iv(context, location, 1, &x);
5484}
5485
Jamie Madill5b772312018-03-08 20:28:32 -05005486bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005487{
5488 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5489}
5490
Jamie Madill5b772312018-03-08 20:28:32 -05005491bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005492{
5493 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5494}
5495
Jamie Madill5b772312018-03-08 20:28:32 -05005496bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005497{
5498 return ValidateUniform(context, GL_INT_VEC2, location, count);
5499}
5500
Jamie Madill5b772312018-03-08 20:28:32 -05005501bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005502{
5503 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5504}
5505
Jamie Madill5b772312018-03-08 20:28:32 -05005506bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005507{
5508 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5509}
5510
Jamie Madill5b772312018-03-08 20:28:32 -05005511bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005512{
5513 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5514}
5515
Jamie Madill5b772312018-03-08 20:28:32 -05005516bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005517{
5518 return ValidateUniform(context, GL_INT_VEC3, location, count);
5519}
5520
Jamie Madill5b772312018-03-08 20:28:32 -05005521bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005522{
5523 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5524}
5525
Jamie Madill5b772312018-03-08 20:28:32 -05005526bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005527{
5528 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5529}
5530
Jamie Madill5b772312018-03-08 20:28:32 -05005531bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005532{
5533 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5534}
5535
Jamie Madill5b772312018-03-08 20:28:32 -05005536bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005537{
5538 return ValidateUniform(context, GL_INT_VEC4, location, count);
5539}
5540
Jamie Madill5b772312018-03-08 20:28:32 -05005541bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005542 GLint location,
5543 GLsizei count,
5544 GLboolean transpose,
5545 const GLfloat *value)
5546{
5547 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5548}
5549
Jamie Madill5b772312018-03-08 20:28:32 -05005550bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005551 GLint location,
5552 GLsizei count,
5553 GLboolean transpose,
5554 const GLfloat *value)
5555{
5556 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5557}
5558
Jamie Madill5b772312018-03-08 20:28:32 -05005559bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005560 GLint location,
5561 GLsizei count,
5562 GLboolean transpose,
5563 const GLfloat *value)
5564{
5565 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5566}
5567
Jamie Madill5b772312018-03-08 20:28:32 -05005568bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005569{
5570 Program *programObject = GetValidProgram(context, program);
5571
5572 if (!programObject)
5573 {
5574 return false;
5575 }
5576
5577 return true;
5578}
5579
Jamie Madill5b772312018-03-08 20:28:32 -05005580bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005581{
5582 return ValidateVertexAttribIndex(context, index);
5583}
5584
Jamie Madill5b772312018-03-08 20:28:32 -05005585bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005586{
5587 return ValidateVertexAttribIndex(context, index);
5588}
5589
Jamie Madill5b772312018-03-08 20:28:32 -05005590bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005591{
5592 return ValidateVertexAttribIndex(context, index);
5593}
5594
Jamie Madill5b772312018-03-08 20:28:32 -05005595bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005596{
5597 return ValidateVertexAttribIndex(context, index);
5598}
5599
Jamie Madill5b772312018-03-08 20:28:32 -05005600bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005601{
5602 return ValidateVertexAttribIndex(context, index);
5603}
5604
Jamie Madill5b772312018-03-08 20:28:32 -05005605bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005606{
5607 return ValidateVertexAttribIndex(context, index);
5608}
5609
Jamie Madill5b772312018-03-08 20:28:32 -05005610bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005611 GLuint index,
5612 GLfloat x,
5613 GLfloat y,
5614 GLfloat z,
5615 GLfloat w)
5616{
5617 return ValidateVertexAttribIndex(context, index);
5618}
5619
Jamie Madill5b772312018-03-08 20:28:32 -05005620bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005621{
5622 return ValidateVertexAttribIndex(context, index);
5623}
5624
Jamie Madill5b772312018-03-08 20:28:32 -05005625bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005626{
5627 if (width < 0 || height < 0)
5628 {
Jamie Madille0472f32018-11-27 16:32:45 -05005629 context->validationError(GL_INVALID_VALUE, kViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005630 return false;
5631 }
5632
5633 return true;
5634}
5635
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005636bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005637 GLenum target,
5638 GLenum attachment,
5639 GLenum pname,
5640 GLint *params)
5641{
5642 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5643 nullptr);
5644}
5645
Jamie Madill5b772312018-03-08 20:28:32 -05005646bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04005647{
5648 return ValidateGetProgramivBase(context, program, pname, nullptr);
5649}
5650
Jamie Madill5b772312018-03-08 20:28:32 -05005651bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005652 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005653 GLint level,
5654 GLenum internalformat,
5655 GLint x,
5656 GLint y,
5657 GLsizei width,
5658 GLsizei height,
5659 GLint border)
5660{
5661 if (context->getClientMajorVersion() < 3)
5662 {
5663 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5664 0, x, y, width, height, border);
5665 }
5666
5667 ASSERT(context->getClientMajorVersion() == 3);
5668 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5669 0, x, y, width, height, border);
5670}
5671
5672bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005673 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005674 GLint level,
5675 GLint xoffset,
5676 GLint yoffset,
5677 GLint x,
5678 GLint y,
5679 GLsizei width,
5680 GLsizei height)
5681{
5682 if (context->getClientMajorVersion() < 3)
5683 {
5684 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5685 yoffset, x, y, width, height, 0);
5686 }
5687
5688 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5689 yoffset, 0, x, y, width, height, 0);
5690}
5691
5692bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5693{
5694 return ValidateGenOrDelete(context, n);
5695}
5696
5697bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5698{
5699 return ValidateGenOrDelete(context, n);
5700}
5701
5702bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5703{
5704 return ValidateGenOrDelete(context, n);
5705}
5706
5707bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5708{
5709 return ValidateGenOrDelete(context, n);
5710}
5711
5712bool ValidateDisable(Context *context, GLenum cap)
5713{
5714 if (!ValidCap(context, cap, false))
5715 {
Jamie Madille0472f32018-11-27 16:32:45 -05005716 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005717 return false;
5718 }
5719
5720 return true;
5721}
5722
5723bool ValidateEnable(Context *context, GLenum cap)
5724{
5725 if (!ValidCap(context, cap, false))
5726 {
Jamie Madille0472f32018-11-27 16:32:45 -05005727 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005728 return false;
5729 }
5730
5731 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5732 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5733 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005734 context->validationError(GL_INVALID_OPERATION, kNoSampleAlphaToCoveragesLimitation);
Jamie Madillbe849e42017-05-02 15:49:00 -04005735
5736 // We also output an error message to the debugger window if tracing is active, so that
5737 // developers can see the error message.
Jamie Madillc3e37312018-11-30 15:25:39 -05005738 ERR() << kNoSampleAlphaToCoveragesLimitation;
Jamie Madillbe849e42017-05-02 15:49:00 -04005739 return false;
5740 }
5741
5742 return true;
5743}
5744
5745bool ValidateFramebufferRenderbuffer(Context *context,
5746 GLenum target,
5747 GLenum attachment,
5748 GLenum renderbuffertarget,
5749 GLuint renderbuffer)
5750{
Geoff Lange8afa902017-09-27 15:00:43 -04005751 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005752 {
Jamie Madille0472f32018-11-27 16:32:45 -05005753 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Brandon Jones6cad5662017-06-14 13:25:13 -07005754 return false;
5755 }
5756
5757 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5758 {
Jamie Madille0472f32018-11-27 16:32:45 -05005759 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005760 return false;
5761 }
5762
5763 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5764 renderbuffertarget, renderbuffer);
5765}
5766
5767bool ValidateFramebufferTexture2D(Context *context,
5768 GLenum target,
5769 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005770 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04005771 GLuint texture,
5772 GLint level)
5773{
5774 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5775 // extension
5776 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5777 level != 0)
5778 {
Jamie Madille0472f32018-11-27 16:32:45 -05005779 context->validationError(GL_INVALID_VALUE, kInvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005780 return false;
5781 }
5782
5783 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5784 {
5785 return false;
5786 }
5787
5788 if (texture != 0)
5789 {
5790 gl::Texture *tex = context->getTexture(texture);
5791 ASSERT(tex);
5792
5793 const gl::Caps &caps = context->getCaps();
5794
5795 switch (textarget)
5796 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005797 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04005798 {
5799 if (level > gl::log2(caps.max2DTextureSize))
5800 {
Jamie Madille0472f32018-11-27 16:32:45 -05005801 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005802 return false;
5803 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005804 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04005805 {
Jamie Madille0472f32018-11-27 16:32:45 -05005806 context->validationError(GL_INVALID_OPERATION, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005807 return false;
5808 }
5809 }
5810 break;
5811
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005812 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005813 {
5814 if (level != 0)
5815 {
Jamie Madille0472f32018-11-27 16:32:45 -05005816 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005817 return false;
5818 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005819 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005820 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005821 context->validationError(GL_INVALID_OPERATION, kTextureTargetMismatch);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005822 return false;
5823 }
5824 }
5825 break;
5826
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005827 case TextureTarget::CubeMapNegativeX:
5828 case TextureTarget::CubeMapNegativeY:
5829 case TextureTarget::CubeMapNegativeZ:
5830 case TextureTarget::CubeMapPositiveX:
5831 case TextureTarget::CubeMapPositiveY:
5832 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04005833 {
5834 if (level > gl::log2(caps.maxCubeMapTextureSize))
5835 {
Jamie Madille0472f32018-11-27 16:32:45 -05005836 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005837 return false;
5838 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005839 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04005840 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005841 context->validationError(GL_INVALID_OPERATION, kTextureTargetMismatch);
Jamie Madillbe849e42017-05-02 15:49:00 -04005842 return false;
5843 }
5844 }
5845 break;
5846
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005847 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04005848 {
Yizhou Jiang7818a852018-09-06 15:02:04 +08005849 if (context->getClientVersion() < ES_3_1 &&
5850 !context->getExtensions().textureMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04005851 {
Jamie Madill610640f2018-11-21 17:28:41 -05005852 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05005853 kMultisampleTextureExtensionOrES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04005854 return false;
5855 }
5856
5857 if (level != 0)
5858 {
Jamie Madille0472f32018-11-27 16:32:45 -05005859 context->validationError(GL_INVALID_VALUE, kLevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04005860 return false;
5861 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005862 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04005863 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005864 context->validationError(GL_INVALID_OPERATION, kTextureTargetMismatch);
Jamie Madillbe849e42017-05-02 15:49:00 -04005865 return false;
5866 }
5867 }
5868 break;
5869
5870 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005871 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005872 return false;
5873 }
Jamie Madillbe849e42017-05-02 15:49:00 -04005874 }
5875
5876 return true;
5877}
5878
5879bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
5880{
5881 return ValidateGenOrDelete(context, n);
5882}
5883
5884bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
5885{
5886 return ValidateGenOrDelete(context, n);
5887}
5888
5889bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
5890{
5891 return ValidateGenOrDelete(context, n);
5892}
5893
5894bool ValidateGenTextures(Context *context, GLint n, GLuint *)
5895{
5896 return ValidateGenOrDelete(context, n);
5897}
5898
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005899bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04005900{
5901 if (!ValidTextureTarget(context, target))
5902 {
Jamie Madille0472f32018-11-27 16:32:45 -05005903 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005904 return false;
5905 }
5906
5907 Texture *texture = context->getTargetTexture(target);
5908
5909 if (texture == nullptr)
5910 {
Jamie Madille0472f32018-11-27 16:32:45 -05005911 context->validationError(GL_INVALID_OPERATION, kTextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005912 return false;
5913 }
5914
5915 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
5916
5917 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
5918 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
5919 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
5920 {
Jamie Madille0472f32018-11-27 16:32:45 -05005921 context->validationError(GL_INVALID_OPERATION, kBaseLevelOutOfRange);
Jamie Madillbe849e42017-05-02 15:49:00 -04005922 return false;
5923 }
5924
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005925 TextureTarget baseTarget = (target == TextureType::CubeMap)
5926 ? TextureTarget::CubeMapPositiveX
5927 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04005928 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
5929 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
5930 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07005931 {
Jamie Madille0472f32018-11-27 16:32:45 -05005932 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Brandon Jones6cad5662017-06-14 13:25:13 -07005933 return false;
5934 }
5935
Geoff Lang536eca12017-09-13 11:23:35 -04005936 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
5937 bool formatUnsized = !format.sized;
5938 bool formatColorRenderableAndFilterable =
5939 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
Yuly Novikovf15f8862018-06-04 18:59:41 -04005940 format.textureAttachmentSupport(context->getClientVersion(), context->getExtensions());
Geoff Lang536eca12017-09-13 11:23:35 -04005941 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04005942 {
Jamie Madille0472f32018-11-27 16:32:45 -05005943 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04005944 return false;
5945 }
5946
Geoff Lang536eca12017-09-13 11:23:35 -04005947 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
5948 // generation
5949 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
5950 {
Jamie Madille0472f32018-11-27 16:32:45 -05005951 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Geoff Lang536eca12017-09-13 11:23:35 -04005952 return false;
5953 }
5954
Jiange2c00842018-07-13 16:50:49 +08005955 // According to the OpenGL extension spec EXT_sRGB.txt, EXT_SRGB is based on ES 2.0 and
5956 // generateMipmap is not allowed if texture format is SRGB_EXT or SRGB_ALPHA_EXT.
5957 if (context->getClientVersion() < Version(3, 0) && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04005958 {
Jamie Madille0472f32018-11-27 16:32:45 -05005959 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04005960 return false;
5961 }
5962
5963 // Non-power of 2 ES2 check
5964 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
5965 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
5966 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
5967 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005968 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
5969 target == TextureType::CubeMap);
Jamie Madille0472f32018-11-27 16:32:45 -05005970 context->validationError(GL_INVALID_OPERATION, kTextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04005971 return false;
5972 }
5973
5974 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005975 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04005976 {
Jamie Madille0472f32018-11-27 16:32:45 -05005977 context->validationError(GL_INVALID_OPERATION, kCubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04005978 return false;
5979 }
5980
James Darpinian83b2f0e2018-11-27 15:56:01 -08005981 if (context->getExtensions().webglCompatibility &&
5982 (texture->getWidth(baseTarget, effectiveBaseLevel) == 0 ||
5983 texture->getHeight(baseTarget, effectiveBaseLevel) == 0))
5984 {
5985 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapZeroSize);
5986 return false;
5987 }
5988
Jamie Madillbe849e42017-05-02 15:49:00 -04005989 return true;
5990}
5991
Jamie Madill5b772312018-03-08 20:28:32 -05005992bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04005993 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005994 GLenum pname,
5995 GLint *params)
5996{
5997 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
5998}
5999
6000bool ValidateGetRenderbufferParameteriv(Context *context,
6001 GLenum target,
6002 GLenum pname,
6003 GLint *params)
6004{
6005 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6006}
6007
6008bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6009{
6010 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6011}
6012
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006013bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006014{
6015 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6016}
6017
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006018bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006019{
6020 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6021}
6022
Till Rathmannb8543632018-10-02 19:46:14 +02006023bool ValidateGetTexParameterIivOES(Context *context,
6024 TextureType target,
6025 GLenum pname,
6026 GLint *params)
6027{
6028 if (context->getClientMajorVersion() < 3)
6029 {
Jamie Madille0472f32018-11-27 16:32:45 -05006030 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006031 return false;
6032 }
6033 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6034}
6035
6036bool ValidateGetTexParameterIuivOES(Context *context,
6037 TextureType target,
6038 GLenum pname,
6039 GLuint *params)
6040{
6041 if (context->getClientMajorVersion() < 3)
6042 {
Jamie Madille0472f32018-11-27 16:32:45 -05006043 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006044 return false;
6045 }
6046 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6047}
6048
Jamie Madillbe849e42017-05-02 15:49:00 -04006049bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6050{
6051 return ValidateGetUniformBase(context, program, location);
6052}
6053
6054bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6055{
6056 return ValidateGetUniformBase(context, program, location);
6057}
6058
6059bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6060{
6061 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6062}
6063
6064bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6065{
6066 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6067}
6068
6069bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6070{
6071 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6072}
6073
6074bool ValidateIsEnabled(Context *context, GLenum cap)
6075{
6076 if (!ValidCap(context, cap, true))
6077 {
Jamie Madille0472f32018-11-27 16:32:45 -05006078 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006079 return false;
6080 }
6081
6082 return true;
6083}
6084
6085bool ValidateLinkProgram(Context *context, GLuint program)
6086{
6087 if (context->hasActiveTransformFeedback(program))
6088 {
6089 // ES 3.0.4 section 2.15 page 91
Jamie Madillc3e37312018-11-30 15:25:39 -05006090 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackActiveDuringLink);
Jamie Madillbe849e42017-05-02 15:49:00 -04006091 return false;
6092 }
6093
6094 Program *programObject = GetValidProgram(context, program);
6095 if (!programObject)
6096 {
6097 return false;
6098 }
6099
6100 return true;
6101}
6102
Jamie Madill4928b7c2017-06-20 12:57:39 -04006103bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006104 GLint x,
6105 GLint y,
6106 GLsizei width,
6107 GLsizei height,
6108 GLenum format,
6109 GLenum type,
6110 void *pixels)
6111{
6112 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6113 nullptr, pixels);
6114}
6115
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006116bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006117{
Till Rathmannb8543632018-10-02 19:46:14 +02006118 return ValidateTexParameterBase(context, target, pname, -1, false, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006119}
6120
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006121bool ValidateTexParameterfv(Context *context,
6122 TextureType target,
6123 GLenum pname,
6124 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006125{
Till Rathmannb8543632018-10-02 19:46:14 +02006126 return ValidateTexParameterBase(context, target, pname, -1, true, params);
Jamie Madillbe849e42017-05-02 15:49:00 -04006127}
6128
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006129bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006130{
Till Rathmannb8543632018-10-02 19:46:14 +02006131 return ValidateTexParameterBase(context, target, pname, -1, false, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006132}
6133
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006134bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006135{
Till Rathmannb8543632018-10-02 19:46:14 +02006136 return ValidateTexParameterBase(context, target, pname, -1, true, params);
6137}
6138
6139bool ValidateTexParameterIivOES(Context *context,
6140 TextureType target,
6141 GLenum pname,
6142 const GLint *params)
6143{
6144 if (context->getClientMajorVersion() < 3)
6145 {
Jamie Madille0472f32018-11-27 16:32:45 -05006146 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006147 return false;
6148 }
6149 return ValidateTexParameterBase(context, target, pname, -1, true, params);
6150}
6151
6152bool ValidateTexParameterIuivOES(Context *context,
6153 TextureType target,
6154 GLenum pname,
6155 const GLuint *params)
6156{
6157 if (context->getClientMajorVersion() < 3)
6158 {
Jamie Madille0472f32018-11-27 16:32:45 -05006159 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006160 return false;
6161 }
6162 return ValidateTexParameterBase(context, target, pname, -1, true, params);
Jamie Madillbe849e42017-05-02 15:49:00 -04006163}
6164
6165bool ValidateUseProgram(Context *context, GLuint program)
6166{
6167 if (program != 0)
6168 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04006169 Program *programObject = context->getProgramResolveLink(program);
Jamie Madillbe849e42017-05-02 15:49:00 -04006170 if (!programObject)
6171 {
6172 // ES 3.1.0 section 7.3 page 72
6173 if (context->getShader(program))
6174 {
Jamie Madille0472f32018-11-27 16:32:45 -05006175 context->validationError(GL_INVALID_OPERATION, kExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006176 return false;
6177 }
6178 else
6179 {
Jamie Madille0472f32018-11-27 16:32:45 -05006180 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006181 return false;
6182 }
6183 }
6184 if (!programObject->isLinked())
6185 {
Jamie Madille0472f32018-11-27 16:32:45 -05006186 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006187 return false;
6188 }
6189 }
Jamie Madillc3dc5d42018-12-30 12:12:04 -05006190 if (context->getState().isTransformFeedbackActiveUnpaused())
Jamie Madillbe849e42017-05-02 15:49:00 -04006191 {
6192 // ES 3.0.4 section 2.15 page 91
Jamie Madillc3e37312018-11-30 15:25:39 -05006193 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackUseProgram);
Jamie Madillbe849e42017-05-02 15:49:00 -04006194 return false;
6195 }
6196
6197 return true;
6198}
6199
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006200bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6201{
6202 if (!context->getExtensions().fence)
6203 {
Jamie Madille0472f32018-11-27 16:32:45 -05006204 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006205 return false;
6206 }
6207
6208 if (n < 0)
6209 {
Jamie Madille0472f32018-11-27 16:32:45 -05006210 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006211 return false;
6212 }
6213
6214 return true;
6215}
6216
6217bool ValidateFinishFenceNV(Context *context, GLuint fence)
6218{
6219 if (!context->getExtensions().fence)
6220 {
Jamie Madille0472f32018-11-27 16:32:45 -05006221 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006222 return false;
6223 }
6224
6225 FenceNV *fenceObject = context->getFenceNV(fence);
6226
6227 if (fenceObject == nullptr)
6228 {
Jamie Madille0472f32018-11-27 16:32:45 -05006229 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006230 return false;
6231 }
6232
6233 if (!fenceObject->isSet())
6234 {
Jamie Madille0472f32018-11-27 16:32:45 -05006235 context->validationError(GL_INVALID_OPERATION, kInvalidFenceState);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006236 return false;
6237 }
6238
6239 return true;
6240}
6241
6242bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6243{
6244 if (!context->getExtensions().fence)
6245 {
Jamie Madille0472f32018-11-27 16:32:45 -05006246 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006247 return false;
6248 }
6249
6250 if (n < 0)
6251 {
Jamie Madille0472f32018-11-27 16:32:45 -05006252 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006253 return false;
6254 }
6255
6256 return true;
6257}
6258
6259bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6260{
6261 if (!context->getExtensions().fence)
6262 {
Jamie Madille0472f32018-11-27 16:32:45 -05006263 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006264 return false;
6265 }
6266
6267 FenceNV *fenceObject = context->getFenceNV(fence);
6268
6269 if (fenceObject == nullptr)
6270 {
Jamie Madille0472f32018-11-27 16:32:45 -05006271 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006272 return false;
6273 }
6274
6275 if (!fenceObject->isSet())
6276 {
Jamie Madille0472f32018-11-27 16:32:45 -05006277 context->validationError(GL_INVALID_OPERATION, kInvalidFenceState);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006278 return false;
6279 }
6280
6281 switch (pname)
6282 {
6283 case GL_FENCE_STATUS_NV:
6284 case GL_FENCE_CONDITION_NV:
6285 break;
6286
6287 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006288 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006289 return false;
6290 }
6291
6292 return true;
6293}
6294
6295bool ValidateGetGraphicsResetStatusEXT(Context *context)
6296{
6297 if (!context->getExtensions().robustness)
6298 {
Jamie Madille0472f32018-11-27 16:32:45 -05006299 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006300 return false;
6301 }
6302
6303 return true;
6304}
6305
6306bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6307 GLuint shader,
6308 GLsizei bufsize,
6309 GLsizei *length,
6310 GLchar *source)
6311{
6312 if (!context->getExtensions().translatedShaderSource)
6313 {
Jamie Madille0472f32018-11-27 16:32:45 -05006314 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006315 return false;
6316 }
6317
6318 if (bufsize < 0)
6319 {
Jamie Madille0472f32018-11-27 16:32:45 -05006320 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006321 return false;
6322 }
6323
6324 Shader *shaderObject = context->getShader(shader);
6325
6326 if (!shaderObject)
6327 {
Jamie Madille0472f32018-11-27 16:32:45 -05006328 context->validationError(GL_INVALID_OPERATION, kInvalidShaderName);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006329 return false;
6330 }
6331
6332 return true;
6333}
6334
6335bool ValidateIsFenceNV(Context *context, GLuint fence)
6336{
6337 if (!context->getExtensions().fence)
6338 {
Jamie Madille0472f32018-11-27 16:32:45 -05006339 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006340 return false;
6341 }
6342
6343 return true;
6344}
6345
Jamie Madill007530e2017-12-28 14:27:04 -05006346bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6347{
6348 if (!context->getExtensions().fence)
6349 {
Jamie Madille0472f32018-11-27 16:32:45 -05006350 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill007530e2017-12-28 14:27:04 -05006351 return false;
6352 }
6353
6354 if (condition != GL_ALL_COMPLETED_NV)
6355 {
Jamie Madille0472f32018-11-27 16:32:45 -05006356 context->validationError(GL_INVALID_ENUM, kInvalidFenceCondition);
Jamie Madill007530e2017-12-28 14:27:04 -05006357 return false;
6358 }
6359
6360 FenceNV *fenceObject = context->getFenceNV(fence);
6361
6362 if (fenceObject == nullptr)
6363 {
Jamie Madille0472f32018-11-27 16:32:45 -05006364 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill007530e2017-12-28 14:27:04 -05006365 return false;
6366 }
6367
6368 return true;
6369}
6370
6371bool ValidateTestFenceNV(Context *context, GLuint fence)
6372{
6373 if (!context->getExtensions().fence)
6374 {
Jamie Madille0472f32018-11-27 16:32:45 -05006375 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill007530e2017-12-28 14:27:04 -05006376 return false;
6377 }
6378
6379 FenceNV *fenceObject = context->getFenceNV(fence);
6380
6381 if (fenceObject == nullptr)
6382 {
Jamie Madille0472f32018-11-27 16:32:45 -05006383 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill007530e2017-12-28 14:27:04 -05006384 return false;
6385 }
6386
6387 if (fenceObject->isSet() != GL_TRUE)
6388 {
Jamie Madille0472f32018-11-27 16:32:45 -05006389 context->validationError(GL_INVALID_OPERATION, kInvalidFenceState);
Jamie Madill007530e2017-12-28 14:27:04 -05006390 return false;
6391 }
6392
6393 return true;
6394}
6395
6396bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006397 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006398 GLsizei levels,
6399 GLenum internalformat,
6400 GLsizei width,
6401 GLsizei height)
6402{
6403 if (!context->getExtensions().textureStorage)
6404 {
Jamie Madille0472f32018-11-27 16:32:45 -05006405 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05006406 return false;
6407 }
6408
6409 if (context->getClientMajorVersion() < 3)
6410 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006411 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006412 height);
6413 }
6414
6415 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006416 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006417 1);
6418}
6419
6420bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6421{
6422 if (!context->getExtensions().instancedArrays)
6423 {
Jamie Madille0472f32018-11-27 16:32:45 -05006424 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05006425 return false;
6426 }
6427
6428 if (index >= MAX_VERTEX_ATTRIBS)
6429 {
Jamie Madille0472f32018-11-27 16:32:45 -05006430 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madill007530e2017-12-28 14:27:04 -05006431 return false;
6432 }
6433
6434 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6435 {
6436 if (index == 0 && divisor != 0)
6437 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006438 context->validationError(GL_INVALID_OPERATION, kAttributeZeroRequiresDivisorLimitation);
Jamie Madill007530e2017-12-28 14:27:04 -05006439
6440 // We also output an error message to the debugger window if tracing is active, so
6441 // that developers can see the error message.
Jamie Madillc3e37312018-11-30 15:25:39 -05006442 ERR() << kAttributeZeroRequiresDivisorLimitation;
Jamie Madill007530e2017-12-28 14:27:04 -05006443 return false;
6444 }
6445 }
6446
6447 return true;
6448}
6449
6450bool ValidateTexImage3DOES(Context *context,
6451 GLenum target,
6452 GLint level,
6453 GLenum internalformat,
6454 GLsizei width,
6455 GLsizei height,
6456 GLsizei depth,
6457 GLint border,
6458 GLenum format,
6459 GLenum type,
6460 const void *pixels)
6461{
6462 UNIMPLEMENTED(); // FIXME
6463 return false;
6464}
6465
6466bool ValidatePopGroupMarkerEXT(Context *context)
6467{
6468 if (!context->getExtensions().debugMarker)
6469 {
6470 // The debug marker calls should not set error state
6471 // However, it seems reasonable to set an error state if the extension is not enabled
Jamie Madille0472f32018-11-27 16:32:45 -05006472 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05006473 return false;
6474 }
6475
6476 return true;
6477}
6478
Jamie Madillfa920eb2018-01-04 11:45:50 -05006479bool ValidateTexStorage1DEXT(Context *context,
6480 GLenum target,
6481 GLsizei levels,
6482 GLenum internalformat,
6483 GLsizei width)
6484{
6485 UNIMPLEMENTED();
Jamie Madille0472f32018-11-27 16:32:45 -05006486 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05006487 return false;
6488}
6489
6490bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006491 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006492 GLsizei levels,
6493 GLenum internalformat,
6494 GLsizei width,
6495 GLsizei height,
6496 GLsizei depth)
6497{
6498 if (!context->getExtensions().textureStorage)
6499 {
Jamie Madille0472f32018-11-27 16:32:45 -05006500 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05006501 return false;
6502 }
6503
6504 if (context->getClientMajorVersion() < 3)
6505 {
Jamie Madille0472f32018-11-27 16:32:45 -05006506 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05006507 return false;
6508 }
6509
6510 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6511 depth);
6512}
6513
jchen1082af6202018-06-22 10:59:52 +08006514bool ValidateMaxShaderCompilerThreadsKHR(Context *context, GLuint count)
6515{
6516 if (!context->getExtensions().parallelShaderCompile)
6517 {
Jamie Madille0472f32018-11-27 16:32:45 -05006518 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
jchen1082af6202018-06-22 10:59:52 +08006519 return false;
6520 }
6521 return true;
6522}
6523
Austin Eng1bf18ce2018-10-19 15:34:02 -07006524bool ValidateMultiDrawArraysANGLE(Context *context,
6525 PrimitiveMode mode,
6526 const GLint *firsts,
6527 const GLsizei *counts,
6528 GLsizei drawcount)
6529{
6530 if (!context->getExtensions().multiDraw)
6531 {
Jamie Madille0472f32018-11-27 16:32:45 -05006532 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07006533 return false;
6534 }
6535 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
6536 {
6537 if (!ValidateDrawArrays(context, mode, firsts[drawID], counts[drawID]))
6538 {
6539 return false;
6540 }
6541 }
6542 return true;
6543}
6544
6545bool ValidateMultiDrawElementsANGLE(Context *context,
6546 PrimitiveMode mode,
6547 const GLsizei *counts,
Jamie Madill8dc27f92018-11-29 11:45:44 -05006548 DrawElementsType type,
Austin Eng3b7c9d02018-11-21 18:09:05 -08006549 const GLvoid *const *indices,
Austin Eng1bf18ce2018-10-19 15:34:02 -07006550 GLsizei drawcount)
6551{
6552 if (!context->getExtensions().multiDraw)
6553 {
Jamie Madille0472f32018-11-27 16:32:45 -05006554 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07006555 return false;
6556 }
6557 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
6558 {
Austin Eng3b7c9d02018-11-21 18:09:05 -08006559 if (!ValidateDrawElements(context, mode, counts[drawID], type, indices[drawID]))
Austin Eng1bf18ce2018-10-19 15:34:02 -07006560 {
6561 return false;
6562 }
6563 }
6564 return true;
6565}
6566
Jeff Gilbert465d6092019-01-02 16:21:18 -08006567bool ValidateProvokingVertexANGLE(Context *context, ProvokingVertex modePacked)
6568{
6569 if (!context->getExtensions().provokingVertex)
6570 {
6571 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
6572 return false;
6573 }
6574
6575 switch (modePacked)
6576 {
6577 case ProvokingVertex::FirstVertexConvention:
6578 case ProvokingVertex::LastVertexConvention:
6579 break;
6580 default:
6581 context->validationError(GL_INVALID_ENUM, kInvalidProvokingVertex);
6582 return false;
6583 }
6584
6585 return true;
6586}
6587
Jamie Madilla5410482019-01-31 19:55:55 -05006588void RecordBindTextureTypeError(Context *context, TextureType target)
6589{
6590 ASSERT(!context->getStateCache().isValidBindTextureType(target));
6591
6592 switch (target)
6593 {
6594 case TextureType::Rectangle:
6595 ASSERT(!context->getExtensions().textureRectangle);
6596 context->validationError(GL_INVALID_ENUM, kTextureRectangleNotSupported);
6597 break;
6598
6599 case TextureType::_3D:
6600 case TextureType::_2DArray:
6601 ASSERT(context->getClientMajorVersion() < 3);
6602 context->validationError(GL_INVALID_ENUM, kES3Required);
6603 break;
6604
6605 case TextureType::_2DMultisample:
6606 ASSERT(context->getClientVersion() < Version(3, 1) &&
6607 !context->getExtensions().textureMultisample);
6608 context->validationError(GL_INVALID_ENUM, kMultisampleTextureExtensionOrES31Required);
6609 break;
6610
6611 case TextureType::_2DMultisampleArray:
6612 ASSERT(!context->getExtensions().textureStorageMultisample2DArray);
6613 context->validationError(GL_INVALID_ENUM, kMultisampleArrayExtensionRequired);
6614 break;
6615
6616 case TextureType::External:
6617 ASSERT(!context->getExtensions().eglImageExternal &&
6618 !context->getExtensions().eglStreamConsumerExternal);
6619 context->validationError(GL_INVALID_ENUM, kExternalTextureNotSupported);
6620 break;
6621
6622 default:
6623 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
6624 }
6625}
6626
Jamie Madillc29968b2016-01-20 11:17:23 -05006627} // namespace gl