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 "main.h"
20#include "mathutil.h"
21#include "Context.h"
22#include "common/debug.h"
23
24#include <limits>
25#include <stdio.h>
26#include <stdlib.h>
27
28namespace es2
29{
30	// ES2 requires that format is equal to internal format at all glTex*Image2D entry points and the implementation
31	// can decide the true, sized, internal format. The ES2FormatMap determines the internal format for all valid
32	// format and type combinations.
33
34	typedef std::pair<GLenum, GLenum> FormatTypePair;
35	typedef std::pair<FormatTypePair, GLenum> FormatPair;
36	typedef std::map<FormatTypePair, GLenum> FormatMap;
37
38	// A helper function to insert data into the format map with fewer characters.
39	static inline void InsertFormatMapping(FormatMap *map, GLenum format, GLenum type, GLenum internalFormat)
40	{
41		map->insert(FormatPair(FormatTypePair(format, type), internalFormat));
42	}
43
44	FormatMap BuildFormatMap()
45	{
46		static const GLenum GL_BGRA4_ANGLEX = 0x6ABC;
47		static const GLenum GL_BGR5_A1_ANGLEX = 0x6ABD;
48
49		FormatMap map;
50
51		//                       | Format | Type | Internal format |
52		InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA8);
53		InsertFormatMapping(&map, GL_RGBA, GL_BYTE, GL_RGBA8_SNORM);
54		InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4);
55		InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1);
56		InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB10_A2);
57		InsertFormatMapping(&map, GL_RGBA, GL_FLOAT, GL_RGBA32F);
58		InsertFormatMapping(&map, GL_RGBA, GL_HALF_FLOAT, GL_RGBA16F);
59		InsertFormatMapping(&map, GL_RGBA, GL_HALF_FLOAT_OES, GL_RGBA16F);
60
61		InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GL_RGBA8UI);
62		InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_BYTE, GL_RGBA8I);
63		InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, GL_RGBA16UI);
64		InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_SHORT, GL_RGBA16I);
65		InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_INT, GL_RGBA32UI);
66		InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_INT, GL_RGBA32I);
67		InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB10_A2UI);
68
69		InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_BYTE, GL_RGB8);
70		InsertFormatMapping(&map, GL_RGB, GL_BYTE, GL_RGB8_SNORM);
71		InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB565);
72		InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_R11F_G11F_B10F);
73		InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, GL_RGB9_E5);
74		InsertFormatMapping(&map, GL_RGB, GL_FLOAT, GL_RGB32F);
75		InsertFormatMapping(&map, GL_RGB, GL_HALF_FLOAT, GL_RGB16F);
76		InsertFormatMapping(&map, GL_RGB, GL_HALF_FLOAT_OES, GL_RGB16F);
77
78		InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, GL_RGB8UI);
79		InsertFormatMapping(&map, GL_RGB_INTEGER, GL_BYTE, GL_RGB8I);
80		InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, GL_RGB16UI);
81		InsertFormatMapping(&map, GL_RGB_INTEGER, GL_SHORT, GL_RGB16I);
82		InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_INT, GL_RGB32UI);
83		InsertFormatMapping(&map, GL_RGB_INTEGER, GL_INT, GL_RGB32I);
84
85		InsertFormatMapping(&map, GL_RG, GL_UNSIGNED_BYTE, GL_RG8);
86		InsertFormatMapping(&map, GL_RG, GL_BYTE, GL_RG8_SNORM);
87		InsertFormatMapping(&map, GL_RG, GL_FLOAT, GL_RG32F);
88		InsertFormatMapping(&map, GL_RG, GL_HALF_FLOAT, GL_RG16F);
89		InsertFormatMapping(&map, GL_RG, GL_HALF_FLOAT_OES, GL_RG16F);
90
91		InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_BYTE, GL_RG8UI);
92		InsertFormatMapping(&map, GL_RG_INTEGER, GL_BYTE, GL_RG8I);
93		InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_SHORT, GL_RG16UI);
94		InsertFormatMapping(&map, GL_RG_INTEGER, GL_SHORT, GL_RG16I);
95		InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_INT, GL_RG32UI);
96		InsertFormatMapping(&map, GL_RG_INTEGER, GL_INT, GL_RG32I);
97
98		InsertFormatMapping(&map, GL_RED, GL_UNSIGNED_BYTE, GL_R8);
99		InsertFormatMapping(&map, GL_RED, GL_BYTE, GL_R8_SNORM);
100		InsertFormatMapping(&map, GL_RED, GL_FLOAT, GL_R32F);
101		InsertFormatMapping(&map, GL_RED, GL_HALF_FLOAT, GL_R16F);
102		InsertFormatMapping(&map, GL_RED, GL_HALF_FLOAT_OES, GL_R16F);
103
104		InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_BYTE, GL_R8UI);
105		InsertFormatMapping(&map, GL_RED_INTEGER, GL_BYTE, GL_R8I);
106		InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_SHORT, GL_R16UI);
107		InsertFormatMapping(&map, GL_RED_INTEGER, GL_SHORT, GL_R16I);
108		InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_INT, GL_R32UI);
109		InsertFormatMapping(&map, GL_RED_INTEGER, GL_INT, GL_R32I);
110
111		InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_LUMINANCE8_ALPHA8_EXT);
112		InsertFormatMapping(&map, GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LUMINANCE8_EXT);
113		InsertFormatMapping(&map, GL_ALPHA, GL_UNSIGNED_BYTE, GL_ALPHA8_EXT);
114		InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_FLOAT, GL_LUMINANCE_ALPHA32F_EXT);
115		InsertFormatMapping(&map, GL_LUMINANCE, GL_FLOAT, GL_LUMINANCE32F_EXT);
116		InsertFormatMapping(&map, GL_ALPHA, GL_FLOAT, GL_ALPHA32F_EXT);
117		InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT, GL_LUMINANCE_ALPHA16F_EXT);
118		InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES, GL_LUMINANCE_ALPHA16F_EXT);
119		InsertFormatMapping(&map, GL_LUMINANCE, GL_HALF_FLOAT, GL_LUMINANCE16F_EXT);
120		InsertFormatMapping(&map, GL_LUMINANCE, GL_HALF_FLOAT_OES, GL_LUMINANCE16F_EXT);
121		InsertFormatMapping(&map, GL_ALPHA, GL_HALF_FLOAT, GL_ALPHA16F_EXT);
122		InsertFormatMapping(&map, GL_ALPHA, GL_HALF_FLOAT_OES, GL_ALPHA16F_EXT);
123
124		InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_BGRA8_EXT);
125		InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_BGRA4_ANGLEX);
126		InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_BGR5_A1_ANGLEX);
127
128		InsertFormatMapping(&map, GL_SRGB_EXT, GL_UNSIGNED_BYTE, GL_SRGB8);
129		InsertFormatMapping(&map, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, GL_SRGB8_ALPHA8);
130
131		InsertFormatMapping(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGB_S3TC_DXT1_EXT);
132		InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT);
133		InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE);
134		InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE);
135
136		InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_DEPTH_COMPONENT16);
137		InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT32_OES);
138		InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_FLOAT, GL_DEPTH_COMPONENT32F);
139
140		InsertFormatMapping(&map, GL_STENCIL, GL_UNSIGNED_BYTE, GL_STENCIL_INDEX8);
141
142		InsertFormatMapping(&map, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_DEPTH24_STENCIL8);
143		InsertFormatMapping(&map, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_DEPTH32F_STENCIL8);
144
145		return map;
146	}
147
148	GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type)
149	{
150		switch(internalFormat)
151		{
152		case GL_ALPHA:
153		case GL_LUMINANCE:
154		case GL_LUMINANCE_ALPHA:
155		case GL_RED:
156		case GL_RG:
157		case GL_RGB:
158		case GL_RGBA:
159		case GL_RED_INTEGER:
160		case GL_RG_INTEGER:
161		case GL_RGB_INTEGER:
162		case GL_RGBA_INTEGER:
163		case GL_BGRA_EXT:
164		case GL_DEPTH_COMPONENT:
165		case GL_DEPTH_STENCIL:
166		case GL_SRGB_EXT:
167		case GL_SRGB_ALPHA_EXT:
168			{
169				static const FormatMap formatMap = BuildFormatMap();
170				FormatMap::const_iterator iter = formatMap.find(FormatTypePair(internalFormat, type));
171				return (iter != formatMap.end()) ? iter->second : GL_NONE;
172			}
173		default:
174			return internalFormat;
175		}
176	}
177
178	unsigned int UniformComponentCount(GLenum type)
179	{
180		switch(type)
181		{
182		case GL_BOOL:
183		case GL_FLOAT:
184		case GL_INT:
185		case GL_UNSIGNED_INT:
186		case GL_SAMPLER_2D:
187		case GL_SAMPLER_CUBE:
188		case GL_SAMPLER_EXTERNAL_OES:
189		case GL_SAMPLER_3D_OES:
190		case GL_SAMPLER_2D_ARRAY:
191		case GL_SAMPLER_2D_SHADOW:
192		case GL_SAMPLER_CUBE_SHADOW:
193		case GL_SAMPLER_2D_ARRAY_SHADOW:
194		case GL_INT_SAMPLER_2D:
195		case GL_UNSIGNED_INT_SAMPLER_2D:
196		case GL_INT_SAMPLER_CUBE:
197		case GL_UNSIGNED_INT_SAMPLER_CUBE:
198		case GL_INT_SAMPLER_3D:
199		case GL_UNSIGNED_INT_SAMPLER_3D:
200		case GL_INT_SAMPLER_2D_ARRAY:
201		case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
202			return 1;
203		case GL_BOOL_VEC2:
204		case GL_FLOAT_VEC2:
205		case GL_INT_VEC2:
206		case GL_UNSIGNED_INT_VEC2:
207			return 2;
208		case GL_INT_VEC3:
209		case GL_UNSIGNED_INT_VEC3:
210		case GL_FLOAT_VEC3:
211		case GL_BOOL_VEC3:
212			return 3;
213		case GL_BOOL_VEC4:
214		case GL_FLOAT_VEC4:
215		case GL_INT_VEC4:
216		case GL_UNSIGNED_INT_VEC4:
217		case GL_FLOAT_MAT2:
218			return 4;
219		case GL_FLOAT_MAT2x3:
220		case GL_FLOAT_MAT3x2:
221			return 6;
222		case GL_FLOAT_MAT2x4:
223		case GL_FLOAT_MAT4x2:
224			return 8;
225		case GL_FLOAT_MAT3:
226			return 9;
227		case GL_FLOAT_MAT3x4:
228		case GL_FLOAT_MAT4x3:
229			return 12;
230		case GL_FLOAT_MAT4:
231			return 16;
232		default:
233			UNREACHABLE(type);
234		}
235
236		return 0;
237	}
238
239	GLenum UniformComponentType(GLenum type)
240	{
241		switch(type)
242		{
243		case GL_BOOL:
244		case GL_BOOL_VEC2:
245		case GL_BOOL_VEC3:
246		case GL_BOOL_VEC4:
247			return GL_BOOL;
248		case GL_FLOAT:
249		case GL_FLOAT_VEC2:
250		case GL_FLOAT_VEC3:
251		case GL_FLOAT_VEC4:
252		case GL_FLOAT_MAT2:
253		case GL_FLOAT_MAT2x3:
254		case GL_FLOAT_MAT2x4:
255		case GL_FLOAT_MAT3:
256		case GL_FLOAT_MAT3x2:
257		case GL_FLOAT_MAT3x4:
258		case GL_FLOAT_MAT4:
259		case GL_FLOAT_MAT4x2:
260		case GL_FLOAT_MAT4x3:
261			return GL_FLOAT;
262		case GL_INT:
263		case GL_SAMPLER_2D:
264		case GL_SAMPLER_CUBE:
265		case GL_SAMPLER_EXTERNAL_OES:
266		case GL_SAMPLER_3D_OES:
267		case GL_SAMPLER_2D_ARRAY:
268		case GL_SAMPLER_2D_SHADOW:
269		case GL_SAMPLER_CUBE_SHADOW:
270		case GL_SAMPLER_2D_ARRAY_SHADOW:
271		case GL_INT_SAMPLER_2D:
272		case GL_UNSIGNED_INT_SAMPLER_2D:
273		case GL_INT_SAMPLER_CUBE:
274		case GL_UNSIGNED_INT_SAMPLER_CUBE:
275		case GL_INT_SAMPLER_3D:
276		case GL_UNSIGNED_INT_SAMPLER_3D:
277		case GL_INT_SAMPLER_2D_ARRAY:
278		case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
279		case GL_INT_VEC2:
280		case GL_INT_VEC3:
281		case GL_INT_VEC4:
282			return GL_INT;
283		case GL_UNSIGNED_INT:
284		case GL_UNSIGNED_INT_VEC2:
285		case GL_UNSIGNED_INT_VEC3:
286		case GL_UNSIGNED_INT_VEC4:
287			return GL_UNSIGNED_INT;
288		default:
289			UNREACHABLE(type);
290		}
291
292		return GL_NONE;
293	}
294
295	size_t UniformTypeSize(GLenum type)
296	{
297		switch(type)
298		{
299		case GL_BOOL:  return sizeof(GLboolean);
300		case GL_FLOAT: return sizeof(GLfloat);
301		case GL_INT:   return sizeof(GLint);
302		case GL_UNSIGNED_INT: return sizeof(GLuint);
303		}
304
305		return UniformTypeSize(UniformComponentType(type)) * UniformComponentCount(type);
306	}
307
308	bool IsSamplerUniform(GLenum type)
309	{
310		switch(type)
311		{
312		case GL_SAMPLER_2D:
313		case GL_SAMPLER_CUBE:
314		case GL_SAMPLER_EXTERNAL_OES:
315		case GL_SAMPLER_3D_OES:
316		case GL_SAMPLER_2D_ARRAY:
317		case GL_SAMPLER_2D_SHADOW:
318		case GL_SAMPLER_CUBE_SHADOW:
319		case GL_SAMPLER_2D_ARRAY_SHADOW:
320		case GL_INT_SAMPLER_2D:
321		case GL_UNSIGNED_INT_SAMPLER_2D:
322		case GL_INT_SAMPLER_CUBE:
323		case GL_UNSIGNED_INT_SAMPLER_CUBE:
324		case GL_INT_SAMPLER_3D:
325		case GL_UNSIGNED_INT_SAMPLER_3D:
326		case GL_INT_SAMPLER_2D_ARRAY:
327		case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
328			return true;
329		default:
330			return false;
331		}
332	}
333
334	int VariableRowCount(GLenum type)
335	{
336		switch(type)
337		{
338		case GL_NONE:
339			return 0;
340		case GL_BOOL:
341		case GL_FLOAT:
342		case GL_INT:
343		case GL_UNSIGNED_INT:
344		case GL_BOOL_VEC2:
345		case GL_FLOAT_VEC2:
346		case GL_INT_VEC2:
347		case GL_UNSIGNED_INT_VEC2:
348		case GL_INT_VEC3:
349		case GL_UNSIGNED_INT_VEC3:
350		case GL_FLOAT_VEC3:
351		case GL_BOOL_VEC3:
352		case GL_BOOL_VEC4:
353		case GL_FLOAT_VEC4:
354		case GL_INT_VEC4:
355		case GL_UNSIGNED_INT_VEC4:
356		case GL_SAMPLER_2D:
357		case GL_SAMPLER_CUBE:
358		case GL_SAMPLER_EXTERNAL_OES:
359		case GL_SAMPLER_3D_OES:
360		case GL_SAMPLER_2D_ARRAY:
361		case GL_SAMPLER_2D_SHADOW:
362		case GL_SAMPLER_CUBE_SHADOW:
363		case GL_SAMPLER_2D_ARRAY_SHADOW:
364		case GL_INT_SAMPLER_2D:
365		case GL_UNSIGNED_INT_SAMPLER_2D:
366		case GL_INT_SAMPLER_CUBE:
367		case GL_UNSIGNED_INT_SAMPLER_CUBE:
368		case GL_INT_SAMPLER_3D:
369		case GL_UNSIGNED_INT_SAMPLER_3D:
370		case GL_INT_SAMPLER_2D_ARRAY:
371		case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
372			return 1;
373		case GL_FLOAT_MAT2:
374		case GL_FLOAT_MAT3x2:
375		case GL_FLOAT_MAT4x2:
376			return 2;
377		case GL_FLOAT_MAT3:
378		case GL_FLOAT_MAT2x3:
379		case GL_FLOAT_MAT4x3:
380			return 3;
381		case GL_FLOAT_MAT4:
382		case GL_FLOAT_MAT2x4:
383		case GL_FLOAT_MAT3x4:
384			return 4;
385		default:
386			UNREACHABLE(type);
387		}
388
389		return 0;
390	}
391
392	int VariableColumnCount(GLenum type)
393	{
394		switch(type)
395		{
396		case GL_NONE:
397			return 0;
398		case GL_BOOL:
399		case GL_FLOAT:
400		case GL_INT:
401		case GL_UNSIGNED_INT:
402			return 1;
403		case GL_BOOL_VEC2:
404		case GL_FLOAT_VEC2:
405		case GL_INT_VEC2:
406		case GL_UNSIGNED_INT_VEC2:
407		case GL_FLOAT_MAT2:
408		case GL_FLOAT_MAT2x3:
409		case GL_FLOAT_MAT2x4:
410			return 2;
411		case GL_INT_VEC3:
412		case GL_UNSIGNED_INT_VEC3:
413		case GL_FLOAT_VEC3:
414		case GL_BOOL_VEC3:
415		case GL_FLOAT_MAT3:
416		case GL_FLOAT_MAT3x2:
417		case GL_FLOAT_MAT3x4:
418			return 3;
419		case GL_BOOL_VEC4:
420		case GL_FLOAT_VEC4:
421		case GL_INT_VEC4:
422		case GL_UNSIGNED_INT_VEC4:
423		case GL_FLOAT_MAT4:
424		case GL_FLOAT_MAT4x2:
425		case GL_FLOAT_MAT4x3:
426			return 4;
427		default:
428			UNREACHABLE(type);
429		}
430
431		return 0;
432	}
433
434	int VariableRegisterCount(GLenum type)
435	{
436		// Number of registers used is the number of columns for matrices or 1 for scalars and vectors
437		return (VariableRowCount(type) > 1) ? VariableColumnCount(type) : 1;
438	}
439
440	int VariableRegisterSize(GLenum type)
441	{
442		// Number of components per register is the number of rows for matrices or columns for scalars and vectors
443		int nbRows = VariableRowCount(type);
444		return (nbRows > 1) ? nbRows : VariableColumnCount(type);
445	}
446
447	int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize)
448	{
449		ASSERT(allocationSize <= bitsSize);
450
451		unsigned int mask = std::numeric_limits<unsigned int>::max() >> (std::numeric_limits<unsigned int>::digits - allocationSize);
452
453		for(unsigned int i = 0; i < bitsSize - allocationSize + 1; i++)
454		{
455			if((*bits & mask) == 0)
456			{
457				*bits |= mask;
458				return i;
459			}
460
461			mask <<= 1;
462		}
463
464		return -1;
465	}
466
467	bool IsCompressed(GLenum format, GLint clientVersion)
468	{
469		return ValidateCompressedFormat(format, clientVersion, true) == GL_NONE;
470	}
471
472	GLenum ValidateCompressedFormat(GLenum format, GLint clientVersion, bool expectCompressedFormats)
473	{
474		switch(format)
475		{
476		case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
477		case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
478		case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
479		case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
480			return S3TC_SUPPORT ? (expectCompressedFormats ? GL_NONE : GL_INVALID_OPERATION) : GL_INVALID_ENUM;
481		case GL_ETC1_RGB8_OES:
482			return expectCompressedFormats ? GL_NONE : GL_INVALID_OPERATION;
483		case GL_COMPRESSED_R11_EAC:
484		case GL_COMPRESSED_SIGNED_R11_EAC:
485		case GL_COMPRESSED_RG11_EAC:
486		case GL_COMPRESSED_SIGNED_RG11_EAC:
487		case GL_COMPRESSED_RGB8_ETC2:
488		case GL_COMPRESSED_SRGB8_ETC2:
489		case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
490		case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
491		case GL_COMPRESSED_RGBA8_ETC2_EAC:
492		case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
493		case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
494		case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
495		case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
496		case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
497		case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
498		case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
499		case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
500		case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
501		case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
502		case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
503		case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
504		case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
505		case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
506		case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
507		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
508		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
509		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
510		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
511		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
512		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
513		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
514		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
515		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
516		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
517		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
518		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
519		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
520		case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
521			return (clientVersion >= 3) ? (expectCompressedFormats ? GL_NONE : GL_INVALID_OPERATION) : GL_INVALID_ENUM;
522		default:
523			return expectCompressedFormats ? GL_INVALID_ENUM : GL_NONE; // Not compressed format
524		}
525	}
526
527	GLenum ValidateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum sizedInternalFormat, Texture *texture)
528	{
529		if(!texture)
530		{
531			return GL_INVALID_OPERATION;
532		}
533
534		if(compressed != texture->isCompressed(target, level))
535		{
536			return GL_INVALID_OPERATION;
537		}
538
539		if(sizedInternalFormat != GL_NONE && sizedInternalFormat != texture->getFormat(target, level))
540		{
541			return GL_INVALID_OPERATION;
542		}
543
544		if(compressed)
545		{
546			if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
547			   (height % 4 != 0 && height != texture->getHeight(target, 0)))
548			{
549				return GL_INVALID_OPERATION;
550			}
551		}
552
553		if(xoffset + width > texture->getWidth(target, level) ||
554		   yoffset + height > texture->getHeight(target, level))
555		{
556			return GL_INVALID_VALUE;
557		}
558
559		return GL_NONE;
560	}
561
562	GLenum ValidateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLsizei depth, GLint xoffset, GLint yoffset, GLint zoffset, GLenum target, GLint level, GLenum sizedInternalFormat, Texture *texture)
563	{
564		if(!texture)
565		{
566			return GL_INVALID_OPERATION;
567		}
568
569		if(compressed != texture->isCompressed(target, level))
570		{
571			return GL_INVALID_OPERATION;
572		}
573
574		if(sizedInternalFormat != GL_NONE && sizedInternalFormat != GetSizedInternalFormat(texture->getFormat(target, level), texture->getType(target, level)))
575		{
576			return GL_INVALID_OPERATION;
577		}
578
579		if(compressed)
580		{
581			if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
582			   (height % 4 != 0 && height != texture->getHeight(target, 0)) ||
583			   (depth % 4 != 0 && depth != texture->getDepth(target, 0)))
584			{
585				return GL_INVALID_OPERATION;
586			}
587		}
588
589		if(xoffset + width > texture->getWidth(target, level) ||
590		   yoffset + height > texture->getHeight(target, level) ||
591		   zoffset + depth > texture->getDepth(target, level))
592		{
593			return GL_INVALID_VALUE;
594		}
595
596		return GL_NONE;
597	}
598
599	bool ValidReadPixelsFormatType(GLenum internalFormat, GLenum internalType, GLenum format, GLenum type, GLint clientVersion)
600	{
601		switch(format)
602		{
603		case GL_RGBA:
604			switch(type)
605			{
606			case GL_UNSIGNED_BYTE:
607				break;
608			case GL_UNSIGNED_INT_2_10_10_10_REV:
609				return (clientVersion >= 3) && (internalFormat == GL_RGB10_A2);
610			case GL_FLOAT:
611				return (clientVersion >= 3) && (internalType == GL_FLOAT);
612			default:
613				return false;
614			}
615			break;
616		case GL_RGBA_INTEGER:
617			if(clientVersion < 3)
618			{
619				return false;
620			}
621			switch(type)
622			{
623			case GL_INT:
624				if(internalType != GL_INT)
625				{
626					return false;
627				}
628				break;
629			case GL_UNSIGNED_INT:
630				if(internalType != GL_UNSIGNED_INT)
631				{
632					return false;
633				}
634				break;
635			default:
636				return false;
637			}
638			break;
639		case GL_BGRA_EXT:
640			switch(type)
641			{
642			case GL_UNSIGNED_BYTE:
643			case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
644			case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
645				break;
646			default:
647				return false;
648			}
649			break;
650		case GL_RG_EXT:
651		case GL_RED_EXT:
652			return (clientVersion >= 3) && (type == GL_UNSIGNED_BYTE);
653		case GL_DEPTH_COMPONENT:
654			if(internalFormat != format)
655			{
656				return false;
657			}
658			switch(type)
659			{
660			case GL_UNSIGNED_SHORT:
661			case GL_FLOAT:
662				if(internalType != type)
663				{
664					return false;
665				}
666				break;
667			default:
668				return false;
669			}
670			break;
671		default:
672			return false;
673		}
674		return true;
675	}
676
677	bool IsDepthTexture(GLenum format)
678	{
679		return format == GL_DEPTH_COMPONENT ||
680		       format == GL_DEPTH_STENCIL_OES ||
681		       format == GL_DEPTH_COMPONENT16 ||
682		       format == GL_DEPTH_COMPONENT24 ||
683		       format == GL_DEPTH_COMPONENT32_OES ||
684		       format == GL_DEPTH_COMPONENT32F ||
685		       format == GL_DEPTH24_STENCIL8 ||
686		       format == GL_DEPTH32F_STENCIL8;
687	}
688
689	bool IsStencilTexture(GLenum format)
690	{
691		return format == GL_STENCIL_INDEX_OES ||
692		       format == GL_DEPTH_STENCIL_OES ||
693		       format == GL_DEPTH24_STENCIL8 ||
694		       format == GL_DEPTH32F_STENCIL8;
695	}
696
697	bool IsCubemapTextureTarget(GLenum target)
698	{
699		return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
700	}
701
702	int CubeFaceIndex(GLenum cubeFace)
703	{
704		switch(cubeFace)
705		{
706		case GL_TEXTURE_CUBE_MAP:
707		case GL_TEXTURE_CUBE_MAP_POSITIVE_X: return 0;
708		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: return 1;
709		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: return 2;
710		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: return 3;
711		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: return 4;
712		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: return 5;
713		default: UNREACHABLE(cubeFace); return 0;
714		}
715	}
716
717	bool IsTextureTarget(GLenum target)
718	{
719		return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target) || target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY;
720	}
721
722	bool ValidateTextureFormatType(GLenum format, GLenum type, GLint internalformat, GLint clientVersion)
723	{
724		switch(type)
725		{
726		case GL_UNSIGNED_BYTE:
727		case GL_UNSIGNED_SHORT_4_4_4_4:
728		case GL_UNSIGNED_SHORT_5_5_5_1:
729		case GL_UNSIGNED_SHORT_5_6_5:
730		case GL_FLOAT:               // GL_OES_texture_float
731		case GL_HALF_FLOAT_OES:      // GL_OES_texture_half_float
732		case GL_UNSIGNED_INT_24_8:   // GL_OES_packed_depth_stencil (GL_UNSIGNED_INT_24_8_EXT)
733		case GL_UNSIGNED_SHORT:      // GL_OES_depth_texture
734		case GL_UNSIGNED_INT:        // GL_OES_depth_texture
735			break;
736		case GL_BYTE:
737		case GL_SHORT:
738		case GL_INT:
739		case GL_HALF_FLOAT:
740		case GL_UNSIGNED_INT_2_10_10_10_REV:
741		case GL_UNSIGNED_INT_10F_11F_11F_REV:
742		case GL_UNSIGNED_INT_5_9_9_9_REV:
743		case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
744			if(clientVersion < 3)
745			{
746				return error(GL_INVALID_ENUM, false);
747			}
748			break;
749		default:
750			return error(GL_INVALID_ENUM, false);
751		}
752
753		switch(format)
754		{
755		case GL_ALPHA:
756		case GL_RGB:
757		case GL_RGBA:
758		case GL_LUMINANCE:
759		case GL_LUMINANCE_ALPHA:
760		case GL_BGRA_EXT:          // GL_EXT_texture_format_BGRA8888
761		case GL_DEPTH_STENCIL:     // GL_OES_packed_depth_stencil (GL_DEPTH_STENCIL_OES)
762		case GL_DEPTH_COMPONENT:   // GL_OES_depth_texture
763			break;
764		case GL_RED:
765		case GL_RED_INTEGER:
766		case GL_RG:
767		case GL_RG_INTEGER:
768		case GL_RGB_INTEGER:
769		case GL_RGBA_INTEGER:
770			if(clientVersion < 3)
771			{
772				return error(GL_INVALID_ENUM, false);
773			}
774			break;
775		default:
776			return error(GL_INVALID_ENUM, false);
777		}
778
779		if(internalformat != format)
780		{
781			if(clientVersion < 3)
782			{
783				return error(GL_INVALID_OPERATION, false);
784			}
785
786			switch(internalformat)
787			{
788			case GL_R8:
789			case GL_R8UI:
790			case GL_R8I:
791			case GL_R16UI:
792			case GL_R16I:
793			case GL_R32UI:
794			case GL_R32I:
795			case GL_RG8:
796			case GL_RG8UI:
797			case GL_RG8I:
798			case GL_RG16UI:
799			case GL_RG16I:
800			case GL_RG32UI:
801			case GL_RG32I:
802			case GL_SRGB8_ALPHA8:
803			case GL_RGB8UI:
804			case GL_RGB8I:
805			case GL_RGB16UI:
806			case GL_RGB16I:
807			case GL_RGB32UI:
808			case GL_RGB32I:
809			case GL_RG8_SNORM:
810			case GL_R8_SNORM:
811			case GL_RGB10_A2:
812			case GL_RGBA8UI:
813			case GL_RGBA8I:
814			case GL_RGB10_A2UI:
815			case GL_RGBA16UI:
816			case GL_RGBA16I:
817			case GL_RGBA32I:
818			case GL_RGBA32UI:
819			case GL_RGBA4:
820			case GL_RGB5_A1:
821			case GL_RGB565:
822			case GL_RGB8_OES:
823			case GL_RGBA8_OES:
824			case GL_R16F:
825			case GL_RG16F:
826			case GL_R11F_G11F_B10F:
827			case GL_RGB16F:
828			case GL_RGBA16F:
829			case GL_R32F:
830			case GL_RG32F:
831			case GL_RGB32F:
832			case GL_RGBA32F:
833			case GL_DEPTH_COMPONENT24:
834			case GL_DEPTH_COMPONENT32_OES:
835			case GL_DEPTH_COMPONENT32F:
836			case GL_DEPTH32F_STENCIL8:
837			case GL_DEPTH_COMPONENT16:
838			case GL_STENCIL_INDEX8:
839			case GL_DEPTH24_STENCIL8_OES:
840			case GL_RGBA8_SNORM:
841			case GL_SRGB8:
842			case GL_RGB8_SNORM:
843			case GL_RGB9_E5:
844				break;
845			default:
846				return error(GL_INVALID_ENUM, false);
847			}
848		}
849
850		// Validate format, type, and sized internalformat combinations [OpenGL ES 3.0 Table 3.2]
851		bool validSizedInternalformat = false;
852		#define VALIDATE_INTERNALFORMAT(...) { GLint validInternalformats[] = {__VA_ARGS__}; for(GLint v : validInternalformats) {if(internalformat == v) validSizedInternalformat = true;} } break;
853
854		switch(format)
855		{
856		case GL_RGBA:
857			switch(type)
858			{
859			case GL_UNSIGNED_BYTE:               VALIDATE_INTERNALFORMAT(GL_RGBA8, GL_RGB5_A1, GL_RGBA4, GL_SRGB8_ALPHA8)
860			case GL_BYTE:                        VALIDATE_INTERNALFORMAT(GL_RGBA8_SNORM)
861			case GL_HALF_FLOAT_OES:              break;
862			case GL_UNSIGNED_SHORT_4_4_4_4:      VALIDATE_INTERNALFORMAT(GL_RGBA4)
863			case GL_UNSIGNED_SHORT_5_5_5_1:      VALIDATE_INTERNALFORMAT(GL_RGB5_A1)
864			case GL_UNSIGNED_INT_2_10_10_10_REV: VALIDATE_INTERNALFORMAT(GL_RGB10_A2, GL_RGB5_A1)
865			case GL_HALF_FLOAT:                  VALIDATE_INTERNALFORMAT(GL_RGBA16F)
866			case GL_FLOAT:                       VALIDATE_INTERNALFORMAT(GL_RGBA32F, GL_RGBA16F)
867			default:                             return error(GL_INVALID_OPERATION, false);
868			}
869			break;
870		case GL_RGBA_INTEGER:
871			switch(type)
872			{
873			case GL_UNSIGNED_BYTE:               VALIDATE_INTERNALFORMAT(GL_RGBA8UI)
874			case GL_BYTE:                        VALIDATE_INTERNALFORMAT(GL_RGBA8I)
875			case GL_UNSIGNED_SHORT:              VALIDATE_INTERNALFORMAT(GL_RGBA16UI)
876			case GL_SHORT:                       VALIDATE_INTERNALFORMAT(GL_RGBA16I)
877			case GL_UNSIGNED_INT:                VALIDATE_INTERNALFORMAT(GL_RGBA32UI)
878			case GL_INT:                         VALIDATE_INTERNALFORMAT(GL_RGBA32I)
879			case GL_UNSIGNED_INT_2_10_10_10_REV: VALIDATE_INTERNALFORMAT(GL_RGB10_A2UI)
880			default:                             return error(GL_INVALID_OPERATION, false);
881			}
882			break;
883		case GL_RGB:
884			switch(type)
885			{
886			case GL_UNSIGNED_BYTE:                VALIDATE_INTERNALFORMAT(GL_RGB8, GL_RGB565, GL_SRGB8)
887			case GL_BYTE:                         VALIDATE_INTERNALFORMAT(GL_RGB8_SNORM)
888			case GL_HALF_FLOAT_OES:               break;
889			case GL_UNSIGNED_SHORT_5_6_5:         VALIDATE_INTERNALFORMAT(GL_RGB565)
890			case GL_UNSIGNED_INT_10F_11F_11F_REV: VALIDATE_INTERNALFORMAT(GL_R11F_G11F_B10F)
891			case GL_UNSIGNED_INT_5_9_9_9_REV:     VALIDATE_INTERNALFORMAT(GL_RGB9_E5)
892			case GL_HALF_FLOAT:                   VALIDATE_INTERNALFORMAT(GL_RGB16F, GL_R11F_G11F_B10F, GL_RGB9_E5)
893			case GL_FLOAT:                        VALIDATE_INTERNALFORMAT(GL_RGB32F, GL_RGB16F, GL_R11F_G11F_B10F, GL_RGB9_E5)
894			default:                              return error(GL_INVALID_OPERATION, false);
895			}
896			break;
897		case GL_RGB_INTEGER:
898			switch(type)
899			{
900			case GL_UNSIGNED_BYTE:               VALIDATE_INTERNALFORMAT(GL_RGB8UI)
901			case GL_BYTE:                        VALIDATE_INTERNALFORMAT(GL_RGB8I)
902			case GL_UNSIGNED_SHORT:              VALIDATE_INTERNALFORMAT(GL_RGB16UI)
903			case GL_SHORT:                       VALIDATE_INTERNALFORMAT(GL_RGB16I)
904			case GL_UNSIGNED_INT:                VALIDATE_INTERNALFORMAT(GL_RGB32UI)
905			case GL_INT:                         VALIDATE_INTERNALFORMAT(GL_RGB32I)
906			default:                             return error(GL_INVALID_OPERATION, false);
907			}
908			break;
909		case GL_RG:
910			switch(type)
911			{
912			case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RG8)
913			case GL_BYTE:          VALIDATE_INTERNALFORMAT(GL_RG8_SNORM)
914			case GL_HALF_FLOAT:    VALIDATE_INTERNALFORMAT(GL_RG16F)
915			case GL_FLOAT:         VALIDATE_INTERNALFORMAT(GL_RG32F, GL_RG16F)
916			default:               return error(GL_INVALID_OPERATION, false);
917			}
918			break;
919		case GL_RG_INTEGER:
920			switch(type)
921			{
922			case GL_UNSIGNED_BYTE:  VALIDATE_INTERNALFORMAT(GL_RG8UI)
923			case GL_BYTE:           VALIDATE_INTERNALFORMAT(GL_RG8I)
924			case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_RG16UI)
925			case GL_SHORT:          VALIDATE_INTERNALFORMAT(GL_RG16I)
926			case GL_UNSIGNED_INT:   VALIDATE_INTERNALFORMAT(GL_RG32UI)
927			case GL_INT:            VALIDATE_INTERNALFORMAT(GL_RG32I)
928			default:                return error(GL_INVALID_OPERATION, false);
929			}
930			break;
931		case GL_RED:
932			switch(type)
933			{
934			case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_R8)
935			case GL_BYTE:          VALIDATE_INTERNALFORMAT(GL_R8_SNORM)
936			case GL_HALF_FLOAT:    VALIDATE_INTERNALFORMAT(GL_R16F)
937			case GL_FLOAT:         VALIDATE_INTERNALFORMAT(GL_R32F, GL_R16F)
938			default:               return error(GL_INVALID_OPERATION, false);
939			}
940			break;
941		case GL_RED_INTEGER:
942			switch(type)
943			{
944			case GL_UNSIGNED_BYTE:  VALIDATE_INTERNALFORMAT(GL_R8UI)
945			case GL_BYTE:           VALIDATE_INTERNALFORMAT(GL_R8I)
946			case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_R16UI)
947			case GL_SHORT:          VALIDATE_INTERNALFORMAT(GL_R16I)
948			case GL_UNSIGNED_INT:   VALIDATE_INTERNALFORMAT(GL_R32UI)
949			case GL_INT:            VALIDATE_INTERNALFORMAT(GL_R32I)
950			default:                return error(GL_INVALID_OPERATION, false);
951			}
952			break;
953		case GL_DEPTH_COMPONENT:
954			switch(type)
955			{
956			case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT16)
957			case GL_UNSIGNED_INT:   VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT16)
958			case GL_FLOAT:          VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT32F)
959			default:                return error(GL_INVALID_OPERATION, false);
960			}
961			break;
962		case GL_DEPTH_STENCIL:
963			switch(type)
964			{
965			case GL_UNSIGNED_INT_24_8:              VALIDATE_INTERNALFORMAT(GL_DEPTH24_STENCIL8)
966			case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: VALIDATE_INTERNALFORMAT(GL_DEPTH32F_STENCIL8)
967			default:                                return error(GL_INVALID_OPERATION, false);
968			}
969			break;
970		case GL_LUMINANCE_ALPHA:
971		case GL_LUMINANCE:
972		case GL_ALPHA:
973			switch(type)
974			{
975			case GL_UNSIGNED_BYTE:
976			case GL_HALF_FLOAT_OES:
977			case GL_FLOAT:
978				break;
979			default:
980				return error(GL_INVALID_OPERATION, false);
981			}
982			break;
983		case GL_BGRA_EXT:
984			if(type != GL_UNSIGNED_BYTE)
985			{
986				return error(GL_INVALID_OPERATION, false);
987			}
988			break;
989		default:
990			UNREACHABLE(format);
991			return error(GL_INVALID_ENUM, false);
992		}
993
994		#undef VALIDATE_INTERNALFORMAT
995
996		if(internalformat != format && !validSizedInternalformat)
997		{
998			return error(GL_INVALID_OPERATION, false);
999		}
1000
1001		return true;
1002	}
1003
1004	bool IsColorRenderable(GLenum internalformat, GLint clientVersion)
1005	{
1006		switch(internalformat)
1007		{
1008		case GL_RGB:
1009		case GL_RGBA:
1010		case GL_RGBA4:
1011		case GL_RGB5_A1:
1012		case GL_RGB565:
1013		case GL_RGB8_OES:
1014		case GL_RGBA8_OES:
1015		case GL_R16F:
1016		case GL_RG16F:
1017		case GL_RGB16F:
1018		case GL_RGBA16F:
1019		case GL_BGRA8_EXT:
1020			return true;
1021		case GL_R8:
1022		case GL_R8UI:
1023		case GL_R8I:
1024		case GL_R16UI:
1025		case GL_R16I:
1026		case GL_R32UI:
1027		case GL_R32I:
1028		case GL_RG8:
1029		case GL_RG8UI:
1030		case GL_RG8I:
1031		case GL_RG16UI:
1032		case GL_RG16I:
1033		case GL_RG32UI:
1034		case GL_RG32I:
1035		case GL_SRGB8_ALPHA8:
1036		case GL_RGB10_A2:
1037		case GL_RGBA8UI:
1038		case GL_RGBA8I:
1039		case GL_RGB10_A2UI:
1040		case GL_RGBA16UI:
1041		case GL_RGBA16I:
1042		case GL_RGBA32I:
1043		case GL_RGBA32UI:
1044		case GL_R11F_G11F_B10F:
1045		case GL_R32F:
1046		case GL_RG32F:
1047		case GL_RGB32F:
1048		case GL_RGBA32F:
1049			return clientVersion >= 3;
1050		case GL_DEPTH_COMPONENT24:
1051		case GL_DEPTH_COMPONENT32_OES:
1052		case GL_DEPTH_COMPONENT32F:
1053		case GL_DEPTH32F_STENCIL8:
1054		case GL_DEPTH_COMPONENT16:
1055		case GL_STENCIL_INDEX8:
1056		case GL_DEPTH24_STENCIL8_OES:
1057			return false;
1058		default:
1059			UNIMPLEMENTED();
1060		}
1061
1062		return false;
1063	}
1064
1065	bool IsDepthRenderable(GLenum internalformat)
1066	{
1067		switch(internalformat)
1068		{
1069		case GL_DEPTH_COMPONENT24:
1070		case GL_DEPTH_COMPONENT32_OES:
1071		case GL_DEPTH_COMPONENT32F:
1072		case GL_DEPTH32F_STENCIL8:
1073		case GL_DEPTH_COMPONENT16:
1074		case GL_DEPTH24_STENCIL8_OES:
1075			return true;
1076		case GL_STENCIL_INDEX8:
1077		case GL_R8:
1078		case GL_R8UI:
1079		case GL_R8I:
1080		case GL_R16UI:
1081		case GL_R16I:
1082		case GL_R32UI:
1083		case GL_R32I:
1084		case GL_RG8:
1085		case GL_RG8UI:
1086		case GL_RG8I:
1087		case GL_RG16UI:
1088		case GL_RG16I:
1089		case GL_RG32UI:
1090		case GL_RG32I:
1091		case GL_SRGB8_ALPHA8:
1092		case GL_RGB10_A2:
1093		case GL_RGBA8UI:
1094		case GL_RGBA8I:
1095		case GL_RGB10_A2UI:
1096		case GL_RGBA16UI:
1097		case GL_RGBA16I:
1098		case GL_RGBA32I:
1099		case GL_RGBA32UI:
1100		case GL_RGBA4:
1101		case GL_RGB5_A1:
1102		case GL_RGB565:
1103		case GL_RGB8_OES:
1104		case GL_RGBA8_OES:
1105		case GL_RGB:
1106		case GL_RGBA:
1107		case GL_R16F:
1108		case GL_RG16F:
1109		case GL_R11F_G11F_B10F:
1110		case GL_RGB16F:
1111		case GL_RGBA16F:
1112		case GL_R32F:
1113		case GL_RG32F:
1114		case GL_RGB32F:
1115		case GL_RGBA32F:
1116			return false;
1117		default:
1118			UNIMPLEMENTED();
1119		}
1120
1121		return false;
1122	}
1123
1124	bool IsStencilRenderable(GLenum internalformat)
1125	{
1126		switch(internalformat)
1127		{
1128		case GL_DEPTH32F_STENCIL8:
1129		case GL_STENCIL_INDEX8:
1130		case GL_DEPTH24_STENCIL8_OES:
1131			return true;
1132		case GL_R8:
1133		case GL_R8UI:
1134		case GL_R8I:
1135		case GL_R16UI:
1136		case GL_R16I:
1137		case GL_R32UI:
1138		case GL_R32I:
1139		case GL_RG8:
1140		case GL_RG8UI:
1141		case GL_RG8I:
1142		case GL_RG16UI:
1143		case GL_RG16I:
1144		case GL_RG32UI:
1145		case GL_RG32I:
1146		case GL_SRGB8_ALPHA8:
1147		case GL_RGB10_A2:
1148		case GL_RGBA8UI:
1149		case GL_RGBA8I:
1150		case GL_RGB10_A2UI:
1151		case GL_RGBA16UI:
1152		case GL_RGBA16I:
1153		case GL_RGBA32I:
1154		case GL_RGBA32UI:
1155		case GL_RGBA4:
1156		case GL_RGB5_A1:
1157		case GL_RGB565:
1158		case GL_RGB8_OES:
1159		case GL_RGBA8_OES:
1160		case GL_RGB:
1161		case GL_RGBA:
1162		case GL_R16F:
1163		case GL_RG16F:
1164		case GL_R11F_G11F_B10F:
1165		case GL_RGB16F:
1166		case GL_RGBA16F:
1167		case GL_R32F:
1168		case GL_RG32F:
1169		case GL_RGB32F:
1170		case GL_RGBA32F:
1171		case GL_DEPTH_COMPONENT16:
1172		case GL_DEPTH_COMPONENT24:
1173		case GL_DEPTH_COMPONENT32_OES:
1174		case GL_DEPTH_COMPONENT32F:
1175			return false;
1176		default:
1177			UNIMPLEMENTED();
1178		}
1179
1180		return false;
1181	}
1182
1183	std::string ParseUniformName(const std::string &name, size_t *outSubscript)
1184	{
1185		// Strip any trailing array operator and retrieve the subscript
1186		size_t open = name.find_last_of('[');
1187		size_t close = name.find_last_of(']');
1188		bool hasIndex = (open != std::string::npos) && (close == name.length() - 1);
1189		if(!hasIndex)
1190		{
1191			if(outSubscript)
1192			{
1193				*outSubscript = GL_INVALID_INDEX;
1194			}
1195			return name;
1196		}
1197
1198		if(outSubscript)
1199		{
1200			int index = atoi(name.substr(open + 1).c_str());
1201			if(index >= 0)
1202			{
1203				*outSubscript = index;
1204			}
1205			else
1206			{
1207				*outSubscript = GL_INVALID_INDEX;
1208			}
1209		}
1210
1211		return name.substr(0, open);
1212	}
1213}
1214
1215namespace es2sw
1216{
1217	sw::DepthCompareMode ConvertDepthComparison(GLenum comparison)
1218	{
1219		switch(comparison)
1220		{
1221		case GL_NEVER:    return sw::DEPTH_NEVER;
1222		case GL_ALWAYS:   return sw::DEPTH_ALWAYS;
1223		case GL_LESS:     return sw::DEPTH_LESS;
1224		case GL_LEQUAL:   return sw::DEPTH_LESSEQUAL;
1225		case GL_EQUAL:    return sw::DEPTH_EQUAL;
1226		case GL_GREATER:  return sw::DEPTH_GREATER;
1227		case GL_GEQUAL:   return sw::DEPTH_GREATEREQUAL;
1228		case GL_NOTEQUAL: return sw::DEPTH_NOTEQUAL;
1229		default: UNREACHABLE(comparison);
1230		}
1231
1232		return sw::DEPTH_ALWAYS;
1233	}
1234
1235	sw::StencilCompareMode ConvertStencilComparison(GLenum comparison)
1236	{
1237		switch(comparison)
1238		{
1239		case GL_NEVER:    return sw::STENCIL_NEVER;
1240		case GL_ALWAYS:   return sw::STENCIL_ALWAYS;
1241		case GL_LESS:     return sw::STENCIL_LESS;
1242		case GL_LEQUAL:   return sw::STENCIL_LESSEQUAL;
1243		case GL_EQUAL:    return sw::STENCIL_EQUAL;
1244		case GL_GREATER:  return sw::STENCIL_GREATER;
1245		case GL_GEQUAL:   return sw::STENCIL_GREATEREQUAL;
1246		case GL_NOTEQUAL: return sw::STENCIL_NOTEQUAL;
1247		default: UNREACHABLE(comparison);
1248		}
1249
1250		return sw::STENCIL_ALWAYS;
1251	}
1252
1253	sw::Color<float> ConvertColor(es2::Color color)
1254	{
1255		return sw::Color<float>(color.red, color.green, color.blue, color.alpha);
1256	}
1257
1258	sw::BlendFactor ConvertBlendFunc(GLenum blend)
1259	{
1260		switch(blend)
1261		{
1262		case GL_ZERO:                     return sw::BLEND_ZERO;
1263		case GL_ONE:                      return sw::BLEND_ONE;
1264		case GL_SRC_COLOR:                return sw::BLEND_SOURCE;
1265		case GL_ONE_MINUS_SRC_COLOR:      return sw::BLEND_INVSOURCE;
1266		case GL_DST_COLOR:                return sw::BLEND_DEST;
1267		case GL_ONE_MINUS_DST_COLOR:      return sw::BLEND_INVDEST;
1268		case GL_SRC_ALPHA:                return sw::BLEND_SOURCEALPHA;
1269		case GL_ONE_MINUS_SRC_ALPHA:      return sw::BLEND_INVSOURCEALPHA;
1270		case GL_DST_ALPHA:                return sw::BLEND_DESTALPHA;
1271		case GL_ONE_MINUS_DST_ALPHA:      return sw::BLEND_INVDESTALPHA;
1272		case GL_CONSTANT_COLOR:           return sw::BLEND_CONSTANT;
1273		case GL_ONE_MINUS_CONSTANT_COLOR: return sw::BLEND_INVCONSTANT;
1274		case GL_CONSTANT_ALPHA:           return sw::BLEND_CONSTANTALPHA;
1275		case GL_ONE_MINUS_CONSTANT_ALPHA: return sw::BLEND_INVCONSTANTALPHA;
1276		case GL_SRC_ALPHA_SATURATE:       return sw::BLEND_SRCALPHASAT;
1277		default: UNREACHABLE(blend);
1278		}
1279
1280		return sw::BLEND_ZERO;
1281	}
1282
1283	sw::BlendOperation ConvertBlendOp(GLenum blendOp)
1284	{
1285		switch(blendOp)
1286		{
1287		case GL_FUNC_ADD:              return sw::BLENDOP_ADD;
1288		case GL_FUNC_SUBTRACT:         return sw::BLENDOP_SUB;
1289		case GL_FUNC_REVERSE_SUBTRACT: return sw::BLENDOP_INVSUB;
1290		case GL_MIN_EXT:               return sw::BLENDOP_MIN;
1291		case GL_MAX_EXT:               return sw::BLENDOP_MAX;
1292		default: UNREACHABLE(blendOp);
1293		}
1294
1295		return sw::BLENDOP_ADD;
1296	}
1297
1298	sw::StencilOperation ConvertStencilOp(GLenum stencilOp)
1299	{
1300		switch(stencilOp)
1301		{
1302		case GL_ZERO:      return sw::OPERATION_ZERO;
1303		case GL_KEEP:      return sw::OPERATION_KEEP;
1304		case GL_REPLACE:   return sw::OPERATION_REPLACE;
1305		case GL_INCR:      return sw::OPERATION_INCRSAT;
1306		case GL_DECR:      return sw::OPERATION_DECRSAT;
1307		case GL_INVERT:    return sw::OPERATION_INVERT;
1308		case GL_INCR_WRAP: return sw::OPERATION_INCR;
1309		case GL_DECR_WRAP: return sw::OPERATION_DECR;
1310		default: UNREACHABLE(stencilOp);
1311		}
1312
1313		return sw::OPERATION_KEEP;
1314	}
1315
1316	sw::AddressingMode ConvertTextureWrap(GLenum wrap)
1317	{
1318		switch(wrap)
1319		{
1320		case GL_REPEAT:            return sw::ADDRESSING_WRAP;
1321		case GL_CLAMP_TO_EDGE:     return sw::ADDRESSING_CLAMP;
1322		case GL_MIRRORED_REPEAT:   return sw::ADDRESSING_MIRROR;
1323		default: UNREACHABLE(wrap);
1324		}
1325
1326		return sw::ADDRESSING_WRAP;
1327	}
1328
1329	sw::SwizzleType ConvertSwizzleType(GLenum swizzleType)
1330	{
1331		switch(swizzleType)
1332		{
1333		case GL_RED:   return sw::SWIZZLE_RED;
1334		case GL_GREEN: return sw::SWIZZLE_GREEN;
1335		case GL_BLUE:  return sw::SWIZZLE_BLUE;
1336		case GL_ALPHA: return sw::SWIZZLE_ALPHA;
1337		case GL_ZERO:  return sw::SWIZZLE_ZERO;
1338		case GL_ONE:   return sw::SWIZZLE_ONE;
1339		default: UNREACHABLE(swizzleType);
1340		}
1341
1342		return sw::SWIZZLE_RED;
1343	};
1344
1345	sw::CullMode ConvertCullMode(GLenum cullFace, GLenum frontFace)
1346	{
1347		switch(cullFace)
1348		{
1349		case GL_FRONT:
1350			return (frontFace == GL_CCW ? sw::CULL_CLOCKWISE : sw::CULL_COUNTERCLOCKWISE);
1351		case GL_BACK:
1352			return (frontFace == GL_CCW ? sw::CULL_COUNTERCLOCKWISE : sw::CULL_CLOCKWISE);
1353		case GL_FRONT_AND_BACK:
1354			return sw::CULL_NONE;   // culling will be handled during draw
1355		default: UNREACHABLE(cullFace);
1356		}
1357
1358		return sw::CULL_COUNTERCLOCKWISE;
1359	}
1360
1361	unsigned int ConvertColorMask(bool red, bool green, bool blue, bool alpha)
1362	{
1363		return (red   ? 0x00000001 : 0) |
1364			   (green ? 0x00000002 : 0) |
1365			   (blue  ? 0x00000004 : 0) |
1366			   (alpha ? 0x00000008 : 0);
1367	}
1368
1369	sw::MipmapType ConvertMipMapFilter(GLenum minFilter)
1370	{
1371		switch(minFilter)
1372		{
1373		case GL_NEAREST:
1374		case GL_LINEAR:
1375			return sw::MIPMAP_NONE;
1376			break;
1377		case GL_NEAREST_MIPMAP_NEAREST:
1378		case GL_LINEAR_MIPMAP_NEAREST:
1379			return sw::MIPMAP_POINT;
1380			break;
1381		case GL_NEAREST_MIPMAP_LINEAR:
1382		case GL_LINEAR_MIPMAP_LINEAR:
1383			return sw::MIPMAP_LINEAR;
1384			break;
1385		default:
1386			UNREACHABLE(minFilter);
1387			return sw::MIPMAP_NONE;
1388		}
1389	}
1390
1391	sw::FilterType ConvertTextureFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy)
1392	{
1393		if(maxAnisotropy > 1.0f)
1394		{
1395			return sw::FILTER_ANISOTROPIC;
1396		}
1397
1398		sw::FilterType magFilterType = sw::FILTER_POINT;
1399		switch(magFilter)
1400		{
1401		case GL_NEAREST: magFilterType = sw::FILTER_POINT;  break;
1402		case GL_LINEAR:  magFilterType = sw::FILTER_LINEAR; break;
1403		default: UNREACHABLE(magFilter);
1404		}
1405
1406		switch(minFilter)
1407		{
1408		case GL_NEAREST:
1409		case GL_NEAREST_MIPMAP_NEAREST:
1410		case GL_NEAREST_MIPMAP_LINEAR:
1411			return (magFilterType == sw::FILTER_POINT) ? sw::FILTER_POINT : sw::FILTER_MIN_POINT_MAG_LINEAR;
1412		case GL_LINEAR:
1413		case GL_LINEAR_MIPMAP_NEAREST:
1414		case GL_LINEAR_MIPMAP_LINEAR:
1415			return (magFilterType == sw::FILTER_POINT) ? sw::FILTER_MIN_LINEAR_MAG_POINT : sw::FILTER_LINEAR;
1416		default:
1417			UNREACHABLE(minFilter);
1418			return (magFilterType == sw::FILTER_POINT) ? sw::FILTER_POINT : sw::FILTER_MIN_POINT_MAG_LINEAR;
1419		}
1420	}
1421
1422	bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount, GLenum elementType, sw::DrawType &drawType, int &primitiveCount, int &verticesPerPrimitive)
1423	{
1424		switch(primitiveType)
1425		{
1426		case GL_POINTS:
1427			drawType = sw::DRAW_POINTLIST;
1428			primitiveCount = elementCount;
1429			verticesPerPrimitive = 1;
1430			break;
1431		case GL_LINES:
1432			drawType = sw::DRAW_LINELIST;
1433			primitiveCount = elementCount / 2;
1434			verticesPerPrimitive = 2;
1435			break;
1436		case GL_LINE_LOOP:
1437			drawType = sw::DRAW_LINELOOP;
1438			primitiveCount = elementCount;
1439			verticesPerPrimitive = 2;
1440			break;
1441		case GL_LINE_STRIP:
1442			drawType = sw::DRAW_LINESTRIP;
1443			primitiveCount = elementCount - 1;
1444			verticesPerPrimitive = 2;
1445			break;
1446		case GL_TRIANGLES:
1447			drawType = sw::DRAW_TRIANGLELIST;
1448			primitiveCount = elementCount / 3;
1449			verticesPerPrimitive = 3;
1450			break;
1451		case GL_TRIANGLE_STRIP:
1452			drawType = sw::DRAW_TRIANGLESTRIP;
1453			primitiveCount = elementCount - 2;
1454			verticesPerPrimitive = 3;
1455			break;
1456		case GL_TRIANGLE_FAN:
1457			drawType = sw::DRAW_TRIANGLEFAN;
1458			primitiveCount = elementCount - 2;
1459			verticesPerPrimitive = 3;
1460			break;
1461		default:
1462			return false;
1463		}
1464
1465		sw::DrawType elementSize;
1466		switch(elementType)
1467		{
1468		case GL_NONE:           elementSize = sw::DRAW_NONINDEXED; break;
1469		case GL_UNSIGNED_BYTE:  elementSize = sw::DRAW_INDEXED8;   break;
1470		case GL_UNSIGNED_SHORT: elementSize = sw::DRAW_INDEXED16;  break;
1471		case GL_UNSIGNED_INT:   elementSize = sw::DRAW_INDEXED32;  break;
1472		default: return false;
1473		}
1474
1475		drawType = sw::DrawType(drawType | elementSize);
1476
1477		return true;
1478	}
1479
1480	sw::Format ConvertRenderbufferFormat(GLenum format)
1481	{
1482		switch(format)
1483		{
1484		case GL_RGBA4:
1485		case GL_RGB5_A1:
1486		case GL_RGBA8_OES:            return sw::FORMAT_A8B8G8R8;
1487		case GL_RGB565:               return sw::FORMAT_R5G6B5;
1488		case GL_RGB8_OES:             return sw::FORMAT_X8B8G8R8;
1489		case GL_DEPTH_COMPONENT16:
1490		case GL_STENCIL_INDEX8:
1491		case GL_DEPTH24_STENCIL8_OES: return sw::FORMAT_D24S8;
1492		case GL_DEPTH_COMPONENT32_OES:return sw::FORMAT_D32;
1493		case GL_R8:                   return sw::FORMAT_R8;
1494		case GL_RG8:                  return sw::FORMAT_G8R8;
1495		case GL_R8I:                  return sw::FORMAT_R8I;
1496		case GL_RG8I:                 return sw::FORMAT_G8R8I;
1497		case GL_RGB8I:                return sw::FORMAT_X8B8G8R8I;
1498		case GL_RGBA8I:               return sw::FORMAT_A8B8G8R8I;
1499		case GL_R8UI:                 return sw::FORMAT_R8UI;
1500		case GL_RG8UI:                return sw::FORMAT_G8R8UI;
1501		case GL_RGB8UI:               return sw::FORMAT_X8B8G8R8UI;
1502		case GL_RGBA8UI:              return sw::FORMAT_A8B8G8R8UI;
1503		case GL_R16I:                 return sw::FORMAT_R16I;
1504		case GL_RG16I:                return sw::FORMAT_G16R16I;
1505		case GL_RGB16I:               return sw::FORMAT_X16B16G16R16I;
1506		case GL_RGBA16I:              return sw::FORMAT_A16B16G16R16I;
1507		case GL_R16UI:                return sw::FORMAT_R16UI;
1508		case GL_RG16UI:               return sw::FORMAT_G16R16UI;
1509		case GL_RGB16UI:              return sw::FORMAT_X16B16G16R16UI;
1510		case GL_RGB10_A2UI:
1511		case GL_RGBA16UI:             return sw::FORMAT_A16B16G16R16UI;
1512		case GL_R32I:                 return sw::FORMAT_R32I;
1513		case GL_RG32I:                return sw::FORMAT_G32R32I;
1514		case GL_RGB32I:               return sw::FORMAT_X32B32G32R32I;
1515		case GL_RGBA32I:              return sw::FORMAT_A32B32G32R32I;
1516		case GL_R32UI:                return sw::FORMAT_R32UI;
1517		case GL_RG32UI:               return sw::FORMAT_G32R32UI;
1518		case GL_RGB32UI:              return sw::FORMAT_X32B32G32R32UI;
1519		case GL_RGBA32UI:             return sw::FORMAT_A32B32G32R32UI;
1520		case GL_R16F:                 return sw::FORMAT_R16F;
1521		case GL_RG16F:                return sw::FORMAT_G16R16F;
1522		case GL_R11F_G11F_B10F:
1523		case GL_RGB16F:               return sw::FORMAT_B16G16R16F;
1524		case GL_RGBA16F:              return sw::FORMAT_A16B16G16R16F;
1525		case GL_R32F:                 return sw::FORMAT_R32F;
1526		case GL_RG32F:                return sw::FORMAT_G32R32F;
1527		case GL_RGB32F:               return sw::FORMAT_B32G32R32F;
1528		case GL_RGBA32F:              return sw::FORMAT_A32B32G32R32F;
1529		case GL_RGB10_A2:             return sw::FORMAT_A2B10G10R10;
1530		case GL_SRGB8:                return sw::FORMAT_SRGB8_X8;
1531		case GL_SRGB8_ALPHA8:         return sw::FORMAT_SRGB8_A8;
1532		default: UNREACHABLE(format); return sw::FORMAT_NULL;
1533		}
1534	}
1535}
1536
1537namespace sw2es
1538{
1539	unsigned int GetStencilSize(sw::Format stencilFormat)
1540	{
1541		switch(stencilFormat)
1542		{
1543		case sw::FORMAT_D24FS8:
1544		case sw::FORMAT_D24S8:
1545		case sw::FORMAT_D32FS8_TEXTURE:
1546		case sw::FORMAT_D32FS8_SHADOW:
1547		case sw::FORMAT_S8:
1548			return 8;
1549	//	case sw::FORMAT_D24X4S4:
1550	//		return 4;
1551	//	case sw::FORMAT_D15S1:
1552	//		return 1;
1553	//	case sw::FORMAT_D16_LOCKABLE:
1554		case sw::FORMAT_D32:
1555		case sw::FORMAT_D24X8:
1556		case sw::FORMAT_D32F_LOCKABLE:
1557		case sw::FORMAT_D16:
1558			return 0;
1559	//	case sw::FORMAT_D32_LOCKABLE:  return 0;
1560	//	case sw::FORMAT_S8_LOCKABLE:   return 8;
1561		default:
1562			return 0;
1563		}
1564	}
1565
1566	unsigned int GetAlphaSize(sw::Format colorFormat)
1567	{
1568		switch(colorFormat)
1569		{
1570		case sw::FORMAT_A16B16G16R16F:
1571		case sw::FORMAT_A16B16G16R16I:
1572		case sw::FORMAT_A16B16G16R16UI:
1573			return 16;
1574		case sw::FORMAT_A32B32G32R32F:
1575		case sw::FORMAT_A32B32G32R32I:
1576		case sw::FORMAT_A32B32G32R32UI:
1577			return 32;
1578		case sw::FORMAT_A2R10G10B10:
1579			return 2;
1580		case sw::FORMAT_A8R8G8B8:
1581		case sw::FORMAT_A8B8G8R8:
1582		case sw::FORMAT_SRGB8_A8:
1583		case sw::FORMAT_A8B8G8R8I:
1584		case sw::FORMAT_A8B8G8R8UI:
1585		case sw::FORMAT_A8B8G8R8I_SNORM:
1586			return 8;
1587		case sw::FORMAT_A2B10G10R10:
1588			return 2;
1589		case sw::FORMAT_A1R5G5B5:
1590			return 1;
1591		case sw::FORMAT_X8R8G8B8:
1592		case sw::FORMAT_X8B8G8R8:
1593		case sw::FORMAT_SRGB8_X8:
1594		case sw::FORMAT_R5G6B5:
1595			return 0;
1596		default:
1597			return 0;
1598		}
1599	}
1600
1601	unsigned int GetRedSize(sw::Format colorFormat)
1602	{
1603		switch(colorFormat)
1604		{
1605		case sw::FORMAT_R16F:
1606		case sw::FORMAT_G16R16F:
1607		case sw::FORMAT_B16G16R16F:
1608		case sw::FORMAT_A16B16G16R16F:
1609		case sw::FORMAT_R16I:
1610		case sw::FORMAT_G16R16I:
1611		case sw::FORMAT_X16B16G16R16I:
1612		case sw::FORMAT_A16B16G16R16I:
1613		case sw::FORMAT_R16UI:
1614		case sw::FORMAT_G16R16UI:
1615		case sw::FORMAT_X16B16G16R16UI:
1616		case sw::FORMAT_A16B16G16R16UI:
1617			return 16;
1618		case sw::FORMAT_R32F:
1619		case sw::FORMAT_G32R32F:
1620		case sw::FORMAT_B32G32R32F:
1621		case sw::FORMAT_X32B32G32R32F:
1622		case sw::FORMAT_A32B32G32R32F:
1623		case sw::FORMAT_R32I:
1624		case sw::FORMAT_G32R32I:
1625		case sw::FORMAT_X32B32G32R32I:
1626		case sw::FORMAT_A32B32G32R32I:
1627		case sw::FORMAT_R32UI:
1628		case sw::FORMAT_G32R32UI:
1629		case sw::FORMAT_X32B32G32R32UI:
1630		case sw::FORMAT_A32B32G32R32UI:
1631			return 32;
1632		case sw::FORMAT_A2B10G10R10:
1633		case sw::FORMAT_A2R10G10B10:
1634			return 10;
1635		case sw::FORMAT_A8R8G8B8:
1636		case sw::FORMAT_A8B8G8R8:
1637		case sw::FORMAT_X8R8G8B8:
1638		case sw::FORMAT_X8B8G8R8:
1639		case sw::FORMAT_SRGB8_A8:
1640		case sw::FORMAT_SRGB8_X8:
1641		case sw::FORMAT_R8:
1642		case sw::FORMAT_G8R8:
1643		case sw::FORMAT_R8I:
1644		case sw::FORMAT_G8R8I:
1645		case sw::FORMAT_X8B8G8R8I:
1646		case sw::FORMAT_A8B8G8R8I:
1647		case sw::FORMAT_R8UI:
1648		case sw::FORMAT_G8R8UI:
1649		case sw::FORMAT_X8B8G8R8UI:
1650		case sw::FORMAT_A8B8G8R8UI:
1651		case sw::FORMAT_R8I_SNORM:
1652		case sw::FORMAT_G8R8I_SNORM:
1653		case sw::FORMAT_X8B8G8R8I_SNORM:
1654		case sw::FORMAT_A8B8G8R8I_SNORM:
1655			return 8;
1656		case sw::FORMAT_A1R5G5B5:
1657		case sw::FORMAT_R5G6B5:
1658			return 5;
1659		default:
1660			return 0;
1661		}
1662	}
1663
1664	unsigned int GetGreenSize(sw::Format colorFormat)
1665	{
1666		switch(colorFormat)
1667		{
1668		case sw::FORMAT_G16R16F:
1669		case sw::FORMAT_B16G16R16F:
1670		case sw::FORMAT_A16B16G16R16F:
1671		case sw::FORMAT_G16R16I:
1672		case sw::FORMAT_X16B16G16R16I:
1673		case sw::FORMAT_A16B16G16R16I:
1674		case sw::FORMAT_G16R16UI:
1675		case sw::FORMAT_X16B16G16R16UI:
1676		case sw::FORMAT_A16B16G16R16UI:
1677			return 16;
1678		case sw::FORMAT_G32R32F:
1679		case sw::FORMAT_B32G32R32F:
1680		case sw::FORMAT_X32B32G32R32F:
1681		case sw::FORMAT_A32B32G32R32F:
1682		case sw::FORMAT_G32R32I:
1683		case sw::FORMAT_X32B32G32R32I:
1684		case sw::FORMAT_A32B32G32R32I:
1685		case sw::FORMAT_G32R32UI:
1686		case sw::FORMAT_X32B32G32R32UI:
1687		case sw::FORMAT_A32B32G32R32UI:
1688			return 32;
1689		case sw::FORMAT_A2B10G10R10:
1690		case sw::FORMAT_A2R10G10B10:
1691			return 10;
1692		case sw::FORMAT_A8R8G8B8:
1693		case sw::FORMAT_A8B8G8R8:
1694		case sw::FORMAT_X8R8G8B8:
1695		case sw::FORMAT_X8B8G8R8:
1696		case sw::FORMAT_SRGB8_A8:
1697		case sw::FORMAT_SRGB8_X8:
1698		case sw::FORMAT_G8R8:
1699		case sw::FORMAT_G8R8I:
1700		case sw::FORMAT_X8B8G8R8I:
1701		case sw::FORMAT_A8B8G8R8I:
1702		case sw::FORMAT_G8R8UI:
1703		case sw::FORMAT_X8B8G8R8UI:
1704		case sw::FORMAT_A8B8G8R8UI:
1705		case sw::FORMAT_G8R8I_SNORM:
1706		case sw::FORMAT_X8B8G8R8I_SNORM:
1707		case sw::FORMAT_A8B8G8R8I_SNORM:
1708			return 8;
1709		case sw::FORMAT_A1R5G5B5:
1710			return 5;
1711		case sw::FORMAT_R5G6B5:
1712			return 6;
1713		default:
1714			return 0;
1715		}
1716	}
1717
1718	unsigned int GetBlueSize(sw::Format colorFormat)
1719	{
1720		switch(colorFormat)
1721		{
1722		case sw::FORMAT_B16G16R16F:
1723		case sw::FORMAT_A16B16G16R16F:
1724		case sw::FORMAT_X16B16G16R16I:
1725		case sw::FORMAT_A16B16G16R16I:
1726		case sw::FORMAT_X16B16G16R16UI:
1727		case sw::FORMAT_A16B16G16R16UI:
1728			return 16;
1729		case sw::FORMAT_B32G32R32F:
1730		case sw::FORMAT_X32B32G32R32F:
1731		case sw::FORMAT_A32B32G32R32F:
1732		case sw::FORMAT_X32B32G32R32I:
1733		case sw::FORMAT_A32B32G32R32I:
1734		case sw::FORMAT_X32B32G32R32UI:
1735		case sw::FORMAT_A32B32G32R32UI:
1736			return 32;
1737		case sw::FORMAT_A2B10G10R10:
1738		case sw::FORMAT_A2R10G10B10:
1739			return 10;
1740		case sw::FORMAT_A8R8G8B8:
1741		case sw::FORMAT_A8B8G8R8:
1742		case sw::FORMAT_X8R8G8B8:
1743		case sw::FORMAT_X8B8G8R8:
1744		case sw::FORMAT_SRGB8_A8:
1745		case sw::FORMAT_SRGB8_X8:
1746		case sw::FORMAT_X8B8G8R8I:
1747		case sw::FORMAT_A8B8G8R8I:
1748		case sw::FORMAT_X8B8G8R8UI:
1749		case sw::FORMAT_A8B8G8R8UI:
1750		case sw::FORMAT_X8B8G8R8I_SNORM:
1751		case sw::FORMAT_A8B8G8R8I_SNORM:
1752			return 8;
1753		case sw::FORMAT_A1R5G5B5:
1754		case sw::FORMAT_R5G6B5:
1755			return 5;
1756		default:
1757			return 0;
1758		}
1759	}
1760
1761	unsigned int GetDepthSize(sw::Format depthFormat)
1762	{
1763		switch(depthFormat)
1764		{
1765	//	case sw::FORMAT_D16_LOCKABLE:   return 16;
1766		case sw::FORMAT_D32:            return 32;
1767	//	case sw::FORMAT_D15S1:          return 15;
1768		case sw::FORMAT_D24S8:          return 24;
1769		case sw::FORMAT_D24X8:          return 24;
1770	//	case sw::FORMAT_D24X4S4:        return 24;
1771		case sw::FORMAT_DF16S8:
1772		case sw::FORMAT_D16:            return 16;
1773		case sw::FORMAT_D32F:
1774		case sw::FORMAT_D32F_COMPLEMENTARY:
1775		case sw::FORMAT_D32F_LOCKABLE:  return 32;
1776		case sw::FORMAT_DF24S8:
1777		case sw::FORMAT_D24FS8:         return 24;
1778	//	case sw::FORMAT_D32_LOCKABLE:   return 32;
1779	//	case sw::FORMAT_S8_LOCKABLE:    return 0;
1780		case sw::FORMAT_D32FS8_SHADOW:
1781		case sw::FORMAT_D32FS8_TEXTURE: return 32;
1782		default:                        return 0;
1783		}
1784	}
1785
1786	GLenum GetComponentType(sw::Format format, GLenum attachment)
1787	{
1788		// Can be one of GL_FLOAT, GL_INT, GL_UNSIGNED_INT, GL_SIGNED_NORMALIZED, or GL_UNSIGNED_NORMALIZED
1789		switch(attachment)
1790		{
1791		case GL_COLOR_ATTACHMENT0:
1792		case GL_COLOR_ATTACHMENT1:
1793		case GL_COLOR_ATTACHMENT2:
1794		case GL_COLOR_ATTACHMENT3:
1795		case GL_COLOR_ATTACHMENT4:
1796		case GL_COLOR_ATTACHMENT5:
1797		case GL_COLOR_ATTACHMENT6:
1798		case GL_COLOR_ATTACHMENT7:
1799		case GL_COLOR_ATTACHMENT8:
1800		case GL_COLOR_ATTACHMENT9:
1801		case GL_COLOR_ATTACHMENT10:
1802		case GL_COLOR_ATTACHMENT11:
1803		case GL_COLOR_ATTACHMENT12:
1804		case GL_COLOR_ATTACHMENT13:
1805		case GL_COLOR_ATTACHMENT14:
1806		case GL_COLOR_ATTACHMENT15:
1807		case GL_COLOR_ATTACHMENT16:
1808		case GL_COLOR_ATTACHMENT17:
1809		case GL_COLOR_ATTACHMENT18:
1810		case GL_COLOR_ATTACHMENT19:
1811		case GL_COLOR_ATTACHMENT20:
1812		case GL_COLOR_ATTACHMENT21:
1813		case GL_COLOR_ATTACHMENT22:
1814		case GL_COLOR_ATTACHMENT23:
1815		case GL_COLOR_ATTACHMENT24:
1816		case GL_COLOR_ATTACHMENT25:
1817		case GL_COLOR_ATTACHMENT26:
1818		case GL_COLOR_ATTACHMENT27:
1819		case GL_COLOR_ATTACHMENT28:
1820		case GL_COLOR_ATTACHMENT29:
1821		case GL_COLOR_ATTACHMENT30:
1822		case GL_COLOR_ATTACHMENT31:
1823			switch(format)
1824			{
1825			case sw::FORMAT_R8I:
1826			case sw::FORMAT_G8R8I:
1827			case sw::FORMAT_X8B8G8R8I:
1828			case sw::FORMAT_A8B8G8R8I:
1829			case sw::FORMAT_R16I:
1830			case sw::FORMAT_G16R16I:
1831			case sw::FORMAT_X16B16G16R16I:
1832			case sw::FORMAT_A16B16G16R16I:
1833			case sw::FORMAT_R32I:
1834			case sw::FORMAT_G32R32I:
1835			case sw::FORMAT_X32B32G32R32I:
1836			case sw::FORMAT_A32B32G32R32I:
1837				return GL_INT;
1838			case sw::FORMAT_R8UI:
1839			case sw::FORMAT_G8R8UI:
1840			case sw::FORMAT_X8B8G8R8UI:
1841			case sw::FORMAT_A8B8G8R8UI:
1842			case sw::FORMAT_R16UI:
1843			case sw::FORMAT_G16R16UI:
1844			case sw::FORMAT_X16B16G16R16UI:
1845			case sw::FORMAT_A16B16G16R16UI:
1846			case sw::FORMAT_R32UI:
1847			case sw::FORMAT_G32R32UI:
1848			case sw::FORMAT_X32B32G32R32UI:
1849			case sw::FORMAT_A32B32G32R32UI:
1850				return GL_UNSIGNED_INT;
1851			case sw::FORMAT_R16F:
1852			case sw::FORMAT_G16R16F:
1853			case sw::FORMAT_B16G16R16F:
1854			case sw::FORMAT_A16B16G16R16F:
1855			case sw::FORMAT_R32F:
1856			case sw::FORMAT_G32R32F:
1857			case sw::FORMAT_B32G32R32F:
1858			case sw::FORMAT_X32B32G32R32F:
1859			case sw::FORMAT_A32B32G32R32F:
1860				return GL_FLOAT;
1861			case sw::FORMAT_R8:
1862			case sw::FORMAT_G8R8:
1863			case sw::FORMAT_A2B10G10R10:
1864			case sw::FORMAT_A2R10G10B10:
1865			case sw::FORMAT_A8R8G8B8:
1866			case sw::FORMAT_A8B8G8R8:
1867			case sw::FORMAT_X8R8G8B8:
1868			case sw::FORMAT_X8B8G8R8:
1869			case sw::FORMAT_SRGB8_A8:
1870			case sw::FORMAT_SRGB8_X8:
1871			case sw::FORMAT_A1R5G5B5:
1872			case sw::FORMAT_R5G6B5:
1873				return GL_UNSIGNED_NORMALIZED;
1874			case sw::FORMAT_R8I_SNORM:
1875			case sw::FORMAT_X8B8G8R8I_SNORM:
1876			case sw::FORMAT_A8B8G8R8I_SNORM:
1877			case sw::FORMAT_G8R8I_SNORM:
1878				return GL_SIGNED_NORMALIZED;
1879			default:
1880				UNREACHABLE(format);
1881				return 0;
1882			}
1883		case GL_DEPTH_ATTACHMENT:
1884		case GL_STENCIL_ATTACHMENT:
1885			// Only color buffers may have integer components.
1886			return GL_FLOAT;
1887		default:
1888			UNREACHABLE(attachment);
1889			return 0;
1890		}
1891	}
1892
1893	GLenum ConvertBackBufferFormat(sw::Format format)
1894	{
1895		switch(format)
1896		{
1897		case sw::FORMAT_A4R4G4B4: return GL_RGBA4;
1898		case sw::FORMAT_A8R8G8B8: return GL_RGBA8_OES;
1899		case sw::FORMAT_A8B8G8R8: return GL_RGBA8_OES;
1900		case sw::FORMAT_A1R5G5B5: return GL_RGB5_A1;
1901		case sw::FORMAT_R5G6B5:   return GL_RGB565;
1902		case sw::FORMAT_X8R8G8B8: return GL_RGB8_OES;
1903		case sw::FORMAT_X8B8G8R8: return GL_RGB8_OES;
1904		case sw::FORMAT_SRGB8_A8: return GL_RGBA8_OES;
1905		case sw::FORMAT_SRGB8_X8: return GL_RGB8_OES;
1906		default:
1907			UNREACHABLE(format);
1908		}
1909
1910		return GL_RGBA4;
1911	}
1912
1913	GLenum ConvertDepthStencilFormat(sw::Format format)
1914	{
1915		switch(format)
1916		{
1917		case sw::FORMAT_D16:
1918		case sw::FORMAT_D24X8:
1919		case sw::FORMAT_D32:
1920			return GL_DEPTH_COMPONENT16;
1921		case sw::FORMAT_D24S8:
1922			return GL_DEPTH24_STENCIL8_OES;
1923		case sw::FORMAT_D32F:
1924		case sw::FORMAT_D32F_COMPLEMENTARY:
1925		case sw::FORMAT_D32F_LOCKABLE:
1926			return GL_DEPTH_COMPONENT32F;
1927		case sw::FORMAT_D32FS8_TEXTURE:
1928		case sw::FORMAT_D32FS8_SHADOW:
1929			return GL_DEPTH32F_STENCIL8;
1930		case sw::FORMAT_S8:
1931			return GL_STENCIL_INDEX8;
1932		default:
1933			UNREACHABLE(format);
1934		}
1935
1936		return GL_DEPTH24_STENCIL8_OES;
1937	}
1938}
1939