blob: f950454df091e41daa4b07debd588b25ed5ed600 [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
9#include "libGLESv2/validationES2.h"
Geoff Langce635692013-09-24 13:56:32 -040010#include "libGLESv2/validationES.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040011#include "libGLESv2/Context.h"
12#include "libGLESv2/Texture.h"
13#include "libGLESv2/Framebuffer.h"
14#include "libGLESv2/Renderbuffer.h"
15#include "libGLESv2/formatutils.h"
16#include "libGLESv2/main.h"
Jamie Madille261b442014-06-25 12:42:21 -040017#include "libGLESv2/FramebufferAttachment.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040018
19#include "common/mathutil.h"
20#include "common/utilities.h"
21
22namespace gl
23{
24
Geoff Langb1196682014-07-23 13:47:29 -040025static bool ValidateSubImageParams2D(Context *context, bool compressed, GLsizei width, GLsizei height,
Geoff Lange8ebe7f2013-08-05 15:03:13 -040026 GLint xoffset, GLint yoffset, GLint level, GLenum format, GLenum type,
27 gl::Texture2D *texture)
28{
29 if (!texture)
30 {
Geoff Langb1196682014-07-23 13:47:29 -040031 context->recordError(Error(GL_INVALID_OPERATION));
32 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040033 }
34
35 if (compressed != texture->isCompressed(level))
36 {
Geoff Langb1196682014-07-23 13:47:29 -040037 context->recordError(Error(GL_INVALID_OPERATION));
38 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040039 }
40
41 if (format != GL_NONE)
42 {
Geoff Lang5d601382014-07-22 15:14:06 -040043 if (gl::GetFormatTypeInfo(format, type).internalFormat != texture->getInternalFormat(level))
Geoff Lange8ebe7f2013-08-05 15:03:13 -040044 {
Geoff Langb1196682014-07-23 13:47:29 -040045 context->recordError(Error(GL_INVALID_OPERATION));
46 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040047 }
48 }
49
50 if (compressed)
51 {
Geoff Langa836e482014-04-28 10:08:27 -040052 if ((width % 4 != 0 && width != texture->getWidth(level)) ||
53 (height % 4 != 0 && height != texture->getHeight(level)))
Geoff Lange8ebe7f2013-08-05 15:03:13 -040054 {
Geoff Langb1196682014-07-23 13:47:29 -040055 context->recordError(Error(GL_INVALID_OPERATION));
56 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040057 }
58 }
59
60 if (xoffset + width > texture->getWidth(level) ||
61 yoffset + height > texture->getHeight(level))
62 {
Geoff Langb1196682014-07-23 13:47:29 -040063 context->recordError(Error(GL_INVALID_VALUE));
64 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040065 }
66
67 return true;
68}
69
Geoff Langb1196682014-07-23 13:47:29 -040070static bool ValidateSubImageParamsCube(Context *context, bool compressed, GLsizei width, GLsizei height,
Geoff Lange8ebe7f2013-08-05 15:03:13 -040071 GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format, GLenum type,
72 gl::TextureCubeMap *texture)
73{
74 if (!texture)
75 {
Geoff Langb1196682014-07-23 13:47:29 -040076 context->recordError(Error(GL_INVALID_OPERATION));
77 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040078 }
79
80 if (compressed != texture->isCompressed(target, level))
81 {
Geoff Langb1196682014-07-23 13:47:29 -040082 context->recordError(Error(GL_INVALID_OPERATION));
83 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040084 }
85
86 if (format != GL_NONE)
87 {
Geoff Lang5d601382014-07-22 15:14:06 -040088 if (gl::GetFormatTypeInfo(format, type).internalFormat != texture->getInternalFormat(target, level))
Geoff Lange8ebe7f2013-08-05 15:03:13 -040089 {
Geoff Langb1196682014-07-23 13:47:29 -040090 context->recordError(Error(GL_INVALID_OPERATION));
91 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040092 }
93 }
94
95 if (compressed)
96 {
97 if ((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
98 (height % 4 != 0 && height != texture->getHeight(target, 0)))
99 {
Geoff Langb1196682014-07-23 13:47:29 -0400100 context->recordError(Error(GL_INVALID_OPERATION));
101 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400102 }
103 }
104
105 if (xoffset + width > texture->getWidth(target, level) ||
106 yoffset + height > texture->getHeight(target, level))
107 {
Geoff Langb1196682014-07-23 13:47:29 -0400108 context->recordError(Error(GL_INVALID_VALUE));
109 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400110 }
111
112 return true;
113}
114
Geoff Langb1196682014-07-23 13:47:29 -0400115bool ValidateES2TexImageParameters(Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage,
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400116 GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
117 GLint border, GLenum format, GLenum type, const GLvoid *pixels)
118{
Jamie Madill6f38f822014-06-06 17:12:20 -0400119 if (!ValidTexture2DDestinationTarget(context, target))
120 {
Geoff Langb1196682014-07-23 13:47:29 -0400121 context->recordError(Error(GL_INVALID_ENUM));
122 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -0400123 }
124
Geoff Langce635692013-09-24 13:56:32 -0400125 if (!ValidImageSize(context, target, level, width, height, 1))
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400126 {
Geoff Langb1196682014-07-23 13:47:29 -0400127 context->recordError(Error(GL_INVALID_VALUE));
128 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400129 }
130
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400131 if (level < 0 || xoffset < 0 ||
132 std::numeric_limits<GLsizei>::max() - xoffset < width ||
133 std::numeric_limits<GLsizei>::max() - yoffset < height)
134 {
Geoff Langb1196682014-07-23 13:47:29 -0400135 context->recordError(Error(GL_INVALID_VALUE));
136 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400137 }
138
Geoff Lang005df412013-10-16 14:12:50 -0400139 if (!isSubImage && !isCompressed && internalformat != format)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400140 {
Geoff Langb1196682014-07-23 13:47:29 -0400141 context->recordError(Error(GL_INVALID_OPERATION));
142 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400143 }
144
Geoff Langaae65a42014-05-26 12:43:44 -0400145 const gl::Caps &caps = context->getCaps();
146
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400147 gl::Texture *texture = NULL;
148 bool textureCompressed = false;
149 GLenum textureInternalFormat = GL_NONE;
150 GLint textureLevelWidth = 0;
151 GLint textureLevelHeight = 0;
152 switch (target)
153 {
154 case GL_TEXTURE_2D:
155 {
Geoff Langaae65a42014-05-26 12:43:44 -0400156 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
157 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400158 {
Geoff Langb1196682014-07-23 13:47:29 -0400159 context->recordError(Error(GL_INVALID_VALUE));
160 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400161 }
162
163 gl::Texture2D *tex2d = context->getTexture2D();
164 if (tex2d)
165 {
166 textureCompressed = tex2d->isCompressed(level);
167 textureInternalFormat = tex2d->getInternalFormat(level);
168 textureLevelWidth = tex2d->getWidth(level);
169 textureLevelHeight = tex2d->getHeight(level);
170 texture = tex2d;
171 }
172
Geoff Langb1196682014-07-23 13:47:29 -0400173 if (isSubImage && !ValidateSubImageParams2D(context, isCompressed, width, height, xoffset, yoffset,
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400174 level, format, type, tex2d))
175 {
176 return false;
177 }
178
179 texture = tex2d;
180 }
181 break;
182
183 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
184 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
185 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
186 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
187 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
188 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
189 {
190 if (!isSubImage && width != height)
191 {
Geoff Langb1196682014-07-23 13:47:29 -0400192 context->recordError(Error(GL_INVALID_VALUE));
193 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400194 }
195
Geoff Langaae65a42014-05-26 12:43:44 -0400196 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
197 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400198 {
Geoff Langb1196682014-07-23 13:47:29 -0400199 context->recordError(Error(GL_INVALID_VALUE));
200 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400201 }
202
203 gl::TextureCubeMap *texCube = context->getTextureCubeMap();
204 if (texCube)
205 {
206 textureCompressed = texCube->isCompressed(target, level);
207 textureInternalFormat = texCube->getInternalFormat(target, level);
208 textureLevelWidth = texCube->getWidth(target, level);
209 textureLevelHeight = texCube->getHeight(target, level);
210 texture = texCube;
211 }
212
Geoff Langb1196682014-07-23 13:47:29 -0400213 if (isSubImage && !ValidateSubImageParamsCube(context, isCompressed, width, height, xoffset, yoffset,
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400214 target, level, format, type, texCube))
215 {
216 return false;
217 }
218 }
219 break;
220
221 default:
Geoff Langb1196682014-07-23 13:47:29 -0400222 context->recordError(Error(GL_INVALID_ENUM));
223 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400224 }
225
226 if (!texture)
227 {
Geoff Langb1196682014-07-23 13:47:29 -0400228 context->recordError(Error(GL_INVALID_OPERATION));
229 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400230 }
231
232 if (!isSubImage && texture->isImmutable())
233 {
Geoff Langb1196682014-07-23 13:47:29 -0400234 context->recordError(Error(GL_INVALID_OPERATION));
235 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400236 }
237
238 // Verify zero border
239 if (border != 0)
240 {
Geoff Langb1196682014-07-23 13:47:29 -0400241 context->recordError(Error(GL_INVALID_VALUE));
242 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400243 }
244
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400245 GLenum actualInternalFormat = isSubImage ? textureInternalFormat : internalformat;
246 if (isCompressed)
247 {
Geoff Langd4f180b2013-09-24 13:57:44 -0400248 if (!ValidCompressedImageSize(context, actualInternalFormat, width, height))
249 {
Geoff Langb1196682014-07-23 13:47:29 -0400250 context->recordError(Error(GL_INVALID_OPERATION));
251 return false;
Geoff Langd4f180b2013-09-24 13:57:44 -0400252 }
253
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400254 switch (actualInternalFormat)
255 {
256 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
257 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400258 if (!context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400259 {
Geoff Langb1196682014-07-23 13:47:29 -0400260 context->recordError(Error(GL_INVALID_ENUM));
261 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400262 }
263 break;
264 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400265 if (!context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400266 {
Geoff Langb1196682014-07-23 13:47:29 -0400267 context->recordError(Error(GL_INVALID_ENUM));
268 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400269 }
270 break;
271 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
Geoff Langb1196682014-07-23 13:47:29 -0400272 if (!context->getExtensions().textureCompressionDXT5)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400273 {
Geoff Langb1196682014-07-23 13:47:29 -0400274 context->recordError(Error(GL_INVALID_ENUM));
275 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400276 }
277 break;
278 default:
Geoff Langb1196682014-07-23 13:47:29 -0400279 context->recordError(Error(GL_INVALID_ENUM));
280 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400281 }
282 }
283 else
284 {
285 // validate <type> by itself (used as secondary key below)
286 switch (type)
287 {
288 case GL_UNSIGNED_BYTE:
289 case GL_UNSIGNED_SHORT_5_6_5:
290 case GL_UNSIGNED_SHORT_4_4_4_4:
291 case GL_UNSIGNED_SHORT_5_5_5_1:
292 case GL_UNSIGNED_SHORT:
293 case GL_UNSIGNED_INT:
294 case GL_UNSIGNED_INT_24_8_OES:
295 case GL_HALF_FLOAT_OES:
296 case GL_FLOAT:
297 break;
298 default:
Geoff Langb1196682014-07-23 13:47:29 -0400299 context->recordError(Error(GL_INVALID_ENUM));
300 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400301 }
302
303 // validate <format> + <type> combinations
304 // - invalid <format> -> sets INVALID_ENUM
305 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
306 switch (format)
307 {
308 case GL_ALPHA:
309 case GL_LUMINANCE:
310 case GL_LUMINANCE_ALPHA:
311 switch (type)
312 {
313 case GL_UNSIGNED_BYTE:
314 case GL_FLOAT:
315 case GL_HALF_FLOAT_OES:
316 break;
Geoff Langb1196682014-07-23 13:47:29 -0400317 default:
318 context->recordError(Error(GL_INVALID_OPERATION));
319 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400320 }
321 break;
Geoff Lang632192d2013-10-04 13:40:46 -0400322 case GL_RED:
Geoff Langcec35902014-04-16 10:52:36 -0400323 case GL_RG:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400324 if (!context->getExtensions().textureRG)
Geoff Lang632192d2013-10-04 13:40:46 -0400325 {
Geoff Langb1196682014-07-23 13:47:29 -0400326 context->recordError(Error(GL_INVALID_ENUM));
327 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400328 }
329 switch (type)
330 {
331 case GL_UNSIGNED_BYTE:
332 case GL_FLOAT:
333 case GL_HALF_FLOAT_OES:
334 break;
335 default:
Geoff Langb1196682014-07-23 13:47:29 -0400336 context->recordError(Error(GL_INVALID_OPERATION));
337 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400338 }
339 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400340 case GL_RGB:
341 switch (type)
342 {
343 case GL_UNSIGNED_BYTE:
344 case GL_UNSIGNED_SHORT_5_6_5:
345 case GL_FLOAT:
346 case GL_HALF_FLOAT_OES:
347 break;
348 default:
Geoff Langb1196682014-07-23 13:47:29 -0400349 context->recordError(Error(GL_INVALID_OPERATION));
350 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400351 }
352 break;
353 case GL_RGBA:
354 switch (type)
355 {
356 case GL_UNSIGNED_BYTE:
357 case GL_UNSIGNED_SHORT_4_4_4_4:
358 case GL_UNSIGNED_SHORT_5_5_5_1:
359 case GL_FLOAT:
360 case GL_HALF_FLOAT_OES:
361 break;
362 default:
Geoff Langb1196682014-07-23 13:47:29 -0400363 context->recordError(Error(GL_INVALID_OPERATION));
364 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400365 }
366 break;
367 case GL_BGRA_EXT:
368 switch (type)
369 {
370 case GL_UNSIGNED_BYTE:
371 break;
372 default:
Geoff Langb1196682014-07-23 13:47:29 -0400373 context->recordError(Error(GL_INVALID_OPERATION));
374 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400375 }
376 break;
Geoff Lang05b05022014-06-11 15:31:45 -0400377 case GL_SRGB_EXT:
378 case GL_SRGB_ALPHA_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400379 if (!context->getExtensions().sRGB)
Geoff Lang05b05022014-06-11 15:31:45 -0400380 {
Geoff Langb1196682014-07-23 13:47:29 -0400381 context->recordError(Error(GL_INVALID_ENUM));
382 return false;
Geoff Lang05b05022014-06-11 15:31:45 -0400383 }
384 switch (type)
385 {
386 case GL_UNSIGNED_BYTE:
387 break;
388 default:
Geoff Langb1196682014-07-23 13:47:29 -0400389 context->recordError(Error(GL_INVALID_OPERATION));
390 return false;
Geoff Lang05b05022014-06-11 15:31:45 -0400391 }
392 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400393 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
394 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
395 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
396 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
397 break;
398 case GL_DEPTH_COMPONENT:
399 switch (type)
400 {
401 case GL_UNSIGNED_SHORT:
402 case GL_UNSIGNED_INT:
403 break;
404 default:
Geoff Langb1196682014-07-23 13:47:29 -0400405 context->recordError(Error(GL_INVALID_OPERATION));
406 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400407 }
408 break;
409 case GL_DEPTH_STENCIL_OES:
410 switch (type)
411 {
412 case GL_UNSIGNED_INT_24_8_OES:
413 break;
414 default:
Geoff Langb1196682014-07-23 13:47:29 -0400415 context->recordError(Error(GL_INVALID_OPERATION));
416 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400417 }
418 break;
419 default:
Geoff Langb1196682014-07-23 13:47:29 -0400420 context->recordError(Error(GL_INVALID_ENUM));
421 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400422 }
423
424 switch (format)
425 {
426 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
427 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400428 if (context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400429 {
Geoff Langb1196682014-07-23 13:47:29 -0400430 context->recordError(Error(GL_INVALID_OPERATION));
431 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400432 }
433 else
434 {
Geoff Langb1196682014-07-23 13:47:29 -0400435 context->recordError(Error(GL_INVALID_ENUM));
436 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400437 }
438 break;
439 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400440 if (context->getExtensions().textureCompressionDXT3)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400441 {
Geoff Langb1196682014-07-23 13:47:29 -0400442 context->recordError(Error(GL_INVALID_OPERATION));
443 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400444 }
445 else
446 {
Geoff Langb1196682014-07-23 13:47:29 -0400447 context->recordError(Error(GL_INVALID_ENUM));
448 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400449 }
450 break;
451 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400452 if (context->getExtensions().textureCompressionDXT5)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400453 {
Geoff Langb1196682014-07-23 13:47:29 -0400454 context->recordError(Error(GL_INVALID_OPERATION));
455 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400456 }
457 else
458 {
Geoff Langb1196682014-07-23 13:47:29 -0400459 context->recordError(Error(GL_INVALID_ENUM));
460 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400461 }
462 break;
463 case GL_DEPTH_COMPONENT:
464 case GL_DEPTH_STENCIL_OES:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400465 if (!context->getExtensions().depthTextures)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400466 {
Geoff Langb1196682014-07-23 13:47:29 -0400467 context->recordError(Error(GL_INVALID_VALUE));
468 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400469 }
470 if (target != GL_TEXTURE_2D)
471 {
Geoff Langb1196682014-07-23 13:47:29 -0400472 context->recordError(Error(GL_INVALID_OPERATION));
473 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400474 }
475 // OES_depth_texture supports loading depth data and multiple levels,
476 // but ANGLE_depth_texture does not
477 if (pixels != NULL || level != 0)
478 {
Geoff Langb1196682014-07-23 13:47:29 -0400479 context->recordError(Error(GL_INVALID_OPERATION));
480 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400481 }
482 break;
483 default:
484 break;
485 }
486
487 if (type == GL_FLOAT)
488 {
Geoff Langc0b9ef42014-07-02 10:02:37 -0400489 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400490 {
Geoff Langb1196682014-07-23 13:47:29 -0400491 context->recordError(Error(GL_INVALID_ENUM));
492 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400493 }
494 }
495 else if (type == GL_HALF_FLOAT_OES)
496 {
Geoff Langc0b9ef42014-07-02 10:02:37 -0400497 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400498 {
Geoff Langb1196682014-07-23 13:47:29 -0400499 context->recordError(Error(GL_INVALID_ENUM));
500 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400501 }
502 }
503 }
504
505 return true;
506}
507
508
509
Geoff Langb1196682014-07-23 13:47:29 -0400510bool ValidateES2CopyTexImageParameters(Context* context, GLenum target, GLint level, GLenum internalformat, bool isSubImage,
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400511 GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height,
512 GLint border)
513{
Jamie Madill560a8d82014-05-21 13:06:20 -0400514 GLenum textureInternalFormat = GL_NONE;
Shannon Woods4dfed832014-03-17 20:03:39 -0400515
Jamie Madill560a8d82014-05-21 13:06:20 -0400516 if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
517 xoffset, yoffset, 0, x, y, width, height, border, &textureInternalFormat))
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400518 {
Jamie Madill560a8d82014-05-21 13:06:20 -0400519 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400520 }
521
Shannon Woods53a94a82014-06-24 15:20:36 -0400522 gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer();
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400523 GLenum colorbufferFormat = framebuffer->getReadColorbuffer()->getInternalFormat();
Geoff Lang5d601382014-07-22 15:14:06 -0400524 GLenum textureFormat = gl::GetInternalFormatInfo(textureInternalFormat).format;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400525
526 // [OpenGL ES 2.0.24] table 3.9
527 if (isSubImage)
528 {
529 switch (textureFormat)
530 {
531 case GL_ALPHA:
532 if (colorbufferFormat != GL_ALPHA8_EXT &&
533 colorbufferFormat != GL_RGBA4 &&
534 colorbufferFormat != GL_RGB5_A1 &&
535 colorbufferFormat != GL_RGBA8_OES)
536 {
Geoff Langb1196682014-07-23 13:47:29 -0400537 context->recordError(Error(GL_INVALID_OPERATION));
538 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400539 }
540 break;
541 case GL_LUMINANCE:
Geoff Lang632192d2013-10-04 13:40:46 -0400542 if (colorbufferFormat != GL_R8_EXT &&
543 colorbufferFormat != GL_RG8_EXT &&
544 colorbufferFormat != GL_RGB565 &&
545 colorbufferFormat != GL_RGB8_OES &&
546 colorbufferFormat != GL_RGBA4 &&
547 colorbufferFormat != GL_RGB5_A1 &&
548 colorbufferFormat != GL_RGBA8_OES)
549 {
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_RGBA8_OES)
562 {
Geoff Langb1196682014-07-23 13:47:29 -0400563 context->recordError(Error(GL_INVALID_OPERATION));
564 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400565 }
566 break;
567 case GL_RG_EXT:
568 if (colorbufferFormat != GL_RG8_EXT &&
569 colorbufferFormat != GL_RGB565 &&
570 colorbufferFormat != GL_RGB8_OES &&
571 colorbufferFormat != GL_RGBA4 &&
572 colorbufferFormat != GL_RGB5_A1 &&
573 colorbufferFormat != GL_RGBA8_OES)
574 {
Geoff Langb1196682014-07-23 13:47:29 -0400575 context->recordError(Error(GL_INVALID_OPERATION));
576 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400577 }
578 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400579 case GL_RGB:
580 if (colorbufferFormat != GL_RGB565 &&
581 colorbufferFormat != GL_RGB8_OES &&
582 colorbufferFormat != GL_RGBA4 &&
583 colorbufferFormat != GL_RGB5_A1 &&
584 colorbufferFormat != GL_RGBA8_OES)
585 {
Geoff Langb1196682014-07-23 13:47:29 -0400586 context->recordError(Error(GL_INVALID_OPERATION));
587 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400588 }
589 break;
590 case GL_LUMINANCE_ALPHA:
591 case GL_RGBA:
592 if (colorbufferFormat != GL_RGBA4 &&
593 colorbufferFormat != GL_RGB5_A1 &&
594 colorbufferFormat != GL_RGBA8_OES)
595 {
Geoff Langb1196682014-07-23 13:47:29 -0400596 context->recordError(Error(GL_INVALID_OPERATION));
597 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400598 }
599 break;
600 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
601 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
602 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
603 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
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 case GL_DEPTH_COMPONENT:
607 case GL_DEPTH_STENCIL_OES:
Geoff Langb1196682014-07-23 13:47:29 -0400608 context->recordError(Error(GL_INVALID_OPERATION));
609 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400610 default:
Geoff Langb1196682014-07-23 13:47:29 -0400611 context->recordError(Error(GL_INVALID_OPERATION));
612 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400613 }
614 }
615 else
616 {
617 switch (internalformat)
618 {
619 case GL_ALPHA:
620 if (colorbufferFormat != GL_ALPHA8_EXT &&
621 colorbufferFormat != GL_RGBA4 &&
622 colorbufferFormat != GL_RGB5_A1 &&
623 colorbufferFormat != GL_BGRA8_EXT &&
624 colorbufferFormat != GL_RGBA8_OES)
625 {
Geoff Langb1196682014-07-23 13:47:29 -0400626 context->recordError(Error(GL_INVALID_OPERATION));
627 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400628 }
629 break;
630 case GL_LUMINANCE:
Geoff Lang632192d2013-10-04 13:40:46 -0400631 if (colorbufferFormat != GL_R8_EXT &&
632 colorbufferFormat != GL_RG8_EXT &&
633 colorbufferFormat != GL_RGB565 &&
634 colorbufferFormat != GL_RGB8_OES &&
635 colorbufferFormat != GL_RGBA4 &&
636 colorbufferFormat != GL_RGB5_A1 &&
637 colorbufferFormat != GL_BGRA8_EXT &&
638 colorbufferFormat != GL_RGBA8_OES)
639 {
Geoff Langb1196682014-07-23 13:47:29 -0400640 context->recordError(Error(GL_INVALID_OPERATION));
641 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400642 }
643 break;
644 case GL_RED_EXT:
645 if (colorbufferFormat != GL_R8_EXT &&
646 colorbufferFormat != GL_RG8_EXT &&
647 colorbufferFormat != GL_RGB565 &&
648 colorbufferFormat != GL_RGB8_OES &&
649 colorbufferFormat != GL_RGBA4 &&
650 colorbufferFormat != GL_RGB5_A1 &&
651 colorbufferFormat != GL_BGRA8_EXT &&
652 colorbufferFormat != GL_RGBA8_OES)
653 {
Geoff Langb1196682014-07-23 13:47:29 -0400654 context->recordError(Error(GL_INVALID_OPERATION));
655 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400656 }
657 break;
658 case GL_RG_EXT:
659 if (colorbufferFormat != GL_RG8_EXT &&
660 colorbufferFormat != GL_RGB565 &&
661 colorbufferFormat != GL_RGB8_OES &&
662 colorbufferFormat != GL_RGBA4 &&
663 colorbufferFormat != GL_RGB5_A1 &&
664 colorbufferFormat != GL_BGRA8_EXT &&
665 colorbufferFormat != GL_RGBA8_OES)
666 {
Geoff Langb1196682014-07-23 13:47:29 -0400667 context->recordError(Error(GL_INVALID_OPERATION));
668 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400669 }
670 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400671 case GL_RGB:
672 if (colorbufferFormat != GL_RGB565 &&
673 colorbufferFormat != GL_RGB8_OES &&
674 colorbufferFormat != GL_RGBA4 &&
675 colorbufferFormat != GL_RGB5_A1 &&
676 colorbufferFormat != GL_BGRA8_EXT &&
677 colorbufferFormat != GL_RGBA8_OES)
678 {
Geoff Langb1196682014-07-23 13:47:29 -0400679 context->recordError(Error(GL_INVALID_OPERATION));
680 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400681 }
682 break;
683 case GL_LUMINANCE_ALPHA:
684 case GL_RGBA:
685 if (colorbufferFormat != GL_RGBA4 &&
686 colorbufferFormat != GL_RGB5_A1 &&
687 colorbufferFormat != GL_BGRA8_EXT &&
688 colorbufferFormat != GL_RGBA8_OES)
689 {
Geoff Langb1196682014-07-23 13:47:29 -0400690 context->recordError(Error(GL_INVALID_OPERATION));
691 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400692 }
693 break;
694 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
695 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400696 if (context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400697 {
Geoff Langb1196682014-07-23 13:47:29 -0400698 context->recordError(Error(GL_INVALID_OPERATION));
699 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400700 }
701 else
702 {
Geoff Langb1196682014-07-23 13:47:29 -0400703 context->recordError(Error(GL_INVALID_ENUM));
704 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400705 }
706 break;
707 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400708 if (context->getExtensions().textureCompressionDXT3)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400709 {
Geoff Langb1196682014-07-23 13:47:29 -0400710 context->recordError(Error(GL_INVALID_OPERATION));
711 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400712 }
713 else
714 {
Geoff Langb1196682014-07-23 13:47:29 -0400715 context->recordError(Error(GL_INVALID_ENUM));
716 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400717 }
718 break;
719 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400720 if (context->getExtensions().textureCompressionDXT5)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400721 {
Geoff Langb1196682014-07-23 13:47:29 -0400722 context->recordError(Error(GL_INVALID_OPERATION));
723 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400724 }
725 else
726 {
Geoff Langb1196682014-07-23 13:47:29 -0400727 context->recordError(Error(GL_INVALID_ENUM));
728 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400729 }
730 break;
731 case GL_DEPTH_COMPONENT:
732 case GL_DEPTH_COMPONENT16:
733 case GL_DEPTH_COMPONENT32_OES:
734 case GL_DEPTH_STENCIL_OES:
735 case GL_DEPTH24_STENCIL8_OES:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400736 if (context->getExtensions().depthTextures)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400737 {
Geoff Langb1196682014-07-23 13:47:29 -0400738 context->recordError(Error(GL_INVALID_OPERATION));
739 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400740 }
741 else
742 {
Geoff Langb1196682014-07-23 13:47:29 -0400743 context->recordError(Error(GL_INVALID_ENUM));
744 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400745 }
746 default:
Geoff Langb1196682014-07-23 13:47:29 -0400747 context->recordError(Error(GL_INVALID_ENUM));
748 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400749 }
750 }
751
Geoff Lang784a8fd2013-09-24 12:33:16 -0400752 // If width or height is zero, it is a no-op. Return false without setting an error.
753 return (width > 0 && height > 0);
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400754}
755
Geoff Langb1196682014-07-23 13:47:29 -0400756bool ValidateES2TexStorageParameters(Context *context, GLenum target, GLsizei levels, GLenum internalformat,
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400757 GLsizei width, GLsizei height)
758{
759 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP)
760 {
Geoff Langb1196682014-07-23 13:47:29 -0400761 context->recordError(Error(GL_INVALID_ENUM));
762 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400763 }
764
765 if (width < 1 || height < 1 || levels < 1)
766 {
Geoff Langb1196682014-07-23 13:47:29 -0400767 context->recordError(Error(GL_INVALID_VALUE));
768 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400769 }
770
771 if (target == GL_TEXTURE_CUBE_MAP && width != height)
772 {
Geoff Langb1196682014-07-23 13:47:29 -0400773 context->recordError(Error(GL_INVALID_VALUE));
774 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400775 }
776
777 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
778 {
Geoff Langb1196682014-07-23 13:47:29 -0400779 context->recordError(Error(GL_INVALID_OPERATION));
780 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400781 }
782
Geoff Lang5d601382014-07-22 15:14:06 -0400783 const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
784 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400785 {
Geoff Langb1196682014-07-23 13:47:29 -0400786 context->recordError(Error(GL_INVALID_ENUM));
787 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400788 }
789
Geoff Langaae65a42014-05-26 12:43:44 -0400790 const gl::Caps &caps = context->getCaps();
791
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400792 switch (target)
793 {
794 case GL_TEXTURE_2D:
Geoff Langaae65a42014-05-26 12:43:44 -0400795 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
796 static_cast<GLuint>(height) > caps.max2DTextureSize)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400797 {
Geoff Langb1196682014-07-23 13:47:29 -0400798 context->recordError(Error(GL_INVALID_VALUE));
799 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400800 }
801 break;
802 case GL_TEXTURE_CUBE_MAP:
Geoff Langaae65a42014-05-26 12:43:44 -0400803 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
804 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400805 {
Geoff Langb1196682014-07-23 13:47:29 -0400806 context->recordError(Error(GL_INVALID_VALUE));
807 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400808 }
809 break;
810 default:
Geoff Langb1196682014-07-23 13:47:29 -0400811 context->recordError(Error(GL_INVALID_ENUM));
812 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400813 }
814
Geoff Langc0b9ef42014-07-02 10:02:37 -0400815 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400816 {
817 if (!gl::isPow2(width) || !gl::isPow2(height))
818 {
Geoff Langb1196682014-07-23 13:47:29 -0400819 context->recordError(Error(GL_INVALID_OPERATION));
820 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400821 }
822 }
823
824 switch (internalformat)
825 {
826 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
827 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400828 if (!context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400829 {
Geoff Langb1196682014-07-23 13:47:29 -0400830 context->recordError(Error(GL_INVALID_ENUM));
831 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400832 }
833 break;
834 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400835 if (!context->getExtensions().textureCompressionDXT3)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400836 {
Geoff Langb1196682014-07-23 13:47:29 -0400837 context->recordError(Error(GL_INVALID_ENUM));
838 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400839 }
840 break;
841 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400842 if (!context->getExtensions().textureCompressionDXT5)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400843 {
Geoff Langb1196682014-07-23 13:47:29 -0400844 context->recordError(Error(GL_INVALID_ENUM));
845 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400846 }
847 break;
848 case GL_RGBA32F_EXT:
849 case GL_RGB32F_EXT:
850 case GL_ALPHA32F_EXT:
851 case GL_LUMINANCE32F_EXT:
852 case GL_LUMINANCE_ALPHA32F_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400853 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400854 {
Geoff Langb1196682014-07-23 13:47:29 -0400855 context->recordError(Error(GL_INVALID_ENUM));
856 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400857 }
858 break;
859 case GL_RGBA16F_EXT:
860 case GL_RGB16F_EXT:
861 case GL_ALPHA16F_EXT:
862 case GL_LUMINANCE16F_EXT:
863 case GL_LUMINANCE_ALPHA16F_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400864 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400865 {
Geoff Langb1196682014-07-23 13:47:29 -0400866 context->recordError(Error(GL_INVALID_ENUM));
867 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400868 }
869 break;
Geoff Lang632192d2013-10-04 13:40:46 -0400870 case GL_R8_EXT:
871 case GL_RG8_EXT:
872 case GL_R16F_EXT:
873 case GL_RG16F_EXT:
874 case GL_R32F_EXT:
875 case GL_RG32F_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400876 if (!context->getExtensions().textureRG)
Geoff Lang632192d2013-10-04 13:40:46 -0400877 {
Geoff Langb1196682014-07-23 13:47:29 -0400878 context->recordError(Error(GL_INVALID_ENUM));
879 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400880 }
881 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400882 case GL_DEPTH_COMPONENT16:
883 case GL_DEPTH_COMPONENT32_OES:
884 case GL_DEPTH24_STENCIL8_OES:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400885 if (!context->getExtensions().depthTextures)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400886 {
Geoff Langb1196682014-07-23 13:47:29 -0400887 context->recordError(Error(GL_INVALID_ENUM));
888 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400889 }
890 if (target != GL_TEXTURE_2D)
891 {
Geoff Langb1196682014-07-23 13:47:29 -0400892 context->recordError(Error(GL_INVALID_OPERATION));
893 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400894 }
895 // ANGLE_depth_texture only supports 1-level textures
896 if (levels != 1)
897 {
Geoff Langb1196682014-07-23 13:47:29 -0400898 context->recordError(Error(GL_INVALID_OPERATION));
899 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400900 }
901 break;
902 default:
903 break;
904 }
905
906 gl::Texture *texture = NULL;
907 switch(target)
908 {
909 case GL_TEXTURE_2D:
910 texture = context->getTexture2D();
911 break;
912 case GL_TEXTURE_CUBE_MAP:
913 texture = context->getTextureCubeMap();
914 break;
915 default:
916 UNREACHABLE();
917 }
918
919 if (!texture || texture->id() == 0)
920 {
Geoff Langb1196682014-07-23 13:47:29 -0400921 context->recordError(Error(GL_INVALID_OPERATION));
922 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400923 }
924
925 if (texture->isImmutable())
926 {
Geoff Langb1196682014-07-23 13:47:29 -0400927 context->recordError(Error(GL_INVALID_OPERATION));
928 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400929 }
930
931 return true;
932}
933
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400934// check for combinations of format and type that are valid for ReadPixels
Geoff Langb1196682014-07-23 13:47:29 -0400935bool ValidES2ReadFormatType(Context *context, GLenum format, GLenum type)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400936{
937 switch (format)
938 {
939 case GL_RGBA:
940 switch (type)
941 {
942 case GL_UNSIGNED_BYTE:
943 break;
944 default:
945 return false;
946 }
947 break;
948 case GL_BGRA_EXT:
949 switch (type)
950 {
951 case GL_UNSIGNED_BYTE:
952 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
953 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
954 break;
955 default:
956 return false;
957 }
958 break;
Geoff Langbdc9b2f2014-04-16 14:41:54 -0400959 case GL_RG_EXT:
960 case GL_RED_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400961 if (!context->getExtensions().textureRG)
Geoff Langbdc9b2f2014-04-16 14:41:54 -0400962 {
963 return false;
964 }
965 switch (type)
966 {
967 case GL_UNSIGNED_BYTE:
968 break;
969 default:
970 return false;
971 }
972 break;
973
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400974 default:
975 return false;
976 }
977 return true;
978}
979
980}