• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 // utilities.cpp: Conversion functions and other utility routines.
16 
17 #include "utilities.h"
18 
19 #include "mathutil.h"
20 #include "Context.h"
21 #include "common/debug.h"
22 
23 #include <limits>
24 #include <stdio.h>
25 
26 namespace gl
27 {
UniformComponentCount(GLenum type)28 	unsigned int UniformComponentCount(GLenum type)
29 	{
30 		switch(type)
31 		{
32 		case GL_BOOL:
33 		case GL_FLOAT:
34 		case GL_INT:
35 		case GL_SAMPLER_2D:
36 		case GL_SAMPLER_CUBE:
37 			return 1;
38 		case GL_BOOL_VEC2:
39 		case GL_FLOAT_VEC2:
40 		case GL_INT_VEC2:
41 			return 2;
42 		case GL_INT_VEC3:
43 		case GL_FLOAT_VEC3:
44 		case GL_BOOL_VEC3:
45 			return 3;
46 		case GL_BOOL_VEC4:
47 		case GL_FLOAT_VEC4:
48 		case GL_INT_VEC4:
49 		case GL_FLOAT_MAT2:
50 			return 4;
51 		case GL_FLOAT_MAT3:
52 			return 9;
53 		case GL_FLOAT_MAT4:
54 			return 16;
55 		default:
56 			UNREACHABLE(type);
57 		}
58 
59 		return 0;
60 	}
61 
UniformComponentType(GLenum type)62 	GLenum UniformComponentType(GLenum type)
63 	{
64 		switch(type)
65 		{
66 		case GL_BOOL:
67 		case GL_BOOL_VEC2:
68 		case GL_BOOL_VEC3:
69 		case GL_BOOL_VEC4:
70 			return GL_BOOL;
71 		case GL_FLOAT:
72 		case GL_FLOAT_VEC2:
73 		case GL_FLOAT_VEC3:
74 		case GL_FLOAT_VEC4:
75 		case GL_FLOAT_MAT2:
76 		case GL_FLOAT_MAT3:
77 		case GL_FLOAT_MAT4:
78 			return GL_FLOAT;
79 		case GL_INT:
80 		case GL_SAMPLER_2D:
81 		case GL_SAMPLER_CUBE:
82 		case GL_INT_VEC2:
83 		case GL_INT_VEC3:
84 		case GL_INT_VEC4:
85 			return GL_INT;
86 		default:
87 			UNREACHABLE(type);
88 		}
89 
90 		return GL_NONE;
91 	}
92 
UniformTypeSize(GLenum type)93 	size_t UniformTypeSize(GLenum type)
94 	{
95 		switch(type)
96 		{
97 		case GL_BOOL:  return sizeof(GLboolean);
98 		case GL_FLOAT: return sizeof(GLfloat);
99 		case GL_INT:   return sizeof(GLint);
100 		}
101 
102 		return UniformTypeSize(UniformComponentType(type)) * UniformComponentCount(type);
103 	}
104 
VariableRowCount(GLenum type)105 	int VariableRowCount(GLenum type)
106 	{
107 		switch(type)
108 		{
109 		case GL_NONE:
110 			return 0;
111 		case GL_BOOL:
112 		case GL_FLOAT:
113 		case GL_INT:
114 		case GL_BOOL_VEC2:
115 		case GL_FLOAT_VEC2:
116 		case GL_INT_VEC2:
117 		case GL_INT_VEC3:
118 		case GL_FLOAT_VEC3:
119 		case GL_BOOL_VEC3:
120 		case GL_BOOL_VEC4:
121 		case GL_FLOAT_VEC4:
122 		case GL_INT_VEC4:
123 		case GL_SAMPLER_2D:
124 		case GL_SAMPLER_CUBE:
125 			return 1;
126 		case GL_FLOAT_MAT2:
127 			return 2;
128 		case GL_FLOAT_MAT3:
129 			return 3;
130 		case GL_FLOAT_MAT4:
131 			return 4;
132 		default:
133 			UNREACHABLE(type);
134 		}
135 
136 		return 0;
137 	}
138 
VariableColumnCount(GLenum type)139 	int VariableColumnCount(GLenum type)
140 	{
141 		switch(type)
142 		{
143 		case GL_NONE:
144 			return 0;
145 		case GL_BOOL:
146 		case GL_FLOAT:
147 		case GL_INT:
148 			return 1;
149 		case GL_BOOL_VEC2:
150 		case GL_FLOAT_VEC2:
151 		case GL_INT_VEC2:
152 		case GL_FLOAT_MAT2:
153 			return 2;
154 		case GL_INT_VEC3:
155 		case GL_FLOAT_VEC3:
156 		case GL_BOOL_VEC3:
157 		case GL_FLOAT_MAT3:
158 			return 3;
159 		case GL_BOOL_VEC4:
160 		case GL_FLOAT_VEC4:
161 		case GL_INT_VEC4:
162 		case GL_FLOAT_MAT4:
163 			return 4;
164 		default:
165 			UNREACHABLE(type);
166 		}
167 
168 		return 0;
169 	}
170 
AllocateFirstFreeBits(unsigned int * bits,unsigned int allocationSize,unsigned int bitsSize)171 	int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize)
172 	{
173 		ASSERT(allocationSize <= bitsSize);
174 
175 		unsigned int mask = std::numeric_limits<unsigned int>::max() >> (std::numeric_limits<unsigned int>::digits - allocationSize);
176 
177 		for(unsigned int i = 0; i < bitsSize - allocationSize + 1; i++)
178 		{
179 			if((*bits & mask) == 0)
180 			{
181 				*bits |= mask;
182 				return i;
183 			}
184 
185 			mask <<= 1;
186 		}
187 
188 		return -1;
189 	}
190 
ComputePitch(GLsizei width,GLenum format,GLenum type,GLint alignment)191 	GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment)
192 	{
193 		ASSERT(alignment > 0 && isPow2(alignment));
194 
195 		GLsizei rawPitch = ComputePixelSize(format, type) * width;
196 		return (rawPitch + alignment - 1) & ~(alignment - 1);
197 	}
198 
ComputeCompressedPitch(GLsizei width,GLenum format)199 	GLsizei ComputeCompressedPitch(GLsizei width, GLenum format)
200 	{
201 		return ComputeCompressedSize(width, 1, format);
202 	}
203 
ComputeCompressedSize(GLsizei width,GLsizei height,GLenum format)204 	GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format)
205 	{
206 		switch(format)
207 		{
208 		case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
209 		case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
210 			return 8 * (GLsizei)ceil((float)width / 4.0f) * (GLsizei)ceil((float)height / 4.0f);
211 		case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
212 		case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
213 			return 16 * (GLsizei)ceil((float)width / 4.0f) * (GLsizei)ceil((float)height / 4.0f);
214 		default:
215 			return 0;
216 		}
217 	}
218 
IsCompressed(GLenum format)219 	bool IsCompressed(GLenum format)
220 	{
221 		return format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
222 		       format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ||
223 		       format == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ||
224 		       format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
225 	}
226 
IsDepthTexture(GLenum format)227 	bool IsDepthTexture(GLenum format)
228 	{
229 		return format == GL_DEPTH_COMPONENT ||
230 		       format == GL_DEPTH_STENCIL_EXT;
231 	}
232 
IsStencilTexture(GLenum format)233 	bool IsStencilTexture(GLenum format)
234 	{
235 		return format == GL_STENCIL_INDEX ||
236 		       format == GL_DEPTH_STENCIL_EXT;
237 	}
238 
239 	// Returns the size, in bytes, of a single texel in an Image
ComputePixelSize(GLenum format,GLenum type)240 	int ComputePixelSize(GLenum format, GLenum type)
241 	{
242 		switch(type)
243 		{
244 		case GL_UNSIGNED_BYTE:
245 			switch(format)
246 			{
247 			case GL_ALPHA:           return sizeof(unsigned char);
248 			case GL_LUMINANCE:       return sizeof(unsigned char);
249 			case GL_LUMINANCE_ALPHA: return sizeof(unsigned char) * 2;
250 			case GL_RGB:             return sizeof(unsigned char) * 3;
251 			case GL_RGBA:            return sizeof(unsigned char) * 4;
252 			case GL_BGRA_EXT:        return sizeof(unsigned char) * 4;
253 			default: UNREACHABLE(format);
254 			}
255 			break;
256 		case GL_UNSIGNED_SHORT_4_4_4_4:
257 		case GL_UNSIGNED_SHORT_5_5_5_1:
258 		case GL_UNSIGNED_SHORT_5_6_5:
259 		case GL_UNSIGNED_SHORT:
260 			return sizeof(unsigned short);
261 		case GL_UNSIGNED_INT:
262 		case GL_UNSIGNED_INT_24_8_EXT:
263 		case GL_UNSIGNED_INT_8_8_8_8_REV:
264 			return sizeof(unsigned int);
265 		case GL_FLOAT:
266 			switch(format)
267 			{
268 			case GL_ALPHA:           return sizeof(float);
269 			case GL_LUMINANCE:       return sizeof(float);
270 			case GL_DEPTH_COMPONENT: return sizeof(float);
271 			case GL_LUMINANCE_ALPHA: return sizeof(float) * 2;
272 			case GL_RGB:             return sizeof(float) * 3;
273 			case GL_RGBA:            return sizeof(float) * 4;
274 			default: UNREACHABLE(format);
275 			}
276 			break;
277 		case GL_HALF_FLOAT:
278 			switch(format)
279 			{
280 			case GL_ALPHA:           return sizeof(unsigned short);
281 			case GL_LUMINANCE:       return sizeof(unsigned short);
282 			case GL_LUMINANCE_ALPHA: return sizeof(unsigned short) * 2;
283 			case GL_RGB:             return sizeof(unsigned short) * 3;
284 			case GL_RGBA:            return sizeof(unsigned short) * 4;
285 			default: UNREACHABLE(format);
286 			}
287 			break;
288 		default: UNREACHABLE(type);
289 		}
290 
291 		return 0;
292 	}
293 
IsCubemapTextureTarget(GLenum target)294 	bool IsCubemapTextureTarget(GLenum target)
295 	{
296 		return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
297 	}
298 
CubeFaceIndex(GLenum cubeFace)299 	int CubeFaceIndex(GLenum cubeFace)
300 	{
301 		switch(cubeFace)
302 		{
303 		case GL_TEXTURE_CUBE_MAP:
304 		case GL_TEXTURE_CUBE_MAP_POSITIVE_X: return 0;
305 		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: return 1;
306 		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: return 2;
307 		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: return 3;
308 		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: return 4;
309 		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: return 5;
310 		default: UNREACHABLE(cubeFace); return 0;
311 		}
312 	}
313 
IsTextureTarget(GLenum target)314 	bool IsTextureTarget(GLenum target)
315 	{
316 		return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target);
317 	}
318 
319 	// Verify that format/type are one of the combinations from table 3.4.
CheckTextureFormatType(GLenum format,GLenum type)320 	bool CheckTextureFormatType(GLenum format, GLenum type)
321 	{
322 		switch(type)
323 		{
324 		case GL_UNSIGNED_BYTE:
325 			switch(format)
326 			{
327 			case GL_RGBA:
328 			case GL_BGRA_EXT:
329 			case GL_RGB:
330 			case GL_ALPHA:
331 			case GL_LUMINANCE:
332 			case GL_LUMINANCE_ALPHA:
333 				return true;
334 			default:
335 				return false;
336 			}
337 		case GL_FLOAT:
338 		case GL_HALF_FLOAT:
339 			switch(format)
340 			{
341 			case GL_RGBA:
342 			case GL_RGB:
343 			case GL_ALPHA:
344 			case GL_LUMINANCE:
345 			case GL_LUMINANCE_ALPHA:
346 				return true;
347 			default:
348 				return false;
349 			}
350 		case GL_UNSIGNED_SHORT_4_4_4_4:
351 		case GL_UNSIGNED_SHORT_5_5_5_1:
352 			return (format == GL_RGBA);
353 		case GL_UNSIGNED_SHORT_5_6_5:
354 			return (format == GL_RGB);
355 		case GL_UNSIGNED_INT:
356 			return (format == GL_DEPTH_COMPONENT);
357 		case GL_UNSIGNED_INT_24_8_EXT:
358 			return (format == GL_DEPTH_STENCIL_EXT);
359 		case GL_UNSIGNED_INT_8_8_8_8_REV:
360 			return (format == GL_BGRA);
361 		default:
362 			return false;
363 		}
364 	}
365 
IsColorRenderable(GLenum internalformat)366 	bool IsColorRenderable(GLenum internalformat)
367 	{
368 		switch(internalformat)
369 		{
370 		case GL_RGBA4:
371 		case GL_RGB5_A1:
372 		case GL_RGB565:
373 		case GL_RGB8_EXT:
374 		case GL_RGBA8_EXT:
375 			return true;
376 		case GL_DEPTH_COMPONENT16:
377 		case GL_DEPTH_COMPONENT24:
378 		case GL_STENCIL_INDEX8:
379 		case GL_DEPTH24_STENCIL8_EXT:
380 			return false;
381 		default:
382 			UNIMPLEMENTED();
383 		}
384 
385 		return false;
386 	}
387 
IsDepthRenderable(GLenum internalformat)388 	bool IsDepthRenderable(GLenum internalformat)
389 	{
390 		switch(internalformat)
391 		{
392 		case GL_DEPTH_COMPONENT16:
393 		case GL_DEPTH_COMPONENT24:
394 		case GL_DEPTH24_STENCIL8_EXT:
395 			return true;
396 		case GL_STENCIL_INDEX8:
397 		case GL_RGBA4:
398 		case GL_RGB5_A1:
399 		case GL_RGB565:
400 		case GL_RGB8_EXT:
401 		case GL_RGBA8_EXT:
402 			return false;
403 		default:
404 			UNIMPLEMENTED();
405 		}
406 
407 		return false;
408 	}
409 
IsStencilRenderable(GLenum internalformat)410 	bool IsStencilRenderable(GLenum internalformat)
411 	{
412 		switch(internalformat)
413 		{
414 		case GL_STENCIL_INDEX8:
415 		case GL_DEPTH24_STENCIL8_EXT:
416 			return true;
417 		case GL_RGBA4:
418 		case GL_RGB5_A1:
419 		case GL_RGB565:
420 		case GL_RGB8_EXT:
421 		case GL_RGBA8_EXT:
422 		case GL_DEPTH_COMPONENT16:
423 		case GL_DEPTH_COMPONENT24:
424 			return false;
425 		default:
426 			UNIMPLEMENTED();
427 		}
428 
429 		return false;
430 	}
431 }
432 
433 namespace es2sw
434 {
ConvertDepthComparison(GLenum comparison)435 	sw::DepthCompareMode ConvertDepthComparison(GLenum comparison)
436 	{
437 		switch(comparison)
438 		{
439 		case GL_NEVER:    return sw::DEPTH_NEVER;
440 		case GL_ALWAYS:   return sw::DEPTH_ALWAYS;
441 		case GL_LESS:     return sw::DEPTH_LESS;
442 		case GL_LEQUAL:   return sw::DEPTH_LESSEQUAL;
443 		case GL_EQUAL:    return sw::DEPTH_EQUAL;
444 		case GL_GREATER:  return sw::DEPTH_GREATER;
445 		case GL_GEQUAL:   return sw::DEPTH_GREATEREQUAL;
446 		case GL_NOTEQUAL: return sw::DEPTH_NOTEQUAL;
447 		default: UNREACHABLE(comparison);
448 		}
449 
450 		return sw::DEPTH_ALWAYS;
451 	}
452 
ConvertStencilComparison(GLenum comparison)453 	sw::StencilCompareMode ConvertStencilComparison(GLenum comparison)
454 	{
455 		switch(comparison)
456 		{
457 		case GL_NEVER:    return sw::STENCIL_NEVER;
458 		case GL_ALWAYS:   return sw::STENCIL_ALWAYS;
459 		case GL_LESS:     return sw::STENCIL_LESS;
460 		case GL_LEQUAL:   return sw::STENCIL_LESSEQUAL;
461 		case GL_EQUAL:    return sw::STENCIL_EQUAL;
462 		case GL_GREATER:  return sw::STENCIL_GREATER;
463 		case GL_GEQUAL:   return sw::STENCIL_GREATEREQUAL;
464 		case GL_NOTEQUAL: return sw::STENCIL_NOTEQUAL;
465 		default: UNREACHABLE(comparison);
466 		}
467 
468 		return sw::STENCIL_ALWAYS;
469 	}
470 
ConvertColor(gl::Color color)471 	sw::Color<float> ConvertColor(gl::Color color)
472 	{
473 		return sw::Color<float>(color.red, color.green, color.blue, color.alpha);
474 	}
475 
ConvertBlendFunc(GLenum blend)476 	sw::BlendFactor ConvertBlendFunc(GLenum blend)
477 	{
478 		switch(blend)
479 		{
480 		case GL_ZERO:                     return sw::BLEND_ZERO;
481 		case GL_ONE:                      return sw::BLEND_ONE;
482 		case GL_SRC_COLOR:                return sw::BLEND_SOURCE;
483 		case GL_ONE_MINUS_SRC_COLOR:      return sw::BLEND_INVSOURCE;
484 		case GL_DST_COLOR:                return sw::BLEND_DEST;
485 		case GL_ONE_MINUS_DST_COLOR:      return sw::BLEND_INVDEST;
486 		case GL_SRC_ALPHA:                return sw::BLEND_SOURCEALPHA;
487 		case GL_ONE_MINUS_SRC_ALPHA:      return sw::BLEND_INVSOURCEALPHA;
488 		case GL_DST_ALPHA:                return sw::BLEND_DESTALPHA;
489 		case GL_ONE_MINUS_DST_ALPHA:      return sw::BLEND_INVDESTALPHA;
490 		case GL_CONSTANT_COLOR:           return sw::BLEND_CONSTANT;
491 		case GL_ONE_MINUS_CONSTANT_COLOR: return sw::BLEND_INVCONSTANT;
492 		case GL_CONSTANT_ALPHA:           return sw::BLEND_CONSTANTALPHA;
493 		case GL_ONE_MINUS_CONSTANT_ALPHA: return sw::BLEND_INVCONSTANTALPHA;
494 		case GL_SRC_ALPHA_SATURATE:       return sw::BLEND_SRCALPHASAT;
495 		default: UNREACHABLE(blend);
496 		}
497 
498 		return sw::BLEND_ZERO;
499 	}
500 
ConvertBlendOp(GLenum blendOp)501 	sw::BlendOperation ConvertBlendOp(GLenum blendOp)
502 	{
503 		switch(blendOp)
504 		{
505 		case GL_FUNC_ADD:              return sw::BLENDOP_ADD;
506 		case GL_FUNC_SUBTRACT:         return sw::BLENDOP_SUB;
507 		case GL_FUNC_REVERSE_SUBTRACT: return sw::BLENDOP_INVSUB;
508 		case GL_MIN_EXT:               return sw::BLENDOP_MIN;
509 		case GL_MAX_EXT:               return sw::BLENDOP_MAX;
510 		default: UNREACHABLE(blendOp);
511 		}
512 
513 		return sw::BLENDOP_ADD;
514 	}
515 
ConvertLogicalOperation(GLenum logicalOperation)516 	sw::LogicalOperation ConvertLogicalOperation(GLenum logicalOperation)
517 	{
518 		switch(logicalOperation)
519 		{
520 		case GL_CLEAR:         return sw::LOGICALOP_CLEAR;
521 		case GL_SET:           return sw::LOGICALOP_SET;
522 		case GL_COPY:          return sw::LOGICALOP_COPY;
523 		case GL_COPY_INVERTED: return sw::LOGICALOP_COPY_INVERTED;
524 		case GL_NOOP:          return sw::LOGICALOP_NOOP;
525 		case GL_INVERT:        return sw::LOGICALOP_INVERT;
526 		case GL_AND:           return sw::LOGICALOP_AND;
527 		case GL_NAND:          return sw::LOGICALOP_NAND;
528 		case GL_OR:            return sw::LOGICALOP_OR;
529 		case GL_NOR:           return sw::LOGICALOP_NOR;
530 		case GL_XOR:           return sw::LOGICALOP_XOR;
531 		case GL_EQUIV:         return sw::LOGICALOP_EQUIV;
532 		case GL_AND_REVERSE:   return sw::LOGICALOP_AND_REVERSE;
533 		case GL_AND_INVERTED:  return sw::LOGICALOP_AND_INVERTED;
534 		case GL_OR_REVERSE:    return sw::LOGICALOP_OR_REVERSE;
535 		case GL_OR_INVERTED:   return sw::LOGICALOP_OR_INVERTED;
536 		default: UNREACHABLE(logicalOperation);
537 		}
538 
539 		return sw::LOGICALOP_COPY;
540 	}
541 
ConvertStencilOp(GLenum stencilOp)542 	sw::StencilOperation ConvertStencilOp(GLenum stencilOp)
543 	{
544 		switch(stencilOp)
545 		{
546 		case GL_ZERO:      return sw::OPERATION_ZERO;
547 		case GL_KEEP:      return sw::OPERATION_KEEP;
548 		case GL_REPLACE:   return sw::OPERATION_REPLACE;
549 		case GL_INCR:      return sw::OPERATION_INCRSAT;
550 		case GL_DECR:      return sw::OPERATION_DECRSAT;
551 		case GL_INVERT:    return sw::OPERATION_INVERT;
552 		case GL_INCR_WRAP: return sw::OPERATION_INCR;
553 		case GL_DECR_WRAP: return sw::OPERATION_DECR;
554 		default: UNREACHABLE(stencilOp);
555 		}
556 
557 		return sw::OPERATION_KEEP;
558 	}
559 
ConvertTextureWrap(GLenum wrap)560 	sw::AddressingMode ConvertTextureWrap(GLenum wrap)
561 	{
562 		switch(wrap)
563 		{
564 		case GL_CLAMP:             return sw::ADDRESSING_CLAMP;
565 		case GL_REPEAT:            return sw::ADDRESSING_WRAP;
566 		case GL_CLAMP_TO_EDGE:     return sw::ADDRESSING_CLAMP;
567 		case GL_MIRRORED_REPEAT:   return sw::ADDRESSING_MIRROR;
568 		default: UNREACHABLE(wrap);
569 		}
570 
571 		return sw::ADDRESSING_WRAP;
572 	}
573 
ConvertCullMode(GLenum cullFace,GLenum frontFace)574 	sw::CullMode ConvertCullMode(GLenum cullFace, GLenum frontFace)
575 	{
576 		switch(cullFace)
577 		{
578 		case GL_FRONT:
579 			return (frontFace == GL_CCW ? sw::CULL_CLOCKWISE : sw::CULL_COUNTERCLOCKWISE);
580 		case GL_BACK:
581 			return (frontFace == GL_CCW ? sw::CULL_COUNTERCLOCKWISE : sw::CULL_CLOCKWISE);
582 		case GL_FRONT_AND_BACK:
583 			return sw::CULL_NONE;   // culling will be handled during draw
584 		default: UNREACHABLE(cullFace);
585 		}
586 
587 		return sw::CULL_COUNTERCLOCKWISE;
588 	}
589 
ConvertColorMask(bool red,bool green,bool blue,bool alpha)590 	unsigned int ConvertColorMask(bool red, bool green, bool blue, bool alpha)
591 	{
592 		return (red   ? 0x00000001 : 0) |
593 			   (green ? 0x00000002 : 0) |
594 			   (blue  ? 0x00000004 : 0) |
595 			   (alpha ? 0x00000008 : 0);
596 	}
597 
ConvertMipMapFilter(GLenum minFilter)598 	sw::MipmapType ConvertMipMapFilter(GLenum minFilter)
599 	{
600 		switch(minFilter)
601 		{
602 		case GL_NEAREST:
603 		case GL_LINEAR:
604 			return sw::MIPMAP_NONE;
605 			break;
606 		case GL_NEAREST_MIPMAP_NEAREST:
607 		case GL_LINEAR_MIPMAP_NEAREST:
608 			return sw::MIPMAP_POINT;
609 			break;
610 		case GL_NEAREST_MIPMAP_LINEAR:
611 		case GL_LINEAR_MIPMAP_LINEAR:
612 			return sw::MIPMAP_LINEAR;
613 			break;
614 		default:
615 			UNREACHABLE(minFilter);
616 			return sw::MIPMAP_NONE;
617 		}
618 	}
619 
ConvertTextureFilter(GLenum minFilter,GLenum magFilter,float maxAnisotropy)620 	sw::FilterType ConvertTextureFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy)
621 	{
622 		if(maxAnisotropy > 1.0f)
623 		{
624 			return sw::FILTER_ANISOTROPIC;
625 		}
626 
627 		switch(minFilter)
628 		{
629 		case GL_NEAREST:
630 		case GL_NEAREST_MIPMAP_NEAREST:
631 		case GL_NEAREST_MIPMAP_LINEAR:
632 			return (magFilter == GL_NEAREST) ? sw::FILTER_POINT : sw::FILTER_MIN_POINT_MAG_LINEAR;
633 		case GL_LINEAR:
634 		case GL_LINEAR_MIPMAP_NEAREST:
635 		case GL_LINEAR_MIPMAP_LINEAR:
636 			return (magFilter == GL_NEAREST) ? sw::FILTER_MIN_LINEAR_MAG_POINT : sw::FILTER_LINEAR;
637 		default:
638 			UNREACHABLE(minFilter);
639 			return sw::FILTER_LINEAR;
640 		}
641 	}
642 
ConvertPrimitiveType(GLenum primitiveType,GLsizei elementCount,gl::PrimitiveType & swPrimitiveType,int & primitiveCount)643 	bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount,  gl::PrimitiveType &swPrimitiveType, int &primitiveCount)
644 	{
645 		switch(primitiveType)
646 		{
647 		case GL_POINTS:
648 			swPrimitiveType = gl::DRAW_POINTLIST;
649 			primitiveCount = elementCount;
650 			break;
651 		case GL_LINES:
652 			swPrimitiveType = gl::DRAW_LINELIST;
653 			primitiveCount = elementCount / 2;
654 			break;
655 		case GL_LINE_LOOP:
656 			swPrimitiveType = gl::DRAW_LINELOOP;
657 			primitiveCount = elementCount;
658 			break;
659 		case GL_LINE_STRIP:
660 			swPrimitiveType = gl::DRAW_LINESTRIP;
661 			primitiveCount = elementCount - 1;
662 			break;
663 		case GL_TRIANGLES:
664 			swPrimitiveType = gl::DRAW_TRIANGLELIST;
665 			primitiveCount = elementCount / 3;
666 			break;
667 		case GL_TRIANGLE_STRIP:
668 			swPrimitiveType = gl::DRAW_TRIANGLESTRIP;
669 			primitiveCount = elementCount - 2;
670 			break;
671 		case GL_TRIANGLE_FAN:
672 			swPrimitiveType = gl::DRAW_TRIANGLEFAN;
673 			primitiveCount = elementCount - 2;
674 			break;
675 		case GL_QUADS:
676 			swPrimitiveType = gl::DRAW_QUADLIST;
677 			primitiveCount = (elementCount / 4) * 2;
678 			break;
679 		default:
680 			return false;
681 		}
682 
683 		return true;
684 	}
685 
ConvertRenderbufferFormat(GLenum format)686 	sw::Format ConvertRenderbufferFormat(GLenum format)
687 	{
688 		switch(format)
689 		{
690 		case GL_RGBA4:
691 		case GL_RGB5_A1:
692 		case GL_RGBA8_EXT:            return sw::FORMAT_A8R8G8B8;
693 		case GL_RGB565:               return sw::FORMAT_R5G6B5;
694 		case GL_RGB8_EXT:             return sw::FORMAT_X8R8G8B8;
695 		case GL_DEPTH_COMPONENT16:
696 		case GL_DEPTH_COMPONENT24:
697 		case GL_STENCIL_INDEX8:
698 		case GL_DEPTH24_STENCIL8_EXT: return sw::FORMAT_D24S8;
699 		default: UNREACHABLE(format); return sw::FORMAT_A8R8G8B8;
700 		}
701 	}
702 }
703 
704 namespace sw2es
705 {
GetStencilSize(sw::Format stencilFormat)706 	unsigned int GetStencilSize(sw::Format stencilFormat)
707 	{
708 		switch(stencilFormat)
709 		{
710 		case sw::FORMAT_D24FS8:
711 		case sw::FORMAT_D24S8:
712 		case sw::FORMAT_D32FS8_TEXTURE:
713 			return 8;
714 	//	case sw::FORMAT_D24X4S4:
715 	//		return 4;
716 	//	case sw::FORMAT_D15S1:
717 	//		return 1;
718 	//	case sw::FORMAT_D16_LOCKABLE:
719 		case sw::FORMAT_D32:
720 		case sw::FORMAT_D24X8:
721 		case sw::FORMAT_D32F_LOCKABLE:
722 		case sw::FORMAT_D16:
723 			return 0;
724 	//	case sw::FORMAT_D32_LOCKABLE:  return 0;
725 	//	case sw::FORMAT_S8_LOCKABLE:   return 8;
726 		default:
727 			return 0;
728 		}
729 	}
730 
GetAlphaSize(sw::Format colorFormat)731 	unsigned int GetAlphaSize(sw::Format colorFormat)
732 	{
733 		switch(colorFormat)
734 		{
735 		case sw::FORMAT_A16B16G16R16F:
736 			return 16;
737 		case sw::FORMAT_A32B32G32R32F:
738 			return 32;
739 		case sw::FORMAT_A2R10G10B10:
740 			return 2;
741 		case sw::FORMAT_A8R8G8B8:
742 			return 8;
743 		case sw::FORMAT_A1R5G5B5:
744 			return 1;
745 		case sw::FORMAT_X8R8G8B8:
746 		case sw::FORMAT_R5G6B5:
747 			return 0;
748 		default:
749 			return 0;
750 		}
751 	}
752 
GetRedSize(sw::Format colorFormat)753 	unsigned int GetRedSize(sw::Format colorFormat)
754 	{
755 		switch(colorFormat)
756 		{
757 		case sw::FORMAT_A16B16G16R16F:
758 			return 16;
759 		case sw::FORMAT_A32B32G32R32F:
760 			return 32;
761 		case sw::FORMAT_A2R10G10B10:
762 			return 10;
763 		case sw::FORMAT_A8R8G8B8:
764 		case sw::FORMAT_X8R8G8B8:
765 			return 8;
766 		case sw::FORMAT_A1R5G5B5:
767 		case sw::FORMAT_R5G6B5:
768 			return 5;
769 		default:
770 			return 0;
771 		}
772 	}
773 
GetGreenSize(sw::Format colorFormat)774 	unsigned int GetGreenSize(sw::Format colorFormat)
775 	{
776 		switch(colorFormat)
777 		{
778 		case sw::FORMAT_A16B16G16R16F:
779 			return 16;
780 		case sw::FORMAT_A32B32G32R32F:
781 			return 32;
782 		case sw::FORMAT_A2R10G10B10:
783 			return 10;
784 		case sw::FORMAT_A8R8G8B8:
785 		case sw::FORMAT_X8R8G8B8:
786 			return 8;
787 		case sw::FORMAT_A1R5G5B5:
788 			return 5;
789 		case sw::FORMAT_R5G6B5:
790 			return 6;
791 		default:
792 			return 0;
793 		}
794 	}
795 
GetBlueSize(sw::Format colorFormat)796 	unsigned int GetBlueSize(sw::Format colorFormat)
797 	{
798 		switch(colorFormat)
799 		{
800 		case sw::FORMAT_A16B16G16R16F:
801 			return 16;
802 		case sw::FORMAT_A32B32G32R32F:
803 			return 32;
804 		case sw::FORMAT_A2R10G10B10:
805 			return 10;
806 		case sw::FORMAT_A8R8G8B8:
807 		case sw::FORMAT_X8R8G8B8:
808 			return 8;
809 		case sw::FORMAT_A1R5G5B5:
810 		case sw::FORMAT_R5G6B5:
811 			return 5;
812 		default:
813 			return 0;
814 		}
815 	}
816 
GetDepthSize(sw::Format depthFormat)817 	unsigned int GetDepthSize(sw::Format depthFormat)
818 	{
819 		switch(depthFormat)
820 		{
821 	//	case sw::FORMAT_D16_LOCKABLE:   return 16;
822 		case sw::FORMAT_D32:            return 32;
823 	//	case sw::FORMAT_D15S1:          return 15;
824 		case sw::FORMAT_D24S8:          return 24;
825 		case sw::FORMAT_D24X8:          return 24;
826 	//	case sw::FORMAT_D24X4S4:        return 24;
827 		case sw::FORMAT_D16:            return 16;
828 		case sw::FORMAT_D32F_LOCKABLE:  return 32;
829 		case sw::FORMAT_D24FS8:         return 24;
830 	//	case sw::FORMAT_D32_LOCKABLE:   return 32;
831 	//	case sw::FORMAT_S8_LOCKABLE:    return 0;
832 		case sw::FORMAT_D32FS8_TEXTURE: return 32;
833 		default:                        return 0;
834 		}
835 	}
836 
ConvertBackBufferFormat(sw::Format format)837 	GLenum ConvertBackBufferFormat(sw::Format format)
838 	{
839 		switch(format)
840 		{
841 		case sw::FORMAT_A4R4G4B4: return GL_RGBA4;
842 		case sw::FORMAT_A8R8G8B8: return GL_RGBA8_EXT;
843 		case sw::FORMAT_A1R5G5B5: return GL_RGB5_A1;
844 		case sw::FORMAT_R5G6B5:   return GL_RGB565;
845 		case sw::FORMAT_X8R8G8B8: return GL_RGB8_EXT;
846 		default:
847 			UNREACHABLE(format);
848 		}
849 
850 		return GL_RGBA4;
851 	}
852 
ConvertDepthStencilFormat(sw::Format format)853 	GLenum ConvertDepthStencilFormat(sw::Format format)
854 	{
855 		switch(format)
856 		{
857 		case sw::FORMAT_D16:
858 			return GL_DEPTH_COMPONENT16;
859 		case sw::FORMAT_D32:
860 			return GL_DEPTH_COMPONENT32;
861 		case sw::FORMAT_D24X8:
862 			return GL_DEPTH_COMPONENT24;
863 		case sw::FORMAT_D24S8:
864 			return GL_DEPTH24_STENCIL8_EXT;
865 		default:
866 			UNREACHABLE(format);
867 		}
868 
869 		return GL_DEPTH24_STENCIL8_EXT;
870 	}
871 }
872