blob: 429f4303356814fe3c06729f8c9295b9e5f3e9f5 [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// validationES2.cpp: Validation functions for OpenGL ES 2.0 entry point parameters
8
Geoff Lang2b5420c2014-11-19 14:20:15 -05009#include "libANGLE/validationES2.h"
10#include "libANGLE/validationES.h"
11#include "libANGLE/Context.h"
12#include "libANGLE/Texture.h"
13#include "libANGLE/Framebuffer.h"
14#include "libANGLE/Renderbuffer.h"
15#include "libANGLE/formatutils.h"
16#include "libANGLE/FramebufferAttachment.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040017
18#include "common/mathutil.h"
19#include "common/utilities.h"
20
21namespace gl
22{
23
Geoff Langb1196682014-07-23 13:47:29 -040024bool ValidateES2TexImageParameters(Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage,
Geoff Lange8ebe7f2013-08-05 15:03:13 -040025 GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
26 GLint border, GLenum format, GLenum type, const GLvoid *pixels)
27{
Jamie Madill6f38f822014-06-06 17:12:20 -040028 if (!ValidTexture2DDestinationTarget(context, target))
29 {
Geoff Langb1196682014-07-23 13:47:29 -040030 context->recordError(Error(GL_INVALID_ENUM));
31 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -040032 }
33
Geoff Langce635692013-09-24 13:56:32 -040034 if (!ValidImageSize(context, target, level, width, height, 1))
Geoff Lange8ebe7f2013-08-05 15:03:13 -040035 {
Geoff Langb1196682014-07-23 13:47:29 -040036 context->recordError(Error(GL_INVALID_VALUE));
37 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040038 }
39
Geoff Lange8ebe7f2013-08-05 15:03:13 -040040 if (level < 0 || xoffset < 0 ||
41 std::numeric_limits<GLsizei>::max() - xoffset < width ||
42 std::numeric_limits<GLsizei>::max() - yoffset < height)
43 {
Geoff Langb1196682014-07-23 13:47:29 -040044 context->recordError(Error(GL_INVALID_VALUE));
45 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040046 }
47
Geoff Lang005df412013-10-16 14:12:50 -040048 if (!isSubImage && !isCompressed && internalformat != format)
Geoff Lange8ebe7f2013-08-05 15:03:13 -040049 {
Geoff Langb1196682014-07-23 13:47:29 -040050 context->recordError(Error(GL_INVALID_OPERATION));
51 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040052 }
53
Geoff Langaae65a42014-05-26 12:43:44 -040054 const gl::Caps &caps = context->getCaps();
55
Geoff Langa9be0dc2014-12-17 12:34:40 -050056 if (target == GL_TEXTURE_2D)
Geoff Lange8ebe7f2013-08-05 15:03:13 -040057 {
Geoff Langa9be0dc2014-12-17 12:34:40 -050058 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
59 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
Geoff Lange8ebe7f2013-08-05 15:03:13 -040060 {
Geoff Langa9be0dc2014-12-17 12:34:40 -050061 context->recordError(Error(GL_INVALID_VALUE));
62 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040063 }
Geoff Langa9be0dc2014-12-17 12:34:40 -050064 }
Geoff Lang691e58c2014-12-19 17:03:25 -050065 else if (IsCubeMapTextureTarget(target))
Geoff Langa9be0dc2014-12-17 12:34:40 -050066 {
67 if (!isSubImage && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -040068 {
Geoff Langa9be0dc2014-12-17 12:34:40 -050069 context->recordError(Error(GL_INVALID_VALUE));
70 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040071 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -040072
Geoff Langa9be0dc2014-12-17 12:34:40 -050073 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
74 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
75 {
76 context->recordError(Error(GL_INVALID_VALUE));
77 return false;
78 }
79 }
80 else
81 {
Geoff Langb1196682014-07-23 13:47:29 -040082 context->recordError(Error(GL_INVALID_ENUM));
83 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040084 }
85
Geoff Lang691e58c2014-12-19 17:03:25 -050086 gl::Texture *texture = context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -040087 if (!texture)
88 {
Geoff Langb1196682014-07-23 13:47:29 -040089 context->recordError(Error(GL_INVALID_OPERATION));
90 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040091 }
92
Geoff Langa9be0dc2014-12-17 12:34:40 -050093 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -040094 {
Geoff Langa9be0dc2014-12-17 12:34:40 -050095 if (format != GL_NONE)
96 {
Geoff Lang051dbc72015-01-05 15:48:58 -050097 if (gl::GetSizedInternalFormat(format, type) != texture->getInternalFormat(target, level))
Geoff Langa9be0dc2014-12-17 12:34:40 -050098 {
99 context->recordError(Error(GL_INVALID_OPERATION));
100 return false;
101 }
102 }
103
104 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
105 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
106 {
107 context->recordError(Error(GL_INVALID_VALUE));
108 return false;
109 }
110 }
111 else
112 {
Geoff Lang69cce582015-09-17 13:20:36 -0400113 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -0500114 {
115 context->recordError(Error(GL_INVALID_OPERATION));
116 return false;
117 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400118 }
119
120 // Verify zero border
121 if (border != 0)
122 {
Geoff Langb1196682014-07-23 13:47:29 -0400123 context->recordError(Error(GL_INVALID_VALUE));
124 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400125 }
126
Geoff Langa9be0dc2014-12-17 12:34:40 -0500127 GLenum actualInternalFormat = isSubImage ? texture->getInternalFormat(target, level) : internalformat;
128 const InternalFormat &actualFormatInfo = GetInternalFormatInfo(actualInternalFormat);
129
130 if (isCompressed != actualFormatInfo.compressed)
131 {
132 context->recordError(Error(GL_INVALID_OPERATION));
133 return false;
134 }
135
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400136 if (isCompressed)
137 {
Geoff Langd4f180b2013-09-24 13:57:44 -0400138 if (!ValidCompressedImageSize(context, actualInternalFormat, width, height))
139 {
Geoff Langb1196682014-07-23 13:47:29 -0400140 context->recordError(Error(GL_INVALID_OPERATION));
141 return false;
Geoff Langd4f180b2013-09-24 13:57:44 -0400142 }
143
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400144 switch (actualInternalFormat)
145 {
146 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
147 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400148 if (!context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400149 {
Geoff Langb1196682014-07-23 13:47:29 -0400150 context->recordError(Error(GL_INVALID_ENUM));
151 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400152 }
153 break;
154 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400155 if (!context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400156 {
Geoff Langb1196682014-07-23 13:47:29 -0400157 context->recordError(Error(GL_INVALID_ENUM));
158 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400159 }
160 break;
161 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
Geoff Langb1196682014-07-23 13:47:29 -0400162 if (!context->getExtensions().textureCompressionDXT5)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400163 {
Geoff Langb1196682014-07-23 13:47:29 -0400164 context->recordError(Error(GL_INVALID_ENUM));
165 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400166 }
167 break;
168 default:
Geoff Langb1196682014-07-23 13:47:29 -0400169 context->recordError(Error(GL_INVALID_ENUM));
170 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400171 }
172 }
173 else
174 {
175 // validate <type> by itself (used as secondary key below)
176 switch (type)
177 {
178 case GL_UNSIGNED_BYTE:
179 case GL_UNSIGNED_SHORT_5_6_5:
180 case GL_UNSIGNED_SHORT_4_4_4_4:
181 case GL_UNSIGNED_SHORT_5_5_5_1:
182 case GL_UNSIGNED_SHORT:
183 case GL_UNSIGNED_INT:
184 case GL_UNSIGNED_INT_24_8_OES:
185 case GL_HALF_FLOAT_OES:
186 case GL_FLOAT:
187 break;
188 default:
Geoff Langb1196682014-07-23 13:47:29 -0400189 context->recordError(Error(GL_INVALID_ENUM));
190 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400191 }
192
193 // validate <format> + <type> combinations
194 // - invalid <format> -> sets INVALID_ENUM
195 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
196 switch (format)
197 {
198 case GL_ALPHA:
199 case GL_LUMINANCE:
200 case GL_LUMINANCE_ALPHA:
201 switch (type)
202 {
203 case GL_UNSIGNED_BYTE:
204 case GL_FLOAT:
205 case GL_HALF_FLOAT_OES:
206 break;
Geoff Langb1196682014-07-23 13:47:29 -0400207 default:
208 context->recordError(Error(GL_INVALID_OPERATION));
209 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400210 }
211 break;
Geoff Lang632192d2013-10-04 13:40:46 -0400212 case GL_RED:
Geoff Langcec35902014-04-16 10:52:36 -0400213 case GL_RG:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400214 if (!context->getExtensions().textureRG)
Geoff Lang632192d2013-10-04 13:40:46 -0400215 {
Geoff Langb1196682014-07-23 13:47:29 -0400216 context->recordError(Error(GL_INVALID_ENUM));
217 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400218 }
219 switch (type)
220 {
221 case GL_UNSIGNED_BYTE:
222 case GL_FLOAT:
223 case GL_HALF_FLOAT_OES:
224 break;
225 default:
Geoff Langb1196682014-07-23 13:47:29 -0400226 context->recordError(Error(GL_INVALID_OPERATION));
227 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400228 }
229 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400230 case GL_RGB:
231 switch (type)
232 {
233 case GL_UNSIGNED_BYTE:
234 case GL_UNSIGNED_SHORT_5_6_5:
235 case GL_FLOAT:
236 case GL_HALF_FLOAT_OES:
237 break;
238 default:
Geoff Langb1196682014-07-23 13:47:29 -0400239 context->recordError(Error(GL_INVALID_OPERATION));
240 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400241 }
242 break;
243 case GL_RGBA:
244 switch (type)
245 {
246 case GL_UNSIGNED_BYTE:
247 case GL_UNSIGNED_SHORT_4_4_4_4:
248 case GL_UNSIGNED_SHORT_5_5_5_1:
249 case GL_FLOAT:
250 case GL_HALF_FLOAT_OES:
251 break;
252 default:
Geoff Langb1196682014-07-23 13:47:29 -0400253 context->recordError(Error(GL_INVALID_OPERATION));
254 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400255 }
256 break;
257 case GL_BGRA_EXT:
258 switch (type)
259 {
260 case GL_UNSIGNED_BYTE:
261 break;
262 default:
Geoff Langb1196682014-07-23 13:47:29 -0400263 context->recordError(Error(GL_INVALID_OPERATION));
264 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400265 }
266 break;
Geoff Lang05b05022014-06-11 15:31:45 -0400267 case GL_SRGB_EXT:
268 case GL_SRGB_ALPHA_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400269 if (!context->getExtensions().sRGB)
Geoff Lang05b05022014-06-11 15:31:45 -0400270 {
Geoff Langb1196682014-07-23 13:47:29 -0400271 context->recordError(Error(GL_INVALID_ENUM));
272 return false;
Geoff Lang05b05022014-06-11 15:31:45 -0400273 }
274 switch (type)
275 {
276 case GL_UNSIGNED_BYTE:
277 break;
278 default:
Geoff Langb1196682014-07-23 13:47:29 -0400279 context->recordError(Error(GL_INVALID_OPERATION));
280 return false;
Geoff Lang05b05022014-06-11 15:31:45 -0400281 }
282 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400283 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
284 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
285 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
286 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
287 break;
288 case GL_DEPTH_COMPONENT:
289 switch (type)
290 {
291 case GL_UNSIGNED_SHORT:
292 case GL_UNSIGNED_INT:
293 break;
294 default:
Geoff Langb1196682014-07-23 13:47:29 -0400295 context->recordError(Error(GL_INVALID_OPERATION));
296 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400297 }
298 break;
299 case GL_DEPTH_STENCIL_OES:
300 switch (type)
301 {
302 case GL_UNSIGNED_INT_24_8_OES:
303 break;
304 default:
Geoff Langb1196682014-07-23 13:47:29 -0400305 context->recordError(Error(GL_INVALID_OPERATION));
306 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400307 }
308 break;
309 default:
Geoff Langb1196682014-07-23 13:47:29 -0400310 context->recordError(Error(GL_INVALID_ENUM));
311 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400312 }
313
314 switch (format)
315 {
316 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
317 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400318 if (context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400319 {
Geoff Langb1196682014-07-23 13:47:29 -0400320 context->recordError(Error(GL_INVALID_OPERATION));
321 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400322 }
323 else
324 {
Geoff Langb1196682014-07-23 13:47:29 -0400325 context->recordError(Error(GL_INVALID_ENUM));
326 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400327 }
328 break;
329 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400330 if (context->getExtensions().textureCompressionDXT3)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400331 {
Geoff Langb1196682014-07-23 13:47:29 -0400332 context->recordError(Error(GL_INVALID_OPERATION));
333 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400334 }
335 else
336 {
Geoff Langb1196682014-07-23 13:47:29 -0400337 context->recordError(Error(GL_INVALID_ENUM));
338 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400339 }
340 break;
341 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400342 if (context->getExtensions().textureCompressionDXT5)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400343 {
Geoff Langb1196682014-07-23 13:47:29 -0400344 context->recordError(Error(GL_INVALID_OPERATION));
345 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400346 }
347 else
348 {
Geoff Langb1196682014-07-23 13:47:29 -0400349 context->recordError(Error(GL_INVALID_ENUM));
350 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400351 }
352 break;
353 case GL_DEPTH_COMPONENT:
354 case GL_DEPTH_STENCIL_OES:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400355 if (!context->getExtensions().depthTextures)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400356 {
Geoff Langb1196682014-07-23 13:47:29 -0400357 context->recordError(Error(GL_INVALID_VALUE));
358 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400359 }
360 if (target != GL_TEXTURE_2D)
361 {
Geoff Langb1196682014-07-23 13:47:29 -0400362 context->recordError(Error(GL_INVALID_OPERATION));
363 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400364 }
365 // OES_depth_texture supports loading depth data and multiple levels,
366 // but ANGLE_depth_texture does not
367 if (pixels != NULL || level != 0)
368 {
Geoff Langb1196682014-07-23 13:47:29 -0400369 context->recordError(Error(GL_INVALID_OPERATION));
370 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400371 }
372 break;
373 default:
374 break;
375 }
376
377 if (type == GL_FLOAT)
378 {
Geoff Langc0b9ef42014-07-02 10:02:37 -0400379 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400380 {
Geoff Langb1196682014-07-23 13:47:29 -0400381 context->recordError(Error(GL_INVALID_ENUM));
382 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400383 }
384 }
385 else if (type == GL_HALF_FLOAT_OES)
386 {
Geoff Langc0b9ef42014-07-02 10:02:37 -0400387 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400388 {
Geoff Langb1196682014-07-23 13:47:29 -0400389 context->recordError(Error(GL_INVALID_ENUM));
390 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400391 }
392 }
393 }
394
395 return true;
396}
397
398
399
Geoff Langb1196682014-07-23 13:47:29 -0400400bool ValidateES2CopyTexImageParameters(Context* context, GLenum target, GLint level, GLenum internalformat, bool isSubImage,
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400401 GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height,
402 GLint border)
403{
Jamie Madill560a8d82014-05-21 13:06:20 -0400404 GLenum textureInternalFormat = GL_NONE;
Shannon Woods4dfed832014-03-17 20:03:39 -0400405
Jamie Madill560a8d82014-05-21 13:06:20 -0400406 if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
407 xoffset, yoffset, 0, x, y, width, height, border, &textureInternalFormat))
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400408 {
Jamie Madill560a8d82014-05-21 13:06:20 -0400409 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400410 }
411
Shannon Woods53a94a82014-06-24 15:20:36 -0400412 gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer();
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400413 GLenum colorbufferFormat = framebuffer->getReadColorbuffer()->getInternalFormat();
Jamie Madillbc393df2015-01-29 13:46:07 -0500414 const auto &internalFormatInfo = gl::GetInternalFormatInfo(textureInternalFormat);
415 GLenum textureFormat = internalFormatInfo.format;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400416
417 // [OpenGL ES 2.0.24] table 3.9
418 if (isSubImage)
419 {
420 switch (textureFormat)
421 {
422 case GL_ALPHA:
423 if (colorbufferFormat != GL_ALPHA8_EXT &&
424 colorbufferFormat != GL_RGBA4 &&
425 colorbufferFormat != GL_RGB5_A1 &&
426 colorbufferFormat != GL_RGBA8_OES)
427 {
Geoff Langb1196682014-07-23 13:47:29 -0400428 context->recordError(Error(GL_INVALID_OPERATION));
429 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400430 }
431 break;
432 case GL_LUMINANCE:
Geoff Lang632192d2013-10-04 13:40:46 -0400433 if (colorbufferFormat != GL_R8_EXT &&
434 colorbufferFormat != GL_RG8_EXT &&
435 colorbufferFormat != GL_RGB565 &&
436 colorbufferFormat != GL_RGB8_OES &&
437 colorbufferFormat != GL_RGBA4 &&
438 colorbufferFormat != GL_RGB5_A1 &&
439 colorbufferFormat != GL_RGBA8_OES)
440 {
Geoff Langb1196682014-07-23 13:47:29 -0400441 context->recordError(Error(GL_INVALID_OPERATION));
442 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400443 }
444 break;
445 case GL_RED_EXT:
446 if (colorbufferFormat != GL_R8_EXT &&
447 colorbufferFormat != GL_RG8_EXT &&
448 colorbufferFormat != GL_RGB565 &&
449 colorbufferFormat != GL_RGB8_OES &&
450 colorbufferFormat != GL_RGBA4 &&
451 colorbufferFormat != GL_RGB5_A1 &&
Jamie Madillbc393df2015-01-29 13:46:07 -0500452 colorbufferFormat != GL_RGBA8_OES &&
453 colorbufferFormat != GL_R32F &&
454 colorbufferFormat != GL_RG32F &&
455 colorbufferFormat != GL_RGB32F &&
456 colorbufferFormat != GL_RGBA32F)
Geoff Lang632192d2013-10-04 13:40:46 -0400457 {
Geoff Langb1196682014-07-23 13:47:29 -0400458 context->recordError(Error(GL_INVALID_OPERATION));
459 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400460 }
461 break;
462 case GL_RG_EXT:
463 if (colorbufferFormat != GL_RG8_EXT &&
464 colorbufferFormat != GL_RGB565 &&
465 colorbufferFormat != GL_RGB8_OES &&
466 colorbufferFormat != GL_RGBA4 &&
467 colorbufferFormat != GL_RGB5_A1 &&
Jamie Madillbc393df2015-01-29 13:46:07 -0500468 colorbufferFormat != GL_RGBA8_OES &&
469 colorbufferFormat != GL_RG32F &&
470 colorbufferFormat != GL_RGB32F &&
471 colorbufferFormat != GL_RGBA32F)
Geoff Lang632192d2013-10-04 13:40:46 -0400472 {
Geoff Langb1196682014-07-23 13:47:29 -0400473 context->recordError(Error(GL_INVALID_OPERATION));
474 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400475 }
476 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400477 case GL_RGB:
478 if (colorbufferFormat != GL_RGB565 &&
479 colorbufferFormat != GL_RGB8_OES &&
480 colorbufferFormat != GL_RGBA4 &&
481 colorbufferFormat != GL_RGB5_A1 &&
Jamie Madillbc393df2015-01-29 13:46:07 -0500482 colorbufferFormat != GL_RGBA8_OES &&
483 colorbufferFormat != GL_RGB32F &&
484 colorbufferFormat != GL_RGBA32F)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400485 {
Geoff Langb1196682014-07-23 13:47:29 -0400486 context->recordError(Error(GL_INVALID_OPERATION));
487 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400488 }
489 break;
490 case GL_LUMINANCE_ALPHA:
491 case GL_RGBA:
492 if (colorbufferFormat != GL_RGBA4 &&
493 colorbufferFormat != GL_RGB5_A1 &&
Jamie Madillbc393df2015-01-29 13:46:07 -0500494 colorbufferFormat != GL_RGBA8_OES &&
495 colorbufferFormat != GL_RGBA32F)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400496 {
Geoff Langb1196682014-07-23 13:47:29 -0400497 context->recordError(Error(GL_INVALID_OPERATION));
498 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400499 }
500 break;
501 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
502 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
503 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
504 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
Geoff Langb1196682014-07-23 13:47:29 -0400505 context->recordError(Error(GL_INVALID_OPERATION));
506 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400507 case GL_DEPTH_COMPONENT:
508 case GL_DEPTH_STENCIL_OES:
Geoff Langb1196682014-07-23 13:47:29 -0400509 context->recordError(Error(GL_INVALID_OPERATION));
510 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400511 default:
Geoff Langb1196682014-07-23 13:47:29 -0400512 context->recordError(Error(GL_INVALID_OPERATION));
513 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400514 }
Jamie Madillbc393df2015-01-29 13:46:07 -0500515
516 if (internalFormatInfo.type == GL_FLOAT &&
517 !context->getExtensions().textureFloat)
518 {
519 context->recordError(Error(GL_INVALID_OPERATION));
520 return false;
521 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400522 }
523 else
524 {
525 switch (internalformat)
526 {
527 case GL_ALPHA:
528 if (colorbufferFormat != GL_ALPHA8_EXT &&
529 colorbufferFormat != GL_RGBA4 &&
530 colorbufferFormat != GL_RGB5_A1 &&
531 colorbufferFormat != GL_BGRA8_EXT &&
Jamie Madill054369e2015-01-07 10:57:08 -0500532 colorbufferFormat != GL_RGBA8_OES &&
533 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400534 {
Geoff Langb1196682014-07-23 13:47:29 -0400535 context->recordError(Error(GL_INVALID_OPERATION));
536 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400537 }
538 break;
539 case GL_LUMINANCE:
Geoff Lang632192d2013-10-04 13:40:46 -0400540 if (colorbufferFormat != GL_R8_EXT &&
541 colorbufferFormat != GL_RG8_EXT &&
542 colorbufferFormat != GL_RGB565 &&
543 colorbufferFormat != GL_RGB8_OES &&
544 colorbufferFormat != GL_RGBA4 &&
545 colorbufferFormat != GL_RGB5_A1 &&
546 colorbufferFormat != GL_BGRA8_EXT &&
Jamie Madill054369e2015-01-07 10:57:08 -0500547 colorbufferFormat != GL_RGBA8_OES &&
548 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Geoff Lang632192d2013-10-04 13:40:46 -0400549 {
Geoff Langb1196682014-07-23 13:47:29 -0400550 context->recordError(Error(GL_INVALID_OPERATION));
551 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400552 }
553 break;
554 case GL_RED_EXT:
555 if (colorbufferFormat != GL_R8_EXT &&
556 colorbufferFormat != GL_RG8_EXT &&
557 colorbufferFormat != GL_RGB565 &&
558 colorbufferFormat != GL_RGB8_OES &&
559 colorbufferFormat != GL_RGBA4 &&
560 colorbufferFormat != GL_RGB5_A1 &&
561 colorbufferFormat != GL_BGRA8_EXT &&
Jamie Madill054369e2015-01-07 10:57:08 -0500562 colorbufferFormat != GL_RGBA8_OES &&
563 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Geoff Lang632192d2013-10-04 13:40:46 -0400564 {
Geoff Langb1196682014-07-23 13:47:29 -0400565 context->recordError(Error(GL_INVALID_OPERATION));
566 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400567 }
568 break;
569 case GL_RG_EXT:
570 if (colorbufferFormat != GL_RG8_EXT &&
571 colorbufferFormat != GL_RGB565 &&
572 colorbufferFormat != GL_RGB8_OES &&
573 colorbufferFormat != GL_RGBA4 &&
574 colorbufferFormat != GL_RGB5_A1 &&
575 colorbufferFormat != GL_BGRA8_EXT &&
Jamie Madill054369e2015-01-07 10:57:08 -0500576 colorbufferFormat != GL_RGBA8_OES &&
577 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Geoff Lang632192d2013-10-04 13:40:46 -0400578 {
Geoff Langb1196682014-07-23 13:47:29 -0400579 context->recordError(Error(GL_INVALID_OPERATION));
580 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400581 }
582 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400583 case GL_RGB:
584 if (colorbufferFormat != GL_RGB565 &&
585 colorbufferFormat != GL_RGB8_OES &&
586 colorbufferFormat != GL_RGBA4 &&
587 colorbufferFormat != GL_RGB5_A1 &&
588 colorbufferFormat != GL_BGRA8_EXT &&
Jamie Madill054369e2015-01-07 10:57:08 -0500589 colorbufferFormat != GL_RGBA8_OES &&
590 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400591 {
Geoff Langb1196682014-07-23 13:47:29 -0400592 context->recordError(Error(GL_INVALID_OPERATION));
593 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400594 }
595 break;
596 case GL_LUMINANCE_ALPHA:
597 case GL_RGBA:
598 if (colorbufferFormat != GL_RGBA4 &&
599 colorbufferFormat != GL_RGB5_A1 &&
600 colorbufferFormat != GL_BGRA8_EXT &&
Jamie Madill054369e2015-01-07 10:57:08 -0500601 colorbufferFormat != GL_RGBA8_OES &&
602 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400603 {
Geoff Langb1196682014-07-23 13:47:29 -0400604 context->recordError(Error(GL_INVALID_OPERATION));
605 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400606 }
607 break;
608 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
609 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400610 if (context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400611 {
Geoff Langb1196682014-07-23 13:47:29 -0400612 context->recordError(Error(GL_INVALID_OPERATION));
613 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400614 }
615 else
616 {
Geoff Langb1196682014-07-23 13:47:29 -0400617 context->recordError(Error(GL_INVALID_ENUM));
618 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400619 }
620 break;
621 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400622 if (context->getExtensions().textureCompressionDXT3)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400623 {
Geoff Langb1196682014-07-23 13:47:29 -0400624 context->recordError(Error(GL_INVALID_OPERATION));
625 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400626 }
627 else
628 {
Geoff Langb1196682014-07-23 13:47:29 -0400629 context->recordError(Error(GL_INVALID_ENUM));
630 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400631 }
632 break;
633 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400634 if (context->getExtensions().textureCompressionDXT5)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400635 {
Geoff Langb1196682014-07-23 13:47:29 -0400636 context->recordError(Error(GL_INVALID_OPERATION));
637 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400638 }
639 else
640 {
Geoff Langb1196682014-07-23 13:47:29 -0400641 context->recordError(Error(GL_INVALID_ENUM));
642 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400643 }
644 break;
645 case GL_DEPTH_COMPONENT:
646 case GL_DEPTH_COMPONENT16:
647 case GL_DEPTH_COMPONENT32_OES:
648 case GL_DEPTH_STENCIL_OES:
649 case GL_DEPTH24_STENCIL8_OES:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400650 if (context->getExtensions().depthTextures)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400651 {
Geoff Langb1196682014-07-23 13:47:29 -0400652 context->recordError(Error(GL_INVALID_OPERATION));
653 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400654 }
655 else
656 {
Geoff Langb1196682014-07-23 13:47:29 -0400657 context->recordError(Error(GL_INVALID_ENUM));
658 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400659 }
660 default:
Geoff Langb1196682014-07-23 13:47:29 -0400661 context->recordError(Error(GL_INVALID_ENUM));
662 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400663 }
664 }
665
Geoff Lang784a8fd2013-09-24 12:33:16 -0400666 // If width or height is zero, it is a no-op. Return false without setting an error.
667 return (width > 0 && height > 0);
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400668}
669
Geoff Langb1196682014-07-23 13:47:29 -0400670bool ValidateES2TexStorageParameters(Context *context, GLenum target, GLsizei levels, GLenum internalformat,
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400671 GLsizei width, GLsizei height)
672{
673 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP)
674 {
Geoff Langb1196682014-07-23 13:47:29 -0400675 context->recordError(Error(GL_INVALID_ENUM));
676 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400677 }
678
679 if (width < 1 || height < 1 || levels < 1)
680 {
Geoff Langb1196682014-07-23 13:47:29 -0400681 context->recordError(Error(GL_INVALID_VALUE));
682 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400683 }
684
685 if (target == GL_TEXTURE_CUBE_MAP && width != height)
686 {
Geoff Langb1196682014-07-23 13:47:29 -0400687 context->recordError(Error(GL_INVALID_VALUE));
688 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400689 }
690
691 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
692 {
Geoff Langb1196682014-07-23 13:47:29 -0400693 context->recordError(Error(GL_INVALID_OPERATION));
694 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400695 }
696
Geoff Lang5d601382014-07-22 15:14:06 -0400697 const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
698 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400699 {
Geoff Langb1196682014-07-23 13:47:29 -0400700 context->recordError(Error(GL_INVALID_ENUM));
701 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400702 }
703
Geoff Langaae65a42014-05-26 12:43:44 -0400704 const gl::Caps &caps = context->getCaps();
705
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400706 switch (target)
707 {
708 case GL_TEXTURE_2D:
Geoff Langaae65a42014-05-26 12:43:44 -0400709 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
710 static_cast<GLuint>(height) > caps.max2DTextureSize)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400711 {
Geoff Langb1196682014-07-23 13:47:29 -0400712 context->recordError(Error(GL_INVALID_VALUE));
713 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400714 }
715 break;
716 case GL_TEXTURE_CUBE_MAP:
Geoff Langaae65a42014-05-26 12:43:44 -0400717 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
718 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400719 {
Geoff Langb1196682014-07-23 13:47:29 -0400720 context->recordError(Error(GL_INVALID_VALUE));
721 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400722 }
723 break;
724 default:
Geoff Langb1196682014-07-23 13:47:29 -0400725 context->recordError(Error(GL_INVALID_ENUM));
726 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400727 }
728
Geoff Langc0b9ef42014-07-02 10:02:37 -0400729 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400730 {
731 if (!gl::isPow2(width) || !gl::isPow2(height))
732 {
Geoff Langb1196682014-07-23 13:47:29 -0400733 context->recordError(Error(GL_INVALID_OPERATION));
734 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400735 }
736 }
737
738 switch (internalformat)
739 {
740 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
741 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400742 if (!context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400743 {
Geoff Langb1196682014-07-23 13:47:29 -0400744 context->recordError(Error(GL_INVALID_ENUM));
745 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400746 }
747 break;
748 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400749 if (!context->getExtensions().textureCompressionDXT3)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400750 {
Geoff Langb1196682014-07-23 13:47:29 -0400751 context->recordError(Error(GL_INVALID_ENUM));
752 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400753 }
754 break;
755 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400756 if (!context->getExtensions().textureCompressionDXT5)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400757 {
Geoff Langb1196682014-07-23 13:47:29 -0400758 context->recordError(Error(GL_INVALID_ENUM));
759 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400760 }
761 break;
762 case GL_RGBA32F_EXT:
763 case GL_RGB32F_EXT:
764 case GL_ALPHA32F_EXT:
765 case GL_LUMINANCE32F_EXT:
766 case GL_LUMINANCE_ALPHA32F_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400767 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400768 {
Geoff Langb1196682014-07-23 13:47:29 -0400769 context->recordError(Error(GL_INVALID_ENUM));
770 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400771 }
772 break;
773 case GL_RGBA16F_EXT:
774 case GL_RGB16F_EXT:
775 case GL_ALPHA16F_EXT:
776 case GL_LUMINANCE16F_EXT:
777 case GL_LUMINANCE_ALPHA16F_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400778 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400779 {
Geoff Langb1196682014-07-23 13:47:29 -0400780 context->recordError(Error(GL_INVALID_ENUM));
781 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400782 }
783 break;
Geoff Lang632192d2013-10-04 13:40:46 -0400784 case GL_R8_EXT:
785 case GL_RG8_EXT:
786 case GL_R16F_EXT:
787 case GL_RG16F_EXT:
788 case GL_R32F_EXT:
789 case GL_RG32F_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400790 if (!context->getExtensions().textureRG)
Geoff Lang632192d2013-10-04 13:40:46 -0400791 {
Geoff Langb1196682014-07-23 13:47:29 -0400792 context->recordError(Error(GL_INVALID_ENUM));
793 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400794 }
795 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400796 case GL_DEPTH_COMPONENT16:
797 case GL_DEPTH_COMPONENT32_OES:
798 case GL_DEPTH24_STENCIL8_OES:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400799 if (!context->getExtensions().depthTextures)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400800 {
Geoff Langb1196682014-07-23 13:47:29 -0400801 context->recordError(Error(GL_INVALID_ENUM));
802 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400803 }
804 if (target != GL_TEXTURE_2D)
805 {
Geoff Langb1196682014-07-23 13:47:29 -0400806 context->recordError(Error(GL_INVALID_OPERATION));
807 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400808 }
809 // ANGLE_depth_texture only supports 1-level textures
810 if (levels != 1)
811 {
Geoff Langb1196682014-07-23 13:47:29 -0400812 context->recordError(Error(GL_INVALID_OPERATION));
813 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400814 }
815 break;
816 default:
817 break;
818 }
819
Geoff Lang691e58c2014-12-19 17:03:25 -0500820 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400821 if (!texture || texture->id() == 0)
822 {
Geoff Langb1196682014-07-23 13:47:29 -0400823 context->recordError(Error(GL_INVALID_OPERATION));
824 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400825 }
826
Geoff Lang69cce582015-09-17 13:20:36 -0400827 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400828 {
Geoff Langb1196682014-07-23 13:47:29 -0400829 context->recordError(Error(GL_INVALID_OPERATION));
830 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400831 }
832
833 return true;
834}
835
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400836// check for combinations of format and type that are valid for ReadPixels
Geoff Langb1196682014-07-23 13:47:29 -0400837bool ValidES2ReadFormatType(Context *context, GLenum format, GLenum type)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400838{
839 switch (format)
840 {
841 case GL_RGBA:
842 switch (type)
843 {
844 case GL_UNSIGNED_BYTE:
845 break;
846 default:
847 return false;
848 }
849 break;
850 case GL_BGRA_EXT:
851 switch (type)
852 {
853 case GL_UNSIGNED_BYTE:
854 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
855 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
856 break;
857 default:
858 return false;
859 }
860 break;
Geoff Langbdc9b2f2014-04-16 14:41:54 -0400861 case GL_RG_EXT:
862 case GL_RED_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400863 if (!context->getExtensions().textureRG)
Geoff Langbdc9b2f2014-04-16 14:41:54 -0400864 {
865 return false;
866 }
867 switch (type)
868 {
869 case GL_UNSIGNED_BYTE:
870 break;
871 default:
872 return false;
873 }
874 break;
875
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400876 default:
877 return false;
878 }
879 return true;
880}
881
Austin Kinross08332632015-05-05 13:35:47 -0700882bool ValidateDiscardFramebufferEXT(Context *context, GLenum target, GLsizei numAttachments,
883 const GLenum *attachments)
884{
885 bool defaultFramebuffer = false;
886
887 switch (target)
888 {
889 case GL_FRAMEBUFFER:
890 defaultFramebuffer = (context->getState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
891 break;
892 default:
893 context->recordError(Error(GL_INVALID_ENUM, "Invalid framebuffer target"));
894 return false;
895 }
896
897 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments, defaultFramebuffer);
898}
899
Dian Xiangbf18ed02015-09-11 10:50:04 -0700900bool ValidateDrawBuffers(Context *context, GLsizei n, const GLenum *bufs)
901{
902 // INVALID_VALUE is generated if n is negative or greater than value of MAX_DRAW_BUFFERS
903 if (n < 0 || static_cast<GLuint>(n) > context->getCaps().maxDrawBuffers)
904 {
905 context->recordError(
906 Error(GL_INVALID_VALUE, "n must be non-negative and no greater than MAX_DRAW_BUFFERS"));
907 return false;
908 }
909
910 ASSERT(context->getState().getDrawFramebuffer());
911 GLuint frameBufferId = context->getState().getDrawFramebuffer()->id();
912 GLuint maxColorAttachment = GL_COLOR_ATTACHMENT0_EXT + context->getCaps().maxColorAttachments;
913
914 // This should come first before the check for the default frame buffer
915 // because when we switch to ES3.1+, invalid enums will return INVALID_ENUM
916 // rather than INVALID_OPERATION
917 for (int colorAttachment = 0; colorAttachment < n; colorAttachment++)
918 {
919 const GLenum attachment = GL_COLOR_ATTACHMENT0_EXT + colorAttachment;
920
921 if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != GL_BACK &&
922 (bufs[colorAttachment] < GL_COLOR_ATTACHMENT0_EXT ||
923 bufs[colorAttachment] >= maxColorAttachment))
924 {
925 // Value in bufs is not NONE, BACK, or GL_COLOR_ATTACHMENTi
926 // In the 3.0 specs, the error should return GL_INVALID_OPERATION.
927 // When we move to 3.1 specs, we should change the error to be GL_INVALID_ENUM
928 context->recordError(Error(GL_INVALID_OPERATION, "Invalid buffer value"));
929 return false;
930 }
931 else if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != attachment &&
932 frameBufferId != 0)
933 {
934 // INVALID_OPERATION-GL is bound to buffer and ith argument
935 // is not COLOR_ATTACHMENTi or NONE
936 context->recordError(
937 Error(GL_INVALID_OPERATION, "Ith value does not match COLOR_ATTACHMENTi or NONE"));
938 return false;
939 }
940 }
941
942 // INVALID_OPERATION is generated if GL is bound to the default framebuffer
943 // and n is not 1 or bufs is bound to value other than BACK and NONE
944 if (frameBufferId == 0)
945 {
946 if (n != 1)
947 {
948 context->recordError(Error(GL_INVALID_OPERATION,
949 "n must be 1 when GL is bound to the default framebuffer"));
950 return false;
951 }
952
953 if (bufs[0] != GL_NONE && bufs[0] != GL_BACK)
954 {
955 context->recordError(Error(
956 GL_INVALID_OPERATION,
957 "Only NONE or BACK are valid values when drawing to the default framebuffer"));
958 return false;
959 }
960 }
961
962 return true;
963}
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400964}