1/*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES Utilities
3 * ------------------------------------------------
4 *
5 * Copyright 2014 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Shader utilities.
22 *//*--------------------------------------------------------------------*/
23
24#include "gluShaderUtil.hpp"
25#include "glwEnums.hpp"
26#include "deArrayUtil.hpp"
27
28namespace glu
29{
30
31// ShadingLanguageVersion
32
33const char* getGLSLVersionName (GLSLVersion version)
34{
35	static const char* s_names[] =
36	{
37		"GLSL ES 1.0",
38		"GLSL ES 3.0",
39		"GLSL ES 3.1",
40		"GLSL 1.3",
41		"GLSL 1.4",
42		"GLSL 1.5",
43		"GLSL 3.3",
44		"GLSL 4.0",
45		"GLSL 4.1",
46		"GLSL 4.2",
47		"GLSL 4.3",
48		"GLSL 4.4",
49	};
50
51	return de::getSizedArrayElement<GLSL_VERSION_LAST>(s_names, version);
52}
53
54const char* getGLSLVersionDeclaration (GLSLVersion version)
55{
56	static const char* s_decl[] =
57	{
58		"#version 100",
59		"#version 300 es",
60		"#version 310 es",
61		"#version 130",
62		"#version 140",
63		"#version 150",
64		"#version 330",
65		"#version 400",
66		"#version 410",
67		"#version 420",
68		"#version 430",
69		"#version 440",
70	};
71
72	return de::getSizedArrayElement<GLSL_VERSION_LAST>(s_decl, version);
73}
74
75bool glslVersionUsesInOutQualifiers (GLSLVersion version)
76{
77	return de::inRange<int>(version, GLSL_VERSION_300_ES, GLSL_VERSION_310_ES) || de::inRange<int>(version, GLSL_VERSION_330, GLSL_VERSION_430);
78}
79
80bool glslVersionIsES (GLSLVersion version)
81{
82	DE_ASSERT(version != GLSL_VERSION_LAST);
83
84	if (version == GLSL_VERSION_100_ES	||
85		version == GLSL_VERSION_300_ES	||
86		version == GLSL_VERSION_310_ES)
87		return true;
88	else
89		return false;
90}
91
92// \todo [2014-10-06 pyry] Export this.
93static ApiType getMinAPIForGLSLVersion (GLSLVersion version)
94{
95	static const ApiType s_minApi[] =
96	{
97		ApiType::es(2,0),
98		ApiType::es(3,0),
99		ApiType::es(3,1),
100		ApiType::core(3,0),
101		ApiType::core(3,1),
102		ApiType::core(3,2),
103		ApiType::core(3,3),
104		ApiType::core(4,0),
105		ApiType::core(4,1),
106		ApiType::core(4,2),
107		ApiType::core(4,3),
108		ApiType::core(4,4),
109	};
110
111	return de::getSizedArrayElement<GLSL_VERSION_LAST>(s_minApi, version);
112}
113
114bool isGLSLVersionSupported (ContextType type, GLSLVersion version)
115{
116	return contextSupports(type, getMinAPIForGLSLVersion(version));
117}
118
119GLSLVersion getContextTypeGLSLVersion (ContextType type)
120{
121	// \note From newer to older
122	for (int version = GLSL_VERSION_LAST-1; version >= 0; version--)
123	{
124		if (isGLSLVersionSupported(type, GLSLVersion(version)))
125			return GLSLVersion(version);
126	}
127
128	DE_ASSERT(false);
129	return GLSL_VERSION_LAST;
130}
131
132// ShaderType
133
134const char* getShaderTypeName (ShaderType shaderType)
135{
136	const char* s_names[] =
137	{
138		"vertex",
139		"fragment",
140		"geometry",
141		"tess_control",
142		"tess_eval",
143		"compute",
144	};
145
146	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_names) == SHADERTYPE_LAST);
147	DE_ASSERT(deInBounds32((int)shaderType, 0, SHADERTYPE_LAST));
148	return s_names[(int)shaderType];
149}
150
151// Precision
152
153const char* getPrecisionName (Precision precision)
154{
155	const char* s_names[] =
156	{
157		"lowp",
158		"mediump",
159		"highp"
160	};
161
162	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_names) == PRECISION_LAST);
163	DE_ASSERT(deInBounds32((int)precision, 0, PRECISION_LAST));
164	return s_names[(int)precision];
165}
166
167// DataType
168
169const char* getDataTypeName (DataType dataType)
170{
171	const char* s_names[] =
172	{
173		"invalid",
174		"float",
175		"vec2",
176		"vec3",
177		"vec4",
178		"mat2",
179		"mat2x3",
180		"mat2x4",
181		"mat3x2",
182		"mat3",
183		"mat3x4",
184		"mat4x2",
185		"mat4x3",
186		"mat4",
187		"int",
188		"ivec2",
189		"ivec3",
190		"ivec4",
191		"uint",
192		"uvec2",
193		"uvec3",
194		"uvec4",
195		"bool",
196		"bvec2",
197		"bvec3",
198		"bvec4",
199		"sampler1D",
200		"sampler2D",
201		"samplerCube",
202		"sampler2DArray",
203		"sampler3D",
204		"samplerCubeArray",
205		"sampler1DShadow",
206		"sampler2DShadow",
207		"samplerCubeShadow",
208		"sampler2DArrayShadow",
209		"samplerCubeArrayShadow",
210		"isampler1D",
211		"isampler2D",
212		"isamplerCube",
213		"isampler2DArray",
214		"isampler3D",
215		"isamplerCubeArray",
216		"usampler1D",
217		"usampler2D",
218		"usamplerCube",
219		"usampler2DArray",
220		"usampler3D",
221		"usamplerCubeArray",
222		"sampler2DMS",
223		"isampler2DMS",
224		"usampler2DMS",
225		"image2D",
226		"imageCube",
227		"image2DArray",
228		"image3D",
229		"imageCubeArray",
230		"iimage2D",
231		"iimageCube",
232		"iimage2DArray",
233		"iimage3D",
234		"iimageCubeArray",
235		"uimage2D",
236		"uimageCube",
237		"uimage2DArray",
238		"uimage3D",
239		"uimageCubeArray",
240		"atomic_uint",
241	};
242
243	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_names) == TYPE_LAST);
244	DE_ASSERT(deInBounds32((int)dataType, 0, DE_LENGTH_OF_ARRAY(s_names)));
245	return s_names[(int)dataType];
246}
247
248int getDataTypeScalarSize (DataType dataType)
249{
250	const int s_sizes[] =
251	{
252		-1,		// invalid
253		1,		// float
254		2,		// vec2
255		3,		// vec3
256		4,		// vec4
257		4,		// mat2
258		6,		// mat2x3
259		8,		// mat2x4
260		6,		// mat3x2
261		9,		// mat3
262		12,		// mat3x4
263		8,		// mat4x2
264		12,		// mat4x3
265		16,		// mat4
266		1,		// int
267		2,		// ivec2
268		3,		// ivec3
269		4,		// ivec4
270		1,		// uint
271		2,		// uvec2
272		3,		// uvec3
273		4,		// uvec4
274		1,		// bool
275		2,		// bvec2
276		3,		// bvec3
277		4,		// bvec4
278		1,		// sampler1D
279		1,		// sampler2D
280		1,		// samplerCube
281		1,		// sampler2DArray
282		1,		// sampler3D
283		1,		// samplerCubeArray
284		1,		// sampler1DShadow
285		1,		// sampler2DShadow
286		1,		// samplerCubeShadow
287		1,		// sampler2DArrayShadow
288		1,		// samplerCubeArrayShadow
289		1,		// isampler1D
290		1,		// isampler2D
291		1,		// isamplerCube
292		1,		// isampler2DArray
293		1,		// isampler3D
294		1,		// isamplerCubeArray
295		1,		// usampler1D
296		1,		// usampler2D
297		1,		// usamplerCube
298		1,		// usampler2DArray
299		1,		// usampler3D
300		1,		// usamplerCubeArray
301		1,		// sampler2DMS
302		1,		// isampler2DMS
303		1,		// usampler2DMS
304		1,		// image2D
305		1,		// imageCube
306		1,		// image2DArray
307		1,		// image3D
308		1,		// imageCubeArray
309		1,		// iimage2D
310		1,		// iimageCube
311		1,		// iimage2DArray
312		1,		// iimage3D
313		1,		// iimageCubeArray
314		1,		// uimage2D
315		1,		// uimageCube
316		1,		// uimage2DArray
317		1,		// uimage3D
318		1,		// uimageCubeArray
319		1,		// atomic_uint
320	};
321
322	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_sizes) == TYPE_LAST);
323	DE_ASSERT(deInBounds32((int)dataType, 0, DE_LENGTH_OF_ARRAY(s_sizes)));
324	return s_sizes[(int)dataType];
325}
326
327DataType getDataTypeScalarType (DataType dataType)
328{
329	const DataType s_scalarTypes[] =
330	{
331		TYPE_INVALID,		// invalid
332		TYPE_FLOAT,			// float
333		TYPE_FLOAT,			// vec2
334		TYPE_FLOAT,			// vec3
335		TYPE_FLOAT,			// vec4
336		TYPE_FLOAT,			// mat2
337		TYPE_FLOAT,			// mat2x3
338		TYPE_FLOAT,			// mat2x4
339		TYPE_FLOAT,			// mat3x2
340		TYPE_FLOAT,			// mat3
341		TYPE_FLOAT,			// mat3x4
342		TYPE_FLOAT,			// mat4x2
343		TYPE_FLOAT,			// mat4x3
344		TYPE_FLOAT,			// mat4
345		TYPE_INT,			// int
346		TYPE_INT,			// ivec2
347		TYPE_INT,			// ivec3
348		TYPE_INT,			// ivec4
349		TYPE_UINT,			// uint
350		TYPE_UINT,			// uvec2
351		TYPE_UINT,			// uvec3
352		TYPE_UINT,			// uvec4
353		TYPE_BOOL,			// bool
354		TYPE_BOOL,			// bvec2
355		TYPE_BOOL,			// bvec3
356		TYPE_BOOL,			// bvec4
357		TYPE_SAMPLER_1D,					// sampler1D
358		TYPE_SAMPLER_2D,					// sampler2D
359		TYPE_SAMPLER_CUBE,					// samplerCube
360		TYPE_SAMPLER_2D_ARRAY,				// sampler2DArray
361		TYPE_SAMPLER_3D,					// sampler3D
362		TYPE_SAMPLER_CUBE_ARRAY,			// samplerCubeArray
363		TYPE_SAMPLER_1D_SHADOW,				// sampler1DShadow
364		TYPE_SAMPLER_2D_SHADOW,				// sampler2DShadow
365		TYPE_SAMPLER_CUBE_SHADOW,			// samplerCubeShadow
366		TYPE_SAMPLER_2D_ARRAY_SHADOW,		// sampler2DArrayShadow
367		TYPE_SAMPLER_CUBE_ARRAY_SHADOW,		// samplerCubeArrayShadow
368		TYPE_INT_SAMPLER_1D,				// isampler1D
369		TYPE_INT_SAMPLER_2D,				// isampler2D
370		TYPE_INT_SAMPLER_CUBE,				// isamplerCube
371		TYPE_INT_SAMPLER_2D_ARRAY,			// isampler2DArray
372		TYPE_INT_SAMPLER_3D,				// isampler3D
373		TYPE_INT_SAMPLER_CUBE_ARRAY,		// isamplerCubeArray
374		TYPE_UINT_SAMPLER_1D,				// usampler1D
375		TYPE_UINT_SAMPLER_2D,				// usampler2D
376		TYPE_UINT_SAMPLER_CUBE,				// usamplerCube
377		TYPE_UINT_SAMPLER_2D_ARRAY,			// usampler2DArray
378		TYPE_UINT_SAMPLER_3D,				// usampler3D
379		TYPE_UINT_SAMPLER_CUBE_ARRAY,		// usamplerCubeArray
380		TYPE_SAMPLER_2D_MULTISAMPLE,		// sampler2DMS
381		TYPE_INT_SAMPLER_2D_MULTISAMPLE,	// isampler2DMS
382		TYPE_UINT_SAMPLER_2D_MULTISAMPLE,	// usampler2DMS
383		TYPE_IMAGE_2D,						// image2D
384		TYPE_IMAGE_CUBE,					// imageCube
385		TYPE_IMAGE_2D_ARRAY,				// image2DArray
386		TYPE_IMAGE_3D,						// image3D
387		TYPE_IMAGE_CUBE_ARRAY,				// imageCubeArray
388		TYPE_INT_IMAGE_2D,					// iimage2D
389		TYPE_INT_IMAGE_CUBE,				// iimageCube
390		TYPE_INT_IMAGE_2D_ARRAY,			// iimage2DArray
391		TYPE_INT_IMAGE_3D,					// iimage3D
392		TYPE_INT_IMAGE_CUBE_ARRAY,			// iimageCubeArray
393		TYPE_UINT_IMAGE_2D,					// uimage2D
394		TYPE_UINT_IMAGE_CUBE,				// uimageCube
395		TYPE_UINT_IMAGE_2D_ARRAY,			// uimage2DArray
396		TYPE_UINT_IMAGE_3D,					// uimage3D
397		TYPE_UINT_IMAGE_CUBE_ARRAY,			// uimageCubeArray
398		TYPE_UINT_ATOMIC_COUNTER,			// atomic_uint
399	};
400
401	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_scalarTypes) == TYPE_LAST);
402	DE_ASSERT(deInBounds32((int)dataType, 0, DE_LENGTH_OF_ARRAY(s_scalarTypes)));
403	return s_scalarTypes[(int)dataType];
404}
405
406DataType getDataTypeFloatScalars (DataType dataType)
407{
408	const DataType s_floatTypes[] =
409	{
410		TYPE_INVALID,		// invalid
411		TYPE_FLOAT,			// float
412		TYPE_FLOAT_VEC2,	// vec2
413		TYPE_FLOAT_VEC3,	// vec3
414		TYPE_FLOAT_VEC4,	// vec4
415		TYPE_FLOAT_MAT2,	// mat2
416		TYPE_FLOAT_MAT2X3,	// mat2x3
417		TYPE_FLOAT_MAT2X4,	// mat2x4
418		TYPE_FLOAT_MAT3X2,	// mat3x2
419		TYPE_FLOAT_MAT3,	// mat3
420		TYPE_FLOAT_MAT3X4,	// mat3x4
421		TYPE_FLOAT_MAT4X2,	// mat4x2
422		TYPE_FLOAT_MAT4X3,	// mat4x3
423		TYPE_FLOAT_MAT4,	// mat4
424		TYPE_FLOAT,			// int
425		TYPE_FLOAT_VEC2,	// ivec2
426		TYPE_FLOAT_VEC3,	// ivec3
427		TYPE_FLOAT_VEC4,	// ivec4
428		TYPE_FLOAT,			// uint
429		TYPE_FLOAT_VEC2,	// uvec2
430		TYPE_FLOAT_VEC3,	// uvec3
431		TYPE_FLOAT_VEC4,	// uvec4
432		TYPE_FLOAT,			// bool
433		TYPE_FLOAT_VEC2,	// bvec2
434		TYPE_FLOAT_VEC3,	// bvec3
435		TYPE_FLOAT_VEC4,	// bvec4
436		TYPE_INVALID,		// sampler1D
437		TYPE_INVALID,		// sampler2D
438		TYPE_INVALID,		// samplerCube
439		TYPE_INVALID,		// sampler2DArray
440		TYPE_INVALID,		// sampler3D
441		TYPE_INVALID,		// samplerCubeArray
442		TYPE_INVALID,		// sampler1DShadow
443		TYPE_INVALID,		// sampler2DShadow
444		TYPE_INVALID,		// samplerCubeShadow
445		TYPE_INVALID,		// sampler2DArrayShadow
446		TYPE_INVALID,		// samplerCubeArrayShadow
447		TYPE_INVALID,		// isampler1D
448		TYPE_INVALID,		// isampler2D
449		TYPE_INVALID,		// isamplerCube
450		TYPE_INVALID,		// isampler2DArray
451		TYPE_INVALID,		// isampler3D
452		TYPE_INVALID,		// isamplerCubeArray
453		TYPE_INVALID,		// usampler1D
454		TYPE_INVALID,		// usampler2D
455		TYPE_INVALID,		// usamplerCube
456		TYPE_INVALID,		// usampler2DArray
457		TYPE_INVALID,		// usampler3D
458		TYPE_INVALID,		// usamplerCubeArray
459		TYPE_INVALID,		// sampler2DMS
460		TYPE_INVALID,		// isampler2DMS
461		TYPE_INVALID,		// usampler2DMS
462		TYPE_INVALID,		// image2D
463		TYPE_INVALID,		// imageCube
464		TYPE_INVALID,		// image2DArray
465		TYPE_INVALID,		// image3D
466		TYPE_INVALID,		// imageCubeArray
467		TYPE_INVALID,		// iimage2D
468		TYPE_INVALID,		// iimageCube
469		TYPE_INVALID,		// iimage2DArray
470		TYPE_INVALID,		// iimage3D
471		TYPE_INVALID,		// iimageCubeArray
472		TYPE_INVALID,		// uimage2D
473		TYPE_INVALID,		// uimageCube
474		TYPE_INVALID,		// uimage2DArray
475		TYPE_INVALID,		// uimage3D
476		TYPE_INVALID,		// uimageCubeArray
477		TYPE_INVALID,		// atomic_uint
478	};
479
480	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == TYPE_LAST);
481	DE_ASSERT(deInBounds32((int)dataType, 0, DE_LENGTH_OF_ARRAY(s_floatTypes)));
482	return s_floatTypes[(int)dataType];
483}
484
485DataType getDataTypeVector (DataType scalarType, int size)
486{
487	DE_ASSERT(deInRange32(size, 1, 4));
488	switch (scalarType)
489	{
490		case TYPE_FLOAT:
491		case TYPE_INT:
492		case TYPE_UINT:
493		case TYPE_BOOL:
494			return (DataType)((int)scalarType + size - 1);
495		default:
496			return TYPE_INVALID;
497	}
498}
499
500DataType getDataTypeFloatVec (int vecSize)
501{
502	return getDataTypeVector(TYPE_FLOAT, vecSize);
503}
504
505DataType getDataTypeIntVec (int vecSize)
506{
507	return getDataTypeVector(TYPE_INT, vecSize);
508}
509
510DataType getDataTypeUintVec (int vecSize)
511{
512	return getDataTypeVector(TYPE_UINT, vecSize);
513}
514
515DataType getDataTypeBoolVec (int vecSize)
516{
517	return getDataTypeVector(TYPE_BOOL, vecSize);
518}
519
520DataType getDataTypeMatrix (int numCols, int numRows)
521{
522	DE_ASSERT(de::inRange(numCols, 2, 4) && de::inRange(numRows, 2, 4));
523	return (DataType)((int)TYPE_FLOAT_MAT2 + (numCols-2)*3 + (numRows-2));
524}
525
526int getDataTypeMatrixNumRows (DataType dataType)
527{
528	switch (dataType)
529	{
530		case TYPE_FLOAT_MAT2:	return 2;
531		case TYPE_FLOAT_MAT2X3:	return 3;
532		case TYPE_FLOAT_MAT2X4:	return 4;
533		case TYPE_FLOAT_MAT3X2:	return 2;
534		case TYPE_FLOAT_MAT3:	return 3;
535		case TYPE_FLOAT_MAT3X4:	return 4;
536		case TYPE_FLOAT_MAT4X2:	return 2;
537		case TYPE_FLOAT_MAT4X3:	return 3;
538		case TYPE_FLOAT_MAT4:	return 4;
539		default:
540			DE_ASSERT(false);
541			return 0;
542	}
543}
544
545int getDataTypeMatrixNumColumns (DataType dataType)
546{
547	switch (dataType)
548	{
549		case TYPE_FLOAT_MAT2:	return 2;
550		case TYPE_FLOAT_MAT2X3:	return 2;
551		case TYPE_FLOAT_MAT2X4:	return 2;
552		case TYPE_FLOAT_MAT3X2:	return 3;
553		case TYPE_FLOAT_MAT3:	return 3;
554		case TYPE_FLOAT_MAT3X4:	return 3;
555		case TYPE_FLOAT_MAT4X2:	return 4;
556		case TYPE_FLOAT_MAT4X3:	return 4;
557		case TYPE_FLOAT_MAT4:	return 4;
558		default:
559			DE_ASSERT(false);
560			return 0;
561	}
562}
563
564int	getDataTypeNumLocations	(DataType dataType)
565{
566	if (isDataTypeScalarOrVector(dataType))
567		return 1;
568	else if (isDataTypeMatrix(dataType))
569		return getDataTypeMatrixNumColumns(dataType);
570
571	DE_ASSERT(!"Illegal datatype.");
572	return 0;
573}
574
575int	getDataTypeNumComponents (DataType dataType)
576{
577	if (isDataTypeScalarOrVector(dataType))
578		return getDataTypeScalarSize(dataType);
579	else if (isDataTypeMatrix(dataType))
580		return getDataTypeMatrixNumRows(dataType);
581
582	DE_ASSERT(!"Illegal datatype.");
583	return 0;
584}
585
586DataType getDataTypeFromGLType (deUint32 glType)
587{
588	switch (glType)
589	{
590		case GL_FLOAT:									return TYPE_FLOAT;
591		case GL_FLOAT_VEC2:								return TYPE_FLOAT_VEC2;
592		case GL_FLOAT_VEC3:								return TYPE_FLOAT_VEC3;
593		case GL_FLOAT_VEC4:								return TYPE_FLOAT_VEC4;
594
595		case GL_FLOAT_MAT2:								return TYPE_FLOAT_MAT2;
596		case GL_FLOAT_MAT2x3:							return TYPE_FLOAT_MAT2X3;
597		case GL_FLOAT_MAT2x4:							return TYPE_FLOAT_MAT2X4;
598
599		case GL_FLOAT_MAT3x2:							return TYPE_FLOAT_MAT3X2;
600		case GL_FLOAT_MAT3:								return TYPE_FLOAT_MAT3;
601		case GL_FLOAT_MAT3x4:							return TYPE_FLOAT_MAT3X4;
602
603		case GL_FLOAT_MAT4x2:							return TYPE_FLOAT_MAT4X2;
604		case GL_FLOAT_MAT4x3:							return TYPE_FLOAT_MAT4X3;
605		case GL_FLOAT_MAT4:								return TYPE_FLOAT_MAT4;
606
607		case GL_INT:									return TYPE_INT;
608		case GL_INT_VEC2:								return TYPE_INT_VEC2;
609		case GL_INT_VEC3:								return TYPE_INT_VEC3;
610		case GL_INT_VEC4:								return TYPE_INT_VEC4;
611
612		case GL_UNSIGNED_INT:							return TYPE_UINT;
613		case GL_UNSIGNED_INT_VEC2:						return TYPE_UINT_VEC2;
614		case GL_UNSIGNED_INT_VEC3:						return TYPE_UINT_VEC3;
615		case GL_UNSIGNED_INT_VEC4:						return TYPE_UINT_VEC4;
616
617		case GL_BOOL:									return TYPE_BOOL;
618		case GL_BOOL_VEC2:								return TYPE_BOOL_VEC2;
619		case GL_BOOL_VEC3:								return TYPE_BOOL_VEC3;
620		case GL_BOOL_VEC4:								return TYPE_BOOL_VEC4;
621
622		case GL_SAMPLER_1D:								return TYPE_SAMPLER_1D;
623		case GL_SAMPLER_2D:								return TYPE_SAMPLER_2D;
624		case GL_SAMPLER_CUBE:							return TYPE_SAMPLER_CUBE;
625		case GL_SAMPLER_2D_ARRAY:						return TYPE_SAMPLER_2D_ARRAY;
626		case GL_SAMPLER_3D:								return TYPE_SAMPLER_3D;
627		case GL_SAMPLER_CUBE_MAP_ARRAY:					return TYPE_SAMPLER_CUBE_ARRAY;
628
629		case GL_SAMPLER_1D_SHADOW:						return TYPE_SAMPLER_1D_SHADOW;
630		case GL_SAMPLER_2D_SHADOW:						return TYPE_SAMPLER_2D_SHADOW;
631		case GL_SAMPLER_CUBE_SHADOW:					return TYPE_SAMPLER_CUBE_SHADOW;
632		case GL_SAMPLER_2D_ARRAY_SHADOW:				return TYPE_SAMPLER_2D_ARRAY_SHADOW;
633		case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:			return TYPE_SAMPLER_CUBE_ARRAY_SHADOW;
634
635		case GL_INT_SAMPLER_1D:							return TYPE_INT_SAMPLER_1D;
636		case GL_INT_SAMPLER_2D:							return TYPE_INT_SAMPLER_2D;
637		case GL_INT_SAMPLER_CUBE:						return TYPE_INT_SAMPLER_CUBE;
638		case GL_INT_SAMPLER_2D_ARRAY:					return TYPE_INT_SAMPLER_2D_ARRAY;
639		case GL_INT_SAMPLER_3D:							return TYPE_INT_SAMPLER_3D;
640		case GL_INT_SAMPLER_CUBE_MAP_ARRAY:				return TYPE_INT_SAMPLER_CUBE_ARRAY;
641
642		case GL_UNSIGNED_INT_SAMPLER_1D:				return TYPE_UINT_SAMPLER_1D;
643		case GL_UNSIGNED_INT_SAMPLER_2D:				return TYPE_UINT_SAMPLER_2D;
644		case GL_UNSIGNED_INT_SAMPLER_CUBE:				return TYPE_UINT_SAMPLER_CUBE;
645		case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:			return TYPE_UINT_SAMPLER_2D_ARRAY;
646		case GL_UNSIGNED_INT_SAMPLER_3D:				return TYPE_UINT_SAMPLER_3D;
647		case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY:	return TYPE_UINT_SAMPLER_CUBE_ARRAY;
648
649		case GL_SAMPLER_2D_MULTISAMPLE:					return TYPE_SAMPLER_2D_MULTISAMPLE;
650		case GL_INT_SAMPLER_2D_MULTISAMPLE:				return TYPE_INT_SAMPLER_2D_MULTISAMPLE;
651		case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:	return TYPE_UINT_SAMPLER_2D_MULTISAMPLE;
652
653		case GL_IMAGE_2D:								return TYPE_IMAGE_2D;
654		case GL_IMAGE_CUBE:								return TYPE_IMAGE_CUBE;
655		case GL_IMAGE_2D_ARRAY:							return TYPE_IMAGE_2D_ARRAY;
656		case GL_IMAGE_3D:								return TYPE_IMAGE_3D;
657		case GL_INT_IMAGE_2D:							return TYPE_INT_IMAGE_2D;
658		case GL_INT_IMAGE_CUBE:							return TYPE_INT_IMAGE_CUBE;
659		case GL_INT_IMAGE_2D_ARRAY:						return TYPE_INT_IMAGE_2D_ARRAY;
660		case GL_INT_IMAGE_3D:							return TYPE_INT_IMAGE_3D;
661		case GL_UNSIGNED_INT_IMAGE_2D:					return TYPE_UINT_IMAGE_2D;
662		case GL_UNSIGNED_INT_IMAGE_CUBE:				return TYPE_UINT_IMAGE_CUBE;
663		case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:			return TYPE_UINT_IMAGE_2D_ARRAY;
664		case GL_UNSIGNED_INT_IMAGE_3D:					return TYPE_UINT_IMAGE_3D;
665
666		case GL_UNSIGNED_INT_ATOMIC_COUNTER:			return TYPE_UINT_ATOMIC_COUNTER;
667
668		default:
669			return TYPE_LAST;
670	}
671}
672
673} // glu
674