blob: cbaa51501af0d99484a5b48664b67f5df7dcd5df [file] [log] [blame]
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001//
Geoff Langcec35902014-04-16 10:52:36 -04002// Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
Geoff Lange8ebe7f2013-08-05 15:03:13 -04003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// validationES3.cpp: Validation functions for OpenGL ES 3.0 entry point parameters
8
Jamie Madill778bf092018-11-14 09:54:36 -05009#include "libANGLE/validationES3_autogen.h"
Jamie Madille2e406c2016-06-02 13:04:10 -040010
Jamie Madill5ea762a2017-06-07 14:59:51 -040011#include "anglebase/numerics/safe_conversions.h"
Jamie Madilld2f0c742016-11-02 10:34:41 -040012#include "common/mathutil.h"
13#include "common/utilities.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050014#include "libANGLE/Context.h"
Martin Radev137032d2017-07-13 10:11:12 +030015#include "libANGLE/ErrorStrings.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050016#include "libANGLE/Framebuffer.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050017#include "libANGLE/FramebufferAttachment.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040018#include "libANGLE/Renderbuffer.h"
19#include "libANGLE/Texture.h"
Jamie Madillc1fd7372018-10-26 22:48:39 -040020#include "libANGLE/VertexArray.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040021#include "libANGLE/formatutils.h"
22#include "libANGLE/validationES.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040023
Jamie Madille2e406c2016-06-02 13:04:10 -040024using namespace angle;
25
Geoff Lange8ebe7f2013-08-05 15:03:13 -040026namespace gl
27{
28
Martin Radev137032d2017-07-13 10:11:12 +030029namespace
30{
31bool ValidateFramebufferTextureMultiviewBaseANGLE(Context *context,
32 GLenum target,
33 GLenum attachment,
34 GLuint texture,
35 GLint level,
36 GLsizei numViews)
37{
38 if (!context->getExtensions().multiview)
39 {
Jamie Madill610640f2018-11-21 17:28:41 -050040 context->validationError(GL_INVALID_OPERATION, kErrorMultiviewNotAvailable);
Martin Radev137032d2017-07-13 10:11:12 +030041 return false;
42 }
43
44 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
45 {
46 return false;
47 }
48
Martin Radev14b21262017-08-25 13:54:37 +030049 if (texture != 0 && numViews < 1)
Martin Radev137032d2017-07-13 10:11:12 +030050 {
Jamie Madill610640f2018-11-21 17:28:41 -050051 context->validationError(GL_INVALID_VALUE, kErrorMultiviewViewsTooSmall);
Martin Radev137032d2017-07-13 10:11:12 +030052 return false;
53 }
54
55 const Extensions &extensions = context->getExtensions();
56 if (static_cast<GLuint>(numViews) > extensions.maxViews)
57 {
Jamie Madill610640f2018-11-21 17:28:41 -050058 context->validationError(GL_INVALID_VALUE, kErrorMultiviewViewsTooLarge);
Martin Radev137032d2017-07-13 10:11:12 +030059 return false;
60 }
61
62 return true;
63}
64
65bool ValidateFramebufferTextureMultiviewLevelAndFormat(Context *context,
66 Texture *texture,
67 GLint level)
68{
Corentin Wallezf0e89be2017-11-08 14:00:32 -080069 TextureType type = texture->getType();
70 if (!ValidMipLevel(context, type, level))
Martin Radev137032d2017-07-13 10:11:12 +030071 {
Jamie Madill610640f2018-11-21 17:28:41 -050072 context->validationError(GL_INVALID_VALUE, kErrorInvalidMipLevel);
Martin Radev137032d2017-07-13 10:11:12 +030073 return false;
74 }
75
Corentin Wallezf0e89be2017-11-08 14:00:32 -080076 const auto &format = texture->getFormat(NonCubeTextureTypeToTarget(type), level);
Martin Radev137032d2017-07-13 10:11:12 +030077 if (format.info->compressed)
78 {
Jamie Madill610640f2018-11-21 17:28:41 -050079 context->validationError(GL_INVALID_OPERATION, kErrorCompressedTexturesNotAttachable);
Martin Radev137032d2017-07-13 10:11:12 +030080 return false;
81 }
82 return true;
83}
84
Jamie Madillff325f12017-08-26 15:06:05 -040085bool ValidateUniformES3(Context *context, GLenum uniformType, GLint location, GLint count)
86{
87 if (context->getClientMajorVersion() < 3)
88 {
Jamie Madill610640f2018-11-21 17:28:41 -050089 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madillff325f12017-08-26 15:06:05 -040090 return false;
91 }
92
93 return ValidateUniform(context, uniformType, location, count);
94}
95
Jamie Madillc8c95812017-08-26 18:40:09 -040096bool ValidateUniformMatrixES3(Context *context,
97 GLenum valueType,
98 GLint location,
99 GLsizei count,
100 GLboolean transpose)
101{
102 // Check for ES3 uniform entry points
103 if (context->getClientMajorVersion() < 3)
104 {
Jamie Madill610640f2018-11-21 17:28:41 -0500105 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madillc8c95812017-08-26 18:40:09 -0400106 return false;
107 }
108
109 return ValidateUniformMatrix(context, valueType, location, count, transpose);
110}
111
Yunchao Hef0fd87d2017-09-12 04:55:05 +0800112bool ValidateGenOrDeleteES3(Context *context, GLint n)
113{
114 if (context->getClientMajorVersion() < 3)
115 {
Jamie Madill610640f2018-11-21 17:28:41 -0500116 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Yunchao Hef0fd87d2017-09-12 04:55:05 +0800117 return false;
118 }
119 return ValidateGenOrDelete(context, n);
120}
121
122bool ValidateGenOrDeleteCountES3(Context *context, GLint count)
123{
124 if (context->getClientMajorVersion() < 3)
125 {
Jamie Madill610640f2018-11-21 17:28:41 -0500126 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Yunchao Hef0fd87d2017-09-12 04:55:05 +0800127 return false;
128 }
129 if (count < 0)
130 {
Jamie Madill610640f2018-11-21 17:28:41 -0500131 context->validationError(GL_INVALID_VALUE, kErrorNegativeCount);
Yunchao Hef0fd87d2017-09-12 04:55:05 +0800132 return false;
133 }
134 return true;
135}
136
Brandon Jones4e6f2ae2018-09-19 11:09:51 -0700137bool ValidateCopyTexture3DCommon(Context *context,
138 const Texture *source,
139 GLint sourceLevel,
140 GLint srcInternalFormat,
141 const Texture *dest,
142 GLint destLevel,
143 GLint internalFormat,
144 TextureTarget destTarget)
145{
146 if (context->getClientMajorVersion() < 3)
147 {
Jamie Madill610640f2018-11-21 17:28:41 -0500148 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -0700149 return false;
150 }
151
152 if (!context->getExtensions().copyTexture3d)
153 {
Jamie Madill610640f2018-11-21 17:28:41 -0500154 context->validationError(GL_INVALID_OPERATION, kErrorANGLECopyTexture3DUnavailable);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -0700155 return false;
156 }
157
158 if (!ValidTexture3DTarget(context, source->getType()))
159 {
Jamie Madill610640f2018-11-21 17:28:41 -0500160 context->validationError(GL_INVALID_ENUM, kErrorInvalidTextureTarget);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -0700161 return false;
162 }
163
164 // Table 1.1 from the ANGLE_copy_texture_3d spec
165 switch (GetUnsizedFormat(srcInternalFormat))
166 {
167 case GL_ALPHA:
168 case GL_LUMINANCE:
169 case GL_LUMINANCE_ALPHA:
170 case GL_RED:
171 case GL_RED_INTEGER:
172 case GL_RG:
173 case GL_RG_INTEGER:
174 case GL_RGB:
175 case GL_RGB_INTEGER:
176 case GL_RGBA:
177 case GL_RGBA_INTEGER:
178 case GL_DEPTH_COMPONENT:
179 case GL_DEPTH_STENCIL:
180 break;
181 default:
Jamie Madill610640f2018-11-21 17:28:41 -0500182 context->validationError(GL_INVALID_OPERATION, kErrorInvalidInternalFormat);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -0700183 return false;
184 }
185
186 if (!ValidTexture3DTarget(context, TextureTargetToType(destTarget)))
187 {
Jamie Madill610640f2018-11-21 17:28:41 -0500188 context->validationError(GL_INVALID_ENUM, kErrorInvalidTextureTarget);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -0700189 return false;
190 }
191
192 // Table 1.0 from the ANGLE_copy_texture_3d spec
193 switch (internalFormat)
194 {
195 case GL_RGB:
196 case GL_RGBA:
197 case GL_LUMINANCE:
198 case GL_LUMINANCE_ALPHA:
199 case GL_ALPHA:
200 case GL_R8:
201 case GL_R8_SNORM:
202 case GL_R16F:
203 case GL_R32F:
204 case GL_R8UI:
205 case GL_R8I:
206 case GL_R16UI:
207 case GL_R16I:
208 case GL_R32UI:
209 case GL_R32I:
210 case GL_RG:
211 case GL_RG8:
212 case GL_RG8_SNORM:
213 case GL_RG16F:
214 case GL_RG32F:
215 case GL_RG8UI:
216 case GL_RG8I:
217 case GL_RG16UI:
218 case GL_RG16I:
219 case GL_RG32UI:
220 case GL_RG32I:
221 case GL_RGB8:
222 case GL_SRGB8:
223 case GL_RGB565:
224 case GL_RGB8_SNORM:
225 case GL_R11F_G11F_B10F:
226 case GL_RGB9_E5:
227 case GL_RGB16F:
228 case GL_RGB32F:
229 case GL_RGB8UI:
230 case GL_RGB8I:
231 case GL_RGB16UI:
232 case GL_RGB16I:
233 case GL_RGB32UI:
234 case GL_RGB32I:
235 case GL_RGBA8:
236 case GL_SRGB8_ALPHA8:
237 case GL_RGBA8_SNORM:
238 case GL_RGB5_A1:
239 case GL_RGBA4:
240 case GL_RGB10_A2:
241 case GL_RGBA16F:
242 case GL_RGBA32F:
243 case GL_RGBA8UI:
244 case GL_RGBA8I:
245 case GL_RGB10_A2UI:
246 case GL_RGBA16UI:
247 case GL_RGBA16I:
248 case GL_RGBA32I:
249 case GL_RGBA32UI:
250 break;
251 default:
Jamie Madill610640f2018-11-21 17:28:41 -0500252 context->validationError(GL_INVALID_OPERATION, kErrorInvalidInternalFormat);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -0700253 return false;
254 }
255
256 return true;
257}
Jamie Madillff325f12017-08-26 15:06:05 -0400258} // anonymous namespace
Martin Radev137032d2017-07-13 10:11:12 +0300259
He Yunchaoced53ae2016-11-29 15:00:51 +0800260static bool ValidateTexImageFormatCombination(gl::Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800261 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +0800262 GLenum internalFormat,
263 GLenum format,
264 GLenum type)
Geoff Lang5d601382014-07-22 15:14:06 -0400265{
Geoff Lang5d601382014-07-22 15:14:06 -0400266
267 // The type and format are valid if any supported internal format has that type and format
Geoff Lang6d1ccf02017-04-24 14:09:58 -0400268 if (!ValidES3Format(format))
Geoff Lang5d601382014-07-22 15:14:06 -0400269 {
Jamie Madill610640f2018-11-21 17:28:41 -0500270 context->validationError(GL_INVALID_ENUM, kErrorInvalidFormat);
Geoff Lang6d1ccf02017-04-24 14:09:58 -0400271 return false;
272 }
273
274 if (!ValidES3Type(type))
275 {
Jamie Madill610640f2018-11-21 17:28:41 -0500276 context->validationError(GL_INVALID_ENUM, kErrorInvalidType);
Geoff Lang6d1ccf02017-04-24 14:09:58 -0400277 return false;
278 }
279
280 // For historical reasons, glTexImage2D and glTexImage3D pass in their internal format as a
281 // GLint instead of a GLenum. Therefor an invalid internal format gives a GL_INVALID_VALUE
282 // error instead of a GL_INVALID_ENUM error. As this validation function is only called in
283 // the validation codepaths for glTexImage2D/3D, we record a GL_INVALID_VALUE error.
284 if (!ValidES3InternalFormat(internalFormat))
285 {
Jamie Madill610640f2018-11-21 17:28:41 -0500286 context->validationError(GL_INVALID_VALUE, kErrorInvalidInternalFormat);
Geoff Langb1196682014-07-23 13:47:29 -0400287 return false;
Geoff Lang5d601382014-07-22 15:14:06 -0400288 }
289
Geoff Langca271392017-04-05 12:30:00 -0400290 // From the ES 3.0 spec section 3.8.3:
291 // Textures with a base internal format of DEPTH_COMPONENT or DEPTH_STENCIL are supported by
292 // texture image specification commands only if target is TEXTURE_2D, TEXTURE_2D_ARRAY, or
293 // TEXTURE_CUBE_MAP.Using these formats in conjunction with any other target will result in an
294 // INVALID_OPERATION error.
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800295 if (target == TextureType::_3D && (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL))
Geoff Langca271392017-04-05 12:30:00 -0400296 {
Jamie Madill610640f2018-11-21 17:28:41 -0500297 context->validationError(GL_INVALID_OPERATION, kError3DDepthStencil);
Geoff Langca271392017-04-05 12:30:00 -0400298 return false;
299 }
300
Geoff Lang5d601382014-07-22 15:14:06 -0400301 // Check if this is a valid format combination to load texture data
Jamie Madill55e98212016-10-05 16:39:13 -0400302 if (!ValidES3FormatCombination(format, type, internalFormat))
Geoff Lang5d601382014-07-22 15:14:06 -0400303 {
Jamie Madill610640f2018-11-21 17:28:41 -0500304 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFormatCombination);
Geoff Lang6d1ccf02017-04-24 14:09:58 -0400305 return false;
306 }
307
308 const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat, type);
309 if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
310 {
Jamie Madill610640f2018-11-21 17:28:41 -0500311 context->validationError(GL_INVALID_OPERATION, kErrorInvalidInternalFormat);
Geoff Langb1196682014-07-23 13:47:29 -0400312 return false;
Geoff Lang5d601382014-07-22 15:14:06 -0400313 }
314
315 return true;
316}
317
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500318bool ValidateES3TexImageParametersBase(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800319 TextureTarget target,
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500320 GLint level,
321 GLenum internalformat,
322 bool isCompressed,
323 bool isSubImage,
324 GLint xoffset,
325 GLint yoffset,
326 GLint zoffset,
327 GLsizei width,
328 GLsizei height,
329 GLsizei depth,
330 GLint border,
331 GLenum format,
332 GLenum type,
Geoff Langff5b2d52016-09-07 11:32:23 -0400333 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -0400334 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400335{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800336 TextureType texType = TextureTargetToType(target);
337
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400338 // Validate image size
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800339 if (!ValidImageSizeParameters(context, texType, level, width, height, depth, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400340 {
Jamie Madill610640f2018-11-21 17:28:41 -0500341 // Error already processed.
Geoff Langb1196682014-07-23 13:47:29 -0400342 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400343 }
344
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400345 // Verify zero border
346 if (border != 0)
347 {
Jamie Madill610640f2018-11-21 17:28:41 -0500348 context->validationError(GL_INVALID_VALUE, kErrorInvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -0400349 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400350 }
351
Jamie Madill610640f2018-11-21 17:28:41 -0500352 if (xoffset < 0 || yoffset < 0 || zoffset < 0)
353 {
354 context->validationError(GL_INVALID_VALUE, kErrorNegativeOffset);
355 return false;
356 }
357
358 if (std::numeric_limits<GLsizei>::max() - xoffset < width ||
Jamie Madill6f38f822014-06-06 17:12:20 -0400359 std::numeric_limits<GLsizei>::max() - yoffset < height ||
360 std::numeric_limits<GLsizei>::max() - zoffset < depth)
361 {
Jamie Madill610640f2018-11-21 17:28:41 -0500362 context->validationError(GL_INVALID_VALUE, kErrorOffsetOverflow);
Geoff Langb1196682014-07-23 13:47:29 -0400363 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -0400364 }
365
Geoff Langaae65a42014-05-26 12:43:44 -0400366 const gl::Caps &caps = context->getCaps();
367
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800368 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400369 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800370 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +0800371 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
372 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
373 {
Jamie Madill610640f2018-11-21 17:28:41 -0500374 context->validationError(GL_INVALID_VALUE, kErrorResourceMaxTextureSize);
He Yunchaoced53ae2016-11-29 15:00:51 +0800375 return false;
376 }
377 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400378
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800379 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400380 ASSERT(level == 0);
381 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
382 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
383 {
Jamie Madill610640f2018-11-21 17:28:41 -0500384 context->validationError(GL_INVALID_VALUE, kErrorResourceMaxTextureSize);
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400385 return false;
386 }
387 if (isCompressed)
388 {
Jamie Madill610640f2018-11-21 17:28:41 -0500389 context->validationError(GL_INVALID_ENUM, kErrorRectangleTextureCompressed);
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400390 return false;
391 }
392 break;
393
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800394 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +0800395 if (!isSubImage && width != height)
396 {
Jamie Madill610640f2018-11-21 17:28:41 -0500397 context->validationError(GL_INVALID_VALUE, kErrorCubemapFacesEqualDimensions);
He Yunchaoced53ae2016-11-29 15:00:51 +0800398 return false;
399 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400400
He Yunchaoced53ae2016-11-29 15:00:51 +0800401 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level))
402 {
Jamie Madill610640f2018-11-21 17:28:41 -0500403 context->validationError(GL_INVALID_VALUE, kErrorResourceMaxTextureSize);
He Yunchaoced53ae2016-11-29 15:00:51 +0800404 return false;
405 }
406 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400407
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800408 case TextureType::_3D:
He Yunchaoced53ae2016-11-29 15:00:51 +0800409 if (static_cast<GLuint>(width) > (caps.max3DTextureSize >> level) ||
410 static_cast<GLuint>(height) > (caps.max3DTextureSize >> level) ||
411 static_cast<GLuint>(depth) > (caps.max3DTextureSize >> level))
412 {
Jamie Madill610640f2018-11-21 17:28:41 -0500413 context->validationError(GL_INVALID_VALUE, kErrorResourceMaxTextureSize);
He Yunchaoced53ae2016-11-29 15:00:51 +0800414 return false;
415 }
416 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400417
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800418 case TextureType::_2DArray:
He Yunchaoced53ae2016-11-29 15:00:51 +0800419 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
420 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level) ||
421 static_cast<GLuint>(depth) > caps.maxArrayTextureLayers)
422 {
Jamie Madill610640f2018-11-21 17:28:41 -0500423 context->validationError(GL_INVALID_VALUE, kErrorResourceMaxTextureSize);
He Yunchaoced53ae2016-11-29 15:00:51 +0800424 return false;
425 }
426 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400427
He Yunchaoced53ae2016-11-29 15:00:51 +0800428 default:
Jamie Madill610640f2018-11-21 17:28:41 -0500429 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +0800430 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400431 }
432
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800433 gl::Texture *texture = context->getTargetTexture(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400434 if (!texture)
435 {
Jamie Madill610640f2018-11-21 17:28:41 -0500436 context->validationError(GL_INVALID_OPERATION, kErrorMissingTexture);
Geoff Langb1196682014-07-23 13:47:29 -0400437 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400438 }
439
Geoff Lang69cce582015-09-17 13:20:36 -0400440 if (texture->getImmutableFormat() && !isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400441 {
Jamie Madill610640f2018-11-21 17:28:41 -0500442 context->validationError(GL_INVALID_OPERATION, kErrorTextureIsImmutable);
Geoff Langb1196682014-07-23 13:47:29 -0400443 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400444 }
445
446 // Validate texture formats
Jamie Madilla3944d42016-07-22 22:13:26 -0400447 GLenum actualInternalFormat =
Geoff Langc4e93662017-05-01 10:45:59 -0400448 isSubImage ? texture->getFormat(target, level).info->internalFormat : internalformat;
Geoff Langc51642b2016-11-14 16:18:26 -0500449 if (isSubImage && actualInternalFormat == GL_NONE)
450 {
Jamie Madill610640f2018-11-21 17:28:41 -0500451 context->validationError(GL_INVALID_OPERATION, "Texture level does not exist.");
Geoff Langc51642b2016-11-14 16:18:26 -0500452 return false;
453 }
454
Geoff Langc4e93662017-05-01 10:45:59 -0400455 const gl::InternalFormat &actualFormatInfo = isSubImage
456 ? *texture->getFormat(target, level).info
457 : GetInternalFormatInfo(internalformat, type);
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400458 if (isCompressed)
459 {
tmartino7c102692015-10-02 16:43:40 -0400460 if (!actualFormatInfo.compressed)
Geoff Langd4f180b2013-09-24 13:57:44 -0400461 {
Jamie Madill610640f2018-11-21 17:28:41 -0500462 context->validationError(
463 GL_INVALID_ENUM, "internalformat is not a supported compressed internal format.");
Geoff Langb1196682014-07-23 13:47:29 -0400464 return false;
Geoff Langd4f180b2013-09-24 13:57:44 -0400465 }
466
Geoff Lang966c9402017-04-18 12:38:27 -0400467 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400468 {
Geoff Lang966c9402017-04-18 12:38:27 -0400469 if (!ValidCompressedSubImageSize(
470 context, actualFormatInfo.internalFormat, xoffset, yoffset, width, height,
471 texture->getWidth(target, level), texture->getHeight(target, level)))
472 {
Jamie Madill610640f2018-11-21 17:28:41 -0500473 context->validationError(GL_INVALID_OPERATION,
474 "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -0400475 return false;
476 }
477
478 if (format != actualInternalFormat)
479 {
Jamie Madill610640f2018-11-21 17:28:41 -0500480 context->validationError(GL_INVALID_OPERATION,
481 "Format must match the internal format of the texture.");
Geoff Lang966c9402017-04-18 12:38:27 -0400482 return false;
483 }
Geoff Lang86f81162017-10-30 15:10:45 -0400484
485 if (actualInternalFormat == GL_ETC1_RGB8_OES)
486 {
Jamie Madill610640f2018-11-21 17:28:41 -0500487 context->validationError(GL_INVALID_OPERATION, kErrorInvalidInternalFormat);
Geoff Lang86f81162017-10-30 15:10:45 -0400488 return false;
489 }
Geoff Lang966c9402017-04-18 12:38:27 -0400490 }
491 else
492 {
493 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
494 {
Jamie Madill610640f2018-11-21 17:28:41 -0500495 context->validationError(GL_INVALID_OPERATION,
496 "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -0400497 return false;
498 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400499 }
500
Geoff Langeb66a6e2016-10-31 13:06:12 -0400501 if (!actualFormatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
Geoff Lang839ce0b2015-10-23 13:13:12 -0400502 {
Jamie Madill610640f2018-11-21 17:28:41 -0500503 context->validationError(GL_INVALID_ENUM, kErrorInvalidFormat);
Geoff Lang839ce0b2015-10-23 13:13:12 -0400504 return false;
505 }
506
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800507 if (texType == TextureType::_3D)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400508 {
Jamie Madill610640f2018-11-21 17:28:41 -0500509 context->validationError(GL_INVALID_OPERATION, kErrorInvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -0400510 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400511 }
512 }
513 else
514 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800515 if (!ValidateTexImageFormatCombination(context, texType, actualInternalFormat, format,
516 type))
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400517 {
Geoff Lang5d601382014-07-22 15:14:06 -0400518 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400519 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400520 }
521
522 // Validate sub image parameters
523 if (isSubImage)
524 {
Geoff Langa9be0dc2014-12-17 12:34:40 -0500525 if (isCompressed != actualFormatInfo.compressed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400526 {
Jamie Madill610640f2018-11-21 17:28:41 -0500527 context->validationError(GL_INVALID_OPERATION, kErrorCompressedMismatch);
Geoff Langb1196682014-07-23 13:47:29 -0400528 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400529 }
530
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400531 if (xoffset < 0 || yoffset < 0 || zoffset < 0)
532 {
Jamie Madill610640f2018-11-21 17:28:41 -0500533 context->validationError(GL_INVALID_VALUE, kErrorNegativeOffset);
Geoff Langb1196682014-07-23 13:47:29 -0400534 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400535 }
536
537 if (std::numeric_limits<GLsizei>::max() - xoffset < width ||
538 std::numeric_limits<GLsizei>::max() - yoffset < height ||
539 std::numeric_limits<GLsizei>::max() - zoffset < depth)
540 {
Jamie Madill610640f2018-11-21 17:28:41 -0500541 context->validationError(GL_INVALID_VALUE, kErrorOffsetOverflow);
Geoff Langb1196682014-07-23 13:47:29 -0400542 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400543 }
544
Geoff Langa9be0dc2014-12-17 12:34:40 -0500545 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
546 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level) ||
547 static_cast<size_t>(zoffset + depth) > texture->getDepth(target, level))
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400548 {
Jamie Madill610640f2018-11-21 17:28:41 -0500549 context->validationError(GL_INVALID_VALUE, kErrorOffsetOverflow);
Geoff Langb1196682014-07-23 13:47:29 -0400550 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400551 }
Geoff Langfb052642017-10-24 13:42:09 -0400552
553 if (width > 0 && height > 0 && depth > 0 && pixels == nullptr &&
Corentin Wallez336129f2017-10-17 15:55:40 -0400554 context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack) == nullptr)
Geoff Langfb052642017-10-24 13:42:09 -0400555 {
Jamie Madill610640f2018-11-21 17:28:41 -0500556 context->validationError(GL_INVALID_VALUE, kErrorPixelDataNull);
Geoff Langfb052642017-10-24 13:42:09 -0400557 return false;
558 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400559 }
560
Geoff Langdbcced82017-06-06 15:55:54 -0400561 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800562 if (!ValidImageDataSize(context, texType, width, height, depth, sizeCheckFormat, type, pixels,
Geoff Langdbcced82017-06-06 15:55:54 -0400563 imageSize))
Geoff Langff5b2d52016-09-07 11:32:23 -0400564 {
565 return false;
566 }
567
Jamie Madillefb2a6f2013-09-24 10:22:42 -0400568 // Check for pixel unpack buffer related API errors
Corentin Wallez336129f2017-10-17 15:55:40 -0400569 gl::Buffer *pixelUnpackBuffer =
570 context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack);
Corentin Wallezece7c5a2016-09-21 15:28:23 -0400571 if (pixelUnpackBuffer != nullptr)
Jamie Madillefb2a6f2013-09-24 10:22:42 -0400572 {
He Yunchaoced53ae2016-11-29 15:00:51 +0800573 // ...data is not evenly divisible into the number of bytes needed to store in memory a
574 // datum
Jamie Madillefb2a6f2013-09-24 10:22:42 -0400575 // indicated by type.
Jamie Madillc751d1e2014-10-21 17:46:29 -0400576 if (!isCompressed)
Jamie Madillefb2a6f2013-09-24 10:22:42 -0400577 {
Geoff Langff5b2d52016-09-07 11:32:23 -0400578 size_t offset = reinterpret_cast<size_t>(pixels);
Jamie Madillc751d1e2014-10-21 17:46:29 -0400579 size_t dataBytesPerPixel = static_cast<size_t>(gl::GetTypeInfo(type).bytes);
580
Geoff Langff5b2d52016-09-07 11:32:23 -0400581 if ((offset % dataBytesPerPixel) != 0)
Jamie Madillc751d1e2014-10-21 17:46:29 -0400582 {
Jamie Madill610640f2018-11-21 17:28:41 -0500583 context->validationError(GL_INVALID_OPERATION,
584 "Reads would overflow the pixel unpack buffer.");
Jamie Madillc751d1e2014-10-21 17:46:29 -0400585 return false;
586 }
Jamie Madillefb2a6f2013-09-24 10:22:42 -0400587 }
588
Jamie Madill7a5f7382014-03-05 15:01:24 -0500589 // ...the buffer object's data store is currently mapped.
Brandon Jonesd38f9262014-06-18 16:26:45 -0700590 if (pixelUnpackBuffer->isMapped())
Jamie Madill7a5f7382014-03-05 15:01:24 -0500591 {
Jamie Madill610640f2018-11-21 17:28:41 -0500592 context->validationError(GL_INVALID_OPERATION, "Pixel unpack buffer is mapped.");
Geoff Langb1196682014-07-23 13:47:29 -0400593 return false;
Jamie Madill7a5f7382014-03-05 15:01:24 -0500594 }
Jamie Madillefb2a6f2013-09-24 10:22:42 -0400595 }
596
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400597 return true;
598}
599
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500600bool ValidateES3TexImage2DParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800601 TextureTarget target,
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500602 GLint level,
603 GLenum internalformat,
604 bool isCompressed,
605 bool isSubImage,
606 GLint xoffset,
607 GLint yoffset,
608 GLint zoffset,
609 GLsizei width,
610 GLsizei height,
611 GLsizei depth,
612 GLint border,
613 GLenum format,
614 GLenum type,
Geoff Langff5b2d52016-09-07 11:32:23 -0400615 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -0400616 const void *pixels)
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500617{
618 if (!ValidTexture2DDestinationTarget(context, target))
619 {
Jamie Madill610640f2018-11-21 17:28:41 -0500620 context->validationError(GL_INVALID_ENUM, kErrorInvalidTextureTarget);
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500621 return false;
622 }
623
624 return ValidateES3TexImageParametersBase(context, target, level, internalformat, isCompressed,
625 isSubImage, xoffset, yoffset, zoffset, width, height,
Geoff Langff5b2d52016-09-07 11:32:23 -0400626 depth, border, format, type, imageSize, pixels);
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500627}
628
629bool ValidateES3TexImage3DParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800630 TextureType target,
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500631 GLint level,
632 GLenum internalformat,
633 bool isCompressed,
634 bool isSubImage,
635 GLint xoffset,
636 GLint yoffset,
637 GLint zoffset,
638 GLsizei width,
639 GLsizei height,
640 GLsizei depth,
641 GLint border,
642 GLenum format,
643 GLenum type,
Geoff Langc52f6f12016-10-14 10:18:00 -0400644 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -0400645 const void *pixels)
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500646{
647 if (!ValidTexture3DDestinationTarget(context, target))
648 {
Jamie Madill610640f2018-11-21 17:28:41 -0500649 context->validationError(GL_INVALID_ENUM, kErrorInvalidTextureTarget);
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500650 return false;
651 }
652
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800653 if (IsETC2EACFormat(format) && target != TextureType::_2DArray)
Luc Ferron9dbaeba2018-02-01 07:26:59 -0500654 {
655 // ES 3.1, Section 8.7, page 169.
Jamie Madill610640f2018-11-21 17:28:41 -0500656 context->validationError(GL_INVALID_OPERATION, kErrorInternalFormatRequiresTexture2DArray);
Luc Ferron9dbaeba2018-02-01 07:26:59 -0500657 return false;
658 }
659
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800660 return ValidateES3TexImageParametersBase(context, NonCubeTextureTypeToTarget(target), level,
661 internalformat, isCompressed, isSubImage, xoffset,
662 yoffset, zoffset, width, height, depth, border, format,
663 type, bufSize, pixels);
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500664}
665
Geoff Lang5d601382014-07-22 15:14:06 -0400666struct EffectiveInternalFormatInfo
667{
Jamie Madill76648fe2016-10-05 17:01:41 -0400668 GLenum effectiveFormat;
669 GLenum destFormat;
670 GLuint minRedBits;
671 GLuint maxRedBits;
672 GLuint minGreenBits;
673 GLuint maxGreenBits;
674 GLuint minBlueBits;
675 GLuint maxBlueBits;
676 GLuint minAlphaBits;
677 GLuint maxAlphaBits;
Geoff Lang5d601382014-07-22 15:14:06 -0400678};
679
Jamie Madill76648fe2016-10-05 17:01:41 -0400680static bool QueryEffectiveFormatList(const InternalFormat &srcFormat,
681 GLenum targetFormat,
682 const EffectiveInternalFormatInfo *list,
683 size_t size,
684 GLenum *outEffectiveFormat)
Geoff Lang5d601382014-07-22 15:14:06 -0400685{
Jamie Madill76648fe2016-10-05 17:01:41 -0400686 for (size_t curFormat = 0; curFormat < size; ++curFormat)
687 {
688 const EffectiveInternalFormatInfo &formatInfo = list[curFormat];
689 if ((formatInfo.destFormat == targetFormat) &&
690 (formatInfo.minRedBits <= srcFormat.redBits &&
691 formatInfo.maxRedBits >= srcFormat.redBits) &&
692 (formatInfo.minGreenBits <= srcFormat.greenBits &&
693 formatInfo.maxGreenBits >= srcFormat.greenBits) &&
694 (formatInfo.minBlueBits <= srcFormat.blueBits &&
695 formatInfo.maxBlueBits >= srcFormat.blueBits) &&
696 (formatInfo.minAlphaBits <= srcFormat.alphaBits &&
697 formatInfo.maxAlphaBits >= srcFormat.alphaBits))
698 {
699 *outEffectiveFormat = formatInfo.effectiveFormat;
700 return true;
701 }
702 }
Geoff Lang5d601382014-07-22 15:14:06 -0400703
Jamie Madill76648fe2016-10-05 17:01:41 -0400704 *outEffectiveFormat = GL_NONE;
705 return false;
Geoff Lang5d601382014-07-22 15:14:06 -0400706}
707
Jamie Madill76648fe2016-10-05 17:01:41 -0400708bool GetSizedEffectiveInternalFormatInfo(const InternalFormat &srcFormat,
709 GLenum *outEffectiveFormat)
Geoff Lang5d601382014-07-22 15:14:06 -0400710{
Jamie Madill76648fe2016-10-05 17:01:41 -0400711 // OpenGL ES 3.0.3 Specification, Table 3.17, pg 141:
712 // Effective internal format coresponding to destination internal format and linear source
713 // buffer component sizes.
714 // | Source channel min/max sizes |
715 // Effective Internal Format | N/A | R | G | B | A |
716 // clang-format off
717 constexpr EffectiveInternalFormatInfo list[] = {
718 { GL_ALPHA8_EXT, GL_NONE, 0, 0, 0, 0, 0, 0, 1, 8 },
719 { GL_R8, GL_NONE, 1, 8, 0, 0, 0, 0, 0, 0 },
720 { GL_RG8, GL_NONE, 1, 8, 1, 8, 0, 0, 0, 0 },
721 { GL_RGB565, GL_NONE, 1, 5, 1, 6, 1, 5, 0, 0 },
722 { GL_RGB8, GL_NONE, 6, 8, 7, 8, 6, 8, 0, 0 },
723 { GL_RGBA4, GL_NONE, 1, 4, 1, 4, 1, 4, 1, 4 },
724 { GL_RGB5_A1, GL_NONE, 5, 5, 5, 5, 5, 5, 1, 1 },
725 { GL_RGBA8, GL_NONE, 5, 8, 5, 8, 5, 8, 2, 8 },
726 { GL_RGB10_A2, GL_NONE, 9, 10, 9, 10, 9, 10, 2, 2 },
727 };
728 // clang-format on
Geoff Lang5d601382014-07-22 15:14:06 -0400729
Jamie Madill76648fe2016-10-05 17:01:41 -0400730 return QueryEffectiveFormatList(srcFormat, GL_NONE, list, ArraySize(list), outEffectiveFormat);
731}
Geoff Lang5d601382014-07-22 15:14:06 -0400732
Jamie Madill76648fe2016-10-05 17:01:41 -0400733bool GetUnsizedEffectiveInternalFormatInfo(const InternalFormat &srcFormat,
734 const InternalFormat &destFormat,
735 GLenum *outEffectiveFormat)
736{
737 constexpr GLuint umax = UINT_MAX;
738
739 // OpenGL ES 3.0.3 Specification, Table 3.17, pg 141:
740 // Effective internal format coresponding to destination internal format andlinear source buffer
741 // component sizes.
742 // | Source channel min/max sizes |
743 // Effective Internal Format | Dest Format | R | G | B | A |
744 // clang-format off
745 constexpr EffectiveInternalFormatInfo list[] = {
746 { GL_ALPHA8_EXT, GL_ALPHA, 0, umax, 0, umax, 0, umax, 1, 8 },
747 { GL_LUMINANCE8_EXT, GL_LUMINANCE, 1, 8, 0, umax, 0, umax, 0, umax },
748 { GL_LUMINANCE8_ALPHA8_EXT, GL_LUMINANCE_ALPHA, 1, 8, 0, umax, 0, umax, 1, 8 },
749 { GL_RGB565, GL_RGB, 1, 5, 1, 6, 1, 5, 0, umax },
750 { GL_RGB8, GL_RGB, 6, 8, 7, 8, 6, 8, 0, umax },
751 { GL_RGBA4, GL_RGBA, 1, 4, 1, 4, 1, 4, 1, 4 },
752 { GL_RGB5_A1, GL_RGBA, 5, 5, 5, 5, 5, 5, 1, 1 },
753 { GL_RGBA8, GL_RGBA, 5, 8, 5, 8, 5, 8, 5, 8 },
754 };
755 // clang-format on
756
757 return QueryEffectiveFormatList(srcFormat, destFormat.format, list, ArraySize(list),
758 outEffectiveFormat);
Geoff Lang5d601382014-07-22 15:14:06 -0400759}
760
He Yunchaoced53ae2016-11-29 15:00:51 +0800761static bool GetEffectiveInternalFormat(const InternalFormat &srcFormat,
762 const InternalFormat &destFormat,
Geoff Lang5d601382014-07-22 15:14:06 -0400763 GLenum *outEffectiveFormat)
764{
Geoff Langca271392017-04-05 12:30:00 -0400765 if (destFormat.sized)
Geoff Lang5d601382014-07-22 15:14:06 -0400766 {
Jamie Madill76648fe2016-10-05 17:01:41 -0400767 return GetSizedEffectiveInternalFormatInfo(srcFormat, outEffectiveFormat);
Geoff Lang5d601382014-07-22 15:14:06 -0400768 }
769 else
770 {
Jamie Madill76648fe2016-10-05 17:01:41 -0400771 return GetUnsizedEffectiveInternalFormatInfo(srcFormat, destFormat, outEffectiveFormat);
Geoff Lang5d601382014-07-22 15:14:06 -0400772 }
Geoff Lang5d601382014-07-22 15:14:06 -0400773}
774
Corentin Wallez76287682016-04-25 09:23:38 -0400775static bool EqualOrFirstZero(GLuint first, GLuint second)
776{
777 return first == 0 || first == second;
778}
779
Geoff Langca271392017-04-05 12:30:00 -0400780static bool IsValidES3CopyTexImageCombination(const InternalFormat &textureFormatInfo,
781 const InternalFormat &framebufferFormatInfo,
Jamie Madill0c8abca2016-07-22 20:21:26 -0400782 GLuint readBufferHandle)
Geoff Lang5d601382014-07-22 15:14:06 -0400783{
Jamie Madill21b786b2016-11-01 17:41:31 -0400784 if (!ValidES3CopyConversion(textureFormatInfo.format, framebufferFormatInfo.format))
Geoff Lang5d601382014-07-22 15:14:06 -0400785 {
Jamie Madill21b786b2016-11-01 17:41:31 -0400786 return false;
787 }
Geoff Lang5d601382014-07-22 15:14:06 -0400788
Jamie Madill21b786b2016-11-01 17:41:31 -0400789 // Section 3.8.5 of the GLES 3.0.3 spec states that source and destination formats
790 // must both be signed, unsigned, or fixed point and both source and destinations
791 // must be either both SRGB or both not SRGB. EXT_color_buffer_float adds allowed
792 // conversion between fixed and floating point.
793
794 if ((textureFormatInfo.colorEncoding == GL_SRGB) !=
795 (framebufferFormatInfo.colorEncoding == GL_SRGB))
796 {
797 return false;
798 }
799
800 if (((textureFormatInfo.componentType == GL_INT) !=
801 (framebufferFormatInfo.componentType == GL_INT)) ||
802 ((textureFormatInfo.componentType == GL_UNSIGNED_INT) !=
803 (framebufferFormatInfo.componentType == GL_UNSIGNED_INT)))
804 {
805 return false;
806 }
807
808 if ((textureFormatInfo.componentType == GL_UNSIGNED_NORMALIZED ||
809 textureFormatInfo.componentType == GL_SIGNED_NORMALIZED ||
810 textureFormatInfo.componentType == GL_FLOAT) &&
811 !(framebufferFormatInfo.componentType == GL_UNSIGNED_NORMALIZED ||
812 framebufferFormatInfo.componentType == GL_SIGNED_NORMALIZED ||
813 framebufferFormatInfo.componentType == GL_FLOAT))
814 {
815 return false;
816 }
817
818 // GLES specification 3.0.3, sec 3.8.5, pg 139-140:
819 // The effective internal format of the source buffer is determined with the following rules
820 // applied in order:
821 // * If the source buffer is a texture or renderbuffer that was created with a sized internal
822 // format then the effective internal format is the source buffer's sized internal format.
823 // * If the source buffer is a texture that was created with an unsized base internal format,
824 // then the effective internal format is the source image array's effective internal
825 // format, as specified by table 3.12, which is determined from the <format> and <type>
826 // that were used when the source image array was specified by TexImage*.
827 // * Otherwise the effective internal format is determined by the row in table 3.17 or 3.18
828 // where Destination Internal Format matches internalformat and where the [source channel
829 // sizes] are consistent with the values of the source buffer's [channel sizes]. Table 3.17
830 // is used if the FRAMEBUFFER_ATTACHMENT_ENCODING is LINEAR and table 3.18 is used if the
831 // FRAMEBUFFER_ATTACHMENT_ENCODING is SRGB.
Yunchao Hed7297bf2017-04-19 15:27:10 +0800832 const InternalFormat *sourceEffectiveFormat = nullptr;
Jamie Madill21b786b2016-11-01 17:41:31 -0400833 if (readBufferHandle != 0)
834 {
835 // Not the default framebuffer, therefore the read buffer must be a user-created texture or
836 // renderbuffer
Geoff Langca271392017-04-05 12:30:00 -0400837 if (framebufferFormatInfo.sized)
Geoff Lang5d601382014-07-22 15:14:06 -0400838 {
Jamie Madill21b786b2016-11-01 17:41:31 -0400839 sourceEffectiveFormat = &framebufferFormatInfo;
Geoff Lang5d601382014-07-22 15:14:06 -0400840 }
Jamie Madill21b786b2016-11-01 17:41:31 -0400841 else
Geoff Lang5d601382014-07-22 15:14:06 -0400842 {
Jamie Madill21b786b2016-11-01 17:41:31 -0400843 // Renderbuffers cannot be created with an unsized internal format, so this must be an
844 // unsized-format texture. We can use the same table we use when creating textures to
845 // get its effective sized format.
Geoff Langca271392017-04-05 12:30:00 -0400846 sourceEffectiveFormat =
847 &GetSizedInternalFormatInfo(framebufferFormatInfo.sizedInternalFormat);
Geoff Lang5d601382014-07-22 15:14:06 -0400848 }
Jamie Madill21b786b2016-11-01 17:41:31 -0400849 }
850 else
851 {
852 // The effective internal format must be derived from the source framebuffer's channel
853 // sizes. This is done in GetEffectiveInternalFormat for linear buffers (table 3.17)
854 if (framebufferFormatInfo.colorEncoding == GL_LINEAR)
Geoff Lang5d601382014-07-22 15:14:06 -0400855 {
Jamie Madill21b786b2016-11-01 17:41:31 -0400856 GLenum effectiveFormat;
857 if (GetEffectiveInternalFormat(framebufferFormatInfo, textureFormatInfo,
858 &effectiveFormat))
Geoff Lang5d601382014-07-22 15:14:06 -0400859 {
Geoff Langca271392017-04-05 12:30:00 -0400860 sourceEffectiveFormat = &GetSizedInternalFormatInfo(effectiveFormat);
Geoff Lang5d601382014-07-22 15:14:06 -0400861 }
862 else
863 {
Jamie Madill21b786b2016-11-01 17:41:31 -0400864 return false;
865 }
866 }
867 else if (framebufferFormatInfo.colorEncoding == GL_SRGB)
868 {
869 // SRGB buffers can only be copied to sized format destinations according to table 3.18
Geoff Langca271392017-04-05 12:30:00 -0400870 if (textureFormatInfo.sized &&
Jamie Madill21b786b2016-11-01 17:41:31 -0400871 (framebufferFormatInfo.redBits >= 1 && framebufferFormatInfo.redBits <= 8) &&
872 (framebufferFormatInfo.greenBits >= 1 && framebufferFormatInfo.greenBits <= 8) &&
873 (framebufferFormatInfo.blueBits >= 1 && framebufferFormatInfo.blueBits <= 8) &&
874 (framebufferFormatInfo.alphaBits >= 1 && framebufferFormatInfo.alphaBits <= 8))
875 {
Geoff Langca271392017-04-05 12:30:00 -0400876 sourceEffectiveFormat = &GetSizedInternalFormatInfo(GL_SRGB8_ALPHA8);
Jamie Madill21b786b2016-11-01 17:41:31 -0400877 }
878 else
879 {
880 return false;
Geoff Lang5d601382014-07-22 15:14:06 -0400881 }
882 }
883 else
884 {
Jamie Madill21b786b2016-11-01 17:41:31 -0400885 UNREACHABLE();
886 return false;
Geoff Lang5d601382014-07-22 15:14:06 -0400887 }
Geoff Lang5d601382014-07-22 15:14:06 -0400888 }
889
Geoff Langca271392017-04-05 12:30:00 -0400890 if (textureFormatInfo.sized)
Jamie Madill21b786b2016-11-01 17:41:31 -0400891 {
892 // Section 3.8.5 of the GLES 3.0.3 spec, pg 139, requires that, if the destination format is
893 // sized, component sizes of the source and destination formats must exactly match if the
894 // destination format exists.
895 if (!EqualOrFirstZero(textureFormatInfo.redBits, sourceEffectiveFormat->redBits) ||
896 !EqualOrFirstZero(textureFormatInfo.greenBits, sourceEffectiveFormat->greenBits) ||
897 !EqualOrFirstZero(textureFormatInfo.blueBits, sourceEffectiveFormat->blueBits) ||
898 !EqualOrFirstZero(textureFormatInfo.alphaBits, sourceEffectiveFormat->alphaBits))
899 {
900 return false;
901 }
902 }
903
904 return true; // A conversion function exists, and no rule in the specification has precluded
905 // conversion between these formats.
Geoff Lang5d601382014-07-22 15:14:06 -0400906}
907
Jamie Madill5b772312018-03-08 20:28:32 -0500908bool ValidateES3CopyTexImageParametersBase(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800909 TextureTarget target,
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500910 GLint level,
911 GLenum internalformat,
912 bool isSubImage,
913 GLint xoffset,
914 GLint yoffset,
915 GLint zoffset,
916 GLint x,
917 GLint y,
918 GLsizei width,
919 GLsizei height,
920 GLint border)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400921{
Jamie Madill0c8abca2016-07-22 20:21:26 -0400922 Format textureFormat = Format::Invalid();
Jamie Madill560a8d82014-05-21 13:06:20 -0400923 if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
Jamie Madill0c8abca2016-07-22 20:21:26 -0400924 xoffset, yoffset, zoffset, x, y, width, height, border,
925 &textureFormat))
Shannon Woods4dfed832014-03-17 20:03:39 -0400926 {
Jamie Madill560a8d82014-05-21 13:06:20 -0400927 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400928 }
Jamie Madill0c8abca2016-07-22 20:21:26 -0400929 ASSERT(textureFormat.valid() || !isSubImage);
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400930
Jamie Madill51f40ec2016-06-15 14:06:00 -0400931 const auto &state = context->getGLState();
932 gl::Framebuffer *framebuffer = state.getReadFramebuffer();
933 GLuint readFramebufferID = framebuffer->id();
Jamie Madill3c7fa222014-06-05 13:08:51 -0400934
Jamie Madill427064d2018-04-13 16:20:34 -0400935 if (!ValidateFramebufferComplete(context, framebuffer))
Jamie Madill3c7fa222014-06-05 13:08:51 -0400936 {
Geoff Langb1196682014-07-23 13:47:29 -0400937 return false;
Jamie Madill3c7fa222014-06-05 13:08:51 -0400938 }
939
Jamie Madille98b1b52018-03-08 09:47:23 -0500940 if (readFramebufferID != 0 && !ValidateFramebufferNotMultisampled(context, framebuffer))
Jamie Madill3c7fa222014-06-05 13:08:51 -0400941 {
Geoff Langb1196682014-07-23 13:47:29 -0400942 return false;
Jamie Madill3c7fa222014-06-05 13:08:51 -0400943 }
944
Jamie Madill0c8abca2016-07-22 20:21:26 -0400945 const FramebufferAttachment *source = framebuffer->getReadColorbuffer();
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400946
Yunchao He096a6c82018-02-27 23:48:21 +0800947 // According to ES 3.x spec, if the internalformat of the texture
948 // is RGB9_E5 and copy to such a texture, generate INVALID_OPERATION.
949 if (textureFormat.info->internalFormat == GL_RGB9_E5)
950 {
Jamie Madill610640f2018-11-21 17:28:41 -0500951 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFormat);
Yunchao He096a6c82018-02-27 23:48:21 +0800952 return false;
953 }
954
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400955 if (isSubImage)
956 {
Geoff Langca271392017-04-05 12:30:00 -0400957 if (!IsValidES3CopyTexImageCombination(*textureFormat.info, *source->getFormat().info,
Jamie Madillc29968b2016-01-20 11:17:23 -0500958 readFramebufferID))
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400959 {
Jamie Madill610640f2018-11-21 17:28:41 -0500960 context->validationError(GL_INVALID_OPERATION, kErrorInvalidCopyCombination);
Geoff Langb1196682014-07-23 13:47:29 -0400961 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400962 }
963 }
Shannon Woods4d161ba2014-03-17 18:13:30 -0400964 else
965 {
Jamie Madill0c8abca2016-07-22 20:21:26 -0400966 // Use format/type from the source FBO. (Might not be perfect for all cases?)
Geoff Langca271392017-04-05 12:30:00 -0400967 const InternalFormat &framebufferFormat = *source->getFormat().info;
968 const InternalFormat &copyFormat = GetInternalFormatInfo(internalformat, GL_UNSIGNED_BYTE);
Jamie Madill0c8abca2016-07-22 20:21:26 -0400969 if (!IsValidES3CopyTexImageCombination(copyFormat, framebufferFormat, readFramebufferID))
Shannon Woods4d161ba2014-03-17 18:13:30 -0400970 {
Jamie Madill610640f2018-11-21 17:28:41 -0500971 context->validationError(GL_INVALID_OPERATION, kErrorInvalidCopyCombination);
Geoff Langb1196682014-07-23 13:47:29 -0400972 return false;
Shannon Woods4d161ba2014-03-17 18:13:30 -0400973 }
974 }
975
Geoff Lang784a8fd2013-09-24 12:33:16 -0400976 // If width or height is zero, it is a no-op. Return false without setting an error.
977 return (width > 0 && height > 0);
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400978}
979
Jamie Madill5b772312018-03-08 20:28:32 -0500980bool ValidateES3CopyTexImage2DParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800981 TextureTarget target,
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500982 GLint level,
983 GLenum internalformat,
984 bool isSubImage,
985 GLint xoffset,
986 GLint yoffset,
987 GLint zoffset,
988 GLint x,
989 GLint y,
990 GLsizei width,
991 GLsizei height,
992 GLint border)
993{
994 if (!ValidTexture2DDestinationTarget(context, target))
995 {
Jamie Madill610640f2018-11-21 17:28:41 -0500996 context->validationError(GL_INVALID_ENUM, kErrorInvalidTextureTarget);
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500997 return false;
998 }
999
1000 return ValidateES3CopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
1001 xoffset, yoffset, zoffset, x, y, width, height,
1002 border);
1003}
1004
Jamie Madill5b772312018-03-08 20:28:32 -05001005bool ValidateES3CopyTexImage3DParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001006 TextureType target,
Ian Ewellfc7cf8e2016-01-20 15:57:46 -05001007 GLint level,
1008 GLenum internalformat,
1009 bool isSubImage,
1010 GLint xoffset,
1011 GLint yoffset,
1012 GLint zoffset,
1013 GLint x,
1014 GLint y,
1015 GLsizei width,
1016 GLsizei height,
1017 GLint border)
1018{
1019 if (!ValidTexture3DDestinationTarget(context, target))
1020 {
Jamie Madill610640f2018-11-21 17:28:41 -05001021 context->validationError(GL_INVALID_ENUM, kErrorInvalidTextureTarget);
Ian Ewellfc7cf8e2016-01-20 15:57:46 -05001022 return false;
1023 }
1024
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001025 return ValidateES3CopyTexImageParametersBase(context, NonCubeTextureTypeToTarget(target), level,
1026 internalformat, isSubImage, xoffset, yoffset,
1027 zoffset, x, y, width, height, border);
Ian Ewellfc7cf8e2016-01-20 15:57:46 -05001028}
1029
1030bool ValidateES3TexStorageParametersBase(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001031 TextureType target,
Ian Ewellfc7cf8e2016-01-20 15:57:46 -05001032 GLsizei levels,
1033 GLenum internalformat,
1034 GLsizei width,
1035 GLsizei height,
1036 GLsizei depth)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001037{
1038 if (width < 1 || height < 1 || depth < 1 || levels < 1)
1039 {
Jamie Madill610640f2018-11-21 17:28:41 -05001040 context->validationError(GL_INVALID_VALUE, kErrorTextureSizeTooSmall);
Geoff Langb1196682014-07-23 13:47:29 -04001041 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001042 }
1043
Geoff Langb92c1332015-09-04 12:54:55 -04001044 GLsizei maxDim = std::max(width, height);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001045 if (target != TextureType::_2DArray)
Geoff Langb92c1332015-09-04 12:54:55 -04001046 {
1047 maxDim = std::max(maxDim, depth);
1048 }
1049
1050 if (levels > gl::log2(maxDim) + 1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001051 {
Jamie Madill610640f2018-11-21 17:28:41 -05001052 context->validationError(GL_INVALID_OPERATION, kErrorInvalidMipLevels);
Geoff Langb1196682014-07-23 13:47:29 -04001053 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001054 }
1055
Geoff Langaae65a42014-05-26 12:43:44 -04001056 const gl::Caps &caps = context->getCaps();
1057
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001058 switch (target)
1059 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001060 case TextureType::_2D:
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001061 {
Geoff Langaae65a42014-05-26 12:43:44 -04001062 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1063 static_cast<GLuint>(height) > caps.max2DTextureSize)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001064 {
Jamie Madill610640f2018-11-21 17:28:41 -05001065 context->validationError(GL_INVALID_VALUE, kErrorResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001066 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001067 }
1068 }
1069 break;
1070
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001071 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001072 {
Jamie Madill610640f2018-11-21 17:28:41 -05001073 if (levels != 1)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001074 {
Jamie Madill610640f2018-11-21 17:28:41 -05001075 context->validationError(GL_INVALID_VALUE, kErrorInvalidMipLevels);
1076 return false;
1077 }
1078
1079 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1080 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1081 {
1082 context->validationError(GL_INVALID_VALUE, kErrorResourceMaxTextureSize);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001083 return false;
1084 }
1085 }
1086 break;
1087
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001088 case TextureType::CubeMap:
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001089 {
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001090 if (width != height)
1091 {
Jamie Madill610640f2018-11-21 17:28:41 -05001092 context->validationError(GL_INVALID_VALUE, kErrorCubemapFacesEqualDimensions);
Geoff Langb1196682014-07-23 13:47:29 -04001093 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001094 }
1095
Geoff Langaae65a42014-05-26 12:43:44 -04001096 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001097 {
Jamie Madill610640f2018-11-21 17:28:41 -05001098 context->validationError(GL_INVALID_VALUE, kErrorResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001099 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001100 }
1101 }
1102 break;
1103
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001104 case TextureType::_3D:
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001105 {
Geoff Langaae65a42014-05-26 12:43:44 -04001106 if (static_cast<GLuint>(width) > caps.max3DTextureSize ||
1107 static_cast<GLuint>(height) > caps.max3DTextureSize ||
1108 static_cast<GLuint>(depth) > caps.max3DTextureSize)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001109 {
Jamie Madill610640f2018-11-21 17:28:41 -05001110 context->validationError(GL_INVALID_VALUE, kErrorResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001111 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001112 }
1113 }
1114 break;
1115
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001116 case TextureType::_2DArray:
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001117 {
Geoff Langaae65a42014-05-26 12:43:44 -04001118 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1119 static_cast<GLuint>(height) > caps.max2DTextureSize ||
1120 static_cast<GLuint>(depth) > caps.maxArrayTextureLayers)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001121 {
Jamie Madill610640f2018-11-21 17:28:41 -05001122 context->validationError(GL_INVALID_VALUE, kErrorResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001123 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001124 }
1125 }
1126 break;
1127
He Yunchaoced53ae2016-11-29 15:00:51 +08001128 default:
1129 UNREACHABLE();
1130 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001131 }
1132
Geoff Lang691e58c2014-12-19 17:03:25 -05001133 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001134 if (!texture || texture->id() == 0)
1135 {
Jamie Madill610640f2018-11-21 17:28:41 -05001136 context->validationError(GL_INVALID_OPERATION, kErrorMissingTexture);
Geoff Langb1196682014-07-23 13:47:29 -04001137 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001138 }
1139
Geoff Lang69cce582015-09-17 13:20:36 -04001140 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001141 {
Jamie Madill610640f2018-11-21 17:28:41 -05001142 context->validationError(GL_INVALID_OPERATION, kErrorTextureIsImmutable);
Geoff Langb1196682014-07-23 13:47:29 -04001143 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001144 }
1145
Geoff Langca271392017-04-05 12:30:00 -04001146 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Langeb66a6e2016-10-31 13:06:12 -04001147 if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001148 {
Jamie Madill610640f2018-11-21 17:28:41 -05001149 context->validationError(GL_INVALID_ENUM, kErrorInvalidFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001150 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001151 }
1152
Geoff Langca271392017-04-05 12:30:00 -04001153 if (!formatInfo.sized)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001154 {
Jamie Madill610640f2018-11-21 17:28:41 -05001155 context->validationError(GL_INVALID_ENUM, kErrorInvalidFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001156 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001157 }
1158
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001159 if (formatInfo.compressed && target == TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001160 {
Jamie Madill610640f2018-11-21 17:28:41 -05001161 context->validationError(GL_INVALID_ENUM, kErrorRectangleTextureCompressed);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001162 return false;
1163 }
1164
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001165 return true;
1166}
1167
Ian Ewellfc7cf8e2016-01-20 15:57:46 -05001168bool ValidateES3TexStorage2DParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001169 TextureType target,
Ian Ewellfc7cf8e2016-01-20 15:57:46 -05001170 GLsizei levels,
1171 GLenum internalformat,
1172 GLsizei width,
1173 GLsizei height,
1174 GLsizei depth)
1175{
1176 if (!ValidTexture2DTarget(context, target))
1177 {
Jamie Madill610640f2018-11-21 17:28:41 -05001178 context->validationError(GL_INVALID_ENUM, kErrorInvalidTextureTarget);
Ian Ewellfc7cf8e2016-01-20 15:57:46 -05001179 return false;
1180 }
1181
1182 return ValidateES3TexStorageParametersBase(context, target, levels, internalformat, width,
1183 height, depth);
1184}
1185
1186bool ValidateES3TexStorage3DParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001187 TextureType target,
Ian Ewellfc7cf8e2016-01-20 15:57:46 -05001188 GLsizei levels,
1189 GLenum internalformat,
1190 GLsizei width,
1191 GLsizei height,
1192 GLsizei depth)
1193{
1194 if (!ValidTexture3DTarget(context, target))
1195 {
Jamie Madill610640f2018-11-21 17:28:41 -05001196 context->validationError(GL_INVALID_ENUM, kErrorInvalidTextureTarget);
Ian Ewellfc7cf8e2016-01-20 15:57:46 -05001197 return false;
1198 }
1199
1200 return ValidateES3TexStorageParametersBase(context, target, levels, internalformat, width,
1201 height, depth);
1202}
1203
Corentin Wallezad3ae902018-03-09 13:40:42 -05001204bool ValidateBeginQuery(gl::Context *context, QueryType target, GLuint id)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001205{
Martin Radev1be913c2016-07-11 17:59:16 +03001206 if (context->getClientMajorVersion() < 3)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001207 {
Jamie Madill610640f2018-11-21 17:28:41 -05001208 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001209 return false;
1210 }
1211
1212 return ValidateBeginQueryBase(context, target, id);
1213}
1214
Corentin Wallezad3ae902018-03-09 13:40:42 -05001215bool ValidateEndQuery(gl::Context *context, QueryType target)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001216{
Martin Radev1be913c2016-07-11 17:59:16 +03001217 if (context->getClientMajorVersion() < 3)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001218 {
Jamie Madill610640f2018-11-21 17:28:41 -05001219 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001220 return false;
1221 }
1222
1223 return ValidateEndQueryBase(context, target);
1224}
1225
Corentin Wallezad3ae902018-03-09 13:40:42 -05001226bool ValidateGetQueryiv(Context *context, QueryType target, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001227{
Martin Radev1be913c2016-07-11 17:59:16 +03001228 if (context->getClientMajorVersion() < 3)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001229 {
Jamie Madill610640f2018-11-21 17:28:41 -05001230 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001231 return false;
1232 }
1233
Geoff Lang2186c382016-10-14 10:54:54 -04001234 return ValidateGetQueryivBase(context, target, pname, nullptr);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001235}
1236
1237bool ValidateGetQueryObjectuiv(Context *context, GLuint id, GLenum pname, GLuint *params)
1238{
Martin Radev1be913c2016-07-11 17:59:16 +03001239 if (context->getClientMajorVersion() < 3)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001240 {
Jamie Madill610640f2018-11-21 17:28:41 -05001241 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001242 return false;
1243 }
1244
Geoff Lang2186c382016-10-14 10:54:54 -04001245 return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001246}
1247
He Yunchaoced53ae2016-11-29 15:00:51 +08001248bool ValidateFramebufferTextureLayer(Context *context,
1249 GLenum target,
1250 GLenum attachment,
1251 GLuint texture,
1252 GLint level,
1253 GLint layer)
Jamie Madill570f7c82014-07-03 10:38:54 -04001254{
Martin Radev1be913c2016-07-11 17:59:16 +03001255 if (context->getClientMajorVersion() < 3)
Jamie Madill570f7c82014-07-03 10:38:54 -04001256 {
Jamie Madill610640f2018-11-21 17:28:41 -05001257 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Geoff Langb1196682014-07-23 13:47:29 -04001258 return false;
Jamie Madill570f7c82014-07-03 10:38:54 -04001259 }
1260
Jamie Madill55ec3b12014-07-03 10:38:57 -04001261 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
1262 {
1263 return false;
1264 }
1265
1266 const gl::Caps &caps = context->getCaps();
1267 if (texture != 0)
1268 {
Geoff Lang23e02842017-10-17 13:24:09 -04001269 if (layer < 0)
1270 {
Jamie Madill610640f2018-11-21 17:28:41 -05001271 context->validationError(GL_INVALID_VALUE, kErrorNegativeLayer);
Geoff Lang23e02842017-10-17 13:24:09 -04001272 return false;
1273 }
1274
Jamie Madill55ec3b12014-07-03 10:38:57 -04001275 gl::Texture *tex = context->getTexture(texture);
1276 ASSERT(tex);
1277
Corentin Wallez99d492c2018-02-27 15:17:10 -05001278 switch (tex->getType())
Jamie Madill55ec3b12014-07-03 10:38:57 -04001279 {
Corentin Wallez99d492c2018-02-27 15:17:10 -05001280 case TextureType::_2DArray:
Jamie Madill55ec3b12014-07-03 10:38:57 -04001281 {
1282 if (level > gl::log2(caps.max2DTextureSize))
1283 {
Jamie Madill610640f2018-11-21 17:28:41 -05001284 context->validationError(GL_INVALID_VALUE,
1285 kErrorFramebufferTextureInvalidMipLevel);
Geoff Langb1196682014-07-23 13:47:29 -04001286 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04001287 }
1288
1289 if (static_cast<GLuint>(layer) >= caps.maxArrayTextureLayers)
1290 {
Jamie Madill610640f2018-11-21 17:28:41 -05001291 context->validationError(GL_INVALID_VALUE,
1292 kErrorFramebufferTextureInvalidLayer);
Geoff Langb1196682014-07-23 13:47:29 -04001293 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04001294 }
Jamie Madill55ec3b12014-07-03 10:38:57 -04001295 }
1296 break;
1297
Corentin Wallez99d492c2018-02-27 15:17:10 -05001298 case TextureType::_3D:
Jamie Madill55ec3b12014-07-03 10:38:57 -04001299 {
1300 if (level > gl::log2(caps.max3DTextureSize))
1301 {
Jamie Madill610640f2018-11-21 17:28:41 -05001302 context->validationError(GL_INVALID_VALUE,
1303 kErrorFramebufferTextureInvalidMipLevel);
Geoff Langb1196682014-07-23 13:47:29 -04001304 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04001305 }
1306
1307 if (static_cast<GLuint>(layer) >= caps.max3DTextureSize)
1308 {
Jamie Madill610640f2018-11-21 17:28:41 -05001309 context->validationError(GL_INVALID_VALUE,
1310 kErrorFramebufferTextureInvalidLayer);
Olli Etuahofd162102018-08-27 16:14:57 +03001311 return false;
1312 }
1313 }
1314 break;
1315
1316 case TextureType::_2DMultisampleArray:
1317 {
1318 if (level != 0)
1319 {
Jamie Madill610640f2018-11-21 17:28:41 -05001320 context->validationError(GL_INVALID_VALUE,
1321 kErrorFramebufferTextureInvalidMipLevel);
Olli Etuahofd162102018-08-27 16:14:57 +03001322 return false;
1323 }
1324
1325 if (static_cast<GLuint>(layer) >= caps.maxArrayTextureLayers)
1326 {
Jamie Madill610640f2018-11-21 17:28:41 -05001327 context->validationError(GL_INVALID_VALUE,
1328 kErrorFramebufferTextureInvalidLayer);
Geoff Langb1196682014-07-23 13:47:29 -04001329 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04001330 }
Jamie Madill55ec3b12014-07-03 10:38:57 -04001331 }
1332 break;
1333
He Yunchaoced53ae2016-11-29 15:00:51 +08001334 default:
Jamie Madill610640f2018-11-21 17:28:41 -05001335 context->validationError(GL_INVALID_OPERATION,
1336 kErrorFramebufferTextureLayerIncorrectTextureType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001337 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04001338 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001339
Corentin Wallez99d492c2018-02-27 15:17:10 -05001340 const auto &format = tex->getFormat(NonCubeTextureTypeToTarget(tex->getType()), level);
Jamie Madilla3944d42016-07-22 22:13:26 -04001341 if (format.info->compressed)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001342 {
Jamie Madill610640f2018-11-21 17:28:41 -05001343 context->validationError(GL_INVALID_OPERATION, kErrorCompressedTexturesNotAttachable);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001344 return false;
1345 }
Jamie Madill55ec3b12014-07-03 10:38:57 -04001346 }
1347
1348 return true;
Jamie Madill570f7c82014-07-03 10:38:54 -04001349}
1350
He Yunchaoced53ae2016-11-29 15:00:51 +08001351bool ValidateInvalidateFramebuffer(Context *context,
1352 GLenum target,
1353 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001354 const GLenum *attachments)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001355{
Martin Radev1be913c2016-07-11 17:59:16 +03001356 if (context->getClientMajorVersion() < 3)
Austin Kinross08332632015-05-05 13:35:47 -07001357 {
Jamie Madill610640f2018-11-21 17:28:41 -05001358 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Austin Kinross08332632015-05-05 13:35:47 -07001359 return false;
1360 }
1361
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001362 bool defaultFramebuffer = false;
1363
1364 switch (target)
1365 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001366 case GL_DRAW_FRAMEBUFFER:
1367 case GL_FRAMEBUFFER:
1368 defaultFramebuffer = context->getGLState().getDrawFramebuffer()->id() == 0;
1369 break;
1370 case GL_READ_FRAMEBUFFER:
1371 defaultFramebuffer = context->getGLState().getReadFramebuffer()->id() == 0;
1372 break;
1373 default:
Jamie Madill610640f2018-11-21 17:28:41 -05001374 context->validationError(GL_INVALID_ENUM, kErrorInvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001375 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001376 }
1377
He Yunchaoced53ae2016-11-29 15:00:51 +08001378 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1379 defaultFramebuffer);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001380}
1381
Jamie Madill3ef140a2017-08-26 23:11:21 -04001382bool ValidateInvalidateSubFramebuffer(Context *context,
1383 GLenum target,
1384 GLsizei numAttachments,
1385 const GLenum *attachments,
1386 GLint x,
1387 GLint y,
1388 GLsizei width,
1389 GLsizei height)
1390{
Yunchao He2f3a0dc2018-02-27 22:39:44 +08001391 if (width < 0 || height < 0)
1392 {
Jamie Madill610640f2018-11-21 17:28:41 -05001393 context->validationError(GL_INVALID_VALUE, kErrorNegativeSize);
Yunchao He2f3a0dc2018-02-27 22:39:44 +08001394 return false;
1395 }
1396
Jamie Madill3ef140a2017-08-26 23:11:21 -04001397 return ValidateInvalidateFramebuffer(context, target, numAttachments, attachments);
1398}
1399
Jamie Madill5b772312018-03-08 20:28:32 -05001400bool ValidateClearBuffer(Context *context)
Jamie Madill13f7d7d2014-06-20 13:21:27 -04001401{
Martin Radev1be913c2016-07-11 17:59:16 +03001402 if (context->getClientMajorVersion() < 3)
Jamie Madill13f7d7d2014-06-20 13:21:27 -04001403 {
Jamie Madill610640f2018-11-21 17:28:41 -05001404 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Geoff Langb1196682014-07-23 13:47:29 -04001405 return false;
Jamie Madill13f7d7d2014-06-20 13:21:27 -04001406 }
1407
Jamie Madill427064d2018-04-13 16:20:34 -04001408 if (!ValidateFramebufferComplete(context, context->getGLState().getDrawFramebuffer()))
Jamie Madill13f7d7d2014-06-20 13:21:27 -04001409 {
Geoff Langb1196682014-07-23 13:47:29 -04001410 return false;
Jamie Madill13f7d7d2014-06-20 13:21:27 -04001411 }
1412
1413 return true;
1414}
1415
Olli Etuaho71dfb362016-03-10 14:04:27 +02001416bool ValidateDrawRangeElements(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04001417 PrimitiveMode mode,
Olli Etuaho71dfb362016-03-10 14:04:27 +02001418 GLuint start,
1419 GLuint end,
1420 GLsizei count,
1421 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001422 const void *indices)
Olli Etuaho71dfb362016-03-10 14:04:27 +02001423{
Martin Radev1be913c2016-07-11 17:59:16 +03001424 if (context->getClientMajorVersion() < 3)
Olli Etuaho71dfb362016-03-10 14:04:27 +02001425 {
Jamie Madill610640f2018-11-21 17:28:41 -05001426 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Olli Etuaho71dfb362016-03-10 14:04:27 +02001427 return false;
1428 }
1429
1430 if (end < start)
1431 {
Jamie Madill610640f2018-11-21 17:28:41 -05001432 context->validationError(GL_INVALID_VALUE, "end < start");
Olli Etuaho71dfb362016-03-10 14:04:27 +02001433 return false;
1434 }
1435
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001436 if (!ValidateDrawElementsCommon(context, mode, count, type, indices, 0))
Olli Etuaho71dfb362016-03-10 14:04:27 +02001437 {
1438 return false;
1439 }
1440
Jamie Madill9fdaa492018-02-16 10:52:11 -05001441 // Skip range checks for no-op calls.
1442 if (count <= 0)
1443 {
1444 return true;
1445 }
1446
Jamie Madillc1fd7372018-10-26 22:48:39 -04001447 // Note that resolving the index range is a bit slow. We should probably optimize this.
1448 IndexRange indexRange;
1449 ANGLE_VALIDATION_TRY(context->getGLState().getVertexArray()->getIndexRange(
1450 context, type, count, indices, &indexRange));
Jamie Madill6f5444d2018-03-14 10:08:11 -04001451
1452 if (indexRange.end > end || indexRange.start < start)
Olli Etuaho71dfb362016-03-10 14:04:27 +02001453 {
1454 // GL spec says that behavior in this case is undefined - generating an error is fine.
Jamie Madill610640f2018-11-21 17:28:41 -05001455 context->validationError(GL_INVALID_OPERATION, "Indices are out of the start, end range.");
Olli Etuaho71dfb362016-03-10 14:04:27 +02001456 return false;
1457 }
1458 return true;
1459}
1460
He Yunchaoced53ae2016-11-29 15:00:51 +08001461bool ValidateGetUniformuiv(Context *context, GLuint program, GLint location, GLuint *params)
Jamie Madill0063c512014-08-25 15:47:53 -04001462{
Martin Radev1be913c2016-07-11 17:59:16 +03001463 if (context->getClientMajorVersion() < 3)
Jamie Madill0063c512014-08-25 15:47:53 -04001464 {
Jamie Madill610640f2018-11-21 17:28:41 -05001465 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Geoff Langb1196682014-07-23 13:47:29 -04001466 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04001467 }
1468
Jamie Madill78f41802014-08-25 15:47:55 -04001469 return ValidateGetUniformBase(context, program, location);
Jamie Madill0063c512014-08-25 15:47:53 -04001470}
1471
Jamie Madillb885e572015-02-03 16:16:04 -05001472bool ValidateReadBuffer(Context *context, GLenum src)
1473{
Martin Radev1be913c2016-07-11 17:59:16 +03001474 if (context->getClientMajorVersion() < 3)
Jamie Madillb885e572015-02-03 16:16:04 -05001475 {
Jamie Madill610640f2018-11-21 17:28:41 -05001476 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madillb885e572015-02-03 16:16:04 -05001477 return false;
1478 }
1479
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001480 const Framebuffer *readFBO = context->getGLState().getReadFramebuffer();
Jamie Madillb885e572015-02-03 16:16:04 -05001481
1482 if (readFBO == nullptr)
1483 {
Jamie Madill610640f2018-11-21 17:28:41 -05001484 context->validationError(GL_INVALID_OPERATION, "No active read framebuffer.");
Jamie Madillb885e572015-02-03 16:16:04 -05001485 return false;
1486 }
1487
1488 if (src == GL_NONE)
1489 {
1490 return true;
1491 }
1492
Olli Etuaho84c9f592016-03-09 14:37:25 +02001493 if (src != GL_BACK && (src < GL_COLOR_ATTACHMENT0 || src > GL_COLOR_ATTACHMENT31))
Jamie Madillb885e572015-02-03 16:16:04 -05001494 {
Jamie Madill610640f2018-11-21 17:28:41 -05001495 context->validationError(GL_INVALID_ENUM, "Unknown enum for 'src' in ReadBuffer");
Jamie Madillb885e572015-02-03 16:16:04 -05001496 return false;
1497 }
1498
1499 if (readFBO->id() == 0)
1500 {
1501 if (src != GL_BACK)
1502 {
Jamie Madill610640f2018-11-21 17:28:41 -05001503 context->validationError(
1504 GL_INVALID_OPERATION,
1505 "'src' must be GL_NONE or GL_BACK when reading from the default framebuffer.");
Jamie Madillb885e572015-02-03 16:16:04 -05001506 return false;
1507 }
1508 }
1509 else
1510 {
1511 GLuint drawBuffer = static_cast<GLuint>(src - GL_COLOR_ATTACHMENT0);
1512
1513 if (drawBuffer >= context->getCaps().maxDrawBuffers)
1514 {
Jamie Madill610640f2018-11-21 17:28:41 -05001515 context->validationError(GL_INVALID_OPERATION,
1516 "'src' is greater than MAX_DRAW_BUFFERS.");
Jamie Madillb885e572015-02-03 16:16:04 -05001517 return false;
1518 }
1519 }
1520
1521 return true;
1522}
1523
Jamie Madill86af3d22015-07-21 15:14:07 -04001524bool ValidateCompressedTexImage3D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001525 TextureType target,
Jamie Madill86af3d22015-07-21 15:14:07 -04001526 GLint level,
1527 GLenum internalformat,
1528 GLsizei width,
1529 GLsizei height,
1530 GLsizei depth,
1531 GLint border,
1532 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001533 const void *data)
Jamie Madill86af3d22015-07-21 15:14:07 -04001534{
Martin Radev1be913c2016-07-11 17:59:16 +03001535 if (context->getClientMajorVersion() < 3)
Jamie Madill86af3d22015-07-21 15:14:07 -04001536 {
Jamie Madill610640f2018-11-21 17:28:41 -05001537 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill86af3d22015-07-21 15:14:07 -04001538 return false;
1539 }
1540
Jamie Madill4b4cdff2016-06-06 13:53:38 -07001541 if (!ValidTextureTarget(context, target))
1542 {
Jamie Madill610640f2018-11-21 17:28:41 -05001543 context->validationError(GL_INVALID_ENUM, kErrorInvalidTextureTarget);
Jamie Madill4b4cdff2016-06-06 13:53:38 -07001544 return false;
1545 }
1546
Jamie Madille2e406c2016-06-02 13:04:10 -04001547 // Validate image size
1548 if (!ValidImageSizeParameters(context, target, level, width, height, depth, false))
1549 {
Jamie Madill610640f2018-11-21 17:28:41 -05001550 // Error already generated.
Jamie Madille2e406c2016-06-02 13:04:10 -04001551 return false;
1552 }
1553
Geoff Langca271392017-04-05 12:30:00 -04001554 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jamie Madill4b4cdff2016-06-06 13:53:38 -07001555 if (!formatInfo.compressed)
1556 {
Jamie Madill610640f2018-11-21 17:28:41 -05001557 context->validationError(GL_INVALID_ENUM, kErrorInvalidCompressedFormat);
Jamie Madill4b4cdff2016-06-06 13:53:38 -07001558 return false;
1559 }
1560
Jamie Madillca2ff382018-07-11 09:01:17 -04001561 GLuint blockSize = 0;
1562 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, depth), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04001563 {
Jamie Madill610640f2018-11-21 17:28:41 -05001564 context->validationError(GL_INVALID_VALUE, kErrorIntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04001565 return false;
1566 }
Jamie Madillca2ff382018-07-11 09:01:17 -04001567
1568 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill86af3d22015-07-21 15:14:07 -04001569 {
Jamie Madill610640f2018-11-21 17:28:41 -05001570 context->validationError(GL_INVALID_VALUE, kErrorInvalidCompressedImageSize);
Jamie Madill86af3d22015-07-21 15:14:07 -04001571 return false;
1572 }
1573
1574 // 3D texture target validation
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001575 if (target != TextureType::_3D && target != TextureType::_2DArray)
Jamie Madill86af3d22015-07-21 15:14:07 -04001576 {
Jamie Madill610640f2018-11-21 17:28:41 -05001577 context->validationError(GL_INVALID_ENUM,
1578 "Must specify a valid 3D texture destination target");
Jamie Madill86af3d22015-07-21 15:14:07 -04001579 return false;
1580 }
1581
1582 // validateES3TexImageFormat sets the error code if there is an error
Ian Ewellfc7cf8e2016-01-20 15:57:46 -05001583 if (!ValidateES3TexImage3DParameters(context, target, level, internalformat, true, false, 0, 0,
Geoff Langc52f6f12016-10-14 10:18:00 -04001584 0, width, height, depth, border, GL_NONE, GL_NONE, -1,
1585 data))
Jamie Madill86af3d22015-07-21 15:14:07 -04001586 {
1587 return false;
1588 }
1589
1590 return true;
1591}
Austin Kinrossbc781f32015-10-26 09:27:38 -07001592
Corentin Wallezb2931602017-04-11 15:58:57 -04001593bool ValidateCompressedTexImage3DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001594 TextureType target,
Corentin Wallezb2931602017-04-11 15:58:57 -04001595 GLint level,
1596 GLenum internalformat,
1597 GLsizei width,
1598 GLsizei height,
1599 GLsizei depth,
1600 GLint border,
1601 GLsizei imageSize,
1602 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001603 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04001604{
1605 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
1606 {
1607 return false;
1608 }
1609
1610 return ValidateCompressedTexImage3D(context, target, level, internalformat, width, height,
1611 depth, border, imageSize, data);
1612}
1613
Austin Kinrossbc781f32015-10-26 09:27:38 -07001614bool ValidateBindVertexArray(Context *context, GLuint array)
1615{
Martin Radev1be913c2016-07-11 17:59:16 +03001616 if (context->getClientMajorVersion() < 3)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001617 {
Jamie Madill610640f2018-11-21 17:28:41 -05001618 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001619 return false;
1620 }
1621
1622 return ValidateBindVertexArrayBase(context, array);
1623}
1624
Jamie Madilld7576732017-08-26 18:49:50 -04001625bool ValidateIsVertexArray(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001626{
Martin Radev1be913c2016-07-11 17:59:16 +03001627 if (context->getClientMajorVersion() < 3)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001628 {
Jamie Madill610640f2018-11-21 17:28:41 -05001629 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001630 return false;
1631 }
1632
1633 return true;
1634}
Geoff Langc5629752015-12-07 16:29:04 -05001635
Jiajia Qin6eafb042016-12-27 17:04:07 +08001636static bool ValidateBindBufferCommon(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04001637 BufferBinding target,
Jiajia Qin6eafb042016-12-27 17:04:07 +08001638 GLuint index,
1639 GLuint buffer,
1640 GLintptr offset,
1641 GLsizeiptr size)
1642{
1643 if (context->getClientMajorVersion() < 3)
1644 {
Jamie Madill610640f2018-11-21 17:28:41 -05001645 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001646 return false;
1647 }
1648
1649 if (buffer != 0 && offset < 0)
1650 {
Jamie Madill610640f2018-11-21 17:28:41 -05001651 context->validationError(GL_INVALID_VALUE, "buffer is non-zero and offset is negative.");
Jiajia Qin6eafb042016-12-27 17:04:07 +08001652 return false;
1653 }
1654
1655 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
1656 !context->isBufferGenerated(buffer))
1657 {
Jamie Madill610640f2018-11-21 17:28:41 -05001658 context->validationError(GL_INVALID_OPERATION, "Buffer was not generated.");
Jiajia Qin6eafb042016-12-27 17:04:07 +08001659 return false;
1660 }
1661
1662 const Caps &caps = context->getCaps();
1663 switch (target)
1664 {
Corentin Wallez336129f2017-10-17 15:55:40 -04001665 case BufferBinding::TransformFeedback:
Jiajia Qin6eafb042016-12-27 17:04:07 +08001666 {
1667 if (index >= caps.maxTransformFeedbackSeparateAttributes)
1668 {
Jamie Madill610640f2018-11-21 17:28:41 -05001669 context->validationError(GL_INVALID_VALUE,
1670 "index is greater than or equal to the "
1671 "number of TRANSFORM_FEEDBACK_BUFFER "
1672 "indexed binding points.");
Jiajia Qin6eafb042016-12-27 17:04:07 +08001673 return false;
1674 }
1675 if (buffer != 0 && ((offset % 4) != 0 || (size % 4) != 0))
1676 {
Jamie Madill610640f2018-11-21 17:28:41 -05001677 context->validationError(GL_INVALID_VALUE,
1678 "offset and size must be multiple of 4.");
Jiajia Qin6eafb042016-12-27 17:04:07 +08001679 return false;
1680 }
1681
1682 TransformFeedback *curTransformFeedback =
1683 context->getGLState().getCurrentTransformFeedback();
1684 if (curTransformFeedback && curTransformFeedback->isActive())
1685 {
Jamie Madill610640f2018-11-21 17:28:41 -05001686 context->validationError(GL_INVALID_OPERATION,
1687 "target is TRANSFORM_FEEDBACK_BUFFER and transform "
1688 "feedback is currently active.");
Jiajia Qin6eafb042016-12-27 17:04:07 +08001689 return false;
1690 }
1691 break;
1692 }
Corentin Wallez336129f2017-10-17 15:55:40 -04001693 case BufferBinding::Uniform:
Jiajia Qin6eafb042016-12-27 17:04:07 +08001694 {
1695 if (index >= caps.maxUniformBufferBindings)
1696 {
Jamie Madill610640f2018-11-21 17:28:41 -05001697 context->validationError(GL_INVALID_VALUE,
1698 "index is greater than or equal to the "
1699 "number of UNIFORM_BUFFER indexed "
1700 "binding points.");
Jiajia Qin6eafb042016-12-27 17:04:07 +08001701 return false;
1702 }
1703
Qin Jiajiaf7af13c2018-06-06 14:14:54 +08001704 ASSERT(caps.uniformBufferOffsetAlignment);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001705 if (buffer != 0 && (offset % caps.uniformBufferOffsetAlignment) != 0)
1706 {
Jamie Madill610640f2018-11-21 17:28:41 -05001707 context->validationError(
1708 GL_INVALID_VALUE,
1709 "offset must be multiple of value of UNIFORM_BUFFER_OFFSET_ALIGNMENT.");
Jiajia Qin6eafb042016-12-27 17:04:07 +08001710 return false;
1711 }
1712 break;
1713 }
Corentin Wallez336129f2017-10-17 15:55:40 -04001714 case BufferBinding::AtomicCounter:
Jiajia Qin6eafb042016-12-27 17:04:07 +08001715 {
1716 if (context->getClientVersion() < ES_3_1)
1717 {
Jamie Madill610640f2018-11-21 17:28:41 -05001718 context->validationError(GL_INVALID_ENUM,
1719 "ATOMIC_COUNTER_BUFFER is not supported before GLES 3.1");
Jiajia Qin6eafb042016-12-27 17:04:07 +08001720 return false;
1721 }
1722 if (index >= caps.maxAtomicCounterBufferBindings)
1723 {
Jamie Madill610640f2018-11-21 17:28:41 -05001724 context->validationError(GL_INVALID_VALUE,
1725 "index is greater than or equal to the "
1726 "number of ATOMIC_COUNTER_BUFFER "
1727 "indexed binding points.");
Jiajia Qin6eafb042016-12-27 17:04:07 +08001728 return false;
1729 }
1730 if (buffer != 0 && (offset % 4) != 0)
1731 {
Jamie Madill610640f2018-11-21 17:28:41 -05001732 context->validationError(GL_INVALID_VALUE, "offset must be a multiple of 4.");
Jiajia Qin6eafb042016-12-27 17:04:07 +08001733 return false;
1734 }
1735 break;
1736 }
Corentin Wallez336129f2017-10-17 15:55:40 -04001737 case BufferBinding::ShaderStorage:
Jiajia Qin6eafb042016-12-27 17:04:07 +08001738 {
1739 if (context->getClientVersion() < ES_3_1)
1740 {
Jamie Madill610640f2018-11-21 17:28:41 -05001741 context->validationError(GL_INVALID_ENUM,
1742 "SHADER_STORAGE_BUFFER is not supported in GLES3.");
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001743 return false;
1744 }
1745 if (index >= caps.maxShaderStorageBufferBindings)
1746 {
Jamie Madill610640f2018-11-21 17:28:41 -05001747 context->validationError(GL_INVALID_VALUE,
1748 "index is greater than or equal to the "
1749 "number of SHADER_STORAGE_BUFFER "
1750 "indexed binding points.");
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001751 return false;
1752 }
Qin Jiajiaf7af13c2018-06-06 14:14:54 +08001753 ASSERT(caps.shaderStorageBufferOffsetAlignment);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001754 if (buffer != 0 && (offset % caps.shaderStorageBufferOffsetAlignment) != 0)
1755 {
Jamie Madill610640f2018-11-21 17:28:41 -05001756 context->validationError(GL_INVALID_VALUE,
1757 "offset must be multiple of value of "
1758 "SHADER_STORAGE_BUFFER_OFFSET_"
1759 "ALIGNMENT.");
Jiajia Qin6eafb042016-12-27 17:04:07 +08001760 return false;
1761 }
1762 break;
1763 }
1764 default:
Jamie Madill610640f2018-11-21 17:28:41 -05001765 context->validationError(GL_INVALID_ENUM, "the target is not supported.");
Jiajia Qin6eafb042016-12-27 17:04:07 +08001766 return false;
1767 }
1768
1769 return true;
1770}
1771
Corentin Wallez336129f2017-10-17 15:55:40 -04001772bool ValidateBindBufferBase(Context *context, BufferBinding target, GLuint index, GLuint buffer)
Jiajia Qin6eafb042016-12-27 17:04:07 +08001773{
1774 return ValidateBindBufferCommon(context, target, index, buffer, 0, 0);
1775}
1776
1777bool ValidateBindBufferRange(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04001778 BufferBinding target,
Jiajia Qin6eafb042016-12-27 17:04:07 +08001779 GLuint index,
1780 GLuint buffer,
1781 GLintptr offset,
1782 GLsizeiptr size)
1783{
1784 if (buffer != 0 && size <= 0)
1785 {
Jamie Madill610640f2018-11-21 17:28:41 -05001786 context->validationError(GL_INVALID_VALUE,
1787 "buffer is non-zero and size is less than or equal to zero.");
Jiajia Qin6eafb042016-12-27 17:04:07 +08001788 return false;
1789 }
1790 return ValidateBindBufferCommon(context, target, index, buffer, offset, size);
1791}
1792
Geoff Langc5629752015-12-07 16:29:04 -05001793bool ValidateProgramBinary(Context *context,
1794 GLuint program,
1795 GLenum binaryFormat,
1796 const void *binary,
1797 GLint length)
1798{
Martin Radev1be913c2016-07-11 17:59:16 +03001799 if (context->getClientMajorVersion() < 3)
Geoff Langc5629752015-12-07 16:29:04 -05001800 {
Jamie Madill610640f2018-11-21 17:28:41 -05001801 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Geoff Langc5629752015-12-07 16:29:04 -05001802 return false;
1803 }
1804
1805 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
1806}
1807
1808bool ValidateGetProgramBinary(Context *context,
1809 GLuint program,
1810 GLsizei bufSize,
1811 GLsizei *length,
1812 GLenum *binaryFormat,
1813 void *binary)
1814{
Martin Radev1be913c2016-07-11 17:59:16 +03001815 if (context->getClientMajorVersion() < 3)
Geoff Langc5629752015-12-07 16:29:04 -05001816 {
Jamie Madill610640f2018-11-21 17:28:41 -05001817 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Geoff Langc5629752015-12-07 16:29:04 -05001818 return false;
1819 }
1820
1821 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
1822}
1823
Olli Etuahof0fee072016-03-30 15:11:58 +03001824bool ValidateProgramParameteri(Context *context, GLuint program, GLenum pname, GLint value)
Geoff Langc5629752015-12-07 16:29:04 -05001825{
Martin Radev1be913c2016-07-11 17:59:16 +03001826 if (context->getClientMajorVersion() < 3)
Geoff Langc5629752015-12-07 16:29:04 -05001827 {
Jamie Madill610640f2018-11-21 17:28:41 -05001828 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Geoff Langc5629752015-12-07 16:29:04 -05001829 return false;
1830 }
1831
1832 if (GetValidProgram(context, program) == nullptr)
1833 {
1834 return false;
1835 }
1836
1837 switch (pname)
1838 {
1839 case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
Olli Etuahof0fee072016-03-30 15:11:58 +03001840 if (value != GL_FALSE && value != GL_TRUE)
1841 {
Jamie Madill610640f2018-11-21 17:28:41 -05001842 context->validationError(GL_INVALID_VALUE, kErrorInvalidBooleanValue);
Olli Etuahof0fee072016-03-30 15:11:58 +03001843 return false;
1844 }
Geoff Langc5629752015-12-07 16:29:04 -05001845 break;
1846
Yunchao He61afff12017-03-14 15:34:03 +08001847 case GL_PROGRAM_SEPARABLE:
1848 if (context->getClientVersion() < ES_3_1)
1849 {
Jamie Madill610640f2018-11-21 17:28:41 -05001850 context->validationError(GL_INVALID_ENUM, kErrorES31Required);
Yunchao He61afff12017-03-14 15:34:03 +08001851 return false;
1852 }
1853
1854 if (value != GL_FALSE && value != GL_TRUE)
1855 {
Jamie Madill610640f2018-11-21 17:28:41 -05001856 context->validationError(GL_INVALID_VALUE, kErrorInvalidBooleanValue);
Yunchao He61afff12017-03-14 15:34:03 +08001857 return false;
1858 }
1859 break;
1860
Geoff Langc5629752015-12-07 16:29:04 -05001861 default:
Jamie Madill610640f2018-11-21 17:28:41 -05001862 context->validationError(GL_INVALID_ENUM, kErrorInvalidPname);
Geoff Langc5629752015-12-07 16:29:04 -05001863 return false;
1864 }
1865
1866 return true;
1867}
Jamie Madillc29968b2016-01-20 11:17:23 -05001868
1869bool ValidateBlitFramebuffer(Context *context,
1870 GLint srcX0,
1871 GLint srcY0,
1872 GLint srcX1,
1873 GLint srcY1,
1874 GLint dstX0,
1875 GLint dstY0,
1876 GLint dstX1,
1877 GLint dstY1,
1878 GLbitfield mask,
1879 GLenum filter)
1880{
Martin Radev1be913c2016-07-11 17:59:16 +03001881 if (context->getClientMajorVersion() < 3)
Jamie Madillc29968b2016-01-20 11:17:23 -05001882 {
Jamie Madill610640f2018-11-21 17:28:41 -05001883 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madillc29968b2016-01-20 11:17:23 -05001884 return false;
1885 }
1886
1887 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
1888 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001889}
Jamie Madillc29968b2016-01-20 11:17:23 -05001890
Jamie Madill5b772312018-03-08 20:28:32 -05001891bool ValidateClearBufferiv(Context *context, GLenum buffer, GLint drawbuffer, const GLint *value)
Jamie Madillc29968b2016-01-20 11:17:23 -05001892{
1893 switch (buffer)
1894 {
1895 case GL_COLOR:
1896 if (drawbuffer < 0 ||
1897 static_cast<GLuint>(drawbuffer) >= context->getCaps().maxDrawBuffers)
1898 {
Jamie Madill610640f2018-11-21 17:28:41 -05001899 context->validationError(GL_INVALID_VALUE, kErrorIndexExceedsMaxDrawBuffer);
Jamie Madillc29968b2016-01-20 11:17:23 -05001900 return false;
1901 }
Geoff Lang76e65652017-03-27 14:58:02 -04001902 if (context->getExtensions().webglCompatibility)
1903 {
1904 constexpr GLenum validComponentTypes[] = {GL_INT};
Geoff Lang0fb08642017-07-04 15:07:23 -04001905 if (!ValidateWebGLFramebufferAttachmentClearType(
Geoff Lang76e65652017-03-27 14:58:02 -04001906 context, drawbuffer, validComponentTypes, ArraySize(validComponentTypes)))
1907 {
1908 return false;
1909 }
1910 }
Jamie Madillc29968b2016-01-20 11:17:23 -05001911 break;
1912
1913 case GL_STENCIL:
1914 if (drawbuffer != 0)
1915 {
Jamie Madill610640f2018-11-21 17:28:41 -05001916 context->validationError(GL_INVALID_VALUE, kErrorInvalidDepthStencilDrawBuffer);
Jamie Madillc29968b2016-01-20 11:17:23 -05001917 return false;
1918 }
1919 break;
1920
1921 default:
Jamie Madill610640f2018-11-21 17:28:41 -05001922 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madillc29968b2016-01-20 11:17:23 -05001923 return false;
1924 }
1925
1926 return ValidateClearBuffer(context);
1927}
1928
Jamie Madill5b772312018-03-08 20:28:32 -05001929bool ValidateClearBufferuiv(Context *context, GLenum buffer, GLint drawbuffer, const GLuint *value)
Jamie Madillc29968b2016-01-20 11:17:23 -05001930{
1931 switch (buffer)
1932 {
1933 case GL_COLOR:
1934 if (drawbuffer < 0 ||
1935 static_cast<GLuint>(drawbuffer) >= context->getCaps().maxDrawBuffers)
1936 {
Jamie Madill610640f2018-11-21 17:28:41 -05001937 context->validationError(GL_INVALID_VALUE, kErrorIndexExceedsMaxDrawBuffer);
Jamie Madillc29968b2016-01-20 11:17:23 -05001938 return false;
1939 }
Geoff Lang76e65652017-03-27 14:58:02 -04001940 if (context->getExtensions().webglCompatibility)
1941 {
1942 constexpr GLenum validComponentTypes[] = {GL_UNSIGNED_INT};
Geoff Lang0fb08642017-07-04 15:07:23 -04001943 if (!ValidateWebGLFramebufferAttachmentClearType(
Geoff Lang76e65652017-03-27 14:58:02 -04001944 context, drawbuffer, validComponentTypes, ArraySize(validComponentTypes)))
1945 {
1946 return false;
1947 }
1948 }
Jamie Madillc29968b2016-01-20 11:17:23 -05001949 break;
1950
1951 default:
Jamie Madill610640f2018-11-21 17:28:41 -05001952 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madillc29968b2016-01-20 11:17:23 -05001953 return false;
1954 }
1955
1956 return ValidateClearBuffer(context);
1957}
1958
Jamie Madill5b772312018-03-08 20:28:32 -05001959bool ValidateClearBufferfv(Context *context, GLenum buffer, GLint drawbuffer, const GLfloat *value)
Jamie Madillc29968b2016-01-20 11:17:23 -05001960{
1961 switch (buffer)
1962 {
1963 case GL_COLOR:
1964 if (drawbuffer < 0 ||
1965 static_cast<GLuint>(drawbuffer) >= context->getCaps().maxDrawBuffers)
1966 {
Jamie Madill610640f2018-11-21 17:28:41 -05001967 context->validationError(GL_INVALID_VALUE, kErrorIndexExceedsMaxDrawBuffer);
Jamie Madillc29968b2016-01-20 11:17:23 -05001968 return false;
1969 }
Geoff Lang76e65652017-03-27 14:58:02 -04001970 if (context->getExtensions().webglCompatibility)
1971 {
1972 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
1973 GL_SIGNED_NORMALIZED};
Geoff Lang0fb08642017-07-04 15:07:23 -04001974 if (!ValidateWebGLFramebufferAttachmentClearType(
Geoff Lang76e65652017-03-27 14:58:02 -04001975 context, drawbuffer, validComponentTypes, ArraySize(validComponentTypes)))
1976 {
1977 return false;
1978 }
1979 }
Jamie Madillc29968b2016-01-20 11:17:23 -05001980 break;
1981
1982 case GL_DEPTH:
1983 if (drawbuffer != 0)
1984 {
Jamie Madill610640f2018-11-21 17:28:41 -05001985 context->validationError(GL_INVALID_VALUE, kErrorInvalidDepthStencilDrawBuffer);
Jamie Madillc29968b2016-01-20 11:17:23 -05001986 return false;
1987 }
1988 break;
1989
1990 default:
Jamie Madill610640f2018-11-21 17:28:41 -05001991 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madillc29968b2016-01-20 11:17:23 -05001992 return false;
1993 }
1994
1995 return ValidateClearBuffer(context);
1996}
1997
Jamie Madill5b772312018-03-08 20:28:32 -05001998bool ValidateClearBufferfi(Context *context,
Jamie Madillc29968b2016-01-20 11:17:23 -05001999 GLenum buffer,
2000 GLint drawbuffer,
2001 GLfloat depth,
2002 GLint stencil)
2003{
2004 switch (buffer)
2005 {
2006 case GL_DEPTH_STENCIL:
2007 if (drawbuffer != 0)
2008 {
Jamie Madill610640f2018-11-21 17:28:41 -05002009 context->validationError(GL_INVALID_VALUE, kErrorInvalidDepthStencilDrawBuffer);
Jamie Madillc29968b2016-01-20 11:17:23 -05002010 return false;
2011 }
2012 break;
2013
2014 default:
Jamie Madill610640f2018-11-21 17:28:41 -05002015 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madillc29968b2016-01-20 11:17:23 -05002016 return false;
2017 }
2018
2019 return ValidateClearBuffer(context);
2020}
2021
Jamie Madill5b772312018-03-08 20:28:32 -05002022bool ValidateDrawBuffers(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002023{
Martin Radev1be913c2016-07-11 17:59:16 +03002024 if (context->getClientMajorVersion() < 3)
Jamie Madillc29968b2016-01-20 11:17:23 -05002025 {
Jamie Madill610640f2018-11-21 17:28:41 -05002026 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madillc29968b2016-01-20 11:17:23 -05002027 return false;
2028 }
2029
2030 return ValidateDrawBuffersBase(context, n, bufs);
2031}
2032
2033bool ValidateCopyTexSubImage3D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002034 TextureType target,
Jamie Madillc29968b2016-01-20 11:17:23 -05002035 GLint level,
2036 GLint xoffset,
2037 GLint yoffset,
2038 GLint zoffset,
2039 GLint x,
2040 GLint y,
2041 GLsizei width,
2042 GLsizei height)
2043{
Martin Radev1be913c2016-07-11 17:59:16 +03002044 if (context->getClientMajorVersion() < 3)
Jamie Madillc29968b2016-01-20 11:17:23 -05002045 {
Jamie Madill610640f2018-11-21 17:28:41 -05002046 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madillc29968b2016-01-20 11:17:23 -05002047 return false;
2048 }
2049
Ian Ewellfc7cf8e2016-01-20 15:57:46 -05002050 return ValidateES3CopyTexImage3DParameters(context, target, level, GL_NONE, true, xoffset,
2051 yoffset, zoffset, x, y, width, height, 0);
Jamie Madillc29968b2016-01-20 11:17:23 -05002052}
2053
Brandon Jones4e6f2ae2018-09-19 11:09:51 -07002054bool ValidateCopyTexture3DANGLE(Context *context,
2055 GLuint sourceId,
2056 GLint sourceLevel,
2057 TextureTarget destTarget,
2058 GLuint destId,
2059 GLint destLevel,
2060 GLint internalFormat,
2061 GLenum destType,
2062 GLboolean unpackFlipY,
2063 GLboolean unpackPremultiplyAlpha,
2064 GLboolean unpackUnmultiplyAlpha)
2065{
2066 const Texture *source = context->getTexture(sourceId);
2067 if (source == nullptr)
2068 {
Jamie Madill610640f2018-11-21 17:28:41 -05002069 context->validationError(GL_INVALID_VALUE, kErrorInvalidSourceTexture);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -07002070 return false;
2071 }
2072
2073 TextureType sourceType = source->getType();
2074 ASSERT(sourceType != TextureType::CubeMap);
2075 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
2076 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
2077
2078 const Texture *dest = context->getTexture(destId);
2079 if (dest == nullptr)
2080 {
Jamie Madill610640f2018-11-21 17:28:41 -05002081 context->validationError(GL_INVALID_VALUE, kErrorInvalidDestinationTexture);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -07002082 return false;
2083 }
2084
2085 if (!ValidateCopyTexture3DCommon(context, source, sourceLevel,
2086 sourceFormat.info->internalFormat, dest, destLevel,
2087 internalFormat, destTarget))
2088 {
2089 return false;
2090 }
2091
2092 if (!ValidMipLevel(context, source->getType(), sourceLevel))
2093 {
Jamie Madill610640f2018-11-21 17:28:41 -05002094 context->validationError(GL_INVALID_VALUE, kErrorInvalidSourceTextureLevel);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -07002095 return false;
2096 }
2097
2098 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
2099 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
2100 if (sourceWidth == 0 || sourceHeight == 0)
2101 {
Jamie Madill610640f2018-11-21 17:28:41 -05002102 context->validationError(GL_INVALID_OPERATION, kErrorInvalidSourceTextureSize);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -07002103 return false;
2104 }
2105
2106 if (dest->getImmutableFormat())
2107 {
Jamie Madill610640f2018-11-21 17:28:41 -05002108 context->validationError(GL_INVALID_OPERATION, kErrorDestinationImmutable);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -07002109 return false;
2110 }
2111
2112 return true;
2113}
2114
2115bool ValidateCopySubTexture3DANGLE(Context *context,
2116 GLuint sourceId,
2117 GLint sourceLevel,
2118 TextureTarget destTarget,
2119 GLuint destId,
2120 GLint destLevel,
2121 GLint xoffset,
2122 GLint yoffset,
2123 GLint zoffset,
2124 GLint x,
2125 GLint y,
2126 GLint z,
2127 GLsizei width,
2128 GLsizei height,
2129 GLsizei depth,
2130 GLboolean unpackFlipY,
2131 GLboolean unpackPremultiplyAlpha,
2132 GLboolean unpackUnmultiplyAlpha)
2133{
2134 const Texture *source = context->getTexture(sourceId);
2135 if (source == nullptr)
2136 {
Jamie Madill610640f2018-11-21 17:28:41 -05002137 context->validationError(GL_INVALID_VALUE, kErrorInvalidSourceTexture);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -07002138 return false;
2139 }
2140
2141 TextureType sourceType = source->getType();
2142 ASSERT(sourceType != TextureType::CubeMap);
2143 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
2144 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
2145
2146 const Texture *dest = context->getTexture(destId);
2147 if (dest == nullptr)
2148 {
Jamie Madill610640f2018-11-21 17:28:41 -05002149 context->validationError(GL_INVALID_VALUE, kErrorInvalidDestinationTexture);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -07002150 return false;
2151 }
2152
2153 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
2154
2155 if (!ValidateCopyTexture3DCommon(context, source, sourceLevel,
2156 sourceFormat.info->internalFormat, dest, destLevel,
2157 destFormat.internalFormat, destTarget))
2158 {
2159 return false;
2160 }
2161
2162 if (x < 0 || y < 0 || z < 0)
2163 {
Jamie Madill610640f2018-11-21 17:28:41 -05002164 context->validationError(GL_INVALID_VALUE, kErrorNegativeXYZ);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -07002165 return false;
2166 }
2167
2168 if (width < 0 || height < 0 || depth < 0)
2169 {
Jamie Madill610640f2018-11-21 17:28:41 -05002170 context->validationError(GL_INVALID_VALUE, kErrorNegativeHeightWidthDepth);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -07002171 return false;
2172 }
2173
2174 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
2175 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel) ||
2176 static_cast<size_t>(z + depth) > source->getDepth(sourceTarget, sourceLevel))
2177 {
Jamie Madill610640f2018-11-21 17:28:41 -05002178 context->validationError(GL_INVALID_VALUE, kErrorSourceTextureTooSmall);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -07002179 return false;
2180 }
2181
2182 if (TextureTargetToType(destTarget) != dest->getType())
2183 {
Jamie Madill610640f2018-11-21 17:28:41 -05002184 context->validationError(GL_INVALID_VALUE, kErrorInvalidDestinationTextureType);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -07002185 return false;
2186 }
2187
2188 if (xoffset < 0 || yoffset < 0 || zoffset < 0)
2189 {
Jamie Madill610640f2018-11-21 17:28:41 -05002190 context->validationError(GL_INVALID_VALUE, kErrorNegativeOffset);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -07002191 return false;
2192 }
2193
2194 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
2195 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel) ||
2196 static_cast<size_t>(zoffset + depth) > dest->getDepth(destTarget, destLevel))
2197 {
Jamie Madill610640f2018-11-21 17:28:41 -05002198 context->validationError(GL_INVALID_VALUE, kErrorDestinationTextureTooSmall);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -07002199 return false;
2200 }
2201
2202 return true;
2203}
2204
Jamie Madill73a84962016-02-12 09:27:23 -05002205bool ValidateTexImage3D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002206 TextureType target,
Jamie Madill73a84962016-02-12 09:27:23 -05002207 GLint level,
2208 GLint internalformat,
2209 GLsizei width,
2210 GLsizei height,
2211 GLsizei depth,
2212 GLint border,
2213 GLenum format,
2214 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002215 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002216{
Martin Radev1be913c2016-07-11 17:59:16 +03002217 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002218 {
Jamie Madill610640f2018-11-21 17:28:41 -05002219 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill73a84962016-02-12 09:27:23 -05002220 return false;
2221 }
2222
2223 return ValidateES3TexImage3DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langc52f6f12016-10-14 10:18:00 -04002224 0, 0, width, height, depth, border, format, type, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002225 pixels);
2226}
2227
Geoff Langc52f6f12016-10-14 10:18:00 -04002228bool ValidateTexImage3DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002229 TextureType target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002230 GLint level,
2231 GLint internalformat,
2232 GLsizei width,
2233 GLsizei height,
2234 GLsizei depth,
2235 GLint border,
2236 GLenum format,
2237 GLenum type,
2238 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002239 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002240{
2241 if (context->getClientMajorVersion() < 3)
2242 {
Jamie Madill610640f2018-11-21 17:28:41 -05002243 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Geoff Langc52f6f12016-10-14 10:18:00 -04002244 return false;
2245 }
2246
2247 if (!ValidateRobustEntryPoint(context, bufSize))
2248 {
2249 return false;
2250 }
2251
2252 return ValidateES3TexImage3DParameters(context, target, level, internalformat, false, false, 0,
2253 0, 0, width, height, depth, border, format, type,
2254 bufSize, pixels);
2255}
2256
Jamie Madill73a84962016-02-12 09:27:23 -05002257bool ValidateTexSubImage3D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002258 TextureType target,
Jamie Madill73a84962016-02-12 09:27:23 -05002259 GLint level,
2260 GLint xoffset,
2261 GLint yoffset,
2262 GLint zoffset,
2263 GLsizei width,
2264 GLsizei height,
2265 GLsizei depth,
2266 GLenum format,
2267 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002268 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002269{
Martin Radev1be913c2016-07-11 17:59:16 +03002270 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002271 {
Jamie Madill610640f2018-11-21 17:28:41 -05002272 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill73a84962016-02-12 09:27:23 -05002273 return false;
2274 }
2275
2276 return ValidateES3TexImage3DParameters(context, target, level, GL_NONE, false, true, xoffset,
2277 yoffset, zoffset, width, height, depth, 0, format, type,
Geoff Langc52f6f12016-10-14 10:18:00 -04002278 -1, pixels);
2279}
2280
2281bool ValidateTexSubImage3DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002282 TextureType target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002283 GLint level,
2284 GLint xoffset,
2285 GLint yoffset,
2286 GLint zoffset,
2287 GLsizei width,
2288 GLsizei height,
2289 GLsizei depth,
2290 GLenum format,
2291 GLenum type,
2292 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002293 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002294{
2295 if (context->getClientMajorVersion() < 3)
2296 {
Jamie Madill610640f2018-11-21 17:28:41 -05002297 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Geoff Langc52f6f12016-10-14 10:18:00 -04002298 return false;
2299 }
2300
2301 if (!ValidateRobustEntryPoint(context, bufSize))
2302 {
2303 return false;
2304 }
2305
2306 return ValidateES3TexImage3DParameters(context, target, level, GL_NONE, false, true, xoffset,
2307 yoffset, zoffset, width, height, depth, 0, format, type,
2308 bufSize, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002309}
2310
2311bool ValidateCompressedTexSubImage3D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002312 TextureType target,
Jamie Madill73a84962016-02-12 09:27:23 -05002313 GLint level,
2314 GLint xoffset,
2315 GLint yoffset,
2316 GLint zoffset,
2317 GLsizei width,
2318 GLsizei height,
2319 GLsizei depth,
2320 GLenum format,
2321 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002322 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002323{
Martin Radev1be913c2016-07-11 17:59:16 +03002324 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002325 {
Jamie Madill610640f2018-11-21 17:28:41 -05002326 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill73a84962016-02-12 09:27:23 -05002327 return false;
2328 }
2329
Geoff Langca271392017-04-05 12:30:00 -04002330 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Geoff Langc5508d62017-02-10 14:58:38 -05002331 if (!formatInfo.compressed)
2332 {
Jamie Madill610640f2018-11-21 17:28:41 -05002333 context->validationError(GL_INVALID_ENUM, kErrorInvalidCompressedFormat);
Geoff Langc5508d62017-02-10 14:58:38 -05002334 return false;
2335 }
2336
Jamie Madillca2ff382018-07-11 09:01:17 -04002337 GLuint blockSize = 0;
2338 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, depth), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002339 {
Jamie Madill610640f2018-11-21 17:28:41 -05002340 context->validationError(GL_INVALID_OPERATION, kErrorIntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002341 return false;
2342 }
Jamie Madillca2ff382018-07-11 09:01:17 -04002343
2344 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002345 {
Jamie Madill610640f2018-11-21 17:28:41 -05002346 context->validationError(GL_INVALID_VALUE, kErrorInvalidCompressedImageSize);
Jamie Madill73a84962016-02-12 09:27:23 -05002347 return false;
2348 }
2349
Luc Ferron9dbaeba2018-02-01 07:26:59 -05002350 if (!ValidateES3TexImage3DParameters(context, target, level, GL_NONE, true, true, xoffset,
2351 yoffset, zoffset, width, height, depth, 0, format, GL_NONE,
2352 -1, data))
2353 {
2354 return false;
2355 }
2356
Jamie Madill73a84962016-02-12 09:27:23 -05002357 if (!data)
2358 {
Jamie Madill610640f2018-11-21 17:28:41 -05002359 context->validationError(GL_INVALID_VALUE, kErrorPixelDataNull);
Jamie Madill73a84962016-02-12 09:27:23 -05002360 return false;
2361 }
2362
Luc Ferron9dbaeba2018-02-01 07:26:59 -05002363 return true;
Jamie Madill73a84962016-02-12 09:27:23 -05002364}
Luc Ferron9dbaeba2018-02-01 07:26:59 -05002365
Corentin Wallezb2931602017-04-11 15:58:57 -04002366bool ValidateCompressedTexSubImage3DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002367 TextureType target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002368 GLint level,
2369 GLint xoffset,
2370 GLint yoffset,
2371 GLint zoffset,
2372 GLsizei width,
2373 GLsizei height,
2374 GLsizei depth,
2375 GLenum format,
2376 GLsizei imageSize,
2377 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002378 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002379{
2380 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2381 {
2382 return false;
2383 }
2384
2385 return ValidateCompressedTexSubImage3D(context, target, level, xoffset, yoffset, zoffset, width,
2386 height, depth, format, imageSize, data);
2387}
Jamie Madill73a84962016-02-12 09:27:23 -05002388
Olli Etuaho41997e72016-03-10 13:38:39 +02002389bool ValidateGenQueries(Context *context, GLint n, GLuint *)
2390{
2391 return ValidateGenOrDeleteES3(context, n);
2392}
2393
2394bool ValidateDeleteQueries(Context *context, GLint n, const GLuint *)
2395{
2396 return ValidateGenOrDeleteES3(context, n);
2397}
2398
2399bool ValidateGenSamplers(Context *context, GLint count, GLuint *)
2400{
2401 return ValidateGenOrDeleteCountES3(context, count);
2402}
2403
2404bool ValidateDeleteSamplers(Context *context, GLint count, const GLuint *)
2405{
2406 return ValidateGenOrDeleteCountES3(context, count);
2407}
2408
2409bool ValidateGenTransformFeedbacks(Context *context, GLint n, GLuint *)
2410{
2411 return ValidateGenOrDeleteES3(context, n);
2412}
2413
2414bool ValidateDeleteTransformFeedbacks(Context *context, GLint n, const GLuint *ids)
2415{
2416 if (!ValidateGenOrDeleteES3(context, n))
2417 {
2418 return false;
2419 }
2420 for (GLint i = 0; i < n; ++i)
2421 {
2422 auto *transformFeedback = context->getTransformFeedback(ids[i]);
2423 if (transformFeedback != nullptr && transformFeedback->isActive())
2424 {
2425 // ES 3.0.4 section 2.15.1 page 86
Jamie Madill610640f2018-11-21 17:28:41 -05002426 context->validationError(GL_INVALID_OPERATION,
2427 "Attempt to delete active transform feedback.");
Olli Etuaho41997e72016-03-10 13:38:39 +02002428 return false;
2429 }
2430 }
2431 return true;
2432}
2433
2434bool ValidateGenVertexArrays(Context *context, GLint n, GLuint *)
2435{
2436 return ValidateGenOrDeleteES3(context, n);
2437}
2438
2439bool ValidateDeleteVertexArrays(Context *context, GLint n, const GLuint *)
2440{
2441 return ValidateGenOrDeleteES3(context, n);
2442}
2443
Jamie Madill493f9572018-05-24 19:52:15 -04002444bool ValidateBeginTransformFeedback(Context *context, PrimitiveMode primitiveMode)
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002445{
Martin Radev1be913c2016-07-11 17:59:16 +03002446 if (context->getClientMajorVersion() < 3)
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002447 {
Jamie Madill610640f2018-11-21 17:28:41 -05002448 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002449 return false;
2450 }
2451 switch (primitiveMode)
2452 {
Jamie Madill493f9572018-05-24 19:52:15 -04002453 case PrimitiveMode::Triangles:
2454 case PrimitiveMode::Lines:
2455 case PrimitiveMode::Points:
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002456 break;
2457
2458 default:
Jamie Madill610640f2018-11-21 17:28:41 -05002459 context->validationError(GL_INVALID_ENUM, "Invalid primitive mode.");
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002460 return false;
2461 }
2462
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002463 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002464 ASSERT(transformFeedback != nullptr);
2465
2466 if (transformFeedback->isActive())
2467 {
Jamie Madill610640f2018-11-21 17:28:41 -05002468 context->validationError(GL_INVALID_OPERATION, "Transform feedback is already active.");
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002469 return false;
2470 }
Geoff Lang79f71042017-08-14 16:43:43 -04002471
2472 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
2473 {
2474 const auto &buffer = transformFeedback->getIndexedBuffer(i);
2475 if (buffer.get() && buffer->isMapped())
2476 {
Jamie Madill610640f2018-11-21 17:28:41 -05002477 context->validationError(GL_INVALID_OPERATION,
2478 "Transform feedback has a mapped buffer.");
Geoff Lang79f71042017-08-14 16:43:43 -04002479 return false;
2480 }
2481 }
2482
Jamie Madill785e8a02018-10-04 17:42:00 -04002483 Program *program = context->getGLState().getLinkedProgram(context);
Olli Etuaho02032bd2017-10-13 18:10:17 +03002484
2485 if (!program)
2486 {
Jamie Madill610640f2018-11-21 17:28:41 -05002487 context->validationError(GL_INVALID_OPERATION, kErrorProgramNotBound);
Olli Etuaho02032bd2017-10-13 18:10:17 +03002488 return false;
2489 }
2490
2491 if (program->getTransformFeedbackVaryingCount() == 0)
2492 {
Jamie Madill610640f2018-11-21 17:28:41 -05002493 context->validationError(GL_INVALID_OPERATION, kErrorNoTransformFeedbackOutputVariables);
Olli Etuaho02032bd2017-10-13 18:10:17 +03002494 return false;
2495 }
2496
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002497 return true;
2498}
2499
Corentin Wallez336129f2017-10-17 15:55:40 -04002500bool ValidateGetBufferPointerv(Context *context, BufferBinding target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002501{
Geoff Lang496c02d2016-10-20 11:38:11 -07002502 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
2503}
2504
2505bool ValidateGetBufferPointervRobustANGLE(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002506 BufferBinding target,
Geoff Lang496c02d2016-10-20 11:38:11 -07002507 GLenum pname,
2508 GLsizei bufSize,
2509 GLsizei *length,
Jamie Madill876429b2017-04-20 15:46:24 -04002510 void **params)
Geoff Lang496c02d2016-10-20 11:38:11 -07002511{
2512 if (!ValidateRobustEntryPoint(context, bufSize))
Olli Etuaho4f667482016-03-30 15:56:35 +03002513 {
Olli Etuaho4f667482016-03-30 15:56:35 +03002514 return false;
2515 }
2516
Brandon Jonesd1049182018-03-28 10:02:20 -07002517 GLsizei numParams = 0;
2518
2519 if (!ValidateGetBufferPointervBase(context, target, pname, &numParams, params))
Geoff Lang496c02d2016-10-20 11:38:11 -07002520 {
2521 return false;
2522 }
2523
Brandon Jonesd1049182018-03-28 10:02:20 -07002524 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang496c02d2016-10-20 11:38:11 -07002525 {
2526 return false;
2527 }
2528
Brandon Jonesd1049182018-03-28 10:02:20 -07002529 SetRobustLengthParam(length, numParams);
2530
Geoff Lang496c02d2016-10-20 11:38:11 -07002531 return true;
Olli Etuaho4f667482016-03-30 15:56:35 +03002532}
2533
Corentin Wallez336129f2017-10-17 15:55:40 -04002534bool ValidateUnmapBuffer(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03002535{
Martin Radev1be913c2016-07-11 17:59:16 +03002536 if (context->getClientMajorVersion() < 3)
Olli Etuaho4f667482016-03-30 15:56:35 +03002537 {
Jamie Madill610640f2018-11-21 17:28:41 -05002538 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Olli Etuaho4f667482016-03-30 15:56:35 +03002539 return false;
2540 }
2541
2542 return ValidateUnmapBufferBase(context, target);
2543}
2544
2545bool ValidateMapBufferRange(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002546 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002547 GLintptr offset,
2548 GLsizeiptr length,
2549 GLbitfield access)
2550{
Martin Radev1be913c2016-07-11 17:59:16 +03002551 if (context->getClientMajorVersion() < 3)
Olli Etuaho4f667482016-03-30 15:56:35 +03002552 {
Jamie Madill610640f2018-11-21 17:28:41 -05002553 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Olli Etuaho4f667482016-03-30 15:56:35 +03002554 return false;
2555 }
2556
2557 return ValidateMapBufferRangeBase(context, target, offset, length, access);
2558}
2559
2560bool ValidateFlushMappedBufferRange(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002561 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002562 GLintptr offset,
2563 GLsizeiptr length)
2564{
Martin Radev1be913c2016-07-11 17:59:16 +03002565 if (context->getClientMajorVersion() < 3)
Olli Etuaho4f667482016-03-30 15:56:35 +03002566 {
Jamie Madill610640f2018-11-21 17:28:41 -05002567 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Olli Etuaho4f667482016-03-30 15:56:35 +03002568 return false;
2569 }
2570
2571 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
2572}
2573
Jamie Madill5b772312018-03-08 20:28:32 -05002574bool ValidateIndexedStateQuery(Context *context, GLenum pname, GLuint index, GLsizei *length)
Martin Radev66fb8202016-07-28 11:45:20 +03002575{
Geoff Lang2e43dbb2016-10-14 12:27:35 -04002576 if (length)
2577 {
2578 *length = 0;
2579 }
2580
Martin Radev66fb8202016-07-28 11:45:20 +03002581 GLenum nativeType;
2582 unsigned int numParams;
2583 if (!context->getIndexedQueryParameterInfo(pname, &nativeType, &numParams))
2584 {
Jamie Madill610640f2018-11-21 17:28:41 -05002585 context->validationError(GL_INVALID_ENUM, kErrorInvalidPname);
Martin Radev66fb8202016-07-28 11:45:20 +03002586 return false;
2587 }
2588
2589 const Caps &caps = context->getCaps();
2590 switch (pname)
2591 {
2592 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
2593 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
2594 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
2595 if (index >= caps.maxTransformFeedbackSeparateAttributes)
2596 {
Jamie Madill610640f2018-11-21 17:28:41 -05002597 context->validationError(GL_INVALID_VALUE,
2598 kErrorIndexExceedsMaxTransformFeedbackAttribs);
Martin Radev66fb8202016-07-28 11:45:20 +03002599 return false;
2600 }
2601 break;
2602
2603 case GL_UNIFORM_BUFFER_START:
2604 case GL_UNIFORM_BUFFER_SIZE:
2605 case GL_UNIFORM_BUFFER_BINDING:
2606 if (index >= caps.maxUniformBufferBindings)
2607 {
Jamie Madill610640f2018-11-21 17:28:41 -05002608 context->validationError(GL_INVALID_VALUE,
2609 kErrorIndexExceedsMaxUniformBufferBindings);
Martin Radev66fb8202016-07-28 11:45:20 +03002610 return false;
2611 }
2612 break;
Shao80957d92017-02-20 21:25:59 +08002613
Martin Radev66fb8202016-07-28 11:45:20 +03002614 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
2615 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
2616 if (index >= 3u)
2617 {
Jamie Madill610640f2018-11-21 17:28:41 -05002618 context->validationError(GL_INVALID_VALUE,
2619 kErrorIndexExceedsMaxWorkgroupDimensions);
Martin Radev66fb8202016-07-28 11:45:20 +03002620 return false;
2621 }
2622 break;
Shao80957d92017-02-20 21:25:59 +08002623
Jiajia Qin6eafb042016-12-27 17:04:07 +08002624 case GL_ATOMIC_COUNTER_BUFFER_START:
2625 case GL_ATOMIC_COUNTER_BUFFER_SIZE:
2626 case GL_ATOMIC_COUNTER_BUFFER_BINDING:
2627 if (context->getClientVersion() < ES_3_1)
2628 {
Jamie Madill610640f2018-11-21 17:28:41 -05002629 context->validationError(GL_INVALID_ENUM, kErrorEnumRequiresGLES31);
Jiajia Qin6eafb042016-12-27 17:04:07 +08002630 return false;
2631 }
2632 if (index >= caps.maxAtomicCounterBufferBindings)
2633 {
Jamie Madill610640f2018-11-21 17:28:41 -05002634 context->validationError(GL_INVALID_VALUE,
2635 kErrorIndexExceedsMaxAtomicCounterBufferBindings);
Jiajia Qin6eafb042016-12-27 17:04:07 +08002636 return false;
2637 }
2638 break;
Shao80957d92017-02-20 21:25:59 +08002639
Jiajia Qinf546e7d2017-03-27 14:12:59 +08002640 case GL_SHADER_STORAGE_BUFFER_START:
2641 case GL_SHADER_STORAGE_BUFFER_SIZE:
2642 case GL_SHADER_STORAGE_BUFFER_BINDING:
2643 if (context->getClientVersion() < ES_3_1)
2644 {
Jamie Madill610640f2018-11-21 17:28:41 -05002645 context->validationError(GL_INVALID_ENUM, kErrorEnumRequiresGLES31);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08002646 return false;
2647 }
2648 if (index >= caps.maxShaderStorageBufferBindings)
2649 {
Jamie Madill610640f2018-11-21 17:28:41 -05002650 context->validationError(
2651 GL_INVALID_VALUE,
2652 "index is outside the valid range for GL_SHADER_STORAGE_BUFFER_BINDING");
Jiajia Qinf546e7d2017-03-27 14:12:59 +08002653 return false;
2654 }
2655 break;
2656
Shao80957d92017-02-20 21:25:59 +08002657 case GL_VERTEX_BINDING_BUFFER:
2658 case GL_VERTEX_BINDING_DIVISOR:
2659 case GL_VERTEX_BINDING_OFFSET:
2660 case GL_VERTEX_BINDING_STRIDE:
2661 if (context->getClientVersion() < ES_3_1)
2662 {
Jamie Madill610640f2018-11-21 17:28:41 -05002663 context->validationError(GL_INVALID_ENUM, kErrorEnumRequiresGLES31);
Shao80957d92017-02-20 21:25:59 +08002664 return false;
2665 }
2666 if (index >= caps.maxVertexAttribBindings)
2667 {
Jamie Madill610640f2018-11-21 17:28:41 -05002668 context->validationError(
2669 GL_INVALID_VALUE,
2670 "bindingindex must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08002671 return false;
2672 }
2673 break;
Jiawei Shaodb342272017-09-27 10:21:45 +08002674 case GL_SAMPLE_MASK_VALUE:
2675 if (context->getClientVersion() < ES_3_1)
2676 {
Jamie Madill610640f2018-11-21 17:28:41 -05002677 context->validationError(GL_INVALID_ENUM, kErrorEnumRequiresGLES31);
Jiawei Shaodb342272017-09-27 10:21:45 +08002678 return false;
2679 }
2680 if (index >= caps.maxSampleMaskWords)
2681 {
Jamie Madill610640f2018-11-21 17:28:41 -05002682 context->validationError(GL_INVALID_VALUE, kErrorInvalidSampleMaskNumber);
Jiawei Shaodb342272017-09-27 10:21:45 +08002683 return false;
2684 }
2685 break;
Xinghua Cao9c8e1a32017-12-06 17:59:58 +08002686 case GL_IMAGE_BINDING_NAME:
2687 case GL_IMAGE_BINDING_LEVEL:
2688 case GL_IMAGE_BINDING_LAYERED:
2689 case GL_IMAGE_BINDING_LAYER:
2690 case GL_IMAGE_BINDING_ACCESS:
2691 case GL_IMAGE_BINDING_FORMAT:
2692 if (context->getClientVersion() < ES_3_1)
2693 {
Jamie Madill610640f2018-11-21 17:28:41 -05002694 context->validationError(GL_INVALID_ENUM, kErrorEnumRequiresGLES31);
Xinghua Cao9c8e1a32017-12-06 17:59:58 +08002695 return false;
2696 }
2697 if (index >= caps.maxImageUnits)
2698 {
Jamie Madill610640f2018-11-21 17:28:41 -05002699 context->validationError(GL_INVALID_VALUE, kErrorInvalidImageUnit);
Xinghua Cao9c8e1a32017-12-06 17:59:58 +08002700 return false;
2701 }
2702 break;
Martin Radev66fb8202016-07-28 11:45:20 +03002703 default:
Jamie Madill610640f2018-11-21 17:28:41 -05002704 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Martin Radev66fb8202016-07-28 11:45:20 +03002705 return false;
2706 }
2707
Geoff Lang2e43dbb2016-10-14 12:27:35 -04002708 if (length)
Martin Radev66fb8202016-07-28 11:45:20 +03002709 {
Geoff Lang2e43dbb2016-10-14 12:27:35 -04002710 *length = 1;
Martin Radev66fb8202016-07-28 11:45:20 +03002711 }
2712
2713 return true;
2714}
2715
Jamie Madill5b772312018-03-08 20:28:32 -05002716bool ValidateGetIntegeri_v(Context *context, GLenum target, GLuint index, GLint *data)
Martin Radev66fb8202016-07-28 11:45:20 +03002717{
Geoff Langeb66a6e2016-10-31 13:06:12 -04002718 if (context->getClientVersion() < ES_3_0)
Martin Radev66fb8202016-07-28 11:45:20 +03002719 {
Jamie Madill610640f2018-11-21 17:28:41 -05002720 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Martin Radev66fb8202016-07-28 11:45:20 +03002721 return false;
2722 }
Geoff Lang2e43dbb2016-10-14 12:27:35 -04002723 return ValidateIndexedStateQuery(context, target, index, nullptr);
Martin Radev66fb8202016-07-28 11:45:20 +03002724}
2725
Jamie Madill5b772312018-03-08 20:28:32 -05002726bool ValidateGetIntegeri_vRobustANGLE(Context *context,
Geoff Langcf255ea2016-10-20 11:39:09 -07002727 GLenum target,
2728 GLuint index,
2729 GLsizei bufSize,
2730 GLsizei *length,
2731 GLint *data)
2732{
Geoff Langeb66a6e2016-10-31 13:06:12 -04002733 if (context->getClientVersion() < ES_3_0)
Geoff Langcf255ea2016-10-20 11:39:09 -07002734 {
Jamie Madill610640f2018-11-21 17:28:41 -05002735 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Geoff Langcf255ea2016-10-20 11:39:09 -07002736 return false;
2737 }
2738
2739 if (!ValidateRobustEntryPoint(context, bufSize))
2740 {
2741 return false;
2742 }
2743
Brandon Jonesd1049182018-03-28 10:02:20 -07002744 GLsizei numParams = 0;
2745
2746 if (!ValidateIndexedStateQuery(context, target, index, &numParams))
Geoff Langcf255ea2016-10-20 11:39:09 -07002747 {
2748 return false;
2749 }
2750
Brandon Jonesd1049182018-03-28 10:02:20 -07002751 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langcf255ea2016-10-20 11:39:09 -07002752 {
2753 return false;
2754 }
2755
Brandon Jonesd1049182018-03-28 10:02:20 -07002756 SetRobustLengthParam(length, numParams);
2757
Geoff Langcf255ea2016-10-20 11:39:09 -07002758 return true;
2759}
2760
Jamie Madill5b772312018-03-08 20:28:32 -05002761bool ValidateGetInteger64i_v(Context *context, GLenum target, GLuint index, GLint64 *data)
Martin Radev66fb8202016-07-28 11:45:20 +03002762{
Geoff Langeb66a6e2016-10-31 13:06:12 -04002763 if (context->getClientVersion() < ES_3_0)
Martin Radev66fb8202016-07-28 11:45:20 +03002764 {
Jamie Madill610640f2018-11-21 17:28:41 -05002765 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Martin Radev66fb8202016-07-28 11:45:20 +03002766 return false;
2767 }
Geoff Lang2e43dbb2016-10-14 12:27:35 -04002768 return ValidateIndexedStateQuery(context, target, index, nullptr);
2769}
2770
Jamie Madill5b772312018-03-08 20:28:32 -05002771bool ValidateGetInteger64i_vRobustANGLE(Context *context,
Geoff Lang2e43dbb2016-10-14 12:27:35 -04002772 GLenum target,
2773 GLuint index,
2774 GLsizei bufSize,
2775 GLsizei *length,
2776 GLint64 *data)
2777{
Geoff Langeb66a6e2016-10-31 13:06:12 -04002778 if (context->getClientVersion() < ES_3_0)
Geoff Lang2e43dbb2016-10-14 12:27:35 -04002779 {
Jamie Madill610640f2018-11-21 17:28:41 -05002780 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Geoff Lang2e43dbb2016-10-14 12:27:35 -04002781 return false;
2782 }
2783
2784 if (!ValidateRobustEntryPoint(context, bufSize))
2785 {
2786 return false;
2787 }
2788
Brandon Jonesd1049182018-03-28 10:02:20 -07002789 GLsizei numParams = 0;
2790
2791 if (!ValidateIndexedStateQuery(context, target, index, &numParams))
Geoff Lang2e43dbb2016-10-14 12:27:35 -04002792 {
2793 return false;
2794 }
2795
Brandon Jonesd1049182018-03-28 10:02:20 -07002796 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2e43dbb2016-10-14 12:27:35 -04002797 {
2798 return false;
2799 }
2800
Brandon Jonesd1049182018-03-28 10:02:20 -07002801 SetRobustLengthParam(length, numParams);
2802
Geoff Lang2e43dbb2016-10-14 12:27:35 -04002803 return true;
Martin Radev66fb8202016-07-28 11:45:20 +03002804}
2805
Jamie Madill5b772312018-03-08 20:28:32 -05002806bool ValidateCopyBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002807 BufferBinding readTarget,
2808 BufferBinding writeTarget,
Jamie Madillb0817d12016-11-01 15:48:31 -04002809 GLintptr readOffset,
2810 GLintptr writeOffset,
2811 GLsizeiptr size)
2812{
2813 if (context->getClientMajorVersion() < 3)
2814 {
Jamie Madill610640f2018-11-21 17:28:41 -05002815 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madillb0817d12016-11-01 15:48:31 -04002816 return false;
2817 }
2818
Corentin Walleze4477002017-12-01 14:39:58 -05002819 if (!context->isValidBufferBinding(readTarget) || !context->isValidBufferBinding(writeTarget))
Jamie Madillb0817d12016-11-01 15:48:31 -04002820 {
Jamie Madill610640f2018-11-21 17:28:41 -05002821 context->validationError(GL_INVALID_ENUM, kErrorInvalidBufferTypes);
Jamie Madillb0817d12016-11-01 15:48:31 -04002822 return false;
2823 }
2824
2825 Buffer *readBuffer = context->getGLState().getTargetBuffer(readTarget);
2826 Buffer *writeBuffer = context->getGLState().getTargetBuffer(writeTarget);
2827
2828 if (!readBuffer || !writeBuffer)
2829 {
Jamie Madill610640f2018-11-21 17:28:41 -05002830 context->validationError(GL_INVALID_OPERATION, "No buffer bound to target");
Jamie Madillb0817d12016-11-01 15:48:31 -04002831 return false;
2832 }
2833
2834 // Verify that readBuffer and writeBuffer are not currently mapped
2835 if (readBuffer->isMapped() || writeBuffer->isMapped())
2836 {
Jamie Madill610640f2018-11-21 17:28:41 -05002837 context->validationError(GL_INVALID_OPERATION,
2838 "Cannot call CopyBufferSubData on a mapped buffer");
Jamie Madillb0817d12016-11-01 15:48:31 -04002839 return false;
2840 }
2841
James Darpiniane8a93c62018-01-04 18:02:24 -08002842 if (context->getExtensions().webglCompatibility &&
2843 (readBuffer->isBoundForTransformFeedbackAndOtherUse() ||
2844 writeBuffer->isBoundForTransformFeedbackAndOtherUse()))
2845 {
Jamie Madill610640f2018-11-21 17:28:41 -05002846 context->validationError(GL_INVALID_OPERATION, kErrorBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08002847 return false;
2848 }
2849
Jamie Madilld2f0c742016-11-02 10:34:41 -04002850 CheckedNumeric<GLintptr> checkedReadOffset(readOffset);
2851 CheckedNumeric<GLintptr> checkedWriteOffset(writeOffset);
2852 CheckedNumeric<GLintptr> checkedSize(size);
2853
2854 auto checkedReadSum = checkedReadOffset + checkedSize;
2855 auto checkedWriteSum = checkedWriteOffset + checkedSize;
2856
2857 if (!checkedReadSum.IsValid() || !checkedWriteSum.IsValid() ||
2858 !IsValueInRangeForNumericType<GLintptr>(readBuffer->getSize()) ||
2859 !IsValueInRangeForNumericType<GLintptr>(writeBuffer->getSize()))
Jamie Madillb0817d12016-11-01 15:48:31 -04002860 {
Jamie Madill610640f2018-11-21 17:28:41 -05002861 context->validationError(GL_INVALID_VALUE, kErrorIntegerOverflow);
Jamie Madillb0817d12016-11-01 15:48:31 -04002862 return false;
2863 }
2864
Jamie Madilld2f0c742016-11-02 10:34:41 -04002865 if (readOffset < 0 || writeOffset < 0 || size < 0)
Jamie Madillb0817d12016-11-01 15:48:31 -04002866 {
Jamie Madill610640f2018-11-21 17:28:41 -05002867 context->validationError(GL_INVALID_VALUE,
2868 "readOffset, writeOffset and size must all be non-negative");
Jamie Madillb0817d12016-11-01 15:48:31 -04002869 return false;
2870 }
2871
Jamie Madilld2f0c742016-11-02 10:34:41 -04002872 if (checkedReadSum.ValueOrDie() > readBuffer->getSize() ||
2873 checkedWriteSum.ValueOrDie() > writeBuffer->getSize())
2874 {
Jamie Madill610640f2018-11-21 17:28:41 -05002875 context->validationError(GL_INVALID_VALUE, "Buffer offset overflow in CopyBufferSubData");
Jamie Madilld2f0c742016-11-02 10:34:41 -04002876 return false;
2877 }
2878
2879 if (readBuffer == writeBuffer)
2880 {
2881 auto checkedOffsetDiff = (checkedReadOffset - checkedWriteOffset).Abs();
2882 if (!checkedOffsetDiff.IsValid())
2883 {
2884 // This shold not be possible.
2885 UNREACHABLE();
Jamie Madill610640f2018-11-21 17:28:41 -05002886 context->validationError(GL_INVALID_VALUE, kErrorIntegerOverflow);
Jamie Madilld2f0c742016-11-02 10:34:41 -04002887 return false;
2888 }
2889
2890 if (checkedOffsetDiff.ValueOrDie() < size)
2891 {
Jamie Madill610640f2018-11-21 17:28:41 -05002892 context->validationError(GL_INVALID_VALUE, kErrorCopyAlias);
Jamie Madilld2f0c742016-11-02 10:34:41 -04002893 return false;
2894 }
2895 }
2896
Jamie Madillb0817d12016-11-01 15:48:31 -04002897 return true;
2898}
2899
Geoff Langc339c4e2016-11-29 10:37:36 -05002900bool ValidateGetStringi(Context *context, GLenum name, GLuint index)
2901{
2902 if (context->getClientMajorVersion() < 3)
2903 {
Jamie Madill610640f2018-11-21 17:28:41 -05002904 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Geoff Langc339c4e2016-11-29 10:37:36 -05002905 return false;
2906 }
2907
2908 switch (name)
2909 {
2910 case GL_EXTENSIONS:
2911 if (index >= context->getExtensionStringCount())
2912 {
Jamie Madill610640f2018-11-21 17:28:41 -05002913 context->validationError(
2914 GL_INVALID_VALUE, "index must be less than the number of extension strings.");
Geoff Langc339c4e2016-11-29 10:37:36 -05002915 return false;
2916 }
2917 break;
2918
2919 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2920 if (!context->getExtensions().requestExtension)
2921 {
Jamie Madill610640f2018-11-21 17:28:41 -05002922 context->validationError(GL_INVALID_ENUM, kErrorInvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05002923 return false;
2924 }
2925 if (index >= context->getRequestableExtensionStringCount())
2926 {
Jamie Madill610640f2018-11-21 17:28:41 -05002927 context->validationError(
2928 GL_INVALID_VALUE,
2929 "index must be less than the number of requestable extension strings.");
Geoff Langc339c4e2016-11-29 10:37:36 -05002930 return false;
2931 }
2932 break;
2933
2934 default:
Jamie Madill610640f2018-11-21 17:28:41 -05002935 context->validationError(GL_INVALID_ENUM, kErrorInvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05002936 return false;
2937 }
2938
2939 return true;
2940}
2941
Jamie Madill5b772312018-03-08 20:28:32 -05002942bool ValidateRenderbufferStorageMultisample(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05002943 GLenum target,
2944 GLsizei samples,
2945 GLenum internalformat,
2946 GLsizei width,
2947 GLsizei height)
2948{
2949 if (context->getClientMajorVersion() < 3)
2950 {
Jamie Madill610640f2018-11-21 17:28:41 -05002951 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madille8fb6402017-02-14 17:56:40 -05002952 return false;
2953 }
2954
2955 if (!ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat, width,
2956 height))
2957 {
2958 return false;
2959 }
2960
2961 // The ES3 spec(section 4.4.2) states that the internal format must be sized and not an integer
Yunchao Hec0810202018-01-22 09:48:48 +08002962 // format if samples is greater than zero. In ES3.1(section 9.2.5), it can support integer
2963 // multisample renderbuffer, but the samples should not be greater than MAX_INTEGER_SAMPLES.
Geoff Langca271392017-04-05 12:30:00 -04002964 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Yunchao Hec0810202018-01-22 09:48:48 +08002965 if ((formatInfo.componentType == GL_UNSIGNED_INT || formatInfo.componentType == GL_INT))
Jamie Madille8fb6402017-02-14 17:56:40 -05002966 {
Yunchao Hec0810202018-01-22 09:48:48 +08002967 if ((samples > 0 && context->getClientVersion() == ES_3_0) ||
2968 static_cast<GLuint>(samples) > context->getCaps().maxIntegerSamples)
2969 {
Jamie Madill610640f2018-11-21 17:28:41 -05002970 context->validationError(GL_INVALID_OPERATION, kErrorSamplesOutOfRange);
Yunchao Hec0810202018-01-22 09:48:48 +08002971 return false;
2972 }
Jamie Madille8fb6402017-02-14 17:56:40 -05002973 }
2974
2975 // The behavior is different than the ANGLE version, which would generate a GL_OUT_OF_MEMORY.
2976 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
2977 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
2978 {
Jamie Madill610640f2018-11-21 17:28:41 -05002979 context->validationError(GL_INVALID_OPERATION, kErrorSamplesOutOfRange);
Jamie Madille8fb6402017-02-14 17:56:40 -05002980 return false;
2981 }
2982
2983 return true;
2984}
2985
Jamie Madill5b772312018-03-08 20:28:32 -05002986bool ValidateVertexAttribIPointer(Context *context,
Geoff Langaa086d62017-03-23 16:47:21 -04002987 GLuint index,
2988 GLint size,
2989 GLenum type,
2990 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04002991 const void *pointer)
Geoff Langaa086d62017-03-23 16:47:21 -04002992{
2993 if (context->getClientMajorVersion() < 3)
2994 {
Jamie Madill610640f2018-11-21 17:28:41 -05002995 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Geoff Langaa086d62017-03-23 16:47:21 -04002996 return false;
2997 }
2998
Shao80957d92017-02-20 21:25:59 +08002999 if (!ValidateVertexFormatBase(context, index, size, type, true))
Geoff Langaa086d62017-03-23 16:47:21 -04003000 {
Geoff Langaa086d62017-03-23 16:47:21 -04003001 return false;
3002 }
3003
Geoff Langaa086d62017-03-23 16:47:21 -04003004 if (stride < 0)
3005 {
Jamie Madill610640f2018-11-21 17:28:41 -05003006 context->validationError(GL_INVALID_VALUE, kErrorNegativeStride);
Geoff Langaa086d62017-03-23 16:47:21 -04003007 return false;
3008 }
3009
Shao80957d92017-02-20 21:25:59 +08003010 const Caps &caps = context->getCaps();
3011 if (context->getClientVersion() >= ES_3_1)
3012 {
3013 if (stride > caps.maxVertexAttribStride)
3014 {
Jamie Madill610640f2018-11-21 17:28:41 -05003015 context->validationError(GL_INVALID_VALUE,
3016 "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08003017 return false;
3018 }
3019
3020 // [OpenGL ES 3.1] Section 10.3.1 page 245:
3021 // glVertexAttribBinding is part of the equivalent code of VertexAttribIPointer, so its
3022 // validation should be inherited.
3023 if (index >= caps.maxVertexAttribBindings)
3024 {
Jamie Madill610640f2018-11-21 17:28:41 -05003025 context->validationError(GL_INVALID_VALUE,
3026 "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08003027 return false;
3028 }
3029 }
3030
Geoff Langaa086d62017-03-23 16:47:21 -04003031 // [OpenGL ES 3.0.2] Section 2.8 page 24:
3032 // An INVALID_OPERATION error is generated when a non-zero vertex array object
3033 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
3034 // and the pointer argument is not NULL.
3035 if (context->getGLState().getVertexArrayId() != 0 &&
Corentin Wallez336129f2017-10-17 15:55:40 -04003036 context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 && pointer != nullptr)
Geoff Langaa086d62017-03-23 16:47:21 -04003037 {
Jamie Madill610640f2018-11-21 17:28:41 -05003038 context->validationError(
3039 GL_INVALID_OPERATION,
3040 "Client data cannot be used with a non-default vertex array object.");
Geoff Langaa086d62017-03-23 16:47:21 -04003041 return false;
3042 }
3043
Geoff Lang2d62ab72017-03-23 16:54:40 -04003044 if (context->getExtensions().webglCompatibility)
3045 {
3046 if (!ValidateWebGLVertexAttribPointer(context, type, false, stride, pointer, true))
3047 {
3048 return false;
3049 }
3050 }
3051
Geoff Langaa086d62017-03-23 16:47:21 -04003052 return true;
3053}
3054
Geoff Lang38f2cfb2017-04-11 15:23:08 -04003055bool ValidateGetSynciv(Context *context,
3056 GLsync sync,
3057 GLenum pname,
3058 GLsizei bufSize,
3059 GLsizei *length,
3060 GLint *values)
3061{
3062 if (context->getClientMajorVersion() < 3)
3063 {
Jamie Madill610640f2018-11-21 17:28:41 -05003064 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Geoff Lang38f2cfb2017-04-11 15:23:08 -04003065 return false;
3066 }
3067
3068 if (bufSize < 0)
3069 {
Jamie Madill610640f2018-11-21 17:28:41 -05003070 context->validationError(GL_INVALID_VALUE, kErrorNegativeBufferSize);
Geoff Lang38f2cfb2017-04-11 15:23:08 -04003071 return false;
3072 }
3073
Jamie Madill70b5bb02017-08-28 13:32:37 -04003074 Sync *syncObject = context->getSync(sync);
3075 if (!syncObject)
Geoff Lang38f2cfb2017-04-11 15:23:08 -04003076 {
Jamie Madill610640f2018-11-21 17:28:41 -05003077 context->validationError(GL_INVALID_VALUE, "Invalid sync object.");
Geoff Lang38f2cfb2017-04-11 15:23:08 -04003078 return false;
3079 }
3080
3081 switch (pname)
3082 {
3083 case GL_OBJECT_TYPE:
3084 case GL_SYNC_CONDITION:
3085 case GL_SYNC_FLAGS:
3086 case GL_SYNC_STATUS:
3087 break;
3088
3089 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003090 context->validationError(GL_INVALID_ENUM, kErrorInvalidPname);
Geoff Lang38f2cfb2017-04-11 15:23:08 -04003091 return false;
3092 }
3093
3094 return true;
3095}
3096
Jamie Madill5b772312018-03-08 20:28:32 -05003097bool ValidateDrawElementsInstanced(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04003098 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003099 GLsizei count,
3100 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003101 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003102 GLsizei instanceCount)
3103{
3104 if (context->getClientMajorVersion() < 3)
3105 {
Jamie Madill610640f2018-11-21 17:28:41 -05003106 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003107 return false;
3108 }
3109
3110 return ValidateDrawElementsInstancedCommon(context, mode, count, type, indices, instanceCount);
3111}
3112
Austin Eng1bf18ce2018-10-19 15:34:02 -07003113bool ValidateMultiDrawArraysInstancedANGLE(Context *context,
3114 PrimitiveMode mode,
3115 const GLint *firsts,
3116 const GLsizei *counts,
3117 const GLsizei *instanceCounts,
3118 GLsizei drawcount)
3119{
3120 if (!context->getExtensions().multiDraw)
3121 {
Jamie Madill610640f2018-11-21 17:28:41 -05003122 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07003123 return false;
3124 }
3125 if (context->getClientMajorVersion() < 3)
3126 {
3127 if (!context->getExtensions().instancedArrays)
3128 {
Jamie Madill610640f2018-11-21 17:28:41 -05003129 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07003130 return false;
3131 }
3132 if (!ValidateDrawInstancedANGLE(context))
3133 {
3134 return false;
3135 }
3136 }
3137 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
3138 {
3139 if (!ValidateDrawArraysInstancedBase(context, mode, firsts[drawID], counts[drawID],
3140 instanceCounts[drawID]))
3141 {
3142 return false;
3143 }
3144 }
3145 return true;
3146}
3147
3148bool ValidateMultiDrawElementsInstancedANGLE(Context *context,
3149 PrimitiveMode mode,
3150 const GLsizei *counts,
3151 GLenum type,
3152 const GLsizei *offsets,
3153 const GLsizei *instanceCounts,
3154 GLsizei drawcount)
3155{
3156 if (!context->getExtensions().multiDraw)
3157 {
Jamie Madill610640f2018-11-21 17:28:41 -05003158 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07003159 return false;
3160 }
3161 if (context->getClientMajorVersion() < 3)
3162 {
3163 if (!context->getExtensions().instancedArrays)
3164 {
Jamie Madill610640f2018-11-21 17:28:41 -05003165 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07003166 return false;
3167 }
3168 if (!ValidateDrawInstancedANGLE(context))
3169 {
3170 return false;
3171 }
3172 }
3173 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
3174 {
3175 const void *indices = reinterpret_cast<void *>(static_cast<long>(offsets[drawID]));
3176 if (!ValidateDrawElementsInstancedCommon(context, mode, counts[drawID], type, indices,
3177 instanceCounts[drawID]))
3178 {
3179 return false;
3180 }
3181 }
3182 return true;
3183}
3184
Martin Radev137032d2017-07-13 10:11:12 +03003185bool ValidateFramebufferTextureMultiviewLayeredANGLE(Context *context,
3186 GLenum target,
3187 GLenum attachment,
3188 GLuint texture,
3189 GLint level,
3190 GLint baseViewIndex,
3191 GLsizei numViews)
3192{
Martin Radev137032d2017-07-13 10:11:12 +03003193 if (!ValidateFramebufferTextureMultiviewBaseANGLE(context, target, attachment, texture, level,
3194 numViews))
3195 {
3196 return false;
3197 }
3198
Martin Radev137032d2017-07-13 10:11:12 +03003199 if (texture != 0)
3200 {
Martin Radev14b21262017-08-25 13:54:37 +03003201 if (baseViewIndex < 0)
3202 {
Jamie Madill610640f2018-11-21 17:28:41 -05003203 context->validationError(GL_INVALID_VALUE, "baseViewIndex cannot be less than 0.");
Martin Radev14b21262017-08-25 13:54:37 +03003204 return false;
3205 }
3206
Martin Radev137032d2017-07-13 10:11:12 +03003207 Texture *tex = context->getTexture(texture);
3208 ASSERT(tex);
3209
Corentin Wallez99d492c2018-02-27 15:17:10 -05003210 switch (tex->getType())
Martin Radev137032d2017-07-13 10:11:12 +03003211 {
Corentin Wallez99d492c2018-02-27 15:17:10 -05003212 case TextureType::_2DArray:
Olli Etuaho2c8f0842018-09-12 14:44:55 +03003213 case TextureType::_2DMultisampleArray:
Martin Radev137032d2017-07-13 10:11:12 +03003214 {
Olli Etuaho2c8f0842018-09-12 14:44:55 +03003215 if (tex->getType() == TextureType::_2DMultisampleArray)
3216 {
3217 if (!context->getExtensions().multiviewMultisample)
3218 {
Jamie Madill610640f2018-11-21 17:28:41 -05003219 context->validationError(GL_INVALID_OPERATION,
3220 "Texture's target must be GL_TEXTURE_2D_ARRAY.");
Olli Etuaho2c8f0842018-09-12 14:44:55 +03003221 return false;
3222 }
3223 }
3224
Martin Radev137032d2017-07-13 10:11:12 +03003225 const Caps &caps = context->getCaps();
3226 if (static_cast<GLuint>(baseViewIndex + numViews) > caps.maxArrayTextureLayers)
3227 {
Jamie Madill610640f2018-11-21 17:28:41 -05003228 context->validationError(GL_INVALID_VALUE,
3229 "baseViewIndex+numViews cannot be "
3230 "greater than "
3231 "GL_MAX_ARRAY_TEXTURE_LAYERS.");
Martin Radev137032d2017-07-13 10:11:12 +03003232 return false;
3233 }
Olli Etuaho2c8f0842018-09-12 14:44:55 +03003234
3235 break;
Martin Radev137032d2017-07-13 10:11:12 +03003236 }
Martin Radev137032d2017-07-13 10:11:12 +03003237 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003238 context->validationError(GL_INVALID_OPERATION,
3239 "Texture's target must be GL_TEXTURE_2D_ARRAY.");
Martin Radev137032d2017-07-13 10:11:12 +03003240 return false;
3241 }
3242
3243 if (!ValidateFramebufferTextureMultiviewLevelAndFormat(context, tex, level))
3244 {
3245 return false;
3246 }
3247 }
3248
3249 return true;
3250}
3251
3252bool ValidateFramebufferTextureMultiviewSideBySideANGLE(Context *context,
3253 GLenum target,
3254 GLenum attachment,
3255 GLuint texture,
3256 GLint level,
3257 GLsizei numViews,
3258 const GLint *viewportOffsets)
3259{
3260 if (!ValidateFramebufferTextureMultiviewBaseANGLE(context, target, attachment, texture, level,
3261 numViews))
3262 {
3263 return false;
3264 }
3265
Martin Radev137032d2017-07-13 10:11:12 +03003266 if (texture != 0)
3267 {
Martin Radev14b21262017-08-25 13:54:37 +03003268 const GLsizei numViewportOffsetValues = numViews * 2;
3269 for (GLsizei i = 0; i < numViewportOffsetValues; ++i)
3270 {
3271 if (viewportOffsets[i] < 0)
3272 {
Jamie Madill610640f2018-11-21 17:28:41 -05003273 context->validationError(GL_INVALID_VALUE,
3274 "viewportOffsets cannot contain negative values.");
Martin Radev14b21262017-08-25 13:54:37 +03003275 return false;
3276 }
3277 }
3278
Martin Radev137032d2017-07-13 10:11:12 +03003279 Texture *tex = context->getTexture(texture);
3280 ASSERT(tex);
3281
Corentin Wallez99d492c2018-02-27 15:17:10 -05003282 switch (tex->getType())
Martin Radev137032d2017-07-13 10:11:12 +03003283 {
Corentin Wallez99d492c2018-02-27 15:17:10 -05003284 case TextureType::_2D:
Martin Radev137032d2017-07-13 10:11:12 +03003285 break;
3286 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003287 context->validationError(GL_INVALID_OPERATION,
3288 "Texture's target must be GL_TEXTURE_2D.");
Martin Radev137032d2017-07-13 10:11:12 +03003289 return false;
3290 }
3291
3292 if (!ValidateFramebufferTextureMultiviewLevelAndFormat(context, tex, level))
3293 {
3294 return false;
3295 }
3296 }
3297
3298 return true;
3299}
3300
Jamie Madillff325f12017-08-26 15:06:05 -04003301bool ValidateUniform1ui(Context *context, GLint location, GLuint v0)
3302{
3303 return ValidateUniformES3(context, GL_UNSIGNED_INT, location, 1);
3304}
3305
3306bool ValidateUniform2ui(Context *context, GLint location, GLuint v0, GLuint v1)
3307{
3308 return ValidateUniformES3(context, GL_UNSIGNED_INT_VEC2, location, 1);
3309}
3310
3311bool ValidateUniform3ui(Context *context, GLint location, GLuint v0, GLuint v1, GLuint v2)
3312{
3313 return ValidateUniformES3(context, GL_UNSIGNED_INT_VEC3, location, 1);
3314}
3315
3316bool ValidateUniform4ui(Context *context,
3317 GLint location,
3318 GLuint v0,
3319 GLuint v1,
3320 GLuint v2,
3321 GLuint v3)
3322{
3323 return ValidateUniformES3(context, GL_UNSIGNED_INT_VEC4, location, 1);
3324}
3325
3326bool ValidateUniform1uiv(Context *context, GLint location, GLsizei count, const GLuint *value)
3327{
3328 return ValidateUniformES3(context, GL_UNSIGNED_INT, location, count);
3329}
3330
3331bool ValidateUniform2uiv(Context *context, GLint location, GLsizei count, const GLuint *value)
3332{
3333 return ValidateUniformES3(context, GL_UNSIGNED_INT_VEC2, location, count);
3334}
3335
3336bool ValidateUniform3uiv(Context *context, GLint location, GLsizei count, const GLuint *value)
3337{
3338 return ValidateUniformES3(context, GL_UNSIGNED_INT_VEC3, location, count);
3339}
3340
3341bool ValidateUniform4uiv(Context *context, GLint location, GLsizei count, const GLuint *value)
3342{
3343 return ValidateUniformES3(context, GL_UNSIGNED_INT_VEC4, location, count);
3344}
3345
Jamie Madillf0e04492017-08-26 15:28:42 -04003346bool ValidateIsQuery(Context *context, GLuint id)
3347{
3348 if (context->getClientMajorVersion() < 3)
3349 {
Jamie Madill610640f2018-11-21 17:28:41 -05003350 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madillf0e04492017-08-26 15:28:42 -04003351 return false;
3352 }
3353
3354 return true;
3355}
3356
Jamie Madillc8c95812017-08-26 18:40:09 -04003357bool ValidateUniformMatrix2x3fv(Context *context,
3358 GLint location,
3359 GLsizei count,
3360 GLboolean transpose,
3361 const GLfloat *value)
3362{
3363 return ValidateUniformMatrixES3(context, GL_FLOAT_MAT2x3, location, count, transpose);
3364}
3365
3366bool ValidateUniformMatrix3x2fv(Context *context,
3367 GLint location,
3368 GLsizei count,
3369 GLboolean transpose,
3370 const GLfloat *value)
3371{
3372 return ValidateUniformMatrixES3(context, GL_FLOAT_MAT3x2, location, count, transpose);
3373}
3374
3375bool ValidateUniformMatrix2x4fv(Context *context,
3376 GLint location,
3377 GLsizei count,
3378 GLboolean transpose,
3379 const GLfloat *value)
3380{
3381 return ValidateUniformMatrixES3(context, GL_FLOAT_MAT2x4, location, count, transpose);
3382}
3383
3384bool ValidateUniformMatrix4x2fv(Context *context,
3385 GLint location,
3386 GLsizei count,
3387 GLboolean transpose,
3388 const GLfloat *value)
3389{
3390 return ValidateUniformMatrixES3(context, GL_FLOAT_MAT4x2, location, count, transpose);
3391}
3392
3393bool ValidateUniformMatrix3x4fv(Context *context,
3394 GLint location,
3395 GLsizei count,
3396 GLboolean transpose,
3397 const GLfloat *value)
3398{
3399 return ValidateUniformMatrixES3(context, GL_FLOAT_MAT3x4, location, count, transpose);
3400}
3401
3402bool ValidateUniformMatrix4x3fv(Context *context,
3403 GLint location,
3404 GLsizei count,
3405 GLboolean transpose,
3406 const GLfloat *value)
3407{
3408 return ValidateUniformMatrixES3(context, GL_FLOAT_MAT4x3, location, count, transpose);
3409}
3410
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003411bool ValidateEndTransformFeedback(Context *context)
3412{
3413 if (context->getClientMajorVersion() < 3)
3414 {
Jamie Madill610640f2018-11-21 17:28:41 -05003415 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003416 return false;
3417 }
3418
3419 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
3420 ASSERT(transformFeedback != nullptr);
3421
3422 if (!transformFeedback->isActive())
3423 {
Jamie Madill610640f2018-11-21 17:28:41 -05003424 context->validationError(GL_INVALID_OPERATION, kErrorTransformFeedbackNotActive);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003425 return false;
3426 }
3427
3428 return true;
3429}
3430
3431bool ValidateTransformFeedbackVaryings(Context *context,
3432 GLuint program,
3433 GLsizei count,
3434 const GLchar *const *varyings,
3435 GLenum bufferMode)
3436{
3437 if (context->getClientMajorVersion() < 3)
3438 {
Jamie Madill610640f2018-11-21 17:28:41 -05003439 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003440 return false;
3441 }
3442
3443 if (count < 0)
3444 {
Jamie Madill610640f2018-11-21 17:28:41 -05003445 context->validationError(GL_INVALID_VALUE, kErrorNegativeCount);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003446 return false;
3447 }
3448
3449 switch (bufferMode)
3450 {
3451 case GL_INTERLEAVED_ATTRIBS:
3452 break;
3453 case GL_SEPARATE_ATTRIBS:
3454 {
3455 const Caps &caps = context->getCaps();
3456 if (static_cast<GLuint>(count) > caps.maxTransformFeedbackSeparateAttributes)
3457 {
Jamie Madill610640f2018-11-21 17:28:41 -05003458 context->validationError(GL_INVALID_VALUE,
3459 kErrorInvalidTransformFeedbackAttribsCount);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003460 return false;
3461 }
3462 break;
3463 }
3464 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003465 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003466 return false;
3467 }
3468
3469 Program *programObject = GetValidProgram(context, program);
3470 if (!programObject)
3471 {
3472 return false;
3473 }
3474
3475 return true;
3476}
3477
3478bool ValidateGetTransformFeedbackVarying(Context *context,
3479 GLuint program,
3480 GLuint index,
3481 GLsizei bufSize,
3482 GLsizei *length,
3483 GLsizei *size,
3484 GLenum *type,
3485 GLchar *name)
3486{
3487 if (context->getClientMajorVersion() < 3)
3488 {
Jamie Madill610640f2018-11-21 17:28:41 -05003489 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003490 return false;
3491 }
3492
3493 if (bufSize < 0)
3494 {
Jamie Madill610640f2018-11-21 17:28:41 -05003495 context->validationError(GL_INVALID_VALUE, kErrorNegativeBufferSize);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003496 return false;
3497 }
3498
3499 Program *programObject = GetValidProgram(context, program);
3500 if (!programObject)
3501 {
3502 return false;
3503 }
3504
3505 if (index >= static_cast<GLuint>(programObject->getTransformFeedbackVaryingCount()))
3506 {
Jamie Madill610640f2018-11-21 17:28:41 -05003507 context->validationError(GL_INVALID_VALUE, kErrorTransformFeedbackVaryingIndexOutOfRange);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003508 return false;
3509 }
3510
3511 return true;
3512}
3513
3514bool ValidateBindTransformFeedback(Context *context, GLenum target, GLuint id)
3515{
3516 if (context->getClientMajorVersion() < 3)
3517 {
Jamie Madill610640f2018-11-21 17:28:41 -05003518 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003519 return false;
3520 }
3521
3522 switch (target)
3523 {
3524 case GL_TRANSFORM_FEEDBACK:
3525 {
3526 // Cannot bind a transform feedback object if the current one is started and not
3527 // paused (3.0.2 pg 85 section 2.14.1)
3528 TransformFeedback *curTransformFeedback =
3529 context->getGLState().getCurrentTransformFeedback();
3530 if (curTransformFeedback && curTransformFeedback->isActive() &&
3531 !curTransformFeedback->isPaused())
3532 {
Jamie Madill610640f2018-11-21 17:28:41 -05003533 context->validationError(GL_INVALID_OPERATION, kErrorTransformFeedbackNotPaused);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003534 return false;
3535 }
3536
3537 // Cannot bind a transform feedback object that does not exist (3.0.2 pg 85 section
3538 // 2.14.1)
3539 if (!context->isTransformFeedbackGenerated(id))
3540 {
Jamie Madill610640f2018-11-21 17:28:41 -05003541 context->validationError(GL_INVALID_OPERATION, kErrorTransformFeedbackDoesNotExist);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003542 return false;
3543 }
3544 }
3545 break;
3546
3547 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003548 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003549 return false;
3550 }
3551
3552 return true;
3553}
3554
3555bool ValidateIsTransformFeedback(Context *context, GLuint id)
3556{
3557 if (context->getClientMajorVersion() < 3)
3558 {
Jamie Madill610640f2018-11-21 17:28:41 -05003559 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003560 return false;
3561 }
3562
3563 return true;
3564}
3565
3566bool ValidatePauseTransformFeedback(Context *context)
3567{
3568 if (context->getClientMajorVersion() < 3)
3569 {
Jamie Madill610640f2018-11-21 17:28:41 -05003570 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003571 return false;
3572 }
3573
3574 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
3575 ASSERT(transformFeedback != nullptr);
3576
3577 // Current transform feedback must be active and not paused in order to pause (3.0.2 pg 86)
Jamie Madill610640f2018-11-21 17:28:41 -05003578 if (!transformFeedback->isActive())
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003579 {
Jamie Madill610640f2018-11-21 17:28:41 -05003580 context->validationError(GL_INVALID_OPERATION, kErrorTransformFeedbackNotActive);
3581 return false;
3582 }
3583
3584 if (transformFeedback->isPaused())
3585 {
3586 context->validationError(GL_INVALID_OPERATION, kErrorTransformFeedbackPaused);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003587 return false;
3588 }
3589
3590 return true;
3591}
3592
3593bool ValidateResumeTransformFeedback(Context *context)
3594{
3595 if (context->getClientMajorVersion() < 3)
3596 {
Jamie Madill610640f2018-11-21 17:28:41 -05003597 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003598 return false;
3599 }
3600
3601 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
3602 ASSERT(transformFeedback != nullptr);
3603
3604 // Current transform feedback must be active and paused in order to resume (3.0.2 pg 86)
Jamie Madill610640f2018-11-21 17:28:41 -05003605 if (!transformFeedback->isActive())
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003606 {
Jamie Madill610640f2018-11-21 17:28:41 -05003607 context->validationError(GL_INVALID_OPERATION, kErrorTransformFeedbackNotActive);
3608 return false;
3609 }
3610
3611 if (!transformFeedback->isPaused())
3612 {
3613 context->validationError(GL_INVALID_OPERATION, kErrorTransformFeedbackNotPaused);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003614 return false;
3615 }
3616
3617 return true;
3618}
3619
Jamie Madill12e957f2017-08-26 21:42:26 -04003620bool ValidateVertexAttribI4i(Context *context, GLuint index, GLint x, GLint y, GLint z, GLint w)
3621{
3622 if (context->getClientMajorVersion() < 3)
3623 {
Jamie Madill610640f2018-11-21 17:28:41 -05003624 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003625 return false;
3626 }
3627
3628 return ValidateVertexAttribIndex(context, index);
3629}
3630
3631bool ValidateVertexAttribI4ui(Context *context,
3632 GLuint index,
3633 GLuint x,
3634 GLuint y,
3635 GLuint z,
3636 GLuint w)
3637{
3638 if (context->getClientMajorVersion() < 3)
3639 {
Jamie Madill610640f2018-11-21 17:28:41 -05003640 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003641 return false;
3642 }
3643
3644 return ValidateVertexAttribIndex(context, index);
3645}
3646
3647bool ValidateVertexAttribI4iv(Context *context, GLuint index, const GLint *v)
3648{
3649 if (context->getClientMajorVersion() < 3)
3650 {
Jamie Madill610640f2018-11-21 17:28:41 -05003651 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003652 return false;
3653 }
3654
3655 return ValidateVertexAttribIndex(context, index);
3656}
3657
3658bool ValidateVertexAttribI4uiv(Context *context, GLuint index, const GLuint *v)
3659{
3660 if (context->getClientMajorVersion() < 3)
3661 {
Jamie Madill610640f2018-11-21 17:28:41 -05003662 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003663 return false;
3664 }
3665
3666 return ValidateVertexAttribIndex(context, index);
3667}
3668
3669bool ValidateGetFragDataLocation(Context *context, GLuint program, const GLchar *name)
3670{
3671 if (context->getClientMajorVersion() < 3)
3672 {
Jamie Madill610640f2018-11-21 17:28:41 -05003673 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003674 return false;
3675 }
3676
3677 Program *programObject = GetValidProgram(context, program);
3678 if (!programObject)
3679 {
3680 return false;
3681 }
3682
3683 if (!programObject->isLinked())
3684 {
Jamie Madill610640f2018-11-21 17:28:41 -05003685 context->validationError(GL_INVALID_OPERATION, kErrorProgramNotLinked);
Jamie Madill12e957f2017-08-26 21:42:26 -04003686 return false;
3687 }
3688
3689 return true;
3690}
3691
3692bool ValidateGetUniformIndices(Context *context,
3693 GLuint program,
3694 GLsizei uniformCount,
3695 const GLchar *const *uniformNames,
3696 GLuint *uniformIndices)
3697{
3698 if (context->getClientMajorVersion() < 3)
3699 {
Jamie Madill610640f2018-11-21 17:28:41 -05003700 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003701 return false;
3702 }
3703
3704 if (uniformCount < 0)
3705 {
Jamie Madill610640f2018-11-21 17:28:41 -05003706 context->validationError(GL_INVALID_VALUE, kErrorNegativeCount);
Jamie Madill12e957f2017-08-26 21:42:26 -04003707 return false;
3708 }
3709
3710 Program *programObject = GetValidProgram(context, program);
3711 if (!programObject)
3712 {
3713 return false;
3714 }
3715
3716 return true;
3717}
3718
3719bool ValidateGetActiveUniformsiv(Context *context,
3720 GLuint program,
3721 GLsizei uniformCount,
3722 const GLuint *uniformIndices,
3723 GLenum pname,
3724 GLint *params)
3725{
3726 if (context->getClientMajorVersion() < 3)
3727 {
Jamie Madill610640f2018-11-21 17:28:41 -05003728 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003729 return false;
3730 }
3731
3732 if (uniformCount < 0)
3733 {
Jamie Madill610640f2018-11-21 17:28:41 -05003734 context->validationError(GL_INVALID_VALUE, kErrorNegativeCount);
Jamie Madill12e957f2017-08-26 21:42:26 -04003735 return false;
3736 }
3737
3738 Program *programObject = GetValidProgram(context, program);
3739 if (!programObject)
3740 {
3741 return false;
3742 }
3743
3744 switch (pname)
3745 {
3746 case GL_UNIFORM_TYPE:
3747 case GL_UNIFORM_SIZE:
Bryan Bernhart22f7aaf2018-08-23 14:13:51 -07003748 break;
Jamie Madill12e957f2017-08-26 21:42:26 -04003749 case GL_UNIFORM_NAME_LENGTH:
Bryan Bernhart22f7aaf2018-08-23 14:13:51 -07003750 if (context->getExtensions().webglCompatibility)
3751 {
Jamie Madill610640f2018-11-21 17:28:41 -05003752 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Bryan Bernhart22f7aaf2018-08-23 14:13:51 -07003753 return false;
3754 }
3755 break;
Jamie Madill12e957f2017-08-26 21:42:26 -04003756 case GL_UNIFORM_BLOCK_INDEX:
3757 case GL_UNIFORM_OFFSET:
3758 case GL_UNIFORM_ARRAY_STRIDE:
3759 case GL_UNIFORM_MATRIX_STRIDE:
3760 case GL_UNIFORM_IS_ROW_MAJOR:
3761 break;
3762
3763 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003764 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madill12e957f2017-08-26 21:42:26 -04003765 return false;
3766 }
3767
3768 if (uniformCount > programObject->getActiveUniformCount())
3769 {
Jamie Madill610640f2018-11-21 17:28:41 -05003770 context->validationError(GL_INVALID_VALUE, kErrorIndexExceedsMaxActiveUniform);
Jamie Madill12e957f2017-08-26 21:42:26 -04003771 return false;
3772 }
3773
3774 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
3775 {
3776 const GLuint index = uniformIndices[uniformId];
3777
3778 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
3779 {
Jamie Madill610640f2018-11-21 17:28:41 -05003780 context->validationError(GL_INVALID_VALUE, kErrorIndexExceedsMaxActiveUniform);
Jamie Madill12e957f2017-08-26 21:42:26 -04003781 return false;
3782 }
3783 }
3784
3785 return true;
3786}
3787
3788bool ValidateGetUniformBlockIndex(Context *context, GLuint program, const GLchar *uniformBlockName)
3789{
3790 if (context->getClientMajorVersion() < 3)
3791 {
Jamie Madill610640f2018-11-21 17:28:41 -05003792 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003793 return false;
3794 }
3795
3796 Program *programObject = GetValidProgram(context, program);
3797 if (!programObject)
3798 {
3799 return false;
3800 }
3801
3802 return true;
3803}
3804
3805bool ValidateGetActiveUniformBlockiv(Context *context,
3806 GLuint program,
3807 GLuint uniformBlockIndex,
3808 GLenum pname,
3809 GLint *params)
3810{
3811 return ValidateGetActiveUniformBlockivBase(context, program, uniformBlockIndex, pname, nullptr);
3812}
3813
3814bool ValidateGetActiveUniformBlockName(Context *context,
3815 GLuint program,
3816 GLuint uniformBlockIndex,
3817 GLsizei bufSize,
3818 GLsizei *length,
3819 GLchar *uniformBlockName)
3820{
3821 if (context->getClientMajorVersion() < 3)
3822 {
Jamie Madill610640f2018-11-21 17:28:41 -05003823 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003824 return false;
3825 }
3826
3827 Program *programObject = GetValidProgram(context, program);
3828 if (!programObject)
3829 {
3830 return false;
3831 }
3832
3833 if (uniformBlockIndex >= programObject->getActiveUniformBlockCount())
3834 {
Jamie Madill610640f2018-11-21 17:28:41 -05003835 context->validationError(GL_INVALID_VALUE, kErrorIndexExceedsMaxActiveUniformBlock);
Jamie Madill12e957f2017-08-26 21:42:26 -04003836 return false;
3837 }
3838
3839 return true;
3840}
3841
3842bool ValidateUniformBlockBinding(Context *context,
3843 GLuint program,
3844 GLuint uniformBlockIndex,
3845 GLuint uniformBlockBinding)
3846{
3847 if (context->getClientMajorVersion() < 3)
3848 {
Jamie Madill610640f2018-11-21 17:28:41 -05003849 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003850 return false;
3851 }
3852
3853 if (uniformBlockBinding >= context->getCaps().maxUniformBufferBindings)
3854 {
Jamie Madill610640f2018-11-21 17:28:41 -05003855 context->validationError(GL_INVALID_VALUE, kErrorIndexExceedsMaxUniformBufferBindings);
Jamie Madill12e957f2017-08-26 21:42:26 -04003856 return false;
3857 }
3858
3859 Program *programObject = GetValidProgram(context, program);
3860 if (!programObject)
3861 {
3862 return false;
3863 }
3864
3865 // if never linked, there won't be any uniform blocks
3866 if (uniformBlockIndex >= programObject->getActiveUniformBlockCount())
3867 {
Jamie Madill610640f2018-11-21 17:28:41 -05003868 context->validationError(GL_INVALID_VALUE, kErrorIndexExceedsMaxUniformBufferBindings);
Jamie Madill12e957f2017-08-26 21:42:26 -04003869 return false;
3870 }
3871
3872 return true;
3873}
3874
3875bool ValidateDrawArraysInstanced(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04003876 PrimitiveMode mode,
Jamie Madill12e957f2017-08-26 21:42:26 -04003877 GLint first,
3878 GLsizei count,
3879 GLsizei primcount)
3880{
3881 if (context->getClientMajorVersion() < 3)
3882 {
Jamie Madill610640f2018-11-21 17:28:41 -05003883 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003884 return false;
3885 }
3886
3887 return ValidateDrawArraysInstancedBase(context, mode, first, count, primcount);
3888}
3889
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003890bool ValidateFenceSync(Context *context, GLenum condition, GLbitfield flags)
3891{
3892 if (context->getClientMajorVersion() < 3)
3893 {
Jamie Madill610640f2018-11-21 17:28:41 -05003894 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003895 return false;
3896 }
3897
3898 if (condition != GL_SYNC_GPU_COMMANDS_COMPLETE)
3899 {
Jamie Madill610640f2018-11-21 17:28:41 -05003900 context->validationError(GL_INVALID_ENUM, kErrorInvalidFenceCondition);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003901 return false;
3902 }
3903
3904 if (flags != 0)
3905 {
Jamie Madill610640f2018-11-21 17:28:41 -05003906 context->validationError(GL_INVALID_VALUE, kErrorInvalidFlags);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003907 return false;
3908 }
3909
3910 return true;
3911}
3912
3913bool ValidateIsSync(Context *context, GLsync sync)
3914{
3915 if (context->getClientMajorVersion() < 3)
3916 {
Jamie Madill610640f2018-11-21 17:28:41 -05003917 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003918 return false;
3919 }
3920
3921 return true;
3922}
3923
3924bool ValidateDeleteSync(Context *context, GLsync sync)
3925{
3926 if (context->getClientMajorVersion() < 3)
3927 {
Jamie Madill610640f2018-11-21 17:28:41 -05003928 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003929 return false;
3930 }
3931
Jamie Madill70b5bb02017-08-28 13:32:37 -04003932 if (sync != static_cast<GLsync>(0) && !context->getSync(sync))
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003933 {
Jamie Madill610640f2018-11-21 17:28:41 -05003934 context->validationError(GL_INVALID_VALUE, kErrorSyncMissing);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003935 return false;
3936 }
3937
3938 return true;
3939}
3940
3941bool ValidateClientWaitSync(Context *context, GLsync sync, GLbitfield flags, GLuint64 timeout)
3942{
3943 if (context->getClientMajorVersion() < 3)
3944 {
Jamie Madill610640f2018-11-21 17:28:41 -05003945 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003946 return false;
3947 }
3948
3949 if ((flags & ~(GL_SYNC_FLUSH_COMMANDS_BIT)) != 0)
3950 {
Jamie Madill610640f2018-11-21 17:28:41 -05003951 context->validationError(GL_INVALID_VALUE, kErrorInvalidFlags);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003952 return false;
3953 }
3954
Jamie Madill70b5bb02017-08-28 13:32:37 -04003955 Sync *clientWaitSync = context->getSync(sync);
3956 if (!clientWaitSync)
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003957 {
Jamie Madill610640f2018-11-21 17:28:41 -05003958 context->validationError(GL_INVALID_VALUE, kErrorSyncMissing);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003959 return false;
3960 }
3961
3962 return true;
3963}
3964
3965bool ValidateWaitSync(Context *context, GLsync sync, GLbitfield flags, GLuint64 timeout)
3966{
3967 if (context->getClientMajorVersion() < 3)
3968 {
Jamie Madill610640f2018-11-21 17:28:41 -05003969 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003970 return false;
3971 }
3972
3973 if (flags != 0)
3974 {
Jamie Madill610640f2018-11-21 17:28:41 -05003975 context->validationError(GL_INVALID_VALUE, kErrorInvalidFlags);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003976 return false;
3977 }
3978
3979 if (timeout != GL_TIMEOUT_IGNORED)
3980 {
Jamie Madill610640f2018-11-21 17:28:41 -05003981 context->validationError(GL_INVALID_VALUE, kErrorInvalidTimeout);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003982 return false;
3983 }
3984
Jamie Madill70b5bb02017-08-28 13:32:37 -04003985 Sync *waitSync = context->getSync(sync);
3986 if (!waitSync)
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003987 {
Jamie Madill610640f2018-11-21 17:28:41 -05003988 context->validationError(GL_INVALID_VALUE, kErrorSyncMissing);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003989 return false;
3990 }
3991
3992 return true;
3993}
3994
3995bool ValidateGetInteger64v(Context *context, GLenum pname, GLint64 *params)
3996{
3997 if (context->getClientMajorVersion() < 3)
3998 {
Jamie Madill610640f2018-11-21 17:28:41 -05003999 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04004000 return false;
4001 }
4002
4003 GLenum nativeType = GL_NONE;
4004 unsigned int numParams = 0;
4005 if (!ValidateStateQuery(context, pname, &nativeType, &numParams))
4006 {
4007 return false;
4008 }
4009
4010 return true;
4011}
4012
Jamie Madill3ef140a2017-08-26 23:11:21 -04004013bool ValidateIsSampler(Context *context, GLuint sampler)
4014{
4015 if (context->getClientMajorVersion() < 3)
4016 {
Jamie Madill610640f2018-11-21 17:28:41 -05004017 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill3ef140a2017-08-26 23:11:21 -04004018 return false;
4019 }
4020
4021 return true;
4022}
4023
4024bool ValidateBindSampler(Context *context, GLuint unit, GLuint sampler)
4025{
4026 if (context->getClientMajorVersion() < 3)
4027 {
Jamie Madill610640f2018-11-21 17:28:41 -05004028 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill3ef140a2017-08-26 23:11:21 -04004029 return false;
4030 }
4031
4032 if (sampler != 0 && !context->isSampler(sampler))
4033 {
Jamie Madill610640f2018-11-21 17:28:41 -05004034 context->validationError(GL_INVALID_OPERATION, kErrorInvalidSampler);
Jamie Madill3ef140a2017-08-26 23:11:21 -04004035 return false;
4036 }
4037
4038 if (unit >= context->getCaps().maxCombinedTextureImageUnits)
4039 {
Jamie Madill610640f2018-11-21 17:28:41 -05004040 context->validationError(GL_INVALID_VALUE, kErrorInvalidCombinedImageUnit);
Jamie Madill3ef140a2017-08-26 23:11:21 -04004041 return false;
4042 }
4043
4044 return true;
4045}
4046
4047bool ValidateVertexAttribDivisor(Context *context, GLuint index, GLuint divisor)
4048{
4049 if (context->getClientMajorVersion() < 3)
4050 {
Jamie Madill610640f2018-11-21 17:28:41 -05004051 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill3ef140a2017-08-26 23:11:21 -04004052 return false;
4053 }
4054
4055 return ValidateVertexAttribIndex(context, index);
4056}
4057
4058bool ValidateTexStorage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004059 TextureType target,
Jamie Madill3ef140a2017-08-26 23:11:21 -04004060 GLsizei levels,
4061 GLenum internalformat,
4062 GLsizei width,
4063 GLsizei height)
4064{
4065 if (context->getClientMajorVersion() < 3)
4066 {
Jamie Madill610640f2018-11-21 17:28:41 -05004067 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill3ef140a2017-08-26 23:11:21 -04004068 return false;
4069 }
4070
4071 if (!ValidateES3TexStorage2DParameters(context, target, levels, internalformat, width, height,
4072 1))
4073 {
4074 return false;
4075 }
4076
4077 return true;
4078}
4079
4080bool ValidateTexStorage3D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004081 TextureType target,
Jamie Madill3ef140a2017-08-26 23:11:21 -04004082 GLsizei levels,
4083 GLenum internalformat,
4084 GLsizei width,
4085 GLsizei height,
4086 GLsizei depth)
4087{
4088 if (context->getClientMajorVersion() < 3)
4089 {
Jamie Madill610640f2018-11-21 17:28:41 -05004090 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill3ef140a2017-08-26 23:11:21 -04004091 return false;
4092 }
4093
4094 if (!ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
4095 depth))
4096 {
4097 return false;
4098 }
4099
4100 return true;
4101}
4102
Jamie Madill5b772312018-03-08 20:28:32 -05004103bool ValidateGetBufferParameteri64v(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004104 BufferBinding target,
Jamie Madill9696d072017-08-26 23:19:57 -04004105 GLenum pname,
4106 GLint64 *params)
4107{
4108 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
4109}
4110
4111bool ValidateGetSamplerParameterfv(Context *context, GLuint sampler, GLenum pname, GLfloat *params)
4112{
4113 return ValidateGetSamplerParameterBase(context, sampler, pname, nullptr);
4114}
4115
4116bool ValidateGetSamplerParameteriv(Context *context, GLuint sampler, GLenum pname, GLint *params)
4117{
4118 return ValidateGetSamplerParameterBase(context, sampler, pname, nullptr);
4119}
4120
Till Rathmannb8543632018-10-02 19:46:14 +02004121bool ValidateGetSamplerParameterIivOES(Context *context,
4122 GLuint sampler,
4123 GLenum pname,
Jamie Madill778bf092018-11-14 09:54:36 -05004124 GLint *params)
Till Rathmannb8543632018-10-02 19:46:14 +02004125{
4126 if (context->getClientMajorVersion() < 3)
4127 {
Jamie Madill610640f2018-11-21 17:28:41 -05004128 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02004129 return false;
4130 }
4131 return ValidateGetSamplerParameterBase(context, sampler, pname, nullptr);
4132}
4133
4134bool ValidateGetSamplerParameterIuivOES(Context *context,
4135 GLuint sampler,
4136 GLenum pname,
Jamie Madill778bf092018-11-14 09:54:36 -05004137 GLuint *params)
Till Rathmannb8543632018-10-02 19:46:14 +02004138{
4139 if (context->getClientMajorVersion() < 3)
4140 {
Jamie Madill610640f2018-11-21 17:28:41 -05004141 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02004142 return false;
4143 }
4144 return ValidateGetSamplerParameterBase(context, sampler, pname, nullptr);
4145}
4146
Jamie Madill9696d072017-08-26 23:19:57 -04004147bool ValidateSamplerParameterf(Context *context, GLuint sampler, GLenum pname, GLfloat param)
4148{
Till Rathmannb8543632018-10-02 19:46:14 +02004149 return ValidateSamplerParameterBase(context, sampler, pname, -1, false, &param);
Jamie Madill9696d072017-08-26 23:19:57 -04004150}
4151
4152bool ValidateSamplerParameterfv(Context *context,
4153 GLuint sampler,
4154 GLenum pname,
4155 const GLfloat *params)
4156{
Till Rathmannb8543632018-10-02 19:46:14 +02004157 return ValidateSamplerParameterBase(context, sampler, pname, -1, true, params);
Jamie Madill9696d072017-08-26 23:19:57 -04004158}
4159
4160bool ValidateSamplerParameteri(Context *context, GLuint sampler, GLenum pname, GLint param)
4161{
Till Rathmannb8543632018-10-02 19:46:14 +02004162 return ValidateSamplerParameterBase(context, sampler, pname, -1, false, &param);
Jamie Madill9696d072017-08-26 23:19:57 -04004163}
4164
4165bool ValidateSamplerParameteriv(Context *context, GLuint sampler, GLenum pname, const GLint *params)
4166{
Till Rathmannb8543632018-10-02 19:46:14 +02004167 return ValidateSamplerParameterBase(context, sampler, pname, -1, true, params);
4168}
4169
4170bool ValidateSamplerParameterIivOES(Context *context,
4171 GLuint sampler,
4172 GLenum pname,
4173 const GLint *params)
4174{
4175 if (context->getClientMajorVersion() < 3)
4176 {
Jamie Madill610640f2018-11-21 17:28:41 -05004177 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02004178 return false;
4179 }
4180 return ValidateSamplerParameterBase(context, sampler, pname, -1, true, params);
4181}
4182
4183bool ValidateSamplerParameterIuivOES(Context *context,
4184 GLuint sampler,
4185 GLenum pname,
4186 const GLuint *params)
4187{
4188 if (context->getClientMajorVersion() < 3)
4189 {
Jamie Madill610640f2018-11-21 17:28:41 -05004190 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02004191 return false;
4192 }
4193 return ValidateSamplerParameterBase(context, sampler, pname, -1, true, params);
Jamie Madill9696d072017-08-26 23:19:57 -04004194}
4195
4196bool ValidateGetVertexAttribIiv(Context *context, GLuint index, GLenum pname, GLint *params)
4197{
4198 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, true);
4199}
4200
4201bool ValidateGetVertexAttribIuiv(Context *context, GLuint index, GLenum pname, GLuint *params)
4202{
4203 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, true);
4204}
4205
4206bool ValidateGetInternalformativ(Context *context,
4207 GLenum target,
4208 GLenum internalformat,
4209 GLenum pname,
4210 GLsizei bufSize,
4211 GLint *params)
4212{
4213 return ValidateGetInternalFormativBase(context, target, internalformat, pname, bufSize,
4214 nullptr);
4215}
4216
Olli Etuaho0ca09752018-09-24 11:00:50 +03004217bool ValidateBindFragDataLocationIndexedEXT(Context *context,
4218 GLuint program,
4219 GLuint colorNumber,
4220 GLuint index,
4221 const char *name)
4222{
4223 if (!context->getExtensions().blendFuncExtended)
4224 {
Jamie Madill610640f2018-11-21 17:28:41 -05004225 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Olli Etuaho0ca09752018-09-24 11:00:50 +03004226 return false;
4227 }
4228 if (context->getClientMajorVersion() < 3)
4229 {
Jamie Madill610640f2018-11-21 17:28:41 -05004230 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Olli Etuaho0ca09752018-09-24 11:00:50 +03004231 return false;
4232 }
4233 if (index < 0 || index > 1)
4234 {
4235 // This error is not explicitly specified but the spec does say that "<index> may be zero or
4236 // one to specify that the color be used as either the first or second color input to the
4237 // blend equation, respectively"
Jamie Madill610640f2018-11-21 17:28:41 -05004238 context->validationError(GL_INVALID_VALUE, kErrorFragDataBindingIndexOutOfRange);
Olli Etuaho0ca09752018-09-24 11:00:50 +03004239 return false;
4240 }
4241 if (index == 1)
4242 {
4243 if (colorNumber >= context->getExtensions().maxDualSourceDrawBuffers)
4244 {
Jamie Madill610640f2018-11-21 17:28:41 -05004245 context->validationError(GL_INVALID_VALUE,
4246 kErrorColorNumberGreaterThanMaxDualSourceDrawBuffers);
Olli Etuaho0ca09752018-09-24 11:00:50 +03004247 return false;
4248 }
4249 }
4250 else
4251 {
4252 if (colorNumber >= context->getCaps().maxDrawBuffers)
4253 {
Jamie Madill610640f2018-11-21 17:28:41 -05004254 context->validationError(GL_INVALID_VALUE, kErrorColorNumberGreaterThanMaxDrawBuffers);
Olli Etuaho0ca09752018-09-24 11:00:50 +03004255 return false;
4256 }
4257 }
4258 Program *programObject = GetValidProgram(context, program);
4259 if (!programObject)
4260 {
4261 return false;
4262 }
4263 return true;
4264}
4265
4266bool ValidateBindFragDataLocationEXT(Context *context,
4267 GLuint program,
4268 GLuint colorNumber,
4269 const char *name)
4270{
4271 return ValidateBindFragDataLocationIndexedEXT(context, program, colorNumber, 0u, name);
4272}
4273
4274bool ValidateGetFragDataIndexEXT(Context *context, GLuint program, const char *name)
4275{
4276 if (!context->getExtensions().blendFuncExtended)
4277 {
Jamie Madill610640f2018-11-21 17:28:41 -05004278 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Olli Etuaho0ca09752018-09-24 11:00:50 +03004279 return false;
4280 }
4281 if (context->getClientMajorVersion() < 3)
4282 {
Jamie Madill610640f2018-11-21 17:28:41 -05004283 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Olli Etuaho0ca09752018-09-24 11:00:50 +03004284 return false;
4285 }
4286 Program *programObject = GetValidProgram(context, program);
4287 if (!programObject)
4288 {
4289 return false;
4290 }
4291 if (!programObject->isLinked())
4292 {
Jamie Madill610640f2018-11-21 17:28:41 -05004293 context->validationError(GL_INVALID_OPERATION, kErrorProgramNotLinked);
Olli Etuaho0ca09752018-09-24 11:00:50 +03004294 return false;
4295 }
4296 return true;
4297}
4298
Yizhou Jiang7818a852018-09-06 15:02:04 +08004299bool ValidateTexStorage2DMultisampleANGLE(Context *context,
4300 TextureType target,
4301 GLsizei samples,
Jamie Madill778bf092018-11-14 09:54:36 -05004302 GLenum internalFormat,
Yizhou Jiang7818a852018-09-06 15:02:04 +08004303 GLsizei width,
4304 GLsizei height,
4305 GLboolean fixedSampleLocations)
4306{
4307 if (!context->getExtensions().textureMultisample)
4308 {
Jamie Madill610640f2018-11-21 17:28:41 -05004309 context->validationError(GL_INVALID_OPERATION,
4310 kErrorMultisampleTextureExtensionOrES31Required);
Yizhou Jiang7818a852018-09-06 15:02:04 +08004311 return false;
4312 }
4313
4314 return ValidateTexStorage2DMultisampleBase(context, target, samples, internalFormat, width,
4315 height);
4316}
4317
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08004318bool ValidateGetTexLevelParameterfvANGLE(Context *context,
4319 TextureTarget target,
4320 GLint level,
4321 GLenum pname,
4322 GLfloat *params)
4323{
4324 if (!context->getExtensions().textureMultisample)
4325 {
Jamie Madill610640f2018-11-21 17:28:41 -05004326 context->validationError(GL_INVALID_OPERATION,
4327 kErrorMultisampleTextureExtensionOrES31Required);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08004328 return false;
4329 }
4330
4331 return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr);
4332}
4333
4334bool ValidateGetTexLevelParameterivANGLE(Context *context,
4335 TextureTarget target,
4336 GLint level,
4337 GLenum pname,
4338 GLint *params)
4339{
4340 if (!context->getExtensions().textureMultisample)
4341 {
Jamie Madill610640f2018-11-21 17:28:41 -05004342 context->validationError(GL_INVALID_OPERATION,
4343 kErrorMultisampleTextureExtensionOrES31Required);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08004344 return false;
4345 }
4346
4347 return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr);
4348}
4349
Jamie Madillc29968b2016-01-20 11:17:23 -05004350} // namespace gl