• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)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 
IsSizedInternalFormat(GLint internalformat)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 
ValidateSubImageParams(bool compressed,bool copy,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLenum type,Texture * texture)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 
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)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 
ValidateCopyFormats(GLenum textureFormat,GLenum colorbufferFormat)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 
ValidateReadPixelsFormatType(const Framebuffer * framebuffer,GLenum format,GLenum type)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_stencil
683 		if(format == GL_STENCIL_INDEX_OES)
684 		{
685 			Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
686 
687 			if(!stencilbuffer)
688 			{
689 				return error(GL_INVALID_OPERATION, false);
690 			}
691 
692 			switch(type)
693 			{
694 			case GL_UNSIGNED_BYTE:
695 				break;
696 			default:
697 				return error(GL_INVALID_ENUM, false);
698 			}
699 
700 			return true;
701 		}
702 
703 		Renderbuffer *colorbuffer = framebuffer->getReadColorbuffer();
704 
705 		if(!colorbuffer)
706 		{
707 			return error(GL_INVALID_OPERATION, false);
708 		}
709 
710 		GLint internalformat = colorbuffer->getFormat();
711 
712 		if(IsNormalizedInteger(internalformat))
713 		{
714 			// Combination always supported by normalized fixed-point rendering surfaces.
715 			if(format == GL_RGBA && type == GL_UNSIGNED_BYTE)
716 			{
717 				return true;
718 			}
719 
720 			// GL_EXT_read_format_bgra combinations.
721 			if(format == GL_BGRA_EXT)
722 			{
723 				if(type == GL_UNSIGNED_BYTE ||
724 				   type == GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT ||
725 				   type == GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT)
726 				{
727 					return true;
728 				}
729 			}
730 		}
731 		else if(IsFloatFormat(internalformat))
732 		{
733 			// Combination always supported by floating-point rendering surfaces.
734 			// Supported in OpenGL ES 2.0 due to GL_EXT_color_buffer_half_float.
735 			if(format == GL_RGBA && type == GL_FLOAT)
736 			{
737 				return true;
738 			}
739 		}
740 		else if(IsSignedNonNormalizedInteger(internalformat))
741 		{
742 			if(format == GL_RGBA_INTEGER && type == GL_INT)
743 			{
744 				return true;
745 			}
746 		}
747 		else if(IsUnsignedNonNormalizedInteger(internalformat))
748 		{
749 			if(format == GL_RGBA_INTEGER && type == GL_UNSIGNED_INT)
750 			{
751 				return true;
752 			}
753 		}
754 		else UNREACHABLE(internalformat);
755 
756 		// GL_IMPLEMENTATION_COLOR_READ_FORMAT / GL_IMPLEMENTATION_COLOR_READ_TYPE
757 		GLenum implementationReadFormat = GL_NONE;
758 		GLenum implementationReadType = GL_NONE;
759 		switch(format)
760 		{
761 		default:
762 			implementationReadFormat = framebuffer->getImplementationColorReadFormat();
763 			implementationReadType = framebuffer->getImplementationColorReadType();
764 			break;
765 		case GL_DEPTH_COMPONENT:
766 			implementationReadFormat = framebuffer->getDepthReadFormat();
767 			implementationReadType = framebuffer->getDepthReadType();
768 			break;
769 		}
770 
771 		GLenum coreType = (type == GL_HALF_FLOAT_OES) ? GL_HALF_FLOAT : type;
772 
773 		if(format == implementationReadFormat && coreType == implementationReadType)
774 		{
775 			return true;
776 		}
777 
778 		// Additional third combination accepted by OpenGL ES 3.0.
779 		if(internalformat == GL_RGB10_A2)
780 		{
781 			if(format == GL_RGBA && type == GL_UNSIGNED_INT_2_10_10_10_REV)
782 			{
783 				return true;
784 			}
785 		}
786 
787 		return error(GL_INVALID_OPERATION, false);
788 	}
789 
IsDepthTexture(GLint format)790 	bool IsDepthTexture(GLint format)
791 	{
792 		return format == GL_DEPTH_COMPONENT16 ||
793 		       format == GL_DEPTH_COMPONENT24 ||
794 		       format == GL_DEPTH_COMPONENT32_OES ||
795 		       format == GL_DEPTH_COMPONENT32F ||
796 		       format == GL_DEPTH24_STENCIL8 ||
797 		       format == GL_DEPTH32F_STENCIL8;
798 	}
799 
IsStencilTexture(GLint format)800 	bool IsStencilTexture(GLint format)
801 	{
802 		return format == GL_DEPTH24_STENCIL8 ||
803 		       format == GL_DEPTH32F_STENCIL8 ||
804 		       format == GL_STENCIL_INDEX8;
805 	}
806 
IsCubemapTextureTarget(GLenum target)807 	bool IsCubemapTextureTarget(GLenum target)
808 	{
809 		return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
810 	}
811 
CubeFaceIndex(GLenum cubeFace)812 	int CubeFaceIndex(GLenum cubeFace)
813 	{
814 		switch(cubeFace)
815 		{
816 		case GL_TEXTURE_CUBE_MAP:
817 		case GL_TEXTURE_CUBE_MAP_POSITIVE_X: return 0;
818 		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: return 1;
819 		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: return 2;
820 		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: return 3;
821 		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: return 4;
822 		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: return 5;
823 		default: UNREACHABLE(cubeFace); return 0;
824 		}
825 	}
826 
IsTexImageTarget(GLenum target)827 	bool IsTexImageTarget(GLenum target)
828 	{
829 		return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target) || target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_RECTANGLE_ARB;
830 	}
831 
IsTextureTarget(GLenum target)832 	bool IsTextureTarget(GLenum target)
833 	{
834 		return IsTexImageTarget(target) || target == GL_TEXTURE_3D;
835 	}
836 
ValidateTextureFormatType(GLenum format,GLenum type,GLint internalformat,GLenum target)837 	GLenum ValidateTextureFormatType(GLenum format, GLenum type, GLint internalformat, GLenum target)
838 	{
839 		switch(type)
840 		{
841 		case GL_UNSIGNED_BYTE:
842 		case GL_UNSIGNED_SHORT_4_4_4_4:
843 		case GL_UNSIGNED_SHORT_5_5_5_1:
844 		case GL_UNSIGNED_SHORT_5_6_5:
845 		case GL_FLOAT:               // GL_OES_texture_float
846 		case GL_HALF_FLOAT_OES:      // GL_OES_texture_half_float
847 		case GL_HALF_FLOAT:
848 		case GL_UNSIGNED_INT_24_8:   // GL_OES_packed_depth_stencil (GL_UNSIGNED_INT_24_8_EXT)
849 		case GL_UNSIGNED_SHORT:      // GL_OES_depth_texture
850 		case GL_UNSIGNED_INT:        // GL_OES_depth_texture
851 			break;
852 		case GL_BYTE:
853 		case GL_SHORT:
854 		case GL_INT:
855 		case GL_UNSIGNED_INT_2_10_10_10_REV:
856 		case GL_UNSIGNED_INT_10F_11F_11F_REV:
857 		case GL_UNSIGNED_INT_5_9_9_9_REV:
858 		case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
859 			break;
860 		default:
861 			return GL_INVALID_ENUM;
862 		}
863 
864 		switch(format)
865 		{
866 		case GL_ALPHA:
867 		case GL_RGB:
868 		case GL_RGBA:
869 		case GL_LUMINANCE:
870 		case GL_LUMINANCE_ALPHA:
871 		case GL_BGRA_EXT:          // GL_EXT_texture_format_BGRA8888
872 		case GL_RED_EXT:           // GL_EXT_texture_rg
873 		case GL_RG_EXT:            // GL_EXT_texture_rg
874 			break;
875 		case GL_DEPTH_STENCIL:     // GL_OES_packed_depth_stencil (GL_DEPTH_STENCIL_OES)
876 		case GL_DEPTH_COMPONENT:   // GL_OES_depth_texture
877 			switch(target)
878 			{
879 			case GL_TEXTURE_2D:
880 			case GL_TEXTURE_2D_ARRAY:
881 			case GL_TEXTURE_CUBE_MAP_POSITIVE_X:   // GL_OES_depth_texture_cube_map
882 			case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
883 			case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
884 			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
885 			case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
886 			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
887 				break;
888 			default:
889 				return GL_INVALID_OPERATION;
890 			}
891 			break;
892 		case GL_RED_INTEGER:
893 		case GL_RG_INTEGER:
894 		case GL_RGB_INTEGER:
895 		case GL_RGBA_INTEGER:
896 			break;
897 		default:
898 			return GL_INVALID_ENUM;
899 		}
900 
901 		if((GLenum)internalformat != format)
902 		{
903 			if(gl::IsUnsizedInternalFormat(internalformat))
904 			{
905 				return GL_INVALID_OPERATION;
906 			}
907 
908 			if(!IsSizedInternalFormat(internalformat))
909 			{
910 				return GL_INVALID_VALUE;
911 			}
912 		}
913 
914 		if((GLenum)internalformat == format)
915 		{
916 			// Validate format, type, and unsized internalformat combinations [OpenGL ES 3.0 Table 3.3]
917 			switch(format)
918 			{
919 			case GL_RGBA:
920 				switch(type)
921 				{
922 				case GL_UNSIGNED_BYTE:
923 				case GL_UNSIGNED_SHORT_4_4_4_4:
924 				case GL_UNSIGNED_SHORT_5_5_5_1:
925 				case GL_FLOAT:            // GL_OES_texture_float
926 				case GL_HALF_FLOAT_OES:   // GL_OES_texture_half_float
927 					break;
928 				default:
929 					return GL_INVALID_OPERATION;
930 				}
931 				break;
932 			case GL_RGB:
933 				switch(type)
934 				{
935 				case GL_UNSIGNED_BYTE:
936 				case GL_UNSIGNED_SHORT_5_6_5:
937 				case GL_FLOAT:            // GL_OES_texture_float
938 				case GL_HALF_FLOAT_OES:   // GL_OES_texture_half_float
939 					break;
940 				default:
941 					return GL_INVALID_OPERATION;
942 				}
943 				break;
944 			case GL_LUMINANCE_ALPHA:
945 			case GL_LUMINANCE:
946 			case GL_ALPHA:
947 				switch(type)
948 				{
949 				case GL_UNSIGNED_BYTE:
950 				case GL_FLOAT:            // GL_OES_texture_float
951 				case GL_HALF_FLOAT_OES:   // GL_OES_texture_half_float
952 					break;
953 				default:
954 					return GL_INVALID_OPERATION;
955 				}
956 				break;
957 			case GL_DEPTH_COMPONENT:
958 				switch(type)
959 				{
960 				case GL_UNSIGNED_SHORT:   // GL_OES_depth_texture
961 				case GL_UNSIGNED_INT:     // GL_OES_depth_texture
962 					break;
963 				default:
964 					return GL_INVALID_OPERATION;
965 				}
966 				break;
967 			case GL_DEPTH_STENCIL_OES:
968 				switch(type)
969 				{
970 				case GL_UNSIGNED_INT_24_8_OES:   // GL_OES_packed_depth_stencil
971 					break;
972 				default:
973 					return GL_INVALID_OPERATION;
974 				}
975 				break;
976 			case GL_RED_EXT:
977 			case GL_RG_EXT:
978 				switch(type)
979 				{
980 				case GL_UNSIGNED_BYTE:    // GL_EXT_texture_rg
981 				case GL_FLOAT:            // GL_EXT_texture_rg + GL_OES_texture_float
982 				case GL_HALF_FLOAT_OES:   // GL_EXT_texture_rg + GL_OES_texture_half_float
983 					break;
984 				default:
985 					return GL_INVALID_OPERATION;
986 				}
987 				break;
988 			case GL_BGRA_EXT:
989 				if(type != GL_UNSIGNED_BYTE)   // GL_APPLE_texture_format_BGRA8888 / GL_EXT_texture_format_BGRA8888
990 				{
991 					return GL_INVALID_OPERATION;
992 				}
993 				break;
994 			default:
995 				UNREACHABLE(format);
996 				return GL_INVALID_ENUM;
997 			}
998 
999 			return GL_NO_ERROR;
1000 		}
1001 
1002 		// Validate format, type, and sized internalformat combinations [OpenGL ES 3.0 Table 3.2]
1003 		bool validSizedInternalformat = false;
1004 		#define VALIDATE_INTERNALFORMAT(...) { GLint validInternalformats[] = {__VA_ARGS__}; for(GLint v : validInternalformats) {if(internalformat == v) validSizedInternalformat = true;} } break;
1005 
1006 		switch(format)
1007 		{
1008 		case GL_RGBA:
1009 			switch(type)
1010 			{
1011 			case GL_UNSIGNED_BYTE:               VALIDATE_INTERNALFORMAT(GL_RGBA8, GL_RGB5_A1, GL_RGBA4, GL_SRGB8_ALPHA8)
1012 			case GL_BYTE:                        VALIDATE_INTERNALFORMAT(GL_RGBA8_SNORM)
1013 			case GL_UNSIGNED_SHORT_4_4_4_4:      VALIDATE_INTERNALFORMAT(GL_RGBA4)
1014 			case GL_UNSIGNED_SHORT_5_5_5_1:      VALIDATE_INTERNALFORMAT(GL_RGB5_A1)
1015 			case GL_UNSIGNED_INT_2_10_10_10_REV: VALIDATE_INTERNALFORMAT(GL_RGB10_A2, GL_RGB5_A1)
1016 			case GL_HALF_FLOAT_OES:
1017 			case GL_HALF_FLOAT:                  VALIDATE_INTERNALFORMAT(GL_RGBA16F)
1018 			case GL_FLOAT:                       VALIDATE_INTERNALFORMAT(GL_RGBA32F, GL_RGBA16F)
1019 			default:                             return GL_INVALID_OPERATION;
1020 			}
1021 			break;
1022 		case GL_RGBA_INTEGER:
1023 			switch(type)
1024 			{
1025 			case GL_UNSIGNED_BYTE:               VALIDATE_INTERNALFORMAT(GL_RGBA8UI)
1026 			case GL_BYTE:                        VALIDATE_INTERNALFORMAT(GL_RGBA8I)
1027 			case GL_UNSIGNED_SHORT:              VALIDATE_INTERNALFORMAT(GL_RGBA16UI)
1028 			case GL_SHORT:                       VALIDATE_INTERNALFORMAT(GL_RGBA16I)
1029 			case GL_UNSIGNED_INT:                VALIDATE_INTERNALFORMAT(GL_RGBA32UI)
1030 			case GL_INT:                         VALIDATE_INTERNALFORMAT(GL_RGBA32I)
1031 			case GL_UNSIGNED_INT_2_10_10_10_REV: VALIDATE_INTERNALFORMAT(GL_RGB10_A2UI)
1032 			default:                             return GL_INVALID_OPERATION;
1033 			}
1034 			break;
1035 		case GL_RGB:
1036 			switch(type)
1037 			{
1038 			case GL_UNSIGNED_BYTE:                VALIDATE_INTERNALFORMAT(GL_RGB8, GL_RGB565, GL_SRGB8)
1039 			case GL_BYTE:                         VALIDATE_INTERNALFORMAT(GL_RGB8_SNORM)
1040 			case GL_UNSIGNED_SHORT_5_6_5:         VALIDATE_INTERNALFORMAT(GL_RGB565)
1041 			case GL_UNSIGNED_INT_10F_11F_11F_REV: VALIDATE_INTERNALFORMAT(GL_R11F_G11F_B10F)
1042 			case GL_UNSIGNED_INT_5_9_9_9_REV:     VALIDATE_INTERNALFORMAT(GL_RGB9_E5)
1043 			case GL_HALF_FLOAT_OES:
1044 			case GL_HALF_FLOAT:                   VALIDATE_INTERNALFORMAT(GL_RGB16F, GL_R11F_G11F_B10F, GL_RGB9_E5)
1045 			case GL_FLOAT:                        VALIDATE_INTERNALFORMAT(GL_RGB32F, GL_RGB16F, GL_R11F_G11F_B10F, GL_RGB9_E5)
1046 			default:                              return GL_INVALID_OPERATION;
1047 			}
1048 			break;
1049 		case GL_RGB_INTEGER:
1050 			switch(type)
1051 			{
1052 			case GL_UNSIGNED_BYTE:  VALIDATE_INTERNALFORMAT(GL_RGB8UI)
1053 			case GL_BYTE:           VALIDATE_INTERNALFORMAT(GL_RGB8I)
1054 			case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_RGB16UI)
1055 			case GL_SHORT:          VALIDATE_INTERNALFORMAT(GL_RGB16I)
1056 			case GL_UNSIGNED_INT:   VALIDATE_INTERNALFORMAT(GL_RGB32UI)
1057 			case GL_INT:            VALIDATE_INTERNALFORMAT(GL_RGB32I)
1058 			default:                return GL_INVALID_OPERATION;
1059 			}
1060 			break;
1061 		case GL_RG:
1062 			switch(type)
1063 			{
1064 			case GL_UNSIGNED_BYTE:  VALIDATE_INTERNALFORMAT(GL_RG8)
1065 			case GL_BYTE:           VALIDATE_INTERNALFORMAT(GL_RG8_SNORM)
1066 			case GL_HALF_FLOAT_OES:
1067 			case GL_HALF_FLOAT:     VALIDATE_INTERNALFORMAT(GL_RG16F)
1068 			case GL_FLOAT:          VALIDATE_INTERNALFORMAT(GL_RG32F, GL_RG16F)
1069 			default:                return GL_INVALID_OPERATION;
1070 			}
1071 			break;
1072 		case GL_RG_INTEGER:
1073 			switch(type)
1074 			{
1075 			case GL_UNSIGNED_BYTE:  VALIDATE_INTERNALFORMAT(GL_RG8UI)
1076 			case GL_BYTE:           VALIDATE_INTERNALFORMAT(GL_RG8I)
1077 			case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_RG16UI)
1078 			case GL_SHORT:          VALIDATE_INTERNALFORMAT(GL_RG16I)
1079 			case GL_UNSIGNED_INT:   VALIDATE_INTERNALFORMAT(GL_RG32UI)
1080 			case GL_INT:            VALIDATE_INTERNALFORMAT(GL_RG32I)
1081 			default:                return GL_INVALID_OPERATION;
1082 			}
1083 			break;
1084 		case GL_RED:
1085 			switch(type)
1086 			{
1087 			case GL_UNSIGNED_BYTE:  VALIDATE_INTERNALFORMAT(GL_R8)
1088 			case GL_BYTE:           VALIDATE_INTERNALFORMAT(GL_R8_SNORM)
1089 			case GL_HALF_FLOAT_OES:
1090 			case GL_HALF_FLOAT:     VALIDATE_INTERNALFORMAT(GL_R16F)
1091 			case GL_FLOAT:          VALIDATE_INTERNALFORMAT(GL_R32F, GL_R16F)
1092 			default:                return GL_INVALID_OPERATION;
1093 			}
1094 			break;
1095 		case GL_RED_INTEGER:
1096 			switch(type)
1097 			{
1098 			case GL_UNSIGNED_BYTE:  VALIDATE_INTERNALFORMAT(GL_R8UI)
1099 			case GL_BYTE:           VALIDATE_INTERNALFORMAT(GL_R8I)
1100 			case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_R16UI)
1101 			case GL_SHORT:          VALIDATE_INTERNALFORMAT(GL_R16I)
1102 			case GL_UNSIGNED_INT:   VALIDATE_INTERNALFORMAT(GL_R32UI)
1103 			case GL_INT:            VALIDATE_INTERNALFORMAT(GL_R32I)
1104 			default:                return GL_INVALID_OPERATION;
1105 			}
1106 			break;
1107 		case GL_DEPTH_COMPONENT:
1108 			switch(type)
1109 			{
1110 			case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT16)
1111 			case GL_UNSIGNED_INT:   VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT16)
1112 			case GL_FLOAT:          VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT32F)
1113 			default:                return GL_INVALID_OPERATION;
1114 			}
1115 			break;
1116 		case GL_DEPTH_STENCIL:
1117 			switch(type)
1118 			{
1119 			case GL_UNSIGNED_INT_24_8:              VALIDATE_INTERNALFORMAT(GL_DEPTH24_STENCIL8)
1120 			case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: VALIDATE_INTERNALFORMAT(GL_DEPTH32F_STENCIL8)
1121 			default:                                return GL_INVALID_OPERATION;
1122 			}
1123 			break;
1124 		case GL_LUMINANCE_ALPHA:
1125 			switch(type)
1126 			{
1127 			case GL_UNSIGNED_BYTE:  VALIDATE_INTERNALFORMAT(GL_LUMINANCE8_ALPHA8_EXT)
1128 			case GL_HALF_FLOAT_OES:
1129 			case GL_HALF_FLOAT:     VALIDATE_INTERNALFORMAT(GL_LUMINANCE_ALPHA16F_EXT)
1130 			case GL_FLOAT:          VALIDATE_INTERNALFORMAT(GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA16F_EXT)
1131 			default:
1132 				return GL_INVALID_OPERATION;
1133 			}
1134 			break;
1135 		case GL_LUMINANCE:
1136 			switch(type)
1137 			{
1138 			case GL_UNSIGNED_BYTE:  VALIDATE_INTERNALFORMAT(GL_LUMINANCE8_EXT)
1139 			case GL_HALF_FLOAT_OES:
1140 			case GL_HALF_FLOAT:     VALIDATE_INTERNALFORMAT(GL_LUMINANCE16F_EXT)
1141 			case GL_FLOAT:          VALIDATE_INTERNALFORMAT(GL_LUMINANCE32F_EXT, GL_LUMINANCE16F_EXT)
1142 			default:
1143 				return GL_INVALID_OPERATION;
1144 			}
1145 			break;
1146 		case GL_ALPHA:
1147 			switch(type)
1148 			{
1149 			case GL_UNSIGNED_BYTE:  VALIDATE_INTERNALFORMAT(GL_ALPHA8_EXT)
1150 			case GL_HALF_FLOAT_OES:
1151 			case GL_HALF_FLOAT:     VALIDATE_INTERNALFORMAT(GL_ALPHA16F_EXT)
1152 			case GL_FLOAT:          VALIDATE_INTERNALFORMAT(GL_ALPHA32F_EXT, GL_ALPHA16F_EXT)
1153 			default:
1154 				return GL_INVALID_OPERATION;
1155 			}
1156 			break;
1157 		case GL_BGRA_EXT:   // GL_APPLE_texture_format_BGRA8888
1158 			switch(type)
1159 			{
1160 			case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_BGRA8_EXT)
1161 			default:               return GL_INVALID_OPERATION;
1162 			}
1163 			break;
1164 		default:
1165 			UNREACHABLE(format);
1166 			return GL_INVALID_ENUM;
1167 		}
1168 
1169 		#undef VALIDATE_INTERNALFORMAT
1170 
1171 		if(!validSizedInternalformat)
1172 		{
1173 			return GL_INVALID_OPERATION;
1174 		}
1175 
1176 		return GL_NO_ERROR;
1177 	}
1178 
GetTypeSize(GLenum type)1179 	size_t GetTypeSize(GLenum type)
1180 	{
1181 		switch(type)
1182 		{
1183 		case GL_BYTE:
1184 		case GL_UNSIGNED_BYTE:
1185 			return 1;
1186 		case GL_UNSIGNED_SHORT_4_4_4_4:
1187 		case GL_UNSIGNED_SHORT_5_5_5_1:
1188 		case GL_UNSIGNED_SHORT_5_6_5:
1189 		case GL_UNSIGNED_SHORT:
1190 		case GL_SHORT:
1191 		case GL_HALF_FLOAT:
1192 		case GL_HALF_FLOAT_OES:
1193 			return 2;
1194 		case GL_FLOAT:
1195 		case GL_UNSIGNED_INT_24_8:
1196 		case GL_UNSIGNED_INT:
1197 		case GL_INT:
1198 		case GL_UNSIGNED_INT_2_10_10_10_REV:
1199 		case GL_UNSIGNED_INT_10F_11F_11F_REV:
1200 		case GL_UNSIGNED_INT_5_9_9_9_REV:
1201 			return 4;
1202 		case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
1203 			return 8;
1204 		default:
1205 			UNREACHABLE(type);
1206 			break;
1207 		}
1208 
1209 		return 1;
1210 	}
1211 
ConvertReadFormatType(GLenum format,GLenum type)1212 	sw::Format ConvertReadFormatType(GLenum format, GLenum type)
1213 	{
1214 		switch(format)
1215 		{
1216 		case GL_LUMINANCE:
1217 			switch(type)
1218 			{
1219 			case GL_UNSIGNED_BYTE:  return sw::FORMAT_L8;
1220 			case GL_HALF_FLOAT:     return sw::FORMAT_L16F;
1221 			case GL_HALF_FLOAT_OES: return sw::FORMAT_L16F;
1222 			case GL_FLOAT:          return sw::FORMAT_L32F;
1223 			default: UNREACHABLE(type);
1224 			}
1225 			break;
1226 		case GL_LUMINANCE_ALPHA:
1227 			switch(type)
1228 			{
1229 			case GL_UNSIGNED_BYTE:  return sw::FORMAT_A8L8;
1230 			case GL_HALF_FLOAT:     return sw::FORMAT_A16L16F;
1231 			case GL_HALF_FLOAT_OES: return sw::FORMAT_A16L16F;
1232 			case GL_FLOAT:          return sw::FORMAT_A32L32F;
1233 			default: UNREACHABLE(type);
1234 			}
1235 			break;
1236 		case GL_RGBA:
1237 			switch(type)
1238 			{
1239 			case GL_UNSIGNED_BYTE:          return sw::FORMAT_A8B8G8R8;
1240 			case GL_UNSIGNED_SHORT_4_4_4_4: return sw::FORMAT_R4G4B4A4;
1241 			case GL_UNSIGNED_SHORT_5_5_5_1: return sw::FORMAT_R5G5B5A1;
1242 			case GL_HALF_FLOAT:             return sw::FORMAT_A16B16G16R16F;
1243 			case GL_HALF_FLOAT_OES:         return sw::FORMAT_A16B16G16R16F;
1244 			case GL_FLOAT:                  return sw::FORMAT_A32B32G32R32F;
1245 			case GL_UNSIGNED_INT_2_10_10_10_REV_EXT: return sw::FORMAT_A2B10G10R10;
1246 			default: UNREACHABLE(type);
1247 			}
1248 			break;
1249 		case GL_BGRA_EXT:
1250 			switch(type)
1251 			{
1252 			case GL_UNSIGNED_BYTE:                  return sw::FORMAT_A8R8G8B8;
1253 			case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: return sw::FORMAT_A4R4G4B4;
1254 			case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: return sw::FORMAT_A1R5G5B5;
1255 			default: UNREACHABLE(type);
1256 			}
1257 			break;
1258 		case GL_RGB:
1259 			switch(type)
1260 			{
1261 			case GL_UNSIGNED_BYTE:          return sw::FORMAT_B8G8R8;
1262 			case GL_UNSIGNED_SHORT_5_6_5:   return sw::FORMAT_R5G6B5;
1263 			case GL_HALF_FLOAT:             return sw::FORMAT_B16G16R16F;
1264 			case GL_HALF_FLOAT_OES:         return sw::FORMAT_B16G16R16F;
1265 			case GL_FLOAT:                  return sw::FORMAT_B32G32R32F;
1266 			default: UNREACHABLE(type);
1267 			}
1268 			break;
1269 		case GL_RG:
1270 			switch(type)
1271 			{
1272 			case GL_UNSIGNED_BYTE:          return sw::FORMAT_G8R8;
1273 			case GL_HALF_FLOAT:             return sw::FORMAT_G16R16F;
1274 			case GL_HALF_FLOAT_OES:         return sw::FORMAT_G16R16F;
1275 			case GL_FLOAT:                  return sw::FORMAT_G32R32F;
1276 			default: UNREACHABLE(type);
1277 			}
1278 			break;
1279 		case GL_RED:
1280 			switch(type)
1281 			{
1282 			case GL_UNSIGNED_BYTE:          return sw::FORMAT_R8;
1283 			case GL_HALF_FLOAT:             return sw::FORMAT_R16F;
1284 			case GL_HALF_FLOAT_OES:         return sw::FORMAT_R16F;
1285 			case GL_FLOAT:                  return sw::FORMAT_R32F;
1286 			default: UNREACHABLE(type);
1287 			}
1288 			break;
1289 		case GL_ALPHA:
1290 			switch(type)
1291 			{
1292 			case GL_UNSIGNED_BYTE:          return sw::FORMAT_A8;
1293 			case GL_HALF_FLOAT:             return sw::FORMAT_A16F;
1294 			case GL_HALF_FLOAT_OES:         return sw::FORMAT_A16F;
1295 			case GL_FLOAT:                  return sw::FORMAT_A32F;
1296 			default: UNREACHABLE(type);
1297 			}
1298 			break;
1299 		case GL_RED_INTEGER:
1300 			switch(type)
1301 			{
1302 			case GL_INT:          return sw::FORMAT_R32I;
1303 			case GL_UNSIGNED_INT: return sw::FORMAT_R32UI;
1304 			default: UNREACHABLE(type);
1305 			}
1306 			break;
1307 		case GL_RG_INTEGER:
1308 			switch(type)
1309 			{
1310 			case GL_INT:          return sw::FORMAT_G32R32I;
1311 			case GL_UNSIGNED_INT: return sw::FORMAT_G32R32UI;
1312 			default: UNREACHABLE(type);
1313 			}
1314 			break;
1315 		case GL_RGB_INTEGER:
1316 			switch(type)
1317 			{
1318 			case GL_INT:          return sw::FORMAT_X32B32G32R32I;
1319 			case GL_UNSIGNED_INT: return sw::FORMAT_X32B32G32R32UI;
1320 			default: UNREACHABLE(type);
1321 			}
1322 			break;
1323 		case GL_RGBA_INTEGER:
1324 			switch(type)
1325 			{
1326 			case GL_INT:          return sw::FORMAT_A32B32G32R32I;
1327 			case GL_UNSIGNED_INT: return sw::FORMAT_A32B32G32R32UI;
1328 			case GL_UNSIGNED_INT_2_10_10_10_REV: return sw::FORMAT_A2B10G10R10UI;
1329 			default: UNREACHABLE(type);
1330 			}
1331 			break;
1332 		case GL_DEPTH_COMPONENT:
1333 			switch(type)
1334 			{
1335 			case GL_UNSIGNED_SHORT:        return sw::FORMAT_D16;
1336 			case GL_UNSIGNED_INT_24_8_OES: return sw::FORMAT_D24X8;
1337 			case GL_FLOAT:                 return sw::FORMAT_D32F_LOCKABLE;
1338 			default: UNREACHABLE(type);
1339 			}
1340 			break;
1341 		case GL_STENCIL_INDEX_OES:
1342 			switch(type)
1343 			{
1344 			case GL_UNSIGNED_BYTE: return sw::FORMAT_S8;
1345 			default: UNREACHABLE(type);
1346 			}
1347 			break;
1348 		case GL_DEPTH_STENCIL_OES:   // Cannot be read as one format. Handled separately.
1349 		default:
1350 			UNREACHABLE(format);
1351 			break;
1352 		}
1353 
1354 		return sw::FORMAT_NULL;
1355 	}
1356 
IsColorRenderable(GLint internalformat)1357 	bool IsColorRenderable(GLint internalformat)
1358 	{
1359 		if(IsCompressed(internalformat))
1360 		{
1361 			return false;
1362 		}
1363 
1364 		switch(internalformat)
1365 		{
1366 		case GL_RGBA4:
1367 		case GL_RGB5_A1:
1368 		case GL_RGB565:
1369 		case GL_R8:
1370 		case GL_RG8:
1371 		case GL_RGB8:
1372 		case GL_RGBA8:
1373 		case GL_R16F:
1374 		case GL_RG16F:
1375 		case GL_RGB16F:
1376 		case GL_RGBA16F:
1377 		case GL_R32F:
1378 		case GL_RG32F:
1379 		case GL_RGB32F:
1380 		case GL_RGBA32F:     // GL_EXT_color_buffer_float, OpenGL ES 3.0+ only.
1381 		case GL_BGRA8_EXT:   // GL_EXT_texture_format_BGRA8888
1382 		case GL_R8UI:
1383 		case GL_R8I:
1384 		case GL_R16UI:
1385 		case GL_R16I:
1386 		case GL_R32UI:
1387 		case GL_R32I:
1388 		case GL_RG8UI:
1389 		case GL_RG8I:
1390 		case GL_RG16UI:
1391 		case GL_RG16I:
1392 		case GL_RG32UI:
1393 		case GL_RG32I:
1394 		case GL_SRGB8_ALPHA8:
1395 		case GL_RGB10_A2:
1396 		case GL_RGBA8UI:
1397 		case GL_RGBA8I:
1398 		case GL_RGB10_A2UI:
1399 		case GL_RGBA16UI:
1400 		case GL_RGBA16I:
1401 		case GL_RGBA32I:
1402 		case GL_RGBA32UI:
1403 		case GL_R11F_G11F_B10F:
1404 			return true;
1405 		case GL_R8_SNORM:
1406 		case GL_RG8_SNORM:
1407 		case GL_RGB8_SNORM:
1408 		case GL_RGBA8_SNORM:
1409 		case GL_ALPHA8_EXT:
1410 		case GL_LUMINANCE8_EXT:
1411 		case GL_LUMINANCE8_ALPHA8_EXT:
1412 		case GL_ALPHA32F_EXT:
1413 		case GL_LUMINANCE32F_EXT:
1414 		case GL_LUMINANCE_ALPHA32F_EXT:
1415 		case GL_ALPHA16F_EXT:
1416 		case GL_LUMINANCE16F_EXT:
1417 		case GL_LUMINANCE_ALPHA16F_EXT:
1418 		case GL_DEPTH_COMPONENT24:
1419 		case GL_DEPTH_COMPONENT32_OES:
1420 		case GL_DEPTH_COMPONENT32F:
1421 		case GL_DEPTH32F_STENCIL8:
1422 		case GL_DEPTH_COMPONENT16:
1423 		case GL_STENCIL_INDEX8:
1424 		case GL_DEPTH24_STENCIL8_OES:
1425 			return false;
1426 		default:
1427 			UNIMPLEMENTED();
1428 		}
1429 
1430 		return false;
1431 	}
1432 
IsDepthRenderable(GLint internalformat)1433 	bool IsDepthRenderable(GLint internalformat)
1434 	{
1435 		if(IsCompressed(internalformat))
1436 		{
1437 			return false;
1438 		}
1439 
1440 		switch(internalformat)
1441 		{
1442 		case GL_DEPTH_COMPONENT24:
1443 		case GL_DEPTH_COMPONENT16:
1444 		case GL_DEPTH24_STENCIL8_OES:    // GL_OES_packed_depth_stencil
1445 		case GL_DEPTH_COMPONENT32_OES:   // GL_OES_depth32
1446 		case GL_DEPTH32F_STENCIL8:
1447 		case GL_DEPTH_COMPONENT32F:
1448 			return true;
1449 		case GL_STENCIL_INDEX8:
1450 		case GL_R8:
1451 		case GL_R8UI:
1452 		case GL_R8I:
1453 		case GL_R16UI:
1454 		case GL_R16I:
1455 		case GL_R32UI:
1456 		case GL_R32I:
1457 		case GL_RG8:
1458 		case GL_RG8UI:
1459 		case GL_RG8I:
1460 		case GL_RG16UI:
1461 		case GL_RG16I:
1462 		case GL_RG32UI:
1463 		case GL_RG32I:
1464 		case GL_SRGB8_ALPHA8:
1465 		case GL_RGB10_A2:
1466 		case GL_RGBA8UI:
1467 		case GL_RGBA8I:
1468 		case GL_RGB10_A2UI:
1469 		case GL_RGBA16UI:
1470 		case GL_RGBA16I:
1471 		case GL_RGBA32I:
1472 		case GL_RGBA32UI:
1473 		case GL_RGBA4:
1474 		case GL_RGB5_A1:
1475 		case GL_RGB565:
1476 		case GL_RGB8:
1477 		case GL_RGBA8:
1478 		case GL_RED:
1479 		case GL_RG:
1480 		case GL_RGB:
1481 		case GL_RGBA:
1482 		case GL_R16F:
1483 		case GL_RG16F:
1484 		case GL_R11F_G11F_B10F:
1485 		case GL_RGB16F:
1486 		case GL_RGBA16F:
1487 		case GL_R32F:
1488 		case GL_RG32F:
1489 		case GL_RGB32F:
1490 		case GL_RGBA32F:
1491 		case GL_R8_SNORM:
1492 		case GL_RG8_SNORM:
1493 		case GL_RGB8_SNORM:
1494 		case GL_RGBA8_SNORM:
1495 			return false;
1496 		default:
1497 			UNIMPLEMENTED();
1498 		}
1499 
1500 		return false;
1501 	}
1502 
IsStencilRenderable(GLint internalformat)1503 	bool IsStencilRenderable(GLint internalformat)
1504 	{
1505 		if(IsCompressed(internalformat))
1506 		{
1507 			return false;
1508 		}
1509 
1510 		switch(internalformat)
1511 		{
1512 		case GL_STENCIL_INDEX8:
1513 		case GL_DEPTH24_STENCIL8_OES:
1514 		case GL_DEPTH32F_STENCIL8:
1515 			return true;
1516 		case GL_R8:
1517 		case GL_R8UI:
1518 		case GL_R8I:
1519 		case GL_R16UI:
1520 		case GL_R16I:
1521 		case GL_R32UI:
1522 		case GL_R32I:
1523 		case GL_RG8:
1524 		case GL_RG8UI:
1525 		case GL_RG8I:
1526 		case GL_RG16UI:
1527 		case GL_RG16I:
1528 		case GL_RG32UI:
1529 		case GL_RG32I:
1530 		case GL_SRGB8_ALPHA8:
1531 		case GL_RGB10_A2:
1532 		case GL_RGBA8UI:
1533 		case GL_RGBA8I:
1534 		case GL_RGB10_A2UI:
1535 		case GL_RGBA16UI:
1536 		case GL_RGBA16I:
1537 		case GL_RGBA32I:
1538 		case GL_RGBA32UI:
1539 		case GL_RGBA4:
1540 		case GL_RGB5_A1:
1541 		case GL_RGB565:
1542 		case GL_RGB8:
1543 		case GL_RGBA8:
1544 		case GL_RED:
1545 		case GL_RG:
1546 		case GL_RGB:
1547 		case GL_RGBA:
1548 		case GL_R16F:
1549 		case GL_RG16F:
1550 		case GL_R11F_G11F_B10F:
1551 		case GL_RGB16F:
1552 		case GL_RGBA16F:
1553 		case GL_R32F:
1554 		case GL_RG32F:
1555 		case GL_RGB32F:
1556 		case GL_RGBA32F:
1557 		case GL_DEPTH_COMPONENT16:
1558 		case GL_DEPTH_COMPONENT24:
1559 		case GL_DEPTH_COMPONENT32_OES:
1560 		case GL_DEPTH_COMPONENT32F:
1561 		case GL_R8_SNORM:
1562 		case GL_RG8_SNORM:
1563 		case GL_RGB8_SNORM:
1564 		case GL_RGBA8_SNORM:
1565 			return false;
1566 		default:
1567 			UNIMPLEMENTED();
1568 		}
1569 
1570 		return false;
1571 	}
1572 
IsMipmappable(GLint internalformat)1573 	bool IsMipmappable(GLint internalformat)
1574 	{
1575 		if(internalformat == GL_NONE)
1576 		{
1577 			return true;   // Image unspecified. Not an error.
1578 		}
1579 
1580 		if(IsNonNormalizedInteger(internalformat))
1581 		{
1582 			return false;
1583 		}
1584 
1585 		switch(internalformat)
1586 		{
1587 		case GL_ALPHA8_EXT:
1588 		case GL_LUMINANCE8_EXT:
1589 		case GL_LUMINANCE8_ALPHA8_EXT:
1590 		case GL_ALPHA32F_EXT:
1591 		case GL_LUMINANCE32F_EXT:
1592 		case GL_LUMINANCE_ALPHA32F_EXT:
1593 		case GL_ALPHA16F_EXT:
1594 		case GL_LUMINANCE16F_EXT:
1595 		case GL_LUMINANCE_ALPHA16F_EXT:
1596 			return true;
1597 		default:
1598 			return IsColorRenderable(internalformat);
1599 		}
1600 	}
1601 
GetAlphaSize(GLint internalformat)1602 	GLuint GetAlphaSize(GLint internalformat)
1603 	{
1604 		switch(internalformat)
1605 		{
1606 		case GL_NONE:           return 0;
1607 		case GL_RGBA4:          return 4;
1608 		case GL_RGB5_A1:        return 1;
1609 		case GL_RGB565:         return 0;
1610 		case GL_R8:             return 0;
1611 		case GL_RG8:            return 0;
1612 		case GL_RGB8:           return 0;
1613 		case GL_RGBA8:          return 8;
1614 		case GL_R16F:           return 0;
1615 		case GL_RG16F:          return 0;
1616 		case GL_RGB16F:         return 0;
1617 		case GL_RGBA16F:        return 16;
1618 		case GL_R32F:           return 0;
1619 		case GL_RG32F:          return 0;
1620 		case GL_RGB32F:         return 0;
1621 		case GL_RGBA32F:        return 32;
1622 		case GL_BGRA8_EXT:      return 8;
1623 		case GL_R8UI:           return 0;
1624 		case GL_R8I:            return 0;
1625 		case GL_R16UI:          return 0;
1626 		case GL_R16I:           return 0;
1627 		case GL_R32UI:          return 0;
1628 		case GL_R32I:           return 0;
1629 		case GL_RG8UI:          return 0;
1630 		case GL_RG8I:           return 0;
1631 		case GL_RG16UI:         return 0;
1632 		case GL_RG16I:          return 0;
1633 		case GL_RG32UI:         return 0;
1634 		case GL_RG32I:          return 0;
1635 		case GL_SRGB8_ALPHA8:   return 8;
1636 		case GL_RGB10_A2:       return 2;
1637 		case GL_RGBA8UI:        return 8;
1638 		case GL_RGBA8I:         return 8;
1639 		case GL_RGB10_A2UI:     return 2;
1640 		case GL_RGBA16UI:       return 16;
1641 		case GL_RGBA16I:        return 16;
1642 		case GL_RGBA32I:        return 32;
1643 		case GL_RGBA32UI:       return 32;
1644 		case GL_R11F_G11F_B10F: return 0;
1645 		default:
1646 		//	UNREACHABLE(internalformat);
1647 			return 0;
1648 		}
1649 	}
1650 
GetRedSize(GLint internalformat)1651 	GLuint GetRedSize(GLint internalformat)
1652 	{
1653 		switch(internalformat)
1654 		{
1655 		case GL_NONE:           return 0;
1656 		case GL_RGBA4:          return 4;
1657 		case GL_RGB5_A1:        return 5;
1658 		case GL_RGB565:         return 5;
1659 		case GL_R8:             return 8;
1660 		case GL_RG8:            return 8;
1661 		case GL_RGB8:           return 8;
1662 		case GL_RGBA8:          return 8;
1663 		case GL_R16F:           return 16;
1664 		case GL_RG16F:          return 16;
1665 		case GL_RGB16F:         return 16;
1666 		case GL_RGBA16F:        return 16;
1667 		case GL_R32F:           return 32;
1668 		case GL_RG32F:          return 32;
1669 		case GL_RGB32F:         return 32;
1670 		case GL_RGBA32F:        return 32;
1671 		case GL_BGRA8_EXT:      return 8;
1672 		case GL_R8UI:           return 8;
1673 		case GL_R8I:            return 8;
1674 		case GL_R16UI:          return 16;
1675 		case GL_R16I:           return 16;
1676 		case GL_R32UI:          return 32;
1677 		case GL_R32I:           return 32;
1678 		case GL_RG8UI:          return 8;
1679 		case GL_RG8I:           return 8;
1680 		case GL_RG16UI:         return 16;
1681 		case GL_RG16I:          return 16;
1682 		case GL_RG32UI:         return 32;
1683 		case GL_RG32I:          return 32;
1684 		case GL_SRGB8_ALPHA8:   return 8;
1685 		case GL_RGB10_A2:       return 10;
1686 		case GL_RGBA8UI:        return 8;
1687 		case GL_RGBA8I:         return 8;
1688 		case GL_RGB10_A2UI:     return 10;
1689 		case GL_RGBA16UI:       return 16;
1690 		case GL_RGBA16I:        return 16;
1691 		case GL_RGBA32I:        return 32;
1692 		case GL_RGBA32UI:       return 32;
1693 		case GL_R11F_G11F_B10F: return 11;
1694 		default:
1695 		//	UNREACHABLE(internalformat);
1696 			return 0;
1697 		}
1698 	}
1699 
GetGreenSize(GLint internalformat)1700 	GLuint GetGreenSize(GLint internalformat)
1701 	{
1702 		switch(internalformat)
1703 		{
1704 		case GL_NONE:           return 0;
1705 		case GL_RGBA4:          return 4;
1706 		case GL_RGB5_A1:        return 5;
1707 		case GL_RGB565:         return 6;
1708 		case GL_R8:             return 0;
1709 		case GL_RG8:            return 8;
1710 		case GL_RGB8:           return 8;
1711 		case GL_RGBA8:          return 8;
1712 		case GL_R16F:           return 0;
1713 		case GL_RG16F:          return 16;
1714 		case GL_RGB16F:         return 16;
1715 		case GL_RGBA16F:        return 16;
1716 		case GL_R32F:           return 0;
1717 		case GL_RG32F:          return 32;
1718 		case GL_RGB32F:         return 32;
1719 		case GL_RGBA32F:        return 32;
1720 		case GL_BGRA8_EXT:      return 8;
1721 		case GL_R8UI:           return 0;
1722 		case GL_R8I:            return 0;
1723 		case GL_R16UI:          return 0;
1724 		case GL_R16I:           return 0;
1725 		case GL_R32UI:          return 0;
1726 		case GL_R32I:           return 0;
1727 		case GL_RG8UI:          return 8;
1728 		case GL_RG8I:           return 8;
1729 		case GL_RG16UI:         return 16;
1730 		case GL_RG16I:          return 16;
1731 		case GL_RG32UI:         return 32;
1732 		case GL_RG32I:          return 32;
1733 		case GL_SRGB8_ALPHA8:   return 8;
1734 		case GL_RGB10_A2:       return 10;
1735 		case GL_RGBA8UI:        return 8;
1736 		case GL_RGBA8I:         return 8;
1737 		case GL_RGB10_A2UI:     return 10;
1738 		case GL_RGBA16UI:       return 16;
1739 		case GL_RGBA16I:        return 16;
1740 		case GL_RGBA32I:        return 32;
1741 		case GL_RGBA32UI:       return 32;
1742 		case GL_R11F_G11F_B10F: return 11;
1743 		default:
1744 		//	UNREACHABLE(internalformat);
1745 			return 0;
1746 		}
1747 	}
1748 
GetBlueSize(GLint internalformat)1749 	GLuint GetBlueSize(GLint internalformat)
1750 	{
1751 		switch(internalformat)
1752 		{
1753 		case GL_NONE:           return 0;
1754 		case GL_RGBA4:          return 4;
1755 		case GL_RGB5_A1:        return 5;
1756 		case GL_RGB565:         return 5;
1757 		case GL_R8:             return 0;
1758 		case GL_RG8:            return 0;
1759 		case GL_RGB8:           return 8;
1760 		case GL_RGBA8:          return 8;
1761 		case GL_R16F:           return 0;
1762 		case GL_RG16F:          return 0;
1763 		case GL_RGB16F:         return 16;
1764 		case GL_RGBA16F:        return 16;
1765 		case GL_R32F:           return 0;
1766 		case GL_RG32F:          return 0;
1767 		case GL_RGB32F:         return 32;
1768 		case GL_RGBA32F:        return 32;
1769 		case GL_BGRA8_EXT:      return 8;
1770 		case GL_R8UI:           return 0;
1771 		case GL_R8I:            return 0;
1772 		case GL_R16UI:          return 0;
1773 		case GL_R16I:           return 0;
1774 		case GL_R32UI:          return 0;
1775 		case GL_R32I:           return 0;
1776 		case GL_RG8UI:          return 0;
1777 		case GL_RG8I:           return 0;
1778 		case GL_RG16UI:         return 0;
1779 		case GL_RG16I:          return 0;
1780 		case GL_RG32UI:         return 0;
1781 		case GL_RG32I:          return 0;
1782 		case GL_SRGB8_ALPHA8:   return 8;
1783 		case GL_RGB10_A2:       return 10;
1784 		case GL_RGBA8UI:        return 8;
1785 		case GL_RGBA8I:         return 8;
1786 		case GL_RGB10_A2UI:     return 10;
1787 		case GL_RGBA16UI:       return 16;
1788 		case GL_RGBA16I:        return 16;
1789 		case GL_RGBA32I:        return 32;
1790 		case GL_RGBA32UI:       return 32;
1791 		case GL_R11F_G11F_B10F: return 10;
1792 		default:
1793 		//	UNREACHABLE(internalformat);
1794 			return 0;
1795 		}
1796 	}
1797 
GetDepthSize(GLint internalformat)1798 	GLuint GetDepthSize(GLint internalformat)
1799 	{
1800 		switch(internalformat)
1801 		{
1802 		case GL_STENCIL_INDEX8:        return 0;
1803 		case GL_DEPTH_COMPONENT16:     return 16;
1804 		case GL_DEPTH_COMPONENT24:     return 24;
1805 		case GL_DEPTH_COMPONENT32_OES: return 32;
1806 		case GL_DEPTH_COMPONENT32F:    return 32;
1807 		case GL_DEPTH24_STENCIL8:      return 24;
1808 		case GL_DEPTH32F_STENCIL8:     return 32;
1809 		default:
1810 		//	UNREACHABLE(internalformat);
1811 			return 0;
1812 		}
1813 	}
1814 
GetStencilSize(GLint internalformat)1815 	GLuint GetStencilSize(GLint internalformat)
1816 	{
1817 		switch(internalformat)
1818 		{
1819 		case GL_STENCIL_INDEX8:        return 8;
1820 		case GL_DEPTH_COMPONENT16:     return 0;
1821 		case GL_DEPTH_COMPONENT24:     return 0;
1822 		case GL_DEPTH_COMPONENT32_OES: return 0;
1823 		case GL_DEPTH_COMPONENT32F:    return 0;
1824 		case GL_DEPTH24_STENCIL8:      return 8;
1825 		case GL_DEPTH32F_STENCIL8:     return 8;
1826 		default:
1827 		//	UNREACHABLE(internalformat);
1828 			return 0;
1829 		}
1830 	}
1831 
GetColorComponentType(GLint internalformat)1832 	GLenum GetColorComponentType(GLint internalformat)
1833 	{
1834 		switch(internalformat)
1835 		{
1836 		case GL_ALPHA8_EXT:
1837 		case GL_LUMINANCE8_ALPHA8_EXT:
1838 		case GL_LUMINANCE8_EXT:
1839 		case GL_R8:
1840 		case GL_RG8:
1841 		case GL_SRGB8_ALPHA8:
1842 		case GL_RGB10_A2:
1843 		case GL_RGBA4:
1844 		case GL_RGB5_A1:
1845 		case GL_RGB565:
1846 		case GL_RGB8:
1847 		case GL_RGBA8:
1848 		case GL_SRGB8:
1849 		case GL_BGRA8_EXT:
1850 			return GL_UNSIGNED_NORMALIZED;
1851 		case GL_R8_SNORM:
1852 		case GL_RG8_SNORM:
1853 		case GL_RGB8_SNORM:
1854 		case GL_RGBA8_SNORM:
1855 			return GL_SIGNED_NORMALIZED;
1856 		case GL_R8UI:
1857 		case GL_R16UI:
1858 		case GL_R32UI:
1859 		case GL_RG8UI:
1860 		case GL_RG16UI:
1861 		case GL_RG32UI:
1862 		case GL_RGB8UI:
1863 		case GL_RGB16UI:
1864 		case GL_RGB32UI:
1865 		case GL_RGB10_A2UI:
1866 		case GL_RGBA16UI:
1867 		case GL_RGBA32UI:
1868 		case GL_RGBA8UI:
1869 			return GL_UNSIGNED_INT;
1870 		case GL_R8I:
1871 		case GL_R16I:
1872 		case GL_R32I:
1873 		case GL_RG8I:
1874 		case GL_RG16I:
1875 		case GL_RG32I:
1876 		case GL_RGB8I:
1877 		case GL_RGB16I:
1878 		case GL_RGB32I:
1879 		case GL_RGBA8I:
1880 		case GL_RGBA16I:
1881 		case GL_RGBA32I:
1882 			return GL_INT;
1883 		case GL_ALPHA32F_EXT:
1884 		case GL_LUMINANCE32F_EXT:
1885 		case GL_LUMINANCE_ALPHA32F_EXT:
1886 		case GL_ALPHA16F_EXT:
1887 		case GL_LUMINANCE16F_EXT:
1888 		case GL_LUMINANCE_ALPHA16F_EXT:
1889 		case GL_R16F:
1890 		case GL_RG16F:
1891 		case GL_R11F_G11F_B10F:
1892 		case GL_RGB16F:
1893 		case GL_RGBA16F:
1894 		case GL_R32F:
1895 		case GL_RG32F:
1896 		case GL_RGB32F:
1897 		case GL_RGBA32F:
1898 		case GL_RGB9_E5:
1899 			return GL_FLOAT;
1900 		default:
1901 		//	UNREACHABLE(internalformat);
1902 			return GL_NONE;
1903 		}
1904 	}
1905 
GetComponentType(GLint internalformat,GLenum attachment)1906 	GLenum GetComponentType(GLint internalformat, GLenum attachment)
1907 	{
1908 		// Can be one of GL_FLOAT, GL_INT, GL_UNSIGNED_INT, GL_SIGNED_NORMALIZED, or GL_UNSIGNED_NORMALIZED
1909 		switch(attachment)
1910 		{
1911 		case GL_COLOR_ATTACHMENT0:
1912 		case GL_COLOR_ATTACHMENT1:
1913 		case GL_COLOR_ATTACHMENT2:
1914 		case GL_COLOR_ATTACHMENT3:
1915 		case GL_COLOR_ATTACHMENT4:
1916 		case GL_COLOR_ATTACHMENT5:
1917 		case GL_COLOR_ATTACHMENT6:
1918 		case GL_COLOR_ATTACHMENT7:
1919 		case GL_COLOR_ATTACHMENT8:
1920 		case GL_COLOR_ATTACHMENT9:
1921 		case GL_COLOR_ATTACHMENT10:
1922 		case GL_COLOR_ATTACHMENT11:
1923 		case GL_COLOR_ATTACHMENT12:
1924 		case GL_COLOR_ATTACHMENT13:
1925 		case GL_COLOR_ATTACHMENT14:
1926 		case GL_COLOR_ATTACHMENT15:
1927 		case GL_COLOR_ATTACHMENT16:
1928 		case GL_COLOR_ATTACHMENT17:
1929 		case GL_COLOR_ATTACHMENT18:
1930 		case GL_COLOR_ATTACHMENT19:
1931 		case GL_COLOR_ATTACHMENT20:
1932 		case GL_COLOR_ATTACHMENT21:
1933 		case GL_COLOR_ATTACHMENT22:
1934 		case GL_COLOR_ATTACHMENT23:
1935 		case GL_COLOR_ATTACHMENT24:
1936 		case GL_COLOR_ATTACHMENT25:
1937 		case GL_COLOR_ATTACHMENT26:
1938 		case GL_COLOR_ATTACHMENT27:
1939 		case GL_COLOR_ATTACHMENT28:
1940 		case GL_COLOR_ATTACHMENT29:
1941 		case GL_COLOR_ATTACHMENT30:
1942 		case GL_COLOR_ATTACHMENT31:
1943 			return GetColorComponentType(internalformat);
1944 		case GL_DEPTH_ATTACHMENT:
1945 		case GL_STENCIL_ATTACHMENT:
1946 			// Only color buffers may have integer components.
1947 			return GL_FLOAT;
1948 		default:
1949 			UNREACHABLE(attachment);
1950 			return GL_NONE;
1951 		}
1952 	}
1953 
IsNormalizedInteger(GLint internalformat)1954 	bool IsNormalizedInteger(GLint internalformat)
1955 	{
1956 		GLenum type = GetColorComponentType(internalformat);
1957 
1958 		return type == GL_UNSIGNED_NORMALIZED || type == GL_SIGNED_NORMALIZED;
1959 	}
1960 
IsNonNormalizedInteger(GLint internalformat)1961 	bool IsNonNormalizedInteger(GLint internalformat)
1962 	{
1963 		GLenum type = GetColorComponentType(internalformat);
1964 
1965 		return type == GL_UNSIGNED_INT || type == GL_INT;
1966 	}
1967 
IsFloatFormat(GLint internalformat)1968 	bool IsFloatFormat(GLint internalformat)
1969 	{
1970 		return GetColorComponentType(internalformat) == GL_FLOAT;
1971 	}
1972 
IsSignedNonNormalizedInteger(GLint internalformat)1973 	bool IsSignedNonNormalizedInteger(GLint internalformat)
1974 	{
1975 		return GetColorComponentType(internalformat) == GL_INT;
1976 	}
1977 
IsUnsignedNonNormalizedInteger(GLint internalformat)1978 	bool IsUnsignedNonNormalizedInteger(GLint internalformat)
1979 	{
1980 		return GetColorComponentType(internalformat) == GL_UNSIGNED_INT;
1981 	}
1982 
GetColorEncoding(GLint internalformat)1983 	GLenum GetColorEncoding(GLint internalformat)
1984 	{
1985 		switch(internalformat)
1986 		{
1987 		case GL_SRGB8:
1988 		case GL_SRGB8_ALPHA8:
1989 			return GL_SRGB;
1990 		default:
1991 			// [OpenGL ES 3.0.5] section 6.1.13 page 242:
1992 			// If attachment is not a color attachment, or no data storage or texture image
1993 			// has been specified for the attachment, params will contain the value LINEAR.
1994 			return GL_LINEAR;
1995 		}
1996 	}
1997 
ParseUniformName(const std::string & name,unsigned int * outSubscript)1998 	std::string ParseUniformName(const std::string &name, unsigned int *outSubscript)
1999 	{
2000 		// Strip any trailing array operator and retrieve the subscript
2001 		size_t open = name.find_last_of('[');
2002 		size_t close = name.find_last_of(']');
2003 		bool hasIndex = (open != std::string::npos) && (close == name.length() - 1);
2004 		if(!hasIndex)
2005 		{
2006 			if(outSubscript)
2007 			{
2008 				*outSubscript = GL_INVALID_INDEX;
2009 			}
2010 			return name;
2011 		}
2012 
2013 		if(outSubscript)
2014 		{
2015 			int index = atoi(name.substr(open + 1).c_str());
2016 			if(index >= 0)
2017 			{
2018 				*outSubscript = index;
2019 			}
2020 			else
2021 			{
2022 				*outSubscript = GL_INVALID_INDEX;
2023 			}
2024 		}
2025 
2026 		return name.substr(0, open);
2027 	}
2028 
FloatFitsInInt(float f)2029 	bool FloatFitsInInt(float f)
2030 	{
2031 		// We can't just do a raw comparison of "f > (float) INT32_MAX",
2032 		// because "(float) INT32_MAX" is unrepresentable as an integer.
2033 		//
2034 		// So instead I subtracted an ULP from "(float) INT32_MAX", cast that
2035 		// to an int, and do the comparison with that value. That value is
2036 		// 2147483520, and can be found with the following code:
2037 		//    float f_max = static_cast<float>(INT32_MAX);
2038 		//    int32_t f_bits = *static_cast<int32_t *>((void *)&f_max);
2039 		//    f_bits -= 1;
2040 		//    float f_next = *static_cast<float *>((void *)&f_bits);
2041 		//    int32_t out = static_cast<int32_t>(f_next);
2042 		return std::isfinite(f) && (-2147483520.f < f) && (f < 2147483520.f);
2043 	}
2044 }
2045 
2046 namespace es2sw
2047 {
ConvertDepthComparison(GLenum comparison)2048 	sw::DepthCompareMode ConvertDepthComparison(GLenum comparison)
2049 	{
2050 		switch(comparison)
2051 		{
2052 		case GL_NEVER:    return sw::DEPTH_NEVER;
2053 		case GL_ALWAYS:   return sw::DEPTH_ALWAYS;
2054 		case GL_LESS:     return sw::DEPTH_LESS;
2055 		case GL_LEQUAL:   return sw::DEPTH_LESSEQUAL;
2056 		case GL_EQUAL:    return sw::DEPTH_EQUAL;
2057 		case GL_GREATER:  return sw::DEPTH_GREATER;
2058 		case GL_GEQUAL:   return sw::DEPTH_GREATEREQUAL;
2059 		case GL_NOTEQUAL: return sw::DEPTH_NOTEQUAL;
2060 		default: UNREACHABLE(comparison);
2061 		}
2062 
2063 		return sw::DEPTH_ALWAYS;
2064 	}
2065 
ConvertStencilComparison(GLenum comparison)2066 	sw::StencilCompareMode ConvertStencilComparison(GLenum comparison)
2067 	{
2068 		switch(comparison)
2069 		{
2070 		case GL_NEVER:    return sw::STENCIL_NEVER;
2071 		case GL_ALWAYS:   return sw::STENCIL_ALWAYS;
2072 		case GL_LESS:     return sw::STENCIL_LESS;
2073 		case GL_LEQUAL:   return sw::STENCIL_LESSEQUAL;
2074 		case GL_EQUAL:    return sw::STENCIL_EQUAL;
2075 		case GL_GREATER:  return sw::STENCIL_GREATER;
2076 		case GL_GEQUAL:   return sw::STENCIL_GREATEREQUAL;
2077 		case GL_NOTEQUAL: return sw::STENCIL_NOTEQUAL;
2078 		default: UNREACHABLE(comparison);
2079 		}
2080 
2081 		return sw::STENCIL_ALWAYS;
2082 	}
2083 
ConvertColor(es2::Color color)2084 	sw::Color<float> ConvertColor(es2::Color color)
2085 	{
2086 		return sw::Color<float>(color.red, color.green, color.blue, color.alpha);
2087 	}
2088 
ConvertBlendFunc(GLenum blend)2089 	sw::BlendFactor ConvertBlendFunc(GLenum blend)
2090 	{
2091 		switch(blend)
2092 		{
2093 		case GL_ZERO:                     return sw::BLEND_ZERO;
2094 		case GL_ONE:                      return sw::BLEND_ONE;
2095 		case GL_SRC_COLOR:                return sw::BLEND_SOURCE;
2096 		case GL_ONE_MINUS_SRC_COLOR:      return sw::BLEND_INVSOURCE;
2097 		case GL_DST_COLOR:                return sw::BLEND_DEST;
2098 		case GL_ONE_MINUS_DST_COLOR:      return sw::BLEND_INVDEST;
2099 		case GL_SRC_ALPHA:                return sw::BLEND_SOURCEALPHA;
2100 		case GL_ONE_MINUS_SRC_ALPHA:      return sw::BLEND_INVSOURCEALPHA;
2101 		case GL_DST_ALPHA:                return sw::BLEND_DESTALPHA;
2102 		case GL_ONE_MINUS_DST_ALPHA:      return sw::BLEND_INVDESTALPHA;
2103 		case GL_CONSTANT_COLOR:           return sw::BLEND_CONSTANT;
2104 		case GL_ONE_MINUS_CONSTANT_COLOR: return sw::BLEND_INVCONSTANT;
2105 		case GL_CONSTANT_ALPHA:           return sw::BLEND_CONSTANTALPHA;
2106 		case GL_ONE_MINUS_CONSTANT_ALPHA: return sw::BLEND_INVCONSTANTALPHA;
2107 		case GL_SRC_ALPHA_SATURATE:       return sw::BLEND_SRCALPHASAT;
2108 		default: UNREACHABLE(blend);
2109 		}
2110 
2111 		return sw::BLEND_ZERO;
2112 	}
2113 
ConvertBlendOp(GLenum blendOp)2114 	sw::BlendOperation ConvertBlendOp(GLenum blendOp)
2115 	{
2116 		switch(blendOp)
2117 		{
2118 		case GL_FUNC_ADD:              return sw::BLENDOP_ADD;
2119 		case GL_FUNC_SUBTRACT:         return sw::BLENDOP_SUB;
2120 		case GL_FUNC_REVERSE_SUBTRACT: return sw::BLENDOP_INVSUB;
2121 		case GL_MIN_EXT:               return sw::BLENDOP_MIN;
2122 		case GL_MAX_EXT:               return sw::BLENDOP_MAX;
2123 		default: UNREACHABLE(blendOp);
2124 		}
2125 
2126 		return sw::BLENDOP_ADD;
2127 	}
2128 
ConvertStencilOp(GLenum stencilOp)2129 	sw::StencilOperation ConvertStencilOp(GLenum stencilOp)
2130 	{
2131 		switch(stencilOp)
2132 		{
2133 		case GL_ZERO:      return sw::OPERATION_ZERO;
2134 		case GL_KEEP:      return sw::OPERATION_KEEP;
2135 		case GL_REPLACE:   return sw::OPERATION_REPLACE;
2136 		case GL_INCR:      return sw::OPERATION_INCRSAT;
2137 		case GL_DECR:      return sw::OPERATION_DECRSAT;
2138 		case GL_INVERT:    return sw::OPERATION_INVERT;
2139 		case GL_INCR_WRAP: return sw::OPERATION_INCR;
2140 		case GL_DECR_WRAP: return sw::OPERATION_DECR;
2141 		default: UNREACHABLE(stencilOp);
2142 		}
2143 
2144 		return sw::OPERATION_KEEP;
2145 	}
2146 
ConvertTextureWrap(GLenum wrap)2147 	sw::AddressingMode ConvertTextureWrap(GLenum wrap)
2148 	{
2149 		switch(wrap)
2150 		{
2151 		case GL_REPEAT:            return sw::ADDRESSING_WRAP;
2152 		case GL_CLAMP_TO_EDGE:     return sw::ADDRESSING_CLAMP;
2153 		case GL_MIRRORED_REPEAT:   return sw::ADDRESSING_MIRROR;
2154 		default: UNREACHABLE(wrap);
2155 		}
2156 
2157 		return sw::ADDRESSING_WRAP;
2158 	}
2159 
ConvertCompareFunc(GLenum compareFunc,GLenum compareMode)2160 	sw::CompareFunc ConvertCompareFunc(GLenum compareFunc, GLenum compareMode)
2161 	{
2162 		if(compareMode == GL_COMPARE_REF_TO_TEXTURE)
2163 		{
2164 			switch(compareFunc)
2165 			{
2166 			case GL_LEQUAL:   return sw::COMPARE_LESSEQUAL;
2167 			case GL_GEQUAL:   return sw::COMPARE_GREATEREQUAL;
2168 			case GL_LESS:     return sw::COMPARE_LESS;
2169 			case GL_GREATER:  return sw::COMPARE_GREATER;
2170 			case GL_EQUAL:    return sw::COMPARE_EQUAL;
2171 			case GL_NOTEQUAL: return sw::COMPARE_NOTEQUAL;
2172 			case GL_ALWAYS:   return sw::COMPARE_ALWAYS;
2173 			case GL_NEVER:    return sw::COMPARE_NEVER;
2174 			default: UNREACHABLE(compareFunc);
2175 			}
2176 		}
2177 		else if(compareMode == GL_NONE)
2178 		{
2179 			return sw::COMPARE_BYPASS;
2180 		}
2181 		else UNREACHABLE(compareMode);
2182 
2183 		return sw::COMPARE_BYPASS;
2184 	}
2185 
ConvertSwizzleType(GLenum swizzleType)2186 	sw::SwizzleType ConvertSwizzleType(GLenum swizzleType)
2187 	{
2188 		switch(swizzleType)
2189 		{
2190 		case GL_RED:   return sw::SWIZZLE_RED;
2191 		case GL_GREEN: return sw::SWIZZLE_GREEN;
2192 		case GL_BLUE:  return sw::SWIZZLE_BLUE;
2193 		case GL_ALPHA: return sw::SWIZZLE_ALPHA;
2194 		case GL_ZERO:  return sw::SWIZZLE_ZERO;
2195 		case GL_ONE:   return sw::SWIZZLE_ONE;
2196 		default: UNREACHABLE(swizzleType);
2197 		}
2198 
2199 		return sw::SWIZZLE_RED;
2200 	}
2201 
ConvertCullMode(GLenum cullFace,GLenum frontFace)2202 	sw::CullMode ConvertCullMode(GLenum cullFace, GLenum frontFace)
2203 	{
2204 		switch(cullFace)
2205 		{
2206 		case GL_FRONT:
2207 			return (frontFace == GL_CCW ? sw::CULL_CLOCKWISE : sw::CULL_COUNTERCLOCKWISE);
2208 		case GL_BACK:
2209 			return (frontFace == GL_CCW ? sw::CULL_COUNTERCLOCKWISE : sw::CULL_CLOCKWISE);
2210 		case GL_FRONT_AND_BACK:
2211 			return sw::CULL_NONE;   // culling will be handled during draw
2212 		default: UNREACHABLE(cullFace);
2213 		}
2214 
2215 		return sw::CULL_COUNTERCLOCKWISE;
2216 	}
2217 
ConvertColorMask(bool red,bool green,bool blue,bool alpha)2218 	unsigned int ConvertColorMask(bool red, bool green, bool blue, bool alpha)
2219 	{
2220 		return (red   ? 0x00000001 : 0) |
2221 			   (green ? 0x00000002 : 0) |
2222 			   (blue  ? 0x00000004 : 0) |
2223 			   (alpha ? 0x00000008 : 0);
2224 	}
2225 
ConvertMipMapFilter(GLenum minFilter)2226 	sw::MipmapType ConvertMipMapFilter(GLenum minFilter)
2227 	{
2228 		switch(minFilter)
2229 		{
2230 		case GL_NEAREST:
2231 		case GL_LINEAR:
2232 			return sw::MIPMAP_NONE;
2233 		case GL_NEAREST_MIPMAP_NEAREST:
2234 		case GL_LINEAR_MIPMAP_NEAREST:
2235 			return sw::MIPMAP_POINT;
2236 		case GL_NEAREST_MIPMAP_LINEAR:
2237 		case GL_LINEAR_MIPMAP_LINEAR:
2238 			return sw::MIPMAP_LINEAR;
2239 		default:
2240 			UNREACHABLE(minFilter);
2241 			return sw::MIPMAP_NONE;
2242 		}
2243 	}
2244 
ConvertTextureFilter(GLenum minFilter,GLenum magFilter,float maxAnisotropy)2245 	sw::FilterType ConvertTextureFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy)
2246 	{
2247 		if(maxAnisotropy > 1.0f)
2248 		{
2249 			return sw::FILTER_ANISOTROPIC;
2250 		}
2251 
2252 		switch(magFilter)
2253 		{
2254 		case GL_NEAREST:
2255 		case GL_LINEAR:
2256 			break;
2257 		default:
2258 			UNREACHABLE(magFilter);
2259 		}
2260 
2261 		switch(minFilter)
2262 		{
2263 		case GL_NEAREST:
2264 		case GL_NEAREST_MIPMAP_NEAREST:
2265 		case GL_NEAREST_MIPMAP_LINEAR:
2266 			return (magFilter == GL_NEAREST) ? sw::FILTER_POINT : sw::FILTER_MIN_POINT_MAG_LINEAR;
2267 		case GL_LINEAR:
2268 		case GL_LINEAR_MIPMAP_NEAREST:
2269 		case GL_LINEAR_MIPMAP_LINEAR:
2270 			return (magFilter == GL_NEAREST) ? sw::FILTER_MIN_LINEAR_MAG_POINT : sw::FILTER_LINEAR;
2271 		default:
2272 			UNREACHABLE(minFilter);
2273 			return sw::FILTER_POINT;
2274 		}
2275 	}
2276 
ConvertPrimitiveType(GLenum primitiveType,GLsizei elementCount,GLenum elementType,sw::DrawType & drawType,int & primitiveCount,int & verticesPerPrimitive)2277 	bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount, GLenum elementType, sw::DrawType &drawType, int &primitiveCount, int &verticesPerPrimitive)
2278 	{
2279 		switch(primitiveType)
2280 		{
2281 		case GL_POINTS:
2282 			drawType = sw::DRAW_POINTLIST;
2283 			primitiveCount = elementCount;
2284 			verticesPerPrimitive = 1;
2285 			break;
2286 		case GL_LINES:
2287 			drawType = sw::DRAW_LINELIST;
2288 			primitiveCount = elementCount / 2;
2289 			verticesPerPrimitive = 2;
2290 			break;
2291 		case GL_LINE_LOOP:
2292 			drawType = sw::DRAW_LINELOOP;
2293 			primitiveCount = elementCount;
2294 			verticesPerPrimitive = 2;
2295 			break;
2296 		case GL_LINE_STRIP:
2297 			drawType = sw::DRAW_LINESTRIP;
2298 			primitiveCount = elementCount - 1;
2299 			verticesPerPrimitive = 2;
2300 			break;
2301 		case GL_TRIANGLES:
2302 			drawType = sw::DRAW_TRIANGLELIST;
2303 			primitiveCount = elementCount / 3;
2304 			verticesPerPrimitive = 3;
2305 			break;
2306 		case GL_TRIANGLE_STRIP:
2307 			drawType = sw::DRAW_TRIANGLESTRIP;
2308 			primitiveCount = elementCount - 2;
2309 			verticesPerPrimitive = 3;
2310 			break;
2311 		case GL_TRIANGLE_FAN:
2312 			drawType = sw::DRAW_TRIANGLEFAN;
2313 			primitiveCount = elementCount - 2;
2314 			verticesPerPrimitive = 3;
2315 			break;
2316 		default:
2317 			return false;
2318 		}
2319 
2320 		sw::DrawType elementSize;
2321 		switch(elementType)
2322 		{
2323 		case GL_NONE:           elementSize = sw::DRAW_NONINDEXED; break;
2324 		case GL_UNSIGNED_BYTE:  elementSize = sw::DRAW_INDEXED8;   break;
2325 		case GL_UNSIGNED_SHORT: elementSize = sw::DRAW_INDEXED16;  break;
2326 		case GL_UNSIGNED_INT:   elementSize = sw::DRAW_INDEXED32;  break;
2327 		default: return false;
2328 		}
2329 
2330 		drawType = sw::DrawType(drawType | elementSize);
2331 
2332 		return true;
2333 	}
2334 }
2335 
2336 namespace sw2es
2337 {
ConvertBackBufferFormat(sw::Format format)2338 	GLenum ConvertBackBufferFormat(sw::Format format)
2339 	{
2340 		switch(format)
2341 		{
2342 		case sw::FORMAT_A4R4G4B4: return GL_RGBA4;
2343 		case sw::FORMAT_A8R8G8B8: return GL_RGBA8;
2344 		case sw::FORMAT_A8B8G8R8: return GL_RGBA8;
2345 		case sw::FORMAT_A1R5G5B5: return GL_RGB5_A1;
2346 		case sw::FORMAT_R5G6B5:   return GL_RGB565;
2347 		case sw::FORMAT_X8R8G8B8: return GL_RGB8;
2348 		case sw::FORMAT_X8B8G8R8: return GL_RGB8;
2349 		case sw::FORMAT_SRGB8_A8: return GL_RGBA8;
2350 		case sw::FORMAT_SRGB8_X8: return GL_RGB8;
2351 		default:
2352 			UNREACHABLE(format);
2353 		}
2354 
2355 		return GL_RGBA4;
2356 	}
2357 
ConvertDepthStencilFormat(sw::Format format)2358 	GLenum ConvertDepthStencilFormat(sw::Format format)
2359 	{
2360 		switch(format)
2361 		{
2362 		case sw::FORMAT_D16:    return GL_DEPTH_COMPONENT16;
2363 		case sw::FORMAT_D24X8:  return GL_DEPTH_COMPONENT24;
2364 		case sw::FORMAT_D32:    return GL_DEPTH_COMPONENT32_OES;
2365 		case sw::FORMAT_D24S8:  return GL_DEPTH24_STENCIL8_OES;
2366 		case sw::FORMAT_D32F:   return GL_DEPTH_COMPONENT32F;
2367 		case sw::FORMAT_D32FS8: return GL_DEPTH32F_STENCIL8;
2368 		case sw::FORMAT_S8:     return GL_STENCIL_INDEX8;
2369 		default:
2370 			UNREACHABLE(format);
2371 		}
2372 
2373 		return GL_DEPTH24_STENCIL8_OES;
2374 	}
2375 }
2376