blob: fef519b1e03c9b2e1485d490a882c68329c87ced [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{
Jamie Madille0472f32018-11-27 16:32:45 -050028using namespace err;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040029
Martin Radev137032d2017-07-13 10:11:12 +030030namespace
31{
32bool ValidateFramebufferTextureMultiviewBaseANGLE(Context *context,
33 GLenum target,
34 GLenum attachment,
35 GLuint texture,
36 GLint level,
37 GLsizei numViews)
38{
39 if (!context->getExtensions().multiview)
40 {
Jamie Madille0472f32018-11-27 16:32:45 -050041 context->validationError(GL_INVALID_OPERATION, kMultiviewNotAvailable);
Martin Radev137032d2017-07-13 10:11:12 +030042 return false;
43 }
44
45 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
46 {
47 return false;
48 }
49
Martin Radev14b21262017-08-25 13:54:37 +030050 if (texture != 0 && numViews < 1)
Martin Radev137032d2017-07-13 10:11:12 +030051 {
Jamie Madille0472f32018-11-27 16:32:45 -050052 context->validationError(GL_INVALID_VALUE, kMultiviewViewsTooSmall);
Martin Radev137032d2017-07-13 10:11:12 +030053 return false;
54 }
55
56 const Extensions &extensions = context->getExtensions();
57 if (static_cast<GLuint>(numViews) > extensions.maxViews)
58 {
Jamie Madille0472f32018-11-27 16:32:45 -050059 context->validationError(GL_INVALID_VALUE, kMultiviewViewsTooLarge);
Martin Radev137032d2017-07-13 10:11:12 +030060 return false;
61 }
62
63 return true;
64}
65
66bool ValidateFramebufferTextureMultiviewLevelAndFormat(Context *context,
67 Texture *texture,
68 GLint level)
69{
Corentin Wallezf0e89be2017-11-08 14:00:32 -080070 TextureType type = texture->getType();
71 if (!ValidMipLevel(context, type, level))
Martin Radev137032d2017-07-13 10:11:12 +030072 {
Jamie Madille0472f32018-11-27 16:32:45 -050073 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Martin Radev137032d2017-07-13 10:11:12 +030074 return false;
75 }
76
Corentin Wallezf0e89be2017-11-08 14:00:32 -080077 const auto &format = texture->getFormat(NonCubeTextureTypeToTarget(type), level);
Martin Radev137032d2017-07-13 10:11:12 +030078 if (format.info->compressed)
79 {
Jamie Madille0472f32018-11-27 16:32:45 -050080 context->validationError(GL_INVALID_OPERATION, kCompressedTexturesNotAttachable);
Martin Radev137032d2017-07-13 10:11:12 +030081 return false;
82 }
83 return true;
84}
85
Jamie Madillff325f12017-08-26 15:06:05 -040086bool ValidateUniformES3(Context *context, GLenum uniformType, GLint location, GLint count)
87{
88 if (context->getClientMajorVersion() < 3)
89 {
Jamie Madille0472f32018-11-27 16:32:45 -050090 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madillff325f12017-08-26 15:06:05 -040091 return false;
92 }
93
94 return ValidateUniform(context, uniformType, location, count);
95}
96
Jamie Madillc8c95812017-08-26 18:40:09 -040097bool ValidateUniformMatrixES3(Context *context,
98 GLenum valueType,
99 GLint location,
100 GLsizei count,
101 GLboolean transpose)
102{
103 // Check for ES3 uniform entry points
104 if (context->getClientMajorVersion() < 3)
105 {
Jamie Madille0472f32018-11-27 16:32:45 -0500106 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madillc8c95812017-08-26 18:40:09 -0400107 return false;
108 }
109
110 return ValidateUniformMatrix(context, valueType, location, count, transpose);
111}
112
Yunchao Hef0fd87d2017-09-12 04:55:05 +0800113bool ValidateGenOrDeleteES3(Context *context, GLint n)
114{
115 if (context->getClientMajorVersion() < 3)
116 {
Jamie Madille0472f32018-11-27 16:32:45 -0500117 context->validationError(GL_INVALID_OPERATION, kES3Required);
Yunchao Hef0fd87d2017-09-12 04:55:05 +0800118 return false;
119 }
120 return ValidateGenOrDelete(context, n);
121}
122
123bool ValidateGenOrDeleteCountES3(Context *context, GLint count)
124{
125 if (context->getClientMajorVersion() < 3)
126 {
Jamie Madille0472f32018-11-27 16:32:45 -0500127 context->validationError(GL_INVALID_OPERATION, kES3Required);
Yunchao Hef0fd87d2017-09-12 04:55:05 +0800128 return false;
129 }
130 if (count < 0)
131 {
Jamie Madille0472f32018-11-27 16:32:45 -0500132 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Yunchao Hef0fd87d2017-09-12 04:55:05 +0800133 return false;
134 }
135 return true;
136}
137
Brandon Jones4e6f2ae2018-09-19 11:09:51 -0700138bool ValidateCopyTexture3DCommon(Context *context,
139 const Texture *source,
140 GLint sourceLevel,
141 GLint srcInternalFormat,
142 const Texture *dest,
143 GLint destLevel,
144 GLint internalFormat,
145 TextureTarget destTarget)
146{
147 if (context->getClientMajorVersion() < 3)
148 {
Jamie Madille0472f32018-11-27 16:32:45 -0500149 context->validationError(GL_INVALID_OPERATION, kES3Required);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -0700150 return false;
151 }
152
153 if (!context->getExtensions().copyTexture3d)
154 {
Jamie Madille0472f32018-11-27 16:32:45 -0500155 context->validationError(GL_INVALID_OPERATION, kANGLECopyTexture3DUnavailable);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -0700156 return false;
157 }
158
159 if (!ValidTexture3DTarget(context, source->getType()))
160 {
Jamie Madille0472f32018-11-27 16:32:45 -0500161 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -0700162 return false;
163 }
164
165 // Table 1.1 from the ANGLE_copy_texture_3d spec
166 switch (GetUnsizedFormat(srcInternalFormat))
167 {
168 case GL_ALPHA:
169 case GL_LUMINANCE:
170 case GL_LUMINANCE_ALPHA:
171 case GL_RED:
172 case GL_RED_INTEGER:
173 case GL_RG:
174 case GL_RG_INTEGER:
175 case GL_RGB:
176 case GL_RGB_INTEGER:
177 case GL_RGBA:
178 case GL_RGBA_INTEGER:
179 case GL_DEPTH_COMPONENT:
180 case GL_DEPTH_STENCIL:
181 break;
182 default:
Jamie Madille0472f32018-11-27 16:32:45 -0500183 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -0700184 return false;
185 }
186
187 if (!ValidTexture3DTarget(context, TextureTargetToType(destTarget)))
188 {
Jamie Madille0472f32018-11-27 16:32:45 -0500189 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -0700190 return false;
191 }
192
193 // Table 1.0 from the ANGLE_copy_texture_3d spec
194 switch (internalFormat)
195 {
196 case GL_RGB:
197 case GL_RGBA:
198 case GL_LUMINANCE:
199 case GL_LUMINANCE_ALPHA:
200 case GL_ALPHA:
201 case GL_R8:
202 case GL_R8_SNORM:
203 case GL_R16F:
204 case GL_R32F:
205 case GL_R8UI:
206 case GL_R8I:
207 case GL_R16UI:
208 case GL_R16I:
209 case GL_R32UI:
210 case GL_R32I:
211 case GL_RG:
212 case GL_RG8:
213 case GL_RG8_SNORM:
214 case GL_RG16F:
215 case GL_RG32F:
216 case GL_RG8UI:
217 case GL_RG8I:
218 case GL_RG16UI:
219 case GL_RG16I:
220 case GL_RG32UI:
221 case GL_RG32I:
222 case GL_RGB8:
223 case GL_SRGB8:
224 case GL_RGB565:
225 case GL_RGB8_SNORM:
226 case GL_R11F_G11F_B10F:
227 case GL_RGB9_E5:
228 case GL_RGB16F:
229 case GL_RGB32F:
230 case GL_RGB8UI:
231 case GL_RGB8I:
232 case GL_RGB16UI:
233 case GL_RGB16I:
234 case GL_RGB32UI:
235 case GL_RGB32I:
236 case GL_RGBA8:
237 case GL_SRGB8_ALPHA8:
238 case GL_RGBA8_SNORM:
239 case GL_RGB5_A1:
240 case GL_RGBA4:
241 case GL_RGB10_A2:
242 case GL_RGBA16F:
243 case GL_RGBA32F:
244 case GL_RGBA8UI:
245 case GL_RGBA8I:
246 case GL_RGB10_A2UI:
247 case GL_RGBA16UI:
248 case GL_RGBA16I:
249 case GL_RGBA32I:
250 case GL_RGBA32UI:
251 break;
252 default:
Jamie Madille0472f32018-11-27 16:32:45 -0500253 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -0700254 return false;
255 }
256
257 return true;
258}
Jamie Madillff325f12017-08-26 15:06:05 -0400259} // anonymous namespace
Martin Radev137032d2017-07-13 10:11:12 +0300260
He Yunchaoced53ae2016-11-29 15:00:51 +0800261static bool ValidateTexImageFormatCombination(gl::Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800262 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +0800263 GLenum internalFormat,
264 GLenum format,
265 GLenum type)
Geoff Lang5d601382014-07-22 15:14:06 -0400266{
Geoff Lang5d601382014-07-22 15:14:06 -0400267
268 // The type and format are valid if any supported internal format has that type and format
Geoff Lang6d1ccf02017-04-24 14:09:58 -0400269 if (!ValidES3Format(format))
Geoff Lang5d601382014-07-22 15:14:06 -0400270 {
Jamie Madille0472f32018-11-27 16:32:45 -0500271 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Lang6d1ccf02017-04-24 14:09:58 -0400272 return false;
273 }
274
275 if (!ValidES3Type(type))
276 {
Jamie Madille0472f32018-11-27 16:32:45 -0500277 context->validationError(GL_INVALID_ENUM, kInvalidType);
Geoff Lang6d1ccf02017-04-24 14:09:58 -0400278 return false;
279 }
280
281 // For historical reasons, glTexImage2D and glTexImage3D pass in their internal format as a
282 // GLint instead of a GLenum. Therefor an invalid internal format gives a GL_INVALID_VALUE
283 // error instead of a GL_INVALID_ENUM error. As this validation function is only called in
284 // the validation codepaths for glTexImage2D/3D, we record a GL_INVALID_VALUE error.
285 if (!ValidES3InternalFormat(internalFormat))
286 {
Jamie Madille0472f32018-11-27 16:32:45 -0500287 context->validationError(GL_INVALID_VALUE, kInvalidInternalFormat);
Geoff Langb1196682014-07-23 13:47:29 -0400288 return false;
Geoff Lang5d601382014-07-22 15:14:06 -0400289 }
290
Geoff Langca271392017-04-05 12:30:00 -0400291 // From the ES 3.0 spec section 3.8.3:
292 // Textures with a base internal format of DEPTH_COMPONENT or DEPTH_STENCIL are supported by
293 // texture image specification commands only if target is TEXTURE_2D, TEXTURE_2D_ARRAY, or
294 // TEXTURE_CUBE_MAP.Using these formats in conjunction with any other target will result in an
295 // INVALID_OPERATION error.
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800296 if (target == TextureType::_3D && (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL))
Geoff Langca271392017-04-05 12:30:00 -0400297 {
Jamie Madille0472f32018-11-27 16:32:45 -0500298 context->validationError(GL_INVALID_OPERATION, k3DDepthStencil);
Geoff Langca271392017-04-05 12:30:00 -0400299 return false;
300 }
301
Geoff Lang5d601382014-07-22 15:14:06 -0400302 // Check if this is a valid format combination to load texture data
Jamie Madill55e98212016-10-05 16:39:13 -0400303 if (!ValidES3FormatCombination(format, type, internalFormat))
Geoff Lang5d601382014-07-22 15:14:06 -0400304 {
Jamie Madille0472f32018-11-27 16:32:45 -0500305 context->validationError(GL_INVALID_OPERATION, kInvalidFormatCombination);
Geoff Lang6d1ccf02017-04-24 14:09:58 -0400306 return false;
307 }
308
309 const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat, type);
310 if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
311 {
Jamie Madille0472f32018-11-27 16:32:45 -0500312 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Langb1196682014-07-23 13:47:29 -0400313 return false;
Geoff Lang5d601382014-07-22 15:14:06 -0400314 }
315
316 return true;
317}
318
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500319bool ValidateES3TexImageParametersBase(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800320 TextureTarget target,
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500321 GLint level,
322 GLenum internalformat,
323 bool isCompressed,
324 bool isSubImage,
325 GLint xoffset,
326 GLint yoffset,
327 GLint zoffset,
328 GLsizei width,
329 GLsizei height,
330 GLsizei depth,
331 GLint border,
332 GLenum format,
333 GLenum type,
Geoff Langff5b2d52016-09-07 11:32:23 -0400334 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -0400335 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400336{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800337 TextureType texType = TextureTargetToType(target);
338
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400339 // Validate image size
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800340 if (!ValidImageSizeParameters(context, texType, level, width, height, depth, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400341 {
Jamie Madill610640f2018-11-21 17:28:41 -0500342 // Error already processed.
Geoff Langb1196682014-07-23 13:47:29 -0400343 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400344 }
345
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400346 // Verify zero border
347 if (border != 0)
348 {
Jamie Madille0472f32018-11-27 16:32:45 -0500349 context->validationError(GL_INVALID_VALUE, kInvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -0400350 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400351 }
352
Jamie Madill610640f2018-11-21 17:28:41 -0500353 if (xoffset < 0 || yoffset < 0 || zoffset < 0)
354 {
Jamie Madille0472f32018-11-27 16:32:45 -0500355 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Jamie Madill610640f2018-11-21 17:28:41 -0500356 return false;
357 }
358
359 if (std::numeric_limits<GLsizei>::max() - xoffset < width ||
Jamie Madill6f38f822014-06-06 17:12:20 -0400360 std::numeric_limits<GLsizei>::max() - yoffset < height ||
361 std::numeric_limits<GLsizei>::max() - zoffset < depth)
362 {
Jamie Madille0472f32018-11-27 16:32:45 -0500363 context->validationError(GL_INVALID_VALUE, kOffsetOverflow);
Geoff Langb1196682014-07-23 13:47:29 -0400364 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -0400365 }
366
Geoff Langaae65a42014-05-26 12:43:44 -0400367 const gl::Caps &caps = context->getCaps();
368
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800369 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400370 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800371 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +0800372 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
373 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
374 {
Jamie Madille0472f32018-11-27 16:32:45 -0500375 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
He Yunchaoced53ae2016-11-29 15:00:51 +0800376 return false;
377 }
378 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400379
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800380 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400381 ASSERT(level == 0);
382 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
383 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
384 {
Jamie Madille0472f32018-11-27 16:32:45 -0500385 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400386 return false;
387 }
388 if (isCompressed)
389 {
Jamie Madille0472f32018-11-27 16:32:45 -0500390 context->validationError(GL_INVALID_ENUM, kRectangleTextureCompressed);
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400391 return false;
392 }
393 break;
394
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800395 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +0800396 if (!isSubImage && width != height)
397 {
Jamie Madille0472f32018-11-27 16:32:45 -0500398 context->validationError(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
He Yunchaoced53ae2016-11-29 15:00:51 +0800399 return false;
400 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400401
He Yunchaoced53ae2016-11-29 15:00:51 +0800402 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level))
403 {
Jamie Madille0472f32018-11-27 16:32:45 -0500404 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
He Yunchaoced53ae2016-11-29 15:00:51 +0800405 return false;
406 }
407 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400408
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800409 case TextureType::_3D:
He Yunchaoced53ae2016-11-29 15:00:51 +0800410 if (static_cast<GLuint>(width) > (caps.max3DTextureSize >> level) ||
411 static_cast<GLuint>(height) > (caps.max3DTextureSize >> level) ||
412 static_cast<GLuint>(depth) > (caps.max3DTextureSize >> level))
413 {
Jamie Madille0472f32018-11-27 16:32:45 -0500414 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
He Yunchaoced53ae2016-11-29 15:00:51 +0800415 return false;
416 }
417 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400418
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800419 case TextureType::_2DArray:
He Yunchaoced53ae2016-11-29 15:00:51 +0800420 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
421 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level) ||
422 static_cast<GLuint>(depth) > caps.maxArrayTextureLayers)
423 {
Jamie Madille0472f32018-11-27 16:32:45 -0500424 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
He Yunchaoced53ae2016-11-29 15:00:51 +0800425 return false;
426 }
427 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400428
He Yunchaoced53ae2016-11-29 15:00:51 +0800429 default:
Jamie Madille0472f32018-11-27 16:32:45 -0500430 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +0800431 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400432 }
433
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800434 gl::Texture *texture = context->getTargetTexture(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400435 if (!texture)
436 {
Jamie Madille0472f32018-11-27 16:32:45 -0500437 context->validationError(GL_INVALID_OPERATION, kMissingTexture);
Geoff Langb1196682014-07-23 13:47:29 -0400438 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400439 }
440
Geoff Lang69cce582015-09-17 13:20:36 -0400441 if (texture->getImmutableFormat() && !isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400442 {
Jamie Madille0472f32018-11-27 16:32:45 -0500443 context->validationError(GL_INVALID_OPERATION, kTextureIsImmutable);
Geoff Langb1196682014-07-23 13:47:29 -0400444 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400445 }
446
447 // Validate texture formats
Jamie Madilla3944d42016-07-22 22:13:26 -0400448 GLenum actualInternalFormat =
Geoff Langc4e93662017-05-01 10:45:59 -0400449 isSubImage ? texture->getFormat(target, level).info->internalFormat : internalformat;
Geoff Langc51642b2016-11-14 16:18:26 -0500450 if (isSubImage && actualInternalFormat == GL_NONE)
451 {
Jamie Madill610640f2018-11-21 17:28:41 -0500452 context->validationError(GL_INVALID_OPERATION, "Texture level does not exist.");
Geoff Langc51642b2016-11-14 16:18:26 -0500453 return false;
454 }
455
Geoff Langc4e93662017-05-01 10:45:59 -0400456 const gl::InternalFormat &actualFormatInfo = isSubImage
457 ? *texture->getFormat(target, level).info
458 : GetInternalFormatInfo(internalformat, type);
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400459 if (isCompressed)
460 {
tmartino7c102692015-10-02 16:43:40 -0400461 if (!actualFormatInfo.compressed)
Geoff Langd4f180b2013-09-24 13:57:44 -0400462 {
Jamie Madill610640f2018-11-21 17:28:41 -0500463 context->validationError(
464 GL_INVALID_ENUM, "internalformat is not a supported compressed internal format.");
Geoff Langb1196682014-07-23 13:47:29 -0400465 return false;
Geoff Langd4f180b2013-09-24 13:57:44 -0400466 }
467
Geoff Lang966c9402017-04-18 12:38:27 -0400468 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400469 {
Geoff Lang966c9402017-04-18 12:38:27 -0400470 if (!ValidCompressedSubImageSize(
471 context, actualFormatInfo.internalFormat, xoffset, yoffset, width, height,
472 texture->getWidth(target, level), texture->getHeight(target, level)))
473 {
Jamie Madill610640f2018-11-21 17:28:41 -0500474 context->validationError(GL_INVALID_OPERATION,
475 "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -0400476 return false;
477 }
478
479 if (format != actualInternalFormat)
480 {
Jamie Madill610640f2018-11-21 17:28:41 -0500481 context->validationError(GL_INVALID_OPERATION,
482 "Format must match the internal format of the texture.");
Geoff Lang966c9402017-04-18 12:38:27 -0400483 return false;
484 }
Geoff Lang86f81162017-10-30 15:10:45 -0400485
486 if (actualInternalFormat == GL_ETC1_RGB8_OES)
487 {
Jamie Madille0472f32018-11-27 16:32:45 -0500488 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang86f81162017-10-30 15:10:45 -0400489 return false;
490 }
Geoff Lang966c9402017-04-18 12:38:27 -0400491 }
492 else
493 {
494 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
495 {
Jamie Madill610640f2018-11-21 17:28:41 -0500496 context->validationError(GL_INVALID_OPERATION,
497 "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -0400498 return false;
499 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400500 }
501
Geoff Langeb66a6e2016-10-31 13:06:12 -0400502 if (!actualFormatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
Geoff Lang839ce0b2015-10-23 13:13:12 -0400503 {
Jamie Madille0472f32018-11-27 16:32:45 -0500504 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Lang839ce0b2015-10-23 13:13:12 -0400505 return false;
506 }
507
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800508 if (texType == TextureType::_3D)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400509 {
Jamie Madille0472f32018-11-27 16:32:45 -0500510 context->validationError(GL_INVALID_OPERATION, kInvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -0400511 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400512 }
513 }
514 else
515 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800516 if (!ValidateTexImageFormatCombination(context, texType, actualInternalFormat, format,
517 type))
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400518 {
Geoff Lang5d601382014-07-22 15:14:06 -0400519 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400520 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400521 }
522
523 // Validate sub image parameters
524 if (isSubImage)
525 {
Geoff Langa9be0dc2014-12-17 12:34:40 -0500526 if (isCompressed != actualFormatInfo.compressed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400527 {
Jamie Madille0472f32018-11-27 16:32:45 -0500528 context->validationError(GL_INVALID_OPERATION, kCompressedMismatch);
Geoff Langb1196682014-07-23 13:47:29 -0400529 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400530 }
531
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400532 if (xoffset < 0 || yoffset < 0 || zoffset < 0)
533 {
Jamie Madille0472f32018-11-27 16:32:45 -0500534 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Geoff Langb1196682014-07-23 13:47:29 -0400535 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400536 }
537
538 if (std::numeric_limits<GLsizei>::max() - xoffset < width ||
539 std::numeric_limits<GLsizei>::max() - yoffset < height ||
540 std::numeric_limits<GLsizei>::max() - zoffset < depth)
541 {
Jamie Madille0472f32018-11-27 16:32:45 -0500542 context->validationError(GL_INVALID_VALUE, kOffsetOverflow);
Geoff Langb1196682014-07-23 13:47:29 -0400543 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400544 }
545
Geoff Langa9be0dc2014-12-17 12:34:40 -0500546 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
547 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level) ||
548 static_cast<size_t>(zoffset + depth) > texture->getDepth(target, level))
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400549 {
Jamie Madille0472f32018-11-27 16:32:45 -0500550 context->validationError(GL_INVALID_VALUE, kOffsetOverflow);
Geoff Langb1196682014-07-23 13:47:29 -0400551 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400552 }
Geoff Langfb052642017-10-24 13:42:09 -0400553
554 if (width > 0 && height > 0 && depth > 0 && pixels == nullptr &&
Corentin Wallez336129f2017-10-17 15:55:40 -0400555 context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack) == nullptr)
Geoff Langfb052642017-10-24 13:42:09 -0400556 {
Jamie Madille0472f32018-11-27 16:32:45 -0500557 context->validationError(GL_INVALID_VALUE, kPixelDataNull);
Geoff Langfb052642017-10-24 13:42:09 -0400558 return false;
559 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400560 }
561
Geoff Langdbcced82017-06-06 15:55:54 -0400562 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800563 if (!ValidImageDataSize(context, texType, width, height, depth, sizeCheckFormat, type, pixels,
Geoff Langdbcced82017-06-06 15:55:54 -0400564 imageSize))
Geoff Langff5b2d52016-09-07 11:32:23 -0400565 {
566 return false;
567 }
568
Jamie Madillefb2a6f2013-09-24 10:22:42 -0400569 // Check for pixel unpack buffer related API errors
Corentin Wallez336129f2017-10-17 15:55:40 -0400570 gl::Buffer *pixelUnpackBuffer =
571 context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack);
Corentin Wallezece7c5a2016-09-21 15:28:23 -0400572 if (pixelUnpackBuffer != nullptr)
Jamie Madillefb2a6f2013-09-24 10:22:42 -0400573 {
He Yunchaoced53ae2016-11-29 15:00:51 +0800574 // ...data is not evenly divisible into the number of bytes needed to store in memory a
575 // datum
Jamie Madillefb2a6f2013-09-24 10:22:42 -0400576 // indicated by type.
Jamie Madillc751d1e2014-10-21 17:46:29 -0400577 if (!isCompressed)
Jamie Madillefb2a6f2013-09-24 10:22:42 -0400578 {
Geoff Langff5b2d52016-09-07 11:32:23 -0400579 size_t offset = reinterpret_cast<size_t>(pixels);
Jamie Madillc751d1e2014-10-21 17:46:29 -0400580 size_t dataBytesPerPixel = static_cast<size_t>(gl::GetTypeInfo(type).bytes);
581
Geoff Langff5b2d52016-09-07 11:32:23 -0400582 if ((offset % dataBytesPerPixel) != 0)
Jamie Madillc751d1e2014-10-21 17:46:29 -0400583 {
Jamie Madill610640f2018-11-21 17:28:41 -0500584 context->validationError(GL_INVALID_OPERATION,
585 "Reads would overflow the pixel unpack buffer.");
Jamie Madillc751d1e2014-10-21 17:46:29 -0400586 return false;
587 }
Jamie Madillefb2a6f2013-09-24 10:22:42 -0400588 }
589
Jamie Madill7a5f7382014-03-05 15:01:24 -0500590 // ...the buffer object's data store is currently mapped.
Brandon Jonesd38f9262014-06-18 16:26:45 -0700591 if (pixelUnpackBuffer->isMapped())
Jamie Madill7a5f7382014-03-05 15:01:24 -0500592 {
Jamie Madill610640f2018-11-21 17:28:41 -0500593 context->validationError(GL_INVALID_OPERATION, "Pixel unpack buffer is mapped.");
Geoff Langb1196682014-07-23 13:47:29 -0400594 return false;
Jamie Madill7a5f7382014-03-05 15:01:24 -0500595 }
Jamie Madillefb2a6f2013-09-24 10:22:42 -0400596 }
597
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400598 return true;
599}
600
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500601bool ValidateES3TexImage2DParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800602 TextureTarget target,
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500603 GLint level,
604 GLenum internalformat,
605 bool isCompressed,
606 bool isSubImage,
607 GLint xoffset,
608 GLint yoffset,
609 GLint zoffset,
610 GLsizei width,
611 GLsizei height,
612 GLsizei depth,
613 GLint border,
614 GLenum format,
615 GLenum type,
Geoff Langff5b2d52016-09-07 11:32:23 -0400616 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -0400617 const void *pixels)
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500618{
619 if (!ValidTexture2DDestinationTarget(context, target))
620 {
Jamie Madille0472f32018-11-27 16:32:45 -0500621 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500622 return false;
623 }
624
625 return ValidateES3TexImageParametersBase(context, target, level, internalformat, isCompressed,
626 isSubImage, xoffset, yoffset, zoffset, width, height,
Geoff Langff5b2d52016-09-07 11:32:23 -0400627 depth, border, format, type, imageSize, pixels);
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500628}
629
630bool ValidateES3TexImage3DParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800631 TextureType target,
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500632 GLint level,
633 GLenum internalformat,
634 bool isCompressed,
635 bool isSubImage,
636 GLint xoffset,
637 GLint yoffset,
638 GLint zoffset,
639 GLsizei width,
640 GLsizei height,
641 GLsizei depth,
642 GLint border,
643 GLenum format,
644 GLenum type,
Geoff Langc52f6f12016-10-14 10:18:00 -0400645 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -0400646 const void *pixels)
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500647{
648 if (!ValidTexture3DDestinationTarget(context, target))
649 {
Jamie Madille0472f32018-11-27 16:32:45 -0500650 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500651 return false;
652 }
653
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800654 if (IsETC2EACFormat(format) && target != TextureType::_2DArray)
Luc Ferron9dbaeba2018-02-01 07:26:59 -0500655 {
656 // ES 3.1, Section 8.7, page 169.
Jamie Madille0472f32018-11-27 16:32:45 -0500657 context->validationError(GL_INVALID_OPERATION, kInternalFormatRequiresTexture2DArray);
Luc Ferron9dbaeba2018-02-01 07:26:59 -0500658 return false;
659 }
660
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800661 return ValidateES3TexImageParametersBase(context, NonCubeTextureTypeToTarget(target), level,
662 internalformat, isCompressed, isSubImage, xoffset,
663 yoffset, zoffset, width, height, depth, border, format,
664 type, bufSize, pixels);
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500665}
666
Geoff Lang5d601382014-07-22 15:14:06 -0400667struct EffectiveInternalFormatInfo
668{
Jamie Madill76648fe2016-10-05 17:01:41 -0400669 GLenum effectiveFormat;
670 GLenum destFormat;
671 GLuint minRedBits;
672 GLuint maxRedBits;
673 GLuint minGreenBits;
674 GLuint maxGreenBits;
675 GLuint minBlueBits;
676 GLuint maxBlueBits;
677 GLuint minAlphaBits;
678 GLuint maxAlphaBits;
Geoff Lang5d601382014-07-22 15:14:06 -0400679};
680
Jamie Madill76648fe2016-10-05 17:01:41 -0400681static bool QueryEffectiveFormatList(const InternalFormat &srcFormat,
682 GLenum targetFormat,
683 const EffectiveInternalFormatInfo *list,
684 size_t size,
685 GLenum *outEffectiveFormat)
Geoff Lang5d601382014-07-22 15:14:06 -0400686{
Jamie Madill76648fe2016-10-05 17:01:41 -0400687 for (size_t curFormat = 0; curFormat < size; ++curFormat)
688 {
689 const EffectiveInternalFormatInfo &formatInfo = list[curFormat];
690 if ((formatInfo.destFormat == targetFormat) &&
691 (formatInfo.minRedBits <= srcFormat.redBits &&
692 formatInfo.maxRedBits >= srcFormat.redBits) &&
693 (formatInfo.minGreenBits <= srcFormat.greenBits &&
694 formatInfo.maxGreenBits >= srcFormat.greenBits) &&
695 (formatInfo.minBlueBits <= srcFormat.blueBits &&
696 formatInfo.maxBlueBits >= srcFormat.blueBits) &&
697 (formatInfo.minAlphaBits <= srcFormat.alphaBits &&
698 formatInfo.maxAlphaBits >= srcFormat.alphaBits))
699 {
700 *outEffectiveFormat = formatInfo.effectiveFormat;
701 return true;
702 }
703 }
Geoff Lang5d601382014-07-22 15:14:06 -0400704
Jamie Madill76648fe2016-10-05 17:01:41 -0400705 *outEffectiveFormat = GL_NONE;
706 return false;
Geoff Lang5d601382014-07-22 15:14:06 -0400707}
708
Jamie Madill76648fe2016-10-05 17:01:41 -0400709bool GetSizedEffectiveInternalFormatInfo(const InternalFormat &srcFormat,
710 GLenum *outEffectiveFormat)
Geoff Lang5d601382014-07-22 15:14:06 -0400711{
Jamie Madill76648fe2016-10-05 17:01:41 -0400712 // OpenGL ES 3.0.3 Specification, Table 3.17, pg 141:
713 // Effective internal format coresponding to destination internal format and linear source
714 // buffer component sizes.
715 // | Source channel min/max sizes |
716 // Effective Internal Format | N/A | R | G | B | A |
717 // clang-format off
718 constexpr EffectiveInternalFormatInfo list[] = {
719 { GL_ALPHA8_EXT, GL_NONE, 0, 0, 0, 0, 0, 0, 1, 8 },
720 { GL_R8, GL_NONE, 1, 8, 0, 0, 0, 0, 0, 0 },
721 { GL_RG8, GL_NONE, 1, 8, 1, 8, 0, 0, 0, 0 },
722 { GL_RGB565, GL_NONE, 1, 5, 1, 6, 1, 5, 0, 0 },
723 { GL_RGB8, GL_NONE, 6, 8, 7, 8, 6, 8, 0, 0 },
724 { GL_RGBA4, GL_NONE, 1, 4, 1, 4, 1, 4, 1, 4 },
725 { GL_RGB5_A1, GL_NONE, 5, 5, 5, 5, 5, 5, 1, 1 },
726 { GL_RGBA8, GL_NONE, 5, 8, 5, 8, 5, 8, 2, 8 },
727 { GL_RGB10_A2, GL_NONE, 9, 10, 9, 10, 9, 10, 2, 2 },
728 };
729 // clang-format on
Geoff Lang5d601382014-07-22 15:14:06 -0400730
Jamie Madill76648fe2016-10-05 17:01:41 -0400731 return QueryEffectiveFormatList(srcFormat, GL_NONE, list, ArraySize(list), outEffectiveFormat);
732}
Geoff Lang5d601382014-07-22 15:14:06 -0400733
Jamie Madill76648fe2016-10-05 17:01:41 -0400734bool GetUnsizedEffectiveInternalFormatInfo(const InternalFormat &srcFormat,
735 const InternalFormat &destFormat,
736 GLenum *outEffectiveFormat)
737{
738 constexpr GLuint umax = UINT_MAX;
739
740 // OpenGL ES 3.0.3 Specification, Table 3.17, pg 141:
741 // Effective internal format coresponding to destination internal format andlinear source buffer
742 // component sizes.
743 // | Source channel min/max sizes |
744 // Effective Internal Format | Dest Format | R | G | B | A |
745 // clang-format off
746 constexpr EffectiveInternalFormatInfo list[] = {
747 { GL_ALPHA8_EXT, GL_ALPHA, 0, umax, 0, umax, 0, umax, 1, 8 },
748 { GL_LUMINANCE8_EXT, GL_LUMINANCE, 1, 8, 0, umax, 0, umax, 0, umax },
749 { GL_LUMINANCE8_ALPHA8_EXT, GL_LUMINANCE_ALPHA, 1, 8, 0, umax, 0, umax, 1, 8 },
750 { GL_RGB565, GL_RGB, 1, 5, 1, 6, 1, 5, 0, umax },
751 { GL_RGB8, GL_RGB, 6, 8, 7, 8, 6, 8, 0, umax },
752 { GL_RGBA4, GL_RGBA, 1, 4, 1, 4, 1, 4, 1, 4 },
753 { GL_RGB5_A1, GL_RGBA, 5, 5, 5, 5, 5, 5, 1, 1 },
754 { GL_RGBA8, GL_RGBA, 5, 8, 5, 8, 5, 8, 5, 8 },
755 };
756 // clang-format on
757
758 return QueryEffectiveFormatList(srcFormat, destFormat.format, list, ArraySize(list),
759 outEffectiveFormat);
Geoff Lang5d601382014-07-22 15:14:06 -0400760}
761
He Yunchaoced53ae2016-11-29 15:00:51 +0800762static bool GetEffectiveInternalFormat(const InternalFormat &srcFormat,
763 const InternalFormat &destFormat,
Geoff Lang5d601382014-07-22 15:14:06 -0400764 GLenum *outEffectiveFormat)
765{
Geoff Langca271392017-04-05 12:30:00 -0400766 if (destFormat.sized)
Geoff Lang5d601382014-07-22 15:14:06 -0400767 {
Jamie Madill76648fe2016-10-05 17:01:41 -0400768 return GetSizedEffectiveInternalFormatInfo(srcFormat, outEffectiveFormat);
Geoff Lang5d601382014-07-22 15:14:06 -0400769 }
770 else
771 {
Jamie Madill76648fe2016-10-05 17:01:41 -0400772 return GetUnsizedEffectiveInternalFormatInfo(srcFormat, destFormat, outEffectiveFormat);
Geoff Lang5d601382014-07-22 15:14:06 -0400773 }
Geoff Lang5d601382014-07-22 15:14:06 -0400774}
775
Corentin Wallez76287682016-04-25 09:23:38 -0400776static bool EqualOrFirstZero(GLuint first, GLuint second)
777{
778 return first == 0 || first == second;
779}
780
Geoff Langca271392017-04-05 12:30:00 -0400781static bool IsValidES3CopyTexImageCombination(const InternalFormat &textureFormatInfo,
782 const InternalFormat &framebufferFormatInfo,
Jamie Madill0c8abca2016-07-22 20:21:26 -0400783 GLuint readBufferHandle)
Geoff Lang5d601382014-07-22 15:14:06 -0400784{
Jamie Madill21b786b2016-11-01 17:41:31 -0400785 if (!ValidES3CopyConversion(textureFormatInfo.format, framebufferFormatInfo.format))
Geoff Lang5d601382014-07-22 15:14:06 -0400786 {
Jamie Madill21b786b2016-11-01 17:41:31 -0400787 return false;
788 }
Geoff Lang5d601382014-07-22 15:14:06 -0400789
Jamie Madill21b786b2016-11-01 17:41:31 -0400790 // Section 3.8.5 of the GLES 3.0.3 spec states that source and destination formats
791 // must both be signed, unsigned, or fixed point and both source and destinations
792 // must be either both SRGB or both not SRGB. EXT_color_buffer_float adds allowed
793 // conversion between fixed and floating point.
794
795 if ((textureFormatInfo.colorEncoding == GL_SRGB) !=
796 (framebufferFormatInfo.colorEncoding == GL_SRGB))
797 {
798 return false;
799 }
800
801 if (((textureFormatInfo.componentType == GL_INT) !=
802 (framebufferFormatInfo.componentType == GL_INT)) ||
803 ((textureFormatInfo.componentType == GL_UNSIGNED_INT) !=
804 (framebufferFormatInfo.componentType == GL_UNSIGNED_INT)))
805 {
806 return false;
807 }
808
809 if ((textureFormatInfo.componentType == GL_UNSIGNED_NORMALIZED ||
810 textureFormatInfo.componentType == GL_SIGNED_NORMALIZED ||
811 textureFormatInfo.componentType == GL_FLOAT) &&
812 !(framebufferFormatInfo.componentType == GL_UNSIGNED_NORMALIZED ||
813 framebufferFormatInfo.componentType == GL_SIGNED_NORMALIZED ||
814 framebufferFormatInfo.componentType == GL_FLOAT))
815 {
816 return false;
817 }
818
819 // GLES specification 3.0.3, sec 3.8.5, pg 139-140:
820 // The effective internal format of the source buffer is determined with the following rules
821 // applied in order:
822 // * If the source buffer is a texture or renderbuffer that was created with a sized internal
823 // format then the effective internal format is the source buffer's sized internal format.
824 // * If the source buffer is a texture that was created with an unsized base internal format,
825 // then the effective internal format is the source image array's effective internal
826 // format, as specified by table 3.12, which is determined from the <format> and <type>
827 // that were used when the source image array was specified by TexImage*.
828 // * Otherwise the effective internal format is determined by the row in table 3.17 or 3.18
829 // where Destination Internal Format matches internalformat and where the [source channel
830 // sizes] are consistent with the values of the source buffer's [channel sizes]. Table 3.17
831 // is used if the FRAMEBUFFER_ATTACHMENT_ENCODING is LINEAR and table 3.18 is used if the
832 // FRAMEBUFFER_ATTACHMENT_ENCODING is SRGB.
Yunchao Hed7297bf2017-04-19 15:27:10 +0800833 const InternalFormat *sourceEffectiveFormat = nullptr;
Jamie Madill21b786b2016-11-01 17:41:31 -0400834 if (readBufferHandle != 0)
835 {
836 // Not the default framebuffer, therefore the read buffer must be a user-created texture or
837 // renderbuffer
Geoff Langca271392017-04-05 12:30:00 -0400838 if (framebufferFormatInfo.sized)
Geoff Lang5d601382014-07-22 15:14:06 -0400839 {
Jamie Madill21b786b2016-11-01 17:41:31 -0400840 sourceEffectiveFormat = &framebufferFormatInfo;
Geoff Lang5d601382014-07-22 15:14:06 -0400841 }
Jamie Madill21b786b2016-11-01 17:41:31 -0400842 else
Geoff Lang5d601382014-07-22 15:14:06 -0400843 {
Jamie Madill21b786b2016-11-01 17:41:31 -0400844 // Renderbuffers cannot be created with an unsized internal format, so this must be an
845 // unsized-format texture. We can use the same table we use when creating textures to
846 // get its effective sized format.
Geoff Langca271392017-04-05 12:30:00 -0400847 sourceEffectiveFormat =
848 &GetSizedInternalFormatInfo(framebufferFormatInfo.sizedInternalFormat);
Geoff Lang5d601382014-07-22 15:14:06 -0400849 }
Jamie Madill21b786b2016-11-01 17:41:31 -0400850 }
851 else
852 {
853 // The effective internal format must be derived from the source framebuffer's channel
854 // sizes. This is done in GetEffectiveInternalFormat for linear buffers (table 3.17)
855 if (framebufferFormatInfo.colorEncoding == GL_LINEAR)
Geoff Lang5d601382014-07-22 15:14:06 -0400856 {
Jamie Madill21b786b2016-11-01 17:41:31 -0400857 GLenum effectiveFormat;
858 if (GetEffectiveInternalFormat(framebufferFormatInfo, textureFormatInfo,
859 &effectiveFormat))
Geoff Lang5d601382014-07-22 15:14:06 -0400860 {
Geoff Langca271392017-04-05 12:30:00 -0400861 sourceEffectiveFormat = &GetSizedInternalFormatInfo(effectiveFormat);
Geoff Lang5d601382014-07-22 15:14:06 -0400862 }
863 else
864 {
Jamie Madill21b786b2016-11-01 17:41:31 -0400865 return false;
866 }
867 }
868 else if (framebufferFormatInfo.colorEncoding == GL_SRGB)
869 {
870 // SRGB buffers can only be copied to sized format destinations according to table 3.18
Geoff Langca271392017-04-05 12:30:00 -0400871 if (textureFormatInfo.sized &&
Jamie Madill21b786b2016-11-01 17:41:31 -0400872 (framebufferFormatInfo.redBits >= 1 && framebufferFormatInfo.redBits <= 8) &&
873 (framebufferFormatInfo.greenBits >= 1 && framebufferFormatInfo.greenBits <= 8) &&
874 (framebufferFormatInfo.blueBits >= 1 && framebufferFormatInfo.blueBits <= 8) &&
875 (framebufferFormatInfo.alphaBits >= 1 && framebufferFormatInfo.alphaBits <= 8))
876 {
Geoff Langca271392017-04-05 12:30:00 -0400877 sourceEffectiveFormat = &GetSizedInternalFormatInfo(GL_SRGB8_ALPHA8);
Jamie Madill21b786b2016-11-01 17:41:31 -0400878 }
879 else
880 {
881 return false;
Geoff Lang5d601382014-07-22 15:14:06 -0400882 }
883 }
884 else
885 {
Jamie Madill21b786b2016-11-01 17:41:31 -0400886 UNREACHABLE();
887 return false;
Geoff Lang5d601382014-07-22 15:14:06 -0400888 }
Geoff Lang5d601382014-07-22 15:14:06 -0400889 }
890
Geoff Langca271392017-04-05 12:30:00 -0400891 if (textureFormatInfo.sized)
Jamie Madill21b786b2016-11-01 17:41:31 -0400892 {
893 // Section 3.8.5 of the GLES 3.0.3 spec, pg 139, requires that, if the destination format is
894 // sized, component sizes of the source and destination formats must exactly match if the
895 // destination format exists.
896 if (!EqualOrFirstZero(textureFormatInfo.redBits, sourceEffectiveFormat->redBits) ||
897 !EqualOrFirstZero(textureFormatInfo.greenBits, sourceEffectiveFormat->greenBits) ||
898 !EqualOrFirstZero(textureFormatInfo.blueBits, sourceEffectiveFormat->blueBits) ||
899 !EqualOrFirstZero(textureFormatInfo.alphaBits, sourceEffectiveFormat->alphaBits))
900 {
901 return false;
902 }
903 }
904
905 return true; // A conversion function exists, and no rule in the specification has precluded
906 // conversion between these formats.
Geoff Lang5d601382014-07-22 15:14:06 -0400907}
908
Jamie Madill5b772312018-03-08 20:28:32 -0500909bool ValidateES3CopyTexImageParametersBase(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800910 TextureTarget target,
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500911 GLint level,
912 GLenum internalformat,
913 bool isSubImage,
914 GLint xoffset,
915 GLint yoffset,
916 GLint zoffset,
917 GLint x,
918 GLint y,
919 GLsizei width,
920 GLsizei height,
921 GLint border)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400922{
Jamie Madill0c8abca2016-07-22 20:21:26 -0400923 Format textureFormat = Format::Invalid();
Jamie Madill560a8d82014-05-21 13:06:20 -0400924 if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
Jamie Madill0c8abca2016-07-22 20:21:26 -0400925 xoffset, yoffset, zoffset, x, y, width, height, border,
926 &textureFormat))
Shannon Woods4dfed832014-03-17 20:03:39 -0400927 {
Jamie Madill560a8d82014-05-21 13:06:20 -0400928 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400929 }
Jamie Madill0c8abca2016-07-22 20:21:26 -0400930 ASSERT(textureFormat.valid() || !isSubImage);
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400931
Jamie Madill51f40ec2016-06-15 14:06:00 -0400932 const auto &state = context->getGLState();
933 gl::Framebuffer *framebuffer = state.getReadFramebuffer();
934 GLuint readFramebufferID = framebuffer->id();
Jamie Madill3c7fa222014-06-05 13:08:51 -0400935
Jamie Madill427064d2018-04-13 16:20:34 -0400936 if (!ValidateFramebufferComplete(context, framebuffer))
Jamie Madill3c7fa222014-06-05 13:08:51 -0400937 {
Geoff Langb1196682014-07-23 13:47:29 -0400938 return false;
Jamie Madill3c7fa222014-06-05 13:08:51 -0400939 }
940
Jamie Madille98b1b52018-03-08 09:47:23 -0500941 if (readFramebufferID != 0 && !ValidateFramebufferNotMultisampled(context, framebuffer))
Jamie Madill3c7fa222014-06-05 13:08:51 -0400942 {
Geoff Langb1196682014-07-23 13:47:29 -0400943 return false;
Jamie Madill3c7fa222014-06-05 13:08:51 -0400944 }
945
Jamie Madill0c8abca2016-07-22 20:21:26 -0400946 const FramebufferAttachment *source = framebuffer->getReadColorbuffer();
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400947
Yunchao He096a6c82018-02-27 23:48:21 +0800948 // According to ES 3.x spec, if the internalformat of the texture
949 // is RGB9_E5 and copy to such a texture, generate INVALID_OPERATION.
950 if (textureFormat.info->internalFormat == GL_RGB9_E5)
951 {
Jamie Madille0472f32018-11-27 16:32:45 -0500952 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Yunchao He096a6c82018-02-27 23:48:21 +0800953 return false;
954 }
955
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400956 if (isSubImage)
957 {
Geoff Langca271392017-04-05 12:30:00 -0400958 if (!IsValidES3CopyTexImageCombination(*textureFormat.info, *source->getFormat().info,
Jamie Madillc29968b2016-01-20 11:17:23 -0500959 readFramebufferID))
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400960 {
Jamie Madille0472f32018-11-27 16:32:45 -0500961 context->validationError(GL_INVALID_OPERATION, kInvalidCopyCombination);
Geoff Langb1196682014-07-23 13:47:29 -0400962 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400963 }
964 }
Shannon Woods4d161ba2014-03-17 18:13:30 -0400965 else
966 {
Jamie Madill0c8abca2016-07-22 20:21:26 -0400967 // Use format/type from the source FBO. (Might not be perfect for all cases?)
Geoff Langca271392017-04-05 12:30:00 -0400968 const InternalFormat &framebufferFormat = *source->getFormat().info;
969 const InternalFormat &copyFormat = GetInternalFormatInfo(internalformat, GL_UNSIGNED_BYTE);
Jamie Madill0c8abca2016-07-22 20:21:26 -0400970 if (!IsValidES3CopyTexImageCombination(copyFormat, framebufferFormat, readFramebufferID))
Shannon Woods4d161ba2014-03-17 18:13:30 -0400971 {
Jamie Madille0472f32018-11-27 16:32:45 -0500972 context->validationError(GL_INVALID_OPERATION, kInvalidCopyCombination);
Geoff Langb1196682014-07-23 13:47:29 -0400973 return false;
Shannon Woods4d161ba2014-03-17 18:13:30 -0400974 }
975 }
976
Geoff Lang784a8fd2013-09-24 12:33:16 -0400977 // If width or height is zero, it is a no-op. Return false without setting an error.
978 return (width > 0 && height > 0);
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400979}
980
Jamie Madill5b772312018-03-08 20:28:32 -0500981bool ValidateES3CopyTexImage2DParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800982 TextureTarget target,
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500983 GLint level,
984 GLenum internalformat,
985 bool isSubImage,
986 GLint xoffset,
987 GLint yoffset,
988 GLint zoffset,
989 GLint x,
990 GLint y,
991 GLsizei width,
992 GLsizei height,
993 GLint border)
994{
995 if (!ValidTexture2DDestinationTarget(context, target))
996 {
Jamie Madille0472f32018-11-27 16:32:45 -0500997 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500998 return false;
999 }
1000
1001 return ValidateES3CopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
1002 xoffset, yoffset, zoffset, x, y, width, height,
1003 border);
1004}
1005
Jamie Madill5b772312018-03-08 20:28:32 -05001006bool ValidateES3CopyTexImage3DParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001007 TextureType target,
Ian Ewellfc7cf8e2016-01-20 15:57:46 -05001008 GLint level,
1009 GLenum internalformat,
1010 bool isSubImage,
1011 GLint xoffset,
1012 GLint yoffset,
1013 GLint zoffset,
1014 GLint x,
1015 GLint y,
1016 GLsizei width,
1017 GLsizei height,
1018 GLint border)
1019{
1020 if (!ValidTexture3DDestinationTarget(context, target))
1021 {
Jamie Madille0472f32018-11-27 16:32:45 -05001022 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Ian Ewellfc7cf8e2016-01-20 15:57:46 -05001023 return false;
1024 }
1025
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001026 return ValidateES3CopyTexImageParametersBase(context, NonCubeTextureTypeToTarget(target), level,
1027 internalformat, isSubImage, xoffset, yoffset,
1028 zoffset, x, y, width, height, border);
Ian Ewellfc7cf8e2016-01-20 15:57:46 -05001029}
1030
1031bool ValidateES3TexStorageParametersBase(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001032 TextureType target,
Ian Ewellfc7cf8e2016-01-20 15:57:46 -05001033 GLsizei levels,
1034 GLenum internalformat,
1035 GLsizei width,
1036 GLsizei height,
1037 GLsizei depth)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001038{
1039 if (width < 1 || height < 1 || depth < 1 || levels < 1)
1040 {
Jamie Madille0472f32018-11-27 16:32:45 -05001041 context->validationError(GL_INVALID_VALUE, kTextureSizeTooSmall);
Geoff Langb1196682014-07-23 13:47:29 -04001042 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001043 }
1044
Geoff Langb92c1332015-09-04 12:54:55 -04001045 GLsizei maxDim = std::max(width, height);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001046 if (target != TextureType::_2DArray)
Geoff Langb92c1332015-09-04 12:54:55 -04001047 {
1048 maxDim = std::max(maxDim, depth);
1049 }
1050
1051 if (levels > gl::log2(maxDim) + 1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001052 {
Jamie Madille0472f32018-11-27 16:32:45 -05001053 context->validationError(GL_INVALID_OPERATION, kInvalidMipLevels);
Geoff Langb1196682014-07-23 13:47:29 -04001054 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001055 }
1056
Geoff Langaae65a42014-05-26 12:43:44 -04001057 const gl::Caps &caps = context->getCaps();
1058
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001059 switch (target)
1060 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001061 case TextureType::_2D:
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001062 {
Geoff Langaae65a42014-05-26 12:43:44 -04001063 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1064 static_cast<GLuint>(height) > caps.max2DTextureSize)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001065 {
Jamie Madille0472f32018-11-27 16:32:45 -05001066 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001067 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001068 }
1069 }
1070 break;
1071
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001072 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001073 {
Jamie Madill610640f2018-11-21 17:28:41 -05001074 if (levels != 1)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001075 {
Jamie Madille0472f32018-11-27 16:32:45 -05001076 context->validationError(GL_INVALID_VALUE, kInvalidMipLevels);
Jamie Madill610640f2018-11-21 17:28:41 -05001077 return false;
1078 }
1079
1080 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1081 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1082 {
Jamie Madille0472f32018-11-27 16:32:45 -05001083 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001084 return false;
1085 }
1086 }
1087 break;
1088
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001089 case TextureType::CubeMap:
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001090 {
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001091 if (width != height)
1092 {
Jamie Madille0472f32018-11-27 16:32:45 -05001093 context->validationError(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
Geoff Langb1196682014-07-23 13:47:29 -04001094 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001095 }
1096
Geoff Langaae65a42014-05-26 12:43:44 -04001097 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001098 {
Jamie Madille0472f32018-11-27 16:32:45 -05001099 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001100 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001101 }
1102 }
1103 break;
1104
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001105 case TextureType::_3D:
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001106 {
Geoff Langaae65a42014-05-26 12:43:44 -04001107 if (static_cast<GLuint>(width) > caps.max3DTextureSize ||
1108 static_cast<GLuint>(height) > caps.max3DTextureSize ||
1109 static_cast<GLuint>(depth) > caps.max3DTextureSize)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001110 {
Jamie Madille0472f32018-11-27 16:32:45 -05001111 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001112 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001113 }
1114 }
1115 break;
1116
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001117 case TextureType::_2DArray:
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001118 {
Geoff Langaae65a42014-05-26 12:43:44 -04001119 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1120 static_cast<GLuint>(height) > caps.max2DTextureSize ||
1121 static_cast<GLuint>(depth) > caps.maxArrayTextureLayers)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001122 {
Jamie Madille0472f32018-11-27 16:32:45 -05001123 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001124 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001125 }
1126 }
1127 break;
1128
He Yunchaoced53ae2016-11-29 15:00:51 +08001129 default:
1130 UNREACHABLE();
1131 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001132 }
1133
Geoff Lang691e58c2014-12-19 17:03:25 -05001134 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001135 if (!texture || texture->id() == 0)
1136 {
Jamie Madille0472f32018-11-27 16:32:45 -05001137 context->validationError(GL_INVALID_OPERATION, kMissingTexture);
Geoff Langb1196682014-07-23 13:47:29 -04001138 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001139 }
1140
Geoff Lang69cce582015-09-17 13:20:36 -04001141 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001142 {
Jamie Madille0472f32018-11-27 16:32:45 -05001143 context->validationError(GL_INVALID_OPERATION, kTextureIsImmutable);
Geoff Langb1196682014-07-23 13:47:29 -04001144 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001145 }
1146
Geoff Langca271392017-04-05 12:30:00 -04001147 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Langeb66a6e2016-10-31 13:06:12 -04001148 if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001149 {
Jamie Madille0472f32018-11-27 16:32:45 -05001150 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001151 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001152 }
1153
Geoff Langca271392017-04-05 12:30:00 -04001154 if (!formatInfo.sized)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001155 {
Jamie Madille0472f32018-11-27 16:32:45 -05001156 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001157 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001158 }
1159
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001160 if (formatInfo.compressed && target == TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001161 {
Jamie Madille0472f32018-11-27 16:32:45 -05001162 context->validationError(GL_INVALID_ENUM, kRectangleTextureCompressed);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001163 return false;
1164 }
1165
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001166 return true;
1167}
1168
Ian Ewellfc7cf8e2016-01-20 15:57:46 -05001169bool ValidateES3TexStorage2DParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001170 TextureType target,
Ian Ewellfc7cf8e2016-01-20 15:57:46 -05001171 GLsizei levels,
1172 GLenum internalformat,
1173 GLsizei width,
1174 GLsizei height,
1175 GLsizei depth)
1176{
1177 if (!ValidTexture2DTarget(context, target))
1178 {
Jamie Madille0472f32018-11-27 16:32:45 -05001179 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Ian Ewellfc7cf8e2016-01-20 15:57:46 -05001180 return false;
1181 }
1182
1183 return ValidateES3TexStorageParametersBase(context, target, levels, internalformat, width,
1184 height, depth);
1185}
1186
1187bool ValidateES3TexStorage3DParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001188 TextureType target,
Ian Ewellfc7cf8e2016-01-20 15:57:46 -05001189 GLsizei levels,
1190 GLenum internalformat,
1191 GLsizei width,
1192 GLsizei height,
1193 GLsizei depth)
1194{
1195 if (!ValidTexture3DTarget(context, target))
1196 {
Jamie Madille0472f32018-11-27 16:32:45 -05001197 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Ian Ewellfc7cf8e2016-01-20 15:57:46 -05001198 return false;
1199 }
1200
1201 return ValidateES3TexStorageParametersBase(context, target, levels, internalformat, width,
1202 height, depth);
1203}
1204
Corentin Wallezad3ae902018-03-09 13:40:42 -05001205bool ValidateBeginQuery(gl::Context *context, QueryType target, GLuint id)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001206{
Martin Radev1be913c2016-07-11 17:59:16 +03001207 if (context->getClientMajorVersion() < 3)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001208 {
Jamie Madille0472f32018-11-27 16:32:45 -05001209 context->validationError(GL_INVALID_OPERATION, kES3Required);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001210 return false;
1211 }
1212
1213 return ValidateBeginQueryBase(context, target, id);
1214}
1215
Corentin Wallezad3ae902018-03-09 13:40:42 -05001216bool ValidateEndQuery(gl::Context *context, QueryType target)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001217{
Martin Radev1be913c2016-07-11 17:59:16 +03001218 if (context->getClientMajorVersion() < 3)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001219 {
Jamie Madille0472f32018-11-27 16:32:45 -05001220 context->validationError(GL_INVALID_OPERATION, kES3Required);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001221 return false;
1222 }
1223
1224 return ValidateEndQueryBase(context, target);
1225}
1226
Corentin Wallezad3ae902018-03-09 13:40:42 -05001227bool ValidateGetQueryiv(Context *context, QueryType target, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001228{
Martin Radev1be913c2016-07-11 17:59:16 +03001229 if (context->getClientMajorVersion() < 3)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001230 {
Jamie Madille0472f32018-11-27 16:32:45 -05001231 context->validationError(GL_INVALID_OPERATION, kES3Required);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001232 return false;
1233 }
1234
Geoff Lang2186c382016-10-14 10:54:54 -04001235 return ValidateGetQueryivBase(context, target, pname, nullptr);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001236}
1237
1238bool ValidateGetQueryObjectuiv(Context *context, GLuint id, GLenum pname, GLuint *params)
1239{
Martin Radev1be913c2016-07-11 17:59:16 +03001240 if (context->getClientMajorVersion() < 3)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001241 {
Jamie Madille0472f32018-11-27 16:32:45 -05001242 context->validationError(GL_INVALID_OPERATION, kES3Required);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001243 return false;
1244 }
1245
Geoff Lang2186c382016-10-14 10:54:54 -04001246 return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001247}
1248
He Yunchaoced53ae2016-11-29 15:00:51 +08001249bool ValidateFramebufferTextureLayer(Context *context,
1250 GLenum target,
1251 GLenum attachment,
1252 GLuint texture,
1253 GLint level,
1254 GLint layer)
Jamie Madill570f7c82014-07-03 10:38:54 -04001255{
Martin Radev1be913c2016-07-11 17:59:16 +03001256 if (context->getClientMajorVersion() < 3)
Jamie Madill570f7c82014-07-03 10:38:54 -04001257 {
Jamie Madille0472f32018-11-27 16:32:45 -05001258 context->validationError(GL_INVALID_OPERATION, kES3Required);
Geoff Langb1196682014-07-23 13:47:29 -04001259 return false;
Jamie Madill570f7c82014-07-03 10:38:54 -04001260 }
1261
Jamie Madill55ec3b12014-07-03 10:38:57 -04001262 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
1263 {
1264 return false;
1265 }
1266
1267 const gl::Caps &caps = context->getCaps();
1268 if (texture != 0)
1269 {
Geoff Lang23e02842017-10-17 13:24:09 -04001270 if (layer < 0)
1271 {
Jamie Madille0472f32018-11-27 16:32:45 -05001272 context->validationError(GL_INVALID_VALUE, kNegativeLayer);
Geoff Lang23e02842017-10-17 13:24:09 -04001273 return false;
1274 }
1275
Jamie Madill55ec3b12014-07-03 10:38:57 -04001276 gl::Texture *tex = context->getTexture(texture);
1277 ASSERT(tex);
1278
Corentin Wallez99d492c2018-02-27 15:17:10 -05001279 switch (tex->getType())
Jamie Madill55ec3b12014-07-03 10:38:57 -04001280 {
Corentin Wallez99d492c2018-02-27 15:17:10 -05001281 case TextureType::_2DArray:
Jamie Madill55ec3b12014-07-03 10:38:57 -04001282 {
1283 if (level > gl::log2(caps.max2DTextureSize))
1284 {
Jamie Madille0472f32018-11-27 16:32:45 -05001285 context->validationError(GL_INVALID_VALUE, kFramebufferTextureInvalidMipLevel);
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 Madille0472f32018-11-27 16:32:45 -05001291 context->validationError(GL_INVALID_VALUE, kFramebufferTextureInvalidLayer);
Geoff Langb1196682014-07-23 13:47:29 -04001292 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04001293 }
Jamie Madill55ec3b12014-07-03 10:38:57 -04001294 }
1295 break;
1296
Corentin Wallez99d492c2018-02-27 15:17:10 -05001297 case TextureType::_3D:
Jamie Madill55ec3b12014-07-03 10:38:57 -04001298 {
1299 if (level > gl::log2(caps.max3DTextureSize))
1300 {
Jamie Madille0472f32018-11-27 16:32:45 -05001301 context->validationError(GL_INVALID_VALUE, kFramebufferTextureInvalidMipLevel);
Geoff Langb1196682014-07-23 13:47:29 -04001302 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04001303 }
1304
1305 if (static_cast<GLuint>(layer) >= caps.max3DTextureSize)
1306 {
Jamie Madille0472f32018-11-27 16:32:45 -05001307 context->validationError(GL_INVALID_VALUE, kFramebufferTextureInvalidLayer);
Olli Etuahofd162102018-08-27 16:14:57 +03001308 return false;
1309 }
1310 }
1311 break;
1312
1313 case TextureType::_2DMultisampleArray:
1314 {
1315 if (level != 0)
1316 {
Jamie Madille0472f32018-11-27 16:32:45 -05001317 context->validationError(GL_INVALID_VALUE, kFramebufferTextureInvalidMipLevel);
Olli Etuahofd162102018-08-27 16:14:57 +03001318 return false;
1319 }
1320
1321 if (static_cast<GLuint>(layer) >= caps.maxArrayTextureLayers)
1322 {
Jamie Madille0472f32018-11-27 16:32:45 -05001323 context->validationError(GL_INVALID_VALUE, kFramebufferTextureInvalidLayer);
Geoff Langb1196682014-07-23 13:47:29 -04001324 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04001325 }
Jamie Madill55ec3b12014-07-03 10:38:57 -04001326 }
1327 break;
1328
He Yunchaoced53ae2016-11-29 15:00:51 +08001329 default:
Jamie Madill610640f2018-11-21 17:28:41 -05001330 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05001331 kFramebufferTextureLayerIncorrectTextureType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001332 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04001333 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001334
Corentin Wallez99d492c2018-02-27 15:17:10 -05001335 const auto &format = tex->getFormat(NonCubeTextureTypeToTarget(tex->getType()), level);
Jamie Madilla3944d42016-07-22 22:13:26 -04001336 if (format.info->compressed)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001337 {
Jamie Madille0472f32018-11-27 16:32:45 -05001338 context->validationError(GL_INVALID_OPERATION, kCompressedTexturesNotAttachable);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001339 return false;
1340 }
Jamie Madill55ec3b12014-07-03 10:38:57 -04001341 }
1342
1343 return true;
Jamie Madill570f7c82014-07-03 10:38:54 -04001344}
1345
He Yunchaoced53ae2016-11-29 15:00:51 +08001346bool ValidateInvalidateFramebuffer(Context *context,
1347 GLenum target,
1348 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001349 const GLenum *attachments)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001350{
Martin Radev1be913c2016-07-11 17:59:16 +03001351 if (context->getClientMajorVersion() < 3)
Austin Kinross08332632015-05-05 13:35:47 -07001352 {
Jamie Madille0472f32018-11-27 16:32:45 -05001353 context->validationError(GL_INVALID_OPERATION, kES3Required);
Austin Kinross08332632015-05-05 13:35:47 -07001354 return false;
1355 }
1356
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001357 bool defaultFramebuffer = false;
1358
1359 switch (target)
1360 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001361 case GL_DRAW_FRAMEBUFFER:
1362 case GL_FRAMEBUFFER:
1363 defaultFramebuffer = context->getGLState().getDrawFramebuffer()->id() == 0;
1364 break;
1365 case GL_READ_FRAMEBUFFER:
1366 defaultFramebuffer = context->getGLState().getReadFramebuffer()->id() == 0;
1367 break;
1368 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001369 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001370 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001371 }
1372
He Yunchaoced53ae2016-11-29 15:00:51 +08001373 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1374 defaultFramebuffer);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001375}
1376
Jamie Madill3ef140a2017-08-26 23:11:21 -04001377bool ValidateInvalidateSubFramebuffer(Context *context,
1378 GLenum target,
1379 GLsizei numAttachments,
1380 const GLenum *attachments,
1381 GLint x,
1382 GLint y,
1383 GLsizei width,
1384 GLsizei height)
1385{
Yunchao He2f3a0dc2018-02-27 22:39:44 +08001386 if (width < 0 || height < 0)
1387 {
Jamie Madille0472f32018-11-27 16:32:45 -05001388 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Yunchao He2f3a0dc2018-02-27 22:39:44 +08001389 return false;
1390 }
1391
Jamie Madill3ef140a2017-08-26 23:11:21 -04001392 return ValidateInvalidateFramebuffer(context, target, numAttachments, attachments);
1393}
1394
Jamie Madill5b772312018-03-08 20:28:32 -05001395bool ValidateClearBuffer(Context *context)
Jamie Madill13f7d7d2014-06-20 13:21:27 -04001396{
Martin Radev1be913c2016-07-11 17:59:16 +03001397 if (context->getClientMajorVersion() < 3)
Jamie Madill13f7d7d2014-06-20 13:21:27 -04001398 {
Jamie Madille0472f32018-11-27 16:32:45 -05001399 context->validationError(GL_INVALID_OPERATION, kES3Required);
Geoff Langb1196682014-07-23 13:47:29 -04001400 return false;
Jamie Madill13f7d7d2014-06-20 13:21:27 -04001401 }
1402
Jamie Madill427064d2018-04-13 16:20:34 -04001403 if (!ValidateFramebufferComplete(context, context->getGLState().getDrawFramebuffer()))
Jamie Madill13f7d7d2014-06-20 13:21:27 -04001404 {
Geoff Langb1196682014-07-23 13:47:29 -04001405 return false;
Jamie Madill13f7d7d2014-06-20 13:21:27 -04001406 }
1407
1408 return true;
1409}
1410
Olli Etuaho71dfb362016-03-10 14:04:27 +02001411bool ValidateDrawRangeElements(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04001412 PrimitiveMode mode,
Olli Etuaho71dfb362016-03-10 14:04:27 +02001413 GLuint start,
1414 GLuint end,
1415 GLsizei count,
Jamie Madill8dc27f92018-11-29 11:45:44 -05001416 DrawElementsType type,
Jamie Madill876429b2017-04-20 15:46:24 -04001417 const void *indices)
Olli Etuaho71dfb362016-03-10 14:04:27 +02001418{
Martin Radev1be913c2016-07-11 17:59:16 +03001419 if (context->getClientMajorVersion() < 3)
Olli Etuaho71dfb362016-03-10 14:04:27 +02001420 {
Jamie Madille0472f32018-11-27 16:32:45 -05001421 context->validationError(GL_INVALID_OPERATION, kES3Required);
Olli Etuaho71dfb362016-03-10 14:04:27 +02001422 return false;
1423 }
1424
1425 if (end < start)
1426 {
Jamie Madill610640f2018-11-21 17:28:41 -05001427 context->validationError(GL_INVALID_VALUE, "end < start");
Olli Etuaho71dfb362016-03-10 14:04:27 +02001428 return false;
1429 }
1430
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001431 if (!ValidateDrawElementsCommon(context, mode, count, type, indices, 0))
Olli Etuaho71dfb362016-03-10 14:04:27 +02001432 {
1433 return false;
1434 }
1435
Jamie Madill9fdaa492018-02-16 10:52:11 -05001436 // Skip range checks for no-op calls.
1437 if (count <= 0)
1438 {
1439 return true;
1440 }
1441
Jamie Madillc1fd7372018-10-26 22:48:39 -04001442 // Note that resolving the index range is a bit slow. We should probably optimize this.
1443 IndexRange indexRange;
1444 ANGLE_VALIDATION_TRY(context->getGLState().getVertexArray()->getIndexRange(
1445 context, type, count, indices, &indexRange));
Jamie Madill6f5444d2018-03-14 10:08:11 -04001446
1447 if (indexRange.end > end || indexRange.start < start)
Olli Etuaho71dfb362016-03-10 14:04:27 +02001448 {
1449 // GL spec says that behavior in this case is undefined - generating an error is fine.
Jamie Madill610640f2018-11-21 17:28:41 -05001450 context->validationError(GL_INVALID_OPERATION, "Indices are out of the start, end range.");
Olli Etuaho71dfb362016-03-10 14:04:27 +02001451 return false;
1452 }
1453 return true;
1454}
1455
He Yunchaoced53ae2016-11-29 15:00:51 +08001456bool ValidateGetUniformuiv(Context *context, GLuint program, GLint location, GLuint *params)
Jamie Madill0063c512014-08-25 15:47:53 -04001457{
Martin Radev1be913c2016-07-11 17:59:16 +03001458 if (context->getClientMajorVersion() < 3)
Jamie Madill0063c512014-08-25 15:47:53 -04001459 {
Jamie Madille0472f32018-11-27 16:32:45 -05001460 context->validationError(GL_INVALID_OPERATION, kES3Required);
Geoff Langb1196682014-07-23 13:47:29 -04001461 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04001462 }
1463
Jamie Madill78f41802014-08-25 15:47:55 -04001464 return ValidateGetUniformBase(context, program, location);
Jamie Madill0063c512014-08-25 15:47:53 -04001465}
1466
Jamie Madillb885e572015-02-03 16:16:04 -05001467bool ValidateReadBuffer(Context *context, GLenum src)
1468{
Martin Radev1be913c2016-07-11 17:59:16 +03001469 if (context->getClientMajorVersion() < 3)
Jamie Madillb885e572015-02-03 16:16:04 -05001470 {
Jamie Madille0472f32018-11-27 16:32:45 -05001471 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madillb885e572015-02-03 16:16:04 -05001472 return false;
1473 }
1474
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001475 const Framebuffer *readFBO = context->getGLState().getReadFramebuffer();
Jamie Madillb885e572015-02-03 16:16:04 -05001476
1477 if (readFBO == nullptr)
1478 {
Jamie Madill610640f2018-11-21 17:28:41 -05001479 context->validationError(GL_INVALID_OPERATION, "No active read framebuffer.");
Jamie Madillb885e572015-02-03 16:16:04 -05001480 return false;
1481 }
1482
1483 if (src == GL_NONE)
1484 {
1485 return true;
1486 }
1487
Olli Etuaho84c9f592016-03-09 14:37:25 +02001488 if (src != GL_BACK && (src < GL_COLOR_ATTACHMENT0 || src > GL_COLOR_ATTACHMENT31))
Jamie Madillb885e572015-02-03 16:16:04 -05001489 {
Jamie Madill610640f2018-11-21 17:28:41 -05001490 context->validationError(GL_INVALID_ENUM, "Unknown enum for 'src' in ReadBuffer");
Jamie Madillb885e572015-02-03 16:16:04 -05001491 return false;
1492 }
1493
1494 if (readFBO->id() == 0)
1495 {
1496 if (src != GL_BACK)
1497 {
Jamie Madill610640f2018-11-21 17:28:41 -05001498 context->validationError(
1499 GL_INVALID_OPERATION,
1500 "'src' must be GL_NONE or GL_BACK when reading from the default framebuffer.");
Jamie Madillb885e572015-02-03 16:16:04 -05001501 return false;
1502 }
1503 }
1504 else
1505 {
1506 GLuint drawBuffer = static_cast<GLuint>(src - GL_COLOR_ATTACHMENT0);
1507
1508 if (drawBuffer >= context->getCaps().maxDrawBuffers)
1509 {
Jamie Madill610640f2018-11-21 17:28:41 -05001510 context->validationError(GL_INVALID_OPERATION,
1511 "'src' is greater than MAX_DRAW_BUFFERS.");
Jamie Madillb885e572015-02-03 16:16:04 -05001512 return false;
1513 }
1514 }
1515
1516 return true;
1517}
1518
Jamie Madill86af3d22015-07-21 15:14:07 -04001519bool ValidateCompressedTexImage3D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001520 TextureType target,
Jamie Madill86af3d22015-07-21 15:14:07 -04001521 GLint level,
1522 GLenum internalformat,
1523 GLsizei width,
1524 GLsizei height,
1525 GLsizei depth,
1526 GLint border,
1527 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001528 const void *data)
Jamie Madill86af3d22015-07-21 15:14:07 -04001529{
Martin Radev1be913c2016-07-11 17:59:16 +03001530 if (context->getClientMajorVersion() < 3)
Jamie Madill86af3d22015-07-21 15:14:07 -04001531 {
Jamie Madille0472f32018-11-27 16:32:45 -05001532 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill86af3d22015-07-21 15:14:07 -04001533 return false;
1534 }
1535
Jamie Madill4b4cdff2016-06-06 13:53:38 -07001536 if (!ValidTextureTarget(context, target))
1537 {
Jamie Madille0472f32018-11-27 16:32:45 -05001538 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madill4b4cdff2016-06-06 13:53:38 -07001539 return false;
1540 }
1541
Jamie Madille2e406c2016-06-02 13:04:10 -04001542 // Validate image size
1543 if (!ValidImageSizeParameters(context, target, level, width, height, depth, false))
1544 {
Jamie Madill610640f2018-11-21 17:28:41 -05001545 // Error already generated.
Jamie Madille2e406c2016-06-02 13:04:10 -04001546 return false;
1547 }
1548
Geoff Langca271392017-04-05 12:30:00 -04001549 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jamie Madill4b4cdff2016-06-06 13:53:38 -07001550 if (!formatInfo.compressed)
1551 {
Jamie Madille0472f32018-11-27 16:32:45 -05001552 context->validationError(GL_INVALID_ENUM, kInvalidCompressedFormat);
Jamie Madill4b4cdff2016-06-06 13:53:38 -07001553 return false;
1554 }
1555
Jamie Madillca2ff382018-07-11 09:01:17 -04001556 GLuint blockSize = 0;
1557 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, depth), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04001558 {
Jamie Madille0472f32018-11-27 16:32:45 -05001559 context->validationError(GL_INVALID_VALUE, kIntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04001560 return false;
1561 }
Jamie Madillca2ff382018-07-11 09:01:17 -04001562
1563 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill86af3d22015-07-21 15:14:07 -04001564 {
Jamie Madille0472f32018-11-27 16:32:45 -05001565 context->validationError(GL_INVALID_VALUE, kInvalidCompressedImageSize);
Jamie Madill86af3d22015-07-21 15:14:07 -04001566 return false;
1567 }
1568
1569 // 3D texture target validation
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001570 if (target != TextureType::_3D && target != TextureType::_2DArray)
Jamie Madill86af3d22015-07-21 15:14:07 -04001571 {
Jamie Madill610640f2018-11-21 17:28:41 -05001572 context->validationError(GL_INVALID_ENUM,
1573 "Must specify a valid 3D texture destination target");
Jamie Madill86af3d22015-07-21 15:14:07 -04001574 return false;
1575 }
1576
1577 // validateES3TexImageFormat sets the error code if there is an error
Ian Ewellfc7cf8e2016-01-20 15:57:46 -05001578 if (!ValidateES3TexImage3DParameters(context, target, level, internalformat, true, false, 0, 0,
Geoff Langc52f6f12016-10-14 10:18:00 -04001579 0, width, height, depth, border, GL_NONE, GL_NONE, -1,
1580 data))
Jamie Madill86af3d22015-07-21 15:14:07 -04001581 {
1582 return false;
1583 }
1584
1585 return true;
1586}
Austin Kinrossbc781f32015-10-26 09:27:38 -07001587
Corentin Wallezb2931602017-04-11 15:58:57 -04001588bool ValidateCompressedTexImage3DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001589 TextureType target,
Corentin Wallezb2931602017-04-11 15:58:57 -04001590 GLint level,
1591 GLenum internalformat,
1592 GLsizei width,
1593 GLsizei height,
1594 GLsizei depth,
1595 GLint border,
1596 GLsizei imageSize,
1597 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001598 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04001599{
1600 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
1601 {
1602 return false;
1603 }
1604
1605 return ValidateCompressedTexImage3D(context, target, level, internalformat, width, height,
1606 depth, border, imageSize, data);
1607}
1608
Austin Kinrossbc781f32015-10-26 09:27:38 -07001609bool ValidateBindVertexArray(Context *context, GLuint array)
1610{
Martin Radev1be913c2016-07-11 17:59:16 +03001611 if (context->getClientMajorVersion() < 3)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001612 {
Jamie Madille0472f32018-11-27 16:32:45 -05001613 context->validationError(GL_INVALID_OPERATION, kES3Required);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001614 return false;
1615 }
1616
1617 return ValidateBindVertexArrayBase(context, array);
1618}
1619
Jamie Madilld7576732017-08-26 18:49:50 -04001620bool ValidateIsVertexArray(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001621{
Martin Radev1be913c2016-07-11 17:59:16 +03001622 if (context->getClientMajorVersion() < 3)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001623 {
Jamie Madille0472f32018-11-27 16:32:45 -05001624 context->validationError(GL_INVALID_OPERATION, kES3Required);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001625 return false;
1626 }
1627
1628 return true;
1629}
Geoff Langc5629752015-12-07 16:29:04 -05001630
Jiajia Qin6eafb042016-12-27 17:04:07 +08001631static bool ValidateBindBufferCommon(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04001632 BufferBinding target,
Jiajia Qin6eafb042016-12-27 17:04:07 +08001633 GLuint index,
1634 GLuint buffer,
1635 GLintptr offset,
1636 GLsizeiptr size)
1637{
1638 if (context->getClientMajorVersion() < 3)
1639 {
Jamie Madille0472f32018-11-27 16:32:45 -05001640 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001641 return false;
1642 }
1643
1644 if (buffer != 0 && offset < 0)
1645 {
Jamie Madill610640f2018-11-21 17:28:41 -05001646 context->validationError(GL_INVALID_VALUE, "buffer is non-zero and offset is negative.");
Jiajia Qin6eafb042016-12-27 17:04:07 +08001647 return false;
1648 }
1649
1650 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
1651 !context->isBufferGenerated(buffer))
1652 {
Jamie Madill610640f2018-11-21 17:28:41 -05001653 context->validationError(GL_INVALID_OPERATION, "Buffer was not generated.");
Jiajia Qin6eafb042016-12-27 17:04:07 +08001654 return false;
1655 }
1656
1657 const Caps &caps = context->getCaps();
1658 switch (target)
1659 {
Corentin Wallez336129f2017-10-17 15:55:40 -04001660 case BufferBinding::TransformFeedback:
Jiajia Qin6eafb042016-12-27 17:04:07 +08001661 {
1662 if (index >= caps.maxTransformFeedbackSeparateAttributes)
1663 {
Jamie Madill610640f2018-11-21 17:28:41 -05001664 context->validationError(GL_INVALID_VALUE,
1665 "index is greater than or equal to the "
1666 "number of TRANSFORM_FEEDBACK_BUFFER "
1667 "indexed binding points.");
Jiajia Qin6eafb042016-12-27 17:04:07 +08001668 return false;
1669 }
1670 if (buffer != 0 && ((offset % 4) != 0 || (size % 4) != 0))
1671 {
Jamie Madill610640f2018-11-21 17:28:41 -05001672 context->validationError(GL_INVALID_VALUE,
1673 "offset and size must be multiple of 4.");
Jiajia Qin6eafb042016-12-27 17:04:07 +08001674 return false;
1675 }
1676
1677 TransformFeedback *curTransformFeedback =
1678 context->getGLState().getCurrentTransformFeedback();
1679 if (curTransformFeedback && curTransformFeedback->isActive())
1680 {
Jamie Madill610640f2018-11-21 17:28:41 -05001681 context->validationError(GL_INVALID_OPERATION,
1682 "target is TRANSFORM_FEEDBACK_BUFFER and transform "
1683 "feedback is currently active.");
Jiajia Qin6eafb042016-12-27 17:04:07 +08001684 return false;
1685 }
1686 break;
1687 }
Corentin Wallez336129f2017-10-17 15:55:40 -04001688 case BufferBinding::Uniform:
Jiajia Qin6eafb042016-12-27 17:04:07 +08001689 {
1690 if (index >= caps.maxUniformBufferBindings)
1691 {
Jamie Madill610640f2018-11-21 17:28:41 -05001692 context->validationError(GL_INVALID_VALUE,
1693 "index is greater than or equal to the "
1694 "number of UNIFORM_BUFFER indexed "
1695 "binding points.");
Jiajia Qin6eafb042016-12-27 17:04:07 +08001696 return false;
1697 }
1698
Qin Jiajiaf7af13c2018-06-06 14:14:54 +08001699 ASSERT(caps.uniformBufferOffsetAlignment);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001700 if (buffer != 0 && (offset % caps.uniformBufferOffsetAlignment) != 0)
1701 {
Jamie Madill610640f2018-11-21 17:28:41 -05001702 context->validationError(
1703 GL_INVALID_VALUE,
1704 "offset must be multiple of value of UNIFORM_BUFFER_OFFSET_ALIGNMENT.");
Jiajia Qin6eafb042016-12-27 17:04:07 +08001705 return false;
1706 }
1707 break;
1708 }
Corentin Wallez336129f2017-10-17 15:55:40 -04001709 case BufferBinding::AtomicCounter:
Jiajia Qin6eafb042016-12-27 17:04:07 +08001710 {
1711 if (context->getClientVersion() < ES_3_1)
1712 {
Jamie Madill610640f2018-11-21 17:28:41 -05001713 context->validationError(GL_INVALID_ENUM,
1714 "ATOMIC_COUNTER_BUFFER is not supported before GLES 3.1");
Jiajia Qin6eafb042016-12-27 17:04:07 +08001715 return false;
1716 }
1717 if (index >= caps.maxAtomicCounterBufferBindings)
1718 {
Jamie Madill610640f2018-11-21 17:28:41 -05001719 context->validationError(GL_INVALID_VALUE,
1720 "index is greater than or equal to the "
1721 "number of ATOMIC_COUNTER_BUFFER "
1722 "indexed binding points.");
Jiajia Qin6eafb042016-12-27 17:04:07 +08001723 return false;
1724 }
1725 if (buffer != 0 && (offset % 4) != 0)
1726 {
Jamie Madill610640f2018-11-21 17:28:41 -05001727 context->validationError(GL_INVALID_VALUE, "offset must be a multiple of 4.");
Jiajia Qin6eafb042016-12-27 17:04:07 +08001728 return false;
1729 }
1730 break;
1731 }
Corentin Wallez336129f2017-10-17 15:55:40 -04001732 case BufferBinding::ShaderStorage:
Jiajia Qin6eafb042016-12-27 17:04:07 +08001733 {
1734 if (context->getClientVersion() < ES_3_1)
1735 {
Jamie Madill610640f2018-11-21 17:28:41 -05001736 context->validationError(GL_INVALID_ENUM,
1737 "SHADER_STORAGE_BUFFER is not supported in GLES3.");
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001738 return false;
1739 }
1740 if (index >= caps.maxShaderStorageBufferBindings)
1741 {
Jamie Madill610640f2018-11-21 17:28:41 -05001742 context->validationError(GL_INVALID_VALUE,
1743 "index is greater than or equal to the "
1744 "number of SHADER_STORAGE_BUFFER "
1745 "indexed binding points.");
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001746 return false;
1747 }
Qin Jiajiaf7af13c2018-06-06 14:14:54 +08001748 ASSERT(caps.shaderStorageBufferOffsetAlignment);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001749 if (buffer != 0 && (offset % caps.shaderStorageBufferOffsetAlignment) != 0)
1750 {
Jamie Madill610640f2018-11-21 17:28:41 -05001751 context->validationError(GL_INVALID_VALUE,
1752 "offset must be multiple of value of "
1753 "SHADER_STORAGE_BUFFER_OFFSET_"
1754 "ALIGNMENT.");
Jiajia Qin6eafb042016-12-27 17:04:07 +08001755 return false;
1756 }
1757 break;
1758 }
1759 default:
Jamie Madill610640f2018-11-21 17:28:41 -05001760 context->validationError(GL_INVALID_ENUM, "the target is not supported.");
Jiajia Qin6eafb042016-12-27 17:04:07 +08001761 return false;
1762 }
1763
1764 return true;
1765}
1766
Corentin Wallez336129f2017-10-17 15:55:40 -04001767bool ValidateBindBufferBase(Context *context, BufferBinding target, GLuint index, GLuint buffer)
Jiajia Qin6eafb042016-12-27 17:04:07 +08001768{
1769 return ValidateBindBufferCommon(context, target, index, buffer, 0, 0);
1770}
1771
1772bool ValidateBindBufferRange(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04001773 BufferBinding target,
Jiajia Qin6eafb042016-12-27 17:04:07 +08001774 GLuint index,
1775 GLuint buffer,
1776 GLintptr offset,
1777 GLsizeiptr size)
1778{
1779 if (buffer != 0 && size <= 0)
1780 {
Jamie Madill610640f2018-11-21 17:28:41 -05001781 context->validationError(GL_INVALID_VALUE,
1782 "buffer is non-zero and size is less than or equal to zero.");
Jiajia Qin6eafb042016-12-27 17:04:07 +08001783 return false;
1784 }
1785 return ValidateBindBufferCommon(context, target, index, buffer, offset, size);
1786}
1787
Geoff Langc5629752015-12-07 16:29:04 -05001788bool ValidateProgramBinary(Context *context,
1789 GLuint program,
1790 GLenum binaryFormat,
1791 const void *binary,
1792 GLint length)
1793{
Martin Radev1be913c2016-07-11 17:59:16 +03001794 if (context->getClientMajorVersion() < 3)
Geoff Langc5629752015-12-07 16:29:04 -05001795 {
Jamie Madille0472f32018-11-27 16:32:45 -05001796 context->validationError(GL_INVALID_OPERATION, kES3Required);
Geoff Langc5629752015-12-07 16:29:04 -05001797 return false;
1798 }
1799
1800 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
1801}
1802
1803bool ValidateGetProgramBinary(Context *context,
1804 GLuint program,
1805 GLsizei bufSize,
1806 GLsizei *length,
1807 GLenum *binaryFormat,
1808 void *binary)
1809{
Martin Radev1be913c2016-07-11 17:59:16 +03001810 if (context->getClientMajorVersion() < 3)
Geoff Langc5629752015-12-07 16:29:04 -05001811 {
Jamie Madille0472f32018-11-27 16:32:45 -05001812 context->validationError(GL_INVALID_OPERATION, kES3Required);
Geoff Langc5629752015-12-07 16:29:04 -05001813 return false;
1814 }
1815
1816 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
1817}
1818
Olli Etuahof0fee072016-03-30 15:11:58 +03001819bool ValidateProgramParameteri(Context *context, GLuint program, GLenum pname, GLint value)
Geoff Langc5629752015-12-07 16:29:04 -05001820{
Martin Radev1be913c2016-07-11 17:59:16 +03001821 if (context->getClientMajorVersion() < 3)
Geoff Langc5629752015-12-07 16:29:04 -05001822 {
Jamie Madille0472f32018-11-27 16:32:45 -05001823 context->validationError(GL_INVALID_OPERATION, kES3Required);
Geoff Langc5629752015-12-07 16:29:04 -05001824 return false;
1825 }
1826
1827 if (GetValidProgram(context, program) == nullptr)
1828 {
1829 return false;
1830 }
1831
1832 switch (pname)
1833 {
1834 case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
Olli Etuahof0fee072016-03-30 15:11:58 +03001835 if (value != GL_FALSE && value != GL_TRUE)
1836 {
Jamie Madille0472f32018-11-27 16:32:45 -05001837 context->validationError(GL_INVALID_VALUE, kInvalidBooleanValue);
Olli Etuahof0fee072016-03-30 15:11:58 +03001838 return false;
1839 }
Geoff Langc5629752015-12-07 16:29:04 -05001840 break;
1841
Yunchao He61afff12017-03-14 15:34:03 +08001842 case GL_PROGRAM_SEPARABLE:
1843 if (context->getClientVersion() < ES_3_1)
1844 {
Jamie Madille0472f32018-11-27 16:32:45 -05001845 context->validationError(GL_INVALID_ENUM, kES31Required);
Yunchao He61afff12017-03-14 15:34:03 +08001846 return false;
1847 }
1848
1849 if (value != GL_FALSE && value != GL_TRUE)
1850 {
Jamie Madille0472f32018-11-27 16:32:45 -05001851 context->validationError(GL_INVALID_VALUE, kInvalidBooleanValue);
Yunchao He61afff12017-03-14 15:34:03 +08001852 return false;
1853 }
1854 break;
1855
Geoff Langc5629752015-12-07 16:29:04 -05001856 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001857 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Geoff Langc5629752015-12-07 16:29:04 -05001858 return false;
1859 }
1860
1861 return true;
1862}
Jamie Madillc29968b2016-01-20 11:17:23 -05001863
1864bool ValidateBlitFramebuffer(Context *context,
1865 GLint srcX0,
1866 GLint srcY0,
1867 GLint srcX1,
1868 GLint srcY1,
1869 GLint dstX0,
1870 GLint dstY0,
1871 GLint dstX1,
1872 GLint dstY1,
1873 GLbitfield mask,
1874 GLenum filter)
1875{
Martin Radev1be913c2016-07-11 17:59:16 +03001876 if (context->getClientMajorVersion() < 3)
Jamie Madillc29968b2016-01-20 11:17:23 -05001877 {
Jamie Madille0472f32018-11-27 16:32:45 -05001878 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madillc29968b2016-01-20 11:17:23 -05001879 return false;
1880 }
1881
1882 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
1883 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001884}
Jamie Madillc29968b2016-01-20 11:17:23 -05001885
Jamie Madill5b772312018-03-08 20:28:32 -05001886bool ValidateClearBufferiv(Context *context, GLenum buffer, GLint drawbuffer, const GLint *value)
Jamie Madillc29968b2016-01-20 11:17:23 -05001887{
1888 switch (buffer)
1889 {
1890 case GL_COLOR:
1891 if (drawbuffer < 0 ||
1892 static_cast<GLuint>(drawbuffer) >= context->getCaps().maxDrawBuffers)
1893 {
Jamie Madille0472f32018-11-27 16:32:45 -05001894 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxDrawBuffer);
Jamie Madillc29968b2016-01-20 11:17:23 -05001895 return false;
1896 }
Geoff Lang76e65652017-03-27 14:58:02 -04001897 if (context->getExtensions().webglCompatibility)
1898 {
1899 constexpr GLenum validComponentTypes[] = {GL_INT};
Geoff Lang0fb08642017-07-04 15:07:23 -04001900 if (!ValidateWebGLFramebufferAttachmentClearType(
Geoff Lang76e65652017-03-27 14:58:02 -04001901 context, drawbuffer, validComponentTypes, ArraySize(validComponentTypes)))
1902 {
1903 return false;
1904 }
1905 }
Jamie Madillc29968b2016-01-20 11:17:23 -05001906 break;
1907
1908 case GL_STENCIL:
1909 if (drawbuffer != 0)
1910 {
Jamie Madille0472f32018-11-27 16:32:45 -05001911 context->validationError(GL_INVALID_VALUE, kInvalidDepthStencilDrawBuffer);
Jamie Madillc29968b2016-01-20 11:17:23 -05001912 return false;
1913 }
1914 break;
1915
1916 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001917 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc29968b2016-01-20 11:17:23 -05001918 return false;
1919 }
1920
1921 return ValidateClearBuffer(context);
1922}
1923
Jamie Madill5b772312018-03-08 20:28:32 -05001924bool ValidateClearBufferuiv(Context *context, GLenum buffer, GLint drawbuffer, const GLuint *value)
Jamie Madillc29968b2016-01-20 11:17:23 -05001925{
1926 switch (buffer)
1927 {
1928 case GL_COLOR:
1929 if (drawbuffer < 0 ||
1930 static_cast<GLuint>(drawbuffer) >= context->getCaps().maxDrawBuffers)
1931 {
Jamie Madille0472f32018-11-27 16:32:45 -05001932 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxDrawBuffer);
Jamie Madillc29968b2016-01-20 11:17:23 -05001933 return false;
1934 }
Geoff Lang76e65652017-03-27 14:58:02 -04001935 if (context->getExtensions().webglCompatibility)
1936 {
1937 constexpr GLenum validComponentTypes[] = {GL_UNSIGNED_INT};
Geoff Lang0fb08642017-07-04 15:07:23 -04001938 if (!ValidateWebGLFramebufferAttachmentClearType(
Geoff Lang76e65652017-03-27 14:58:02 -04001939 context, drawbuffer, validComponentTypes, ArraySize(validComponentTypes)))
1940 {
1941 return false;
1942 }
1943 }
Jamie Madillc29968b2016-01-20 11:17:23 -05001944 break;
1945
1946 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001947 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc29968b2016-01-20 11:17:23 -05001948 return false;
1949 }
1950
1951 return ValidateClearBuffer(context);
1952}
1953
Jamie Madill5b772312018-03-08 20:28:32 -05001954bool ValidateClearBufferfv(Context *context, GLenum buffer, GLint drawbuffer, const GLfloat *value)
Jamie Madillc29968b2016-01-20 11:17:23 -05001955{
1956 switch (buffer)
1957 {
1958 case GL_COLOR:
1959 if (drawbuffer < 0 ||
1960 static_cast<GLuint>(drawbuffer) >= context->getCaps().maxDrawBuffers)
1961 {
Jamie Madille0472f32018-11-27 16:32:45 -05001962 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxDrawBuffer);
Jamie Madillc29968b2016-01-20 11:17:23 -05001963 return false;
1964 }
Geoff Lang76e65652017-03-27 14:58:02 -04001965 if (context->getExtensions().webglCompatibility)
1966 {
1967 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
1968 GL_SIGNED_NORMALIZED};
Geoff Lang0fb08642017-07-04 15:07:23 -04001969 if (!ValidateWebGLFramebufferAttachmentClearType(
Geoff Lang76e65652017-03-27 14:58:02 -04001970 context, drawbuffer, validComponentTypes, ArraySize(validComponentTypes)))
1971 {
1972 return false;
1973 }
1974 }
Jamie Madillc29968b2016-01-20 11:17:23 -05001975 break;
1976
1977 case GL_DEPTH:
1978 if (drawbuffer != 0)
1979 {
Jamie Madille0472f32018-11-27 16:32:45 -05001980 context->validationError(GL_INVALID_VALUE, kInvalidDepthStencilDrawBuffer);
Jamie Madillc29968b2016-01-20 11:17:23 -05001981 return false;
1982 }
1983 break;
1984
1985 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001986 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc29968b2016-01-20 11:17:23 -05001987 return false;
1988 }
1989
1990 return ValidateClearBuffer(context);
1991}
1992
Jamie Madill5b772312018-03-08 20:28:32 -05001993bool ValidateClearBufferfi(Context *context,
Jamie Madillc29968b2016-01-20 11:17:23 -05001994 GLenum buffer,
1995 GLint drawbuffer,
1996 GLfloat depth,
1997 GLint stencil)
1998{
1999 switch (buffer)
2000 {
2001 case GL_DEPTH_STENCIL:
2002 if (drawbuffer != 0)
2003 {
Jamie Madille0472f32018-11-27 16:32:45 -05002004 context->validationError(GL_INVALID_VALUE, kInvalidDepthStencilDrawBuffer);
Jamie Madillc29968b2016-01-20 11:17:23 -05002005 return false;
2006 }
2007 break;
2008
2009 default:
Jamie Madille0472f32018-11-27 16:32:45 -05002010 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc29968b2016-01-20 11:17:23 -05002011 return false;
2012 }
2013
2014 return ValidateClearBuffer(context);
2015}
2016
Jamie Madill5b772312018-03-08 20:28:32 -05002017bool ValidateDrawBuffers(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002018{
Martin Radev1be913c2016-07-11 17:59:16 +03002019 if (context->getClientMajorVersion() < 3)
Jamie Madillc29968b2016-01-20 11:17:23 -05002020 {
Jamie Madille0472f32018-11-27 16:32:45 -05002021 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madillc29968b2016-01-20 11:17:23 -05002022 return false;
2023 }
2024
2025 return ValidateDrawBuffersBase(context, n, bufs);
2026}
2027
2028bool ValidateCopyTexSubImage3D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002029 TextureType target,
Jamie Madillc29968b2016-01-20 11:17:23 -05002030 GLint level,
2031 GLint xoffset,
2032 GLint yoffset,
2033 GLint zoffset,
2034 GLint x,
2035 GLint y,
2036 GLsizei width,
2037 GLsizei height)
2038{
Martin Radev1be913c2016-07-11 17:59:16 +03002039 if (context->getClientMajorVersion() < 3)
Jamie Madillc29968b2016-01-20 11:17:23 -05002040 {
Jamie Madille0472f32018-11-27 16:32:45 -05002041 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madillc29968b2016-01-20 11:17:23 -05002042 return false;
2043 }
2044
Ian Ewellfc7cf8e2016-01-20 15:57:46 -05002045 return ValidateES3CopyTexImage3DParameters(context, target, level, GL_NONE, true, xoffset,
2046 yoffset, zoffset, x, y, width, height, 0);
Jamie Madillc29968b2016-01-20 11:17:23 -05002047}
2048
Brandon Jones4e6f2ae2018-09-19 11:09:51 -07002049bool ValidateCopyTexture3DANGLE(Context *context,
2050 GLuint sourceId,
2051 GLint sourceLevel,
2052 TextureTarget destTarget,
2053 GLuint destId,
2054 GLint destLevel,
2055 GLint internalFormat,
2056 GLenum destType,
2057 GLboolean unpackFlipY,
2058 GLboolean unpackPremultiplyAlpha,
2059 GLboolean unpackUnmultiplyAlpha)
2060{
2061 const Texture *source = context->getTexture(sourceId);
2062 if (source == nullptr)
2063 {
Jamie Madille0472f32018-11-27 16:32:45 -05002064 context->validationError(GL_INVALID_VALUE, kInvalidSourceTexture);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -07002065 return false;
2066 }
2067
2068 TextureType sourceType = source->getType();
2069 ASSERT(sourceType != TextureType::CubeMap);
2070 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
2071 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
2072
2073 const Texture *dest = context->getTexture(destId);
2074 if (dest == nullptr)
2075 {
Jamie Madille0472f32018-11-27 16:32:45 -05002076 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTexture);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -07002077 return false;
2078 }
2079
2080 if (!ValidateCopyTexture3DCommon(context, source, sourceLevel,
2081 sourceFormat.info->internalFormat, dest, destLevel,
2082 internalFormat, destTarget))
2083 {
2084 return false;
2085 }
2086
2087 if (!ValidMipLevel(context, source->getType(), sourceLevel))
2088 {
Jamie Madille0472f32018-11-27 16:32:45 -05002089 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureLevel);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -07002090 return false;
2091 }
2092
2093 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
2094 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
2095 if (sourceWidth == 0 || sourceHeight == 0)
2096 {
Jamie Madille0472f32018-11-27 16:32:45 -05002097 context->validationError(GL_INVALID_OPERATION, kInvalidSourceTextureSize);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -07002098 return false;
2099 }
2100
2101 if (dest->getImmutableFormat())
2102 {
Jamie Madille0472f32018-11-27 16:32:45 -05002103 context->validationError(GL_INVALID_OPERATION, kDestinationImmutable);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -07002104 return false;
2105 }
2106
2107 return true;
2108}
2109
2110bool ValidateCopySubTexture3DANGLE(Context *context,
2111 GLuint sourceId,
2112 GLint sourceLevel,
2113 TextureTarget destTarget,
2114 GLuint destId,
2115 GLint destLevel,
2116 GLint xoffset,
2117 GLint yoffset,
2118 GLint zoffset,
2119 GLint x,
2120 GLint y,
2121 GLint z,
2122 GLsizei width,
2123 GLsizei height,
2124 GLsizei depth,
2125 GLboolean unpackFlipY,
2126 GLboolean unpackPremultiplyAlpha,
2127 GLboolean unpackUnmultiplyAlpha)
2128{
2129 const Texture *source = context->getTexture(sourceId);
2130 if (source == nullptr)
2131 {
Jamie Madille0472f32018-11-27 16:32:45 -05002132 context->validationError(GL_INVALID_VALUE, kInvalidSourceTexture);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -07002133 return false;
2134 }
2135
2136 TextureType sourceType = source->getType();
2137 ASSERT(sourceType != TextureType::CubeMap);
2138 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
2139 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
2140
2141 const Texture *dest = context->getTexture(destId);
2142 if (dest == nullptr)
2143 {
Jamie Madille0472f32018-11-27 16:32:45 -05002144 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTexture);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -07002145 return false;
2146 }
2147
2148 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
2149
2150 if (!ValidateCopyTexture3DCommon(context, source, sourceLevel,
2151 sourceFormat.info->internalFormat, dest, destLevel,
2152 destFormat.internalFormat, destTarget))
2153 {
2154 return false;
2155 }
2156
2157 if (x < 0 || y < 0 || z < 0)
2158 {
Jamie Madille0472f32018-11-27 16:32:45 -05002159 context->validationError(GL_INVALID_VALUE, kNegativeXYZ);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -07002160 return false;
2161 }
2162
2163 if (width < 0 || height < 0 || depth < 0)
2164 {
Jamie Madille0472f32018-11-27 16:32:45 -05002165 context->validationError(GL_INVALID_VALUE, kNegativeHeightWidthDepth);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -07002166 return false;
2167 }
2168
2169 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
2170 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel) ||
2171 static_cast<size_t>(z + depth) > source->getDepth(sourceTarget, sourceLevel))
2172 {
Jamie Madille0472f32018-11-27 16:32:45 -05002173 context->validationError(GL_INVALID_VALUE, kSourceTextureTooSmall);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -07002174 return false;
2175 }
2176
2177 if (TextureTargetToType(destTarget) != dest->getType())
2178 {
Jamie Madille0472f32018-11-27 16:32:45 -05002179 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTextureType);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -07002180 return false;
2181 }
2182
2183 if (xoffset < 0 || yoffset < 0 || zoffset < 0)
2184 {
Jamie Madille0472f32018-11-27 16:32:45 -05002185 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -07002186 return false;
2187 }
2188
2189 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
2190 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel) ||
2191 static_cast<size_t>(zoffset + depth) > dest->getDepth(destTarget, destLevel))
2192 {
Jamie Madille0472f32018-11-27 16:32:45 -05002193 context->validationError(GL_INVALID_VALUE, kDestinationTextureTooSmall);
Brandon Jones4e6f2ae2018-09-19 11:09:51 -07002194 return false;
2195 }
2196
2197 return true;
2198}
2199
Jamie Madill73a84962016-02-12 09:27:23 -05002200bool ValidateTexImage3D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002201 TextureType target,
Jamie Madill73a84962016-02-12 09:27:23 -05002202 GLint level,
2203 GLint internalformat,
2204 GLsizei width,
2205 GLsizei height,
2206 GLsizei depth,
2207 GLint border,
2208 GLenum format,
2209 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002210 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002211{
Martin Radev1be913c2016-07-11 17:59:16 +03002212 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002213 {
Jamie Madille0472f32018-11-27 16:32:45 -05002214 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill73a84962016-02-12 09:27:23 -05002215 return false;
2216 }
2217
2218 return ValidateES3TexImage3DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langc52f6f12016-10-14 10:18:00 -04002219 0, 0, width, height, depth, border, format, type, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002220 pixels);
2221}
2222
Geoff Langc52f6f12016-10-14 10:18:00 -04002223bool ValidateTexImage3DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002224 TextureType target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002225 GLint level,
2226 GLint internalformat,
2227 GLsizei width,
2228 GLsizei height,
2229 GLsizei depth,
2230 GLint border,
2231 GLenum format,
2232 GLenum type,
2233 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002234 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002235{
2236 if (context->getClientMajorVersion() < 3)
2237 {
Jamie Madille0472f32018-11-27 16:32:45 -05002238 context->validationError(GL_INVALID_OPERATION, kES3Required);
Geoff Langc52f6f12016-10-14 10:18:00 -04002239 return false;
2240 }
2241
2242 if (!ValidateRobustEntryPoint(context, bufSize))
2243 {
2244 return false;
2245 }
2246
2247 return ValidateES3TexImage3DParameters(context, target, level, internalformat, false, false, 0,
2248 0, 0, width, height, depth, border, format, type,
2249 bufSize, pixels);
2250}
2251
Jamie Madill73a84962016-02-12 09:27:23 -05002252bool ValidateTexSubImage3D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002253 TextureType target,
Jamie Madill73a84962016-02-12 09:27:23 -05002254 GLint level,
2255 GLint xoffset,
2256 GLint yoffset,
2257 GLint zoffset,
2258 GLsizei width,
2259 GLsizei height,
2260 GLsizei depth,
2261 GLenum format,
2262 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002263 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002264{
Martin Radev1be913c2016-07-11 17:59:16 +03002265 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002266 {
Jamie Madille0472f32018-11-27 16:32:45 -05002267 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill73a84962016-02-12 09:27:23 -05002268 return false;
2269 }
2270
2271 return ValidateES3TexImage3DParameters(context, target, level, GL_NONE, false, true, xoffset,
2272 yoffset, zoffset, width, height, depth, 0, format, type,
Geoff Langc52f6f12016-10-14 10:18:00 -04002273 -1, pixels);
2274}
2275
2276bool ValidateTexSubImage3DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002277 TextureType target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002278 GLint level,
2279 GLint xoffset,
2280 GLint yoffset,
2281 GLint zoffset,
2282 GLsizei width,
2283 GLsizei height,
2284 GLsizei depth,
2285 GLenum format,
2286 GLenum type,
2287 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002288 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002289{
2290 if (context->getClientMajorVersion() < 3)
2291 {
Jamie Madille0472f32018-11-27 16:32:45 -05002292 context->validationError(GL_INVALID_OPERATION, kES3Required);
Geoff Langc52f6f12016-10-14 10:18:00 -04002293 return false;
2294 }
2295
2296 if (!ValidateRobustEntryPoint(context, bufSize))
2297 {
2298 return false;
2299 }
2300
2301 return ValidateES3TexImage3DParameters(context, target, level, GL_NONE, false, true, xoffset,
2302 yoffset, zoffset, width, height, depth, 0, format, type,
2303 bufSize, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002304}
2305
2306bool ValidateCompressedTexSubImage3D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002307 TextureType target,
Jamie Madill73a84962016-02-12 09:27:23 -05002308 GLint level,
2309 GLint xoffset,
2310 GLint yoffset,
2311 GLint zoffset,
2312 GLsizei width,
2313 GLsizei height,
2314 GLsizei depth,
2315 GLenum format,
2316 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002317 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002318{
Martin Radev1be913c2016-07-11 17:59:16 +03002319 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002320 {
Jamie Madille0472f32018-11-27 16:32:45 -05002321 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill73a84962016-02-12 09:27:23 -05002322 return false;
2323 }
2324
Geoff Langca271392017-04-05 12:30:00 -04002325 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Geoff Langc5508d62017-02-10 14:58:38 -05002326 if (!formatInfo.compressed)
2327 {
Jamie Madille0472f32018-11-27 16:32:45 -05002328 context->validationError(GL_INVALID_ENUM, kInvalidCompressedFormat);
Geoff Langc5508d62017-02-10 14:58:38 -05002329 return false;
2330 }
2331
Jamie Madillca2ff382018-07-11 09:01:17 -04002332 GLuint blockSize = 0;
2333 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, depth), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002334 {
Jamie Madille0472f32018-11-27 16:32:45 -05002335 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002336 return false;
2337 }
Jamie Madillca2ff382018-07-11 09:01:17 -04002338
2339 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002340 {
Jamie Madille0472f32018-11-27 16:32:45 -05002341 context->validationError(GL_INVALID_VALUE, kInvalidCompressedImageSize);
Jamie Madill73a84962016-02-12 09:27:23 -05002342 return false;
2343 }
2344
Luc Ferron9dbaeba2018-02-01 07:26:59 -05002345 if (!ValidateES3TexImage3DParameters(context, target, level, GL_NONE, true, true, xoffset,
2346 yoffset, zoffset, width, height, depth, 0, format, GL_NONE,
2347 -1, data))
2348 {
2349 return false;
2350 }
2351
Jamie Madill73a84962016-02-12 09:27:23 -05002352 if (!data)
2353 {
Jamie Madille0472f32018-11-27 16:32:45 -05002354 context->validationError(GL_INVALID_VALUE, kPixelDataNull);
Jamie Madill73a84962016-02-12 09:27:23 -05002355 return false;
2356 }
2357
Luc Ferron9dbaeba2018-02-01 07:26:59 -05002358 return true;
Jamie Madill73a84962016-02-12 09:27:23 -05002359}
Luc Ferron9dbaeba2018-02-01 07:26:59 -05002360
Corentin Wallezb2931602017-04-11 15:58:57 -04002361bool ValidateCompressedTexSubImage3DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002362 TextureType target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002363 GLint level,
2364 GLint xoffset,
2365 GLint yoffset,
2366 GLint zoffset,
2367 GLsizei width,
2368 GLsizei height,
2369 GLsizei depth,
2370 GLenum format,
2371 GLsizei imageSize,
2372 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002373 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002374{
2375 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2376 {
2377 return false;
2378 }
2379
2380 return ValidateCompressedTexSubImage3D(context, target, level, xoffset, yoffset, zoffset, width,
2381 height, depth, format, imageSize, data);
2382}
Jamie Madill73a84962016-02-12 09:27:23 -05002383
Olli Etuaho41997e72016-03-10 13:38:39 +02002384bool ValidateGenQueries(Context *context, GLint n, GLuint *)
2385{
2386 return ValidateGenOrDeleteES3(context, n);
2387}
2388
2389bool ValidateDeleteQueries(Context *context, GLint n, const GLuint *)
2390{
2391 return ValidateGenOrDeleteES3(context, n);
2392}
2393
2394bool ValidateGenSamplers(Context *context, GLint count, GLuint *)
2395{
2396 return ValidateGenOrDeleteCountES3(context, count);
2397}
2398
2399bool ValidateDeleteSamplers(Context *context, GLint count, const GLuint *)
2400{
2401 return ValidateGenOrDeleteCountES3(context, count);
2402}
2403
2404bool ValidateGenTransformFeedbacks(Context *context, GLint n, GLuint *)
2405{
2406 return ValidateGenOrDeleteES3(context, n);
2407}
2408
2409bool ValidateDeleteTransformFeedbacks(Context *context, GLint n, const GLuint *ids)
2410{
2411 if (!ValidateGenOrDeleteES3(context, n))
2412 {
2413 return false;
2414 }
2415 for (GLint i = 0; i < n; ++i)
2416 {
2417 auto *transformFeedback = context->getTransformFeedback(ids[i]);
2418 if (transformFeedback != nullptr && transformFeedback->isActive())
2419 {
2420 // ES 3.0.4 section 2.15.1 page 86
Jamie Madill610640f2018-11-21 17:28:41 -05002421 context->validationError(GL_INVALID_OPERATION,
2422 "Attempt to delete active transform feedback.");
Olli Etuaho41997e72016-03-10 13:38:39 +02002423 return false;
2424 }
2425 }
2426 return true;
2427}
2428
2429bool ValidateGenVertexArrays(Context *context, GLint n, GLuint *)
2430{
2431 return ValidateGenOrDeleteES3(context, n);
2432}
2433
2434bool ValidateDeleteVertexArrays(Context *context, GLint n, const GLuint *)
2435{
2436 return ValidateGenOrDeleteES3(context, n);
2437}
2438
Jamie Madill493f9572018-05-24 19:52:15 -04002439bool ValidateBeginTransformFeedback(Context *context, PrimitiveMode primitiveMode)
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002440{
Martin Radev1be913c2016-07-11 17:59:16 +03002441 if (context->getClientMajorVersion() < 3)
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002442 {
Jamie Madille0472f32018-11-27 16:32:45 -05002443 context->validationError(GL_INVALID_OPERATION, kES3Required);
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002444 return false;
2445 }
2446 switch (primitiveMode)
2447 {
Jamie Madill493f9572018-05-24 19:52:15 -04002448 case PrimitiveMode::Triangles:
2449 case PrimitiveMode::Lines:
2450 case PrimitiveMode::Points:
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002451 break;
2452
2453 default:
Jamie Madill610640f2018-11-21 17:28:41 -05002454 context->validationError(GL_INVALID_ENUM, "Invalid primitive mode.");
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002455 return false;
2456 }
2457
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002458 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002459 ASSERT(transformFeedback != nullptr);
2460
2461 if (transformFeedback->isActive())
2462 {
Jamie Madill610640f2018-11-21 17:28:41 -05002463 context->validationError(GL_INVALID_OPERATION, "Transform feedback is already active.");
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002464 return false;
2465 }
Geoff Lang79f71042017-08-14 16:43:43 -04002466
2467 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
2468 {
2469 const auto &buffer = transformFeedback->getIndexedBuffer(i);
James Darpinian471b8d42018-11-21 15:37:47 -08002470 if (buffer.get())
Geoff Lang79f71042017-08-14 16:43:43 -04002471 {
James Darpinian471b8d42018-11-21 15:37:47 -08002472 if (buffer->isMapped())
2473 {
2474 context->validationError(GL_INVALID_OPERATION,
2475 "Transform feedback has a mapped buffer.");
2476 return false;
2477 }
2478 if ((context->getLimitations().noDoubleBoundTransformFeedbackBuffers ||
2479 context->getExtensions().webglCompatibility) &&
2480 buffer->isDoubleBoundForTransformFeedback())
2481 {
2482 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002483 kTransformFeedbackBufferMultipleOutputs);
James Darpinian471b8d42018-11-21 15:37:47 -08002484 return false;
2485 }
Geoff Lang79f71042017-08-14 16:43:43 -04002486 }
2487 }
2488
Jamie Madill785e8a02018-10-04 17:42:00 -04002489 Program *program = context->getGLState().getLinkedProgram(context);
Olli Etuaho02032bd2017-10-13 18:10:17 +03002490
2491 if (!program)
2492 {
Jamie Madille0472f32018-11-27 16:32:45 -05002493 context->validationError(GL_INVALID_OPERATION, kProgramNotBound);
Olli Etuaho02032bd2017-10-13 18:10:17 +03002494 return false;
2495 }
2496
2497 if (program->getTransformFeedbackVaryingCount() == 0)
2498 {
Jamie Madille0472f32018-11-27 16:32:45 -05002499 context->validationError(GL_INVALID_OPERATION, kNoTransformFeedbackOutputVariables);
Olli Etuaho02032bd2017-10-13 18:10:17 +03002500 return false;
2501 }
2502
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002503 return true;
2504}
2505
Corentin Wallez336129f2017-10-17 15:55:40 -04002506bool ValidateGetBufferPointerv(Context *context, BufferBinding target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002507{
Geoff Lang496c02d2016-10-20 11:38:11 -07002508 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
2509}
2510
2511bool ValidateGetBufferPointervRobustANGLE(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002512 BufferBinding target,
Geoff Lang496c02d2016-10-20 11:38:11 -07002513 GLenum pname,
2514 GLsizei bufSize,
2515 GLsizei *length,
Jamie Madill876429b2017-04-20 15:46:24 -04002516 void **params)
Geoff Lang496c02d2016-10-20 11:38:11 -07002517{
2518 if (!ValidateRobustEntryPoint(context, bufSize))
Olli Etuaho4f667482016-03-30 15:56:35 +03002519 {
Olli Etuaho4f667482016-03-30 15:56:35 +03002520 return false;
2521 }
2522
Brandon Jonesd1049182018-03-28 10:02:20 -07002523 GLsizei numParams = 0;
2524
2525 if (!ValidateGetBufferPointervBase(context, target, pname, &numParams, params))
Geoff Lang496c02d2016-10-20 11:38:11 -07002526 {
2527 return false;
2528 }
2529
Brandon Jonesd1049182018-03-28 10:02:20 -07002530 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang496c02d2016-10-20 11:38:11 -07002531 {
2532 return false;
2533 }
2534
Brandon Jonesd1049182018-03-28 10:02:20 -07002535 SetRobustLengthParam(length, numParams);
2536
Geoff Lang496c02d2016-10-20 11:38:11 -07002537 return true;
Olli Etuaho4f667482016-03-30 15:56:35 +03002538}
2539
Corentin Wallez336129f2017-10-17 15:55:40 -04002540bool ValidateUnmapBuffer(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03002541{
Martin Radev1be913c2016-07-11 17:59:16 +03002542 if (context->getClientMajorVersion() < 3)
Olli Etuaho4f667482016-03-30 15:56:35 +03002543 {
Jamie Madille0472f32018-11-27 16:32:45 -05002544 context->validationError(GL_INVALID_OPERATION, kES3Required);
Olli Etuaho4f667482016-03-30 15:56:35 +03002545 return false;
2546 }
2547
2548 return ValidateUnmapBufferBase(context, target);
2549}
2550
2551bool ValidateMapBufferRange(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002552 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002553 GLintptr offset,
2554 GLsizeiptr length,
2555 GLbitfield access)
2556{
Martin Radev1be913c2016-07-11 17:59:16 +03002557 if (context->getClientMajorVersion() < 3)
Olli Etuaho4f667482016-03-30 15:56:35 +03002558 {
Jamie Madille0472f32018-11-27 16:32:45 -05002559 context->validationError(GL_INVALID_OPERATION, kES3Required);
Olli Etuaho4f667482016-03-30 15:56:35 +03002560 return false;
2561 }
2562
2563 return ValidateMapBufferRangeBase(context, target, offset, length, access);
2564}
2565
2566bool ValidateFlushMappedBufferRange(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002567 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002568 GLintptr offset,
2569 GLsizeiptr length)
2570{
Martin Radev1be913c2016-07-11 17:59:16 +03002571 if (context->getClientMajorVersion() < 3)
Olli Etuaho4f667482016-03-30 15:56:35 +03002572 {
Jamie Madille0472f32018-11-27 16:32:45 -05002573 context->validationError(GL_INVALID_OPERATION, kES3Required);
Olli Etuaho4f667482016-03-30 15:56:35 +03002574 return false;
2575 }
2576
2577 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
2578}
2579
Jamie Madill5b772312018-03-08 20:28:32 -05002580bool ValidateIndexedStateQuery(Context *context, GLenum pname, GLuint index, GLsizei *length)
Martin Radev66fb8202016-07-28 11:45:20 +03002581{
Geoff Lang2e43dbb2016-10-14 12:27:35 -04002582 if (length)
2583 {
2584 *length = 0;
2585 }
2586
Martin Radev66fb8202016-07-28 11:45:20 +03002587 GLenum nativeType;
2588 unsigned int numParams;
2589 if (!context->getIndexedQueryParameterInfo(pname, &nativeType, &numParams))
2590 {
Jamie Madille0472f32018-11-27 16:32:45 -05002591 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Martin Radev66fb8202016-07-28 11:45:20 +03002592 return false;
2593 }
2594
2595 const Caps &caps = context->getCaps();
2596 switch (pname)
2597 {
2598 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
2599 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
2600 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
2601 if (index >= caps.maxTransformFeedbackSeparateAttributes)
2602 {
Jamie Madill610640f2018-11-21 17:28:41 -05002603 context->validationError(GL_INVALID_VALUE,
Jamie Madille0472f32018-11-27 16:32:45 -05002604 kIndexExceedsMaxTransformFeedbackAttribs);
Martin Radev66fb8202016-07-28 11:45:20 +03002605 return false;
2606 }
2607 break;
2608
2609 case GL_UNIFORM_BUFFER_START:
2610 case GL_UNIFORM_BUFFER_SIZE:
2611 case GL_UNIFORM_BUFFER_BINDING:
2612 if (index >= caps.maxUniformBufferBindings)
2613 {
Jamie Madille0472f32018-11-27 16:32:45 -05002614 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxUniformBufferBindings);
Martin Radev66fb8202016-07-28 11:45:20 +03002615 return false;
2616 }
2617 break;
Shao80957d92017-02-20 21:25:59 +08002618
Martin Radev66fb8202016-07-28 11:45:20 +03002619 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
2620 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
2621 if (index >= 3u)
2622 {
Jamie Madille0472f32018-11-27 16:32:45 -05002623 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxWorkgroupDimensions);
Martin Radev66fb8202016-07-28 11:45:20 +03002624 return false;
2625 }
2626 break;
Shao80957d92017-02-20 21:25:59 +08002627
Jiajia Qin6eafb042016-12-27 17:04:07 +08002628 case GL_ATOMIC_COUNTER_BUFFER_START:
2629 case GL_ATOMIC_COUNTER_BUFFER_SIZE:
2630 case GL_ATOMIC_COUNTER_BUFFER_BINDING:
2631 if (context->getClientVersion() < ES_3_1)
2632 {
Jamie Madille0472f32018-11-27 16:32:45 -05002633 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES31);
Jiajia Qin6eafb042016-12-27 17:04:07 +08002634 return false;
2635 }
2636 if (index >= caps.maxAtomicCounterBufferBindings)
2637 {
Jamie Madill610640f2018-11-21 17:28:41 -05002638 context->validationError(GL_INVALID_VALUE,
Jamie Madille0472f32018-11-27 16:32:45 -05002639 kIndexExceedsMaxAtomicCounterBufferBindings);
Jiajia Qin6eafb042016-12-27 17:04:07 +08002640 return false;
2641 }
2642 break;
Shao80957d92017-02-20 21:25:59 +08002643
Jiajia Qinf546e7d2017-03-27 14:12:59 +08002644 case GL_SHADER_STORAGE_BUFFER_START:
2645 case GL_SHADER_STORAGE_BUFFER_SIZE:
2646 case GL_SHADER_STORAGE_BUFFER_BINDING:
2647 if (context->getClientVersion() < ES_3_1)
2648 {
Jamie Madille0472f32018-11-27 16:32:45 -05002649 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES31);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08002650 return false;
2651 }
2652 if (index >= caps.maxShaderStorageBufferBindings)
2653 {
Jamie Madill610640f2018-11-21 17:28:41 -05002654 context->validationError(
2655 GL_INVALID_VALUE,
2656 "index is outside the valid range for GL_SHADER_STORAGE_BUFFER_BINDING");
Jiajia Qinf546e7d2017-03-27 14:12:59 +08002657 return false;
2658 }
2659 break;
2660
Shao80957d92017-02-20 21:25:59 +08002661 case GL_VERTEX_BINDING_BUFFER:
2662 case GL_VERTEX_BINDING_DIVISOR:
2663 case GL_VERTEX_BINDING_OFFSET:
2664 case GL_VERTEX_BINDING_STRIDE:
2665 if (context->getClientVersion() < ES_3_1)
2666 {
Jamie Madille0472f32018-11-27 16:32:45 -05002667 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES31);
Shao80957d92017-02-20 21:25:59 +08002668 return false;
2669 }
2670 if (index >= caps.maxVertexAttribBindings)
2671 {
Jamie Madill610640f2018-11-21 17:28:41 -05002672 context->validationError(
2673 GL_INVALID_VALUE,
2674 "bindingindex must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08002675 return false;
2676 }
2677 break;
Jiawei Shaodb342272017-09-27 10:21:45 +08002678 case GL_SAMPLE_MASK_VALUE:
2679 if (context->getClientVersion() < ES_3_1)
2680 {
Jamie Madille0472f32018-11-27 16:32:45 -05002681 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES31);
Jiawei Shaodb342272017-09-27 10:21:45 +08002682 return false;
2683 }
2684 if (index >= caps.maxSampleMaskWords)
2685 {
Jamie Madille0472f32018-11-27 16:32:45 -05002686 context->validationError(GL_INVALID_VALUE, kInvalidSampleMaskNumber);
Jiawei Shaodb342272017-09-27 10:21:45 +08002687 return false;
2688 }
2689 break;
Xinghua Cao9c8e1a32017-12-06 17:59:58 +08002690 case GL_IMAGE_BINDING_NAME:
2691 case GL_IMAGE_BINDING_LEVEL:
2692 case GL_IMAGE_BINDING_LAYERED:
2693 case GL_IMAGE_BINDING_LAYER:
2694 case GL_IMAGE_BINDING_ACCESS:
2695 case GL_IMAGE_BINDING_FORMAT:
2696 if (context->getClientVersion() < ES_3_1)
2697 {
Jamie Madille0472f32018-11-27 16:32:45 -05002698 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES31);
Xinghua Cao9c8e1a32017-12-06 17:59:58 +08002699 return false;
2700 }
2701 if (index >= caps.maxImageUnits)
2702 {
Jamie Madille0472f32018-11-27 16:32:45 -05002703 context->validationError(GL_INVALID_VALUE, kInvalidImageUnit);
Xinghua Cao9c8e1a32017-12-06 17:59:58 +08002704 return false;
2705 }
2706 break;
Martin Radev66fb8202016-07-28 11:45:20 +03002707 default:
Jamie Madille0472f32018-11-27 16:32:45 -05002708 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Martin Radev66fb8202016-07-28 11:45:20 +03002709 return false;
2710 }
2711
Geoff Lang2e43dbb2016-10-14 12:27:35 -04002712 if (length)
Martin Radev66fb8202016-07-28 11:45:20 +03002713 {
Geoff Lang2e43dbb2016-10-14 12:27:35 -04002714 *length = 1;
Martin Radev66fb8202016-07-28 11:45:20 +03002715 }
2716
2717 return true;
2718}
2719
Jamie Madill5b772312018-03-08 20:28:32 -05002720bool ValidateGetIntegeri_v(Context *context, GLenum target, GLuint index, GLint *data)
Martin Radev66fb8202016-07-28 11:45:20 +03002721{
Geoff Langeb66a6e2016-10-31 13:06:12 -04002722 if (context->getClientVersion() < ES_3_0)
Martin Radev66fb8202016-07-28 11:45:20 +03002723 {
Jamie Madille0472f32018-11-27 16:32:45 -05002724 context->validationError(GL_INVALID_OPERATION, kES3Required);
Martin Radev66fb8202016-07-28 11:45:20 +03002725 return false;
2726 }
Geoff Lang2e43dbb2016-10-14 12:27:35 -04002727 return ValidateIndexedStateQuery(context, target, index, nullptr);
Martin Radev66fb8202016-07-28 11:45:20 +03002728}
2729
Jamie Madill5b772312018-03-08 20:28:32 -05002730bool ValidateGetIntegeri_vRobustANGLE(Context *context,
Geoff Langcf255ea2016-10-20 11:39:09 -07002731 GLenum target,
2732 GLuint index,
2733 GLsizei bufSize,
2734 GLsizei *length,
2735 GLint *data)
2736{
Geoff Langeb66a6e2016-10-31 13:06:12 -04002737 if (context->getClientVersion() < ES_3_0)
Geoff Langcf255ea2016-10-20 11:39:09 -07002738 {
Jamie Madille0472f32018-11-27 16:32:45 -05002739 context->validationError(GL_INVALID_OPERATION, kES3Required);
Geoff Langcf255ea2016-10-20 11:39:09 -07002740 return false;
2741 }
2742
2743 if (!ValidateRobustEntryPoint(context, bufSize))
2744 {
2745 return false;
2746 }
2747
Brandon Jonesd1049182018-03-28 10:02:20 -07002748 GLsizei numParams = 0;
2749
2750 if (!ValidateIndexedStateQuery(context, target, index, &numParams))
Geoff Langcf255ea2016-10-20 11:39:09 -07002751 {
2752 return false;
2753 }
2754
Brandon Jonesd1049182018-03-28 10:02:20 -07002755 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langcf255ea2016-10-20 11:39:09 -07002756 {
2757 return false;
2758 }
2759
Brandon Jonesd1049182018-03-28 10:02:20 -07002760 SetRobustLengthParam(length, numParams);
2761
Geoff Langcf255ea2016-10-20 11:39:09 -07002762 return true;
2763}
2764
Jamie Madill5b772312018-03-08 20:28:32 -05002765bool ValidateGetInteger64i_v(Context *context, GLenum target, GLuint index, GLint64 *data)
Martin Radev66fb8202016-07-28 11:45:20 +03002766{
Geoff Langeb66a6e2016-10-31 13:06:12 -04002767 if (context->getClientVersion() < ES_3_0)
Martin Radev66fb8202016-07-28 11:45:20 +03002768 {
Jamie Madille0472f32018-11-27 16:32:45 -05002769 context->validationError(GL_INVALID_OPERATION, kES3Required);
Martin Radev66fb8202016-07-28 11:45:20 +03002770 return false;
2771 }
Geoff Lang2e43dbb2016-10-14 12:27:35 -04002772 return ValidateIndexedStateQuery(context, target, index, nullptr);
2773}
2774
Jamie Madill5b772312018-03-08 20:28:32 -05002775bool ValidateGetInteger64i_vRobustANGLE(Context *context,
Geoff Lang2e43dbb2016-10-14 12:27:35 -04002776 GLenum target,
2777 GLuint index,
2778 GLsizei bufSize,
2779 GLsizei *length,
2780 GLint64 *data)
2781{
Geoff Langeb66a6e2016-10-31 13:06:12 -04002782 if (context->getClientVersion() < ES_3_0)
Geoff Lang2e43dbb2016-10-14 12:27:35 -04002783 {
Jamie Madille0472f32018-11-27 16:32:45 -05002784 context->validationError(GL_INVALID_OPERATION, kES3Required);
Geoff Lang2e43dbb2016-10-14 12:27:35 -04002785 return false;
2786 }
2787
2788 if (!ValidateRobustEntryPoint(context, bufSize))
2789 {
2790 return false;
2791 }
2792
Brandon Jonesd1049182018-03-28 10:02:20 -07002793 GLsizei numParams = 0;
2794
2795 if (!ValidateIndexedStateQuery(context, target, index, &numParams))
Geoff Lang2e43dbb2016-10-14 12:27:35 -04002796 {
2797 return false;
2798 }
2799
Brandon Jonesd1049182018-03-28 10:02:20 -07002800 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2e43dbb2016-10-14 12:27:35 -04002801 {
2802 return false;
2803 }
2804
Brandon Jonesd1049182018-03-28 10:02:20 -07002805 SetRobustLengthParam(length, numParams);
2806
Geoff Lang2e43dbb2016-10-14 12:27:35 -04002807 return true;
Martin Radev66fb8202016-07-28 11:45:20 +03002808}
2809
Jamie Madill5b772312018-03-08 20:28:32 -05002810bool ValidateCopyBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002811 BufferBinding readTarget,
2812 BufferBinding writeTarget,
Jamie Madillb0817d12016-11-01 15:48:31 -04002813 GLintptr readOffset,
2814 GLintptr writeOffset,
2815 GLsizeiptr size)
2816{
2817 if (context->getClientMajorVersion() < 3)
2818 {
Jamie Madille0472f32018-11-27 16:32:45 -05002819 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madillb0817d12016-11-01 15:48:31 -04002820 return false;
2821 }
2822
Corentin Walleze4477002017-12-01 14:39:58 -05002823 if (!context->isValidBufferBinding(readTarget) || !context->isValidBufferBinding(writeTarget))
Jamie Madillb0817d12016-11-01 15:48:31 -04002824 {
Jamie Madille0472f32018-11-27 16:32:45 -05002825 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Jamie Madillb0817d12016-11-01 15:48:31 -04002826 return false;
2827 }
2828
2829 Buffer *readBuffer = context->getGLState().getTargetBuffer(readTarget);
2830 Buffer *writeBuffer = context->getGLState().getTargetBuffer(writeTarget);
2831
2832 if (!readBuffer || !writeBuffer)
2833 {
Jamie Madill610640f2018-11-21 17:28:41 -05002834 context->validationError(GL_INVALID_OPERATION, "No buffer bound to target");
Jamie Madillb0817d12016-11-01 15:48:31 -04002835 return false;
2836 }
2837
2838 // Verify that readBuffer and writeBuffer are not currently mapped
2839 if (readBuffer->isMapped() || writeBuffer->isMapped())
2840 {
Jamie Madill610640f2018-11-21 17:28:41 -05002841 context->validationError(GL_INVALID_OPERATION,
2842 "Cannot call CopyBufferSubData on a mapped buffer");
Jamie Madillb0817d12016-11-01 15:48:31 -04002843 return false;
2844 }
2845
James Darpiniane8a93c62018-01-04 18:02:24 -08002846 if (context->getExtensions().webglCompatibility &&
2847 (readBuffer->isBoundForTransformFeedbackAndOtherUse() ||
2848 writeBuffer->isBoundForTransformFeedbackAndOtherUse()))
2849 {
Jamie Madille0472f32018-11-27 16:32:45 -05002850 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08002851 return false;
2852 }
2853
Jamie Madilld2f0c742016-11-02 10:34:41 -04002854 CheckedNumeric<GLintptr> checkedReadOffset(readOffset);
2855 CheckedNumeric<GLintptr> checkedWriteOffset(writeOffset);
2856 CheckedNumeric<GLintptr> checkedSize(size);
2857
2858 auto checkedReadSum = checkedReadOffset + checkedSize;
2859 auto checkedWriteSum = checkedWriteOffset + checkedSize;
2860
2861 if (!checkedReadSum.IsValid() || !checkedWriteSum.IsValid() ||
2862 !IsValueInRangeForNumericType<GLintptr>(readBuffer->getSize()) ||
2863 !IsValueInRangeForNumericType<GLintptr>(writeBuffer->getSize()))
Jamie Madillb0817d12016-11-01 15:48:31 -04002864 {
Jamie Madille0472f32018-11-27 16:32:45 -05002865 context->validationError(GL_INVALID_VALUE, kIntegerOverflow);
Jamie Madillb0817d12016-11-01 15:48:31 -04002866 return false;
2867 }
2868
Jamie Madilld2f0c742016-11-02 10:34:41 -04002869 if (readOffset < 0 || writeOffset < 0 || size < 0)
Jamie Madillb0817d12016-11-01 15:48:31 -04002870 {
Jamie Madill610640f2018-11-21 17:28:41 -05002871 context->validationError(GL_INVALID_VALUE,
2872 "readOffset, writeOffset and size must all be non-negative");
Jamie Madillb0817d12016-11-01 15:48:31 -04002873 return false;
2874 }
2875
Jamie Madilld2f0c742016-11-02 10:34:41 -04002876 if (checkedReadSum.ValueOrDie() > readBuffer->getSize() ||
2877 checkedWriteSum.ValueOrDie() > writeBuffer->getSize())
2878 {
Jamie Madill610640f2018-11-21 17:28:41 -05002879 context->validationError(GL_INVALID_VALUE, "Buffer offset overflow in CopyBufferSubData");
Jamie Madilld2f0c742016-11-02 10:34:41 -04002880 return false;
2881 }
2882
2883 if (readBuffer == writeBuffer)
2884 {
2885 auto checkedOffsetDiff = (checkedReadOffset - checkedWriteOffset).Abs();
2886 if (!checkedOffsetDiff.IsValid())
2887 {
2888 // This shold not be possible.
2889 UNREACHABLE();
Jamie Madille0472f32018-11-27 16:32:45 -05002890 context->validationError(GL_INVALID_VALUE, kIntegerOverflow);
Jamie Madilld2f0c742016-11-02 10:34:41 -04002891 return false;
2892 }
2893
2894 if (checkedOffsetDiff.ValueOrDie() < size)
2895 {
Jamie Madille0472f32018-11-27 16:32:45 -05002896 context->validationError(GL_INVALID_VALUE, kCopyAlias);
Jamie Madilld2f0c742016-11-02 10:34:41 -04002897 return false;
2898 }
2899 }
2900
Jamie Madillb0817d12016-11-01 15:48:31 -04002901 return true;
2902}
2903
Geoff Langc339c4e2016-11-29 10:37:36 -05002904bool ValidateGetStringi(Context *context, GLenum name, GLuint index)
2905{
2906 if (context->getClientMajorVersion() < 3)
2907 {
Jamie Madille0472f32018-11-27 16:32:45 -05002908 context->validationError(GL_INVALID_OPERATION, kES3Required);
Geoff Langc339c4e2016-11-29 10:37:36 -05002909 return false;
2910 }
2911
2912 switch (name)
2913 {
2914 case GL_EXTENSIONS:
2915 if (index >= context->getExtensionStringCount())
2916 {
Jamie Madill610640f2018-11-21 17:28:41 -05002917 context->validationError(
2918 GL_INVALID_VALUE, "index must be less than the number of extension strings.");
Geoff Langc339c4e2016-11-29 10:37:36 -05002919 return false;
2920 }
2921 break;
2922
2923 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2924 if (!context->getExtensions().requestExtension)
2925 {
Jamie Madille0472f32018-11-27 16:32:45 -05002926 context->validationError(GL_INVALID_ENUM, kInvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05002927 return false;
2928 }
2929 if (index >= context->getRequestableExtensionStringCount())
2930 {
Jamie Madill610640f2018-11-21 17:28:41 -05002931 context->validationError(
2932 GL_INVALID_VALUE,
2933 "index must be less than the number of requestable extension strings.");
Geoff Langc339c4e2016-11-29 10:37:36 -05002934 return false;
2935 }
2936 break;
2937
2938 default:
Jamie Madille0472f32018-11-27 16:32:45 -05002939 context->validationError(GL_INVALID_ENUM, kInvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05002940 return false;
2941 }
2942
2943 return true;
2944}
2945
Jamie Madill5b772312018-03-08 20:28:32 -05002946bool ValidateRenderbufferStorageMultisample(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05002947 GLenum target,
2948 GLsizei samples,
2949 GLenum internalformat,
2950 GLsizei width,
2951 GLsizei height)
2952{
2953 if (context->getClientMajorVersion() < 3)
2954 {
Jamie Madille0472f32018-11-27 16:32:45 -05002955 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madille8fb6402017-02-14 17:56:40 -05002956 return false;
2957 }
2958
2959 if (!ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat, width,
2960 height))
2961 {
2962 return false;
2963 }
2964
2965 // 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 +08002966 // format if samples is greater than zero. In ES3.1(section 9.2.5), it can support integer
2967 // multisample renderbuffer, but the samples should not be greater than MAX_INTEGER_SAMPLES.
Geoff Langca271392017-04-05 12:30:00 -04002968 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Yunchao Hec0810202018-01-22 09:48:48 +08002969 if ((formatInfo.componentType == GL_UNSIGNED_INT || formatInfo.componentType == GL_INT))
Jamie Madille8fb6402017-02-14 17:56:40 -05002970 {
Yunchao Hec0810202018-01-22 09:48:48 +08002971 if ((samples > 0 && context->getClientVersion() == ES_3_0) ||
2972 static_cast<GLuint>(samples) > context->getCaps().maxIntegerSamples)
2973 {
Jamie Madille0472f32018-11-27 16:32:45 -05002974 context->validationError(GL_INVALID_OPERATION, kSamplesOutOfRange);
Yunchao Hec0810202018-01-22 09:48:48 +08002975 return false;
2976 }
Jamie Madille8fb6402017-02-14 17:56:40 -05002977 }
2978
2979 // The behavior is different than the ANGLE version, which would generate a GL_OUT_OF_MEMORY.
2980 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
2981 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
2982 {
Jamie Madille0472f32018-11-27 16:32:45 -05002983 context->validationError(GL_INVALID_OPERATION, kSamplesOutOfRange);
Jamie Madille8fb6402017-02-14 17:56:40 -05002984 return false;
2985 }
2986
2987 return true;
2988}
2989
Jamie Madill5b772312018-03-08 20:28:32 -05002990bool ValidateVertexAttribIPointer(Context *context,
Geoff Langaa086d62017-03-23 16:47:21 -04002991 GLuint index,
2992 GLint size,
2993 GLenum type,
2994 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04002995 const void *pointer)
Geoff Langaa086d62017-03-23 16:47:21 -04002996{
2997 if (context->getClientMajorVersion() < 3)
2998 {
Jamie Madille0472f32018-11-27 16:32:45 -05002999 context->validationError(GL_INVALID_OPERATION, kES3Required);
Geoff Langaa086d62017-03-23 16:47:21 -04003000 return false;
3001 }
3002
Shao80957d92017-02-20 21:25:59 +08003003 if (!ValidateVertexFormatBase(context, index, size, type, true))
Geoff Langaa086d62017-03-23 16:47:21 -04003004 {
Geoff Langaa086d62017-03-23 16:47:21 -04003005 return false;
3006 }
3007
Geoff Langaa086d62017-03-23 16:47:21 -04003008 if (stride < 0)
3009 {
Jamie Madille0472f32018-11-27 16:32:45 -05003010 context->validationError(GL_INVALID_VALUE, kNegativeStride);
Geoff Langaa086d62017-03-23 16:47:21 -04003011 return false;
3012 }
3013
Shao80957d92017-02-20 21:25:59 +08003014 const Caps &caps = context->getCaps();
3015 if (context->getClientVersion() >= ES_3_1)
3016 {
3017 if (stride > caps.maxVertexAttribStride)
3018 {
Jamie Madill610640f2018-11-21 17:28:41 -05003019 context->validationError(GL_INVALID_VALUE,
3020 "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08003021 return false;
3022 }
3023
3024 // [OpenGL ES 3.1] Section 10.3.1 page 245:
3025 // glVertexAttribBinding is part of the equivalent code of VertexAttribIPointer, so its
3026 // validation should be inherited.
3027 if (index >= caps.maxVertexAttribBindings)
3028 {
Jamie Madill610640f2018-11-21 17:28:41 -05003029 context->validationError(GL_INVALID_VALUE,
3030 "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08003031 return false;
3032 }
3033 }
3034
Geoff Langaa086d62017-03-23 16:47:21 -04003035 // [OpenGL ES 3.0.2] Section 2.8 page 24:
3036 // An INVALID_OPERATION error is generated when a non-zero vertex array object
3037 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
3038 // and the pointer argument is not NULL.
3039 if (context->getGLState().getVertexArrayId() != 0 &&
Corentin Wallez336129f2017-10-17 15:55:40 -04003040 context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 && pointer != nullptr)
Geoff Langaa086d62017-03-23 16:47:21 -04003041 {
Jamie Madill610640f2018-11-21 17:28:41 -05003042 context->validationError(
3043 GL_INVALID_OPERATION,
3044 "Client data cannot be used with a non-default vertex array object.");
Geoff Langaa086d62017-03-23 16:47:21 -04003045 return false;
3046 }
3047
Geoff Lang2d62ab72017-03-23 16:54:40 -04003048 if (context->getExtensions().webglCompatibility)
3049 {
3050 if (!ValidateWebGLVertexAttribPointer(context, type, false, stride, pointer, true))
3051 {
3052 return false;
3053 }
3054 }
3055
Geoff Langaa086d62017-03-23 16:47:21 -04003056 return true;
3057}
3058
Geoff Lang38f2cfb2017-04-11 15:23:08 -04003059bool ValidateGetSynciv(Context *context,
3060 GLsync sync,
3061 GLenum pname,
3062 GLsizei bufSize,
3063 GLsizei *length,
3064 GLint *values)
3065{
3066 if (context->getClientMajorVersion() < 3)
3067 {
Jamie Madille0472f32018-11-27 16:32:45 -05003068 context->validationError(GL_INVALID_OPERATION, kES3Required);
Geoff Lang38f2cfb2017-04-11 15:23:08 -04003069 return false;
3070 }
3071
3072 if (bufSize < 0)
3073 {
Jamie Madille0472f32018-11-27 16:32:45 -05003074 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Lang38f2cfb2017-04-11 15:23:08 -04003075 return false;
3076 }
3077
Jamie Madill70b5bb02017-08-28 13:32:37 -04003078 Sync *syncObject = context->getSync(sync);
3079 if (!syncObject)
Geoff Lang38f2cfb2017-04-11 15:23:08 -04003080 {
Jamie Madill610640f2018-11-21 17:28:41 -05003081 context->validationError(GL_INVALID_VALUE, "Invalid sync object.");
Geoff Lang38f2cfb2017-04-11 15:23:08 -04003082 return false;
3083 }
3084
3085 switch (pname)
3086 {
3087 case GL_OBJECT_TYPE:
3088 case GL_SYNC_CONDITION:
3089 case GL_SYNC_FLAGS:
3090 case GL_SYNC_STATUS:
3091 break;
3092
3093 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003094 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Geoff Lang38f2cfb2017-04-11 15:23:08 -04003095 return false;
3096 }
3097
3098 return true;
3099}
3100
Jamie Madill5b772312018-03-08 20:28:32 -05003101bool ValidateDrawElementsInstanced(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04003102 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003103 GLsizei count,
Jamie Madill8dc27f92018-11-29 11:45:44 -05003104 DrawElementsType type,
Jamie Madill876429b2017-04-20 15:46:24 -04003105 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003106 GLsizei instanceCount)
3107{
3108 if (context->getClientMajorVersion() < 3)
3109 {
Jamie Madille0472f32018-11-27 16:32:45 -05003110 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003111 return false;
3112 }
3113
3114 return ValidateDrawElementsInstancedCommon(context, mode, count, type, indices, instanceCount);
3115}
3116
Austin Eng1bf18ce2018-10-19 15:34:02 -07003117bool ValidateMultiDrawArraysInstancedANGLE(Context *context,
3118 PrimitiveMode mode,
3119 const GLint *firsts,
3120 const GLsizei *counts,
3121 const GLsizei *instanceCounts,
3122 GLsizei drawcount)
3123{
3124 if (!context->getExtensions().multiDraw)
3125 {
Jamie Madille0472f32018-11-27 16:32:45 -05003126 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07003127 return false;
3128 }
3129 if (context->getClientMajorVersion() < 3)
3130 {
3131 if (!context->getExtensions().instancedArrays)
3132 {
Jamie Madille0472f32018-11-27 16:32:45 -05003133 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07003134 return false;
3135 }
3136 if (!ValidateDrawInstancedANGLE(context))
3137 {
3138 return false;
3139 }
3140 }
3141 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
3142 {
3143 if (!ValidateDrawArraysInstancedBase(context, mode, firsts[drawID], counts[drawID],
3144 instanceCounts[drawID]))
3145 {
3146 return false;
3147 }
3148 }
3149 return true;
3150}
3151
3152bool ValidateMultiDrawElementsInstancedANGLE(Context *context,
3153 PrimitiveMode mode,
3154 const GLsizei *counts,
Jamie Madill8dc27f92018-11-29 11:45:44 -05003155 DrawElementsType type,
Austin Eng3b7c9d02018-11-21 18:09:05 -08003156 const GLvoid *const *indices,
Austin Eng1bf18ce2018-10-19 15:34:02 -07003157 const GLsizei *instanceCounts,
3158 GLsizei drawcount)
3159{
3160 if (!context->getExtensions().multiDraw)
3161 {
Jamie Madille0472f32018-11-27 16:32:45 -05003162 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07003163 return false;
3164 }
3165 if (context->getClientMajorVersion() < 3)
3166 {
3167 if (!context->getExtensions().instancedArrays)
3168 {
Jamie Madille0472f32018-11-27 16:32:45 -05003169 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07003170 return false;
3171 }
3172 if (!ValidateDrawInstancedANGLE(context))
3173 {
3174 return false;
3175 }
3176 }
3177 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
3178 {
Austin Eng3b7c9d02018-11-21 18:09:05 -08003179 if (!ValidateDrawElementsInstancedCommon(context, mode, counts[drawID], type,
3180 indices[drawID], instanceCounts[drawID]))
Austin Eng1bf18ce2018-10-19 15:34:02 -07003181 {
3182 return false;
3183 }
3184 }
3185 return true;
3186}
3187
Martin Radev137032d2017-07-13 10:11:12 +03003188bool ValidateFramebufferTextureMultiviewLayeredANGLE(Context *context,
3189 GLenum target,
3190 GLenum attachment,
3191 GLuint texture,
3192 GLint level,
3193 GLint baseViewIndex,
3194 GLsizei numViews)
3195{
Martin Radev137032d2017-07-13 10:11:12 +03003196 if (!ValidateFramebufferTextureMultiviewBaseANGLE(context, target, attachment, texture, level,
3197 numViews))
3198 {
3199 return false;
3200 }
3201
Martin Radev137032d2017-07-13 10:11:12 +03003202 if (texture != 0)
3203 {
Martin Radev14b21262017-08-25 13:54:37 +03003204 if (baseViewIndex < 0)
3205 {
Jamie Madill610640f2018-11-21 17:28:41 -05003206 context->validationError(GL_INVALID_VALUE, "baseViewIndex cannot be less than 0.");
Martin Radev14b21262017-08-25 13:54:37 +03003207 return false;
3208 }
3209
Martin Radev137032d2017-07-13 10:11:12 +03003210 Texture *tex = context->getTexture(texture);
3211 ASSERT(tex);
3212
Corentin Wallez99d492c2018-02-27 15:17:10 -05003213 switch (tex->getType())
Martin Radev137032d2017-07-13 10:11:12 +03003214 {
Corentin Wallez99d492c2018-02-27 15:17:10 -05003215 case TextureType::_2DArray:
Olli Etuaho2c8f0842018-09-12 14:44:55 +03003216 case TextureType::_2DMultisampleArray:
Martin Radev137032d2017-07-13 10:11:12 +03003217 {
Olli Etuaho2c8f0842018-09-12 14:44:55 +03003218 if (tex->getType() == TextureType::_2DMultisampleArray)
3219 {
3220 if (!context->getExtensions().multiviewMultisample)
3221 {
Jamie Madill610640f2018-11-21 17:28:41 -05003222 context->validationError(GL_INVALID_OPERATION,
3223 "Texture's target must be GL_TEXTURE_2D_ARRAY.");
Olli Etuaho2c8f0842018-09-12 14:44:55 +03003224 return false;
3225 }
3226 }
3227
Martin Radev137032d2017-07-13 10:11:12 +03003228 const Caps &caps = context->getCaps();
3229 if (static_cast<GLuint>(baseViewIndex + numViews) > caps.maxArrayTextureLayers)
3230 {
Jamie Madill610640f2018-11-21 17:28:41 -05003231 context->validationError(GL_INVALID_VALUE,
3232 "baseViewIndex+numViews cannot be "
3233 "greater than "
3234 "GL_MAX_ARRAY_TEXTURE_LAYERS.");
Martin Radev137032d2017-07-13 10:11:12 +03003235 return false;
3236 }
Olli Etuaho2c8f0842018-09-12 14:44:55 +03003237
3238 break;
Martin Radev137032d2017-07-13 10:11:12 +03003239 }
Martin Radev137032d2017-07-13 10:11:12 +03003240 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003241 context->validationError(GL_INVALID_OPERATION,
3242 "Texture's target must be GL_TEXTURE_2D_ARRAY.");
Martin Radev137032d2017-07-13 10:11:12 +03003243 return false;
3244 }
3245
3246 if (!ValidateFramebufferTextureMultiviewLevelAndFormat(context, tex, level))
3247 {
3248 return false;
3249 }
3250 }
3251
3252 return true;
3253}
3254
3255bool ValidateFramebufferTextureMultiviewSideBySideANGLE(Context *context,
3256 GLenum target,
3257 GLenum attachment,
3258 GLuint texture,
3259 GLint level,
3260 GLsizei numViews,
3261 const GLint *viewportOffsets)
3262{
3263 if (!ValidateFramebufferTextureMultiviewBaseANGLE(context, target, attachment, texture, level,
3264 numViews))
3265 {
3266 return false;
3267 }
3268
Martin Radev137032d2017-07-13 10:11:12 +03003269 if (texture != 0)
3270 {
Martin Radev14b21262017-08-25 13:54:37 +03003271 const GLsizei numViewportOffsetValues = numViews * 2;
3272 for (GLsizei i = 0; i < numViewportOffsetValues; ++i)
3273 {
3274 if (viewportOffsets[i] < 0)
3275 {
Jamie Madill610640f2018-11-21 17:28:41 -05003276 context->validationError(GL_INVALID_VALUE,
3277 "viewportOffsets cannot contain negative values.");
Martin Radev14b21262017-08-25 13:54:37 +03003278 return false;
3279 }
3280 }
3281
Martin Radev137032d2017-07-13 10:11:12 +03003282 Texture *tex = context->getTexture(texture);
3283 ASSERT(tex);
3284
Corentin Wallez99d492c2018-02-27 15:17:10 -05003285 switch (tex->getType())
Martin Radev137032d2017-07-13 10:11:12 +03003286 {
Corentin Wallez99d492c2018-02-27 15:17:10 -05003287 case TextureType::_2D:
Martin Radev137032d2017-07-13 10:11:12 +03003288 break;
3289 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003290 context->validationError(GL_INVALID_OPERATION,
3291 "Texture's target must be GL_TEXTURE_2D.");
Martin Radev137032d2017-07-13 10:11:12 +03003292 return false;
3293 }
3294
3295 if (!ValidateFramebufferTextureMultiviewLevelAndFormat(context, tex, level))
3296 {
3297 return false;
3298 }
3299 }
3300
3301 return true;
3302}
3303
Jamie Madillff325f12017-08-26 15:06:05 -04003304bool ValidateUniform1ui(Context *context, GLint location, GLuint v0)
3305{
3306 return ValidateUniformES3(context, GL_UNSIGNED_INT, location, 1);
3307}
3308
3309bool ValidateUniform2ui(Context *context, GLint location, GLuint v0, GLuint v1)
3310{
3311 return ValidateUniformES3(context, GL_UNSIGNED_INT_VEC2, location, 1);
3312}
3313
3314bool ValidateUniform3ui(Context *context, GLint location, GLuint v0, GLuint v1, GLuint v2)
3315{
3316 return ValidateUniformES3(context, GL_UNSIGNED_INT_VEC3, location, 1);
3317}
3318
3319bool ValidateUniform4ui(Context *context,
3320 GLint location,
3321 GLuint v0,
3322 GLuint v1,
3323 GLuint v2,
3324 GLuint v3)
3325{
3326 return ValidateUniformES3(context, GL_UNSIGNED_INT_VEC4, location, 1);
3327}
3328
3329bool ValidateUniform1uiv(Context *context, GLint location, GLsizei count, const GLuint *value)
3330{
3331 return ValidateUniformES3(context, GL_UNSIGNED_INT, location, count);
3332}
3333
3334bool ValidateUniform2uiv(Context *context, GLint location, GLsizei count, const GLuint *value)
3335{
3336 return ValidateUniformES3(context, GL_UNSIGNED_INT_VEC2, location, count);
3337}
3338
3339bool ValidateUniform3uiv(Context *context, GLint location, GLsizei count, const GLuint *value)
3340{
3341 return ValidateUniformES3(context, GL_UNSIGNED_INT_VEC3, location, count);
3342}
3343
3344bool ValidateUniform4uiv(Context *context, GLint location, GLsizei count, const GLuint *value)
3345{
3346 return ValidateUniformES3(context, GL_UNSIGNED_INT_VEC4, location, count);
3347}
3348
Jamie Madillf0e04492017-08-26 15:28:42 -04003349bool ValidateIsQuery(Context *context, GLuint id)
3350{
3351 if (context->getClientMajorVersion() < 3)
3352 {
Jamie Madille0472f32018-11-27 16:32:45 -05003353 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madillf0e04492017-08-26 15:28:42 -04003354 return false;
3355 }
3356
3357 return true;
3358}
3359
Jamie Madillc8c95812017-08-26 18:40:09 -04003360bool ValidateUniformMatrix2x3fv(Context *context,
3361 GLint location,
3362 GLsizei count,
3363 GLboolean transpose,
3364 const GLfloat *value)
3365{
3366 return ValidateUniformMatrixES3(context, GL_FLOAT_MAT2x3, location, count, transpose);
3367}
3368
3369bool ValidateUniformMatrix3x2fv(Context *context,
3370 GLint location,
3371 GLsizei count,
3372 GLboolean transpose,
3373 const GLfloat *value)
3374{
3375 return ValidateUniformMatrixES3(context, GL_FLOAT_MAT3x2, location, count, transpose);
3376}
3377
3378bool ValidateUniformMatrix2x4fv(Context *context,
3379 GLint location,
3380 GLsizei count,
3381 GLboolean transpose,
3382 const GLfloat *value)
3383{
3384 return ValidateUniformMatrixES3(context, GL_FLOAT_MAT2x4, location, count, transpose);
3385}
3386
3387bool ValidateUniformMatrix4x2fv(Context *context,
3388 GLint location,
3389 GLsizei count,
3390 GLboolean transpose,
3391 const GLfloat *value)
3392{
3393 return ValidateUniformMatrixES3(context, GL_FLOAT_MAT4x2, location, count, transpose);
3394}
3395
3396bool ValidateUniformMatrix3x4fv(Context *context,
3397 GLint location,
3398 GLsizei count,
3399 GLboolean transpose,
3400 const GLfloat *value)
3401{
3402 return ValidateUniformMatrixES3(context, GL_FLOAT_MAT3x4, location, count, transpose);
3403}
3404
3405bool ValidateUniformMatrix4x3fv(Context *context,
3406 GLint location,
3407 GLsizei count,
3408 GLboolean transpose,
3409 const GLfloat *value)
3410{
3411 return ValidateUniformMatrixES3(context, GL_FLOAT_MAT4x3, location, count, transpose);
3412}
3413
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003414bool ValidateEndTransformFeedback(Context *context)
3415{
3416 if (context->getClientMajorVersion() < 3)
3417 {
Jamie Madille0472f32018-11-27 16:32:45 -05003418 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003419 return false;
3420 }
3421
3422 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
3423 ASSERT(transformFeedback != nullptr);
3424
3425 if (!transformFeedback->isActive())
3426 {
Jamie Madille0472f32018-11-27 16:32:45 -05003427 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackNotActive);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003428 return false;
3429 }
3430
3431 return true;
3432}
3433
3434bool ValidateTransformFeedbackVaryings(Context *context,
3435 GLuint program,
3436 GLsizei count,
3437 const GLchar *const *varyings,
3438 GLenum bufferMode)
3439{
3440 if (context->getClientMajorVersion() < 3)
3441 {
Jamie Madille0472f32018-11-27 16:32:45 -05003442 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003443 return false;
3444 }
3445
3446 if (count < 0)
3447 {
Jamie Madille0472f32018-11-27 16:32:45 -05003448 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003449 return false;
3450 }
3451
3452 switch (bufferMode)
3453 {
3454 case GL_INTERLEAVED_ATTRIBS:
3455 break;
3456 case GL_SEPARATE_ATTRIBS:
3457 {
3458 const Caps &caps = context->getCaps();
3459 if (static_cast<GLuint>(count) > caps.maxTransformFeedbackSeparateAttributes)
3460 {
Jamie Madille0472f32018-11-27 16:32:45 -05003461 context->validationError(GL_INVALID_VALUE, kInvalidTransformFeedbackAttribsCount);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003462 return false;
3463 }
3464 break;
3465 }
3466 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003467 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003468 return false;
3469 }
3470
3471 Program *programObject = GetValidProgram(context, program);
3472 if (!programObject)
3473 {
3474 return false;
3475 }
3476
3477 return true;
3478}
3479
3480bool ValidateGetTransformFeedbackVarying(Context *context,
3481 GLuint program,
3482 GLuint index,
3483 GLsizei bufSize,
3484 GLsizei *length,
3485 GLsizei *size,
3486 GLenum *type,
3487 GLchar *name)
3488{
3489 if (context->getClientMajorVersion() < 3)
3490 {
Jamie Madille0472f32018-11-27 16:32:45 -05003491 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003492 return false;
3493 }
3494
3495 if (bufSize < 0)
3496 {
Jamie Madille0472f32018-11-27 16:32:45 -05003497 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003498 return false;
3499 }
3500
3501 Program *programObject = GetValidProgram(context, program);
3502 if (!programObject)
3503 {
3504 return false;
3505 }
3506
3507 if (index >= static_cast<GLuint>(programObject->getTransformFeedbackVaryingCount()))
3508 {
Jamie Madille0472f32018-11-27 16:32:45 -05003509 context->validationError(GL_INVALID_VALUE, kTransformFeedbackVaryingIndexOutOfRange);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003510 return false;
3511 }
3512
3513 return true;
3514}
3515
3516bool ValidateBindTransformFeedback(Context *context, GLenum target, GLuint id)
3517{
3518 if (context->getClientMajorVersion() < 3)
3519 {
Jamie Madille0472f32018-11-27 16:32:45 -05003520 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003521 return false;
3522 }
3523
3524 switch (target)
3525 {
3526 case GL_TRANSFORM_FEEDBACK:
3527 {
3528 // Cannot bind a transform feedback object if the current one is started and not
3529 // paused (3.0.2 pg 85 section 2.14.1)
3530 TransformFeedback *curTransformFeedback =
3531 context->getGLState().getCurrentTransformFeedback();
3532 if (curTransformFeedback && curTransformFeedback->isActive() &&
3533 !curTransformFeedback->isPaused())
3534 {
Jamie Madille0472f32018-11-27 16:32:45 -05003535 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackNotPaused);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003536 return false;
3537 }
3538
3539 // Cannot bind a transform feedback object that does not exist (3.0.2 pg 85 section
3540 // 2.14.1)
3541 if (!context->isTransformFeedbackGenerated(id))
3542 {
Jamie Madille0472f32018-11-27 16:32:45 -05003543 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackDoesNotExist);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003544 return false;
3545 }
3546 }
3547 break;
3548
3549 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003550 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003551 return false;
3552 }
3553
3554 return true;
3555}
3556
3557bool ValidateIsTransformFeedback(Context *context, GLuint id)
3558{
3559 if (context->getClientMajorVersion() < 3)
3560 {
Jamie Madille0472f32018-11-27 16:32:45 -05003561 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003562 return false;
3563 }
3564
3565 return true;
3566}
3567
3568bool ValidatePauseTransformFeedback(Context *context)
3569{
3570 if (context->getClientMajorVersion() < 3)
3571 {
Jamie Madille0472f32018-11-27 16:32:45 -05003572 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003573 return false;
3574 }
3575
3576 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
3577 ASSERT(transformFeedback != nullptr);
3578
3579 // 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 -05003580 if (!transformFeedback->isActive())
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003581 {
Jamie Madille0472f32018-11-27 16:32:45 -05003582 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackNotActive);
Jamie Madill610640f2018-11-21 17:28:41 -05003583 return false;
3584 }
3585
3586 if (transformFeedback->isPaused())
3587 {
Jamie Madille0472f32018-11-27 16:32:45 -05003588 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackPaused);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003589 return false;
3590 }
3591
3592 return true;
3593}
3594
3595bool ValidateResumeTransformFeedback(Context *context)
3596{
3597 if (context->getClientMajorVersion() < 3)
3598 {
Jamie Madille0472f32018-11-27 16:32:45 -05003599 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003600 return false;
3601 }
3602
3603 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
3604 ASSERT(transformFeedback != nullptr);
3605
3606 // Current transform feedback must be active and paused in order to resume (3.0.2 pg 86)
Jamie Madill610640f2018-11-21 17:28:41 -05003607 if (!transformFeedback->isActive())
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003608 {
Jamie Madille0472f32018-11-27 16:32:45 -05003609 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackNotActive);
Jamie Madill610640f2018-11-21 17:28:41 -05003610 return false;
3611 }
3612
3613 if (!transformFeedback->isPaused())
3614 {
Jamie Madille0472f32018-11-27 16:32:45 -05003615 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackNotPaused);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003616 return false;
3617 }
3618
3619 return true;
3620}
3621
Jamie Madill12e957f2017-08-26 21:42:26 -04003622bool ValidateVertexAttribI4i(Context *context, GLuint index, GLint x, GLint y, GLint z, GLint w)
3623{
3624 if (context->getClientMajorVersion() < 3)
3625 {
Jamie Madille0472f32018-11-27 16:32:45 -05003626 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003627 return false;
3628 }
3629
3630 return ValidateVertexAttribIndex(context, index);
3631}
3632
3633bool ValidateVertexAttribI4ui(Context *context,
3634 GLuint index,
3635 GLuint x,
3636 GLuint y,
3637 GLuint z,
3638 GLuint w)
3639{
3640 if (context->getClientMajorVersion() < 3)
3641 {
Jamie Madille0472f32018-11-27 16:32:45 -05003642 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003643 return false;
3644 }
3645
3646 return ValidateVertexAttribIndex(context, index);
3647}
3648
3649bool ValidateVertexAttribI4iv(Context *context, GLuint index, const GLint *v)
3650{
3651 if (context->getClientMajorVersion() < 3)
3652 {
Jamie Madille0472f32018-11-27 16:32:45 -05003653 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003654 return false;
3655 }
3656
3657 return ValidateVertexAttribIndex(context, index);
3658}
3659
3660bool ValidateVertexAttribI4uiv(Context *context, GLuint index, const GLuint *v)
3661{
3662 if (context->getClientMajorVersion() < 3)
3663 {
Jamie Madille0472f32018-11-27 16:32:45 -05003664 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003665 return false;
3666 }
3667
3668 return ValidateVertexAttribIndex(context, index);
3669}
3670
3671bool ValidateGetFragDataLocation(Context *context, GLuint program, const GLchar *name)
3672{
3673 if (context->getClientMajorVersion() < 3)
3674 {
Jamie Madille0472f32018-11-27 16:32:45 -05003675 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003676 return false;
3677 }
3678
3679 Program *programObject = GetValidProgram(context, program);
3680 if (!programObject)
3681 {
3682 return false;
3683 }
3684
3685 if (!programObject->isLinked())
3686 {
Jamie Madille0472f32018-11-27 16:32:45 -05003687 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madill12e957f2017-08-26 21:42:26 -04003688 return false;
3689 }
3690
3691 return true;
3692}
3693
3694bool ValidateGetUniformIndices(Context *context,
3695 GLuint program,
3696 GLsizei uniformCount,
3697 const GLchar *const *uniformNames,
3698 GLuint *uniformIndices)
3699{
3700 if (context->getClientMajorVersion() < 3)
3701 {
Jamie Madille0472f32018-11-27 16:32:45 -05003702 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003703 return false;
3704 }
3705
3706 if (uniformCount < 0)
3707 {
Jamie Madille0472f32018-11-27 16:32:45 -05003708 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madill12e957f2017-08-26 21:42:26 -04003709 return false;
3710 }
3711
3712 Program *programObject = GetValidProgram(context, program);
3713 if (!programObject)
3714 {
3715 return false;
3716 }
3717
3718 return true;
3719}
3720
3721bool ValidateGetActiveUniformsiv(Context *context,
3722 GLuint program,
3723 GLsizei uniformCount,
3724 const GLuint *uniformIndices,
3725 GLenum pname,
3726 GLint *params)
3727{
3728 if (context->getClientMajorVersion() < 3)
3729 {
Jamie Madille0472f32018-11-27 16:32:45 -05003730 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003731 return false;
3732 }
3733
3734 if (uniformCount < 0)
3735 {
Jamie Madille0472f32018-11-27 16:32:45 -05003736 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madill12e957f2017-08-26 21:42:26 -04003737 return false;
3738 }
3739
3740 Program *programObject = GetValidProgram(context, program);
3741 if (!programObject)
3742 {
3743 return false;
3744 }
3745
3746 switch (pname)
3747 {
3748 case GL_UNIFORM_TYPE:
3749 case GL_UNIFORM_SIZE:
Bryan Bernhart22f7aaf2018-08-23 14:13:51 -07003750 break;
Jamie Madill12e957f2017-08-26 21:42:26 -04003751 case GL_UNIFORM_NAME_LENGTH:
Bryan Bernhart22f7aaf2018-08-23 14:13:51 -07003752 if (context->getExtensions().webglCompatibility)
3753 {
Jamie Madille0472f32018-11-27 16:32:45 -05003754 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Bryan Bernhart22f7aaf2018-08-23 14:13:51 -07003755 return false;
3756 }
3757 break;
Jamie Madill12e957f2017-08-26 21:42:26 -04003758 case GL_UNIFORM_BLOCK_INDEX:
3759 case GL_UNIFORM_OFFSET:
3760 case GL_UNIFORM_ARRAY_STRIDE:
3761 case GL_UNIFORM_MATRIX_STRIDE:
3762 case GL_UNIFORM_IS_ROW_MAJOR:
3763 break;
3764
3765 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003766 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madill12e957f2017-08-26 21:42:26 -04003767 return false;
3768 }
3769
3770 if (uniformCount > programObject->getActiveUniformCount())
3771 {
Jamie Madille0472f32018-11-27 16:32:45 -05003772 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform);
Jamie Madill12e957f2017-08-26 21:42:26 -04003773 return false;
3774 }
3775
3776 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
3777 {
3778 const GLuint index = uniformIndices[uniformId];
3779
3780 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
3781 {
Jamie Madille0472f32018-11-27 16:32:45 -05003782 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform);
Jamie Madill12e957f2017-08-26 21:42:26 -04003783 return false;
3784 }
3785 }
3786
3787 return true;
3788}
3789
3790bool ValidateGetUniformBlockIndex(Context *context, GLuint program, const GLchar *uniformBlockName)
3791{
3792 if (context->getClientMajorVersion() < 3)
3793 {
Jamie Madille0472f32018-11-27 16:32:45 -05003794 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003795 return false;
3796 }
3797
3798 Program *programObject = GetValidProgram(context, program);
3799 if (!programObject)
3800 {
3801 return false;
3802 }
3803
3804 return true;
3805}
3806
3807bool ValidateGetActiveUniformBlockiv(Context *context,
3808 GLuint program,
3809 GLuint uniformBlockIndex,
3810 GLenum pname,
3811 GLint *params)
3812{
3813 return ValidateGetActiveUniformBlockivBase(context, program, uniformBlockIndex, pname, nullptr);
3814}
3815
3816bool ValidateGetActiveUniformBlockName(Context *context,
3817 GLuint program,
3818 GLuint uniformBlockIndex,
3819 GLsizei bufSize,
3820 GLsizei *length,
3821 GLchar *uniformBlockName)
3822{
3823 if (context->getClientMajorVersion() < 3)
3824 {
Jamie Madille0472f32018-11-27 16:32:45 -05003825 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003826 return false;
3827 }
3828
3829 Program *programObject = GetValidProgram(context, program);
3830 if (!programObject)
3831 {
3832 return false;
3833 }
3834
3835 if (uniformBlockIndex >= programObject->getActiveUniformBlockCount())
3836 {
Jamie Madille0472f32018-11-27 16:32:45 -05003837 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxActiveUniformBlock);
Jamie Madill12e957f2017-08-26 21:42:26 -04003838 return false;
3839 }
3840
3841 return true;
3842}
3843
3844bool ValidateUniformBlockBinding(Context *context,
3845 GLuint program,
3846 GLuint uniformBlockIndex,
3847 GLuint uniformBlockBinding)
3848{
3849 if (context->getClientMajorVersion() < 3)
3850 {
Jamie Madille0472f32018-11-27 16:32:45 -05003851 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003852 return false;
3853 }
3854
3855 if (uniformBlockBinding >= context->getCaps().maxUniformBufferBindings)
3856 {
Jamie Madille0472f32018-11-27 16:32:45 -05003857 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxUniformBufferBindings);
Jamie Madill12e957f2017-08-26 21:42:26 -04003858 return false;
3859 }
3860
3861 Program *programObject = GetValidProgram(context, program);
3862 if (!programObject)
3863 {
3864 return false;
3865 }
3866
3867 // if never linked, there won't be any uniform blocks
3868 if (uniformBlockIndex >= programObject->getActiveUniformBlockCount())
3869 {
Jamie Madille0472f32018-11-27 16:32:45 -05003870 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxUniformBufferBindings);
Jamie Madill12e957f2017-08-26 21:42:26 -04003871 return false;
3872 }
3873
3874 return true;
3875}
3876
3877bool ValidateDrawArraysInstanced(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04003878 PrimitiveMode mode,
Jamie Madill12e957f2017-08-26 21:42:26 -04003879 GLint first,
3880 GLsizei count,
3881 GLsizei primcount)
3882{
3883 if (context->getClientMajorVersion() < 3)
3884 {
Jamie Madille0472f32018-11-27 16:32:45 -05003885 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003886 return false;
3887 }
3888
3889 return ValidateDrawArraysInstancedBase(context, mode, first, count, primcount);
3890}
3891
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003892bool ValidateFenceSync(Context *context, GLenum condition, GLbitfield flags)
3893{
3894 if (context->getClientMajorVersion() < 3)
3895 {
Jamie Madille0472f32018-11-27 16:32:45 -05003896 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003897 return false;
3898 }
3899
3900 if (condition != GL_SYNC_GPU_COMMANDS_COMPLETE)
3901 {
Jamie Madille0472f32018-11-27 16:32:45 -05003902 context->validationError(GL_INVALID_ENUM, kInvalidFenceCondition);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003903 return false;
3904 }
3905
3906 if (flags != 0)
3907 {
Jamie Madille0472f32018-11-27 16:32:45 -05003908 context->validationError(GL_INVALID_VALUE, kInvalidFlags);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003909 return false;
3910 }
3911
3912 return true;
3913}
3914
3915bool ValidateIsSync(Context *context, GLsync sync)
3916{
3917 if (context->getClientMajorVersion() < 3)
3918 {
Jamie Madille0472f32018-11-27 16:32:45 -05003919 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003920 return false;
3921 }
3922
3923 return true;
3924}
3925
3926bool ValidateDeleteSync(Context *context, GLsync sync)
3927{
3928 if (context->getClientMajorVersion() < 3)
3929 {
Jamie Madille0472f32018-11-27 16:32:45 -05003930 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003931 return false;
3932 }
3933
Jamie Madill70b5bb02017-08-28 13:32:37 -04003934 if (sync != static_cast<GLsync>(0) && !context->getSync(sync))
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003935 {
Jamie Madille0472f32018-11-27 16:32:45 -05003936 context->validationError(GL_INVALID_VALUE, kSyncMissing);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003937 return false;
3938 }
3939
3940 return true;
3941}
3942
3943bool ValidateClientWaitSync(Context *context, GLsync sync, GLbitfield flags, GLuint64 timeout)
3944{
3945 if (context->getClientMajorVersion() < 3)
3946 {
Jamie Madille0472f32018-11-27 16:32:45 -05003947 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003948 return false;
3949 }
3950
3951 if ((flags & ~(GL_SYNC_FLUSH_COMMANDS_BIT)) != 0)
3952 {
Jamie Madille0472f32018-11-27 16:32:45 -05003953 context->validationError(GL_INVALID_VALUE, kInvalidFlags);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003954 return false;
3955 }
3956
Jamie Madill70b5bb02017-08-28 13:32:37 -04003957 Sync *clientWaitSync = context->getSync(sync);
3958 if (!clientWaitSync)
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003959 {
Jamie Madille0472f32018-11-27 16:32:45 -05003960 context->validationError(GL_INVALID_VALUE, kSyncMissing);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003961 return false;
3962 }
3963
3964 return true;
3965}
3966
3967bool ValidateWaitSync(Context *context, GLsync sync, GLbitfield flags, GLuint64 timeout)
3968{
3969 if (context->getClientMajorVersion() < 3)
3970 {
Jamie Madille0472f32018-11-27 16:32:45 -05003971 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003972 return false;
3973 }
3974
3975 if (flags != 0)
3976 {
Jamie Madille0472f32018-11-27 16:32:45 -05003977 context->validationError(GL_INVALID_VALUE, kInvalidFlags);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003978 return false;
3979 }
3980
3981 if (timeout != GL_TIMEOUT_IGNORED)
3982 {
Jamie Madille0472f32018-11-27 16:32:45 -05003983 context->validationError(GL_INVALID_VALUE, kInvalidTimeout);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003984 return false;
3985 }
3986
Jamie Madill70b5bb02017-08-28 13:32:37 -04003987 Sync *waitSync = context->getSync(sync);
3988 if (!waitSync)
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003989 {
Jamie Madille0472f32018-11-27 16:32:45 -05003990 context->validationError(GL_INVALID_VALUE, kSyncMissing);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003991 return false;
3992 }
3993
3994 return true;
3995}
3996
3997bool ValidateGetInteger64v(Context *context, GLenum pname, GLint64 *params)
3998{
3999 if (context->getClientMajorVersion() < 3)
4000 {
Jamie Madille0472f32018-11-27 16:32:45 -05004001 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04004002 return false;
4003 }
4004
4005 GLenum nativeType = GL_NONE;
4006 unsigned int numParams = 0;
4007 if (!ValidateStateQuery(context, pname, &nativeType, &numParams))
4008 {
4009 return false;
4010 }
4011
4012 return true;
4013}
4014
Jamie Madill3ef140a2017-08-26 23:11:21 -04004015bool ValidateIsSampler(Context *context, GLuint sampler)
4016{
4017 if (context->getClientMajorVersion() < 3)
4018 {
Jamie Madille0472f32018-11-27 16:32:45 -05004019 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill3ef140a2017-08-26 23:11:21 -04004020 return false;
4021 }
4022
4023 return true;
4024}
4025
4026bool ValidateBindSampler(Context *context, GLuint unit, GLuint sampler)
4027{
4028 if (context->getClientMajorVersion() < 3)
4029 {
Jamie Madille0472f32018-11-27 16:32:45 -05004030 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill3ef140a2017-08-26 23:11:21 -04004031 return false;
4032 }
4033
4034 if (sampler != 0 && !context->isSampler(sampler))
4035 {
Jamie Madille0472f32018-11-27 16:32:45 -05004036 context->validationError(GL_INVALID_OPERATION, kInvalidSampler);
Jamie Madill3ef140a2017-08-26 23:11:21 -04004037 return false;
4038 }
4039
4040 if (unit >= context->getCaps().maxCombinedTextureImageUnits)
4041 {
Jamie Madille0472f32018-11-27 16:32:45 -05004042 context->validationError(GL_INVALID_VALUE, kInvalidCombinedImageUnit);
Jamie Madill3ef140a2017-08-26 23:11:21 -04004043 return false;
4044 }
4045
4046 return true;
4047}
4048
4049bool ValidateVertexAttribDivisor(Context *context, GLuint index, GLuint divisor)
4050{
4051 if (context->getClientMajorVersion() < 3)
4052 {
Jamie Madille0472f32018-11-27 16:32:45 -05004053 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill3ef140a2017-08-26 23:11:21 -04004054 return false;
4055 }
4056
4057 return ValidateVertexAttribIndex(context, index);
4058}
4059
4060bool ValidateTexStorage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004061 TextureType target,
Jamie Madill3ef140a2017-08-26 23:11:21 -04004062 GLsizei levels,
4063 GLenum internalformat,
4064 GLsizei width,
4065 GLsizei height)
4066{
4067 if (context->getClientMajorVersion() < 3)
4068 {
Jamie Madille0472f32018-11-27 16:32:45 -05004069 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill3ef140a2017-08-26 23:11:21 -04004070 return false;
4071 }
4072
4073 if (!ValidateES3TexStorage2DParameters(context, target, levels, internalformat, width, height,
4074 1))
4075 {
4076 return false;
4077 }
4078
4079 return true;
4080}
4081
4082bool ValidateTexStorage3D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004083 TextureType target,
Jamie Madill3ef140a2017-08-26 23:11:21 -04004084 GLsizei levels,
4085 GLenum internalformat,
4086 GLsizei width,
4087 GLsizei height,
4088 GLsizei depth)
4089{
4090 if (context->getClientMajorVersion() < 3)
4091 {
Jamie Madille0472f32018-11-27 16:32:45 -05004092 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill3ef140a2017-08-26 23:11:21 -04004093 return false;
4094 }
4095
4096 if (!ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
4097 depth))
4098 {
4099 return false;
4100 }
4101
4102 return true;
4103}
4104
Jamie Madill5b772312018-03-08 20:28:32 -05004105bool ValidateGetBufferParameteri64v(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004106 BufferBinding target,
Jamie Madill9696d072017-08-26 23:19:57 -04004107 GLenum pname,
4108 GLint64 *params)
4109{
4110 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
4111}
4112
4113bool ValidateGetSamplerParameterfv(Context *context, GLuint sampler, GLenum pname, GLfloat *params)
4114{
4115 return ValidateGetSamplerParameterBase(context, sampler, pname, nullptr);
4116}
4117
4118bool ValidateGetSamplerParameteriv(Context *context, GLuint sampler, GLenum pname, GLint *params)
4119{
4120 return ValidateGetSamplerParameterBase(context, sampler, pname, nullptr);
4121}
4122
Till Rathmannb8543632018-10-02 19:46:14 +02004123bool ValidateGetSamplerParameterIivOES(Context *context,
4124 GLuint sampler,
4125 GLenum pname,
Jamie Madill778bf092018-11-14 09:54:36 -05004126 GLint *params)
Till Rathmannb8543632018-10-02 19:46:14 +02004127{
4128 if (context->getClientMajorVersion() < 3)
4129 {
Jamie Madille0472f32018-11-27 16:32:45 -05004130 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02004131 return false;
4132 }
4133 return ValidateGetSamplerParameterBase(context, sampler, pname, nullptr);
4134}
4135
4136bool ValidateGetSamplerParameterIuivOES(Context *context,
4137 GLuint sampler,
4138 GLenum pname,
Jamie Madill778bf092018-11-14 09:54:36 -05004139 GLuint *params)
Till Rathmannb8543632018-10-02 19:46:14 +02004140{
4141 if (context->getClientMajorVersion() < 3)
4142 {
Jamie Madille0472f32018-11-27 16:32:45 -05004143 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02004144 return false;
4145 }
4146 return ValidateGetSamplerParameterBase(context, sampler, pname, nullptr);
4147}
4148
Jamie Madill9696d072017-08-26 23:19:57 -04004149bool ValidateSamplerParameterf(Context *context, GLuint sampler, GLenum pname, GLfloat param)
4150{
Till Rathmannb8543632018-10-02 19:46:14 +02004151 return ValidateSamplerParameterBase(context, sampler, pname, -1, false, &param);
Jamie Madill9696d072017-08-26 23:19:57 -04004152}
4153
4154bool ValidateSamplerParameterfv(Context *context,
4155 GLuint sampler,
4156 GLenum pname,
4157 const GLfloat *params)
4158{
Till Rathmannb8543632018-10-02 19:46:14 +02004159 return ValidateSamplerParameterBase(context, sampler, pname, -1, true, params);
Jamie Madill9696d072017-08-26 23:19:57 -04004160}
4161
4162bool ValidateSamplerParameteri(Context *context, GLuint sampler, GLenum pname, GLint param)
4163{
Till Rathmannb8543632018-10-02 19:46:14 +02004164 return ValidateSamplerParameterBase(context, sampler, pname, -1, false, &param);
Jamie Madill9696d072017-08-26 23:19:57 -04004165}
4166
4167bool ValidateSamplerParameteriv(Context *context, GLuint sampler, GLenum pname, const GLint *params)
4168{
Till Rathmannb8543632018-10-02 19:46:14 +02004169 return ValidateSamplerParameterBase(context, sampler, pname, -1, true, params);
4170}
4171
4172bool ValidateSamplerParameterIivOES(Context *context,
4173 GLuint sampler,
4174 GLenum pname,
4175 const GLint *params)
4176{
4177 if (context->getClientMajorVersion() < 3)
4178 {
Jamie Madille0472f32018-11-27 16:32:45 -05004179 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02004180 return false;
4181 }
4182 return ValidateSamplerParameterBase(context, sampler, pname, -1, true, params);
4183}
4184
4185bool ValidateSamplerParameterIuivOES(Context *context,
4186 GLuint sampler,
4187 GLenum pname,
4188 const GLuint *params)
4189{
4190 if (context->getClientMajorVersion() < 3)
4191 {
Jamie Madille0472f32018-11-27 16:32:45 -05004192 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02004193 return false;
4194 }
4195 return ValidateSamplerParameterBase(context, sampler, pname, -1, true, params);
Jamie Madill9696d072017-08-26 23:19:57 -04004196}
4197
4198bool ValidateGetVertexAttribIiv(Context *context, GLuint index, GLenum pname, GLint *params)
4199{
4200 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, true);
4201}
4202
4203bool ValidateGetVertexAttribIuiv(Context *context, GLuint index, GLenum pname, GLuint *params)
4204{
4205 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, true);
4206}
4207
4208bool ValidateGetInternalformativ(Context *context,
4209 GLenum target,
4210 GLenum internalformat,
4211 GLenum pname,
4212 GLsizei bufSize,
4213 GLint *params)
4214{
4215 return ValidateGetInternalFormativBase(context, target, internalformat, pname, bufSize,
4216 nullptr);
4217}
4218
Olli Etuaho0ca09752018-09-24 11:00:50 +03004219bool ValidateBindFragDataLocationIndexedEXT(Context *context,
4220 GLuint program,
4221 GLuint colorNumber,
4222 GLuint index,
4223 const char *name)
4224{
4225 if (!context->getExtensions().blendFuncExtended)
4226 {
Jamie Madille0472f32018-11-27 16:32:45 -05004227 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho0ca09752018-09-24 11:00:50 +03004228 return false;
4229 }
4230 if (context->getClientMajorVersion() < 3)
4231 {
Jamie Madille0472f32018-11-27 16:32:45 -05004232 context->validationError(GL_INVALID_OPERATION, kES3Required);
Olli Etuaho0ca09752018-09-24 11:00:50 +03004233 return false;
4234 }
4235 if (index < 0 || index > 1)
4236 {
4237 // This error is not explicitly specified but the spec does say that "<index> may be zero or
4238 // one to specify that the color be used as either the first or second color input to the
4239 // blend equation, respectively"
Jamie Madille0472f32018-11-27 16:32:45 -05004240 context->validationError(GL_INVALID_VALUE, kFragDataBindingIndexOutOfRange);
Olli Etuaho0ca09752018-09-24 11:00:50 +03004241 return false;
4242 }
4243 if (index == 1)
4244 {
4245 if (colorNumber >= context->getExtensions().maxDualSourceDrawBuffers)
4246 {
Jamie Madill610640f2018-11-21 17:28:41 -05004247 context->validationError(GL_INVALID_VALUE,
Jamie Madille0472f32018-11-27 16:32:45 -05004248 kColorNumberGreaterThanMaxDualSourceDrawBuffers);
Olli Etuaho0ca09752018-09-24 11:00:50 +03004249 return false;
4250 }
4251 }
4252 else
4253 {
4254 if (colorNumber >= context->getCaps().maxDrawBuffers)
4255 {
Jamie Madille0472f32018-11-27 16:32:45 -05004256 context->validationError(GL_INVALID_VALUE, kColorNumberGreaterThanMaxDrawBuffers);
Olli Etuaho0ca09752018-09-24 11:00:50 +03004257 return false;
4258 }
4259 }
4260 Program *programObject = GetValidProgram(context, program);
4261 if (!programObject)
4262 {
4263 return false;
4264 }
4265 return true;
4266}
4267
4268bool ValidateBindFragDataLocationEXT(Context *context,
4269 GLuint program,
4270 GLuint colorNumber,
4271 const char *name)
4272{
4273 return ValidateBindFragDataLocationIndexedEXT(context, program, colorNumber, 0u, name);
4274}
4275
4276bool ValidateGetFragDataIndexEXT(Context *context, GLuint program, const char *name)
4277{
4278 if (!context->getExtensions().blendFuncExtended)
4279 {
Jamie Madille0472f32018-11-27 16:32:45 -05004280 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho0ca09752018-09-24 11:00:50 +03004281 return false;
4282 }
4283 if (context->getClientMajorVersion() < 3)
4284 {
Jamie Madille0472f32018-11-27 16:32:45 -05004285 context->validationError(GL_INVALID_OPERATION, kES3Required);
Olli Etuaho0ca09752018-09-24 11:00:50 +03004286 return false;
4287 }
4288 Program *programObject = GetValidProgram(context, program);
4289 if (!programObject)
4290 {
4291 return false;
4292 }
4293 if (!programObject->isLinked())
4294 {
Jamie Madille0472f32018-11-27 16:32:45 -05004295 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Olli Etuaho0ca09752018-09-24 11:00:50 +03004296 return false;
4297 }
4298 return true;
4299}
4300
Yizhou Jiang7818a852018-09-06 15:02:04 +08004301bool ValidateTexStorage2DMultisampleANGLE(Context *context,
4302 TextureType target,
4303 GLsizei samples,
Jamie Madill778bf092018-11-14 09:54:36 -05004304 GLenum internalFormat,
Yizhou Jiang7818a852018-09-06 15:02:04 +08004305 GLsizei width,
4306 GLsizei height,
4307 GLboolean fixedSampleLocations)
4308{
4309 if (!context->getExtensions().textureMultisample)
4310 {
Jamie Madille0472f32018-11-27 16:32:45 -05004311 context->validationError(GL_INVALID_OPERATION, kMultisampleTextureExtensionOrES31Required);
Yizhou Jiang7818a852018-09-06 15:02:04 +08004312 return false;
4313 }
4314
4315 return ValidateTexStorage2DMultisampleBase(context, target, samples, internalFormat, width,
4316 height);
4317}
4318
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08004319bool ValidateGetTexLevelParameterfvANGLE(Context *context,
4320 TextureTarget target,
4321 GLint level,
4322 GLenum pname,
4323 GLfloat *params)
4324{
4325 if (!context->getExtensions().textureMultisample)
4326 {
Jamie Madille0472f32018-11-27 16:32:45 -05004327 context->validationError(GL_INVALID_OPERATION, kMultisampleTextureExtensionOrES31Required);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08004328 return false;
4329 }
4330
4331 return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr);
4332}
4333
4334bool ValidateGetTexLevelParameterivANGLE(Context *context,
4335 TextureTarget target,
4336 GLint level,
4337 GLenum pname,
4338 GLint *params)
4339{
4340 if (!context->getExtensions().textureMultisample)
4341 {
Jamie Madille0472f32018-11-27 16:32:45 -05004342 context->validationError(GL_INVALID_OPERATION, kMultisampleTextureExtensionOrES31Required);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08004343 return false;
4344 }
4345
4346 return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr);
4347}
4348
Yizhou Jiang7310da32018-11-05 14:40:01 +08004349bool ValidateGetMultisamplefvANGLE(Context *context, GLenum pname, GLuint index, GLfloat *val)
4350{
4351 if (!context->getExtensions().textureMultisample)
4352 {
4353 context->validationError(GL_INVALID_OPERATION, kMultisampleTextureExtensionOrES31Required);
4354 return false;
4355 }
4356
4357 return ValidateGetMultisamplefvBase(context, pname, index, val);
4358}
4359
4360bool ValidateSampleMaskiANGLE(Context *context, GLuint maskNumber, GLbitfield mask)
4361{
4362 if (!context->getExtensions().textureMultisample)
4363 {
4364 context->validationError(GL_INVALID_OPERATION, kMultisampleTextureExtensionOrES31Required);
4365 return false;
4366 }
4367
4368 return ValidateSampleMaskiBase(context, maskNumber, mask);
4369}
Jamie Madillc29968b2016-01-20 11:17:23 -05004370} // namespace gl