blob: b499f1f3da097eda27b76e6f711a8ecbbfb7a463 [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,
1416 GLenum 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,
3104 GLenum 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,
3155 GLenum type,
3156 const GLsizei *offsets,
3157 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 {
3179 const void *indices = reinterpret_cast<void *>(static_cast<long>(offsets[drawID]));
3180 if (!ValidateDrawElementsInstancedCommon(context, mode, counts[drawID], type, indices,
3181 instanceCounts[drawID]))
3182 {
3183 return false;
3184 }
3185 }
3186 return true;
3187}
3188
Martin Radev137032d2017-07-13 10:11:12 +03003189bool ValidateFramebufferTextureMultiviewLayeredANGLE(Context *context,
3190 GLenum target,
3191 GLenum attachment,
3192 GLuint texture,
3193 GLint level,
3194 GLint baseViewIndex,
3195 GLsizei numViews)
3196{
Martin Radev137032d2017-07-13 10:11:12 +03003197 if (!ValidateFramebufferTextureMultiviewBaseANGLE(context, target, attachment, texture, level,
3198 numViews))
3199 {
3200 return false;
3201 }
3202
Martin Radev137032d2017-07-13 10:11:12 +03003203 if (texture != 0)
3204 {
Martin Radev14b21262017-08-25 13:54:37 +03003205 if (baseViewIndex < 0)
3206 {
Jamie Madill610640f2018-11-21 17:28:41 -05003207 context->validationError(GL_INVALID_VALUE, "baseViewIndex cannot be less than 0.");
Martin Radev14b21262017-08-25 13:54:37 +03003208 return false;
3209 }
3210
Martin Radev137032d2017-07-13 10:11:12 +03003211 Texture *tex = context->getTexture(texture);
3212 ASSERT(tex);
3213
Corentin Wallez99d492c2018-02-27 15:17:10 -05003214 switch (tex->getType())
Martin Radev137032d2017-07-13 10:11:12 +03003215 {
Corentin Wallez99d492c2018-02-27 15:17:10 -05003216 case TextureType::_2DArray:
Olli Etuaho2c8f0842018-09-12 14:44:55 +03003217 case TextureType::_2DMultisampleArray:
Martin Radev137032d2017-07-13 10:11:12 +03003218 {
Olli Etuaho2c8f0842018-09-12 14:44:55 +03003219 if (tex->getType() == TextureType::_2DMultisampleArray)
3220 {
3221 if (!context->getExtensions().multiviewMultisample)
3222 {
Jamie Madill610640f2018-11-21 17:28:41 -05003223 context->validationError(GL_INVALID_OPERATION,
3224 "Texture's target must be GL_TEXTURE_2D_ARRAY.");
Olli Etuaho2c8f0842018-09-12 14:44:55 +03003225 return false;
3226 }
3227 }
3228
Martin Radev137032d2017-07-13 10:11:12 +03003229 const Caps &caps = context->getCaps();
3230 if (static_cast<GLuint>(baseViewIndex + numViews) > caps.maxArrayTextureLayers)
3231 {
Jamie Madill610640f2018-11-21 17:28:41 -05003232 context->validationError(GL_INVALID_VALUE,
3233 "baseViewIndex+numViews cannot be "
3234 "greater than "
3235 "GL_MAX_ARRAY_TEXTURE_LAYERS.");
Martin Radev137032d2017-07-13 10:11:12 +03003236 return false;
3237 }
Olli Etuaho2c8f0842018-09-12 14:44:55 +03003238
3239 break;
Martin Radev137032d2017-07-13 10:11:12 +03003240 }
Martin Radev137032d2017-07-13 10:11:12 +03003241 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003242 context->validationError(GL_INVALID_OPERATION,
3243 "Texture's target must be GL_TEXTURE_2D_ARRAY.");
Martin Radev137032d2017-07-13 10:11:12 +03003244 return false;
3245 }
3246
3247 if (!ValidateFramebufferTextureMultiviewLevelAndFormat(context, tex, level))
3248 {
3249 return false;
3250 }
3251 }
3252
3253 return true;
3254}
3255
3256bool ValidateFramebufferTextureMultiviewSideBySideANGLE(Context *context,
3257 GLenum target,
3258 GLenum attachment,
3259 GLuint texture,
3260 GLint level,
3261 GLsizei numViews,
3262 const GLint *viewportOffsets)
3263{
3264 if (!ValidateFramebufferTextureMultiviewBaseANGLE(context, target, attachment, texture, level,
3265 numViews))
3266 {
3267 return false;
3268 }
3269
Martin Radev137032d2017-07-13 10:11:12 +03003270 if (texture != 0)
3271 {
Martin Radev14b21262017-08-25 13:54:37 +03003272 const GLsizei numViewportOffsetValues = numViews * 2;
3273 for (GLsizei i = 0; i < numViewportOffsetValues; ++i)
3274 {
3275 if (viewportOffsets[i] < 0)
3276 {
Jamie Madill610640f2018-11-21 17:28:41 -05003277 context->validationError(GL_INVALID_VALUE,
3278 "viewportOffsets cannot contain negative values.");
Martin Radev14b21262017-08-25 13:54:37 +03003279 return false;
3280 }
3281 }
3282
Martin Radev137032d2017-07-13 10:11:12 +03003283 Texture *tex = context->getTexture(texture);
3284 ASSERT(tex);
3285
Corentin Wallez99d492c2018-02-27 15:17:10 -05003286 switch (tex->getType())
Martin Radev137032d2017-07-13 10:11:12 +03003287 {
Corentin Wallez99d492c2018-02-27 15:17:10 -05003288 case TextureType::_2D:
Martin Radev137032d2017-07-13 10:11:12 +03003289 break;
3290 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003291 context->validationError(GL_INVALID_OPERATION,
3292 "Texture's target must be GL_TEXTURE_2D.");
Martin Radev137032d2017-07-13 10:11:12 +03003293 return false;
3294 }
3295
3296 if (!ValidateFramebufferTextureMultiviewLevelAndFormat(context, tex, level))
3297 {
3298 return false;
3299 }
3300 }
3301
3302 return true;
3303}
3304
Jamie Madillff325f12017-08-26 15:06:05 -04003305bool ValidateUniform1ui(Context *context, GLint location, GLuint v0)
3306{
3307 return ValidateUniformES3(context, GL_UNSIGNED_INT, location, 1);
3308}
3309
3310bool ValidateUniform2ui(Context *context, GLint location, GLuint v0, GLuint v1)
3311{
3312 return ValidateUniformES3(context, GL_UNSIGNED_INT_VEC2, location, 1);
3313}
3314
3315bool ValidateUniform3ui(Context *context, GLint location, GLuint v0, GLuint v1, GLuint v2)
3316{
3317 return ValidateUniformES3(context, GL_UNSIGNED_INT_VEC3, location, 1);
3318}
3319
3320bool ValidateUniform4ui(Context *context,
3321 GLint location,
3322 GLuint v0,
3323 GLuint v1,
3324 GLuint v2,
3325 GLuint v3)
3326{
3327 return ValidateUniformES3(context, GL_UNSIGNED_INT_VEC4, location, 1);
3328}
3329
3330bool ValidateUniform1uiv(Context *context, GLint location, GLsizei count, const GLuint *value)
3331{
3332 return ValidateUniformES3(context, GL_UNSIGNED_INT, location, count);
3333}
3334
3335bool ValidateUniform2uiv(Context *context, GLint location, GLsizei count, const GLuint *value)
3336{
3337 return ValidateUniformES3(context, GL_UNSIGNED_INT_VEC2, location, count);
3338}
3339
3340bool ValidateUniform3uiv(Context *context, GLint location, GLsizei count, const GLuint *value)
3341{
3342 return ValidateUniformES3(context, GL_UNSIGNED_INT_VEC3, location, count);
3343}
3344
3345bool ValidateUniform4uiv(Context *context, GLint location, GLsizei count, const GLuint *value)
3346{
3347 return ValidateUniformES3(context, GL_UNSIGNED_INT_VEC4, location, count);
3348}
3349
Jamie Madillf0e04492017-08-26 15:28:42 -04003350bool ValidateIsQuery(Context *context, GLuint id)
3351{
3352 if (context->getClientMajorVersion() < 3)
3353 {
Jamie Madille0472f32018-11-27 16:32:45 -05003354 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madillf0e04492017-08-26 15:28:42 -04003355 return false;
3356 }
3357
3358 return true;
3359}
3360
Jamie Madillc8c95812017-08-26 18:40:09 -04003361bool ValidateUniformMatrix2x3fv(Context *context,
3362 GLint location,
3363 GLsizei count,
3364 GLboolean transpose,
3365 const GLfloat *value)
3366{
3367 return ValidateUniformMatrixES3(context, GL_FLOAT_MAT2x3, location, count, transpose);
3368}
3369
3370bool ValidateUniformMatrix3x2fv(Context *context,
3371 GLint location,
3372 GLsizei count,
3373 GLboolean transpose,
3374 const GLfloat *value)
3375{
3376 return ValidateUniformMatrixES3(context, GL_FLOAT_MAT3x2, location, count, transpose);
3377}
3378
3379bool ValidateUniformMatrix2x4fv(Context *context,
3380 GLint location,
3381 GLsizei count,
3382 GLboolean transpose,
3383 const GLfloat *value)
3384{
3385 return ValidateUniformMatrixES3(context, GL_FLOAT_MAT2x4, location, count, transpose);
3386}
3387
3388bool ValidateUniformMatrix4x2fv(Context *context,
3389 GLint location,
3390 GLsizei count,
3391 GLboolean transpose,
3392 const GLfloat *value)
3393{
3394 return ValidateUniformMatrixES3(context, GL_FLOAT_MAT4x2, location, count, transpose);
3395}
3396
3397bool ValidateUniformMatrix3x4fv(Context *context,
3398 GLint location,
3399 GLsizei count,
3400 GLboolean transpose,
3401 const GLfloat *value)
3402{
3403 return ValidateUniformMatrixES3(context, GL_FLOAT_MAT3x4, location, count, transpose);
3404}
3405
3406bool ValidateUniformMatrix4x3fv(Context *context,
3407 GLint location,
3408 GLsizei count,
3409 GLboolean transpose,
3410 const GLfloat *value)
3411{
3412 return ValidateUniformMatrixES3(context, GL_FLOAT_MAT4x3, location, count, transpose);
3413}
3414
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003415bool ValidateEndTransformFeedback(Context *context)
3416{
3417 if (context->getClientMajorVersion() < 3)
3418 {
Jamie Madille0472f32018-11-27 16:32:45 -05003419 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003420 return false;
3421 }
3422
3423 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
3424 ASSERT(transformFeedback != nullptr);
3425
3426 if (!transformFeedback->isActive())
3427 {
Jamie Madille0472f32018-11-27 16:32:45 -05003428 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackNotActive);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003429 return false;
3430 }
3431
3432 return true;
3433}
3434
3435bool ValidateTransformFeedbackVaryings(Context *context,
3436 GLuint program,
3437 GLsizei count,
3438 const GLchar *const *varyings,
3439 GLenum bufferMode)
3440{
3441 if (context->getClientMajorVersion() < 3)
3442 {
Jamie Madille0472f32018-11-27 16:32:45 -05003443 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003444 return false;
3445 }
3446
3447 if (count < 0)
3448 {
Jamie Madille0472f32018-11-27 16:32:45 -05003449 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003450 return false;
3451 }
3452
3453 switch (bufferMode)
3454 {
3455 case GL_INTERLEAVED_ATTRIBS:
3456 break;
3457 case GL_SEPARATE_ATTRIBS:
3458 {
3459 const Caps &caps = context->getCaps();
3460 if (static_cast<GLuint>(count) > caps.maxTransformFeedbackSeparateAttributes)
3461 {
Jamie Madille0472f32018-11-27 16:32:45 -05003462 context->validationError(GL_INVALID_VALUE, kInvalidTransformFeedbackAttribsCount);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003463 return false;
3464 }
3465 break;
3466 }
3467 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003468 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003469 return false;
3470 }
3471
3472 Program *programObject = GetValidProgram(context, program);
3473 if (!programObject)
3474 {
3475 return false;
3476 }
3477
3478 return true;
3479}
3480
3481bool ValidateGetTransformFeedbackVarying(Context *context,
3482 GLuint program,
3483 GLuint index,
3484 GLsizei bufSize,
3485 GLsizei *length,
3486 GLsizei *size,
3487 GLenum *type,
3488 GLchar *name)
3489{
3490 if (context->getClientMajorVersion() < 3)
3491 {
Jamie Madille0472f32018-11-27 16:32:45 -05003492 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003493 return false;
3494 }
3495
3496 if (bufSize < 0)
3497 {
Jamie Madille0472f32018-11-27 16:32:45 -05003498 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003499 return false;
3500 }
3501
3502 Program *programObject = GetValidProgram(context, program);
3503 if (!programObject)
3504 {
3505 return false;
3506 }
3507
3508 if (index >= static_cast<GLuint>(programObject->getTransformFeedbackVaryingCount()))
3509 {
Jamie Madille0472f32018-11-27 16:32:45 -05003510 context->validationError(GL_INVALID_VALUE, kTransformFeedbackVaryingIndexOutOfRange);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003511 return false;
3512 }
3513
3514 return true;
3515}
3516
3517bool ValidateBindTransformFeedback(Context *context, GLenum target, GLuint id)
3518{
3519 if (context->getClientMajorVersion() < 3)
3520 {
Jamie Madille0472f32018-11-27 16:32:45 -05003521 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003522 return false;
3523 }
3524
3525 switch (target)
3526 {
3527 case GL_TRANSFORM_FEEDBACK:
3528 {
3529 // Cannot bind a transform feedback object if the current one is started and not
3530 // paused (3.0.2 pg 85 section 2.14.1)
3531 TransformFeedback *curTransformFeedback =
3532 context->getGLState().getCurrentTransformFeedback();
3533 if (curTransformFeedback && curTransformFeedback->isActive() &&
3534 !curTransformFeedback->isPaused())
3535 {
Jamie Madille0472f32018-11-27 16:32:45 -05003536 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackNotPaused);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003537 return false;
3538 }
3539
3540 // Cannot bind a transform feedback object that does not exist (3.0.2 pg 85 section
3541 // 2.14.1)
3542 if (!context->isTransformFeedbackGenerated(id))
3543 {
Jamie Madille0472f32018-11-27 16:32:45 -05003544 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackDoesNotExist);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003545 return false;
3546 }
3547 }
3548 break;
3549
3550 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003551 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003552 return false;
3553 }
3554
3555 return true;
3556}
3557
3558bool ValidateIsTransformFeedback(Context *context, GLuint id)
3559{
3560 if (context->getClientMajorVersion() < 3)
3561 {
Jamie Madille0472f32018-11-27 16:32:45 -05003562 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003563 return false;
3564 }
3565
3566 return true;
3567}
3568
3569bool ValidatePauseTransformFeedback(Context *context)
3570{
3571 if (context->getClientMajorVersion() < 3)
3572 {
Jamie Madille0472f32018-11-27 16:32:45 -05003573 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003574 return false;
3575 }
3576
3577 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
3578 ASSERT(transformFeedback != nullptr);
3579
3580 // 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 -05003581 if (!transformFeedback->isActive())
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003582 {
Jamie Madille0472f32018-11-27 16:32:45 -05003583 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackNotActive);
Jamie Madill610640f2018-11-21 17:28:41 -05003584 return false;
3585 }
3586
3587 if (transformFeedback->isPaused())
3588 {
Jamie Madille0472f32018-11-27 16:32:45 -05003589 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackPaused);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003590 return false;
3591 }
3592
3593 return true;
3594}
3595
3596bool ValidateResumeTransformFeedback(Context *context)
3597{
3598 if (context->getClientMajorVersion() < 3)
3599 {
Jamie Madille0472f32018-11-27 16:32:45 -05003600 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003601 return false;
3602 }
3603
3604 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
3605 ASSERT(transformFeedback != nullptr);
3606
3607 // Current transform feedback must be active and paused in order to resume (3.0.2 pg 86)
Jamie Madill610640f2018-11-21 17:28:41 -05003608 if (!transformFeedback->isActive())
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003609 {
Jamie Madille0472f32018-11-27 16:32:45 -05003610 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackNotActive);
Jamie Madill610640f2018-11-21 17:28:41 -05003611 return false;
3612 }
3613
3614 if (!transformFeedback->isPaused())
3615 {
Jamie Madille0472f32018-11-27 16:32:45 -05003616 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackNotPaused);
Jamie Madillf0dcb8b2017-08-26 19:05:13 -04003617 return false;
3618 }
3619
3620 return true;
3621}
3622
Jamie Madill12e957f2017-08-26 21:42:26 -04003623bool ValidateVertexAttribI4i(Context *context, GLuint index, GLint x, GLint y, GLint z, GLint w)
3624{
3625 if (context->getClientMajorVersion() < 3)
3626 {
Jamie Madille0472f32018-11-27 16:32:45 -05003627 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003628 return false;
3629 }
3630
3631 return ValidateVertexAttribIndex(context, index);
3632}
3633
3634bool ValidateVertexAttribI4ui(Context *context,
3635 GLuint index,
3636 GLuint x,
3637 GLuint y,
3638 GLuint z,
3639 GLuint w)
3640{
3641 if (context->getClientMajorVersion() < 3)
3642 {
Jamie Madille0472f32018-11-27 16:32:45 -05003643 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003644 return false;
3645 }
3646
3647 return ValidateVertexAttribIndex(context, index);
3648}
3649
3650bool ValidateVertexAttribI4iv(Context *context, GLuint index, const GLint *v)
3651{
3652 if (context->getClientMajorVersion() < 3)
3653 {
Jamie Madille0472f32018-11-27 16:32:45 -05003654 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003655 return false;
3656 }
3657
3658 return ValidateVertexAttribIndex(context, index);
3659}
3660
3661bool ValidateVertexAttribI4uiv(Context *context, GLuint index, const GLuint *v)
3662{
3663 if (context->getClientMajorVersion() < 3)
3664 {
Jamie Madille0472f32018-11-27 16:32:45 -05003665 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003666 return false;
3667 }
3668
3669 return ValidateVertexAttribIndex(context, index);
3670}
3671
3672bool ValidateGetFragDataLocation(Context *context, GLuint program, const GLchar *name)
3673{
3674 if (context->getClientMajorVersion() < 3)
3675 {
Jamie Madille0472f32018-11-27 16:32:45 -05003676 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003677 return false;
3678 }
3679
3680 Program *programObject = GetValidProgram(context, program);
3681 if (!programObject)
3682 {
3683 return false;
3684 }
3685
3686 if (!programObject->isLinked())
3687 {
Jamie Madille0472f32018-11-27 16:32:45 -05003688 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madill12e957f2017-08-26 21:42:26 -04003689 return false;
3690 }
3691
3692 return true;
3693}
3694
3695bool ValidateGetUniformIndices(Context *context,
3696 GLuint program,
3697 GLsizei uniformCount,
3698 const GLchar *const *uniformNames,
3699 GLuint *uniformIndices)
3700{
3701 if (context->getClientMajorVersion() < 3)
3702 {
Jamie Madille0472f32018-11-27 16:32:45 -05003703 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003704 return false;
3705 }
3706
3707 if (uniformCount < 0)
3708 {
Jamie Madille0472f32018-11-27 16:32:45 -05003709 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madill12e957f2017-08-26 21:42:26 -04003710 return false;
3711 }
3712
3713 Program *programObject = GetValidProgram(context, program);
3714 if (!programObject)
3715 {
3716 return false;
3717 }
3718
3719 return true;
3720}
3721
3722bool ValidateGetActiveUniformsiv(Context *context,
3723 GLuint program,
3724 GLsizei uniformCount,
3725 const GLuint *uniformIndices,
3726 GLenum pname,
3727 GLint *params)
3728{
3729 if (context->getClientMajorVersion() < 3)
3730 {
Jamie Madille0472f32018-11-27 16:32:45 -05003731 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003732 return false;
3733 }
3734
3735 if (uniformCount < 0)
3736 {
Jamie Madille0472f32018-11-27 16:32:45 -05003737 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madill12e957f2017-08-26 21:42:26 -04003738 return false;
3739 }
3740
3741 Program *programObject = GetValidProgram(context, program);
3742 if (!programObject)
3743 {
3744 return false;
3745 }
3746
3747 switch (pname)
3748 {
3749 case GL_UNIFORM_TYPE:
3750 case GL_UNIFORM_SIZE:
Bryan Bernhart22f7aaf2018-08-23 14:13:51 -07003751 break;
Jamie Madill12e957f2017-08-26 21:42:26 -04003752 case GL_UNIFORM_NAME_LENGTH:
Bryan Bernhart22f7aaf2018-08-23 14:13:51 -07003753 if (context->getExtensions().webglCompatibility)
3754 {
Jamie Madille0472f32018-11-27 16:32:45 -05003755 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Bryan Bernhart22f7aaf2018-08-23 14:13:51 -07003756 return false;
3757 }
3758 break;
Jamie Madill12e957f2017-08-26 21:42:26 -04003759 case GL_UNIFORM_BLOCK_INDEX:
3760 case GL_UNIFORM_OFFSET:
3761 case GL_UNIFORM_ARRAY_STRIDE:
3762 case GL_UNIFORM_MATRIX_STRIDE:
3763 case GL_UNIFORM_IS_ROW_MAJOR:
3764 break;
3765
3766 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003767 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madill12e957f2017-08-26 21:42:26 -04003768 return false;
3769 }
3770
3771 if (uniformCount > programObject->getActiveUniformCount())
3772 {
Jamie Madille0472f32018-11-27 16:32:45 -05003773 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform);
Jamie Madill12e957f2017-08-26 21:42:26 -04003774 return false;
3775 }
3776
3777 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
3778 {
3779 const GLuint index = uniformIndices[uniformId];
3780
3781 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
3782 {
Jamie Madille0472f32018-11-27 16:32:45 -05003783 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform);
Jamie Madill12e957f2017-08-26 21:42:26 -04003784 return false;
3785 }
3786 }
3787
3788 return true;
3789}
3790
3791bool ValidateGetUniformBlockIndex(Context *context, GLuint program, const GLchar *uniformBlockName)
3792{
3793 if (context->getClientMajorVersion() < 3)
3794 {
Jamie Madille0472f32018-11-27 16:32:45 -05003795 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003796 return false;
3797 }
3798
3799 Program *programObject = GetValidProgram(context, program);
3800 if (!programObject)
3801 {
3802 return false;
3803 }
3804
3805 return true;
3806}
3807
3808bool ValidateGetActiveUniformBlockiv(Context *context,
3809 GLuint program,
3810 GLuint uniformBlockIndex,
3811 GLenum pname,
3812 GLint *params)
3813{
3814 return ValidateGetActiveUniformBlockivBase(context, program, uniformBlockIndex, pname, nullptr);
3815}
3816
3817bool ValidateGetActiveUniformBlockName(Context *context,
3818 GLuint program,
3819 GLuint uniformBlockIndex,
3820 GLsizei bufSize,
3821 GLsizei *length,
3822 GLchar *uniformBlockName)
3823{
3824 if (context->getClientMajorVersion() < 3)
3825 {
Jamie Madille0472f32018-11-27 16:32:45 -05003826 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003827 return false;
3828 }
3829
3830 Program *programObject = GetValidProgram(context, program);
3831 if (!programObject)
3832 {
3833 return false;
3834 }
3835
3836 if (uniformBlockIndex >= programObject->getActiveUniformBlockCount())
3837 {
Jamie Madille0472f32018-11-27 16:32:45 -05003838 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxActiveUniformBlock);
Jamie Madill12e957f2017-08-26 21:42:26 -04003839 return false;
3840 }
3841
3842 return true;
3843}
3844
3845bool ValidateUniformBlockBinding(Context *context,
3846 GLuint program,
3847 GLuint uniformBlockIndex,
3848 GLuint uniformBlockBinding)
3849{
3850 if (context->getClientMajorVersion() < 3)
3851 {
Jamie Madille0472f32018-11-27 16:32:45 -05003852 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003853 return false;
3854 }
3855
3856 if (uniformBlockBinding >= context->getCaps().maxUniformBufferBindings)
3857 {
Jamie Madille0472f32018-11-27 16:32:45 -05003858 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxUniformBufferBindings);
Jamie Madill12e957f2017-08-26 21:42:26 -04003859 return false;
3860 }
3861
3862 Program *programObject = GetValidProgram(context, program);
3863 if (!programObject)
3864 {
3865 return false;
3866 }
3867
3868 // if never linked, there won't be any uniform blocks
3869 if (uniformBlockIndex >= programObject->getActiveUniformBlockCount())
3870 {
Jamie Madille0472f32018-11-27 16:32:45 -05003871 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxUniformBufferBindings);
Jamie Madill12e957f2017-08-26 21:42:26 -04003872 return false;
3873 }
3874
3875 return true;
3876}
3877
3878bool ValidateDrawArraysInstanced(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04003879 PrimitiveMode mode,
Jamie Madill12e957f2017-08-26 21:42:26 -04003880 GLint first,
3881 GLsizei count,
3882 GLsizei primcount)
3883{
3884 if (context->getClientMajorVersion() < 3)
3885 {
Jamie Madille0472f32018-11-27 16:32:45 -05003886 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04003887 return false;
3888 }
3889
3890 return ValidateDrawArraysInstancedBase(context, mode, first, count, primcount);
3891}
3892
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003893bool ValidateFenceSync(Context *context, GLenum condition, GLbitfield flags)
3894{
3895 if (context->getClientMajorVersion() < 3)
3896 {
Jamie Madille0472f32018-11-27 16:32:45 -05003897 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003898 return false;
3899 }
3900
3901 if (condition != GL_SYNC_GPU_COMMANDS_COMPLETE)
3902 {
Jamie Madille0472f32018-11-27 16:32:45 -05003903 context->validationError(GL_INVALID_ENUM, kInvalidFenceCondition);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003904 return false;
3905 }
3906
3907 if (flags != 0)
3908 {
Jamie Madille0472f32018-11-27 16:32:45 -05003909 context->validationError(GL_INVALID_VALUE, kInvalidFlags);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003910 return false;
3911 }
3912
3913 return true;
3914}
3915
3916bool ValidateIsSync(Context *context, GLsync sync)
3917{
3918 if (context->getClientMajorVersion() < 3)
3919 {
Jamie Madille0472f32018-11-27 16:32:45 -05003920 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003921 return false;
3922 }
3923
3924 return true;
3925}
3926
3927bool ValidateDeleteSync(Context *context, GLsync sync)
3928{
3929 if (context->getClientMajorVersion() < 3)
3930 {
Jamie Madille0472f32018-11-27 16:32:45 -05003931 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003932 return false;
3933 }
3934
Jamie Madill70b5bb02017-08-28 13:32:37 -04003935 if (sync != static_cast<GLsync>(0) && !context->getSync(sync))
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003936 {
Jamie Madille0472f32018-11-27 16:32:45 -05003937 context->validationError(GL_INVALID_VALUE, kSyncMissing);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003938 return false;
3939 }
3940
3941 return true;
3942}
3943
3944bool ValidateClientWaitSync(Context *context, GLsync sync, GLbitfield flags, GLuint64 timeout)
3945{
3946 if (context->getClientMajorVersion() < 3)
3947 {
Jamie Madille0472f32018-11-27 16:32:45 -05003948 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003949 return false;
3950 }
3951
3952 if ((flags & ~(GL_SYNC_FLUSH_COMMANDS_BIT)) != 0)
3953 {
Jamie Madille0472f32018-11-27 16:32:45 -05003954 context->validationError(GL_INVALID_VALUE, kInvalidFlags);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003955 return false;
3956 }
3957
Jamie Madill70b5bb02017-08-28 13:32:37 -04003958 Sync *clientWaitSync = context->getSync(sync);
3959 if (!clientWaitSync)
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003960 {
Jamie Madille0472f32018-11-27 16:32:45 -05003961 context->validationError(GL_INVALID_VALUE, kSyncMissing);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003962 return false;
3963 }
3964
3965 return true;
3966}
3967
3968bool ValidateWaitSync(Context *context, GLsync sync, GLbitfield flags, GLuint64 timeout)
3969{
3970 if (context->getClientMajorVersion() < 3)
3971 {
Jamie Madille0472f32018-11-27 16:32:45 -05003972 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003973 return false;
3974 }
3975
3976 if (flags != 0)
3977 {
Jamie Madille0472f32018-11-27 16:32:45 -05003978 context->validationError(GL_INVALID_VALUE, kInvalidFlags);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003979 return false;
3980 }
3981
3982 if (timeout != GL_TIMEOUT_IGNORED)
3983 {
Jamie Madille0472f32018-11-27 16:32:45 -05003984 context->validationError(GL_INVALID_VALUE, kInvalidTimeout);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003985 return false;
3986 }
3987
Jamie Madill70b5bb02017-08-28 13:32:37 -04003988 Sync *waitSync = context->getSync(sync);
3989 if (!waitSync)
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003990 {
Jamie Madille0472f32018-11-27 16:32:45 -05003991 context->validationError(GL_INVALID_VALUE, kSyncMissing);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04003992 return false;
3993 }
3994
3995 return true;
3996}
3997
3998bool ValidateGetInteger64v(Context *context, GLenum pname, GLint64 *params)
3999{
4000 if (context->getClientMajorVersion() < 3)
4001 {
Jamie Madille0472f32018-11-27 16:32:45 -05004002 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill7f0c5a42017-08-26 22:43:26 -04004003 return false;
4004 }
4005
4006 GLenum nativeType = GL_NONE;
4007 unsigned int numParams = 0;
4008 if (!ValidateStateQuery(context, pname, &nativeType, &numParams))
4009 {
4010 return false;
4011 }
4012
4013 return true;
4014}
4015
Jamie Madill3ef140a2017-08-26 23:11:21 -04004016bool ValidateIsSampler(Context *context, GLuint sampler)
4017{
4018 if (context->getClientMajorVersion() < 3)
4019 {
Jamie Madille0472f32018-11-27 16:32:45 -05004020 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill3ef140a2017-08-26 23:11:21 -04004021 return false;
4022 }
4023
4024 return true;
4025}
4026
4027bool ValidateBindSampler(Context *context, GLuint unit, GLuint sampler)
4028{
4029 if (context->getClientMajorVersion() < 3)
4030 {
Jamie Madille0472f32018-11-27 16:32:45 -05004031 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill3ef140a2017-08-26 23:11:21 -04004032 return false;
4033 }
4034
4035 if (sampler != 0 && !context->isSampler(sampler))
4036 {
Jamie Madille0472f32018-11-27 16:32:45 -05004037 context->validationError(GL_INVALID_OPERATION, kInvalidSampler);
Jamie Madill3ef140a2017-08-26 23:11:21 -04004038 return false;
4039 }
4040
4041 if (unit >= context->getCaps().maxCombinedTextureImageUnits)
4042 {
Jamie Madille0472f32018-11-27 16:32:45 -05004043 context->validationError(GL_INVALID_VALUE, kInvalidCombinedImageUnit);
Jamie Madill3ef140a2017-08-26 23:11:21 -04004044 return false;
4045 }
4046
4047 return true;
4048}
4049
4050bool ValidateVertexAttribDivisor(Context *context, GLuint index, GLuint divisor)
4051{
4052 if (context->getClientMajorVersion() < 3)
4053 {
Jamie Madille0472f32018-11-27 16:32:45 -05004054 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill3ef140a2017-08-26 23:11:21 -04004055 return false;
4056 }
4057
4058 return ValidateVertexAttribIndex(context, index);
4059}
4060
4061bool ValidateTexStorage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004062 TextureType target,
Jamie Madill3ef140a2017-08-26 23:11:21 -04004063 GLsizei levels,
4064 GLenum internalformat,
4065 GLsizei width,
4066 GLsizei height)
4067{
4068 if (context->getClientMajorVersion() < 3)
4069 {
Jamie Madille0472f32018-11-27 16:32:45 -05004070 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill3ef140a2017-08-26 23:11:21 -04004071 return false;
4072 }
4073
4074 if (!ValidateES3TexStorage2DParameters(context, target, levels, internalformat, width, height,
4075 1))
4076 {
4077 return false;
4078 }
4079
4080 return true;
4081}
4082
4083bool ValidateTexStorage3D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004084 TextureType target,
Jamie Madill3ef140a2017-08-26 23:11:21 -04004085 GLsizei levels,
4086 GLenum internalformat,
4087 GLsizei width,
4088 GLsizei height,
4089 GLsizei depth)
4090{
4091 if (context->getClientMajorVersion() < 3)
4092 {
Jamie Madille0472f32018-11-27 16:32:45 -05004093 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill3ef140a2017-08-26 23:11:21 -04004094 return false;
4095 }
4096
4097 if (!ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
4098 depth))
4099 {
4100 return false;
4101 }
4102
4103 return true;
4104}
4105
Jamie Madill5b772312018-03-08 20:28:32 -05004106bool ValidateGetBufferParameteri64v(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004107 BufferBinding target,
Jamie Madill9696d072017-08-26 23:19:57 -04004108 GLenum pname,
4109 GLint64 *params)
4110{
4111 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
4112}
4113
4114bool ValidateGetSamplerParameterfv(Context *context, GLuint sampler, GLenum pname, GLfloat *params)
4115{
4116 return ValidateGetSamplerParameterBase(context, sampler, pname, nullptr);
4117}
4118
4119bool ValidateGetSamplerParameteriv(Context *context, GLuint sampler, GLenum pname, GLint *params)
4120{
4121 return ValidateGetSamplerParameterBase(context, sampler, pname, nullptr);
4122}
4123
Till Rathmannb8543632018-10-02 19:46:14 +02004124bool ValidateGetSamplerParameterIivOES(Context *context,
4125 GLuint sampler,
4126 GLenum pname,
Jamie Madill778bf092018-11-14 09:54:36 -05004127 GLint *params)
Till Rathmannb8543632018-10-02 19:46:14 +02004128{
4129 if (context->getClientMajorVersion() < 3)
4130 {
Jamie Madille0472f32018-11-27 16:32:45 -05004131 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02004132 return false;
4133 }
4134 return ValidateGetSamplerParameterBase(context, sampler, pname, nullptr);
4135}
4136
4137bool ValidateGetSamplerParameterIuivOES(Context *context,
4138 GLuint sampler,
4139 GLenum pname,
Jamie Madill778bf092018-11-14 09:54:36 -05004140 GLuint *params)
Till Rathmannb8543632018-10-02 19:46:14 +02004141{
4142 if (context->getClientMajorVersion() < 3)
4143 {
Jamie Madille0472f32018-11-27 16:32:45 -05004144 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02004145 return false;
4146 }
4147 return ValidateGetSamplerParameterBase(context, sampler, pname, nullptr);
4148}
4149
Jamie Madill9696d072017-08-26 23:19:57 -04004150bool ValidateSamplerParameterf(Context *context, GLuint sampler, GLenum pname, GLfloat param)
4151{
Till Rathmannb8543632018-10-02 19:46:14 +02004152 return ValidateSamplerParameterBase(context, sampler, pname, -1, false, &param);
Jamie Madill9696d072017-08-26 23:19:57 -04004153}
4154
4155bool ValidateSamplerParameterfv(Context *context,
4156 GLuint sampler,
4157 GLenum pname,
4158 const GLfloat *params)
4159{
Till Rathmannb8543632018-10-02 19:46:14 +02004160 return ValidateSamplerParameterBase(context, sampler, pname, -1, true, params);
Jamie Madill9696d072017-08-26 23:19:57 -04004161}
4162
4163bool ValidateSamplerParameteri(Context *context, GLuint sampler, GLenum pname, GLint param)
4164{
Till Rathmannb8543632018-10-02 19:46:14 +02004165 return ValidateSamplerParameterBase(context, sampler, pname, -1, false, &param);
Jamie Madill9696d072017-08-26 23:19:57 -04004166}
4167
4168bool ValidateSamplerParameteriv(Context *context, GLuint sampler, GLenum pname, const GLint *params)
4169{
Till Rathmannb8543632018-10-02 19:46:14 +02004170 return ValidateSamplerParameterBase(context, sampler, pname, -1, true, params);
4171}
4172
4173bool ValidateSamplerParameterIivOES(Context *context,
4174 GLuint sampler,
4175 GLenum pname,
4176 const GLint *params)
4177{
4178 if (context->getClientMajorVersion() < 3)
4179 {
Jamie Madille0472f32018-11-27 16:32:45 -05004180 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02004181 return false;
4182 }
4183 return ValidateSamplerParameterBase(context, sampler, pname, -1, true, params);
4184}
4185
4186bool ValidateSamplerParameterIuivOES(Context *context,
4187 GLuint sampler,
4188 GLenum pname,
4189 const GLuint *params)
4190{
4191 if (context->getClientMajorVersion() < 3)
4192 {
Jamie Madille0472f32018-11-27 16:32:45 -05004193 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02004194 return false;
4195 }
4196 return ValidateSamplerParameterBase(context, sampler, pname, -1, true, params);
Jamie Madill9696d072017-08-26 23:19:57 -04004197}
4198
4199bool ValidateGetVertexAttribIiv(Context *context, GLuint index, GLenum pname, GLint *params)
4200{
4201 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, true);
4202}
4203
4204bool ValidateGetVertexAttribIuiv(Context *context, GLuint index, GLenum pname, GLuint *params)
4205{
4206 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, true);
4207}
4208
4209bool ValidateGetInternalformativ(Context *context,
4210 GLenum target,
4211 GLenum internalformat,
4212 GLenum pname,
4213 GLsizei bufSize,
4214 GLint *params)
4215{
4216 return ValidateGetInternalFormativBase(context, target, internalformat, pname, bufSize,
4217 nullptr);
4218}
4219
Olli Etuaho0ca09752018-09-24 11:00:50 +03004220bool ValidateBindFragDataLocationIndexedEXT(Context *context,
4221 GLuint program,
4222 GLuint colorNumber,
4223 GLuint index,
4224 const char *name)
4225{
4226 if (!context->getExtensions().blendFuncExtended)
4227 {
Jamie Madille0472f32018-11-27 16:32:45 -05004228 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho0ca09752018-09-24 11:00:50 +03004229 return false;
4230 }
4231 if (context->getClientMajorVersion() < 3)
4232 {
Jamie Madille0472f32018-11-27 16:32:45 -05004233 context->validationError(GL_INVALID_OPERATION, kES3Required);
Olli Etuaho0ca09752018-09-24 11:00:50 +03004234 return false;
4235 }
4236 if (index < 0 || index > 1)
4237 {
4238 // This error is not explicitly specified but the spec does say that "<index> may be zero or
4239 // one to specify that the color be used as either the first or second color input to the
4240 // blend equation, respectively"
Jamie Madille0472f32018-11-27 16:32:45 -05004241 context->validationError(GL_INVALID_VALUE, kFragDataBindingIndexOutOfRange);
Olli Etuaho0ca09752018-09-24 11:00:50 +03004242 return false;
4243 }
4244 if (index == 1)
4245 {
4246 if (colorNumber >= context->getExtensions().maxDualSourceDrawBuffers)
4247 {
Jamie Madill610640f2018-11-21 17:28:41 -05004248 context->validationError(GL_INVALID_VALUE,
Jamie Madille0472f32018-11-27 16:32:45 -05004249 kColorNumberGreaterThanMaxDualSourceDrawBuffers);
Olli Etuaho0ca09752018-09-24 11:00:50 +03004250 return false;
4251 }
4252 }
4253 else
4254 {
4255 if (colorNumber >= context->getCaps().maxDrawBuffers)
4256 {
Jamie Madille0472f32018-11-27 16:32:45 -05004257 context->validationError(GL_INVALID_VALUE, kColorNumberGreaterThanMaxDrawBuffers);
Olli Etuaho0ca09752018-09-24 11:00:50 +03004258 return false;
4259 }
4260 }
4261 Program *programObject = GetValidProgram(context, program);
4262 if (!programObject)
4263 {
4264 return false;
4265 }
4266 return true;
4267}
4268
4269bool ValidateBindFragDataLocationEXT(Context *context,
4270 GLuint program,
4271 GLuint colorNumber,
4272 const char *name)
4273{
4274 return ValidateBindFragDataLocationIndexedEXT(context, program, colorNumber, 0u, name);
4275}
4276
4277bool ValidateGetFragDataIndexEXT(Context *context, GLuint program, const char *name)
4278{
4279 if (!context->getExtensions().blendFuncExtended)
4280 {
Jamie Madille0472f32018-11-27 16:32:45 -05004281 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho0ca09752018-09-24 11:00:50 +03004282 return false;
4283 }
4284 if (context->getClientMajorVersion() < 3)
4285 {
Jamie Madille0472f32018-11-27 16:32:45 -05004286 context->validationError(GL_INVALID_OPERATION, kES3Required);
Olli Etuaho0ca09752018-09-24 11:00:50 +03004287 return false;
4288 }
4289 Program *programObject = GetValidProgram(context, program);
4290 if (!programObject)
4291 {
4292 return false;
4293 }
4294 if (!programObject->isLinked())
4295 {
Jamie Madille0472f32018-11-27 16:32:45 -05004296 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Olli Etuaho0ca09752018-09-24 11:00:50 +03004297 return false;
4298 }
4299 return true;
4300}
4301
Yizhou Jiang7818a852018-09-06 15:02:04 +08004302bool ValidateTexStorage2DMultisampleANGLE(Context *context,
4303 TextureType target,
4304 GLsizei samples,
Jamie Madill778bf092018-11-14 09:54:36 -05004305 GLenum internalFormat,
Yizhou Jiang7818a852018-09-06 15:02:04 +08004306 GLsizei width,
4307 GLsizei height,
4308 GLboolean fixedSampleLocations)
4309{
4310 if (!context->getExtensions().textureMultisample)
4311 {
Jamie Madille0472f32018-11-27 16:32:45 -05004312 context->validationError(GL_INVALID_OPERATION, kMultisampleTextureExtensionOrES31Required);
Yizhou Jiang7818a852018-09-06 15:02:04 +08004313 return false;
4314 }
4315
4316 return ValidateTexStorage2DMultisampleBase(context, target, samples, internalFormat, width,
4317 height);
4318}
4319
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08004320bool ValidateGetTexLevelParameterfvANGLE(Context *context,
4321 TextureTarget target,
4322 GLint level,
4323 GLenum pname,
4324 GLfloat *params)
4325{
4326 if (!context->getExtensions().textureMultisample)
4327 {
Jamie Madille0472f32018-11-27 16:32:45 -05004328 context->validationError(GL_INVALID_OPERATION, kMultisampleTextureExtensionOrES31Required);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08004329 return false;
4330 }
4331
4332 return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr);
4333}
4334
4335bool ValidateGetTexLevelParameterivANGLE(Context *context,
4336 TextureTarget target,
4337 GLint level,
4338 GLenum pname,
4339 GLint *params)
4340{
4341 if (!context->getExtensions().textureMultisample)
4342 {
Jamie Madille0472f32018-11-27 16:32:45 -05004343 context->validationError(GL_INVALID_OPERATION, kMultisampleTextureExtensionOrES31Required);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08004344 return false;
4345 }
4346
4347 return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr);
4348}
4349
Jamie Madillc29968b2016-01-20 11:17:23 -05004350} // namespace gl