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