blob: 138eb9f62562d38b040d897ad2d998e1bb477d21 [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;
147 bool textureCompressed = false;
148 GLenum textureInternalFormat = GL_NONE;
149 GLint textureLevelWidth = 0;
150 GLint textureLevelHeight = 0;
151 switch (target)
152 {
153 case GL_TEXTURE_2D:
154 {
Geoff Langaae65a42014-05-26 12:43:44 -0400155 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
156 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400157 {
Geoff Langb1196682014-07-23 13:47:29 -0400158 context->recordError(Error(GL_INVALID_VALUE));
159 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400160 }
161
162 gl::Texture2D *tex2d = context->getTexture2D();
163 if (tex2d)
164 {
165 textureCompressed = tex2d->isCompressed(level);
166 textureInternalFormat = tex2d->getInternalFormat(level);
167 textureLevelWidth = tex2d->getWidth(level);
168 textureLevelHeight = tex2d->getHeight(level);
169 texture = tex2d;
170 }
171
Geoff Langb1196682014-07-23 13:47:29 -0400172 if (isSubImage && !ValidateSubImageParams2D(context, isCompressed, width, height, xoffset, yoffset,
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400173 level, format, type, tex2d))
174 {
175 return false;
176 }
177
178 texture = tex2d;
179 }
180 break;
181
182 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
183 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
184 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
185 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
186 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
187 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
188 {
189 if (!isSubImage && width != height)
190 {
Geoff Langb1196682014-07-23 13:47:29 -0400191 context->recordError(Error(GL_INVALID_VALUE));
192 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400193 }
194
Geoff Langaae65a42014-05-26 12:43:44 -0400195 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
196 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400197 {
Geoff Langb1196682014-07-23 13:47:29 -0400198 context->recordError(Error(GL_INVALID_VALUE));
199 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400200 }
201
202 gl::TextureCubeMap *texCube = context->getTextureCubeMap();
203 if (texCube)
204 {
205 textureCompressed = texCube->isCompressed(target, level);
206 textureInternalFormat = texCube->getInternalFormat(target, level);
207 textureLevelWidth = texCube->getWidth(target, level);
208 textureLevelHeight = texCube->getHeight(target, level);
209 texture = texCube;
210 }
211
Geoff Langb1196682014-07-23 13:47:29 -0400212 if (isSubImage && !ValidateSubImageParamsCube(context, isCompressed, width, height, xoffset, yoffset,
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400213 target, level, format, type, texCube))
214 {
215 return false;
216 }
217 }
218 break;
219
220 default:
Geoff Langb1196682014-07-23 13:47:29 -0400221 context->recordError(Error(GL_INVALID_ENUM));
222 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400223 }
224
225 if (!texture)
226 {
Geoff Langb1196682014-07-23 13:47:29 -0400227 context->recordError(Error(GL_INVALID_OPERATION));
228 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400229 }
230
231 if (!isSubImage && texture->isImmutable())
232 {
Geoff Langb1196682014-07-23 13:47:29 -0400233 context->recordError(Error(GL_INVALID_OPERATION));
234 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400235 }
236
237 // Verify zero border
238 if (border != 0)
239 {
Geoff Langb1196682014-07-23 13:47:29 -0400240 context->recordError(Error(GL_INVALID_VALUE));
241 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400242 }
243
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400244 GLenum actualInternalFormat = isSubImage ? textureInternalFormat : internalformat;
245 if (isCompressed)
246 {
Geoff Langd4f180b2013-09-24 13:57:44 -0400247 if (!ValidCompressedImageSize(context, actualInternalFormat, width, height))
248 {
Geoff Langb1196682014-07-23 13:47:29 -0400249 context->recordError(Error(GL_INVALID_OPERATION));
250 return false;
Geoff Langd4f180b2013-09-24 13:57:44 -0400251 }
252
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400253 switch (actualInternalFormat)
254 {
255 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
256 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400257 if (!context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400258 {
Geoff Langb1196682014-07-23 13:47:29 -0400259 context->recordError(Error(GL_INVALID_ENUM));
260 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400261 }
262 break;
263 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400264 if (!context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400265 {
Geoff Langb1196682014-07-23 13:47:29 -0400266 context->recordError(Error(GL_INVALID_ENUM));
267 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400268 }
269 break;
270 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
Geoff Langb1196682014-07-23 13:47:29 -0400271 if (!context->getExtensions().textureCompressionDXT5)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400272 {
Geoff Langb1196682014-07-23 13:47:29 -0400273 context->recordError(Error(GL_INVALID_ENUM));
274 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400275 }
276 break;
277 default:
Geoff Langb1196682014-07-23 13:47:29 -0400278 context->recordError(Error(GL_INVALID_ENUM));
279 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400280 }
281 }
282 else
283 {
284 // validate <type> by itself (used as secondary key below)
285 switch (type)
286 {
287 case GL_UNSIGNED_BYTE:
288 case GL_UNSIGNED_SHORT_5_6_5:
289 case GL_UNSIGNED_SHORT_4_4_4_4:
290 case GL_UNSIGNED_SHORT_5_5_5_1:
291 case GL_UNSIGNED_SHORT:
292 case GL_UNSIGNED_INT:
293 case GL_UNSIGNED_INT_24_8_OES:
294 case GL_HALF_FLOAT_OES:
295 case GL_FLOAT:
296 break;
297 default:
Geoff Langb1196682014-07-23 13:47:29 -0400298 context->recordError(Error(GL_INVALID_ENUM));
299 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400300 }
301
302 // validate <format> + <type> combinations
303 // - invalid <format> -> sets INVALID_ENUM
304 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
305 switch (format)
306 {
307 case GL_ALPHA:
308 case GL_LUMINANCE:
309 case GL_LUMINANCE_ALPHA:
310 switch (type)
311 {
312 case GL_UNSIGNED_BYTE:
313 case GL_FLOAT:
314 case GL_HALF_FLOAT_OES:
315 break;
Geoff Langb1196682014-07-23 13:47:29 -0400316 default:
317 context->recordError(Error(GL_INVALID_OPERATION));
318 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400319 }
320 break;
Geoff Lang632192d2013-10-04 13:40:46 -0400321 case GL_RED:
Geoff Langcec35902014-04-16 10:52:36 -0400322 case GL_RG:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400323 if (!context->getExtensions().textureRG)
Geoff Lang632192d2013-10-04 13:40:46 -0400324 {
Geoff Langb1196682014-07-23 13:47:29 -0400325 context->recordError(Error(GL_INVALID_ENUM));
326 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400327 }
328 switch (type)
329 {
330 case GL_UNSIGNED_BYTE:
331 case GL_FLOAT:
332 case GL_HALF_FLOAT_OES:
333 break;
334 default:
Geoff Langb1196682014-07-23 13:47:29 -0400335 context->recordError(Error(GL_INVALID_OPERATION));
336 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400337 }
338 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400339 case GL_RGB:
340 switch (type)
341 {
342 case GL_UNSIGNED_BYTE:
343 case GL_UNSIGNED_SHORT_5_6_5:
344 case GL_FLOAT:
345 case GL_HALF_FLOAT_OES:
346 break;
347 default:
Geoff Langb1196682014-07-23 13:47:29 -0400348 context->recordError(Error(GL_INVALID_OPERATION));
349 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400350 }
351 break;
352 case GL_RGBA:
353 switch (type)
354 {
355 case GL_UNSIGNED_BYTE:
356 case GL_UNSIGNED_SHORT_4_4_4_4:
357 case GL_UNSIGNED_SHORT_5_5_5_1:
358 case GL_FLOAT:
359 case GL_HALF_FLOAT_OES:
360 break;
361 default:
Geoff Langb1196682014-07-23 13:47:29 -0400362 context->recordError(Error(GL_INVALID_OPERATION));
363 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400364 }
365 break;
366 case GL_BGRA_EXT:
367 switch (type)
368 {
369 case GL_UNSIGNED_BYTE:
370 break;
371 default:
Geoff Langb1196682014-07-23 13:47:29 -0400372 context->recordError(Error(GL_INVALID_OPERATION));
373 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400374 }
375 break;
Geoff Lang05b05022014-06-11 15:31:45 -0400376 case GL_SRGB_EXT:
377 case GL_SRGB_ALPHA_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400378 if (!context->getExtensions().sRGB)
Geoff Lang05b05022014-06-11 15:31:45 -0400379 {
Geoff Langb1196682014-07-23 13:47:29 -0400380 context->recordError(Error(GL_INVALID_ENUM));
381 return false;
Geoff Lang05b05022014-06-11 15:31:45 -0400382 }
383 switch (type)
384 {
385 case GL_UNSIGNED_BYTE:
386 break;
387 default:
Geoff Langb1196682014-07-23 13:47:29 -0400388 context->recordError(Error(GL_INVALID_OPERATION));
389 return false;
Geoff Lang05b05022014-06-11 15:31:45 -0400390 }
391 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400392 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
393 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
394 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
395 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
396 break;
397 case GL_DEPTH_COMPONENT:
398 switch (type)
399 {
400 case GL_UNSIGNED_SHORT:
401 case GL_UNSIGNED_INT:
402 break;
403 default:
Geoff Langb1196682014-07-23 13:47:29 -0400404 context->recordError(Error(GL_INVALID_OPERATION));
405 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400406 }
407 break;
408 case GL_DEPTH_STENCIL_OES:
409 switch (type)
410 {
411 case GL_UNSIGNED_INT_24_8_OES:
412 break;
413 default:
Geoff Langb1196682014-07-23 13:47:29 -0400414 context->recordError(Error(GL_INVALID_OPERATION));
415 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400416 }
417 break;
418 default:
Geoff Langb1196682014-07-23 13:47:29 -0400419 context->recordError(Error(GL_INVALID_ENUM));
420 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400421 }
422
423 switch (format)
424 {
425 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
426 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400427 if (context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400428 {
Geoff Langb1196682014-07-23 13:47:29 -0400429 context->recordError(Error(GL_INVALID_OPERATION));
430 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400431 }
432 else
433 {
Geoff Langb1196682014-07-23 13:47:29 -0400434 context->recordError(Error(GL_INVALID_ENUM));
435 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400436 }
437 break;
438 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400439 if (context->getExtensions().textureCompressionDXT3)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400440 {
Geoff Langb1196682014-07-23 13:47:29 -0400441 context->recordError(Error(GL_INVALID_OPERATION));
442 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400443 }
444 else
445 {
Geoff Langb1196682014-07-23 13:47:29 -0400446 context->recordError(Error(GL_INVALID_ENUM));
447 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400448 }
449 break;
450 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400451 if (context->getExtensions().textureCompressionDXT5)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400452 {
Geoff Langb1196682014-07-23 13:47:29 -0400453 context->recordError(Error(GL_INVALID_OPERATION));
454 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400455 }
456 else
457 {
Geoff Langb1196682014-07-23 13:47:29 -0400458 context->recordError(Error(GL_INVALID_ENUM));
459 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400460 }
461 break;
462 case GL_DEPTH_COMPONENT:
463 case GL_DEPTH_STENCIL_OES:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400464 if (!context->getExtensions().depthTextures)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400465 {
Geoff Langb1196682014-07-23 13:47:29 -0400466 context->recordError(Error(GL_INVALID_VALUE));
467 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400468 }
469 if (target != GL_TEXTURE_2D)
470 {
Geoff Langb1196682014-07-23 13:47:29 -0400471 context->recordError(Error(GL_INVALID_OPERATION));
472 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400473 }
474 // OES_depth_texture supports loading depth data and multiple levels,
475 // but ANGLE_depth_texture does not
476 if (pixels != NULL || level != 0)
477 {
Geoff Langb1196682014-07-23 13:47:29 -0400478 context->recordError(Error(GL_INVALID_OPERATION));
479 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400480 }
481 break;
482 default:
483 break;
484 }
485
486 if (type == GL_FLOAT)
487 {
Geoff Langc0b9ef42014-07-02 10:02:37 -0400488 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400489 {
Geoff Langb1196682014-07-23 13:47:29 -0400490 context->recordError(Error(GL_INVALID_ENUM));
491 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400492 }
493 }
494 else if (type == GL_HALF_FLOAT_OES)
495 {
Geoff Langc0b9ef42014-07-02 10:02:37 -0400496 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400497 {
Geoff Langb1196682014-07-23 13:47:29 -0400498 context->recordError(Error(GL_INVALID_ENUM));
499 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400500 }
501 }
502 }
503
504 return true;
505}
506
507
508
Geoff Langb1196682014-07-23 13:47:29 -0400509bool ValidateES2CopyTexImageParameters(Context* context, GLenum target, GLint level, GLenum internalformat, bool isSubImage,
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400510 GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height,
511 GLint border)
512{
Jamie Madill560a8d82014-05-21 13:06:20 -0400513 GLenum textureInternalFormat = GL_NONE;
Shannon Woods4dfed832014-03-17 20:03:39 -0400514
Jamie Madill560a8d82014-05-21 13:06:20 -0400515 if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
516 xoffset, yoffset, 0, x, y, width, height, border, &textureInternalFormat))
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400517 {
Jamie Madill560a8d82014-05-21 13:06:20 -0400518 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400519 }
520
Shannon Woods53a94a82014-06-24 15:20:36 -0400521 gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer();
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400522 GLenum colorbufferFormat = framebuffer->getReadColorbuffer()->getInternalFormat();
Geoff Lang5d601382014-07-22 15:14:06 -0400523 GLenum textureFormat = gl::GetInternalFormatInfo(textureInternalFormat).format;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400524
525 // [OpenGL ES 2.0.24] table 3.9
526 if (isSubImage)
527 {
528 switch (textureFormat)
529 {
530 case GL_ALPHA:
531 if (colorbufferFormat != GL_ALPHA8_EXT &&
532 colorbufferFormat != GL_RGBA4 &&
533 colorbufferFormat != GL_RGB5_A1 &&
534 colorbufferFormat != GL_RGBA8_OES)
535 {
Geoff Langb1196682014-07-23 13:47:29 -0400536 context->recordError(Error(GL_INVALID_OPERATION));
537 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400538 }
539 break;
540 case GL_LUMINANCE:
Geoff Lang632192d2013-10-04 13:40:46 -0400541 if (colorbufferFormat != GL_R8_EXT &&
542 colorbufferFormat != GL_RG8_EXT &&
543 colorbufferFormat != GL_RGB565 &&
544 colorbufferFormat != GL_RGB8_OES &&
545 colorbufferFormat != GL_RGBA4 &&
546 colorbufferFormat != GL_RGB5_A1 &&
547 colorbufferFormat != GL_RGBA8_OES)
548 {
Geoff Langb1196682014-07-23 13:47:29 -0400549 context->recordError(Error(GL_INVALID_OPERATION));
550 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400551 }
552 break;
553 case GL_RED_EXT:
554 if (colorbufferFormat != GL_R8_EXT &&
555 colorbufferFormat != GL_RG8_EXT &&
556 colorbufferFormat != GL_RGB565 &&
557 colorbufferFormat != GL_RGB8_OES &&
558 colorbufferFormat != GL_RGBA4 &&
559 colorbufferFormat != GL_RGB5_A1 &&
560 colorbufferFormat != GL_RGBA8_OES)
561 {
Geoff Langb1196682014-07-23 13:47:29 -0400562 context->recordError(Error(GL_INVALID_OPERATION));
563 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400564 }
565 break;
566 case GL_RG_EXT:
567 if (colorbufferFormat != GL_RG8_EXT &&
568 colorbufferFormat != GL_RGB565 &&
569 colorbufferFormat != GL_RGB8_OES &&
570 colorbufferFormat != GL_RGBA4 &&
571 colorbufferFormat != GL_RGB5_A1 &&
572 colorbufferFormat != GL_RGBA8_OES)
573 {
Geoff Langb1196682014-07-23 13:47:29 -0400574 context->recordError(Error(GL_INVALID_OPERATION));
575 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400576 }
577 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400578 case GL_RGB:
579 if (colorbufferFormat != GL_RGB565 &&
580 colorbufferFormat != GL_RGB8_OES &&
581 colorbufferFormat != GL_RGBA4 &&
582 colorbufferFormat != GL_RGB5_A1 &&
583 colorbufferFormat != GL_RGBA8_OES)
584 {
Geoff Langb1196682014-07-23 13:47:29 -0400585 context->recordError(Error(GL_INVALID_OPERATION));
586 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400587 }
588 break;
589 case GL_LUMINANCE_ALPHA:
590 case GL_RGBA:
591 if (colorbufferFormat != GL_RGBA4 &&
592 colorbufferFormat != GL_RGB5_A1 &&
593 colorbufferFormat != GL_RGBA8_OES)
594 {
Geoff Langb1196682014-07-23 13:47:29 -0400595 context->recordError(Error(GL_INVALID_OPERATION));
596 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400597 }
598 break;
599 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
600 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
601 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
602 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
Geoff Langb1196682014-07-23 13:47:29 -0400603 context->recordError(Error(GL_INVALID_OPERATION));
604 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400605 case GL_DEPTH_COMPONENT:
606 case GL_DEPTH_STENCIL_OES:
Geoff Langb1196682014-07-23 13:47:29 -0400607 context->recordError(Error(GL_INVALID_OPERATION));
608 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400609 default:
Geoff Langb1196682014-07-23 13:47:29 -0400610 context->recordError(Error(GL_INVALID_OPERATION));
611 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400612 }
613 }
614 else
615 {
616 switch (internalformat)
617 {
618 case GL_ALPHA:
619 if (colorbufferFormat != GL_ALPHA8_EXT &&
620 colorbufferFormat != GL_RGBA4 &&
621 colorbufferFormat != GL_RGB5_A1 &&
622 colorbufferFormat != GL_BGRA8_EXT &&
623 colorbufferFormat != GL_RGBA8_OES)
624 {
Geoff Langb1196682014-07-23 13:47:29 -0400625 context->recordError(Error(GL_INVALID_OPERATION));
626 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400627 }
628 break;
629 case GL_LUMINANCE:
Geoff Lang632192d2013-10-04 13:40:46 -0400630 if (colorbufferFormat != GL_R8_EXT &&
631 colorbufferFormat != GL_RG8_EXT &&
632 colorbufferFormat != GL_RGB565 &&
633 colorbufferFormat != GL_RGB8_OES &&
634 colorbufferFormat != GL_RGBA4 &&
635 colorbufferFormat != GL_RGB5_A1 &&
636 colorbufferFormat != GL_BGRA8_EXT &&
637 colorbufferFormat != GL_RGBA8_OES)
638 {
Geoff Langb1196682014-07-23 13:47:29 -0400639 context->recordError(Error(GL_INVALID_OPERATION));
640 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400641 }
642 break;
643 case GL_RED_EXT:
644 if (colorbufferFormat != GL_R8_EXT &&
645 colorbufferFormat != GL_RG8_EXT &&
646 colorbufferFormat != GL_RGB565 &&
647 colorbufferFormat != GL_RGB8_OES &&
648 colorbufferFormat != GL_RGBA4 &&
649 colorbufferFormat != GL_RGB5_A1 &&
650 colorbufferFormat != GL_BGRA8_EXT &&
651 colorbufferFormat != GL_RGBA8_OES)
652 {
Geoff Langb1196682014-07-23 13:47:29 -0400653 context->recordError(Error(GL_INVALID_OPERATION));
654 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400655 }
656 break;
657 case GL_RG_EXT:
658 if (colorbufferFormat != GL_RG8_EXT &&
659 colorbufferFormat != GL_RGB565 &&
660 colorbufferFormat != GL_RGB8_OES &&
661 colorbufferFormat != GL_RGBA4 &&
662 colorbufferFormat != GL_RGB5_A1 &&
663 colorbufferFormat != GL_BGRA8_EXT &&
664 colorbufferFormat != GL_RGBA8_OES)
665 {
Geoff Langb1196682014-07-23 13:47:29 -0400666 context->recordError(Error(GL_INVALID_OPERATION));
667 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400668 }
669 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400670 case GL_RGB:
671 if (colorbufferFormat != GL_RGB565 &&
672 colorbufferFormat != GL_RGB8_OES &&
673 colorbufferFormat != GL_RGBA4 &&
674 colorbufferFormat != GL_RGB5_A1 &&
675 colorbufferFormat != GL_BGRA8_EXT &&
676 colorbufferFormat != GL_RGBA8_OES)
677 {
Geoff Langb1196682014-07-23 13:47:29 -0400678 context->recordError(Error(GL_INVALID_OPERATION));
679 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400680 }
681 break;
682 case GL_LUMINANCE_ALPHA:
683 case GL_RGBA:
684 if (colorbufferFormat != GL_RGBA4 &&
685 colorbufferFormat != GL_RGB5_A1 &&
686 colorbufferFormat != GL_BGRA8_EXT &&
687 colorbufferFormat != GL_RGBA8_OES)
688 {
Geoff Langb1196682014-07-23 13:47:29 -0400689 context->recordError(Error(GL_INVALID_OPERATION));
690 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400691 }
692 break;
693 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
694 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400695 if (context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400696 {
Geoff Langb1196682014-07-23 13:47:29 -0400697 context->recordError(Error(GL_INVALID_OPERATION));
698 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400699 }
700 else
701 {
Geoff Langb1196682014-07-23 13:47:29 -0400702 context->recordError(Error(GL_INVALID_ENUM));
703 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400704 }
705 break;
706 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400707 if (context->getExtensions().textureCompressionDXT3)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400708 {
Geoff Langb1196682014-07-23 13:47:29 -0400709 context->recordError(Error(GL_INVALID_OPERATION));
710 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400711 }
712 else
713 {
Geoff Langb1196682014-07-23 13:47:29 -0400714 context->recordError(Error(GL_INVALID_ENUM));
715 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400716 }
717 break;
718 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400719 if (context->getExtensions().textureCompressionDXT5)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400720 {
Geoff Langb1196682014-07-23 13:47:29 -0400721 context->recordError(Error(GL_INVALID_OPERATION));
722 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400723 }
724 else
725 {
Geoff Langb1196682014-07-23 13:47:29 -0400726 context->recordError(Error(GL_INVALID_ENUM));
727 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400728 }
729 break;
730 case GL_DEPTH_COMPONENT:
731 case GL_DEPTH_COMPONENT16:
732 case GL_DEPTH_COMPONENT32_OES:
733 case GL_DEPTH_STENCIL_OES:
734 case GL_DEPTH24_STENCIL8_OES:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400735 if (context->getExtensions().depthTextures)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400736 {
Geoff Langb1196682014-07-23 13:47:29 -0400737 context->recordError(Error(GL_INVALID_OPERATION));
738 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400739 }
740 else
741 {
Geoff Langb1196682014-07-23 13:47:29 -0400742 context->recordError(Error(GL_INVALID_ENUM));
743 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400744 }
745 default:
Geoff Langb1196682014-07-23 13:47:29 -0400746 context->recordError(Error(GL_INVALID_ENUM));
747 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400748 }
749 }
750
Geoff Lang784a8fd2013-09-24 12:33:16 -0400751 // If width or height is zero, it is a no-op. Return false without setting an error.
752 return (width > 0 && height > 0);
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400753}
754
Geoff Langb1196682014-07-23 13:47:29 -0400755bool ValidateES2TexStorageParameters(Context *context, GLenum target, GLsizei levels, GLenum internalformat,
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400756 GLsizei width, GLsizei height)
757{
758 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP)
759 {
Geoff Langb1196682014-07-23 13:47:29 -0400760 context->recordError(Error(GL_INVALID_ENUM));
761 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400762 }
763
764 if (width < 1 || height < 1 || levels < 1)
765 {
Geoff Langb1196682014-07-23 13:47:29 -0400766 context->recordError(Error(GL_INVALID_VALUE));
767 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400768 }
769
770 if (target == GL_TEXTURE_CUBE_MAP && width != height)
771 {
Geoff Langb1196682014-07-23 13:47:29 -0400772 context->recordError(Error(GL_INVALID_VALUE));
773 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400774 }
775
776 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
777 {
Geoff Langb1196682014-07-23 13:47:29 -0400778 context->recordError(Error(GL_INVALID_OPERATION));
779 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400780 }
781
Geoff Lang5d601382014-07-22 15:14:06 -0400782 const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
783 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400784 {
Geoff Langb1196682014-07-23 13:47:29 -0400785 context->recordError(Error(GL_INVALID_ENUM));
786 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400787 }
788
Geoff Langaae65a42014-05-26 12:43:44 -0400789 const gl::Caps &caps = context->getCaps();
790
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400791 switch (target)
792 {
793 case GL_TEXTURE_2D:
Geoff Langaae65a42014-05-26 12:43:44 -0400794 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
795 static_cast<GLuint>(height) > caps.max2DTextureSize)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400796 {
Geoff Langb1196682014-07-23 13:47:29 -0400797 context->recordError(Error(GL_INVALID_VALUE));
798 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400799 }
800 break;
801 case GL_TEXTURE_CUBE_MAP:
Geoff Langaae65a42014-05-26 12:43:44 -0400802 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
803 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400804 {
Geoff Langb1196682014-07-23 13:47:29 -0400805 context->recordError(Error(GL_INVALID_VALUE));
806 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400807 }
808 break;
809 default:
Geoff Langb1196682014-07-23 13:47:29 -0400810 context->recordError(Error(GL_INVALID_ENUM));
811 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400812 }
813
Geoff Langc0b9ef42014-07-02 10:02:37 -0400814 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400815 {
816 if (!gl::isPow2(width) || !gl::isPow2(height))
817 {
Geoff Langb1196682014-07-23 13:47:29 -0400818 context->recordError(Error(GL_INVALID_OPERATION));
819 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400820 }
821 }
822
823 switch (internalformat)
824 {
825 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
826 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400827 if (!context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400828 {
Geoff Langb1196682014-07-23 13:47:29 -0400829 context->recordError(Error(GL_INVALID_ENUM));
830 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400831 }
832 break;
833 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400834 if (!context->getExtensions().textureCompressionDXT3)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400835 {
Geoff Langb1196682014-07-23 13:47:29 -0400836 context->recordError(Error(GL_INVALID_ENUM));
837 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400838 }
839 break;
840 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400841 if (!context->getExtensions().textureCompressionDXT5)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400842 {
Geoff Langb1196682014-07-23 13:47:29 -0400843 context->recordError(Error(GL_INVALID_ENUM));
844 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400845 }
846 break;
847 case GL_RGBA32F_EXT:
848 case GL_RGB32F_EXT:
849 case GL_ALPHA32F_EXT:
850 case GL_LUMINANCE32F_EXT:
851 case GL_LUMINANCE_ALPHA32F_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400852 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400853 {
Geoff Langb1196682014-07-23 13:47:29 -0400854 context->recordError(Error(GL_INVALID_ENUM));
855 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400856 }
857 break;
858 case GL_RGBA16F_EXT:
859 case GL_RGB16F_EXT:
860 case GL_ALPHA16F_EXT:
861 case GL_LUMINANCE16F_EXT:
862 case GL_LUMINANCE_ALPHA16F_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400863 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400864 {
Geoff Langb1196682014-07-23 13:47:29 -0400865 context->recordError(Error(GL_INVALID_ENUM));
866 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400867 }
868 break;
Geoff Lang632192d2013-10-04 13:40:46 -0400869 case GL_R8_EXT:
870 case GL_RG8_EXT:
871 case GL_R16F_EXT:
872 case GL_RG16F_EXT:
873 case GL_R32F_EXT:
874 case GL_RG32F_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400875 if (!context->getExtensions().textureRG)
Geoff Lang632192d2013-10-04 13:40:46 -0400876 {
Geoff Langb1196682014-07-23 13:47:29 -0400877 context->recordError(Error(GL_INVALID_ENUM));
878 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400879 }
880 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400881 case GL_DEPTH_COMPONENT16:
882 case GL_DEPTH_COMPONENT32_OES:
883 case GL_DEPTH24_STENCIL8_OES:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400884 if (!context->getExtensions().depthTextures)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400885 {
Geoff Langb1196682014-07-23 13:47:29 -0400886 context->recordError(Error(GL_INVALID_ENUM));
887 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400888 }
889 if (target != GL_TEXTURE_2D)
890 {
Geoff Langb1196682014-07-23 13:47:29 -0400891 context->recordError(Error(GL_INVALID_OPERATION));
892 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400893 }
894 // ANGLE_depth_texture only supports 1-level textures
895 if (levels != 1)
896 {
Geoff Langb1196682014-07-23 13:47:29 -0400897 context->recordError(Error(GL_INVALID_OPERATION));
898 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400899 }
900 break;
901 default:
902 break;
903 }
904
905 gl::Texture *texture = NULL;
906 switch(target)
907 {
908 case GL_TEXTURE_2D:
909 texture = context->getTexture2D();
910 break;
911 case GL_TEXTURE_CUBE_MAP:
912 texture = context->getTextureCubeMap();
913 break;
914 default:
915 UNREACHABLE();
916 }
917
918 if (!texture || texture->id() == 0)
919 {
Geoff Langb1196682014-07-23 13:47:29 -0400920 context->recordError(Error(GL_INVALID_OPERATION));
921 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400922 }
923
924 if (texture->isImmutable())
925 {
Geoff Langb1196682014-07-23 13:47:29 -0400926 context->recordError(Error(GL_INVALID_OPERATION));
927 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400928 }
929
930 return true;
931}
932
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400933// check for combinations of format and type that are valid for ReadPixels
Geoff Langb1196682014-07-23 13:47:29 -0400934bool ValidES2ReadFormatType(Context *context, GLenum format, GLenum type)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400935{
936 switch (format)
937 {
938 case GL_RGBA:
939 switch (type)
940 {
941 case GL_UNSIGNED_BYTE:
942 break;
943 default:
944 return false;
945 }
946 break;
947 case GL_BGRA_EXT:
948 switch (type)
949 {
950 case GL_UNSIGNED_BYTE:
951 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
952 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
953 break;
954 default:
955 return false;
956 }
957 break;
Geoff Langbdc9b2f2014-04-16 14:41:54 -0400958 case GL_RG_EXT:
959 case GL_RED_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400960 if (!context->getExtensions().textureRG)
Geoff Langbdc9b2f2014-04-16 14:41:54 -0400961 {
962 return false;
963 }
964 switch (type)
965 {
966 case GL_UNSIGNED_BYTE:
967 break;
968 default:
969 return false;
970 }
971 break;
972
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400973 default:
974 return false;
975 }
976 return true;
977}
978
979}