blob: a038c994d6d7af41a0440ff52e0bf9e4cb5aa682 [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);
James Darpinian471b8d42018-11-21 15:37:47 -08002475 if (buffer.get())
Geoff Lang79f71042017-08-14 16:43:43 -04002476 {
James Darpinian471b8d42018-11-21 15:37:47 -08002477 if (buffer->isMapped())
2478 {
2479 context->validationError(GL_INVALID_OPERATION,
2480 "Transform feedback has a mapped buffer.");
2481 return false;
2482 }
2483 if ((context->getLimitations().noDoubleBoundTransformFeedbackBuffers ||
2484 context->getExtensions().webglCompatibility) &&
2485 buffer->isDoubleBoundForTransformFeedback())
2486 {
2487 context->validationError(GL_INVALID_OPERATION,
2488 kErrorDoubleBoundTransformFeedbackBuffer);
2489 return false;
2490 }
Geoff Lang79f71042017-08-14 16:43:43 -04002491 }
2492 }
2493
Jamie Madill785e8a02018-10-04 17:42:00 -04002494 Program *program = context->getGLState().getLinkedProgram(context);
Olli Etuaho02032bd2017-10-13 18:10:17 +03002495
2496 if (!program)
2497 {
Jamie Madill610640f2018-11-21 17:28:41 -05002498 context->validationError(GL_INVALID_OPERATION, kErrorProgramNotBound);
Olli Etuaho02032bd2017-10-13 18:10:17 +03002499 return false;
2500 }
2501
2502 if (program->getTransformFeedbackVaryingCount() == 0)
2503 {
Jamie Madill610640f2018-11-21 17:28:41 -05002504 context->validationError(GL_INVALID_OPERATION, kErrorNoTransformFeedbackOutputVariables);
Olli Etuaho02032bd2017-10-13 18:10:17 +03002505 return false;
2506 }
2507
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002508 return true;
2509}
2510
Corentin Wallez336129f2017-10-17 15:55:40 -04002511bool ValidateGetBufferPointerv(Context *context, BufferBinding target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002512{
Geoff Lang496c02d2016-10-20 11:38:11 -07002513 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
2514}
2515
2516bool ValidateGetBufferPointervRobustANGLE(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002517 BufferBinding target,
Geoff Lang496c02d2016-10-20 11:38:11 -07002518 GLenum pname,
2519 GLsizei bufSize,
2520 GLsizei *length,
Jamie Madill876429b2017-04-20 15:46:24 -04002521 void **params)
Geoff Lang496c02d2016-10-20 11:38:11 -07002522{
2523 if (!ValidateRobustEntryPoint(context, bufSize))
Olli Etuaho4f667482016-03-30 15:56:35 +03002524 {
Olli Etuaho4f667482016-03-30 15:56:35 +03002525 return false;
2526 }
2527
Brandon Jonesd1049182018-03-28 10:02:20 -07002528 GLsizei numParams = 0;
2529
2530 if (!ValidateGetBufferPointervBase(context, target, pname, &numParams, params))
Geoff Lang496c02d2016-10-20 11:38:11 -07002531 {
2532 return false;
2533 }
2534
Brandon Jonesd1049182018-03-28 10:02:20 -07002535 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang496c02d2016-10-20 11:38:11 -07002536 {
2537 return false;
2538 }
2539
Brandon Jonesd1049182018-03-28 10:02:20 -07002540 SetRobustLengthParam(length, numParams);
2541
Geoff Lang496c02d2016-10-20 11:38:11 -07002542 return true;
Olli Etuaho4f667482016-03-30 15:56:35 +03002543}
2544
Corentin Wallez336129f2017-10-17 15:55:40 -04002545bool ValidateUnmapBuffer(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03002546{
Martin Radev1be913c2016-07-11 17:59:16 +03002547 if (context->getClientMajorVersion() < 3)
Olli Etuaho4f667482016-03-30 15:56:35 +03002548 {
Jamie Madill610640f2018-11-21 17:28:41 -05002549 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Olli Etuaho4f667482016-03-30 15:56:35 +03002550 return false;
2551 }
2552
2553 return ValidateUnmapBufferBase(context, target);
2554}
2555
2556bool ValidateMapBufferRange(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002557 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002558 GLintptr offset,
2559 GLsizeiptr length,
2560 GLbitfield access)
2561{
Martin Radev1be913c2016-07-11 17:59:16 +03002562 if (context->getClientMajorVersion() < 3)
Olli Etuaho4f667482016-03-30 15:56:35 +03002563 {
Jamie Madill610640f2018-11-21 17:28:41 -05002564 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Olli Etuaho4f667482016-03-30 15:56:35 +03002565 return false;
2566 }
2567
2568 return ValidateMapBufferRangeBase(context, target, offset, length, access);
2569}
2570
2571bool ValidateFlushMappedBufferRange(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002572 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002573 GLintptr offset,
2574 GLsizeiptr length)
2575{
Martin Radev1be913c2016-07-11 17:59:16 +03002576 if (context->getClientMajorVersion() < 3)
Olli Etuaho4f667482016-03-30 15:56:35 +03002577 {
Jamie Madill610640f2018-11-21 17:28:41 -05002578 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Olli Etuaho4f667482016-03-30 15:56:35 +03002579 return false;
2580 }
2581
2582 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
2583}
2584
Jamie Madill5b772312018-03-08 20:28:32 -05002585bool ValidateIndexedStateQuery(Context *context, GLenum pname, GLuint index, GLsizei *length)
Martin Radev66fb8202016-07-28 11:45:20 +03002586{
Geoff Lang2e43dbb2016-10-14 12:27:35 -04002587 if (length)
2588 {
2589 *length = 0;
2590 }
2591
Martin Radev66fb8202016-07-28 11:45:20 +03002592 GLenum nativeType;
2593 unsigned int numParams;
2594 if (!context->getIndexedQueryParameterInfo(pname, &nativeType, &numParams))
2595 {
Jamie Madill610640f2018-11-21 17:28:41 -05002596 context->validationError(GL_INVALID_ENUM, kErrorInvalidPname);
Martin Radev66fb8202016-07-28 11:45:20 +03002597 return false;
2598 }
2599
2600 const Caps &caps = context->getCaps();
2601 switch (pname)
2602 {
2603 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
2604 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
2605 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
2606 if (index >= caps.maxTransformFeedbackSeparateAttributes)
2607 {
Jamie Madill610640f2018-11-21 17:28:41 -05002608 context->validationError(GL_INVALID_VALUE,
2609 kErrorIndexExceedsMaxTransformFeedbackAttribs);
Martin Radev66fb8202016-07-28 11:45:20 +03002610 return false;
2611 }
2612 break;
2613
2614 case GL_UNIFORM_BUFFER_START:
2615 case GL_UNIFORM_BUFFER_SIZE:
2616 case GL_UNIFORM_BUFFER_BINDING:
2617 if (index >= caps.maxUniformBufferBindings)
2618 {
Jamie Madill610640f2018-11-21 17:28:41 -05002619 context->validationError(GL_INVALID_VALUE,
2620 kErrorIndexExceedsMaxUniformBufferBindings);
Martin Radev66fb8202016-07-28 11:45:20 +03002621 return false;
2622 }
2623 break;
Shao80957d92017-02-20 21:25:59 +08002624
Martin Radev66fb8202016-07-28 11:45:20 +03002625 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
2626 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
2627 if (index >= 3u)
2628 {
Jamie Madill610640f2018-11-21 17:28:41 -05002629 context->validationError(GL_INVALID_VALUE,
2630 kErrorIndexExceedsMaxWorkgroupDimensions);
Martin Radev66fb8202016-07-28 11:45:20 +03002631 return false;
2632 }
2633 break;
Shao80957d92017-02-20 21:25:59 +08002634
Jiajia Qin6eafb042016-12-27 17:04:07 +08002635 case GL_ATOMIC_COUNTER_BUFFER_START:
2636 case GL_ATOMIC_COUNTER_BUFFER_SIZE:
2637 case GL_ATOMIC_COUNTER_BUFFER_BINDING:
2638 if (context->getClientVersion() < ES_3_1)
2639 {
Jamie Madill610640f2018-11-21 17:28:41 -05002640 context->validationError(GL_INVALID_ENUM, kErrorEnumRequiresGLES31);
Jiajia Qin6eafb042016-12-27 17:04:07 +08002641 return false;
2642 }
2643 if (index >= caps.maxAtomicCounterBufferBindings)
2644 {
Jamie Madill610640f2018-11-21 17:28:41 -05002645 context->validationError(GL_INVALID_VALUE,
2646 kErrorIndexExceedsMaxAtomicCounterBufferBindings);
Jiajia Qin6eafb042016-12-27 17:04:07 +08002647 return false;
2648 }
2649 break;
Shao80957d92017-02-20 21:25:59 +08002650
Jiajia Qinf546e7d2017-03-27 14:12:59 +08002651 case GL_SHADER_STORAGE_BUFFER_START:
2652 case GL_SHADER_STORAGE_BUFFER_SIZE:
2653 case GL_SHADER_STORAGE_BUFFER_BINDING:
2654 if (context->getClientVersion() < ES_3_1)
2655 {
Jamie Madill610640f2018-11-21 17:28:41 -05002656 context->validationError(GL_INVALID_ENUM, kErrorEnumRequiresGLES31);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08002657 return false;
2658 }
2659 if (index >= caps.maxShaderStorageBufferBindings)
2660 {
Jamie Madill610640f2018-11-21 17:28:41 -05002661 context->validationError(
2662 GL_INVALID_VALUE,
2663 "index is outside the valid range for GL_SHADER_STORAGE_BUFFER_BINDING");
Jiajia Qinf546e7d2017-03-27 14:12:59 +08002664 return false;
2665 }
2666 break;
2667
Shao80957d92017-02-20 21:25:59 +08002668 case GL_VERTEX_BINDING_BUFFER:
2669 case GL_VERTEX_BINDING_DIVISOR:
2670 case GL_VERTEX_BINDING_OFFSET:
2671 case GL_VERTEX_BINDING_STRIDE:
2672 if (context->getClientVersion() < ES_3_1)
2673 {
Jamie Madill610640f2018-11-21 17:28:41 -05002674 context->validationError(GL_INVALID_ENUM, kErrorEnumRequiresGLES31);
Shao80957d92017-02-20 21:25:59 +08002675 return false;
2676 }
2677 if (index >= caps.maxVertexAttribBindings)
2678 {
Jamie Madill610640f2018-11-21 17:28:41 -05002679 context->validationError(
2680 GL_INVALID_VALUE,
2681 "bindingindex must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08002682 return false;
2683 }
2684 break;
Jiawei Shaodb342272017-09-27 10:21:45 +08002685 case GL_SAMPLE_MASK_VALUE:
2686 if (context->getClientVersion() < ES_3_1)
2687 {
Jamie Madill610640f2018-11-21 17:28:41 -05002688 context->validationError(GL_INVALID_ENUM, kErrorEnumRequiresGLES31);
Jiawei Shaodb342272017-09-27 10:21:45 +08002689 return false;
2690 }
2691 if (index >= caps.maxSampleMaskWords)
2692 {
Jamie Madill610640f2018-11-21 17:28:41 -05002693 context->validationError(GL_INVALID_VALUE, kErrorInvalidSampleMaskNumber);
Jiawei Shaodb342272017-09-27 10:21:45 +08002694 return false;
2695 }
2696 break;
Xinghua Cao9c8e1a32017-12-06 17:59:58 +08002697 case GL_IMAGE_BINDING_NAME:
2698 case GL_IMAGE_BINDING_LEVEL:
2699 case GL_IMAGE_BINDING_LAYERED:
2700 case GL_IMAGE_BINDING_LAYER:
2701 case GL_IMAGE_BINDING_ACCESS:
2702 case GL_IMAGE_BINDING_FORMAT:
2703 if (context->getClientVersion() < ES_3_1)
2704 {
Jamie Madill610640f2018-11-21 17:28:41 -05002705 context->validationError(GL_INVALID_ENUM, kErrorEnumRequiresGLES31);
Xinghua Cao9c8e1a32017-12-06 17:59:58 +08002706 return false;
2707 }
2708 if (index >= caps.maxImageUnits)
2709 {
Jamie Madill610640f2018-11-21 17:28:41 -05002710 context->validationError(GL_INVALID_VALUE, kErrorInvalidImageUnit);
Xinghua Cao9c8e1a32017-12-06 17:59:58 +08002711 return false;
2712 }
2713 break;
Martin Radev66fb8202016-07-28 11:45:20 +03002714 default:
Jamie Madill610640f2018-11-21 17:28:41 -05002715 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Martin Radev66fb8202016-07-28 11:45:20 +03002716 return false;
2717 }
2718
Geoff Lang2e43dbb2016-10-14 12:27:35 -04002719 if (length)
Martin Radev66fb8202016-07-28 11:45:20 +03002720 {
Geoff Lang2e43dbb2016-10-14 12:27:35 -04002721 *length = 1;
Martin Radev66fb8202016-07-28 11:45:20 +03002722 }
2723
2724 return true;
2725}
2726
Jamie Madill5b772312018-03-08 20:28:32 -05002727bool ValidateGetIntegeri_v(Context *context, GLenum target, GLuint index, GLint *data)
Martin Radev66fb8202016-07-28 11:45:20 +03002728{
Geoff Langeb66a6e2016-10-31 13:06:12 -04002729 if (context->getClientVersion() < ES_3_0)
Martin Radev66fb8202016-07-28 11:45:20 +03002730 {
Jamie Madill610640f2018-11-21 17:28:41 -05002731 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Martin Radev66fb8202016-07-28 11:45:20 +03002732 return false;
2733 }
Geoff Lang2e43dbb2016-10-14 12:27:35 -04002734 return ValidateIndexedStateQuery(context, target, index, nullptr);
Martin Radev66fb8202016-07-28 11:45:20 +03002735}
2736
Jamie Madill5b772312018-03-08 20:28:32 -05002737bool ValidateGetIntegeri_vRobustANGLE(Context *context,
Geoff Langcf255ea2016-10-20 11:39:09 -07002738 GLenum target,
2739 GLuint index,
2740 GLsizei bufSize,
2741 GLsizei *length,
2742 GLint *data)
2743{
Geoff Langeb66a6e2016-10-31 13:06:12 -04002744 if (context->getClientVersion() < ES_3_0)
Geoff Langcf255ea2016-10-20 11:39:09 -07002745 {
Jamie Madill610640f2018-11-21 17:28:41 -05002746 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Geoff Langcf255ea2016-10-20 11:39:09 -07002747 return false;
2748 }
2749
2750 if (!ValidateRobustEntryPoint(context, bufSize))
2751 {
2752 return false;
2753 }
2754
Brandon Jonesd1049182018-03-28 10:02:20 -07002755 GLsizei numParams = 0;
2756
2757 if (!ValidateIndexedStateQuery(context, target, index, &numParams))
Geoff Langcf255ea2016-10-20 11:39:09 -07002758 {
2759 return false;
2760 }
2761
Brandon Jonesd1049182018-03-28 10:02:20 -07002762 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langcf255ea2016-10-20 11:39:09 -07002763 {
2764 return false;
2765 }
2766
Brandon Jonesd1049182018-03-28 10:02:20 -07002767 SetRobustLengthParam(length, numParams);
2768
Geoff Langcf255ea2016-10-20 11:39:09 -07002769 return true;
2770}
2771
Jamie Madill5b772312018-03-08 20:28:32 -05002772bool ValidateGetInteger64i_v(Context *context, GLenum target, GLuint index, GLint64 *data)
Martin Radev66fb8202016-07-28 11:45:20 +03002773{
Geoff Langeb66a6e2016-10-31 13:06:12 -04002774 if (context->getClientVersion() < ES_3_0)
Martin Radev66fb8202016-07-28 11:45:20 +03002775 {
Jamie Madill610640f2018-11-21 17:28:41 -05002776 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Martin Radev66fb8202016-07-28 11:45:20 +03002777 return false;
2778 }
Geoff Lang2e43dbb2016-10-14 12:27:35 -04002779 return ValidateIndexedStateQuery(context, target, index, nullptr);
2780}
2781
Jamie Madill5b772312018-03-08 20:28:32 -05002782bool ValidateGetInteger64i_vRobustANGLE(Context *context,
Geoff Lang2e43dbb2016-10-14 12:27:35 -04002783 GLenum target,
2784 GLuint index,
2785 GLsizei bufSize,
2786 GLsizei *length,
2787 GLint64 *data)
2788{
Geoff Langeb66a6e2016-10-31 13:06:12 -04002789 if (context->getClientVersion() < ES_3_0)
Geoff Lang2e43dbb2016-10-14 12:27:35 -04002790 {
Jamie Madill610640f2018-11-21 17:28:41 -05002791 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Geoff Lang2e43dbb2016-10-14 12:27:35 -04002792 return false;
2793 }
2794
2795 if (!ValidateRobustEntryPoint(context, bufSize))
2796 {
2797 return false;
2798 }
2799
Brandon Jonesd1049182018-03-28 10:02:20 -07002800 GLsizei numParams = 0;
2801
2802 if (!ValidateIndexedStateQuery(context, target, index, &numParams))
Geoff Lang2e43dbb2016-10-14 12:27:35 -04002803 {
2804 return false;
2805 }
2806
Brandon Jonesd1049182018-03-28 10:02:20 -07002807 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2e43dbb2016-10-14 12:27:35 -04002808 {
2809 return false;
2810 }
2811
Brandon Jonesd1049182018-03-28 10:02:20 -07002812 SetRobustLengthParam(length, numParams);
2813
Geoff Lang2e43dbb2016-10-14 12:27:35 -04002814 return true;
Martin Radev66fb8202016-07-28 11:45:20 +03002815}
2816
Jamie Madill5b772312018-03-08 20:28:32 -05002817bool ValidateCopyBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002818 BufferBinding readTarget,
2819 BufferBinding writeTarget,
Jamie Madillb0817d12016-11-01 15:48:31 -04002820 GLintptr readOffset,
2821 GLintptr writeOffset,
2822 GLsizeiptr size)
2823{
2824 if (context->getClientMajorVersion() < 3)
2825 {
Jamie Madill610640f2018-11-21 17:28:41 -05002826 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madillb0817d12016-11-01 15:48:31 -04002827 return false;
2828 }
2829
Corentin Walleze4477002017-12-01 14:39:58 -05002830 if (!context->isValidBufferBinding(readTarget) || !context->isValidBufferBinding(writeTarget))
Jamie Madillb0817d12016-11-01 15:48:31 -04002831 {
Jamie Madill610640f2018-11-21 17:28:41 -05002832 context->validationError(GL_INVALID_ENUM, kErrorInvalidBufferTypes);
Jamie Madillb0817d12016-11-01 15:48:31 -04002833 return false;
2834 }
2835
2836 Buffer *readBuffer = context->getGLState().getTargetBuffer(readTarget);
2837 Buffer *writeBuffer = context->getGLState().getTargetBuffer(writeTarget);
2838
2839 if (!readBuffer || !writeBuffer)
2840 {
Jamie Madill610640f2018-11-21 17:28:41 -05002841 context->validationError(GL_INVALID_OPERATION, "No buffer bound to target");
Jamie Madillb0817d12016-11-01 15:48:31 -04002842 return false;
2843 }
2844
2845 // Verify that readBuffer and writeBuffer are not currently mapped
2846 if (readBuffer->isMapped() || writeBuffer->isMapped())
2847 {
Jamie Madill610640f2018-11-21 17:28:41 -05002848 context->validationError(GL_INVALID_OPERATION,
2849 "Cannot call CopyBufferSubData on a mapped buffer");
Jamie Madillb0817d12016-11-01 15:48:31 -04002850 return false;
2851 }
2852
James Darpiniane8a93c62018-01-04 18:02:24 -08002853 if (context->getExtensions().webglCompatibility &&
2854 (readBuffer->isBoundForTransformFeedbackAndOtherUse() ||
2855 writeBuffer->isBoundForTransformFeedbackAndOtherUse()))
2856 {
Jamie Madill610640f2018-11-21 17:28:41 -05002857 context->validationError(GL_INVALID_OPERATION, kErrorBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08002858 return false;
2859 }
2860
Jamie Madilld2f0c742016-11-02 10:34:41 -04002861 CheckedNumeric<GLintptr> checkedReadOffset(readOffset);
2862 CheckedNumeric<GLintptr> checkedWriteOffset(writeOffset);
2863 CheckedNumeric<GLintptr> checkedSize(size);
2864
2865 auto checkedReadSum = checkedReadOffset + checkedSize;
2866 auto checkedWriteSum = checkedWriteOffset + checkedSize;
2867
2868 if (!checkedReadSum.IsValid() || !checkedWriteSum.IsValid() ||
2869 !IsValueInRangeForNumericType<GLintptr>(readBuffer->getSize()) ||
2870 !IsValueInRangeForNumericType<GLintptr>(writeBuffer->getSize()))
Jamie Madillb0817d12016-11-01 15:48:31 -04002871 {
Jamie Madill610640f2018-11-21 17:28:41 -05002872 context->validationError(GL_INVALID_VALUE, kErrorIntegerOverflow);
Jamie Madillb0817d12016-11-01 15:48:31 -04002873 return false;
2874 }
2875
Jamie Madilld2f0c742016-11-02 10:34:41 -04002876 if (readOffset < 0 || writeOffset < 0 || size < 0)
Jamie Madillb0817d12016-11-01 15:48:31 -04002877 {
Jamie Madill610640f2018-11-21 17:28:41 -05002878 context->validationError(GL_INVALID_VALUE,
2879 "readOffset, writeOffset and size must all be non-negative");
Jamie Madillb0817d12016-11-01 15:48:31 -04002880 return false;
2881 }
2882
Jamie Madilld2f0c742016-11-02 10:34:41 -04002883 if (checkedReadSum.ValueOrDie() > readBuffer->getSize() ||
2884 checkedWriteSum.ValueOrDie() > writeBuffer->getSize())
2885 {
Jamie Madill610640f2018-11-21 17:28:41 -05002886 context->validationError(GL_INVALID_VALUE, "Buffer offset overflow in CopyBufferSubData");
Jamie Madilld2f0c742016-11-02 10:34:41 -04002887 return false;
2888 }
2889
2890 if (readBuffer == writeBuffer)
2891 {
2892 auto checkedOffsetDiff = (checkedReadOffset - checkedWriteOffset).Abs();
2893 if (!checkedOffsetDiff.IsValid())
2894 {
2895 // This shold not be possible.
2896 UNREACHABLE();
Jamie Madill610640f2018-11-21 17:28:41 -05002897 context->validationError(GL_INVALID_VALUE, kErrorIntegerOverflow);
Jamie Madilld2f0c742016-11-02 10:34:41 -04002898 return false;
2899 }
2900
2901 if (checkedOffsetDiff.ValueOrDie() < size)
2902 {
Jamie Madill610640f2018-11-21 17:28:41 -05002903 context->validationError(GL_INVALID_VALUE, kErrorCopyAlias);
Jamie Madilld2f0c742016-11-02 10:34:41 -04002904 return false;
2905 }
2906 }
2907
Jamie Madillb0817d12016-11-01 15:48:31 -04002908 return true;
2909}
2910
Geoff Langc339c4e2016-11-29 10:37:36 -05002911bool ValidateGetStringi(Context *context, GLenum name, GLuint index)
2912{
2913 if (context->getClientMajorVersion() < 3)
2914 {
Jamie Madill610640f2018-11-21 17:28:41 -05002915 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Geoff Langc339c4e2016-11-29 10:37:36 -05002916 return false;
2917 }
2918
2919 switch (name)
2920 {
2921 case GL_EXTENSIONS:
2922 if (index >= context->getExtensionStringCount())
2923 {
Jamie Madill610640f2018-11-21 17:28:41 -05002924 context->validationError(
2925 GL_INVALID_VALUE, "index must be less than the number of extension strings.");
Geoff Langc339c4e2016-11-29 10:37:36 -05002926 return false;
2927 }
2928 break;
2929
2930 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2931 if (!context->getExtensions().requestExtension)
2932 {
Jamie Madill610640f2018-11-21 17:28:41 -05002933 context->validationError(GL_INVALID_ENUM, kErrorInvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05002934 return false;
2935 }
2936 if (index >= context->getRequestableExtensionStringCount())
2937 {
Jamie Madill610640f2018-11-21 17:28:41 -05002938 context->validationError(
2939 GL_INVALID_VALUE,
2940 "index must be less than the number of requestable extension strings.");
Geoff Langc339c4e2016-11-29 10:37:36 -05002941 return false;
2942 }
2943 break;
2944
2945 default:
Jamie Madill610640f2018-11-21 17:28:41 -05002946 context->validationError(GL_INVALID_ENUM, kErrorInvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05002947 return false;
2948 }
2949
2950 return true;
2951}
2952
Jamie Madill5b772312018-03-08 20:28:32 -05002953bool ValidateRenderbufferStorageMultisample(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05002954 GLenum target,
2955 GLsizei samples,
2956 GLenum internalformat,
2957 GLsizei width,
2958 GLsizei height)
2959{
2960 if (context->getClientMajorVersion() < 3)
2961 {
Jamie Madill610640f2018-11-21 17:28:41 -05002962 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madille8fb6402017-02-14 17:56:40 -05002963 return false;
2964 }
2965
2966 if (!ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat, width,
2967 height))
2968 {
2969 return false;
2970 }
2971
2972 // 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 +08002973 // format if samples is greater than zero. In ES3.1(section 9.2.5), it can support integer
2974 // multisample renderbuffer, but the samples should not be greater than MAX_INTEGER_SAMPLES.
Geoff Langca271392017-04-05 12:30:00 -04002975 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Yunchao Hec0810202018-01-22 09:48:48 +08002976 if ((formatInfo.componentType == GL_UNSIGNED_INT || formatInfo.componentType == GL_INT))
Jamie Madille8fb6402017-02-14 17:56:40 -05002977 {
Yunchao Hec0810202018-01-22 09:48:48 +08002978 if ((samples > 0 && context->getClientVersion() == ES_3_0) ||
2979 static_cast<GLuint>(samples) > context->getCaps().maxIntegerSamples)
2980 {
Jamie Madill610640f2018-11-21 17:28:41 -05002981 context->validationError(GL_INVALID_OPERATION, kErrorSamplesOutOfRange);
Yunchao Hec0810202018-01-22 09:48:48 +08002982 return false;
2983 }
Jamie Madille8fb6402017-02-14 17:56:40 -05002984 }
2985
2986 // The behavior is different than the ANGLE version, which would generate a GL_OUT_OF_MEMORY.
2987 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
2988 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
2989 {
Jamie Madill610640f2018-11-21 17:28:41 -05002990 context->validationError(GL_INVALID_OPERATION, kErrorSamplesOutOfRange);
Jamie Madille8fb6402017-02-14 17:56:40 -05002991 return false;
2992 }
2993
2994 return true;
2995}
2996
Jamie Madill5b772312018-03-08 20:28:32 -05002997bool ValidateVertexAttribIPointer(Context *context,
Geoff Langaa086d62017-03-23 16:47:21 -04002998 GLuint index,
2999 GLint size,
3000 GLenum type,
3001 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003002 const void *pointer)
Geoff Langaa086d62017-03-23 16:47:21 -04003003{
3004 if (context->getClientMajorVersion() < 3)
3005 {
Jamie Madill610640f2018-11-21 17:28:41 -05003006 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Geoff Langaa086d62017-03-23 16:47:21 -04003007 return false;
3008 }
3009
Shao80957d92017-02-20 21:25:59 +08003010 if (!ValidateVertexFormatBase(context, index, size, type, true))
Geoff Langaa086d62017-03-23 16:47:21 -04003011 {
Geoff Langaa086d62017-03-23 16:47:21 -04003012 return false;
3013 }
3014
Geoff Langaa086d62017-03-23 16:47:21 -04003015 if (stride < 0)
3016 {
Jamie Madill610640f2018-11-21 17:28:41 -05003017 context->validationError(GL_INVALID_VALUE, kErrorNegativeStride);
Geoff Langaa086d62017-03-23 16:47:21 -04003018 return false;
3019 }
3020
Shao80957d92017-02-20 21:25:59 +08003021 const Caps &caps = context->getCaps();
3022 if (context->getClientVersion() >= ES_3_1)
3023 {
3024 if (stride > caps.maxVertexAttribStride)
3025 {
Jamie Madill610640f2018-11-21 17:28:41 -05003026 context->validationError(GL_INVALID_VALUE,
3027 "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08003028 return false;
3029 }
3030
3031 // [OpenGL ES 3.1] Section 10.3.1 page 245:
3032 // glVertexAttribBinding is part of the equivalent code of VertexAttribIPointer, so its
3033 // validation should be inherited.
3034 if (index >= caps.maxVertexAttribBindings)
3035 {
Jamie Madill610640f2018-11-21 17:28:41 -05003036 context->validationError(GL_INVALID_VALUE,
3037 "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08003038 return false;
3039 }
3040 }
3041
Geoff Langaa086d62017-03-23 16:47:21 -04003042 // [OpenGL ES 3.0.2] Section 2.8 page 24:
3043 // An INVALID_OPERATION error is generated when a non-zero vertex array object
3044 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
3045 // and the pointer argument is not NULL.
3046 if (context->getGLState().getVertexArrayId() != 0 &&
Corentin Wallez336129f2017-10-17 15:55:40 -04003047 context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 && pointer != nullptr)
Geoff Langaa086d62017-03-23 16:47:21 -04003048 {
Jamie Madill610640f2018-11-21 17:28:41 -05003049 context->validationError(
3050 GL_INVALID_OPERATION,
3051 "Client data cannot be used with a non-default vertex array object.");
Geoff Langaa086d62017-03-23 16:47:21 -04003052 return false;
3053 }
3054
Geoff Lang2d62ab72017-03-23 16:54:40 -04003055 if (context->getExtensions().webglCompatibility)
3056 {
3057 if (!ValidateWebGLVertexAttribPointer(context, type, false, stride, pointer, true))
3058 {
3059 return false;
3060 }
3061 }
3062
Geoff Langaa086d62017-03-23 16:47:21 -04003063 return true;
3064}
3065
Geoff Lang38f2cfb2017-04-11 15:23:08 -04003066bool ValidateGetSynciv(Context *context,
3067 GLsync sync,
3068 GLenum pname,
3069 GLsizei bufSize,
3070 GLsizei *length,
3071 GLint *values)
3072{
3073 if (context->getClientMajorVersion() < 3)
3074 {
Jamie Madill610640f2018-11-21 17:28:41 -05003075 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Geoff Lang38f2cfb2017-04-11 15:23:08 -04003076 return false;
3077 }
3078
3079 if (bufSize < 0)
3080 {
Jamie Madill610640f2018-11-21 17:28:41 -05003081 context->validationError(GL_INVALID_VALUE, kErrorNegativeBufferSize);
Geoff Lang38f2cfb2017-04-11 15:23:08 -04003082 return false;
3083 }
3084
Jamie Madill70b5bb02017-08-28 13:32:37 -04003085 Sync *syncObject = context->getSync(sync);
3086 if (!syncObject)
Geoff Lang38f2cfb2017-04-11 15:23:08 -04003087 {
Jamie Madill610640f2018-11-21 17:28:41 -05003088 context->validationError(GL_INVALID_VALUE, "Invalid sync object.");
Geoff Lang38f2cfb2017-04-11 15:23:08 -04003089 return false;
3090 }
3091
3092 switch (pname)
3093 {
3094 case GL_OBJECT_TYPE:
3095 case GL_SYNC_CONDITION:
3096 case GL_SYNC_FLAGS:
3097 case GL_SYNC_STATUS:
3098 break;
3099
3100 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003101 context->validationError(GL_INVALID_ENUM, kErrorInvalidPname);
Geoff Lang38f2cfb2017-04-11 15:23:08 -04003102 return false;
3103 }
3104
3105 return true;
3106}
3107
Jamie Madill5b772312018-03-08 20:28:32 -05003108bool ValidateDrawElementsInstanced(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04003109 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003110 GLsizei count,
3111 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003112 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003113 GLsizei instanceCount)
3114{
3115 if (context->getClientMajorVersion() < 3)
3116 {
Jamie Madill610640f2018-11-21 17:28:41 -05003117 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003118 return false;
3119 }
3120
3121 return ValidateDrawElementsInstancedCommon(context, mode, count, type, indices, instanceCount);
3122}
3123
Austin Eng1bf18ce2018-10-19 15:34:02 -07003124bool ValidateMultiDrawArraysInstancedANGLE(Context *context,
3125 PrimitiveMode mode,
3126 const GLint *firsts,
3127 const GLsizei *counts,
3128 const GLsizei *instanceCounts,
3129 GLsizei drawcount)
3130{
3131 if (!context->getExtensions().multiDraw)
3132 {
Jamie Madill610640f2018-11-21 17:28:41 -05003133 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07003134 return false;
3135 }
3136 if (context->getClientMajorVersion() < 3)
3137 {
3138 if (!context->getExtensions().instancedArrays)
3139 {
Jamie Madill610640f2018-11-21 17:28:41 -05003140 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07003141 return false;
3142 }
3143 if (!ValidateDrawInstancedANGLE(context))
3144 {
3145 return false;
3146 }
3147 }
3148 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
3149 {
3150 if (!ValidateDrawArraysInstancedBase(context, mode, firsts[drawID], counts[drawID],
3151 instanceCounts[drawID]))
3152 {
3153 return false;
3154 }
3155 }
3156 return true;
3157}
3158
3159bool ValidateMultiDrawElementsInstancedANGLE(Context *context,
3160 PrimitiveMode mode,
3161 const GLsizei *counts,
3162 GLenum type,
3163 const GLsizei *offsets,
3164 const GLsizei *instanceCounts,
3165 GLsizei drawcount)
3166{
3167 if (!context->getExtensions().multiDraw)
3168 {
Jamie Madill610640f2018-11-21 17:28:41 -05003169 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07003170 return false;
3171 }
3172 if (context->getClientMajorVersion() < 3)
3173 {
3174 if (!context->getExtensions().instancedArrays)
3175 {
Jamie Madill610640f2018-11-21 17:28:41 -05003176 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07003177 return false;
3178 }
3179 if (!ValidateDrawInstancedANGLE(context))
3180 {
3181 return false;
3182 }
3183 }
3184 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
3185 {
3186 const void *indices = reinterpret_cast<void *>(static_cast<long>(offsets[drawID]));
3187 if (!ValidateDrawElementsInstancedCommon(context, mode, counts[drawID], type, indices,
3188 instanceCounts[drawID]))
3189 {
3190 return false;
3191 }
3192 }
3193 return true;
3194}
3195
Martin Radev137032d2017-07-13 10:11:12 +03003196bool ValidateFramebufferTextureMultiviewLayeredANGLE(Context *context,
3197 GLenum target,
3198 GLenum attachment,
3199 GLuint texture,
3200 GLint level,
3201 GLint baseViewIndex,
3202 GLsizei numViews)
3203{
Martin Radev137032d2017-07-13 10:11:12 +03003204 if (!ValidateFramebufferTextureMultiviewBaseANGLE(context, target, attachment, texture, level,
3205 numViews))
3206 {
3207 return false;
3208 }
3209
Martin Radev137032d2017-07-13 10:11:12 +03003210 if (texture != 0)
3211 {
Martin Radev14b21262017-08-25 13:54:37 +03003212 if (baseViewIndex < 0)
3213 {
Jamie Madill610640f2018-11-21 17:28:41 -05003214 context->validationError(GL_INVALID_VALUE, "baseViewIndex cannot be less than 0.");
Martin Radev14b21262017-08-25 13:54:37 +03003215 return false;
3216 }
3217
Martin Radev137032d2017-07-13 10:11:12 +03003218 Texture *tex = context->getTexture(texture);
3219 ASSERT(tex);
3220
Corentin Wallez99d492c2018-02-27 15:17:10 -05003221 switch (tex->getType())
Martin Radev137032d2017-07-13 10:11:12 +03003222 {
Corentin Wallez99d492c2018-02-27 15:17:10 -05003223 case TextureType::_2DArray:
Olli Etuaho2c8f0842018-09-12 14:44:55 +03003224 case TextureType::_2DMultisampleArray:
Martin Radev137032d2017-07-13 10:11:12 +03003225 {
Olli Etuaho2c8f0842018-09-12 14:44:55 +03003226 if (tex->getType() == TextureType::_2DMultisampleArray)
3227 {
3228 if (!context->getExtensions().multiviewMultisample)
3229 {
Jamie Madill610640f2018-11-21 17:28:41 -05003230 context->validationError(GL_INVALID_OPERATION,
3231 "Texture's target must be GL_TEXTURE_2D_ARRAY.");
Olli Etuaho2c8f0842018-09-12 14:44:55 +03003232 return false;
3233 }
3234 }
3235
Martin Radev137032d2017-07-13 10:11:12 +03003236 const Caps &caps = context->getCaps();
3237 if (static_cast<GLuint>(baseViewIndex + numViews) > caps.maxArrayTextureLayers)
3238 {
Jamie Madill610640f2018-11-21 17:28:41 -05003239 context->validationError(GL_INVALID_VALUE,
3240 "baseViewIndex+numViews cannot be "
3241 "greater than "
3242 "GL_MAX_ARRAY_TEXTURE_LAYERS.");
Martin Radev137032d2017-07-13 10:11:12 +03003243 return false;
3244 }
Olli Etuaho2c8f0842018-09-12 14:44:55 +03003245
3246 break;
Martin Radev137032d2017-07-13 10:11:12 +03003247 }
Martin Radev137032d2017-07-13 10:11:12 +03003248 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003249 context->validationError(GL_INVALID_OPERATION,
3250 "Texture's target must be GL_TEXTURE_2D_ARRAY.");
Martin Radev137032d2017-07-13 10:11:12 +03003251 return false;
3252 }
3253
3254 if (!ValidateFramebufferTextureMultiviewLevelAndFormat(context, tex, level))
3255 {
3256 return false;
3257 }
3258 }
3259
3260 return true;
3261}
3262
3263bool ValidateFramebufferTextureMultiviewSideBySideANGLE(Context *context,
3264 GLenum target,
3265 GLenum attachment,
3266 GLuint texture,
3267 GLint level,
3268 GLsizei numViews,
3269 const GLint *viewportOffsets)
3270{
3271 if (!ValidateFramebufferTextureMultiviewBaseANGLE(context, target, attachment, texture, level,
3272 numViews))
3273 {
3274 return false;
3275 }
3276
Martin Radev137032d2017-07-13 10:11:12 +03003277 if (texture != 0)
3278 {
Martin Radev14b21262017-08-25 13:54:37 +03003279 const GLsizei numViewportOffsetValues = numViews * 2;
3280 for (GLsizei i = 0; i < numViewportOffsetValues; ++i)
3281 {
3282 if (viewportOffsets[i] < 0)
3283 {
Jamie Madill610640f2018-11-21 17:28:41 -05003284 context->validationError(GL_INVALID_VALUE,
3285 "viewportOffsets cannot contain negative values.");
Martin Radev14b21262017-08-25 13:54:37 +03003286 return false;
3287 }
3288 }
3289
Martin Radev137032d2017-07-13 10:11:12 +03003290 Texture *tex = context->getTexture(texture);
3291 ASSERT(tex);
3292
Corentin Wallez99d492c2018-02-27 15:17:10 -05003293 switch (tex->getType())
Martin Radev137032d2017-07-13 10:11:12 +03003294 {
Corentin Wallez99d492c2018-02-27 15:17:10 -05003295 case TextureType::_2D:
Martin Radev137032d2017-07-13 10:11:12 +03003296 break;
3297 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003298 context->validationError(GL_INVALID_OPERATION,
3299 "Texture's target must be GL_TEXTURE_2D.");
Martin Radev137032d2017-07-13 10:11:12 +03003300 return false;
3301 }
3302
3303 if (!ValidateFramebufferTextureMultiviewLevelAndFormat(context, tex, level))
3304 {
3305 return false;
3306 }
3307 }
3308
3309 return true;
3310}
3311
Jamie Madillff325f12017-08-26 15:06:05 -04003312bool ValidateUniform1ui(Context *context, GLint location, GLuint v0)
3313{
3314 return ValidateUniformES3(context, GL_UNSIGNED_INT, location, 1);
3315}
3316
3317bool ValidateUniform2ui(Context *context, GLint location, GLuint v0, GLuint v1)
3318{
3319 return ValidateUniformES3(context, GL_UNSIGNED_INT_VEC2, location, 1);
3320}
3321
3322bool ValidateUniform3ui(Context *context, GLint location, GLuint v0, GLuint v1, GLuint v2)
3323{
3324 return ValidateUniformES3(context, GL_UNSIGNED_INT_VEC3, location, 1);
3325}
3326
3327bool ValidateUniform4ui(Context *context,
3328 GLint location,
3329 GLuint v0,
3330 GLuint v1,
3331 GLuint v2,
3332 GLuint v3)
3333{
3334 return ValidateUniformES3(context, GL_UNSIGNED_INT_VEC4, location, 1);
3335}
3336
3337bool ValidateUniform1uiv(Context *context, GLint location, GLsizei count, const GLuint *value)
3338{
3339 return ValidateUniformES3(context, GL_UNSIGNED_INT, location, count);
3340}
3341
3342bool ValidateUniform2uiv(Context *context, GLint location, GLsizei count, const GLuint *value)
3343{
3344 return ValidateUniformES3(context, GL_UNSIGNED_INT_VEC2, location, count);
3345}
3346
3347bool ValidateUniform3uiv(Context *context, GLint location, GLsizei count, const GLuint *value)
3348{
3349 return ValidateUniformES3(context, GL_UNSIGNED_INT_VEC3, location, count);
3350}
3351
3352bool ValidateUniform4uiv(Context *context, GLint location, GLsizei count, const GLuint *value)
3353{
3354 return ValidateUniformES3(context, GL_UNSIGNED_INT_VEC4, location, count);
3355}
3356
Jamie Madillf0e04492017-08-26 15:28:42 -04003357bool ValidateIsQuery(Context *context, GLuint id)
3358{
3359 if (context->getClientMajorVersion() < 3)
3360 {
Jamie Madill610640f2018-11-21 17:28:41 -05003361 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madillf0e04492017-08-26 15:28:42 -04003362 return false;
3363 }
3364
3365 return true;
3366}
3367
Jamie Madillc8c95812017-08-26 18:40:09 -04003368bool ValidateUniformMatrix2x3fv(Context *context,
3369 GLint location,
3370 GLsizei count,
3371 GLboolean transpose,
3372 const GLfloat *value)
3373{
3374 return ValidateUniformMatrixES3(context, GL_FLOAT_MAT2x3, location, count, transpose);
3375}
3376
3377bool ValidateUniformMatrix3x2fv(Context *context,
3378 GLint location,
3379 GLsizei count,
3380 GLboolean transpose,
3381 const GLfloat *value)
3382{
3383 return ValidateUniformMatrixES3(context, GL_FLOAT_MAT3x2, location, count, transpose);
3384}
3385
3386bool ValidateUniformMatrix2x4fv(Context *context,
3387 GLint location,
3388 GLsizei count,
3389 GLboolean transpose,
3390 const GLfloat *value)
3391{
3392 return ValidateUniformMatrixES3(context, GL_FLOAT_MAT2x4, location, count, transpose);
3393}
3394
3395bool ValidateUniformMatrix4x2fv(Context *context,
3396 GLint location,
3397 GLsizei count,
3398 GLboolean transpose,
3399 const GLfloat *value)
3400{
3401 return ValidateUniformMatrixES3(context, GL_FLOAT_MAT4x2, location, count, transpose);
3402}
3403
3404bool ValidateUniformMatrix3x4fv(Context *context,
3405 GLint location,
3406 GLsizei count,
3407 GLboolean transpose,
3408 const GLfloat *value)
3409{
3410 return ValidateUniformMatrixES3(context, GL_FLOAT_MAT3x4, location, count, transpose);
3411}
3412
3413bool ValidateUniformMatrix4x3fv(Context *context,
3414 GLint location,
3415 GLsizei count,
3416 GLboolean transpose,
3417 const GLfloat *value)
3418{
3419 return ValidateUniformMatrixES3(context, GL_FLOAT_MAT4x3, location, count, transpose);
3420}
3421
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003422bool ValidateEndTransformFeedback(Context *context)
3423{
3424 if (context->getClientMajorVersion() < 3)
3425 {
Jamie Madill610640f2018-11-21 17:28:41 -05003426 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003427 return false;
3428 }
3429
3430 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
3431 ASSERT(transformFeedback != nullptr);
3432
3433 if (!transformFeedback->isActive())
3434 {
Jamie Madill610640f2018-11-21 17:28:41 -05003435 context->validationError(GL_INVALID_OPERATION, kErrorTransformFeedbackNotActive);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003436 return false;
3437 }
3438
3439 return true;
3440}
3441
3442bool ValidateTransformFeedbackVaryings(Context *context,
3443 GLuint program,
3444 GLsizei count,
3445 const GLchar *const *varyings,
3446 GLenum bufferMode)
3447{
3448 if (context->getClientMajorVersion() < 3)
3449 {
Jamie Madill610640f2018-11-21 17:28:41 -05003450 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003451 return false;
3452 }
3453
3454 if (count < 0)
3455 {
Jamie Madill610640f2018-11-21 17:28:41 -05003456 context->validationError(GL_INVALID_VALUE, kErrorNegativeCount);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003457 return false;
3458 }
3459
3460 switch (bufferMode)
3461 {
3462 case GL_INTERLEAVED_ATTRIBS:
3463 break;
3464 case GL_SEPARATE_ATTRIBS:
3465 {
3466 const Caps &caps = context->getCaps();
3467 if (static_cast<GLuint>(count) > caps.maxTransformFeedbackSeparateAttributes)
3468 {
Jamie Madill610640f2018-11-21 17:28:41 -05003469 context->validationError(GL_INVALID_VALUE,
3470 kErrorInvalidTransformFeedbackAttribsCount);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003471 return false;
3472 }
3473 break;
3474 }
3475 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003476 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003477 return false;
3478 }
3479
3480 Program *programObject = GetValidProgram(context, program);
3481 if (!programObject)
3482 {
3483 return false;
3484 }
3485
3486 return true;
3487}
3488
3489bool ValidateGetTransformFeedbackVarying(Context *context,
3490 GLuint program,
3491 GLuint index,
3492 GLsizei bufSize,
3493 GLsizei *length,
3494 GLsizei *size,
3495 GLenum *type,
3496 GLchar *name)
3497{
3498 if (context->getClientMajorVersion() < 3)
3499 {
Jamie Madill610640f2018-11-21 17:28:41 -05003500 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003501 return false;
3502 }
3503
3504 if (bufSize < 0)
3505 {
Jamie Madill610640f2018-11-21 17:28:41 -05003506 context->validationError(GL_INVALID_VALUE, kErrorNegativeBufferSize);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003507 return false;
3508 }
3509
3510 Program *programObject = GetValidProgram(context, program);
3511 if (!programObject)
3512 {
3513 return false;
3514 }
3515
3516 if (index >= static_cast<GLuint>(programObject->getTransformFeedbackVaryingCount()))
3517 {
Jamie Madill610640f2018-11-21 17:28:41 -05003518 context->validationError(GL_INVALID_VALUE, kErrorTransformFeedbackVaryingIndexOutOfRange);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003519 return false;
3520 }
3521
3522 return true;
3523}
3524
3525bool ValidateBindTransformFeedback(Context *context, GLenum target, GLuint id)
3526{
3527 if (context->getClientMajorVersion() < 3)
3528 {
Jamie Madill610640f2018-11-21 17:28:41 -05003529 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003530 return false;
3531 }
3532
3533 switch (target)
3534 {
3535 case GL_TRANSFORM_FEEDBACK:
3536 {
3537 // Cannot bind a transform feedback object if the current one is started and not
3538 // paused (3.0.2 pg 85 section 2.14.1)
3539 TransformFeedback *curTransformFeedback =
3540 context->getGLState().getCurrentTransformFeedback();
3541 if (curTransformFeedback && curTransformFeedback->isActive() &&
3542 !curTransformFeedback->isPaused())
3543 {
Jamie Madill610640f2018-11-21 17:28:41 -05003544 context->validationError(GL_INVALID_OPERATION, kErrorTransformFeedbackNotPaused);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003545 return false;
3546 }
3547
3548 // Cannot bind a transform feedback object that does not exist (3.0.2 pg 85 section
3549 // 2.14.1)
3550 if (!context->isTransformFeedbackGenerated(id))
3551 {
Jamie Madill610640f2018-11-21 17:28:41 -05003552 context->validationError(GL_INVALID_OPERATION, kErrorTransformFeedbackDoesNotExist);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003553 return false;
3554 }
3555 }
3556 break;
3557
3558 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003559 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003560 return false;
3561 }
3562
3563 return true;
3564}
3565
3566bool ValidateIsTransformFeedback(Context *context, GLuint id)
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 return true;
3575}
3576
3577bool ValidatePauseTransformFeedback(Context *context)
3578{
3579 if (context->getClientMajorVersion() < 3)
3580 {
Jamie Madill610640f2018-11-21 17:28:41 -05003581 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003582 return false;
3583 }
3584
3585 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
3586 ASSERT(transformFeedback != nullptr);
3587
3588 // 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 -05003589 if (!transformFeedback->isActive())
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003590 {
Jamie Madill610640f2018-11-21 17:28:41 -05003591 context->validationError(GL_INVALID_OPERATION, kErrorTransformFeedbackNotActive);
3592 return false;
3593 }
3594
3595 if (transformFeedback->isPaused())
3596 {
3597 context->validationError(GL_INVALID_OPERATION, kErrorTransformFeedbackPaused);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003598 return false;
3599 }
3600
3601 return true;
3602}
3603
3604bool ValidateResumeTransformFeedback(Context *context)
3605{
3606 if (context->getClientMajorVersion() < 3)
3607 {
Jamie Madill610640f2018-11-21 17:28:41 -05003608 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003609 return false;
3610 }
3611
3612 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
3613 ASSERT(transformFeedback != nullptr);
3614
3615 // Current transform feedback must be active and paused in order to resume (3.0.2 pg 86)
Jamie Madill610640f2018-11-21 17:28:41 -05003616 if (!transformFeedback->isActive())
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003617 {
Jamie Madill610640f2018-11-21 17:28:41 -05003618 context->validationError(GL_INVALID_OPERATION, kErrorTransformFeedbackNotActive);
3619 return false;
3620 }
3621
3622 if (!transformFeedback->isPaused())
3623 {
3624 context->validationError(GL_INVALID_OPERATION, kErrorTransformFeedbackNotPaused);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003625 return false;
3626 }
3627
3628 return true;
3629}
3630
Jamie Madill12e957f2017-08-26 21:42:26 -04003631bool ValidateVertexAttribI4i(Context *context, GLuint index, GLint x, GLint y, GLint z, GLint w)
3632{
3633 if (context->getClientMajorVersion() < 3)
3634 {
Jamie Madill610640f2018-11-21 17:28:41 -05003635 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003636 return false;
3637 }
3638
3639 return ValidateVertexAttribIndex(context, index);
3640}
3641
3642bool ValidateVertexAttribI4ui(Context *context,
3643 GLuint index,
3644 GLuint x,
3645 GLuint y,
3646 GLuint z,
3647 GLuint w)
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 ValidateVertexAttribI4iv(Context *context, GLuint index, const GLint *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 ValidateVertexAttribI4uiv(Context *context, GLuint index, const GLuint *v)
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 return ValidateVertexAttribIndex(context, index);
3678}
3679
3680bool ValidateGetFragDataLocation(Context *context, GLuint program, const GLchar *name)
3681{
3682 if (context->getClientMajorVersion() < 3)
3683 {
Jamie Madill610640f2018-11-21 17:28:41 -05003684 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003685 return false;
3686 }
3687
3688 Program *programObject = GetValidProgram(context, program);
3689 if (!programObject)
3690 {
3691 return false;
3692 }
3693
3694 if (!programObject->isLinked())
3695 {
Jamie Madill610640f2018-11-21 17:28:41 -05003696 context->validationError(GL_INVALID_OPERATION, kErrorProgramNotLinked);
Jamie Madill12e957f2017-08-26 21:42:26 -04003697 return false;
3698 }
3699
3700 return true;
3701}
3702
3703bool ValidateGetUniformIndices(Context *context,
3704 GLuint program,
3705 GLsizei uniformCount,
3706 const GLchar *const *uniformNames,
3707 GLuint *uniformIndices)
3708{
3709 if (context->getClientMajorVersion() < 3)
3710 {
Jamie Madill610640f2018-11-21 17:28:41 -05003711 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003712 return false;
3713 }
3714
3715 if (uniformCount < 0)
3716 {
Jamie Madill610640f2018-11-21 17:28:41 -05003717 context->validationError(GL_INVALID_VALUE, kErrorNegativeCount);
Jamie Madill12e957f2017-08-26 21:42:26 -04003718 return false;
3719 }
3720
3721 Program *programObject = GetValidProgram(context, program);
3722 if (!programObject)
3723 {
3724 return false;
3725 }
3726
3727 return true;
3728}
3729
3730bool ValidateGetActiveUniformsiv(Context *context,
3731 GLuint program,
3732 GLsizei uniformCount,
3733 const GLuint *uniformIndices,
3734 GLenum pname,
3735 GLint *params)
3736{
3737 if (context->getClientMajorVersion() < 3)
3738 {
Jamie Madill610640f2018-11-21 17:28:41 -05003739 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003740 return false;
3741 }
3742
3743 if (uniformCount < 0)
3744 {
Jamie Madill610640f2018-11-21 17:28:41 -05003745 context->validationError(GL_INVALID_VALUE, kErrorNegativeCount);
Jamie Madill12e957f2017-08-26 21:42:26 -04003746 return false;
3747 }
3748
3749 Program *programObject = GetValidProgram(context, program);
3750 if (!programObject)
3751 {
3752 return false;
3753 }
3754
3755 switch (pname)
3756 {
3757 case GL_UNIFORM_TYPE:
3758 case GL_UNIFORM_SIZE:
Bryan Bernhart22f7aaf2018-08-23 14:13:51 -07003759 break;
Jamie Madill12e957f2017-08-26 21:42:26 -04003760 case GL_UNIFORM_NAME_LENGTH:
Bryan Bernhart22f7aaf2018-08-23 14:13:51 -07003761 if (context->getExtensions().webglCompatibility)
3762 {
Jamie Madill610640f2018-11-21 17:28:41 -05003763 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Bryan Bernhart22f7aaf2018-08-23 14:13:51 -07003764 return false;
3765 }
3766 break;
Jamie Madill12e957f2017-08-26 21:42:26 -04003767 case GL_UNIFORM_BLOCK_INDEX:
3768 case GL_UNIFORM_OFFSET:
3769 case GL_UNIFORM_ARRAY_STRIDE:
3770 case GL_UNIFORM_MATRIX_STRIDE:
3771 case GL_UNIFORM_IS_ROW_MAJOR:
3772 break;
3773
3774 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003775 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madill12e957f2017-08-26 21:42:26 -04003776 return false;
3777 }
3778
3779 if (uniformCount > programObject->getActiveUniformCount())
3780 {
Jamie Madill610640f2018-11-21 17:28:41 -05003781 context->validationError(GL_INVALID_VALUE, kErrorIndexExceedsMaxActiveUniform);
Jamie Madill12e957f2017-08-26 21:42:26 -04003782 return false;
3783 }
3784
3785 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
3786 {
3787 const GLuint index = uniformIndices[uniformId];
3788
3789 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
3790 {
Jamie Madill610640f2018-11-21 17:28:41 -05003791 context->validationError(GL_INVALID_VALUE, kErrorIndexExceedsMaxActiveUniform);
Jamie Madill12e957f2017-08-26 21:42:26 -04003792 return false;
3793 }
3794 }
3795
3796 return true;
3797}
3798
3799bool ValidateGetUniformBlockIndex(Context *context, GLuint program, const GLchar *uniformBlockName)
3800{
3801 if (context->getClientMajorVersion() < 3)
3802 {
Jamie Madill610640f2018-11-21 17:28:41 -05003803 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003804 return false;
3805 }
3806
3807 Program *programObject = GetValidProgram(context, program);
3808 if (!programObject)
3809 {
3810 return false;
3811 }
3812
3813 return true;
3814}
3815
3816bool ValidateGetActiveUniformBlockiv(Context *context,
3817 GLuint program,
3818 GLuint uniformBlockIndex,
3819 GLenum pname,
3820 GLint *params)
3821{
3822 return ValidateGetActiveUniformBlockivBase(context, program, uniformBlockIndex, pname, nullptr);
3823}
3824
3825bool ValidateGetActiveUniformBlockName(Context *context,
3826 GLuint program,
3827 GLuint uniformBlockIndex,
3828 GLsizei bufSize,
3829 GLsizei *length,
3830 GLchar *uniformBlockName)
3831{
3832 if (context->getClientMajorVersion() < 3)
3833 {
Jamie Madill610640f2018-11-21 17:28:41 -05003834 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003835 return false;
3836 }
3837
3838 Program *programObject = GetValidProgram(context, program);
3839 if (!programObject)
3840 {
3841 return false;
3842 }
3843
3844 if (uniformBlockIndex >= programObject->getActiveUniformBlockCount())
3845 {
Jamie Madill610640f2018-11-21 17:28:41 -05003846 context->validationError(GL_INVALID_VALUE, kErrorIndexExceedsMaxActiveUniformBlock);
Jamie Madill12e957f2017-08-26 21:42:26 -04003847 return false;
3848 }
3849
3850 return true;
3851}
3852
3853bool ValidateUniformBlockBinding(Context *context,
3854 GLuint program,
3855 GLuint uniformBlockIndex,
3856 GLuint uniformBlockBinding)
3857{
3858 if (context->getClientMajorVersion() < 3)
3859 {
Jamie Madill610640f2018-11-21 17:28:41 -05003860 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003861 return false;
3862 }
3863
3864 if (uniformBlockBinding >= context->getCaps().maxUniformBufferBindings)
3865 {
Jamie Madill610640f2018-11-21 17:28:41 -05003866 context->validationError(GL_INVALID_VALUE, kErrorIndexExceedsMaxUniformBufferBindings);
Jamie Madill12e957f2017-08-26 21:42:26 -04003867 return false;
3868 }
3869
3870 Program *programObject = GetValidProgram(context, program);
3871 if (!programObject)
3872 {
3873 return false;
3874 }
3875
3876 // if never linked, there won't be any uniform blocks
3877 if (uniformBlockIndex >= programObject->getActiveUniformBlockCount())
3878 {
Jamie Madill610640f2018-11-21 17:28:41 -05003879 context->validationError(GL_INVALID_VALUE, kErrorIndexExceedsMaxUniformBufferBindings);
Jamie Madill12e957f2017-08-26 21:42:26 -04003880 return false;
3881 }
3882
3883 return true;
3884}
3885
3886bool ValidateDrawArraysInstanced(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04003887 PrimitiveMode mode,
Jamie Madill12e957f2017-08-26 21:42:26 -04003888 GLint first,
3889 GLsizei count,
3890 GLsizei primcount)
3891{
3892 if (context->getClientMajorVersion() < 3)
3893 {
Jamie Madill610640f2018-11-21 17:28:41 -05003894 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003895 return false;
3896 }
3897
3898 return ValidateDrawArraysInstancedBase(context, mode, first, count, primcount);
3899}
3900
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003901bool ValidateFenceSync(Context *context, GLenum condition, GLbitfield flags)
3902{
3903 if (context->getClientMajorVersion() < 3)
3904 {
Jamie Madill610640f2018-11-21 17:28:41 -05003905 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003906 return false;
3907 }
3908
3909 if (condition != GL_SYNC_GPU_COMMANDS_COMPLETE)
3910 {
Jamie Madill610640f2018-11-21 17:28:41 -05003911 context->validationError(GL_INVALID_ENUM, kErrorInvalidFenceCondition);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003912 return false;
3913 }
3914
3915 if (flags != 0)
3916 {
Jamie Madill610640f2018-11-21 17:28:41 -05003917 context->validationError(GL_INVALID_VALUE, kErrorInvalidFlags);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003918 return false;
3919 }
3920
3921 return true;
3922}
3923
3924bool ValidateIsSync(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
3932 return true;
3933}
3934
3935bool ValidateDeleteSync(Context *context, GLsync sync)
3936{
3937 if (context->getClientMajorVersion() < 3)
3938 {
Jamie Madill610640f2018-11-21 17:28:41 -05003939 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003940 return false;
3941 }
3942
Jamie Madill70b5bb02017-08-28 13:32:37 -04003943 if (sync != static_cast<GLsync>(0) && !context->getSync(sync))
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003944 {
Jamie Madill610640f2018-11-21 17:28:41 -05003945 context->validationError(GL_INVALID_VALUE, kErrorSyncMissing);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003946 return false;
3947 }
3948
3949 return true;
3950}
3951
3952bool ValidateClientWaitSync(Context *context, GLsync sync, GLbitfield flags, GLuint64 timeout)
3953{
3954 if (context->getClientMajorVersion() < 3)
3955 {
Jamie Madill610640f2018-11-21 17:28:41 -05003956 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003957 return false;
3958 }
3959
3960 if ((flags & ~(GL_SYNC_FLUSH_COMMANDS_BIT)) != 0)
3961 {
Jamie Madill610640f2018-11-21 17:28:41 -05003962 context->validationError(GL_INVALID_VALUE, kErrorInvalidFlags);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003963 return false;
3964 }
3965
Jamie Madill70b5bb02017-08-28 13:32:37 -04003966 Sync *clientWaitSync = context->getSync(sync);
3967 if (!clientWaitSync)
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003968 {
Jamie Madill610640f2018-11-21 17:28:41 -05003969 context->validationError(GL_INVALID_VALUE, kErrorSyncMissing);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003970 return false;
3971 }
3972
3973 return true;
3974}
3975
3976bool ValidateWaitSync(Context *context, GLsync sync, GLbitfield flags, GLuint64 timeout)
3977{
3978 if (context->getClientMajorVersion() < 3)
3979 {
Jamie Madill610640f2018-11-21 17:28:41 -05003980 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003981 return false;
3982 }
3983
3984 if (flags != 0)
3985 {
Jamie Madill610640f2018-11-21 17:28:41 -05003986 context->validationError(GL_INVALID_VALUE, kErrorInvalidFlags);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003987 return false;
3988 }
3989
3990 if (timeout != GL_TIMEOUT_IGNORED)
3991 {
Jamie Madill610640f2018-11-21 17:28:41 -05003992 context->validationError(GL_INVALID_VALUE, kErrorInvalidTimeout);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003993 return false;
3994 }
3995
Jamie Madill70b5bb02017-08-28 13:32:37 -04003996 Sync *waitSync = context->getSync(sync);
3997 if (!waitSync)
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003998 {
Jamie Madill610640f2018-11-21 17:28:41 -05003999 context->validationError(GL_INVALID_VALUE, kErrorSyncMissing);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04004000 return false;
4001 }
4002
4003 return true;
4004}
4005
4006bool ValidateGetInteger64v(Context *context, GLenum pname, GLint64 *params)
4007{
4008 if (context->getClientMajorVersion() < 3)
4009 {
Jamie Madill610640f2018-11-21 17:28:41 -05004010 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04004011 return false;
4012 }
4013
4014 GLenum nativeType = GL_NONE;
4015 unsigned int numParams = 0;
4016 if (!ValidateStateQuery(context, pname, &nativeType, &numParams))
4017 {
4018 return false;
4019 }
4020
4021 return true;
4022}
4023
Jamie Madill3ef140a2017-08-26 23:11:21 -04004024bool ValidateIsSampler(Context *context, 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 return true;
4033}
4034
4035bool ValidateBindSampler(Context *context, GLuint unit, GLuint sampler)
4036{
4037 if (context->getClientMajorVersion() < 3)
4038 {
Jamie Madill610640f2018-11-21 17:28:41 -05004039 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill3ef140a2017-08-26 23:11:21 -04004040 return false;
4041 }
4042
4043 if (sampler != 0 && !context->isSampler(sampler))
4044 {
Jamie Madill610640f2018-11-21 17:28:41 -05004045 context->validationError(GL_INVALID_OPERATION, kErrorInvalidSampler);
Jamie Madill3ef140a2017-08-26 23:11:21 -04004046 return false;
4047 }
4048
4049 if (unit >= context->getCaps().maxCombinedTextureImageUnits)
4050 {
Jamie Madill610640f2018-11-21 17:28:41 -05004051 context->validationError(GL_INVALID_VALUE, kErrorInvalidCombinedImageUnit);
Jamie Madill3ef140a2017-08-26 23:11:21 -04004052 return false;
4053 }
4054
4055 return true;
4056}
4057
4058bool ValidateVertexAttribDivisor(Context *context, GLuint index, GLuint divisor)
4059{
4060 if (context->getClientMajorVersion() < 3)
4061 {
Jamie Madill610640f2018-11-21 17:28:41 -05004062 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill3ef140a2017-08-26 23:11:21 -04004063 return false;
4064 }
4065
4066 return ValidateVertexAttribIndex(context, index);
4067}
4068
4069bool ValidateTexStorage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004070 TextureType target,
Jamie Madill3ef140a2017-08-26 23:11:21 -04004071 GLsizei levels,
4072 GLenum internalformat,
4073 GLsizei width,
4074 GLsizei height)
4075{
4076 if (context->getClientMajorVersion() < 3)
4077 {
Jamie Madill610640f2018-11-21 17:28:41 -05004078 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill3ef140a2017-08-26 23:11:21 -04004079 return false;
4080 }
4081
4082 if (!ValidateES3TexStorage2DParameters(context, target, levels, internalformat, width, height,
4083 1))
4084 {
4085 return false;
4086 }
4087
4088 return true;
4089}
4090
4091bool ValidateTexStorage3D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004092 TextureType target,
Jamie Madill3ef140a2017-08-26 23:11:21 -04004093 GLsizei levels,
4094 GLenum internalformat,
4095 GLsizei width,
4096 GLsizei height,
4097 GLsizei depth)
4098{
4099 if (context->getClientMajorVersion() < 3)
4100 {
Jamie Madill610640f2018-11-21 17:28:41 -05004101 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill3ef140a2017-08-26 23:11:21 -04004102 return false;
4103 }
4104
4105 if (!ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
4106 depth))
4107 {
4108 return false;
4109 }
4110
4111 return true;
4112}
4113
Jamie Madill5b772312018-03-08 20:28:32 -05004114bool ValidateGetBufferParameteri64v(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004115 BufferBinding target,
Jamie Madill9696d072017-08-26 23:19:57 -04004116 GLenum pname,
4117 GLint64 *params)
4118{
4119 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
4120}
4121
4122bool ValidateGetSamplerParameterfv(Context *context, GLuint sampler, GLenum pname, GLfloat *params)
4123{
4124 return ValidateGetSamplerParameterBase(context, sampler, pname, nullptr);
4125}
4126
4127bool ValidateGetSamplerParameteriv(Context *context, GLuint sampler, GLenum pname, GLint *params)
4128{
4129 return ValidateGetSamplerParameterBase(context, sampler, pname, nullptr);
4130}
4131
Till Rathmannb8543632018-10-02 19:46:14 +02004132bool ValidateGetSamplerParameterIivOES(Context *context,
4133 GLuint sampler,
4134 GLenum pname,
Jamie Madill778bf092018-11-14 09:54:36 -05004135 GLint *params)
Till Rathmannb8543632018-10-02 19:46:14 +02004136{
4137 if (context->getClientMajorVersion() < 3)
4138 {
Jamie Madill610640f2018-11-21 17:28:41 -05004139 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02004140 return false;
4141 }
4142 return ValidateGetSamplerParameterBase(context, sampler, pname, nullptr);
4143}
4144
4145bool ValidateGetSamplerParameterIuivOES(Context *context,
4146 GLuint sampler,
4147 GLenum pname,
Jamie Madill778bf092018-11-14 09:54:36 -05004148 GLuint *params)
Till Rathmannb8543632018-10-02 19:46:14 +02004149{
4150 if (context->getClientMajorVersion() < 3)
4151 {
Jamie Madill610640f2018-11-21 17:28:41 -05004152 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02004153 return false;
4154 }
4155 return ValidateGetSamplerParameterBase(context, sampler, pname, nullptr);
4156}
4157
Jamie Madill9696d072017-08-26 23:19:57 -04004158bool ValidateSamplerParameterf(Context *context, GLuint sampler, GLenum pname, GLfloat param)
4159{
Till Rathmannb8543632018-10-02 19:46:14 +02004160 return ValidateSamplerParameterBase(context, sampler, pname, -1, false, &param);
Jamie Madill9696d072017-08-26 23:19:57 -04004161}
4162
4163bool ValidateSamplerParameterfv(Context *context,
4164 GLuint sampler,
4165 GLenum pname,
4166 const GLfloat *params)
4167{
Till Rathmannb8543632018-10-02 19:46:14 +02004168 return ValidateSamplerParameterBase(context, sampler, pname, -1, true, params);
Jamie Madill9696d072017-08-26 23:19:57 -04004169}
4170
4171bool ValidateSamplerParameteri(Context *context, GLuint sampler, GLenum pname, GLint param)
4172{
Till Rathmannb8543632018-10-02 19:46:14 +02004173 return ValidateSamplerParameterBase(context, sampler, pname, -1, false, &param);
Jamie Madill9696d072017-08-26 23:19:57 -04004174}
4175
4176bool ValidateSamplerParameteriv(Context *context, GLuint sampler, GLenum pname, const GLint *params)
4177{
Till Rathmannb8543632018-10-02 19:46:14 +02004178 return ValidateSamplerParameterBase(context, sampler, pname, -1, true, params);
4179}
4180
4181bool ValidateSamplerParameterIivOES(Context *context,
4182 GLuint sampler,
4183 GLenum pname,
4184 const GLint *params)
4185{
4186 if (context->getClientMajorVersion() < 3)
4187 {
Jamie Madill610640f2018-11-21 17:28:41 -05004188 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02004189 return false;
4190 }
4191 return ValidateSamplerParameterBase(context, sampler, pname, -1, true, params);
4192}
4193
4194bool ValidateSamplerParameterIuivOES(Context *context,
4195 GLuint sampler,
4196 GLenum pname,
4197 const GLuint *params)
4198{
4199 if (context->getClientMajorVersion() < 3)
4200 {
Jamie Madill610640f2018-11-21 17:28:41 -05004201 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02004202 return false;
4203 }
4204 return ValidateSamplerParameterBase(context, sampler, pname, -1, true, params);
Jamie Madill9696d072017-08-26 23:19:57 -04004205}
4206
4207bool ValidateGetVertexAttribIiv(Context *context, GLuint index, GLenum pname, GLint *params)
4208{
4209 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, true);
4210}
4211
4212bool ValidateGetVertexAttribIuiv(Context *context, GLuint index, GLenum pname, GLuint *params)
4213{
4214 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, true);
4215}
4216
4217bool ValidateGetInternalformativ(Context *context,
4218 GLenum target,
4219 GLenum internalformat,
4220 GLenum pname,
4221 GLsizei bufSize,
4222 GLint *params)
4223{
4224 return ValidateGetInternalFormativBase(context, target, internalformat, pname, bufSize,
4225 nullptr);
4226}
4227
Olli Etuaho0ca09752018-09-24 11:00:50 +03004228bool ValidateBindFragDataLocationIndexedEXT(Context *context,
4229 GLuint program,
4230 GLuint colorNumber,
4231 GLuint index,
4232 const char *name)
4233{
4234 if (!context->getExtensions().blendFuncExtended)
4235 {
Jamie Madill610640f2018-11-21 17:28:41 -05004236 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Olli Etuaho0ca09752018-09-24 11:00:50 +03004237 return false;
4238 }
4239 if (context->getClientMajorVersion() < 3)
4240 {
Jamie Madill610640f2018-11-21 17:28:41 -05004241 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Olli Etuaho0ca09752018-09-24 11:00:50 +03004242 return false;
4243 }
4244 if (index < 0 || index > 1)
4245 {
4246 // This error is not explicitly specified but the spec does say that "<index> may be zero or
4247 // one to specify that the color be used as either the first or second color input to the
4248 // blend equation, respectively"
Jamie Madill610640f2018-11-21 17:28:41 -05004249 context->validationError(GL_INVALID_VALUE, kErrorFragDataBindingIndexOutOfRange);
Olli Etuaho0ca09752018-09-24 11:00:50 +03004250 return false;
4251 }
4252 if (index == 1)
4253 {
4254 if (colorNumber >= context->getExtensions().maxDualSourceDrawBuffers)
4255 {
Jamie Madill610640f2018-11-21 17:28:41 -05004256 context->validationError(GL_INVALID_VALUE,
4257 kErrorColorNumberGreaterThanMaxDualSourceDrawBuffers);
Olli Etuaho0ca09752018-09-24 11:00:50 +03004258 return false;
4259 }
4260 }
4261 else
4262 {
4263 if (colorNumber >= context->getCaps().maxDrawBuffers)
4264 {
Jamie Madill610640f2018-11-21 17:28:41 -05004265 context->validationError(GL_INVALID_VALUE, kErrorColorNumberGreaterThanMaxDrawBuffers);
Olli Etuaho0ca09752018-09-24 11:00:50 +03004266 return false;
4267 }
4268 }
4269 Program *programObject = GetValidProgram(context, program);
4270 if (!programObject)
4271 {
4272 return false;
4273 }
4274 return true;
4275}
4276
4277bool ValidateBindFragDataLocationEXT(Context *context,
4278 GLuint program,
4279 GLuint colorNumber,
4280 const char *name)
4281{
4282 return ValidateBindFragDataLocationIndexedEXT(context, program, colorNumber, 0u, name);
4283}
4284
4285bool ValidateGetFragDataIndexEXT(Context *context, GLuint program, const char *name)
4286{
4287 if (!context->getExtensions().blendFuncExtended)
4288 {
Jamie Madill610640f2018-11-21 17:28:41 -05004289 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Olli Etuaho0ca09752018-09-24 11:00:50 +03004290 return false;
4291 }
4292 if (context->getClientMajorVersion() < 3)
4293 {
Jamie Madill610640f2018-11-21 17:28:41 -05004294 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Olli Etuaho0ca09752018-09-24 11:00:50 +03004295 return false;
4296 }
4297 Program *programObject = GetValidProgram(context, program);
4298 if (!programObject)
4299 {
4300 return false;
4301 }
4302 if (!programObject->isLinked())
4303 {
Jamie Madill610640f2018-11-21 17:28:41 -05004304 context->validationError(GL_INVALID_OPERATION, kErrorProgramNotLinked);
Olli Etuaho0ca09752018-09-24 11:00:50 +03004305 return false;
4306 }
4307 return true;
4308}
4309
Yizhou Jiang7818a852018-09-06 15:02:04 +08004310bool ValidateTexStorage2DMultisampleANGLE(Context *context,
4311 TextureType target,
4312 GLsizei samples,
Jamie Madill778bf092018-11-14 09:54:36 -05004313 GLenum internalFormat,
Yizhou Jiang7818a852018-09-06 15:02:04 +08004314 GLsizei width,
4315 GLsizei height,
4316 GLboolean fixedSampleLocations)
4317{
4318 if (!context->getExtensions().textureMultisample)
4319 {
Jamie Madill610640f2018-11-21 17:28:41 -05004320 context->validationError(GL_INVALID_OPERATION,
4321 kErrorMultisampleTextureExtensionOrES31Required);
Yizhou Jiang7818a852018-09-06 15:02:04 +08004322 return false;
4323 }
4324
4325 return ValidateTexStorage2DMultisampleBase(context, target, samples, internalFormat, width,
4326 height);
4327}
4328
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08004329bool ValidateGetTexLevelParameterfvANGLE(Context *context,
4330 TextureTarget target,
4331 GLint level,
4332 GLenum pname,
4333 GLfloat *params)
4334{
4335 if (!context->getExtensions().textureMultisample)
4336 {
Jamie Madill610640f2018-11-21 17:28:41 -05004337 context->validationError(GL_INVALID_OPERATION,
4338 kErrorMultisampleTextureExtensionOrES31Required);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08004339 return false;
4340 }
4341
4342 return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr);
4343}
4344
4345bool ValidateGetTexLevelParameterivANGLE(Context *context,
4346 TextureTarget target,
4347 GLint level,
4348 GLenum pname,
4349 GLint *params)
4350{
4351 if (!context->getExtensions().textureMultisample)
4352 {
Jamie Madill610640f2018-11-21 17:28:41 -05004353 context->validationError(GL_INVALID_OPERATION,
4354 kErrorMultisampleTextureExtensionOrES31Required);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08004355 return false;
4356 }
4357
4358 return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr);
4359}
4360
Jamie Madillc29968b2016-01-20 11:17:23 -05004361} // namespace gl