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 
30 namespace es2
31 {
32 
UniformComponentCount(GLenum type)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 
UniformComponentType(GLenum type)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 
UniformTypeSize(GLenum type)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 
IsSamplerUniform(GLenum type)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 
VariableRowCount(GLenum type)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 
VariableColumnCount(GLenum type)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 
VariableRegisterCount(GLenum type)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 
VariableRegisterSize(GLenum type)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 
AllocateFirstFreeBits(unsigned int * bits,unsigned int allocationSize,unsigned int bitsSize)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 
IsCompressed(GLint internalformat,GLint clientVersion)326 	bool IsCompressed(GLint internalformat, GLint clientVersion)
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 			return true;
336 		case GL_COMPRESSED_R11_EAC:
337 		case GL_COMPRESSED_SIGNED_R11_EAC:
338 		case GL_COMPRESSED_RG11_EAC:
339 		case GL_COMPRESSED_SIGNED_RG11_EAC:
340 		case GL_COMPRESSED_RGB8_ETC2:
341 		case GL_COMPRESSED_SRGB8_ETC2:
342 		case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
343 		case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
344 		case GL_COMPRESSED_RGBA8_ETC2_EAC:
345 		case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
346 			return (clientVersion >= 3);
347 		case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
348 		case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
349 		case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
350 		case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
351 		case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
352 		case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
353 		case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
354 		case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
355 		case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
356 		case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
357 		case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
358 		case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
359 		case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
360 		case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
361 		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
362 		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
363 		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
364 		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
365 		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
366 		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
367 		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
368 		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
369 		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
370 		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
371 		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
372 		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
373 		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
374 		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
375 			return ASTC_SUPPORT && (clientVersion >= 3);
376 		default:
377 			return false;
378 		}
379 	}
380 
IsSizedInternalFormat(GLint internalformat)381 	bool IsSizedInternalFormat(GLint internalformat)
382 	{
383 		switch(internalformat)
384 		{
385 		case GL_ALPHA8_EXT:
386 		case GL_LUMINANCE8_EXT:
387 		case GL_LUMINANCE8_ALPHA8_EXT:
388 		case GL_ALPHA32F_EXT:
389 		case GL_LUMINANCE32F_EXT:
390 		case GL_LUMINANCE_ALPHA32F_EXT:
391 		case GL_ALPHA16F_EXT:
392 		case GL_LUMINANCE16F_EXT:
393 		case GL_LUMINANCE_ALPHA16F_EXT:
394 		case GL_R8:
395 		case GL_R8UI:
396 		case GL_R8I:
397 		case GL_R16UI:
398 		case GL_R16I:
399 		case GL_R32UI:
400 		case GL_R32I:
401 		case GL_RG8:
402 		case GL_RG8UI:
403 		case GL_RG8I:
404 		case GL_RG16UI:
405 		case GL_RG16I:
406 		case GL_RG32UI:
407 		case GL_RG32I:
408 		case GL_SRGB8_ALPHA8:
409 		case GL_RGB8UI:
410 		case GL_RGB8I:
411 		case GL_RGB16UI:
412 		case GL_RGB16I:
413 		case GL_RGB32UI:
414 		case GL_RGB32I:
415 		case GL_RG8_SNORM:
416 		case GL_R8_SNORM:
417 		case GL_RGB10_A2:
418 		case GL_RGBA8UI:
419 		case GL_RGBA8I:
420 		case GL_RGB10_A2UI:
421 		case GL_RGBA16UI:
422 		case GL_RGBA16I:
423 		case GL_RGBA32I:
424 		case GL_RGBA32UI:
425 		case GL_RGBA4:
426 		case GL_RGB5_A1:
427 		case GL_RGB565:
428 		case GL_RGB8:
429 		case GL_RGBA8:
430 		case GL_BGRA8_EXT:   // GL_APPLE_texture_format_BGRA8888
431 		case GL_R16F:
432 		case GL_RG16F:
433 		case GL_R11F_G11F_B10F:
434 		case GL_RGB16F:
435 		case GL_RGBA16F:
436 		case GL_R32F:
437 		case GL_RG32F:
438 		case GL_RGB32F:
439 		case GL_RGBA32F:
440 		case GL_DEPTH_COMPONENT24:
441 		case GL_DEPTH_COMPONENT32_OES:
442 		case GL_DEPTH_COMPONENT32F:
443 		case GL_DEPTH32F_STENCIL8:
444 		case GL_DEPTH_COMPONENT16:
445 		case GL_STENCIL_INDEX8:
446 		case GL_DEPTH24_STENCIL8_OES:
447 		case GL_RGBA8_SNORM:
448 		case GL_SRGB8:
449 		case GL_RGB8_SNORM:
450 		case GL_RGB9_E5:
451 			return true;
452 		default:
453 			return false;
454 		}
455 	}
456 
ValidateSubImageParams(bool compressed,bool copy,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLenum type,Texture * texture,GLint clientVersion)457 	GLenum ValidateSubImageParams(bool compressed, bool copy, GLenum target, GLint level, GLint xoffset, GLint yoffset,
458 	                              GLsizei width, GLsizei height, GLenum format, GLenum type, Texture *texture, GLint clientVersion)
459 	{
460 		if(!texture)
461 		{
462 			return GL_INVALID_OPERATION;
463 		}
464 
465 		GLenum sizedInternalFormat = texture->getFormat(target, level);
466 
467 		if(compressed)
468 		{
469 			if(format != sizedInternalFormat)
470 			{
471 				return GL_INVALID_OPERATION;
472 			}
473 		}
474 		else if(!copy)   // CopyTexSubImage doesn't have format/type parameters.
475 		{
476 			GLenum validationError = ValidateTextureFormatType(format, type, sizedInternalFormat, target, clientVersion);
477 			if(validationError != GL_NO_ERROR)
478 			{
479 				return validationError;
480 			}
481 		}
482 
483 		if(compressed)
484 		{
485 			if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
486 			   (height % 4 != 0 && height != texture->getHeight(target, 0)))
487 			{
488 				return GL_INVALID_OPERATION;
489 			}
490 		}
491 
492 		if(xoffset + width > texture->getWidth(target, level) ||
493 		   yoffset + height > texture->getHeight(target, level))
494 		{
495 			return GL_INVALID_VALUE;
496 		}
497 
498 		return GL_NO_ERROR;
499 	}
500 
ValidateSubImageParams(bool compressed,bool copy,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,Texture * texture,GLint clientVersion)501 	GLenum ValidateSubImageParams(bool compressed, bool copy, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
502 	                              GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, Texture *texture, GLint clientVersion)
503 	{
504 		if(!texture)
505 		{
506 			return GL_INVALID_OPERATION;
507 		}
508 
509 		if(compressed != texture->isCompressed(target, level))
510 		{
511 			return GL_INVALID_OPERATION;
512 		}
513 
514 		if(!copy)
515 		{
516 			GLenum sizedInternalFormat = texture->getFormat(target, level);
517 
518 			GLenum validationError = ValidateTextureFormatType(format, type, sizedInternalFormat, target, clientVersion);
519 			if(validationError != GL_NO_ERROR)
520 			{
521 				return validationError;
522 			}
523 		}
524 
525 		if(compressed)
526 		{
527 			if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
528 			   (height % 4 != 0 && height != texture->getHeight(target, 0)) ||
529 			   (depth % 4 != 0 && depth != texture->getDepth(target, 0)))
530 			{
531 				return GL_INVALID_OPERATION;
532 			}
533 		}
534 
535 		if(xoffset + width > texture->getWidth(target, level) ||
536 		   yoffset + height > texture->getHeight(target, level) ||
537 		   zoffset + depth > texture->getDepth(target, level))
538 		{
539 			return GL_INVALID_VALUE;
540 		}
541 
542 		return GL_NO_ERROR;
543 	}
544 
ValidateCopyFormats(GLenum textureFormat,GLenum colorbufferFormat)545 	bool ValidateCopyFormats(GLenum textureFormat, GLenum colorbufferFormat)
546 	{
547 		ASSERT(!gl::IsUnsizedInternalFormat(textureFormat));
548 		ASSERT(!gl::IsUnsizedInternalFormat(colorbufferFormat));
549 
550 		if(GetColorComponentType(textureFormat) == GL_NONE)
551 		{
552 			return error(GL_INVALID_ENUM, false);
553 		}
554 
555 		if(GetColorComponentType(colorbufferFormat) != GetColorComponentType(textureFormat))
556 		{
557 			return error(GL_INVALID_OPERATION, false);
558 		}
559 
560 		if(GetColorEncoding(colorbufferFormat) != GetColorEncoding(textureFormat))
561 		{
562 			return error(GL_INVALID_OPERATION, false);
563 		}
564 
565 		GLenum baseTexureFormat = gl::GetBaseInternalFormat(textureFormat);
566 		GLenum baseColorbufferFormat = gl::GetBaseInternalFormat(colorbufferFormat);
567 
568 		// [OpenGL ES 2.0.24] table 3.9
569 		// [OpenGL ES 3.0.5] table 3.16
570 		switch(baseTexureFormat)
571 		{
572 		case GL_ALPHA:
573 			if(baseColorbufferFormat != GL_ALPHA &&
574 			   baseColorbufferFormat != GL_RGBA &&
575 			   baseColorbufferFormat != GL_BGRA_EXT)   // GL_EXT_texture_format_BGRA8888 / GL_APPLE_texture_format_BGRA8888
576 			{
577 				return error(GL_INVALID_OPERATION, false);
578 			}
579 			break;
580 		case GL_LUMINANCE_ALPHA:
581 		case GL_RGBA:
582 			if(baseColorbufferFormat != GL_RGBA &&
583 			   baseColorbufferFormat != GL_BGRA_EXT)   // GL_EXT_texture_format_BGRA8888 / GL_APPLE_texture_format_BGRA8888
584 			{
585 				return error(GL_INVALID_OPERATION, false);
586 			}
587 			break;
588 		case GL_LUMINANCE:
589 		case GL_RED:
590 			if(baseColorbufferFormat != GL_RED &&
591 			   baseColorbufferFormat != GL_RG &&
592 			   baseColorbufferFormat != GL_RGB &&
593 			   baseColorbufferFormat != GL_RGBA &&
594 			   baseColorbufferFormat != GL_BGRA_EXT)   // GL_EXT_texture_format_BGRA8888 / GL_APPLE_texture_format_BGRA8888
595 			{
596 				return error(GL_INVALID_OPERATION, false);
597 			}
598 			break;
599 		case GL_RG:
600 			if(baseColorbufferFormat != GL_RG &&
601 			   baseColorbufferFormat != GL_RGB &&
602 			   baseColorbufferFormat != GL_RGBA &&
603 			   baseColorbufferFormat != GL_BGRA_EXT)   // GL_EXT_texture_format_BGRA8888 / GL_APPLE_texture_format_BGRA8888
604 			{
605 				return error(GL_INVALID_OPERATION, false);
606 			}
607 			break;
608 		case GL_RGB:
609 			if(baseColorbufferFormat != GL_RGB &&
610 			   baseColorbufferFormat != GL_RGBA &&
611 			   baseColorbufferFormat != GL_BGRA_EXT)   // GL_EXT_texture_format_BGRA8888 / GL_APPLE_texture_format_BGRA8888
612 			{
613 				return error(GL_INVALID_OPERATION, false);
614 			}
615 			break;
616 		case GL_DEPTH_COMPONENT:
617 		case GL_DEPTH_STENCIL_OES:
618 			return error(GL_INVALID_OPERATION, false);
619 		case GL_BGRA_EXT:   // GL_EXT_texture_format_BGRA8888 nor GL_APPLE_texture_format_BGRA8888 mention the format to be accepted by glCopyTexImage2D.
620 		default:
621 			return error(GL_INVALID_ENUM, false);
622 		}
623 
624 		return true;
625 	}
626 
IsValidReadPixelsFormatType(const Framebuffer * framebuffer,GLenum format,GLenum type,GLint clientVersion)627 	bool IsValidReadPixelsFormatType(const Framebuffer *framebuffer, GLenum format, GLenum type, GLint clientVersion)
628 	{
629 		// GL_NV_read_depth
630 		if(format == GL_DEPTH_COMPONENT)
631 		{
632 			Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
633 
634 			if(!depthbuffer)
635 			{
636 				return false;
637 			}
638 
639 			switch(type)
640 			{
641 			case GL_UNSIGNED_SHORT:
642 			case GL_FLOAT:
643 				return true;
644 			default:
645 				UNIMPLEMENTED();
646 				return false;
647 			}
648 		}
649 
650 		Renderbuffer *colorbuffer = framebuffer->getReadColorbuffer();
651 
652 		if(!colorbuffer)
653 		{
654 			return false;
655 		}
656 
657 		GLint internalformat = colorbuffer->getFormat();
658 
659 		if(IsNormalizedInteger(internalformat))
660 		{
661 			// Combination always supported by normalized fixed-point rendering surfaces.
662 			if(format == GL_RGBA && type == GL_UNSIGNED_BYTE)
663 			{
664 				return true;
665 			}
666 
667 			// GL_EXT_read_format_bgra combinations.
668 			if(format == GL_BGRA_EXT)
669 			{
670 				if(type == GL_UNSIGNED_BYTE ||
671 				   type == GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT ||
672 				   type == GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT)
673 				{
674 					return true;
675 				}
676 			}
677 		}
678 		else if(IsFloatFormat(internalformat))
679 		{
680 			// Combination always supported by floating-point rendering surfaces.
681 			// Supported in OpenGL ES 2.0 due to GL_EXT_color_buffer_half_float.
682 			if(format == GL_RGBA && type == GL_FLOAT)
683 			{
684 				return true;
685 			}
686 		}
687 		else if(IsSignedNonNormalizedInteger(internalformat))
688 		{
689 			ASSERT(clientVersion >= 3);
690 
691 			if(format == GL_RGBA_INTEGER && type == GL_INT)
692 			{
693 				return true;
694 			}
695 		}
696 		else if(IsUnsignedNonNormalizedInteger(internalformat))
697 		{
698 			ASSERT(clientVersion >= 3);
699 
700 			if(format == GL_RGBA_INTEGER && type == GL_UNSIGNED_INT)
701 			{
702 				return true;
703 			}
704 		}
705 		else UNREACHABLE(internalformat);
706 
707 		// GL_IMPLEMENTATION_COLOR_READ_FORMAT / GL_IMPLEMENTATION_COLOR_READ_TYPE
708 		GLenum implementationReadFormat = GL_NONE;
709 		GLenum implementationReadType = GL_NONE;
710 		switch(format)
711 		{
712 		default:
713 			implementationReadFormat = framebuffer->getImplementationColorReadFormat();
714 			implementationReadType = framebuffer->getImplementationColorReadType();
715 			break;
716 		case GL_DEPTH_COMPONENT:
717 			implementationReadFormat = framebuffer->getDepthReadFormat();
718 			implementationReadType = framebuffer->getDepthReadType();
719 			break;
720 		}
721 
722 		if(format == implementationReadFormat && type == implementationReadType)
723 		{
724 			return true;
725 		}
726 
727 		// Additional third combination accepted by OpenGL ES 3.0.
728 		if(internalformat == GL_RGB10_A2)
729 		{
730 			ASSERT(clientVersion >= 3);
731 
732 			if(format == GL_RGBA && type == GL_UNSIGNED_INT_2_10_10_10_REV)
733 			{
734 				return true;
735 			}
736 		}
737 
738 		return false;
739 	}
740 
IsDepthTexture(GLenum format)741 	bool IsDepthTexture(GLenum format)
742 	{
743 		return format == GL_DEPTH_COMPONENT ||
744 		       format == GL_DEPTH_STENCIL_OES ||
745 		       format == GL_DEPTH_COMPONENT16 ||
746 		       format == GL_DEPTH_COMPONENT24 ||
747 		       format == GL_DEPTH_COMPONENT32_OES ||
748 		       format == GL_DEPTH_COMPONENT32F ||
749 		       format == GL_DEPTH24_STENCIL8 ||
750 		       format == GL_DEPTH32F_STENCIL8;
751 	}
752 
IsStencilTexture(GLenum format)753 	bool IsStencilTexture(GLenum format)
754 	{
755 		return format == GL_STENCIL_INDEX_OES ||
756 		       format == GL_DEPTH_STENCIL_OES ||
757 		       format == GL_DEPTH24_STENCIL8 ||
758 		       format == GL_DEPTH32F_STENCIL8;
759 	}
760 
IsCubemapTextureTarget(GLenum target)761 	bool IsCubemapTextureTarget(GLenum target)
762 	{
763 		return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
764 	}
765 
CubeFaceIndex(GLenum cubeFace)766 	int CubeFaceIndex(GLenum cubeFace)
767 	{
768 		switch(cubeFace)
769 		{
770 		case GL_TEXTURE_CUBE_MAP:
771 		case GL_TEXTURE_CUBE_MAP_POSITIVE_X: return 0;
772 		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: return 1;
773 		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: return 2;
774 		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: return 3;
775 		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: return 4;
776 		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: return 5;
777 		default: UNREACHABLE(cubeFace); return 0;
778 		}
779 	}
780 
IsTextureTarget(GLenum target)781 	bool IsTextureTarget(GLenum target)
782 	{
783 		return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target) || target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_RECTANGLE_ARB;
784 	}
785 
ValidateTextureFormatType(GLenum format,GLenum type,GLint internalformat,GLenum target,GLint clientVersion)786 	GLenum ValidateTextureFormatType(GLenum format, GLenum type, GLint internalformat, GLenum target, GLint clientVersion)
787 	{
788 		switch(type)
789 		{
790 		case GL_UNSIGNED_BYTE:
791 		case GL_UNSIGNED_SHORT_4_4_4_4:
792 		case GL_UNSIGNED_SHORT_5_5_5_1:
793 		case GL_UNSIGNED_SHORT_5_6_5:
794 		case GL_FLOAT:               // GL_OES_texture_float
795 		case GL_HALF_FLOAT_OES:      // GL_OES_texture_half_float
796 		case GL_HALF_FLOAT:
797 		case GL_UNSIGNED_INT_24_8:   // GL_OES_packed_depth_stencil (GL_UNSIGNED_INT_24_8_EXT)
798 		case GL_UNSIGNED_SHORT:      // GL_OES_depth_texture
799 		case GL_UNSIGNED_INT:        // GL_OES_depth_texture
800 			break;
801 		case GL_BYTE:
802 		case GL_SHORT:
803 		case GL_INT:
804 		case GL_UNSIGNED_INT_2_10_10_10_REV:
805 		case GL_UNSIGNED_INT_10F_11F_11F_REV:
806 		case GL_UNSIGNED_INT_5_9_9_9_REV:
807 		case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
808 			if(clientVersion < 3)
809 			{
810 				return GL_INVALID_ENUM;
811 			}
812 			break;
813 		default:
814 			return GL_INVALID_ENUM;
815 		}
816 
817 		switch(format)
818 		{
819 		case GL_ALPHA:
820 		case GL_RGB:
821 		case GL_RGBA:
822 		case GL_LUMINANCE:
823 		case GL_LUMINANCE_ALPHA:
824 		case GL_BGRA_EXT:          // GL_EXT_texture_format_BGRA8888
825 		case GL_RED_EXT:           // GL_EXT_texture_rg
826 		case GL_RG_EXT:            // GL_EXT_texture_rg
827 			break;
828 		case GL_DEPTH_STENCIL:     // GL_OES_packed_depth_stencil (GL_DEPTH_STENCIL_OES)
829 		case GL_DEPTH_COMPONENT:   // GL_OES_depth_texture
830 			switch(target)
831 			{
832 			case GL_TEXTURE_2D:
833 			case GL_TEXTURE_2D_ARRAY:
834 			case GL_TEXTURE_CUBE_MAP_POSITIVE_X:   // GL_OES_depth_texture_cube_map
835 			case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
836 			case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
837 			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
838 			case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
839 			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
840 				break;
841 			default:
842 				return GL_INVALID_OPERATION;
843 			}
844 			break;
845 		case GL_RED_INTEGER:
846 		case GL_RG_INTEGER:
847 		case GL_RGB_INTEGER:
848 		case GL_RGBA_INTEGER:
849 			if(clientVersion < 3)
850 			{
851 				return GL_INVALID_ENUM;
852 			}
853 			break;
854 		default:
855 			return GL_INVALID_ENUM;
856 		}
857 
858 		if((GLenum)internalformat != format)
859 		{
860 			if(gl::IsUnsizedInternalFormat(internalformat))
861 			{
862 				return GL_INVALID_OPERATION;
863 			}
864 
865 			if(!IsSizedInternalFormat(internalformat))
866 			{
867 				return GL_INVALID_VALUE;
868 			}
869 		}
870 
871 		if((GLenum)internalformat == format)
872 		{
873 			// Validate format, type, and unsized internalformat combinations [OpenGL ES 3.0 Table 3.3]
874 			switch(format)
875 			{
876 			case GL_RGBA:
877 				switch(type)
878 				{
879 				case GL_UNSIGNED_BYTE:
880 				case GL_UNSIGNED_SHORT_4_4_4_4:
881 				case GL_UNSIGNED_SHORT_5_5_5_1:
882 				case GL_FLOAT:            // GL_OES_texture_float
883 				case GL_HALF_FLOAT_OES:   // GL_OES_texture_half_float
884 					break;
885 				default:
886 					return GL_INVALID_OPERATION;
887 				}
888 				break;
889 			case GL_RGB:
890 				switch(type)
891 				{
892 				case GL_UNSIGNED_BYTE:
893 				case GL_UNSIGNED_SHORT_5_6_5:
894 				case GL_FLOAT:            // GL_OES_texture_float
895 				case GL_HALF_FLOAT_OES:   // GL_OES_texture_half_float
896 					break;
897 				default:
898 					return GL_INVALID_OPERATION;
899 				}
900 				break;
901 			case GL_LUMINANCE_ALPHA:
902 			case GL_LUMINANCE:
903 			case GL_ALPHA:
904 				switch(type)
905 				{
906 				case GL_UNSIGNED_BYTE:
907 				case GL_FLOAT:            // GL_OES_texture_float
908 				case GL_HALF_FLOAT_OES:   // GL_OES_texture_half_float
909 					break;
910 				default:
911 					return GL_INVALID_OPERATION;
912 				}
913 				break;
914 			case GL_DEPTH_COMPONENT:
915 				switch(type)
916 				{
917 				case GL_UNSIGNED_SHORT:   // GL_OES_depth_texture
918 				case GL_UNSIGNED_INT:     // GL_OES_depth_texture
919 					break;
920 				default:
921 					return GL_INVALID_OPERATION;
922 				}
923 				break;
924 			case GL_DEPTH_STENCIL_OES:
925 				switch(type)
926 				{
927 				case GL_UNSIGNED_INT_24_8_OES:   // GL_OES_packed_depth_stencil
928 					break;
929 				default:
930 					return GL_INVALID_OPERATION;
931 				}
932 				break;
933 			case GL_RED_EXT:
934 			case GL_RG_EXT:
935 				switch(type)
936 				{
937 				case GL_UNSIGNED_BYTE:    // GL_EXT_texture_rg
938 				case GL_FLOAT:            // GL_EXT_texture_rg + GL_OES_texture_float
939 				case GL_HALF_FLOAT_OES:   // GL_EXT_texture_rg + GL_OES_texture_half_float
940 					break;
941 				default:
942 					return GL_INVALID_OPERATION;
943 				}
944 				break;
945 			case GL_BGRA_EXT:
946 				if(type != GL_UNSIGNED_BYTE)   // GL_APPLE_texture_format_BGRA8888 / GL_EXT_texture_format_BGRA8888
947 				{
948 					return GL_INVALID_OPERATION;
949 				}
950 				break;
951 			default:
952 				UNREACHABLE(format);
953 				return GL_INVALID_ENUM;
954 			}
955 
956 			return GL_NO_ERROR;
957 		}
958 
959 		// Validate format, type, and sized internalformat combinations [OpenGL ES 3.0 Table 3.2]
960 		bool validSizedInternalformat = false;
961 		#define VALIDATE_INTERNALFORMAT(...) { GLint validInternalformats[] = {__VA_ARGS__}; for(GLint v : validInternalformats) {if(internalformat == v) validSizedInternalformat = true;} } break;
962 
963 		switch(format)
964 		{
965 		case GL_RGBA:
966 			switch(type)
967 			{
968 			case GL_UNSIGNED_BYTE:               VALIDATE_INTERNALFORMAT(GL_RGBA8, GL_RGB5_A1, GL_RGBA4, GL_SRGB8_ALPHA8)
969 			case GL_BYTE:                        VALIDATE_INTERNALFORMAT(GL_RGBA8_SNORM)
970 			case GL_UNSIGNED_SHORT_4_4_4_4:      VALIDATE_INTERNALFORMAT(GL_RGBA4)
971 			case GL_UNSIGNED_SHORT_5_5_5_1:      VALIDATE_INTERNALFORMAT(GL_RGB5_A1)
972 			case GL_UNSIGNED_INT_2_10_10_10_REV: VALIDATE_INTERNALFORMAT(GL_RGB10_A2, GL_RGB5_A1)
973 			case GL_HALF_FLOAT_OES:
974 			case GL_HALF_FLOAT:                  VALIDATE_INTERNALFORMAT(GL_RGBA16F)
975 			case GL_FLOAT:                       VALIDATE_INTERNALFORMAT(GL_RGBA32F, GL_RGBA16F)
976 			default:                             return GL_INVALID_OPERATION;
977 			}
978 			break;
979 		case GL_RGBA_INTEGER:
980 			switch(type)
981 			{
982 			case GL_UNSIGNED_BYTE:               VALIDATE_INTERNALFORMAT(GL_RGBA8UI)
983 			case GL_BYTE:                        VALIDATE_INTERNALFORMAT(GL_RGBA8I)
984 			case GL_UNSIGNED_SHORT:              VALIDATE_INTERNALFORMAT(GL_RGBA16UI)
985 			case GL_SHORT:                       VALIDATE_INTERNALFORMAT(GL_RGBA16I)
986 			case GL_UNSIGNED_INT:                VALIDATE_INTERNALFORMAT(GL_RGBA32UI)
987 			case GL_INT:                         VALIDATE_INTERNALFORMAT(GL_RGBA32I)
988 			case GL_UNSIGNED_INT_2_10_10_10_REV: VALIDATE_INTERNALFORMAT(GL_RGB10_A2UI)
989 			default:                             return GL_INVALID_OPERATION;
990 			}
991 			break;
992 		case GL_RGB:
993 			switch(type)
994 			{
995 			case GL_UNSIGNED_BYTE:                VALIDATE_INTERNALFORMAT(GL_RGB8, GL_RGB565, GL_SRGB8)
996 			case GL_BYTE:                         VALIDATE_INTERNALFORMAT(GL_RGB8_SNORM)
997 			case GL_UNSIGNED_SHORT_5_6_5:         VALIDATE_INTERNALFORMAT(GL_RGB565)
998 			case GL_UNSIGNED_INT_10F_11F_11F_REV: VALIDATE_INTERNALFORMAT(GL_R11F_G11F_B10F)
999 			case GL_UNSIGNED_INT_5_9_9_9_REV:     VALIDATE_INTERNALFORMAT(GL_RGB9_E5)
1000 			case GL_HALF_FLOAT_OES:
1001 			case GL_HALF_FLOAT:                   VALIDATE_INTERNALFORMAT(GL_RGB16F, GL_R11F_G11F_B10F, GL_RGB9_E5)
1002 			case GL_FLOAT:                        VALIDATE_INTERNALFORMAT(GL_RGB32F, GL_RGB16F, GL_R11F_G11F_B10F, GL_RGB9_E5)
1003 			default:                              return GL_INVALID_OPERATION;
1004 			}
1005 			break;
1006 		case GL_RGB_INTEGER:
1007 			switch(type)
1008 			{
1009 			case GL_UNSIGNED_BYTE:  VALIDATE_INTERNALFORMAT(GL_RGB8UI)
1010 			case GL_BYTE:           VALIDATE_INTERNALFORMAT(GL_RGB8I)
1011 			case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_RGB16UI)
1012 			case GL_SHORT:          VALIDATE_INTERNALFORMAT(GL_RGB16I)
1013 			case GL_UNSIGNED_INT:   VALIDATE_INTERNALFORMAT(GL_RGB32UI)
1014 			case GL_INT:            VALIDATE_INTERNALFORMAT(GL_RGB32I)
1015 			default:                return GL_INVALID_OPERATION;
1016 			}
1017 			break;
1018 		case GL_RG:
1019 			switch(type)
1020 			{
1021 			case GL_UNSIGNED_BYTE:  VALIDATE_INTERNALFORMAT(GL_RG8)
1022 			case GL_BYTE:           VALIDATE_INTERNALFORMAT(GL_RG8_SNORM)
1023 			case GL_HALF_FLOAT_OES:
1024 			case GL_HALF_FLOAT:     VALIDATE_INTERNALFORMAT(GL_RG16F)
1025 			case GL_FLOAT:          VALIDATE_INTERNALFORMAT(GL_RG32F, GL_RG16F)
1026 			default:                return GL_INVALID_OPERATION;
1027 			}
1028 			break;
1029 		case GL_RG_INTEGER:
1030 			switch(type)
1031 			{
1032 			case GL_UNSIGNED_BYTE:  VALIDATE_INTERNALFORMAT(GL_RG8UI)
1033 			case GL_BYTE:           VALIDATE_INTERNALFORMAT(GL_RG8I)
1034 			case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_RG16UI)
1035 			case GL_SHORT:          VALIDATE_INTERNALFORMAT(GL_RG16I)
1036 			case GL_UNSIGNED_INT:   VALIDATE_INTERNALFORMAT(GL_RG32UI)
1037 			case GL_INT:            VALIDATE_INTERNALFORMAT(GL_RG32I)
1038 			default:                return GL_INVALID_OPERATION;
1039 			}
1040 			break;
1041 		case GL_RED:
1042 			switch(type)
1043 			{
1044 			case GL_UNSIGNED_BYTE:  VALIDATE_INTERNALFORMAT(GL_R8)
1045 			case GL_BYTE:           VALIDATE_INTERNALFORMAT(GL_R8_SNORM)
1046 			case GL_HALF_FLOAT_OES:
1047 			case GL_HALF_FLOAT:     VALIDATE_INTERNALFORMAT(GL_R16F)
1048 			case GL_FLOAT:          VALIDATE_INTERNALFORMAT(GL_R32F, GL_R16F)
1049 			default:                return GL_INVALID_OPERATION;
1050 			}
1051 			break;
1052 		case GL_RED_INTEGER:
1053 			switch(type)
1054 			{
1055 			case GL_UNSIGNED_BYTE:  VALIDATE_INTERNALFORMAT(GL_R8UI)
1056 			case GL_BYTE:           VALIDATE_INTERNALFORMAT(GL_R8I)
1057 			case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_R16UI)
1058 			case GL_SHORT:          VALIDATE_INTERNALFORMAT(GL_R16I)
1059 			case GL_UNSIGNED_INT:   VALIDATE_INTERNALFORMAT(GL_R32UI)
1060 			case GL_INT:            VALIDATE_INTERNALFORMAT(GL_R32I)
1061 			default:                return GL_INVALID_OPERATION;
1062 			}
1063 			break;
1064 		case GL_DEPTH_COMPONENT:
1065 			switch(type)
1066 			{
1067 			case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT16)
1068 			case GL_UNSIGNED_INT:   VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT16)
1069 			case GL_FLOAT:          VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT32F)
1070 			default:                return GL_INVALID_OPERATION;
1071 			}
1072 			break;
1073 		case GL_DEPTH_STENCIL:
1074 			switch(type)
1075 			{
1076 			case GL_UNSIGNED_INT_24_8:              VALIDATE_INTERNALFORMAT(GL_DEPTH24_STENCIL8)
1077 			case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: VALIDATE_INTERNALFORMAT(GL_DEPTH32F_STENCIL8)
1078 			default:                                return GL_INVALID_OPERATION;
1079 			}
1080 			break;
1081 		case GL_LUMINANCE_ALPHA:
1082 			switch(type)
1083 			{
1084 			case GL_UNSIGNED_BYTE:  VALIDATE_INTERNALFORMAT(GL_LUMINANCE8_ALPHA8_EXT)
1085 			case GL_HALF_FLOAT_OES:
1086 			case GL_HALF_FLOAT:     VALIDATE_INTERNALFORMAT(GL_LUMINANCE_ALPHA16F_EXT)
1087 			case GL_FLOAT:          VALIDATE_INTERNALFORMAT(GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA16F_EXT)
1088 			default:
1089 				return GL_INVALID_OPERATION;
1090 			}
1091 			break;
1092 		case GL_LUMINANCE:
1093 			switch(type)
1094 			{
1095 			case GL_UNSIGNED_BYTE:  VALIDATE_INTERNALFORMAT(GL_LUMINANCE8_EXT)
1096 			case GL_HALF_FLOAT_OES:
1097 			case GL_HALF_FLOAT:     VALIDATE_INTERNALFORMAT(GL_LUMINANCE16F_EXT)
1098 			case GL_FLOAT:          VALIDATE_INTERNALFORMAT(GL_LUMINANCE32F_EXT, GL_LUMINANCE16F_EXT)
1099 			default:
1100 				return GL_INVALID_OPERATION;
1101 			}
1102 			break;
1103 		case GL_ALPHA:
1104 			switch(type)
1105 			{
1106 			case GL_UNSIGNED_BYTE:  VALIDATE_INTERNALFORMAT(GL_ALPHA8_EXT)
1107 			case GL_HALF_FLOAT_OES:
1108 			case GL_HALF_FLOAT:     VALIDATE_INTERNALFORMAT(GL_ALPHA16F_EXT)
1109 			case GL_FLOAT:          VALIDATE_INTERNALFORMAT(GL_ALPHA32F_EXT, GL_ALPHA16F_EXT)
1110 			default:
1111 				return GL_INVALID_OPERATION;
1112 			}
1113 			break;
1114 		case GL_BGRA_EXT:   // GL_APPLE_texture_format_BGRA8888
1115 			switch(type)
1116 			{
1117 			case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_BGRA8_EXT)
1118 			default:               return GL_INVALID_OPERATION;
1119 			}
1120 			break;
1121 		default:
1122 			UNREACHABLE(format);
1123 			return GL_INVALID_ENUM;
1124 		}
1125 
1126 		#undef VALIDATE_INTERNALFORMAT
1127 
1128 		if(!validSizedInternalformat)
1129 		{
1130 			return GL_INVALID_OPERATION;
1131 		}
1132 
1133 		return GL_NO_ERROR;
1134 	}
1135 
GetTypeSize(GLenum type)1136 	size_t GetTypeSize(GLenum type)
1137 	{
1138 		switch(type)
1139 		{
1140 		case GL_BYTE:
1141 		case GL_UNSIGNED_BYTE:
1142 			return 1;
1143 		case GL_UNSIGNED_SHORT_4_4_4_4:
1144 		case GL_UNSIGNED_SHORT_5_5_5_1:
1145 		case GL_UNSIGNED_SHORT_5_6_5:
1146 		case GL_UNSIGNED_SHORT:
1147 		case GL_SHORT:
1148 		case GL_HALF_FLOAT:
1149 		case GL_HALF_FLOAT_OES:
1150 			return 2;
1151 		case GL_FLOAT:
1152 		case GL_UNSIGNED_INT_24_8:
1153 		case GL_UNSIGNED_INT:
1154 		case GL_INT:
1155 		case GL_UNSIGNED_INT_2_10_10_10_REV:
1156 		case GL_UNSIGNED_INT_10F_11F_11F_REV:
1157 		case GL_UNSIGNED_INT_5_9_9_9_REV:
1158 		case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
1159 			return 4;
1160 		default:
1161 			UNREACHABLE(type);
1162 			break;
1163 		}
1164 
1165 		return 1;
1166 	}
1167 
IsColorRenderable(GLint internalformat,GLint clientVersion)1168 	bool IsColorRenderable(GLint internalformat, GLint clientVersion)
1169 	{
1170 		if(IsCompressed(internalformat, clientVersion))
1171 		{
1172 			return false;
1173 		}
1174 
1175 		switch(internalformat)
1176 		{
1177 		case GL_RGBA4:
1178 		case GL_RGB5_A1:
1179 		case GL_RGB565:
1180 		case GL_R8:
1181 		case GL_RG8:
1182 		case GL_RGB8:
1183 		case GL_RGBA8:
1184 		case GL_R16F:
1185 		case GL_RG16F:
1186 		case GL_RGB16F:
1187 		case GL_RGBA16F:
1188 		case GL_R32F:
1189 		case GL_RG32F:
1190 		case GL_RGB32F:
1191 		case GL_RGBA32F:
1192 		case GL_BGRA8_EXT:   // GL_EXT_texture_format_BGRA8888
1193 			return true;
1194 		case GL_R8UI:
1195 		case GL_R8I:
1196 		case GL_R16UI:
1197 		case GL_R16I:
1198 		case GL_R32UI:
1199 		case GL_R32I:
1200 		case GL_RG8UI:
1201 		case GL_RG8I:
1202 		case GL_RG16UI:
1203 		case GL_RG16I:
1204 		case GL_RG32UI:
1205 		case GL_RG32I:
1206 		case GL_SRGB8_ALPHA8:
1207 		case GL_RGB10_A2:
1208 		case GL_RGBA8UI:
1209 		case GL_RGBA8I:
1210 		case GL_RGB10_A2UI:
1211 		case GL_RGBA16UI:
1212 		case GL_RGBA16I:
1213 		case GL_RGBA32I:
1214 		case GL_RGBA32UI:
1215 		case GL_R11F_G11F_B10F:
1216 			return clientVersion >= 3;
1217 		case GL_R8_SNORM:
1218 		case GL_RG8_SNORM:
1219 		case GL_RGB8_SNORM:
1220 		case GL_RGBA8_SNORM:
1221 		case GL_ALPHA8_EXT:
1222 		case GL_LUMINANCE8_EXT:
1223 		case GL_LUMINANCE8_ALPHA8_EXT:
1224 		case GL_ALPHA32F_EXT:
1225 		case GL_LUMINANCE32F_EXT:
1226 		case GL_LUMINANCE_ALPHA32F_EXT:
1227 		case GL_ALPHA16F_EXT:
1228 		case GL_LUMINANCE16F_EXT:
1229 		case GL_LUMINANCE_ALPHA16F_EXT:
1230 		case GL_DEPTH_COMPONENT24:
1231 		case GL_DEPTH_COMPONENT32_OES:
1232 		case GL_DEPTH_COMPONENT32F:
1233 		case GL_DEPTH32F_STENCIL8:
1234 		case GL_DEPTH_COMPONENT16:
1235 		case GL_STENCIL_INDEX8:
1236 		case GL_DEPTH24_STENCIL8_OES:
1237 			return false;
1238 		default:
1239 			UNIMPLEMENTED();
1240 		}
1241 
1242 		return false;
1243 	}
1244 
IsDepthRenderable(GLint internalformat,GLint clientVersion)1245 	bool IsDepthRenderable(GLint internalformat, GLint clientVersion)
1246 	{
1247 		if(IsCompressed(internalformat, clientVersion))
1248 		{
1249 			return false;
1250 		}
1251 
1252 		switch(internalformat)
1253 		{
1254 		case GL_DEPTH_COMPONENT24:
1255 		case GL_DEPTH_COMPONENT16:
1256 		case GL_DEPTH24_STENCIL8_OES:    // GL_OES_packed_depth_stencil
1257 		case GL_DEPTH_COMPONENT32_OES:   // GL_OES_depth32
1258 			return true;
1259 		case GL_DEPTH32F_STENCIL8:
1260 		case GL_DEPTH_COMPONENT32F:
1261 			return clientVersion >= 3;
1262 		case GL_STENCIL_INDEX8:
1263 		case GL_R8:
1264 		case GL_R8UI:
1265 		case GL_R8I:
1266 		case GL_R16UI:
1267 		case GL_R16I:
1268 		case GL_R32UI:
1269 		case GL_R32I:
1270 		case GL_RG8:
1271 		case GL_RG8UI:
1272 		case GL_RG8I:
1273 		case GL_RG16UI:
1274 		case GL_RG16I:
1275 		case GL_RG32UI:
1276 		case GL_RG32I:
1277 		case GL_SRGB8_ALPHA8:
1278 		case GL_RGB10_A2:
1279 		case GL_RGBA8UI:
1280 		case GL_RGBA8I:
1281 		case GL_RGB10_A2UI:
1282 		case GL_RGBA16UI:
1283 		case GL_RGBA16I:
1284 		case GL_RGBA32I:
1285 		case GL_RGBA32UI:
1286 		case GL_RGBA4:
1287 		case GL_RGB5_A1:
1288 		case GL_RGB565:
1289 		case GL_RGB8:
1290 		case GL_RGBA8:
1291 		case GL_RED:
1292 		case GL_RG:
1293 		case GL_RGB:
1294 		case GL_RGBA:
1295 		case GL_R16F:
1296 		case GL_RG16F:
1297 		case GL_R11F_G11F_B10F:
1298 		case GL_RGB16F:
1299 		case GL_RGBA16F:
1300 		case GL_R32F:
1301 		case GL_RG32F:
1302 		case GL_RGB32F:
1303 		case GL_RGBA32F:
1304 		case GL_R8_SNORM:
1305 		case GL_RG8_SNORM:
1306 		case GL_RGB8_SNORM:
1307 		case GL_RGBA8_SNORM:
1308 			return false;
1309 		default:
1310 			UNIMPLEMENTED();
1311 		}
1312 
1313 		return false;
1314 	}
1315 
IsStencilRenderable(GLint internalformat,GLint clientVersion)1316 	bool IsStencilRenderable(GLint internalformat, GLint clientVersion)
1317 	{
1318 		if(IsCompressed(internalformat, clientVersion))
1319 		{
1320 			return false;
1321 		}
1322 
1323 		switch(internalformat)
1324 		{
1325 		case GL_STENCIL_INDEX8:
1326 		case GL_DEPTH24_STENCIL8_OES:
1327 			return true;
1328 		case GL_DEPTH32F_STENCIL8:
1329 			return clientVersion >= 3;
1330 		case GL_R8:
1331 		case GL_R8UI:
1332 		case GL_R8I:
1333 		case GL_R16UI:
1334 		case GL_R16I:
1335 		case GL_R32UI:
1336 		case GL_R32I:
1337 		case GL_RG8:
1338 		case GL_RG8UI:
1339 		case GL_RG8I:
1340 		case GL_RG16UI:
1341 		case GL_RG16I:
1342 		case GL_RG32UI:
1343 		case GL_RG32I:
1344 		case GL_SRGB8_ALPHA8:
1345 		case GL_RGB10_A2:
1346 		case GL_RGBA8UI:
1347 		case GL_RGBA8I:
1348 		case GL_RGB10_A2UI:
1349 		case GL_RGBA16UI:
1350 		case GL_RGBA16I:
1351 		case GL_RGBA32I:
1352 		case GL_RGBA32UI:
1353 		case GL_RGBA4:
1354 		case GL_RGB5_A1:
1355 		case GL_RGB565:
1356 		case GL_RGB8:
1357 		case GL_RGBA8:
1358 		case GL_RED:
1359 		case GL_RG:
1360 		case GL_RGB:
1361 		case GL_RGBA:
1362 		case GL_R16F:
1363 		case GL_RG16F:
1364 		case GL_R11F_G11F_B10F:
1365 		case GL_RGB16F:
1366 		case GL_RGBA16F:
1367 		case GL_R32F:
1368 		case GL_RG32F:
1369 		case GL_RGB32F:
1370 		case GL_RGBA32F:
1371 		case GL_DEPTH_COMPONENT16:
1372 		case GL_DEPTH_COMPONENT24:
1373 		case GL_DEPTH_COMPONENT32_OES:
1374 		case GL_DEPTH_COMPONENT32F:
1375 		case GL_R8_SNORM:
1376 		case GL_RG8_SNORM:
1377 		case GL_RGB8_SNORM:
1378 		case GL_RGBA8_SNORM:
1379 			return false;
1380 		default:
1381 			UNIMPLEMENTED();
1382 		}
1383 
1384 		return false;
1385 	}
1386 
IsMipmappable(GLint internalformat,GLint clientVersion)1387 	bool IsMipmappable(GLint internalformat, GLint clientVersion)
1388 	{
1389 		if(IsNonNormalizedInteger(internalformat))
1390 		{
1391 			return false;
1392 		}
1393 
1394 		switch(internalformat)
1395 		{
1396 		case GL_ALPHA8_EXT:
1397 		case GL_LUMINANCE8_EXT:
1398 		case GL_LUMINANCE8_ALPHA8_EXT:
1399 		case GL_ALPHA32F_EXT:
1400 		case GL_LUMINANCE32F_EXT:
1401 		case GL_LUMINANCE_ALPHA32F_EXT:
1402 		case GL_ALPHA16F_EXT:
1403 		case GL_LUMINANCE16F_EXT:
1404 		case GL_LUMINANCE_ALPHA16F_EXT:
1405 			return true;
1406 		default:
1407 			return IsColorRenderable(internalformat, clientVersion);
1408 		}
1409 	}
1410 
GetAlphaSize(GLint internalformat)1411 	GLuint GetAlphaSize(GLint internalformat)
1412 	{
1413 		switch(internalformat)
1414 		{
1415 		case GL_NONE:           return 0;
1416 		case GL_RGBA4:          return 4;
1417 		case GL_RGB5_A1:        return 1;
1418 		case GL_RGB565:         return 0;
1419 		case GL_R8:             return 0;
1420 		case GL_RG8:            return 0;
1421 		case GL_RGB8:           return 0;
1422 		case GL_RGBA8:          return 8;
1423 		case GL_R16F:           return 0;
1424 		case GL_RG16F:          return 0;
1425 		case GL_RGB16F:         return 0;
1426 		case GL_RGBA16F:        return 16;
1427 		case GL_R32F:           return 0;
1428 		case GL_RG32F:          return 0;
1429 		case GL_RGB32F:         return 0;
1430 		case GL_RGBA32F:        return 32;
1431 		case GL_BGRA8_EXT:      return 8;
1432 		case GL_R8UI:           return 0;
1433 		case GL_R8I:            return 0;
1434 		case GL_R16UI:          return 0;
1435 		case GL_R16I:           return 0;
1436 		case GL_R32UI:          return 0;
1437 		case GL_R32I:           return 0;
1438 		case GL_RG8UI:          return 0;
1439 		case GL_RG8I:           return 0;
1440 		case GL_RG16UI:         return 0;
1441 		case GL_RG16I:          return 0;
1442 		case GL_RG32UI:         return 0;
1443 		case GL_RG32I:          return 0;
1444 		case GL_SRGB8_ALPHA8:   return 8;
1445 		case GL_RGB10_A2:       return 2;
1446 		case GL_RGBA8UI:        return 8;
1447 		case GL_RGBA8I:         return 8;
1448 		case GL_RGB10_A2UI:     return 2;
1449 		case GL_RGBA16UI:       return 16;
1450 		case GL_RGBA16I:        return 16;
1451 		case GL_RGBA32I:        return 32;
1452 		case GL_RGBA32UI:       return 32;
1453 		case GL_R11F_G11F_B10F: return 0;
1454 		default:
1455 		//	UNREACHABLE(internalformat);
1456 			return 0;
1457 		}
1458 	}
1459 
GetRedSize(GLint internalformat)1460 	GLuint GetRedSize(GLint internalformat)
1461 	{
1462 		switch(internalformat)
1463 		{
1464 		case GL_NONE:           return 0;
1465 		case GL_RGBA4:          return 4;
1466 		case GL_RGB5_A1:        return 5;
1467 		case GL_RGB565:         return 5;
1468 		case GL_R8:             return 8;
1469 		case GL_RG8:            return 8;
1470 		case GL_RGB8:           return 8;
1471 		case GL_RGBA8:          return 8;
1472 		case GL_R16F:           return 16;
1473 		case GL_RG16F:          return 16;
1474 		case GL_RGB16F:         return 16;
1475 		case GL_RGBA16F:        return 16;
1476 		case GL_R32F:           return 32;
1477 		case GL_RG32F:          return 32;
1478 		case GL_RGB32F:         return 32;
1479 		case GL_RGBA32F:        return 32;
1480 		case GL_BGRA8_EXT:      return 8;
1481 		case GL_R8UI:           return 8;
1482 		case GL_R8I:            return 8;
1483 		case GL_R16UI:          return 16;
1484 		case GL_R16I:           return 16;
1485 		case GL_R32UI:          return 32;
1486 		case GL_R32I:           return 32;
1487 		case GL_RG8UI:          return 8;
1488 		case GL_RG8I:           return 8;
1489 		case GL_RG16UI:         return 16;
1490 		case GL_RG16I:          return 16;
1491 		case GL_RG32UI:         return 32;
1492 		case GL_RG32I:          return 32;
1493 		case GL_SRGB8_ALPHA8:   return 8;
1494 		case GL_RGB10_A2:       return 10;
1495 		case GL_RGBA8UI:        return 8;
1496 		case GL_RGBA8I:         return 8;
1497 		case GL_RGB10_A2UI:     return 10;
1498 		case GL_RGBA16UI:       return 16;
1499 		case GL_RGBA16I:        return 16;
1500 		case GL_RGBA32I:        return 32;
1501 		case GL_RGBA32UI:       return 32;
1502 		case GL_R11F_G11F_B10F: return 11;
1503 		default:
1504 		//	UNREACHABLE(internalformat);
1505 			return 0;
1506 		}
1507 	}
1508 
GetGreenSize(GLint internalformat)1509 	GLuint GetGreenSize(GLint internalformat)
1510 	{
1511 		switch(internalformat)
1512 		{
1513 		case GL_NONE:           return 0;
1514 		case GL_RGBA4:          return 4;
1515 		case GL_RGB5_A1:        return 5;
1516 		case GL_RGB565:         return 6;
1517 		case GL_R8:             return 0;
1518 		case GL_RG8:            return 8;
1519 		case GL_RGB8:           return 8;
1520 		case GL_RGBA8:          return 8;
1521 		case GL_R16F:           return 0;
1522 		case GL_RG16F:          return 16;
1523 		case GL_RGB16F:         return 16;
1524 		case GL_RGBA16F:        return 16;
1525 		case GL_R32F:           return 0;
1526 		case GL_RG32F:          return 32;
1527 		case GL_RGB32F:         return 32;
1528 		case GL_RGBA32F:        return 32;
1529 		case GL_BGRA8_EXT:      return 8;
1530 		case GL_R8UI:           return 0;
1531 		case GL_R8I:            return 0;
1532 		case GL_R16UI:          return 0;
1533 		case GL_R16I:           return 0;
1534 		case GL_R32UI:          return 0;
1535 		case GL_R32I:           return 0;
1536 		case GL_RG8UI:          return 8;
1537 		case GL_RG8I:           return 8;
1538 		case GL_RG16UI:         return 16;
1539 		case GL_RG16I:          return 16;
1540 		case GL_RG32UI:         return 32;
1541 		case GL_RG32I:          return 32;
1542 		case GL_SRGB8_ALPHA8:   return 8;
1543 		case GL_RGB10_A2:       return 10;
1544 		case GL_RGBA8UI:        return 8;
1545 		case GL_RGBA8I:         return 8;
1546 		case GL_RGB10_A2UI:     return 10;
1547 		case GL_RGBA16UI:       return 16;
1548 		case GL_RGBA16I:        return 16;
1549 		case GL_RGBA32I:        return 32;
1550 		case GL_RGBA32UI:       return 32;
1551 		case GL_R11F_G11F_B10F: return 11;
1552 		default:
1553 		//	UNREACHABLE(internalformat);
1554 			return 0;
1555 		}
1556 	}
1557 
GetBlueSize(GLint internalformat)1558 	GLuint GetBlueSize(GLint internalformat)
1559 	{
1560 		switch(internalformat)
1561 		{
1562 		case GL_NONE:           return 0;
1563 		case GL_RGBA4:          return 4;
1564 		case GL_RGB5_A1:        return 5;
1565 		case GL_RGB565:         return 5;
1566 		case GL_R8:             return 0;
1567 		case GL_RG8:            return 0;
1568 		case GL_RGB8:           return 8;
1569 		case GL_RGBA8:          return 8;
1570 		case GL_R16F:           return 0;
1571 		case GL_RG16F:          return 0;
1572 		case GL_RGB16F:         return 16;
1573 		case GL_RGBA16F:        return 16;
1574 		case GL_R32F:           return 0;
1575 		case GL_RG32F:          return 0;
1576 		case GL_RGB32F:         return 32;
1577 		case GL_RGBA32F:        return 32;
1578 		case GL_BGRA8_EXT:      return 8;
1579 		case GL_R8UI:           return 0;
1580 		case GL_R8I:            return 0;
1581 		case GL_R16UI:          return 0;
1582 		case GL_R16I:           return 0;
1583 		case GL_R32UI:          return 0;
1584 		case GL_R32I:           return 0;
1585 		case GL_RG8UI:          return 0;
1586 		case GL_RG8I:           return 0;
1587 		case GL_RG16UI:         return 0;
1588 		case GL_RG16I:          return 0;
1589 		case GL_RG32UI:         return 0;
1590 		case GL_RG32I:          return 0;
1591 		case GL_SRGB8_ALPHA8:   return 8;
1592 		case GL_RGB10_A2:       return 10;
1593 		case GL_RGBA8UI:        return 8;
1594 		case GL_RGBA8I:         return 8;
1595 		case GL_RGB10_A2UI:     return 10;
1596 		case GL_RGBA16UI:       return 16;
1597 		case GL_RGBA16I:        return 16;
1598 		case GL_RGBA32I:        return 32;
1599 		case GL_RGBA32UI:       return 32;
1600 		case GL_R11F_G11F_B10F: return 10;
1601 		default:
1602 		//	UNREACHABLE(internalformat);
1603 			return 0;
1604 		}
1605 	}
1606 
GetDepthSize(GLint internalformat)1607 	GLuint GetDepthSize(GLint internalformat)
1608 	{
1609 		switch(internalformat)
1610 		{
1611 		case GL_STENCIL_INDEX8:        return 0;
1612 		case GL_DEPTH_COMPONENT16:     return 16;
1613 		case GL_DEPTH_COMPONENT24:     return 24;
1614 		case GL_DEPTH_COMPONENT32_OES: return 32;
1615 		case GL_DEPTH_COMPONENT32F:    return 32;
1616 		case GL_DEPTH24_STENCIL8:      return 24;
1617 		case GL_DEPTH32F_STENCIL8:     return 32;
1618 		default:
1619 		//	UNREACHABLE(internalformat);
1620 			return 0;
1621 		}
1622 	}
1623 
GetStencilSize(GLint internalformat)1624 	GLuint GetStencilSize(GLint internalformat)
1625 	{
1626 		switch(internalformat)
1627 		{
1628 		case GL_STENCIL_INDEX8:        return 8;
1629 		case GL_DEPTH_COMPONENT16:     return 0;
1630 		case GL_DEPTH_COMPONENT24:     return 0;
1631 		case GL_DEPTH_COMPONENT32_OES: return 0;
1632 		case GL_DEPTH_COMPONENT32F:    return 0;
1633 		case GL_DEPTH24_STENCIL8:      return 8;
1634 		case GL_DEPTH32F_STENCIL8:     return 8;
1635 		default:
1636 		//	UNREACHABLE(internalformat);
1637 			return 0;
1638 		}
1639 	}
1640 
GetColorComponentType(GLint internalformat)1641 	GLenum GetColorComponentType(GLint internalformat)
1642 	{
1643 		switch(internalformat)
1644 		{
1645 		case GL_ALPHA8_EXT:
1646 		case GL_LUMINANCE8_ALPHA8_EXT:
1647 		case GL_LUMINANCE8_EXT:
1648 		case GL_R8:
1649 		case GL_RG8:
1650 		case GL_SRGB8_ALPHA8:
1651 		case GL_RGB10_A2:
1652 		case GL_RGBA4:
1653 		case GL_RGB5_A1:
1654 		case GL_RGB565:
1655 		case GL_RGB8:
1656 		case GL_RGBA8:
1657 		case GL_SRGB8:
1658 		case GL_BGRA8_EXT:
1659 			return GL_UNSIGNED_NORMALIZED;
1660 		case GL_R8_SNORM:
1661 		case GL_RG8_SNORM:
1662 		case GL_RGB8_SNORM:
1663 		case GL_RGBA8_SNORM:
1664 			return GL_SIGNED_NORMALIZED;
1665 		case GL_R8UI:
1666 		case GL_R16UI:
1667 		case GL_R32UI:
1668 		case GL_RG8UI:
1669 		case GL_RG16UI:
1670 		case GL_RG32UI:
1671 		case GL_RGB8UI:
1672 		case GL_RGB16UI:
1673 		case GL_RGB32UI:
1674 		case GL_RGB10_A2UI:
1675 		case GL_RGBA16UI:
1676 		case GL_RGBA32UI:
1677 		case GL_RGBA8UI:
1678 			return GL_UNSIGNED_INT;
1679 		case GL_R8I:
1680 		case GL_R16I:
1681 		case GL_R32I:
1682 		case GL_RG8I:
1683 		case GL_RG16I:
1684 		case GL_RG32I:
1685 		case GL_RGB8I:
1686 		case GL_RGB16I:
1687 		case GL_RGB32I:
1688 		case GL_RGBA8I:
1689 		case GL_RGBA16I:
1690 		case GL_RGBA32I:
1691 			return GL_INT;
1692 		case GL_ALPHA32F_EXT:
1693 		case GL_LUMINANCE32F_EXT:
1694 		case GL_LUMINANCE_ALPHA32F_EXT:
1695 		case GL_ALPHA16F_EXT:
1696 		case GL_LUMINANCE16F_EXT:
1697 		case GL_LUMINANCE_ALPHA16F_EXT:
1698 		case GL_R16F:
1699 		case GL_RG16F:
1700 		case GL_R11F_G11F_B10F:
1701 		case GL_RGB16F:
1702 		case GL_RGBA16F:
1703 		case GL_R32F:
1704 		case GL_RG32F:
1705 		case GL_RGB32F:
1706 		case GL_RGBA32F:
1707 		case GL_RGB9_E5:
1708 			return GL_FLOAT;
1709 		default:
1710 		//	UNREACHABLE(internalformat);
1711 			return GL_NONE;
1712 		}
1713 	}
1714 
GetComponentType(GLint internalformat,GLenum attachment)1715 	GLenum GetComponentType(GLint internalformat, GLenum attachment)
1716 	{
1717 		// Can be one of GL_FLOAT, GL_INT, GL_UNSIGNED_INT, GL_SIGNED_NORMALIZED, or GL_UNSIGNED_NORMALIZED
1718 		switch(attachment)
1719 		{
1720 		case GL_COLOR_ATTACHMENT0:
1721 		case GL_COLOR_ATTACHMENT1:
1722 		case GL_COLOR_ATTACHMENT2:
1723 		case GL_COLOR_ATTACHMENT3:
1724 		case GL_COLOR_ATTACHMENT4:
1725 		case GL_COLOR_ATTACHMENT5:
1726 		case GL_COLOR_ATTACHMENT6:
1727 		case GL_COLOR_ATTACHMENT7:
1728 		case GL_COLOR_ATTACHMENT8:
1729 		case GL_COLOR_ATTACHMENT9:
1730 		case GL_COLOR_ATTACHMENT10:
1731 		case GL_COLOR_ATTACHMENT11:
1732 		case GL_COLOR_ATTACHMENT12:
1733 		case GL_COLOR_ATTACHMENT13:
1734 		case GL_COLOR_ATTACHMENT14:
1735 		case GL_COLOR_ATTACHMENT15:
1736 		case GL_COLOR_ATTACHMENT16:
1737 		case GL_COLOR_ATTACHMENT17:
1738 		case GL_COLOR_ATTACHMENT18:
1739 		case GL_COLOR_ATTACHMENT19:
1740 		case GL_COLOR_ATTACHMENT20:
1741 		case GL_COLOR_ATTACHMENT21:
1742 		case GL_COLOR_ATTACHMENT22:
1743 		case GL_COLOR_ATTACHMENT23:
1744 		case GL_COLOR_ATTACHMENT24:
1745 		case GL_COLOR_ATTACHMENT25:
1746 		case GL_COLOR_ATTACHMENT26:
1747 		case GL_COLOR_ATTACHMENT27:
1748 		case GL_COLOR_ATTACHMENT28:
1749 		case GL_COLOR_ATTACHMENT29:
1750 		case GL_COLOR_ATTACHMENT30:
1751 		case GL_COLOR_ATTACHMENT31:
1752 			return GetColorComponentType(internalformat);
1753 		case GL_DEPTH_ATTACHMENT:
1754 		case GL_STENCIL_ATTACHMENT:
1755 			// Only color buffers may have integer components.
1756 			return GL_FLOAT;
1757 		default:
1758 			UNREACHABLE(attachment);
1759 			return GL_NONE;
1760 		}
1761 	}
1762 
IsNormalizedInteger(GLint internalformat)1763 	bool IsNormalizedInteger(GLint internalformat)
1764 	{
1765 		GLenum type = GetColorComponentType(internalformat);
1766 
1767 		return type == GL_UNSIGNED_NORMALIZED || type == GL_SIGNED_NORMALIZED;
1768 	}
1769 
IsNonNormalizedInteger(GLint internalformat)1770 	bool IsNonNormalizedInteger(GLint internalformat)
1771 	{
1772 		GLenum type = GetColorComponentType(internalformat);
1773 
1774 		return type == GL_UNSIGNED_INT || type == GL_INT;
1775 	}
1776 
IsFloatFormat(GLint internalformat)1777 	bool IsFloatFormat(GLint internalformat)
1778 	{
1779 		return GetColorComponentType(internalformat) == GL_FLOAT;
1780 	}
1781 
IsSignedNonNormalizedInteger(GLint internalformat)1782 	bool IsSignedNonNormalizedInteger(GLint internalformat)
1783 	{
1784 		return GetColorComponentType(internalformat) == GL_INT;
1785 	}
1786 
IsUnsignedNonNormalizedInteger(GLint internalformat)1787 	bool IsUnsignedNonNormalizedInteger(GLint internalformat)
1788 	{
1789 		return GetColorComponentType(internalformat) == GL_UNSIGNED_INT;
1790 	}
1791 
GetColorEncoding(GLint internalformat)1792 	GLenum GetColorEncoding(GLint internalformat)
1793 	{
1794 		switch(internalformat)
1795 		{
1796 		case GL_SRGB8:
1797 		case GL_SRGB8_ALPHA8:
1798 			return GL_SRGB;
1799 		default:
1800 			// [OpenGL ES 3.0.5] section 6.1.13 page 242:
1801 			// If attachment is not a color attachment, or no data storage or texture image
1802 			// has been specified for the attachment, params will contain the value LINEAR.
1803 			return GL_LINEAR;
1804 		}
1805 	}
1806 
ParseUniformName(const std::string & name,unsigned int * outSubscript)1807 	std::string ParseUniformName(const std::string &name, unsigned int *outSubscript)
1808 	{
1809 		// Strip any trailing array operator and retrieve the subscript
1810 		size_t open = name.find_last_of('[');
1811 		size_t close = name.find_last_of(']');
1812 		bool hasIndex = (open != std::string::npos) && (close == name.length() - 1);
1813 		if(!hasIndex)
1814 		{
1815 			if(outSubscript)
1816 			{
1817 				*outSubscript = GL_INVALID_INDEX;
1818 			}
1819 			return name;
1820 		}
1821 
1822 		if(outSubscript)
1823 		{
1824 			int index = atoi(name.substr(open + 1).c_str());
1825 			if(index >= 0)
1826 			{
1827 				*outSubscript = index;
1828 			}
1829 			else
1830 			{
1831 				*outSubscript = GL_INVALID_INDEX;
1832 			}
1833 		}
1834 
1835 		return name.substr(0, open);
1836 	}
1837 }
1838 
1839 namespace es2sw
1840 {
ConvertDepthComparison(GLenum comparison)1841 	sw::DepthCompareMode ConvertDepthComparison(GLenum comparison)
1842 	{
1843 		switch(comparison)
1844 		{
1845 		case GL_NEVER:    return sw::DEPTH_NEVER;
1846 		case GL_ALWAYS:   return sw::DEPTH_ALWAYS;
1847 		case GL_LESS:     return sw::DEPTH_LESS;
1848 		case GL_LEQUAL:   return sw::DEPTH_LESSEQUAL;
1849 		case GL_EQUAL:    return sw::DEPTH_EQUAL;
1850 		case GL_GREATER:  return sw::DEPTH_GREATER;
1851 		case GL_GEQUAL:   return sw::DEPTH_GREATEREQUAL;
1852 		case GL_NOTEQUAL: return sw::DEPTH_NOTEQUAL;
1853 		default: UNREACHABLE(comparison);
1854 		}
1855 
1856 		return sw::DEPTH_ALWAYS;
1857 	}
1858 
ConvertStencilComparison(GLenum comparison)1859 	sw::StencilCompareMode ConvertStencilComparison(GLenum comparison)
1860 	{
1861 		switch(comparison)
1862 		{
1863 		case GL_NEVER:    return sw::STENCIL_NEVER;
1864 		case GL_ALWAYS:   return sw::STENCIL_ALWAYS;
1865 		case GL_LESS:     return sw::STENCIL_LESS;
1866 		case GL_LEQUAL:   return sw::STENCIL_LESSEQUAL;
1867 		case GL_EQUAL:    return sw::STENCIL_EQUAL;
1868 		case GL_GREATER:  return sw::STENCIL_GREATER;
1869 		case GL_GEQUAL:   return sw::STENCIL_GREATEREQUAL;
1870 		case GL_NOTEQUAL: return sw::STENCIL_NOTEQUAL;
1871 		default: UNREACHABLE(comparison);
1872 		}
1873 
1874 		return sw::STENCIL_ALWAYS;
1875 	}
1876 
ConvertColor(es2::Color color)1877 	sw::Color<float> ConvertColor(es2::Color color)
1878 	{
1879 		return sw::Color<float>(color.red, color.green, color.blue, color.alpha);
1880 	}
1881 
ConvertBlendFunc(GLenum blend)1882 	sw::BlendFactor ConvertBlendFunc(GLenum blend)
1883 	{
1884 		switch(blend)
1885 		{
1886 		case GL_ZERO:                     return sw::BLEND_ZERO;
1887 		case GL_ONE:                      return sw::BLEND_ONE;
1888 		case GL_SRC_COLOR:                return sw::BLEND_SOURCE;
1889 		case GL_ONE_MINUS_SRC_COLOR:      return sw::BLEND_INVSOURCE;
1890 		case GL_DST_COLOR:                return sw::BLEND_DEST;
1891 		case GL_ONE_MINUS_DST_COLOR:      return sw::BLEND_INVDEST;
1892 		case GL_SRC_ALPHA:                return sw::BLEND_SOURCEALPHA;
1893 		case GL_ONE_MINUS_SRC_ALPHA:      return sw::BLEND_INVSOURCEALPHA;
1894 		case GL_DST_ALPHA:                return sw::BLEND_DESTALPHA;
1895 		case GL_ONE_MINUS_DST_ALPHA:      return sw::BLEND_INVDESTALPHA;
1896 		case GL_CONSTANT_COLOR:           return sw::BLEND_CONSTANT;
1897 		case GL_ONE_MINUS_CONSTANT_COLOR: return sw::BLEND_INVCONSTANT;
1898 		case GL_CONSTANT_ALPHA:           return sw::BLEND_CONSTANTALPHA;
1899 		case GL_ONE_MINUS_CONSTANT_ALPHA: return sw::BLEND_INVCONSTANTALPHA;
1900 		case GL_SRC_ALPHA_SATURATE:       return sw::BLEND_SRCALPHASAT;
1901 		default: UNREACHABLE(blend);
1902 		}
1903 
1904 		return sw::BLEND_ZERO;
1905 	}
1906 
ConvertBlendOp(GLenum blendOp)1907 	sw::BlendOperation ConvertBlendOp(GLenum blendOp)
1908 	{
1909 		switch(blendOp)
1910 		{
1911 		case GL_FUNC_ADD:              return sw::BLENDOP_ADD;
1912 		case GL_FUNC_SUBTRACT:         return sw::BLENDOP_SUB;
1913 		case GL_FUNC_REVERSE_SUBTRACT: return sw::BLENDOP_INVSUB;
1914 		case GL_MIN_EXT:               return sw::BLENDOP_MIN;
1915 		case GL_MAX_EXT:               return sw::BLENDOP_MAX;
1916 		default: UNREACHABLE(blendOp);
1917 		}
1918 
1919 		return sw::BLENDOP_ADD;
1920 	}
1921 
ConvertStencilOp(GLenum stencilOp)1922 	sw::StencilOperation ConvertStencilOp(GLenum stencilOp)
1923 	{
1924 		switch(stencilOp)
1925 		{
1926 		case GL_ZERO:      return sw::OPERATION_ZERO;
1927 		case GL_KEEP:      return sw::OPERATION_KEEP;
1928 		case GL_REPLACE:   return sw::OPERATION_REPLACE;
1929 		case GL_INCR:      return sw::OPERATION_INCRSAT;
1930 		case GL_DECR:      return sw::OPERATION_DECRSAT;
1931 		case GL_INVERT:    return sw::OPERATION_INVERT;
1932 		case GL_INCR_WRAP: return sw::OPERATION_INCR;
1933 		case GL_DECR_WRAP: return sw::OPERATION_DECR;
1934 		default: UNREACHABLE(stencilOp);
1935 		}
1936 
1937 		return sw::OPERATION_KEEP;
1938 	}
1939 
ConvertTextureWrap(GLenum wrap)1940 	sw::AddressingMode ConvertTextureWrap(GLenum wrap)
1941 	{
1942 		switch(wrap)
1943 		{
1944 		case GL_REPEAT:            return sw::ADDRESSING_WRAP;
1945 		case GL_CLAMP_TO_EDGE:     return sw::ADDRESSING_CLAMP;
1946 		case GL_MIRRORED_REPEAT:   return sw::ADDRESSING_MIRROR;
1947 		default: UNREACHABLE(wrap);
1948 		}
1949 
1950 		return sw::ADDRESSING_WRAP;
1951 	}
1952 
ConvertCompareFunc(GLenum compareFunc,GLenum compareMode)1953 	sw::CompareFunc ConvertCompareFunc(GLenum compareFunc, GLenum compareMode)
1954 	{
1955 		if(compareMode == GL_COMPARE_REF_TO_TEXTURE)
1956 		{
1957 			switch(compareFunc)
1958 			{
1959 			case GL_LEQUAL:   return sw::COMPARE_LESSEQUAL;
1960 			case GL_GEQUAL:   return sw::COMPARE_GREATEREQUAL;
1961 			case GL_LESS:     return sw::COMPARE_LESS;
1962 			case GL_GREATER:  return sw::COMPARE_GREATER;
1963 			case GL_EQUAL:    return sw::COMPARE_EQUAL;
1964 			case GL_NOTEQUAL: return sw::COMPARE_NOTEQUAL;
1965 			case GL_ALWAYS:   return sw::COMPARE_ALWAYS;
1966 			case GL_NEVER:    return sw::COMPARE_NEVER;
1967 			default: UNREACHABLE(compareFunc);
1968 			}
1969 		}
1970 		else if(compareMode == GL_NONE)
1971 		{
1972 			return sw::COMPARE_BYPASS;
1973 		}
1974 		else UNREACHABLE(compareMode);
1975 
1976 		return sw::COMPARE_BYPASS;
1977 	};
1978 
ConvertSwizzleType(GLenum swizzleType)1979 	sw::SwizzleType ConvertSwizzleType(GLenum swizzleType)
1980 	{
1981 		switch(swizzleType)
1982 		{
1983 		case GL_RED:   return sw::SWIZZLE_RED;
1984 		case GL_GREEN: return sw::SWIZZLE_GREEN;
1985 		case GL_BLUE:  return sw::SWIZZLE_BLUE;
1986 		case GL_ALPHA: return sw::SWIZZLE_ALPHA;
1987 		case GL_ZERO:  return sw::SWIZZLE_ZERO;
1988 		case GL_ONE:   return sw::SWIZZLE_ONE;
1989 		default: UNREACHABLE(swizzleType);
1990 		}
1991 
1992 		return sw::SWIZZLE_RED;
1993 	};
1994 
ConvertCullMode(GLenum cullFace,GLenum frontFace)1995 	sw::CullMode ConvertCullMode(GLenum cullFace, GLenum frontFace)
1996 	{
1997 		switch(cullFace)
1998 		{
1999 		case GL_FRONT:
2000 			return (frontFace == GL_CCW ? sw::CULL_CLOCKWISE : sw::CULL_COUNTERCLOCKWISE);
2001 		case GL_BACK:
2002 			return (frontFace == GL_CCW ? sw::CULL_COUNTERCLOCKWISE : sw::CULL_CLOCKWISE);
2003 		case GL_FRONT_AND_BACK:
2004 			return sw::CULL_NONE;   // culling will be handled during draw
2005 		default: UNREACHABLE(cullFace);
2006 		}
2007 
2008 		return sw::CULL_COUNTERCLOCKWISE;
2009 	}
2010 
ConvertColorMask(bool red,bool green,bool blue,bool alpha)2011 	unsigned int ConvertColorMask(bool red, bool green, bool blue, bool alpha)
2012 	{
2013 		return (red   ? 0x00000001 : 0) |
2014 			   (green ? 0x00000002 : 0) |
2015 			   (blue  ? 0x00000004 : 0) |
2016 			   (alpha ? 0x00000008 : 0);
2017 	}
2018 
ConvertMipMapFilter(GLenum minFilter)2019 	sw::MipmapType ConvertMipMapFilter(GLenum minFilter)
2020 	{
2021 		switch(minFilter)
2022 		{
2023 		case GL_NEAREST:
2024 		case GL_LINEAR:
2025 			return sw::MIPMAP_NONE;
2026 		case GL_NEAREST_MIPMAP_NEAREST:
2027 		case GL_LINEAR_MIPMAP_NEAREST:
2028 			return sw::MIPMAP_POINT;
2029 		case GL_NEAREST_MIPMAP_LINEAR:
2030 		case GL_LINEAR_MIPMAP_LINEAR:
2031 			return sw::MIPMAP_LINEAR;
2032 		default:
2033 			UNREACHABLE(minFilter);
2034 			return sw::MIPMAP_NONE;
2035 		}
2036 	}
2037 
ConvertTextureFilter(GLenum minFilter,GLenum magFilter,float maxAnisotropy)2038 	sw::FilterType ConvertTextureFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy)
2039 	{
2040 		if(maxAnisotropy > 1.0f)
2041 		{
2042 			return sw::FILTER_ANISOTROPIC;
2043 		}
2044 
2045 		switch(magFilter)
2046 		{
2047 		case GL_NEAREST:
2048 		case GL_LINEAR:
2049 			break;
2050 		default:
2051 			UNREACHABLE(magFilter);
2052 		}
2053 
2054 		switch(minFilter)
2055 		{
2056 		case GL_NEAREST:
2057 		case GL_NEAREST_MIPMAP_NEAREST:
2058 		case GL_NEAREST_MIPMAP_LINEAR:
2059 			return (magFilter == GL_NEAREST) ? sw::FILTER_POINT : sw::FILTER_MIN_POINT_MAG_LINEAR;
2060 		case GL_LINEAR:
2061 		case GL_LINEAR_MIPMAP_NEAREST:
2062 		case GL_LINEAR_MIPMAP_LINEAR:
2063 			return (magFilter == GL_NEAREST) ? sw::FILTER_MIN_LINEAR_MAG_POINT : sw::FILTER_LINEAR;
2064 		default:
2065 			UNREACHABLE(minFilter);
2066 			return sw::FILTER_POINT;
2067 		}
2068 	}
2069 
ConvertPrimitiveType(GLenum primitiveType,GLsizei elementCount,GLenum elementType,sw::DrawType & drawType,int & primitiveCount,int & verticesPerPrimitive)2070 	bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount, GLenum elementType, sw::DrawType &drawType, int &primitiveCount, int &verticesPerPrimitive)
2071 	{
2072 		switch(primitiveType)
2073 		{
2074 		case GL_POINTS:
2075 			drawType = sw::DRAW_POINTLIST;
2076 			primitiveCount = elementCount;
2077 			verticesPerPrimitive = 1;
2078 			break;
2079 		case GL_LINES:
2080 			drawType = sw::DRAW_LINELIST;
2081 			primitiveCount = elementCount / 2;
2082 			verticesPerPrimitive = 2;
2083 			break;
2084 		case GL_LINE_LOOP:
2085 			drawType = sw::DRAW_LINELOOP;
2086 			primitiveCount = elementCount;
2087 			verticesPerPrimitive = 2;
2088 			break;
2089 		case GL_LINE_STRIP:
2090 			drawType = sw::DRAW_LINESTRIP;
2091 			primitiveCount = elementCount - 1;
2092 			verticesPerPrimitive = 2;
2093 			break;
2094 		case GL_TRIANGLES:
2095 			drawType = sw::DRAW_TRIANGLELIST;
2096 			primitiveCount = elementCount / 3;
2097 			verticesPerPrimitive = 3;
2098 			break;
2099 		case GL_TRIANGLE_STRIP:
2100 			drawType = sw::DRAW_TRIANGLESTRIP;
2101 			primitiveCount = elementCount - 2;
2102 			verticesPerPrimitive = 3;
2103 			break;
2104 		case GL_TRIANGLE_FAN:
2105 			drawType = sw::DRAW_TRIANGLEFAN;
2106 			primitiveCount = elementCount - 2;
2107 			verticesPerPrimitive = 3;
2108 			break;
2109 		default:
2110 			return false;
2111 		}
2112 
2113 		sw::DrawType elementSize;
2114 		switch(elementType)
2115 		{
2116 		case GL_NONE:           elementSize = sw::DRAW_NONINDEXED; break;
2117 		case GL_UNSIGNED_BYTE:  elementSize = sw::DRAW_INDEXED8;   break;
2118 		case GL_UNSIGNED_SHORT: elementSize = sw::DRAW_INDEXED16;  break;
2119 		case GL_UNSIGNED_INT:   elementSize = sw::DRAW_INDEXED32;  break;
2120 		default: return false;
2121 		}
2122 
2123 		drawType = sw::DrawType(drawType | elementSize);
2124 
2125 		return true;
2126 	}
2127 }
2128 
2129 namespace sw2es
2130 {
ConvertBackBufferFormat(sw::Format format)2131 	GLenum ConvertBackBufferFormat(sw::Format format)
2132 	{
2133 		switch(format)
2134 		{
2135 		case sw::FORMAT_A4R4G4B4: return GL_RGBA4;
2136 		case sw::FORMAT_A8R8G8B8: return GL_RGBA8;
2137 		case sw::FORMAT_A8B8G8R8: return GL_RGBA8;
2138 		case sw::FORMAT_A1R5G5B5: return GL_RGB5_A1;
2139 		case sw::FORMAT_R5G6B5:   return GL_RGB565;
2140 		case sw::FORMAT_X8R8G8B8: return GL_RGB8;
2141 		case sw::FORMAT_X8B8G8R8: return GL_RGB8;
2142 		case sw::FORMAT_SRGB8_A8: return GL_RGBA8;
2143 		case sw::FORMAT_SRGB8_X8: return GL_RGB8;
2144 		default:
2145 			UNREACHABLE(format);
2146 		}
2147 
2148 		return GL_RGBA4;
2149 	}
2150 
ConvertDepthStencilFormat(sw::Format format)2151 	GLenum ConvertDepthStencilFormat(sw::Format format)
2152 	{
2153 		switch(format)
2154 		{
2155 		case sw::FORMAT_D16:    return GL_DEPTH_COMPONENT16;
2156 		case sw::FORMAT_D24X8:  return GL_DEPTH_COMPONENT24;
2157 		case sw::FORMAT_D32:    return GL_DEPTH_COMPONENT32_OES;
2158 		case sw::FORMAT_D24S8:  return GL_DEPTH24_STENCIL8_OES;
2159 		case sw::FORMAT_D32F:   return GL_DEPTH_COMPONENT32F;
2160 		case sw::FORMAT_D32FS8: return GL_DEPTH32F_STENCIL8;
2161 		case sw::FORMAT_S8:     return GL_STENCIL_INDEX8;
2162 		default:
2163 			UNREACHABLE(format);
2164 		}
2165 
2166 		return GL_DEPTH24_STENCIL8_OES;
2167 	}
2168 }