1// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// utilities.cpp: Conversion functions and other utility routines.
16
17#include "utilities.h"
18
19#include "Framebuffer.h"
20#include "main.h"
21#include "mathutil.h"
22#include "Context.h"
23#include "Shader.h"
24#include "common/debug.h"
25
26#include <limits>
27#include <stdio.h>
28#include <stdlib.h>
29
30namespace es2
31{
32
33 unsigned int UniformComponentCount(GLenum type)
34 {
35 switch(type)
36 {
37 case GL_BOOL:
38 case GL_FLOAT:
39 case GL_INT:
40 case GL_UNSIGNED_INT:
41 case GL_SAMPLER_2D:
42 case GL_SAMPLER_CUBE:
43 case GL_SAMPLER_2D_RECT_ARB:
44 case GL_SAMPLER_EXTERNAL_OES:
45 case GL_SAMPLER_3D_OES:
46 case GL_SAMPLER_2D_ARRAY:
47 case GL_SAMPLER_2D_SHADOW:
48 case GL_SAMPLER_CUBE_SHADOW:
49 case GL_SAMPLER_2D_ARRAY_SHADOW:
50 case GL_INT_SAMPLER_2D:
51 case GL_UNSIGNED_INT_SAMPLER_2D:
52 case GL_INT_SAMPLER_CUBE:
53 case GL_UNSIGNED_INT_SAMPLER_CUBE:
54 case GL_INT_SAMPLER_3D:
55 case GL_UNSIGNED_INT_SAMPLER_3D:
56 case GL_INT_SAMPLER_2D_ARRAY:
57 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
58 return 1;
59 case GL_BOOL_VEC2:
60 case GL_FLOAT_VEC2:
61 case GL_INT_VEC2:
62 case GL_UNSIGNED_INT_VEC2:
63 return 2;
64 case GL_INT_VEC3:
65 case GL_UNSIGNED_INT_VEC3:
66 case GL_FLOAT_VEC3:
67 case GL_BOOL_VEC3:
68 return 3;
69 case GL_BOOL_VEC4:
70 case GL_FLOAT_VEC4:
71 case GL_INT_VEC4:
72 case GL_UNSIGNED_INT_VEC4:
73 case GL_FLOAT_MAT2:
74 return 4;
75 case GL_FLOAT_MAT2x3:
76 case GL_FLOAT_MAT3x2:
77 return 6;
78 case GL_FLOAT_MAT2x4:
79 case GL_FLOAT_MAT4x2:
80 return 8;
81 case GL_FLOAT_MAT3:
82 return 9;
83 case GL_FLOAT_MAT3x4:
84 case GL_FLOAT_MAT4x3:
85 return 12;
86 case GL_FLOAT_MAT4:
87 return 16;
88 default:
89 UNREACHABLE(type);
90 }
91
92 return 0;
93 }
94
95 GLenum UniformComponentType(GLenum type)
96 {
97 switch(type)
98 {
99 case GL_BOOL:
100 case GL_BOOL_VEC2:
101 case GL_BOOL_VEC3:
102 case GL_BOOL_VEC4:
103 return GL_BOOL;
104 case GL_FLOAT:
105 case GL_FLOAT_VEC2:
106 case GL_FLOAT_VEC3:
107 case GL_FLOAT_VEC4:
108 case GL_FLOAT_MAT2:
109 case GL_FLOAT_MAT2x3:
110 case GL_FLOAT_MAT2x4:
111 case GL_FLOAT_MAT3:
112 case GL_FLOAT_MAT3x2:
113 case GL_FLOAT_MAT3x4:
114 case GL_FLOAT_MAT4:
115 case GL_FLOAT_MAT4x2:
116 case GL_FLOAT_MAT4x3:
117 return GL_FLOAT;
118 case GL_INT:
119 case GL_SAMPLER_2D:
120 case GL_SAMPLER_CUBE:
121 case GL_SAMPLER_2D_RECT_ARB:
122 case GL_SAMPLER_EXTERNAL_OES:
123 case GL_SAMPLER_3D_OES:
124 case GL_SAMPLER_2D_ARRAY:
125 case GL_SAMPLER_2D_SHADOW:
126 case GL_SAMPLER_CUBE_SHADOW:
127 case GL_SAMPLER_2D_ARRAY_SHADOW:
128 case GL_INT_SAMPLER_2D:
129 case GL_UNSIGNED_INT_SAMPLER_2D:
130 case GL_INT_SAMPLER_CUBE:
131 case GL_UNSIGNED_INT_SAMPLER_CUBE:
132 case GL_INT_SAMPLER_3D:
133 case GL_UNSIGNED_INT_SAMPLER_3D:
134 case GL_INT_SAMPLER_2D_ARRAY:
135 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
136 case GL_INT_VEC2:
137 case GL_INT_VEC3:
138 case GL_INT_VEC4:
139 return GL_INT;
140 case GL_UNSIGNED_INT:
141 case GL_UNSIGNED_INT_VEC2:
142 case GL_UNSIGNED_INT_VEC3:
143 case GL_UNSIGNED_INT_VEC4:
144 return GL_UNSIGNED_INT;
145 default:
146 UNREACHABLE(type);
147 }
148
149 return GL_NONE;
150 }
151
152 size_t UniformTypeSize(GLenum type)
153 {
154 switch(type)
155 {
156 case GL_BOOL: return sizeof(GLboolean);
157 case GL_FLOAT: return sizeof(GLfloat);
158 case GL_INT: return sizeof(GLint);
159 case GL_UNSIGNED_INT: return sizeof(GLuint);
160 }
161
162 return UniformTypeSize(UniformComponentType(type)) * UniformComponentCount(type);
163 }
164
165 bool IsSamplerUniform(GLenum type)
166 {
167 switch(type)
168 {
169 case GL_SAMPLER_2D:
170 case GL_SAMPLER_CUBE:
171 case GL_SAMPLER_2D_RECT_ARB:
172 case GL_SAMPLER_EXTERNAL_OES:
173 case GL_SAMPLER_3D_OES:
174 case GL_SAMPLER_2D_ARRAY:
175 case GL_SAMPLER_2D_SHADOW:
176 case GL_SAMPLER_CUBE_SHADOW:
177 case GL_SAMPLER_2D_ARRAY_SHADOW:
178 case GL_INT_SAMPLER_2D:
179 case GL_UNSIGNED_INT_SAMPLER_2D:
180 case GL_INT_SAMPLER_CUBE:
181 case GL_UNSIGNED_INT_SAMPLER_CUBE:
182 case GL_INT_SAMPLER_3D:
183 case GL_UNSIGNED_INT_SAMPLER_3D:
184 case GL_INT_SAMPLER_2D_ARRAY:
185 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
186 return true;
187 default:
188 return false;
189 }
190 }
191
192 int VariableRowCount(GLenum type)
193 {
194 switch(type)
195 {
196 case GL_NONE:
197 return 0;
198 case GL_BOOL:
199 case GL_FLOAT:
200 case GL_INT:
201 case GL_UNSIGNED_INT:
202 case GL_BOOL_VEC2:
203 case GL_FLOAT_VEC2:
204 case GL_INT_VEC2:
205 case GL_UNSIGNED_INT_VEC2:
206 case GL_INT_VEC3:
207 case GL_UNSIGNED_INT_VEC3:
208 case GL_FLOAT_VEC3:
209 case GL_BOOL_VEC3:
210 case GL_BOOL_VEC4:
211 case GL_FLOAT_VEC4:
212 case GL_INT_VEC4:
213 case GL_UNSIGNED_INT_VEC4:
214 case GL_SAMPLER_2D:
215 case GL_SAMPLER_CUBE:
216 case GL_SAMPLER_2D_RECT_ARB:
217 case GL_SAMPLER_EXTERNAL_OES:
218 case GL_SAMPLER_3D_OES:
219 case GL_SAMPLER_2D_ARRAY:
220 case GL_SAMPLER_2D_SHADOW:
221 case GL_SAMPLER_CUBE_SHADOW:
222 case GL_SAMPLER_2D_ARRAY_SHADOW:
223 case GL_INT_SAMPLER_2D:
224 case GL_UNSIGNED_INT_SAMPLER_2D:
225 case GL_INT_SAMPLER_CUBE:
226 case GL_UNSIGNED_INT_SAMPLER_CUBE:
227 case GL_INT_SAMPLER_3D:
228 case GL_UNSIGNED_INT_SAMPLER_3D:
229 case GL_INT_SAMPLER_2D_ARRAY:
230 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
231 return 1;
232 case GL_FLOAT_MAT2:
233 case GL_FLOAT_MAT3x2:
234 case GL_FLOAT_MAT4x2:
235 return 2;
236 case GL_FLOAT_MAT3:
237 case GL_FLOAT_MAT2x3:
238 case GL_FLOAT_MAT4x3:
239 return 3;
240 case GL_FLOAT_MAT4:
241 case GL_FLOAT_MAT2x4:
242 case GL_FLOAT_MAT3x4:
243 return 4;
244 default:
245 UNREACHABLE(type);
246 }
247
248 return 0;
249 }
250
251 int VariableColumnCount(GLenum type)
252 {
253 switch(type)
254 {
255 case GL_NONE:
256 return 0;
257 case GL_BOOL:
258 case GL_FLOAT:
259 case GL_INT:
260 case GL_UNSIGNED_INT:
261 return 1;
262 case GL_BOOL_VEC2:
263 case GL_FLOAT_VEC2:
264 case GL_INT_VEC2:
265 case GL_UNSIGNED_INT_VEC2:
266 case GL_FLOAT_MAT2:
267 case GL_FLOAT_MAT2x3:
268 case GL_FLOAT_MAT2x4:
269 return 2;
270 case GL_INT_VEC3:
271 case GL_UNSIGNED_INT_VEC3:
272 case GL_FLOAT_VEC3:
273 case GL_BOOL_VEC3:
274 case GL_FLOAT_MAT3:
275 case GL_FLOAT_MAT3x2:
276 case GL_FLOAT_MAT3x4:
277 return 3;
278 case GL_BOOL_VEC4:
279 case GL_FLOAT_VEC4:
280 case GL_INT_VEC4:
281 case GL_UNSIGNED_INT_VEC4:
282 case GL_FLOAT_MAT4:
283 case GL_FLOAT_MAT4x2:
284 case GL_FLOAT_MAT4x3:
285 return 4;
286 default:
287 UNREACHABLE(type);
288 }
289
290 return 0;
291 }
292
293 int VariableRegisterCount(GLenum type)
294 {
295 // Number of registers used is the number of columns for matrices or 1 for scalars and vectors
296 return (VariableRowCount(type) > 1) ? VariableColumnCount(type) : 1;
297 }
298
299 int VariableRegisterSize(GLenum type)
300 {
301 // Number of components per register is the number of rows for matrices or columns for scalars and vectors
302 int nbRows = VariableRowCount(type);
303 return (nbRows > 1) ? nbRows : VariableColumnCount(type);
304 }
305
306 int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize)
307 {
308 ASSERT(allocationSize <= bitsSize);
309
310 unsigned int mask = std::numeric_limits<unsigned int>::max() >> (std::numeric_limits<unsigned int>::digits - allocationSize);
311
312 for(unsigned int i = 0; i < bitsSize - allocationSize + 1; i++)
313 {
314 if((*bits & mask) == 0)
315 {
316 *bits |= mask;
317 return i;
318 }
319
320 mask <<= 1;
321 }
322
323 return -1;
324 }
325
326 bool IsCompressed(GLint internalformat)
327 {
328 switch(internalformat)
329 {
330 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
331 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
332 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
333 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
334 case GL_ETC1_RGB8_OES:
335 case GL_COMPRESSED_R11_EAC:
336 case GL_COMPRESSED_SIGNED_R11_EAC:
337 case GL_COMPRESSED_RG11_EAC:
338 case GL_COMPRESSED_SIGNED_RG11_EAC:
339 case GL_COMPRESSED_RGB8_ETC2:
340 case GL_COMPRESSED_SRGB8_ETC2:
341 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
342 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
343 case GL_COMPRESSED_RGBA8_ETC2_EAC:
344 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
345 return true;
346 case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
347 case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
348 case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
349 case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
350 case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
351 case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
352 case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
353 case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
354 case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
355 case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
356 case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
357 case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
358 case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
359 case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
360 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
361 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
362 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
363 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
364 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
365 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
366 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
367 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
368 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
369 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
370 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
371 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
372 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
373 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
374 return ASTC_SUPPORT;
375 default:
376 return false;
377 }
378 }
379
380 bool IsSizedInternalFormat(GLint internalformat)
381 {
382 switch(internalformat)
383 {
384 case GL_ALPHA8_EXT:
385 case GL_LUMINANCE8_EXT:
386 case GL_LUMINANCE8_ALPHA8_EXT:
387 case GL_ALPHA32F_EXT:
388 case GL_LUMINANCE32F_EXT:
389 case GL_LUMINANCE_ALPHA32F_EXT:
390 case GL_ALPHA16F_EXT:
391 case GL_LUMINANCE16F_EXT:
392 case GL_LUMINANCE_ALPHA16F_EXT:
393 case GL_R8:
394 case GL_R8UI:
395 case GL_R8I:
396 case GL_R16UI:
397 case GL_R16I:
398 case GL_R32UI:
399 case GL_R32I:
400 case GL_RG8:
401 case GL_RG8UI:
402 case GL_RG8I:
403 case GL_RG16UI:
404 case GL_RG16I:
405 case GL_RG32UI:
406 case GL_RG32I:
407 case GL_SRGB8_ALPHA8:
408 case GL_RGB8UI:
409 case GL_RGB8I:
410 case GL_RGB16UI:
411 case GL_RGB16I:
412 case GL_RGB32UI:
413 case GL_RGB32I:
414 case GL_RG8_SNORM:
415 case GL_R8_SNORM:
416 case GL_RGB10_A2:
417 case GL_RGBA8UI:
418 case GL_RGBA8I:
419 case GL_RGB10_A2UI:
420 case GL_RGBA16UI:
421 case GL_RGBA16I:
422 case GL_RGBA32I:
423 case GL_RGBA32UI:
424 case GL_RGBA4:
425 case GL_RGB5_A1:
426 case GL_RGB565:
427 case GL_RGB8:
428 case GL_RGBA8:
429 case GL_BGRA8_EXT: // GL_APPLE_texture_format_BGRA8888
430 case GL_R16F:
431 case GL_RG16F:
432 case GL_R11F_G11F_B10F:
433 case GL_RGB16F:
434 case GL_RGBA16F:
435 case GL_R32F:
436 case GL_RG32F:
437 case GL_RGB32F:
438 case GL_RGBA32F:
439 case GL_DEPTH_COMPONENT24:
440 case GL_DEPTH_COMPONENT32_OES:
441 case GL_DEPTH_COMPONENT32F:
442 case GL_DEPTH32F_STENCIL8:
443 case GL_DEPTH_COMPONENT16:
444 case GL_STENCIL_INDEX8:
445 case GL_DEPTH24_STENCIL8_OES:
446 case GL_RGBA8_SNORM:
447 case GL_SRGB8:
448 case GL_RGB8_SNORM:
449 case GL_RGB9_E5:
450 return true;
451 default:
452 return false;
453 }
454 }
455
456 GLenum ValidateSubImageParams(bool compressed, bool copy, GLenum target, GLint level, GLint xoffset, GLint yoffset,
457 GLsizei width, GLsizei height, GLenum format, GLenum type, Texture *texture)
458 {
459 if(!texture)
460 {
461 return GL_INVALID_OPERATION;
462 }
463
464 GLenum sizedInternalFormat = texture->getFormat(target, level);
465
466 if(compressed)
467 {
468 if(format != sizedInternalFormat)
469 {
470 return GL_INVALID_OPERATION;
471 }
472 }
473 else if(!copy) // CopyTexSubImage doesn't have format/type parameters.
474 {
475 GLenum validationError = ValidateTextureFormatType(format, type, sizedInternalFormat, target);
476 if(validationError != GL_NO_ERROR)
477 {
478 return validationError;
479 }
480 }
481
482 if(compressed)
483 {
484 if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
485 (height % 4 != 0 && height != texture->getHeight(target, 0)))
486 {
487 return GL_INVALID_OPERATION;
488 }
489 }
490
491 if(xoffset + width > texture->getWidth(target, level) ||
492 yoffset + height > texture->getHeight(target, level))
493 {
494 return GL_INVALID_VALUE;
495 }
496
497 return GL_NO_ERROR;
498 }
499
500 GLenum ValidateSubImageParams(bool compressed, bool copy, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
501 GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, Texture *texture)
502 {
503 if(!texture)
504 {
505 return GL_INVALID_OPERATION;
506 }
507
508 if(compressed != texture->isCompressed(target, level))
509 {
510 return GL_INVALID_OPERATION;
511 }
512
513 if(!copy)
514 {
515 GLenum sizedInternalFormat = texture->getFormat(target, level);
516
517 GLenum validationError = ValidateTextureFormatType(format, type, sizedInternalFormat, target);
518 if(validationError != GL_NO_ERROR)
519 {
520 return validationError;
521 }
522 }
523
524 if(compressed)
525 {
526 if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
527 (height % 4 != 0 && height != texture->getHeight(target, 0)) ||
528 (depth % 4 != 0 && depth != texture->getDepth(target, 0)))
529 {
530 return GL_INVALID_OPERATION;
531 }
532 }
533
534 if(xoffset + width > texture->getWidth(target, level) ||
535 yoffset + height > texture->getHeight(target, level) ||
536 zoffset + depth > texture->getDepth(target, level))
537 {
538 return GL_INVALID_VALUE;
539 }
540
541 return GL_NO_ERROR;
542 }
543
544 bool ValidateCopyFormats(GLenum textureFormat, GLenum colorbufferFormat)
545 {
546 ASSERT(!gl::IsUnsizedInternalFormat(textureFormat));
547 ASSERT(!gl::IsUnsizedInternalFormat(colorbufferFormat));
548
549 if(GetColorComponentType(textureFormat) == GL_NONE)
550 {
551 return error(GL_INVALID_ENUM, false);
552 }
553
554 if(GetColorComponentType(colorbufferFormat) != GetColorComponentType(textureFormat))
555 {
556 return error(GL_INVALID_OPERATION, false);
557 }
558
559 if(GetColorEncoding(colorbufferFormat) != GetColorEncoding(textureFormat))
560 {
561 return error(GL_INVALID_OPERATION, false);
562 }
563
564 GLenum baseTexureFormat = gl::GetBaseInternalFormat(textureFormat);
565 GLenum baseColorbufferFormat = gl::GetBaseInternalFormat(colorbufferFormat);
566
567 // [OpenGL ES 2.0.24] table 3.9
568 // [OpenGL ES 3.0.5] table 3.16
569 switch(baseTexureFormat)
570 {
571 case GL_ALPHA:
572 if(baseColorbufferFormat != GL_ALPHA &&
573 baseColorbufferFormat != GL_RGBA &&
574 baseColorbufferFormat != GL_BGRA_EXT) // GL_EXT_texture_format_BGRA8888 / GL_APPLE_texture_format_BGRA8888
575 {
576 return error(GL_INVALID_OPERATION, false);
577 }
578 break;
579 case GL_LUMINANCE_ALPHA:
580 case GL_RGBA:
581 if(baseColorbufferFormat != GL_RGBA &&
582 baseColorbufferFormat != GL_BGRA_EXT) // GL_EXT_texture_format_BGRA8888 / GL_APPLE_texture_format_BGRA8888
583 {
584 return error(GL_INVALID_OPERATION, false);
585 }
586 break;
587 case GL_LUMINANCE:
588 case GL_RED:
589 if(baseColorbufferFormat != GL_RED &&
590 baseColorbufferFormat != GL_RG &&
591 baseColorbufferFormat != GL_RGB &&
592 baseColorbufferFormat != GL_RGBA &&
593 baseColorbufferFormat != GL_BGRA_EXT) // GL_EXT_texture_format_BGRA8888 / GL_APPLE_texture_format_BGRA8888
594 {
595 return error(GL_INVALID_OPERATION, false);
596 }
597 break;
598 case GL_RG:
599 if(baseColorbufferFormat != GL_RG &&
600 baseColorbufferFormat != GL_RGB &&
601 baseColorbufferFormat != GL_RGBA &&
602 baseColorbufferFormat != GL_BGRA_EXT) // GL_EXT_texture_format_BGRA8888 / GL_APPLE_texture_format_BGRA8888
603 {
604 return error(GL_INVALID_OPERATION, false);
605 }
606 break;
607 case GL_RGB:
608 if(baseColorbufferFormat != GL_RGB &&
609 baseColorbufferFormat != GL_RGBA &&
610 baseColorbufferFormat != GL_BGRA_EXT) // GL_EXT_texture_format_BGRA8888 / GL_APPLE_texture_format_BGRA8888
611 {
612 return error(GL_INVALID_OPERATION, false);
613 }
614 break;
615 case GL_DEPTH_COMPONENT:
616 case GL_DEPTH_STENCIL_OES:
617 return error(GL_INVALID_OPERATION, false);
618 case GL_BGRA_EXT: // GL_EXT_texture_format_BGRA8888 nor GL_APPLE_texture_format_BGRA8888 mention the format to be accepted by glCopyTexImage2D.
619 default:
620 return error(GL_INVALID_ENUM, false);
621 }
622
623 return true;
624 }
625
626 bool ValidateReadPixelsFormatType(const Framebuffer *framebuffer, GLenum format, GLenum type)
627 {
628 // GL_NV_read_depth
629 if(format == GL_DEPTH_COMPONENT)
630 {
631 Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
632
633 if(!depthbuffer)
634 {
635 return error(GL_INVALID_OPERATION, false);
636 }
637
638 GLint internalformat = depthbuffer->getFormat();
639
640 switch(type)
641 {
642 case GL_UNSIGNED_SHORT:
643 case GL_UNSIGNED_INT_24_8_OES:
644 switch(internalformat)
645 {
646 case GL_DEPTH_COMPONENT16:
647 case GL_DEPTH_COMPONENT24:
648 case GL_DEPTH_COMPONENT32_OES:
649 case GL_DEPTH24_STENCIL8:
650 break;
651 case GL_DEPTH_COMPONENT32F:
652 case GL_DEPTH32F_STENCIL8:
653 return error(GL_INVALID_OPERATION, false);
654 default:
655 UNREACHABLE(internalformat);
656 return error(GL_INVALID_OPERATION, false);
657 }
658 break;
659 case GL_FLOAT:
660 switch(internalformat)
661 {
662 case GL_DEPTH_COMPONENT32F:
663 case GL_DEPTH32F_STENCIL8:
664 break;
665 case GL_DEPTH_COMPONENT16:
666 case GL_DEPTH_COMPONENT24:
667 case GL_DEPTH_COMPONENT32_OES:
668 case GL_DEPTH24_STENCIL8:
669 return error(GL_INVALID_OPERATION, false);
670 default:
671 UNREACHABLE(internalformat);
672 return error(GL_INVALID_OPERATION, false);
673 }
674 break;
675 default:
676 return error(GL_INVALID_ENUM, false);
677 }
678
679 return true;
680 }
681
682 // GL_NV_read_depth_stencil
683 if(format == GL_DEPTH_STENCIL_OES)
684 {
685 Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
686
687 if(!depthbuffer)
688 {
689 return error(GL_INVALID_OPERATION, false);
690 }
691
692 GLint internalformat = depthbuffer->getFormat();
693
694 switch(type)
695 {
696 case GL_UNSIGNED_INT_24_8_OES:
697 switch(internalformat)
698 {
699 case GL_DEPTH24_STENCIL8:
700 break;
701 case GL_DEPTH32F_STENCIL8:
702 return error(GL_INVALID_OPERATION, false);
703 default:
704 UNREACHABLE(internalformat);
705 return error(GL_INVALID_OPERATION, false);
706 }
707 break;
708 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
709 switch(internalformat)
710 {
711 case GL_DEPTH32F_STENCIL8:
712 break;
713 case GL_DEPTH24_STENCIL8:
714 return error(GL_INVALID_OPERATION, false);
715 default:
716 UNREACHABLE(internalformat);
717 return error(GL_INVALID_OPERATION, false);
718 }
719 break;
720 default:
721 return error(GL_INVALID_ENUM, false);
722 }
723
724 return true;
725 }
726
727 // GL_NV_read_stencil
728 if(format == GL_STENCIL_INDEX_OES)
729 {
730 Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
731
732 if(!stencilbuffer)
733 {
734 return error(GL_INVALID_OPERATION, false);
735 }
736
737 switch(type)
738 {
739 case GL_UNSIGNED_BYTE:
740 break;
741 default:
742 return error(GL_INVALID_ENUM, false);
743 }
744
745 return true;
746 }
747
748 Renderbuffer *colorbuffer = framebuffer->getReadColorbuffer();
749
750 if(!colorbuffer)
751 {
752 return error(GL_INVALID_OPERATION, false);
753 }
754
755 GLint internalformat = colorbuffer->getFormat();
756
757 if(IsNormalizedInteger(internalformat))
758 {
759 // Combination always supported by normalized fixed-point rendering surfaces.
760 if(format == GL_RGBA && type == GL_UNSIGNED_BYTE)
761 {
762 return true;
763 }
764
765 // GL_EXT_read_format_bgra combinations.
766 if(format == GL_BGRA_EXT)
767 {
768 if(type == GL_UNSIGNED_BYTE ||
769 type == GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT ||
770 type == GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT)
771 {
772 return true;
773 }
774 }
775 }
776 else if(IsFloatFormat(internalformat))
777 {
778 // Combination always supported by floating-point rendering surfaces.
779 // Supported in OpenGL ES 2.0 due to GL_EXT_color_buffer_half_float.
780 if(format == GL_RGBA && type == GL_FLOAT)
781 {
782 return true;
783 }
784 }
785 else if(IsSignedNonNormalizedInteger(internalformat))
786 {
787 if(format == GL_RGBA_INTEGER && type == GL_INT)
788 {
789 return true;
790 }
791 }
792 else if(IsUnsignedNonNormalizedInteger(internalformat))
793 {
794 if(format == GL_RGBA_INTEGER && type == GL_UNSIGNED_INT)
795 {
796 return true;
797 }
798 }
799 else UNREACHABLE(internalformat);
800
801 // GL_IMPLEMENTATION_COLOR_READ_FORMAT / GL_IMPLEMENTATION_COLOR_READ_TYPE
802 GLenum implementationReadFormat = GL_NONE;
803 GLenum implementationReadType = GL_NONE;
804 switch(format)
805 {
806 default:
807 implementationReadFormat = framebuffer->getImplementationColorReadFormat();
808 implementationReadType = framebuffer->getImplementationColorReadType();
809 break;
810 case GL_DEPTH_COMPONENT:
811 implementationReadFormat = framebuffer->getDepthReadFormat();
812 implementationReadType = framebuffer->getDepthReadType();
813 break;
814 }
815
816 GLenum coreType = (type == GL_HALF_FLOAT_OES) ? GL_HALF_FLOAT : type;
817
818 if(format == implementationReadFormat && coreType == implementationReadType)
819 {
820 return true;
821 }
822
823 // Additional third combination accepted by OpenGL ES 3.0.
824 if(internalformat == GL_RGB10_A2)
825 {
826 if(format == GL_RGBA && type == GL_UNSIGNED_INT_2_10_10_10_REV)
827 {
828 return true;
829 }
830 }
831
832 return error(GL_INVALID_OPERATION, false);
833 }
834
835 bool IsDepthTexture(GLint format)
836 {
837 return format == GL_DEPTH_COMPONENT16 ||
838 format == GL_DEPTH_COMPONENT24 ||
839 format == GL_DEPTH_COMPONENT32_OES ||
840 format == GL_DEPTH_COMPONENT32F ||
841 format == GL_DEPTH24_STENCIL8 ||
842 format == GL_DEPTH32F_STENCIL8;
843 }
844
845 bool IsStencilTexture(GLint format)
846 {
847 return format == GL_DEPTH24_STENCIL8 ||
848 format == GL_DEPTH32F_STENCIL8 ||
849 format == GL_STENCIL_INDEX8;
850 }
851
852 bool IsCubemapTextureTarget(GLenum target)
853 {
854 return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
855 }
856
857 int CubeFaceIndex(GLenum cubeFace)
858 {
859 switch(cubeFace)
860 {
861 case GL_TEXTURE_CUBE_MAP:
862 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: return 0;
863 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: return 1;
864 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: return 2;
865 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: return 3;
866 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: return 4;
867 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: return 5;
868 default: UNREACHABLE(cubeFace); return 0;
869 }
870 }
871
872 bool IsTexImageTarget(GLenum target)
873 {
874 return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target) || target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_RECTANGLE_ARB;
875 }
876
877 bool IsTextureTarget(GLenum target)
878 {
879 return IsTexImageTarget(target) || target == GL_TEXTURE_3D;
880 }
881
882 GLenum ValidateTextureFormatType(GLenum format, GLenum type, GLint internalformat, GLenum target)
883 {
884 switch(type)
885 {
886 case GL_UNSIGNED_BYTE:
887 case GL_UNSIGNED_SHORT_4_4_4_4:
888 case GL_UNSIGNED_SHORT_5_5_5_1:
889 case GL_UNSIGNED_SHORT_5_6_5:
890 case GL_FLOAT: // GL_OES_texture_float
891 case GL_HALF_FLOAT_OES: // GL_OES_texture_half_float
892 case GL_HALF_FLOAT:
893 case GL_UNSIGNED_INT_24_8: // GL_OES_packed_depth_stencil (GL_UNSIGNED_INT_24_8_EXT)
894 case GL_UNSIGNED_SHORT: // GL_OES_depth_texture
895 case GL_UNSIGNED_INT: // GL_OES_depth_texture
896 break;
897 case GL_BYTE:
898 case GL_SHORT:
899 case GL_INT:
900 case GL_UNSIGNED_INT_2_10_10_10_REV:
901 case GL_UNSIGNED_INT_10F_11F_11F_REV:
902 case GL_UNSIGNED_INT_5_9_9_9_REV:
903 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
904 break;
905 default:
906 return GL_INVALID_ENUM;
907 }
908
909 switch(format)
910 {
911 case GL_ALPHA:
912 case GL_RGB:
913 case GL_RGBA:
914 case GL_LUMINANCE:
915 case GL_LUMINANCE_ALPHA:
916 case GL_BGRA_EXT: // GL_EXT_texture_format_BGRA8888
917 case GL_RED_EXT: // GL_EXT_texture_rg
918 case GL_RG_EXT: // GL_EXT_texture_rg
919 break;
920 case GL_DEPTH_STENCIL: // GL_OES_packed_depth_stencil (GL_DEPTH_STENCIL_OES)
921 case GL_DEPTH_COMPONENT: // GL_OES_depth_texture
922 switch(target)
923 {
924 case GL_TEXTURE_2D:
925 case GL_TEXTURE_2D_ARRAY:
926 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: // GL_OES_depth_texture_cube_map
927 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
928 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
929 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
930 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
931 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
932 break;
933 default:
934 return GL_INVALID_OPERATION;
935 }
936 break;
937 case GL_RED_INTEGER:
938 case GL_RG_INTEGER:
939 case GL_RGB_INTEGER:
940 case GL_RGBA_INTEGER:
941 break;
942 default:
943 return GL_INVALID_ENUM;
944 }
945
946 if((GLenum)internalformat != format)
947 {
948 if(gl::IsUnsizedInternalFormat(internalformat))
949 {
950 return GL_INVALID_OPERATION;
951 }
952
953 if(!IsSizedInternalFormat(internalformat))
954 {
955 return GL_INVALID_VALUE;
956 }
957 }
958
959 if((GLenum)internalformat == format)
960 {
961 // Validate format, type, and unsized internalformat combinations [OpenGL ES 3.0 Table 3.3]
962 switch(format)
963 {
964 case GL_RGBA:
965 switch(type)
966 {
967 case GL_UNSIGNED_BYTE:
968 case GL_UNSIGNED_SHORT_4_4_4_4:
969 case GL_UNSIGNED_SHORT_5_5_5_1:
970 case GL_FLOAT: // GL_OES_texture_float
971 case GL_HALF_FLOAT_OES: // GL_OES_texture_half_float
972 break;
973 default:
974 return GL_INVALID_OPERATION;
975 }
976 break;
977 case GL_RGB:
978 switch(type)
979 {
980 case GL_UNSIGNED_BYTE:
981 case GL_UNSIGNED_SHORT_5_6_5:
982 case GL_FLOAT: // GL_OES_texture_float
983 case GL_HALF_FLOAT_OES: // GL_OES_texture_half_float
984 break;
985 default:
986 return GL_INVALID_OPERATION;
987 }
988 break;
989 case GL_LUMINANCE_ALPHA:
990 case GL_LUMINANCE:
991 case GL_ALPHA:
992 switch(type)
993 {
994 case GL_UNSIGNED_BYTE:
995 case GL_FLOAT: // GL_OES_texture_float
996 case GL_HALF_FLOAT_OES: // GL_OES_texture_half_float
997 break;
998 default:
999 return GL_INVALID_OPERATION;
1000 }
1001 break;
1002 case GL_DEPTH_COMPONENT:
1003 switch(type)
1004 {
1005 case GL_UNSIGNED_SHORT: // GL_OES_depth_texture
1006 case GL_UNSIGNED_INT: // GL_OES_depth_texture
1007 break;
1008 default:
1009 return GL_INVALID_OPERATION;
1010 }
1011 break;
1012 case GL_DEPTH_STENCIL_OES:
1013 switch(type)
1014 {
1015 case GL_UNSIGNED_INT_24_8_OES: // GL_OES_packed_depth_stencil
1016 break;
1017 default:
1018 return GL_INVALID_OPERATION;
1019 }
1020 break;
1021 case GL_RED_EXT:
1022 case GL_RG_EXT:
1023 switch(type)
1024 {
1025 case GL_UNSIGNED_BYTE: // GL_EXT_texture_rg
1026 case GL_FLOAT: // GL_EXT_texture_rg + GL_OES_texture_float
1027 case GL_HALF_FLOAT_OES: // GL_EXT_texture_rg + GL_OES_texture_half_float
1028 break;
1029 default:
1030 return GL_INVALID_OPERATION;
1031 }
1032 break;
1033 case GL_BGRA_EXT:
1034 if(type != GL_UNSIGNED_BYTE) // GL_APPLE_texture_format_BGRA8888 / GL_EXT_texture_format_BGRA8888
1035 {
1036 return GL_INVALID_OPERATION;
1037 }
1038 break;
1039 default:
1040 UNREACHABLE(format);
1041 return GL_INVALID_ENUM;
1042 }
1043
1044 return GL_NO_ERROR;
1045 }
1046
1047 // Validate format, type, and sized internalformat combinations [OpenGL ES 3.0 Table 3.2]
1048 bool validSizedInternalformat = false;
1049 #define VALIDATE_INTERNALFORMAT(...) { GLint validInternalformats[] = {__VA_ARGS__}; for(GLint v : validInternalformats) {if(internalformat == v) validSizedInternalformat = true;} } break;
1050
1051 switch(format)
1052 {
1053 case GL_RGBA:
1054 switch(type)
1055 {
1056 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RGBA8, GL_RGB5_A1, GL_RGBA4, GL_SRGB8_ALPHA8)
1057 case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_RGBA8_SNORM)
1058 case GL_UNSIGNED_SHORT_4_4_4_4: VALIDATE_INTERNALFORMAT(GL_RGBA4)
1059 case GL_UNSIGNED_SHORT_5_5_5_1: VALIDATE_INTERNALFORMAT(GL_RGB5_A1)
1060 case GL_UNSIGNED_INT_2_10_10_10_REV: VALIDATE_INTERNALFORMAT(GL_RGB10_A2, GL_RGB5_A1)
1061 case GL_HALF_FLOAT_OES:
1062 case GL_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_RGBA16F)
1063 case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_RGBA32F, GL_RGBA16F)
1064 default: return GL_INVALID_OPERATION;
1065 }
1066 break;
1067 case GL_RGBA_INTEGER:
1068 switch(type)
1069 {
1070 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RGBA8UI)
1071 case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_RGBA8I)
1072 case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_RGBA16UI)
1073 case GL_SHORT: VALIDATE_INTERNALFORMAT(GL_RGBA16I)
1074 case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_RGBA32UI)
1075 case GL_INT: VALIDATE_INTERNALFORMAT(GL_RGBA32I)
1076 case GL_UNSIGNED_INT_2_10_10_10_REV: VALIDATE_INTERNALFORMAT(GL_RGB10_A2UI)
1077 default: return GL_INVALID_OPERATION;
1078 }
1079 break;
1080 case GL_RGB:
1081 switch(type)
1082 {
1083 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RGB8, GL_RGB565, GL_SRGB8)
1084 case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_RGB8_SNORM)
1085 case GL_UNSIGNED_SHORT_5_6_5: VALIDATE_INTERNALFORMAT(GL_RGB565)
1086 case GL_UNSIGNED_INT_10F_11F_11F_REV: VALIDATE_INTERNALFORMAT(GL_R11F_G11F_B10F)
1087 case GL_UNSIGNED_INT_5_9_9_9_REV: VALIDATE_INTERNALFORMAT(GL_RGB9_E5)
1088 case GL_HALF_FLOAT_OES:
1089 case GL_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_RGB16F, GL_R11F_G11F_B10F, GL_RGB9_E5)
1090 case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_RGB32F, GL_RGB16F, GL_R11F_G11F_B10F, GL_RGB9_E5)
1091 default: return GL_INVALID_OPERATION;
1092 }
1093 break;
1094 case GL_RGB_INTEGER:
1095 switch(type)
1096 {
1097 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RGB8UI)
1098 case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_RGB8I)
1099 case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_RGB16UI)
1100 case GL_SHORT: VALIDATE_INTERNALFORMAT(GL_RGB16I)
1101 case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_RGB32UI)
1102 case GL_INT: VALIDATE_INTERNALFORMAT(GL_RGB32I)
1103 default: return GL_INVALID_OPERATION;
1104 }
1105 break;
1106 case GL_RG:
1107 switch(type)
1108 {
1109 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RG8)
1110 case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_RG8_SNORM)
1111 case GL_HALF_FLOAT_OES:
1112 case GL_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_RG16F)
1113 case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_RG32F, GL_RG16F)
1114 default: return GL_INVALID_OPERATION;
1115 }
1116 break;
1117 case GL_RG_INTEGER:
1118 switch(type)
1119 {
1120 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RG8UI)
1121 case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_RG8I)
1122 case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_RG16UI)
1123 case GL_SHORT: VALIDATE_INTERNALFORMAT(GL_RG16I)
1124 case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_RG32UI)
1125 case GL_INT: VALIDATE_INTERNALFORMAT(GL_RG32I)
1126 default: return GL_INVALID_OPERATION;
1127 }
1128 break;
1129 case GL_RED:
1130 switch(type)
1131 {
1132 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_R8)
1133 case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_R8_SNORM)
1134 case GL_HALF_FLOAT_OES:
1135 case GL_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_R16F)
1136 case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_R32F, GL_R16F)
1137 default: return GL_INVALID_OPERATION;
1138 }
1139 break;
1140 case GL_RED_INTEGER:
1141 switch(type)
1142 {
1143 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_R8UI)
1144 case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_R8I)
1145 case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_R16UI)
1146 case GL_SHORT: VALIDATE_INTERNALFORMAT(GL_R16I)
1147 case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_R32UI)
1148 case GL_INT: VALIDATE_INTERNALFORMAT(GL_R32I)
1149 default: return GL_INVALID_OPERATION;
1150 }
1151 break;
1152 case GL_DEPTH_COMPONENT:
1153 switch(type)
1154 {
1155 case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT16)
1156 case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT16)
1157 case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT32F)
1158 default: return GL_INVALID_OPERATION;
1159 }
1160 break;
1161 case GL_DEPTH_STENCIL:
1162 switch(type)
1163 {
1164 case GL_UNSIGNED_INT_24_8: VALIDATE_INTERNALFORMAT(GL_DEPTH24_STENCIL8)
1165 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: VALIDATE_INTERNALFORMAT(GL_DEPTH32F_STENCIL8)
1166 default: return GL_INVALID_OPERATION;
1167 }
1168 break;
1169 case GL_LUMINANCE_ALPHA:
1170 switch(type)
1171 {
1172 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_LUMINANCE8_ALPHA8_EXT)
1173 case GL_HALF_FLOAT_OES:
1174 case GL_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_LUMINANCE_ALPHA16F_EXT)
1175 case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA16F_EXT)
1176 default:
1177 return GL_INVALID_OPERATION;
1178 }
1179 break;
1180 case GL_LUMINANCE:
1181 switch(type)
1182 {
1183 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_LUMINANCE8_EXT)
1184 case GL_HALF_FLOAT_OES:
1185 case GL_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_LUMINANCE16F_EXT)
1186 case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_LUMINANCE32F_EXT, GL_LUMINANCE16F_EXT)
1187 default:
1188 return GL_INVALID_OPERATION;
1189 }
1190 break;
1191 case GL_ALPHA:
1192 switch(type)
1193 {
1194 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_ALPHA8_EXT)
1195 case GL_HALF_FLOAT_OES:
1196 case GL_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_ALPHA16F_EXT)
1197 case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_ALPHA32F_EXT, GL_ALPHA16F_EXT)
1198 default:
1199 return GL_INVALID_OPERATION;
1200 }
1201 break;
1202 case GL_BGRA_EXT: // GL_APPLE_texture_format_BGRA8888
1203 switch(type)
1204 {
1205 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_BGRA8_EXT)
1206 default: return GL_INVALID_OPERATION;
1207 }
1208 break;
1209 default:
1210 UNREACHABLE(format);
1211 return GL_INVALID_ENUM;
1212 }
1213
1214 #undef VALIDATE_INTERNALFORMAT
1215
1216 if(!validSizedInternalformat)
1217 {
1218 return GL_INVALID_OPERATION;
1219 }
1220
1221 return GL_NO_ERROR;
1222 }
1223
1224 size_t GetTypeSize(GLenum type)
1225 {
1226 switch(type)
1227 {
1228 case GL_BYTE:
1229 case GL_UNSIGNED_BYTE:
1230 return 1;
1231 case GL_UNSIGNED_SHORT_4_4_4_4:
1232 case GL_UNSIGNED_SHORT_5_5_5_1:
1233 case GL_UNSIGNED_SHORT_5_6_5:
1234 case GL_UNSIGNED_SHORT:
1235 case GL_SHORT:
1236 case GL_HALF_FLOAT:
1237 case GL_HALF_FLOAT_OES:
1238 return 2;
1239 case GL_FLOAT:
1240 case GL_UNSIGNED_INT_24_8:
1241 case GL_UNSIGNED_INT:
1242 case GL_INT:
1243 case GL_UNSIGNED_INT_2_10_10_10_REV:
1244 case GL_UNSIGNED_INT_10F_11F_11F_REV:
1245 case GL_UNSIGNED_INT_5_9_9_9_REV:
1246 return 4;
1247 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
1248 return 8;
1249 default:
1250 UNREACHABLE(type);
1251 break;
1252 }
1253
1254 return 1;
1255 }
1256
1257 sw::Format ConvertReadFormatType(GLenum format, GLenum type)
1258 {
1259 switch(format)
1260 {
1261 case GL_LUMINANCE:
1262 switch(type)
1263 {
1264 case GL_UNSIGNED_BYTE: return sw::FORMAT_L8;
1265 case GL_HALF_FLOAT: return sw::FORMAT_L16F;
1266 case GL_HALF_FLOAT_OES: return sw::FORMAT_L16F;
1267 case GL_FLOAT: return sw::FORMAT_L32F;
1268 default: UNREACHABLE(type);
1269 }
1270 break;
1271 case GL_LUMINANCE_ALPHA:
1272 switch(type)
1273 {
1274 case GL_UNSIGNED_BYTE: return sw::FORMAT_A8L8;
1275 case GL_HALF_FLOAT: return sw::FORMAT_A16L16F;
1276 case GL_HALF_FLOAT_OES: return sw::FORMAT_A16L16F;
1277 case GL_FLOAT: return sw::FORMAT_A32L32F;
1278 default: UNREACHABLE(type);
1279 }
1280 break;
1281 case GL_RGBA:
1282 switch(type)
1283 {
1284 case GL_UNSIGNED_BYTE: return sw::FORMAT_A8B8G8R8;
1285 case GL_UNSIGNED_SHORT_4_4_4_4: return sw::FORMAT_R4G4B4A4;
1286 case GL_UNSIGNED_SHORT_5_5_5_1: return sw::FORMAT_R5G5B5A1;
1287 case GL_HALF_FLOAT: return sw::FORMAT_A16B16G16R16F;
1288 case GL_HALF_FLOAT_OES: return sw::FORMAT_A16B16G16R16F;
1289 case GL_FLOAT: return sw::FORMAT_A32B32G32R32F;
1290 case GL_UNSIGNED_INT_2_10_10_10_REV_EXT: return sw::FORMAT_A2B10G10R10;
1291 default: UNREACHABLE(type);
1292 }
1293 break;
1294 case GL_BGRA_EXT:
1295 switch(type)
1296 {
1297 case GL_UNSIGNED_BYTE: return sw::FORMAT_A8R8G8B8;
1298 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: return sw::FORMAT_A4R4G4B4;
1299 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: return sw::FORMAT_A1R5G5B5;
1300 default: UNREACHABLE(type);
1301 }
1302 break;
1303 case GL_RGB:
1304 switch(type)
1305 {
1306 case GL_UNSIGNED_BYTE: return sw::FORMAT_B8G8R8;
1307 case GL_UNSIGNED_SHORT_5_6_5: return sw::FORMAT_R5G6B5;
1308 case GL_HALF_FLOAT: return sw::FORMAT_B16G16R16F;
1309 case GL_HALF_FLOAT_OES: return sw::FORMAT_B16G16R16F;
1310 case GL_FLOAT: return sw::FORMAT_B32G32R32F;
1311 default: UNREACHABLE(type);
1312 }
1313 break;
1314 case GL_RG:
1315 switch(type)
1316 {
1317 case GL_UNSIGNED_BYTE: return sw::FORMAT_G8R8;
1318 case GL_HALF_FLOAT: return sw::FORMAT_G16R16F;
1319 case GL_HALF_FLOAT_OES: return sw::FORMAT_G16R16F;
1320 case GL_FLOAT: return sw::FORMAT_G32R32F;
1321 default: UNREACHABLE(type);
1322 }
1323 break;
1324 case GL_RED:
1325 switch(type)
1326 {
1327 case GL_UNSIGNED_BYTE: return sw::FORMAT_R8;
1328 case GL_HALF_FLOAT: return sw::FORMAT_R16F;
1329 case GL_HALF_FLOAT_OES: return sw::FORMAT_R16F;
1330 case GL_FLOAT: return sw::FORMAT_R32F;
1331 default: UNREACHABLE(type);
1332 }
1333 break;
1334 case GL_ALPHA:
1335 switch(type)
1336 {
1337 case GL_UNSIGNED_BYTE: return sw::FORMAT_A8;
1338 case GL_HALF_FLOAT: return sw::FORMAT_A16F;
1339 case GL_HALF_FLOAT_OES: return sw::FORMAT_A16F;
1340 case GL_FLOAT: return sw::FORMAT_A32F;
1341 default: UNREACHABLE(type);
1342 }
1343 break;
1344 case GL_RED_INTEGER:
1345 switch(type)
1346 {
1347 case GL_INT: return sw::FORMAT_R32I;
1348 case GL_UNSIGNED_INT: return sw::FORMAT_R32UI;
1349 default: UNREACHABLE(type);
1350 }
1351 break;
1352 case GL_RG_INTEGER:
1353 switch(type)
1354 {
1355 case GL_INT: return sw::FORMAT_G32R32I;
1356 case GL_UNSIGNED_INT: return sw::FORMAT_G32R32UI;
1357 default: UNREACHABLE(type);
1358 }
1359 break;
1360 case GL_RGB_INTEGER:
1361 switch(type)
1362 {
1363 case GL_INT: return sw::FORMAT_X32B32G32R32I;
1364 case GL_UNSIGNED_INT: return sw::FORMAT_X32B32G32R32UI;
1365 default: UNREACHABLE(type);
1366 }
1367 break;
1368 case GL_RGBA_INTEGER:
1369 switch(type)
1370 {
1371 case GL_INT: return sw::FORMAT_A32B32G32R32I;
1372 case GL_UNSIGNED_INT: return sw::FORMAT_A32B32G32R32UI;
1373 case GL_UNSIGNED_INT_2_10_10_10_REV: return sw::FORMAT_A2B10G10R10UI;
1374 default: UNREACHABLE(type);
1375 }
1376 break;
1377 case GL_DEPTH_COMPONENT:
1378 switch(type)
1379 {
1380 case GL_UNSIGNED_SHORT: return sw::FORMAT_D16;
1381 case GL_UNSIGNED_INT_24_8_OES: return sw::FORMAT_D24X8;
1382 case GL_FLOAT: return sw::FORMAT_D32F_LOCKABLE;
1383 default: UNREACHABLE(type);
1384 }
1385 break;
1386 case GL_STENCIL_INDEX_OES:
1387 switch(type)
1388 {
1389 case GL_UNSIGNED_BYTE: return sw::FORMAT_S8;
1390 default: UNREACHABLE(type);
1391 }
1392 break;
1393 case GL_DEPTH_STENCIL_OES: // Cannot be read as one format. Handled separately.
1394 default:
1395 UNREACHABLE(format);
1396 break;
1397 }
1398
1399 return sw::FORMAT_NULL;
1400 }
1401
1402 bool IsColorRenderable(GLint internalformat)
1403 {
1404 if(IsCompressed(internalformat))
1405 {
1406 return false;
1407 }
1408
1409 switch(internalformat)
1410 {
1411 case GL_RGBA4:
1412 case GL_RGB5_A1:
1413 case GL_RGB565:
1414 case GL_R8:
1415 case GL_RG8:
1416 case GL_RGB8:
1417 case GL_RGBA8:
1418 case GL_R16F:
1419 case GL_RG16F:
1420 case GL_RGB16F:
1421 case GL_RGBA16F:
1422 case GL_R32F:
1423 case GL_RG32F:
1424 case GL_RGB32F:
1425 case GL_RGBA32F: // GL_EXT_color_buffer_float, OpenGL ES 3.0+ only.
1426 case GL_BGRA8_EXT: // GL_EXT_texture_format_BGRA8888
1427 case GL_R8UI:
1428 case GL_R8I:
1429 case GL_R16UI:
1430 case GL_R16I:
1431 case GL_R32UI:
1432 case GL_R32I:
1433 case GL_RG8UI:
1434 case GL_RG8I:
1435 case GL_RG16UI:
1436 case GL_RG16I:
1437 case GL_RG32UI:
1438 case GL_RG32I:
1439 case GL_SRGB8_ALPHA8:
1440 case GL_RGB10_A2:
1441 case GL_RGBA8UI:
1442 case GL_RGBA8I:
1443 case GL_RGB10_A2UI:
1444 case GL_RGBA16UI:
1445 case GL_RGBA16I:
1446 case GL_RGBA32I:
1447 case GL_RGBA32UI:
1448 case GL_R11F_G11F_B10F:
1449 return true;
1450 case GL_R8_SNORM:
1451 case GL_RG8_SNORM:
1452 case GL_RGB8_SNORM:
1453 case GL_RGBA8_SNORM:
1454 case GL_ALPHA8_EXT:
1455 case GL_LUMINANCE8_EXT:
1456 case GL_LUMINANCE8_ALPHA8_EXT:
1457 case GL_ALPHA32F_EXT:
1458 case GL_LUMINANCE32F_EXT:
1459 case GL_LUMINANCE_ALPHA32F_EXT:
1460 case GL_ALPHA16F_EXT:
1461 case GL_LUMINANCE16F_EXT:
1462 case GL_LUMINANCE_ALPHA16F_EXT:
1463 case GL_DEPTH_COMPONENT24:
1464 case GL_DEPTH_COMPONENT32_OES:
1465 case GL_DEPTH_COMPONENT32F:
1466 case GL_DEPTH32F_STENCIL8:
1467 case GL_DEPTH_COMPONENT16:
1468 case GL_STENCIL_INDEX8:
1469 case GL_DEPTH24_STENCIL8_OES:
1470 return false;
1471 default:
1472 UNIMPLEMENTED();
1473 }
1474
1475 return false;
1476 }
1477
1478 bool IsDepthRenderable(GLint internalformat)
1479 {
1480 if(IsCompressed(internalformat))
1481 {
1482 return false;
1483 }
1484
1485 switch(internalformat)
1486 {
1487 case GL_DEPTH_COMPONENT24:
1488 case GL_DEPTH_COMPONENT16:
1489 case GL_DEPTH24_STENCIL8_OES: // GL_OES_packed_depth_stencil
1490 case GL_DEPTH_COMPONENT32_OES: // GL_OES_depth32
1491 case GL_DEPTH32F_STENCIL8:
1492 case GL_DEPTH_COMPONENT32F:
1493 return true;
1494 case GL_STENCIL_INDEX8:
1495 case GL_R8:
1496 case GL_R8UI:
1497 case GL_R8I:
1498 case GL_R16UI:
1499 case GL_R16I:
1500 case GL_R32UI:
1501 case GL_R32I:
1502 case GL_RG8:
1503 case GL_RG8UI:
1504 case GL_RG8I:
1505 case GL_RG16UI:
1506 case GL_RG16I:
1507 case GL_RG32UI:
1508 case GL_RG32I:
1509 case GL_SRGB8_ALPHA8:
1510 case GL_RGB10_A2:
1511 case GL_RGBA8UI:
1512 case GL_RGBA8I:
1513 case GL_RGB10_A2UI:
1514 case GL_RGBA16UI:
1515 case GL_RGBA16I:
1516 case GL_RGBA32I:
1517 case GL_RGBA32UI:
1518 case GL_RGBA4:
1519 case GL_RGB5_A1:
1520 case GL_RGB565:
1521 case GL_RGB8:
1522 case GL_RGBA8:
1523 case GL_RED:
1524 case GL_RG:
1525 case GL_RGB:
1526 case GL_RGBA:
1527 case GL_R16F:
1528 case GL_RG16F:
1529 case GL_R11F_G11F_B10F:
1530 case GL_RGB16F:
1531 case GL_RGBA16F:
1532 case GL_R32F:
1533 case GL_RG32F:
1534 case GL_RGB32F:
1535 case GL_RGBA32F:
1536 case GL_R8_SNORM:
1537 case GL_RG8_SNORM:
1538 case GL_RGB8_SNORM:
1539 case GL_RGBA8_SNORM:
1540 return false;
1541 default:
1542 UNIMPLEMENTED();
1543 }
1544
1545 return false;
1546 }
1547
1548 bool IsStencilRenderable(GLint internalformat)
1549 {
1550 if(IsCompressed(internalformat))
1551 {
1552 return false;
1553 }
1554
1555 switch(internalformat)
1556 {
1557 case GL_STENCIL_INDEX8:
1558 case GL_DEPTH24_STENCIL8_OES:
1559 case GL_DEPTH32F_STENCIL8:
1560 return true;
1561 case GL_R8:
1562 case GL_R8UI:
1563 case GL_R8I:
1564 case GL_R16UI:
1565 case GL_R16I:
1566 case GL_R32UI:
1567 case GL_R32I:
1568 case GL_RG8:
1569 case GL_RG8UI:
1570 case GL_RG8I:
1571 case GL_RG16UI:
1572 case GL_RG16I:
1573 case GL_RG32UI:
1574 case GL_RG32I:
1575 case GL_SRGB8_ALPHA8:
1576 case GL_RGB10_A2:
1577 case GL_RGBA8UI:
1578 case GL_RGBA8I:
1579 case GL_RGB10_A2UI:
1580 case GL_RGBA16UI:
1581 case GL_RGBA16I:
1582 case GL_RGBA32I:
1583 case GL_RGBA32UI:
1584 case GL_RGBA4:
1585 case GL_RGB5_A1:
1586 case GL_RGB565:
1587 case GL_RGB8:
1588 case GL_RGBA8:
1589 case GL_RED:
1590 case GL_RG:
1591 case GL_RGB:
1592 case GL_RGBA:
1593 case GL_R16F:
1594 case GL_RG16F:
1595 case GL_R11F_G11F_B10F:
1596 case GL_RGB16F:
1597 case GL_RGBA16F:
1598 case GL_R32F:
1599 case GL_RG32F:
1600 case GL_RGB32F:
1601 case GL_RGBA32F:
1602 case GL_DEPTH_COMPONENT16:
1603 case GL_DEPTH_COMPONENT24:
1604 case GL_DEPTH_COMPONENT32_OES:
1605 case GL_DEPTH_COMPONENT32F:
1606 case GL_R8_SNORM:
1607 case GL_RG8_SNORM:
1608 case GL_RGB8_SNORM:
1609 case GL_RGBA8_SNORM:
1610 return false;
1611 default:
1612 UNIMPLEMENTED();
1613 }
1614
1615 return false;
1616 }
1617
1618 bool IsMipmappable(GLint internalformat)
1619 {
1620 if(internalformat == GL_NONE)
1621 {
1622 return true; // Image unspecified. Not an error.
1623 }
1624
1625 if(IsNonNormalizedInteger(internalformat))
1626 {
1627 return false;
1628 }
1629
1630 switch(internalformat)
1631 {
1632 case GL_ALPHA8_EXT:
1633 case GL_LUMINANCE8_EXT:
1634 case GL_LUMINANCE8_ALPHA8_EXT:
1635 case GL_ALPHA32F_EXT:
1636 case GL_LUMINANCE32F_EXT:
1637 case GL_LUMINANCE_ALPHA32F_EXT:
1638 case GL_ALPHA16F_EXT:
1639 case GL_LUMINANCE16F_EXT:
1640 case GL_LUMINANCE_ALPHA16F_EXT:
1641 return true;
1642 default:
1643 return IsColorRenderable(internalformat);
1644 }
1645 }
1646
1647 GLuint GetAlphaSize(GLint internalformat)
1648 {
1649 switch(internalformat)
1650 {
1651 case GL_NONE: return 0;
1652 case GL_RGBA4: return 4;
1653 case GL_RGB5_A1: return 1;
1654 case GL_RGB565: return 0;
1655 case GL_R8: return 0;
1656 case GL_RG8: return 0;
1657 case GL_RGB8: return 0;
1658 case GL_RGBA8: return 8;
1659 case GL_R16F: return 0;
1660 case GL_RG16F: return 0;
1661 case GL_RGB16F: return 0;
1662 case GL_RGBA16F: return 16;
1663 case GL_R32F: return 0;
1664 case GL_RG32F: return 0;
1665 case GL_RGB32F: return 0;
1666 case GL_RGBA32F: return 32;
1667 case GL_BGRA8_EXT: return 8;
1668 case GL_R8UI: return 0;
1669 case GL_R8I: return 0;
1670 case GL_R16UI: return 0;
1671 case GL_R16I: return 0;
1672 case GL_R32UI: return 0;
1673 case GL_R32I: return 0;
1674 case GL_RG8UI: return 0;
1675 case GL_RG8I: return 0;
1676 case GL_RG16UI: return 0;
1677 case GL_RG16I: return 0;
1678 case GL_RG32UI: return 0;
1679 case GL_RG32I: return 0;
1680 case GL_SRGB8_ALPHA8: return 8;
1681 case GL_RGB10_A2: return 2;
1682 case GL_RGBA8UI: return 8;
1683 case GL_RGBA8I: return 8;
1684 case GL_RGB10_A2UI: return 2;
1685 case GL_RGBA16UI: return 16;
1686 case GL_RGBA16I: return 16;
1687 case GL_RGBA32I: return 32;
1688 case GL_RGBA32UI: return 32;
1689 case GL_R11F_G11F_B10F: return 0;
1690 default:
1691 // UNREACHABLE(internalformat);
1692 return 0;
1693 }
1694 }
1695
1696 GLuint GetRedSize(GLint internalformat)
1697 {
1698 switch(internalformat)
1699 {
1700 case GL_NONE: return 0;
1701 case GL_RGBA4: return 4;
1702 case GL_RGB5_A1: return 5;
1703 case GL_RGB565: return 5;
1704 case GL_R8: return 8;
1705 case GL_RG8: return 8;
1706 case GL_RGB8: return 8;
1707 case GL_RGBA8: return 8;
1708 case GL_R16F: return 16;
1709 case GL_RG16F: return 16;
1710 case GL_RGB16F: return 16;
1711 case GL_RGBA16F: return 16;
1712 case GL_R32F: return 32;
1713 case GL_RG32F: return 32;
1714 case GL_RGB32F: return 32;
1715 case GL_RGBA32F: return 32;
1716 case GL_BGRA8_EXT: return 8;
1717 case GL_R8UI: return 8;
1718 case GL_R8I: return 8;
1719 case GL_R16UI: return 16;
1720 case GL_R16I: return 16;
1721 case GL_R32UI: return 32;
1722 case GL_R32I: return 32;
1723 case GL_RG8UI: return 8;
1724 case GL_RG8I: return 8;
1725 case GL_RG16UI: return 16;
1726 case GL_RG16I: return 16;
1727 case GL_RG32UI: return 32;
1728 case GL_RG32I: return 32;
1729 case GL_SRGB8_ALPHA8: return 8;
1730 case GL_RGB10_A2: return 10;
1731 case GL_RGBA8UI: return 8;
1732 case GL_RGBA8I: return 8;
1733 case GL_RGB10_A2UI: return 10;
1734 case GL_RGBA16UI: return 16;
1735 case GL_RGBA16I: return 16;
1736 case GL_RGBA32I: return 32;
1737 case GL_RGBA32UI: return 32;
1738 case GL_R11F_G11F_B10F: return 11;
1739 default:
1740 // UNREACHABLE(internalformat);
1741 return 0;
1742 }
1743 }
1744
1745 GLuint GetGreenSize(GLint internalformat)
1746 {
1747 switch(internalformat)
1748 {
1749 case GL_NONE: return 0;
1750 case GL_RGBA4: return 4;
1751 case GL_RGB5_A1: return 5;
1752 case GL_RGB565: return 6;
1753 case GL_R8: return 0;
1754 case GL_RG8: return 8;
1755 case GL_RGB8: return 8;
1756 case GL_RGBA8: return 8;
1757 case GL_R16F: return 0;
1758 case GL_RG16F: return 16;
1759 case GL_RGB16F: return 16;
1760 case GL_RGBA16F: return 16;
1761 case GL_R32F: return 0;
1762 case GL_RG32F: return 32;
1763 case GL_RGB32F: return 32;
1764 case GL_RGBA32F: return 32;
1765 case GL_BGRA8_EXT: return 8;
1766 case GL_R8UI: return 0;
1767 case GL_R8I: return 0;
1768 case GL_R16UI: return 0;
1769 case GL_R16I: return 0;
1770 case GL_R32UI: return 0;
1771 case GL_R32I: return 0;
1772 case GL_RG8UI: return 8;
1773 case GL_RG8I: return 8;
1774 case GL_RG16UI: return 16;
1775 case GL_RG16I: return 16;
1776 case GL_RG32UI: return 32;
1777 case GL_RG32I: return 32;
1778 case GL_SRGB8_ALPHA8: return 8;
1779 case GL_RGB10_A2: return 10;
1780 case GL_RGBA8UI: return 8;
1781 case GL_RGBA8I: return 8;
1782 case GL_RGB10_A2UI: return 10;
1783 case GL_RGBA16UI: return 16;
1784 case GL_RGBA16I: return 16;
1785 case GL_RGBA32I: return 32;
1786 case GL_RGBA32UI: return 32;
1787 case GL_R11F_G11F_B10F: return 11;
1788 default:
1789 // UNREACHABLE(internalformat);
1790 return 0;
1791 }
1792 }
1793
1794 GLuint GetBlueSize(GLint internalformat)
1795 {
1796 switch(internalformat)
1797 {
1798 case GL_NONE: return 0;
1799 case GL_RGBA4: return 4;
1800 case GL_RGB5_A1: return 5;
1801 case GL_RGB565: return 5;
1802 case GL_R8: return 0;
1803 case GL_RG8: return 0;
1804 case GL_RGB8: return 8;
1805 case GL_RGBA8: return 8;
1806 case GL_R16F: return 0;
1807 case GL_RG16F: return 0;
1808 case GL_RGB16F: return 16;
1809 case GL_RGBA16F: return 16;
1810 case GL_R32F: return 0;
1811 case GL_RG32F: return 0;
1812 case GL_RGB32F: return 32;
1813 case GL_RGBA32F: return 32;
1814 case GL_BGRA8_EXT: return 8;
1815 case GL_R8UI: return 0;
1816 case GL_R8I: return 0;
1817 case GL_R16UI: return 0;
1818 case GL_R16I: return 0;
1819 case GL_R32UI: return 0;
1820 case GL_R32I: return 0;
1821 case GL_RG8UI: return 0;
1822 case GL_RG8I: return 0;
1823 case GL_RG16UI: return 0;
1824 case GL_RG16I: return 0;
1825 case GL_RG32UI: return 0;
1826 case GL_RG32I: return 0;
1827 case GL_SRGB8_ALPHA8: return 8;
1828 case GL_RGB10_A2: return 10;
1829 case GL_RGBA8UI: return 8;
1830 case GL_RGBA8I: return 8;
1831 case GL_RGB10_A2UI: return 10;
1832 case GL_RGBA16UI: return 16;
1833 case GL_RGBA16I: return 16;
1834 case GL_RGBA32I: return 32;
1835 case GL_RGBA32UI: return 32;
1836 case GL_R11F_G11F_B10F: return 10;
1837 default:
1838 // UNREACHABLE(internalformat);
1839 return 0;
1840 }
1841 }
1842
1843 GLuint GetDepthSize(GLint internalformat)
1844 {
1845 switch(internalformat)
1846 {
1847 case GL_STENCIL_INDEX8: return 0;
1848 case GL_DEPTH_COMPONENT16: return 16;
1849 case GL_DEPTH_COMPONENT24: return 24;
1850 case GL_DEPTH_COMPONENT32_OES: return 32;
1851 case GL_DEPTH_COMPONENT32F: return 32;
1852 case GL_DEPTH24_STENCIL8: return 24;
1853 case GL_DEPTH32F_STENCIL8: return 32;
1854 default:
1855 // UNREACHABLE(internalformat);
1856 return 0;
1857 }
1858 }
1859
1860 GLuint GetStencilSize(GLint internalformat)
1861 {
1862 switch(internalformat)
1863 {
1864 case GL_STENCIL_INDEX8: return 8;
1865 case GL_DEPTH_COMPONENT16: return 0;
1866 case GL_DEPTH_COMPONENT24: return 0;
1867 case GL_DEPTH_COMPONENT32_OES: return 0;
1868 case GL_DEPTH_COMPONENT32F: return 0;
1869 case GL_DEPTH24_STENCIL8: return 8;
1870 case GL_DEPTH32F_STENCIL8: return 8;
1871 default:
1872 // UNREACHABLE(internalformat);
1873 return 0;
1874 }
1875 }
1876
1877 GLenum GetColorComponentType(GLint internalformat)
1878 {
1879 switch(internalformat)
1880 {
1881 case GL_ALPHA8_EXT:
1882 case GL_LUMINANCE8_ALPHA8_EXT:
1883 case GL_LUMINANCE8_EXT:
1884 case GL_R8:
1885 case GL_RG8:
1886 case GL_SRGB8_ALPHA8:
1887 case GL_RGB10_A2:
1888 case GL_RGBA4:
1889 case GL_RGB5_A1:
1890 case GL_RGB565:
1891 case GL_RGB8:
1892 case GL_RGBA8:
1893 case GL_SRGB8:
1894 case GL_BGRA8_EXT:
1895 return GL_UNSIGNED_NORMALIZED;
1896 case GL_R8_SNORM:
1897 case GL_RG8_SNORM:
1898 case GL_RGB8_SNORM:
1899 case GL_RGBA8_SNORM:
1900 return GL_SIGNED_NORMALIZED;
1901 case GL_R8UI:
1902 case GL_R16UI:
1903 case GL_R32UI:
1904 case GL_RG8UI:
1905 case GL_RG16UI:
1906 case GL_RG32UI:
1907 case GL_RGB8UI:
1908 case GL_RGB16UI:
1909 case GL_RGB32UI:
1910 case GL_RGB10_A2UI:
1911 case GL_RGBA16UI:
1912 case GL_RGBA32UI:
1913 case GL_RGBA8UI:
1914 return GL_UNSIGNED_INT;
1915 case GL_R8I:
1916 case GL_R16I:
1917 case GL_R32I:
1918 case GL_RG8I:
1919 case GL_RG16I:
1920 case GL_RG32I:
1921 case GL_RGB8I:
1922 case GL_RGB16I:
1923 case GL_RGB32I:
1924 case GL_RGBA8I:
1925 case GL_RGBA16I:
1926 case GL_RGBA32I:
1927 return GL_INT;
1928 case GL_ALPHA32F_EXT:
1929 case GL_LUMINANCE32F_EXT:
1930 case GL_LUMINANCE_ALPHA32F_EXT:
1931 case GL_ALPHA16F_EXT:
1932 case GL_LUMINANCE16F_EXT:
1933 case GL_LUMINANCE_ALPHA16F_EXT:
1934 case GL_R16F:
1935 case GL_RG16F:
1936 case GL_R11F_G11F_B10F:
1937 case GL_RGB16F:
1938 case GL_RGBA16F:
1939 case GL_R32F:
1940 case GL_RG32F:
1941 case GL_RGB32F:
1942 case GL_RGBA32F:
1943 case GL_RGB9_E5:
1944 return GL_FLOAT;
1945 default:
1946 // UNREACHABLE(internalformat);
1947 return GL_NONE;
1948 }
1949 }
1950
1951 GLenum GetComponentType(GLint internalformat, GLenum attachment)
1952 {
1953 // Can be one of GL_FLOAT, GL_INT, GL_UNSIGNED_INT, GL_SIGNED_NORMALIZED, or GL_UNSIGNED_NORMALIZED
1954 switch(attachment)
1955 {
1956 case GL_COLOR_ATTACHMENT0:
1957 case GL_COLOR_ATTACHMENT1:
1958 case GL_COLOR_ATTACHMENT2:
1959 case GL_COLOR_ATTACHMENT3:
1960 case GL_COLOR_ATTACHMENT4:
1961 case GL_COLOR_ATTACHMENT5:
1962 case GL_COLOR_ATTACHMENT6:
1963 case GL_COLOR_ATTACHMENT7:
1964 case GL_COLOR_ATTACHMENT8:
1965 case GL_COLOR_ATTACHMENT9:
1966 case GL_COLOR_ATTACHMENT10:
1967 case GL_COLOR_ATTACHMENT11:
1968 case GL_COLOR_ATTACHMENT12:
1969 case GL_COLOR_ATTACHMENT13:
1970 case GL_COLOR_ATTACHMENT14:
1971 case GL_COLOR_ATTACHMENT15:
1972 case GL_COLOR_ATTACHMENT16:
1973 case GL_COLOR_ATTACHMENT17:
1974 case GL_COLOR_ATTACHMENT18:
1975 case GL_COLOR_ATTACHMENT19:
1976 case GL_COLOR_ATTACHMENT20:
1977 case GL_COLOR_ATTACHMENT21:
1978 case GL_COLOR_ATTACHMENT22:
1979 case GL_COLOR_ATTACHMENT23:
1980 case GL_COLOR_ATTACHMENT24:
1981 case GL_COLOR_ATTACHMENT25:
1982 case GL_COLOR_ATTACHMENT26:
1983 case GL_COLOR_ATTACHMENT27:
1984 case GL_COLOR_ATTACHMENT28:
1985 case GL_COLOR_ATTACHMENT29:
1986 case GL_COLOR_ATTACHMENT30:
1987 case GL_COLOR_ATTACHMENT31:
1988 return GetColorComponentType(internalformat);
1989 case GL_DEPTH_ATTACHMENT:
1990 case GL_STENCIL_ATTACHMENT:
1991 // Only color buffers may have integer components.
1992 return GL_FLOAT;
1993 default:
1994 UNREACHABLE(attachment);
1995 return GL_NONE;
1996 }
1997 }
1998
1999 bool IsNormalizedInteger(GLint internalformat)
2000 {
2001 GLenum type = GetColorComponentType(internalformat);
2002
2003 return type == GL_UNSIGNED_NORMALIZED || type == GL_SIGNED_NORMALIZED;
2004 }
2005
2006 bool IsNonNormalizedInteger(GLint internalformat)
2007 {
2008 GLenum type = GetColorComponentType(internalformat);
2009
2010 return type == GL_UNSIGNED_INT || type == GL_INT;
2011 }
2012
2013 bool IsFloatFormat(GLint internalformat)
2014 {
2015 return GetColorComponentType(internalformat) == GL_FLOAT;
2016 }
2017
2018 bool IsSignedNonNormalizedInteger(GLint internalformat)
2019 {
2020 return GetColorComponentType(internalformat) == GL_INT;
2021 }
2022
2023 bool IsUnsignedNonNormalizedInteger(GLint internalformat)
2024 {
2025 return GetColorComponentType(internalformat) == GL_UNSIGNED_INT;
2026 }
2027
2028 GLenum GetColorEncoding(GLint internalformat)
2029 {
2030 switch(internalformat)
2031 {
2032 case GL_SRGB8:
2033 case GL_SRGB8_ALPHA8:
2034 return GL_SRGB;
2035 default:
2036 // [OpenGL ES 3.0.5] section 6.1.13 page 242:
2037 // If attachment is not a color attachment, or no data storage or texture image
2038 // has been specified for the attachment, params will contain the value LINEAR.
2039 return GL_LINEAR;
2040 }
2041 }
2042
2043 std::string ParseUniformName(const std::string &name, unsigned int *outSubscript)
2044 {
2045 // Strip any trailing array operator and retrieve the subscript
2046 size_t open = name.find_last_of('[');
2047 size_t close = name.find_last_of(']');
2048 bool hasIndex = (open != std::string::npos) && (close == name.length() - 1);
2049 if(!hasIndex)
2050 {
2051 if(outSubscript)
2052 {
2053 *outSubscript = GL_INVALID_INDEX;
2054 }
2055 return name;
2056 }
2057
2058 if(outSubscript)
2059 {
2060 int index = atoi(name.substr(open + 1).c_str());
2061 if(index >= 0)
2062 {
2063 *outSubscript = index;
2064 }
2065 else
2066 {
2067 *outSubscript = GL_INVALID_INDEX;
2068 }
2069 }
2070
2071 return name.substr(0, open);
2072 }
2073
2074 bool FloatFitsInInt(float f)
2075 {
2076 // We can't just do a raw comparison of "f > (float) INT32_MAX",
2077 // because "(float) INT32_MAX" is unrepresentable as an integer.
2078 //
2079 // So instead I subtracted an ULP from "(float) INT32_MAX", cast that
2080 // to an int, and do the comparison with that value. That value is
2081 // 2147483520, and can be found with the following code:
2082 // float f_max = static_cast<float>(INT32_MAX);
2083 // int32_t f_bits = *static_cast<int32_t *>((void *)&f_max);
2084 // f_bits -= 1;
2085 // float f_next = *static_cast<float *>((void *)&f_bits);
2086 // int32_t out = static_cast<int32_t>(f_next);
2087 return std::isfinite(f) && (-2147483520.f < f) && (f < 2147483520.f);
2088 }
2089}
2090
2091namespace es2sw
2092{
2093 sw::DepthCompareMode ConvertDepthComparison(GLenum comparison)
2094 {
2095 switch(comparison)
2096 {
2097 case GL_NEVER: return sw::DEPTH_NEVER;
2098 case GL_ALWAYS: return sw::DEPTH_ALWAYS;
2099 case GL_LESS: return sw::DEPTH_LESS;
2100 case GL_LEQUAL: return sw::DEPTH_LESSEQUAL;
2101 case GL_EQUAL: return sw::DEPTH_EQUAL;
2102 case GL_GREATER: return sw::DEPTH_GREATER;
2103 case GL_GEQUAL: return sw::DEPTH_GREATEREQUAL;
2104 case GL_NOTEQUAL: return sw::DEPTH_NOTEQUAL;
2105 default: UNREACHABLE(comparison);
2106 }
2107
2108 return sw::DEPTH_ALWAYS;
2109 }
2110
2111 sw::StencilCompareMode ConvertStencilComparison(GLenum comparison)
2112 {
2113 switch(comparison)
2114 {
2115 case GL_NEVER: return sw::STENCIL_NEVER;
2116 case GL_ALWAYS: return sw::STENCIL_ALWAYS;
2117 case GL_LESS: return sw::STENCIL_LESS;
2118 case GL_LEQUAL: return sw::STENCIL_LESSEQUAL;
2119 case GL_EQUAL: return sw::STENCIL_EQUAL;
2120 case GL_GREATER: return sw::STENCIL_GREATER;
2121 case GL_GEQUAL: return sw::STENCIL_GREATEREQUAL;
2122 case GL_NOTEQUAL: return sw::STENCIL_NOTEQUAL;
2123 default: UNREACHABLE(comparison);
2124 }
2125
2126 return sw::STENCIL_ALWAYS;
2127 }
2128
2129 sw::Color<float> ConvertColor(es2::Color color)
2130 {
2131 return sw::Color<float>(color.red, color.green, color.blue, color.alpha);
2132 }
2133
2134 sw::BlendFactor ConvertBlendFunc(GLenum blend)
2135 {
2136 switch(blend)
2137 {
2138 case GL_ZERO: return sw::BLEND_ZERO;
2139 case GL_ONE: return sw::BLEND_ONE;
2140 case GL_SRC_COLOR: return sw::BLEND_SOURCE;
2141 case GL_ONE_MINUS_SRC_COLOR: return sw::BLEND_INVSOURCE;
2142 case GL_DST_COLOR: return sw::BLEND_DEST;
2143 case GL_ONE_MINUS_DST_COLOR: return sw::BLEND_INVDEST;
2144 case GL_SRC_ALPHA: return sw::BLEND_SOURCEALPHA;
2145 case GL_ONE_MINUS_SRC_ALPHA: return sw::BLEND_INVSOURCEALPHA;
2146 case GL_DST_ALPHA: return sw::BLEND_DESTALPHA;
2147 case GL_ONE_MINUS_DST_ALPHA: return sw::BLEND_INVDESTALPHA;
2148 case GL_CONSTANT_COLOR: return sw::BLEND_CONSTANT;
2149 case GL_ONE_MINUS_CONSTANT_COLOR: return sw::BLEND_INVCONSTANT;
2150 case GL_CONSTANT_ALPHA: return sw::BLEND_CONSTANTALPHA;
2151 case GL_ONE_MINUS_CONSTANT_ALPHA: return sw::BLEND_INVCONSTANTALPHA;
2152 case GL_SRC_ALPHA_SATURATE: return sw::BLEND_SRCALPHASAT;
2153 default: UNREACHABLE(blend);
2154 }
2155
2156 return sw::BLEND_ZERO;
2157 }
2158
2159 sw::BlendOperation ConvertBlendOp(GLenum blendOp)
2160 {
2161 switch(blendOp)
2162 {
2163 case GL_FUNC_ADD: return sw::BLENDOP_ADD;
2164 case GL_FUNC_SUBTRACT: return sw::BLENDOP_SUB;
2165 case GL_FUNC_REVERSE_SUBTRACT: return sw::BLENDOP_INVSUB;
2166 case GL_MIN_EXT: return sw::BLENDOP_MIN;
2167 case GL_MAX_EXT: return sw::BLENDOP_MAX;
2168 default: UNREACHABLE(blendOp);
2169 }
2170
2171 return sw::BLENDOP_ADD;
2172 }
2173
2174 sw::StencilOperation ConvertStencilOp(GLenum stencilOp)
2175 {
2176 switch(stencilOp)
2177 {
2178 case GL_ZERO: return sw::OPERATION_ZERO;
2179 case GL_KEEP: return sw::OPERATION_KEEP;
2180 case GL_REPLACE: return sw::OPERATION_REPLACE;
2181 case GL_INCR: return sw::OPERATION_INCRSAT;
2182 case GL_DECR: return sw::OPERATION_DECRSAT;
2183 case GL_INVERT: return sw::OPERATION_INVERT;
2184 case GL_INCR_WRAP: return sw::OPERATION_INCR;
2185 case GL_DECR_WRAP: return sw::OPERATION_DECR;
2186 default: UNREACHABLE(stencilOp);
2187 }
2188
2189 return sw::OPERATION_KEEP;
2190 }
2191
2192 sw::AddressingMode ConvertTextureWrap(GLenum wrap)
2193 {
2194 switch(wrap)
2195 {
2196 case GL_REPEAT: return sw::ADDRESSING_WRAP;
2197 case GL_CLAMP_TO_EDGE: return sw::ADDRESSING_CLAMP;
2198 case GL_MIRRORED_REPEAT: return sw::ADDRESSING_MIRROR;
2199 default: UNREACHABLE(wrap);
2200 }
2201
2202 return sw::ADDRESSING_WRAP;
2203 }
2204
2205 sw::CompareFunc ConvertCompareFunc(GLenum compareFunc, GLenum compareMode)
2206 {
2207 if(compareMode == GL_COMPARE_REF_TO_TEXTURE)
2208 {
2209 switch(compareFunc)
2210 {
2211 case GL_LEQUAL: return sw::COMPARE_LESSEQUAL;
2212 case GL_GEQUAL: return sw::COMPARE_GREATEREQUAL;
2213 case GL_LESS: return sw::COMPARE_LESS;
2214 case GL_GREATER: return sw::COMPARE_GREATER;
2215 case GL_EQUAL: return sw::COMPARE_EQUAL;
2216 case GL_NOTEQUAL: return sw::COMPARE_NOTEQUAL;
2217 case GL_ALWAYS: return sw::COMPARE_ALWAYS;
2218 case GL_NEVER: return sw::COMPARE_NEVER;
2219 default: UNREACHABLE(compareFunc);
2220 }
2221 }
2222 else if(compareMode == GL_NONE)
2223 {
2224 return sw::COMPARE_BYPASS;
2225 }
2226 else UNREACHABLE(compareMode);
2227
2228 return sw::COMPARE_BYPASS;
2229 }
2230
2231 sw::SwizzleType ConvertSwizzleType(GLenum swizzleType)
2232 {
2233 switch(swizzleType)
2234 {
2235 case GL_RED: return sw::SWIZZLE_RED;
2236 case GL_GREEN: return sw::SWIZZLE_GREEN;
2237 case GL_BLUE: return sw::SWIZZLE_BLUE;
2238 case GL_ALPHA: return sw::SWIZZLE_ALPHA;
2239 case GL_ZERO: return sw::SWIZZLE_ZERO;
2240 case GL_ONE: return sw::SWIZZLE_ONE;
2241 default: UNREACHABLE(swizzleType);
2242 }
2243
2244 return sw::SWIZZLE_RED;
2245 }
2246
2247 sw::CullMode ConvertCullMode(GLenum cullFace, GLenum frontFace)
2248 {
2249 switch(cullFace)
2250 {
2251 case GL_FRONT:
2252 return (frontFace == GL_CCW ? sw::CULL_CLOCKWISE : sw::CULL_COUNTERCLOCKWISE);
2253 case GL_BACK:
2254 return (frontFace == GL_CCW ? sw::CULL_COUNTERCLOCKWISE : sw::CULL_CLOCKWISE);
2255 case GL_FRONT_AND_BACK:
2256 return sw::CULL_NONE; // culling will be handled during draw
2257 default: UNREACHABLE(cullFace);
2258 }
2259
2260 return sw::CULL_COUNTERCLOCKWISE;
2261 }
2262
2263 unsigned int ConvertColorMask(bool red, bool green, bool blue, bool alpha)
2264 {
2265 return (red ? 0x00000001 : 0) |
2266 (green ? 0x00000002 : 0) |
2267 (blue ? 0x00000004 : 0) |
2268 (alpha ? 0x00000008 : 0);
2269 }
2270
2271 sw::MipmapType ConvertMipMapFilter(GLenum minFilter)
2272 {
2273 switch(minFilter)
2274 {
2275 case GL_NEAREST:
2276 case GL_LINEAR:
2277 return sw::MIPMAP_NONE;
2278 case GL_NEAREST_MIPMAP_NEAREST:
2279 case GL_LINEAR_MIPMAP_NEAREST:
2280 return sw::MIPMAP_POINT;
2281 case GL_NEAREST_MIPMAP_LINEAR:
2282 case GL_LINEAR_MIPMAP_LINEAR:
2283 return sw::MIPMAP_LINEAR;
2284 default:
2285 UNREACHABLE(minFilter);
2286 return sw::MIPMAP_NONE;
2287 }
2288 }
2289
2290 sw::FilterType ConvertTextureFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy)
2291 {
2292 if(maxAnisotropy > 1.0f)
2293 {
2294 return sw::FILTER_ANISOTROPIC;
2295 }
2296
2297 switch(magFilter)
2298 {
2299 case GL_NEAREST:
2300 case GL_LINEAR:
2301 break;
2302 default:
2303 UNREACHABLE(magFilter);
2304 }
2305
2306 switch(minFilter)
2307 {
2308 case GL_NEAREST:
2309 case GL_NEAREST_MIPMAP_NEAREST:
2310 case GL_NEAREST_MIPMAP_LINEAR:
2311 return (magFilter == GL_NEAREST) ? sw::FILTER_POINT : sw::FILTER_MIN_POINT_MAG_LINEAR;
2312 case GL_LINEAR:
2313 case GL_LINEAR_MIPMAP_NEAREST:
2314 case GL_LINEAR_MIPMAP_LINEAR:
2315 return (magFilter == GL_NEAREST) ? sw::FILTER_MIN_LINEAR_MAG_POINT : sw::FILTER_LINEAR;
2316 default:
2317 UNREACHABLE(minFilter);
2318 return sw::FILTER_POINT;
2319 }
2320 }
2321
2322 bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount, GLenum elementType, sw::DrawType &drawType, int &primitiveCount, int &verticesPerPrimitive)
2323 {
2324 switch(primitiveType)
2325 {
2326 case GL_POINTS:
2327 drawType = sw::DRAW_POINTLIST;
2328 primitiveCount = elementCount;
2329 verticesPerPrimitive = 1;
2330 break;
2331 case GL_LINES:
2332 drawType = sw::DRAW_LINELIST;
2333 primitiveCount = elementCount / 2;
2334 verticesPerPrimitive = 2;
2335 break;
2336 case GL_LINE_LOOP:
2337 drawType = sw::DRAW_LINELOOP;
2338 primitiveCount = elementCount;
2339 verticesPerPrimitive = 2;
2340 break;
2341 case GL_LINE_STRIP:
2342 drawType = sw::DRAW_LINESTRIP;
2343 primitiveCount = elementCount - 1;
2344 verticesPerPrimitive = 2;
2345 break;
2346 case GL_TRIANGLES:
2347 drawType = sw::DRAW_TRIANGLELIST;
2348 primitiveCount = elementCount / 3;
2349 verticesPerPrimitive = 3;
2350 break;
2351 case GL_TRIANGLE_STRIP:
2352 drawType = sw::DRAW_TRIANGLESTRIP;
2353 primitiveCount = elementCount - 2;
2354 verticesPerPrimitive = 3;
2355 break;
2356 case GL_TRIANGLE_FAN:
2357 drawType = sw::DRAW_TRIANGLEFAN;
2358 primitiveCount = elementCount - 2;
2359 verticesPerPrimitive = 3;
2360 break;
2361 default:
2362 return false;
2363 }
2364
2365 sw::DrawType elementSize;
2366 switch(elementType)
2367 {
2368 case GL_NONE: elementSize = sw::DRAW_NONINDEXED; break;
2369 case GL_UNSIGNED_BYTE: elementSize = sw::DRAW_INDEXED8; break;
2370 case GL_UNSIGNED_SHORT: elementSize = sw::DRAW_INDEXED16; break;
2371 case GL_UNSIGNED_INT: elementSize = sw::DRAW_INDEXED32; break;
2372 default: return false;
2373 }
2374
2375 drawType = sw::DrawType(drawType | elementSize);
2376
2377 return true;
2378 }
2379}
2380
2381namespace sw2es
2382{
2383 GLenum ConvertBackBufferFormat(sw::Format format)
2384 {
2385 switch(format)
2386 {
2387 case sw::FORMAT_A4R4G4B4: return GL_RGBA4;
2388 case sw::FORMAT_A8R8G8B8: return GL_RGBA8;
2389 case sw::FORMAT_A8B8G8R8: return GL_RGBA8;
2390 case sw::FORMAT_A1R5G5B5: return GL_RGB5_A1;
2391 case sw::FORMAT_R5G6B5: return GL_RGB565;
2392 case sw::FORMAT_X8R8G8B8: return GL_RGB8;
2393 case sw::FORMAT_X8B8G8R8: return GL_RGB8;
2394 case sw::FORMAT_SRGB8_A8: return GL_RGBA8;
2395 case sw::FORMAT_SRGB8_X8: return GL_RGB8;
2396 default:
2397 UNREACHABLE(format);
2398 }
2399
2400 return GL_RGBA4;
2401 }
2402
2403 GLenum ConvertDepthStencilFormat(sw::Format format)
2404 {
2405 switch(format)
2406 {
2407 case sw::FORMAT_D16: return GL_DEPTH_COMPONENT16;
2408 case sw::FORMAT_D24X8: return GL_DEPTH_COMPONENT24;
2409 case sw::FORMAT_D32: return GL_DEPTH_COMPONENT32_OES;
2410 case sw::FORMAT_D24S8: return GL_DEPTH24_STENCIL8_OES;
2411 case sw::FORMAT_D32F: return GL_DEPTH_COMPONENT32F;
2412 case sw::FORMAT_D32FS8: return GL_DEPTH32F_STENCIL8;
2413 case sw::FORMAT_S8: return GL_STENCIL_INDEX8;
2414 default:
2415 UNREACHABLE(format);
2416 }
2417
2418 return GL_DEPTH24_STENCIL8_OES;
2419 }
2420}
2421