• 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 es1
27 {
IsCompressed(GLenum format)28 	bool IsCompressed(GLenum format)
29 	{
30 		return format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
31 		       format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ||
32                format == GL_ETC1_RGB8_OES;
33 	}
34 
IsDepthTexture(GLenum format)35 	bool IsDepthTexture(GLenum format)
36 	{
37 		return format == GL_DEPTH_STENCIL_OES;
38 	}
39 
IsStencilTexture(GLenum format)40 	bool IsStencilTexture(GLenum format)
41 	{
42 		return format == GL_DEPTH_STENCIL_OES;
43 	}
44 
IsCubemapTextureTarget(GLenum target)45 	bool IsCubemapTextureTarget(GLenum target)
46 	{
47 		return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES);
48 	}
49 
CubeFaceIndex(GLenum cubeFace)50 	int CubeFaceIndex(GLenum cubeFace)
51 	{
52 		switch(cubeFace)
53 		{
54 		case GL_TEXTURE_CUBE_MAP_OES:
55 		case GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES: return 0;
56 		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_OES: return 1;
57 		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_OES: return 2;
58 		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_OES: return 3;
59 		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_OES: return 4;
60 		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES: return 5;
61 		default: UNREACHABLE(cubeFace); return 0;
62 		}
63 	}
64 
IsTextureTarget(GLenum target)65 	bool IsTextureTarget(GLenum target)
66 	{
67 		return target == GL_TEXTURE_2D;
68 	}
69 
70 	// Verify that format/type are one of the combinations from table 3.4.
CheckTextureFormatType(GLenum format,GLenum type)71 	bool CheckTextureFormatType(GLenum format, GLenum type)
72 	{
73 		switch(type)
74 		{
75 		case GL_UNSIGNED_BYTE:
76 			switch(format)
77 			{
78 			case GL_RGBA:
79 			case GL_BGRA_EXT:
80 			case GL_RGB:
81 			case GL_ALPHA:
82 			case GL_LUMINANCE:
83 			case GL_LUMINANCE_ALPHA:
84 				return true;
85 			default:
86 				return false;
87 			}
88 		case GL_FLOAT:
89 		case GL_UNSIGNED_SHORT_4_4_4_4:
90 		case GL_UNSIGNED_SHORT_5_5_5_1:
91 			return (format == GL_RGBA);
92 		case GL_UNSIGNED_SHORT_5_6_5:
93 			return (format == GL_RGB);
94 		case GL_UNSIGNED_INT_24_8_OES:
95 			return (format == GL_DEPTH_STENCIL_OES);
96 		default:
97 			return false;
98 		}
99 	}
100 
IsColorRenderable(GLenum internalformat)101 	bool IsColorRenderable(GLenum internalformat)
102 	{
103 		switch(internalformat)
104 		{
105 		case GL_RGB:
106 		case GL_RGBA:
107 		case GL_RGBA4_OES:
108 		case GL_RGB5_A1_OES:
109 		case GL_RGB565_OES:
110 		case GL_RGB8_OES:
111 		case GL_RGBA8_OES:
112 			return true;
113 		case GL_DEPTH_COMPONENT16_OES:
114 		case GL_STENCIL_INDEX8_OES:
115 		case GL_DEPTH24_STENCIL8_OES:
116 			return false;
117 		default:
118 			UNIMPLEMENTED();
119 		}
120 
121 		return false;
122 	}
123 
IsDepthRenderable(GLenum internalformat)124 	bool IsDepthRenderable(GLenum internalformat)
125 	{
126 		switch(internalformat)
127 		{
128 		case GL_DEPTH_COMPONENT16_OES:
129 		case GL_DEPTH24_STENCIL8_OES:
130 			return true;
131 		case GL_STENCIL_INDEX8_OES:
132 		case GL_RGBA4_OES:
133 		case GL_RGB5_A1_OES:
134 		case GL_RGB565_OES:
135 		case GL_RGB8_OES:
136 		case GL_RGBA8_OES:
137 			return false;
138 		default:
139 			UNIMPLEMENTED();
140 		}
141 
142 		return false;
143 	}
144 
IsStencilRenderable(GLenum internalformat)145 	bool IsStencilRenderable(GLenum internalformat)
146 	{
147 		switch(internalformat)
148 		{
149 		case GL_STENCIL_INDEX8_OES:
150 		case GL_DEPTH24_STENCIL8_OES:
151 			return true;
152 		case GL_RGBA4_OES:
153 		case GL_RGB5_A1_OES:
154 		case GL_RGB565_OES:
155 		case GL_RGB8_OES:
156 		case GL_RGBA8_OES:
157 		case GL_DEPTH_COMPONENT16_OES:
158 			return false;
159 		default:
160 			UNIMPLEMENTED();
161 		}
162 
163 		return false;
164 	}
165 
IsAlpha(GLenum texFormat)166 	bool IsAlpha(GLenum texFormat)
167 	{
168 		switch(texFormat)
169 		{
170 		case GL_ALPHA:
171 			return true;
172 		default:
173 			return false;
174 		}
175 	}
176 
IsRGB(GLenum texFormat)177 	bool IsRGB(GLenum texFormat)
178 	{
179 		switch(texFormat)
180 		{
181 		case GL_LUMINANCE:
182 		case GL_RGB:
183 		case GL_RGB565_OES:   // GL_OES_framebuffer_object
184 		case GL_RGB8_OES:     // GL_OES_rgb8_rgba8
185 		case SW_YV12_BT601:
186 		case SW_YV12_BT709:
187 		case SW_YV12_JFIF:
188 			return true;
189 		default:
190 			return false;
191 		}
192 	}
193 
IsRGBA(GLenum texFormat)194 	bool IsRGBA(GLenum texFormat)
195 	{
196 		switch(texFormat)
197 		{
198 		case GL_LUMINANCE_ALPHA:
199 		case GL_RGBA:
200 		case GL_BGRA_EXT:      // GL_EXT_texture_format_BGRA8888
201 		case GL_RGBA4_OES:     // GL_OES_framebuffer_object
202 		case GL_RGB5_A1_OES:   // GL_OES_framebuffer_object
203 		case GL_RGBA8_OES:     // GL_OES_rgb8_rgba8
204 			return true;
205 		default:
206 			return false;
207 		}
208 	}
209 }
210 
211 namespace es2sw
212 {
ConvertDepthComparison(GLenum comparison)213 	sw::DepthCompareMode ConvertDepthComparison(GLenum comparison)
214 	{
215 		switch(comparison)
216 		{
217 		case GL_NEVER:    return sw::DEPTH_NEVER;
218 		case GL_ALWAYS:   return sw::DEPTH_ALWAYS;
219 		case GL_LESS:     return sw::DEPTH_LESS;
220 		case GL_LEQUAL:   return sw::DEPTH_LESSEQUAL;
221 		case GL_EQUAL:    return sw::DEPTH_EQUAL;
222 		case GL_GREATER:  return sw::DEPTH_GREATER;
223 		case GL_GEQUAL:   return sw::DEPTH_GREATEREQUAL;
224 		case GL_NOTEQUAL: return sw::DEPTH_NOTEQUAL;
225 		default: UNREACHABLE(comparison);
226 		}
227 
228 		return sw::DEPTH_ALWAYS;
229 	}
230 
ConvertStencilComparison(GLenum comparison)231 	sw::StencilCompareMode ConvertStencilComparison(GLenum comparison)
232 	{
233 		switch(comparison)
234 		{
235 		case GL_NEVER:    return sw::STENCIL_NEVER;
236 		case GL_ALWAYS:   return sw::STENCIL_ALWAYS;
237 		case GL_LESS:     return sw::STENCIL_LESS;
238 		case GL_LEQUAL:   return sw::STENCIL_LESSEQUAL;
239 		case GL_EQUAL:    return sw::STENCIL_EQUAL;
240 		case GL_GREATER:  return sw::STENCIL_GREATER;
241 		case GL_GEQUAL:   return sw::STENCIL_GREATEREQUAL;
242 		case GL_NOTEQUAL: return sw::STENCIL_NOTEQUAL;
243 		default: UNREACHABLE(comparison);
244 		}
245 
246 		return sw::STENCIL_ALWAYS;
247 	}
248 
ConvertAlphaComparison(GLenum comparison)249 	sw::AlphaCompareMode ConvertAlphaComparison(GLenum comparison)
250 	{
251 		switch(comparison)
252 		{
253 		case GL_NEVER:    return sw::ALPHA_NEVER;
254 		case GL_ALWAYS:   return sw::ALPHA_ALWAYS;
255 		case GL_LESS:     return sw::ALPHA_LESS;
256 		case GL_LEQUAL:   return sw::ALPHA_LESSEQUAL;
257 		case GL_EQUAL:    return sw::ALPHA_EQUAL;
258 		case GL_GREATER:  return sw::ALPHA_GREATER;
259 		case GL_GEQUAL:   return sw::ALPHA_GREATEREQUAL;
260 		case GL_NOTEQUAL: return sw::ALPHA_NOTEQUAL;
261 		default: UNREACHABLE(comparison);
262 		}
263 
264 		return sw::ALPHA_ALWAYS;
265 	}
266 
ConvertColor(es1::Color color)267 	sw::Color<float> ConvertColor(es1::Color color)
268 	{
269 		return sw::Color<float>(color.red, color.green, color.blue, color.alpha);
270 	}
271 
ConvertBlendFunc(GLenum blend)272 	sw::BlendFactor ConvertBlendFunc(GLenum blend)
273 	{
274 		switch(blend)
275 		{
276 		case GL_ZERO:                     return sw::BLEND_ZERO;
277 		case GL_ONE:                      return sw::BLEND_ONE;
278 		case GL_SRC_COLOR:                return sw::BLEND_SOURCE;
279 		case GL_ONE_MINUS_SRC_COLOR:      return sw::BLEND_INVSOURCE;
280 		case GL_DST_COLOR:                return sw::BLEND_DEST;
281 		case GL_ONE_MINUS_DST_COLOR:      return sw::BLEND_INVDEST;
282 		case GL_SRC_ALPHA:                return sw::BLEND_SOURCEALPHA;
283 		case GL_ONE_MINUS_SRC_ALPHA:      return sw::BLEND_INVSOURCEALPHA;
284 		case GL_DST_ALPHA:                return sw::BLEND_DESTALPHA;
285 		case GL_ONE_MINUS_DST_ALPHA:      return sw::BLEND_INVDESTALPHA;
286 		case GL_SRC_ALPHA_SATURATE:       return sw::BLEND_SRCALPHASAT;
287 		default: UNREACHABLE(blend);
288 		}
289 
290 		return sw::BLEND_ZERO;
291 	}
292 
ConvertBlendOp(GLenum blendOp)293 	sw::BlendOperation ConvertBlendOp(GLenum blendOp)
294 	{
295 		switch(blendOp)
296 		{
297 		case GL_FUNC_ADD_OES:              return sw::BLENDOP_ADD;
298 		case GL_FUNC_SUBTRACT_OES:         return sw::BLENDOP_SUB;
299 		case GL_FUNC_REVERSE_SUBTRACT_OES: return sw::BLENDOP_INVSUB;
300 		case GL_MIN_EXT:                   return sw::BLENDOP_MIN;
301 		case GL_MAX_EXT:                   return sw::BLENDOP_MAX;
302 		default: UNREACHABLE(blendOp);
303 		}
304 
305 		return sw::BLENDOP_ADD;
306 	}
307 
ConvertLogicalOperation(GLenum logicalOperation)308 	sw::LogicalOperation ConvertLogicalOperation(GLenum logicalOperation)
309 	{
310 		switch(logicalOperation)
311 		{
312 		case GL_CLEAR:         return sw::LOGICALOP_CLEAR;
313 		case GL_SET:           return sw::LOGICALOP_SET;
314 		case GL_COPY:          return sw::LOGICALOP_COPY;
315 		case GL_COPY_INVERTED: return sw::LOGICALOP_COPY_INVERTED;
316 		case GL_NOOP:          return sw::LOGICALOP_NOOP;
317 		case GL_INVERT:        return sw::LOGICALOP_INVERT;
318 		case GL_AND:           return sw::LOGICALOP_AND;
319 		case GL_NAND:          return sw::LOGICALOP_NAND;
320 		case GL_OR:            return sw::LOGICALOP_OR;
321 		case GL_NOR:           return sw::LOGICALOP_NOR;
322 		case GL_XOR:           return sw::LOGICALOP_XOR;
323 		case GL_EQUIV:         return sw::LOGICALOP_EQUIV;
324 		case GL_AND_REVERSE:   return sw::LOGICALOP_AND_REVERSE;
325 		case GL_AND_INVERTED:  return sw::LOGICALOP_AND_INVERTED;
326 		case GL_OR_REVERSE:    return sw::LOGICALOP_OR_REVERSE;
327 		case GL_OR_INVERTED:   return sw::LOGICALOP_OR_INVERTED;
328 		default: UNREACHABLE(logicalOperation);
329 		}
330 
331 		return sw::LOGICALOP_COPY;
332 	}
333 
ConvertStencilOp(GLenum stencilOp)334 	sw::StencilOperation ConvertStencilOp(GLenum stencilOp)
335 	{
336 		switch(stencilOp)
337 		{
338 		case GL_ZERO:          return sw::OPERATION_ZERO;
339 		case GL_KEEP:          return sw::OPERATION_KEEP;
340 		case GL_REPLACE:       return sw::OPERATION_REPLACE;
341 		case GL_INCR:          return sw::OPERATION_INCRSAT;
342 		case GL_DECR:          return sw::OPERATION_DECRSAT;
343 		case GL_INVERT:        return sw::OPERATION_INVERT;
344 		case GL_INCR_WRAP_OES: return sw::OPERATION_INCR;
345 		case GL_DECR_WRAP_OES: return sw::OPERATION_DECR;
346 		default: UNREACHABLE(stencilOp);
347 		}
348 
349 		return sw::OPERATION_KEEP;
350 	}
351 
ConvertTextureWrap(GLenum wrap)352 	sw::AddressingMode ConvertTextureWrap(GLenum wrap)
353 	{
354 		switch(wrap)
355 		{
356 		case GL_REPEAT:              return sw::ADDRESSING_WRAP;
357 		case GL_CLAMP_TO_EDGE:       return sw::ADDRESSING_CLAMP;
358 		case GL_MIRRORED_REPEAT_OES: return sw::ADDRESSING_MIRROR;
359 		default: UNREACHABLE(wrap);
360 		}
361 
362 		return sw::ADDRESSING_WRAP;
363 	}
364 
ConvertCullMode(GLenum cullFace,GLenum frontFace)365 	sw::CullMode ConvertCullMode(GLenum cullFace, GLenum frontFace)
366 	{
367 		switch(cullFace)
368 		{
369 		case GL_FRONT:
370 			return (frontFace == GL_CCW ? sw::CULL_CLOCKWISE : sw::CULL_COUNTERCLOCKWISE);
371 		case GL_BACK:
372 			return (frontFace == GL_CCW ? sw::CULL_COUNTERCLOCKWISE : sw::CULL_CLOCKWISE);
373 		case GL_FRONT_AND_BACK:
374 			return sw::CULL_NONE;   // culling will be handled during draw
375 		default: UNREACHABLE(cullFace);
376 		}
377 
378 		return sw::CULL_COUNTERCLOCKWISE;
379 	}
380 
ConvertColorMask(bool red,bool green,bool blue,bool alpha)381 	unsigned int ConvertColorMask(bool red, bool green, bool blue, bool alpha)
382 	{
383 		return (red   ? 0x00000001 : 0) |
384 			   (green ? 0x00000002 : 0) |
385 			   (blue  ? 0x00000004 : 0) |
386 			   (alpha ? 0x00000008 : 0);
387 	}
388 
ConvertMipMapFilter(GLenum minFilter)389 	sw::MipmapType ConvertMipMapFilter(GLenum minFilter)
390 	{
391 		switch(minFilter)
392 		{
393 		case GL_NEAREST:
394 		case GL_LINEAR:
395 			return sw::MIPMAP_NONE;
396 			break;
397 		case GL_NEAREST_MIPMAP_NEAREST:
398 		case GL_LINEAR_MIPMAP_NEAREST:
399 			return sw::MIPMAP_POINT;
400 			break;
401 		case GL_NEAREST_MIPMAP_LINEAR:
402 		case GL_LINEAR_MIPMAP_LINEAR:
403 			return sw::MIPMAP_LINEAR;
404 			break;
405 		default:
406 			UNREACHABLE(minFilter);
407 			return sw::MIPMAP_NONE;
408 		}
409 	}
410 
ConvertTextureFilter(GLenum minFilter,GLenum magFilter,float maxAnisotropy)411 	sw::FilterType ConvertTextureFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy)
412 	{
413 		if(maxAnisotropy > 1.0f)
414 		{
415 			return sw::FILTER_ANISOTROPIC;
416 		}
417 
418 		sw::FilterType magFilterType = sw::FILTER_POINT;
419 		switch(magFilter)
420 		{
421 		case GL_NEAREST: magFilterType = sw::FILTER_POINT;  break;
422 		case GL_LINEAR:  magFilterType = sw::FILTER_LINEAR; break;
423 		default: UNREACHABLE(magFilter);
424 		}
425 
426 		switch(minFilter)
427 		{
428 		case GL_NEAREST:
429 		case GL_NEAREST_MIPMAP_NEAREST:
430 		case GL_NEAREST_MIPMAP_LINEAR:
431 			return (magFilterType == sw::FILTER_POINT) ? sw::FILTER_POINT : sw::FILTER_MIN_POINT_MAG_LINEAR;
432 		case GL_LINEAR:
433 		case GL_LINEAR_MIPMAP_NEAREST:
434 		case GL_LINEAR_MIPMAP_LINEAR:
435 			return (magFilterType == sw::FILTER_POINT) ? sw::FILTER_MIN_LINEAR_MAG_POINT : sw::FILTER_LINEAR;
436 		default:
437 			UNREACHABLE(minFilter);
438 			return (magFilterType == sw::FILTER_POINT) ? sw::FILTER_POINT : sw::FILTER_MIN_POINT_MAG_LINEAR;
439 		}
440 	}
441 
ConvertPrimitiveType(GLenum primitiveType,GLsizei elementCount,GLenum elementType,sw::DrawType & drawType,int & primitiveCount)442 	bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount, GLenum elementType,  sw::DrawType &drawType, int &primitiveCount)
443 	{
444 		switch(primitiveType)
445 		{
446 		case GL_POINTS:
447 			drawType = sw::DRAW_POINTLIST;
448 			primitiveCount = elementCount;
449 			break;
450 		case GL_LINES:
451 			drawType = sw::DRAW_LINELIST;
452 			primitiveCount = elementCount / 2;
453 			break;
454 		case GL_LINE_LOOP:
455 			drawType = sw::DRAW_LINELOOP;
456 			primitiveCount = elementCount;
457 			break;
458 		case GL_LINE_STRIP:
459 			drawType = sw::DRAW_LINESTRIP;
460 			primitiveCount = elementCount - 1;
461 			break;
462 		case GL_TRIANGLES:
463 			drawType = sw::DRAW_TRIANGLELIST;
464 			primitiveCount = elementCount / 3;
465 			break;
466 		case GL_TRIANGLE_STRIP:
467 			drawType = sw::DRAW_TRIANGLESTRIP;
468 			primitiveCount = elementCount - 2;
469 			break;
470 		case GL_TRIANGLE_FAN:
471 			drawType = sw::DRAW_TRIANGLEFAN;
472 			primitiveCount = elementCount - 2;
473 			break;
474 		default:
475 			return false;
476 		}
477 
478 		sw::DrawType elementSize;
479 		switch(elementType)
480 		{
481 		case GL_NONE:           elementSize = sw::DRAW_NONINDEXED; break;
482 		case GL_UNSIGNED_BYTE:  elementSize = sw::DRAW_INDEXED8;   break;
483 		case GL_UNSIGNED_SHORT: elementSize = sw::DRAW_INDEXED16;  break;
484 		case GL_UNSIGNED_INT:   elementSize = sw::DRAW_INDEXED32;  break;
485 		default: return false;
486 		}
487 
488 		drawType = sw::DrawType(drawType | elementSize);
489 
490 		return true;
491 	}
492 
ConvertRenderbufferFormat(GLenum format)493 	sw::Format ConvertRenderbufferFormat(GLenum format)
494 	{
495 		switch(format)
496 		{
497 		case GL_RGBA4_OES:
498 		case GL_RGB5_A1_OES:
499 		case GL_RGBA8_OES:            return sw::FORMAT_A8B8G8R8;
500 		case GL_RGB565_OES:           return sw::FORMAT_R5G6B5;
501 		case GL_RGB8_OES:             return sw::FORMAT_X8B8G8R8;
502 		case GL_DEPTH_COMPONENT16_OES:
503 		case GL_STENCIL_INDEX8_OES:
504 		case GL_DEPTH24_STENCIL8_OES: return sw::FORMAT_D24S8;
505 		default: UNREACHABLE(format); return sw::FORMAT_A8B8G8R8;
506 		}
507 	}
508 
ConvertCombineOperation(GLenum operation)509 	sw::TextureStage::StageOperation ConvertCombineOperation(GLenum operation)
510 	{
511 		switch(operation)
512 		{
513 		case GL_REPLACE:        return sw::TextureStage::STAGE_SELECTARG1;
514 		case GL_MODULATE:       return sw::TextureStage::STAGE_MODULATE;
515 		case GL_ADD:            return sw::TextureStage::STAGE_ADD;
516 		case GL_ADD_SIGNED:     return sw::TextureStage::STAGE_ADDSIGNED;
517 		case GL_INTERPOLATE:    return sw::TextureStage::STAGE_LERP;
518 		case GL_SUBTRACT:       return sw::TextureStage::STAGE_SUBTRACT;
519 		case GL_DOT3_RGB:       return sw::TextureStage::STAGE_DOT3;
520 		case GL_DOT3_RGBA:      return sw::TextureStage::STAGE_DOT3;
521 		default: UNREACHABLE(operation); return sw::TextureStage::STAGE_SELECTARG1;
522 		}
523 	}
524 
ConvertSourceArgument(GLenum argument)525 	sw::TextureStage::SourceArgument ConvertSourceArgument(GLenum argument)
526 	{
527 		switch(argument)
528 		{
529 		case GL_TEXTURE:        return sw::TextureStage::SOURCE_TEXTURE;
530 		case GL_CONSTANT:       return sw::TextureStage::SOURCE_CONSTANT;
531 		case GL_PRIMARY_COLOR:  return sw::TextureStage::SOURCE_DIFFUSE;
532 		case GL_PREVIOUS:       return sw::TextureStage::SOURCE_CURRENT;
533 		default: UNREACHABLE(argument); return sw::TextureStage::SOURCE_CURRENT;
534 		}
535 	}
536 
ConvertSourceOperand(GLenum operand)537 	sw::TextureStage::ArgumentModifier ConvertSourceOperand(GLenum operand)
538 	{
539 		switch(operand)
540 		{
541 		case GL_SRC_COLOR:           return sw::TextureStage::MODIFIER_COLOR;
542 		case GL_ONE_MINUS_SRC_COLOR: return sw::TextureStage::MODIFIER_INVCOLOR;
543 		case GL_SRC_ALPHA:           return sw::TextureStage::MODIFIER_ALPHA;
544 		case GL_ONE_MINUS_SRC_ALPHA: return sw::TextureStage::MODIFIER_INVALPHA;
545 		default: UNREACHABLE(operand);      return sw::TextureStage::MODIFIER_COLOR;
546 		}
547 	}
548 }
549 
550 namespace sw2es
551 {
GetStencilSize(sw::Format stencilFormat)552 	unsigned int GetStencilSize(sw::Format stencilFormat)
553 	{
554 		switch(stencilFormat)
555 		{
556 		case sw::FORMAT_D24FS8:
557 		case sw::FORMAT_D24S8:
558 		case sw::FORMAT_D32FS8_TEXTURE:
559 			return 8;
560 	//	case sw::FORMAT_D24X4S4:
561 	//		return 4;
562 	//	case sw::FORMAT_D15S1:
563 	//		return 1;
564 	//	case sw::FORMAT_D16_LOCKABLE:
565 		case sw::FORMAT_D32:
566 		case sw::FORMAT_D24X8:
567 		case sw::FORMAT_D32F_LOCKABLE:
568 		case sw::FORMAT_D16:
569 			return 0;
570 	//	case sw::FORMAT_D32_LOCKABLE:  return 0;
571 	//	case sw::FORMAT_S8_LOCKABLE:   return 8;
572 		default:
573 			return 0;
574 		}
575 	}
576 
GetAlphaSize(sw::Format colorFormat)577 	unsigned int GetAlphaSize(sw::Format colorFormat)
578 	{
579 		switch(colorFormat)
580 		{
581 		case sw::FORMAT_A16B16G16R16F:
582 			return 16;
583 		case sw::FORMAT_A32B32G32R32F:
584 			return 32;
585 		case sw::FORMAT_A2R10G10B10:
586 			return 2;
587 		case sw::FORMAT_A8R8G8B8:
588 		case sw::FORMAT_A8B8G8R8:
589 			return 8;
590 		case sw::FORMAT_A1R5G5B5:
591 			return 1;
592 		case sw::FORMAT_X8R8G8B8:
593 		case sw::FORMAT_X8B8G8R8:
594 		case sw::FORMAT_R5G6B5:
595 			return 0;
596 		default:
597 			return 0;
598 		}
599 	}
600 
GetRedSize(sw::Format colorFormat)601 	unsigned int GetRedSize(sw::Format colorFormat)
602 	{
603 		switch(colorFormat)
604 		{
605 		case sw::FORMAT_A16B16G16R16F:
606 			return 16;
607 		case sw::FORMAT_A32B32G32R32F:
608 			return 32;
609 		case sw::FORMAT_A2R10G10B10:
610 			return 10;
611 		case sw::FORMAT_A8R8G8B8:
612 		case sw::FORMAT_A8B8G8R8:
613 		case sw::FORMAT_X8R8G8B8:
614 		case sw::FORMAT_X8B8G8R8:
615 			return 8;
616 		case sw::FORMAT_A1R5G5B5:
617 		case sw::FORMAT_R5G6B5:
618 			return 5;
619 		default:
620 			return 0;
621 		}
622 	}
623 
GetGreenSize(sw::Format colorFormat)624 	unsigned int GetGreenSize(sw::Format colorFormat)
625 	{
626 		switch(colorFormat)
627 		{
628 		case sw::FORMAT_A16B16G16R16F:
629 			return 16;
630 		case sw::FORMAT_A32B32G32R32F:
631 			return 32;
632 		case sw::FORMAT_A2R10G10B10:
633 			return 10;
634 		case sw::FORMAT_A8R8G8B8:
635 		case sw::FORMAT_A8B8G8R8:
636 		case sw::FORMAT_X8R8G8B8:
637 		case sw::FORMAT_X8B8G8R8:
638 			return 8;
639 		case sw::FORMAT_A1R5G5B5:
640 			return 5;
641 		case sw::FORMAT_R5G6B5:
642 			return 6;
643 		default:
644 			return 0;
645 		}
646 	}
647 
GetBlueSize(sw::Format colorFormat)648 	unsigned int GetBlueSize(sw::Format colorFormat)
649 	{
650 		switch(colorFormat)
651 		{
652 		case sw::FORMAT_A16B16G16R16F:
653 			return 16;
654 		case sw::FORMAT_A32B32G32R32F:
655 			return 32;
656 		case sw::FORMAT_A2R10G10B10:
657 			return 10;
658 		case sw::FORMAT_A8R8G8B8:
659 		case sw::FORMAT_A8B8G8R8:
660 		case sw::FORMAT_X8R8G8B8:
661 		case sw::FORMAT_X8B8G8R8:
662 			return 8;
663 		case sw::FORMAT_A1R5G5B5:
664 		case sw::FORMAT_R5G6B5:
665 			return 5;
666 		default:
667 			return 0;
668 		}
669 	}
670 
GetDepthSize(sw::Format depthFormat)671 	unsigned int GetDepthSize(sw::Format depthFormat)
672 	{
673 		switch(depthFormat)
674 		{
675 	//	case sw::FORMAT_D16_LOCKABLE:   return 16;
676 		case sw::FORMAT_D32:            return 32;
677 	//	case sw::FORMAT_D15S1:          return 15;
678 		case sw::FORMAT_D24S8:          return 24;
679 		case sw::FORMAT_D24X8:          return 24;
680 	//	case sw::FORMAT_D24X4S4:        return 24;
681 		case sw::FORMAT_D16:            return 16;
682 		case sw::FORMAT_D32F_LOCKABLE:  return 32;
683 		case sw::FORMAT_D24FS8:         return 24;
684 	//	case sw::FORMAT_D32_LOCKABLE:   return 32;
685 	//	case sw::FORMAT_S8_LOCKABLE:    return 0;
686 		case sw::FORMAT_D32FS8_TEXTURE: return 32;
687 		default:                        return 0;
688 		}
689 	}
690 
ConvertBackBufferFormat(sw::Format format)691 	GLenum ConvertBackBufferFormat(sw::Format format)
692 	{
693 		switch(format)
694 		{
695 		case sw::FORMAT_A4R4G4B4: return GL_RGBA4_OES;
696 		case sw::FORMAT_A8R8G8B8: return GL_RGBA8_OES;
697 		case sw::FORMAT_A8B8G8R8: return GL_RGBA8_OES;
698 		case sw::FORMAT_A1R5G5B5: return GL_RGB5_A1_OES;
699 		case sw::FORMAT_R5G6B5:   return GL_RGB565_OES;
700 		case sw::FORMAT_X8R8G8B8: return GL_RGB8_OES;
701 		case sw::FORMAT_X8B8G8R8: return GL_RGB8_OES;
702 		default:
703 			UNREACHABLE(format);
704 		}
705 
706 		return GL_RGBA4_OES;
707 	}
708 
ConvertDepthStencilFormat(sw::Format format)709 	GLenum ConvertDepthStencilFormat(sw::Format format)
710 	{
711 		switch(format)
712 		{
713 		case sw::FORMAT_D16:
714 		case sw::FORMAT_D24X8:
715 		case sw::FORMAT_D32:
716 			return GL_DEPTH_COMPONENT16_OES;
717 		case sw::FORMAT_D24S8:
718 			return GL_DEPTH24_STENCIL8_OES;
719 		default:
720 			UNREACHABLE(format);
721 		}
722 
723 		return GL_DEPTH24_STENCIL8_OES;
724 	}
725 }
726