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