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