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 
28 namespace 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.
InsertFormatMapping(FormatMap * map,GLenum format,GLenum type,GLenum internalFormat)39 	static inline void InsertFormatMapping(FormatMap *map, GLenum format, GLenum type, GLenum internalFormat)
40 	{
41 		map->insert(FormatPair(FormatTypePair(format, type), internalFormat));
42 	}
43 
BuildFormatMap()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 
GetSizedInternalFormat(GLenum internalFormat,GLenum type)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 
UniformComponentCount(GLenum type)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 
UniformComponentType(GLenum type)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 
UniformTypeSize(GLenum type)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 
IsSamplerUniform(GLenum type)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 
VariableRowCount(GLenum type)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 
VariableColumnCount(GLenum type)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 
VariableRegisterCount(GLenum type)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 
VariableRegisterSize(GLenum type)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 
AllocateFirstFreeBits(unsigned int * bits,unsigned int allocationSize,unsigned int bitsSize)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 
IsCompressed(GLenum format,GLint clientVersion)467 	bool IsCompressed(GLenum format, GLint clientVersion)
468 	{
469 		return ValidateCompressedFormat(format, clientVersion, true) == GL_NONE;
470 	}
471 
ValidateCompressedFormat(GLenum format,GLint clientVersion,bool expectCompressedFormats)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 
ValidateSubImageParams(bool compressed,GLsizei width,GLsizei height,GLint xoffset,GLint yoffset,GLenum target,GLint level,GLenum sizedInternalFormat,Texture * texture)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 
ValidateSubImageParams(bool compressed,GLsizei width,GLsizei height,GLsizei depth,GLint xoffset,GLint yoffset,GLint zoffset,GLenum target,GLint level,GLenum sizedInternalFormat,Texture * texture)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 
ValidReadPixelsFormatType(GLenum internalFormat,GLenum internalType,GLenum format,GLenum type,GLint clientVersion)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 
IsDepthTexture(GLenum format)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 
IsStencilTexture(GLenum format)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 
IsCubemapTextureTarget(GLenum target)697 	bool IsCubemapTextureTarget(GLenum target)
698 	{
699 		return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
700 	}
701 
CubeFaceIndex(GLenum cubeFace)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 
IsTextureTarget(GLenum target)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 
ValidateTextureFormatType(GLenum format,GLenum type,GLint internalformat,GLint clientVersion)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 
IsColorRenderable(GLenum internalformat,GLint clientVersion)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 
IsDepthRenderable(GLenum internalformat)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 
IsStencilRenderable(GLenum internalformat)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 
ParseUniformName(const std::string & name,size_t * outSubscript)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 
1215 namespace es2sw
1216 {
ConvertDepthComparison(GLenum comparison)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 
ConvertStencilComparison(GLenum comparison)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 
ConvertColor(es2::Color color)1253 	sw::Color<float> ConvertColor(es2::Color color)
1254 	{
1255 		return sw::Color<float>(color.red, color.green, color.blue, color.alpha);
1256 	}
1257 
ConvertBlendFunc(GLenum blend)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 
ConvertBlendOp(GLenum blendOp)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 
ConvertStencilOp(GLenum stencilOp)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 
ConvertTextureWrap(GLenum wrap)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 
ConvertSwizzleType(GLenum swizzleType)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 
ConvertCullMode(GLenum cullFace,GLenum frontFace)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 
ConvertColorMask(bool red,bool green,bool blue,bool alpha)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 
ConvertMipMapFilter(GLenum minFilter)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 
ConvertTextureFilter(GLenum minFilter,GLenum magFilter,float maxAnisotropy)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 
ConvertPrimitiveType(GLenum primitiveType,GLsizei elementCount,GLenum elementType,sw::DrawType & drawType,int & primitiveCount,int & verticesPerPrimitive)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 
ConvertRenderbufferFormat(GLenum format)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 
1537 namespace sw2es
1538 {
GetStencilSize(sw::Format stencilFormat)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 
GetAlphaSize(sw::Format colorFormat)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 
GetRedSize(sw::Format colorFormat)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 
GetGreenSize(sw::Format colorFormat)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 
GetBlueSize(sw::Format colorFormat)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 
GetDepthSize(sw::Format depthFormat)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 
GetComponentType(sw::Format format,GLenum attachment)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 
ConvertBackBufferFormat(sw::Format format)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 
ConvertDepthStencilFormat(sw::Format format)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