blob: 1143546dc11611cdde6ee7bc65d95638071890e0 [file] [log] [blame]
Nicolas Capens0bac2852016-05-07 06:09:58 -04001// 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 GLint floatToInt(GLfloat value)
468 {
469 return static_cast<GLint>((static_cast<GLfloat>(0xFFFFFFFF) * value - 1.0f) * 0.5f);
470 }
471
472 bool IsCompressed(GLenum format, GLint clientVersion)
473 {
474 return ValidateCompressedFormat(format, clientVersion, true) == GL_NONE;
475 }
476
477 GLenum ValidateCompressedFormat(GLenum format, GLint clientVersion, bool expectCompressedFormats)
478 {
479 switch(format)
480 {
481 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
482 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
483 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
484 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
485 return S3TC_SUPPORT ? (expectCompressedFormats ? GL_NONE : GL_INVALID_OPERATION) : GL_INVALID_ENUM;
486 case GL_ETC1_RGB8_OES:
487 return expectCompressedFormats ? GL_NONE : GL_INVALID_OPERATION;
488 case GL_COMPRESSED_R11_EAC:
489 case GL_COMPRESSED_SIGNED_R11_EAC:
490 case GL_COMPRESSED_RG11_EAC:
491 case GL_COMPRESSED_SIGNED_RG11_EAC:
492 case GL_COMPRESSED_RGB8_ETC2:
493 case GL_COMPRESSED_SRGB8_ETC2:
494 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
495 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
496 case GL_COMPRESSED_RGBA8_ETC2_EAC:
497 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
498 case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
499 case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
500 case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
501 case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
502 case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
503 case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
504 case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
505 case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
506 case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
507 case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
508 case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
509 case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
510 case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
511 case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
512 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
513 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
514 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
515 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
516 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
517 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
518 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
519 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
520 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
521 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
522 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
523 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
524 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
525 case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
526 return (clientVersion >= 3) ? (expectCompressedFormats ? GL_NONE : GL_INVALID_OPERATION) : GL_INVALID_ENUM;
527 default:
528 return expectCompressedFormats ? GL_INVALID_ENUM : GL_NONE; // Not compressed format
529 }
530 }
531
532 GLenum ValidateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum sizedInternalFormat, Texture *texture)
533 {
534 if(!texture)
535 {
536 return GL_INVALID_OPERATION;
537 }
538
539 if(compressed != texture->isCompressed(target, level))
540 {
541 return GL_INVALID_OPERATION;
542 }
543
544 if(sizedInternalFormat != GL_NONE && sizedInternalFormat != texture->getFormat(target, level))
545 {
546 return GL_INVALID_OPERATION;
547 }
548
549 if(compressed)
550 {
551 if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
552 (height % 4 != 0 && height != texture->getHeight(target, 0)))
553 {
554 return GL_INVALID_OPERATION;
555 }
556 }
557
558 if(xoffset + width > texture->getWidth(target, level) ||
559 yoffset + height > texture->getHeight(target, level))
560 {
561 return GL_INVALID_VALUE;
562 }
563
564 return GL_NONE;
565 }
566
567 GLenum ValidateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLsizei depth, GLint xoffset, GLint yoffset, GLint zoffset, GLenum target, GLint level, GLenum sizedInternalFormat, Texture *texture)
568 {
569 if(!texture)
570 {
571 return GL_INVALID_OPERATION;
572 }
573
574 if(compressed != texture->isCompressed(target, level))
575 {
576 return GL_INVALID_OPERATION;
577 }
578
579 if(sizedInternalFormat != GL_NONE && sizedInternalFormat != GetSizedInternalFormat(texture->getFormat(target, level), texture->getType(target, level)))
580 {
581 return GL_INVALID_OPERATION;
582 }
583
584 if(compressed)
585 {
586 if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
587 (height % 4 != 0 && height != texture->getHeight(target, 0)) ||
588 (depth % 4 != 0 && depth != texture->getDepth(target, 0)))
589 {
590 return GL_INVALID_OPERATION;
591 }
592 }
593
594 if(xoffset + width > texture->getWidth(target, level) ||
595 yoffset + height > texture->getHeight(target, level) ||
596 zoffset + depth > texture->getDepth(target, level))
597 {
598 return GL_INVALID_VALUE;
599 }
600
601 return GL_NONE;
602 }
603
604 bool ValidReadPixelsFormatType(GLenum internalFormat, GLenum internalType, GLenum format, GLenum type, GLint clientVersion)
605 {
606 switch(format)
607 {
608 case GL_RGBA:
609 switch(type)
610 {
611 case GL_UNSIGNED_BYTE:
612 break;
613 case GL_UNSIGNED_INT_2_10_10_10_REV:
614 return (clientVersion >= 3) && (internalFormat == GL_RGB10_A2);
615 case GL_FLOAT:
616 return (clientVersion >= 3) && (internalType == GL_FLOAT);
617 default:
618 return false;
619 }
620 break;
621 case GL_RGBA_INTEGER:
622 if(clientVersion < 3)
623 {
624 return false;
625 }
626 switch(type)
627 {
628 case GL_INT:
629 if(internalType != GL_INT)
630 {
631 return false;
632 }
633 break;
634 case GL_UNSIGNED_INT:
635 if(internalType != GL_UNSIGNED_INT)
636 {
637 return false;
638 }
639 break;
640 default:
641 return false;
642 }
643 break;
644 case GL_BGRA_EXT:
645 switch(type)
646 {
647 case GL_UNSIGNED_BYTE:
648 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
649 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
650 break;
651 default:
652 return false;
653 }
654 break;
655 case GL_RG_EXT:
656 case GL_RED_EXT:
657 return (clientVersion >= 3) && (type == GL_UNSIGNED_BYTE);
658 case GL_DEPTH_COMPONENT:
659 if(internalFormat != format)
660 {
661 return false;
662 }
663 switch(type)
664 {
665 case GL_UNSIGNED_SHORT:
666 case GL_FLOAT:
667 if(internalType != type)
668 {
669 return false;
670 }
671 break;
672 default:
673 return false;
674 }
675 break;
676 default:
677 return false;
678 }
679 return true;
680 }
681
682 bool IsDepthTexture(GLenum format)
683 {
684 return format == GL_DEPTH_COMPONENT ||
685 format == GL_DEPTH_STENCIL_OES ||
686 format == GL_DEPTH_COMPONENT16 ||
687 format == GL_DEPTH_COMPONENT24 ||
688 format == GL_DEPTH_COMPONENT32_OES ||
689 format == GL_DEPTH_COMPONENT32F ||
690 format == GL_DEPTH24_STENCIL8 ||
691 format == GL_DEPTH32F_STENCIL8;
692 }
693
694 bool IsStencilTexture(GLenum format)
695 {
696 return format == GL_STENCIL_INDEX_OES ||
697 format == GL_DEPTH_STENCIL_OES ||
698 format == GL_DEPTH24_STENCIL8 ||
699 format == GL_DEPTH32F_STENCIL8;
700 }
701
702 bool IsCubemapTextureTarget(GLenum target)
703 {
704 return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
705 }
706
707 int CubeFaceIndex(GLenum cubeFace)
708 {
709 switch(cubeFace)
710 {
711 case GL_TEXTURE_CUBE_MAP:
712 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: return 0;
713 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: return 1;
714 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: return 2;
715 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: return 3;
716 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: return 4;
717 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: return 5;
718 default: UNREACHABLE(cubeFace); return 0;
719 }
720 }
721
722 bool IsTextureTarget(GLenum target)
723 {
724 return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target) || target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY;
725 }
726
727 bool ValidateTextureFormatType(GLenum format, GLenum type, GLint internalformat, GLint clientVersion)
728 {
729 switch(type)
730 {
731 case GL_UNSIGNED_BYTE:
732 case GL_UNSIGNED_SHORT_4_4_4_4:
733 case GL_UNSIGNED_SHORT_5_5_5_1:
734 case GL_UNSIGNED_SHORT_5_6_5:
735 case GL_FLOAT: // GL_OES_texture_float
736 case GL_HALF_FLOAT_OES: // GL_OES_texture_half_float
737 case GL_UNSIGNED_INT_24_8: // GL_OES_packed_depth_stencil (GL_UNSIGNED_INT_24_8_EXT)
738 case GL_UNSIGNED_SHORT: // GL_OES_depth_texture
739 case GL_UNSIGNED_INT: // GL_OES_depth_texture
740 break;
741 case GL_BYTE:
742 case GL_SHORT:
743 case GL_INT:
744 case GL_HALF_FLOAT:
745 case GL_UNSIGNED_INT_2_10_10_10_REV:
746 case GL_UNSIGNED_INT_10F_11F_11F_REV:
747 case GL_UNSIGNED_INT_5_9_9_9_REV:
748 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
749 if(clientVersion < 3)
750 {
751 return error(GL_INVALID_ENUM, false);
752 }
753 break;
754 default:
755 return error(GL_INVALID_ENUM, false);
756 }
757
758 switch(format)
759 {
760 case GL_ALPHA:
761 case GL_RGB:
762 case GL_RGBA:
763 case GL_LUMINANCE:
764 case GL_LUMINANCE_ALPHA:
765 case GL_BGRA_EXT: // GL_EXT_texture_format_BGRA8888
766 case GL_DEPTH_STENCIL: // GL_OES_packed_depth_stencil (GL_DEPTH_STENCIL_OES)
767 case GL_DEPTH_COMPONENT: // GL_OES_depth_texture
768 break;
769 case GL_RED:
770 case GL_RED_INTEGER:
771 case GL_RG:
772 case GL_RG_INTEGER:
773 case GL_RGB_INTEGER:
774 case GL_RGBA_INTEGER:
775 if(clientVersion < 3)
776 {
777 return error(GL_INVALID_ENUM, false);
778 }
779 break;
780 default:
781 return error(GL_INVALID_ENUM, false);
782 }
783
784 if(internalformat != format)
785 {
786 if(clientVersion < 3)
787 {
788 return error(GL_INVALID_OPERATION, false);
789 }
790
791 switch(internalformat)
792 {
793 case GL_R8:
794 case GL_R8UI:
795 case GL_R8I:
796 case GL_R16UI:
797 case GL_R16I:
798 case GL_R32UI:
799 case GL_R32I:
800 case GL_RG8:
801 case GL_RG8UI:
802 case GL_RG8I:
803 case GL_RG16UI:
804 case GL_RG16I:
805 case GL_RG32UI:
806 case GL_RG32I:
807 case GL_SRGB8_ALPHA8:
808 case GL_RGB8UI:
809 case GL_RGB8I:
810 case GL_RGB16UI:
811 case GL_RGB16I:
812 case GL_RGB32UI:
813 case GL_RGB32I:
814 case GL_RG8_SNORM:
815 case GL_R8_SNORM:
816 case GL_RGB10_A2:
817 case GL_RGBA8UI:
818 case GL_RGBA8I:
819 case GL_RGB10_A2UI:
820 case GL_RGBA16UI:
821 case GL_RGBA16I:
822 case GL_RGBA32I:
823 case GL_RGBA32UI:
824 case GL_RGBA4:
825 case GL_RGB5_A1:
826 case GL_RGB565:
827 case GL_RGB8_OES:
828 case GL_RGBA8_OES:
829 case GL_R16F:
830 case GL_RG16F:
831 case GL_R11F_G11F_B10F:
832 case GL_RGB16F:
833 case GL_RGBA16F:
834 case GL_R32F:
835 case GL_RG32F:
836 case GL_RGB32F:
837 case GL_RGBA32F:
838 case GL_DEPTH_COMPONENT24:
839 case GL_DEPTH_COMPONENT32_OES:
840 case GL_DEPTH_COMPONENT32F:
841 case GL_DEPTH32F_STENCIL8:
842 case GL_DEPTH_COMPONENT16:
843 case GL_STENCIL_INDEX8:
844 case GL_DEPTH24_STENCIL8_OES:
845 case GL_RGBA8_SNORM:
846 case GL_SRGB8:
847 case GL_RGB8_SNORM:
848 case GL_RGB9_E5:
849 break;
850 default:
851 return error(GL_INVALID_ENUM, false);
852 }
853 }
854
855 // Validate format, type, and sized internalformat combinations [OpenGL ES 3.0 Table 3.2]
856 bool validSizedInternalformat = false;
857 #define VALIDATE_INTERNALFORMAT(...) { GLint validInternalformats[] = {__VA_ARGS__}; for(GLint v : validInternalformats) {if(internalformat == v) validSizedInternalformat = true;} } break;
858
859 switch(format)
860 {
861 case GL_RGBA:
862 switch(type)
863 {
864 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RGBA8, GL_RGB5_A1, GL_RGBA4, GL_SRGB8_ALPHA8)
865 case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_RGBA8_SNORM)
866 case GL_HALF_FLOAT_OES: break;
867 case GL_UNSIGNED_SHORT_4_4_4_4: VALIDATE_INTERNALFORMAT(GL_RGBA4)
868 case GL_UNSIGNED_SHORT_5_5_5_1: VALIDATE_INTERNALFORMAT(GL_RGB5_A1)
869 case GL_UNSIGNED_INT_2_10_10_10_REV: VALIDATE_INTERNALFORMAT(GL_RGB10_A2, GL_RGB5_A1)
870 case GL_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_RGBA16F)
871 case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_RGBA32F, GL_RGBA16F)
872 default: return error(GL_INVALID_OPERATION, false);
873 }
874 break;
875 case GL_RGBA_INTEGER:
876 switch(type)
877 {
878 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RGBA8UI)
879 case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_RGBA8I)
880 case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_RGBA16UI)
881 case GL_SHORT: VALIDATE_INTERNALFORMAT(GL_RGBA16I)
882 case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_RGBA32UI)
883 case GL_INT: VALIDATE_INTERNALFORMAT(GL_RGBA32I)
884 case GL_UNSIGNED_INT_2_10_10_10_REV: VALIDATE_INTERNALFORMAT(GL_RGB10_A2UI)
885 default: return error(GL_INVALID_OPERATION, false);
886 }
887 break;
888 case GL_RGB:
889 switch(type)
890 {
891 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RGB8, GL_RGB565, GL_SRGB8)
892 case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_RGB8_SNORM)
893 case GL_HALF_FLOAT_OES: break;
894 case GL_UNSIGNED_SHORT_5_6_5: VALIDATE_INTERNALFORMAT(GL_RGB565)
895 case GL_UNSIGNED_INT_10F_11F_11F_REV: VALIDATE_INTERNALFORMAT(GL_R11F_G11F_B10F)
896 case GL_UNSIGNED_INT_5_9_9_9_REV: VALIDATE_INTERNALFORMAT(GL_RGB9_E5)
897 case GL_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_RGB16F, GL_R11F_G11F_B10F, GL_RGB9_E5)
898 case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_RGB32F, GL_RGB16F, GL_R11F_G11F_B10F, GL_RGB9_E5)
899 default: return error(GL_INVALID_OPERATION, false);
900 }
901 break;
902 case GL_RGB_INTEGER:
903 switch(type)
904 {
905 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RGB8UI)
906 case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_RGB8I)
907 case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_RGB16UI)
908 case GL_SHORT: VALIDATE_INTERNALFORMAT(GL_RGB16I)
909 case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_RGB32UI)
910 case GL_INT: VALIDATE_INTERNALFORMAT(GL_RGB32I)
911 default: return error(GL_INVALID_OPERATION, false);
912 }
913 break;
914 case GL_RG:
915 switch(type)
916 {
917 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RG8)
918 case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_RG8_SNORM)
919 case GL_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_RG16F)
920 case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_RG32F, GL_RG16F)
921 default: return error(GL_INVALID_OPERATION, false);
922 }
923 break;
924 case GL_RG_INTEGER:
925 switch(type)
926 {
927 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RG8UI)
928 case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_RG8I)
929 case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_RG16UI)
930 case GL_SHORT: VALIDATE_INTERNALFORMAT(GL_RG16I)
931 case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_RG32UI)
932 case GL_INT: VALIDATE_INTERNALFORMAT(GL_RG32I)
933 default: return error(GL_INVALID_OPERATION, false);
934 }
935 break;
936 case GL_RED:
937 switch(type)
938 {
939 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_R8)
940 case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_R8_SNORM)
941 case GL_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_R16F)
942 case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_R32F, GL_R16F)
943 default: return error(GL_INVALID_OPERATION, false);
944 }
945 break;
946 case GL_RED_INTEGER:
947 switch(type)
948 {
949 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_R8UI)
950 case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_R8I)
951 case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_R16UI)
952 case GL_SHORT: VALIDATE_INTERNALFORMAT(GL_R16I)
953 case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_R32UI)
954 case GL_INT: VALIDATE_INTERNALFORMAT(GL_R32I)
955 default: return error(GL_INVALID_OPERATION, false);
956 }
957 break;
958 case GL_DEPTH_COMPONENT:
959 switch(type)
960 {
961 case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT16)
962 case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT16)
963 case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT32F)
964 default: return error(GL_INVALID_OPERATION, false);
965 }
966 break;
967 case GL_DEPTH_STENCIL:
968 switch(type)
969 {
970 case GL_UNSIGNED_INT_24_8: VALIDATE_INTERNALFORMAT(GL_DEPTH24_STENCIL8)
971 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: VALIDATE_INTERNALFORMAT(GL_DEPTH32F_STENCIL8)
972 default: return error(GL_INVALID_OPERATION, false);
973 }
974 break;
975 case GL_LUMINANCE_ALPHA:
976 case GL_LUMINANCE:
977 case GL_ALPHA:
978 switch(type)
979 {
980 case GL_UNSIGNED_BYTE:
981 case GL_HALF_FLOAT_OES:
982 case GL_FLOAT:
983 break;
984 default:
985 return error(GL_INVALID_OPERATION, false);
986 }
987 break;
988 case GL_BGRA_EXT:
989 if(type != GL_UNSIGNED_BYTE)
990 {
991 return error(GL_INVALID_OPERATION, false);
992 }
993 break;
994 default:
995 UNREACHABLE(format);
996 return error(GL_INVALID_ENUM, false);
997 }
998
999 #undef VALIDATE_INTERNALFORMAT
1000
1001 if(internalformat != format && !validSizedInternalformat)
1002 {
1003 return error(GL_INVALID_OPERATION, false);
1004 }
1005
1006 return true;
1007 }
1008
1009 bool IsColorRenderable(GLenum internalformat, GLint clientVersion)
1010 {
1011 switch(internalformat)
1012 {
1013 case GL_RGBA4:
1014 case GL_RGB5_A1:
1015 case GL_RGB565:
1016 case GL_RGB8_OES:
1017 case GL_RGBA8_OES:
1018 case GL_R16F:
1019 case GL_RG16F:
1020 case GL_RGB16F:
1021 case GL_RGBA16F:
1022 case GL_BGRA8_EXT:
1023 return true;
1024 case GL_R8:
1025 case GL_R8UI:
1026 case GL_R8I:
1027 case GL_R16UI:
1028 case GL_R16I:
1029 case GL_R32UI:
1030 case GL_R32I:
1031 case GL_RG8:
1032 case GL_RG8UI:
1033 case GL_RG8I:
1034 case GL_RG16UI:
1035 case GL_RG16I:
1036 case GL_RG32UI:
1037 case GL_RG32I:
1038 case GL_SRGB8_ALPHA8:
1039 case GL_RGB10_A2:
1040 case GL_RGBA8UI:
1041 case GL_RGBA8I:
1042 case GL_RGB10_A2UI:
1043 case GL_RGBA16UI:
1044 case GL_RGBA16I:
1045 case GL_RGBA32I:
1046 case GL_RGBA32UI:
1047 case GL_R11F_G11F_B10F:
1048 case GL_R32F:
1049 case GL_RG32F:
1050 case GL_RGB32F:
1051 case GL_RGBA32F:
1052 return clientVersion >= 3;
1053 case GL_DEPTH_COMPONENT24:
1054 case GL_DEPTH_COMPONENT32_OES:
1055 case GL_DEPTH_COMPONENT32F:
1056 case GL_DEPTH32F_STENCIL8:
1057 case GL_DEPTH_COMPONENT16:
1058 case GL_STENCIL_INDEX8:
1059 case GL_DEPTH24_STENCIL8_OES:
1060 return false;
1061 default:
1062 UNIMPLEMENTED();
1063 }
1064
1065 return false;
1066 }
1067
1068 bool IsDepthRenderable(GLenum internalformat)
1069 {
1070 switch(internalformat)
1071 {
1072 case GL_DEPTH_COMPONENT24:
1073 case GL_DEPTH_COMPONENT32_OES:
1074 case GL_DEPTH_COMPONENT32F:
1075 case GL_DEPTH32F_STENCIL8:
1076 case GL_DEPTH_COMPONENT16:
1077 case GL_DEPTH24_STENCIL8_OES:
1078 return true;
1079 case GL_STENCIL_INDEX8:
1080 case GL_R8:
1081 case GL_R8UI:
1082 case GL_R8I:
1083 case GL_R16UI:
1084 case GL_R16I:
1085 case GL_R32UI:
1086 case GL_R32I:
1087 case GL_RG8:
1088 case GL_RG8UI:
1089 case GL_RG8I:
1090 case GL_RG16UI:
1091 case GL_RG16I:
1092 case GL_RG32UI:
1093 case GL_RG32I:
1094 case GL_SRGB8_ALPHA8:
1095 case GL_RGB10_A2:
1096 case GL_RGBA8UI:
1097 case GL_RGBA8I:
1098 case GL_RGB10_A2UI:
1099 case GL_RGBA16UI:
1100 case GL_RGBA16I:
1101 case GL_RGBA32I:
1102 case GL_RGBA32UI:
1103 case GL_RGBA4:
1104 case GL_RGB5_A1:
1105 case GL_RGB565:
1106 case GL_RGB8_OES:
1107 case GL_RGBA8_OES:
1108 case GL_RGB:
1109 case GL_RGBA:
1110 case GL_R16F:
1111 case GL_RG16F:
1112 case GL_R11F_G11F_B10F:
1113 case GL_RGB16F:
1114 case GL_RGBA16F:
1115 case GL_R32F:
1116 case GL_RG32F:
1117 case GL_RGB32F:
1118 case GL_RGBA32F:
1119 return false;
1120 default:
1121 UNIMPLEMENTED();
1122 }
1123
1124 return false;
1125 }
1126
1127 bool IsStencilRenderable(GLenum internalformat)
1128 {
1129 switch(internalformat)
1130 {
1131 case GL_DEPTH32F_STENCIL8:
1132 case GL_STENCIL_INDEX8:
1133 case GL_DEPTH24_STENCIL8_OES:
1134 return true;
1135 case GL_R8:
1136 case GL_R8UI:
1137 case GL_R8I:
1138 case GL_R16UI:
1139 case GL_R16I:
1140 case GL_R32UI:
1141 case GL_R32I:
1142 case GL_RG8:
1143 case GL_RG8UI:
1144 case GL_RG8I:
1145 case GL_RG16UI:
1146 case GL_RG16I:
1147 case GL_RG32UI:
1148 case GL_RG32I:
1149 case GL_SRGB8_ALPHA8:
1150 case GL_RGB10_A2:
1151 case GL_RGBA8UI:
1152 case GL_RGBA8I:
1153 case GL_RGB10_A2UI:
1154 case GL_RGBA16UI:
1155 case GL_RGBA16I:
1156 case GL_RGBA32I:
1157 case GL_RGBA32UI:
1158 case GL_RGBA4:
1159 case GL_RGB5_A1:
1160 case GL_RGB565:
1161 case GL_RGB8_OES:
1162 case GL_RGBA8_OES:
1163 case GL_RGB:
1164 case GL_RGBA:
1165 case GL_R16F:
1166 case GL_RG16F:
1167 case GL_R11F_G11F_B10F:
1168 case GL_RGB16F:
1169 case GL_RGBA16F:
1170 case GL_R32F:
1171 case GL_RG32F:
1172 case GL_RGB32F:
1173 case GL_RGBA32F:
1174 case GL_DEPTH_COMPONENT16:
1175 case GL_DEPTH_COMPONENT24:
1176 case GL_DEPTH_COMPONENT32_OES:
1177 case GL_DEPTH_COMPONENT32F:
1178 return false;
1179 default:
1180 UNIMPLEMENTED();
1181 }
1182
1183 return false;
1184 }
1185
1186 std::string ParseUniformName(const std::string &name, size_t *outSubscript)
1187 {
1188 // Strip any trailing array operator and retrieve the subscript
1189 size_t open = name.find_last_of('[');
1190 size_t close = name.find_last_of(']');
1191 bool hasIndex = (open != std::string::npos) && (close == name.length() - 1);
1192 if(!hasIndex)
1193 {
1194 if(outSubscript)
1195 {
1196 *outSubscript = GL_INVALID_INDEX;
1197 }
1198 return name;
1199 }
1200
1201 if(outSubscript)
1202 {
1203 int index = atoi(name.substr(open + 1).c_str());
1204 if(index >= 0)
1205 {
1206 *outSubscript = index;
1207 }
1208 else
1209 {
1210 *outSubscript = GL_INVALID_INDEX;
1211 }
1212 }
1213
1214 return name.substr(0, open);
1215 }
1216}
1217
1218namespace es2sw
1219{
1220 sw::DepthCompareMode ConvertDepthComparison(GLenum comparison)
1221 {
1222 switch(comparison)
1223 {
1224 case GL_NEVER: return sw::DEPTH_NEVER;
1225 case GL_ALWAYS: return sw::DEPTH_ALWAYS;
1226 case GL_LESS: return sw::DEPTH_LESS;
1227 case GL_LEQUAL: return sw::DEPTH_LESSEQUAL;
1228 case GL_EQUAL: return sw::DEPTH_EQUAL;
1229 case GL_GREATER: return sw::DEPTH_GREATER;
1230 case GL_GEQUAL: return sw::DEPTH_GREATEREQUAL;
1231 case GL_NOTEQUAL: return sw::DEPTH_NOTEQUAL;
1232 default: UNREACHABLE(comparison);
1233 }
1234
1235 return sw::DEPTH_ALWAYS;
1236 }
1237
1238 sw::StencilCompareMode ConvertStencilComparison(GLenum comparison)
1239 {
1240 switch(comparison)
1241 {
1242 case GL_NEVER: return sw::STENCIL_NEVER;
1243 case GL_ALWAYS: return sw::STENCIL_ALWAYS;
1244 case GL_LESS: return sw::STENCIL_LESS;
1245 case GL_LEQUAL: return sw::STENCIL_LESSEQUAL;
1246 case GL_EQUAL: return sw::STENCIL_EQUAL;
1247 case GL_GREATER: return sw::STENCIL_GREATER;
1248 case GL_GEQUAL: return sw::STENCIL_GREATEREQUAL;
1249 case GL_NOTEQUAL: return sw::STENCIL_NOTEQUAL;
1250 default: UNREACHABLE(comparison);
1251 }
1252
1253 return sw::STENCIL_ALWAYS;
1254 }
1255
1256 sw::Color<float> ConvertColor(es2::Color color)
1257 {
1258 return sw::Color<float>(color.red, color.green, color.blue, color.alpha);
1259 }
1260
1261 sw::BlendFactor ConvertBlendFunc(GLenum blend)
1262 {
1263 switch(blend)
1264 {
1265 case GL_ZERO: return sw::BLEND_ZERO;
1266 case GL_ONE: return sw::BLEND_ONE;
1267 case GL_SRC_COLOR: return sw::BLEND_SOURCE;
1268 case GL_ONE_MINUS_SRC_COLOR: return sw::BLEND_INVSOURCE;
1269 case GL_DST_COLOR: return sw::BLEND_DEST;
1270 case GL_ONE_MINUS_DST_COLOR: return sw::BLEND_INVDEST;
1271 case GL_SRC_ALPHA: return sw::BLEND_SOURCEALPHA;
1272 case GL_ONE_MINUS_SRC_ALPHA: return sw::BLEND_INVSOURCEALPHA;
1273 case GL_DST_ALPHA: return sw::BLEND_DESTALPHA;
1274 case GL_ONE_MINUS_DST_ALPHA: return sw::BLEND_INVDESTALPHA;
1275 case GL_CONSTANT_COLOR: return sw::BLEND_CONSTANT;
1276 case GL_ONE_MINUS_CONSTANT_COLOR: return sw::BLEND_INVCONSTANT;
1277 case GL_CONSTANT_ALPHA: return sw::BLEND_CONSTANTALPHA;
1278 case GL_ONE_MINUS_CONSTANT_ALPHA: return sw::BLEND_INVCONSTANTALPHA;
1279 case GL_SRC_ALPHA_SATURATE: return sw::BLEND_SRCALPHASAT;
1280 default: UNREACHABLE(blend);
1281 }
1282
1283 return sw::BLEND_ZERO;
1284 }
1285
1286 sw::BlendOperation ConvertBlendOp(GLenum blendOp)
1287 {
1288 switch(blendOp)
1289 {
1290 case GL_FUNC_ADD: return sw::BLENDOP_ADD;
1291 case GL_FUNC_SUBTRACT: return sw::BLENDOP_SUB;
1292 case GL_FUNC_REVERSE_SUBTRACT: return sw::BLENDOP_INVSUB;
1293 case GL_MIN_EXT: return sw::BLENDOP_MIN;
1294 case GL_MAX_EXT: return sw::BLENDOP_MAX;
1295 default: UNREACHABLE(blendOp);
1296 }
1297
1298 return sw::BLENDOP_ADD;
1299 }
1300
1301 sw::StencilOperation ConvertStencilOp(GLenum stencilOp)
1302 {
1303 switch(stencilOp)
1304 {
1305 case GL_ZERO: return sw::OPERATION_ZERO;
1306 case GL_KEEP: return sw::OPERATION_KEEP;
1307 case GL_REPLACE: return sw::OPERATION_REPLACE;
1308 case GL_INCR: return sw::OPERATION_INCRSAT;
1309 case GL_DECR: return sw::OPERATION_DECRSAT;
1310 case GL_INVERT: return sw::OPERATION_INVERT;
1311 case GL_INCR_WRAP: return sw::OPERATION_INCR;
1312 case GL_DECR_WRAP: return sw::OPERATION_DECR;
1313 default: UNREACHABLE(stencilOp);
1314 }
1315
1316 return sw::OPERATION_KEEP;
1317 }
1318
1319 sw::AddressingMode ConvertTextureWrap(GLenum wrap)
1320 {
1321 switch(wrap)
1322 {
1323 case GL_REPEAT: return sw::ADDRESSING_WRAP;
1324 case GL_CLAMP_TO_EDGE: return sw::ADDRESSING_CLAMP;
1325 case GL_MIRRORED_REPEAT: return sw::ADDRESSING_MIRROR;
1326 default: UNREACHABLE(wrap);
1327 }
1328
1329 return sw::ADDRESSING_WRAP;
1330 }
1331
1332 sw::SwizzleType ConvertSwizzleType(GLenum swizzleType)
1333 {
1334 switch(swizzleType)
1335 {
1336 case GL_RED: return sw::SWIZZLE_RED;
1337 case GL_GREEN: return sw::SWIZZLE_GREEN;
1338 case GL_BLUE: return sw::SWIZZLE_BLUE;
1339 case GL_ALPHA: return sw::SWIZZLE_ALPHA;
1340 case GL_ZERO: return sw::SWIZZLE_ZERO;
1341 case GL_ONE: return sw::SWIZZLE_ONE;
1342 default: UNREACHABLE(swizzleType);
1343 }
1344
1345 return sw::SWIZZLE_RED;
1346 };
1347
1348 sw::CullMode ConvertCullMode(GLenum cullFace, GLenum frontFace)
1349 {
1350 switch(cullFace)
1351 {
1352 case GL_FRONT:
1353 return (frontFace == GL_CCW ? sw::CULL_CLOCKWISE : sw::CULL_COUNTERCLOCKWISE);
1354 case GL_BACK:
1355 return (frontFace == GL_CCW ? sw::CULL_COUNTERCLOCKWISE : sw::CULL_CLOCKWISE);
1356 case GL_FRONT_AND_BACK:
1357 return sw::CULL_NONE; // culling will be handled during draw
1358 default: UNREACHABLE(cullFace);
1359 }
1360
1361 return sw::CULL_COUNTERCLOCKWISE;
1362 }
1363
1364 unsigned int ConvertColorMask(bool red, bool green, bool blue, bool alpha)
1365 {
1366 return (red ? 0x00000001 : 0) |
1367 (green ? 0x00000002 : 0) |
1368 (blue ? 0x00000004 : 0) |
1369 (alpha ? 0x00000008 : 0);
1370 }
1371
1372 sw::MipmapType ConvertMipMapFilter(GLenum minFilter)
1373 {
1374 switch(minFilter)
1375 {
1376 case GL_NEAREST:
1377 case GL_LINEAR:
1378 return sw::MIPMAP_NONE;
1379 break;
1380 case GL_NEAREST_MIPMAP_NEAREST:
1381 case GL_LINEAR_MIPMAP_NEAREST:
1382 return sw::MIPMAP_POINT;
1383 break;
1384 case GL_NEAREST_MIPMAP_LINEAR:
1385 case GL_LINEAR_MIPMAP_LINEAR:
1386 return sw::MIPMAP_LINEAR;
1387 break;
1388 default:
1389 UNREACHABLE(minFilter);
1390 return sw::MIPMAP_NONE;
1391 }
1392 }
1393
1394 sw::FilterType ConvertTextureFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy)
1395 {
1396 if(maxAnisotropy > 1.0f)
1397 {
1398 return sw::FILTER_ANISOTROPIC;
1399 }
1400
1401 sw::FilterType magFilterType = sw::FILTER_POINT;
1402 switch(magFilter)
1403 {
1404 case GL_NEAREST: magFilterType = sw::FILTER_POINT; break;
1405 case GL_LINEAR: magFilterType = sw::FILTER_LINEAR; break;
1406 default: UNREACHABLE(magFilter);
1407 }
1408
1409 switch(minFilter)
1410 {
1411 case GL_NEAREST:
1412 case GL_NEAREST_MIPMAP_NEAREST:
1413 case GL_NEAREST_MIPMAP_LINEAR:
1414 return (magFilterType == sw::FILTER_POINT) ? sw::FILTER_POINT : sw::FILTER_MIN_POINT_MAG_LINEAR;
1415 case GL_LINEAR:
1416 case GL_LINEAR_MIPMAP_NEAREST:
1417 case GL_LINEAR_MIPMAP_LINEAR:
1418 return (magFilterType == sw::FILTER_POINT) ? sw::FILTER_MIN_LINEAR_MAG_POINT : sw::FILTER_LINEAR;
1419 default:
1420 UNREACHABLE(minFilter);
1421 return (magFilterType == sw::FILTER_POINT) ? sw::FILTER_POINT : sw::FILTER_MIN_POINT_MAG_LINEAR;
1422 }
1423 }
1424
Alexis Hetu7b2403b2016-05-04 16:43:21 -04001425 bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount, GLenum elementType, sw::DrawType &drawType, int &primitiveCount, int &verticesPerPrimitive)
Nicolas Capens0bac2852016-05-07 06:09:58 -04001426 {
1427 switch(primitiveType)
1428 {
1429 case GL_POINTS:
1430 drawType = sw::DRAW_POINTLIST;
1431 primitiveCount = elementCount;
Alexis Hetu7b2403b2016-05-04 16:43:21 -04001432 verticesPerPrimitive = 1;
Nicolas Capens0bac2852016-05-07 06:09:58 -04001433 break;
1434 case GL_LINES:
1435 drawType = sw::DRAW_LINELIST;
1436 primitiveCount = elementCount / 2;
Alexis Hetu7b2403b2016-05-04 16:43:21 -04001437 verticesPerPrimitive = 2;
Nicolas Capens0bac2852016-05-07 06:09:58 -04001438 break;
1439 case GL_LINE_LOOP:
1440 drawType = sw::DRAW_LINELOOP;
1441 primitiveCount = elementCount;
Alexis Hetu7b2403b2016-05-04 16:43:21 -04001442 verticesPerPrimitive = 2;
Nicolas Capens0bac2852016-05-07 06:09:58 -04001443 break;
1444 case GL_LINE_STRIP:
1445 drawType = sw::DRAW_LINESTRIP;
1446 primitiveCount = elementCount - 1;
Alexis Hetu7b2403b2016-05-04 16:43:21 -04001447 verticesPerPrimitive = 2;
Nicolas Capens0bac2852016-05-07 06:09:58 -04001448 break;
1449 case GL_TRIANGLES:
1450 drawType = sw::DRAW_TRIANGLELIST;
1451 primitiveCount = elementCount / 3;
Alexis Hetu7b2403b2016-05-04 16:43:21 -04001452 verticesPerPrimitive = 3;
Nicolas Capens0bac2852016-05-07 06:09:58 -04001453 break;
1454 case GL_TRIANGLE_STRIP:
1455 drawType = sw::DRAW_TRIANGLESTRIP;
1456 primitiveCount = elementCount - 2;
Alexis Hetu7b2403b2016-05-04 16:43:21 -04001457 verticesPerPrimitive = 3;
Nicolas Capens0bac2852016-05-07 06:09:58 -04001458 break;
1459 case GL_TRIANGLE_FAN:
1460 drawType = sw::DRAW_TRIANGLEFAN;
1461 primitiveCount = elementCount - 2;
Alexis Hetu7b2403b2016-05-04 16:43:21 -04001462 verticesPerPrimitive = 3;
Nicolas Capens0bac2852016-05-07 06:09:58 -04001463 break;
1464 default:
1465 return false;
1466 }
1467
1468 sw::DrawType elementSize;
1469 switch(elementType)
1470 {
1471 case GL_NONE: elementSize = sw::DRAW_NONINDEXED; break;
1472 case GL_UNSIGNED_BYTE: elementSize = sw::DRAW_INDEXED8; break;
1473 case GL_UNSIGNED_SHORT: elementSize = sw::DRAW_INDEXED16; break;
1474 case GL_UNSIGNED_INT: elementSize = sw::DRAW_INDEXED32; break;
1475 default: return false;
1476 }
1477
1478 drawType = sw::DrawType(drawType | elementSize);
1479
1480 return true;
1481 }
1482
1483 sw::Format ConvertRenderbufferFormat(GLenum format)
1484 {
1485 switch(format)
1486 {
1487 case GL_RGBA4:
1488 case GL_RGB5_A1:
1489 case GL_RGBA8_OES: return sw::FORMAT_A8B8G8R8;
1490 case GL_RGB565: return sw::FORMAT_R5G6B5;
1491 case GL_RGB8_OES: return sw::FORMAT_X8B8G8R8;
1492 case GL_DEPTH_COMPONENT16:
1493 case GL_STENCIL_INDEX8:
1494 case GL_DEPTH24_STENCIL8_OES: return sw::FORMAT_D24S8;
1495 case GL_DEPTH_COMPONENT32_OES:return sw::FORMAT_D32;
1496 case GL_R8: return sw::FORMAT_R8;
1497 case GL_RG8: return sw::FORMAT_G8R8;
1498 case GL_R8I: return sw::FORMAT_R8I;
1499 case GL_RG8I: return sw::FORMAT_G8R8I;
1500 case GL_RGB8I: return sw::FORMAT_X8B8G8R8I;
1501 case GL_RGBA8I: return sw::FORMAT_A8B8G8R8I;
1502 case GL_R8UI: return sw::FORMAT_R8UI;
1503 case GL_RG8UI: return sw::FORMAT_G8R8UI;
1504 case GL_RGB8UI: return sw::FORMAT_X8B8G8R8UI;
1505 case GL_RGBA8UI: return sw::FORMAT_A8B8G8R8UI;
1506 case GL_R16I: return sw::FORMAT_R16I;
1507 case GL_RG16I: return sw::FORMAT_G16R16I;
1508 case GL_RGB16I: return sw::FORMAT_X16B16G16R16I;
1509 case GL_RGBA16I: return sw::FORMAT_A16B16G16R16I;
1510 case GL_R16UI: return sw::FORMAT_R16UI;
1511 case GL_RG16UI: return sw::FORMAT_G16R16UI;
1512 case GL_RGB16UI: return sw::FORMAT_X16B16G16R16UI;
1513 case GL_RGB10_A2UI:
1514 case GL_RGBA16UI: return sw::FORMAT_A16B16G16R16UI;
1515 case GL_R32I: return sw::FORMAT_R32I;
1516 case GL_RG32I: return sw::FORMAT_G32R32I;
1517 case GL_RGB32I: return sw::FORMAT_X32B32G32R32I;
1518 case GL_RGBA32I: return sw::FORMAT_A32B32G32R32I;
1519 case GL_R32UI: return sw::FORMAT_R32UI;
1520 case GL_RG32UI: return sw::FORMAT_G32R32UI;
1521 case GL_RGB32UI: return sw::FORMAT_X32B32G32R32UI;
1522 case GL_RGBA32UI: return sw::FORMAT_A32B32G32R32UI;
1523 case GL_R16F: return sw::FORMAT_R16F;
1524 case GL_RG16F: return sw::FORMAT_G16R16F;
1525 case GL_R11F_G11F_B10F:
1526 case GL_RGB16F: return sw::FORMAT_B16G16R16F;
1527 case GL_RGBA16F: return sw::FORMAT_A16B16G16R16F;
1528 case GL_R32F: return sw::FORMAT_R32F;
1529 case GL_RG32F: return sw::FORMAT_G32R32F;
1530 case GL_RGB32F: return sw::FORMAT_B32G32R32F;
1531 case GL_RGBA32F: return sw::FORMAT_A32B32G32R32F;
1532 case GL_RGB10_A2: return sw::FORMAT_A2B10G10R10;
1533 case GL_SRGB8: return sw::FORMAT_SRGB8_X8;
1534 case GL_SRGB8_ALPHA8: return sw::FORMAT_SRGB8_A8;
1535 default: UNREACHABLE(format); return sw::FORMAT_NULL;
1536 }
1537 }
1538}
1539
1540namespace sw2es
1541{
1542 unsigned int GetStencilSize(sw::Format stencilFormat)
1543 {
1544 switch(stencilFormat)
1545 {
1546 case sw::FORMAT_D24FS8:
1547 case sw::FORMAT_D24S8:
1548 case sw::FORMAT_D32FS8_TEXTURE:
1549 case sw::FORMAT_D32FS8_SHADOW:
1550 case sw::FORMAT_S8:
1551 return 8;
1552 // case sw::FORMAT_D24X4S4:
1553 // return 4;
1554 // case sw::FORMAT_D15S1:
1555 // return 1;
1556 // case sw::FORMAT_D16_LOCKABLE:
1557 case sw::FORMAT_D32:
1558 case sw::FORMAT_D24X8:
1559 case sw::FORMAT_D32F_LOCKABLE:
1560 case sw::FORMAT_D16:
1561 return 0;
1562 // case sw::FORMAT_D32_LOCKABLE: return 0;
1563 // case sw::FORMAT_S8_LOCKABLE: return 8;
1564 default:
1565 return 0;
1566 }
1567 }
1568
1569 unsigned int GetAlphaSize(sw::Format colorFormat)
1570 {
1571 switch(colorFormat)
1572 {
1573 case sw::FORMAT_A16B16G16R16F:
1574 case sw::FORMAT_A16B16G16R16I:
1575 case sw::FORMAT_A16B16G16R16UI:
1576 return 16;
1577 case sw::FORMAT_A32B32G32R32F:
1578 case sw::FORMAT_A32B32G32R32I:
1579 case sw::FORMAT_A32B32G32R32UI:
1580 return 32;
1581 case sw::FORMAT_A2R10G10B10:
1582 return 2;
1583 case sw::FORMAT_A8R8G8B8:
1584 case sw::FORMAT_A8B8G8R8:
1585 case sw::FORMAT_SRGB8_A8:
1586 case sw::FORMAT_A8B8G8R8I:
1587 case sw::FORMAT_A8B8G8R8UI:
1588 case sw::FORMAT_A8B8G8R8I_SNORM:
1589 return 8;
1590 case sw::FORMAT_A2B10G10R10:
1591 return 2;
1592 case sw::FORMAT_A1R5G5B5:
1593 return 1;
1594 case sw::FORMAT_X8R8G8B8:
1595 case sw::FORMAT_X8B8G8R8:
1596 case sw::FORMAT_SRGB8_X8:
1597 case sw::FORMAT_R5G6B5:
1598 return 0;
1599 default:
1600 return 0;
1601 }
1602 }
1603
1604 unsigned int GetRedSize(sw::Format colorFormat)
1605 {
1606 switch(colorFormat)
1607 {
1608 case sw::FORMAT_R16F:
1609 case sw::FORMAT_G16R16F:
1610 case sw::FORMAT_B16G16R16F:
1611 case sw::FORMAT_A16B16G16R16F:
1612 case sw::FORMAT_R16I:
1613 case sw::FORMAT_G16R16I:
1614 case sw::FORMAT_X16B16G16R16I:
1615 case sw::FORMAT_A16B16G16R16I:
1616 case sw::FORMAT_R16UI:
1617 case sw::FORMAT_G16R16UI:
1618 case sw::FORMAT_X16B16G16R16UI:
1619 case sw::FORMAT_A16B16G16R16UI:
1620 return 16;
1621 case sw::FORMAT_R32F:
1622 case sw::FORMAT_G32R32F:
1623 case sw::FORMAT_B32G32R32F:
1624 case sw::FORMAT_X32B32G32R32F:
1625 case sw::FORMAT_A32B32G32R32F:
1626 case sw::FORMAT_R32I:
1627 case sw::FORMAT_G32R32I:
1628 case sw::FORMAT_X32B32G32R32I:
1629 case sw::FORMAT_A32B32G32R32I:
1630 case sw::FORMAT_R32UI:
1631 case sw::FORMAT_G32R32UI:
1632 case sw::FORMAT_X32B32G32R32UI:
1633 case sw::FORMAT_A32B32G32R32UI:
1634 return 32;
1635 case sw::FORMAT_A2B10G10R10:
1636 case sw::FORMAT_A2R10G10B10:
1637 return 10;
1638 case sw::FORMAT_A8R8G8B8:
1639 case sw::FORMAT_A8B8G8R8:
1640 case sw::FORMAT_X8R8G8B8:
1641 case sw::FORMAT_X8B8G8R8:
1642 case sw::FORMAT_SRGB8_A8:
1643 case sw::FORMAT_SRGB8_X8:
1644 case sw::FORMAT_R8:
1645 case sw::FORMAT_G8R8:
1646 case sw::FORMAT_R8I:
1647 case sw::FORMAT_G8R8I:
1648 case sw::FORMAT_X8B8G8R8I:
1649 case sw::FORMAT_A8B8G8R8I:
1650 case sw::FORMAT_R8UI:
1651 case sw::FORMAT_G8R8UI:
1652 case sw::FORMAT_X8B8G8R8UI:
1653 case sw::FORMAT_A8B8G8R8UI:
1654 case sw::FORMAT_R8I_SNORM:
1655 case sw::FORMAT_G8R8I_SNORM:
1656 case sw::FORMAT_X8B8G8R8I_SNORM:
1657 case sw::FORMAT_A8B8G8R8I_SNORM:
1658 return 8;
1659 case sw::FORMAT_A1R5G5B5:
1660 case sw::FORMAT_R5G6B5:
1661 return 5;
1662 default:
1663 return 0;
1664 }
1665 }
1666
1667 unsigned int GetGreenSize(sw::Format colorFormat)
1668 {
1669 switch(colorFormat)
1670 {
1671 case sw::FORMAT_G16R16F:
1672 case sw::FORMAT_B16G16R16F:
1673 case sw::FORMAT_A16B16G16R16F:
1674 case sw::FORMAT_G16R16I:
1675 case sw::FORMAT_X16B16G16R16I:
1676 case sw::FORMAT_A16B16G16R16I:
1677 case sw::FORMAT_G16R16UI:
1678 case sw::FORMAT_X16B16G16R16UI:
1679 case sw::FORMAT_A16B16G16R16UI:
1680 return 16;
1681 case sw::FORMAT_G32R32F:
1682 case sw::FORMAT_B32G32R32F:
1683 case sw::FORMAT_X32B32G32R32F:
1684 case sw::FORMAT_A32B32G32R32F:
1685 case sw::FORMAT_G32R32I:
1686 case sw::FORMAT_X32B32G32R32I:
1687 case sw::FORMAT_A32B32G32R32I:
1688 case sw::FORMAT_G32R32UI:
1689 case sw::FORMAT_X32B32G32R32UI:
1690 case sw::FORMAT_A32B32G32R32UI:
1691 return 32;
1692 case sw::FORMAT_A2B10G10R10:
1693 case sw::FORMAT_A2R10G10B10:
1694 return 10;
1695 case sw::FORMAT_A8R8G8B8:
1696 case sw::FORMAT_A8B8G8R8:
1697 case sw::FORMAT_X8R8G8B8:
1698 case sw::FORMAT_X8B8G8R8:
1699 case sw::FORMAT_SRGB8_A8:
1700 case sw::FORMAT_SRGB8_X8:
1701 case sw::FORMAT_G8R8:
1702 case sw::FORMAT_G8R8I:
1703 case sw::FORMAT_X8B8G8R8I:
1704 case sw::FORMAT_A8B8G8R8I:
1705 case sw::FORMAT_G8R8UI:
1706 case sw::FORMAT_X8B8G8R8UI:
1707 case sw::FORMAT_A8B8G8R8UI:
1708 case sw::FORMAT_G8R8I_SNORM:
1709 case sw::FORMAT_X8B8G8R8I_SNORM:
1710 case sw::FORMAT_A8B8G8R8I_SNORM:
1711 return 8;
1712 case sw::FORMAT_A1R5G5B5:
1713 return 5;
1714 case sw::FORMAT_R5G6B5:
1715 return 6;
1716 default:
1717 return 0;
1718 }
1719 }
1720
1721 unsigned int GetBlueSize(sw::Format colorFormat)
1722 {
1723 switch(colorFormat)
1724 {
1725 case sw::FORMAT_B16G16R16F:
1726 case sw::FORMAT_A16B16G16R16F:
1727 case sw::FORMAT_X16B16G16R16I:
1728 case sw::FORMAT_A16B16G16R16I:
1729 case sw::FORMAT_X16B16G16R16UI:
1730 case sw::FORMAT_A16B16G16R16UI:
1731 return 16;
1732 case sw::FORMAT_B32G32R32F:
1733 case sw::FORMAT_X32B32G32R32F:
1734 case sw::FORMAT_A32B32G32R32F:
1735 case sw::FORMAT_X32B32G32R32I:
1736 case sw::FORMAT_A32B32G32R32I:
1737 case sw::FORMAT_X32B32G32R32UI:
1738 case sw::FORMAT_A32B32G32R32UI:
1739 return 32;
1740 case sw::FORMAT_A2B10G10R10:
1741 case sw::FORMAT_A2R10G10B10:
1742 return 10;
1743 case sw::FORMAT_A8R8G8B8:
1744 case sw::FORMAT_A8B8G8R8:
1745 case sw::FORMAT_X8R8G8B8:
1746 case sw::FORMAT_X8B8G8R8:
1747 case sw::FORMAT_SRGB8_A8:
1748 case sw::FORMAT_SRGB8_X8:
1749 case sw::FORMAT_X8B8G8R8I:
1750 case sw::FORMAT_A8B8G8R8I:
1751 case sw::FORMAT_X8B8G8R8UI:
1752 case sw::FORMAT_A8B8G8R8UI:
1753 case sw::FORMAT_X8B8G8R8I_SNORM:
1754 case sw::FORMAT_A8B8G8R8I_SNORM:
1755 return 8;
1756 case sw::FORMAT_A1R5G5B5:
1757 case sw::FORMAT_R5G6B5:
1758 return 5;
1759 default:
1760 return 0;
1761 }
1762 }
1763
1764 unsigned int GetDepthSize(sw::Format depthFormat)
1765 {
1766 switch(depthFormat)
1767 {
1768 // case sw::FORMAT_D16_LOCKABLE: return 16;
1769 case sw::FORMAT_D32: return 32;
1770 // case sw::FORMAT_D15S1: return 15;
1771 case sw::FORMAT_D24S8: return 24;
1772 case sw::FORMAT_D24X8: return 24;
1773 // case sw::FORMAT_D24X4S4: return 24;
1774 case sw::FORMAT_DF16S8:
1775 case sw::FORMAT_D16: return 16;
1776 case sw::FORMAT_D32F:
1777 case sw::FORMAT_D32F_COMPLEMENTARY:
1778 case sw::FORMAT_D32F_LOCKABLE: return 32;
1779 case sw::FORMAT_DF24S8:
1780 case sw::FORMAT_D24FS8: return 24;
1781 // case sw::FORMAT_D32_LOCKABLE: return 32;
1782 // case sw::FORMAT_S8_LOCKABLE: return 0;
1783 case sw::FORMAT_D32FS8_SHADOW:
1784 case sw::FORMAT_D32FS8_TEXTURE: return 32;
1785 default: return 0;
1786 }
1787 }
1788
1789 GLenum GetComponentType(sw::Format format, GLenum attachment)
1790 {
1791 // Can be one of GL_FLOAT, GL_INT, GL_UNSIGNED_INT, GL_SIGNED_NORMALIZED, or GL_UNSIGNED_NORMALIZED
1792 switch(attachment)
1793 {
1794 case GL_COLOR_ATTACHMENT0:
1795 case GL_COLOR_ATTACHMENT1:
1796 case GL_COLOR_ATTACHMENT2:
1797 case GL_COLOR_ATTACHMENT3:
1798 case GL_COLOR_ATTACHMENT4:
1799 case GL_COLOR_ATTACHMENT5:
1800 case GL_COLOR_ATTACHMENT6:
1801 case GL_COLOR_ATTACHMENT7:
1802 case GL_COLOR_ATTACHMENT8:
1803 case GL_COLOR_ATTACHMENT9:
1804 case GL_COLOR_ATTACHMENT10:
1805 case GL_COLOR_ATTACHMENT11:
1806 case GL_COLOR_ATTACHMENT12:
1807 case GL_COLOR_ATTACHMENT13:
1808 case GL_COLOR_ATTACHMENT14:
1809 case GL_COLOR_ATTACHMENT15:
1810 case GL_COLOR_ATTACHMENT16:
1811 case GL_COLOR_ATTACHMENT17:
1812 case GL_COLOR_ATTACHMENT18:
1813 case GL_COLOR_ATTACHMENT19:
1814 case GL_COLOR_ATTACHMENT20:
1815 case GL_COLOR_ATTACHMENT21:
1816 case GL_COLOR_ATTACHMENT22:
1817 case GL_COLOR_ATTACHMENT23:
1818 case GL_COLOR_ATTACHMENT24:
1819 case GL_COLOR_ATTACHMENT25:
1820 case GL_COLOR_ATTACHMENT26:
1821 case GL_COLOR_ATTACHMENT27:
1822 case GL_COLOR_ATTACHMENT28:
1823 case GL_COLOR_ATTACHMENT29:
1824 case GL_COLOR_ATTACHMENT30:
1825 case GL_COLOR_ATTACHMENT31:
1826 switch(format)
1827 {
1828 case sw::FORMAT_R8I:
1829 case sw::FORMAT_G8R8I:
1830 case sw::FORMAT_X8B8G8R8I:
1831 case sw::FORMAT_A8B8G8R8I:
1832 case sw::FORMAT_R16I:
1833 case sw::FORMAT_G16R16I:
1834 case sw::FORMAT_X16B16G16R16I:
1835 case sw::FORMAT_A16B16G16R16I:
1836 case sw::FORMAT_R32I:
1837 case sw::FORMAT_G32R32I:
1838 case sw::FORMAT_X32B32G32R32I:
1839 case sw::FORMAT_A32B32G32R32I:
1840 return GL_INT;
1841 case sw::FORMAT_R8UI:
1842 case sw::FORMAT_G8R8UI:
1843 case sw::FORMAT_X8B8G8R8UI:
1844 case sw::FORMAT_A8B8G8R8UI:
1845 case sw::FORMAT_R16UI:
1846 case sw::FORMAT_G16R16UI:
1847 case sw::FORMAT_X16B16G16R16UI:
1848 case sw::FORMAT_A16B16G16R16UI:
1849 case sw::FORMAT_R32UI:
1850 case sw::FORMAT_G32R32UI:
1851 case sw::FORMAT_X32B32G32R32UI:
1852 case sw::FORMAT_A32B32G32R32UI:
1853 return GL_UNSIGNED_INT;
1854 case sw::FORMAT_R16F:
1855 case sw::FORMAT_G16R16F:
1856 case sw::FORMAT_B16G16R16F:
1857 case sw::FORMAT_A16B16G16R16F:
1858 case sw::FORMAT_R32F:
1859 case sw::FORMAT_G32R32F:
1860 case sw::FORMAT_B32G32R32F:
1861 case sw::FORMAT_X32B32G32R32F:
1862 case sw::FORMAT_A32B32G32R32F:
1863 return GL_FLOAT;
1864 case sw::FORMAT_R8:
1865 case sw::FORMAT_G8R8:
1866 case sw::FORMAT_A2B10G10R10:
1867 case sw::FORMAT_A2R10G10B10:
1868 case sw::FORMAT_A8R8G8B8:
1869 case sw::FORMAT_A8B8G8R8:
1870 case sw::FORMAT_X8R8G8B8:
1871 case sw::FORMAT_X8B8G8R8:
1872 case sw::FORMAT_SRGB8_A8:
1873 case sw::FORMAT_SRGB8_X8:
1874 case sw::FORMAT_A1R5G5B5:
1875 case sw::FORMAT_R5G6B5:
1876 return GL_UNSIGNED_NORMALIZED;
1877 case sw::FORMAT_R8I_SNORM:
1878 case sw::FORMAT_X8B8G8R8I_SNORM:
1879 case sw::FORMAT_A8B8G8R8I_SNORM:
1880 case sw::FORMAT_G8R8I_SNORM:
1881 return GL_SIGNED_NORMALIZED;
1882 default:
1883 UNREACHABLE(format);
1884 return 0;
1885 }
1886 case GL_DEPTH_ATTACHMENT:
1887 case GL_STENCIL_ATTACHMENT:
1888 // Only color buffers may have integer components.
1889 return GL_FLOAT;
1890 default:
1891 UNREACHABLE(attachment);
1892 return 0;
1893 }
1894 }
1895
1896 GLenum ConvertBackBufferFormat(sw::Format format)
1897 {
1898 switch(format)
1899 {
1900 case sw::FORMAT_A4R4G4B4: return GL_RGBA4;
1901 case sw::FORMAT_A8R8G8B8: return GL_RGBA8_OES;
1902 case sw::FORMAT_A8B8G8R8: return GL_RGBA8_OES;
1903 case sw::FORMAT_A1R5G5B5: return GL_RGB5_A1;
1904 case sw::FORMAT_R5G6B5: return GL_RGB565;
1905 case sw::FORMAT_X8R8G8B8: return GL_RGB8_OES;
1906 case sw::FORMAT_X8B8G8R8: return GL_RGB8_OES;
1907 case sw::FORMAT_SRGB8_A8: return GL_RGBA8_OES;
1908 case sw::FORMAT_SRGB8_X8: return GL_RGB8_OES;
1909 default:
1910 UNREACHABLE(format);
1911 }
1912
1913 return GL_RGBA4;
1914 }
1915
1916 GLenum ConvertDepthStencilFormat(sw::Format format)
1917 {
1918 switch(format)
1919 {
1920 case sw::FORMAT_D16:
1921 case sw::FORMAT_D24X8:
1922 case sw::FORMAT_D32:
1923 return GL_DEPTH_COMPONENT16;
1924 case sw::FORMAT_D24S8:
1925 return GL_DEPTH24_STENCIL8_OES;
1926 case sw::FORMAT_D32F:
1927 case sw::FORMAT_D32F_COMPLEMENTARY:
1928 case sw::FORMAT_D32F_LOCKABLE:
1929 return GL_DEPTH_COMPONENT32F;
1930 case sw::FORMAT_D32FS8_TEXTURE:
1931 case sw::FORMAT_D32FS8_SHADOW:
1932 return GL_DEPTH32F_STENCIL8;
1933 case sw::FORMAT_S8:
1934 return GL_STENCIL_INDEX8;
1935 default:
1936 UNREACHABLE(format);
1937 }
1938
1939 return GL_DEPTH24_STENCIL8_OES;
1940 }
1941}