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