blob: 234cf84b0cb02d81b076b1b58d3c123a3ea1db21 [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;
730 case GL_DEPTH_COMPONENT:
731 case GL_DEPTH_COMPONENT16:
732 case GL_DEPTH_COMPONENT32_OES:
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -0600733 if (context->getExtensions().depthTextureAny())
Jamie Madillbe849e42017-05-02 15:49:00 -0400734 {
Jamie Madille0472f32018-11-27 16:32:45 -0500735 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400736 return false;
737 }
738 else
739 {
Jamie Madille0472f32018-11-27 16:32:45 -0500740 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400741 return false;
742 }
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -0600743 break;
744 case GL_DEPTH_STENCIL_OES:
745 case GL_DEPTH24_STENCIL8_OES:
746 if (context->getExtensions().depthTextureAny() ||
747 context->getExtensions().packedDepthStencil)
748 {
749 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
750 return false;
751 }
752 else
753 {
754 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
755 return false;
756 }
757 break;
Jamie Madillbe849e42017-05-02 15:49:00 -0400758 default:
Jamie Madille0472f32018-11-27 16:32:45 -0500759 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400760 return false;
761 }
762 }
763
764 // If width or height is zero, it is a no-op. Return false without setting an error.
765 return (width > 0 && height > 0);
766}
767
768bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
769{
770 switch (cap)
771 {
772 // EXT_multisample_compatibility
773 case GL_MULTISAMPLE_EXT:
774 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
775 return context->getExtensions().multisampleCompatibility;
776
777 case GL_CULL_FACE:
778 case GL_POLYGON_OFFSET_FILL:
779 case GL_SAMPLE_ALPHA_TO_COVERAGE:
780 case GL_SAMPLE_COVERAGE:
781 case GL_SCISSOR_TEST:
782 case GL_STENCIL_TEST:
783 case GL_DEPTH_TEST:
784 case GL_BLEND:
785 case GL_DITHER:
786 return true;
787
788 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
789 case GL_RASTERIZER_DISCARD:
790 return (context->getClientMajorVersion() >= 3);
791
792 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
793 case GL_DEBUG_OUTPUT:
794 return context->getExtensions().debug;
795
796 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
797 return queryOnly && context->getExtensions().bindGeneratesResource;
798
799 case GL_CLIENT_ARRAYS_ANGLE:
800 return queryOnly && context->getExtensions().clientArrays;
801
802 case GL_FRAMEBUFFER_SRGB_EXT:
803 return context->getExtensions().sRGBWriteControl;
804
805 case GL_SAMPLE_MASK:
806 return context->getClientVersion() >= Version(3, 1);
807
Geoff Langb433e872017-10-05 14:01:47 -0400808 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
Jamie Madillbe849e42017-05-02 15:49:00 -0400809 return queryOnly && context->getExtensions().robustResourceInitialization;
810
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700811 // GLES1 emulation: GLES1-specific caps
812 case GL_ALPHA_TEST:
Lingfeng Yang01074432018-04-16 10:19:51 -0700813 case GL_VERTEX_ARRAY:
814 case GL_NORMAL_ARRAY:
815 case GL_COLOR_ARRAY:
816 case GL_TEXTURE_COORD_ARRAY:
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700817 case GL_TEXTURE_2D:
Lingfeng Yangd0febe72018-05-17 22:36:52 -0700818 case GL_LIGHTING:
819 case GL_LIGHT0:
820 case GL_LIGHT1:
821 case GL_LIGHT2:
822 case GL_LIGHT3:
823 case GL_LIGHT4:
824 case GL_LIGHT5:
825 case GL_LIGHT6:
826 case GL_LIGHT7:
827 case GL_NORMALIZE:
828 case GL_RESCALE_NORMAL:
829 case GL_COLOR_MATERIAL:
Lingfeng Yang060088a2018-05-30 20:40:57 -0700830 case GL_CLIP_PLANE0:
831 case GL_CLIP_PLANE1:
832 case GL_CLIP_PLANE2:
833 case GL_CLIP_PLANE3:
834 case GL_CLIP_PLANE4:
835 case GL_CLIP_PLANE5:
Lingfeng Yang7ba3f422018-06-01 09:43:04 -0700836 case GL_FOG:
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700837 case GL_POINT_SMOOTH:
Lingfeng Yang6e5bf362018-08-15 09:53:17 -0700838 case GL_LINE_SMOOTH:
839 case GL_COLOR_LOGIC_OP:
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700840 return context->getClientVersion() < Version(2, 0);
Lingfeng Yang01074432018-04-16 10:19:51 -0700841 case GL_POINT_SIZE_ARRAY_OES:
842 return context->getClientVersion() < Version(2, 0) &&
843 context->getExtensions().pointSizeArray;
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700844 case GL_TEXTURE_CUBE_MAP:
845 return context->getClientVersion() < Version(2, 0) &&
846 context->getExtensions().textureCubeMap;
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700847 case GL_POINT_SPRITE_OES:
848 return context->getClientVersion() < Version(2, 0) &&
849 context->getExtensions().pointSprite;
Jamie Madillbe849e42017-05-02 15:49:00 -0400850 default:
851 return false;
852 }
853}
854
Geoff Langfc32e8b2017-05-31 14:16:59 -0400855// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
856// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400857bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400858{
859 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400860 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
861 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400862 {
863 return true;
864 }
865
866 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
867 if (c >= 9 && c <= 13)
868 {
869 return true;
870 }
871
872 return false;
873}
874
Geoff Langcab92ee2017-07-19 17:32:07 -0400875bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400876{
Geoff Langa71a98e2017-06-19 15:15:00 -0400877 for (size_t i = 0; i < len; i++)
878 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400879 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400880 {
881 return false;
882 }
883 }
884
885 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400886}
887
Geoff Langcab92ee2017-07-19 17:32:07 -0400888bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
889{
890 enum class ParseState
891 {
892 // Have not seen an ASCII non-whitespace character yet on
893 // this line. Possible that we might see a preprocessor
894 // directive.
895 BEGINING_OF_LINE,
896
897 // Have seen at least one ASCII non-whitespace character
898 // on this line.
899 MIDDLE_OF_LINE,
900
901 // Handling a preprocessor directive. Passes through all
902 // characters up to the end of the line. Disables comment
903 // processing.
904 IN_PREPROCESSOR_DIRECTIVE,
905
906 // Handling a single-line comment. The comment text is
907 // replaced with a single space.
908 IN_SINGLE_LINE_COMMENT,
909
910 // Handling a multi-line comment. Newlines are passed
911 // through to preserve line numbers.
912 IN_MULTI_LINE_COMMENT
913 };
914
915 ParseState state = ParseState::BEGINING_OF_LINE;
916 size_t pos = 0;
917
918 while (pos < len)
919 {
920 char c = str[pos];
921 char next = pos + 1 < len ? str[pos + 1] : 0;
922
923 // Check for newlines
924 if (c == '\n' || c == '\r')
925 {
926 if (state != ParseState::IN_MULTI_LINE_COMMENT)
927 {
928 state = ParseState::BEGINING_OF_LINE;
929 }
930
931 pos++;
932 continue;
933 }
934
935 switch (state)
936 {
937 case ParseState::BEGINING_OF_LINE:
938 if (c == ' ')
939 {
940 // Maintain the BEGINING_OF_LINE state until a non-space is seen
941 pos++;
942 }
943 else if (c == '#')
944 {
945 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
946 pos++;
947 }
948 else
949 {
950 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
951 state = ParseState::MIDDLE_OF_LINE;
952 }
953 break;
954
955 case ParseState::MIDDLE_OF_LINE:
956 if (c == '/' && next == '/')
957 {
958 state = ParseState::IN_SINGLE_LINE_COMMENT;
959 pos++;
960 }
961 else if (c == '/' && next == '*')
962 {
963 state = ParseState::IN_MULTI_LINE_COMMENT;
964 pos++;
965 }
966 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
967 {
968 // Skip line continuation characters
969 }
970 else if (!IsValidESSLCharacter(c))
971 {
972 return false;
973 }
974 pos++;
975 break;
976
977 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700978 // Line-continuation characters may not be permitted.
979 // Otherwise, just pass it through. Do not parse comments in this state.
980 if (!lineContinuationAllowed && c == '\\')
981 {
982 return false;
983 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400984 pos++;
985 break;
986
987 case ParseState::IN_SINGLE_LINE_COMMENT:
988 // Line-continuation characters are processed before comment processing.
989 // Advance string if a new line character is immediately behind
990 // line-continuation character.
991 if (c == '\\' && (next == '\n' || next == '\r'))
992 {
993 pos++;
994 }
995 pos++;
996 break;
997
998 case ParseState::IN_MULTI_LINE_COMMENT:
999 if (c == '*' && next == '/')
1000 {
1001 state = ParseState::MIDDLE_OF_LINE;
1002 pos++;
1003 }
1004 pos++;
1005 break;
1006 }
1007 }
1008
1009 return true;
1010}
1011
Jamie Madill5b772312018-03-08 20:28:32 -05001012bool ValidateWebGLNamePrefix(Context *context, const GLchar *name)
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001013{
1014 ASSERT(context->isWebGL());
1015
1016 // WebGL 1.0 [Section 6.16] GLSL Constructs
1017 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
1018 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
1019 {
Jamie Madille0472f32018-11-27 16:32:45 -05001020 context->validationError(GL_INVALID_OPERATION, kWebglBindAttribLocationReservedPrefix);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001021 return false;
1022 }
1023
1024 return true;
1025}
1026
Jamie Madill5b772312018-03-08 20:28:32 -05001027bool ValidateWebGLNameLength(Context *context, size_t length)
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001028{
1029 ASSERT(context->isWebGL());
1030
1031 if (context->isWebGL1() && length > 256)
1032 {
1033 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
1034 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
1035 // locations.
Jamie Madille0472f32018-11-27 16:32:45 -05001036 context->validationError(GL_INVALID_VALUE, kWebglNameLengthLimitExceeded);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001037
1038 return false;
1039 }
1040 else if (length > 1024)
1041 {
1042 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
1043 // uniform and attribute locations.
Jamie Madille0472f32018-11-27 16:32:45 -05001044 context->validationError(GL_INVALID_VALUE, kWebgl2NameLengthLimitExceeded);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001045 return false;
1046 }
1047
1048 return true;
1049}
1050
Jamie Madill007530e2017-12-28 14:27:04 -05001051bool ValidateMatrixMode(Context *context, GLenum matrixMode)
1052{
1053 if (!context->getExtensions().pathRendering)
1054 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001055 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05001056 return false;
1057 }
1058
1059 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
1060 {
Jamie Madille0472f32018-11-27 16:32:45 -05001061 context->validationError(GL_INVALID_ENUM, kInvalidMatrixMode);
Jamie Madill007530e2017-12-28 14:27:04 -05001062 return false;
1063 }
1064 return true;
1065}
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03001066
1067bool ValidBlendFunc(const Context *context, GLenum val)
1068{
1069 const gl::Extensions &ext = context->getExtensions();
1070
1071 // these are always valid for src and dst.
1072 switch (val)
1073 {
1074 case GL_ZERO:
1075 case GL_ONE:
1076 case GL_SRC_COLOR:
1077 case GL_ONE_MINUS_SRC_COLOR:
1078 case GL_DST_COLOR:
1079 case GL_ONE_MINUS_DST_COLOR:
1080 case GL_SRC_ALPHA:
1081 case GL_ONE_MINUS_SRC_ALPHA:
1082 case GL_DST_ALPHA:
1083 case GL_ONE_MINUS_DST_ALPHA:
1084 case GL_CONSTANT_COLOR:
1085 case GL_ONE_MINUS_CONSTANT_COLOR:
1086 case GL_CONSTANT_ALPHA:
1087 case GL_ONE_MINUS_CONSTANT_ALPHA:
1088 return true;
1089
1090 // EXT_blend_func_extended.
1091 case GL_SRC1_COLOR_EXT:
1092 case GL_SRC1_ALPHA_EXT:
1093 case GL_ONE_MINUS_SRC1_COLOR_EXT:
1094 case GL_ONE_MINUS_SRC1_ALPHA_EXT:
1095 case GL_SRC_ALPHA_SATURATE_EXT:
1096 return ext.blendFuncExtended;
1097
1098 default:
1099 return false;
1100 }
1101}
1102
1103bool ValidSrcBlendFunc(const Context *context, GLenum val)
1104{
1105 if (ValidBlendFunc(context, val))
1106 return true;
1107
1108 if (val == GL_SRC_ALPHA_SATURATE)
1109 return true;
1110
1111 return false;
1112}
1113
1114bool ValidDstBlendFunc(const Context *context, GLenum val)
1115{
1116 if (ValidBlendFunc(context, val))
1117 return true;
1118
1119 if (val == GL_SRC_ALPHA_SATURATE)
1120 {
1121 if (context->getClientMajorVersion() >= 3)
1122 return true;
1123 }
1124
1125 return false;
1126}
Michael Spangab6a59b2019-05-21 21:26:26 -04001127
1128bool IsValidImageLayout(ImageLayout layout)
1129{
1130 switch (layout)
1131 {
Michael Spang6c824a12019-06-18 15:43:33 -04001132 case ImageLayout::Undefined:
Michael Spangab6a59b2019-05-21 21:26:26 -04001133 case ImageLayout::General:
1134 case ImageLayout::ColorAttachment:
1135 case ImageLayout::DepthStencilAttachment:
1136 case ImageLayout::DepthStencilReadOnlyAttachment:
1137 case ImageLayout::ShaderReadOnly:
1138 case ImageLayout::TransferSrc:
1139 case ImageLayout::TransferDst:
1140 case ImageLayout::DepthReadOnlyStencilAttachment:
1141 case ImageLayout::DepthAttachmentStencilReadOnly:
1142 return true;
1143
1144 default:
1145 return false;
1146 }
1147}
1148
Geoff Langff5b2d52016-09-07 11:32:23 -04001149bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001150 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001151 GLint level,
1152 GLenum internalformat,
1153 bool isCompressed,
1154 bool isSubImage,
1155 GLint xoffset,
1156 GLint yoffset,
1157 GLsizei width,
1158 GLsizei height,
1159 GLint border,
1160 GLenum format,
1161 GLenum type,
1162 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001163 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001164{
Jamie Madill6f38f822014-06-06 17:12:20 -04001165 if (!ValidTexture2DDestinationTarget(context, target))
1166 {
Jamie Madille0472f32018-11-27 16:32:45 -05001167 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001168 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001169 }
1170
Geoff Lang857880e2019-05-27 13:39:15 -04001171 return ValidateES2TexImageParametersBase(context, target, level, internalformat, isCompressed,
1172 isSubImage, xoffset, yoffset, width, height, border,
1173 format, type, imageSize, pixels);
1174}
1175
1176} // anonymous namespace
1177
1178bool ValidateES2TexImageParametersBase(Context *context,
1179 TextureTarget target,
1180 GLint level,
1181 GLenum internalformat,
1182 bool isCompressed,
1183 bool isSubImage,
1184 GLint xoffset,
1185 GLint yoffset,
1186 GLsizei width,
1187 GLsizei height,
1188 GLint border,
1189 GLenum format,
1190 GLenum type,
1191 GLsizei imageSize,
1192 const void *pixels)
1193{
1194
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001195 TextureType texType = TextureTargetToType(target);
1196 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001197 {
Jamie Madill610640f2018-11-21 17:28:41 -05001198 // Error already handled.
Geoff Langb1196682014-07-23 13:47:29 -04001199 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001200 }
1201
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001202 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001203 {
Jamie Madille0472f32018-11-27 16:32:45 -05001204 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Brandon Jones6cad5662017-06-14 13:25:13 -07001205 return false;
1206 }
1207
1208 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001209 std::numeric_limits<GLsizei>::max() - yoffset < height)
1210 {
Jamie Madille0472f32018-11-27 16:32:45 -05001211 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001212 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001213 }
1214
Geoff Langaae65a42014-05-26 12:43:44 -04001215 const gl::Caps &caps = context->getCaps();
1216
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001217 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001218 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001219 case TextureType::_2D:
Geoff Lang857880e2019-05-27 13:39:15 -04001220 case TextureType::External:
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001221 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1222 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1223 {
Jamie Madille0472f32018-11-27 16:32:45 -05001224 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001225 return false;
1226 }
1227 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001228
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001229 case TextureType::Rectangle:
1230 ASSERT(level == 0);
1231 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1232 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1233 {
Jamie Madille0472f32018-11-27 16:32:45 -05001234 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001235 return false;
1236 }
1237 if (isCompressed)
1238 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001239 context->validationError(GL_INVALID_ENUM, kRectangleTextureCompressed);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001240 return false;
1241 }
1242 break;
1243
1244 case TextureType::CubeMap:
1245 if (!isSubImage && width != height)
1246 {
Jamie Madille0472f32018-11-27 16:32:45 -05001247 context->validationError(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001248 return false;
1249 }
1250
1251 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1252 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> 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;
1258
1259 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001260 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001261 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001262 }
1263
Jamie Madillcfc73cc2019-04-08 16:26:51 -04001264 gl::Texture *texture = context->getTextureByType(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001265 if (!texture)
1266 {
Jamie Madille0472f32018-11-27 16:32:45 -05001267 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001268 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001269 }
1270
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001271 // Verify zero border
1272 if (border != 0)
1273 {
Jamie Madille0472f32018-11-27 16:32:45 -05001274 context->validationError(GL_INVALID_VALUE, kInvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001275 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001276 }
1277
Tim Van Patten208af3e2019-03-19 09:15:55 -06001278 bool nonEqualFormatsAllowed = false;
1279
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001280 if (isCompressed)
1281 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001282 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001283 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1284 : internalformat;
Geoff Lange88e4542018-05-03 15:05:57 -04001285
1286 const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(actualInternalFormat);
1287
1288 if (!internalFormatInfo.compressed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001289 {
Jamie Madille0472f32018-11-27 16:32:45 -05001290 context->validationError(GL_INVALID_ENUM, kInvalidInternalFormat);
Geoff Lange88e4542018-05-03 15:05:57 -04001291 return false;
1292 }
1293
1294 if (!internalFormatInfo.textureSupport(context->getClientVersion(),
1295 context->getExtensions()))
1296 {
Jamie Madille0472f32018-11-27 16:32:45 -05001297 context->validationError(GL_INVALID_ENUM, kInvalidInternalFormat);
Geoff Lange88e4542018-05-03 15:05:57 -04001298 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001299 }
Geoff Lang966c9402017-04-18 12:38:27 -04001300
1301 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001302 {
Geoff Lange88e4542018-05-03 15:05:57 -04001303 // From the OES_compressed_ETC1_RGB8_texture spec:
1304 // INVALID_OPERATION is generated by CompressedTexSubImage2D, TexSubImage2D, or
1305 // CopyTexSubImage2D if the texture image <level> bound to <target> has internal format
1306 // ETC1_RGB8_OES.
1307 if (actualInternalFormat == GL_ETC1_RGB8_OES)
1308 {
Jamie Madille0472f32018-11-27 16:32:45 -05001309 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lange88e4542018-05-03 15:05:57 -04001310 return false;
1311 }
1312
Geoff Langd9c17102019-07-10 14:56:26 -04001313 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, 0,
1314 width, height, 1, texture->getWidth(target, level),
1315 texture->getHeight(target, level),
1316 texture->getDepth(target, level)))
Geoff Lang966c9402017-04-18 12:38:27 -04001317 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001318 context->validationError(GL_INVALID_OPERATION, kInvalidCompressedImageSize);
Geoff Lang966c9402017-04-18 12:38:27 -04001319 return false;
1320 }
1321
1322 if (format != actualInternalFormat)
1323 {
Jamie Madille0472f32018-11-27 16:32:45 -05001324 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001325 return false;
1326 }
1327 }
1328 else
1329 {
Geoff Langd9c17102019-07-10 14:56:26 -04001330 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height, 1))
Geoff Lang966c9402017-04-18 12:38:27 -04001331 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001332 context->validationError(GL_INVALID_OPERATION, kInvalidCompressedImageSize);
Geoff Lang966c9402017-04-18 12:38:27 -04001333 return false;
1334 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001335 }
1336 }
1337 else
1338 {
1339 // validate <type> by itself (used as secondary key below)
1340 switch (type)
1341 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001342 case GL_UNSIGNED_BYTE:
1343 case GL_UNSIGNED_SHORT_5_6_5:
1344 case GL_UNSIGNED_SHORT_4_4_4_4:
1345 case GL_UNSIGNED_SHORT_5_5_5_1:
1346 case GL_UNSIGNED_SHORT:
1347 case GL_UNSIGNED_INT:
1348 case GL_UNSIGNED_INT_24_8_OES:
1349 case GL_HALF_FLOAT_OES:
1350 case GL_FLOAT:
1351 break;
Jaedon Lee3b468852019-07-30 16:50:36 +09001352 case GL_UNSIGNED_INT_2_10_10_10_REV_EXT:
1353 if (!context->getExtensions().textureFormat2101010REV)
1354 {
1355 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
1356 return false;
1357 }
1358 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001359 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001360 context->validationError(GL_INVALID_ENUM, kInvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001361 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001362 }
1363
1364 // validate <format> + <type> combinations
1365 // - invalid <format> -> sets INVALID_ENUM
1366 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1367 switch (format)
1368 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001369 case GL_ALPHA:
1370 case GL_LUMINANCE:
1371 case GL_LUMINANCE_ALPHA:
1372 switch (type)
1373 {
1374 case GL_UNSIGNED_BYTE:
1375 case GL_FLOAT:
1376 case GL_HALF_FLOAT_OES:
1377 break;
1378 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001379 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001380 return false;
1381 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001382 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001383 case GL_RED:
1384 case GL_RG:
1385 if (!context->getExtensions().textureRG)
1386 {
Jamie Madille0472f32018-11-27 16:32:45 -05001387 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001388 return false;
1389 }
1390 switch (type)
1391 {
1392 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001393 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001394 case GL_FLOAT:
1395 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001396 if (!context->getExtensions().textureFloat)
1397 {
Jamie Madille0472f32018-11-27 16:32:45 -05001398 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001399 return false;
1400 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001401 break;
1402 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001403 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001404 return false;
1405 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001406 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001407 case GL_RGB:
1408 switch (type)
1409 {
1410 case GL_UNSIGNED_BYTE:
1411 case GL_UNSIGNED_SHORT_5_6_5:
Jaedon Lee3b468852019-07-30 16:50:36 +09001412 case GL_UNSIGNED_INT_2_10_10_10_REV_EXT:
He Yunchaoced53ae2016-11-29 15:00:51 +08001413 case GL_FLOAT:
1414 case GL_HALF_FLOAT_OES:
1415 break;
1416 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001417 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001418 return false;
1419 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001420 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001421 case GL_RGBA:
1422 switch (type)
1423 {
1424 case GL_UNSIGNED_BYTE:
1425 case GL_UNSIGNED_SHORT_4_4_4_4:
1426 case GL_UNSIGNED_SHORT_5_5_5_1:
1427 case GL_FLOAT:
1428 case GL_HALF_FLOAT_OES:
Jaedon Lee3b468852019-07-30 16:50:36 +09001429 case GL_UNSIGNED_INT_2_10_10_10_REV_EXT:
He Yunchaoced53ae2016-11-29 15:00:51 +08001430 break;
1431 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001432 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001433 return false;
1434 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001435 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001436 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001437 if (!context->getExtensions().textureFormatBGRA8888)
1438 {
Jamie Madille0472f32018-11-27 16:32:45 -05001439 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001440 return false;
1441 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001442 switch (type)
1443 {
1444 case GL_UNSIGNED_BYTE:
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 }
1450 break;
1451 case GL_SRGB_EXT:
1452 case GL_SRGB_ALPHA_EXT:
1453 if (!context->getExtensions().sRGB)
1454 {
Jamie Madille0472f32018-11-27 16:32:45 -05001455 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001456 return false;
1457 }
1458 switch (type)
1459 {
1460 case GL_UNSIGNED_BYTE:
1461 break;
1462 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001463 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001464 return false;
1465 }
1466 break;
1467 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1468 // handled below
1469 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1470 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1471 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1472 break;
1473 case GL_DEPTH_COMPONENT:
1474 switch (type)
1475 {
1476 case GL_UNSIGNED_SHORT:
1477 case GL_UNSIGNED_INT:
1478 break;
1479 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001480 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001481 return false;
1482 }
1483 break;
1484 case GL_DEPTH_STENCIL_OES:
1485 switch (type)
1486 {
1487 case GL_UNSIGNED_INT_24_8_OES:
1488 break;
1489 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001490 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001491 return false;
1492 }
1493 break;
1494 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001495 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001496 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001497 }
1498
1499 switch (format)
1500 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001501 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1502 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1503 if (context->getExtensions().textureCompressionDXT1)
1504 {
Jamie Madille0472f32018-11-27 16:32:45 -05001505 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001506 return false;
1507 }
1508 else
1509 {
Jamie Madille0472f32018-11-27 16:32:45 -05001510 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001511 return false;
1512 }
1513 break;
1514 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1515 if (context->getExtensions().textureCompressionDXT3)
1516 {
Jamie Madille0472f32018-11-27 16:32:45 -05001517 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001518 return false;
1519 }
1520 else
1521 {
Jamie Madille0472f32018-11-27 16:32:45 -05001522 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001523 return false;
1524 }
1525 break;
1526 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1527 if (context->getExtensions().textureCompressionDXT5)
1528 {
Jamie Madille0472f32018-11-27 16:32:45 -05001529 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001530 return false;
1531 }
1532 else
1533 {
Jamie Madille0472f32018-11-27 16:32:45 -05001534 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001535 return false;
1536 }
1537 break;
1538 case GL_ETC1_RGB8_OES:
1539 if (context->getExtensions().compressedETC1RGB8Texture)
1540 {
Jamie Madille0472f32018-11-27 16:32:45 -05001541 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001542 return false;
1543 }
1544 else
1545 {
Jamie Madille0472f32018-11-27 16:32:45 -05001546 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001547 return false;
1548 }
1549 break;
1550 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001551 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1552 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1553 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1554 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001555 if (context->getExtensions().lossyETCDecode)
1556 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001557 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001558 return false;
1559 }
1560 else
1561 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001562 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001563 return false;
1564 }
1565 break;
1566 case GL_DEPTH_COMPONENT:
1567 case GL_DEPTH_STENCIL_OES:
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001568 if (!context->getExtensions().depthTextureANGLE &&
1569 !(context->getExtensions().packedDepthStencil &&
1570 context->getExtensions().depthTextureOES))
He Yunchaoced53ae2016-11-29 15:00:51 +08001571 {
Jamie Madille0472f32018-11-27 16:32:45 -05001572 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001573 return false;
1574 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001575 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001576 {
Jamie Madille0472f32018-11-27 16:32:45 -05001577 context->validationError(GL_INVALID_OPERATION, kMismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001578 return false;
1579 }
1580 // OES_depth_texture supports loading depth data and multiple levels,
1581 // but ANGLE_depth_texture does not
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001582 if (!context->getExtensions().depthTextureOES)
He Yunchaoced53ae2016-11-29 15:00:51 +08001583 {
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001584 if (pixels != nullptr)
1585 {
1586 context->validationError(GL_INVALID_OPERATION, kPixelDataNotNull);
1587 return false;
1588 }
1589 if (level != 0)
1590 {
1591 context->validationError(GL_INVALID_OPERATION, kLevelNotZero);
1592 return false;
1593 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001594 }
1595 break;
1596 default:
1597 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001598 }
1599
Geoff Lang6e898aa2017-06-02 11:17:26 -04001600 if (!isSubImage)
1601 {
1602 switch (internalformat)
1603 {
Tim Van Patten208af3e2019-03-19 09:15:55 -06001604 // Core ES 2.0 formats
1605 case GL_ALPHA:
1606 case GL_LUMINANCE:
1607 case GL_LUMINANCE_ALPHA:
1608 case GL_RGB:
1609 case GL_RGBA:
1610 break;
1611
Geoff Lang6e898aa2017-06-02 11:17:26 -04001612 case GL_RGBA32F:
1613 if (!context->getExtensions().colorBufferFloatRGBA)
1614 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001615 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001616 return false;
1617 }
Tim Van Patten208af3e2019-03-19 09:15:55 -06001618
1619 nonEqualFormatsAllowed = true;
1620
Geoff Lang6e898aa2017-06-02 11:17:26 -04001621 if (type != GL_FLOAT)
1622 {
Jamie Madille0472f32018-11-27 16:32:45 -05001623 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001624 return false;
1625 }
1626 if (format != GL_RGBA)
1627 {
Jamie Madille0472f32018-11-27 16:32:45 -05001628 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001629 return false;
1630 }
1631 break;
1632
1633 case GL_RGB32F:
1634 if (!context->getExtensions().colorBufferFloatRGB)
1635 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001636 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001637 return false;
1638 }
Tim Van Patten208af3e2019-03-19 09:15:55 -06001639
1640 nonEqualFormatsAllowed = true;
1641
Geoff Lang6e898aa2017-06-02 11:17:26 -04001642 if (type != GL_FLOAT)
1643 {
Jamie Madille0472f32018-11-27 16:32:45 -05001644 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001645 return false;
1646 }
1647 if (format != GL_RGB)
1648 {
Jamie Madille0472f32018-11-27 16:32:45 -05001649 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001650 return false;
1651 }
1652 break;
1653
Tim Van Patten208af3e2019-03-19 09:15:55 -06001654 case GL_BGRA_EXT:
1655 if (!context->getExtensions().textureFormatBGRA8888)
1656 {
1657 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
1658 return false;
1659 }
Geoff Lang6e898aa2017-06-02 11:17:26 -04001660 break;
Tim Van Patten208af3e2019-03-19 09:15:55 -06001661
1662 case GL_DEPTH_COMPONENT:
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001663 if (!(context->getExtensions().depthTextureAny()))
1664 {
1665 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
1666 return false;
1667 }
1668 break;
1669
Tim Van Patten208af3e2019-03-19 09:15:55 -06001670 case GL_DEPTH_STENCIL:
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001671 if (!(context->getExtensions().depthTextureANGLE ||
1672 context->getExtensions().packedDepthStencil))
Tim Van Patten208af3e2019-03-19 09:15:55 -06001673 {
1674 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
1675 return false;
1676 }
1677 break;
1678
1679 case GL_RED:
1680 case GL_RG:
1681 if (!context->getExtensions().textureRG)
1682 {
1683 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
1684 return false;
1685 }
1686 break;
1687
1688 case GL_SRGB_EXT:
1689 case GL_SRGB_ALPHA_EXT:
1690 if (!context->getExtensions().sRGB)
1691 {
1692 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
1693 return false;
1694 }
1695 break;
1696
Jaedon Lee3b468852019-07-30 16:50:36 +09001697 case GL_RGB10_A2_EXT:
1698 if (!context->getExtensions().textureFormat2101010REV)
1699 {
1700 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
1701 return false;
1702 }
1703
1704 if (type != GL_UNSIGNED_INT_2_10_10_10_REV_EXT || format != GL_RGBA)
1705 {
1706 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
1707 return false;
1708 }
1709
1710 nonEqualFormatsAllowed = true;
1711
1712 break;
1713
1714 case GL_RGB5_A1:
1715 if (context->getExtensions().textureFormat2101010REV &&
1716 type == GL_UNSIGNED_INT_2_10_10_10_REV_EXT && format == GL_RGBA)
1717 {
1718 nonEqualFormatsAllowed = true;
1719 }
1720
1721 break;
1722
Tim Van Patten208af3e2019-03-19 09:15:55 -06001723 default:
1724 context->validationError(GL_INVALID_VALUE, kInvalidInternalFormat);
1725 return false;
Geoff Lang6e898aa2017-06-02 11:17:26 -04001726 }
1727 }
1728
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001729 if (type == GL_FLOAT)
1730 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001731 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001732 {
Jamie Madille0472f32018-11-27 16:32:45 -05001733 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001734 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001735 }
1736 }
1737 else if (type == GL_HALF_FLOAT_OES)
1738 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001739 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001740 {
Jamie Madille0472f32018-11-27 16:32:45 -05001741 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001742 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001743 }
1744 }
1745 }
1746
Tim Van Patten208af3e2019-03-19 09:15:55 -06001747 if (isSubImage)
Geoff Langff5b2d52016-09-07 11:32:23 -04001748 {
Tim Van Patten208af3e2019-03-19 09:15:55 -06001749 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1750 if (textureInternalFormat.internalFormat == GL_NONE)
1751 {
1752 context->validationError(GL_INVALID_OPERATION, kInvalidTextureLevel);
1753 return false;
1754 }
1755
Tim Van Patten5f388c22019-03-14 09:54:23 -06001756 if (format != textureInternalFormat.format)
1757 {
1758 context->validationError(GL_INVALID_OPERATION, err::kTextureFormatMismatch);
1759 return false;
1760 }
1761
1762 if (context->getExtensions().webglCompatibility)
Tim Van Patten208af3e2019-03-19 09:15:55 -06001763 {
1764 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1765 textureInternalFormat.sizedInternalFormat)
1766 {
Tim Van Patten5f388c22019-03-14 09:54:23 -06001767 context->validationError(GL_INVALID_OPERATION, kTextureTypeMismatch);
Tim Van Patten208af3e2019-03-19 09:15:55 -06001768 return false;
1769 }
1770 }
1771
1772 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1773 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1774 {
1775 context->validationError(GL_INVALID_VALUE, kOffsetOverflow);
1776 return false;
1777 }
1778
1779 if (width > 0 && height > 0 && pixels == nullptr &&
1780 context->getState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
1781 {
1782 context->validationError(GL_INVALID_VALUE, kPixelDataNull);
1783 return false;
1784 }
1785 }
1786 else
1787 {
1788 if (texture->getImmutableFormat())
1789 {
1790 context->validationError(GL_INVALID_OPERATION, kTextureIsImmutable);
1791 return false;
1792 }
1793 }
1794
1795 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1796 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1797 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1798 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1799 // case.
1800 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
1801 {
1802 context->validationError(GL_INVALID_OPERATION, kInvalidFormatCombination);
Geoff Langff5b2d52016-09-07 11:32:23 -04001803 return false;
1804 }
1805
Tim Van Patten208af3e2019-03-19 09:15:55 -06001806 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
1807 return ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
1808 imageSize);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001809}
1810
He Yunchaoced53ae2016-11-29 15:00:51 +08001811bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001812 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001813 GLsizei levels,
1814 GLenum internalformat,
1815 GLsizei width,
1816 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001817{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001818 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1819 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001820 {
Jamie Madille0472f32018-11-27 16:32:45 -05001821 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001822 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001823 }
1824
1825 if (width < 1 || height < 1 || levels < 1)
1826 {
Jamie Madille0472f32018-11-27 16:32:45 -05001827 context->validationError(GL_INVALID_VALUE, kTextureSizeTooSmall);
Geoff Langb1196682014-07-23 13:47:29 -04001828 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001829 }
1830
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001831 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001832 {
Jamie Madille0472f32018-11-27 16:32:45 -05001833 context->validationError(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
Geoff Langb1196682014-07-23 13:47:29 -04001834 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001835 }
1836
1837 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1838 {
Jamie Madille0472f32018-11-27 16:32:45 -05001839 context->validationError(GL_INVALID_OPERATION, kInvalidMipLevels);
Geoff Langb1196682014-07-23 13:47:29 -04001840 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001841 }
1842
Geoff Langca271392017-04-05 12:30:00 -04001843 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001844 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001845 {
Jamie Madille0472f32018-11-27 16:32:45 -05001846 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001847 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001848 }
1849
Geoff Langaae65a42014-05-26 12:43:44 -04001850 const gl::Caps &caps = context->getCaps();
1851
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001852 switch (target)
1853 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001854 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001855 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1856 static_cast<GLuint>(height) > caps.max2DTextureSize)
1857 {
Jamie Madille0472f32018-11-27 16:32:45 -05001858 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
He Yunchaoced53ae2016-11-29 15:00:51 +08001859 return false;
1860 }
1861 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001862 case TextureType::Rectangle:
Jamie Madill610640f2018-11-21 17:28:41 -05001863 if (levels != 1)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001864 {
Jamie Madille0472f32018-11-27 16:32:45 -05001865 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madill610640f2018-11-21 17:28:41 -05001866 return false;
1867 }
1868
1869 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1870 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1871 {
Jamie Madille0472f32018-11-27 16:32:45 -05001872 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001873 return false;
1874 }
1875 if (formatInfo.compressed)
1876 {
Jamie Madille0472f32018-11-27 16:32:45 -05001877 context->validationError(GL_INVALID_ENUM, kRectangleTextureCompressed);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001878 return false;
1879 }
1880 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001881 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001882 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1883 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1884 {
Jamie Madille0472f32018-11-27 16:32:45 -05001885 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
He Yunchaoced53ae2016-11-29 15:00:51 +08001886 return false;
1887 }
1888 break;
1889 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001890 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001891 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001892 }
1893
Geoff Langc0b9ef42014-07-02 10:02:37 -04001894 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001895 {
1896 if (!gl::isPow2(width) || !gl::isPow2(height))
1897 {
Jamie Madille0472f32018-11-27 16:32:45 -05001898 context->validationError(GL_INVALID_OPERATION, kDimensionsMustBePow2);
Geoff Langb1196682014-07-23 13:47:29 -04001899 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001900 }
1901 }
1902
1903 switch (internalformat)
1904 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001905 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1906 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1907 if (!context->getExtensions().textureCompressionDXT1)
1908 {
Jamie Madille0472f32018-11-27 16:32:45 -05001909 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001910 return false;
1911 }
1912 break;
1913 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1914 if (!context->getExtensions().textureCompressionDXT3)
1915 {
Jamie Madille0472f32018-11-27 16:32:45 -05001916 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001917 return false;
1918 }
1919 break;
1920 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1921 if (!context->getExtensions().textureCompressionDXT5)
1922 {
Jamie Madille0472f32018-11-27 16:32:45 -05001923 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001924 return false;
1925 }
1926 break;
1927 case GL_ETC1_RGB8_OES:
1928 if (!context->getExtensions().compressedETC1RGB8Texture)
1929 {
Jamie Madille0472f32018-11-27 16:32:45 -05001930 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001931 return false;
1932 }
1933 break;
1934 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001935 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1936 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1937 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1938 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001939 if (!context->getExtensions().lossyETCDecode)
1940 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001941 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001942 return false;
1943 }
1944 break;
1945 case GL_RGBA32F_EXT:
1946 case GL_RGB32F_EXT:
1947 case GL_ALPHA32F_EXT:
1948 case GL_LUMINANCE32F_EXT:
1949 case GL_LUMINANCE_ALPHA32F_EXT:
1950 if (!context->getExtensions().textureFloat)
1951 {
Jamie Madille0472f32018-11-27 16:32:45 -05001952 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001953 return false;
1954 }
1955 break;
1956 case GL_RGBA16F_EXT:
1957 case GL_RGB16F_EXT:
1958 case GL_ALPHA16F_EXT:
1959 case GL_LUMINANCE16F_EXT:
1960 case GL_LUMINANCE_ALPHA16F_EXT:
1961 if (!context->getExtensions().textureHalfFloat)
1962 {
Jamie Madille0472f32018-11-27 16:32:45 -05001963 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001964 return false;
1965 }
1966 break;
1967 case GL_R8_EXT:
1968 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001969 if (!context->getExtensions().textureRG)
1970 {
Jamie Madille0472f32018-11-27 16:32:45 -05001971 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang677bb6f2017-04-05 12:40:40 -04001972 return false;
1973 }
1974 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001975 case GL_R16F_EXT:
1976 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001977 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1978 {
Jamie Madille0472f32018-11-27 16:32:45 -05001979 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang677bb6f2017-04-05 12:40:40 -04001980 return false;
1981 }
1982 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001983 case GL_R32F_EXT:
1984 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001985 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001986 {
Jamie Madille0472f32018-11-27 16:32:45 -05001987 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001988 return false;
1989 }
1990 break;
1991 case GL_DEPTH_COMPONENT16:
1992 case GL_DEPTH_COMPONENT32_OES:
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001993 if (!(context->getExtensions().depthTextureAny()))
He Yunchaoced53ae2016-11-29 15:00:51 +08001994 {
Jamie Madille0472f32018-11-27 16:32:45 -05001995 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001996 return false;
1997 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001998 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001999 {
Jamie Madille0472f32018-11-27 16:32:45 -05002000 context->validationError(GL_INVALID_OPERATION, kInvalidTextureTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08002001 return false;
2002 }
2003 // ANGLE_depth_texture only supports 1-level textures
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06002004 if (!context->getExtensions().depthTextureOES)
He Yunchaoced53ae2016-11-29 15:00:51 +08002005 {
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06002006 if (levels != 1)
2007 {
2008 context->validationError(GL_INVALID_OPERATION, kInvalidMipLevels);
2009 return false;
2010 }
He Yunchaoced53ae2016-11-29 15:00:51 +08002011 }
2012 break;
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06002013 case GL_DEPTH24_STENCIL8_OES:
2014 if (!(context->getExtensions().depthTextureANGLE ||
2015 (context->getExtensions().packedDepthStencil &&
2016 context->getExtensions().textureStorage)))
2017 {
2018 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
2019 return false;
2020 }
2021 if (target != TextureType::_2D)
2022 {
2023 context->validationError(GL_INVALID_OPERATION, kInvalidTextureTarget);
2024 return false;
2025 }
2026 if (!context->getExtensions().packedDepthStencil)
2027 {
2028 // ANGLE_depth_texture only supports 1-level textures
2029 if (levels != 1)
2030 {
2031 context->validationError(GL_INVALID_OPERATION, kInvalidMipLevels);
2032 return false;
2033 }
2034 }
2035 break;
2036
He Yunchaoced53ae2016-11-29 15:00:51 +08002037 default:
2038 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002039 }
2040
Jamie Madillcfc73cc2019-04-08 16:26:51 -04002041 gl::Texture *texture = context->getTextureByType(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002042 if (!texture || texture->id() == 0)
2043 {
Jamie Madille0472f32018-11-27 16:32:45 -05002044 context->validationError(GL_INVALID_OPERATION, kMissingTexture);
Geoff Langb1196682014-07-23 13:47:29 -04002045 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002046 }
2047
Geoff Lang69cce582015-09-17 13:20:36 -04002048 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002049 {
Jamie Madille0472f32018-11-27 16:32:45 -05002050 context->validationError(GL_INVALID_OPERATION, kTextureIsImmutable);
Geoff Langb1196682014-07-23 13:47:29 -04002051 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002052 }
2053
2054 return true;
2055}
2056
He Yunchaoced53ae2016-11-29 15:00:51 +08002057bool ValidateDiscardFramebufferEXT(Context *context,
2058 GLenum target,
2059 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07002060 const GLenum *attachments)
2061{
Jamie Madillc29968b2016-01-20 11:17:23 -05002062 if (!context->getExtensions().discardFramebuffer)
2063 {
Jamie Madille0472f32018-11-27 16:32:45 -05002064 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05002065 return false;
2066 }
2067
Austin Kinross08332632015-05-05 13:35:47 -07002068 bool defaultFramebuffer = false;
2069
2070 switch (target)
2071 {
He Yunchaoced53ae2016-11-29 15:00:51 +08002072 case GL_FRAMEBUFFER:
2073 defaultFramebuffer =
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002074 (context->getState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
He Yunchaoced53ae2016-11-29 15:00:51 +08002075 break;
2076 default:
Jamie Madille0472f32018-11-27 16:32:45 -05002077 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08002078 return false;
Austin Kinross08332632015-05-05 13:35:47 -07002079 }
2080
He Yunchaoced53ae2016-11-29 15:00:51 +08002081 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
2082 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07002083}
2084
Austin Kinrossbc781f32015-10-26 09:27:38 -07002085bool ValidateBindVertexArrayOES(Context *context, GLuint array)
2086{
2087 if (!context->getExtensions().vertexArrayObject)
2088 {
Jamie Madille0472f32018-11-27 16:32:45 -05002089 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07002090 return false;
2091 }
2092
2093 return ValidateBindVertexArrayBase(context, array);
2094}
2095
Jamie Madilld7576732017-08-26 18:49:50 -04002096bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07002097{
2098 if (!context->getExtensions().vertexArrayObject)
2099 {
Jamie Madille0472f32018-11-27 16:32:45 -05002100 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07002101 return false;
2102 }
2103
Olli Etuaho41997e72016-03-10 13:38:39 +02002104 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07002105}
2106
Jamie Madilld7576732017-08-26 18:49:50 -04002107bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07002108{
2109 if (!context->getExtensions().vertexArrayObject)
2110 {
Jamie Madille0472f32018-11-27 16:32:45 -05002111 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07002112 return false;
2113 }
2114
Olli Etuaho41997e72016-03-10 13:38:39 +02002115 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07002116}
2117
Jamie Madilld7576732017-08-26 18:49:50 -04002118bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07002119{
2120 if (!context->getExtensions().vertexArrayObject)
2121 {
Jamie Madille0472f32018-11-27 16:32:45 -05002122 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07002123 return false;
2124 }
2125
2126 return true;
2127}
Geoff Langc5629752015-12-07 16:29:04 -05002128
2129bool ValidateProgramBinaryOES(Context *context,
Jiacheng Lu120b61d2019-08-21 12:51:58 -06002130 ShaderProgramID program,
Geoff Langc5629752015-12-07 16:29:04 -05002131 GLenum binaryFormat,
2132 const void *binary,
2133 GLint length)
2134{
2135 if (!context->getExtensions().getProgramBinary)
2136 {
Jamie Madille0472f32018-11-27 16:32:45 -05002137 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05002138 return false;
2139 }
2140
2141 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
2142}
2143
2144bool ValidateGetProgramBinaryOES(Context *context,
Jiacheng Lu120b61d2019-08-21 12:51:58 -06002145 ShaderProgramID program,
Geoff Langc5629752015-12-07 16:29:04 -05002146 GLsizei bufSize,
2147 GLsizei *length,
2148 GLenum *binaryFormat,
2149 void *binary)
2150{
2151 if (!context->getExtensions().getProgramBinary)
2152 {
Jamie Madille0472f32018-11-27 16:32:45 -05002153 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05002154 return false;
2155 }
2156
2157 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
2158}
Geoff Lange102fee2015-12-10 11:23:30 -05002159
Geoff Lang70d0f492015-12-10 17:45:46 -05002160static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
2161{
2162 switch (source)
2163 {
2164 case GL_DEBUG_SOURCE_API:
2165 case GL_DEBUG_SOURCE_SHADER_COMPILER:
2166 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
2167 case GL_DEBUG_SOURCE_OTHER:
2168 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
2169 return !mustBeThirdPartyOrApplication;
2170
2171 case GL_DEBUG_SOURCE_THIRD_PARTY:
2172 case GL_DEBUG_SOURCE_APPLICATION:
2173 return true;
2174
2175 default:
2176 return false;
2177 }
2178}
2179
2180static bool ValidDebugType(GLenum type)
2181{
2182 switch (type)
2183 {
2184 case GL_DEBUG_TYPE_ERROR:
2185 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
2186 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
2187 case GL_DEBUG_TYPE_PERFORMANCE:
2188 case GL_DEBUG_TYPE_PORTABILITY:
2189 case GL_DEBUG_TYPE_OTHER:
2190 case GL_DEBUG_TYPE_MARKER:
2191 case GL_DEBUG_TYPE_PUSH_GROUP:
2192 case GL_DEBUG_TYPE_POP_GROUP:
2193 return true;
2194
2195 default:
2196 return false;
2197 }
2198}
2199
2200static bool ValidDebugSeverity(GLenum severity)
2201{
2202 switch (severity)
2203 {
2204 case GL_DEBUG_SEVERITY_HIGH:
2205 case GL_DEBUG_SEVERITY_MEDIUM:
2206 case GL_DEBUG_SEVERITY_LOW:
2207 case GL_DEBUG_SEVERITY_NOTIFICATION:
2208 return true;
2209
2210 default:
2211 return false;
2212 }
2213}
2214
Geoff Lange102fee2015-12-10 11:23:30 -05002215bool ValidateDebugMessageControlKHR(Context *context,
2216 GLenum source,
2217 GLenum type,
2218 GLenum severity,
2219 GLsizei count,
2220 const GLuint *ids,
2221 GLboolean enabled)
2222{
2223 if (!context->getExtensions().debug)
2224 {
Jamie Madille0472f32018-11-27 16:32:45 -05002225 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002226 return false;
2227 }
2228
Geoff Lang70d0f492015-12-10 17:45:46 -05002229 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
2230 {
Jamie Madille0472f32018-11-27 16:32:45 -05002231 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002232 return false;
2233 }
2234
2235 if (!ValidDebugType(type) && type != GL_DONT_CARE)
2236 {
Jamie Madille0472f32018-11-27 16:32:45 -05002237 context->validationError(GL_INVALID_ENUM, kInvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002238 return false;
2239 }
2240
2241 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
2242 {
Jamie Madille0472f32018-11-27 16:32:45 -05002243 context->validationError(GL_INVALID_ENUM, kInvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05002244 return false;
2245 }
2246
2247 if (count > 0)
2248 {
2249 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
2250 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002251 context->validationError(GL_INVALID_OPERATION, kInvalidDebugSourceType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002252 return false;
2253 }
2254
2255 if (severity != GL_DONT_CARE)
2256 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002257 context->validationError(GL_INVALID_OPERATION, kInvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05002258 return false;
2259 }
2260 }
2261
Geoff Lange102fee2015-12-10 11:23:30 -05002262 return true;
2263}
2264
2265bool ValidateDebugMessageInsertKHR(Context *context,
2266 GLenum source,
2267 GLenum type,
2268 GLuint id,
2269 GLenum severity,
2270 GLsizei length,
2271 const GLchar *buf)
2272{
2273 if (!context->getExtensions().debug)
2274 {
Jamie Madille0472f32018-11-27 16:32:45 -05002275 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002276 return false;
2277 }
2278
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002279 if (!context->getState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002280 {
2281 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2282 // not generate an error.
2283 return false;
2284 }
2285
2286 if (!ValidDebugSeverity(severity))
2287 {
Jamie Madille0472f32018-11-27 16:32:45 -05002288 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002289 return false;
2290 }
2291
2292 if (!ValidDebugType(type))
2293 {
Jamie Madille0472f32018-11-27 16:32:45 -05002294 context->validationError(GL_INVALID_ENUM, kInvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002295 return false;
2296 }
2297
2298 if (!ValidDebugSource(source, true))
2299 {
Jamie Madille0472f32018-11-27 16:32:45 -05002300 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002301 return false;
2302 }
2303
2304 size_t messageLength = (length < 0) ? strlen(buf) : length;
2305 if (messageLength > context->getExtensions().maxDebugMessageLength)
2306 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002307 context->validationError(GL_INVALID_VALUE, kExceedsMaxDebugMessageLength);
Geoff Lang70d0f492015-12-10 17:45:46 -05002308 return false;
2309 }
2310
Geoff Lange102fee2015-12-10 11:23:30 -05002311 return true;
2312}
2313
2314bool ValidateDebugMessageCallbackKHR(Context *context,
2315 GLDEBUGPROCKHR callback,
2316 const void *userParam)
2317{
2318 if (!context->getExtensions().debug)
2319 {
Jamie Madille0472f32018-11-27 16:32:45 -05002320 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002321 return false;
2322 }
2323
Geoff Lange102fee2015-12-10 11:23:30 -05002324 return true;
2325}
2326
2327bool ValidateGetDebugMessageLogKHR(Context *context,
2328 GLuint count,
2329 GLsizei bufSize,
2330 GLenum *sources,
2331 GLenum *types,
2332 GLuint *ids,
2333 GLenum *severities,
2334 GLsizei *lengths,
2335 GLchar *messageLog)
2336{
2337 if (!context->getExtensions().debug)
2338 {
Jamie Madille0472f32018-11-27 16:32:45 -05002339 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002340 return false;
2341 }
2342
Geoff Lang70d0f492015-12-10 17:45:46 -05002343 if (bufSize < 0 && messageLog != nullptr)
2344 {
Jamie Madille0472f32018-11-27 16:32:45 -05002345 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002346 return false;
2347 }
2348
Geoff Lange102fee2015-12-10 11:23:30 -05002349 return true;
2350}
2351
2352bool ValidatePushDebugGroupKHR(Context *context,
2353 GLenum source,
2354 GLuint id,
2355 GLsizei length,
2356 const GLchar *message)
2357{
2358 if (!context->getExtensions().debug)
2359 {
Jamie Madille0472f32018-11-27 16:32:45 -05002360 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002361 return false;
2362 }
2363
Geoff Lang70d0f492015-12-10 17:45:46 -05002364 if (!ValidDebugSource(source, true))
2365 {
Jamie Madille0472f32018-11-27 16:32:45 -05002366 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002367 return false;
2368 }
2369
2370 size_t messageLength = (length < 0) ? strlen(message) : length;
2371 if (messageLength > context->getExtensions().maxDebugMessageLength)
2372 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002373 context->validationError(GL_INVALID_VALUE, kExceedsMaxDebugMessageLength);
Geoff Lang70d0f492015-12-10 17:45:46 -05002374 return false;
2375 }
2376
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002377 size_t currentStackSize = context->getState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002378 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2379 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002380 context->validationError(GL_STACK_OVERFLOW, kExceedsMaxDebugGroupStackDepth);
Geoff Lang70d0f492015-12-10 17:45:46 -05002381 return false;
2382 }
2383
Geoff Lange102fee2015-12-10 11:23:30 -05002384 return true;
2385}
2386
2387bool ValidatePopDebugGroupKHR(Context *context)
2388{
2389 if (!context->getExtensions().debug)
2390 {
Jamie Madille0472f32018-11-27 16:32:45 -05002391 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002392 return false;
2393 }
2394
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002395 size_t currentStackSize = context->getState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002396 if (currentStackSize <= 1)
2397 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002398 context->validationError(GL_STACK_UNDERFLOW, kCannotPopDefaultDebugGroup);
Geoff Lang70d0f492015-12-10 17:45:46 -05002399 return false;
2400 }
2401
2402 return true;
2403}
2404
2405static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2406{
2407 switch (identifier)
2408 {
2409 case GL_BUFFER:
Jamie Madill3b3fe832019-08-06 17:44:12 -04002410 if (context->getBuffer({name}) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002411 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002412 context->validationError(GL_INVALID_VALUE, kInvalidBufferName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002413 return false;
2414 }
2415 return true;
2416
2417 case GL_SHADER:
Jiacheng Lu120b61d2019-08-21 12:51:58 -06002418 if (context->getShader({name}) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002419 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002420 context->validationError(GL_INVALID_VALUE, kInvalidShaderName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002421 return false;
2422 }
2423 return true;
2424
2425 case GL_PROGRAM:
Jiacheng Lu120b61d2019-08-21 12:51:58 -06002426 if (context->getProgramNoResolveLink({name}) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002427 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002428 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002429 return false;
2430 }
2431 return true;
2432
2433 case GL_VERTEX_ARRAY:
2434 if (context->getVertexArray(name) == nullptr)
2435 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002436 context->validationError(GL_INVALID_VALUE, kInvalidVertexArrayName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002437 return false;
2438 }
2439 return true;
2440
2441 case GL_QUERY:
Jiacheng Lu814a0a12019-08-22 11:50:43 -06002442 if (context->getQuery({name}) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002443 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002444 context->validationError(GL_INVALID_VALUE, kInvalidQueryName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002445 return false;
2446 }
2447 return true;
2448
2449 case GL_TRANSFORM_FEEDBACK:
2450 if (context->getTransformFeedback(name) == nullptr)
2451 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002452 context->validationError(GL_INVALID_VALUE, kInvalidTransformFeedbackName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002453 return false;
2454 }
2455 return true;
2456
2457 case GL_SAMPLER:
Jiacheng Luee79e2f2019-08-20 11:28:36 -06002458 if (context->getSampler({name}) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002459 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002460 context->validationError(GL_INVALID_VALUE, kInvalidSamplerName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002461 return false;
2462 }
2463 return true;
2464
2465 case GL_TEXTURE:
Jamie Madill2ab08ed2019-08-12 16:20:21 -04002466 if (context->getTexture({name}) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002467 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002468 context->validationError(GL_INVALID_VALUE, kInvalidTextureName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002469 return false;
2470 }
2471 return true;
2472
2473 case GL_RENDERBUFFER:
Jamie Madill7c7dec02019-08-06 17:44:11 -04002474 if (!context->isRenderbuffer({name}))
Geoff Lang70d0f492015-12-10 17:45:46 -05002475 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002476 context->validationError(GL_INVALID_VALUE, kInvalidRenderbufferName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002477 return false;
2478 }
2479 return true;
2480
2481 case GL_FRAMEBUFFER:
2482 if (context->getFramebuffer(name) == nullptr)
2483 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002484 context->validationError(GL_INVALID_VALUE, kInvalidFramebufferName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002485 return false;
2486 }
2487 return true;
2488
2489 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05002490 context->validationError(GL_INVALID_ENUM, kInvalidIndentifier);
Geoff Lang70d0f492015-12-10 17:45:46 -05002491 return false;
2492 }
Geoff Lange102fee2015-12-10 11:23:30 -05002493}
2494
Martin Radev9d901792016-07-15 15:58:58 +03002495static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2496{
2497 size_t labelLength = 0;
2498
2499 if (length < 0)
2500 {
2501 if (label != nullptr)
2502 {
2503 labelLength = strlen(label);
2504 }
2505 }
2506 else
2507 {
2508 labelLength = static_cast<size_t>(length);
2509 }
2510
2511 if (labelLength > context->getExtensions().maxLabelLength)
2512 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002513 context->validationError(GL_INVALID_VALUE, kExceedsMaxLabelLength);
Martin Radev9d901792016-07-15 15:58:58 +03002514 return false;
2515 }
2516
2517 return true;
2518}
2519
Geoff Lange102fee2015-12-10 11:23:30 -05002520bool ValidateObjectLabelKHR(Context *context,
2521 GLenum identifier,
2522 GLuint name,
2523 GLsizei length,
2524 const GLchar *label)
2525{
2526 if (!context->getExtensions().debug)
2527 {
Jamie Madille0472f32018-11-27 16:32:45 -05002528 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002529 return false;
2530 }
2531
Geoff Lang70d0f492015-12-10 17:45:46 -05002532 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2533 {
2534 return false;
2535 }
2536
Martin Radev9d901792016-07-15 15:58:58 +03002537 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002538 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002539 return false;
2540 }
2541
Geoff Lange102fee2015-12-10 11:23:30 -05002542 return true;
2543}
2544
2545bool ValidateGetObjectLabelKHR(Context *context,
2546 GLenum identifier,
2547 GLuint name,
2548 GLsizei bufSize,
2549 GLsizei *length,
2550 GLchar *label)
2551{
2552 if (!context->getExtensions().debug)
2553 {
Jamie Madille0472f32018-11-27 16:32:45 -05002554 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002555 return false;
2556 }
2557
Geoff Lang70d0f492015-12-10 17:45:46 -05002558 if (bufSize < 0)
2559 {
Jamie Madille0472f32018-11-27 16:32:45 -05002560 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002561 return false;
2562 }
2563
2564 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2565 {
2566 return false;
2567 }
2568
Martin Radev9d901792016-07-15 15:58:58 +03002569 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002570}
2571
2572static bool ValidateObjectPtrName(Context *context, const void *ptr)
2573{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002574 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002575 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002576 context->validationError(GL_INVALID_VALUE, kInvalidSyncPointer);
Geoff Lang70d0f492015-12-10 17:45:46 -05002577 return false;
2578 }
2579
Geoff Lange102fee2015-12-10 11:23:30 -05002580 return true;
2581}
2582
2583bool ValidateObjectPtrLabelKHR(Context *context,
2584 const void *ptr,
2585 GLsizei length,
2586 const GLchar *label)
2587{
2588 if (!context->getExtensions().debug)
2589 {
Jamie Madille0472f32018-11-27 16:32:45 -05002590 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002591 return false;
2592 }
2593
Geoff Lang70d0f492015-12-10 17:45:46 -05002594 if (!ValidateObjectPtrName(context, ptr))
2595 {
2596 return false;
2597 }
2598
Martin Radev9d901792016-07-15 15:58:58 +03002599 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002600 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002601 return false;
2602 }
2603
Geoff Lange102fee2015-12-10 11:23:30 -05002604 return true;
2605}
2606
2607bool ValidateGetObjectPtrLabelKHR(Context *context,
2608 const void *ptr,
2609 GLsizei bufSize,
2610 GLsizei *length,
2611 GLchar *label)
2612{
2613 if (!context->getExtensions().debug)
2614 {
Jamie Madille0472f32018-11-27 16:32:45 -05002615 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002616 return false;
2617 }
2618
Geoff Lang70d0f492015-12-10 17:45:46 -05002619 if (bufSize < 0)
2620 {
Jamie Madille0472f32018-11-27 16:32:45 -05002621 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002622 return false;
2623 }
2624
2625 if (!ValidateObjectPtrName(context, ptr))
2626 {
2627 return false;
2628 }
2629
Martin Radev9d901792016-07-15 15:58:58 +03002630 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002631}
2632
2633bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2634{
2635 if (!context->getExtensions().debug)
2636 {
Jamie Madille0472f32018-11-27 16:32:45 -05002637 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002638 return false;
2639 }
2640
Geoff Lang70d0f492015-12-10 17:45:46 -05002641 // TODO: represent this in Context::getQueryParameterInfo.
2642 switch (pname)
2643 {
2644 case GL_DEBUG_CALLBACK_FUNCTION:
2645 case GL_DEBUG_CALLBACK_USER_PARAM:
2646 break;
2647
2648 default:
Jamie Madille0472f32018-11-27 16:32:45 -05002649 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002650 return false;
2651 }
2652
Geoff Lange102fee2015-12-10 11:23:30 -05002653 return true;
2654}
Jamie Madillc29968b2016-01-20 11:17:23 -05002655
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07002656bool ValidateGetPointervRobustANGLERobustANGLE(Context *context,
2657 GLenum pname,
2658 GLsizei bufSize,
2659 GLsizei *length,
2660 void **params)
2661{
2662 UNIMPLEMENTED();
2663 return false;
2664}
2665
Jamie Madillc29968b2016-01-20 11:17:23 -05002666bool ValidateBlitFramebufferANGLE(Context *context,
2667 GLint srcX0,
2668 GLint srcY0,
2669 GLint srcX1,
2670 GLint srcY1,
2671 GLint dstX0,
2672 GLint dstY0,
2673 GLint dstX1,
2674 GLint dstY1,
2675 GLbitfield mask,
2676 GLenum filter)
2677{
2678 if (!context->getExtensions().framebufferBlit)
2679 {
Jamie Madille0472f32018-11-27 16:32:45 -05002680 context->validationError(GL_INVALID_OPERATION, kBlitExtensionNotAvailable);
Jamie Madillc29968b2016-01-20 11:17:23 -05002681 return false;
2682 }
2683
2684 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2685 {
2686 // TODO(jmadill): Determine if this should be available on other implementations.
Jamie Madille0472f32018-11-27 16:32:45 -05002687 context->validationError(GL_INVALID_OPERATION, kBlitExtensionScaleOrFlip);
Jamie Madillc29968b2016-01-20 11:17:23 -05002688 return false;
2689 }
2690
2691 if (filter == GL_LINEAR)
2692 {
Jamie Madille0472f32018-11-27 16:32:45 -05002693 context->validationError(GL_INVALID_ENUM, kBlitExtensionLinear);
Jamie Madillc29968b2016-01-20 11:17:23 -05002694 return false;
2695 }
2696
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002697 Framebuffer *readFramebuffer = context->getState().getReadFramebuffer();
2698 Framebuffer *drawFramebuffer = context->getState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002699
2700 if (mask & GL_COLOR_BUFFER_BIT)
2701 {
Jamie Madill4e71b2b2019-07-08 13:23:38 -04002702 const FramebufferAttachment *readColorAttachment =
2703 readFramebuffer->getReadColorAttachment();
2704 const FramebufferAttachment *drawColorAttachment =
2705 drawFramebuffer->getFirstColorAttachment();
Jamie Madillc29968b2016-01-20 11:17:23 -05002706
2707 if (readColorAttachment && drawColorAttachment)
2708 {
2709 if (!(readColorAttachment->type() == GL_TEXTURE &&
Kenneth Russellcbdf8612019-07-09 20:30:45 -07002710 (readColorAttachment->getTextureImageIndex().getType() == TextureType::_2D ||
2711 readColorAttachment->getTextureImageIndex().getType() ==
2712 TextureType::Rectangle)) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002713 readColorAttachment->type() != GL_RENDERBUFFER &&
2714 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2715 {
Jamie Madill610640f2018-11-21 17:28:41 -05002716 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002717 kBlitExtensionFromInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002718 return false;
2719 }
2720
Geoff Langa15472a2015-08-11 11:48:03 -04002721 for (size_t drawbufferIdx = 0;
2722 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002723 {
Geoff Langa15472a2015-08-11 11:48:03 -04002724 const FramebufferAttachment *attachment =
2725 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2726 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002727 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002728 if (!(attachment->type() == GL_TEXTURE &&
Kenneth Russellcbdf8612019-07-09 20:30:45 -07002729 (attachment->getTextureImageIndex().getType() == TextureType::_2D ||
2730 attachment->getTextureImageIndex().getType() ==
2731 TextureType::Rectangle)) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002732 attachment->type() != GL_RENDERBUFFER &&
2733 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2734 {
Jamie Madill610640f2018-11-21 17:28:41 -05002735 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002736 kBlitExtensionToInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002737 return false;
2738 }
2739
2740 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002741 if (!Format::EquivalentForBlit(attachment->getFormat(),
2742 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002743 {
Jamie Madill610640f2018-11-21 17:28:41 -05002744 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002745 kBlitExtensionFormatMismatch);
Jamie Madillc29968b2016-01-20 11:17:23 -05002746 return false;
2747 }
2748 }
2749 }
2750
Jamie Madill427064d2018-04-13 16:20:34 -04002751 GLint samples = readFramebuffer->getSamples(context);
Jamie Madille98b1b52018-03-08 09:47:23 -05002752 if (samples != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002753 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2754 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2755 {
Jamie Madill610640f2018-11-21 17:28:41 -05002756 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002757 kBlitExtensionMultisampledWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002758 return false;
2759 }
2760 }
2761 }
2762
2763 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2764 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2765 for (size_t i = 0; i < 2; i++)
2766 {
2767 if (mask & masks[i])
2768 {
2769 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002770 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002771 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002772 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002773
2774 if (readBuffer && drawBuffer)
2775 {
2776 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2777 dstX0, dstY0, dstX1, dstY1))
2778 {
2779 // only whole-buffer copies are permitted
Jamie Madill610640f2018-11-21 17:28:41 -05002780 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002781 kBlitExtensionDepthStencilWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002782 return false;
2783 }
2784
2785 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2786 {
Jamie Madill610640f2018-11-21 17:28:41 -05002787 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002788 kBlitExtensionMultisampledDepthOrStencil);
Jamie Madillc29968b2016-01-20 11:17:23 -05002789 return false;
2790 }
2791 }
2792 }
2793 }
2794
2795 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2796 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002797}
Jamie Madillc29968b2016-01-20 11:17:23 -05002798
Jamie Madill5b772312018-03-08 20:28:32 -05002799bool ValidateClear(Context *context, GLbitfield mask)
Jamie Madillc29968b2016-01-20 11:17:23 -05002800{
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002801 Framebuffer *fbo = context->getState().getDrawFramebuffer();
Olli Etuaho94c91a92018-07-19 15:10:24 +03002802 const Extensions &extensions = context->getExtensions();
Jamie Madille98b1b52018-03-08 09:47:23 -05002803
Jamie Madill427064d2018-04-13 16:20:34 -04002804 if (!ValidateFramebufferComplete(context, fbo))
Jamie Madillc29968b2016-01-20 11:17:23 -05002805 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002806 return false;
2807 }
2808
2809 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2810 {
Jamie Madille0472f32018-11-27 16:32:45 -05002811 context->validationError(GL_INVALID_VALUE, kInvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002812 return false;
2813 }
2814
Olli Etuaho94c91a92018-07-19 15:10:24 +03002815 if (extensions.webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
Geoff Lang76e65652017-03-27 14:58:02 -04002816 {
2817 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2818 GL_SIGNED_NORMALIZED};
2819
Corentin Wallez59c41592017-07-11 13:19:54 -04002820 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002821 drawBufferIdx++)
2822 {
2823 if (!ValidateWebGLFramebufferAttachmentClearType(
2824 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2825 {
2826 return false;
2827 }
2828 }
2829 }
2830
Mingyu Huebab6702019-04-19 14:36:45 -07002831 if ((extensions.multiview || extensions.multiview2) && extensions.disjointTimerQuery)
Olli Etuaho94c91a92018-07-19 15:10:24 +03002832 {
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002833 const State &state = context->getState();
Olli Etuaho94c91a92018-07-19 15:10:24 +03002834 Framebuffer *framebuffer = state.getDrawFramebuffer();
2835 if (framebuffer->getNumViews() > 1 && state.isQueryActive(QueryType::TimeElapsed))
2836 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002837 context->validationError(GL_INVALID_OPERATION, kMultiviewTimerQuery);
Olli Etuaho94c91a92018-07-19 15:10:24 +03002838 return false;
2839 }
2840 }
2841
Jamie Madillc29968b2016-01-20 11:17:23 -05002842 return true;
2843}
2844
Jamie Madill5b772312018-03-08 20:28:32 -05002845bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002846{
2847 if (!context->getExtensions().drawBuffers)
2848 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002849 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05002850 return false;
2851 }
2852
2853 return ValidateDrawBuffersBase(context, n, bufs);
2854}
2855
Jamie Madill73a84962016-02-12 09:27:23 -05002856bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002857 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002858 GLint level,
2859 GLint internalformat,
2860 GLsizei width,
2861 GLsizei height,
2862 GLint border,
2863 GLenum format,
2864 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002865 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002866{
Martin Radev1be913c2016-07-11 17:59:16 +03002867 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002868 {
2869 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002870 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002871 }
2872
Martin Radev1be913c2016-07-11 17:59:16 +03002873 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002874 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002875 0, 0, width, height, 1, border, format, type, -1,
2876 pixels);
2877}
2878
Brandon Jones416aaf92018-04-10 08:10:16 -07002879bool ValidateTexImage2DRobustANGLE(Context *context,
2880 TextureTarget target,
2881 GLint level,
2882 GLint internalformat,
2883 GLsizei width,
2884 GLsizei height,
2885 GLint border,
2886 GLenum format,
2887 GLenum type,
2888 GLsizei bufSize,
2889 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002890{
2891 if (!ValidateRobustEntryPoint(context, bufSize))
2892 {
2893 return false;
2894 }
2895
2896 if (context->getClientMajorVersion() < 3)
2897 {
2898 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2899 0, 0, width, height, border, format, type, bufSize,
2900 pixels);
2901 }
2902
2903 ASSERT(context->getClientMajorVersion() >= 3);
2904 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2905 0, 0, width, height, 1, border, format, type, bufSize,
2906 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002907}
2908
2909bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002910 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002911 GLint level,
2912 GLint xoffset,
2913 GLint yoffset,
2914 GLsizei width,
2915 GLsizei height,
2916 GLenum format,
2917 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002918 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002919{
2920
Martin Radev1be913c2016-07-11 17:59:16 +03002921 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002922 {
2923 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002924 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002925 }
2926
Martin Radev1be913c2016-07-11 17:59:16 +03002927 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002928 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002929 yoffset, 0, width, height, 1, 0, format, type, -1,
2930 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002931}
2932
Geoff Langc52f6f12016-10-14 10:18:00 -04002933bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002934 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002935 GLint level,
2936 GLint xoffset,
2937 GLint yoffset,
2938 GLsizei width,
2939 GLsizei height,
2940 GLenum format,
2941 GLenum type,
2942 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002943 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002944{
2945 if (!ValidateRobustEntryPoint(context, bufSize))
2946 {
2947 return false;
2948 }
2949
2950 if (context->getClientMajorVersion() < 3)
2951 {
2952 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2953 yoffset, width, height, 0, format, type, bufSize,
2954 pixels);
2955 }
2956
2957 ASSERT(context->getClientMajorVersion() >= 3);
2958 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2959 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2960 pixels);
2961}
2962
Cody Northrop5faff912019-06-28 14:04:50 -06002963bool ValidateTexSubImage3DOES(Context *context,
2964 TextureTarget target,
2965 GLint level,
2966 GLint xoffset,
2967 GLint yoffset,
2968 GLint zoffset,
2969 GLsizei width,
2970 GLsizei height,
2971 GLsizei depth,
2972 GLenum format,
2973 GLenum type,
2974 const void *pixels)
2975{
2976 return ValidateTexSubImage3D(context, target, level, xoffset, yoffset, zoffset, width, height,
2977 depth, format, type, pixels);
2978}
2979
Jamie Madill73a84962016-02-12 09:27:23 -05002980bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002981 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002982 GLint level,
2983 GLenum internalformat,
2984 GLsizei width,
2985 GLsizei height,
2986 GLint border,
2987 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002988 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002989{
Martin Radev1be913c2016-07-11 17:59:16 +03002990 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002991 {
2992 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002993 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002994 {
2995 return false;
2996 }
2997 }
2998 else
2999 {
Martin Radev1be913c2016-07-11 17:59:16 +03003000 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05003001 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04003002 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05003003 data))
3004 {
3005 return false;
3006 }
3007 }
3008
Geoff Langca271392017-04-05 12:30:00 -04003009 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jamie Madillca2ff382018-07-11 09:01:17 -04003010
3011 GLuint blockSize = 0;
3012 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04003013 {
Jamie Madille0472f32018-11-27 16:32:45 -05003014 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04003015 return false;
3016 }
3017
Jamie Madillca2ff382018-07-11 09:01:17 -04003018 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05003019 {
Jamie Madille0472f32018-11-27 16:32:45 -05003020 context->validationError(GL_INVALID_VALUE, kCompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05003021 return false;
3022 }
3023
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003024 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04003025 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003026 context->validationError(GL_INVALID_ENUM, kRectangleTextureCompressed);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04003027 return false;
3028 }
3029
Jamie Madill73a84962016-02-12 09:27:23 -05003030 return true;
3031}
3032
Corentin Wallezb2931602017-04-11 15:58:57 -04003033bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003034 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04003035 GLint level,
3036 GLenum internalformat,
3037 GLsizei width,
3038 GLsizei height,
3039 GLint border,
3040 GLsizei imageSize,
3041 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003042 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04003043{
3044 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
3045 {
3046 return false;
3047 }
3048
3049 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
3050 border, imageSize, data);
3051}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003052
Cody Northrop5faff912019-06-28 14:04:50 -06003053bool ValidateCompressedTexImage3DOES(Context *context,
3054 TextureTarget target,
3055 GLint level,
3056 GLenum internalformat,
3057 GLsizei width,
3058 GLsizei height,
3059 GLsizei depth,
3060 GLint border,
3061 GLsizei imageSize,
3062 const void *data)
3063{
3064 return ValidateCompressedTexImage3D(context, target, level, internalformat, width, height,
3065 depth, border, imageSize, data);
3066}
3067
Corentin Wallezb2931602017-04-11 15:58:57 -04003068bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003069 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04003070 GLint level,
3071 GLint xoffset,
3072 GLint yoffset,
3073 GLsizei width,
3074 GLsizei height,
3075 GLenum format,
3076 GLsizei imageSize,
3077 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003078 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04003079{
3080 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
3081 {
3082 return false;
3083 }
3084
3085 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
3086 format, imageSize, data);
3087}
3088
Jamie Madill73a84962016-02-12 09:27:23 -05003089bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003090 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05003091 GLint level,
3092 GLint xoffset,
3093 GLint yoffset,
3094 GLsizei width,
3095 GLsizei height,
3096 GLenum format,
3097 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003098 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003099{
Martin Radev1be913c2016-07-11 17:59:16 +03003100 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05003101 {
3102 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04003103 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05003104 {
3105 return false;
3106 }
3107 }
3108 else
3109 {
Martin Radev1be913c2016-07-11 17:59:16 +03003110 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05003111 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04003112 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05003113 data))
3114 {
3115 return false;
3116 }
3117 }
3118
Geoff Langca271392017-04-05 12:30:00 -04003119 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jamie Madillca2ff382018-07-11 09:01:17 -04003120 GLuint blockSize = 0;
3121 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04003122 {
Jamie Madille0472f32018-11-27 16:32:45 -05003123 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04003124 return false;
3125 }
3126
Jamie Madillca2ff382018-07-11 09:01:17 -04003127 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05003128 {
Jamie Madille0472f32018-11-27 16:32:45 -05003129 context->validationError(GL_INVALID_VALUE, kInvalidCompressedImageSize);
Jamie Madill73a84962016-02-12 09:27:23 -05003130 return false;
3131 }
3132
3133 return true;
3134}
3135
Cody Northrop5faff912019-06-28 14:04:50 -06003136bool ValidateCompressedTexSubImage3DOES(Context *context,
3137 TextureTarget target,
3138 GLint level,
3139 GLint xoffset,
3140 GLint yoffset,
3141 GLint zoffset,
3142 GLsizei width,
3143 GLsizei height,
3144 GLsizei depth,
3145 GLenum format,
3146 GLsizei imageSize,
3147 const void *data)
3148{
3149 return ValidateCompressedTexSubImage3D(context, target, level, xoffset, yoffset, zoffset, width,
3150 height, depth, format, imageSize, data);
3151}
3152
Corentin Wallez336129f2017-10-17 15:55:40 -04003153bool ValidateGetBufferPointervOES(Context *context,
3154 BufferBinding target,
3155 GLenum pname,
3156 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003157{
Jamie Madillc3e37312018-11-30 15:25:39 -05003158 if (!context->getExtensions().mapBuffer)
3159 {
3160 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3161 return false;
3162 }
3163
Geoff Lang496c02d2016-10-20 11:38:11 -07003164 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003165}
3166
Corentin Wallez336129f2017-10-17 15:55:40 -04003167bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003168{
3169 if (!context->getExtensions().mapBuffer)
3170 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003171 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03003172 return false;
3173 }
3174
Corentin Walleze4477002017-12-01 14:39:58 -05003175 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003176 {
Jamie Madille0472f32018-11-27 16:32:45 -05003177 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003178 return false;
3179 }
3180
Jamie Madillc3dc5d42018-12-30 12:12:04 -05003181 Buffer *buffer = context->getState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003182
3183 if (buffer == nullptr)
3184 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003185 context->validationError(GL_INVALID_OPERATION, kBufferNotMappable);
Olli Etuaho4f667482016-03-30 15:56:35 +03003186 return false;
3187 }
3188
3189 if (access != GL_WRITE_ONLY_OES)
3190 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003191 context->validationError(GL_INVALID_ENUM, kInvalidAccessBits);
Olli Etuaho4f667482016-03-30 15:56:35 +03003192 return false;
3193 }
3194
3195 if (buffer->isMapped())
3196 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003197 context->validationError(GL_INVALID_OPERATION, kBufferAlreadyMapped);
Olli Etuaho4f667482016-03-30 15:56:35 +03003198 return false;
3199 }
3200
Geoff Lang79f71042017-08-14 16:43:43 -04003201 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003202}
3203
Corentin Wallez336129f2017-10-17 15:55:40 -04003204bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03003205{
3206 if (!context->getExtensions().mapBuffer)
3207 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003208 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03003209 return false;
3210 }
3211
3212 return ValidateUnmapBufferBase(context, target);
3213}
3214
3215bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003216 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003217 GLintptr offset,
3218 GLsizeiptr length,
3219 GLbitfield access)
3220{
3221 if (!context->getExtensions().mapBufferRange)
3222 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003223 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03003224 return false;
3225 }
3226
3227 return ValidateMapBufferRangeBase(context, target, offset, length, access);
3228}
3229
Michael Spang7a8c3e52019-04-03 14:49:57 -04003230bool ValidateBufferStorageMemEXT(Context *context,
3231 TextureType target,
3232 GLsizeiptr size,
3233 GLuint memory,
3234 GLuint64 offset)
3235{
3236 if (!context->getExtensions().memoryObject)
3237 {
3238 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3239 return false;
3240 }
3241
3242 UNIMPLEMENTED();
3243 return false;
3244}
3245
3246bool ValidateCreateMemoryObjectsEXT(Context *context, GLsizei n, GLuint *memoryObjects)
3247{
3248 if (!context->getExtensions().memoryObject)
3249 {
3250 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3251 return false;
3252 }
3253
Michael Spangfb201c52019-04-03 14:57:35 -04003254 return ValidateGenOrDelete(context, n);
Michael Spang7a8c3e52019-04-03 14:49:57 -04003255}
3256
3257bool ValidateDeleteMemoryObjectsEXT(Context *context, GLsizei n, const GLuint *memoryObjects)
3258{
3259 if (!context->getExtensions().memoryObject)
3260 {
3261 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3262 return false;
3263 }
3264
Michael Spangfb201c52019-04-03 14:57:35 -04003265 return ValidateGenOrDelete(context, n);
Michael Spang7a8c3e52019-04-03 14:49:57 -04003266}
3267
3268bool ValidateGetMemoryObjectParameterivEXT(Context *context,
3269 GLuint memoryObject,
3270 GLenum pname,
3271 GLint *params)
3272{
3273 if (!context->getExtensions().memoryObject)
3274 {
3275 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3276 return false;
3277 }
3278
3279 UNIMPLEMENTED();
3280 return false;
3281}
3282
3283bool ValidateGetUnsignedBytevEXT(Context *context, GLenum pname, GLubyte *data)
3284{
3285 if (!context->getExtensions().memoryObject && !context->getExtensions().semaphore)
3286 {
3287 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3288 return false;
3289 }
3290
3291 UNIMPLEMENTED();
3292 return false;
3293}
3294
3295bool ValidateGetUnsignedBytei_vEXT(Context *context, GLenum target, GLuint index, GLubyte *data)
3296{
3297 if (!context->getExtensions().memoryObject && !context->getExtensions().semaphore)
3298 {
3299 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3300 return false;
3301 }
3302
3303 UNIMPLEMENTED();
3304 return false;
3305}
3306
3307bool ValidateIsMemoryObjectEXT(Context *context, GLuint memoryObject)
3308{
3309 if (!context->getExtensions().memoryObject)
3310 {
3311 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3312 return false;
3313 }
3314
Michael Spangfb201c52019-04-03 14:57:35 -04003315 return true;
Michael Spang7a8c3e52019-04-03 14:49:57 -04003316}
3317
3318bool ValidateMemoryObjectParameterivEXT(Context *context,
3319 GLuint memoryObject,
3320 GLenum pname,
3321 const GLint *params)
3322{
3323 if (!context->getExtensions().memoryObject)
3324 {
3325 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3326 return false;
3327 }
3328
3329 UNIMPLEMENTED();
3330 return false;
3331}
3332
3333bool ValidateTexStorageMem2DEXT(Context *context,
3334 TextureType target,
3335 GLsizei levels,
3336 GLenum internalFormat,
3337 GLsizei width,
3338 GLsizei height,
3339 GLuint memory,
3340 GLuint64 offset)
3341{
3342 if (!context->getExtensions().memoryObject)
3343 {
3344 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3345 return false;
3346 }
3347
Michael Spangf02a7672019-04-09 18:45:23 -04003348 if (context->getClientMajorVersion() < 3)
3349 {
3350 return ValidateES2TexStorageParameters(context, target, levels, internalFormat, width,
3351 height);
3352 }
3353
3354 ASSERT(context->getClientMajorVersion() >= 3);
3355 return ValidateES3TexStorage2DParameters(context, target, levels, internalFormat, width, height,
3356 1);
Michael Spang7a8c3e52019-04-03 14:49:57 -04003357}
3358
3359bool ValidateTexStorageMem3DEXT(Context *context,
3360 TextureType target,
3361 GLsizei levels,
3362 GLenum internalFormat,
3363 GLsizei width,
3364 GLsizei height,
3365 GLsizei depth,
3366 GLuint memory,
3367 GLuint64 offset)
3368{
3369 if (!context->getExtensions().memoryObject)
3370 {
3371 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3372 return false;
3373 }
3374
3375 UNIMPLEMENTED();
3376 return false;
3377}
3378
Michael Spang9de3ddb2019-04-03 16:23:40 -04003379bool ValidateImportMemoryFdEXT(Context *context,
3380 GLuint memory,
3381 GLuint64 size,
Michael Spange0da9ce2019-04-16 14:34:51 -04003382 HandleType handleType,
Michael Spang9de3ddb2019-04-03 16:23:40 -04003383 GLint fd)
3384{
3385 if (!context->getExtensions().memoryObjectFd)
3386 {
3387 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3388 return false;
3389 }
3390
Michael Spang3b2c6bf2019-04-16 17:19:50 -04003391 switch (handleType)
3392 {
3393 case HandleType::OpaqueFd:
3394 break;
3395 default:
3396 context->validationError(GL_INVALID_ENUM, kInvalidHandleType);
3397 return false;
3398 }
3399
3400 return true;
Michael Spang9de3ddb2019-04-03 16:23:40 -04003401}
3402
Michael Spang7a8c3e52019-04-03 14:49:57 -04003403bool ValidateDeleteSemaphoresEXT(Context *context, GLsizei n, const GLuint *semaphores)
3404{
3405 if (!context->getExtensions().semaphore)
3406 {
3407 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3408 return false;
3409 }
3410
Michael Spang5093ba62019-05-14 17:36:36 -04003411 return ValidateGenOrDelete(context, n);
Michael Spang7a8c3e52019-04-03 14:49:57 -04003412}
3413
3414bool ValidateGenSemaphoresEXT(Context *context, GLsizei n, GLuint *semaphores)
3415{
3416 if (!context->getExtensions().semaphore)
3417 {
3418 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3419 return false;
3420 }
3421
Michael Spang5093ba62019-05-14 17:36:36 -04003422 return ValidateGenOrDelete(context, n);
Michael Spang7a8c3e52019-04-03 14:49:57 -04003423}
3424
3425bool ValidateGetSemaphoreParameterui64vEXT(Context *context,
3426 GLuint semaphore,
3427 GLenum pname,
3428 GLuint64 *params)
3429{
3430 if (!context->getExtensions().semaphore)
3431 {
3432 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3433 return false;
3434 }
3435
3436 UNIMPLEMENTED();
3437 return false;
3438}
3439
3440bool ValidateIsSemaphoreEXT(Context *context, GLuint semaphore)
3441{
3442 if (!context->getExtensions().semaphore)
3443 {
3444 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3445 return false;
3446 }
3447
Michael Spang5093ba62019-05-14 17:36:36 -04003448 return true;
Michael Spang7a8c3e52019-04-03 14:49:57 -04003449}
3450
3451bool ValidateSemaphoreParameterui64vEXT(Context *context,
3452 GLuint semaphore,
3453 GLenum pname,
3454 const GLuint64 *params)
3455{
3456 if (!context->getExtensions().semaphore)
3457 {
3458 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3459 return false;
3460 }
3461
3462 UNIMPLEMENTED();
3463 return false;
3464}
3465
3466bool ValidateSignalSemaphoreEXT(Context *context,
3467 GLuint semaphore,
3468 GLuint numBufferBarriers,
Jamie Madill3b3fe832019-08-06 17:44:12 -04003469 const BufferID *buffers,
Michael Spang7a8c3e52019-04-03 14:49:57 -04003470 GLuint numTextureBarriers,
Jamie Madill2ab08ed2019-08-12 16:20:21 -04003471 const TextureID *textures,
Michael Spang7a8c3e52019-04-03 14:49:57 -04003472 const GLenum *dstLayouts)
3473{
3474 if (!context->getExtensions().semaphore)
3475 {
3476 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3477 return false;
3478 }
3479
Michael Spangab6a59b2019-05-21 21:26:26 -04003480 for (GLuint i = 0; i < numTextureBarriers; ++i)
3481 {
3482 if (!IsValidImageLayout(FromGLenum<ImageLayout>(dstLayouts[i])))
3483 {
3484 context->validationError(GL_INVALID_ENUM, kInvalidImageLayout);
3485 return false;
3486 }
3487 }
3488
3489 return true;
Michael Spang7a8c3e52019-04-03 14:49:57 -04003490}
3491
3492bool ValidateWaitSemaphoreEXT(Context *context,
3493 GLuint semaphore,
3494 GLuint numBufferBarriers,
Jamie Madill3b3fe832019-08-06 17:44:12 -04003495 const BufferID *buffers,
Michael Spang7a8c3e52019-04-03 14:49:57 -04003496 GLuint numTextureBarriers,
Jamie Madill2ab08ed2019-08-12 16:20:21 -04003497 const TextureID *textures,
Michael Spang7a8c3e52019-04-03 14:49:57 -04003498 const GLenum *srcLayouts)
3499{
3500 if (!context->getExtensions().semaphore)
3501 {
3502 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3503 return false;
3504 }
3505
Michael Spangab6a59b2019-05-21 21:26:26 -04003506 for (GLuint i = 0; i < numTextureBarriers; ++i)
3507 {
3508 if (!IsValidImageLayout(FromGLenum<ImageLayout>(srcLayouts[i])))
3509 {
3510 context->validationError(GL_INVALID_ENUM, kInvalidImageLayout);
3511 return false;
3512 }
3513 }
3514
3515 return true;
Michael Spang7a8c3e52019-04-03 14:49:57 -04003516}
3517
Michael Spange0da9ce2019-04-16 14:34:51 -04003518bool ValidateImportSemaphoreFdEXT(Context *context,
3519 GLuint semaphore,
3520 HandleType handleType,
3521 GLint fd)
Michael Spang9de3ddb2019-04-03 16:23:40 -04003522{
3523 if (!context->getExtensions().semaphoreFd)
3524 {
3525 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3526 return false;
3527 }
3528
Michael Spang6bb193c2019-05-22 16:32:21 -04003529 switch (handleType)
3530 {
3531 case HandleType::OpaqueFd:
3532 break;
3533 default:
3534 context->validationError(GL_INVALID_ENUM, kInvalidHandleType);
3535 return false;
3536 }
3537
3538 return true;
Michael Spang9de3ddb2019-04-03 16:23:40 -04003539}
3540
Corentin Wallez336129f2017-10-17 15:55:40 -04003541bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04003542{
Jamie Madillc3dc5d42018-12-30 12:12:04 -05003543 Buffer *buffer = context->getState().getTargetBuffer(target);
Geoff Lang79f71042017-08-14 16:43:43 -04003544 ASSERT(buffer != nullptr);
3545
3546 // Check if this buffer is currently being used as a transform feedback output buffer
Shahbaz Youssefi8af6c6f2019-06-18 15:43:44 -04003547 if (context->getState().isTransformFeedbackActive())
Geoff Lang79f71042017-08-14 16:43:43 -04003548 {
Shahbaz Youssefi8af6c6f2019-06-18 15:43:44 -04003549 TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
Geoff Lang79f71042017-08-14 16:43:43 -04003550 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
3551 {
3552 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
3553 if (transformFeedbackBuffer.get() == buffer)
3554 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003555 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
Geoff Lang79f71042017-08-14 16:43:43 -04003556 return false;
3557 }
3558 }
3559 }
3560
James Darpiniane8a93c62018-01-04 18:02:24 -08003561 if (context->getExtensions().webglCompatibility &&
3562 buffer->isBoundForTransformFeedbackAndOtherUse())
3563 {
Jamie Madille0472f32018-11-27 16:32:45 -05003564 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08003565 return false;
3566 }
3567
Geoff Lang79f71042017-08-14 16:43:43 -04003568 return true;
3569}
3570
Olli Etuaho4f667482016-03-30 15:56:35 +03003571bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003572 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003573 GLintptr offset,
3574 GLsizeiptr length)
3575{
3576 if (!context->getExtensions().mapBufferRange)
3577 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003578 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03003579 return false;
3580 }
3581
3582 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
3583}
3584
Geoff Langd8605522016-04-13 10:19:12 -04003585bool ValidateBindUniformLocationCHROMIUM(Context *context,
Jiacheng Lu120b61d2019-08-21 12:51:58 -06003586 ShaderProgramID program,
Geoff Langd8605522016-04-13 10:19:12 -04003587 GLint location,
3588 const GLchar *name)
3589{
3590 if (!context->getExtensions().bindUniformLocation)
3591 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003592 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langd8605522016-04-13 10:19:12 -04003593 return false;
3594 }
3595
3596 Program *programObject = GetValidProgram(context, program);
3597 if (!programObject)
3598 {
3599 return false;
3600 }
3601
3602 if (location < 0)
3603 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003604 context->validationError(GL_INVALID_VALUE, kNegativeLocation);
Geoff Langd8605522016-04-13 10:19:12 -04003605 return false;
3606 }
3607
3608 const Caps &caps = context->getCaps();
3609 if (static_cast<size_t>(location) >=
3610 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3611 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003612 context->validationError(GL_INVALID_VALUE, kInvalidBindUniformLocation);
Geoff Langd8605522016-04-13 10:19:12 -04003613 return false;
3614 }
3615
Geoff Langfc32e8b2017-05-31 14:16:59 -04003616 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3617 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003618 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003619 {
Jamie Madille0472f32018-11-27 16:32:45 -05003620 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003621 return false;
3622 }
3623
Geoff Langd8605522016-04-13 10:19:12 -04003624 if (strncmp(name, "gl_", 3) == 0)
3625 {
Jamie Madille0472f32018-11-27 16:32:45 -05003626 context->validationError(GL_INVALID_VALUE, kNameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003627 return false;
3628 }
3629
3630 return true;
3631}
3632
Jamie Madille2e406c2016-06-02 13:04:10 -04003633bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003634{
3635 if (!context->getExtensions().framebufferMixedSamples)
3636 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003637 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänena797e062016-05-12 15:23:40 +03003638 return false;
3639 }
3640 switch (components)
3641 {
3642 case GL_RGB:
3643 case GL_RGBA:
3644 case GL_ALPHA:
3645 case GL_NONE:
3646 break;
3647 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003648 context->validationError(GL_INVALID_ENUM, kInvalidCoverageComponents);
Sami Väisänena797e062016-05-12 15:23:40 +03003649 return false;
3650 }
3651
3652 return true;
3653}
3654
Sami Väisänene45e53b2016-05-25 10:36:04 +03003655// CHROMIUM_path_rendering
3656
Jamie Madill007530e2017-12-28 14:27:04 -05003657bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003658{
Jamie Madill007530e2017-12-28 14:27:04 -05003659 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003660 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003661 return false;
3662 }
Jamie Madill007530e2017-12-28 14:27:04 -05003663
Sami Väisänene45e53b2016-05-25 10:36:04 +03003664 if (matrix == nullptr)
3665 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003666 context->validationError(GL_INVALID_OPERATION, kInvalidPathMatrix);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003667 return false;
3668 }
Jamie Madill007530e2017-12-28 14:27:04 -05003669
Sami Väisänene45e53b2016-05-25 10:36:04 +03003670 return true;
3671}
3672
Jamie Madill007530e2017-12-28 14:27:04 -05003673bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003674{
Jamie Madill007530e2017-12-28 14:27:04 -05003675 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003676}
3677
Jamie Madill007530e2017-12-28 14:27:04 -05003678bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003679{
3680 if (!context->getExtensions().pathRendering)
3681 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003682 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003683 return false;
3684 }
3685
3686 // range = 0 is undefined in NV_path_rendering.
3687 // we add stricter semantic check here and require a non zero positive range.
3688 if (range <= 0)
3689 {
Jamie Madille0472f32018-11-27 16:32:45 -05003690 context->validationError(GL_INVALID_VALUE, kInvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003691 return false;
3692 }
3693
3694 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3695 {
Jamie Madille0472f32018-11-27 16:32:45 -05003696 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003697 return false;
3698 }
3699
3700 return true;
3701}
3702
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06003703bool ValidateDeletePathsCHROMIUM(Context *context, PathID path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003704{
3705 if (!context->getExtensions().pathRendering)
3706 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003707 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003708 return false;
3709 }
3710
3711 // range = 0 is undefined in NV_path_rendering.
3712 // we add stricter semantic check here and require a non zero positive range.
3713 if (range <= 0)
3714 {
Jamie Madille0472f32018-11-27 16:32:45 -05003715 context->validationError(GL_INVALID_VALUE, kInvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003716 return false;
3717 }
3718
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06003719 angle::CheckedNumeric<std::uint32_t> checkedRange(path.value);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003720 checkedRange += range;
3721
3722 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3723 {
Jamie Madille0472f32018-11-27 16:32:45 -05003724 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003725 return false;
3726 }
3727 return true;
3728}
3729
Jamie Madill007530e2017-12-28 14:27:04 -05003730bool ValidatePathCommandsCHROMIUM(Context *context,
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06003731 PathID path,
Jamie Madill007530e2017-12-28 14:27:04 -05003732 GLsizei numCommands,
3733 const GLubyte *commands,
3734 GLsizei numCoords,
3735 GLenum coordType,
3736 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003737{
3738 if (!context->getExtensions().pathRendering)
3739 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003740 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003741 return false;
3742 }
Brandon Jones59770802018-04-02 13:18:42 -07003743 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003744 {
Jamie Madille0472f32018-11-27 16:32:45 -05003745 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003746 return false;
3747 }
3748
3749 if (numCommands < 0)
3750 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003751 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCommands);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003752 return false;
3753 }
3754 else if (numCommands > 0)
3755 {
3756 if (!commands)
3757 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003758 context->validationError(GL_INVALID_VALUE, kInvalidPathCommandsArray);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003759 return false;
3760 }
3761 }
3762
3763 if (numCoords < 0)
3764 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003765 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCoords);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003766 return false;
3767 }
3768 else if (numCoords > 0)
3769 {
3770 if (!coords)
3771 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003772 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCoordsArray);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003773 return false;
3774 }
3775 }
3776
3777 std::uint32_t coordTypeSize = 0;
3778 switch (coordType)
3779 {
3780 case GL_BYTE:
3781 coordTypeSize = sizeof(GLbyte);
3782 break;
3783
3784 case GL_UNSIGNED_BYTE:
3785 coordTypeSize = sizeof(GLubyte);
3786 break;
3787
3788 case GL_SHORT:
3789 coordTypeSize = sizeof(GLshort);
3790 break;
3791
3792 case GL_UNSIGNED_SHORT:
3793 coordTypeSize = sizeof(GLushort);
3794 break;
3795
3796 case GL_FLOAT:
3797 coordTypeSize = sizeof(GLfloat);
3798 break;
3799
3800 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003801 context->validationError(GL_INVALID_ENUM, kInvalidPathCoordinateType);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003802 return false;
3803 }
3804
3805 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3806 checkedSize += (coordTypeSize * numCoords);
3807 if (!checkedSize.IsValid())
3808 {
Jamie Madille0472f32018-11-27 16:32:45 -05003809 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003810 return false;
3811 }
3812
3813 // early return skips command data validation when it doesn't exist.
3814 if (!commands)
3815 return true;
3816
3817 GLsizei expectedNumCoords = 0;
3818 for (GLsizei i = 0; i < numCommands; ++i)
3819 {
3820 switch (commands[i])
3821 {
3822 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3823 break;
3824 case GL_MOVE_TO_CHROMIUM:
3825 case GL_LINE_TO_CHROMIUM:
3826 expectedNumCoords += 2;
3827 break;
3828 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3829 expectedNumCoords += 4;
3830 break;
3831 case GL_CUBIC_CURVE_TO_CHROMIUM:
3832 expectedNumCoords += 6;
3833 break;
3834 case GL_CONIC_CURVE_TO_CHROMIUM:
3835 expectedNumCoords += 5;
3836 break;
3837 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003838 context->validationError(GL_INVALID_ENUM, kInvalidPathCommand);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003839 return false;
3840 }
3841 }
Jamie Madillc3e37312018-11-30 15:25:39 -05003842
Sami Väisänene45e53b2016-05-25 10:36:04 +03003843 if (expectedNumCoords != numCoords)
3844 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003845 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCoords);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003846 return false;
3847 }
3848
3849 return true;
3850}
3851
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06003852bool ValidatePathParameterfCHROMIUM(Context *context, PathID path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003853{
3854 if (!context->getExtensions().pathRendering)
3855 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003856 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003857 return false;
3858 }
Brandon Jones59770802018-04-02 13:18:42 -07003859 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003860 {
Jamie Madille0472f32018-11-27 16:32:45 -05003861 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003862 return false;
3863 }
3864
3865 switch (pname)
3866 {
3867 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3868 if (value < 0.0f)
3869 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003870 context->validationError(GL_INVALID_VALUE, kInvalidPathStrokeWidth);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003871 return false;
3872 }
3873 break;
3874 case GL_PATH_END_CAPS_CHROMIUM:
3875 switch (static_cast<GLenum>(value))
3876 {
3877 case GL_FLAT_CHROMIUM:
3878 case GL_SQUARE_CHROMIUM:
3879 case GL_ROUND_CHROMIUM:
3880 break;
3881 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003882 context->validationError(GL_INVALID_ENUM, kInvalidPathEndCaps);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003883 return false;
3884 }
3885 break;
3886 case GL_PATH_JOIN_STYLE_CHROMIUM:
3887 switch (static_cast<GLenum>(value))
3888 {
3889 case GL_MITER_REVERT_CHROMIUM:
3890 case GL_BEVEL_CHROMIUM:
3891 case GL_ROUND_CHROMIUM:
3892 break;
3893 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003894 context->validationError(GL_INVALID_ENUM, kInvalidPathJoinStyle);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003895 return false;
3896 }
Nico Weber41b072b2018-02-09 10:01:32 -05003897 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003898 case GL_PATH_MITER_LIMIT_CHROMIUM:
3899 if (value < 0.0f)
3900 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003901 context->validationError(GL_INVALID_VALUE, kInvalidPathMiterLimit);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003902 return false;
3903 }
3904 break;
3905
3906 case GL_PATH_STROKE_BOUND_CHROMIUM:
3907 // no errors, only clamping.
3908 break;
3909
3910 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003911 context->validationError(GL_INVALID_ENUM, kInvalidPathParameter);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003912 return false;
3913 }
3914 return true;
3915}
3916
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06003917bool ValidatePathParameteriCHROMIUM(Context *context, PathID path, GLenum pname, GLint value)
Jamie Madill007530e2017-12-28 14:27:04 -05003918{
3919 // TODO(jmadill): Use proper clamping cast.
3920 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3921}
3922
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06003923bool ValidateGetPathParameterfvCHROMIUM(Context *context, PathID path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003924{
3925 if (!context->getExtensions().pathRendering)
3926 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003927 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003928 return false;
3929 }
3930
Brandon Jones59770802018-04-02 13:18:42 -07003931 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003932 {
Jamie Madille0472f32018-11-27 16:32:45 -05003933 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003934 return false;
3935 }
Jamie Madillc3e37312018-11-30 15:25:39 -05003936
Sami Väisänene45e53b2016-05-25 10:36:04 +03003937 if (!value)
3938 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003939 context->validationError(GL_INVALID_VALUE, kInvalidPathValueArray);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003940 return false;
3941 }
3942
3943 switch (pname)
3944 {
3945 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3946 case GL_PATH_END_CAPS_CHROMIUM:
3947 case GL_PATH_JOIN_STYLE_CHROMIUM:
3948 case GL_PATH_MITER_LIMIT_CHROMIUM:
3949 case GL_PATH_STROKE_BOUND_CHROMIUM:
3950 break;
3951
3952 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003953 context->validationError(GL_INVALID_ENUM, kInvalidPathParameter);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003954 return false;
3955 }
3956
3957 return true;
3958}
3959
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06003960bool ValidateGetPathParameterivCHROMIUM(Context *context, PathID path, GLenum pname, GLint *value)
Jamie Madill007530e2017-12-28 14:27:04 -05003961{
3962 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3963 reinterpret_cast<GLfloat *>(value));
3964}
3965
3966bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003967{
3968 if (!context->getExtensions().pathRendering)
3969 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003970 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003971 return false;
3972 }
3973
3974 switch (func)
3975 {
3976 case GL_NEVER:
3977 case GL_ALWAYS:
3978 case GL_LESS:
3979 case GL_LEQUAL:
3980 case GL_EQUAL:
3981 case GL_GEQUAL:
3982 case GL_GREATER:
3983 case GL_NOTEQUAL:
3984 break;
3985 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003986 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003987 return false;
3988 }
3989
3990 return true;
3991}
3992
3993// Note that the spec specifies that for the path drawing commands
3994// if the path object is not an existing path object the command
3995// does nothing and no error is generated.
3996// However if the path object exists but has not been specified any
3997// commands then an error is generated.
3998
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06003999bool ValidateStencilFillPathCHROMIUM(Context *context, PathID path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03004000{
4001 if (!context->getExtensions().pathRendering)
4002 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004003 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03004004 return false;
4005 }
Brandon Jones59770802018-04-02 13:18:42 -07004006 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03004007 {
Jamie Madille0472f32018-11-27 16:32:45 -05004008 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03004009 return false;
4010 }
4011
4012 switch (fillMode)
4013 {
Chris Daltona9dfb3b2019-06-26 18:36:10 -06004014 case GL_INVERT:
Sami Väisänene45e53b2016-05-25 10:36:04 +03004015 case GL_COUNT_UP_CHROMIUM:
4016 case GL_COUNT_DOWN_CHROMIUM:
4017 break;
4018 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004019 context->validationError(GL_INVALID_ENUM, kInvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03004020 return false;
4021 }
4022
4023 if (!isPow2(mask + 1))
4024 {
Jamie Madille0472f32018-11-27 16:32:45 -05004025 context->validationError(GL_INVALID_VALUE, kInvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03004026 return false;
4027 }
4028
4029 return true;
4030}
4031
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06004032bool ValidateStencilStrokePathCHROMIUM(Context *context, PathID path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03004033{
4034 if (!context->getExtensions().pathRendering)
4035 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004036 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03004037 return false;
4038 }
Jamie Madillc3e37312018-11-30 15:25:39 -05004039
Brandon Jones59770802018-04-02 13:18:42 -07004040 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03004041 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004042 context->validationError(GL_INVALID_OPERATION, kNoPathOrNoPathData);
Sami Väisänene45e53b2016-05-25 10:36:04 +03004043 return false;
4044 }
4045
4046 return true;
4047}
4048
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06004049bool ValidateCoverPathCHROMIUM(Context *context, PathID path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03004050{
4051 if (!context->getExtensions().pathRendering)
4052 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004053 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03004054 return false;
4055 }
Brandon Jones59770802018-04-02 13:18:42 -07004056 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03004057 {
Jamie Madille0472f32018-11-27 16:32:45 -05004058 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03004059 return false;
4060 }
4061
4062 switch (coverMode)
4063 {
4064 case GL_CONVEX_HULL_CHROMIUM:
4065 case GL_BOUNDING_BOX_CHROMIUM:
4066 break;
4067 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004068 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03004069 return false;
4070 }
4071 return true;
4072}
4073
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06004074bool ValidateCoverFillPathCHROMIUM(Context *context, PathID path, GLenum coverMode)
Jamie Madill778bf092018-11-14 09:54:36 -05004075{
4076 return ValidateCoverPathCHROMIUM(context, path, coverMode);
4077}
4078
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06004079bool ValidateCoverStrokePathCHROMIUM(Context *context, PathID path, GLenum coverMode)
Jamie Madill778bf092018-11-14 09:54:36 -05004080{
4081 return ValidateCoverPathCHROMIUM(context, path, coverMode);
4082}
4083
Jamie Madill007530e2017-12-28 14:27:04 -05004084bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06004085 PathID path,
Jamie Madill007530e2017-12-28 14:27:04 -05004086 GLenum fillMode,
4087 GLuint mask,
4088 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03004089{
Jamie Madill007530e2017-12-28 14:27:04 -05004090 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
4091 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03004092}
4093
Jamie Madill007530e2017-12-28 14:27:04 -05004094bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06004095 PathID path,
Jamie Madill007530e2017-12-28 14:27:04 -05004096 GLint reference,
4097 GLuint mask,
4098 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03004099{
Jamie Madill007530e2017-12-28 14:27:04 -05004100 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
4101 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03004102}
4103
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06004104bool ValidateIsPathCHROMIUM(Context *context, PathID path)
Sami Väisänene45e53b2016-05-25 10:36:04 +03004105{
4106 if (!context->getExtensions().pathRendering)
4107 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004108 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03004109 return false;
4110 }
4111 return true;
4112}
4113
Jamie Madill007530e2017-12-28 14:27:04 -05004114bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
4115 GLsizei numPaths,
4116 GLenum pathNameType,
4117 const void *paths,
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06004118 PathID pathBase,
Jamie Madill007530e2017-12-28 14:27:04 -05004119 GLenum coverMode,
4120 GLenum transformType,
4121 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03004122{
4123 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
4124 transformType, transformValues))
4125 return false;
4126
4127 switch (coverMode)
4128 {
4129 case GL_CONVEX_HULL_CHROMIUM:
4130 case GL_BOUNDING_BOX_CHROMIUM:
4131 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
4132 break;
4133 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004134 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03004135 return false;
4136 }
4137
4138 return true;
4139}
4140
Jamie Madill007530e2017-12-28 14:27:04 -05004141bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
4142 GLsizei numPaths,
4143 GLenum pathNameType,
4144 const void *paths,
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06004145 PathID pathBase,
Jamie Madill007530e2017-12-28 14:27:04 -05004146 GLenum coverMode,
4147 GLenum transformType,
4148 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03004149{
4150 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
4151 transformType, transformValues))
4152 return false;
4153
4154 switch (coverMode)
4155 {
4156 case GL_CONVEX_HULL_CHROMIUM:
4157 case GL_BOUNDING_BOX_CHROMIUM:
4158 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
4159 break;
4160 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004161 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03004162 return false;
4163 }
4164
4165 return true;
4166}
4167
Jamie Madill007530e2017-12-28 14:27:04 -05004168bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
4169 GLsizei numPaths,
4170 GLenum pathNameType,
4171 const void *paths,
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06004172 PathID pathBase,
Jamie Madill007530e2017-12-28 14:27:04 -05004173 GLenum fillMode,
4174 GLuint mask,
4175 GLenum transformType,
4176 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03004177{
4178
4179 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
4180 transformType, transformValues))
4181 return false;
4182
4183 switch (fillMode)
4184 {
Chris Daltona9dfb3b2019-06-26 18:36:10 -06004185 case GL_INVERT:
Sami Väisänend59ca052016-06-21 16:10:00 +03004186 case GL_COUNT_UP_CHROMIUM:
4187 case GL_COUNT_DOWN_CHROMIUM:
4188 break;
4189 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004190 context->validationError(GL_INVALID_ENUM, kInvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03004191 return false;
4192 }
4193 if (!isPow2(mask + 1))
4194 {
Jamie Madille0472f32018-11-27 16:32:45 -05004195 context->validationError(GL_INVALID_VALUE, kInvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03004196 return false;
4197 }
4198 return true;
4199}
4200
Jamie Madill007530e2017-12-28 14:27:04 -05004201bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
4202 GLsizei numPaths,
4203 GLenum pathNameType,
4204 const void *paths,
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06004205 PathID pathBase,
Jamie Madill007530e2017-12-28 14:27:04 -05004206 GLint reference,
4207 GLuint mask,
4208 GLenum transformType,
4209 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03004210{
4211 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
4212 transformType, transformValues))
4213 return false;
4214
4215 // no more validation here.
4216
4217 return true;
4218}
4219
Jamie Madill007530e2017-12-28 14:27:04 -05004220bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
4221 GLsizei numPaths,
4222 GLenum pathNameType,
4223 const void *paths,
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06004224 PathID pathBase,
Jamie Madill007530e2017-12-28 14:27:04 -05004225 GLenum fillMode,
4226 GLuint mask,
4227 GLenum coverMode,
4228 GLenum transformType,
4229 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03004230{
4231 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
4232 transformType, transformValues))
4233 return false;
4234
4235 switch (coverMode)
4236 {
4237 case GL_CONVEX_HULL_CHROMIUM:
4238 case GL_BOUNDING_BOX_CHROMIUM:
4239 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
4240 break;
4241 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004242 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03004243 return false;
4244 }
4245
4246 switch (fillMode)
4247 {
Chris Daltona9dfb3b2019-06-26 18:36:10 -06004248 case GL_INVERT:
Sami Väisänend59ca052016-06-21 16:10:00 +03004249 case GL_COUNT_UP_CHROMIUM:
4250 case GL_COUNT_DOWN_CHROMIUM:
4251 break;
4252 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004253 context->validationError(GL_INVALID_ENUM, kInvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03004254 return false;
4255 }
4256 if (!isPow2(mask + 1))
4257 {
Jamie Madille0472f32018-11-27 16:32:45 -05004258 context->validationError(GL_INVALID_VALUE, kInvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03004259 return false;
4260 }
4261
4262 return true;
4263}
4264
Jamie Madill007530e2017-12-28 14:27:04 -05004265bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
4266 GLsizei numPaths,
4267 GLenum pathNameType,
4268 const void *paths,
Jiacheng Lu7b5744f2019-08-22 16:26:35 -06004269 PathID pathBase,
Jamie Madill007530e2017-12-28 14:27:04 -05004270 GLint reference,
4271 GLuint mask,
4272 GLenum coverMode,
4273 GLenum transformType,
4274 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03004275{
4276 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
4277 transformType, transformValues))
4278 return false;
4279
4280 switch (coverMode)
4281 {
4282 case GL_CONVEX_HULL_CHROMIUM:
4283 case GL_BOUNDING_BOX_CHROMIUM:
4284 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
4285 break;
4286 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004287 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03004288 return false;
4289 }
4290
4291 return true;
4292}
4293
Jamie Madill007530e2017-12-28 14:27:04 -05004294bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
Jiacheng Lu120b61d2019-08-21 12:51:58 -06004295 ShaderProgramID program,
Jamie Madill007530e2017-12-28 14:27:04 -05004296 GLint location,
4297 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03004298{
4299 if (!context->getExtensions().pathRendering)
4300 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004301 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004302 return false;
4303 }
4304
4305 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
4306 if (location >= MaxLocation)
4307 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004308 context->validationError(GL_INVALID_VALUE, kInvalidVaryingLocation);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004309 return false;
4310 }
4311
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004312 const auto *programObject = context->getProgramNoResolveLink(program);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004313 if (!programObject)
4314 {
Jamie Madille0472f32018-11-27 16:32:45 -05004315 context->validationError(GL_INVALID_OPERATION, kProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004316 return false;
4317 }
4318
4319 if (!name)
4320 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004321 context->validationError(GL_INVALID_VALUE, kMissingName);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004322 return false;
4323 }
4324
4325 if (angle::BeginsWith(name, "gl_"))
4326 {
Jamie Madille0472f32018-11-27 16:32:45 -05004327 context->validationError(GL_INVALID_OPERATION, kNameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004328 return false;
4329 }
4330
4331 return true;
4332}
4333
Jamie Madill007530e2017-12-28 14:27:04 -05004334bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
Jiacheng Lu120b61d2019-08-21 12:51:58 -06004335 ShaderProgramID program,
Jamie Madill007530e2017-12-28 14:27:04 -05004336 GLint location,
4337 GLenum genMode,
4338 GLint components,
4339 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03004340{
4341 if (!context->getExtensions().pathRendering)
4342 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004343 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004344 return false;
4345 }
4346
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004347 const auto *programObject = context->getProgramResolveLink(program);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004348 if (!programObject || programObject->isFlaggedForDeletion())
4349 {
Jamie Madille0472f32018-11-27 16:32:45 -05004350 context->validationError(GL_INVALID_OPERATION, kProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004351 return false;
4352 }
4353
4354 if (!programObject->isLinked())
4355 {
Jamie Madille0472f32018-11-27 16:32:45 -05004356 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004357 return false;
4358 }
4359
4360 switch (genMode)
4361 {
4362 case GL_NONE:
4363 if (components != 0)
4364 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004365 context->validationError(GL_INVALID_VALUE, kInvalidComponents);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004366 return false;
4367 }
4368 break;
4369
4370 case GL_OBJECT_LINEAR_CHROMIUM:
4371 case GL_EYE_LINEAR_CHROMIUM:
4372 case GL_CONSTANT_CHROMIUM:
4373 if (components < 1 || components > 4)
4374 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004375 context->validationError(GL_INVALID_VALUE, kInvalidComponents);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004376 return false;
4377 }
4378 if (!coeffs)
4379 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004380 context->validationError(GL_INVALID_VALUE, kInvalidPathCoefficientsArray);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004381 return false;
4382 }
4383 break;
4384
4385 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05004386 context->validationError(GL_INVALID_ENUM, kInvalidPathGenMode);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004387 return false;
4388 }
4389
4390 // If the location is -1 then the command is silently ignored
4391 // and no further validation is needed.
4392 if (location == -1)
4393 return true;
4394
jchen103fd614d2018-08-13 12:21:58 +08004395 const auto &binding = programObject->getFragmentInputBindingInfo(location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004396
4397 if (!binding.valid)
4398 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004399 context->validationError(GL_INVALID_OPERATION, kInvalidFragmentInputBinding);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004400 return false;
4401 }
4402
4403 if (binding.type != GL_NONE)
4404 {
4405 GLint expectedComponents = 0;
4406 switch (binding.type)
4407 {
4408 case GL_FLOAT:
4409 expectedComponents = 1;
4410 break;
4411 case GL_FLOAT_VEC2:
4412 expectedComponents = 2;
4413 break;
4414 case GL_FLOAT_VEC3:
4415 expectedComponents = 3;
4416 break;
4417 case GL_FLOAT_VEC4:
4418 expectedComponents = 4;
4419 break;
4420 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05004421 context->validationError(GL_INVALID_OPERATION, kFragmentInputTypeNotFloatingPoint);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004422 return false;
4423 }
4424 if (expectedComponents != components && genMode != GL_NONE)
4425 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004426 context->validationError(GL_INVALID_OPERATION, kInvalidPathComponents);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004427 return false;
4428 }
4429 }
4430 return true;
4431}
4432
Geoff Lang97073d12016-04-20 10:42:34 -07004433bool ValidateCopyTextureCHROMIUM(Context *context,
Jamie Madill2ab08ed2019-08-12 16:20:21 -04004434 TextureID sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04004435 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004436 TextureTarget destTarget,
Jamie Madill2ab08ed2019-08-12 16:20:21 -04004437 TextureID destId,
Geoff Langfc72a072017-03-24 14:52:39 -04004438 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07004439 GLint internalFormat,
4440 GLenum destType,
4441 GLboolean unpackFlipY,
4442 GLboolean unpackPremultiplyAlpha,
4443 GLboolean unpackUnmultiplyAlpha)
4444{
4445 if (!context->getExtensions().copyTexture)
4446 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004447 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang97073d12016-04-20 10:42:34 -07004448 return false;
4449 }
4450
Geoff Lang4f0e0032017-05-01 16:04:35 -04004451 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004452 if (source == nullptr)
4453 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004454 context->validationError(GL_INVALID_VALUE, kInvalidSourceTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07004455 return false;
4456 }
4457
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004458 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004459 {
Jamie Madille0472f32018-11-27 16:32:45 -05004460 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004461 return false;
4462 }
4463
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004464 TextureType sourceType = source->getType();
4465 ASSERT(sourceType != TextureType::CubeMap);
4466 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004467
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004468 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004469 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004470 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureLevel);
Geoff Lang97073d12016-04-20 10:42:34 -07004471 return false;
4472 }
4473
Geoff Lang4f0e0032017-05-01 16:04:35 -04004474 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
4475 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
4476 if (sourceWidth == 0 || sourceHeight == 0)
4477 {
Jamie Madille0472f32018-11-27 16:32:45 -05004478 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004479 return false;
4480 }
4481
4482 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
4483 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004484 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004485 context->validationError(GL_INVALID_OPERATION, kInvalidSourceTextureInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004486 return false;
4487 }
4488
Geoff Lang63458a32017-10-30 15:16:53 -04004489 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4490 {
Jamie Madille0472f32018-11-27 16:32:45 -05004491 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Lang63458a32017-10-30 15:16:53 -04004492 return false;
4493 }
4494
Geoff Lang4f0e0032017-05-01 16:04:35 -04004495 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004496 if (dest == nullptr)
4497 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004498 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07004499 return false;
4500 }
4501
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004502 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004503 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004504 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTextureType);
Geoff Lang97073d12016-04-20 10:42:34 -07004505 return false;
4506 }
4507
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004508 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08004509 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004510 {
Jamie Madille0472f32018-11-27 16:32:45 -05004511 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004512 return false;
4513 }
4514
Geoff Lang97073d12016-04-20 10:42:34 -07004515 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
4516 {
Geoff Lang97073d12016-04-20 10:42:34 -07004517 return false;
4518 }
4519
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004520 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04004521 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004522 context->validationError(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004523 return false;
4524 }
4525
Geoff Lang97073d12016-04-20 10:42:34 -07004526 if (dest->getImmutableFormat())
4527 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004528 context->validationError(GL_INVALID_OPERATION, kDestinationImmutable);
Geoff Lang97073d12016-04-20 10:42:34 -07004529 return false;
4530 }
4531
4532 return true;
4533}
4534
4535bool ValidateCopySubTextureCHROMIUM(Context *context,
Jamie Madill2ab08ed2019-08-12 16:20:21 -04004536 TextureID sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04004537 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004538 TextureTarget destTarget,
Jamie Madill2ab08ed2019-08-12 16:20:21 -04004539 TextureID destId,
Geoff Langfc72a072017-03-24 14:52:39 -04004540 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07004541 GLint xoffset,
4542 GLint yoffset,
4543 GLint x,
4544 GLint y,
4545 GLsizei width,
4546 GLsizei height,
4547 GLboolean unpackFlipY,
4548 GLboolean unpackPremultiplyAlpha,
4549 GLboolean unpackUnmultiplyAlpha)
4550{
4551 if (!context->getExtensions().copyTexture)
4552 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004553 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang97073d12016-04-20 10:42:34 -07004554 return false;
4555 }
4556
Geoff Lang4f0e0032017-05-01 16:04:35 -04004557 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004558 if (source == nullptr)
4559 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004560 context->validationError(GL_INVALID_VALUE, kInvalidSourceTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07004561 return false;
4562 }
4563
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004564 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004565 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004566 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureType);
Geoff Lang97073d12016-04-20 10:42:34 -07004567 return false;
4568 }
4569
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004570 TextureType sourceType = source->getType();
4571 ASSERT(sourceType != TextureType::CubeMap);
4572 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004573
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004574 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004575 {
Jamie Madille0472f32018-11-27 16:32:45 -05004576 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004577 return false;
4578 }
4579
4580 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4581 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004582 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004583 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureLevel);
Geoff Lang97073d12016-04-20 10:42:34 -07004584 return false;
4585 }
4586
4587 if (x < 0 || y < 0)
4588 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004589 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004590 return false;
4591 }
4592
4593 if (width < 0 || height < 0)
4594 {
Jamie Madille0472f32018-11-27 16:32:45 -05004595 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004596 return false;
4597 }
4598
Geoff Lang4f0e0032017-05-01 16:04:35 -04004599 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4600 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004601 {
Jamie Madille0472f32018-11-27 16:32:45 -05004602 context->validationError(GL_INVALID_VALUE, kSourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004603 return false;
4604 }
4605
Geoff Lang4f0e0032017-05-01 16:04:35 -04004606 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4607 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004608 {
Jamie Madille0472f32018-11-27 16:32:45 -05004609 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004610 return false;
4611 }
4612
Geoff Lang63458a32017-10-30 15:16:53 -04004613 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4614 {
Jamie Madille0472f32018-11-27 16:32:45 -05004615 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Lang63458a32017-10-30 15:16:53 -04004616 return false;
4617 }
4618
Geoff Lang4f0e0032017-05-01 16:04:35 -04004619 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004620 if (dest == nullptr)
4621 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004622 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07004623 return false;
4624 }
4625
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004626 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004627 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004628 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTextureType);
Geoff Lang97073d12016-04-20 10:42:34 -07004629 return false;
4630 }
4631
Brandon Jones28783792018-03-05 09:37:32 -08004632 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4633 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004634 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004635 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Lang97073d12016-04-20 10:42:34 -07004636 return false;
4637 }
4638
Geoff Lang4f0e0032017-05-01 16:04:35 -04004639 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4640 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004641 context->validationError(GL_INVALID_OPERATION, kDestinationLevelNotDefined);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004642 return false;
4643 }
4644
4645 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4646 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004647 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004648 context->validationError(GL_INVALID_OPERATION, kInvalidFormatCombination);
Geoff Lang97073d12016-04-20 10:42:34 -07004649 return false;
4650 }
4651
4652 if (xoffset < 0 || yoffset < 0)
4653 {
Jamie Madille0472f32018-11-27 16:32:45 -05004654 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004655 return false;
4656 }
4657
Geoff Lang4f0e0032017-05-01 16:04:35 -04004658 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4659 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004660 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004661 context->validationError(GL_INVALID_VALUE, kOffsetOverflow);
Geoff Lang97073d12016-04-20 10:42:34 -07004662 return false;
4663 }
4664
4665 return true;
4666}
4667
Jamie Madill2ab08ed2019-08-12 16:20:21 -04004668bool ValidateCompressedCopyTextureCHROMIUM(Context *context, TextureID sourceId, TextureID destId)
Geoff Lang47110bf2016-04-20 11:13:22 -07004669{
4670 if (!context->getExtensions().copyCompressedTexture)
4671 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004672 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang47110bf2016-04-20 11:13:22 -07004673 return false;
4674 }
4675
4676 const gl::Texture *source = context->getTexture(sourceId);
4677 if (source == nullptr)
4678 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004679 context->validationError(GL_INVALID_VALUE, kInvalidSourceTexture);
Geoff Lang47110bf2016-04-20 11:13:22 -07004680 return false;
4681 }
4682
Corentin Wallez99d492c2018-02-27 15:17:10 -05004683 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004684 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004685 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureType);
Geoff Lang47110bf2016-04-20 11:13:22 -07004686 return false;
4687 }
4688
Corentin Wallez99d492c2018-02-27 15:17:10 -05004689 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4690 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004691 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004692 context->validationError(GL_INVALID_VALUE, kSourceTextureLevelZeroDefined);
Geoff Lang47110bf2016-04-20 11:13:22 -07004693 return false;
4694 }
4695
Corentin Wallez99d492c2018-02-27 15:17:10 -05004696 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004697 if (!sourceFormat.info->compressed)
4698 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004699 context->validationError(GL_INVALID_OPERATION, kSourceTextureMustBeCompressed);
Geoff Lang47110bf2016-04-20 11:13:22 -07004700 return false;
4701 }
4702
4703 const gl::Texture *dest = context->getTexture(destId);
4704 if (dest == nullptr)
4705 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004706 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTexture);
Geoff Lang47110bf2016-04-20 11:13:22 -07004707 return false;
4708 }
4709
Corentin Wallez99d492c2018-02-27 15:17:10 -05004710 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004711 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004712 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTextureType);
Geoff Lang47110bf2016-04-20 11:13:22 -07004713 return false;
4714 }
4715
4716 if (dest->getImmutableFormat())
4717 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004718 context->validationError(GL_INVALID_OPERATION, kDestinationImmutable);
Geoff Lang47110bf2016-04-20 11:13:22 -07004719 return false;
4720 }
4721
4722 return true;
4723}
4724
Jiawei Shao385b3e02018-03-21 09:43:28 +08004725bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004726{
4727 switch (type)
4728 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004729 case ShaderType::Vertex:
4730 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004731 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004732
Jiawei Shao385b3e02018-03-21 09:43:28 +08004733 case ShaderType::Compute:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004734 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004735 {
Jamie Madille0472f32018-11-27 16:32:45 -05004736 context->validationError(GL_INVALID_ENUM, kES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004737 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004738 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004739 break;
4740
Jiawei Shao385b3e02018-03-21 09:43:28 +08004741 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004742 if (!context->getExtensions().geometryShader)
4743 {
Jamie Madille0472f32018-11-27 16:32:45 -05004744 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
Jiawei Shao89be29a2017-11-06 14:36:45 +08004745 return false;
4746 }
4747 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004748 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004749 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004750 return false;
4751 }
Jamie Madill29639852016-09-02 15:00:09 -04004752
4753 return true;
4754}
4755
Jamie Madill5b772312018-03-08 20:28:32 -05004756bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004757 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004758 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004759 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004760 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004761{
4762 if (size < 0)
4763 {
Jamie Madille0472f32018-11-27 16:32:45 -05004764 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004765 return false;
4766 }
4767
4768 switch (usage)
4769 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004770 case BufferUsage::StreamDraw:
4771 case BufferUsage::StaticDraw:
4772 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004773 break;
4774
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004775 case BufferUsage::StreamRead:
4776 case BufferUsage::StaticRead:
4777 case BufferUsage::DynamicRead:
4778 case BufferUsage::StreamCopy:
4779 case BufferUsage::StaticCopy:
4780 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004781 if (context->getClientMajorVersion() < 3)
4782 {
Jamie Madille0472f32018-11-27 16:32:45 -05004783 context->validationError(GL_INVALID_ENUM, kInvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004784 return false;
4785 }
4786 break;
4787
4788 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004789 context->validationError(GL_INVALID_ENUM, kInvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004790 return false;
4791 }
4792
Corentin Walleze4477002017-12-01 14:39:58 -05004793 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004794 {
Jamie Madille0472f32018-11-27 16:32:45 -05004795 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004796 return false;
4797 }
4798
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004799 Buffer *buffer = context->getState().getTargetBuffer(target);
Jamie Madill29639852016-09-02 15:00:09 -04004800
4801 if (!buffer)
4802 {
Jamie Madille0472f32018-11-27 16:32:45 -05004803 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004804 return false;
4805 }
4806
James Darpiniane8a93c62018-01-04 18:02:24 -08004807 if (context->getExtensions().webglCompatibility &&
4808 buffer->isBoundForTransformFeedbackAndOtherUse())
4809 {
Jamie Madille0472f32018-11-27 16:32:45 -05004810 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08004811 return false;
4812 }
4813
Jamie Madill29639852016-09-02 15:00:09 -04004814 return true;
4815}
4816
Jamie Madill5b772312018-03-08 20:28:32 -05004817bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004818 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004819 GLintptr offset,
4820 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004821 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004822{
Brandon Jones6cad5662017-06-14 13:25:13 -07004823 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004824 {
Jamie Madille0472f32018-11-27 16:32:45 -05004825 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Brandon Jones6cad5662017-06-14 13:25:13 -07004826 return false;
4827 }
4828
4829 if (offset < 0)
4830 {
Jamie Madille0472f32018-11-27 16:32:45 -05004831 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004832 return false;
4833 }
4834
Corentin Walleze4477002017-12-01 14:39:58 -05004835 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004836 {
Jamie Madille0472f32018-11-27 16:32:45 -05004837 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004838 return false;
4839 }
4840
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004841 Buffer *buffer = context->getState().getTargetBuffer(target);
Jamie Madill29639852016-09-02 15:00:09 -04004842
4843 if (!buffer)
4844 {
Jamie Madille0472f32018-11-27 16:32:45 -05004845 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004846 return false;
4847 }
4848
4849 if (buffer->isMapped())
4850 {
Jamie Madille0472f32018-11-27 16:32:45 -05004851 context->validationError(GL_INVALID_OPERATION, kBufferMapped);
Jamie Madill29639852016-09-02 15:00:09 -04004852 return false;
4853 }
4854
James Darpiniane8a93c62018-01-04 18:02:24 -08004855 if (context->getExtensions().webglCompatibility &&
4856 buffer->isBoundForTransformFeedbackAndOtherUse())
4857 {
Jamie Madille0472f32018-11-27 16:32:45 -05004858 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08004859 return false;
4860 }
4861
Jamie Madill29639852016-09-02 15:00:09 -04004862 // Check for possible overflow of size + offset
4863 angle::CheckedNumeric<size_t> checkedSize(size);
4864 checkedSize += offset;
4865 if (!checkedSize.IsValid())
4866 {
Jamie Madille0472f32018-11-27 16:32:45 -05004867 context->validationError(GL_INVALID_VALUE, kParamOverflow);
Jamie Madill29639852016-09-02 15:00:09 -04004868 return false;
4869 }
4870
4871 if (size + offset > buffer->getSize())
4872 {
Jamie Madille0472f32018-11-27 16:32:45 -05004873 context->validationError(GL_INVALID_VALUE, kInsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004874 return false;
4875 }
4876
Martin Radev4c4c8e72016-08-04 12:25:34 +03004877 return true;
4878}
4879
Geoff Lang111a99e2017-10-17 10:58:41 -04004880bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004881{
Geoff Langc339c4e2016-11-29 10:37:36 -05004882 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004883 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004884 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langc287ea62016-09-16 14:46:51 -04004885 return false;
4886 }
4887
Geoff Lang111a99e2017-10-17 10:58:41 -04004888 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004889 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004890 context->validationError(GL_INVALID_OPERATION, kExtensionNotRequestable);
Geoff Langc287ea62016-09-16 14:46:51 -04004891 return false;
4892 }
4893
4894 return true;
4895}
4896
Jamie Madill5b772312018-03-08 20:28:32 -05004897bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004898{
Lingfeng Yang038dd532018-03-29 17:31:52 -07004899 if (context->getClientMajorVersion() < 2)
4900 {
4901 return ValidateMultitextureUnit(context, texture);
4902 }
4903
Jamie Madillef300b12016-10-07 15:12:09 -04004904 if (texture < GL_TEXTURE0 ||
4905 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4906 {
Jamie Madille0472f32018-11-27 16:32:45 -05004907 context->validationError(GL_INVALID_ENUM, kInvalidCombinedImageUnit);
Jamie Madillef300b12016-10-07 15:12:09 -04004908 return false;
4909 }
4910
4911 return true;
4912}
4913
Jiacheng Lu120b61d2019-08-21 12:51:58 -06004914bool ValidateAttachShader(Context *context, ShaderProgramID program, ShaderProgramID shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004915{
4916 Program *programObject = GetValidProgram(context, program);
4917 if (!programObject)
4918 {
4919 return false;
4920 }
4921
4922 Shader *shaderObject = GetValidShader(context, shader);
4923 if (!shaderObject)
4924 {
4925 return false;
4926 }
4927
Jiawei Shao385b3e02018-03-21 09:43:28 +08004928 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04004929 {
Jamie Madille0472f32018-11-27 16:32:45 -05004930 context->validationError(GL_INVALID_OPERATION, kShaderAttachmentHasShader);
Jiawei Shao385b3e02018-03-21 09:43:28 +08004931 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04004932 }
4933
4934 return true;
4935}
4936
Jiacheng Lu120b61d2019-08-21 12:51:58 -06004937bool ValidateBindAttribLocation(Context *context,
4938 ShaderProgramID program,
4939 GLuint index,
4940 const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004941{
4942 if (index >= MAX_VERTEX_ATTRIBS)
4943 {
Jamie Madille0472f32018-11-27 16:32:45 -05004944 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004945 return false;
4946 }
4947
4948 if (strncmp(name, "gl_", 3) == 0)
4949 {
Jamie Madille0472f32018-11-27 16:32:45 -05004950 context->validationError(GL_INVALID_OPERATION, kNameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004951 return false;
4952 }
4953
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004954 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004955 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004956 const size_t length = strlen(name);
4957
4958 if (!IsValidESSLString(name, length))
4959 {
4960 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4961 // for shader-related entry points
Jamie Madille0472f32018-11-27 16:32:45 -05004962 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004963 return false;
4964 }
4965
4966 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4967 {
4968 return false;
4969 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004970 }
4971
Jamie Madill01a80ee2016-11-07 12:06:18 -05004972 return GetValidProgram(context, program) != nullptr;
4973}
4974
Jamie Madill5b772312018-03-08 20:28:32 -05004975bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004976{
Geoff Lange8afa902017-09-27 15:00:43 -04004977 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004978 {
Jamie Madille0472f32018-11-27 16:32:45 -05004979 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004980 return false;
4981 }
4982
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004983 if (!context->getState().isBindGeneratesResourceEnabled() &&
Jamie Madill01a80ee2016-11-07 12:06:18 -05004984 !context->isFramebufferGenerated(framebuffer))
4985 {
Jamie Madille0472f32018-11-27 16:32:45 -05004986 context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004987 return false;
4988 }
4989
4990 return true;
4991}
4992
Jamie Madill7c7dec02019-08-06 17:44:11 -04004993bool ValidateBindRenderbuffer(Context *context, GLenum target, RenderbufferID renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004994{
4995 if (target != GL_RENDERBUFFER)
4996 {
Jamie Madille0472f32018-11-27 16:32:45 -05004997 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004998 return false;
4999 }
5000
Jamie Madillc3dc5d42018-12-30 12:12:04 -05005001 if (!context->getState().isBindGeneratesResourceEnabled() &&
Jamie Madill01a80ee2016-11-07 12:06:18 -05005002 !context->isRenderbufferGenerated(renderbuffer))
5003 {
Jamie Madille0472f32018-11-27 16:32:45 -05005004 context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05005005 return false;
5006 }
5007
5008 return true;
5009}
5010
Jamie Madill5b772312018-03-08 20:28:32 -05005011static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005012{
5013 switch (mode)
5014 {
5015 case GL_FUNC_ADD:
5016 case GL_FUNC_SUBTRACT:
5017 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04005018 return true;
5019
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005020 case GL_MIN:
5021 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04005022 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005023
5024 default:
5025 return false;
5026 }
5027}
5028
Jamie Madill5b772312018-03-08 20:28:32 -05005029bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005030{
5031 return true;
5032}
5033
Jamie Madill5b772312018-03-08 20:28:32 -05005034bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005035{
Geoff Lang50cac572017-09-26 17:37:43 -04005036 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005037 {
Jamie Madille0472f32018-11-27 16:32:45 -05005038 context->validationError(GL_INVALID_ENUM, kInvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005039 return false;
5040 }
5041
5042 return true;
5043}
5044
Jamie Madill5b772312018-03-08 20:28:32 -05005045bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005046{
Geoff Lang50cac572017-09-26 17:37:43 -04005047 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005048 {
Jamie Madille0472f32018-11-27 16:32:45 -05005049 context->validationError(GL_INVALID_ENUM, kInvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005050 return false;
5051 }
5052
Geoff Lang50cac572017-09-26 17:37:43 -04005053 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005054 {
Jamie Madille0472f32018-11-27 16:32:45 -05005055 context->validationError(GL_INVALID_ENUM, kInvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005056 return false;
5057 }
5058
5059 return true;
5060}
5061
Jamie Madill5b772312018-03-08 20:28:32 -05005062bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005063{
5064 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
5065}
5066
Jamie Madill5b772312018-03-08 20:28:32 -05005067bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005068 GLenum srcRGB,
5069 GLenum dstRGB,
5070 GLenum srcAlpha,
5071 GLenum dstAlpha)
5072{
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03005073 if (!ValidSrcBlendFunc(context, srcRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005074 {
Jamie Madille0472f32018-11-27 16:32:45 -05005075 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005076 return false;
5077 }
5078
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03005079 if (!ValidDstBlendFunc(context, dstRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005080 {
Jamie Madille0472f32018-11-27 16:32:45 -05005081 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005082 return false;
5083 }
5084
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03005085 if (!ValidSrcBlendFunc(context, srcAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005086 {
Jamie Madille0472f32018-11-27 16:32:45 -05005087 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005088 return false;
5089 }
5090
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03005091 if (!ValidDstBlendFunc(context, dstAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005092 {
Jamie Madille0472f32018-11-27 16:32:45 -05005093 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005094 return false;
5095 }
5096
Frank Henigman146e8a12017-03-02 23:22:37 -05005097 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
5098 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005099 {
5100 bool constantColorUsed =
5101 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
5102 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
5103
5104 bool constantAlphaUsed =
5105 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
5106 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
5107
5108 if (constantColorUsed && constantAlphaUsed)
5109 {
Frank Henigman146e8a12017-03-02 23:22:37 -05005110 if (context->getExtensions().webglCompatibility)
5111 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005112 context->validationError(GL_INVALID_OPERATION, kInvalidConstantColor);
5113 return false;
Frank Henigman146e8a12017-03-02 23:22:37 -05005114 }
Jamie Madillc3e37312018-11-30 15:25:39 -05005115
5116 WARN() << kConstantColorAlphaLimitation;
5117 context->validationError(GL_INVALID_OPERATION, kConstantColorAlphaLimitation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05005118 return false;
5119 }
5120 }
5121
5122 return true;
5123}
5124
Geoff Langc339c4e2016-11-29 10:37:36 -05005125bool ValidateGetString(Context *context, GLenum name)
5126{
5127 switch (name)
5128 {
5129 case GL_VENDOR:
5130 case GL_RENDERER:
5131 case GL_VERSION:
5132 case GL_SHADING_LANGUAGE_VERSION:
5133 case GL_EXTENSIONS:
5134 break;
5135
5136 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
5137 if (!context->getExtensions().requestExtension)
5138 {
Jamie Madille0472f32018-11-27 16:32:45 -05005139 context->validationError(GL_INVALID_ENUM, kInvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05005140 return false;
5141 }
5142 break;
5143
5144 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005145 context->validationError(GL_INVALID_ENUM, kInvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05005146 return false;
5147 }
5148
5149 return true;
5150}
5151
Jamie Madill5b772312018-03-08 20:28:32 -05005152bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05005153{
5154 if (width <= 0.0f || isNaN(width))
5155 {
Jamie Madille0472f32018-11-27 16:32:45 -05005156 context->validationError(GL_INVALID_VALUE, kInvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05005157 return false;
5158 }
5159
5160 return true;
5161}
5162
Jamie Madill5b772312018-03-08 20:28:32 -05005163bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05005164{
5165 if (context->getExtensions().webglCompatibility && zNear > zFar)
5166 {
Jamie Madille0472f32018-11-27 16:32:45 -05005167 context->validationError(GL_INVALID_OPERATION, kInvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05005168 return false;
5169 }
5170
5171 return true;
5172}
5173
Jamie Madill5b772312018-03-08 20:28:32 -05005174bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05005175 GLenum target,
5176 GLenum internalformat,
5177 GLsizei width,
5178 GLsizei height)
5179{
5180 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
5181 height);
5182}
5183
Jamie Madill5b772312018-03-08 20:28:32 -05005184bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05005185 GLenum target,
5186 GLsizei samples,
5187 GLenum internalformat,
5188 GLsizei width,
5189 GLsizei height)
5190{
5191 if (!context->getExtensions().framebufferMultisample)
5192 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005193 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madille8fb6402017-02-14 17:56:40 -05005194 return false;
5195 }
5196
5197 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
Jamie Madill610640f2018-11-21 17:28:41 -05005198 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_VALUE is
Jamie Madille8fb6402017-02-14 17:56:40 -05005199 // generated.
5200 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
5201 {
Jamie Madille0472f32018-11-27 16:32:45 -05005202 context->validationError(GL_INVALID_VALUE, kSamplesOutOfRange);
Jamie Madille8fb6402017-02-14 17:56:40 -05005203 return false;
5204 }
5205
5206 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
5207 // the specified storage. This is different than ES 3.0 in which a sample number higher
5208 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
5209 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
5210 if (context->getClientMajorVersion() >= 3)
5211 {
5212 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
5213 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
5214 {
Jamie Madille0472f32018-11-27 16:32:45 -05005215 context->validationError(GL_OUT_OF_MEMORY, kSamplesOutOfRange);
Jamie Madille8fb6402017-02-14 17:56:40 -05005216 return false;
5217 }
5218 }
5219
5220 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
5221 width, height);
5222}
5223
Jamie Madill5b772312018-03-08 20:28:32 -05005224bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005225{
Geoff Lange8afa902017-09-27 15:00:43 -04005226 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04005227 {
Jamie Madille0472f32018-11-27 16:32:45 -05005228 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005229 return false;
5230 }
5231
5232 return true;
5233}
5234
Jamie Madill5b772312018-03-08 20:28:32 -05005235bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005236{
5237 return true;
5238}
5239
Jamie Madill5b772312018-03-08 20:28:32 -05005240bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005241{
5242 return true;
5243}
5244
Jamie Madill5b772312018-03-08 20:28:32 -05005245bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005246{
5247 return true;
5248}
5249
Jamie Madill5b772312018-03-08 20:28:32 -05005250bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005251 GLboolean red,
5252 GLboolean green,
5253 GLboolean blue,
5254 GLboolean alpha)
5255{
5256 return true;
5257}
5258
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005259bool ValidateCompileShader(Context *context, ShaderProgramID shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005260{
5261 return true;
5262}
5263
Jamie Madill5b772312018-03-08 20:28:32 -05005264bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005265{
5266 return true;
5267}
5268
Jamie Madill5b772312018-03-08 20:28:32 -05005269bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005270{
5271 switch (mode)
5272 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04005273 case CullFaceMode::Front:
5274 case CullFaceMode::Back:
5275 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04005276 break;
5277
5278 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005279 context->validationError(GL_INVALID_ENUM, kInvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005280 return false;
5281 }
5282
5283 return true;
5284}
5285
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005286bool ValidateDeleteProgram(Context *context, ShaderProgramID program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005287{
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005288 if (program.value == 0)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005289 {
5290 return false;
5291 }
5292
Jamie Madill44a6fbf2018-10-02 13:38:56 -04005293 if (!context->getProgramResolveLink(program))
Jamie Madillc1d770e2017-04-13 17:31:24 -04005294 {
5295 if (context->getShader(program))
5296 {
Jamie Madille0472f32018-11-27 16:32:45 -05005297 context->validationError(GL_INVALID_OPERATION, kExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005298 return false;
5299 }
5300 else
5301 {
Jamie Madille0472f32018-11-27 16:32:45 -05005302 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005303 return false;
5304 }
5305 }
5306
5307 return true;
5308}
5309
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005310bool ValidateDeleteShader(Context *context, ShaderProgramID shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005311{
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005312 if (shader.value == 0)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005313 {
5314 return false;
5315 }
5316
5317 if (!context->getShader(shader))
5318 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04005319 if (context->getProgramResolveLink(shader))
Jamie Madillc1d770e2017-04-13 17:31:24 -04005320 {
Jamie Madille0472f32018-11-27 16:32:45 -05005321 context->validationError(GL_INVALID_OPERATION, kInvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005322 return false;
5323 }
5324 else
5325 {
Jamie Madille0472f32018-11-27 16:32:45 -05005326 context->validationError(GL_INVALID_VALUE, kExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005327 return false;
5328 }
5329 }
5330
5331 return true;
5332}
5333
Jamie Madill5b772312018-03-08 20:28:32 -05005334bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005335{
5336 switch (func)
5337 {
5338 case GL_NEVER:
5339 case GL_ALWAYS:
5340 case GL_LESS:
5341 case GL_LEQUAL:
5342 case GL_EQUAL:
5343 case GL_GREATER:
5344 case GL_GEQUAL:
5345 case GL_NOTEQUAL:
5346 break;
5347
5348 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005349 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005350 return false;
5351 }
5352
5353 return true;
5354}
5355
Jamie Madill5b772312018-03-08 20:28:32 -05005356bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005357{
5358 return true;
5359}
5360
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005361bool ValidateDetachShader(Context *context, ShaderProgramID program, ShaderProgramID shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005362{
5363 Program *programObject = GetValidProgram(context, program);
5364 if (!programObject)
5365 {
5366 return false;
5367 }
5368
5369 Shader *shaderObject = GetValidShader(context, shader);
5370 if (!shaderObject)
5371 {
5372 return false;
5373 }
5374
Jiawei Shao385b3e02018-03-21 09:43:28 +08005375 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005376 if (attachedShader != shaderObject)
5377 {
Jamie Madille0472f32018-11-27 16:32:45 -05005378 context->validationError(GL_INVALID_OPERATION, kShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005379 return false;
5380 }
5381
5382 return true;
5383}
5384
Jamie Madill5b772312018-03-08 20:28:32 -05005385bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005386{
5387 if (index >= MAX_VERTEX_ATTRIBS)
5388 {
Jamie Madille0472f32018-11-27 16:32:45 -05005389 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005390 return false;
5391 }
5392
5393 return true;
5394}
5395
Jamie Madill5b772312018-03-08 20:28:32 -05005396bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005397{
5398 if (index >= MAX_VERTEX_ATTRIBS)
5399 {
Jamie Madille0472f32018-11-27 16:32:45 -05005400 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005401 return false;
5402 }
5403
5404 return true;
5405}
5406
Jamie Madill5b772312018-03-08 20:28:32 -05005407bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005408{
5409 return true;
5410}
5411
Jamie Madill5b772312018-03-08 20:28:32 -05005412bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005413{
5414 return true;
5415}
5416
Jamie Madill5b772312018-03-08 20:28:32 -05005417bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005418{
5419 switch (mode)
5420 {
5421 case GL_CW:
5422 case GL_CCW:
5423 break;
5424 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005425 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005426 return false;
5427 }
5428
5429 return true;
5430}
5431
Jamie Madill5b772312018-03-08 20:28:32 -05005432bool ValidateGetActiveAttrib(Context *context,
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005433 ShaderProgramID program,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005434 GLuint index,
5435 GLsizei bufsize,
5436 GLsizei *length,
5437 GLint *size,
5438 GLenum *type,
5439 GLchar *name)
5440{
5441 if (bufsize < 0)
5442 {
Jamie Madille0472f32018-11-27 16:32:45 -05005443 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005444 return false;
5445 }
5446
5447 Program *programObject = GetValidProgram(context, program);
5448
5449 if (!programObject)
5450 {
5451 return false;
5452 }
5453
5454 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5455 {
Jamie Madille0472f32018-11-27 16:32:45 -05005456 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005457 return false;
5458 }
5459
5460 return true;
5461}
5462
Jamie Madill5b772312018-03-08 20:28:32 -05005463bool ValidateGetActiveUniform(Context *context,
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005464 ShaderProgramID program,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005465 GLuint index,
5466 GLsizei bufsize,
5467 GLsizei *length,
5468 GLint *size,
5469 GLenum *type,
5470 GLchar *name)
5471{
5472 if (bufsize < 0)
5473 {
Jamie Madille0472f32018-11-27 16:32:45 -05005474 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005475 return false;
5476 }
5477
5478 Program *programObject = GetValidProgram(context, program);
5479
5480 if (!programObject)
5481 {
5482 return false;
5483 }
5484
5485 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5486 {
Jamie Madille0472f32018-11-27 16:32:45 -05005487 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005488 return false;
5489 }
5490
5491 return true;
5492}
5493
Jamie Madill5b772312018-03-08 20:28:32 -05005494bool ValidateGetAttachedShaders(Context *context,
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005495 ShaderProgramID program,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005496 GLsizei maxcount,
5497 GLsizei *count,
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005498 ShaderProgramID *shaders)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005499{
5500 if (maxcount < 0)
5501 {
Jamie Madille0472f32018-11-27 16:32:45 -05005502 context->validationError(GL_INVALID_VALUE, kNegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005503 return false;
5504 }
5505
5506 Program *programObject = GetValidProgram(context, program);
5507
5508 if (!programObject)
5509 {
5510 return false;
5511 }
5512
5513 return true;
5514}
5515
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005516bool ValidateGetAttribLocation(Context *context, ShaderProgramID program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005517{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005518 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5519 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005520 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005521 {
Jamie Madille0472f32018-11-27 16:32:45 -05005522 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005523 return false;
5524 }
5525
Jamie Madillc1d770e2017-04-13 17:31:24 -04005526 Program *programObject = GetValidProgram(context, program);
5527
5528 if (!programObject)
5529 {
Jamie Madille0472f32018-11-27 16:32:45 -05005530 context->validationError(GL_INVALID_OPERATION, kProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005531 return false;
5532 }
5533
5534 if (!programObject->isLinked())
5535 {
Jamie Madille0472f32018-11-27 16:32:45 -05005536 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005537 return false;
5538 }
5539
5540 return true;
5541}
5542
Jamie Madill5b772312018-03-08 20:28:32 -05005543bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005544{
5545 GLenum nativeType;
5546 unsigned int numParams = 0;
5547 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5548}
5549
Jamie Madill5b772312018-03-08 20:28:32 -05005550bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005551{
5552 return true;
5553}
5554
Jamie Madill5b772312018-03-08 20:28:32 -05005555bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005556{
5557 GLenum nativeType;
5558 unsigned int numParams = 0;
5559 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5560}
5561
Jamie Madill5b772312018-03-08 20:28:32 -05005562bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005563{
5564 GLenum nativeType;
5565 unsigned int numParams = 0;
5566 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5567}
5568
Jamie Madill5b772312018-03-08 20:28:32 -05005569bool ValidateGetProgramInfoLog(Context *context,
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005570 ShaderProgramID program,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005571 GLsizei bufsize,
5572 GLsizei *length,
5573 GLchar *infolog)
5574{
5575 if (bufsize < 0)
5576 {
Jamie Madille0472f32018-11-27 16:32:45 -05005577 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005578 return false;
5579 }
5580
5581 Program *programObject = GetValidProgram(context, program);
5582 if (!programObject)
5583 {
5584 return false;
5585 }
5586
5587 return true;
5588}
5589
Jamie Madill5b772312018-03-08 20:28:32 -05005590bool ValidateGetShaderInfoLog(Context *context,
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005591 ShaderProgramID shader,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005592 GLsizei bufsize,
5593 GLsizei *length,
5594 GLchar *infolog)
5595{
5596 if (bufsize < 0)
5597 {
Jamie Madille0472f32018-11-27 16:32:45 -05005598 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005599 return false;
5600 }
5601
5602 Shader *shaderObject = GetValidShader(context, shader);
5603 if (!shaderObject)
5604 {
5605 return false;
5606 }
5607
5608 return true;
5609}
5610
Jamie Madill5b772312018-03-08 20:28:32 -05005611bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005612 GLenum shadertype,
5613 GLenum precisiontype,
5614 GLint *range,
5615 GLint *precision)
5616{
5617 switch (shadertype)
5618 {
5619 case GL_VERTEX_SHADER:
5620 case GL_FRAGMENT_SHADER:
5621 break;
5622 case GL_COMPUTE_SHADER:
Jamie Madillc3e37312018-11-30 15:25:39 -05005623 context->validationError(GL_INVALID_OPERATION, kUnimplementedComputeShaderPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005624 return false;
5625 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005626 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005627 return false;
5628 }
5629
5630 switch (precisiontype)
5631 {
5632 case GL_LOW_FLOAT:
5633 case GL_MEDIUM_FLOAT:
5634 case GL_HIGH_FLOAT:
5635 case GL_LOW_INT:
5636 case GL_MEDIUM_INT:
5637 case GL_HIGH_INT:
5638 break;
5639
5640 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005641 context->validationError(GL_INVALID_ENUM, kInvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005642 return false;
5643 }
5644
5645 return true;
5646}
5647
Jamie Madill5b772312018-03-08 20:28:32 -05005648bool ValidateGetShaderSource(Context *context,
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005649 ShaderProgramID shader,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005650 GLsizei bufsize,
5651 GLsizei *length,
5652 GLchar *source)
5653{
5654 if (bufsize < 0)
5655 {
Jamie Madille0472f32018-11-27 16:32:45 -05005656 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005657 return false;
5658 }
5659
5660 Shader *shaderObject = GetValidShader(context, shader);
5661 if (!shaderObject)
5662 {
5663 return false;
5664 }
5665
5666 return true;
5667}
5668
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005669bool ValidateGetUniformLocation(Context *context, ShaderProgramID program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005670{
5671 if (strstr(name, "gl_") == name)
5672 {
5673 return false;
5674 }
5675
Geoff Langfc32e8b2017-05-31 14:16:59 -04005676 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5677 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005678 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005679 {
Jamie Madille0472f32018-11-27 16:32:45 -05005680 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005681 return false;
5682 }
5683
Jamie Madillc1d770e2017-04-13 17:31:24 -04005684 Program *programObject = GetValidProgram(context, program);
5685
5686 if (!programObject)
5687 {
5688 return false;
5689 }
5690
5691 if (!programObject->isLinked())
5692 {
Jamie Madille0472f32018-11-27 16:32:45 -05005693 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005694 return false;
5695 }
5696
5697 return true;
5698}
5699
Jamie Madill5b772312018-03-08 20:28:32 -05005700bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005701{
5702 switch (mode)
5703 {
5704 case GL_FASTEST:
5705 case GL_NICEST:
5706 case GL_DONT_CARE:
5707 break;
5708
5709 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005710 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005711 return false;
5712 }
5713
5714 switch (target)
5715 {
5716 case GL_GENERATE_MIPMAP_HINT:
5717 break;
5718
Geoff Lange7bd2182017-06-16 16:13:13 -04005719 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5720 if (context->getClientVersion() < ES_3_0 &&
5721 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005722 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005723 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005724 return false;
5725 }
5726 break;
5727
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07005728 case GL_PERSPECTIVE_CORRECTION_HINT:
5729 case GL_POINT_SMOOTH_HINT:
5730 case GL_LINE_SMOOTH_HINT:
5731 case GL_FOG_HINT:
5732 if (context->getClientMajorVersion() >= 2)
5733 {
Jamie Madille0472f32018-11-27 16:32:45 -05005734 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07005735 return false;
5736 }
5737 break;
5738
Jamie Madillc1d770e2017-04-13 17:31:24 -04005739 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005740 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005741 return false;
5742 }
5743
5744 return true;
5745}
5746
Jamie Madill3b3fe832019-08-06 17:44:12 -04005747bool ValidateIsBuffer(Context *context, BufferID buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005748{
5749 return true;
5750}
5751
Jamie Madill5b772312018-03-08 20:28:32 -05005752bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005753{
5754 return true;
5755}
5756
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005757bool ValidateIsProgram(Context *context, ShaderProgramID program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005758{
5759 return true;
5760}
5761
Jamie Madill7c7dec02019-08-06 17:44:11 -04005762bool ValidateIsRenderbuffer(Context *context, RenderbufferID renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005763{
5764 return true;
5765}
5766
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005767bool ValidateIsShader(Context *context, ShaderProgramID shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005768{
5769 return true;
5770}
5771
Jamie Madill2ab08ed2019-08-12 16:20:21 -04005772bool ValidateIsTexture(Context *context, TextureID texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005773{
5774 return true;
5775}
5776
Jamie Madill5b772312018-03-08 20:28:32 -05005777bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005778{
5779 if (context->getClientMajorVersion() < 3)
5780 {
5781 switch (pname)
5782 {
5783 case GL_UNPACK_IMAGE_HEIGHT:
5784 case GL_UNPACK_SKIP_IMAGES:
Jamie Madille0472f32018-11-27 16:32:45 -05005785 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005786 return false;
5787
5788 case GL_UNPACK_ROW_LENGTH:
5789 case GL_UNPACK_SKIP_ROWS:
5790 case GL_UNPACK_SKIP_PIXELS:
5791 if (!context->getExtensions().unpackSubimage)
5792 {
Jamie Madille0472f32018-11-27 16:32:45 -05005793 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005794 return false;
5795 }
5796 break;
5797
5798 case GL_PACK_ROW_LENGTH:
5799 case GL_PACK_SKIP_ROWS:
5800 case GL_PACK_SKIP_PIXELS:
5801 if (!context->getExtensions().packSubimage)
5802 {
Jamie Madille0472f32018-11-27 16:32:45 -05005803 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005804 return false;
5805 }
5806 break;
5807 }
5808 }
5809
5810 if (param < 0)
5811 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005812 context->validationError(GL_INVALID_VALUE, kNegativeParam);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005813 return false;
5814 }
5815
5816 switch (pname)
5817 {
5818 case GL_UNPACK_ALIGNMENT:
5819 if (param != 1 && param != 2 && param != 4 && param != 8)
5820 {
Jamie Madille0472f32018-11-27 16:32:45 -05005821 context->validationError(GL_INVALID_VALUE, kInvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005822 return false;
5823 }
5824 break;
5825
5826 case GL_PACK_ALIGNMENT:
5827 if (param != 1 && param != 2 && param != 4 && param != 8)
5828 {
Jamie Madille0472f32018-11-27 16:32:45 -05005829 context->validationError(GL_INVALID_VALUE, kInvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005830 return false;
5831 }
5832 break;
5833
5834 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005835 if (!context->getExtensions().packReverseRowOrder)
5836 {
Jamie Madille0472f32018-11-27 16:32:45 -05005837 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang000dab82017-09-27 14:27:07 -04005838 }
5839 break;
5840
Jamie Madillc1d770e2017-04-13 17:31:24 -04005841 case GL_UNPACK_ROW_LENGTH:
5842 case GL_UNPACK_IMAGE_HEIGHT:
5843 case GL_UNPACK_SKIP_IMAGES:
5844 case GL_UNPACK_SKIP_ROWS:
5845 case GL_UNPACK_SKIP_PIXELS:
5846 case GL_PACK_ROW_LENGTH:
5847 case GL_PACK_SKIP_ROWS:
5848 case GL_PACK_SKIP_PIXELS:
5849 break;
5850
5851 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005852 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005853 return false;
5854 }
5855
5856 return true;
5857}
5858
Jamie Madill5b772312018-03-08 20:28:32 -05005859bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005860{
5861 return true;
5862}
5863
Jamie Madill5b772312018-03-08 20:28:32 -05005864bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005865{
5866 return true;
5867}
5868
Jamie Madill5b772312018-03-08 20:28:32 -05005869bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005870{
5871 return true;
5872}
5873
Jamie Madill5b772312018-03-08 20:28:32 -05005874bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005875{
5876 if (width < 0 || height < 0)
5877 {
Jamie Madille0472f32018-11-27 16:32:45 -05005878 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005879 return false;
5880 }
5881
5882 return true;
5883}
5884
Jamie Madill5b772312018-03-08 20:28:32 -05005885bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005886 GLsizei n,
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005887 const ShaderProgramID *shaders,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005888 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005889 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005890 GLsizei length)
5891{
5892 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5893 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5894 shaderBinaryFormats.end())
5895 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005896 context->validationError(GL_INVALID_ENUM, kInvalidShaderBinaryFormat);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005897 return false;
5898 }
5899
5900 return true;
5901}
5902
Jamie Madill5b772312018-03-08 20:28:32 -05005903bool ValidateShaderSource(Context *context,
Jiacheng Lu120b61d2019-08-21 12:51:58 -06005904 ShaderProgramID shader,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005905 GLsizei count,
5906 const GLchar *const *string,
5907 const GLint *length)
5908{
5909 if (count < 0)
5910 {
Jamie Madille0472f32018-11-27 16:32:45 -05005911 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005912 return false;
5913 }
5914
Geoff Langfc32e8b2017-05-31 14:16:59 -04005915 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5916 // shader-related entry points
5917 if (context->getExtensions().webglCompatibility)
5918 {
5919 for (GLsizei i = 0; i < count; i++)
5920 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005921 size_t len =
5922 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005923
5924 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005925 if (!IsValidESSLShaderSourceString(string[i], len,
5926 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005927 {
Jamie Madille0472f32018-11-27 16:32:45 -05005928 context->validationError(GL_INVALID_VALUE, kShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005929 return false;
5930 }
5931 }
5932 }
5933
Jamie Madillc1d770e2017-04-13 17:31:24 -04005934 Shader *shaderObject = GetValidShader(context, shader);
5935 if (!shaderObject)
5936 {
5937 return false;
5938 }
5939
5940 return true;
5941}
5942
Jamie Madill5b772312018-03-08 20:28:32 -05005943bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005944{
5945 if (!IsValidStencilFunc(func))
5946 {
Jamie Madille0472f32018-11-27 16:32:45 -05005947 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005948 return false;
5949 }
5950
5951 return true;
5952}
5953
Jamie Madill5b772312018-03-08 20:28:32 -05005954bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005955{
5956 if (!IsValidStencilFace(face))
5957 {
Jamie Madille0472f32018-11-27 16:32:45 -05005958 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005959 return false;
5960 }
5961
5962 if (!IsValidStencilFunc(func))
5963 {
Jamie Madille0472f32018-11-27 16:32:45 -05005964 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005965 return false;
5966 }
5967
5968 return true;
5969}
5970
Jamie Madill5b772312018-03-08 20:28:32 -05005971bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005972{
5973 return true;
5974}
5975
Jamie Madill5b772312018-03-08 20:28:32 -05005976bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005977{
5978 if (!IsValidStencilFace(face))
5979 {
Jamie Madille0472f32018-11-27 16:32:45 -05005980 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005981 return false;
5982 }
5983
5984 return true;
5985}
5986
Jamie Madill5b772312018-03-08 20:28:32 -05005987bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005988{
5989 if (!IsValidStencilOp(fail))
5990 {
Jamie Madille0472f32018-11-27 16:32:45 -05005991 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005992 return false;
5993 }
5994
5995 if (!IsValidStencilOp(zfail))
5996 {
Jamie Madille0472f32018-11-27 16:32:45 -05005997 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005998 return false;
5999 }
6000
6001 if (!IsValidStencilOp(zpass))
6002 {
Jamie Madille0472f32018-11-27 16:32:45 -05006003 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04006004 return false;
6005 }
6006
6007 return true;
6008}
6009
Jamie Madill5b772312018-03-08 20:28:32 -05006010bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04006011 GLenum face,
6012 GLenum fail,
6013 GLenum zfail,
6014 GLenum zpass)
6015{
6016 if (!IsValidStencilFace(face))
6017 {
Jamie Madille0472f32018-11-27 16:32:45 -05006018 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04006019 return false;
6020 }
6021
6022 return ValidateStencilOp(context, fail, zfail, zpass);
6023}
6024
Jamie Madill5b772312018-03-08 20:28:32 -05006025bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006026{
6027 return ValidateUniform(context, GL_FLOAT, location, 1);
6028}
6029
Jamie Madill5b772312018-03-08 20:28:32 -05006030bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006031{
6032 return ValidateUniform(context, GL_FLOAT, location, count);
6033}
6034
Jamie Madill5b772312018-03-08 20:28:32 -05006035bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04006036{
6037 return ValidateUniform1iv(context, location, 1, &x);
6038}
6039
Jamie Madill5b772312018-03-08 20:28:32 -05006040bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006041{
6042 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
6043}
6044
Jamie Madill5b772312018-03-08 20:28:32 -05006045bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006046{
6047 return ValidateUniform(context, GL_INT_VEC2, location, 1);
6048}
6049
Jamie Madill5b772312018-03-08 20:28:32 -05006050bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006051{
6052 return ValidateUniform(context, GL_INT_VEC2, location, count);
6053}
6054
Jamie Madill5b772312018-03-08 20:28:32 -05006055bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006056{
6057 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
6058}
6059
Jamie Madill5b772312018-03-08 20:28:32 -05006060bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006061{
6062 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
6063}
6064
Jamie Madill5b772312018-03-08 20:28:32 -05006065bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006066{
6067 return ValidateUniform(context, GL_INT_VEC3, location, 1);
6068}
6069
Jamie Madill5b772312018-03-08 20:28:32 -05006070bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006071{
6072 return ValidateUniform(context, GL_INT_VEC3, location, count);
6073}
6074
Jamie Madill5b772312018-03-08 20:28:32 -05006075bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006076{
6077 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
6078}
6079
Jamie Madill5b772312018-03-08 20:28:32 -05006080bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006081{
6082 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
6083}
6084
Jamie Madill5b772312018-03-08 20:28:32 -05006085bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006086{
6087 return ValidateUniform(context, GL_INT_VEC4, location, 1);
6088}
6089
Jamie Madill5b772312018-03-08 20:28:32 -05006090bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006091{
6092 return ValidateUniform(context, GL_INT_VEC4, location, count);
6093}
6094
Jamie Madill5b772312018-03-08 20:28:32 -05006095bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04006096 GLint location,
6097 GLsizei count,
6098 GLboolean transpose,
6099 const GLfloat *value)
6100{
6101 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
6102}
6103
Jamie Madill5b772312018-03-08 20:28:32 -05006104bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04006105 GLint location,
6106 GLsizei count,
6107 GLboolean transpose,
6108 const GLfloat *value)
6109{
6110 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
6111}
6112
Jamie Madill5b772312018-03-08 20:28:32 -05006113bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04006114 GLint location,
6115 GLsizei count,
6116 GLboolean transpose,
6117 const GLfloat *value)
6118{
6119 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
6120}
6121
Jiacheng Lu120b61d2019-08-21 12:51:58 -06006122bool ValidateValidateProgram(Context *context, ShaderProgramID program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006123{
6124 Program *programObject = GetValidProgram(context, program);
6125
6126 if (!programObject)
6127 {
6128 return false;
6129 }
6130
6131 return true;
6132}
6133
Jamie Madill5b772312018-03-08 20:28:32 -05006134bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006135{
6136 return ValidateVertexAttribIndex(context, index);
6137}
6138
Jamie Madill5b772312018-03-08 20:28:32 -05006139bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006140{
6141 return ValidateVertexAttribIndex(context, index);
6142}
6143
Jamie Madill5b772312018-03-08 20:28:32 -05006144bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006145{
6146 return ValidateVertexAttribIndex(context, index);
6147}
6148
Jamie Madill5b772312018-03-08 20:28:32 -05006149bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006150{
6151 return ValidateVertexAttribIndex(context, index);
6152}
6153
Jamie Madill5b772312018-03-08 20:28:32 -05006154bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006155{
6156 return ValidateVertexAttribIndex(context, index);
6157}
6158
Jamie Madill5b772312018-03-08 20:28:32 -05006159bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006160{
6161 return ValidateVertexAttribIndex(context, index);
6162}
6163
Jamie Madill5b772312018-03-08 20:28:32 -05006164bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04006165 GLuint index,
6166 GLfloat x,
6167 GLfloat y,
6168 GLfloat z,
6169 GLfloat w)
6170{
6171 return ValidateVertexAttribIndex(context, index);
6172}
6173
Jamie Madill5b772312018-03-08 20:28:32 -05006174bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006175{
6176 return ValidateVertexAttribIndex(context, index);
6177}
6178
Jamie Madill5b772312018-03-08 20:28:32 -05006179bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006180{
6181 if (width < 0 || height < 0)
6182 {
Jamie Madille0472f32018-11-27 16:32:45 -05006183 context->validationError(GL_INVALID_VALUE, kViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04006184 return false;
6185 }
6186
6187 return true;
6188}
6189
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08006190bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006191 GLenum target,
6192 GLenum attachment,
6193 GLenum pname,
6194 GLint *params)
6195{
6196 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
6197 nullptr);
6198}
6199
Jiacheng Lu120b61d2019-08-21 12:51:58 -06006200bool ValidateGetProgramiv(Context *context, ShaderProgramID program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006201{
6202 return ValidateGetProgramivBase(context, program, pname, nullptr);
6203}
6204
Jamie Madill5b772312018-03-08 20:28:32 -05006205bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006206 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006207 GLint level,
6208 GLenum internalformat,
6209 GLint x,
6210 GLint y,
6211 GLsizei width,
6212 GLsizei height,
6213 GLint border)
6214{
6215 if (context->getClientMajorVersion() < 3)
6216 {
6217 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
6218 0, x, y, width, height, border);
6219 }
6220
6221 ASSERT(context->getClientMajorVersion() == 3);
6222 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
6223 0, x, y, width, height, border);
6224}
6225
6226bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006227 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006228 GLint level,
6229 GLint xoffset,
6230 GLint yoffset,
6231 GLint x,
6232 GLint y,
6233 GLsizei width,
6234 GLsizei height)
6235{
6236 if (context->getClientMajorVersion() < 3)
6237 {
6238 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
6239 yoffset, x, y, width, height, 0);
6240 }
6241
6242 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
6243 yoffset, 0, x, y, width, height, 0);
6244}
6245
Cody Northrop5faff912019-06-28 14:04:50 -06006246bool ValidateCopyTexSubImage3DOES(Context *context,
6247 TextureTarget target,
6248 GLint level,
6249 GLint xoffset,
6250 GLint yoffset,
6251 GLint zoffset,
6252 GLint x,
6253 GLint y,
6254 GLsizei width,
6255 GLsizei height)
6256{
6257 return ValidateCopyTexSubImage3D(context, target, level, xoffset, yoffset, zoffset, x, y, width,
6258 height);
6259}
6260
Jamie Madill3b3fe832019-08-06 17:44:12 -04006261bool ValidateDeleteBuffers(Context *context, GLint n, const BufferID *buffers)
Jamie Madillbe849e42017-05-02 15:49:00 -04006262{
6263 return ValidateGenOrDelete(context, n);
6264}
6265
6266bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
6267{
6268 return ValidateGenOrDelete(context, n);
6269}
6270
Jamie Madill7c7dec02019-08-06 17:44:11 -04006271bool ValidateDeleteRenderbuffers(Context *context, GLint n, const RenderbufferID *renderbuffers)
Jamie Madillbe849e42017-05-02 15:49:00 -04006272{
6273 return ValidateGenOrDelete(context, n);
6274}
6275
Jamie Madill2ab08ed2019-08-12 16:20:21 -04006276bool ValidateDeleteTextures(Context *context, GLint n, const TextureID *textures)
Jamie Madillbe849e42017-05-02 15:49:00 -04006277{
6278 return ValidateGenOrDelete(context, n);
6279}
6280
6281bool ValidateDisable(Context *context, GLenum cap)
6282{
6283 if (!ValidCap(context, cap, false))
6284 {
Jamie Madille0472f32018-11-27 16:32:45 -05006285 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006286 return false;
6287 }
6288
6289 return true;
6290}
6291
6292bool ValidateEnable(Context *context, GLenum cap)
6293{
6294 if (!ValidCap(context, cap, false))
6295 {
Jamie Madille0472f32018-11-27 16:32:45 -05006296 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006297 return false;
6298 }
6299
6300 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
6301 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
6302 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006303 context->validationError(GL_INVALID_OPERATION, kNoSampleAlphaToCoveragesLimitation);
Jamie Madillbe849e42017-05-02 15:49:00 -04006304
6305 // We also output an error message to the debugger window if tracing is active, so that
6306 // developers can see the error message.
Jamie Madillc3e37312018-11-30 15:25:39 -05006307 ERR() << kNoSampleAlphaToCoveragesLimitation;
Jamie Madillbe849e42017-05-02 15:49:00 -04006308 return false;
6309 }
6310
6311 return true;
6312}
6313
6314bool ValidateFramebufferRenderbuffer(Context *context,
6315 GLenum target,
6316 GLenum attachment,
6317 GLenum renderbuffertarget,
Jamie Madill7c7dec02019-08-06 17:44:11 -04006318 RenderbufferID renderbuffer)
Jamie Madillbe849e42017-05-02 15:49:00 -04006319{
Geoff Lange8afa902017-09-27 15:00:43 -04006320 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04006321 {
Jamie Madille0472f32018-11-27 16:32:45 -05006322 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Brandon Jones6cad5662017-06-14 13:25:13 -07006323 return false;
6324 }
6325
Jamie Madill7c7dec02019-08-06 17:44:11 -04006326 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer.value != 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006327 {
Jamie Madille0472f32018-11-27 16:32:45 -05006328 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006329 return false;
6330 }
6331
6332 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
6333 renderbuffertarget, renderbuffer);
6334}
6335
6336bool ValidateFramebufferTexture2D(Context *context,
6337 GLenum target,
6338 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006339 TextureTarget textarget,
Jamie Madill2ab08ed2019-08-12 16:20:21 -04006340 TextureID texture,
Jamie Madillbe849e42017-05-02 15:49:00 -04006341 GLint level)
6342{
6343 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
6344 // extension
6345 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
6346 level != 0)
6347 {
Jamie Madille0472f32018-11-27 16:32:45 -05006348 context->validationError(GL_INVALID_VALUE, kInvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04006349 return false;
6350 }
6351
6352 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
6353 {
6354 return false;
6355 }
6356
Jamie Madill2ab08ed2019-08-12 16:20:21 -04006357 if (texture.value != 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04006358 {
6359 gl::Texture *tex = context->getTexture(texture);
6360 ASSERT(tex);
6361
6362 const gl::Caps &caps = context->getCaps();
6363
6364 switch (textarget)
6365 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006366 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04006367 {
6368 if (level > gl::log2(caps.max2DTextureSize))
6369 {
Jamie Madille0472f32018-11-27 16:32:45 -05006370 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04006371 return false;
6372 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006373 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04006374 {
Jamie Madille0472f32018-11-27 16:32:45 -05006375 context->validationError(GL_INVALID_OPERATION, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006376 return false;
6377 }
6378 }
6379 break;
6380
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006381 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006382 {
6383 if (level != 0)
6384 {
Jamie Madille0472f32018-11-27 16:32:45 -05006385 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006386 return false;
6387 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006388 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006389 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006390 context->validationError(GL_INVALID_OPERATION, kTextureTargetMismatch);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006391 return false;
6392 }
6393 }
6394 break;
6395
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006396 case TextureTarget::CubeMapNegativeX:
6397 case TextureTarget::CubeMapNegativeY:
6398 case TextureTarget::CubeMapNegativeZ:
6399 case TextureTarget::CubeMapPositiveX:
6400 case TextureTarget::CubeMapPositiveY:
6401 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04006402 {
6403 if (level > gl::log2(caps.maxCubeMapTextureSize))
6404 {
Jamie Madille0472f32018-11-27 16:32:45 -05006405 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04006406 return false;
6407 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006408 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04006409 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006410 context->validationError(GL_INVALID_OPERATION, kTextureTargetMismatch);
Jamie Madillbe849e42017-05-02 15:49:00 -04006411 return false;
6412 }
6413 }
6414 break;
6415
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006416 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04006417 {
Yizhou Jiang7818a852018-09-06 15:02:04 +08006418 if (context->getClientVersion() < ES_3_1 &&
6419 !context->getExtensions().textureMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006420 {
Jamie Madill610640f2018-11-21 17:28:41 -05006421 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05006422 kMultisampleTextureExtensionOrES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006423 return false;
6424 }
6425
6426 if (level != 0)
6427 {
Jamie Madille0472f32018-11-27 16:32:45 -05006428 context->validationError(GL_INVALID_VALUE, kLevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006429 return false;
6430 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006431 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006432 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006433 context->validationError(GL_INVALID_OPERATION, kTextureTargetMismatch);
Jamie Madillbe849e42017-05-02 15:49:00 -04006434 return false;
6435 }
6436 }
6437 break;
6438
6439 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006440 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006441 return false;
6442 }
Jamie Madillbe849e42017-05-02 15:49:00 -04006443 }
6444
6445 return true;
6446}
6447
Cody Northrop5faff912019-06-28 14:04:50 -06006448bool ValidateFramebufferTexture3DOES(Context *context,
6449 GLenum target,
6450 GLenum attachment,
6451 TextureTarget textargetPacked,
Jamie Madill2ab08ed2019-08-12 16:20:21 -04006452 TextureID texture,
Cody Northrop5faff912019-06-28 14:04:50 -06006453 GLint level,
6454 GLint zoffset)
6455{
Cody Northrop90958e32019-08-07 16:26:14 -06006456 // We don't call into a base ValidateFramebufferTexture3D here because
6457 // it doesn't exist for OpenGL ES. This function is replaced by
6458 // FramebufferTextureLayer in ES 3.x, which has broader support.
6459 if (!context->getExtensions().texture3DOES)
6460 {
6461 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
6462 return false;
6463 }
6464
6465 // Attachments are required to be bound to level 0 without ES3 or the
6466 // GL_OES_fbo_render_mipmap extension
6467 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
6468 level != 0)
6469 {
6470 context->validationError(GL_INVALID_VALUE, kInvalidFramebufferTextureLevel);
6471 return false;
6472 }
6473
6474 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
6475 {
6476 return false;
6477 }
6478
Jamie Madill2ab08ed2019-08-12 16:20:21 -04006479 if (texture.value != 0)
Cody Northrop90958e32019-08-07 16:26:14 -06006480 {
6481 gl::Texture *tex = context->getTexture(texture);
6482 ASSERT(tex);
6483
6484 const gl::Caps &caps = context->getCaps();
6485
6486 switch (textargetPacked)
6487 {
6488 case TextureTarget::_3D:
6489 {
6490 if (level > gl::log2(caps.max3DTextureSize))
6491 {
6492 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
6493 return false;
6494 }
6495 if (static_cast<size_t>(zoffset) >= caps.max3DTextureSize)
6496 {
6497 context->validationError(GL_INVALID_VALUE, kInvalidZOffset);
6498 return false;
6499 }
6500 if (tex->getType() != TextureType::_3D)
6501 {
6502 context->validationError(GL_INVALID_OPERATION, kInvalidTextureType);
6503 return false;
6504 }
6505 }
6506 break;
6507
6508 default:
6509 context->validationError(GL_INVALID_OPERATION, kInvalidTextureTarget);
6510 return false;
6511 }
6512 }
6513
6514 return true;
Cody Northrop5faff912019-06-28 14:04:50 -06006515}
6516
Jamie Madill3b3fe832019-08-06 17:44:12 -04006517bool ValidateGenBuffers(Context *context, GLint n, BufferID *buffers)
Jamie Madillbe849e42017-05-02 15:49:00 -04006518{
6519 return ValidateGenOrDelete(context, n);
6520}
6521
6522bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6523{
6524 return ValidateGenOrDelete(context, n);
6525}
6526
Jamie Madill7c7dec02019-08-06 17:44:11 -04006527bool ValidateGenRenderbuffers(Context *context, GLint n, RenderbufferID *renderbuffers)
Jamie Madillbe849e42017-05-02 15:49:00 -04006528{
6529 return ValidateGenOrDelete(context, n);
6530}
6531
Jamie Madill2ab08ed2019-08-12 16:20:21 -04006532bool ValidateGenTextures(Context *context, GLint n, TextureID *textures)
Jamie Madillbe849e42017-05-02 15:49:00 -04006533{
6534 return ValidateGenOrDelete(context, n);
6535}
6536
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006537bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006538{
6539 if (!ValidTextureTarget(context, target))
6540 {
Jamie Madille0472f32018-11-27 16:32:45 -05006541 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006542 return false;
6543 }
6544
Jamie Madillcfc73cc2019-04-08 16:26:51 -04006545 Texture *texture = context->getTextureByType(target);
Jamie Madillbe849e42017-05-02 15:49:00 -04006546
6547 if (texture == nullptr)
6548 {
Jamie Madille0472f32018-11-27 16:32:45 -05006549 context->validationError(GL_INVALID_OPERATION, kTextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006550 return false;
6551 }
6552
6553 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6554
6555 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6556 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6557 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6558 {
Jamie Madille0472f32018-11-27 16:32:45 -05006559 context->validationError(GL_INVALID_OPERATION, kBaseLevelOutOfRange);
Jamie Madillbe849e42017-05-02 15:49:00 -04006560 return false;
6561 }
6562
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006563 TextureTarget baseTarget = (target == TextureType::CubeMap)
6564 ? TextureTarget::CubeMapPositiveX
6565 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006566 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6567 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6568 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006569 {
Jamie Madille0472f32018-11-27 16:32:45 -05006570 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Brandon Jones6cad5662017-06-14 13:25:13 -07006571 return false;
6572 }
6573
Geoff Lang536eca12017-09-13 11:23:35 -04006574 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6575 bool formatUnsized = !format.sized;
6576 bool formatColorRenderableAndFilterable =
6577 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
Yuly Novikovf15f8862018-06-04 18:59:41 -04006578 format.textureAttachmentSupport(context->getClientVersion(), context->getExtensions());
Geoff Lang536eca12017-09-13 11:23:35 -04006579 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006580 {
Jamie Madille0472f32018-11-27 16:32:45 -05006581 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006582 return false;
6583 }
6584
Geoff Lang536eca12017-09-13 11:23:35 -04006585 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6586 // generation
6587 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6588 {
Jamie Madille0472f32018-11-27 16:32:45 -05006589 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Geoff Lang536eca12017-09-13 11:23:35 -04006590 return false;
6591 }
6592
Jiange2c00842018-07-13 16:50:49 +08006593 // According to the OpenGL extension spec EXT_sRGB.txt, EXT_SRGB is based on ES 2.0 and
6594 // generateMipmap is not allowed if texture format is SRGB_EXT or SRGB_ALPHA_EXT.
6595 if (context->getClientVersion() < Version(3, 0) && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006596 {
Jamie Madille0472f32018-11-27 16:32:45 -05006597 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006598 return false;
6599 }
6600
6601 // Non-power of 2 ES2 check
6602 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6603 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6604 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6605 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006606 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6607 target == TextureType::CubeMap);
Jamie Madille0472f32018-11-27 16:32:45 -05006608 context->validationError(GL_INVALID_OPERATION, kTextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006609 return false;
6610 }
6611
6612 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006613 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006614 {
Jamie Madille0472f32018-11-27 16:32:45 -05006615 context->validationError(GL_INVALID_OPERATION, kCubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006616 return false;
6617 }
6618
James Darpinian83b2f0e2018-11-27 15:56:01 -08006619 if (context->getExtensions().webglCompatibility &&
6620 (texture->getWidth(baseTarget, effectiveBaseLevel) == 0 ||
6621 texture->getHeight(baseTarget, effectiveBaseLevel) == 0))
6622 {
6623 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapZeroSize);
6624 return false;
6625 }
6626
Jamie Madillbe849e42017-05-02 15:49:00 -04006627 return true;
6628}
6629
Jamie Madill5b772312018-03-08 20:28:32 -05006630bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006631 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006632 GLenum pname,
6633 GLint *params)
6634{
6635 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6636}
6637
6638bool ValidateGetRenderbufferParameteriv(Context *context,
6639 GLenum target,
6640 GLenum pname,
6641 GLint *params)
6642{
6643 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6644}
6645
Jiacheng Lu120b61d2019-08-21 12:51:58 -06006646bool ValidateGetShaderiv(Context *context, ShaderProgramID shader, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006647{
6648 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6649}
6650
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006651bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006652{
6653 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6654}
6655
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006656bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006657{
6658 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6659}
6660
Till Rathmannb8543632018-10-02 19:46:14 +02006661bool ValidateGetTexParameterIivOES(Context *context,
6662 TextureType target,
6663 GLenum pname,
6664 GLint *params)
6665{
6666 if (context->getClientMajorVersion() < 3)
6667 {
Jamie Madille0472f32018-11-27 16:32:45 -05006668 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006669 return false;
6670 }
6671 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6672}
6673
6674bool ValidateGetTexParameterIuivOES(Context *context,
6675 TextureType target,
6676 GLenum pname,
6677 GLuint *params)
6678{
6679 if (context->getClientMajorVersion() < 3)
6680 {
Jamie Madille0472f32018-11-27 16:32:45 -05006681 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006682 return false;
6683 }
6684 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6685}
6686
Jiacheng Lu120b61d2019-08-21 12:51:58 -06006687bool ValidateGetUniformfv(Context *context,
6688 ShaderProgramID program,
6689 GLint location,
6690 GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006691{
6692 return ValidateGetUniformBase(context, program, location);
6693}
6694
Jiacheng Lu120b61d2019-08-21 12:51:58 -06006695bool ValidateGetUniformiv(Context *context, ShaderProgramID program, GLint location, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006696{
6697 return ValidateGetUniformBase(context, program, location);
6698}
6699
6700bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6701{
6702 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6703}
6704
6705bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6706{
6707 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6708}
6709
6710bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6711{
6712 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6713}
6714
6715bool ValidateIsEnabled(Context *context, GLenum cap)
6716{
6717 if (!ValidCap(context, cap, true))
6718 {
Jamie Madille0472f32018-11-27 16:32:45 -05006719 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006720 return false;
6721 }
6722
6723 return true;
6724}
6725
Jiacheng Lu120b61d2019-08-21 12:51:58 -06006726bool ValidateLinkProgram(Context *context, ShaderProgramID program)
Jamie Madillbe849e42017-05-02 15:49:00 -04006727{
6728 if (context->hasActiveTransformFeedback(program))
6729 {
6730 // ES 3.0.4 section 2.15 page 91
Jamie Madillc3e37312018-11-30 15:25:39 -05006731 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackActiveDuringLink);
Jamie Madillbe849e42017-05-02 15:49:00 -04006732 return false;
6733 }
6734
6735 Program *programObject = GetValidProgram(context, program);
6736 if (!programObject)
6737 {
6738 return false;
6739 }
6740
6741 return true;
6742}
6743
Jamie Madill4928b7c2017-06-20 12:57:39 -04006744bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006745 GLint x,
6746 GLint y,
6747 GLsizei width,
6748 GLsizei height,
6749 GLenum format,
6750 GLenum type,
6751 void *pixels)
6752{
6753 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6754 nullptr, pixels);
6755}
6756
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006757bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006758{
Till Rathmannb8543632018-10-02 19:46:14 +02006759 return ValidateTexParameterBase(context, target, pname, -1, false, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006760}
6761
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006762bool ValidateTexParameterfv(Context *context,
6763 TextureType target,
6764 GLenum pname,
6765 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006766{
Till Rathmannb8543632018-10-02 19:46:14 +02006767 return ValidateTexParameterBase(context, target, pname, -1, true, params);
Jamie Madillbe849e42017-05-02 15:49:00 -04006768}
6769
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006770bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006771{
Till Rathmannb8543632018-10-02 19:46:14 +02006772 return ValidateTexParameterBase(context, target, pname, -1, false, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006773}
6774
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006775bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006776{
Till Rathmannb8543632018-10-02 19:46:14 +02006777 return ValidateTexParameterBase(context, target, pname, -1, true, params);
6778}
6779
6780bool ValidateTexParameterIivOES(Context *context,
6781 TextureType target,
6782 GLenum pname,
6783 const GLint *params)
6784{
6785 if (context->getClientMajorVersion() < 3)
6786 {
Jamie Madille0472f32018-11-27 16:32:45 -05006787 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006788 return false;
6789 }
6790 return ValidateTexParameterBase(context, target, pname, -1, true, params);
6791}
6792
6793bool ValidateTexParameterIuivOES(Context *context,
6794 TextureType target,
6795 GLenum pname,
6796 const GLuint *params)
6797{
6798 if (context->getClientMajorVersion() < 3)
6799 {
Jamie Madille0472f32018-11-27 16:32:45 -05006800 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006801 return false;
6802 }
6803 return ValidateTexParameterBase(context, target, pname, -1, true, params);
Jamie Madillbe849e42017-05-02 15:49:00 -04006804}
6805
Jiacheng Lu120b61d2019-08-21 12:51:58 -06006806bool ValidateUseProgram(Context *context, ShaderProgramID program)
Jamie Madillbe849e42017-05-02 15:49:00 -04006807{
Jiacheng Lu120b61d2019-08-21 12:51:58 -06006808 if (program.value != 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04006809 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04006810 Program *programObject = context->getProgramResolveLink(program);
Jamie Madillbe849e42017-05-02 15:49:00 -04006811 if (!programObject)
6812 {
6813 // ES 3.1.0 section 7.3 page 72
6814 if (context->getShader(program))
6815 {
Jamie Madille0472f32018-11-27 16:32:45 -05006816 context->validationError(GL_INVALID_OPERATION, kExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006817 return false;
6818 }
6819 else
6820 {
Jamie Madille0472f32018-11-27 16:32:45 -05006821 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006822 return false;
6823 }
6824 }
6825 if (!programObject->isLinked())
6826 {
Jamie Madille0472f32018-11-27 16:32:45 -05006827 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006828 return false;
6829 }
6830 }
Jamie Madillc3dc5d42018-12-30 12:12:04 -05006831 if (context->getState().isTransformFeedbackActiveUnpaused())
Jamie Madillbe849e42017-05-02 15:49:00 -04006832 {
6833 // ES 3.0.4 section 2.15 page 91
Jamie Madillc3e37312018-11-30 15:25:39 -05006834 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackUseProgram);
Jamie Madillbe849e42017-05-02 15:49:00 -04006835 return false;
6836 }
6837
6838 return true;
6839}
6840
Jiacheng Lu962503e2019-08-21 13:18:30 -06006841bool ValidateDeleteFencesNV(Context *context, GLsizei n, const FenceNVID *fences)
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006842{
6843 if (!context->getExtensions().fence)
6844 {
Jamie Madille0472f32018-11-27 16:32:45 -05006845 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006846 return false;
6847 }
6848
6849 if (n < 0)
6850 {
Jamie Madille0472f32018-11-27 16:32:45 -05006851 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006852 return false;
6853 }
6854
6855 return true;
6856}
6857
Jiacheng Lu962503e2019-08-21 13:18:30 -06006858bool ValidateFinishFenceNV(Context *context, FenceNVID fence)
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006859{
6860 if (!context->getExtensions().fence)
6861 {
Jamie Madille0472f32018-11-27 16:32:45 -05006862 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006863 return false;
6864 }
6865
6866 FenceNV *fenceObject = context->getFenceNV(fence);
6867
6868 if (fenceObject == nullptr)
6869 {
Jamie Madille0472f32018-11-27 16:32:45 -05006870 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006871 return false;
6872 }
6873
6874 if (!fenceObject->isSet())
6875 {
Jamie Madille0472f32018-11-27 16:32:45 -05006876 context->validationError(GL_INVALID_OPERATION, kInvalidFenceState);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006877 return false;
6878 }
6879
6880 return true;
6881}
6882
Jiacheng Lu962503e2019-08-21 13:18:30 -06006883bool ValidateGenFencesNV(Context *context, GLsizei n, FenceNVID *fences)
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006884{
6885 if (!context->getExtensions().fence)
6886 {
Jamie Madille0472f32018-11-27 16:32:45 -05006887 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006888 return false;
6889 }
6890
6891 if (n < 0)
6892 {
Jamie Madille0472f32018-11-27 16:32:45 -05006893 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006894 return false;
6895 }
6896
6897 return true;
6898}
6899
Jiacheng Lu962503e2019-08-21 13:18:30 -06006900bool ValidateGetFenceivNV(Context *context, FenceNVID fence, GLenum pname, GLint *params)
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006901{
6902 if (!context->getExtensions().fence)
6903 {
Jamie Madille0472f32018-11-27 16:32:45 -05006904 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006905 return false;
6906 }
6907
6908 FenceNV *fenceObject = context->getFenceNV(fence);
6909
6910 if (fenceObject == nullptr)
6911 {
Jamie Madille0472f32018-11-27 16:32:45 -05006912 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006913 return false;
6914 }
6915
6916 if (!fenceObject->isSet())
6917 {
Jamie Madille0472f32018-11-27 16:32:45 -05006918 context->validationError(GL_INVALID_OPERATION, kInvalidFenceState);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006919 return false;
6920 }
6921
6922 switch (pname)
6923 {
6924 case GL_FENCE_STATUS_NV:
6925 case GL_FENCE_CONDITION_NV:
6926 break;
6927
6928 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006929 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006930 return false;
6931 }
6932
6933 return true;
6934}
6935
6936bool ValidateGetGraphicsResetStatusEXT(Context *context)
6937{
6938 if (!context->getExtensions().robustness)
6939 {
Jamie Madille0472f32018-11-27 16:32:45 -05006940 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006941 return false;
6942 }
6943
6944 return true;
6945}
6946
6947bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
Jiacheng Lu120b61d2019-08-21 12:51:58 -06006948 ShaderProgramID shader,
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006949 GLsizei bufsize,
6950 GLsizei *length,
6951 GLchar *source)
6952{
6953 if (!context->getExtensions().translatedShaderSource)
6954 {
Jamie Madille0472f32018-11-27 16:32:45 -05006955 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006956 return false;
6957 }
6958
6959 if (bufsize < 0)
6960 {
Jamie Madille0472f32018-11-27 16:32:45 -05006961 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006962 return false;
6963 }
6964
6965 Shader *shaderObject = context->getShader(shader);
6966
6967 if (!shaderObject)
6968 {
Jamie Madille0472f32018-11-27 16:32:45 -05006969 context->validationError(GL_INVALID_OPERATION, kInvalidShaderName);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006970 return false;
6971 }
6972
6973 return true;
6974}
6975
Jiacheng Lu962503e2019-08-21 13:18:30 -06006976bool ValidateIsFenceNV(Context *context, FenceNVID fence)
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006977{
6978 if (!context->getExtensions().fence)
6979 {
Jamie Madille0472f32018-11-27 16:32:45 -05006980 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006981 return false;
6982 }
6983
6984 return true;
6985}
6986
Jiacheng Lu962503e2019-08-21 13:18:30 -06006987bool ValidateSetFenceNV(Context *context, FenceNVID fence, GLenum condition)
Jamie Madill007530e2017-12-28 14:27:04 -05006988{
6989 if (!context->getExtensions().fence)
6990 {
Jamie Madille0472f32018-11-27 16:32:45 -05006991 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill007530e2017-12-28 14:27:04 -05006992 return false;
6993 }
6994
6995 if (condition != GL_ALL_COMPLETED_NV)
6996 {
Jamie Madille0472f32018-11-27 16:32:45 -05006997 context->validationError(GL_INVALID_ENUM, kInvalidFenceCondition);
Jamie Madill007530e2017-12-28 14:27:04 -05006998 return false;
6999 }
7000
7001 FenceNV *fenceObject = context->getFenceNV(fence);
7002
7003 if (fenceObject == nullptr)
7004 {
Jamie Madille0472f32018-11-27 16:32:45 -05007005 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill007530e2017-12-28 14:27:04 -05007006 return false;
7007 }
7008
7009 return true;
7010}
7011
Jiacheng Lu962503e2019-08-21 13:18:30 -06007012bool ValidateTestFenceNV(Context *context, FenceNVID fence)
Jamie Madill007530e2017-12-28 14:27:04 -05007013{
7014 if (!context->getExtensions().fence)
7015 {
Jamie Madille0472f32018-11-27 16:32:45 -05007016 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill007530e2017-12-28 14:27:04 -05007017 return false;
7018 }
7019
7020 FenceNV *fenceObject = context->getFenceNV(fence);
7021
7022 if (fenceObject == nullptr)
7023 {
Jamie Madille0472f32018-11-27 16:32:45 -05007024 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill007530e2017-12-28 14:27:04 -05007025 return false;
7026 }
7027
7028 if (fenceObject->isSet() != GL_TRUE)
7029 {
Jamie Madille0472f32018-11-27 16:32:45 -05007030 context->validationError(GL_INVALID_OPERATION, kInvalidFenceState);
Jamie Madill007530e2017-12-28 14:27:04 -05007031 return false;
7032 }
7033
7034 return true;
7035}
7036
7037bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08007038 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05007039 GLsizei levels,
7040 GLenum internalformat,
7041 GLsizei width,
7042 GLsizei height)
7043{
7044 if (!context->getExtensions().textureStorage)
7045 {
Jamie Madille0472f32018-11-27 16:32:45 -05007046 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05007047 return false;
7048 }
7049
7050 if (context->getClientMajorVersion() < 3)
7051 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08007052 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05007053 height);
7054 }
7055
7056 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08007057 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05007058 1);
7059}
7060
7061bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
7062{
Jonah Ryan-Davis2b0553c2019-02-08 10:07:21 -05007063 if (!context->getExtensions().instancedArraysANGLE)
Jamie Madill007530e2017-12-28 14:27:04 -05007064 {
Jamie Madille0472f32018-11-27 16:32:45 -05007065 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05007066 return false;
7067 }
7068
7069 if (index >= MAX_VERTEX_ATTRIBS)
7070 {
Jamie Madille0472f32018-11-27 16:32:45 -05007071 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madill007530e2017-12-28 14:27:04 -05007072 return false;
7073 }
7074
7075 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
7076 {
7077 if (index == 0 && divisor != 0)
7078 {
Jamie Madillc3e37312018-11-30 15:25:39 -05007079 context->validationError(GL_INVALID_OPERATION, kAttributeZeroRequiresDivisorLimitation);
Jamie Madill007530e2017-12-28 14:27:04 -05007080
7081 // We also output an error message to the debugger window if tracing is active, so
7082 // that developers can see the error message.
Jamie Madillc3e37312018-11-30 15:25:39 -05007083 ERR() << kAttributeZeroRequiresDivisorLimitation;
Jamie Madill007530e2017-12-28 14:27:04 -05007084 return false;
7085 }
7086 }
7087
7088 return true;
7089}
7090
Jonah Ryan-Davis2b0553c2019-02-08 10:07:21 -05007091bool ValidateVertexAttribDivisorEXT(Context *context, GLuint index, GLuint divisor)
7092{
7093 if (!context->getExtensions().instancedArraysEXT)
7094 {
7095 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
7096 return false;
7097 }
7098
7099 if (index >= MAX_VERTEX_ATTRIBS)
7100 {
7101 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
7102 return false;
7103 }
7104
7105 return true;
7106}
7107
Jamie Madill007530e2017-12-28 14:27:04 -05007108bool ValidateTexImage3DOES(Context *context,
Cody Northrop5faff912019-06-28 14:04:50 -06007109 TextureTarget target,
Jamie Madill007530e2017-12-28 14:27:04 -05007110 GLint level,
7111 GLenum internalformat,
7112 GLsizei width,
7113 GLsizei height,
7114 GLsizei depth,
7115 GLint border,
7116 GLenum format,
7117 GLenum type,
7118 const void *pixels)
7119{
Cody Northrop5faff912019-06-28 14:04:50 -06007120 return ValidateTexImage3D(context, target, level, internalformat, width, height, depth, border,
7121 format, type, pixels);
Jamie Madill007530e2017-12-28 14:27:04 -05007122}
7123
7124bool ValidatePopGroupMarkerEXT(Context *context)
7125{
7126 if (!context->getExtensions().debugMarker)
7127 {
7128 // The debug marker calls should not set error state
7129 // However, it seems reasonable to set an error state if the extension is not enabled
Jamie Madille0472f32018-11-27 16:32:45 -05007130 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05007131 return false;
7132 }
7133
7134 return true;
7135}
7136
Jamie Madillfa920eb2018-01-04 11:45:50 -05007137bool ValidateTexStorage1DEXT(Context *context,
7138 GLenum target,
7139 GLsizei levels,
7140 GLenum internalformat,
7141 GLsizei width)
7142{
7143 UNIMPLEMENTED();
Jamie Madille0472f32018-11-27 16:32:45 -05007144 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05007145 return false;
7146}
7147
7148bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08007149 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05007150 GLsizei levels,
7151 GLenum internalformat,
7152 GLsizei width,
7153 GLsizei height,
7154 GLsizei depth)
7155{
7156 if (!context->getExtensions().textureStorage)
7157 {
Jamie Madille0472f32018-11-27 16:32:45 -05007158 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05007159 return false;
7160 }
7161
7162 if (context->getClientMajorVersion() < 3)
7163 {
Jamie Madille0472f32018-11-27 16:32:45 -05007164 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05007165 return false;
7166 }
7167
7168 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
7169 depth);
7170}
7171
jchen1082af6202018-06-22 10:59:52 +08007172bool ValidateMaxShaderCompilerThreadsKHR(Context *context, GLuint count)
7173{
7174 if (!context->getExtensions().parallelShaderCompile)
7175 {
Jamie Madille0472f32018-11-27 16:32:45 -05007176 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
jchen1082af6202018-06-22 10:59:52 +08007177 return false;
7178 }
7179 return true;
7180}
7181
Austin Eng1bf18ce2018-10-19 15:34:02 -07007182bool ValidateMultiDrawArraysANGLE(Context *context,
7183 PrimitiveMode mode,
7184 const GLint *firsts,
7185 const GLsizei *counts,
7186 GLsizei drawcount)
7187{
7188 if (!context->getExtensions().multiDraw)
7189 {
Jamie Madille0472f32018-11-27 16:32:45 -05007190 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07007191 return false;
7192 }
7193 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
7194 {
7195 if (!ValidateDrawArrays(context, mode, firsts[drawID], counts[drawID]))
7196 {
7197 return false;
7198 }
7199 }
7200 return true;
7201}
7202
7203bool ValidateMultiDrawElementsANGLE(Context *context,
7204 PrimitiveMode mode,
7205 const GLsizei *counts,
Jamie Madill8dc27f92018-11-29 11:45:44 -05007206 DrawElementsType type,
Austin Eng3b7c9d02018-11-21 18:09:05 -08007207 const GLvoid *const *indices,
Austin Eng1bf18ce2018-10-19 15:34:02 -07007208 GLsizei drawcount)
7209{
7210 if (!context->getExtensions().multiDraw)
7211 {
Jamie Madille0472f32018-11-27 16:32:45 -05007212 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07007213 return false;
7214 }
7215 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
7216 {
Austin Eng3b7c9d02018-11-21 18:09:05 -08007217 if (!ValidateDrawElements(context, mode, counts[drawID], type, indices[drawID]))
Austin Eng1bf18ce2018-10-19 15:34:02 -07007218 {
7219 return false;
7220 }
7221 }
7222 return true;
7223}
7224
Clemen Dengce330592019-07-16 10:02:21 -04007225bool ValidateProvokingVertexANGLE(Context *context, ProvokingVertexConvention modePacked)
Jeff Gilbert465d6092019-01-02 16:21:18 -08007226{
7227 if (!context->getExtensions().provokingVertex)
7228 {
7229 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
7230 return false;
7231 }
7232
7233 switch (modePacked)
7234 {
Clemen Dengce330592019-07-16 10:02:21 -04007235 case ProvokingVertexConvention::FirstVertexConvention:
7236 case ProvokingVertexConvention::LastVertexConvention:
Jeff Gilbert465d6092019-01-02 16:21:18 -08007237 break;
7238 default:
7239 context->validationError(GL_INVALID_ENUM, kInvalidProvokingVertex);
7240 return false;
7241 }
7242
7243 return true;
7244}
7245
Jamie Madilla5410482019-01-31 19:55:55 -05007246void RecordBindTextureTypeError(Context *context, TextureType target)
7247{
7248 ASSERT(!context->getStateCache().isValidBindTextureType(target));
7249
7250 switch (target)
7251 {
7252 case TextureType::Rectangle:
7253 ASSERT(!context->getExtensions().textureRectangle);
7254 context->validationError(GL_INVALID_ENUM, kTextureRectangleNotSupported);
7255 break;
7256
7257 case TextureType::_3D:
7258 case TextureType::_2DArray:
7259 ASSERT(context->getClientMajorVersion() < 3);
7260 context->validationError(GL_INVALID_ENUM, kES3Required);
7261 break;
7262
7263 case TextureType::_2DMultisample:
7264 ASSERT(context->getClientVersion() < Version(3, 1) &&
7265 !context->getExtensions().textureMultisample);
7266 context->validationError(GL_INVALID_ENUM, kMultisampleTextureExtensionOrES31Required);
7267 break;
7268
7269 case TextureType::_2DMultisampleArray:
7270 ASSERT(!context->getExtensions().textureStorageMultisample2DArray);
7271 context->validationError(GL_INVALID_ENUM, kMultisampleArrayExtensionRequired);
7272 break;
7273
7274 case TextureType::External:
7275 ASSERT(!context->getExtensions().eglImageExternal &&
7276 !context->getExtensions().eglStreamConsumerExternal);
7277 context->validationError(GL_INVALID_ENUM, kExternalTextureNotSupported);
7278 break;
7279
7280 default:
7281 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
7282 }
7283}
7284
Jamie Madillc29968b2016-01-20 11:17:23 -05007285} // namespace gl