blob: 63a23c5b64a960031bab9f581925fc5dfcc0494c [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 &&
614 colorbufferFormat != GL_RGBA8_OES)
615 {
Geoff Langb1196682014-07-23 13:47:29 -0400616 context->recordError(Error(GL_INVALID_OPERATION));
617 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400618 }
619 break;
620 case GL_LUMINANCE:
Geoff Lang632192d2013-10-04 13:40:46 -0400621 if (colorbufferFormat != GL_R8_EXT &&
622 colorbufferFormat != GL_RG8_EXT &&
623 colorbufferFormat != GL_RGB565 &&
624 colorbufferFormat != GL_RGB8_OES &&
625 colorbufferFormat != GL_RGBA4 &&
626 colorbufferFormat != GL_RGB5_A1 &&
627 colorbufferFormat != GL_BGRA8_EXT &&
628 colorbufferFormat != GL_RGBA8_OES)
629 {
Geoff Langb1196682014-07-23 13:47:29 -0400630 context->recordError(Error(GL_INVALID_OPERATION));
631 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400632 }
633 break;
634 case GL_RED_EXT:
635 if (colorbufferFormat != GL_R8_EXT &&
636 colorbufferFormat != GL_RG8_EXT &&
637 colorbufferFormat != GL_RGB565 &&
638 colorbufferFormat != GL_RGB8_OES &&
639 colorbufferFormat != GL_RGBA4 &&
640 colorbufferFormat != GL_RGB5_A1 &&
641 colorbufferFormat != GL_BGRA8_EXT &&
642 colorbufferFormat != GL_RGBA8_OES)
643 {
Geoff Langb1196682014-07-23 13:47:29 -0400644 context->recordError(Error(GL_INVALID_OPERATION));
645 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400646 }
647 break;
648 case GL_RG_EXT:
649 if (colorbufferFormat != GL_RG8_EXT &&
650 colorbufferFormat != GL_RGB565 &&
651 colorbufferFormat != GL_RGB8_OES &&
652 colorbufferFormat != GL_RGBA4 &&
653 colorbufferFormat != GL_RGB5_A1 &&
654 colorbufferFormat != GL_BGRA8_EXT &&
655 colorbufferFormat != GL_RGBA8_OES)
656 {
Geoff Langb1196682014-07-23 13:47:29 -0400657 context->recordError(Error(GL_INVALID_OPERATION));
658 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400659 }
660 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400661 case GL_RGB:
662 if (colorbufferFormat != GL_RGB565 &&
663 colorbufferFormat != GL_RGB8_OES &&
664 colorbufferFormat != GL_RGBA4 &&
665 colorbufferFormat != GL_RGB5_A1 &&
666 colorbufferFormat != GL_BGRA8_EXT &&
667 colorbufferFormat != GL_RGBA8_OES)
668 {
Geoff Langb1196682014-07-23 13:47:29 -0400669 context->recordError(Error(GL_INVALID_OPERATION));
670 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400671 }
672 break;
673 case GL_LUMINANCE_ALPHA:
674 case GL_RGBA:
675 if (colorbufferFormat != GL_RGBA4 &&
676 colorbufferFormat != GL_RGB5_A1 &&
677 colorbufferFormat != GL_BGRA8_EXT &&
678 colorbufferFormat != GL_RGBA8_OES)
679 {
Geoff Langb1196682014-07-23 13:47:29 -0400680 context->recordError(Error(GL_INVALID_OPERATION));
681 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400682 }
683 break;
684 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
685 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400686 if (context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400687 {
Geoff Langb1196682014-07-23 13:47:29 -0400688 context->recordError(Error(GL_INVALID_OPERATION));
689 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400690 }
691 else
692 {
Geoff Langb1196682014-07-23 13:47:29 -0400693 context->recordError(Error(GL_INVALID_ENUM));
694 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400695 }
696 break;
697 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400698 if (context->getExtensions().textureCompressionDXT3)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400699 {
Geoff Langb1196682014-07-23 13:47:29 -0400700 context->recordError(Error(GL_INVALID_OPERATION));
701 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400702 }
703 else
704 {
Geoff Langb1196682014-07-23 13:47:29 -0400705 context->recordError(Error(GL_INVALID_ENUM));
706 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400707 }
708 break;
709 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400710 if (context->getExtensions().textureCompressionDXT5)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400711 {
Geoff Langb1196682014-07-23 13:47:29 -0400712 context->recordError(Error(GL_INVALID_OPERATION));
713 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400714 }
715 else
716 {
Geoff Langb1196682014-07-23 13:47:29 -0400717 context->recordError(Error(GL_INVALID_ENUM));
718 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400719 }
720 break;
721 case GL_DEPTH_COMPONENT:
722 case GL_DEPTH_COMPONENT16:
723 case GL_DEPTH_COMPONENT32_OES:
724 case GL_DEPTH_STENCIL_OES:
725 case GL_DEPTH24_STENCIL8_OES:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400726 if (context->getExtensions().depthTextures)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400727 {
Geoff Langb1196682014-07-23 13:47:29 -0400728 context->recordError(Error(GL_INVALID_OPERATION));
729 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400730 }
731 else
732 {
Geoff Langb1196682014-07-23 13:47:29 -0400733 context->recordError(Error(GL_INVALID_ENUM));
734 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400735 }
736 default:
Geoff Langb1196682014-07-23 13:47:29 -0400737 context->recordError(Error(GL_INVALID_ENUM));
738 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400739 }
740 }
741
Geoff Lang784a8fd2013-09-24 12:33:16 -0400742 // If width or height is zero, it is a no-op. Return false without setting an error.
743 return (width > 0 && height > 0);
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400744}
745
Geoff Langb1196682014-07-23 13:47:29 -0400746bool ValidateES2TexStorageParameters(Context *context, GLenum target, GLsizei levels, GLenum internalformat,
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400747 GLsizei width, GLsizei height)
748{
749 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP)
750 {
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
755 if (width < 1 || height < 1 || levels < 1)
756 {
Geoff Langb1196682014-07-23 13:47:29 -0400757 context->recordError(Error(GL_INVALID_VALUE));
758 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400759 }
760
761 if (target == GL_TEXTURE_CUBE_MAP && width != height)
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 (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
768 {
Geoff Langb1196682014-07-23 13:47:29 -0400769 context->recordError(Error(GL_INVALID_OPERATION));
770 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400771 }
772
Geoff Lang5d601382014-07-22 15:14:06 -0400773 const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
774 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400775 {
Geoff Langb1196682014-07-23 13:47:29 -0400776 context->recordError(Error(GL_INVALID_ENUM));
777 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400778 }
779
Geoff Langaae65a42014-05-26 12:43:44 -0400780 const gl::Caps &caps = context->getCaps();
781
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400782 switch (target)
783 {
784 case GL_TEXTURE_2D:
Geoff Langaae65a42014-05-26 12:43:44 -0400785 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
786 static_cast<GLuint>(height) > caps.max2DTextureSize)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400787 {
Geoff Langb1196682014-07-23 13:47:29 -0400788 context->recordError(Error(GL_INVALID_VALUE));
789 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400790 }
791 break;
792 case GL_TEXTURE_CUBE_MAP:
Geoff Langaae65a42014-05-26 12:43:44 -0400793 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
794 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400795 {
Geoff Langb1196682014-07-23 13:47:29 -0400796 context->recordError(Error(GL_INVALID_VALUE));
797 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400798 }
799 break;
800 default:
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
Geoff Langc0b9ef42014-07-02 10:02:37 -0400805 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400806 {
807 if (!gl::isPow2(width) || !gl::isPow2(height))
808 {
Geoff Langb1196682014-07-23 13:47:29 -0400809 context->recordError(Error(GL_INVALID_OPERATION));
810 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400811 }
812 }
813
814 switch (internalformat)
815 {
816 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
817 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400818 if (!context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400819 {
Geoff Langb1196682014-07-23 13:47:29 -0400820 context->recordError(Error(GL_INVALID_ENUM));
821 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400822 }
823 break;
824 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400825 if (!context->getExtensions().textureCompressionDXT3)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400826 {
Geoff Langb1196682014-07-23 13:47:29 -0400827 context->recordError(Error(GL_INVALID_ENUM));
828 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400829 }
830 break;
831 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400832 if (!context->getExtensions().textureCompressionDXT5)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400833 {
Geoff Langb1196682014-07-23 13:47:29 -0400834 context->recordError(Error(GL_INVALID_ENUM));
835 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400836 }
837 break;
838 case GL_RGBA32F_EXT:
839 case GL_RGB32F_EXT:
840 case GL_ALPHA32F_EXT:
841 case GL_LUMINANCE32F_EXT:
842 case GL_LUMINANCE_ALPHA32F_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400843 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400844 {
Geoff Langb1196682014-07-23 13:47:29 -0400845 context->recordError(Error(GL_INVALID_ENUM));
846 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400847 }
848 break;
849 case GL_RGBA16F_EXT:
850 case GL_RGB16F_EXT:
851 case GL_ALPHA16F_EXT:
852 case GL_LUMINANCE16F_EXT:
853 case GL_LUMINANCE_ALPHA16F_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400854 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400855 {
Geoff Langb1196682014-07-23 13:47:29 -0400856 context->recordError(Error(GL_INVALID_ENUM));
857 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400858 }
859 break;
Geoff Lang632192d2013-10-04 13:40:46 -0400860 case GL_R8_EXT:
861 case GL_RG8_EXT:
862 case GL_R16F_EXT:
863 case GL_RG16F_EXT:
864 case GL_R32F_EXT:
865 case GL_RG32F_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400866 if (!context->getExtensions().textureRG)
Geoff Lang632192d2013-10-04 13:40:46 -0400867 {
Geoff Langb1196682014-07-23 13:47:29 -0400868 context->recordError(Error(GL_INVALID_ENUM));
869 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400870 }
871 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400872 case GL_DEPTH_COMPONENT16:
873 case GL_DEPTH_COMPONENT32_OES:
874 case GL_DEPTH24_STENCIL8_OES:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400875 if (!context->getExtensions().depthTextures)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400876 {
Geoff Langb1196682014-07-23 13:47:29 -0400877 context->recordError(Error(GL_INVALID_ENUM));
878 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400879 }
880 if (target != GL_TEXTURE_2D)
881 {
Geoff Langb1196682014-07-23 13:47:29 -0400882 context->recordError(Error(GL_INVALID_OPERATION));
883 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400884 }
885 // ANGLE_depth_texture only supports 1-level textures
886 if (levels != 1)
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 break;
892 default:
893 break;
894 }
895
896 gl::Texture *texture = NULL;
897 switch(target)
898 {
899 case GL_TEXTURE_2D:
900 texture = context->getTexture2D();
901 break;
902 case GL_TEXTURE_CUBE_MAP:
903 texture = context->getTextureCubeMap();
904 break;
905 default:
906 UNREACHABLE();
907 }
908
909 if (!texture || texture->id() == 0)
910 {
Geoff Langb1196682014-07-23 13:47:29 -0400911 context->recordError(Error(GL_INVALID_OPERATION));
912 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400913 }
914
915 if (texture->isImmutable())
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 return true;
922}
923
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400924// check for combinations of format and type that are valid for ReadPixels
Geoff Langb1196682014-07-23 13:47:29 -0400925bool ValidES2ReadFormatType(Context *context, GLenum format, GLenum type)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400926{
927 switch (format)
928 {
929 case GL_RGBA:
930 switch (type)
931 {
932 case GL_UNSIGNED_BYTE:
933 break;
934 default:
935 return false;
936 }
937 break;
938 case GL_BGRA_EXT:
939 switch (type)
940 {
941 case GL_UNSIGNED_BYTE:
942 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
943 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
944 break;
945 default:
946 return false;
947 }
948 break;
Geoff Langbdc9b2f2014-04-16 14:41:54 -0400949 case GL_RG_EXT:
950 case GL_RED_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400951 if (!context->getExtensions().textureRG)
Geoff Langbdc9b2f2014-04-16 14:41:54 -0400952 {
953 return false;
954 }
955 switch (type)
956 {
957 case GL_UNSIGNED_BYTE:
958 break;
959 default:
960 return false;
961 }
962 break;
963
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400964 default:
965 return false;
966 }
967 return true;
968}
969
970}