Home | History | Annotate | Download | only in libGLES_CM
      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 {
     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 
     35 	bool IsDepthTexture(GLenum format)
     36 	{
     37 		return format == GL_DEPTH_STENCIL_OES;
     38 	}
     39 
     40 	bool IsStencilTexture(GLenum format)
     41 	{
     42 		return format == GL_DEPTH_STENCIL_OES;
     43 	}
     44 
     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 
     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 
     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.
     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 
    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 
    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 
    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 
    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 
    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 
    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 {
    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 
    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 
    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 
    267 	sw::Color<float> ConvertColor(es1::Color color)
    268 	{
    269 		return sw::Color<float>(color.red, color.green, color.blue, color.alpha);
    270 	}
    271 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 {
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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