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     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 
pixelStoreParam(GL2Encoder * ctx,GLenum param)73 bool 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 
pixelStoreValue(GLenum param,GLint value)93 bool 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 
rboFormat(GL2Encoder * ctx,GLenum internalformat)112 bool 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 
framebufferTarget(GL2Encoder * ctx,GLenum target)187 bool 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 
framebufferAttachment(GL2Encoder * ctx,GLenum attachment)199 bool 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 
readPixelsFormat(GLenum format)227 bool 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 
readPixelsType(GLenum format)245 bool 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 
vertexAttribType(GL2Encoder * ctx,GLenum type)264 bool 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 
readPixelsFboFormatMatch(GLenum format,GLenum type,GLenum fboTexType)292 bool 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 
blitFramebufferFormat(GLenum readFormat,GLenum drawFormat)307 bool 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 
textureTarget(GL2Encoder * ctx,GLenum target)325 bool 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 
ceildiv(GLsizei x,GLsizei y)351 static GLsizei ceildiv(GLsizei x, GLsizei y) {
352     return (x + y - 1) / y;
353 }
354 
compressedTexImageSize(GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth)355 GLsizei 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 
isCompressedFormat(GLenum internalformat)379 bool 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 
supportedCompressedFormat(GL2Encoder * ctx,GLenum internalformat)429 bool 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 
unsizedFormat(GLenum format)488 bool 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
filterableTexFormat(GL2Encoder * ctx,GLenum internalformat)509 bool 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 
colorRenderableFormat(GL2Encoder * ctx,GLenum internalformat)541 bool 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 
depthRenderableFormat(GL2Encoder * ctx,GLenum internalformat)589 bool 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 
stencilRenderableFormat(GL2Encoder * ctx,GLenum internalformat)603 bool 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 
isCubeMapTarget(GLenum target)614 bool 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 
pixelType(GL2Encoder * ctx,GLenum type)664 bool 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 
pixelFormat(GL2Encoder * ctx,GLenum format)697 bool 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 
pixelInternalFormat(GLenum internalformat)795 bool 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 
shaderType(GL2Encoder * ctx,GLenum type)808 bool 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 
internalFormatTarget(GL2Encoder * ctx,GLenum target)821 bool 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 
vertexAttribIndexRangeErrorMsg(GL2Encoder * ctx,GLuint index)833 std::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