blob: d9a69d1f569a54d6b6707354f0d62e4fc3faaf76 [file] [log] [blame]
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001//
Geoff Langcec35902014-04-16 10:52:36 -04002// Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
Geoff Lange8ebe7f2013-08-05 15:03:13 -04003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// validationES2.cpp: Validation functions for OpenGL ES 2.0 entry point parameters
8
Geoff Lang2b5420c2014-11-19 14:20:15 -05009#include "libANGLE/validationES2.h"
10#include "libANGLE/validationES.h"
11#include "libANGLE/Context.h"
12#include "libANGLE/Texture.h"
13#include "libANGLE/Framebuffer.h"
14#include "libANGLE/Renderbuffer.h"
15#include "libANGLE/formatutils.h"
16#include "libANGLE/FramebufferAttachment.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040017
18#include "common/mathutil.h"
19#include "common/utilities.h"
20
21namespace gl
22{
23
Geoff Langb1196682014-07-23 13:47:29 -040024bool ValidateES2TexImageParameters(Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage,
Geoff Lange8ebe7f2013-08-05 15:03:13 -040025 GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
26 GLint border, GLenum format, GLenum type, const GLvoid *pixels)
27{
Jamie Madill6f38f822014-06-06 17:12:20 -040028 if (!ValidTexture2DDestinationTarget(context, target))
29 {
Geoff Langb1196682014-07-23 13:47:29 -040030 context->recordError(Error(GL_INVALID_ENUM));
31 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -040032 }
33
Austin Kinross08528e12015-10-07 16:24:40 -070034 if (!ValidImageSizeParameters(context, target, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -040035 {
Geoff Langb1196682014-07-23 13:47:29 -040036 context->recordError(Error(GL_INVALID_VALUE));
37 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040038 }
39
Geoff Lange8ebe7f2013-08-05 15:03:13 -040040 if (level < 0 || xoffset < 0 ||
41 std::numeric_limits<GLsizei>::max() - xoffset < width ||
42 std::numeric_limits<GLsizei>::max() - yoffset < height)
43 {
Geoff Langb1196682014-07-23 13:47:29 -040044 context->recordError(Error(GL_INVALID_VALUE));
45 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040046 }
47
Geoff Lang005df412013-10-16 14:12:50 -040048 if (!isSubImage && !isCompressed && internalformat != format)
Geoff Lange8ebe7f2013-08-05 15:03:13 -040049 {
Geoff Langb1196682014-07-23 13:47:29 -040050 context->recordError(Error(GL_INVALID_OPERATION));
51 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040052 }
53
Geoff Langaae65a42014-05-26 12:43:44 -040054 const gl::Caps &caps = context->getCaps();
55
Geoff Langa9be0dc2014-12-17 12:34:40 -050056 if (target == GL_TEXTURE_2D)
Geoff Lange8ebe7f2013-08-05 15:03:13 -040057 {
Geoff Langa9be0dc2014-12-17 12:34:40 -050058 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
59 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
Geoff Lange8ebe7f2013-08-05 15:03:13 -040060 {
Geoff Langa9be0dc2014-12-17 12:34:40 -050061 context->recordError(Error(GL_INVALID_VALUE));
62 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040063 }
Geoff Langa9be0dc2014-12-17 12:34:40 -050064 }
Geoff Lang691e58c2014-12-19 17:03:25 -050065 else if (IsCubeMapTextureTarget(target))
Geoff Langa9be0dc2014-12-17 12:34:40 -050066 {
67 if (!isSubImage && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -040068 {
Geoff Langa9be0dc2014-12-17 12:34:40 -050069 context->recordError(Error(GL_INVALID_VALUE));
70 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040071 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -040072
Geoff Langa9be0dc2014-12-17 12:34:40 -050073 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
74 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
75 {
76 context->recordError(Error(GL_INVALID_VALUE));
77 return false;
78 }
79 }
80 else
81 {
Geoff Langb1196682014-07-23 13:47:29 -040082 context->recordError(Error(GL_INVALID_ENUM));
83 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040084 }
85
Geoff Lang691e58c2014-12-19 17:03:25 -050086 gl::Texture *texture = context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -040087 if (!texture)
88 {
Geoff Langb1196682014-07-23 13:47:29 -040089 context->recordError(Error(GL_INVALID_OPERATION));
90 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040091 }
92
Geoff Langa9be0dc2014-12-17 12:34:40 -050093 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -040094 {
Geoff Langa9be0dc2014-12-17 12:34:40 -050095 if (format != GL_NONE)
96 {
Geoff Lang051dbc72015-01-05 15:48:58 -050097 if (gl::GetSizedInternalFormat(format, type) != texture->getInternalFormat(target, level))
Geoff Langa9be0dc2014-12-17 12:34:40 -050098 {
99 context->recordError(Error(GL_INVALID_OPERATION));
100 return false;
101 }
102 }
103
104 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
105 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
106 {
107 context->recordError(Error(GL_INVALID_VALUE));
108 return false;
109 }
110 }
111 else
112 {
Geoff Lang69cce582015-09-17 13:20:36 -0400113 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -0500114 {
115 context->recordError(Error(GL_INVALID_OPERATION));
116 return false;
117 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400118 }
119
120 // Verify zero border
121 if (border != 0)
122 {
Geoff Langb1196682014-07-23 13:47:29 -0400123 context->recordError(Error(GL_INVALID_VALUE));
124 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400125 }
126
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400127 if (isCompressed)
128 {
tmartino0ccd5ae2015-10-01 14:33:14 -0400129 GLenum actualInternalFormat =
130 isSubImage ? texture->getInternalFormat(target, level) : internalformat;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400131 switch (actualInternalFormat)
132 {
133 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
134 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400135 if (!context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400136 {
Geoff Langb1196682014-07-23 13:47:29 -0400137 context->recordError(Error(GL_INVALID_ENUM));
138 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400139 }
140 break;
141 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400142 if (!context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400143 {
Geoff Langb1196682014-07-23 13:47:29 -0400144 context->recordError(Error(GL_INVALID_ENUM));
145 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400146 }
147 break;
148 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
Geoff Langb1196682014-07-23 13:47:29 -0400149 if (!context->getExtensions().textureCompressionDXT5)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400150 {
Geoff Langb1196682014-07-23 13:47:29 -0400151 context->recordError(Error(GL_INVALID_ENUM));
152 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400153 }
154 break;
Geoff Lang6ea6f942015-09-11 13:11:22 -0400155 case GL_ETC1_RGB8_OES:
156 if (!context->getExtensions().compressedETC1RGB8Texture)
157 {
158 context->recordError(Error(GL_INVALID_ENUM));
159 return false;
160 }
161 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400162 default:
tmartino0ccd5ae2015-10-01 14:33:14 -0400163 context->recordError(Error(
164 GL_INVALID_ENUM, "internalformat is not a supported compressed internal format"));
165 return false;
166 }
167 if (!ValidCompressedImageSize(context, actualInternalFormat, width, height))
168 {
169 context->recordError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400170 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400171 }
172 }
173 else
174 {
175 // validate <type> by itself (used as secondary key below)
176 switch (type)
177 {
178 case GL_UNSIGNED_BYTE:
179 case GL_UNSIGNED_SHORT_5_6_5:
180 case GL_UNSIGNED_SHORT_4_4_4_4:
181 case GL_UNSIGNED_SHORT_5_5_5_1:
182 case GL_UNSIGNED_SHORT:
183 case GL_UNSIGNED_INT:
184 case GL_UNSIGNED_INT_24_8_OES:
185 case GL_HALF_FLOAT_OES:
186 case GL_FLOAT:
187 break;
188 default:
Geoff Langb1196682014-07-23 13:47:29 -0400189 context->recordError(Error(GL_INVALID_ENUM));
190 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400191 }
192
193 // validate <format> + <type> combinations
194 // - invalid <format> -> sets INVALID_ENUM
195 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
196 switch (format)
197 {
198 case GL_ALPHA:
199 case GL_LUMINANCE:
200 case GL_LUMINANCE_ALPHA:
201 switch (type)
202 {
203 case GL_UNSIGNED_BYTE:
204 case GL_FLOAT:
205 case GL_HALF_FLOAT_OES:
206 break;
Geoff Langb1196682014-07-23 13:47:29 -0400207 default:
208 context->recordError(Error(GL_INVALID_OPERATION));
209 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400210 }
211 break;
Geoff Lang632192d2013-10-04 13:40:46 -0400212 case GL_RED:
Geoff Langcec35902014-04-16 10:52:36 -0400213 case GL_RG:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400214 if (!context->getExtensions().textureRG)
Geoff Lang632192d2013-10-04 13:40:46 -0400215 {
Geoff Langb1196682014-07-23 13:47:29 -0400216 context->recordError(Error(GL_INVALID_ENUM));
217 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400218 }
219 switch (type)
220 {
221 case GL_UNSIGNED_BYTE:
222 case GL_FLOAT:
223 case GL_HALF_FLOAT_OES:
224 break;
225 default:
Geoff Langb1196682014-07-23 13:47:29 -0400226 context->recordError(Error(GL_INVALID_OPERATION));
227 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400228 }
229 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400230 case GL_RGB:
231 switch (type)
232 {
233 case GL_UNSIGNED_BYTE:
234 case GL_UNSIGNED_SHORT_5_6_5:
235 case GL_FLOAT:
236 case GL_HALF_FLOAT_OES:
237 break;
238 default:
Geoff Langb1196682014-07-23 13:47:29 -0400239 context->recordError(Error(GL_INVALID_OPERATION));
240 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400241 }
242 break;
243 case GL_RGBA:
244 switch (type)
245 {
246 case GL_UNSIGNED_BYTE:
247 case GL_UNSIGNED_SHORT_4_4_4_4:
248 case GL_UNSIGNED_SHORT_5_5_5_1:
249 case GL_FLOAT:
250 case GL_HALF_FLOAT_OES:
251 break;
252 default:
Geoff Langb1196682014-07-23 13:47:29 -0400253 context->recordError(Error(GL_INVALID_OPERATION));
254 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400255 }
256 break;
257 case GL_BGRA_EXT:
258 switch (type)
259 {
260 case GL_UNSIGNED_BYTE:
261 break;
262 default:
Geoff Langb1196682014-07-23 13:47:29 -0400263 context->recordError(Error(GL_INVALID_OPERATION));
264 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400265 }
266 break;
Geoff Lang05b05022014-06-11 15:31:45 -0400267 case GL_SRGB_EXT:
268 case GL_SRGB_ALPHA_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400269 if (!context->getExtensions().sRGB)
Geoff Lang05b05022014-06-11 15:31:45 -0400270 {
Geoff Langb1196682014-07-23 13:47:29 -0400271 context->recordError(Error(GL_INVALID_ENUM));
272 return false;
Geoff Lang05b05022014-06-11 15:31:45 -0400273 }
274 switch (type)
275 {
276 case GL_UNSIGNED_BYTE:
277 break;
278 default:
Geoff Langb1196682014-07-23 13:47:29 -0400279 context->recordError(Error(GL_INVALID_OPERATION));
280 return false;
Geoff Lang05b05022014-06-11 15:31:45 -0400281 }
282 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400283 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
284 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
285 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
286 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
287 break;
288 case GL_DEPTH_COMPONENT:
289 switch (type)
290 {
291 case GL_UNSIGNED_SHORT:
292 case GL_UNSIGNED_INT:
293 break;
294 default:
Geoff Langb1196682014-07-23 13:47:29 -0400295 context->recordError(Error(GL_INVALID_OPERATION));
296 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400297 }
298 break;
299 case GL_DEPTH_STENCIL_OES:
300 switch (type)
301 {
302 case GL_UNSIGNED_INT_24_8_OES:
303 break;
304 default:
Geoff Langb1196682014-07-23 13:47:29 -0400305 context->recordError(Error(GL_INVALID_OPERATION));
306 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400307 }
308 break;
309 default:
Geoff Langb1196682014-07-23 13:47:29 -0400310 context->recordError(Error(GL_INVALID_ENUM));
311 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400312 }
313
314 switch (format)
315 {
316 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
317 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400318 if (context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400319 {
Geoff Langb1196682014-07-23 13:47:29 -0400320 context->recordError(Error(GL_INVALID_OPERATION));
321 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400322 }
323 else
324 {
Geoff Langb1196682014-07-23 13:47:29 -0400325 context->recordError(Error(GL_INVALID_ENUM));
326 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400327 }
328 break;
329 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400330 if (context->getExtensions().textureCompressionDXT3)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400331 {
Geoff Langb1196682014-07-23 13:47:29 -0400332 context->recordError(Error(GL_INVALID_OPERATION));
333 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400334 }
335 else
336 {
Geoff Langb1196682014-07-23 13:47:29 -0400337 context->recordError(Error(GL_INVALID_ENUM));
338 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400339 }
340 break;
341 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400342 if (context->getExtensions().textureCompressionDXT5)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400343 {
Geoff Langb1196682014-07-23 13:47:29 -0400344 context->recordError(Error(GL_INVALID_OPERATION));
345 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400346 }
347 else
348 {
Geoff Langb1196682014-07-23 13:47:29 -0400349 context->recordError(Error(GL_INVALID_ENUM));
350 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400351 }
352 break;
Geoff Lang6ea6f942015-09-11 13:11:22 -0400353 case GL_ETC1_RGB8_OES:
354 if (context->getExtensions().compressedETC1RGB8Texture)
355 {
356 context->recordError(Error(GL_INVALID_OPERATION));
357 return false;
358 }
359 else
360 {
361 context->recordError(Error(GL_INVALID_ENUM));
362 return false;
363 }
364 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400365 case GL_DEPTH_COMPONENT:
366 case GL_DEPTH_STENCIL_OES:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400367 if (!context->getExtensions().depthTextures)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400368 {
Geoff Langb1196682014-07-23 13:47:29 -0400369 context->recordError(Error(GL_INVALID_VALUE));
370 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400371 }
372 if (target != GL_TEXTURE_2D)
373 {
Geoff Langb1196682014-07-23 13:47:29 -0400374 context->recordError(Error(GL_INVALID_OPERATION));
375 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400376 }
377 // OES_depth_texture supports loading depth data and multiple levels,
378 // but ANGLE_depth_texture does not
379 if (pixels != NULL || level != 0)
380 {
Geoff Langb1196682014-07-23 13:47:29 -0400381 context->recordError(Error(GL_INVALID_OPERATION));
382 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400383 }
384 break;
385 default:
386 break;
387 }
388
389 if (type == GL_FLOAT)
390 {
Geoff Langc0b9ef42014-07-02 10:02:37 -0400391 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400392 {
Geoff Langb1196682014-07-23 13:47:29 -0400393 context->recordError(Error(GL_INVALID_ENUM));
394 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400395 }
396 }
397 else if (type == GL_HALF_FLOAT_OES)
398 {
Geoff Langc0b9ef42014-07-02 10:02:37 -0400399 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400400 {
Geoff Langb1196682014-07-23 13:47:29 -0400401 context->recordError(Error(GL_INVALID_ENUM));
402 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400403 }
404 }
405 }
406
407 return true;
408}
409
410
411
Geoff Langb1196682014-07-23 13:47:29 -0400412bool ValidateES2CopyTexImageParameters(Context* context, GLenum target, GLint level, GLenum internalformat, bool isSubImage,
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400413 GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height,
414 GLint border)
415{
Jamie Madill560a8d82014-05-21 13:06:20 -0400416 GLenum textureInternalFormat = GL_NONE;
Shannon Woods4dfed832014-03-17 20:03:39 -0400417
Jamie Madill560a8d82014-05-21 13:06:20 -0400418 if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
419 xoffset, yoffset, 0, x, y, width, height, border, &textureInternalFormat))
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400420 {
Jamie Madill560a8d82014-05-21 13:06:20 -0400421 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400422 }
423
Shannon Woods53a94a82014-06-24 15:20:36 -0400424 gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer();
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400425 GLenum colorbufferFormat = framebuffer->getReadColorbuffer()->getInternalFormat();
Jamie Madillbc393df2015-01-29 13:46:07 -0500426 const auto &internalFormatInfo = gl::GetInternalFormatInfo(textureInternalFormat);
427 GLenum textureFormat = internalFormatInfo.format;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400428
429 // [OpenGL ES 2.0.24] table 3.9
430 if (isSubImage)
431 {
432 switch (textureFormat)
433 {
434 case GL_ALPHA:
435 if (colorbufferFormat != GL_ALPHA8_EXT &&
436 colorbufferFormat != GL_RGBA4 &&
437 colorbufferFormat != GL_RGB5_A1 &&
438 colorbufferFormat != GL_RGBA8_OES)
439 {
Geoff Langb1196682014-07-23 13:47:29 -0400440 context->recordError(Error(GL_INVALID_OPERATION));
441 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400442 }
443 break;
444 case GL_LUMINANCE:
Geoff Lang632192d2013-10-04 13:40:46 -0400445 if (colorbufferFormat != GL_R8_EXT &&
446 colorbufferFormat != GL_RG8_EXT &&
447 colorbufferFormat != GL_RGB565 &&
448 colorbufferFormat != GL_RGB8_OES &&
449 colorbufferFormat != GL_RGBA4 &&
450 colorbufferFormat != GL_RGB5_A1 &&
451 colorbufferFormat != GL_RGBA8_OES)
452 {
Geoff Langb1196682014-07-23 13:47:29 -0400453 context->recordError(Error(GL_INVALID_OPERATION));
454 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400455 }
456 break;
457 case GL_RED_EXT:
458 if (colorbufferFormat != GL_R8_EXT &&
459 colorbufferFormat != GL_RG8_EXT &&
460 colorbufferFormat != GL_RGB565 &&
461 colorbufferFormat != GL_RGB8_OES &&
462 colorbufferFormat != GL_RGBA4 &&
463 colorbufferFormat != GL_RGB5_A1 &&
Jamie Madillbc393df2015-01-29 13:46:07 -0500464 colorbufferFormat != GL_RGBA8_OES &&
465 colorbufferFormat != GL_R32F &&
466 colorbufferFormat != GL_RG32F &&
467 colorbufferFormat != GL_RGB32F &&
468 colorbufferFormat != GL_RGBA32F)
Geoff Lang632192d2013-10-04 13:40:46 -0400469 {
Geoff Langb1196682014-07-23 13:47:29 -0400470 context->recordError(Error(GL_INVALID_OPERATION));
471 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400472 }
473 break;
474 case GL_RG_EXT:
475 if (colorbufferFormat != GL_RG8_EXT &&
476 colorbufferFormat != GL_RGB565 &&
477 colorbufferFormat != GL_RGB8_OES &&
478 colorbufferFormat != GL_RGBA4 &&
479 colorbufferFormat != GL_RGB5_A1 &&
Jamie Madillbc393df2015-01-29 13:46:07 -0500480 colorbufferFormat != GL_RGBA8_OES &&
481 colorbufferFormat != GL_RG32F &&
482 colorbufferFormat != GL_RGB32F &&
483 colorbufferFormat != GL_RGBA32F)
Geoff Lang632192d2013-10-04 13:40:46 -0400484 {
Geoff Langb1196682014-07-23 13:47:29 -0400485 context->recordError(Error(GL_INVALID_OPERATION));
486 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400487 }
488 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400489 case GL_RGB:
490 if (colorbufferFormat != GL_RGB565 &&
491 colorbufferFormat != GL_RGB8_OES &&
492 colorbufferFormat != GL_RGBA4 &&
493 colorbufferFormat != GL_RGB5_A1 &&
Jamie Madillbc393df2015-01-29 13:46:07 -0500494 colorbufferFormat != GL_RGBA8_OES &&
495 colorbufferFormat != GL_RGB32F &&
496 colorbufferFormat != GL_RGBA32F)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400497 {
Geoff Langb1196682014-07-23 13:47:29 -0400498 context->recordError(Error(GL_INVALID_OPERATION));
499 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400500 }
501 break;
502 case GL_LUMINANCE_ALPHA:
503 case GL_RGBA:
504 if (colorbufferFormat != GL_RGBA4 &&
505 colorbufferFormat != GL_RGB5_A1 &&
Jamie Madillbc393df2015-01-29 13:46:07 -0500506 colorbufferFormat != GL_RGBA8_OES &&
507 colorbufferFormat != GL_RGBA32F)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400508 {
Geoff Langb1196682014-07-23 13:47:29 -0400509 context->recordError(Error(GL_INVALID_OPERATION));
510 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400511 }
512 break;
513 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
514 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
515 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
516 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
Geoff Lang6ea6f942015-09-11 13:11:22 -0400517 case GL_ETC1_RGB8_OES:
Geoff Langb1196682014-07-23 13:47:29 -0400518 context->recordError(Error(GL_INVALID_OPERATION));
519 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400520 case GL_DEPTH_COMPONENT:
521 case GL_DEPTH_STENCIL_OES:
Geoff Langb1196682014-07-23 13:47:29 -0400522 context->recordError(Error(GL_INVALID_OPERATION));
523 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400524 default:
Geoff Langb1196682014-07-23 13:47:29 -0400525 context->recordError(Error(GL_INVALID_OPERATION));
526 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400527 }
Jamie Madillbc393df2015-01-29 13:46:07 -0500528
529 if (internalFormatInfo.type == GL_FLOAT &&
530 !context->getExtensions().textureFloat)
531 {
532 context->recordError(Error(GL_INVALID_OPERATION));
533 return false;
534 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400535 }
536 else
537 {
538 switch (internalformat)
539 {
540 case GL_ALPHA:
541 if (colorbufferFormat != GL_ALPHA8_EXT &&
542 colorbufferFormat != GL_RGBA4 &&
543 colorbufferFormat != GL_RGB5_A1 &&
544 colorbufferFormat != GL_BGRA8_EXT &&
Jamie Madill054369e2015-01-07 10:57:08 -0500545 colorbufferFormat != GL_RGBA8_OES &&
546 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400547 {
Geoff Langb1196682014-07-23 13:47:29 -0400548 context->recordError(Error(GL_INVALID_OPERATION));
549 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400550 }
551 break;
552 case GL_LUMINANCE:
Geoff Lang632192d2013-10-04 13:40:46 -0400553 if (colorbufferFormat != GL_R8_EXT &&
554 colorbufferFormat != GL_RG8_EXT &&
555 colorbufferFormat != GL_RGB565 &&
556 colorbufferFormat != GL_RGB8_OES &&
557 colorbufferFormat != GL_RGBA4 &&
558 colorbufferFormat != GL_RGB5_A1 &&
559 colorbufferFormat != GL_BGRA8_EXT &&
Jamie Madill054369e2015-01-07 10:57:08 -0500560 colorbufferFormat != GL_RGBA8_OES &&
561 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Geoff Lang632192d2013-10-04 13:40:46 -0400562 {
Geoff Langb1196682014-07-23 13:47:29 -0400563 context->recordError(Error(GL_INVALID_OPERATION));
564 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400565 }
566 break;
567 case GL_RED_EXT:
568 if (colorbufferFormat != GL_R8_EXT &&
569 colorbufferFormat != GL_RG8_EXT &&
570 colorbufferFormat != GL_RGB565 &&
571 colorbufferFormat != GL_RGB8_OES &&
572 colorbufferFormat != GL_RGBA4 &&
573 colorbufferFormat != GL_RGB5_A1 &&
574 colorbufferFormat != GL_BGRA8_EXT &&
Jamie Madill054369e2015-01-07 10:57:08 -0500575 colorbufferFormat != GL_RGBA8_OES &&
576 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Geoff Lang632192d2013-10-04 13:40:46 -0400577 {
Geoff Langb1196682014-07-23 13:47:29 -0400578 context->recordError(Error(GL_INVALID_OPERATION));
579 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400580 }
581 break;
582 case GL_RG_EXT:
583 if (colorbufferFormat != GL_RG8_EXT &&
584 colorbufferFormat != GL_RGB565 &&
585 colorbufferFormat != GL_RGB8_OES &&
586 colorbufferFormat != GL_RGBA4 &&
587 colorbufferFormat != GL_RGB5_A1 &&
588 colorbufferFormat != GL_BGRA8_EXT &&
Jamie Madill054369e2015-01-07 10:57:08 -0500589 colorbufferFormat != GL_RGBA8_OES &&
590 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Geoff Lang632192d2013-10-04 13:40:46 -0400591 {
Geoff Langb1196682014-07-23 13:47:29 -0400592 context->recordError(Error(GL_INVALID_OPERATION));
593 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400594 }
595 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400596 case GL_RGB:
597 if (colorbufferFormat != GL_RGB565 &&
598 colorbufferFormat != GL_RGB8_OES &&
599 colorbufferFormat != GL_RGBA4 &&
600 colorbufferFormat != GL_RGB5_A1 &&
601 colorbufferFormat != GL_BGRA8_EXT &&
Jamie Madill054369e2015-01-07 10:57:08 -0500602 colorbufferFormat != GL_RGBA8_OES &&
603 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400604 {
Geoff Langb1196682014-07-23 13:47:29 -0400605 context->recordError(Error(GL_INVALID_OPERATION));
606 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400607 }
608 break;
609 case GL_LUMINANCE_ALPHA:
610 case GL_RGBA:
611 if (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_COMPRESSED_RGB_S3TC_DXT1_EXT:
622 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400623 if (context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400624 {
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 else
629 {
Geoff Langb1196682014-07-23 13:47:29 -0400630 context->recordError(Error(GL_INVALID_ENUM));
631 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400632 }
633 break;
634 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400635 if (context->getExtensions().textureCompressionDXT3)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400636 {
Geoff Langb1196682014-07-23 13:47:29 -0400637 context->recordError(Error(GL_INVALID_OPERATION));
638 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400639 }
640 else
641 {
Geoff Langb1196682014-07-23 13:47:29 -0400642 context->recordError(Error(GL_INVALID_ENUM));
643 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400644 }
645 break;
646 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400647 if (context->getExtensions().textureCompressionDXT5)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400648 {
Geoff Langb1196682014-07-23 13:47:29 -0400649 context->recordError(Error(GL_INVALID_OPERATION));
650 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400651 }
652 else
653 {
Geoff Langb1196682014-07-23 13:47:29 -0400654 context->recordError(Error(GL_INVALID_ENUM));
655 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400656 }
657 break;
Geoff Lang6ea6f942015-09-11 13:11:22 -0400658 case GL_ETC1_RGB8_OES:
659 if (context->getExtensions().compressedETC1RGB8Texture)
660 {
661 context->recordError(Error(GL_INVALID_OPERATION));
662 return false;
663 }
664 else
665 {
666 context->recordError(Error(GL_INVALID_ENUM));
667 return false;
668 }
669 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400670 case GL_DEPTH_COMPONENT:
671 case GL_DEPTH_COMPONENT16:
672 case GL_DEPTH_COMPONENT32_OES:
673 case GL_DEPTH_STENCIL_OES:
674 case GL_DEPTH24_STENCIL8_OES:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400675 if (context->getExtensions().depthTextures)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400676 {
Geoff Langb1196682014-07-23 13:47:29 -0400677 context->recordError(Error(GL_INVALID_OPERATION));
678 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400679 }
680 else
681 {
Geoff Langb1196682014-07-23 13:47:29 -0400682 context->recordError(Error(GL_INVALID_ENUM));
683 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400684 }
685 default:
Geoff Langb1196682014-07-23 13:47:29 -0400686 context->recordError(Error(GL_INVALID_ENUM));
687 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400688 }
689 }
690
Geoff Lang784a8fd2013-09-24 12:33:16 -0400691 // If width or height is zero, it is a no-op. Return false without setting an error.
692 return (width > 0 && height > 0);
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400693}
694
Geoff Langb1196682014-07-23 13:47:29 -0400695bool ValidateES2TexStorageParameters(Context *context, GLenum target, GLsizei levels, GLenum internalformat,
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400696 GLsizei width, GLsizei height)
697{
698 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP)
699 {
Geoff Langb1196682014-07-23 13:47:29 -0400700 context->recordError(Error(GL_INVALID_ENUM));
701 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400702 }
703
704 if (width < 1 || height < 1 || levels < 1)
705 {
Geoff Langb1196682014-07-23 13:47:29 -0400706 context->recordError(Error(GL_INVALID_VALUE));
707 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400708 }
709
710 if (target == GL_TEXTURE_CUBE_MAP && width != height)
711 {
Geoff Langb1196682014-07-23 13:47:29 -0400712 context->recordError(Error(GL_INVALID_VALUE));
713 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400714 }
715
716 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
717 {
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
Geoff Lang5d601382014-07-22 15:14:06 -0400722 const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
723 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400724 {
Geoff Langb1196682014-07-23 13:47:29 -0400725 context->recordError(Error(GL_INVALID_ENUM));
726 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400727 }
728
Geoff Langaae65a42014-05-26 12:43:44 -0400729 const gl::Caps &caps = context->getCaps();
730
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400731 switch (target)
732 {
733 case GL_TEXTURE_2D:
Geoff Langaae65a42014-05-26 12:43:44 -0400734 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
735 static_cast<GLuint>(height) > caps.max2DTextureSize)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400736 {
Geoff Langb1196682014-07-23 13:47:29 -0400737 context->recordError(Error(GL_INVALID_VALUE));
738 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400739 }
740 break;
741 case GL_TEXTURE_CUBE_MAP:
Geoff Langaae65a42014-05-26 12:43:44 -0400742 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
743 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400744 {
Geoff Langb1196682014-07-23 13:47:29 -0400745 context->recordError(Error(GL_INVALID_VALUE));
746 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400747 }
748 break;
749 default:
Geoff Langb1196682014-07-23 13:47:29 -0400750 context->recordError(Error(GL_INVALID_ENUM));
751 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400752 }
753
Geoff Langc0b9ef42014-07-02 10:02:37 -0400754 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400755 {
756 if (!gl::isPow2(width) || !gl::isPow2(height))
757 {
Geoff Langb1196682014-07-23 13:47:29 -0400758 context->recordError(Error(GL_INVALID_OPERATION));
759 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400760 }
761 }
762
763 switch (internalformat)
764 {
765 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
766 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400767 if (!context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400768 {
Geoff Langb1196682014-07-23 13:47:29 -0400769 context->recordError(Error(GL_INVALID_ENUM));
770 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400771 }
772 break;
773 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400774 if (!context->getExtensions().textureCompressionDXT3)
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 break;
780 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400781 if (!context->getExtensions().textureCompressionDXT5)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400782 {
Geoff Langb1196682014-07-23 13:47:29 -0400783 context->recordError(Error(GL_INVALID_ENUM));
784 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400785 }
786 break;
Geoff Lang6ea6f942015-09-11 13:11:22 -0400787 case GL_ETC1_RGB8_OES:
788 if (!context->getExtensions().compressedETC1RGB8Texture)
789 {
790 context->recordError(Error(GL_INVALID_ENUM));
791 return false;
792 }
793 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400794 case GL_RGBA32F_EXT:
795 case GL_RGB32F_EXT:
796 case GL_ALPHA32F_EXT:
797 case GL_LUMINANCE32F_EXT:
798 case GL_LUMINANCE_ALPHA32F_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400799 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400800 {
Geoff Langb1196682014-07-23 13:47:29 -0400801 context->recordError(Error(GL_INVALID_ENUM));
802 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400803 }
804 break;
805 case GL_RGBA16F_EXT:
806 case GL_RGB16F_EXT:
807 case GL_ALPHA16F_EXT:
808 case GL_LUMINANCE16F_EXT:
809 case GL_LUMINANCE_ALPHA16F_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400810 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400811 {
Geoff Langb1196682014-07-23 13:47:29 -0400812 context->recordError(Error(GL_INVALID_ENUM));
813 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400814 }
815 break;
Geoff Lang632192d2013-10-04 13:40:46 -0400816 case GL_R8_EXT:
817 case GL_RG8_EXT:
818 case GL_R16F_EXT:
819 case GL_RG16F_EXT:
820 case GL_R32F_EXT:
821 case GL_RG32F_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400822 if (!context->getExtensions().textureRG)
Geoff Lang632192d2013-10-04 13:40:46 -0400823 {
Geoff Langb1196682014-07-23 13:47:29 -0400824 context->recordError(Error(GL_INVALID_ENUM));
825 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400826 }
827 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400828 case GL_DEPTH_COMPONENT16:
829 case GL_DEPTH_COMPONENT32_OES:
830 case GL_DEPTH24_STENCIL8_OES:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400831 if (!context->getExtensions().depthTextures)
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 if (target != GL_TEXTURE_2D)
837 {
Geoff Langb1196682014-07-23 13:47:29 -0400838 context->recordError(Error(GL_INVALID_OPERATION));
839 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400840 }
841 // ANGLE_depth_texture only supports 1-level textures
842 if (levels != 1)
843 {
Geoff Langb1196682014-07-23 13:47:29 -0400844 context->recordError(Error(GL_INVALID_OPERATION));
845 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400846 }
847 break;
848 default:
849 break;
850 }
851
Geoff Lang691e58c2014-12-19 17:03:25 -0500852 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400853 if (!texture || texture->id() == 0)
854 {
Geoff Langb1196682014-07-23 13:47:29 -0400855 context->recordError(Error(GL_INVALID_OPERATION));
856 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400857 }
858
Geoff Lang69cce582015-09-17 13:20:36 -0400859 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400860 {
Geoff Langb1196682014-07-23 13:47:29 -0400861 context->recordError(Error(GL_INVALID_OPERATION));
862 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400863 }
864
865 return true;
866}
867
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400868// check for combinations of format and type that are valid for ReadPixels
Geoff Langb1196682014-07-23 13:47:29 -0400869bool ValidES2ReadFormatType(Context *context, GLenum format, GLenum type)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400870{
871 switch (format)
872 {
873 case GL_RGBA:
874 switch (type)
875 {
876 case GL_UNSIGNED_BYTE:
877 break;
878 default:
879 return false;
880 }
881 break;
882 case GL_BGRA_EXT:
883 switch (type)
884 {
885 case GL_UNSIGNED_BYTE:
886 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
887 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
888 break;
889 default:
890 return false;
891 }
892 break;
Geoff Langbdc9b2f2014-04-16 14:41:54 -0400893 case GL_RG_EXT:
894 case GL_RED_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400895 if (!context->getExtensions().textureRG)
Geoff Langbdc9b2f2014-04-16 14:41:54 -0400896 {
897 return false;
898 }
899 switch (type)
900 {
901 case GL_UNSIGNED_BYTE:
902 break;
903 default:
904 return false;
905 }
906 break;
907
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400908 default:
909 return false;
910 }
911 return true;
912}
913
Austin Kinross08332632015-05-05 13:35:47 -0700914bool ValidateDiscardFramebufferEXT(Context *context, GLenum target, GLsizei numAttachments,
915 const GLenum *attachments)
916{
917 bool defaultFramebuffer = false;
918
919 switch (target)
920 {
921 case GL_FRAMEBUFFER:
922 defaultFramebuffer = (context->getState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
923 break;
924 default:
925 context->recordError(Error(GL_INVALID_ENUM, "Invalid framebuffer target"));
926 return false;
927 }
928
929 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments, defaultFramebuffer);
930}
931
Dian Xiangbf18ed02015-09-11 10:50:04 -0700932bool ValidateDrawBuffers(Context *context, GLsizei n, const GLenum *bufs)
933{
934 // INVALID_VALUE is generated if n is negative or greater than value of MAX_DRAW_BUFFERS
935 if (n < 0 || static_cast<GLuint>(n) > context->getCaps().maxDrawBuffers)
936 {
937 context->recordError(
938 Error(GL_INVALID_VALUE, "n must be non-negative and no greater than MAX_DRAW_BUFFERS"));
939 return false;
940 }
941
942 ASSERT(context->getState().getDrawFramebuffer());
943 GLuint frameBufferId = context->getState().getDrawFramebuffer()->id();
944 GLuint maxColorAttachment = GL_COLOR_ATTACHMENT0_EXT + context->getCaps().maxColorAttachments;
945
946 // This should come first before the check for the default frame buffer
947 // because when we switch to ES3.1+, invalid enums will return INVALID_ENUM
948 // rather than INVALID_OPERATION
949 for (int colorAttachment = 0; colorAttachment < n; colorAttachment++)
950 {
951 const GLenum attachment = GL_COLOR_ATTACHMENT0_EXT + colorAttachment;
952
953 if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != GL_BACK &&
954 (bufs[colorAttachment] < GL_COLOR_ATTACHMENT0_EXT ||
955 bufs[colorAttachment] >= maxColorAttachment))
956 {
957 // Value in bufs is not NONE, BACK, or GL_COLOR_ATTACHMENTi
958 // In the 3.0 specs, the error should return GL_INVALID_OPERATION.
959 // When we move to 3.1 specs, we should change the error to be GL_INVALID_ENUM
960 context->recordError(Error(GL_INVALID_OPERATION, "Invalid buffer value"));
961 return false;
962 }
963 else if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != attachment &&
964 frameBufferId != 0)
965 {
966 // INVALID_OPERATION-GL is bound to buffer and ith argument
967 // is not COLOR_ATTACHMENTi or NONE
968 context->recordError(
969 Error(GL_INVALID_OPERATION, "Ith value does not match COLOR_ATTACHMENTi or NONE"));
970 return false;
971 }
972 }
973
974 // INVALID_OPERATION is generated if GL is bound to the default framebuffer
975 // and n is not 1 or bufs is bound to value other than BACK and NONE
976 if (frameBufferId == 0)
977 {
978 if (n != 1)
979 {
980 context->recordError(Error(GL_INVALID_OPERATION,
981 "n must be 1 when GL is bound to the default framebuffer"));
982 return false;
983 }
984
985 if (bufs[0] != GL_NONE && bufs[0] != GL_BACK)
986 {
987 context->recordError(Error(
988 GL_INVALID_OPERATION,
989 "Only NONE or BACK are valid values when drawing to the default framebuffer"));
990 return false;
991 }
992 }
993
994 return true;
995}
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400996}