blob: c1ccc4c72306a1eee437cce69b5c2e5566e9b3f9 [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 -040024static bool ValidateSubImageParams2D(Context *context, bool compressed, GLsizei width, GLsizei height,
Geoff Lange8ebe7f2013-08-05 15:03:13 -040025 GLint xoffset, GLint yoffset, GLint level, GLenum format, GLenum type,
26 gl::Texture2D *texture)
27{
28 if (!texture)
29 {
Geoff Langb1196682014-07-23 13:47:29 -040030 context->recordError(Error(GL_INVALID_OPERATION));
31 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040032 }
33
34 if (compressed != texture->isCompressed(level))
35 {
Geoff Langb1196682014-07-23 13:47:29 -040036 context->recordError(Error(GL_INVALID_OPERATION));
37 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040038 }
39
40 if (format != GL_NONE)
41 {
Geoff Lang5d601382014-07-22 15:14:06 -040042 if (gl::GetFormatTypeInfo(format, type).internalFormat != texture->getInternalFormat(level))
Geoff Lange8ebe7f2013-08-05 15:03:13 -040043 {
Geoff Langb1196682014-07-23 13:47:29 -040044 context->recordError(Error(GL_INVALID_OPERATION));
45 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040046 }
47 }
48
49 if (compressed)
50 {
Geoff Langa836e482014-04-28 10:08:27 -040051 if ((width % 4 != 0 && width != texture->getWidth(level)) ||
52 (height % 4 != 0 && height != texture->getHeight(level)))
Geoff Lange8ebe7f2013-08-05 15:03:13 -040053 {
Geoff Langb1196682014-07-23 13:47:29 -040054 context->recordError(Error(GL_INVALID_OPERATION));
55 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040056 }
57 }
58
59 if (xoffset + width > texture->getWidth(level) ||
60 yoffset + height > texture->getHeight(level))
61 {
Geoff Langb1196682014-07-23 13:47:29 -040062 context->recordError(Error(GL_INVALID_VALUE));
63 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040064 }
65
66 return true;
67}
68
Geoff Langb1196682014-07-23 13:47:29 -040069static bool ValidateSubImageParamsCube(Context *context, bool compressed, GLsizei width, GLsizei height,
Geoff Lange8ebe7f2013-08-05 15:03:13 -040070 GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format, GLenum type,
71 gl::TextureCubeMap *texture)
72{
73 if (!texture)
74 {
Geoff Langb1196682014-07-23 13:47:29 -040075 context->recordError(Error(GL_INVALID_OPERATION));
76 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040077 }
78
79 if (compressed != texture->isCompressed(target, level))
80 {
Geoff Langb1196682014-07-23 13:47:29 -040081 context->recordError(Error(GL_INVALID_OPERATION));
82 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040083 }
84
85 if (format != GL_NONE)
86 {
Geoff Lang5d601382014-07-22 15:14:06 -040087 if (gl::GetFormatTypeInfo(format, type).internalFormat != texture->getInternalFormat(target, level))
Geoff Lange8ebe7f2013-08-05 15:03:13 -040088 {
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 }
93
94 if (compressed)
95 {
96 if ((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
97 (height % 4 != 0 && height != texture->getHeight(target, 0)))
98 {
Geoff Langb1196682014-07-23 13:47:29 -040099 context->recordError(Error(GL_INVALID_OPERATION));
100 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400101 }
102 }
103
104 if (xoffset + width > texture->getWidth(target, level) ||
105 yoffset + height > texture->getHeight(target, level))
106 {
Geoff Langb1196682014-07-23 13:47:29 -0400107 context->recordError(Error(GL_INVALID_VALUE));
108 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400109 }
110
111 return true;
112}
113
Geoff Langb1196682014-07-23 13:47:29 -0400114bool ValidateES2TexImageParameters(Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage,
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400115 GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
116 GLint border, GLenum format, GLenum type, const GLvoid *pixels)
117{
Jamie Madill6f38f822014-06-06 17:12:20 -0400118 if (!ValidTexture2DDestinationTarget(context, target))
119 {
Geoff Langb1196682014-07-23 13:47:29 -0400120 context->recordError(Error(GL_INVALID_ENUM));
121 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -0400122 }
123
Geoff Langce635692013-09-24 13:56:32 -0400124 if (!ValidImageSize(context, target, level, width, height, 1))
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400125 {
Geoff Langb1196682014-07-23 13:47:29 -0400126 context->recordError(Error(GL_INVALID_VALUE));
127 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400128 }
129
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400130 if (level < 0 || xoffset < 0 ||
131 std::numeric_limits<GLsizei>::max() - xoffset < width ||
132 std::numeric_limits<GLsizei>::max() - yoffset < height)
133 {
Geoff Langb1196682014-07-23 13:47:29 -0400134 context->recordError(Error(GL_INVALID_VALUE));
135 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400136 }
137
Geoff Lang005df412013-10-16 14:12:50 -0400138 if (!isSubImage && !isCompressed && internalformat != format)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400139 {
Geoff Langb1196682014-07-23 13:47:29 -0400140 context->recordError(Error(GL_INVALID_OPERATION));
141 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400142 }
143
Geoff Langaae65a42014-05-26 12:43:44 -0400144 const gl::Caps &caps = context->getCaps();
145
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400146 gl::Texture *texture = NULL;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400147 GLenum textureInternalFormat = GL_NONE;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400148 switch (target)
149 {
150 case GL_TEXTURE_2D:
151 {
Geoff Langaae65a42014-05-26 12:43:44 -0400152 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
153 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400154 {
Geoff Langb1196682014-07-23 13:47:29 -0400155 context->recordError(Error(GL_INVALID_VALUE));
156 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400157 }
158
159 gl::Texture2D *tex2d = context->getTexture2D();
160 if (tex2d)
161 {
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400162 textureInternalFormat = tex2d->getInternalFormat(level);
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400163 texture = tex2d;
164 }
165
Geoff Langb1196682014-07-23 13:47:29 -0400166 if (isSubImage && !ValidateSubImageParams2D(context, isCompressed, width, height, xoffset, yoffset,
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400167 level, format, type, tex2d))
168 {
169 return false;
170 }
171
172 texture = tex2d;
173 }
174 break;
175
176 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
177 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
178 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
179 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
180 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
181 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
182 {
183 if (!isSubImage && width != height)
184 {
Geoff Langb1196682014-07-23 13:47:29 -0400185 context->recordError(Error(GL_INVALID_VALUE));
186 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400187 }
188
Geoff Langaae65a42014-05-26 12:43:44 -0400189 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
190 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400191 {
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
196 gl::TextureCubeMap *texCube = context->getTextureCubeMap();
197 if (texCube)
198 {
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400199 textureInternalFormat = texCube->getInternalFormat(target, level);
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400200 texture = texCube;
201 }
202
Geoff Langb1196682014-07-23 13:47:29 -0400203 if (isSubImage && !ValidateSubImageParamsCube(context, isCompressed, width, height, xoffset, yoffset,
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400204 target, level, format, type, texCube))
205 {
206 return false;
207 }
208 }
209 break;
210
211 default:
Geoff Langb1196682014-07-23 13:47:29 -0400212 context->recordError(Error(GL_INVALID_ENUM));
213 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400214 }
215
216 if (!texture)
217 {
Geoff Langb1196682014-07-23 13:47:29 -0400218 context->recordError(Error(GL_INVALID_OPERATION));
219 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400220 }
221
222 if (!isSubImage && texture->isImmutable())
223 {
Geoff Langb1196682014-07-23 13:47:29 -0400224 context->recordError(Error(GL_INVALID_OPERATION));
225 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400226 }
227
228 // Verify zero border
229 if (border != 0)
230 {
Geoff Langb1196682014-07-23 13:47:29 -0400231 context->recordError(Error(GL_INVALID_VALUE));
232 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400233 }
234
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400235 GLenum actualInternalFormat = isSubImage ? textureInternalFormat : internalformat;
236 if (isCompressed)
237 {
Geoff Langd4f180b2013-09-24 13:57:44 -0400238 if (!ValidCompressedImageSize(context, actualInternalFormat, width, height))
239 {
Geoff Langb1196682014-07-23 13:47:29 -0400240 context->recordError(Error(GL_INVALID_OPERATION));
241 return false;
Geoff Langd4f180b2013-09-24 13:57:44 -0400242 }
243
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400244 switch (actualInternalFormat)
245 {
246 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
247 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400248 if (!context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400249 {
Geoff Langb1196682014-07-23 13:47:29 -0400250 context->recordError(Error(GL_INVALID_ENUM));
251 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400252 }
253 break;
254 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400255 if (!context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400256 {
Geoff Langb1196682014-07-23 13:47:29 -0400257 context->recordError(Error(GL_INVALID_ENUM));
258 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400259 }
260 break;
261 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
Geoff Langb1196682014-07-23 13:47:29 -0400262 if (!context->getExtensions().textureCompressionDXT5)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400263 {
Geoff Langb1196682014-07-23 13:47:29 -0400264 context->recordError(Error(GL_INVALID_ENUM));
265 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400266 }
267 break;
268 default:
Geoff Langb1196682014-07-23 13:47:29 -0400269 context->recordError(Error(GL_INVALID_ENUM));
270 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400271 }
272 }
273 else
274 {
275 // validate <type> by itself (used as secondary key below)
276 switch (type)
277 {
278 case GL_UNSIGNED_BYTE:
279 case GL_UNSIGNED_SHORT_5_6_5:
280 case GL_UNSIGNED_SHORT_4_4_4_4:
281 case GL_UNSIGNED_SHORT_5_5_5_1:
282 case GL_UNSIGNED_SHORT:
283 case GL_UNSIGNED_INT:
284 case GL_UNSIGNED_INT_24_8_OES:
285 case GL_HALF_FLOAT_OES:
286 case GL_FLOAT:
287 break;
288 default:
Geoff Langb1196682014-07-23 13:47:29 -0400289 context->recordError(Error(GL_INVALID_ENUM));
290 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400291 }
292
293 // validate <format> + <type> combinations
294 // - invalid <format> -> sets INVALID_ENUM
295 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
296 switch (format)
297 {
298 case GL_ALPHA:
299 case GL_LUMINANCE:
300 case GL_LUMINANCE_ALPHA:
301 switch (type)
302 {
303 case GL_UNSIGNED_BYTE:
304 case GL_FLOAT:
305 case GL_HALF_FLOAT_OES:
306 break;
Geoff Langb1196682014-07-23 13:47:29 -0400307 default:
308 context->recordError(Error(GL_INVALID_OPERATION));
309 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400310 }
311 break;
Geoff Lang632192d2013-10-04 13:40:46 -0400312 case GL_RED:
Geoff Langcec35902014-04-16 10:52:36 -0400313 case GL_RG:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400314 if (!context->getExtensions().textureRG)
Geoff Lang632192d2013-10-04 13:40:46 -0400315 {
Geoff Langb1196682014-07-23 13:47:29 -0400316 context->recordError(Error(GL_INVALID_ENUM));
317 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400318 }
319 switch (type)
320 {
321 case GL_UNSIGNED_BYTE:
322 case GL_FLOAT:
323 case GL_HALF_FLOAT_OES:
324 break;
325 default:
Geoff Langb1196682014-07-23 13:47:29 -0400326 context->recordError(Error(GL_INVALID_OPERATION));
327 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400328 }
329 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400330 case GL_RGB:
331 switch (type)
332 {
333 case GL_UNSIGNED_BYTE:
334 case GL_UNSIGNED_SHORT_5_6_5:
335 case GL_FLOAT:
336 case GL_HALF_FLOAT_OES:
337 break;
338 default:
Geoff Langb1196682014-07-23 13:47:29 -0400339 context->recordError(Error(GL_INVALID_OPERATION));
340 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400341 }
342 break;
343 case GL_RGBA:
344 switch (type)
345 {
346 case GL_UNSIGNED_BYTE:
347 case GL_UNSIGNED_SHORT_4_4_4_4:
348 case GL_UNSIGNED_SHORT_5_5_5_1:
349 case GL_FLOAT:
350 case GL_HALF_FLOAT_OES:
351 break;
352 default:
Geoff Langb1196682014-07-23 13:47:29 -0400353 context->recordError(Error(GL_INVALID_OPERATION));
354 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400355 }
356 break;
357 case GL_BGRA_EXT:
358 switch (type)
359 {
360 case GL_UNSIGNED_BYTE:
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;
Geoff Lang05b05022014-06-11 15:31:45 -0400367 case GL_SRGB_EXT:
368 case GL_SRGB_ALPHA_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400369 if (!context->getExtensions().sRGB)
Geoff Lang05b05022014-06-11 15:31:45 -0400370 {
Geoff Langb1196682014-07-23 13:47:29 -0400371 context->recordError(Error(GL_INVALID_ENUM));
372 return false;
Geoff Lang05b05022014-06-11 15:31:45 -0400373 }
374 switch (type)
375 {
376 case GL_UNSIGNED_BYTE:
377 break;
378 default:
Geoff Langb1196682014-07-23 13:47:29 -0400379 context->recordError(Error(GL_INVALID_OPERATION));
380 return false;
Geoff Lang05b05022014-06-11 15:31:45 -0400381 }
382 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400383 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
384 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
385 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
386 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
387 break;
388 case GL_DEPTH_COMPONENT:
389 switch (type)
390 {
391 case GL_UNSIGNED_SHORT:
392 case GL_UNSIGNED_INT:
393 break;
394 default:
Geoff Langb1196682014-07-23 13:47:29 -0400395 context->recordError(Error(GL_INVALID_OPERATION));
396 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400397 }
398 break;
399 case GL_DEPTH_STENCIL_OES:
400 switch (type)
401 {
402 case GL_UNSIGNED_INT_24_8_OES:
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 default:
Geoff Langb1196682014-07-23 13:47:29 -0400410 context->recordError(Error(GL_INVALID_ENUM));
411 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400412 }
413
414 switch (format)
415 {
416 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
417 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400418 if (context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400419 {
Geoff Langb1196682014-07-23 13:47:29 -0400420 context->recordError(Error(GL_INVALID_OPERATION));
421 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400422 }
423 else
424 {
Geoff Langb1196682014-07-23 13:47:29 -0400425 context->recordError(Error(GL_INVALID_ENUM));
426 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400427 }
428 break;
429 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400430 if (context->getExtensions().textureCompressionDXT3)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400431 {
Geoff Langb1196682014-07-23 13:47:29 -0400432 context->recordError(Error(GL_INVALID_OPERATION));
433 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400434 }
435 else
436 {
Geoff Langb1196682014-07-23 13:47:29 -0400437 context->recordError(Error(GL_INVALID_ENUM));
438 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400439 }
440 break;
441 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400442 if (context->getExtensions().textureCompressionDXT5)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400443 {
Geoff Langb1196682014-07-23 13:47:29 -0400444 context->recordError(Error(GL_INVALID_OPERATION));
445 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400446 }
447 else
448 {
Geoff Langb1196682014-07-23 13:47:29 -0400449 context->recordError(Error(GL_INVALID_ENUM));
450 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400451 }
452 break;
453 case GL_DEPTH_COMPONENT:
454 case GL_DEPTH_STENCIL_OES:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400455 if (!context->getExtensions().depthTextures)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400456 {
Geoff Langb1196682014-07-23 13:47:29 -0400457 context->recordError(Error(GL_INVALID_VALUE));
458 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400459 }
460 if (target != GL_TEXTURE_2D)
461 {
Geoff Langb1196682014-07-23 13:47:29 -0400462 context->recordError(Error(GL_INVALID_OPERATION));
463 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400464 }
465 // OES_depth_texture supports loading depth data and multiple levels,
466 // but ANGLE_depth_texture does not
467 if (pixels != NULL || level != 0)
468 {
Geoff Langb1196682014-07-23 13:47:29 -0400469 context->recordError(Error(GL_INVALID_OPERATION));
470 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400471 }
472 break;
473 default:
474 break;
475 }
476
477 if (type == GL_FLOAT)
478 {
Geoff Langc0b9ef42014-07-02 10:02:37 -0400479 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400480 {
Geoff Langb1196682014-07-23 13:47:29 -0400481 context->recordError(Error(GL_INVALID_ENUM));
482 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400483 }
484 }
485 else if (type == GL_HALF_FLOAT_OES)
486 {
Geoff Langc0b9ef42014-07-02 10:02:37 -0400487 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400488 {
Geoff Langb1196682014-07-23 13:47:29 -0400489 context->recordError(Error(GL_INVALID_ENUM));
490 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400491 }
492 }
493 }
494
495 return true;
496}
497
498
499
Geoff Langb1196682014-07-23 13:47:29 -0400500bool ValidateES2CopyTexImageParameters(Context* context, GLenum target, GLint level, GLenum internalformat, bool isSubImage,
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400501 GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height,
502 GLint border)
503{
Jamie Madill560a8d82014-05-21 13:06:20 -0400504 GLenum textureInternalFormat = GL_NONE;
Shannon Woods4dfed832014-03-17 20:03:39 -0400505
Jamie Madill560a8d82014-05-21 13:06:20 -0400506 if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
507 xoffset, yoffset, 0, x, y, width, height, border, &textureInternalFormat))
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400508 {
Jamie Madill560a8d82014-05-21 13:06:20 -0400509 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400510 }
511
Shannon Woods53a94a82014-06-24 15:20:36 -0400512 gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer();
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400513 GLenum colorbufferFormat = framebuffer->getReadColorbuffer()->getInternalFormat();
Geoff Lang5d601382014-07-22 15:14:06 -0400514 GLenum textureFormat = gl::GetInternalFormatInfo(textureInternalFormat).format;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400515
516 // [OpenGL ES 2.0.24] table 3.9
517 if (isSubImage)
518 {
519 switch (textureFormat)
520 {
521 case GL_ALPHA:
522 if (colorbufferFormat != GL_ALPHA8_EXT &&
523 colorbufferFormat != GL_RGBA4 &&
524 colorbufferFormat != GL_RGB5_A1 &&
525 colorbufferFormat != GL_RGBA8_OES)
526 {
Geoff Langb1196682014-07-23 13:47:29 -0400527 context->recordError(Error(GL_INVALID_OPERATION));
528 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400529 }
530 break;
531 case GL_LUMINANCE:
Geoff Lang632192d2013-10-04 13:40:46 -0400532 if (colorbufferFormat != GL_R8_EXT &&
533 colorbufferFormat != GL_RG8_EXT &&
534 colorbufferFormat != GL_RGB565 &&
535 colorbufferFormat != GL_RGB8_OES &&
536 colorbufferFormat != GL_RGBA4 &&
537 colorbufferFormat != GL_RGB5_A1 &&
538 colorbufferFormat != GL_RGBA8_OES)
539 {
Geoff Langb1196682014-07-23 13:47:29 -0400540 context->recordError(Error(GL_INVALID_OPERATION));
541 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400542 }
543 break;
544 case GL_RED_EXT:
545 if (colorbufferFormat != GL_R8_EXT &&
546 colorbufferFormat != GL_RG8_EXT &&
547 colorbufferFormat != GL_RGB565 &&
548 colorbufferFormat != GL_RGB8_OES &&
549 colorbufferFormat != GL_RGBA4 &&
550 colorbufferFormat != GL_RGB5_A1 &&
551 colorbufferFormat != GL_RGBA8_OES)
552 {
Geoff Langb1196682014-07-23 13:47:29 -0400553 context->recordError(Error(GL_INVALID_OPERATION));
554 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400555 }
556 break;
557 case GL_RG_EXT:
558 if (colorbufferFormat != GL_RG8_EXT &&
559 colorbufferFormat != GL_RGB565 &&
560 colorbufferFormat != GL_RGB8_OES &&
561 colorbufferFormat != GL_RGBA4 &&
562 colorbufferFormat != GL_RGB5_A1 &&
563 colorbufferFormat != GL_RGBA8_OES)
564 {
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;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400569 case GL_RGB:
570 if (colorbufferFormat != GL_RGB565 &&
571 colorbufferFormat != GL_RGB8_OES &&
572 colorbufferFormat != GL_RGBA4 &&
573 colorbufferFormat != GL_RGB5_A1 &&
574 colorbufferFormat != GL_RGBA8_OES)
575 {
Geoff Langb1196682014-07-23 13:47:29 -0400576 context->recordError(Error(GL_INVALID_OPERATION));
577 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400578 }
579 break;
580 case GL_LUMINANCE_ALPHA:
581 case GL_RGBA:
582 if (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_COMPRESSED_RGB_S3TC_DXT1_EXT:
591 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
592 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
593 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
Geoff Langb1196682014-07-23 13:47:29 -0400594 context->recordError(Error(GL_INVALID_OPERATION));
595 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400596 case GL_DEPTH_COMPONENT:
597 case GL_DEPTH_STENCIL_OES:
Geoff Langb1196682014-07-23 13:47:29 -0400598 context->recordError(Error(GL_INVALID_OPERATION));
599 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400600 default:
Geoff Langb1196682014-07-23 13:47:29 -0400601 context->recordError(Error(GL_INVALID_OPERATION));
602 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400603 }
604 }
605 else
606 {
607 switch (internalformat)
608 {
609 case GL_ALPHA:
610 if (colorbufferFormat != GL_ALPHA8_EXT &&
611 colorbufferFormat != GL_RGBA4 &&
612 colorbufferFormat != GL_RGB5_A1 &&
613 colorbufferFormat != GL_BGRA8_EXT &&
Jamie Madill054369e2015-01-07 10:57:08 -0500614 colorbufferFormat != GL_RGBA8_OES &&
615 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400616 {
Geoff Langb1196682014-07-23 13:47:29 -0400617 context->recordError(Error(GL_INVALID_OPERATION));
618 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400619 }
620 break;
621 case GL_LUMINANCE:
Geoff Lang632192d2013-10-04 13:40:46 -0400622 if (colorbufferFormat != GL_R8_EXT &&
623 colorbufferFormat != GL_RG8_EXT &&
624 colorbufferFormat != GL_RGB565 &&
625 colorbufferFormat != GL_RGB8_OES &&
626 colorbufferFormat != GL_RGBA4 &&
627 colorbufferFormat != GL_RGB5_A1 &&
628 colorbufferFormat != GL_BGRA8_EXT &&
Jamie Madill054369e2015-01-07 10:57:08 -0500629 colorbufferFormat != GL_RGBA8_OES &&
630 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Geoff Lang632192d2013-10-04 13:40:46 -0400631 {
Geoff Langb1196682014-07-23 13:47:29 -0400632 context->recordError(Error(GL_INVALID_OPERATION));
633 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400634 }
635 break;
636 case GL_RED_EXT:
637 if (colorbufferFormat != GL_R8_EXT &&
638 colorbufferFormat != GL_RG8_EXT &&
639 colorbufferFormat != GL_RGB565 &&
640 colorbufferFormat != GL_RGB8_OES &&
641 colorbufferFormat != GL_RGBA4 &&
642 colorbufferFormat != GL_RGB5_A1 &&
643 colorbufferFormat != GL_BGRA8_EXT &&
Jamie Madill054369e2015-01-07 10:57:08 -0500644 colorbufferFormat != GL_RGBA8_OES &&
645 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Geoff Lang632192d2013-10-04 13:40:46 -0400646 {
Geoff Langb1196682014-07-23 13:47:29 -0400647 context->recordError(Error(GL_INVALID_OPERATION));
648 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400649 }
650 break;
651 case GL_RG_EXT:
652 if (colorbufferFormat != GL_RG8_EXT &&
653 colorbufferFormat != GL_RGB565 &&
654 colorbufferFormat != GL_RGB8_OES &&
655 colorbufferFormat != GL_RGBA4 &&
656 colorbufferFormat != GL_RGB5_A1 &&
657 colorbufferFormat != GL_BGRA8_EXT &&
Jamie Madill054369e2015-01-07 10:57:08 -0500658 colorbufferFormat != GL_RGBA8_OES &&
659 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Geoff Lang632192d2013-10-04 13:40:46 -0400660 {
Geoff Langb1196682014-07-23 13:47:29 -0400661 context->recordError(Error(GL_INVALID_OPERATION));
662 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400663 }
664 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400665 case GL_RGB:
666 if (colorbufferFormat != GL_RGB565 &&
667 colorbufferFormat != GL_RGB8_OES &&
668 colorbufferFormat != GL_RGBA4 &&
669 colorbufferFormat != GL_RGB5_A1 &&
670 colorbufferFormat != GL_BGRA8_EXT &&
Jamie Madill054369e2015-01-07 10:57:08 -0500671 colorbufferFormat != GL_RGBA8_OES &&
672 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400673 {
Geoff Langb1196682014-07-23 13:47:29 -0400674 context->recordError(Error(GL_INVALID_OPERATION));
675 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400676 }
677 break;
678 case GL_LUMINANCE_ALPHA:
679 case GL_RGBA:
680 if (colorbufferFormat != GL_RGBA4 &&
681 colorbufferFormat != GL_RGB5_A1 &&
682 colorbufferFormat != GL_BGRA8_EXT &&
Jamie Madill054369e2015-01-07 10:57:08 -0500683 colorbufferFormat != GL_RGBA8_OES &&
684 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400685 {
Geoff Langb1196682014-07-23 13:47:29 -0400686 context->recordError(Error(GL_INVALID_OPERATION));
687 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400688 }
689 break;
690 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
691 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400692 if (context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400693 {
Geoff Langb1196682014-07-23 13:47:29 -0400694 context->recordError(Error(GL_INVALID_OPERATION));
695 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400696 }
697 else
698 {
Geoff Langb1196682014-07-23 13:47:29 -0400699 context->recordError(Error(GL_INVALID_ENUM));
700 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400701 }
702 break;
703 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400704 if (context->getExtensions().textureCompressionDXT3)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400705 {
Geoff Langb1196682014-07-23 13:47:29 -0400706 context->recordError(Error(GL_INVALID_OPERATION));
707 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400708 }
709 else
710 {
Geoff Langb1196682014-07-23 13:47:29 -0400711 context->recordError(Error(GL_INVALID_ENUM));
712 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400713 }
714 break;
715 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400716 if (context->getExtensions().textureCompressionDXT5)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400717 {
Geoff Langb1196682014-07-23 13:47:29 -0400718 context->recordError(Error(GL_INVALID_OPERATION));
719 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400720 }
721 else
722 {
Geoff Langb1196682014-07-23 13:47:29 -0400723 context->recordError(Error(GL_INVALID_ENUM));
724 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400725 }
726 break;
727 case GL_DEPTH_COMPONENT:
728 case GL_DEPTH_COMPONENT16:
729 case GL_DEPTH_COMPONENT32_OES:
730 case GL_DEPTH_STENCIL_OES:
731 case GL_DEPTH24_STENCIL8_OES:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400732 if (context->getExtensions().depthTextures)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400733 {
Geoff Langb1196682014-07-23 13:47:29 -0400734 context->recordError(Error(GL_INVALID_OPERATION));
735 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400736 }
737 else
738 {
Geoff Langb1196682014-07-23 13:47:29 -0400739 context->recordError(Error(GL_INVALID_ENUM));
740 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400741 }
742 default:
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 }
747
Geoff Lang784a8fd2013-09-24 12:33:16 -0400748 // If width or height is zero, it is a no-op. Return false without setting an error.
749 return (width > 0 && height > 0);
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400750}
751
Geoff Langb1196682014-07-23 13:47:29 -0400752bool ValidateES2TexStorageParameters(Context *context, GLenum target, GLsizei levels, GLenum internalformat,
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400753 GLsizei width, GLsizei height)
754{
755 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP)
756 {
Geoff Langb1196682014-07-23 13:47:29 -0400757 context->recordError(Error(GL_INVALID_ENUM));
758 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400759 }
760
761 if (width < 1 || height < 1 || levels < 1)
762 {
Geoff Langb1196682014-07-23 13:47:29 -0400763 context->recordError(Error(GL_INVALID_VALUE));
764 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400765 }
766
767 if (target == GL_TEXTURE_CUBE_MAP && width != height)
768 {
Geoff Langb1196682014-07-23 13:47:29 -0400769 context->recordError(Error(GL_INVALID_VALUE));
770 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400771 }
772
773 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
774 {
Geoff Langb1196682014-07-23 13:47:29 -0400775 context->recordError(Error(GL_INVALID_OPERATION));
776 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400777 }
778
Geoff Lang5d601382014-07-22 15:14:06 -0400779 const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
780 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400781 {
Geoff Langb1196682014-07-23 13:47:29 -0400782 context->recordError(Error(GL_INVALID_ENUM));
783 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400784 }
785
Geoff Langaae65a42014-05-26 12:43:44 -0400786 const gl::Caps &caps = context->getCaps();
787
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400788 switch (target)
789 {
790 case GL_TEXTURE_2D:
Geoff Langaae65a42014-05-26 12:43:44 -0400791 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
792 static_cast<GLuint>(height) > caps.max2DTextureSize)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400793 {
Geoff Langb1196682014-07-23 13:47:29 -0400794 context->recordError(Error(GL_INVALID_VALUE));
795 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400796 }
797 break;
798 case GL_TEXTURE_CUBE_MAP:
Geoff Langaae65a42014-05-26 12:43:44 -0400799 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
800 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400801 {
Geoff Langb1196682014-07-23 13:47:29 -0400802 context->recordError(Error(GL_INVALID_VALUE));
803 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400804 }
805 break;
806 default:
Geoff Langb1196682014-07-23 13:47:29 -0400807 context->recordError(Error(GL_INVALID_ENUM));
808 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400809 }
810
Geoff Langc0b9ef42014-07-02 10:02:37 -0400811 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400812 {
813 if (!gl::isPow2(width) || !gl::isPow2(height))
814 {
Geoff Langb1196682014-07-23 13:47:29 -0400815 context->recordError(Error(GL_INVALID_OPERATION));
816 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400817 }
818 }
819
820 switch (internalformat)
821 {
822 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
823 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400824 if (!context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400825 {
Geoff Langb1196682014-07-23 13:47:29 -0400826 context->recordError(Error(GL_INVALID_ENUM));
827 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400828 }
829 break;
830 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400831 if (!context->getExtensions().textureCompressionDXT3)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400832 {
Geoff Langb1196682014-07-23 13:47:29 -0400833 context->recordError(Error(GL_INVALID_ENUM));
834 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400835 }
836 break;
837 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400838 if (!context->getExtensions().textureCompressionDXT5)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400839 {
Geoff Langb1196682014-07-23 13:47:29 -0400840 context->recordError(Error(GL_INVALID_ENUM));
841 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400842 }
843 break;
844 case GL_RGBA32F_EXT:
845 case GL_RGB32F_EXT:
846 case GL_ALPHA32F_EXT:
847 case GL_LUMINANCE32F_EXT:
848 case GL_LUMINANCE_ALPHA32F_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400849 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400850 {
Geoff Langb1196682014-07-23 13:47:29 -0400851 context->recordError(Error(GL_INVALID_ENUM));
852 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400853 }
854 break;
855 case GL_RGBA16F_EXT:
856 case GL_RGB16F_EXT:
857 case GL_ALPHA16F_EXT:
858 case GL_LUMINANCE16F_EXT:
859 case GL_LUMINANCE_ALPHA16F_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400860 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400861 {
Geoff Langb1196682014-07-23 13:47:29 -0400862 context->recordError(Error(GL_INVALID_ENUM));
863 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400864 }
865 break;
Geoff Lang632192d2013-10-04 13:40:46 -0400866 case GL_R8_EXT:
867 case GL_RG8_EXT:
868 case GL_R16F_EXT:
869 case GL_RG16F_EXT:
870 case GL_R32F_EXT:
871 case GL_RG32F_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400872 if (!context->getExtensions().textureRG)
Geoff Lang632192d2013-10-04 13:40:46 -0400873 {
Geoff Langb1196682014-07-23 13:47:29 -0400874 context->recordError(Error(GL_INVALID_ENUM));
875 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400876 }
877 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400878 case GL_DEPTH_COMPONENT16:
879 case GL_DEPTH_COMPONENT32_OES:
880 case GL_DEPTH24_STENCIL8_OES:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400881 if (!context->getExtensions().depthTextures)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400882 {
Geoff Langb1196682014-07-23 13:47:29 -0400883 context->recordError(Error(GL_INVALID_ENUM));
884 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400885 }
886 if (target != GL_TEXTURE_2D)
887 {
Geoff Langb1196682014-07-23 13:47:29 -0400888 context->recordError(Error(GL_INVALID_OPERATION));
889 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400890 }
891 // ANGLE_depth_texture only supports 1-level textures
892 if (levels != 1)
893 {
Geoff Langb1196682014-07-23 13:47:29 -0400894 context->recordError(Error(GL_INVALID_OPERATION));
895 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400896 }
897 break;
898 default:
899 break;
900 }
901
902 gl::Texture *texture = NULL;
903 switch(target)
904 {
905 case GL_TEXTURE_2D:
906 texture = context->getTexture2D();
907 break;
908 case GL_TEXTURE_CUBE_MAP:
909 texture = context->getTextureCubeMap();
910 break;
911 default:
912 UNREACHABLE();
913 }
914
915 if (!texture || texture->id() == 0)
916 {
Geoff Langb1196682014-07-23 13:47:29 -0400917 context->recordError(Error(GL_INVALID_OPERATION));
918 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400919 }
920
921 if (texture->isImmutable())
922 {
Geoff Langb1196682014-07-23 13:47:29 -0400923 context->recordError(Error(GL_INVALID_OPERATION));
924 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400925 }
926
927 return true;
928}
929
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400930// check for combinations of format and type that are valid for ReadPixels
Geoff Langb1196682014-07-23 13:47:29 -0400931bool ValidES2ReadFormatType(Context *context, GLenum format, GLenum type)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400932{
933 switch (format)
934 {
935 case GL_RGBA:
936 switch (type)
937 {
938 case GL_UNSIGNED_BYTE:
939 break;
940 default:
941 return false;
942 }
943 break;
944 case GL_BGRA_EXT:
945 switch (type)
946 {
947 case GL_UNSIGNED_BYTE:
948 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
949 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
950 break;
951 default:
952 return false;
953 }
954 break;
Geoff Langbdc9b2f2014-04-16 14:41:54 -0400955 case GL_RG_EXT:
956 case GL_RED_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400957 if (!context->getExtensions().textureRG)
Geoff Langbdc9b2f2014-04-16 14:41:54 -0400958 {
959 return false;
960 }
961 switch (type)
962 {
963 case GL_UNSIGNED_BYTE:
964 break;
965 default:
966 return false;
967 }
968 break;
969
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400970 default:
971 return false;
972 }
973 return true;
974}
975
976}