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