1 /*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "GLESv2Validation.h"
18
19 #include <sstream>
20
21 namespace GLESv2Validation {
22
23 GLbitfield allBufferMapAccessFlags =
24 GL_MAP_READ_BIT | GL_MAP_WRITE_BIT |
25 GL_MAP_INVALIDATE_RANGE_BIT |
26 GL_MAP_INVALIDATE_BUFFER_BIT |
27 GL_MAP_FLUSH_EXPLICIT_BIT |
28 GL_MAP_UNSYNCHRONIZED_BIT;
29
bufferTarget(GL2Encoder * ctx,GLenum target)30 bool bufferTarget(GL2Encoder* ctx, GLenum target) {
31 int glesMajorVersion = ctx->majorVersion();
32 int glesMinorVersion = ctx->minorVersion();
33 switch (target) {
34 case GL_ARRAY_BUFFER: // Vertex attributes
35 case GL_ELEMENT_ARRAY_BUFFER: // Vertex array indices
36 return true;
37 // GLES 3.0 buffers
38 case GL_COPY_READ_BUFFER: // Buffer copy source
39 case GL_COPY_WRITE_BUFFER: // Buffer copy destination
40 case GL_PIXEL_PACK_BUFFER: // Pixel read target
41 case GL_PIXEL_UNPACK_BUFFER: // Texture data source
42 case GL_TRANSFORM_FEEDBACK_BUFFER: // Transform feedback buffer
43 case GL_UNIFORM_BUFFER: // Uniform block storage
44 return glesMajorVersion >= 3;
45 // GLES 3.1 buffers
46 case GL_ATOMIC_COUNTER_BUFFER: // Atomic counter storage
47 case GL_DISPATCH_INDIRECT_BUFFER: // Indirect compute dispatch commands
48 case GL_DRAW_INDIRECT_BUFFER: // Indirect command arguments
49 case GL_SHADER_STORAGE_BUFFER: // Read-write storage for shaders
50 return glesMajorVersion >= 3 && glesMinorVersion >= 1;
51 default:
52 return false;
53 }
54 }
55
bufferParam(GL2Encoder * ctx,GLenum pname)56 bool bufferParam(GL2Encoder* ctx, GLenum pname) {
57 int glesMajorVersion = ctx->majorVersion();
58 switch (pname) {
59 case GL_BUFFER_SIZE:
60 case GL_BUFFER_USAGE:
61 return true;
62 case GL_BUFFER_ACCESS_FLAGS:
63 case GL_BUFFER_MAPPED:
64 case GL_BUFFER_MAP_LENGTH:
65 case GL_BUFFER_MAP_OFFSET:
66 return glesMajorVersion >= 3;
67 default:
68 return false;
69 }
70 }
71
pixelStoreParam(GL2Encoder * ctx,GLenum param)72 bool pixelStoreParam(GL2Encoder* ctx, GLenum param) {
73 int glesMajorVersion = ctx->majorVersion();
74 switch(param) {
75 case GL_UNPACK_ALIGNMENT:
76 case GL_PACK_ALIGNMENT:
77 return true;
78 case GL_UNPACK_ROW_LENGTH:
79 case GL_UNPACK_IMAGE_HEIGHT:
80 case GL_UNPACK_SKIP_PIXELS:
81 case GL_UNPACK_SKIP_ROWS:
82 case GL_UNPACK_SKIP_IMAGES:
83 case GL_PACK_ROW_LENGTH:
84 case GL_PACK_SKIP_PIXELS:
85 case GL_PACK_SKIP_ROWS:
86 return glesMajorVersion >= 3;
87 default:
88 return false;
89 }
90 }
91
pixelStoreValue(GLenum param,GLint value)92 bool pixelStoreValue(GLenum param, GLint value) {
93 switch(param) {
94 case GL_UNPACK_ALIGNMENT:
95 case GL_PACK_ALIGNMENT:
96 return (value == 1) || (value == 2) || (value == 4) || (value == 8);
97 case GL_UNPACK_ROW_LENGTH:
98 case GL_UNPACK_IMAGE_HEIGHT:
99 case GL_UNPACK_SKIP_PIXELS:
100 case GL_UNPACK_SKIP_ROWS:
101 case GL_UNPACK_SKIP_IMAGES:
102 case GL_PACK_ROW_LENGTH:
103 case GL_PACK_SKIP_PIXELS:
104 case GL_PACK_SKIP_ROWS:
105 return value >= 0;
106 default:
107 return false;
108 }
109 }
110
rboFormat(GL2Encoder * ctx,GLenum internalformat)111 bool rboFormat(GL2Encoder* ctx, GLenum internalformat) {
112 int glesMajorVersion = ctx->majorVersion();
113
114 switch (internalformat) {
115 // Funny internal formats
116 // that will cause an incomplete framebuffer
117 // attachment error pre-gles3. For dEQP,
118 // we can also just abort early here in
119 // RenderbufferStorage with a GL_INVALID_ENUM.
120 case GL_DEPTH_COMPONENT32F:
121 case GL_R8:
122 case GL_R8UI:
123 case GL_R8I:
124 case GL_R16UI:
125 case GL_R16I:
126 case GL_R32UI:
127 case GL_R32I:
128 case GL_RG8:
129 case GL_RG8UI:
130 case GL_RG8I:
131 case GL_RG16UI:
132 case GL_RG16I:
133 case GL_RG32UI:
134 case GL_RG32I:
135 case GL_SRGB8_ALPHA8:
136 case GL_RGBA8UI:
137 case GL_RGBA8I:
138 case GL_RGB10_A2:
139 case GL_RGB10_A2UI:
140 case GL_RGBA16UI:
141 case GL_RGBA16I:
142 case GL_RGBA32I:
143 case GL_RGBA32UI:
144 case GL_RGB32F:
145 return glesMajorVersion >= 3;
146 // These 4 formats are still not OK,
147 // but dEQP expects GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT or
148 // GL_FRAMEBUFFER_UNSUPPORTED if the extension is not present,
149 // not a GL_INVALID_ENUM from earlier on.
150 // So let's forward these to the rest of
151 // FBO initialization
152 // In GLES 3, these are rejected immediately if not
153 // supported.
154 case GL_R16F:
155 case GL_RG16F:
156 case GL_RGBA16F:
157 case GL_R32F:
158 case GL_RG32F:
159 case GL_RGBA32F:
160 case GL_R11F_G11F_B10F:
161 return glesMajorVersion >= 3 && ctx->hasExtension("GL_EXT_color_buffer_float");
162 case GL_RGB16F:
163 return glesMajorVersion >= 3 && ctx->hasExtension("GL_EXT_color_buffer_half_float");
164 // dEQP expects GL_FRAMEBUFFER_UNSUPPORTED or GL_FRAMEBUFFER_COMPLETE
165 // for this format
166 // These formats are OK
167 case GL_DEPTH_COMPONENT16:
168 case GL_DEPTH_COMPONENT24:
169 case GL_DEPTH_COMPONENT32_OES:
170 case GL_RGBA4:
171 case GL_RGB5_A1:
172 case GL_RGB565:
173 case GL_RGB8_OES:
174 case GL_RGBA8_OES:
175 case GL_STENCIL_INDEX8:
176 case GL_DEPTH32F_STENCIL8:
177 case GL_DEPTH24_STENCIL8_OES:
178 return true;
179 break;
180 // Everything else: still not OK,
181 // and they need the GL_INVALID_ENUM
182 }
183 return false;
184 }
185
framebufferTarget(GL2Encoder * ctx,GLenum target)186 bool framebufferTarget(GL2Encoder* ctx, GLenum target) {
187 int glesMajorVersion = ctx->majorVersion();
188 switch (target) {
189 case GL_FRAMEBUFFER:
190 return true;
191 case GL_DRAW_FRAMEBUFFER:
192 case GL_READ_FRAMEBUFFER:
193 return glesMajorVersion >= 3;
194 }
195 return false;
196 }
197
framebufferAttachment(GL2Encoder * ctx,GLenum attachment)198 bool framebufferAttachment(GL2Encoder* ctx, GLenum attachment) {
199 int glesMajorVersion = ctx->majorVersion();
200 switch (attachment) {
201 case GL_COLOR_ATTACHMENT0:
202 case GL_DEPTH_ATTACHMENT:
203 case GL_STENCIL_ATTACHMENT:
204 return true;
205 case GL_COLOR_ATTACHMENT1:
206 case GL_COLOR_ATTACHMENT2:
207 case GL_COLOR_ATTACHMENT3:
208 case GL_COLOR_ATTACHMENT4:
209 case GL_COLOR_ATTACHMENT5:
210 case GL_COLOR_ATTACHMENT6:
211 case GL_COLOR_ATTACHMENT7:
212 case GL_COLOR_ATTACHMENT8:
213 case GL_COLOR_ATTACHMENT9:
214 case GL_COLOR_ATTACHMENT10:
215 case GL_COLOR_ATTACHMENT11:
216 case GL_COLOR_ATTACHMENT12:
217 case GL_COLOR_ATTACHMENT13:
218 case GL_COLOR_ATTACHMENT14:
219 case GL_COLOR_ATTACHMENT15:
220 case GL_DEPTH_STENCIL_ATTACHMENT:
221 return glesMajorVersion >= 3;
222 }
223 return false;
224 }
225
readPixelsFormat(GLenum format)226 bool readPixelsFormat(GLenum format) {
227 switch (format) {
228 case GL_RED:
229 case GL_RED_INTEGER:
230 case GL_RG:
231 case GL_RG_INTEGER:
232 case GL_RGB:
233 case GL_RGB_INTEGER:
234 case GL_RGBA:
235 case GL_RGBA_INTEGER:
236 case GL_LUMINANCE_ALPHA:
237 case GL_LUMINANCE:
238 case GL_ALPHA:
239 return true;
240 }
241 return false;
242 }
243
readPixelsType(GLenum format)244 bool readPixelsType(GLenum format) {
245 switch (format) {
246 case GL_UNSIGNED_BYTE:
247 case GL_BYTE:
248 case GL_HALF_FLOAT:
249 case GL_FLOAT:
250 case GL_INT:
251 case GL_UNSIGNED_SHORT_5_6_5:
252 case GL_UNSIGNED_SHORT_4_4_4_4:
253 case GL_UNSIGNED_SHORT_5_5_5_1:
254 case GL_UNSIGNED_INT:
255 case GL_UNSIGNED_INT_2_10_10_10_REV:
256 case GL_UNSIGNED_INT_10F_11F_11F_REV:
257 case GL_UNSIGNED_INT_5_9_9_9_REV:
258 return true;
259 }
260 return false;
261 }
262
vertexAttribType(GL2Encoder * ctx,GLenum type)263 bool vertexAttribType(GL2Encoder* ctx, GLenum type)
264 {
265 int glesMajorVersion = ctx->majorVersion();
266 bool retval = false;
267 switch (type) {
268 case GL_BYTE:
269 case GL_UNSIGNED_BYTE:
270 case GL_SHORT:
271 case GL_UNSIGNED_SHORT:
272 case GL_FIXED:
273 case GL_FLOAT:
274 // The following are technically only available if certain GLES2 extensions are.
275 // However, they are supported by desktop GL3, which is a reasonable requirement
276 // for the desktop GL version. Therefore, consider them valid.
277 case GL_INT:
278 case GL_UNSIGNED_INT:
279 case GL_HALF_FLOAT_OES:
280 retval = true;
281 break;
282 case GL_HALF_FLOAT:
283 case GL_INT_2_10_10_10_REV:
284 case GL_UNSIGNED_INT_2_10_10_10_REV:
285 retval = glesMajorVersion >= 3;
286 break;
287 }
288 return retval;
289 }
290
readPixelsFboFormatMatch(GLenum,GLenum type,GLenum fboTexType)291 bool readPixelsFboFormatMatch(GLenum, GLenum type, GLenum fboTexType) {
292 #define INVALID_TYPE_MATCH(x, y) \
293 if (type == x && fboTexType == y) return false; \
294 if (type == y && fboTexType == x) return false; \
295
296 // These are meant to reject additional format/type mismatches
297 // not caught by underlying system.
298 INVALID_TYPE_MATCH(GL_FLOAT, GL_BYTE)
299 INVALID_TYPE_MATCH(GL_FLOAT, GL_UNSIGNED_BYTE)
300 INVALID_TYPE_MATCH(GL_FLOAT, GL_UNSIGNED_INT)
301 INVALID_TYPE_MATCH(GL_FLOAT, GL_INT)
302
303 return true;
304 }
305
blitFramebufferFormat(GLenum readFormat,GLenum drawFormat)306 bool blitFramebufferFormat(GLenum readFormat, GLenum drawFormat) {
307 #define INVALID_MATCH(x, y) \
308 if (readFormat == x && drawFormat == y) return false; \
309 if (readFormat == y && drawFormat == x) return false; \
310
311 INVALID_MATCH(GL_FLOAT, GL_BYTE)
312 INVALID_MATCH(GL_FLOAT, GL_UNSIGNED_BYTE)
313 INVALID_MATCH(GL_FLOAT, GL_UNSIGNED_INT)
314 INVALID_MATCH(GL_FLOAT, GL_INT)
315 INVALID_MATCH(GL_INT, GL_UNSIGNED_BYTE);
316 INVALID_MATCH(GL_UNSIGNED_INT, GL_UNSIGNED_BYTE);
317 INVALID_MATCH(GL_INT, GL_BYTE);
318 INVALID_MATCH(GL_UNSIGNED_INT, GL_BYTE);
319 INVALID_MATCH(GL_DEPTH32F_STENCIL8, GL_DEPTH24_STENCIL8);
320
321 return true;
322 }
323
textureTarget(GL2Encoder * ctx,GLenum target)324 bool textureTarget(GL2Encoder* ctx, GLenum target) {
325 int glesMajorVersion = ctx->majorVersion();
326 int glesMinorVersion = ctx->minorVersion();
327 switch (target) {
328 case GL_TEXTURE_EXTERNAL_OES:
329 case GL_TEXTURE_2D:
330 case GL_TEXTURE_CUBE_MAP:
331 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
332 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
333 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
334 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
335 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
336 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
337 return true;
338 case GL_TEXTURE_2D_ARRAY:
339 case GL_TEXTURE_3D:
340 return glesMajorVersion >= 3;
341 case GL_TEXTURE_2D_MULTISAMPLE:
342 return glesMajorVersion >= 3 &&
343 glesMinorVersion >= 1;
344 default:
345 break;
346 }
347 return false;
348 }
349
ceildiv(GLsizei x,GLsizei y)350 static GLsizei ceildiv(GLsizei x, GLsizei y) {
351 return (x + y - 1) / y;
352 }
353
compressedTexImageSize(GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth)354 GLsizei compressedTexImageSize(GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) {
355 GLsizei base_size = ceildiv(width, 4) * ceildiv(height, 4) * depth;
356 #define COMPRESSED_TEX_IMAGE_SIZE_CASE(internal, multiplier) \
357 case internal: \
358 return base_size * multiplier; \
359
360 switch (internalformat) {
361 COMPRESSED_TEX_IMAGE_SIZE_CASE(GL_COMPRESSED_R11_EAC, 8)
362 COMPRESSED_TEX_IMAGE_SIZE_CASE(GL_COMPRESSED_SIGNED_R11_EAC, 8)
363 COMPRESSED_TEX_IMAGE_SIZE_CASE(GL_COMPRESSED_RG11_EAC, 16)
364 COMPRESSED_TEX_IMAGE_SIZE_CASE(GL_COMPRESSED_SIGNED_RG11_EAC, 16)
365 COMPRESSED_TEX_IMAGE_SIZE_CASE(GL_COMPRESSED_RGB8_ETC2, 8)
366 COMPRESSED_TEX_IMAGE_SIZE_CASE(GL_COMPRESSED_SRGB8_ETC2, 8)
367 COMPRESSED_TEX_IMAGE_SIZE_CASE(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, 8)
368 COMPRESSED_TEX_IMAGE_SIZE_CASE(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, 8)
369 COMPRESSED_TEX_IMAGE_SIZE_CASE(GL_COMPRESSED_RGBA8_ETC2_EAC, 16)
370 COMPRESSED_TEX_IMAGE_SIZE_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, 16)
371 default:
372 break;
373 }
374
375 return 0;
376 }
377
isCompressedFormat(GLenum internalformat)378 bool isCompressedFormat(GLenum internalformat) {
379 #define COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(internal) \
380 case internal: \
381 return true; \
382
383 switch (internalformat) {
384 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_R11_EAC)
385 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_SIGNED_R11_EAC)
386 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_RG11_EAC)
387 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_SIGNED_RG11_EAC)
388 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_RGB8_ETC2)
389 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_SRGB8_ETC2)
390 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2)
391 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2)
392 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_RGBA8_ETC2_EAC)
393 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC)
394 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_RGBA_ASTC_4x4_KHR)
395 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_RGBA_ASTC_5x4_KHR)
396 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_RGBA_ASTC_5x5_KHR)
397 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_RGBA_ASTC_6x5_KHR)
398 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_RGBA_ASTC_6x6_KHR)
399 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_RGBA_ASTC_8x5_KHR)
400 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_RGBA_ASTC_8x6_KHR)
401 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_RGBA_ASTC_8x8_KHR)
402 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_RGBA_ASTC_10x5_KHR)
403 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_RGBA_ASTC_10x6_KHR)
404 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_RGBA_ASTC_10x8_KHR)
405 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_RGBA_ASTC_10x10_KHR)
406 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_RGBA_ASTC_12x10_KHR)
407 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_RGBA_ASTC_12x12_KHR)
408 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR)
409 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR)
410 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR)
411 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR)
412 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR)
413 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR)
414 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR)
415 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR)
416 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR)
417 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR)
418 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR)
419 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR)
420 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR)
421 COMPRESSED_TEX_IMAGE_IS_COMPRESSED_FORMAT_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR)
422 default:
423 break;
424 }
425 return false;
426 }
427
supportedCompressedFormat(GL2Encoder * ctx,GLenum internalformat)428 bool supportedCompressedFormat(GL2Encoder* ctx, GLenum internalformat) {
429 int glesMajorVersion = ctx->majorVersion();
430 int glesMinorVersion = ctx->minorVersion();
431
432 #define COMPRESSED_TEX_IMAGE_SUPPORT_CASE_ASTC(internal) \
433 case internal: \
434 return glesMajorVersion > 1 && ctx->hasExtension("GL_KHR_texture_compression_astc_ldr"); \
435
436 #define COMPRESSED_TEX_IMAGE_SUPPORT_CASE(internal, maj, min) \
437 case internal: \
438 if (maj < 3) return true; \
439 if (glesMajorVersion < maj) return false; \
440 if (glesMinorVersion < min) return false; \
441 break; \
442
443 #define COMPRESSED_TEX_IMAGE_NOTSUPPORTED(internal) \
444 case internal: \
445 return false ; \
446
447 switch (internalformat) {
448 COMPRESSED_TEX_IMAGE_SUPPORT_CASE(GL_COMPRESSED_R11_EAC, 2, 0)
449 COMPRESSED_TEX_IMAGE_SUPPORT_CASE(GL_COMPRESSED_SIGNED_R11_EAC, 2, 0)
450 COMPRESSED_TEX_IMAGE_SUPPORT_CASE(GL_COMPRESSED_RG11_EAC, 2, 0)
451 COMPRESSED_TEX_IMAGE_SUPPORT_CASE(GL_COMPRESSED_SIGNED_RG11_EAC, 2, 0)
452 COMPRESSED_TEX_IMAGE_SUPPORT_CASE(GL_COMPRESSED_RGB8_ETC2, 2, 0)
453 COMPRESSED_TEX_IMAGE_SUPPORT_CASE(GL_COMPRESSED_SRGB8_ETC2, 2, 0)
454 COMPRESSED_TEX_IMAGE_SUPPORT_CASE(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, 2, 0)
455 COMPRESSED_TEX_IMAGE_SUPPORT_CASE(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, 2, 0)
456 COMPRESSED_TEX_IMAGE_SUPPORT_CASE(GL_COMPRESSED_RGBA8_ETC2_EAC, 2, 0)
457 COMPRESSED_TEX_IMAGE_SUPPORT_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, 2, 0)
458 COMPRESSED_TEX_IMAGE_SUPPORT_CASE_ASTC(GL_COMPRESSED_RGBA_ASTC_4x4_KHR)
459 COMPRESSED_TEX_IMAGE_SUPPORT_CASE_ASTC(GL_COMPRESSED_RGBA_ASTC_5x4_KHR)
460 COMPRESSED_TEX_IMAGE_SUPPORT_CASE_ASTC(GL_COMPRESSED_RGBA_ASTC_5x5_KHR)
461 COMPRESSED_TEX_IMAGE_SUPPORT_CASE_ASTC(GL_COMPRESSED_RGBA_ASTC_6x5_KHR)
462 COMPRESSED_TEX_IMAGE_SUPPORT_CASE_ASTC(GL_COMPRESSED_RGBA_ASTC_6x6_KHR)
463 COMPRESSED_TEX_IMAGE_SUPPORT_CASE_ASTC(GL_COMPRESSED_RGBA_ASTC_8x5_KHR)
464 COMPRESSED_TEX_IMAGE_SUPPORT_CASE_ASTC(GL_COMPRESSED_RGBA_ASTC_8x6_KHR)
465 COMPRESSED_TEX_IMAGE_SUPPORT_CASE_ASTC(GL_COMPRESSED_RGBA_ASTC_8x8_KHR)
466 COMPRESSED_TEX_IMAGE_SUPPORT_CASE_ASTC(GL_COMPRESSED_RGBA_ASTC_10x5_KHR)
467 COMPRESSED_TEX_IMAGE_SUPPORT_CASE_ASTC(GL_COMPRESSED_RGBA_ASTC_10x6_KHR)
468 COMPRESSED_TEX_IMAGE_SUPPORT_CASE_ASTC(GL_COMPRESSED_RGBA_ASTC_10x8_KHR)
469 COMPRESSED_TEX_IMAGE_SUPPORT_CASE_ASTC(GL_COMPRESSED_RGBA_ASTC_10x10_KHR)
470 COMPRESSED_TEX_IMAGE_SUPPORT_CASE_ASTC(GL_COMPRESSED_RGBA_ASTC_12x10_KHR)
471 COMPRESSED_TEX_IMAGE_SUPPORT_CASE_ASTC(GL_COMPRESSED_RGBA_ASTC_12x12_KHR)
472 COMPRESSED_TEX_IMAGE_SUPPORT_CASE_ASTC(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR)
473 COMPRESSED_TEX_IMAGE_SUPPORT_CASE_ASTC(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR)
474 COMPRESSED_TEX_IMAGE_SUPPORT_CASE_ASTC(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR)
475 COMPRESSED_TEX_IMAGE_SUPPORT_CASE_ASTC(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR)
476 COMPRESSED_TEX_IMAGE_SUPPORT_CASE_ASTC(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR)
477 COMPRESSED_TEX_IMAGE_SUPPORT_CASE_ASTC(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR)
478 COMPRESSED_TEX_IMAGE_SUPPORT_CASE_ASTC(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR)
479 COMPRESSED_TEX_IMAGE_SUPPORT_CASE_ASTC(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR)
480 COMPRESSED_TEX_IMAGE_SUPPORT_CASE_ASTC(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR)
481 COMPRESSED_TEX_IMAGE_SUPPORT_CASE_ASTC(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR)
482 COMPRESSED_TEX_IMAGE_SUPPORT_CASE_ASTC(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR)
483 COMPRESSED_TEX_IMAGE_SUPPORT_CASE_ASTC(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR)
484 COMPRESSED_TEX_IMAGE_SUPPORT_CASE_ASTC(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR)
485 COMPRESSED_TEX_IMAGE_SUPPORT_CASE_ASTC(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR)
486 default:
487 break;
488 }
489 return true;
490 }
491
unsizedFormat(GLenum format)492 bool unsizedFormat(GLenum format) {
493 switch (format) {
494 case GL_RED:
495 case GL_RED_INTEGER:
496 case GL_DEPTH_COMPONENT:
497 case GL_DEPTH_STENCIL:
498 case GL_RG:
499 case GL_RG_INTEGER:
500 case GL_RGB:
501 case GL_RGB_INTEGER:
502 case GL_RGBA:
503 case GL_RGBA_INTEGER:
504 case GL_ALPHA:
505 case GL_LUMINANCE:
506 case GL_LUMINANCE_ALPHA:
507 return true;
508 }
509 return false;
510 }
511
512 // TODO: fix this
filterableTexFormat(GL2Encoder * ctx,GLenum internalformat)513 bool filterableTexFormat(GL2Encoder* ctx, GLenum internalformat) {
514 switch (internalformat) {
515 case GL_R32F:
516 case GL_RG32F:
517 case GL_RGB32F:
518 case GL_RGBA32F:
519 return ctx->hasExtension("GL_OES_texture_float");
520 case GL_R8UI:
521 case GL_R8I:
522 case GL_R16UI:
523 case GL_R16I:
524 case GL_R32UI:
525 case GL_R32I:
526 case GL_RG8UI:
527 case GL_RG8I:
528 case GL_RG16UI:
529 case GL_RG16I:
530 case GL_RG32UI:
531 case GL_RG32I:
532 case GL_RGBA8UI:
533 case GL_RGBA8I:
534 case GL_RGB10_A2UI:
535 case GL_RGBA16UI:
536 case GL_RGBA16I:
537 case GL_RGBA32I:
538 case GL_RGBA32UI:
539 return false;
540 }
541 return true;
542 }
543
544
colorRenderableFormat(GL2Encoder * ctx,GLenum internalformat)545 bool colorRenderableFormat(GL2Encoder* ctx, GLenum internalformat) {
546 int glesMajorVersion = ctx->majorVersion();
547 switch (internalformat) {
548 case GL_R8:
549 case GL_RG8:
550 case GL_RGB8:
551 case GL_RGB565:
552 case GL_RGBA4:
553 case GL_RGB5_A1:
554 case GL_RGBA8:
555 case GL_RGB10_A2:
556 case GL_RGB10_A2UI:
557 case GL_SRGB8_ALPHA8:
558 case GL_R8I:
559 case GL_R8UI:
560 case GL_R16I:
561 case GL_R16UI:
562 case GL_R32I:
563 case GL_R32UI:
564 case GL_RG8I:
565 case GL_RG8UI:
566 case GL_RG16I:
567 case GL_RG16UI:
568 case GL_RG32I:
569 case GL_RG32UI:
570 case GL_RGBA8I:
571 case GL_RGBA8UI:
572 case GL_RGBA16I:
573 case GL_RGBA16UI:
574 case GL_RGBA32I:
575 case GL_RGBA32UI:
576 return true;
577 case GL_R16F:
578 case GL_RG16F:
579 case GL_RGBA16F:
580 case GL_R32F:
581 case GL_RG32F:
582 case GL_RGBA32F:
583 case GL_R11F_G11F_B10F:
584 return glesMajorVersion >= 3 && ctx->hasExtension("GL_EXT_color_buffer_float");
585 break;
586 case GL_RGB16F:
587 return glesMajorVersion >= 3 && ctx->hasExtension("GL_EXT_color_buffer_half_float");
588 break;
589 }
590 return false;
591 }
592
depthRenderableFormat(GL2Encoder *,GLenum internalformat)593 bool depthRenderableFormat(GL2Encoder*, GLenum internalformat) {
594 switch (internalformat) {
595 case GL_DEPTH_COMPONENT:
596 case GL_DEPTH_STENCIL:
597 case GL_DEPTH_COMPONENT16:
598 case GL_DEPTH_COMPONENT24:
599 case GL_DEPTH_COMPONENT32F:
600 case GL_DEPTH24_STENCIL8:
601 case GL_DEPTH32F_STENCIL8:
602 return true;
603 }
604 return false;
605 }
606
stencilRenderableFormat(GL2Encoder *,GLenum internalformat)607 bool stencilRenderableFormat(GL2Encoder*, GLenum internalformat) {
608 switch (internalformat) {
609 case GL_DEPTH_STENCIL:
610 case GL_STENCIL_INDEX8:
611 case GL_DEPTH24_STENCIL8:
612 case GL_DEPTH32F_STENCIL8:
613 return true;
614 }
615 return false;
616 }
617
isCubeMapTarget(GLenum target)618 bool isCubeMapTarget(GLenum target) {
619 switch (target) {
620 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
621 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
622 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
623 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
624 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
625 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
626 return true;
627 default:
628 break;
629 }
630 return false;
631 }
632
633 #define LIST_VALID_TEXFORMATS(f) \
634 f(GL_DEPTH_COMPONENT) \
635 f(GL_DEPTH_STENCIL) \
636 f(GL_RED) \
637 f(GL_RED_INTEGER) \
638 f(GL_RG) \
639 f(GL_RGB) \
640 f(GL_RGBA) \
641 f(GL_RGBA_INTEGER) \
642 f(GL_RGB_INTEGER) \
643 f(GL_RG_INTEGER) \
644 f(GL_BGRA_EXT) \
645 f(GL_ALPHA) \
646 f(GL_LUMINANCE) \
647 f(GL_LUMINANCE_ALPHA) \
648
649 #define LIST_VALID_TEXTYPES(f) \
650 f(GL_BYTE) \
651 f(GL_FLOAT) \
652 f(GL_FLOAT_32_UNSIGNED_INT_24_8_REV) \
653 f(GL_HALF_FLOAT) \
654 f(GL_HALF_FLOAT_OES) \
655 f(GL_INT) \
656 f(GL_SHORT) \
657 f(GL_UNSIGNED_BYTE) \
658 f(GL_UNSIGNED_INT) \
659 f(GL_UNSIGNED_INT_10F_11F_11F_REV) \
660 f(GL_UNSIGNED_INT_2_10_10_10_REV) \
661 f(GL_UNSIGNED_INT_24_8) \
662 f(GL_UNSIGNED_INT_5_9_9_9_REV) \
663 f(GL_UNSIGNED_SHORT) \
664 f(GL_UNSIGNED_SHORT_4_4_4_4) \
665 f(GL_UNSIGNED_SHORT_5_5_5_1) \
666 f(GL_UNSIGNED_SHORT_5_6_5) \
667
pixelType(GL2Encoder * ctx,GLenum type)668 bool pixelType(GL2Encoder* ctx, GLenum type) {
669 int glesMajorVersion = ctx->majorVersion();
670 if (glesMajorVersion < 3) {
671 switch (type) {
672 case GL_UNSIGNED_BYTE:
673 case GL_UNSIGNED_SHORT:
674 case GL_UNSIGNED_SHORT_5_6_5:
675 case GL_UNSIGNED_SHORT_4_4_4_4:
676 case GL_UNSIGNED_SHORT_5_5_5_1:
677 case GL_UNSIGNED_INT:
678 case GL_UNSIGNED_INT_10F_11F_11F_REV:
679 case GL_UNSIGNED_INT_24_8:
680 case GL_HALF_FLOAT:
681 case GL_HALF_FLOAT_OES:
682 case GL_FLOAT:
683 return true;
684 }
685 return false;
686 }
687
688 #define GLES3_TYPE_CASE(type) \
689 case type: \
690
691 switch (type) {
692 LIST_VALID_TEXTYPES(GLES3_TYPE_CASE)
693 return glesMajorVersion >= 3;
694 default:
695 break;
696 }
697
698 return false;
699 }
700
pixelFormat(GL2Encoder * ctx,GLenum format)701 bool pixelFormat(GL2Encoder* ctx, GLenum format) {
702 int glesMajorVersion = ctx->majorVersion();
703 if (glesMajorVersion < 3) {
704 switch (format) {
705 case GL_DEPTH_COMPONENT:
706 // GLES3 compatible
707 // Required in dEQP
708 case GL_RED:
709 case GL_RG:
710 case GL_DEPTH_STENCIL_OES:
711 case GL_ALPHA:
712 case GL_RGB:
713 case GL_RGBA:
714 case GL_BGRA_EXT:
715 case GL_LUMINANCE:
716 case GL_LUMINANCE_ALPHA:
717 return true;
718 }
719 return false;
720 }
721
722 #define GLES3_FORMAT_CASE(format) \
723 case format:
724
725 switch (format) {
726 LIST_VALID_TEXFORMATS(GLES3_FORMAT_CASE)
727 return glesMajorVersion >= 3;
728 default:
729 break;
730 }
731 return false;
732 }
733 #define LIST_VALID_TEX_INTERNALFORMATS(f) \
734 f(GL_BGRA8_EXT) \
735 f(GL_R8) \
736 f(GL_R8_SNORM) \
737 f(GL_R16F) \
738 f(GL_R32F) \
739 f(GL_R8UI) \
740 f(GL_R8I) \
741 f(GL_R16UI) \
742 f(GL_R16I) \
743 f(GL_R32UI) \
744 f(GL_R32I) \
745 f(GL_RG8) \
746 f(GL_RG8_SNORM) \
747 f(GL_RG16F) \
748 f(GL_RG32F) \
749 f(GL_RG8UI) \
750 f(GL_RG8I) \
751 f(GL_RG16UI) \
752 f(GL_RG16I) \
753 f(GL_RG32UI) \
754 f(GL_RG32I) \
755 f(GL_RGB8) \
756 f(GL_SRGB8) \
757 f(GL_RGB565) \
758 f(GL_RGB8_SNORM) \
759 f(GL_R11F_G11F_B10F) \
760 f(GL_RGB9_E5) \
761 f(GL_RGB16F) \
762 f(GL_RGB32F) \
763 f(GL_RGB8UI) \
764 f(GL_RGB8I) \
765 f(GL_RGB16UI) \
766 f(GL_RGB16I) \
767 f(GL_RGB32UI) \
768 f(GL_RGB32I) \
769 f(GL_RGBA8) \
770 f(GL_SRGB8_ALPHA8) \
771 f(GL_RGBA8_SNORM) \
772 f(GL_RGB5_A1) \
773 f(GL_RGBA4) \
774 f(GL_RGB10_A2) \
775 f(GL_RGBA16F) \
776 f(GL_RGBA32F) \
777 f(GL_RGBA8UI) \
778 f(GL_RGBA8I) \
779 f(GL_RGB10_A2UI) \
780 f(GL_RGBA16UI) \
781 f(GL_RGBA16I) \
782 f(GL_RGBA32I) \
783 f(GL_RGBA32UI) \
784 f(GL_DEPTH_COMPONENT16) \
785 f(GL_DEPTH_COMPONENT24) \
786 f(GL_DEPTH_COMPONENT32F) \
787 f(GL_DEPTH24_STENCIL8) \
788 f(GL_DEPTH32F_STENCIL8) \
789 f(GL_ETC1_RGB8_OES) \
790 f(GL_COMPRESSED_R11_EAC) \
791 f(GL_COMPRESSED_SIGNED_R11_EAC) \
792 f(GL_COMPRESSED_RG11_EAC) \
793 f(GL_COMPRESSED_SIGNED_RG11_EAC) \
794 f(GL_COMPRESSED_RGB8_ETC2) \
795 f(GL_COMPRESSED_SRGB8_ETC2) \
796 f(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2) \
797 f(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2) \
798 f(GL_COMPRESSED_RGBA8_ETC2_EAC) \
799 f(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC) \
800 f(GL_COMPRESSED_RGBA_ASTC_4x4_KHR) \
801 f(GL_COMPRESSED_RGBA_ASTC_5x4_KHR) \
802 f(GL_COMPRESSED_RGBA_ASTC_5x5_KHR) \
803 f(GL_COMPRESSED_RGBA_ASTC_6x5_KHR) \
804 f(GL_COMPRESSED_RGBA_ASTC_6x6_KHR) \
805 f(GL_COMPRESSED_RGBA_ASTC_8x5_KHR) \
806 f(GL_COMPRESSED_RGBA_ASTC_8x6_KHR) \
807 f(GL_COMPRESSED_RGBA_ASTC_8x8_KHR) \
808 f(GL_COMPRESSED_RGBA_ASTC_10x5_KHR) \
809 f(GL_COMPRESSED_RGBA_ASTC_10x6_KHR) \
810 f(GL_COMPRESSED_RGBA_ASTC_10x8_KHR) \
811 f(GL_COMPRESSED_RGBA_ASTC_10x10_KHR) \
812 f(GL_COMPRESSED_RGBA_ASTC_12x10_KHR) \
813 f(GL_COMPRESSED_RGBA_ASTC_12x12_KHR) \
814 f(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR) \
815 f(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR) \
816 f(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR) \
817 f(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR) \
818 f(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR) \
819 f(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR) \
820 f(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR) \
821 f(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR) \
822 f(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR) \
823 f(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR) \
824 f(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR) \
825 f(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR) \
826 f(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR) \
827 f(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR) \
828
829
pixelInternalFormat(GLenum internalformat)830 bool pixelInternalFormat(GLenum internalformat) {
831 #define VALID_INTERNAL_FORMAT(format) \
832 case format: \
833 return true; \
834
835 switch (internalformat) {
836 LIST_VALID_TEX_INTERNALFORMATS(VALID_INTERNAL_FORMAT)
837 default:
838 break;
839 }
840 return false;
841 }
842
shaderType(GL2Encoder * ctx,GLenum type)843 bool shaderType(GL2Encoder* ctx, GLenum type) {
844 int glesMajorVersion = ctx->majorVersion();
845 int glesMinorVersion = ctx->minorVersion();
846 switch (type) {
847 case GL_VERTEX_SHADER:
848 case GL_FRAGMENT_SHADER:
849 return true;
850 case GL_COMPUTE_SHADER:
851 return glesMajorVersion >= 3 && glesMinorVersion >= 1;
852 }
853 return false;
854 }
855
internalFormatTarget(GL2Encoder * ctx,GLenum target)856 bool internalFormatTarget(GL2Encoder* ctx, GLenum target) {
857 int glesMajorVersion = ctx->majorVersion();
858 int glesMinorVersion = ctx->minorVersion();
859 switch (target) {
860 case GL_RENDERBUFFER:
861 return true;
862 case GL_TEXTURE_2D_MULTISAMPLE:
863 return glesMajorVersion >= 3 && glesMinorVersion >= 1;
864 }
865 return false;
866 }
867
vertexAttribIndexRangeErrorMsg(GL2Encoder * ctx,GLuint index)868 std::string vertexAttribIndexRangeErrorMsg(GL2Encoder* ctx, GLuint index) {
869 std::stringstream ss;
870 GLint maxIndex;
871 ctx->glGetIntegerv(ctx, GL_MAX_VERTEX_ATTRIBS, &maxIndex);
872 ss << "Invalid vertex attribute index. Wanted index: " << index << ". Max index: " << maxIndex;
873 return ss.str();
874 }
875
876 } // namespace GLESv2Validation
877