blob: d1ffe9b2ebf9fba1ba989254efeb5637e4228f33 [file] [log] [blame]
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001//
Stuart Morgan9d737962019-08-14 12:25:12 -07002// Copyright 2013 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,
Jiacheng Lu7b5744f2019-08-22 16:26:35 -060073 PathID pathBase)
Sami Väisänend59ca052016-06-21 16:10:00 +030074{
75 const auto *array = static_cast<const T *>(paths);
76
77 for (GLsizei i = 0; i < numPaths; ++i)
78 {
Jiacheng Lu7b5744f2019-08-22 16:26:35 -060079 const GLuint pathName = array[i] + pathBase.value;
80 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,
Jiacheng Lu7b5744f2019-08-22 16:26:35 -060093 PathID pathBase,
Sami Väisänend59ca052016-06-21 16:10:00 +030094 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 =
Jamie Madill4e71b2b2019-07-08 13:23:38 -0400495 framebuffer->getReadColorAttachment()->getFormat().info->sizedInternalFormat;
Jamie Madillbe849e42017-05-02 15:49:00 -0400496 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;
Le Quyen6e653982019-10-09 15:19:02 +0800730 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
731 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
732 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
733 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
734 if (context->getExtensions().compressedTexturePVRTC)
735 {
736 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
737 return false;
738 }
739 else
740 {
741 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
742 return false;
743 }
744 break;
745 case GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT:
746 case GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT:
747 case GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT:
748 case GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT:
749 if (context->getExtensions().compressedTexturePVRTCsRGB)
750 {
751 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
752 return false;
753 }
754 else
755 {
756 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
757 return false;
758 }
759 break;
Jamie Madillbe849e42017-05-02 15:49:00 -0400760 case GL_DEPTH_COMPONENT:
761 case GL_DEPTH_COMPONENT16:
762 case GL_DEPTH_COMPONENT32_OES:
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -0600763 if (context->getExtensions().depthTextureAny())
Jamie Madillbe849e42017-05-02 15:49:00 -0400764 {
Jamie Madille0472f32018-11-27 16:32:45 -0500765 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400766 return false;
767 }
768 else
769 {
Jamie Madille0472f32018-11-27 16:32:45 -0500770 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400771 return false;
772 }
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -0600773 break;
774 case GL_DEPTH_STENCIL_OES:
775 case GL_DEPTH24_STENCIL8_OES:
776 if (context->getExtensions().depthTextureAny() ||
777 context->getExtensions().packedDepthStencil)
778 {
779 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
780 return false;
781 }
782 else
783 {
784 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
785 return false;
786 }
787 break;
Jamie Madillbe849e42017-05-02 15:49:00 -0400788 default:
Jamie Madille0472f32018-11-27 16:32:45 -0500789 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400790 return false;
791 }
792 }
793
794 // If width or height is zero, it is a no-op. Return false without setting an error.
795 return (width > 0 && height > 0);
796}
797
798bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
799{
800 switch (cap)
801 {
802 // EXT_multisample_compatibility
803 case GL_MULTISAMPLE_EXT:
804 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
805 return context->getExtensions().multisampleCompatibility;
806
807 case GL_CULL_FACE:
808 case GL_POLYGON_OFFSET_FILL:
809 case GL_SAMPLE_ALPHA_TO_COVERAGE:
810 case GL_SAMPLE_COVERAGE:
811 case GL_SCISSOR_TEST:
812 case GL_STENCIL_TEST:
813 case GL_DEPTH_TEST:
814 case GL_BLEND:
815 case GL_DITHER:
816 return true;
817
818 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
819 case GL_RASTERIZER_DISCARD:
820 return (context->getClientMajorVersion() >= 3);
821
822 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
823 case GL_DEBUG_OUTPUT:
824 return context->getExtensions().debug;
825
826 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
827 return queryOnly && context->getExtensions().bindGeneratesResource;
828
829 case GL_CLIENT_ARRAYS_ANGLE:
830 return queryOnly && context->getExtensions().clientArrays;
831
832 case GL_FRAMEBUFFER_SRGB_EXT:
833 return context->getExtensions().sRGBWriteControl;
834
835 case GL_SAMPLE_MASK:
836 return context->getClientVersion() >= Version(3, 1);
837
Geoff Langb433e872017-10-05 14:01:47 -0400838 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
Jamie Madillbe849e42017-05-02 15:49:00 -0400839 return queryOnly && context->getExtensions().robustResourceInitialization;
840
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700841 // GLES1 emulation: GLES1-specific caps
842 case GL_ALPHA_TEST:
Lingfeng Yang01074432018-04-16 10:19:51 -0700843 case GL_VERTEX_ARRAY:
844 case GL_NORMAL_ARRAY:
845 case GL_COLOR_ARRAY:
846 case GL_TEXTURE_COORD_ARRAY:
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700847 case GL_TEXTURE_2D:
Lingfeng Yangd0febe72018-05-17 22:36:52 -0700848 case GL_LIGHTING:
849 case GL_LIGHT0:
850 case GL_LIGHT1:
851 case GL_LIGHT2:
852 case GL_LIGHT3:
853 case GL_LIGHT4:
854 case GL_LIGHT5:
855 case GL_LIGHT6:
856 case GL_LIGHT7:
857 case GL_NORMALIZE:
858 case GL_RESCALE_NORMAL:
859 case GL_COLOR_MATERIAL:
Lingfeng Yang060088a2018-05-30 20:40:57 -0700860 case GL_CLIP_PLANE0:
861 case GL_CLIP_PLANE1:
862 case GL_CLIP_PLANE2:
863 case GL_CLIP_PLANE3:
864 case GL_CLIP_PLANE4:
865 case GL_CLIP_PLANE5:
Lingfeng Yang7ba3f422018-06-01 09:43:04 -0700866 case GL_FOG:
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700867 case GL_POINT_SMOOTH:
Lingfeng Yang6e5bf362018-08-15 09:53:17 -0700868 case GL_LINE_SMOOTH:
869 case GL_COLOR_LOGIC_OP:
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700870 return context->getClientVersion() < Version(2, 0);
Lingfeng Yang01074432018-04-16 10:19:51 -0700871 case GL_POINT_SIZE_ARRAY_OES:
872 return context->getClientVersion() < Version(2, 0) &&
873 context->getExtensions().pointSizeArray;
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700874 case GL_TEXTURE_CUBE_MAP:
875 return context->getClientVersion() < Version(2, 0) &&
876 context->getExtensions().textureCubeMap;
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700877 case GL_POINT_SPRITE_OES:
878 return context->getClientVersion() < Version(2, 0) &&
879 context->getExtensions().pointSprite;
Jamie Madillbe849e42017-05-02 15:49:00 -0400880 default:
881 return false;
882 }
883}
884
Geoff Langfc32e8b2017-05-31 14:16:59 -0400885// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
886// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400887bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400888{
889 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400890 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
891 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400892 {
893 return true;
894 }
895
896 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
897 if (c >= 9 && c <= 13)
898 {
899 return true;
900 }
901
902 return false;
903}
904
Geoff Langcab92ee2017-07-19 17:32:07 -0400905bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400906{
Geoff Langa71a98e2017-06-19 15:15:00 -0400907 for (size_t i = 0; i < len; i++)
908 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400909 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400910 {
911 return false;
912 }
913 }
914
915 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400916}
917
Geoff Langcab92ee2017-07-19 17:32:07 -0400918bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
919{
920 enum class ParseState
921 {
922 // Have not seen an ASCII non-whitespace character yet on
923 // this line. Possible that we might see a preprocessor
924 // directive.
925 BEGINING_OF_LINE,
926
927 // Have seen at least one ASCII non-whitespace character
928 // on this line.
929 MIDDLE_OF_LINE,
930
931 // Handling a preprocessor directive. Passes through all
932 // characters up to the end of the line. Disables comment
933 // processing.
934 IN_PREPROCESSOR_DIRECTIVE,
935
936 // Handling a single-line comment. The comment text is
937 // replaced with a single space.
938 IN_SINGLE_LINE_COMMENT,
939
940 // Handling a multi-line comment. Newlines are passed
941 // through to preserve line numbers.
942 IN_MULTI_LINE_COMMENT
943 };
944
945 ParseState state = ParseState::BEGINING_OF_LINE;
946 size_t pos = 0;
947
948 while (pos < len)
949 {
950 char c = str[pos];
951 char next = pos + 1 < len ? str[pos + 1] : 0;
952
953 // Check for newlines
954 if (c == '\n' || c == '\r')
955 {
956 if (state != ParseState::IN_MULTI_LINE_COMMENT)
957 {
958 state = ParseState::BEGINING_OF_LINE;
959 }
960
961 pos++;
962 continue;
963 }
964
965 switch (state)
966 {
967 case ParseState::BEGINING_OF_LINE:
968 if (c == ' ')
969 {
970 // Maintain the BEGINING_OF_LINE state until a non-space is seen
971 pos++;
972 }
973 else if (c == '#')
974 {
975 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
976 pos++;
977 }
978 else
979 {
980 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
981 state = ParseState::MIDDLE_OF_LINE;
982 }
983 break;
984
985 case ParseState::MIDDLE_OF_LINE:
986 if (c == '/' && next == '/')
987 {
988 state = ParseState::IN_SINGLE_LINE_COMMENT;
989 pos++;
990 }
991 else if (c == '/' && next == '*')
992 {
993 state = ParseState::IN_MULTI_LINE_COMMENT;
994 pos++;
995 }
996 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
997 {
998 // Skip line continuation characters
999 }
1000 else if (!IsValidESSLCharacter(c))
1001 {
1002 return false;
1003 }
1004 pos++;
1005 break;
1006
1007 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -07001008 // Line-continuation characters may not be permitted.
1009 // Otherwise, just pass it through. Do not parse comments in this state.
1010 if (!lineContinuationAllowed && c == '\\')
1011 {
1012 return false;
1013 }
Geoff Langcab92ee2017-07-19 17:32:07 -04001014 pos++;
1015 break;
1016
1017 case ParseState::IN_SINGLE_LINE_COMMENT:
1018 // Line-continuation characters are processed before comment processing.
1019 // Advance string if a new line character is immediately behind
1020 // line-continuation character.
1021 if (c == '\\' && (next == '\n' || next == '\r'))
1022 {
1023 pos++;
1024 }
1025 pos++;
1026 break;
1027
1028 case ParseState::IN_MULTI_LINE_COMMENT:
1029 if (c == '*' && next == '/')
1030 {
1031 state = ParseState::MIDDLE_OF_LINE;
1032 pos++;
1033 }
1034 pos++;
1035 break;
1036 }
1037 }
1038
1039 return true;
1040}
1041
Jamie Madill5b772312018-03-08 20:28:32 -05001042bool ValidateWebGLNamePrefix(Context *context, const GLchar *name)
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001043{
1044 ASSERT(context->isWebGL());
1045
1046 // WebGL 1.0 [Section 6.16] GLSL Constructs
1047 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
1048 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
1049 {
Jamie Madille0472f32018-11-27 16:32:45 -05001050 context->validationError(GL_INVALID_OPERATION, kWebglBindAttribLocationReservedPrefix);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001051 return false;
1052 }
1053
1054 return true;
1055}
1056
Jamie Madill5b772312018-03-08 20:28:32 -05001057bool ValidateWebGLNameLength(Context *context, size_t length)
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001058{
1059 ASSERT(context->isWebGL());
1060
1061 if (context->isWebGL1() && length > 256)
1062 {
1063 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
1064 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
1065 // locations.
Jamie Madille0472f32018-11-27 16:32:45 -05001066 context->validationError(GL_INVALID_VALUE, kWebglNameLengthLimitExceeded);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001067
1068 return false;
1069 }
1070 else if (length > 1024)
1071 {
1072 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
1073 // uniform and attribute locations.
Jamie Madille0472f32018-11-27 16:32:45 -05001074 context->validationError(GL_INVALID_VALUE, kWebgl2NameLengthLimitExceeded);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001075 return false;
1076 }
1077
1078 return true;
1079}
1080
Jamie Madill007530e2017-12-28 14:27:04 -05001081bool ValidateMatrixMode(Context *context, GLenum matrixMode)
1082{
1083 if (!context->getExtensions().pathRendering)
1084 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001085 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05001086 return false;
1087 }
1088
1089 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
1090 {
Jamie Madille0472f32018-11-27 16:32:45 -05001091 context->validationError(GL_INVALID_ENUM, kInvalidMatrixMode);
Jamie Madill007530e2017-12-28 14:27:04 -05001092 return false;
1093 }
1094 return true;
1095}
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03001096
1097bool ValidBlendFunc(const Context *context, GLenum val)
1098{
1099 const gl::Extensions &ext = context->getExtensions();
1100
1101 // these are always valid for src and dst.
1102 switch (val)
1103 {
1104 case GL_ZERO:
1105 case GL_ONE:
1106 case GL_SRC_COLOR:
1107 case GL_ONE_MINUS_SRC_COLOR:
1108 case GL_DST_COLOR:
1109 case GL_ONE_MINUS_DST_COLOR:
1110 case GL_SRC_ALPHA:
1111 case GL_ONE_MINUS_SRC_ALPHA:
1112 case GL_DST_ALPHA:
1113 case GL_ONE_MINUS_DST_ALPHA:
1114 case GL_CONSTANT_COLOR:
1115 case GL_ONE_MINUS_CONSTANT_COLOR:
1116 case GL_CONSTANT_ALPHA:
1117 case GL_ONE_MINUS_CONSTANT_ALPHA:
1118 return true;
1119
1120 // EXT_blend_func_extended.
1121 case GL_SRC1_COLOR_EXT:
1122 case GL_SRC1_ALPHA_EXT:
1123 case GL_ONE_MINUS_SRC1_COLOR_EXT:
1124 case GL_ONE_MINUS_SRC1_ALPHA_EXT:
1125 case GL_SRC_ALPHA_SATURATE_EXT:
1126 return ext.blendFuncExtended;
1127
1128 default:
1129 return false;
1130 }
1131}
1132
1133bool ValidSrcBlendFunc(const Context *context, GLenum val)
1134{
1135 if (ValidBlendFunc(context, val))
1136 return true;
1137
1138 if (val == GL_SRC_ALPHA_SATURATE)
1139 return true;
1140
1141 return false;
1142}
1143
1144bool ValidDstBlendFunc(const Context *context, GLenum val)
1145{
1146 if (ValidBlendFunc(context, val))
1147 return true;
1148
1149 if (val == GL_SRC_ALPHA_SATURATE)
1150 {
1151 if (context->getClientMajorVersion() >= 3)
1152 return true;
1153 }
1154
1155 return false;
1156}
Michael Spangab6a59b2019-05-21 21:26:26 -04001157
1158bool IsValidImageLayout(ImageLayout layout)
1159{
1160 switch (layout)
1161 {
Michael Spang6c824a12019-06-18 15:43:33 -04001162 case ImageLayout::Undefined:
Michael Spangab6a59b2019-05-21 21:26:26 -04001163 case ImageLayout::General:
1164 case ImageLayout::ColorAttachment:
1165 case ImageLayout::DepthStencilAttachment:
1166 case ImageLayout::DepthStencilReadOnlyAttachment:
1167 case ImageLayout::ShaderReadOnly:
1168 case ImageLayout::TransferSrc:
1169 case ImageLayout::TransferDst:
1170 case ImageLayout::DepthReadOnlyStencilAttachment:
1171 case ImageLayout::DepthAttachmentStencilReadOnly:
1172 return true;
1173
1174 default:
1175 return false;
1176 }
1177}
1178
Geoff Langff5b2d52016-09-07 11:32:23 -04001179bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001180 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001181 GLint level,
1182 GLenum internalformat,
1183 bool isCompressed,
1184 bool isSubImage,
1185 GLint xoffset,
1186 GLint yoffset,
1187 GLsizei width,
1188 GLsizei height,
1189 GLint border,
1190 GLenum format,
1191 GLenum type,
1192 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001193 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001194{
Jamie Madill6f38f822014-06-06 17:12:20 -04001195 if (!ValidTexture2DDestinationTarget(context, target))
1196 {
Jamie Madille0472f32018-11-27 16:32:45 -05001197 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001198 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001199 }
1200
Geoff Lang857880e2019-05-27 13:39:15 -04001201 return ValidateES2TexImageParametersBase(context, target, level, internalformat, isCompressed,
1202 isSubImage, xoffset, yoffset, width, height, border,
1203 format, type, imageSize, pixels);
1204}
1205
1206} // anonymous namespace
1207
1208bool ValidateES2TexImageParametersBase(Context *context,
1209 TextureTarget target,
1210 GLint level,
1211 GLenum internalformat,
1212 bool isCompressed,
1213 bool isSubImage,
1214 GLint xoffset,
1215 GLint yoffset,
1216 GLsizei width,
1217 GLsizei height,
1218 GLint border,
1219 GLenum format,
1220 GLenum type,
1221 GLsizei imageSize,
1222 const void *pixels)
1223{
1224
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001225 TextureType texType = TextureTargetToType(target);
1226 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001227 {
Jamie Madill610640f2018-11-21 17:28:41 -05001228 // Error already handled.
Geoff Langb1196682014-07-23 13:47:29 -04001229 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001230 }
1231
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001232 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001233 {
Jamie Madille0472f32018-11-27 16:32:45 -05001234 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Brandon Jones6cad5662017-06-14 13:25:13 -07001235 return false;
1236 }
1237
1238 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001239 std::numeric_limits<GLsizei>::max() - yoffset < height)
1240 {
Jamie Madille0472f32018-11-27 16:32:45 -05001241 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001242 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001243 }
1244
Geoff Langaae65a42014-05-26 12:43:44 -04001245 const gl::Caps &caps = context->getCaps();
1246
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001247 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001248 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001249 case TextureType::_2D:
Geoff Lang857880e2019-05-27 13:39:15 -04001250 case TextureType::External:
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001251 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1252 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1253 {
Jamie Madille0472f32018-11-27 16:32:45 -05001254 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001255 return false;
1256 }
1257 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001258
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001259 case TextureType::Rectangle:
1260 ASSERT(level == 0);
1261 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1262 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1263 {
Jamie Madille0472f32018-11-27 16:32:45 -05001264 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001265 return false;
1266 }
1267 if (isCompressed)
1268 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001269 context->validationError(GL_INVALID_ENUM, kRectangleTextureCompressed);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001270 return false;
1271 }
1272 break;
1273
1274 case TextureType::CubeMap:
1275 if (!isSubImage && width != height)
1276 {
Jamie Madille0472f32018-11-27 16:32:45 -05001277 context->validationError(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001278 return false;
1279 }
1280
1281 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1282 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1283 {
Jamie Madille0472f32018-11-27 16:32:45 -05001284 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001285 return false;
1286 }
1287 break;
1288
1289 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001290 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001291 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001292 }
1293
Jamie Madillcfc73cc2019-04-08 16:26:51 -04001294 gl::Texture *texture = context->getTextureByType(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001295 if (!texture)
1296 {
Jamie Madille0472f32018-11-27 16:32:45 -05001297 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001298 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001299 }
1300
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001301 // Verify zero border
1302 if (border != 0)
1303 {
Jamie Madille0472f32018-11-27 16:32:45 -05001304 context->validationError(GL_INVALID_VALUE, kInvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001305 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001306 }
1307
Tim Van Patten208af3e2019-03-19 09:15:55 -06001308 bool nonEqualFormatsAllowed = false;
1309
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001310 if (isCompressed)
1311 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001312 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001313 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1314 : internalformat;
Geoff Lange88e4542018-05-03 15:05:57 -04001315
1316 const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(actualInternalFormat);
1317
1318 if (!internalFormatInfo.compressed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001319 {
Jamie Madille0472f32018-11-27 16:32:45 -05001320 context->validationError(GL_INVALID_ENUM, kInvalidInternalFormat);
Geoff Lange88e4542018-05-03 15:05:57 -04001321 return false;
1322 }
1323
1324 if (!internalFormatInfo.textureSupport(context->getClientVersion(),
1325 context->getExtensions()))
1326 {
Jamie Madille0472f32018-11-27 16:32:45 -05001327 context->validationError(GL_INVALID_ENUM, kInvalidInternalFormat);
Geoff Lange88e4542018-05-03 15:05:57 -04001328 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001329 }
Geoff Lang966c9402017-04-18 12:38:27 -04001330
1331 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001332 {
Geoff Lange88e4542018-05-03 15:05:57 -04001333 // From the OES_compressed_ETC1_RGB8_texture spec:
1334 // INVALID_OPERATION is generated by CompressedTexSubImage2D, TexSubImage2D, or
1335 // CopyTexSubImage2D if the texture image <level> bound to <target> has internal format
1336 // ETC1_RGB8_OES.
1337 if (actualInternalFormat == GL_ETC1_RGB8_OES)
1338 {
Jamie Madille0472f32018-11-27 16:32:45 -05001339 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lange88e4542018-05-03 15:05:57 -04001340 return false;
1341 }
1342
Geoff Langd9c17102019-07-10 14:56:26 -04001343 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, 0,
1344 width, height, 1, texture->getWidth(target, level),
1345 texture->getHeight(target, level),
1346 texture->getDepth(target, level)))
Geoff Lang966c9402017-04-18 12:38:27 -04001347 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001348 context->validationError(GL_INVALID_OPERATION, kInvalidCompressedImageSize);
Geoff Lang966c9402017-04-18 12:38:27 -04001349 return false;
1350 }
1351
1352 if (format != actualInternalFormat)
1353 {
Jamie Madille0472f32018-11-27 16:32:45 -05001354 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001355 return false;
1356 }
1357 }
1358 else
1359 {
Geoff Langd9c17102019-07-10 14:56:26 -04001360 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height, 1))
Geoff Lang966c9402017-04-18 12:38:27 -04001361 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001362 context->validationError(GL_INVALID_OPERATION, kInvalidCompressedImageSize);
Geoff Lang966c9402017-04-18 12:38:27 -04001363 return false;
1364 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001365 }
1366 }
1367 else
1368 {
1369 // validate <type> by itself (used as secondary key below)
1370 switch (type)
1371 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001372 case GL_UNSIGNED_BYTE:
1373 case GL_UNSIGNED_SHORT_5_6_5:
1374 case GL_UNSIGNED_SHORT_4_4_4_4:
1375 case GL_UNSIGNED_SHORT_5_5_5_1:
1376 case GL_UNSIGNED_SHORT:
1377 case GL_UNSIGNED_INT:
1378 case GL_UNSIGNED_INT_24_8_OES:
1379 case GL_HALF_FLOAT_OES:
1380 case GL_FLOAT:
1381 break;
Jaedon Lee3b468852019-07-30 16:50:36 +09001382 case GL_UNSIGNED_INT_2_10_10_10_REV_EXT:
1383 if (!context->getExtensions().textureFormat2101010REV)
1384 {
1385 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
1386 return false;
1387 }
1388 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001389 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001390 context->validationError(GL_INVALID_ENUM, kInvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001391 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001392 }
1393
1394 // validate <format> + <type> combinations
1395 // - invalid <format> -> sets INVALID_ENUM
1396 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1397 switch (format)
1398 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001399 case GL_ALPHA:
1400 case GL_LUMINANCE:
1401 case GL_LUMINANCE_ALPHA:
1402 switch (type)
1403 {
1404 case GL_UNSIGNED_BYTE:
1405 case GL_FLOAT:
1406 case GL_HALF_FLOAT_OES:
1407 break;
1408 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001409 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001410 return false;
1411 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001412 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001413 case GL_RED:
1414 case GL_RG:
1415 if (!context->getExtensions().textureRG)
1416 {
Jamie Madille0472f32018-11-27 16:32:45 -05001417 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001418 return false;
1419 }
1420 switch (type)
1421 {
1422 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001423 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001424 case GL_FLOAT:
1425 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001426 if (!context->getExtensions().textureFloat)
1427 {
Jamie Madille0472f32018-11-27 16:32:45 -05001428 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001429 return false;
1430 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001431 break;
1432 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001433 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001434 return false;
1435 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001436 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001437 case GL_RGB:
1438 switch (type)
1439 {
1440 case GL_UNSIGNED_BYTE:
1441 case GL_UNSIGNED_SHORT_5_6_5:
Jaedon Lee3b468852019-07-30 16:50:36 +09001442 case GL_UNSIGNED_INT_2_10_10_10_REV_EXT:
He Yunchaoced53ae2016-11-29 15:00:51 +08001443 case GL_FLOAT:
1444 case GL_HALF_FLOAT_OES:
1445 break;
1446 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001447 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001448 return false;
1449 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001450 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001451 case GL_RGBA:
1452 switch (type)
1453 {
1454 case GL_UNSIGNED_BYTE:
1455 case GL_UNSIGNED_SHORT_4_4_4_4:
1456 case GL_UNSIGNED_SHORT_5_5_5_1:
1457 case GL_FLOAT:
1458 case GL_HALF_FLOAT_OES:
Jaedon Lee3b468852019-07-30 16:50:36 +09001459 case GL_UNSIGNED_INT_2_10_10_10_REV_EXT:
He Yunchaoced53ae2016-11-29 15:00:51 +08001460 break;
1461 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001462 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001463 return false;
1464 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001465 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001466 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001467 if (!context->getExtensions().textureFormatBGRA8888)
1468 {
Jamie Madille0472f32018-11-27 16:32:45 -05001469 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001470 return false;
1471 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001472 switch (type)
1473 {
1474 case GL_UNSIGNED_BYTE:
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 case GL_SRGB_EXT:
1482 case GL_SRGB_ALPHA_EXT:
1483 if (!context->getExtensions().sRGB)
1484 {
Jamie Madille0472f32018-11-27 16:32:45 -05001485 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001486 return false;
1487 }
1488 switch (type)
1489 {
1490 case GL_UNSIGNED_BYTE:
1491 break;
1492 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001493 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001494 return false;
1495 }
1496 break;
1497 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1498 // handled below
1499 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1500 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1501 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1502 break;
1503 case GL_DEPTH_COMPONENT:
1504 switch (type)
1505 {
1506 case GL_UNSIGNED_SHORT:
1507 case GL_UNSIGNED_INT:
1508 break;
1509 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001510 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001511 return false;
1512 }
1513 break;
1514 case GL_DEPTH_STENCIL_OES:
1515 switch (type)
1516 {
1517 case GL_UNSIGNED_INT_24_8_OES:
1518 break;
1519 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001520 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001521 return false;
1522 }
1523 break;
1524 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001525 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001526 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001527 }
1528
1529 switch (format)
1530 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001531 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1532 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1533 if (context->getExtensions().textureCompressionDXT1)
1534 {
Jamie Madille0472f32018-11-27 16:32:45 -05001535 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001536 return false;
1537 }
1538 else
1539 {
Jamie Madille0472f32018-11-27 16:32:45 -05001540 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001541 return false;
1542 }
1543 break;
1544 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1545 if (context->getExtensions().textureCompressionDXT3)
1546 {
Jamie Madille0472f32018-11-27 16:32:45 -05001547 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001548 return false;
1549 }
1550 else
1551 {
Jamie Madille0472f32018-11-27 16:32:45 -05001552 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001553 return false;
1554 }
1555 break;
1556 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1557 if (context->getExtensions().textureCompressionDXT5)
1558 {
Jamie Madille0472f32018-11-27 16:32:45 -05001559 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001560 return false;
1561 }
1562 else
1563 {
Jamie Madille0472f32018-11-27 16:32:45 -05001564 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001565 return false;
1566 }
1567 break;
1568 case GL_ETC1_RGB8_OES:
1569 if (context->getExtensions().compressedETC1RGB8Texture)
1570 {
Jamie Madille0472f32018-11-27 16:32:45 -05001571 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001572 return false;
1573 }
1574 else
1575 {
Jamie Madille0472f32018-11-27 16:32:45 -05001576 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001577 return false;
1578 }
1579 break;
1580 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001581 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1582 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1583 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1584 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001585 if (context->getExtensions().lossyETCDecode)
1586 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001587 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001588 return false;
1589 }
1590 else
1591 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001592 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001593 return false;
1594 }
1595 break;
Le Quyen6e653982019-10-09 15:19:02 +08001596 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
1597 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
1598 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
1599 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
1600 if (context->getExtensions().compressedTexturePVRTC)
1601 {
1602 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
1603 return false;
1604 }
1605 else
1606 {
1607 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
1608 return false;
1609 }
1610 break;
1611 case GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT:
1612 case GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT:
1613 case GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT:
1614 case GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT:
1615 if (context->getExtensions().compressedTexturePVRTCsRGB)
1616 {
1617 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
1618 return false;
1619 }
1620 else
1621 {
1622 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
1623 return false;
1624 }
1625 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001626 case GL_DEPTH_COMPONENT:
1627 case GL_DEPTH_STENCIL_OES:
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001628 if (!context->getExtensions().depthTextureANGLE &&
1629 !(context->getExtensions().packedDepthStencil &&
1630 context->getExtensions().depthTextureOES))
He Yunchaoced53ae2016-11-29 15:00:51 +08001631 {
Jamie Madille0472f32018-11-27 16:32:45 -05001632 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001633 return false;
1634 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001635 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001636 {
Jamie Madille0472f32018-11-27 16:32:45 -05001637 context->validationError(GL_INVALID_OPERATION, kMismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001638 return false;
1639 }
1640 // OES_depth_texture supports loading depth data and multiple levels,
1641 // but ANGLE_depth_texture does not
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001642 if (!context->getExtensions().depthTextureOES)
He Yunchaoced53ae2016-11-29 15:00:51 +08001643 {
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001644 if (pixels != nullptr)
1645 {
1646 context->validationError(GL_INVALID_OPERATION, kPixelDataNotNull);
1647 return false;
1648 }
1649 if (level != 0)
1650 {
1651 context->validationError(GL_INVALID_OPERATION, kLevelNotZero);
1652 return false;
1653 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001654 }
1655 break;
1656 default:
1657 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001658 }
1659
Geoff Lang6e898aa2017-06-02 11:17:26 -04001660 if (!isSubImage)
1661 {
1662 switch (internalformat)
1663 {
Tim Van Patten208af3e2019-03-19 09:15:55 -06001664 // Core ES 2.0 formats
1665 case GL_ALPHA:
1666 case GL_LUMINANCE:
1667 case GL_LUMINANCE_ALPHA:
1668 case GL_RGB:
1669 case GL_RGBA:
1670 break;
1671
Geoff Lang6e898aa2017-06-02 11:17:26 -04001672 case GL_RGBA32F:
1673 if (!context->getExtensions().colorBufferFloatRGBA)
1674 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001675 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001676 return false;
1677 }
Tim Van Patten208af3e2019-03-19 09:15:55 -06001678
1679 nonEqualFormatsAllowed = true;
1680
Geoff Lang6e898aa2017-06-02 11:17:26 -04001681 if (type != GL_FLOAT)
1682 {
Jamie Madille0472f32018-11-27 16:32:45 -05001683 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001684 return false;
1685 }
1686 if (format != GL_RGBA)
1687 {
Jamie Madille0472f32018-11-27 16:32:45 -05001688 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001689 return false;
1690 }
1691 break;
1692
1693 case GL_RGB32F:
1694 if (!context->getExtensions().colorBufferFloatRGB)
1695 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001696 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001697 return false;
1698 }
Tim Van Patten208af3e2019-03-19 09:15:55 -06001699
1700 nonEqualFormatsAllowed = true;
1701
Geoff Lang6e898aa2017-06-02 11:17:26 -04001702 if (type != GL_FLOAT)
1703 {
Jamie Madille0472f32018-11-27 16:32:45 -05001704 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001705 return false;
1706 }
1707 if (format != GL_RGB)
1708 {
Jamie Madille0472f32018-11-27 16:32:45 -05001709 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001710 return false;
1711 }
1712 break;
1713
Tim Van Patten208af3e2019-03-19 09:15:55 -06001714 case GL_BGRA_EXT:
1715 if (!context->getExtensions().textureFormatBGRA8888)
1716 {
1717 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
1718 return false;
1719 }
Geoff Lang6e898aa2017-06-02 11:17:26 -04001720 break;
Tim Van Patten208af3e2019-03-19 09:15:55 -06001721
1722 case GL_DEPTH_COMPONENT:
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001723 if (!(context->getExtensions().depthTextureAny()))
1724 {
1725 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
1726 return false;
1727 }
1728 break;
1729
Tim Van Patten208af3e2019-03-19 09:15:55 -06001730 case GL_DEPTH_STENCIL:
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001731 if (!(context->getExtensions().depthTextureANGLE ||
1732 context->getExtensions().packedDepthStencil))
Tim Van Patten208af3e2019-03-19 09:15:55 -06001733 {
1734 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
1735 return false;
1736 }
1737 break;
1738
1739 case GL_RED:
1740 case GL_RG:
1741 if (!context->getExtensions().textureRG)
1742 {
1743 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
1744 return false;
1745 }
1746 break;
1747
1748 case GL_SRGB_EXT:
1749 case GL_SRGB_ALPHA_EXT:
1750 if (!context->getExtensions().sRGB)
1751 {
1752 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
1753 return false;
1754 }
1755 break;
1756
Jaedon Lee3b468852019-07-30 16:50:36 +09001757 case GL_RGB10_A2_EXT:
1758 if (!context->getExtensions().textureFormat2101010REV)
1759 {
1760 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
1761 return false;
1762 }
1763
1764 if (type != GL_UNSIGNED_INT_2_10_10_10_REV_EXT || format != GL_RGBA)
1765 {
1766 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
1767 return false;
1768 }
1769
1770 nonEqualFormatsAllowed = true;
1771
1772 break;
1773
1774 case GL_RGB5_A1:
1775 if (context->getExtensions().textureFormat2101010REV &&
1776 type == GL_UNSIGNED_INT_2_10_10_10_REV_EXT && format == GL_RGBA)
1777 {
1778 nonEqualFormatsAllowed = true;
1779 }
1780
1781 break;
1782
Tim Van Patten208af3e2019-03-19 09:15:55 -06001783 default:
1784 context->validationError(GL_INVALID_VALUE, kInvalidInternalFormat);
1785 return false;
Geoff Lang6e898aa2017-06-02 11:17:26 -04001786 }
1787 }
1788
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001789 if (type == GL_FLOAT)
1790 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001791 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001792 {
Jamie Madille0472f32018-11-27 16:32:45 -05001793 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001794 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001795 }
1796 }
1797 else if (type == GL_HALF_FLOAT_OES)
1798 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001799 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001800 {
Jamie Madille0472f32018-11-27 16:32:45 -05001801 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001802 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001803 }
1804 }
1805 }
1806
Tim Van Patten208af3e2019-03-19 09:15:55 -06001807 if (isSubImage)
Geoff Langff5b2d52016-09-07 11:32:23 -04001808 {
Tim Van Patten208af3e2019-03-19 09:15:55 -06001809 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1810 if (textureInternalFormat.internalFormat == GL_NONE)
1811 {
1812 context->validationError(GL_INVALID_OPERATION, kInvalidTextureLevel);
1813 return false;
1814 }
1815
Tim Van Patten5f388c22019-03-14 09:54:23 -06001816 if (format != textureInternalFormat.format)
1817 {
1818 context->validationError(GL_INVALID_OPERATION, err::kTextureFormatMismatch);
1819 return false;
1820 }
1821
1822 if (context->getExtensions().webglCompatibility)
Tim Van Patten208af3e2019-03-19 09:15:55 -06001823 {
1824 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1825 textureInternalFormat.sizedInternalFormat)
1826 {
Tim Van Patten5f388c22019-03-14 09:54:23 -06001827 context->validationError(GL_INVALID_OPERATION, kTextureTypeMismatch);
Tim Van Patten208af3e2019-03-19 09:15:55 -06001828 return false;
1829 }
1830 }
1831
1832 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1833 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1834 {
1835 context->validationError(GL_INVALID_VALUE, kOffsetOverflow);
1836 return false;
1837 }
1838
1839 if (width > 0 && height > 0 && pixels == nullptr &&
1840 context->getState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
1841 {
1842 context->validationError(GL_INVALID_VALUE, kPixelDataNull);
1843 return false;
1844 }
1845 }
1846 else
1847 {
1848 if (texture->getImmutableFormat())
1849 {
1850 context->validationError(GL_INVALID_OPERATION, kTextureIsImmutable);
1851 return false;
1852 }
1853 }
1854
1855 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1856 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1857 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1858 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1859 // case.
1860 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
1861 {
1862 context->validationError(GL_INVALID_OPERATION, kInvalidFormatCombination);
Geoff Langff5b2d52016-09-07 11:32:23 -04001863 return false;
1864 }
1865
Tim Van Patten208af3e2019-03-19 09:15:55 -06001866 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
1867 return ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
1868 imageSize);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001869}
1870
He Yunchaoced53ae2016-11-29 15:00:51 +08001871bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001872 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001873 GLsizei levels,
1874 GLenum internalformat,
1875 GLsizei width,
1876 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001877{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001878 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1879 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001880 {
Jamie Madille0472f32018-11-27 16:32:45 -05001881 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001882 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001883 }
1884
1885 if (width < 1 || height < 1 || levels < 1)
1886 {
Jamie Madille0472f32018-11-27 16:32:45 -05001887 context->validationError(GL_INVALID_VALUE, kTextureSizeTooSmall);
Geoff Langb1196682014-07-23 13:47:29 -04001888 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001889 }
1890
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001891 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001892 {
Jamie Madille0472f32018-11-27 16:32:45 -05001893 context->validationError(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
Geoff Langb1196682014-07-23 13:47:29 -04001894 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001895 }
1896
1897 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1898 {
Jamie Madille0472f32018-11-27 16:32:45 -05001899 context->validationError(GL_INVALID_OPERATION, kInvalidMipLevels);
Geoff Langb1196682014-07-23 13:47:29 -04001900 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001901 }
1902
Geoff Langca271392017-04-05 12:30:00 -04001903 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001904 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001905 {
Jamie Madille0472f32018-11-27 16:32:45 -05001906 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001907 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001908 }
1909
Geoff Langaae65a42014-05-26 12:43:44 -04001910 const gl::Caps &caps = context->getCaps();
1911
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001912 switch (target)
1913 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001914 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001915 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1916 static_cast<GLuint>(height) > caps.max2DTextureSize)
1917 {
Jamie Madille0472f32018-11-27 16:32:45 -05001918 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
He Yunchaoced53ae2016-11-29 15:00:51 +08001919 return false;
1920 }
1921 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001922 case TextureType::Rectangle:
Jamie Madill610640f2018-11-21 17:28:41 -05001923 if (levels != 1)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001924 {
Jamie Madille0472f32018-11-27 16:32:45 -05001925 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madill610640f2018-11-21 17:28:41 -05001926 return false;
1927 }
1928
1929 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1930 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1931 {
Jamie Madille0472f32018-11-27 16:32:45 -05001932 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001933 return false;
1934 }
1935 if (formatInfo.compressed)
1936 {
Jamie Madille0472f32018-11-27 16:32:45 -05001937 context->validationError(GL_INVALID_ENUM, kRectangleTextureCompressed);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001938 return false;
1939 }
1940 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001941 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001942 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1943 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1944 {
Jamie Madille0472f32018-11-27 16:32:45 -05001945 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
He Yunchaoced53ae2016-11-29 15:00:51 +08001946 return false;
1947 }
1948 break;
1949 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001950 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001951 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001952 }
1953
Geoff Langc0b9ef42014-07-02 10:02:37 -04001954 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001955 {
1956 if (!gl::isPow2(width) || !gl::isPow2(height))
1957 {
Jamie Madille0472f32018-11-27 16:32:45 -05001958 context->validationError(GL_INVALID_OPERATION, kDimensionsMustBePow2);
Geoff Langb1196682014-07-23 13:47:29 -04001959 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001960 }
1961 }
1962
1963 switch (internalformat)
1964 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001965 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1966 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1967 if (!context->getExtensions().textureCompressionDXT1)
1968 {
Jamie Madille0472f32018-11-27 16:32:45 -05001969 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001970 return false;
1971 }
1972 break;
1973 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1974 if (!context->getExtensions().textureCompressionDXT3)
1975 {
Jamie Madille0472f32018-11-27 16:32:45 -05001976 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001977 return false;
1978 }
1979 break;
1980 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1981 if (!context->getExtensions().textureCompressionDXT5)
1982 {
Jamie Madille0472f32018-11-27 16:32:45 -05001983 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001984 return false;
1985 }
1986 break;
1987 case GL_ETC1_RGB8_OES:
1988 if (!context->getExtensions().compressedETC1RGB8Texture)
1989 {
Jamie Madille0472f32018-11-27 16:32:45 -05001990 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001991 return false;
1992 }
1993 break;
1994 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001995 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1996 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1997 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1998 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001999 if (!context->getExtensions().lossyETCDecode)
2000 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002001 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08002002 return false;
2003 }
2004 break;
Le Quyen6e653982019-10-09 15:19:02 +08002005 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
2006 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
2007 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
2008 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
2009 if (!context->getExtensions().compressedTexturePVRTC)
2010 {
2011 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
2012 return false;
2013 }
2014 break;
2015 case GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT:
2016 case GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT:
2017 case GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT:
2018 case GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT:
2019 if (!context->getExtensions().compressedTexturePVRTCsRGB)
2020 {
2021 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
2022 return false;
2023 }
2024 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08002025 case GL_RGBA32F_EXT:
2026 case GL_RGB32F_EXT:
2027 case GL_ALPHA32F_EXT:
2028 case GL_LUMINANCE32F_EXT:
2029 case GL_LUMINANCE_ALPHA32F_EXT:
2030 if (!context->getExtensions().textureFloat)
2031 {
Jamie Madille0472f32018-11-27 16:32:45 -05002032 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08002033 return false;
2034 }
2035 break;
2036 case GL_RGBA16F_EXT:
2037 case GL_RGB16F_EXT:
2038 case GL_ALPHA16F_EXT:
2039 case GL_LUMINANCE16F_EXT:
2040 case GL_LUMINANCE_ALPHA16F_EXT:
2041 if (!context->getExtensions().textureHalfFloat)
2042 {
Jamie Madille0472f32018-11-27 16:32:45 -05002043 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08002044 return false;
2045 }
2046 break;
2047 case GL_R8_EXT:
2048 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04002049 if (!context->getExtensions().textureRG)
2050 {
Jamie Madille0472f32018-11-27 16:32:45 -05002051 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang677bb6f2017-04-05 12:40:40 -04002052 return false;
2053 }
2054 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08002055 case GL_R16F_EXT:
2056 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04002057 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
2058 {
Jamie Madille0472f32018-11-27 16:32:45 -05002059 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang677bb6f2017-04-05 12:40:40 -04002060 return false;
2061 }
2062 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08002063 case GL_R32F_EXT:
2064 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04002065 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08002066 {
Jamie Madille0472f32018-11-27 16:32:45 -05002067 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08002068 return false;
2069 }
2070 break;
2071 case GL_DEPTH_COMPONENT16:
2072 case GL_DEPTH_COMPONENT32_OES:
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06002073 if (!(context->getExtensions().depthTextureAny()))
He Yunchaoced53ae2016-11-29 15:00:51 +08002074 {
Jamie Madille0472f32018-11-27 16:32:45 -05002075 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08002076 return false;
2077 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002078 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08002079 {
Jamie Madille0472f32018-11-27 16:32:45 -05002080 context->validationError(GL_INVALID_OPERATION, kInvalidTextureTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08002081 return false;
2082 }
2083 // ANGLE_depth_texture only supports 1-level textures
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06002084 if (!context->getExtensions().depthTextureOES)
He Yunchaoced53ae2016-11-29 15:00:51 +08002085 {
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06002086 if (levels != 1)
2087 {
2088 context->validationError(GL_INVALID_OPERATION, kInvalidMipLevels);
2089 return false;
2090 }
He Yunchaoced53ae2016-11-29 15:00:51 +08002091 }
2092 break;
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06002093 case GL_DEPTH24_STENCIL8_OES:
2094 if (!(context->getExtensions().depthTextureANGLE ||
2095 (context->getExtensions().packedDepthStencil &&
2096 context->getExtensions().textureStorage)))
2097 {
2098 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
2099 return false;
2100 }
2101 if (target != TextureType::_2D)
2102 {
2103 context->validationError(GL_INVALID_OPERATION, kInvalidTextureTarget);
2104 return false;
2105 }
2106 if (!context->getExtensions().packedDepthStencil)
2107 {
2108 // ANGLE_depth_texture only supports 1-level textures
2109 if (levels != 1)
2110 {
2111 context->validationError(GL_INVALID_OPERATION, kInvalidMipLevels);
2112 return false;
2113 }
2114 }
2115 break;
2116
He Yunchaoced53ae2016-11-29 15:00:51 +08002117 default:
2118 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002119 }
2120
Jamie Madillcfc73cc2019-04-08 16:26:51 -04002121 gl::Texture *texture = context->getTextureByType(target);
Jamie Madillf7034432019-09-21 14:10:35 -04002122 if (!texture || texture->id().value == 0)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002123 {
Jamie Madille0472f32018-11-27 16:32:45 -05002124 context->validationError(GL_INVALID_OPERATION, kMissingTexture);
Geoff Langb1196682014-07-23 13:47:29 -04002125 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002126 }
2127
Geoff Lang69cce582015-09-17 13:20:36 -04002128 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002129 {
Jamie Madille0472f32018-11-27 16:32:45 -05002130 context->validationError(GL_INVALID_OPERATION, kTextureIsImmutable);
Geoff Langb1196682014-07-23 13:47:29 -04002131 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002132 }
2133
2134 return true;
2135}
2136
He Yunchaoced53ae2016-11-29 15:00:51 +08002137bool ValidateDiscardFramebufferEXT(Context *context,
2138 GLenum target,
2139 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07002140 const GLenum *attachments)
2141{
Jamie Madillc29968b2016-01-20 11:17:23 -05002142 if (!context->getExtensions().discardFramebuffer)
2143 {
Jamie Madille0472f32018-11-27 16:32:45 -05002144 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05002145 return false;
2146 }
2147
Austin Kinross08332632015-05-05 13:35:47 -07002148 bool defaultFramebuffer = false;
2149
2150 switch (target)
2151 {
He Yunchaoced53ae2016-11-29 15:00:51 +08002152 case GL_FRAMEBUFFER:
2153 defaultFramebuffer =
Tim Van Patten56ba54c2019-08-08 13:03:34 -06002154 (context->getState().getTargetFramebuffer(GL_FRAMEBUFFER)->isDefault());
He Yunchaoced53ae2016-11-29 15:00:51 +08002155 break;
2156 default:
Jamie Madille0472f32018-11-27 16:32:45 -05002157 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08002158 return false;
Austin Kinross08332632015-05-05 13:35:47 -07002159 }
2160
He Yunchaoced53ae2016-11-29 15:00:51 +08002161 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
2162 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07002163}
2164
Jiacheng Lufeb85072019-09-03 13:22:04 -04002165bool ValidateBindVertexArrayOES(Context *context, VertexArrayID array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07002166{
2167 if (!context->getExtensions().vertexArrayObject)
2168 {
Jamie Madille0472f32018-11-27 16:32:45 -05002169 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07002170 return false;
2171 }
2172
2173 return ValidateBindVertexArrayBase(context, array);
2174}
2175
Jiacheng Lufeb85072019-09-03 13:22:04 -04002176bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const VertexArrayID *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07002177{
2178 if (!context->getExtensions().vertexArrayObject)
2179 {
Jamie Madille0472f32018-11-27 16:32:45 -05002180 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07002181 return false;
2182 }
2183
Olli Etuaho41997e72016-03-10 13:38:39 +02002184 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07002185}
2186
Jiacheng Lufeb85072019-09-03 13:22:04 -04002187bool ValidateGenVertexArraysOES(Context *context, GLsizei n, VertexArrayID *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07002188{
2189 if (!context->getExtensions().vertexArrayObject)
2190 {
Jamie Madille0472f32018-11-27 16:32:45 -05002191 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07002192 return false;
2193 }
2194
Olli Etuaho41997e72016-03-10 13:38:39 +02002195 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07002196}
2197
Jiacheng Lufeb85072019-09-03 13:22:04 -04002198bool ValidateIsVertexArrayOES(Context *context, VertexArrayID array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07002199{
2200 if (!context->getExtensions().vertexArrayObject)
2201 {
Jamie Madille0472f32018-11-27 16:32:45 -05002202 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07002203 return false;
2204 }
2205
2206 return true;
2207}
Geoff Langc5629752015-12-07 16:29:04 -05002208
2209bool ValidateProgramBinaryOES(Context *context,
Jiacheng Lu120b61d2019-08-21 12:51:58 -06002210 ShaderProgramID program,
Geoff Langc5629752015-12-07 16:29:04 -05002211 GLenum binaryFormat,
2212 const void *binary,
2213 GLint length)
2214{
2215 if (!context->getExtensions().getProgramBinary)
2216 {
Jamie Madille0472f32018-11-27 16:32:45 -05002217 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05002218 return false;
2219 }
2220
2221 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
2222}
2223
2224bool ValidateGetProgramBinaryOES(Context *context,
Jiacheng Lu120b61d2019-08-21 12:51:58 -06002225 ShaderProgramID program,
Geoff Langc5629752015-12-07 16:29:04 -05002226 GLsizei bufSize,
2227 GLsizei *length,
2228 GLenum *binaryFormat,
2229 void *binary)
2230{
2231 if (!context->getExtensions().getProgramBinary)
2232 {
Jamie Madille0472f32018-11-27 16:32:45 -05002233 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05002234 return false;
2235 }
2236
2237 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
2238}
Geoff Lange102fee2015-12-10 11:23:30 -05002239
Geoff Lang70d0f492015-12-10 17:45:46 -05002240static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
2241{
2242 switch (source)
2243 {
2244 case GL_DEBUG_SOURCE_API:
2245 case GL_DEBUG_SOURCE_SHADER_COMPILER:
2246 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
2247 case GL_DEBUG_SOURCE_OTHER:
2248 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
2249 return !mustBeThirdPartyOrApplication;
2250
2251 case GL_DEBUG_SOURCE_THIRD_PARTY:
2252 case GL_DEBUG_SOURCE_APPLICATION:
2253 return true;
2254
2255 default:
2256 return false;
2257 }
2258}
2259
2260static bool ValidDebugType(GLenum type)
2261{
2262 switch (type)
2263 {
2264 case GL_DEBUG_TYPE_ERROR:
2265 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
2266 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
2267 case GL_DEBUG_TYPE_PERFORMANCE:
2268 case GL_DEBUG_TYPE_PORTABILITY:
2269 case GL_DEBUG_TYPE_OTHER:
2270 case GL_DEBUG_TYPE_MARKER:
2271 case GL_DEBUG_TYPE_PUSH_GROUP:
2272 case GL_DEBUG_TYPE_POP_GROUP:
2273 return true;
2274
2275 default:
2276 return false;
2277 }
2278}
2279
2280static bool ValidDebugSeverity(GLenum severity)
2281{
2282 switch (severity)
2283 {
2284 case GL_DEBUG_SEVERITY_HIGH:
2285 case GL_DEBUG_SEVERITY_MEDIUM:
2286 case GL_DEBUG_SEVERITY_LOW:
2287 case GL_DEBUG_SEVERITY_NOTIFICATION:
2288 return true;
2289
2290 default:
2291 return false;
2292 }
2293}
2294
Geoff Lange102fee2015-12-10 11:23:30 -05002295bool ValidateDebugMessageControlKHR(Context *context,
2296 GLenum source,
2297 GLenum type,
2298 GLenum severity,
2299 GLsizei count,
2300 const GLuint *ids,
2301 GLboolean enabled)
2302{
2303 if (!context->getExtensions().debug)
2304 {
Jamie Madille0472f32018-11-27 16:32:45 -05002305 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002306 return false;
2307 }
2308
Geoff Lang70d0f492015-12-10 17:45:46 -05002309 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
2310 {
Jamie Madille0472f32018-11-27 16:32:45 -05002311 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002312 return false;
2313 }
2314
2315 if (!ValidDebugType(type) && type != GL_DONT_CARE)
2316 {
Jamie Madille0472f32018-11-27 16:32:45 -05002317 context->validationError(GL_INVALID_ENUM, kInvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002318 return false;
2319 }
2320
2321 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
2322 {
Jamie Madille0472f32018-11-27 16:32:45 -05002323 context->validationError(GL_INVALID_ENUM, kInvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05002324 return false;
2325 }
2326
2327 if (count > 0)
2328 {
2329 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
2330 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002331 context->validationError(GL_INVALID_OPERATION, kInvalidDebugSourceType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002332 return false;
2333 }
2334
2335 if (severity != GL_DONT_CARE)
2336 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002337 context->validationError(GL_INVALID_OPERATION, kInvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05002338 return false;
2339 }
2340 }
2341
Geoff Lange102fee2015-12-10 11:23:30 -05002342 return true;
2343}
2344
2345bool ValidateDebugMessageInsertKHR(Context *context,
2346 GLenum source,
2347 GLenum type,
2348 GLuint id,
2349 GLenum severity,
2350 GLsizei length,
2351 const GLchar *buf)
2352{
2353 if (!context->getExtensions().debug)
2354 {
Jamie Madille0472f32018-11-27 16:32:45 -05002355 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002356 return false;
2357 }
2358
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002359 if (!context->getState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002360 {
2361 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2362 // not generate an error.
2363 return false;
2364 }
2365
2366 if (!ValidDebugSeverity(severity))
2367 {
Jamie Madille0472f32018-11-27 16:32:45 -05002368 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002369 return false;
2370 }
2371
2372 if (!ValidDebugType(type))
2373 {
Jamie Madille0472f32018-11-27 16:32:45 -05002374 context->validationError(GL_INVALID_ENUM, kInvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002375 return false;
2376 }
2377
2378 if (!ValidDebugSource(source, true))
2379 {
Jamie Madille0472f32018-11-27 16:32:45 -05002380 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002381 return false;
2382 }
2383
2384 size_t messageLength = (length < 0) ? strlen(buf) : length;
2385 if (messageLength > context->getExtensions().maxDebugMessageLength)
2386 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002387 context->validationError(GL_INVALID_VALUE, kExceedsMaxDebugMessageLength);
Geoff Lang70d0f492015-12-10 17:45:46 -05002388 return false;
2389 }
2390
Geoff Lange102fee2015-12-10 11:23:30 -05002391 return true;
2392}
2393
2394bool ValidateDebugMessageCallbackKHR(Context *context,
2395 GLDEBUGPROCKHR callback,
2396 const void *userParam)
2397{
2398 if (!context->getExtensions().debug)
2399 {
Jamie Madille0472f32018-11-27 16:32:45 -05002400 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002401 return false;
2402 }
2403
Geoff Lange102fee2015-12-10 11:23:30 -05002404 return true;
2405}
2406
2407bool ValidateGetDebugMessageLogKHR(Context *context,
2408 GLuint count,
2409 GLsizei bufSize,
2410 GLenum *sources,
2411 GLenum *types,
2412 GLuint *ids,
2413 GLenum *severities,
2414 GLsizei *lengths,
2415 GLchar *messageLog)
2416{
2417 if (!context->getExtensions().debug)
2418 {
Jamie Madille0472f32018-11-27 16:32:45 -05002419 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002420 return false;
2421 }
2422
Geoff Lang70d0f492015-12-10 17:45:46 -05002423 if (bufSize < 0 && messageLog != nullptr)
2424 {
Jamie Madille0472f32018-11-27 16:32:45 -05002425 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002426 return false;
2427 }
2428
Geoff Lange102fee2015-12-10 11:23:30 -05002429 return true;
2430}
2431
2432bool ValidatePushDebugGroupKHR(Context *context,
2433 GLenum source,
2434 GLuint id,
2435 GLsizei length,
2436 const GLchar *message)
2437{
2438 if (!context->getExtensions().debug)
2439 {
Jamie Madille0472f32018-11-27 16:32:45 -05002440 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002441 return false;
2442 }
2443
Geoff Lang70d0f492015-12-10 17:45:46 -05002444 if (!ValidDebugSource(source, true))
2445 {
Jamie Madille0472f32018-11-27 16:32:45 -05002446 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002447 return false;
2448 }
2449
2450 size_t messageLength = (length < 0) ? strlen(message) : length;
2451 if (messageLength > context->getExtensions().maxDebugMessageLength)
2452 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002453 context->validationError(GL_INVALID_VALUE, kExceedsMaxDebugMessageLength);
Geoff Lang70d0f492015-12-10 17:45:46 -05002454 return false;
2455 }
2456
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002457 size_t currentStackSize = context->getState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002458 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2459 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002460 context->validationError(GL_STACK_OVERFLOW, kExceedsMaxDebugGroupStackDepth);
Geoff Lang70d0f492015-12-10 17:45:46 -05002461 return false;
2462 }
2463
Geoff Lange102fee2015-12-10 11:23:30 -05002464 return true;
2465}
2466
2467bool ValidatePopDebugGroupKHR(Context *context)
2468{
2469 if (!context->getExtensions().debug)
2470 {
Jamie Madille0472f32018-11-27 16:32:45 -05002471 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002472 return false;
2473 }
2474
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002475 size_t currentStackSize = context->getState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002476 if (currentStackSize <= 1)
2477 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002478 context->validationError(GL_STACK_UNDERFLOW, kCannotPopDefaultDebugGroup);
Geoff Lang70d0f492015-12-10 17:45:46 -05002479 return false;
2480 }
2481
2482 return true;
2483}
2484
2485static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2486{
2487 switch (identifier)
2488 {
2489 case GL_BUFFER:
Jamie Madill3b3fe832019-08-06 17:44:12 -04002490 if (context->getBuffer({name}) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002491 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002492 context->validationError(GL_INVALID_VALUE, kInvalidBufferName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002493 return false;
2494 }
2495 return true;
2496
2497 case GL_SHADER:
Jiacheng Lu120b61d2019-08-21 12:51:58 -06002498 if (context->getShader({name}) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002499 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002500 context->validationError(GL_INVALID_VALUE, kInvalidShaderName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002501 return false;
2502 }
2503 return true;
2504
2505 case GL_PROGRAM:
Jiacheng Lu120b61d2019-08-21 12:51:58 -06002506 if (context->getProgramNoResolveLink({name}) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002507 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002508 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002509 return false;
2510 }
2511 return true;
2512
2513 case GL_VERTEX_ARRAY:
Jiacheng Lufeb85072019-09-03 13:22:04 -04002514 if (context->getVertexArray({name}) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002515 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002516 context->validationError(GL_INVALID_VALUE, kInvalidVertexArrayName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002517 return false;
2518 }
2519 return true;
2520
2521 case GL_QUERY:
Jiacheng Lu814a0a12019-08-22 11:50:43 -06002522 if (context->getQuery({name}) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002523 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002524 context->validationError(GL_INVALID_VALUE, kInvalidQueryName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002525 return false;
2526 }
2527 return true;
2528
2529 case GL_TRANSFORM_FEEDBACK:
Jiacheng Luc3f78732019-08-30 15:00:52 -06002530 if (context->getTransformFeedback({name}) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002531 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002532 context->validationError(GL_INVALID_VALUE, kInvalidTransformFeedbackName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002533 return false;
2534 }
2535 return true;
2536
2537 case GL_SAMPLER:
Jiacheng Luee79e2f2019-08-20 11:28:36 -06002538 if (context->getSampler({name}) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002539 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002540 context->validationError(GL_INVALID_VALUE, kInvalidSamplerName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002541 return false;
2542 }
2543 return true;
2544
2545 case GL_TEXTURE:
Jamie Madill2ab08ed2019-08-12 16:20:21 -04002546 if (context->getTexture({name}) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002547 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002548 context->validationError(GL_INVALID_VALUE, kInvalidTextureName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002549 return false;
2550 }
2551 return true;
2552
2553 case GL_RENDERBUFFER:
Jamie Madill7c7dec02019-08-06 17:44:11 -04002554 if (!context->isRenderbuffer({name}))
Geoff Lang70d0f492015-12-10 17:45:46 -05002555 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002556 context->validationError(GL_INVALID_VALUE, kInvalidRenderbufferName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002557 return false;
2558 }
2559 return true;
2560
2561 case GL_FRAMEBUFFER:
Jiacheng Lu2c5d48a2019-08-23 09:28:35 -06002562 if (context->getFramebuffer({name}) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002563 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002564 context->validationError(GL_INVALID_VALUE, kInvalidFramebufferName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002565 return false;
2566 }
2567 return true;
2568
2569 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05002570 context->validationError(GL_INVALID_ENUM, kInvalidIndentifier);
Geoff Lang70d0f492015-12-10 17:45:46 -05002571 return false;
2572 }
Geoff Lange102fee2015-12-10 11:23:30 -05002573}
2574
Martin Radev9d901792016-07-15 15:58:58 +03002575static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2576{
2577 size_t labelLength = 0;
2578
2579 if (length < 0)
2580 {
2581 if (label != nullptr)
2582 {
2583 labelLength = strlen(label);
2584 }
2585 }
2586 else
2587 {
2588 labelLength = static_cast<size_t>(length);
2589 }
2590
2591 if (labelLength > context->getExtensions().maxLabelLength)
2592 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002593 context->validationError(GL_INVALID_VALUE, kExceedsMaxLabelLength);
Martin Radev9d901792016-07-15 15:58:58 +03002594 return false;
2595 }
2596
2597 return true;
2598}
2599
Geoff Lange102fee2015-12-10 11:23:30 -05002600bool ValidateObjectLabelKHR(Context *context,
2601 GLenum identifier,
2602 GLuint name,
2603 GLsizei length,
2604 const GLchar *label)
2605{
2606 if (!context->getExtensions().debug)
2607 {
Jamie Madille0472f32018-11-27 16:32:45 -05002608 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002609 return false;
2610 }
2611
Geoff Lang70d0f492015-12-10 17:45:46 -05002612 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2613 {
2614 return false;
2615 }
2616
Martin Radev9d901792016-07-15 15:58:58 +03002617 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002618 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002619 return false;
2620 }
2621
Geoff Lange102fee2015-12-10 11:23:30 -05002622 return true;
2623}
2624
2625bool ValidateGetObjectLabelKHR(Context *context,
2626 GLenum identifier,
2627 GLuint name,
2628 GLsizei bufSize,
2629 GLsizei *length,
2630 GLchar *label)
2631{
2632 if (!context->getExtensions().debug)
2633 {
Jamie Madille0472f32018-11-27 16:32:45 -05002634 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002635 return false;
2636 }
2637
Geoff Lang70d0f492015-12-10 17:45:46 -05002638 if (bufSize < 0)
2639 {
Jamie Madille0472f32018-11-27 16:32:45 -05002640 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002641 return false;
2642 }
2643
2644 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2645 {
2646 return false;
2647 }
2648
Martin Radev9d901792016-07-15 15:58:58 +03002649 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002650}
2651
2652static bool ValidateObjectPtrName(Context *context, const void *ptr)
2653{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002654 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002655 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002656 context->validationError(GL_INVALID_VALUE, kInvalidSyncPointer);
Geoff Lang70d0f492015-12-10 17:45:46 -05002657 return false;
2658 }
2659
Geoff Lange102fee2015-12-10 11:23:30 -05002660 return true;
2661}
2662
2663bool ValidateObjectPtrLabelKHR(Context *context,
2664 const void *ptr,
2665 GLsizei length,
2666 const GLchar *label)
2667{
2668 if (!context->getExtensions().debug)
2669 {
Jamie Madille0472f32018-11-27 16:32:45 -05002670 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002671 return false;
2672 }
2673
Geoff Lang70d0f492015-12-10 17:45:46 -05002674 if (!ValidateObjectPtrName(context, ptr))
2675 {
2676 return false;
2677 }
2678
Martin Radev9d901792016-07-15 15:58:58 +03002679 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002680 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002681 return false;
2682 }
2683
Geoff Lange102fee2015-12-10 11:23:30 -05002684 return true;
2685}
2686
2687bool ValidateGetObjectPtrLabelKHR(Context *context,
2688 const void *ptr,
2689 GLsizei bufSize,
2690 GLsizei *length,
2691 GLchar *label)
2692{
2693 if (!context->getExtensions().debug)
2694 {
Jamie Madille0472f32018-11-27 16:32:45 -05002695 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002696 return false;
2697 }
2698
Geoff Lang70d0f492015-12-10 17:45:46 -05002699 if (bufSize < 0)
2700 {
Jamie Madille0472f32018-11-27 16:32:45 -05002701 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002702 return false;
2703 }
2704
2705 if (!ValidateObjectPtrName(context, ptr))
2706 {
2707 return false;
2708 }
2709
Martin Radev9d901792016-07-15 15:58:58 +03002710 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002711}
2712
2713bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2714{
2715 if (!context->getExtensions().debug)
2716 {
Jamie Madille0472f32018-11-27 16:32:45 -05002717 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002718 return false;
2719 }
2720
Geoff Lang70d0f492015-12-10 17:45:46 -05002721 // TODO: represent this in Context::getQueryParameterInfo.
2722 switch (pname)
2723 {
2724 case GL_DEBUG_CALLBACK_FUNCTION:
2725 case GL_DEBUG_CALLBACK_USER_PARAM:
2726 break;
2727
2728 default:
Jamie Madille0472f32018-11-27 16:32:45 -05002729 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002730 return false;
2731 }
2732
Geoff Lange102fee2015-12-10 11:23:30 -05002733 return true;
2734}
Jamie Madillc29968b2016-01-20 11:17:23 -05002735
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07002736bool ValidateGetPointervRobustANGLERobustANGLE(Context *context,
2737 GLenum pname,
2738 GLsizei bufSize,
2739 GLsizei *length,
2740 void **params)
2741{
2742 UNIMPLEMENTED();
2743 return false;
2744}
2745
Jamie Madillc29968b2016-01-20 11:17:23 -05002746bool ValidateBlitFramebufferANGLE(Context *context,
2747 GLint srcX0,
2748 GLint srcY0,
2749 GLint srcX1,
2750 GLint srcY1,
2751 GLint dstX0,
2752 GLint dstY0,
2753 GLint dstX1,
2754 GLint dstY1,
2755 GLbitfield mask,
2756 GLenum filter)
2757{
2758 if (!context->getExtensions().framebufferBlit)
2759 {
Jamie Madille0472f32018-11-27 16:32:45 -05002760 context->validationError(GL_INVALID_OPERATION, kBlitExtensionNotAvailable);
Jamie Madillc29968b2016-01-20 11:17:23 -05002761 return false;
2762 }
2763
2764 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2765 {
2766 // TODO(jmadill): Determine if this should be available on other implementations.
Jamie Madille0472f32018-11-27 16:32:45 -05002767 context->validationError(GL_INVALID_OPERATION, kBlitExtensionScaleOrFlip);
Jamie Madillc29968b2016-01-20 11:17:23 -05002768 return false;
2769 }
2770
2771 if (filter == GL_LINEAR)
2772 {
Jamie Madille0472f32018-11-27 16:32:45 -05002773 context->validationError(GL_INVALID_ENUM, kBlitExtensionLinear);
Jamie Madillc29968b2016-01-20 11:17:23 -05002774 return false;
2775 }
2776
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002777 Framebuffer *readFramebuffer = context->getState().getReadFramebuffer();
2778 Framebuffer *drawFramebuffer = context->getState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002779
2780 if (mask & GL_COLOR_BUFFER_BIT)
2781 {
Jamie Madill4e71b2b2019-07-08 13:23:38 -04002782 const FramebufferAttachment *readColorAttachment =
2783 readFramebuffer->getReadColorAttachment();
2784 const FramebufferAttachment *drawColorAttachment =
2785 drawFramebuffer->getFirstColorAttachment();
Jamie Madillc29968b2016-01-20 11:17:23 -05002786
2787 if (readColorAttachment && drawColorAttachment)
2788 {
2789 if (!(readColorAttachment->type() == GL_TEXTURE &&
Kenneth Russellcbdf8612019-07-09 20:30:45 -07002790 (readColorAttachment->getTextureImageIndex().getType() == TextureType::_2D ||
2791 readColorAttachment->getTextureImageIndex().getType() ==
2792 TextureType::Rectangle)) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002793 readColorAttachment->type() != GL_RENDERBUFFER &&
2794 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2795 {
Jamie Madill610640f2018-11-21 17:28:41 -05002796 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002797 kBlitExtensionFromInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002798 return false;
2799 }
2800
Geoff Langa15472a2015-08-11 11:48:03 -04002801 for (size_t drawbufferIdx = 0;
2802 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002803 {
Geoff Langa15472a2015-08-11 11:48:03 -04002804 const FramebufferAttachment *attachment =
2805 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2806 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002807 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002808 if (!(attachment->type() == GL_TEXTURE &&
Kenneth Russellcbdf8612019-07-09 20:30:45 -07002809 (attachment->getTextureImageIndex().getType() == TextureType::_2D ||
2810 attachment->getTextureImageIndex().getType() ==
2811 TextureType::Rectangle)) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002812 attachment->type() != GL_RENDERBUFFER &&
2813 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2814 {
Jamie Madill610640f2018-11-21 17:28:41 -05002815 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002816 kBlitExtensionToInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002817 return false;
2818 }
2819
2820 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002821 if (!Format::EquivalentForBlit(attachment->getFormat(),
2822 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002823 {
Jamie Madill610640f2018-11-21 17:28:41 -05002824 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002825 kBlitExtensionFormatMismatch);
Jamie Madillc29968b2016-01-20 11:17:23 -05002826 return false;
2827 }
2828 }
2829 }
2830
Jamie Madill427064d2018-04-13 16:20:34 -04002831 GLint samples = readFramebuffer->getSamples(context);
Jamie Madille98b1b52018-03-08 09:47:23 -05002832 if (samples != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002833 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2834 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2835 {
Jamie Madill610640f2018-11-21 17:28:41 -05002836 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002837 kBlitExtensionMultisampledWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002838 return false;
2839 }
2840 }
2841 }
2842
2843 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2844 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2845 for (size_t i = 0; i < 2; i++)
2846 {
2847 if (mask & masks[i])
2848 {
2849 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002850 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002851 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002852 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002853
2854 if (readBuffer && drawBuffer)
2855 {
2856 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2857 dstX0, dstY0, dstX1, dstY1))
2858 {
2859 // only whole-buffer copies are permitted
Jamie Madill610640f2018-11-21 17:28:41 -05002860 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002861 kBlitExtensionDepthStencilWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002862 return false;
2863 }
2864
2865 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2866 {
Jamie Madill610640f2018-11-21 17:28:41 -05002867 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002868 kBlitExtensionMultisampledDepthOrStencil);
Jamie Madillc29968b2016-01-20 11:17:23 -05002869 return false;
2870 }
2871 }
2872 }
2873 }
2874
2875 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2876 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002877}
Jamie Madillc29968b2016-01-20 11:17:23 -05002878
Jamie Madill5b772312018-03-08 20:28:32 -05002879bool ValidateClear(Context *context, GLbitfield mask)
Jamie Madillc29968b2016-01-20 11:17:23 -05002880{
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002881 Framebuffer *fbo = context->getState().getDrawFramebuffer();
Olli Etuaho94c91a92018-07-19 15:10:24 +03002882 const Extensions &extensions = context->getExtensions();
Jamie Madille98b1b52018-03-08 09:47:23 -05002883
Jamie Madill427064d2018-04-13 16:20:34 -04002884 if (!ValidateFramebufferComplete(context, fbo))
Jamie Madillc29968b2016-01-20 11:17:23 -05002885 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002886 return false;
2887 }
2888
2889 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2890 {
Jamie Madille0472f32018-11-27 16:32:45 -05002891 context->validationError(GL_INVALID_VALUE, kInvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002892 return false;
2893 }
2894
Olli Etuaho94c91a92018-07-19 15:10:24 +03002895 if (extensions.webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
Geoff Lang76e65652017-03-27 14:58:02 -04002896 {
2897 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2898 GL_SIGNED_NORMALIZED};
2899
Corentin Wallez59c41592017-07-11 13:19:54 -04002900 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002901 drawBufferIdx++)
2902 {
2903 if (!ValidateWebGLFramebufferAttachmentClearType(
2904 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2905 {
2906 return false;
2907 }
2908 }
2909 }
2910
Mingyu Huebab6702019-04-19 14:36:45 -07002911 if ((extensions.multiview || extensions.multiview2) && extensions.disjointTimerQuery)
Olli Etuaho94c91a92018-07-19 15:10:24 +03002912 {
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002913 const State &state = context->getState();
Olli Etuaho94c91a92018-07-19 15:10:24 +03002914 Framebuffer *framebuffer = state.getDrawFramebuffer();
2915 if (framebuffer->getNumViews() > 1 && state.isQueryActive(QueryType::TimeElapsed))
2916 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002917 context->validationError(GL_INVALID_OPERATION, kMultiviewTimerQuery);
Olli Etuaho94c91a92018-07-19 15:10:24 +03002918 return false;
2919 }
2920 }
2921
Jamie Madillc29968b2016-01-20 11:17:23 -05002922 return true;
2923}
2924
Jamie Madill5b772312018-03-08 20:28:32 -05002925bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002926{
2927 if (!context->getExtensions().drawBuffers)
2928 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002929 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05002930 return false;
2931 }
2932
2933 return ValidateDrawBuffersBase(context, n, bufs);
2934}
2935
Jamie Madill73a84962016-02-12 09:27:23 -05002936bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002937 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002938 GLint level,
2939 GLint internalformat,
2940 GLsizei width,
2941 GLsizei height,
2942 GLint border,
2943 GLenum format,
2944 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002945 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002946{
Martin Radev1be913c2016-07-11 17:59:16 +03002947 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002948 {
2949 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002950 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002951 }
2952
Martin Radev1be913c2016-07-11 17:59:16 +03002953 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002954 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002955 0, 0, width, height, 1, border, format, type, -1,
2956 pixels);
2957}
2958
Brandon Jones416aaf92018-04-10 08:10:16 -07002959bool ValidateTexImage2DRobustANGLE(Context *context,
2960 TextureTarget target,
2961 GLint level,
2962 GLint internalformat,
2963 GLsizei width,
2964 GLsizei height,
2965 GLint border,
2966 GLenum format,
2967 GLenum type,
2968 GLsizei bufSize,
2969 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002970{
2971 if (!ValidateRobustEntryPoint(context, bufSize))
2972 {
2973 return false;
2974 }
2975
2976 if (context->getClientMajorVersion() < 3)
2977 {
2978 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2979 0, 0, width, height, border, format, type, bufSize,
2980 pixels);
2981 }
2982
2983 ASSERT(context->getClientMajorVersion() >= 3);
2984 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2985 0, 0, width, height, 1, border, format, type, bufSize,
2986 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002987}
2988
2989bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002990 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002991 GLint level,
2992 GLint xoffset,
2993 GLint yoffset,
2994 GLsizei width,
2995 GLsizei height,
2996 GLenum format,
2997 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002998 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002999{
3000
Martin Radev1be913c2016-07-11 17:59:16 +03003001 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05003002 {
3003 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04003004 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05003005 }
3006
Martin Radev1be913c2016-07-11 17:59:16 +03003007 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05003008 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04003009 yoffset, 0, width, height, 1, 0, format, type, -1,
3010 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05003011}
3012
Geoff Langc52f6f12016-10-14 10:18:00 -04003013bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003014 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04003015 GLint level,
3016 GLint xoffset,
3017 GLint yoffset,
3018 GLsizei width,
3019 GLsizei height,
3020 GLenum format,
3021 GLenum type,
3022 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003023 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04003024{
3025 if (!ValidateRobustEntryPoint(context, bufSize))
3026 {
3027 return false;
3028 }
3029
3030 if (context->getClientMajorVersion() < 3)
3031 {
3032 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
3033 yoffset, width, height, 0, format, type, bufSize,
3034 pixels);
3035 }
3036
3037 ASSERT(context->getClientMajorVersion() >= 3);
3038 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
3039 yoffset, 0, width, height, 1, 0, format, type, bufSize,
3040 pixels);
3041}
3042
Cody Northrop5faff912019-06-28 14:04:50 -06003043bool ValidateTexSubImage3DOES(Context *context,
3044 TextureTarget target,
3045 GLint level,
3046 GLint xoffset,
3047 GLint yoffset,
3048 GLint zoffset,
3049 GLsizei width,
3050 GLsizei height,
3051 GLsizei depth,
3052 GLenum format,
3053 GLenum type,
3054 const void *pixels)
3055{
3056 return ValidateTexSubImage3D(context, target, level, xoffset, yoffset, zoffset, width, height,
3057 depth, format, type, pixels);
3058}
3059
Jamie Madill73a84962016-02-12 09:27:23 -05003060bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003061 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05003062 GLint level,
3063 GLenum internalformat,
3064 GLsizei width,
3065 GLsizei height,
3066 GLint border,
3067 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003068 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003069{
Martin Radev1be913c2016-07-11 17:59:16 +03003070 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05003071 {
3072 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04003073 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05003074 {
3075 return false;
3076 }
3077 }
3078 else
3079 {
Martin Radev1be913c2016-07-11 17:59:16 +03003080 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05003081 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04003082 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05003083 data))
3084 {
3085 return false;
3086 }
3087 }
3088
Geoff Langca271392017-04-05 12:30:00 -04003089 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jamie Madillca2ff382018-07-11 09:01:17 -04003090
3091 GLuint blockSize = 0;
3092 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04003093 {
Jamie Madille0472f32018-11-27 16:32:45 -05003094 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04003095 return false;
3096 }
3097
Jamie Madillca2ff382018-07-11 09:01:17 -04003098 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05003099 {
Jamie Madille0472f32018-11-27 16:32:45 -05003100 context->validationError(GL_INVALID_VALUE, kCompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05003101 return false;
3102 }
3103
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003104 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04003105 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003106 context->validationError(GL_INVALID_ENUM, kRectangleTextureCompressed);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04003107 return false;
3108 }
3109
Jamie Madill73a84962016-02-12 09:27:23 -05003110 return true;
3111}
3112
Corentin Wallezb2931602017-04-11 15:58:57 -04003113bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003114 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04003115 GLint level,
3116 GLenum internalformat,
3117 GLsizei width,
3118 GLsizei height,
3119 GLint border,
3120 GLsizei imageSize,
3121 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003122 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04003123{
3124 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
3125 {
3126 return false;
3127 }
3128
3129 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
3130 border, imageSize, data);
3131}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003132
Cody Northrop5faff912019-06-28 14:04:50 -06003133bool ValidateCompressedTexImage3DOES(Context *context,
3134 TextureTarget target,
3135 GLint level,
3136 GLenum internalformat,
3137 GLsizei width,
3138 GLsizei height,
3139 GLsizei depth,
3140 GLint border,
3141 GLsizei imageSize,
3142 const void *data)
3143{
3144 return ValidateCompressedTexImage3D(context, target, level, internalformat, width, height,
3145 depth, border, imageSize, data);
3146}
3147
Corentin Wallezb2931602017-04-11 15:58:57 -04003148bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003149 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04003150 GLint level,
3151 GLint xoffset,
3152 GLint yoffset,
3153 GLsizei width,
3154 GLsizei height,
3155 GLenum format,
3156 GLsizei imageSize,
3157 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003158 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04003159{
3160 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
3161 {
3162 return false;
3163 }
3164
3165 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
3166 format, imageSize, data);
3167}
3168
Jamie Madill73a84962016-02-12 09:27:23 -05003169bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003170 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05003171 GLint level,
3172 GLint xoffset,
3173 GLint yoffset,
3174 GLsizei width,
3175 GLsizei height,
3176 GLenum format,
3177 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003178 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003179{
Martin Radev1be913c2016-07-11 17:59:16 +03003180 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05003181 {
3182 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04003183 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05003184 {
3185 return false;
3186 }
3187 }
3188 else
3189 {
Martin Radev1be913c2016-07-11 17:59:16 +03003190 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05003191 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04003192 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05003193 data))
3194 {
3195 return false;
3196 }
3197 }
3198
Geoff Langca271392017-04-05 12:30:00 -04003199 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jamie Madillca2ff382018-07-11 09:01:17 -04003200 GLuint blockSize = 0;
3201 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04003202 {
Jamie Madille0472f32018-11-27 16:32:45 -05003203 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04003204 return false;
3205 }
3206
Jamie Madillca2ff382018-07-11 09:01:17 -04003207 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05003208 {
Jamie Madille0472f32018-11-27 16:32:45 -05003209 context->validationError(GL_INVALID_VALUE, kInvalidCompressedImageSize);
Jamie Madill73a84962016-02-12 09:27:23 -05003210 return false;
3211 }
3212
3213 return true;
3214}
3215
Cody Northrop5faff912019-06-28 14:04:50 -06003216bool ValidateCompressedTexSubImage3DOES(Context *context,
3217 TextureTarget target,
3218 GLint level,
3219 GLint xoffset,
3220 GLint yoffset,
3221 GLint zoffset,
3222 GLsizei width,
3223 GLsizei height,
3224 GLsizei depth,
3225 GLenum format,
3226 GLsizei imageSize,
3227 const void *data)
3228{
3229 return ValidateCompressedTexSubImage3D(context, target, level, xoffset, yoffset, zoffset, width,
3230 height, depth, format, imageSize, data);
3231}
3232
Corentin Wallez336129f2017-10-17 15:55:40 -04003233bool ValidateGetBufferPointervOES(Context *context,
3234 BufferBinding target,
3235 GLenum pname,
3236 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003237{
Jamie Madillc3e37312018-11-30 15:25:39 -05003238 if (!context->getExtensions().mapBuffer)
3239 {
3240 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3241 return false;
3242 }
3243
Geoff Lang496c02d2016-10-20 11:38:11 -07003244 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003245}
3246
Corentin Wallez336129f2017-10-17 15:55:40 -04003247bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003248{
3249 if (!context->getExtensions().mapBuffer)
3250 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003251 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03003252 return false;
3253 }
3254
Corentin Walleze4477002017-12-01 14:39:58 -05003255 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003256 {
Jamie Madille0472f32018-11-27 16:32:45 -05003257 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003258 return false;
3259 }
3260
Jamie Madillc3dc5d42018-12-30 12:12:04 -05003261 Buffer *buffer = context->getState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003262
3263 if (buffer == nullptr)
3264 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003265 context->validationError(GL_INVALID_OPERATION, kBufferNotMappable);
Olli Etuaho4f667482016-03-30 15:56:35 +03003266 return false;
3267 }
3268
3269 if (access != GL_WRITE_ONLY_OES)
3270 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003271 context->validationError(GL_INVALID_ENUM, kInvalidAccessBits);
Olli Etuaho4f667482016-03-30 15:56:35 +03003272 return false;
3273 }
3274
3275 if (buffer->isMapped())
3276 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003277 context->validationError(GL_INVALID_OPERATION, kBufferAlreadyMapped);
Olli Etuaho4f667482016-03-30 15:56:35 +03003278 return false;
3279 }
3280
Geoff Lang79f71042017-08-14 16:43:43 -04003281 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003282}
3283
Corentin Wallez336129f2017-10-17 15:55:40 -04003284bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03003285{
3286 if (!context->getExtensions().mapBuffer)
3287 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003288 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03003289 return false;
3290 }
3291
3292 return ValidateUnmapBufferBase(context, target);
3293}
3294
3295bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003296 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003297 GLintptr offset,
3298 GLsizeiptr length,
3299 GLbitfield access)
3300{
3301 if (!context->getExtensions().mapBufferRange)
3302 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003303 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03003304 return false;
3305 }
3306
3307 return ValidateMapBufferRangeBase(context, target, offset, length, access);
3308}
3309
Michael Spang7a8c3e52019-04-03 14:49:57 -04003310bool ValidateBufferStorageMemEXT(Context *context,
3311 TextureType target,
3312 GLsizeiptr size,
Jiacheng Lu9deb3bf2019-08-23 15:57:50 -06003313 MemoryObjectID memory,
Michael Spang7a8c3e52019-04-03 14:49:57 -04003314 GLuint64 offset)
3315{
3316 if (!context->getExtensions().memoryObject)
3317 {
3318 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3319 return false;
3320 }
3321
3322 UNIMPLEMENTED();
3323 return false;
3324}
3325
Jiacheng Lu9deb3bf2019-08-23 15:57:50 -06003326bool ValidateCreateMemoryObjectsEXT(Context *context, GLsizei n, MemoryObjectID *memoryObjects)
Michael Spang7a8c3e52019-04-03 14:49:57 -04003327{
3328 if (!context->getExtensions().memoryObject)
3329 {
3330 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3331 return false;
3332 }
3333
Michael Spangfb201c52019-04-03 14:57:35 -04003334 return ValidateGenOrDelete(context, n);
Michael Spang7a8c3e52019-04-03 14:49:57 -04003335}
3336
Jiacheng Lu9deb3bf2019-08-23 15:57:50 -06003337bool ValidateDeleteMemoryObjectsEXT(Context *context,
3338 GLsizei n,
3339 const MemoryObjectID *memoryObjects)
Michael Spang7a8c3e52019-04-03 14:49:57 -04003340{
3341 if (!context->getExtensions().memoryObject)
3342 {
3343 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3344 return false;
3345 }
3346
Michael Spangfb201c52019-04-03 14:57:35 -04003347 return ValidateGenOrDelete(context, n);
Michael Spang7a8c3e52019-04-03 14:49:57 -04003348}
3349
3350bool ValidateGetMemoryObjectParameterivEXT(Context *context,
Jiacheng Lu9deb3bf2019-08-23 15:57:50 -06003351 MemoryObjectID memoryObject,
Michael Spang7a8c3e52019-04-03 14:49:57 -04003352 GLenum pname,
3353 GLint *params)
3354{
3355 if (!context->getExtensions().memoryObject)
3356 {
3357 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3358 return false;
3359 }
3360
3361 UNIMPLEMENTED();
3362 return false;
3363}
3364
3365bool ValidateGetUnsignedBytevEXT(Context *context, GLenum pname, GLubyte *data)
3366{
3367 if (!context->getExtensions().memoryObject && !context->getExtensions().semaphore)
3368 {
3369 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3370 return false;
3371 }
3372
3373 UNIMPLEMENTED();
3374 return false;
3375}
3376
3377bool ValidateGetUnsignedBytei_vEXT(Context *context, GLenum target, GLuint index, GLubyte *data)
3378{
3379 if (!context->getExtensions().memoryObject && !context->getExtensions().semaphore)
3380 {
3381 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3382 return false;
3383 }
3384
3385 UNIMPLEMENTED();
3386 return false;
3387}
3388
Jiacheng Lu9deb3bf2019-08-23 15:57:50 -06003389bool ValidateIsMemoryObjectEXT(Context *context, MemoryObjectID memoryObject)
Michael Spang7a8c3e52019-04-03 14:49:57 -04003390{
3391 if (!context->getExtensions().memoryObject)
3392 {
3393 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3394 return false;
3395 }
3396
Michael Spangfb201c52019-04-03 14:57:35 -04003397 return true;
Michael Spang7a8c3e52019-04-03 14:49:57 -04003398}
3399
3400bool ValidateMemoryObjectParameterivEXT(Context *context,
Jiacheng Lu9deb3bf2019-08-23 15:57:50 -06003401 MemoryObjectID memoryObject,
Michael Spang7a8c3e52019-04-03 14:49:57 -04003402 GLenum pname,
3403 const GLint *params)
3404{
3405 if (!context->getExtensions().memoryObject)
3406 {
3407 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3408 return false;
3409 }
3410
3411 UNIMPLEMENTED();
3412 return false;
3413}
3414
3415bool ValidateTexStorageMem2DEXT(Context *context,
3416 TextureType target,
3417 GLsizei levels,
3418 GLenum internalFormat,
3419 GLsizei width,
3420 GLsizei height,
Jiacheng Lu9deb3bf2019-08-23 15:57:50 -06003421 MemoryObjectID memory,
Michael Spang7a8c3e52019-04-03 14:49:57 -04003422 GLuint64 offset)
3423{
3424 if (!context->getExtensions().memoryObject)
3425 {
3426 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3427 return false;
3428 }
3429
Michael Spangf02a7672019-04-09 18:45:23 -04003430 if (context->getClientMajorVersion() < 3)
3431 {
3432 return ValidateES2TexStorageParameters(context, target, levels, internalFormat, width,
3433 height);
3434 }
3435
3436 ASSERT(context->getClientMajorVersion() >= 3);
3437 return ValidateES3TexStorage2DParameters(context, target, levels, internalFormat, width, height,
3438 1);
Michael Spang7a8c3e52019-04-03 14:49:57 -04003439}
3440
3441bool ValidateTexStorageMem3DEXT(Context *context,
3442 TextureType target,
3443 GLsizei levels,
3444 GLenum internalFormat,
3445 GLsizei width,
3446 GLsizei height,
3447 GLsizei depth,
Jiacheng Lu9deb3bf2019-08-23 15:57:50 -06003448 MemoryObjectID memory,
Michael Spang7a8c3e52019-04-03 14:49:57 -04003449 GLuint64 offset)
3450{
3451 if (!context->getExtensions().memoryObject)
3452 {
3453 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3454 return false;
3455 }
3456
3457 UNIMPLEMENTED();
3458 return false;
3459}
3460
Michael Spang9de3ddb2019-04-03 16:23:40 -04003461bool ValidateImportMemoryFdEXT(Context *context,
Jiacheng Lu9deb3bf2019-08-23 15:57:50 -06003462 MemoryObjectID memory,
Michael Spang9de3ddb2019-04-03 16:23:40 -04003463 GLuint64 size,
Michael Spange0da9ce2019-04-16 14:34:51 -04003464 HandleType handleType,
Michael Spang9de3ddb2019-04-03 16:23:40 -04003465 GLint fd)
3466{
3467 if (!context->getExtensions().memoryObjectFd)
3468 {
3469 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3470 return false;
3471 }
3472
Michael Spang3b2c6bf2019-04-16 17:19:50 -04003473 switch (handleType)
3474 {
3475 case HandleType::OpaqueFd:
3476 break;
3477 default:
3478 context->validationError(GL_INVALID_ENUM, kInvalidHandleType);
3479 return false;
3480 }
3481
3482 return true;
Michael Spang9de3ddb2019-04-03 16:23:40 -04003483}
3484
Jiacheng Luf0640bc2019-08-23 10:26:25 -06003485bool ValidateDeleteSemaphoresEXT(Context *context, GLsizei n, const SemaphoreID *semaphores)
Michael Spang7a8c3e52019-04-03 14:49:57 -04003486{
3487 if (!context->getExtensions().semaphore)
3488 {
3489 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3490 return false;
3491 }
3492
Michael Spang5093ba62019-05-14 17:36:36 -04003493 return ValidateGenOrDelete(context, n);
Michael Spang7a8c3e52019-04-03 14:49:57 -04003494}
3495
Jiacheng Luf0640bc2019-08-23 10:26:25 -06003496bool ValidateGenSemaphoresEXT(Context *context, GLsizei n, SemaphoreID *semaphores)
Michael Spang7a8c3e52019-04-03 14:49:57 -04003497{
3498 if (!context->getExtensions().semaphore)
3499 {
3500 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3501 return false;
3502 }
3503
Michael Spang5093ba62019-05-14 17:36:36 -04003504 return ValidateGenOrDelete(context, n);
Michael Spang7a8c3e52019-04-03 14:49:57 -04003505}
3506
3507bool ValidateGetSemaphoreParameterui64vEXT(Context *context,
Jiacheng Luf0640bc2019-08-23 10:26:25 -06003508 SemaphoreID semaphore,
Michael Spang7a8c3e52019-04-03 14:49:57 -04003509 GLenum pname,
3510 GLuint64 *params)
3511{
3512 if (!context->getExtensions().semaphore)
3513 {
3514 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3515 return false;
3516 }
3517
3518 UNIMPLEMENTED();
3519 return false;
3520}
3521
Jiacheng Luf0640bc2019-08-23 10:26:25 -06003522bool ValidateIsSemaphoreEXT(Context *context, SemaphoreID semaphore)
Michael Spang7a8c3e52019-04-03 14:49:57 -04003523{
3524 if (!context->getExtensions().semaphore)
3525 {
3526 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3527 return false;
3528 }
3529
Michael Spang5093ba62019-05-14 17:36:36 -04003530 return true;
Michael Spang7a8c3e52019-04-03 14:49:57 -04003531}
3532
3533bool ValidateSemaphoreParameterui64vEXT(Context *context,
Jiacheng Luf0640bc2019-08-23 10:26:25 -06003534 SemaphoreID semaphore,
Michael Spang7a8c3e52019-04-03 14:49:57 -04003535 GLenum pname,
3536 const GLuint64 *params)
3537{
3538 if (!context->getExtensions().semaphore)
3539 {
3540 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3541 return false;
3542 }
3543
3544 UNIMPLEMENTED();
3545 return false;
3546}
3547
3548bool ValidateSignalSemaphoreEXT(Context *context,
Jiacheng Luf0640bc2019-08-23 10:26:25 -06003549 SemaphoreID semaphore,
Michael Spang7a8c3e52019-04-03 14:49:57 -04003550 GLuint numBufferBarriers,
Jamie Madill3b3fe832019-08-06 17:44:12 -04003551 const BufferID *buffers,
Michael Spang7a8c3e52019-04-03 14:49:57 -04003552 GLuint numTextureBarriers,
Jamie Madill2ab08ed2019-08-12 16:20:21 -04003553 const TextureID *textures,
Michael Spang7a8c3e52019-04-03 14:49:57 -04003554 const GLenum *dstLayouts)
3555{
3556 if (!context->getExtensions().semaphore)
3557 {
3558 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3559 return false;
3560 }
3561
Michael Spangab6a59b2019-05-21 21:26:26 -04003562 for (GLuint i = 0; i < numTextureBarriers; ++i)
3563 {
3564 if (!IsValidImageLayout(FromGLenum<ImageLayout>(dstLayouts[i])))
3565 {
3566 context->validationError(GL_INVALID_ENUM, kInvalidImageLayout);
3567 return false;
3568 }
3569 }
3570
3571 return true;
Michael Spang7a8c3e52019-04-03 14:49:57 -04003572}
3573
3574bool ValidateWaitSemaphoreEXT(Context *context,
Jiacheng Luf0640bc2019-08-23 10:26:25 -06003575 SemaphoreID semaphore,
Michael Spang7a8c3e52019-04-03 14:49:57 -04003576 GLuint numBufferBarriers,
Jamie Madill3b3fe832019-08-06 17:44:12 -04003577 const BufferID *buffers,
Michael Spang7a8c3e52019-04-03 14:49:57 -04003578 GLuint numTextureBarriers,
Jamie Madill2ab08ed2019-08-12 16:20:21 -04003579 const TextureID *textures,
Michael Spang7a8c3e52019-04-03 14:49:57 -04003580 const GLenum *srcLayouts)
3581{
3582 if (!context->getExtensions().semaphore)
3583 {
3584 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3585 return false;
3586 }
3587
Michael Spangab6a59b2019-05-21 21:26:26 -04003588 for (GLuint i = 0; i < numTextureBarriers; ++i)
3589 {
3590 if (!IsValidImageLayout(FromGLenum<ImageLayout>(srcLayouts[i])))
3591 {
3592 context->validationError(GL_INVALID_ENUM, kInvalidImageLayout);
3593 return false;
3594 }
3595 }
3596
3597 return true;
Michael Spang7a8c3e52019-04-03 14:49:57 -04003598}
3599
Michael Spange0da9ce2019-04-16 14:34:51 -04003600bool ValidateImportSemaphoreFdEXT(Context *context,
Jiacheng Luf0640bc2019-08-23 10:26:25 -06003601 SemaphoreID semaphore,
Michael Spange0da9ce2019-04-16 14:34:51 -04003602 HandleType handleType,
3603 GLint fd)
Michael Spang9de3ddb2019-04-03 16:23:40 -04003604{
3605 if (!context->getExtensions().semaphoreFd)
3606 {
3607 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3608 return false;
3609 }
3610
Michael Spang6bb193c2019-05-22 16:32:21 -04003611 switch (handleType)
3612 {
3613 case HandleType::OpaqueFd:
3614 break;
3615 default:
3616 context->validationError(GL_INVALID_ENUM, kInvalidHandleType);
3617 return false;
3618 }
3619
3620 return true;
Michael Spang9de3ddb2019-04-03 16:23:40 -04003621}
3622
Corentin Wallez336129f2017-10-17 15:55:40 -04003623bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04003624{
Jamie Madillc3dc5d42018-12-30 12:12:04 -05003625 Buffer *buffer = context->getState().getTargetBuffer(target);
Geoff Lang79f71042017-08-14 16:43:43 -04003626 ASSERT(buffer != nullptr);
3627
3628 // Check if this buffer is currently being used as a transform feedback output buffer
Shahbaz Youssefi8af6c6f2019-06-18 15:43:44 -04003629 if (context->getState().isTransformFeedbackActive())
Geoff Lang79f71042017-08-14 16:43:43 -04003630 {
Shahbaz Youssefi8af6c6f2019-06-18 15:43:44 -04003631 TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
Geoff Lang79f71042017-08-14 16:43:43 -04003632 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
3633 {
3634 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
3635 if (transformFeedbackBuffer.get() == buffer)
3636 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003637 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
Geoff Lang79f71042017-08-14 16:43:43 -04003638 return false;
3639 }
3640 }
3641 }
3642
James Darpiniane8a93c62018-01-04 18:02:24 -08003643 if (context->getExtensions().webglCompatibility &&
3644 buffer->isBoundForTransformFeedbackAndOtherUse())
3645 {
Jamie Madille0472f32018-11-27 16:32:45 -05003646 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08003647 return false;
3648 }
3649
Geoff Lang79f71042017-08-14 16:43:43 -04003650 return true;
3651}
3652
Olli Etuaho4f667482016-03-30 15:56:35 +03003653bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003654 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003655 GLintptr offset,
3656 GLsizeiptr length)
3657{
3658 if (!context->getExtensions().mapBufferRange)
3659 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003660 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03003661 return false;
3662 }
3663
3664 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
3665}
3666
Geoff Langd8605522016-04-13 10:19:12 -04003667bool ValidateBindUniformLocationCHROMIUM(Context *context,
Jiacheng Lu120b61d2019-08-21 12:51:58 -06003668 ShaderProgramID program,
Geoff Langd8605522016-04-13 10:19:12 -04003669 GLint location,
3670 const GLchar *name)
3671{
3672 if (!context->getExtensions().bindUniformLocation)
3673 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003674 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langd8605522016-04-13 10:19:12 -04003675 return false;
3676 }
3677
3678 Program *programObject = GetValidProgram(context, program);
3679 if (!programObject)
3680 {
3681 return false;
3682 }
3683
3684 if (location < 0)
3685 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003686 context->validationError(GL_INVALID_VALUE, kNegativeLocation);
Geoff Langd8605522016-04-13 10:19:12 -04003687 return false;
3688 }
3689
3690 const Caps &caps = context->getCaps();
3691 if (static_cast<size_t>(location) >=
3692 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3693 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003694 context->validationError(GL_INVALID_VALUE, kInvalidBindUniformLocation);
Geoff Langd8605522016-04-13 10:19:12 -04003695 return false;
3696 }
3697
Geoff Langfc32e8b2017-05-31 14:16:59 -04003698 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3699 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003700 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003701 {
Jamie Madille0472f32018-11-27 16:32:45 -05003702 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003703 return false;
3704 }
3705
Geoff Langd8605522016-04-13 10:19:12 -04003706 if (strncmp(name, "gl_", 3) == 0)
3707 {
Jamie Madille0472f32018-11-27 16:32:45 -05003708 context->validationError(GL_INVALID_VALUE, kNameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003709 return false;
3710 }
3711
3712 return true;
3713}
3714
Jamie Madille2e406c2016-06-02 13:04:10 -04003715bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003716{
3717 if (!context->getExtensions().framebufferMixedSamples)
3718 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003719 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänena797e062016-05-12 15:23:40 +03003720 return false;
3721 }
3722 switch (components)
3723 {
3724 case GL_RGB:
3725 case GL_RGBA:
3726 case GL_ALPHA:
3727 case GL_NONE:
3728 break;
3729 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003730 context->validationError(GL_INVALID_ENUM, kInvalidCoverageComponents);
Sami Väisänena797e062016-05-12 15:23:40 +03003731 return false;
3732 }
3733
3734 return true;
3735}
3736
Sami Väisänene45e53b2016-05-25 10:36:04 +03003737// CHROMIUM_path_rendering
3738
Jamie Madill007530e2017-12-28 14:27:04 -05003739bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003740{
Jamie Madill007530e2017-12-28 14:27:04 -05003741 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003742 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003743 return false;
3744 }
Jamie Madill007530e2017-12-28 14:27:04 -05003745
Sami Väisänene45e53b2016-05-25 10:36:04 +03003746 if (matrix == nullptr)
3747 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003748 context->validationError(GL_INVALID_OPERATION, kInvalidPathMatrix);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003749 return false;
3750 }
Jamie Madill007530e2017-12-28 14:27:04 -05003751
Sami Väisänene45e53b2016-05-25 10:36:04 +03003752 return true;
3753}
3754
Jamie Madill007530e2017-12-28 14:27:04 -05003755bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003756{
Jamie Madill007530e2017-12-28 14:27:04 -05003757 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003758}
3759
Jamie Madill007530e2017-12-28 14:27:04 -05003760bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003761{
3762 if (!context->getExtensions().pathRendering)
3763 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003764 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003765 return false;
3766 }
3767
3768 // range = 0 is undefined in NV_path_rendering.
3769 // we add stricter semantic check here and require a non zero positive range.
3770 if (range <= 0)
3771 {
Jamie Madille0472f32018-11-27 16:32:45 -05003772 context->validationError(GL_INVALID_VALUE, kInvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003773 return false;
3774 }
3775
3776 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3777 {
Jamie Madille0472f32018-11-27 16:32:45 -05003778 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003779 return false;
3780 }
3781
3782 return true;
3783}
3784
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06003785bool ValidateDeletePathsCHROMIUM(Context *context, PathID path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003786{
3787 if (!context->getExtensions().pathRendering)
3788 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003789 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003790 return false;
3791 }
3792
3793 // range = 0 is undefined in NV_path_rendering.
3794 // we add stricter semantic check here and require a non zero positive range.
3795 if (range <= 0)
3796 {
Jamie Madille0472f32018-11-27 16:32:45 -05003797 context->validationError(GL_INVALID_VALUE, kInvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003798 return false;
3799 }
3800
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06003801 angle::CheckedNumeric<std::uint32_t> checkedRange(path.value);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003802 checkedRange += range;
3803
3804 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3805 {
Jamie Madille0472f32018-11-27 16:32:45 -05003806 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003807 return false;
3808 }
3809 return true;
3810}
3811
Jamie Madill007530e2017-12-28 14:27:04 -05003812bool ValidatePathCommandsCHROMIUM(Context *context,
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06003813 PathID path,
Jamie Madill007530e2017-12-28 14:27:04 -05003814 GLsizei numCommands,
3815 const GLubyte *commands,
3816 GLsizei numCoords,
3817 GLenum coordType,
3818 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003819{
3820 if (!context->getExtensions().pathRendering)
3821 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003822 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003823 return false;
3824 }
Brandon Jones59770802018-04-02 13:18:42 -07003825 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003826 {
Jamie Madille0472f32018-11-27 16:32:45 -05003827 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003828 return false;
3829 }
3830
3831 if (numCommands < 0)
3832 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003833 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCommands);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003834 return false;
3835 }
3836 else if (numCommands > 0)
3837 {
3838 if (!commands)
3839 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003840 context->validationError(GL_INVALID_VALUE, kInvalidPathCommandsArray);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003841 return false;
3842 }
3843 }
3844
3845 if (numCoords < 0)
3846 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003847 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCoords);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003848 return false;
3849 }
3850 else if (numCoords > 0)
3851 {
3852 if (!coords)
3853 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003854 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCoordsArray);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003855 return false;
3856 }
3857 }
3858
3859 std::uint32_t coordTypeSize = 0;
3860 switch (coordType)
3861 {
3862 case GL_BYTE:
3863 coordTypeSize = sizeof(GLbyte);
3864 break;
3865
3866 case GL_UNSIGNED_BYTE:
3867 coordTypeSize = sizeof(GLubyte);
3868 break;
3869
3870 case GL_SHORT:
3871 coordTypeSize = sizeof(GLshort);
3872 break;
3873
3874 case GL_UNSIGNED_SHORT:
3875 coordTypeSize = sizeof(GLushort);
3876 break;
3877
3878 case GL_FLOAT:
3879 coordTypeSize = sizeof(GLfloat);
3880 break;
3881
3882 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003883 context->validationError(GL_INVALID_ENUM, kInvalidPathCoordinateType);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003884 return false;
3885 }
3886
3887 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3888 checkedSize += (coordTypeSize * numCoords);
3889 if (!checkedSize.IsValid())
3890 {
Jamie Madille0472f32018-11-27 16:32:45 -05003891 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003892 return false;
3893 }
3894
3895 // early return skips command data validation when it doesn't exist.
3896 if (!commands)
3897 return true;
3898
3899 GLsizei expectedNumCoords = 0;
3900 for (GLsizei i = 0; i < numCommands; ++i)
3901 {
3902 switch (commands[i])
3903 {
3904 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3905 break;
3906 case GL_MOVE_TO_CHROMIUM:
3907 case GL_LINE_TO_CHROMIUM:
3908 expectedNumCoords += 2;
3909 break;
3910 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3911 expectedNumCoords += 4;
3912 break;
3913 case GL_CUBIC_CURVE_TO_CHROMIUM:
3914 expectedNumCoords += 6;
3915 break;
3916 case GL_CONIC_CURVE_TO_CHROMIUM:
3917 expectedNumCoords += 5;
3918 break;
3919 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003920 context->validationError(GL_INVALID_ENUM, kInvalidPathCommand);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003921 return false;
3922 }
3923 }
Jamie Madillc3e37312018-11-30 15:25:39 -05003924
Sami Väisänene45e53b2016-05-25 10:36:04 +03003925 if (expectedNumCoords != numCoords)
3926 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003927 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCoords);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003928 return false;
3929 }
3930
3931 return true;
3932}
3933
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06003934bool ValidatePathParameterfCHROMIUM(Context *context, PathID path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003935{
3936 if (!context->getExtensions().pathRendering)
3937 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003938 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003939 return false;
3940 }
Brandon Jones59770802018-04-02 13:18:42 -07003941 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003942 {
Jamie Madille0472f32018-11-27 16:32:45 -05003943 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003944 return false;
3945 }
3946
3947 switch (pname)
3948 {
3949 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3950 if (value < 0.0f)
3951 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003952 context->validationError(GL_INVALID_VALUE, kInvalidPathStrokeWidth);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003953 return false;
3954 }
3955 break;
3956 case GL_PATH_END_CAPS_CHROMIUM:
3957 switch (static_cast<GLenum>(value))
3958 {
3959 case GL_FLAT_CHROMIUM:
3960 case GL_SQUARE_CHROMIUM:
3961 case GL_ROUND_CHROMIUM:
3962 break;
3963 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003964 context->validationError(GL_INVALID_ENUM, kInvalidPathEndCaps);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003965 return false;
3966 }
3967 break;
3968 case GL_PATH_JOIN_STYLE_CHROMIUM:
3969 switch (static_cast<GLenum>(value))
3970 {
3971 case GL_MITER_REVERT_CHROMIUM:
3972 case GL_BEVEL_CHROMIUM:
3973 case GL_ROUND_CHROMIUM:
3974 break;
3975 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003976 context->validationError(GL_INVALID_ENUM, kInvalidPathJoinStyle);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003977 return false;
3978 }
Nico Weber41b072b2018-02-09 10:01:32 -05003979 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003980 case GL_PATH_MITER_LIMIT_CHROMIUM:
3981 if (value < 0.0f)
3982 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003983 context->validationError(GL_INVALID_VALUE, kInvalidPathMiterLimit);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003984 return false;
3985 }
3986 break;
3987
3988 case GL_PATH_STROKE_BOUND_CHROMIUM:
3989 // no errors, only clamping.
3990 break;
3991
3992 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003993 context->validationError(GL_INVALID_ENUM, kInvalidPathParameter);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003994 return false;
3995 }
3996 return true;
3997}
3998
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06003999bool ValidatePathParameteriCHROMIUM(Context *context, PathID path, GLenum pname, GLint value)
Jamie Madill007530e2017-12-28 14:27:04 -05004000{
4001 // TODO(jmadill): Use proper clamping cast.
4002 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
4003}
4004
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06004005bool ValidateGetPathParameterfvCHROMIUM(Context *context, PathID path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03004006{
4007 if (!context->getExtensions().pathRendering)
4008 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004009 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03004010 return false;
4011 }
4012
Brandon Jones59770802018-04-02 13:18:42 -07004013 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03004014 {
Jamie Madille0472f32018-11-27 16:32:45 -05004015 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03004016 return false;
4017 }
Jamie Madillc3e37312018-11-30 15:25:39 -05004018
Sami Väisänene45e53b2016-05-25 10:36:04 +03004019 if (!value)
4020 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004021 context->validationError(GL_INVALID_VALUE, kInvalidPathValueArray);
Sami Väisänene45e53b2016-05-25 10:36:04 +03004022 return false;
4023 }
4024
4025 switch (pname)
4026 {
4027 case GL_PATH_STROKE_WIDTH_CHROMIUM:
4028 case GL_PATH_END_CAPS_CHROMIUM:
4029 case GL_PATH_JOIN_STYLE_CHROMIUM:
4030 case GL_PATH_MITER_LIMIT_CHROMIUM:
4031 case GL_PATH_STROKE_BOUND_CHROMIUM:
4032 break;
4033
4034 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05004035 context->validationError(GL_INVALID_ENUM, kInvalidPathParameter);
Sami Väisänene45e53b2016-05-25 10:36:04 +03004036 return false;
4037 }
4038
4039 return true;
4040}
4041
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06004042bool ValidateGetPathParameterivCHROMIUM(Context *context, PathID path, GLenum pname, GLint *value)
Jamie Madill007530e2017-12-28 14:27:04 -05004043{
4044 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
4045 reinterpret_cast<GLfloat *>(value));
4046}
4047
4048bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03004049{
4050 if (!context->getExtensions().pathRendering)
4051 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004052 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03004053 return false;
4054 }
4055
4056 switch (func)
4057 {
4058 case GL_NEVER:
4059 case GL_ALWAYS:
4060 case GL_LESS:
4061 case GL_LEQUAL:
4062 case GL_EQUAL:
4063 case GL_GEQUAL:
4064 case GL_GREATER:
4065 case GL_NOTEQUAL:
4066 break;
4067 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004068 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03004069 return false;
4070 }
4071
4072 return true;
4073}
4074
4075// Note that the spec specifies that for the path drawing commands
4076// if the path object is not an existing path object the command
4077// does nothing and no error is generated.
4078// However if the path object exists but has not been specified any
4079// commands then an error is generated.
4080
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06004081bool ValidateStencilFillPathCHROMIUM(Context *context, PathID path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03004082{
4083 if (!context->getExtensions().pathRendering)
4084 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004085 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03004086 return false;
4087 }
Brandon Jones59770802018-04-02 13:18:42 -07004088 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03004089 {
Jamie Madille0472f32018-11-27 16:32:45 -05004090 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03004091 return false;
4092 }
4093
4094 switch (fillMode)
4095 {
Chris Daltona9dfb3b2019-06-26 18:36:10 -06004096 case GL_INVERT:
Sami Väisänene45e53b2016-05-25 10:36:04 +03004097 case GL_COUNT_UP_CHROMIUM:
4098 case GL_COUNT_DOWN_CHROMIUM:
4099 break;
4100 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004101 context->validationError(GL_INVALID_ENUM, kInvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03004102 return false;
4103 }
4104
4105 if (!isPow2(mask + 1))
4106 {
Jamie Madille0472f32018-11-27 16:32:45 -05004107 context->validationError(GL_INVALID_VALUE, kInvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03004108 return false;
4109 }
4110
4111 return true;
4112}
4113
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06004114bool ValidateStencilStrokePathCHROMIUM(Context *context, PathID path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03004115{
4116 if (!context->getExtensions().pathRendering)
4117 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004118 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03004119 return false;
4120 }
Jamie Madillc3e37312018-11-30 15:25:39 -05004121
Brandon Jones59770802018-04-02 13:18:42 -07004122 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03004123 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004124 context->validationError(GL_INVALID_OPERATION, kNoPathOrNoPathData);
Sami Väisänene45e53b2016-05-25 10:36:04 +03004125 return false;
4126 }
4127
4128 return true;
4129}
4130
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06004131bool ValidateCoverPathCHROMIUM(Context *context, PathID path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03004132{
4133 if (!context->getExtensions().pathRendering)
4134 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004135 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03004136 return false;
4137 }
Brandon Jones59770802018-04-02 13:18:42 -07004138 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03004139 {
Jamie Madille0472f32018-11-27 16:32:45 -05004140 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03004141 return false;
4142 }
4143
4144 switch (coverMode)
4145 {
4146 case GL_CONVEX_HULL_CHROMIUM:
4147 case GL_BOUNDING_BOX_CHROMIUM:
4148 break;
4149 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004150 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03004151 return false;
4152 }
4153 return true;
4154}
4155
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06004156bool ValidateCoverFillPathCHROMIUM(Context *context, PathID path, GLenum coverMode)
Jamie Madill778bf092018-11-14 09:54:36 -05004157{
4158 return ValidateCoverPathCHROMIUM(context, path, coverMode);
4159}
4160
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06004161bool ValidateCoverStrokePathCHROMIUM(Context *context, PathID path, GLenum coverMode)
Jamie Madill778bf092018-11-14 09:54:36 -05004162{
4163 return ValidateCoverPathCHROMIUM(context, path, coverMode);
4164}
4165
Jamie Madill007530e2017-12-28 14:27:04 -05004166bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06004167 PathID path,
Jamie Madill007530e2017-12-28 14:27:04 -05004168 GLenum fillMode,
4169 GLuint mask,
4170 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03004171{
Jamie Madill007530e2017-12-28 14:27:04 -05004172 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
4173 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03004174}
4175
Jamie Madill007530e2017-12-28 14:27:04 -05004176bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06004177 PathID path,
Jamie Madill007530e2017-12-28 14:27:04 -05004178 GLint reference,
4179 GLuint mask,
4180 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03004181{
Jamie Madill007530e2017-12-28 14:27:04 -05004182 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
4183 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03004184}
4185
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06004186bool ValidateIsPathCHROMIUM(Context *context, PathID path)
Sami Väisänene45e53b2016-05-25 10:36:04 +03004187{
4188 if (!context->getExtensions().pathRendering)
4189 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004190 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03004191 return false;
4192 }
4193 return true;
4194}
4195
Jamie Madill007530e2017-12-28 14:27:04 -05004196bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
4197 GLsizei numPaths,
4198 GLenum pathNameType,
4199 const void *paths,
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06004200 PathID pathBase,
Jamie Madill007530e2017-12-28 14:27:04 -05004201 GLenum coverMode,
4202 GLenum transformType,
4203 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03004204{
4205 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
4206 transformType, transformValues))
4207 return false;
4208
4209 switch (coverMode)
4210 {
4211 case GL_CONVEX_HULL_CHROMIUM:
4212 case GL_BOUNDING_BOX_CHROMIUM:
4213 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
4214 break;
4215 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004216 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03004217 return false;
4218 }
4219
4220 return true;
4221}
4222
Jamie Madill007530e2017-12-28 14:27:04 -05004223bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
4224 GLsizei numPaths,
4225 GLenum pathNameType,
4226 const void *paths,
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06004227 PathID pathBase,
Jamie Madill007530e2017-12-28 14:27:04 -05004228 GLenum coverMode,
4229 GLenum transformType,
4230 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03004231{
4232 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
4233 transformType, transformValues))
4234 return false;
4235
4236 switch (coverMode)
4237 {
4238 case GL_CONVEX_HULL_CHROMIUM:
4239 case GL_BOUNDING_BOX_CHROMIUM:
4240 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
4241 break;
4242 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004243 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03004244 return false;
4245 }
4246
4247 return true;
4248}
4249
Jamie Madill007530e2017-12-28 14:27:04 -05004250bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
4251 GLsizei numPaths,
4252 GLenum pathNameType,
4253 const void *paths,
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06004254 PathID pathBase,
Jamie Madill007530e2017-12-28 14:27:04 -05004255 GLenum fillMode,
4256 GLuint mask,
4257 GLenum transformType,
4258 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03004259{
4260
4261 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
4262 transformType, transformValues))
4263 return false;
4264
4265 switch (fillMode)
4266 {
Chris Daltona9dfb3b2019-06-26 18:36:10 -06004267 case GL_INVERT:
Sami Väisänend59ca052016-06-21 16:10:00 +03004268 case GL_COUNT_UP_CHROMIUM:
4269 case GL_COUNT_DOWN_CHROMIUM:
4270 break;
4271 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004272 context->validationError(GL_INVALID_ENUM, kInvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03004273 return false;
4274 }
4275 if (!isPow2(mask + 1))
4276 {
Jamie Madille0472f32018-11-27 16:32:45 -05004277 context->validationError(GL_INVALID_VALUE, kInvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03004278 return false;
4279 }
4280 return true;
4281}
4282
Jamie Madill007530e2017-12-28 14:27:04 -05004283bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
4284 GLsizei numPaths,
4285 GLenum pathNameType,
4286 const void *paths,
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06004287 PathID pathBase,
Jamie Madill007530e2017-12-28 14:27:04 -05004288 GLint reference,
4289 GLuint mask,
4290 GLenum transformType,
4291 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03004292{
4293 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
4294 transformType, transformValues))
4295 return false;
4296
4297 // no more validation here.
4298
4299 return true;
4300}
4301
Jamie Madill007530e2017-12-28 14:27:04 -05004302bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
4303 GLsizei numPaths,
4304 GLenum pathNameType,
4305 const void *paths,
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06004306 PathID pathBase,
Jamie Madill007530e2017-12-28 14:27:04 -05004307 GLenum fillMode,
4308 GLuint mask,
4309 GLenum coverMode,
4310 GLenum transformType,
4311 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03004312{
4313 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
4314 transformType, transformValues))
4315 return false;
4316
4317 switch (coverMode)
4318 {
4319 case GL_CONVEX_HULL_CHROMIUM:
4320 case GL_BOUNDING_BOX_CHROMIUM:
4321 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
4322 break;
4323 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004324 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03004325 return false;
4326 }
4327
4328 switch (fillMode)
4329 {
Chris Daltona9dfb3b2019-06-26 18:36:10 -06004330 case GL_INVERT:
Sami Väisänend59ca052016-06-21 16:10:00 +03004331 case GL_COUNT_UP_CHROMIUM:
4332 case GL_COUNT_DOWN_CHROMIUM:
4333 break;
4334 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004335 context->validationError(GL_INVALID_ENUM, kInvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03004336 return false;
4337 }
4338 if (!isPow2(mask + 1))
4339 {
Jamie Madille0472f32018-11-27 16:32:45 -05004340 context->validationError(GL_INVALID_VALUE, kInvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03004341 return false;
4342 }
4343
4344 return true;
4345}
4346
Jamie Madill007530e2017-12-28 14:27:04 -05004347bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
4348 GLsizei numPaths,
4349 GLenum pathNameType,
4350 const void *paths,
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06004351 PathID pathBase,
Jamie Madill007530e2017-12-28 14:27:04 -05004352 GLint reference,
4353 GLuint mask,
4354 GLenum coverMode,
4355 GLenum transformType,
4356 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03004357{
4358 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
4359 transformType, transformValues))
4360 return false;
4361
4362 switch (coverMode)
4363 {
4364 case GL_CONVEX_HULL_CHROMIUM:
4365 case GL_BOUNDING_BOX_CHROMIUM:
4366 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
4367 break;
4368 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004369 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03004370 return false;
4371 }
4372
4373 return true;
4374}
4375
Jamie Madill007530e2017-12-28 14:27:04 -05004376bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
Jiacheng Lu120b61d2019-08-21 12:51:58 -06004377 ShaderProgramID program,
Jamie Madill007530e2017-12-28 14:27:04 -05004378 GLint location,
4379 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03004380{
4381 if (!context->getExtensions().pathRendering)
4382 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004383 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004384 return false;
4385 }
4386
4387 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
4388 if (location >= MaxLocation)
4389 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004390 context->validationError(GL_INVALID_VALUE, kInvalidVaryingLocation);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004391 return false;
4392 }
4393
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004394 const auto *programObject = context->getProgramNoResolveLink(program);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004395 if (!programObject)
4396 {
Jamie Madille0472f32018-11-27 16:32:45 -05004397 context->validationError(GL_INVALID_OPERATION, kProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004398 return false;
4399 }
4400
4401 if (!name)
4402 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004403 context->validationError(GL_INVALID_VALUE, kMissingName);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004404 return false;
4405 }
4406
4407 if (angle::BeginsWith(name, "gl_"))
4408 {
Jamie Madille0472f32018-11-27 16:32:45 -05004409 context->validationError(GL_INVALID_OPERATION, kNameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004410 return false;
4411 }
4412
4413 return true;
4414}
4415
Jamie Madill007530e2017-12-28 14:27:04 -05004416bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
Jiacheng Lu120b61d2019-08-21 12:51:58 -06004417 ShaderProgramID program,
Jamie Madill007530e2017-12-28 14:27:04 -05004418 GLint location,
4419 GLenum genMode,
4420 GLint components,
4421 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03004422{
4423 if (!context->getExtensions().pathRendering)
4424 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004425 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004426 return false;
4427 }
4428
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004429 const auto *programObject = context->getProgramResolveLink(program);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004430 if (!programObject || programObject->isFlaggedForDeletion())
4431 {
Jamie Madille0472f32018-11-27 16:32:45 -05004432 context->validationError(GL_INVALID_OPERATION, kProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004433 return false;
4434 }
4435
4436 if (!programObject->isLinked())
4437 {
Jamie Madille0472f32018-11-27 16:32:45 -05004438 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004439 return false;
4440 }
4441
4442 switch (genMode)
4443 {
4444 case GL_NONE:
4445 if (components != 0)
4446 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004447 context->validationError(GL_INVALID_VALUE, kInvalidComponents);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004448 return false;
4449 }
4450 break;
4451
4452 case GL_OBJECT_LINEAR_CHROMIUM:
4453 case GL_EYE_LINEAR_CHROMIUM:
4454 case GL_CONSTANT_CHROMIUM:
4455 if (components < 1 || components > 4)
4456 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004457 context->validationError(GL_INVALID_VALUE, kInvalidComponents);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004458 return false;
4459 }
4460 if (!coeffs)
4461 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004462 context->validationError(GL_INVALID_VALUE, kInvalidPathCoefficientsArray);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004463 return false;
4464 }
4465 break;
4466
4467 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05004468 context->validationError(GL_INVALID_ENUM, kInvalidPathGenMode);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004469 return false;
4470 }
4471
4472 // If the location is -1 then the command is silently ignored
4473 // and no further validation is needed.
4474 if (location == -1)
4475 return true;
4476
jchen103fd614d2018-08-13 12:21:58 +08004477 const auto &binding = programObject->getFragmentInputBindingInfo(location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004478
4479 if (!binding.valid)
4480 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004481 context->validationError(GL_INVALID_OPERATION, kInvalidFragmentInputBinding);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004482 return false;
4483 }
4484
4485 if (binding.type != GL_NONE)
4486 {
4487 GLint expectedComponents = 0;
4488 switch (binding.type)
4489 {
4490 case GL_FLOAT:
4491 expectedComponents = 1;
4492 break;
4493 case GL_FLOAT_VEC2:
4494 expectedComponents = 2;
4495 break;
4496 case GL_FLOAT_VEC3:
4497 expectedComponents = 3;
4498 break;
4499 case GL_FLOAT_VEC4:
4500 expectedComponents = 4;
4501 break;
4502 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05004503 context->validationError(GL_INVALID_OPERATION, kFragmentInputTypeNotFloatingPoint);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004504 return false;
4505 }
4506 if (expectedComponents != components && genMode != GL_NONE)
4507 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004508 context->validationError(GL_INVALID_OPERATION, kInvalidPathComponents);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004509 return false;
4510 }
4511 }
4512 return true;
4513}
4514
Geoff Lang97073d12016-04-20 10:42:34 -07004515bool ValidateCopyTextureCHROMIUM(Context *context,
Jamie Madill2ab08ed2019-08-12 16:20:21 -04004516 TextureID sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04004517 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004518 TextureTarget destTarget,
Jamie Madill2ab08ed2019-08-12 16:20:21 -04004519 TextureID destId,
Geoff Langfc72a072017-03-24 14:52:39 -04004520 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07004521 GLint internalFormat,
4522 GLenum destType,
4523 GLboolean unpackFlipY,
4524 GLboolean unpackPremultiplyAlpha,
4525 GLboolean unpackUnmultiplyAlpha)
4526{
4527 if (!context->getExtensions().copyTexture)
4528 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004529 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang97073d12016-04-20 10:42:34 -07004530 return false;
4531 }
4532
Geoff Lang4f0e0032017-05-01 16:04:35 -04004533 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004534 if (source == nullptr)
4535 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004536 context->validationError(GL_INVALID_VALUE, kInvalidSourceTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07004537 return false;
4538 }
4539
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004540 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004541 {
Jamie Madille0472f32018-11-27 16:32:45 -05004542 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004543 return false;
4544 }
4545
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004546 TextureType sourceType = source->getType();
4547 ASSERT(sourceType != TextureType::CubeMap);
4548 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004549
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004550 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004551 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004552 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureLevel);
Geoff Lang97073d12016-04-20 10:42:34 -07004553 return false;
4554 }
4555
Geoff Lang4f0e0032017-05-01 16:04:35 -04004556 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
4557 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
4558 if (sourceWidth == 0 || sourceHeight == 0)
4559 {
Jamie Madille0472f32018-11-27 16:32:45 -05004560 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004561 return false;
4562 }
4563
4564 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
4565 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004566 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004567 context->validationError(GL_INVALID_OPERATION, kInvalidSourceTextureInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004568 return false;
4569 }
4570
Geoff Lang63458a32017-10-30 15:16:53 -04004571 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4572 {
Jamie Madille0472f32018-11-27 16:32:45 -05004573 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Lang63458a32017-10-30 15:16:53 -04004574 return false;
4575 }
4576
Geoff Lang4f0e0032017-05-01 16:04:35 -04004577 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004578 if (dest == nullptr)
4579 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004580 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07004581 return false;
4582 }
4583
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004584 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004585 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004586 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTextureType);
Geoff Lang97073d12016-04-20 10:42:34 -07004587 return false;
4588 }
4589
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004590 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08004591 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004592 {
Jamie Madille0472f32018-11-27 16:32:45 -05004593 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004594 return false;
4595 }
4596
Geoff Lang97073d12016-04-20 10:42:34 -07004597 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
4598 {
Geoff Lang97073d12016-04-20 10:42:34 -07004599 return false;
4600 }
4601
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004602 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04004603 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004604 context->validationError(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004605 return false;
4606 }
4607
Geoff Lang97073d12016-04-20 10:42:34 -07004608 if (dest->getImmutableFormat())
4609 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004610 context->validationError(GL_INVALID_OPERATION, kDestinationImmutable);
Geoff Lang97073d12016-04-20 10:42:34 -07004611 return false;
4612 }
4613
4614 return true;
4615}
4616
4617bool ValidateCopySubTextureCHROMIUM(Context *context,
Jamie Madill2ab08ed2019-08-12 16:20:21 -04004618 TextureID sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04004619 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004620 TextureTarget destTarget,
Jamie Madill2ab08ed2019-08-12 16:20:21 -04004621 TextureID destId,
Geoff Langfc72a072017-03-24 14:52:39 -04004622 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07004623 GLint xoffset,
4624 GLint yoffset,
4625 GLint x,
4626 GLint y,
4627 GLsizei width,
4628 GLsizei height,
4629 GLboolean unpackFlipY,
4630 GLboolean unpackPremultiplyAlpha,
4631 GLboolean unpackUnmultiplyAlpha)
4632{
4633 if (!context->getExtensions().copyTexture)
4634 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004635 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang97073d12016-04-20 10:42:34 -07004636 return false;
4637 }
4638
Geoff Lang4f0e0032017-05-01 16:04:35 -04004639 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004640 if (source == nullptr)
4641 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004642 context->validationError(GL_INVALID_VALUE, kInvalidSourceTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07004643 return false;
4644 }
4645
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004646 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004647 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004648 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureType);
Geoff Lang97073d12016-04-20 10:42:34 -07004649 return false;
4650 }
4651
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004652 TextureType sourceType = source->getType();
4653 ASSERT(sourceType != TextureType::CubeMap);
4654 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004655
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004656 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004657 {
Jamie Madille0472f32018-11-27 16:32:45 -05004658 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004659 return false;
4660 }
4661
4662 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4663 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004664 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004665 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureLevel);
Geoff Lang97073d12016-04-20 10:42:34 -07004666 return false;
4667 }
4668
4669 if (x < 0 || y < 0)
4670 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004671 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004672 return false;
4673 }
4674
4675 if (width < 0 || height < 0)
4676 {
Jamie Madille0472f32018-11-27 16:32:45 -05004677 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004678 return false;
4679 }
4680
Geoff Lang4f0e0032017-05-01 16:04:35 -04004681 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4682 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004683 {
Jamie Madille0472f32018-11-27 16:32:45 -05004684 context->validationError(GL_INVALID_VALUE, kSourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004685 return false;
4686 }
4687
Geoff Lang4f0e0032017-05-01 16:04:35 -04004688 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4689 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004690 {
Jamie Madille0472f32018-11-27 16:32:45 -05004691 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004692 return false;
4693 }
4694
Geoff Lang63458a32017-10-30 15:16:53 -04004695 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4696 {
Jamie Madille0472f32018-11-27 16:32:45 -05004697 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Lang63458a32017-10-30 15:16:53 -04004698 return false;
4699 }
4700
Geoff Lang4f0e0032017-05-01 16:04:35 -04004701 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004702 if (dest == nullptr)
4703 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004704 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07004705 return false;
4706 }
4707
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004708 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004709 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004710 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTextureType);
Geoff Lang97073d12016-04-20 10:42:34 -07004711 return false;
4712 }
4713
Brandon Jones28783792018-03-05 09:37:32 -08004714 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4715 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004716 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004717 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Lang97073d12016-04-20 10:42:34 -07004718 return false;
4719 }
4720
Geoff Lang4f0e0032017-05-01 16:04:35 -04004721 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4722 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004723 context->validationError(GL_INVALID_OPERATION, kDestinationLevelNotDefined);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004724 return false;
4725 }
4726
4727 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4728 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004729 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004730 context->validationError(GL_INVALID_OPERATION, kInvalidFormatCombination);
Geoff Lang97073d12016-04-20 10:42:34 -07004731 return false;
4732 }
4733
4734 if (xoffset < 0 || yoffset < 0)
4735 {
Jamie Madille0472f32018-11-27 16:32:45 -05004736 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004737 return false;
4738 }
4739
Geoff Lang4f0e0032017-05-01 16:04:35 -04004740 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4741 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004742 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004743 context->validationError(GL_INVALID_VALUE, kOffsetOverflow);
Geoff Lang97073d12016-04-20 10:42:34 -07004744 return false;
4745 }
4746
4747 return true;
4748}
4749
Jamie Madill2ab08ed2019-08-12 16:20:21 -04004750bool ValidateCompressedCopyTextureCHROMIUM(Context *context, TextureID sourceId, TextureID destId)
Geoff Lang47110bf2016-04-20 11:13:22 -07004751{
4752 if (!context->getExtensions().copyCompressedTexture)
4753 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004754 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang47110bf2016-04-20 11:13:22 -07004755 return false;
4756 }
4757
4758 const gl::Texture *source = context->getTexture(sourceId);
4759 if (source == nullptr)
4760 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004761 context->validationError(GL_INVALID_VALUE, kInvalidSourceTexture);
Geoff Lang47110bf2016-04-20 11:13:22 -07004762 return false;
4763 }
4764
Corentin Wallez99d492c2018-02-27 15:17:10 -05004765 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004766 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004767 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureType);
Geoff Lang47110bf2016-04-20 11:13:22 -07004768 return false;
4769 }
4770
Corentin Wallez99d492c2018-02-27 15:17:10 -05004771 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4772 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004773 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004774 context->validationError(GL_INVALID_VALUE, kSourceTextureLevelZeroDefined);
Geoff Lang47110bf2016-04-20 11:13:22 -07004775 return false;
4776 }
4777
Corentin Wallez99d492c2018-02-27 15:17:10 -05004778 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004779 if (!sourceFormat.info->compressed)
4780 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004781 context->validationError(GL_INVALID_OPERATION, kSourceTextureMustBeCompressed);
Geoff Lang47110bf2016-04-20 11:13:22 -07004782 return false;
4783 }
4784
4785 const gl::Texture *dest = context->getTexture(destId);
4786 if (dest == nullptr)
4787 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004788 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTexture);
Geoff Lang47110bf2016-04-20 11:13:22 -07004789 return false;
4790 }
4791
Corentin Wallez99d492c2018-02-27 15:17:10 -05004792 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004793 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004794 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTextureType);
Geoff Lang47110bf2016-04-20 11:13:22 -07004795 return false;
4796 }
4797
4798 if (dest->getImmutableFormat())
4799 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004800 context->validationError(GL_INVALID_OPERATION, kDestinationImmutable);
Geoff Lang47110bf2016-04-20 11:13:22 -07004801 return false;
4802 }
4803
4804 return true;
4805}
4806
Jiawei Shao385b3e02018-03-21 09:43:28 +08004807bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004808{
4809 switch (type)
4810 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004811 case ShaderType::Vertex:
4812 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004813 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004814
Jiawei Shao385b3e02018-03-21 09:43:28 +08004815 case ShaderType::Compute:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004816 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004817 {
Jamie Madille0472f32018-11-27 16:32:45 -05004818 context->validationError(GL_INVALID_ENUM, kES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004819 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004820 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004821 break;
4822
Jiawei Shao385b3e02018-03-21 09:43:28 +08004823 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004824 if (!context->getExtensions().geometryShader)
4825 {
Jamie Madille0472f32018-11-27 16:32:45 -05004826 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
Jiawei Shao89be29a2017-11-06 14:36:45 +08004827 return false;
4828 }
4829 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004830 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004831 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004832 return false;
4833 }
Jamie Madill29639852016-09-02 15:00:09 -04004834
4835 return true;
4836}
4837
Jamie Madill5b772312018-03-08 20:28:32 -05004838bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004839 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004840 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004841 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004842 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004843{
4844 if (size < 0)
4845 {
Jamie Madille0472f32018-11-27 16:32:45 -05004846 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004847 return false;
4848 }
4849
4850 switch (usage)
4851 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004852 case BufferUsage::StreamDraw:
4853 case BufferUsage::StaticDraw:
4854 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004855 break;
4856
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004857 case BufferUsage::StreamRead:
4858 case BufferUsage::StaticRead:
4859 case BufferUsage::DynamicRead:
4860 case BufferUsage::StreamCopy:
4861 case BufferUsage::StaticCopy:
4862 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004863 if (context->getClientMajorVersion() < 3)
4864 {
Jamie Madille0472f32018-11-27 16:32:45 -05004865 context->validationError(GL_INVALID_ENUM, kInvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004866 return false;
4867 }
4868 break;
4869
4870 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004871 context->validationError(GL_INVALID_ENUM, kInvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004872 return false;
4873 }
4874
Corentin Walleze4477002017-12-01 14:39:58 -05004875 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004876 {
Jamie Madille0472f32018-11-27 16:32:45 -05004877 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004878 return false;
4879 }
4880
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004881 Buffer *buffer = context->getState().getTargetBuffer(target);
Jamie Madill29639852016-09-02 15:00:09 -04004882
4883 if (!buffer)
4884 {
Jamie Madille0472f32018-11-27 16:32:45 -05004885 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004886 return false;
4887 }
4888
James Darpiniane8a93c62018-01-04 18:02:24 -08004889 if (context->getExtensions().webglCompatibility &&
4890 buffer->isBoundForTransformFeedbackAndOtherUse())
4891 {
Jamie Madille0472f32018-11-27 16:32:45 -05004892 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08004893 return false;
4894 }
4895
Jamie Madill29639852016-09-02 15:00:09 -04004896 return true;
4897}
4898
Jamie Madill5b772312018-03-08 20:28:32 -05004899bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004900 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004901 GLintptr offset,
4902 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004903 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004904{
Brandon Jones6cad5662017-06-14 13:25:13 -07004905 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004906 {
Jamie Madille0472f32018-11-27 16:32:45 -05004907 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Brandon Jones6cad5662017-06-14 13:25:13 -07004908 return false;
4909 }
4910
4911 if (offset < 0)
4912 {
Jamie Madille0472f32018-11-27 16:32:45 -05004913 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004914 return false;
4915 }
4916
Corentin Walleze4477002017-12-01 14:39:58 -05004917 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004918 {
Jamie Madille0472f32018-11-27 16:32:45 -05004919 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004920 return false;
4921 }
4922
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004923 Buffer *buffer = context->getState().getTargetBuffer(target);
Jamie Madill29639852016-09-02 15:00:09 -04004924
4925 if (!buffer)
4926 {
Jamie Madille0472f32018-11-27 16:32:45 -05004927 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004928 return false;
4929 }
4930
4931 if (buffer->isMapped())
4932 {
Jamie Madille0472f32018-11-27 16:32:45 -05004933 context->validationError(GL_INVALID_OPERATION, kBufferMapped);
Jamie Madill29639852016-09-02 15:00:09 -04004934 return false;
4935 }
4936
James Darpiniane8a93c62018-01-04 18:02:24 -08004937 if (context->getExtensions().webglCompatibility &&
4938 buffer->isBoundForTransformFeedbackAndOtherUse())
4939 {
Jamie Madille0472f32018-11-27 16:32:45 -05004940 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08004941 return false;
4942 }
4943
Jamie Madill29639852016-09-02 15:00:09 -04004944 // Check for possible overflow of size + offset
4945 angle::CheckedNumeric<size_t> checkedSize(size);
4946 checkedSize += offset;
4947 if (!checkedSize.IsValid())
4948 {
Jamie Madille0472f32018-11-27 16:32:45 -05004949 context->validationError(GL_INVALID_VALUE, kParamOverflow);
Jamie Madill29639852016-09-02 15:00:09 -04004950 return false;
4951 }
4952
4953 if (size + offset > buffer->getSize())
4954 {
Jamie Madille0472f32018-11-27 16:32:45 -05004955 context->validationError(GL_INVALID_VALUE, kInsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004956 return false;
4957 }
4958
Martin Radev4c4c8e72016-08-04 12:25:34 +03004959 return true;
4960}
4961
Geoff Lang111a99e2017-10-17 10:58:41 -04004962bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004963{
Geoff Langc339c4e2016-11-29 10:37:36 -05004964 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004965 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004966 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langc287ea62016-09-16 14:46:51 -04004967 return false;
4968 }
4969
Geoff Lang111a99e2017-10-17 10:58:41 -04004970 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004971 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004972 context->validationError(GL_INVALID_OPERATION, kExtensionNotRequestable);
Geoff Langc287ea62016-09-16 14:46:51 -04004973 return false;
4974 }
4975
4976 return true;
4977}
4978
James Darpinianc42da4e2019-10-03 13:46:28 -07004979bool ValidateDisableExtensionANGLE(Context *context, const GLchar *name)
4980{
4981 if (!context->getExtensions().requestExtension)
4982 {
4983 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
4984 return false;
4985 }
4986
4987 if (!context->isExtensionDisablable(name))
4988 {
4989 context->validationError(GL_INVALID_OPERATION, kExtensionNotDisablable);
4990 return false;
4991 }
4992
4993 return true;
4994}
4995
Jamie Madill5b772312018-03-08 20:28:32 -05004996bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004997{
Lingfeng Yang038dd532018-03-29 17:31:52 -07004998 if (context->getClientMajorVersion() < 2)
4999 {
5000 return ValidateMultitextureUnit(context, texture);
5001 }
5002
Jamie Madillef300b12016-10-07 15:12:09 -04005003 if (texture < GL_TEXTURE0 ||
5004 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
5005 {
Jamie Madille0472f32018-11-27 16:32:45 -05005006 context->validationError(GL_INVALID_ENUM, kInvalidCombinedImageUnit);
Jamie Madillef300b12016-10-07 15:12:09 -04005007 return false;
5008 }
5009
5010 return true;
5011}
5012
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005013bool ValidateAttachShader(Context *context, ShaderProgramID program, ShaderProgramID shader)
Jamie Madillef300b12016-10-07 15:12:09 -04005014{
5015 Program *programObject = GetValidProgram(context, program);
5016 if (!programObject)
5017 {
5018 return false;
5019 }
5020
5021 Shader *shaderObject = GetValidShader(context, shader);
5022 if (!shaderObject)
5023 {
5024 return false;
5025 }
5026
Jiawei Shao385b3e02018-03-21 09:43:28 +08005027 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04005028 {
Jamie Madille0472f32018-11-27 16:32:45 -05005029 context->validationError(GL_INVALID_OPERATION, kShaderAttachmentHasShader);
Jiawei Shao385b3e02018-03-21 09:43:28 +08005030 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04005031 }
5032
5033 return true;
5034}
5035
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005036bool ValidateBindAttribLocation(Context *context,
5037 ShaderProgramID program,
5038 GLuint index,
5039 const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05005040{
5041 if (index >= MAX_VERTEX_ATTRIBS)
5042 {
Jamie Madille0472f32018-11-27 16:32:45 -05005043 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05005044 return false;
5045 }
5046
5047 if (strncmp(name, "gl_", 3) == 0)
5048 {
Jamie Madille0472f32018-11-27 16:32:45 -05005049 context->validationError(GL_INVALID_OPERATION, kNameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05005050 return false;
5051 }
5052
Brandon Jonesed5b46f2017-07-21 08:39:17 -07005053 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04005054 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07005055 const size_t length = strlen(name);
5056
5057 if (!IsValidESSLString(name, length))
5058 {
5059 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
5060 // for shader-related entry points
Jamie Madille0472f32018-11-27 16:32:45 -05005061 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07005062 return false;
5063 }
5064
5065 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
5066 {
5067 return false;
5068 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04005069 }
5070
Jamie Madill01a80ee2016-11-07 12:06:18 -05005071 return GetValidProgram(context, program) != nullptr;
5072}
5073
Jiacheng Lu2c5d48a2019-08-23 09:28:35 -06005074bool ValidateBindFramebuffer(Context *context, GLenum target, FramebufferID framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05005075{
Geoff Lange8afa902017-09-27 15:00:43 -04005076 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05005077 {
Jamie Madille0472f32018-11-27 16:32:45 -05005078 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05005079 return false;
5080 }
5081
Jamie Madillc3dc5d42018-12-30 12:12:04 -05005082 if (!context->getState().isBindGeneratesResourceEnabled() &&
Jamie Madill01a80ee2016-11-07 12:06:18 -05005083 !context->isFramebufferGenerated(framebuffer))
5084 {
Jamie Madille0472f32018-11-27 16:32:45 -05005085 context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05005086 return false;
5087 }
5088
5089 return true;
5090}
5091
Jamie Madill7c7dec02019-08-06 17:44:11 -04005092bool ValidateBindRenderbuffer(Context *context, GLenum target, RenderbufferID renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05005093{
5094 if (target != GL_RENDERBUFFER)
5095 {
Jamie Madille0472f32018-11-27 16:32:45 -05005096 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05005097 return false;
5098 }
5099
Jamie Madillc3dc5d42018-12-30 12:12:04 -05005100 if (!context->getState().isBindGeneratesResourceEnabled() &&
Jamie Madill01a80ee2016-11-07 12:06:18 -05005101 !context->isRenderbufferGenerated(renderbuffer))
5102 {
Jamie Madille0472f32018-11-27 16:32:45 -05005103 context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05005104 return false;
5105 }
5106
5107 return true;
5108}
5109
Jamie Madill5b772312018-03-08 20:28:32 -05005110static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005111{
5112 switch (mode)
5113 {
5114 case GL_FUNC_ADD:
5115 case GL_FUNC_SUBTRACT:
5116 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04005117 return true;
5118
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005119 case GL_MIN:
5120 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04005121 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005122
5123 default:
5124 return false;
5125 }
5126}
5127
Jamie Madill5b772312018-03-08 20:28:32 -05005128bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005129{
5130 return true;
5131}
5132
Jamie Madill5b772312018-03-08 20:28:32 -05005133bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005134{
Geoff Lang50cac572017-09-26 17:37:43 -04005135 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005136 {
Jamie Madille0472f32018-11-27 16:32:45 -05005137 context->validationError(GL_INVALID_ENUM, kInvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005138 return false;
5139 }
5140
5141 return true;
5142}
5143
Jamie Madill5b772312018-03-08 20:28:32 -05005144bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005145{
Geoff Lang50cac572017-09-26 17:37:43 -04005146 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005147 {
Jamie Madille0472f32018-11-27 16:32:45 -05005148 context->validationError(GL_INVALID_ENUM, kInvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005149 return false;
5150 }
5151
Geoff Lang50cac572017-09-26 17:37:43 -04005152 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005153 {
Jamie Madille0472f32018-11-27 16:32:45 -05005154 context->validationError(GL_INVALID_ENUM, kInvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005155 return false;
5156 }
5157
5158 return true;
5159}
5160
Jamie Madill5b772312018-03-08 20:28:32 -05005161bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005162{
5163 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
5164}
5165
Jamie Madill5b772312018-03-08 20:28:32 -05005166bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005167 GLenum srcRGB,
5168 GLenum dstRGB,
5169 GLenum srcAlpha,
5170 GLenum dstAlpha)
5171{
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03005172 if (!ValidSrcBlendFunc(context, srcRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005173 {
Jamie Madille0472f32018-11-27 16:32:45 -05005174 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005175 return false;
5176 }
5177
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03005178 if (!ValidDstBlendFunc(context, dstRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005179 {
Jamie Madille0472f32018-11-27 16:32:45 -05005180 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005181 return false;
5182 }
5183
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03005184 if (!ValidSrcBlendFunc(context, srcAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005185 {
Jamie Madille0472f32018-11-27 16:32:45 -05005186 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005187 return false;
5188 }
5189
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03005190 if (!ValidDstBlendFunc(context, dstAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005191 {
Jamie Madille0472f32018-11-27 16:32:45 -05005192 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005193 return false;
5194 }
5195
Frank Henigman146e8a12017-03-02 23:22:37 -05005196 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
5197 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005198 {
5199 bool constantColorUsed =
5200 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
5201 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
5202
5203 bool constantAlphaUsed =
5204 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
5205 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
5206
5207 if (constantColorUsed && constantAlphaUsed)
5208 {
Frank Henigman146e8a12017-03-02 23:22:37 -05005209 if (context->getExtensions().webglCompatibility)
5210 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005211 context->validationError(GL_INVALID_OPERATION, kInvalidConstantColor);
5212 return false;
Frank Henigman146e8a12017-03-02 23:22:37 -05005213 }
Jamie Madillc3e37312018-11-30 15:25:39 -05005214
5215 WARN() << kConstantColorAlphaLimitation;
5216 context->validationError(GL_INVALID_OPERATION, kConstantColorAlphaLimitation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005217 return false;
5218 }
5219 }
5220
5221 return true;
5222}
5223
Geoff Langc339c4e2016-11-29 10:37:36 -05005224bool ValidateGetString(Context *context, GLenum name)
5225{
5226 switch (name)
5227 {
5228 case GL_VENDOR:
5229 case GL_RENDERER:
5230 case GL_VERSION:
5231 case GL_SHADING_LANGUAGE_VERSION:
5232 case GL_EXTENSIONS:
5233 break;
5234
5235 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
5236 if (!context->getExtensions().requestExtension)
5237 {
Jamie Madille0472f32018-11-27 16:32:45 -05005238 context->validationError(GL_INVALID_ENUM, kInvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05005239 return false;
5240 }
5241 break;
5242
5243 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005244 context->validationError(GL_INVALID_ENUM, kInvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05005245 return false;
5246 }
5247
5248 return true;
5249}
5250
Jamie Madill5b772312018-03-08 20:28:32 -05005251bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05005252{
5253 if (width <= 0.0f || isNaN(width))
5254 {
Jamie Madille0472f32018-11-27 16:32:45 -05005255 context->validationError(GL_INVALID_VALUE, kInvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05005256 return false;
5257 }
5258
5259 return true;
5260}
5261
Jamie Madill5b772312018-03-08 20:28:32 -05005262bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05005263{
5264 if (context->getExtensions().webglCompatibility && zNear > zFar)
5265 {
Jamie Madille0472f32018-11-27 16:32:45 -05005266 context->validationError(GL_INVALID_OPERATION, kInvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05005267 return false;
5268 }
5269
5270 return true;
5271}
5272
Jamie Madill5b772312018-03-08 20:28:32 -05005273bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05005274 GLenum target,
5275 GLenum internalformat,
5276 GLsizei width,
5277 GLsizei height)
5278{
5279 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
5280 height);
5281}
5282
Jamie Madill5b772312018-03-08 20:28:32 -05005283bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05005284 GLenum target,
5285 GLsizei samples,
5286 GLenum internalformat,
5287 GLsizei width,
5288 GLsizei height)
5289{
5290 if (!context->getExtensions().framebufferMultisample)
5291 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005292 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madille8fb6402017-02-14 17:56:40 -05005293 return false;
5294 }
5295
5296 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
Jamie Madill610640f2018-11-21 17:28:41 -05005297 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_VALUE is
Jamie Madille8fb6402017-02-14 17:56:40 -05005298 // generated.
5299 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
5300 {
Jamie Madille0472f32018-11-27 16:32:45 -05005301 context->validationError(GL_INVALID_VALUE, kSamplesOutOfRange);
Jamie Madille8fb6402017-02-14 17:56:40 -05005302 return false;
5303 }
5304
5305 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
5306 // the specified storage. This is different than ES 3.0 in which a sample number higher
5307 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
5308 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
5309 if (context->getClientMajorVersion() >= 3)
5310 {
5311 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
5312 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
5313 {
Jamie Madille0472f32018-11-27 16:32:45 -05005314 context->validationError(GL_OUT_OF_MEMORY, kSamplesOutOfRange);
Jamie Madille8fb6402017-02-14 17:56:40 -05005315 return false;
5316 }
5317 }
5318
5319 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
5320 width, height);
5321}
5322
Jamie Madill5b772312018-03-08 20:28:32 -05005323bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005324{
Geoff Lange8afa902017-09-27 15:00:43 -04005325 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04005326 {
Jamie Madille0472f32018-11-27 16:32:45 -05005327 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005328 return false;
5329 }
5330
5331 return true;
5332}
5333
Jamie Madill5b772312018-03-08 20:28:32 -05005334bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005335{
5336 return true;
5337}
5338
Jamie Madill5b772312018-03-08 20:28:32 -05005339bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005340{
5341 return true;
5342}
5343
Jamie Madill5b772312018-03-08 20:28:32 -05005344bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005345{
5346 return true;
5347}
5348
Jamie Madill5b772312018-03-08 20:28:32 -05005349bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005350 GLboolean red,
5351 GLboolean green,
5352 GLboolean blue,
5353 GLboolean alpha)
5354{
5355 return true;
5356}
5357
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005358bool ValidateCompileShader(Context *context, ShaderProgramID shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005359{
5360 return true;
5361}
5362
Jamie Madill5b772312018-03-08 20:28:32 -05005363bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005364{
5365 return true;
5366}
5367
Jamie Madill5b772312018-03-08 20:28:32 -05005368bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005369{
5370 switch (mode)
5371 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04005372 case CullFaceMode::Front:
5373 case CullFaceMode::Back:
5374 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04005375 break;
5376
5377 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005378 context->validationError(GL_INVALID_ENUM, kInvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005379 return false;
5380 }
5381
5382 return true;
5383}
5384
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005385bool ValidateDeleteProgram(Context *context, ShaderProgramID program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005386{
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005387 if (program.value == 0)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005388 {
5389 return false;
5390 }
5391
Jamie Madill44a6fbf2018-10-02 13:38:56 -04005392 if (!context->getProgramResolveLink(program))
Jamie Madillc1d770e2017-04-13 17:31:24 -04005393 {
5394 if (context->getShader(program))
5395 {
Jamie Madille0472f32018-11-27 16:32:45 -05005396 context->validationError(GL_INVALID_OPERATION, kExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005397 return false;
5398 }
5399 else
5400 {
Jamie Madille0472f32018-11-27 16:32:45 -05005401 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005402 return false;
5403 }
5404 }
5405
5406 return true;
5407}
5408
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005409bool ValidateDeleteShader(Context *context, ShaderProgramID shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005410{
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005411 if (shader.value == 0)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005412 {
5413 return false;
5414 }
5415
5416 if (!context->getShader(shader))
5417 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04005418 if (context->getProgramResolveLink(shader))
Jamie Madillc1d770e2017-04-13 17:31:24 -04005419 {
Jamie Madille0472f32018-11-27 16:32:45 -05005420 context->validationError(GL_INVALID_OPERATION, kInvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005421 return false;
5422 }
5423 else
5424 {
Jamie Madille0472f32018-11-27 16:32:45 -05005425 context->validationError(GL_INVALID_VALUE, kExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005426 return false;
5427 }
5428 }
5429
5430 return true;
5431}
5432
Jamie Madill5b772312018-03-08 20:28:32 -05005433bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005434{
5435 switch (func)
5436 {
5437 case GL_NEVER:
5438 case GL_ALWAYS:
5439 case GL_LESS:
5440 case GL_LEQUAL:
5441 case GL_EQUAL:
5442 case GL_GREATER:
5443 case GL_GEQUAL:
5444 case GL_NOTEQUAL:
5445 break;
5446
5447 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005448 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005449 return false;
5450 }
5451
5452 return true;
5453}
5454
Jamie Madill5b772312018-03-08 20:28:32 -05005455bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005456{
5457 return true;
5458}
5459
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005460bool ValidateDetachShader(Context *context, ShaderProgramID program, ShaderProgramID shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005461{
5462 Program *programObject = GetValidProgram(context, program);
5463 if (!programObject)
5464 {
5465 return false;
5466 }
5467
5468 Shader *shaderObject = GetValidShader(context, shader);
5469 if (!shaderObject)
5470 {
5471 return false;
5472 }
5473
Jiawei Shao385b3e02018-03-21 09:43:28 +08005474 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005475 if (attachedShader != shaderObject)
5476 {
Jamie Madille0472f32018-11-27 16:32:45 -05005477 context->validationError(GL_INVALID_OPERATION, kShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005478 return false;
5479 }
5480
5481 return true;
5482}
5483
Jamie Madill5b772312018-03-08 20:28:32 -05005484bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005485{
5486 if (index >= MAX_VERTEX_ATTRIBS)
5487 {
Jamie Madille0472f32018-11-27 16:32:45 -05005488 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005489 return false;
5490 }
5491
5492 return true;
5493}
5494
Jamie Madill5b772312018-03-08 20:28:32 -05005495bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005496{
5497 if (index >= MAX_VERTEX_ATTRIBS)
5498 {
Jamie Madille0472f32018-11-27 16:32:45 -05005499 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005500 return false;
5501 }
5502
5503 return true;
5504}
5505
Jamie Madill5b772312018-03-08 20:28:32 -05005506bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005507{
5508 return true;
5509}
5510
Jamie Madill5b772312018-03-08 20:28:32 -05005511bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005512{
5513 return true;
5514}
5515
Jamie Madill5b772312018-03-08 20:28:32 -05005516bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005517{
5518 switch (mode)
5519 {
5520 case GL_CW:
5521 case GL_CCW:
5522 break;
5523 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005524 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005525 return false;
5526 }
5527
5528 return true;
5529}
5530
Jamie Madill5b772312018-03-08 20:28:32 -05005531bool ValidateGetActiveAttrib(Context *context,
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005532 ShaderProgramID program,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005533 GLuint index,
5534 GLsizei bufsize,
5535 GLsizei *length,
5536 GLint *size,
5537 GLenum *type,
5538 GLchar *name)
5539{
5540 if (bufsize < 0)
5541 {
Jamie Madille0472f32018-11-27 16:32:45 -05005542 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005543 return false;
5544 }
5545
5546 Program *programObject = GetValidProgram(context, program);
5547
5548 if (!programObject)
5549 {
5550 return false;
5551 }
5552
5553 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5554 {
Jamie Madille0472f32018-11-27 16:32:45 -05005555 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005556 return false;
5557 }
5558
5559 return true;
5560}
5561
Jamie Madill5b772312018-03-08 20:28:32 -05005562bool ValidateGetActiveUniform(Context *context,
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005563 ShaderProgramID program,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005564 GLuint index,
5565 GLsizei bufsize,
5566 GLsizei *length,
5567 GLint *size,
5568 GLenum *type,
5569 GLchar *name)
5570{
5571 if (bufsize < 0)
5572 {
Jamie Madille0472f32018-11-27 16:32:45 -05005573 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005574 return false;
5575 }
5576
5577 Program *programObject = GetValidProgram(context, program);
5578
5579 if (!programObject)
5580 {
5581 return false;
5582 }
5583
5584 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5585 {
Jamie Madille0472f32018-11-27 16:32:45 -05005586 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005587 return false;
5588 }
5589
5590 return true;
5591}
5592
Jamie Madill5b772312018-03-08 20:28:32 -05005593bool ValidateGetAttachedShaders(Context *context,
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005594 ShaderProgramID program,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005595 GLsizei maxcount,
5596 GLsizei *count,
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005597 ShaderProgramID *shaders)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005598{
5599 if (maxcount < 0)
5600 {
Jamie Madille0472f32018-11-27 16:32:45 -05005601 context->validationError(GL_INVALID_VALUE, kNegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005602 return false;
5603 }
5604
5605 Program *programObject = GetValidProgram(context, program);
5606
5607 if (!programObject)
5608 {
5609 return false;
5610 }
5611
5612 return true;
5613}
5614
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005615bool ValidateGetAttribLocation(Context *context, ShaderProgramID program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005616{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005617 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5618 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005619 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005620 {
Jamie Madille0472f32018-11-27 16:32:45 -05005621 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005622 return false;
5623 }
5624
Jamie Madillc1d770e2017-04-13 17:31:24 -04005625 Program *programObject = GetValidProgram(context, program);
5626
5627 if (!programObject)
5628 {
Jamie Madille0472f32018-11-27 16:32:45 -05005629 context->validationError(GL_INVALID_OPERATION, kProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005630 return false;
5631 }
5632
5633 if (!programObject->isLinked())
5634 {
Jamie Madille0472f32018-11-27 16:32:45 -05005635 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005636 return false;
5637 }
5638
5639 return true;
5640}
5641
Jamie Madill5b772312018-03-08 20:28:32 -05005642bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005643{
5644 GLenum nativeType;
5645 unsigned int numParams = 0;
5646 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5647}
5648
Jamie Madill5b772312018-03-08 20:28:32 -05005649bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005650{
5651 return true;
5652}
5653
Jamie Madill5b772312018-03-08 20:28:32 -05005654bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005655{
5656 GLenum nativeType;
5657 unsigned int numParams = 0;
5658 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5659}
5660
Jamie Madill5b772312018-03-08 20:28:32 -05005661bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005662{
5663 GLenum nativeType;
5664 unsigned int numParams = 0;
5665 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5666}
5667
Jamie Madill5b772312018-03-08 20:28:32 -05005668bool ValidateGetProgramInfoLog(Context *context,
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005669 ShaderProgramID program,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005670 GLsizei bufsize,
5671 GLsizei *length,
5672 GLchar *infolog)
5673{
5674 if (bufsize < 0)
5675 {
Jamie Madille0472f32018-11-27 16:32:45 -05005676 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005677 return false;
5678 }
5679
5680 Program *programObject = GetValidProgram(context, program);
5681 if (!programObject)
5682 {
5683 return false;
5684 }
5685
5686 return true;
5687}
5688
Jamie Madill5b772312018-03-08 20:28:32 -05005689bool ValidateGetShaderInfoLog(Context *context,
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005690 ShaderProgramID shader,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005691 GLsizei bufsize,
5692 GLsizei *length,
5693 GLchar *infolog)
5694{
5695 if (bufsize < 0)
5696 {
Jamie Madille0472f32018-11-27 16:32:45 -05005697 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005698 return false;
5699 }
5700
5701 Shader *shaderObject = GetValidShader(context, shader);
5702 if (!shaderObject)
5703 {
5704 return false;
5705 }
5706
5707 return true;
5708}
5709
Jamie Madill5b772312018-03-08 20:28:32 -05005710bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005711 GLenum shadertype,
5712 GLenum precisiontype,
5713 GLint *range,
5714 GLint *precision)
5715{
5716 switch (shadertype)
5717 {
5718 case GL_VERTEX_SHADER:
5719 case GL_FRAGMENT_SHADER:
5720 break;
5721 case GL_COMPUTE_SHADER:
Jamie Madillc3e37312018-11-30 15:25:39 -05005722 context->validationError(GL_INVALID_OPERATION, kUnimplementedComputeShaderPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005723 return false;
5724 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005725 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005726 return false;
5727 }
5728
5729 switch (precisiontype)
5730 {
5731 case GL_LOW_FLOAT:
5732 case GL_MEDIUM_FLOAT:
5733 case GL_HIGH_FLOAT:
5734 case GL_LOW_INT:
5735 case GL_MEDIUM_INT:
5736 case GL_HIGH_INT:
5737 break;
5738
5739 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005740 context->validationError(GL_INVALID_ENUM, kInvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005741 return false;
5742 }
5743
5744 return true;
5745}
5746
Jamie Madill5b772312018-03-08 20:28:32 -05005747bool ValidateGetShaderSource(Context *context,
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005748 ShaderProgramID shader,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005749 GLsizei bufsize,
5750 GLsizei *length,
5751 GLchar *source)
5752{
5753 if (bufsize < 0)
5754 {
Jamie Madille0472f32018-11-27 16:32:45 -05005755 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005756 return false;
5757 }
5758
5759 Shader *shaderObject = GetValidShader(context, shader);
5760 if (!shaderObject)
5761 {
5762 return false;
5763 }
5764
5765 return true;
5766}
5767
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005768bool ValidateGetUniformLocation(Context *context, ShaderProgramID program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005769{
5770 if (strstr(name, "gl_") == name)
5771 {
5772 return false;
5773 }
5774
Geoff Langfc32e8b2017-05-31 14:16:59 -04005775 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5776 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005777 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005778 {
Jamie Madille0472f32018-11-27 16:32:45 -05005779 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005780 return false;
5781 }
5782
Jamie Madillc1d770e2017-04-13 17:31:24 -04005783 Program *programObject = GetValidProgram(context, program);
5784
5785 if (!programObject)
5786 {
5787 return false;
5788 }
5789
5790 if (!programObject->isLinked())
5791 {
Jamie Madille0472f32018-11-27 16:32:45 -05005792 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005793 return false;
5794 }
5795
5796 return true;
5797}
5798
Jamie Madill5b772312018-03-08 20:28:32 -05005799bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005800{
5801 switch (mode)
5802 {
5803 case GL_FASTEST:
5804 case GL_NICEST:
5805 case GL_DONT_CARE:
5806 break;
5807
5808 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005809 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005810 return false;
5811 }
5812
5813 switch (target)
5814 {
5815 case GL_GENERATE_MIPMAP_HINT:
5816 break;
5817
Geoff Lange7bd2182017-06-16 16:13:13 -04005818 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5819 if (context->getClientVersion() < ES_3_0 &&
5820 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005821 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005822 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005823 return false;
5824 }
5825 break;
5826
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07005827 case GL_PERSPECTIVE_CORRECTION_HINT:
5828 case GL_POINT_SMOOTH_HINT:
5829 case GL_LINE_SMOOTH_HINT:
5830 case GL_FOG_HINT:
5831 if (context->getClientMajorVersion() >= 2)
5832 {
Jamie Madille0472f32018-11-27 16:32:45 -05005833 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07005834 return false;
5835 }
5836 break;
5837
Jamie Madillc1d770e2017-04-13 17:31:24 -04005838 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005839 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005840 return false;
5841 }
5842
5843 return true;
5844}
5845
Jamie Madill3b3fe832019-08-06 17:44:12 -04005846bool ValidateIsBuffer(Context *context, BufferID buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005847{
5848 return true;
5849}
5850
Jiacheng Lu2c5d48a2019-08-23 09:28:35 -06005851bool ValidateIsFramebuffer(Context *context, FramebufferID framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005852{
5853 return true;
5854}
5855
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005856bool ValidateIsProgram(Context *context, ShaderProgramID program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005857{
5858 return true;
5859}
5860
Jamie Madill7c7dec02019-08-06 17:44:11 -04005861bool ValidateIsRenderbuffer(Context *context, RenderbufferID renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005862{
5863 return true;
5864}
5865
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005866bool ValidateIsShader(Context *context, ShaderProgramID shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005867{
5868 return true;
5869}
5870
Jamie Madill2ab08ed2019-08-12 16:20:21 -04005871bool ValidateIsTexture(Context *context, TextureID texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005872{
5873 return true;
5874}
5875
Jamie Madill5b772312018-03-08 20:28:32 -05005876bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005877{
5878 if (context->getClientMajorVersion() < 3)
5879 {
5880 switch (pname)
5881 {
5882 case GL_UNPACK_IMAGE_HEIGHT:
5883 case GL_UNPACK_SKIP_IMAGES:
Jamie Madille0472f32018-11-27 16:32:45 -05005884 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005885 return false;
5886
5887 case GL_UNPACK_ROW_LENGTH:
5888 case GL_UNPACK_SKIP_ROWS:
5889 case GL_UNPACK_SKIP_PIXELS:
5890 if (!context->getExtensions().unpackSubimage)
5891 {
Jamie Madille0472f32018-11-27 16:32:45 -05005892 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005893 return false;
5894 }
5895 break;
5896
5897 case GL_PACK_ROW_LENGTH:
5898 case GL_PACK_SKIP_ROWS:
5899 case GL_PACK_SKIP_PIXELS:
5900 if (!context->getExtensions().packSubimage)
5901 {
Jamie Madille0472f32018-11-27 16:32:45 -05005902 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005903 return false;
5904 }
5905 break;
5906 }
5907 }
5908
5909 if (param < 0)
5910 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005911 context->validationError(GL_INVALID_VALUE, kNegativeParam);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005912 return false;
5913 }
5914
5915 switch (pname)
5916 {
5917 case GL_UNPACK_ALIGNMENT:
5918 if (param != 1 && param != 2 && param != 4 && param != 8)
5919 {
Jamie Madille0472f32018-11-27 16:32:45 -05005920 context->validationError(GL_INVALID_VALUE, kInvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005921 return false;
5922 }
5923 break;
5924
5925 case GL_PACK_ALIGNMENT:
5926 if (param != 1 && param != 2 && param != 4 && param != 8)
5927 {
Jamie Madille0472f32018-11-27 16:32:45 -05005928 context->validationError(GL_INVALID_VALUE, kInvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005929 return false;
5930 }
5931 break;
5932
5933 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005934 if (!context->getExtensions().packReverseRowOrder)
5935 {
Jamie Madille0472f32018-11-27 16:32:45 -05005936 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang000dab82017-09-27 14:27:07 -04005937 }
5938 break;
5939
Jamie Madillc1d770e2017-04-13 17:31:24 -04005940 case GL_UNPACK_ROW_LENGTH:
5941 case GL_UNPACK_IMAGE_HEIGHT:
5942 case GL_UNPACK_SKIP_IMAGES:
5943 case GL_UNPACK_SKIP_ROWS:
5944 case GL_UNPACK_SKIP_PIXELS:
5945 case GL_PACK_ROW_LENGTH:
5946 case GL_PACK_SKIP_ROWS:
5947 case GL_PACK_SKIP_PIXELS:
5948 break;
5949
5950 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005951 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005952 return false;
5953 }
5954
5955 return true;
5956}
5957
Jamie Madill5b772312018-03-08 20:28:32 -05005958bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005959{
5960 return true;
5961}
5962
Jamie Madill5b772312018-03-08 20:28:32 -05005963bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005964{
5965 return true;
5966}
5967
Jamie Madill5b772312018-03-08 20:28:32 -05005968bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005969{
5970 return true;
5971}
5972
Jamie Madill5b772312018-03-08 20:28:32 -05005973bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005974{
5975 if (width < 0 || height < 0)
5976 {
Jamie Madille0472f32018-11-27 16:32:45 -05005977 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005978 return false;
5979 }
5980
5981 return true;
5982}
5983
Jamie Madill5b772312018-03-08 20:28:32 -05005984bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005985 GLsizei n,
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005986 const ShaderProgramID *shaders,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005987 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005988 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005989 GLsizei length)
5990{
5991 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5992 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5993 shaderBinaryFormats.end())
5994 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005995 context->validationError(GL_INVALID_ENUM, kInvalidShaderBinaryFormat);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005996 return false;
5997 }
5998
5999 return true;
6000}
6001
Jamie Madill5b772312018-03-08 20:28:32 -05006002bool ValidateShaderSource(Context *context,
Jiacheng Lu120b61d2019-08-21 12:51:58 -06006003 ShaderProgramID shader,
Jamie Madillc1d770e2017-04-13 17:31:24 -04006004 GLsizei count,
6005 const GLchar *const *string,
6006 const GLint *length)
6007{
6008 if (count < 0)
6009 {
Jamie Madille0472f32018-11-27 16:32:45 -05006010 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04006011 return false;
6012 }
6013
Geoff Langfc32e8b2017-05-31 14:16:59 -04006014 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
6015 // shader-related entry points
6016 if (context->getExtensions().webglCompatibility)
6017 {
6018 for (GLsizei i = 0; i < count; i++)
6019 {
Geoff Langcab92ee2017-07-19 17:32:07 -04006020 size_t len =
6021 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04006022
6023 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04006024 if (!IsValidESSLShaderSourceString(string[i], len,
6025 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04006026 {
Jamie Madille0472f32018-11-27 16:32:45 -05006027 context->validationError(GL_INVALID_VALUE, kShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04006028 return false;
6029 }
6030 }
6031 }
6032
Jamie Madillc1d770e2017-04-13 17:31:24 -04006033 Shader *shaderObject = GetValidShader(context, shader);
6034 if (!shaderObject)
6035 {
6036 return false;
6037 }
6038
6039 return true;
6040}
6041
Jamie Madill5b772312018-03-08 20:28:32 -05006042bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006043{
6044 if (!IsValidStencilFunc(func))
6045 {
Jamie Madille0472f32018-11-27 16:32:45 -05006046 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04006047 return false;
6048 }
6049
6050 return true;
6051}
6052
Jamie Madill5b772312018-03-08 20:28:32 -05006053bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006054{
6055 if (!IsValidStencilFace(face))
6056 {
Jamie Madille0472f32018-11-27 16:32:45 -05006057 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04006058 return false;
6059 }
6060
6061 if (!IsValidStencilFunc(func))
6062 {
Jamie Madille0472f32018-11-27 16:32:45 -05006063 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04006064 return false;
6065 }
6066
6067 return true;
6068}
6069
Jamie Madill5b772312018-03-08 20:28:32 -05006070bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006071{
6072 return true;
6073}
6074
Jamie Madill5b772312018-03-08 20:28:32 -05006075bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006076{
6077 if (!IsValidStencilFace(face))
6078 {
Jamie Madille0472f32018-11-27 16:32:45 -05006079 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04006080 return false;
6081 }
6082
6083 return true;
6084}
6085
Jamie Madill5b772312018-03-08 20:28:32 -05006086bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006087{
6088 if (!IsValidStencilOp(fail))
6089 {
Jamie Madille0472f32018-11-27 16:32:45 -05006090 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04006091 return false;
6092 }
6093
6094 if (!IsValidStencilOp(zfail))
6095 {
Jamie Madille0472f32018-11-27 16:32:45 -05006096 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04006097 return false;
6098 }
6099
6100 if (!IsValidStencilOp(zpass))
6101 {
Jamie Madille0472f32018-11-27 16:32:45 -05006102 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04006103 return false;
6104 }
6105
6106 return true;
6107}
6108
Jamie Madill5b772312018-03-08 20:28:32 -05006109bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04006110 GLenum face,
6111 GLenum fail,
6112 GLenum zfail,
6113 GLenum zpass)
6114{
6115 if (!IsValidStencilFace(face))
6116 {
Jamie Madille0472f32018-11-27 16:32:45 -05006117 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04006118 return false;
6119 }
6120
6121 return ValidateStencilOp(context, fail, zfail, zpass);
6122}
6123
Jamie Madill5b772312018-03-08 20:28:32 -05006124bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006125{
6126 return ValidateUniform(context, GL_FLOAT, location, 1);
6127}
6128
Jamie Madill5b772312018-03-08 20:28:32 -05006129bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006130{
6131 return ValidateUniform(context, GL_FLOAT, location, count);
6132}
6133
Jamie Madill5b772312018-03-08 20:28:32 -05006134bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04006135{
6136 return ValidateUniform1iv(context, location, 1, &x);
6137}
6138
Jamie Madill5b772312018-03-08 20:28:32 -05006139bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006140{
6141 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
6142}
6143
Jamie Madill5b772312018-03-08 20:28:32 -05006144bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006145{
6146 return ValidateUniform(context, GL_INT_VEC2, location, 1);
6147}
6148
Jamie Madill5b772312018-03-08 20:28:32 -05006149bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006150{
6151 return ValidateUniform(context, GL_INT_VEC2, location, count);
6152}
6153
Jamie Madill5b772312018-03-08 20:28:32 -05006154bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006155{
6156 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
6157}
6158
Jamie Madill5b772312018-03-08 20:28:32 -05006159bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006160{
6161 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
6162}
6163
Jamie Madill5b772312018-03-08 20:28:32 -05006164bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006165{
6166 return ValidateUniform(context, GL_INT_VEC3, location, 1);
6167}
6168
Jamie Madill5b772312018-03-08 20:28:32 -05006169bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006170{
6171 return ValidateUniform(context, GL_INT_VEC3, location, count);
6172}
6173
Jamie Madill5b772312018-03-08 20:28:32 -05006174bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006175{
6176 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
6177}
6178
Jamie Madill5b772312018-03-08 20:28:32 -05006179bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006180{
6181 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
6182}
6183
Jamie Madill5b772312018-03-08 20:28:32 -05006184bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006185{
6186 return ValidateUniform(context, GL_INT_VEC4, location, 1);
6187}
6188
Jamie Madill5b772312018-03-08 20:28:32 -05006189bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006190{
6191 return ValidateUniform(context, GL_INT_VEC4, location, count);
6192}
6193
Jamie Madill5b772312018-03-08 20:28:32 -05006194bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04006195 GLint location,
6196 GLsizei count,
6197 GLboolean transpose,
6198 const GLfloat *value)
6199{
6200 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
6201}
6202
Jamie Madill5b772312018-03-08 20:28:32 -05006203bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04006204 GLint location,
6205 GLsizei count,
6206 GLboolean transpose,
6207 const GLfloat *value)
6208{
6209 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
6210}
6211
Jamie Madill5b772312018-03-08 20:28:32 -05006212bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04006213 GLint location,
6214 GLsizei count,
6215 GLboolean transpose,
6216 const GLfloat *value)
6217{
6218 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
6219}
6220
Jiacheng Lu120b61d2019-08-21 12:51:58 -06006221bool ValidateValidateProgram(Context *context, ShaderProgramID program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006222{
6223 Program *programObject = GetValidProgram(context, program);
6224
6225 if (!programObject)
6226 {
6227 return false;
6228 }
6229
6230 return true;
6231}
6232
Jamie Madill5b772312018-03-08 20:28:32 -05006233bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006234{
6235 return ValidateVertexAttribIndex(context, index);
6236}
6237
Jamie Madill5b772312018-03-08 20:28:32 -05006238bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006239{
6240 return ValidateVertexAttribIndex(context, index);
6241}
6242
Jamie Madill5b772312018-03-08 20:28:32 -05006243bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006244{
6245 return ValidateVertexAttribIndex(context, index);
6246}
6247
Jamie Madill5b772312018-03-08 20:28:32 -05006248bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006249{
6250 return ValidateVertexAttribIndex(context, index);
6251}
6252
Jamie Madill5b772312018-03-08 20:28:32 -05006253bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006254{
6255 return ValidateVertexAttribIndex(context, index);
6256}
6257
Jamie Madill5b772312018-03-08 20:28:32 -05006258bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006259{
6260 return ValidateVertexAttribIndex(context, index);
6261}
6262
Jamie Madill5b772312018-03-08 20:28:32 -05006263bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04006264 GLuint index,
6265 GLfloat x,
6266 GLfloat y,
6267 GLfloat z,
6268 GLfloat w)
6269{
6270 return ValidateVertexAttribIndex(context, index);
6271}
6272
Jamie Madill5b772312018-03-08 20:28:32 -05006273bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006274{
6275 return ValidateVertexAttribIndex(context, index);
6276}
6277
Jamie Madill5b772312018-03-08 20:28:32 -05006278bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006279{
6280 if (width < 0 || height < 0)
6281 {
Jamie Madille0472f32018-11-27 16:32:45 -05006282 context->validationError(GL_INVALID_VALUE, kViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04006283 return false;
6284 }
6285
6286 return true;
6287}
6288
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08006289bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006290 GLenum target,
6291 GLenum attachment,
6292 GLenum pname,
6293 GLint *params)
6294{
6295 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
6296 nullptr);
6297}
6298
Jiacheng Lu120b61d2019-08-21 12:51:58 -06006299bool ValidateGetProgramiv(Context *context, ShaderProgramID program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006300{
6301 return ValidateGetProgramivBase(context, program, pname, nullptr);
6302}
6303
Jamie Madill5b772312018-03-08 20:28:32 -05006304bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006305 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006306 GLint level,
6307 GLenum internalformat,
6308 GLint x,
6309 GLint y,
6310 GLsizei width,
6311 GLsizei height,
6312 GLint border)
6313{
6314 if (context->getClientMajorVersion() < 3)
6315 {
6316 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
6317 0, x, y, width, height, border);
6318 }
6319
6320 ASSERT(context->getClientMajorVersion() == 3);
6321 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
6322 0, x, y, width, height, border);
6323}
6324
6325bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006326 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006327 GLint level,
6328 GLint xoffset,
6329 GLint yoffset,
6330 GLint x,
6331 GLint y,
6332 GLsizei width,
6333 GLsizei height)
6334{
6335 if (context->getClientMajorVersion() < 3)
6336 {
6337 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
6338 yoffset, x, y, width, height, 0);
6339 }
6340
6341 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
6342 yoffset, 0, x, y, width, height, 0);
6343}
6344
Cody Northrop5faff912019-06-28 14:04:50 -06006345bool ValidateCopyTexSubImage3DOES(Context *context,
6346 TextureTarget target,
6347 GLint level,
6348 GLint xoffset,
6349 GLint yoffset,
6350 GLint zoffset,
6351 GLint x,
6352 GLint y,
6353 GLsizei width,
6354 GLsizei height)
6355{
6356 return ValidateCopyTexSubImage3D(context, target, level, xoffset, yoffset, zoffset, x, y, width,
6357 height);
6358}
6359
Jamie Madill3b3fe832019-08-06 17:44:12 -04006360bool ValidateDeleteBuffers(Context *context, GLint n, const BufferID *buffers)
Jamie Madillbe849e42017-05-02 15:49:00 -04006361{
6362 return ValidateGenOrDelete(context, n);
6363}
6364
Jiacheng Lu2c5d48a2019-08-23 09:28:35 -06006365bool ValidateDeleteFramebuffers(Context *context, GLint n, const FramebufferID *framebuffers)
Jamie Madillbe849e42017-05-02 15:49:00 -04006366{
6367 return ValidateGenOrDelete(context, n);
6368}
6369
Jamie Madill7c7dec02019-08-06 17:44:11 -04006370bool ValidateDeleteRenderbuffers(Context *context, GLint n, const RenderbufferID *renderbuffers)
Jamie Madillbe849e42017-05-02 15:49:00 -04006371{
6372 return ValidateGenOrDelete(context, n);
6373}
6374
Jamie Madill2ab08ed2019-08-12 16:20:21 -04006375bool ValidateDeleteTextures(Context *context, GLint n, const TextureID *textures)
Jamie Madillbe849e42017-05-02 15:49:00 -04006376{
6377 return ValidateGenOrDelete(context, n);
6378}
6379
6380bool ValidateDisable(Context *context, GLenum cap)
6381{
6382 if (!ValidCap(context, cap, false))
6383 {
Jamie Madille0472f32018-11-27 16:32:45 -05006384 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006385 return false;
6386 }
6387
6388 return true;
6389}
6390
6391bool ValidateEnable(Context *context, GLenum cap)
6392{
6393 if (!ValidCap(context, cap, false))
6394 {
Jamie Madille0472f32018-11-27 16:32:45 -05006395 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006396 return false;
6397 }
6398
6399 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
6400 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
6401 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006402 context->validationError(GL_INVALID_OPERATION, kNoSampleAlphaToCoveragesLimitation);
Jamie Madillbe849e42017-05-02 15:49:00 -04006403
6404 // We also output an error message to the debugger window if tracing is active, so that
6405 // developers can see the error message.
Jamie Madillc3e37312018-11-30 15:25:39 -05006406 ERR() << kNoSampleAlphaToCoveragesLimitation;
Jamie Madillbe849e42017-05-02 15:49:00 -04006407 return false;
6408 }
6409
6410 return true;
6411}
6412
6413bool ValidateFramebufferRenderbuffer(Context *context,
6414 GLenum target,
6415 GLenum attachment,
6416 GLenum renderbuffertarget,
Jamie Madill7c7dec02019-08-06 17:44:11 -04006417 RenderbufferID renderbuffer)
Jamie Madillbe849e42017-05-02 15:49:00 -04006418{
Geoff Lange8afa902017-09-27 15:00:43 -04006419 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04006420 {
Jamie Madille0472f32018-11-27 16:32:45 -05006421 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Brandon Jones6cad5662017-06-14 13:25:13 -07006422 return false;
6423 }
6424
Jamie Madill7c7dec02019-08-06 17:44:11 -04006425 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer.value != 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006426 {
Jamie Madille0472f32018-11-27 16:32:45 -05006427 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006428 return false;
6429 }
6430
6431 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
6432 renderbuffertarget, renderbuffer);
6433}
6434
6435bool ValidateFramebufferTexture2D(Context *context,
6436 GLenum target,
6437 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006438 TextureTarget textarget,
Jamie Madill2ab08ed2019-08-12 16:20:21 -04006439 TextureID texture,
Jamie Madillbe849e42017-05-02 15:49:00 -04006440 GLint level)
6441{
6442 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
6443 // extension
6444 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
6445 level != 0)
6446 {
Jamie Madille0472f32018-11-27 16:32:45 -05006447 context->validationError(GL_INVALID_VALUE, kInvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04006448 return false;
6449 }
6450
6451 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
6452 {
6453 return false;
6454 }
6455
Jamie Madill2ab08ed2019-08-12 16:20:21 -04006456 if (texture.value != 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04006457 {
6458 gl::Texture *tex = context->getTexture(texture);
6459 ASSERT(tex);
6460
6461 const gl::Caps &caps = context->getCaps();
6462
6463 switch (textarget)
6464 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006465 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04006466 {
6467 if (level > gl::log2(caps.max2DTextureSize))
6468 {
Jamie Madille0472f32018-11-27 16:32:45 -05006469 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04006470 return false;
6471 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006472 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04006473 {
Jamie Madille0472f32018-11-27 16:32:45 -05006474 context->validationError(GL_INVALID_OPERATION, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006475 return false;
6476 }
6477 }
6478 break;
6479
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006480 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006481 {
6482 if (level != 0)
6483 {
Jamie Madille0472f32018-11-27 16:32:45 -05006484 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006485 return false;
6486 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006487 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006488 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006489 context->validationError(GL_INVALID_OPERATION, kTextureTargetMismatch);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006490 return false;
6491 }
6492 }
6493 break;
6494
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006495 case TextureTarget::CubeMapNegativeX:
6496 case TextureTarget::CubeMapNegativeY:
6497 case TextureTarget::CubeMapNegativeZ:
6498 case TextureTarget::CubeMapPositiveX:
6499 case TextureTarget::CubeMapPositiveY:
6500 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04006501 {
6502 if (level > gl::log2(caps.maxCubeMapTextureSize))
6503 {
Jamie Madille0472f32018-11-27 16:32:45 -05006504 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04006505 return false;
6506 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006507 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04006508 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006509 context->validationError(GL_INVALID_OPERATION, kTextureTargetMismatch);
Jamie Madillbe849e42017-05-02 15:49:00 -04006510 return false;
6511 }
6512 }
6513 break;
6514
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006515 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04006516 {
Yizhou Jiang7818a852018-09-06 15:02:04 +08006517 if (context->getClientVersion() < ES_3_1 &&
6518 !context->getExtensions().textureMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006519 {
Jamie Madill610640f2018-11-21 17:28:41 -05006520 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05006521 kMultisampleTextureExtensionOrES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006522 return false;
6523 }
6524
6525 if (level != 0)
6526 {
Jamie Madille0472f32018-11-27 16:32:45 -05006527 context->validationError(GL_INVALID_VALUE, kLevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006528 return false;
6529 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006530 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006531 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006532 context->validationError(GL_INVALID_OPERATION, kTextureTargetMismatch);
Jamie Madillbe849e42017-05-02 15:49:00 -04006533 return false;
6534 }
6535 }
6536 break;
6537
6538 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006539 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006540 return false;
6541 }
Jamie Madillbe849e42017-05-02 15:49:00 -04006542 }
6543
6544 return true;
6545}
6546
Cody Northrop5faff912019-06-28 14:04:50 -06006547bool ValidateFramebufferTexture3DOES(Context *context,
6548 GLenum target,
6549 GLenum attachment,
6550 TextureTarget textargetPacked,
Jamie Madill2ab08ed2019-08-12 16:20:21 -04006551 TextureID texture,
Cody Northrop5faff912019-06-28 14:04:50 -06006552 GLint level,
6553 GLint zoffset)
6554{
Cody Northrop90958e32019-08-07 16:26:14 -06006555 // We don't call into a base ValidateFramebufferTexture3D here because
6556 // it doesn't exist for OpenGL ES. This function is replaced by
6557 // FramebufferTextureLayer in ES 3.x, which has broader support.
6558 if (!context->getExtensions().texture3DOES)
6559 {
6560 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
6561 return false;
6562 }
6563
6564 // Attachments are required to be bound to level 0 without ES3 or the
6565 // GL_OES_fbo_render_mipmap extension
6566 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
6567 level != 0)
6568 {
6569 context->validationError(GL_INVALID_VALUE, kInvalidFramebufferTextureLevel);
6570 return false;
6571 }
6572
6573 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
6574 {
6575 return false;
6576 }
6577
Jamie Madill2ab08ed2019-08-12 16:20:21 -04006578 if (texture.value != 0)
Cody Northrop90958e32019-08-07 16:26:14 -06006579 {
6580 gl::Texture *tex = context->getTexture(texture);
6581 ASSERT(tex);
6582
6583 const gl::Caps &caps = context->getCaps();
6584
6585 switch (textargetPacked)
6586 {
6587 case TextureTarget::_3D:
6588 {
6589 if (level > gl::log2(caps.max3DTextureSize))
6590 {
6591 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
6592 return false;
6593 }
6594 if (static_cast<size_t>(zoffset) >= caps.max3DTextureSize)
6595 {
6596 context->validationError(GL_INVALID_VALUE, kInvalidZOffset);
6597 return false;
6598 }
6599 if (tex->getType() != TextureType::_3D)
6600 {
6601 context->validationError(GL_INVALID_OPERATION, kInvalidTextureType);
6602 return false;
6603 }
6604 }
6605 break;
6606
6607 default:
6608 context->validationError(GL_INVALID_OPERATION, kInvalidTextureTarget);
6609 return false;
6610 }
6611 }
6612
6613 return true;
Cody Northrop5faff912019-06-28 14:04:50 -06006614}
6615
Jamie Madill3b3fe832019-08-06 17:44:12 -04006616bool ValidateGenBuffers(Context *context, GLint n, BufferID *buffers)
Jamie Madillbe849e42017-05-02 15:49:00 -04006617{
6618 return ValidateGenOrDelete(context, n);
6619}
6620
Jiacheng Lu2c5d48a2019-08-23 09:28:35 -06006621bool ValidateGenFramebuffers(Context *context, GLint n, FramebufferID *framebuffers)
Jamie Madillbe849e42017-05-02 15:49:00 -04006622{
6623 return ValidateGenOrDelete(context, n);
6624}
6625
Jamie Madill7c7dec02019-08-06 17:44:11 -04006626bool ValidateGenRenderbuffers(Context *context, GLint n, RenderbufferID *renderbuffers)
Jamie Madillbe849e42017-05-02 15:49:00 -04006627{
6628 return ValidateGenOrDelete(context, n);
6629}
6630
Jamie Madill2ab08ed2019-08-12 16:20:21 -04006631bool ValidateGenTextures(Context *context, GLint n, TextureID *textures)
Jamie Madillbe849e42017-05-02 15:49:00 -04006632{
6633 return ValidateGenOrDelete(context, n);
6634}
6635
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006636bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006637{
6638 if (!ValidTextureTarget(context, target))
6639 {
Jamie Madille0472f32018-11-27 16:32:45 -05006640 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006641 return false;
6642 }
6643
Jamie Madillcfc73cc2019-04-08 16:26:51 -04006644 Texture *texture = context->getTextureByType(target);
Jamie Madillbe849e42017-05-02 15:49:00 -04006645
6646 if (texture == nullptr)
6647 {
Jamie Madille0472f32018-11-27 16:32:45 -05006648 context->validationError(GL_INVALID_OPERATION, kTextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006649 return false;
6650 }
6651
6652 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6653
6654 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6655 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6656 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6657 {
Jamie Madille0472f32018-11-27 16:32:45 -05006658 context->validationError(GL_INVALID_OPERATION, kBaseLevelOutOfRange);
Jamie Madillbe849e42017-05-02 15:49:00 -04006659 return false;
6660 }
6661
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006662 TextureTarget baseTarget = (target == TextureType::CubeMap)
6663 ? TextureTarget::CubeMapPositiveX
6664 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006665 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6666 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6667 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006668 {
Jamie Madille0472f32018-11-27 16:32:45 -05006669 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Brandon Jones6cad5662017-06-14 13:25:13 -07006670 return false;
6671 }
6672
Geoff Lang536eca12017-09-13 11:23:35 -04006673 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6674 bool formatUnsized = !format.sized;
6675 bool formatColorRenderableAndFilterable =
6676 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
Yuly Novikovf15f8862018-06-04 18:59:41 -04006677 format.textureAttachmentSupport(context->getClientVersion(), context->getExtensions());
Geoff Lang536eca12017-09-13 11:23:35 -04006678 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006679 {
Jamie Madille0472f32018-11-27 16:32:45 -05006680 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006681 return false;
6682 }
6683
Geoff Lang536eca12017-09-13 11:23:35 -04006684 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6685 // generation
6686 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6687 {
Jamie Madille0472f32018-11-27 16:32:45 -05006688 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Geoff Lang536eca12017-09-13 11:23:35 -04006689 return false;
6690 }
6691
Jiange2c00842018-07-13 16:50:49 +08006692 // According to the OpenGL extension spec EXT_sRGB.txt, EXT_SRGB is based on ES 2.0 and
6693 // generateMipmap is not allowed if texture format is SRGB_EXT or SRGB_ALPHA_EXT.
6694 if (context->getClientVersion() < Version(3, 0) && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006695 {
Jamie Madille0472f32018-11-27 16:32:45 -05006696 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006697 return false;
6698 }
6699
6700 // Non-power of 2 ES2 check
6701 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6702 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6703 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6704 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006705 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6706 target == TextureType::CubeMap);
Jamie Madille0472f32018-11-27 16:32:45 -05006707 context->validationError(GL_INVALID_OPERATION, kTextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006708 return false;
6709 }
6710
6711 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006712 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006713 {
Jamie Madille0472f32018-11-27 16:32:45 -05006714 context->validationError(GL_INVALID_OPERATION, kCubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006715 return false;
6716 }
6717
James Darpinian83b2f0e2018-11-27 15:56:01 -08006718 if (context->getExtensions().webglCompatibility &&
6719 (texture->getWidth(baseTarget, effectiveBaseLevel) == 0 ||
6720 texture->getHeight(baseTarget, effectiveBaseLevel) == 0))
6721 {
6722 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapZeroSize);
6723 return false;
6724 }
6725
Jamie Madillbe849e42017-05-02 15:49:00 -04006726 return true;
6727}
6728
Jamie Madill5b772312018-03-08 20:28:32 -05006729bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006730 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006731 GLenum pname,
6732 GLint *params)
6733{
6734 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6735}
6736
6737bool ValidateGetRenderbufferParameteriv(Context *context,
6738 GLenum target,
6739 GLenum pname,
6740 GLint *params)
6741{
6742 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6743}
6744
Jiacheng Lu120b61d2019-08-21 12:51:58 -06006745bool ValidateGetShaderiv(Context *context, ShaderProgramID shader, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006746{
6747 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6748}
6749
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006750bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006751{
6752 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6753}
6754
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006755bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006756{
6757 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6758}
6759
Till Rathmannb8543632018-10-02 19:46:14 +02006760bool ValidateGetTexParameterIivOES(Context *context,
6761 TextureType target,
6762 GLenum pname,
6763 GLint *params)
6764{
6765 if (context->getClientMajorVersion() < 3)
6766 {
Jamie Madille0472f32018-11-27 16:32:45 -05006767 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006768 return false;
6769 }
6770 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6771}
6772
6773bool ValidateGetTexParameterIuivOES(Context *context,
6774 TextureType target,
6775 GLenum pname,
6776 GLuint *params)
6777{
6778 if (context->getClientMajorVersion() < 3)
6779 {
Jamie Madille0472f32018-11-27 16:32:45 -05006780 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006781 return false;
6782 }
6783 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6784}
6785
Jiacheng Lu120b61d2019-08-21 12:51:58 -06006786bool ValidateGetUniformfv(Context *context,
6787 ShaderProgramID program,
6788 GLint location,
6789 GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006790{
6791 return ValidateGetUniformBase(context, program, location);
6792}
6793
Jiacheng Lu120b61d2019-08-21 12:51:58 -06006794bool ValidateGetUniformiv(Context *context, ShaderProgramID program, GLint location, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006795{
6796 return ValidateGetUniformBase(context, program, location);
6797}
6798
6799bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6800{
6801 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6802}
6803
6804bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6805{
6806 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6807}
6808
6809bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6810{
6811 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6812}
6813
6814bool ValidateIsEnabled(Context *context, GLenum cap)
6815{
6816 if (!ValidCap(context, cap, true))
6817 {
Jamie Madille0472f32018-11-27 16:32:45 -05006818 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006819 return false;
6820 }
6821
6822 return true;
6823}
6824
Jiacheng Lu120b61d2019-08-21 12:51:58 -06006825bool ValidateLinkProgram(Context *context, ShaderProgramID program)
Jamie Madillbe849e42017-05-02 15:49:00 -04006826{
6827 if (context->hasActiveTransformFeedback(program))
6828 {
6829 // ES 3.0.4 section 2.15 page 91
Jamie Madillc3e37312018-11-30 15:25:39 -05006830 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackActiveDuringLink);
Jamie Madillbe849e42017-05-02 15:49:00 -04006831 return false;
6832 }
6833
6834 Program *programObject = GetValidProgram(context, program);
6835 if (!programObject)
6836 {
6837 return false;
6838 }
6839
6840 return true;
6841}
6842
Jamie Madill4928b7c2017-06-20 12:57:39 -04006843bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006844 GLint x,
6845 GLint y,
6846 GLsizei width,
6847 GLsizei height,
6848 GLenum format,
6849 GLenum type,
6850 void *pixels)
6851{
6852 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6853 nullptr, pixels);
6854}
6855
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006856bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006857{
Till Rathmannb8543632018-10-02 19:46:14 +02006858 return ValidateTexParameterBase(context, target, pname, -1, false, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006859}
6860
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006861bool ValidateTexParameterfv(Context *context,
6862 TextureType target,
6863 GLenum pname,
6864 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006865{
Till Rathmannb8543632018-10-02 19:46:14 +02006866 return ValidateTexParameterBase(context, target, pname, -1, true, params);
Jamie Madillbe849e42017-05-02 15:49:00 -04006867}
6868
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006869bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006870{
Till Rathmannb8543632018-10-02 19:46:14 +02006871 return ValidateTexParameterBase(context, target, pname, -1, false, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006872}
6873
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006874bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006875{
Till Rathmannb8543632018-10-02 19:46:14 +02006876 return ValidateTexParameterBase(context, target, pname, -1, true, params);
6877}
6878
6879bool ValidateTexParameterIivOES(Context *context,
6880 TextureType target,
6881 GLenum pname,
6882 const GLint *params)
6883{
6884 if (context->getClientMajorVersion() < 3)
6885 {
Jamie Madille0472f32018-11-27 16:32:45 -05006886 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006887 return false;
6888 }
6889 return ValidateTexParameterBase(context, target, pname, -1, true, params);
6890}
6891
6892bool ValidateTexParameterIuivOES(Context *context,
6893 TextureType target,
6894 GLenum pname,
6895 const GLuint *params)
6896{
6897 if (context->getClientMajorVersion() < 3)
6898 {
Jamie Madille0472f32018-11-27 16:32:45 -05006899 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006900 return false;
6901 }
6902 return ValidateTexParameterBase(context, target, pname, -1, true, params);
Jamie Madillbe849e42017-05-02 15:49:00 -04006903}
6904
Jiacheng Lu120b61d2019-08-21 12:51:58 -06006905bool ValidateUseProgram(Context *context, ShaderProgramID program)
Jamie Madillbe849e42017-05-02 15:49:00 -04006906{
Jiacheng Lu120b61d2019-08-21 12:51:58 -06006907 if (program.value != 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04006908 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04006909 Program *programObject = context->getProgramResolveLink(program);
Jamie Madillbe849e42017-05-02 15:49:00 -04006910 if (!programObject)
6911 {
6912 // ES 3.1.0 section 7.3 page 72
6913 if (context->getShader(program))
6914 {
Jamie Madille0472f32018-11-27 16:32:45 -05006915 context->validationError(GL_INVALID_OPERATION, kExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006916 return false;
6917 }
6918 else
6919 {
Jamie Madille0472f32018-11-27 16:32:45 -05006920 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006921 return false;
6922 }
6923 }
6924 if (!programObject->isLinked())
6925 {
Jamie Madille0472f32018-11-27 16:32:45 -05006926 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006927 return false;
6928 }
6929 }
Jamie Madillc3dc5d42018-12-30 12:12:04 -05006930 if (context->getState().isTransformFeedbackActiveUnpaused())
Jamie Madillbe849e42017-05-02 15:49:00 -04006931 {
6932 // ES 3.0.4 section 2.15 page 91
Jamie Madillc3e37312018-11-30 15:25:39 -05006933 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackUseProgram);
Jamie Madillbe849e42017-05-02 15:49:00 -04006934 return false;
6935 }
6936
6937 return true;
6938}
6939
Jiacheng Lu962503e2019-08-21 13:18:30 -06006940bool ValidateDeleteFencesNV(Context *context, GLsizei n, const FenceNVID *fences)
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006941{
6942 if (!context->getExtensions().fence)
6943 {
Jamie Madille0472f32018-11-27 16:32:45 -05006944 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006945 return false;
6946 }
6947
6948 if (n < 0)
6949 {
Jamie Madille0472f32018-11-27 16:32:45 -05006950 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006951 return false;
6952 }
6953
6954 return true;
6955}
6956
Jiacheng Lu962503e2019-08-21 13:18:30 -06006957bool ValidateFinishFenceNV(Context *context, FenceNVID fence)
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006958{
6959 if (!context->getExtensions().fence)
6960 {
Jamie Madille0472f32018-11-27 16:32:45 -05006961 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006962 return false;
6963 }
6964
6965 FenceNV *fenceObject = context->getFenceNV(fence);
6966
6967 if (fenceObject == nullptr)
6968 {
Jamie Madille0472f32018-11-27 16:32:45 -05006969 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006970 return false;
6971 }
6972
6973 if (!fenceObject->isSet())
6974 {
Jamie Madille0472f32018-11-27 16:32:45 -05006975 context->validationError(GL_INVALID_OPERATION, kInvalidFenceState);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006976 return false;
6977 }
6978
6979 return true;
6980}
6981
Jiacheng Lu962503e2019-08-21 13:18:30 -06006982bool ValidateGenFencesNV(Context *context, GLsizei n, FenceNVID *fences)
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006983{
6984 if (!context->getExtensions().fence)
6985 {
Jamie Madille0472f32018-11-27 16:32:45 -05006986 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006987 return false;
6988 }
6989
6990 if (n < 0)
6991 {
Jamie Madille0472f32018-11-27 16:32:45 -05006992 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006993 return false;
6994 }
6995
6996 return true;
6997}
6998
Jiacheng Lu962503e2019-08-21 13:18:30 -06006999bool ValidateGetFenceivNV(Context *context, FenceNVID fence, GLenum pname, GLint *params)
Jamie Madill2b7bbc22017-12-21 17:30:38 -05007000{
7001 if (!context->getExtensions().fence)
7002 {
Jamie Madille0472f32018-11-27 16:32:45 -05007003 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05007004 return false;
7005 }
7006
7007 FenceNV *fenceObject = context->getFenceNV(fence);
7008
7009 if (fenceObject == nullptr)
7010 {
Jamie Madille0472f32018-11-27 16:32:45 -05007011 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05007012 return false;
7013 }
7014
7015 if (!fenceObject->isSet())
7016 {
Jamie Madille0472f32018-11-27 16:32:45 -05007017 context->validationError(GL_INVALID_OPERATION, kInvalidFenceState);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05007018 return false;
7019 }
7020
7021 switch (pname)
7022 {
7023 case GL_FENCE_STATUS_NV:
7024 case GL_FENCE_CONDITION_NV:
7025 break;
7026
7027 default:
Jamie Madille0472f32018-11-27 16:32:45 -05007028 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05007029 return false;
7030 }
7031
7032 return true;
7033}
7034
7035bool ValidateGetGraphicsResetStatusEXT(Context *context)
7036{
7037 if (!context->getExtensions().robustness)
7038 {
Jamie Madille0472f32018-11-27 16:32:45 -05007039 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05007040 return false;
7041 }
7042
7043 return true;
7044}
7045
7046bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
Jiacheng Lu120b61d2019-08-21 12:51:58 -06007047 ShaderProgramID shader,
Jamie Madill2b7bbc22017-12-21 17:30:38 -05007048 GLsizei bufsize,
7049 GLsizei *length,
7050 GLchar *source)
7051{
7052 if (!context->getExtensions().translatedShaderSource)
7053 {
Jamie Madille0472f32018-11-27 16:32:45 -05007054 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05007055 return false;
7056 }
7057
7058 if (bufsize < 0)
7059 {
Jamie Madille0472f32018-11-27 16:32:45 -05007060 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05007061 return false;
7062 }
7063
7064 Shader *shaderObject = context->getShader(shader);
7065
7066 if (!shaderObject)
7067 {
Jamie Madille0472f32018-11-27 16:32:45 -05007068 context->validationError(GL_INVALID_OPERATION, kInvalidShaderName);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05007069 return false;
7070 }
7071
7072 return true;
7073}
7074
Jiacheng Lu962503e2019-08-21 13:18:30 -06007075bool ValidateIsFenceNV(Context *context, FenceNVID fence)
Jamie Madill2b7bbc22017-12-21 17:30:38 -05007076{
7077 if (!context->getExtensions().fence)
7078 {
Jamie Madille0472f32018-11-27 16:32:45 -05007079 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05007080 return false;
7081 }
7082
7083 return true;
7084}
7085
Jiacheng Lu962503e2019-08-21 13:18:30 -06007086bool ValidateSetFenceNV(Context *context, FenceNVID fence, GLenum condition)
Jamie Madill007530e2017-12-28 14:27:04 -05007087{
7088 if (!context->getExtensions().fence)
7089 {
Jamie Madille0472f32018-11-27 16:32:45 -05007090 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill007530e2017-12-28 14:27:04 -05007091 return false;
7092 }
7093
7094 if (condition != GL_ALL_COMPLETED_NV)
7095 {
Jamie Madille0472f32018-11-27 16:32:45 -05007096 context->validationError(GL_INVALID_ENUM, kInvalidFenceCondition);
Jamie Madill007530e2017-12-28 14:27:04 -05007097 return false;
7098 }
7099
7100 FenceNV *fenceObject = context->getFenceNV(fence);
7101
7102 if (fenceObject == nullptr)
7103 {
Jamie Madille0472f32018-11-27 16:32:45 -05007104 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill007530e2017-12-28 14:27:04 -05007105 return false;
7106 }
7107
7108 return true;
7109}
7110
Jiacheng Lu962503e2019-08-21 13:18:30 -06007111bool ValidateTestFenceNV(Context *context, FenceNVID fence)
Jamie Madill007530e2017-12-28 14:27:04 -05007112{
7113 if (!context->getExtensions().fence)
7114 {
Jamie Madille0472f32018-11-27 16:32:45 -05007115 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill007530e2017-12-28 14:27:04 -05007116 return false;
7117 }
7118
7119 FenceNV *fenceObject = context->getFenceNV(fence);
7120
7121 if (fenceObject == nullptr)
7122 {
Jamie Madille0472f32018-11-27 16:32:45 -05007123 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill007530e2017-12-28 14:27:04 -05007124 return false;
7125 }
7126
7127 if (fenceObject->isSet() != GL_TRUE)
7128 {
Jamie Madille0472f32018-11-27 16:32:45 -05007129 context->validationError(GL_INVALID_OPERATION, kInvalidFenceState);
Jamie Madill007530e2017-12-28 14:27:04 -05007130 return false;
7131 }
7132
7133 return true;
7134}
7135
7136bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08007137 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05007138 GLsizei levels,
7139 GLenum internalformat,
7140 GLsizei width,
7141 GLsizei height)
7142{
7143 if (!context->getExtensions().textureStorage)
7144 {
Jamie Madille0472f32018-11-27 16:32:45 -05007145 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05007146 return false;
7147 }
7148
7149 if (context->getClientMajorVersion() < 3)
7150 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08007151 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05007152 height);
7153 }
7154
7155 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08007156 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05007157 1);
7158}
7159
7160bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
7161{
Jonah Ryan-Davis2b0553c2019-02-08 10:07:21 -05007162 if (!context->getExtensions().instancedArraysANGLE)
Jamie Madill007530e2017-12-28 14:27:04 -05007163 {
Jamie Madille0472f32018-11-27 16:32:45 -05007164 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05007165 return false;
7166 }
7167
7168 if (index >= MAX_VERTEX_ATTRIBS)
7169 {
Jamie Madille0472f32018-11-27 16:32:45 -05007170 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madill007530e2017-12-28 14:27:04 -05007171 return false;
7172 }
7173
7174 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
7175 {
7176 if (index == 0 && divisor != 0)
7177 {
Jamie Madillc3e37312018-11-30 15:25:39 -05007178 context->validationError(GL_INVALID_OPERATION, kAttributeZeroRequiresDivisorLimitation);
Jamie Madill007530e2017-12-28 14:27:04 -05007179
7180 // We also output an error message to the debugger window if tracing is active, so
7181 // that developers can see the error message.
Jamie Madillc3e37312018-11-30 15:25:39 -05007182 ERR() << kAttributeZeroRequiresDivisorLimitation;
Jamie Madill007530e2017-12-28 14:27:04 -05007183 return false;
7184 }
7185 }
7186
7187 return true;
7188}
7189
Jonah Ryan-Davis2b0553c2019-02-08 10:07:21 -05007190bool ValidateVertexAttribDivisorEXT(Context *context, GLuint index, GLuint divisor)
7191{
7192 if (!context->getExtensions().instancedArraysEXT)
7193 {
7194 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
7195 return false;
7196 }
7197
7198 if (index >= MAX_VERTEX_ATTRIBS)
7199 {
7200 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
7201 return false;
7202 }
7203
7204 return true;
7205}
7206
Jamie Madill007530e2017-12-28 14:27:04 -05007207bool ValidateTexImage3DOES(Context *context,
Cody Northrop5faff912019-06-28 14:04:50 -06007208 TextureTarget target,
Jamie Madill007530e2017-12-28 14:27:04 -05007209 GLint level,
7210 GLenum internalformat,
7211 GLsizei width,
7212 GLsizei height,
7213 GLsizei depth,
7214 GLint border,
7215 GLenum format,
7216 GLenum type,
7217 const void *pixels)
7218{
Cody Northrop5faff912019-06-28 14:04:50 -06007219 return ValidateTexImage3D(context, target, level, internalformat, width, height, depth, border,
7220 format, type, pixels);
Jamie Madill007530e2017-12-28 14:27:04 -05007221}
7222
7223bool ValidatePopGroupMarkerEXT(Context *context)
7224{
7225 if (!context->getExtensions().debugMarker)
7226 {
7227 // The debug marker calls should not set error state
7228 // However, it seems reasonable to set an error state if the extension is not enabled
Jamie Madille0472f32018-11-27 16:32:45 -05007229 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05007230 return false;
7231 }
7232
7233 return true;
7234}
7235
Jamie Madillfa920eb2018-01-04 11:45:50 -05007236bool ValidateTexStorage1DEXT(Context *context,
7237 GLenum target,
7238 GLsizei levels,
7239 GLenum internalformat,
7240 GLsizei width)
7241{
7242 UNIMPLEMENTED();
Jamie Madille0472f32018-11-27 16:32:45 -05007243 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05007244 return false;
7245}
7246
7247bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08007248 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05007249 GLsizei levels,
7250 GLenum internalformat,
7251 GLsizei width,
7252 GLsizei height,
7253 GLsizei depth)
7254{
7255 if (!context->getExtensions().textureStorage)
7256 {
Jamie Madille0472f32018-11-27 16:32:45 -05007257 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05007258 return false;
7259 }
7260
7261 if (context->getClientMajorVersion() < 3)
7262 {
Jamie Madille0472f32018-11-27 16:32:45 -05007263 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05007264 return false;
7265 }
7266
7267 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
7268 depth);
7269}
7270
jchen1082af6202018-06-22 10:59:52 +08007271bool ValidateMaxShaderCompilerThreadsKHR(Context *context, GLuint count)
7272{
7273 if (!context->getExtensions().parallelShaderCompile)
7274 {
Jamie Madille0472f32018-11-27 16:32:45 -05007275 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
jchen1082af6202018-06-22 10:59:52 +08007276 return false;
7277 }
7278 return true;
7279}
7280
Austin Eng1bf18ce2018-10-19 15:34:02 -07007281bool ValidateMultiDrawArraysANGLE(Context *context,
7282 PrimitiveMode mode,
7283 const GLint *firsts,
7284 const GLsizei *counts,
7285 GLsizei drawcount)
7286{
7287 if (!context->getExtensions().multiDraw)
7288 {
Jamie Madille0472f32018-11-27 16:32:45 -05007289 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07007290 return false;
7291 }
7292 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
7293 {
7294 if (!ValidateDrawArrays(context, mode, firsts[drawID], counts[drawID]))
7295 {
7296 return false;
7297 }
7298 }
7299 return true;
7300}
7301
7302bool ValidateMultiDrawElementsANGLE(Context *context,
7303 PrimitiveMode mode,
7304 const GLsizei *counts,
Jamie Madill8dc27f92018-11-29 11:45:44 -05007305 DrawElementsType type,
Austin Eng3b7c9d02018-11-21 18:09:05 -08007306 const GLvoid *const *indices,
Austin Eng1bf18ce2018-10-19 15:34:02 -07007307 GLsizei drawcount)
7308{
7309 if (!context->getExtensions().multiDraw)
7310 {
Jamie Madille0472f32018-11-27 16:32:45 -05007311 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07007312 return false;
7313 }
7314 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
7315 {
Austin Eng3b7c9d02018-11-21 18:09:05 -08007316 if (!ValidateDrawElements(context, mode, counts[drawID], type, indices[drawID]))
Austin Eng1bf18ce2018-10-19 15:34:02 -07007317 {
7318 return false;
7319 }
7320 }
7321 return true;
7322}
7323
Clemen Dengce330592019-07-16 10:02:21 -04007324bool ValidateProvokingVertexANGLE(Context *context, ProvokingVertexConvention modePacked)
Jeff Gilbert465d6092019-01-02 16:21:18 -08007325{
7326 if (!context->getExtensions().provokingVertex)
7327 {
7328 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
7329 return false;
7330 }
7331
7332 switch (modePacked)
7333 {
Clemen Dengce330592019-07-16 10:02:21 -04007334 case ProvokingVertexConvention::FirstVertexConvention:
7335 case ProvokingVertexConvention::LastVertexConvention:
Jeff Gilbert465d6092019-01-02 16:21:18 -08007336 break;
7337 default:
7338 context->validationError(GL_INVALID_ENUM, kInvalidProvokingVertex);
7339 return false;
7340 }
7341
7342 return true;
7343}
7344
Mingyu Hu7e44ec22019-08-26 15:59:48 -07007345bool ValidateFramebufferTexture2DMultisampleEXT(Context *context,
7346 GLenum target,
7347 GLenum attachment,
7348 GLenum textarget,
7349 GLuint texture,
7350 GLint level,
7351 GLsizei samples)
7352{
7353 return true;
7354}
7355
7356bool ValidateRenderbufferStorageMultisampleEXT(Context *context,
7357 GLenum target,
7358 GLsizei samples,
7359 GLenum internalformat,
7360 GLsizei width,
7361 GLsizei height)
7362{
7363 return true;
7364}
7365
Jamie Madilla5410482019-01-31 19:55:55 -05007366void RecordBindTextureTypeError(Context *context, TextureType target)
7367{
7368 ASSERT(!context->getStateCache().isValidBindTextureType(target));
7369
7370 switch (target)
7371 {
7372 case TextureType::Rectangle:
7373 ASSERT(!context->getExtensions().textureRectangle);
7374 context->validationError(GL_INVALID_ENUM, kTextureRectangleNotSupported);
7375 break;
7376
7377 case TextureType::_3D:
7378 case TextureType::_2DArray:
7379 ASSERT(context->getClientMajorVersion() < 3);
7380 context->validationError(GL_INVALID_ENUM, kES3Required);
7381 break;
7382
7383 case TextureType::_2DMultisample:
7384 ASSERT(context->getClientVersion() < Version(3, 1) &&
7385 !context->getExtensions().textureMultisample);
7386 context->validationError(GL_INVALID_ENUM, kMultisampleTextureExtensionOrES31Required);
7387 break;
7388
7389 case TextureType::_2DMultisampleArray:
7390 ASSERT(!context->getExtensions().textureStorageMultisample2DArray);
7391 context->validationError(GL_INVALID_ENUM, kMultisampleArrayExtensionRequired);
7392 break;
7393
7394 case TextureType::External:
7395 ASSERT(!context->getExtensions().eglImageExternal &&
7396 !context->getExtensions().eglStreamConsumerExternal);
7397 context->validationError(GL_INVALID_ENUM, kExternalTextureNotSupported);
7398 break;
7399
7400 default:
7401 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
7402 }
7403}
7404
Jamie Madillc29968b2016-01-20 11:17:23 -05007405} // namespace gl