Home | History | Annotate | Download | only in libGLESv2
      1 //
      2 // Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 
      7 // utilities.cpp: Conversion functions and other utility routines.
      8 
      9 #include "libGLESv2/utilities.h"
     10 
     11 #include <limits>
     12 
     13 #include "common/debug.h"
     14 
     15 #include "libGLESv2/mathutil.h"
     16 #include "libGLESv2/Context.h"
     17 
     18 namespace gl
     19 {
     20 
     21 int UniformComponentCount(GLenum type)
     22 {
     23     switch (type)
     24     {
     25       case GL_BOOL:
     26       case GL_FLOAT:
     27       case GL_INT:
     28       case GL_SAMPLER_2D:
     29       case GL_SAMPLER_CUBE:
     30           return 1;
     31       case GL_BOOL_VEC2:
     32       case GL_FLOAT_VEC2:
     33       case GL_INT_VEC2:
     34           return 2;
     35       case GL_INT_VEC3:
     36       case GL_FLOAT_VEC3:
     37       case GL_BOOL_VEC3:
     38           return 3;
     39       case GL_BOOL_VEC4:
     40       case GL_FLOAT_VEC4:
     41       case GL_INT_VEC4:
     42       case GL_FLOAT_MAT2:
     43           return 4;
     44       case GL_FLOAT_MAT3:
     45           return 9;
     46       case GL_FLOAT_MAT4:
     47           return 16;
     48       default:
     49           UNREACHABLE();
     50     }
     51 
     52     return 0;
     53 }
     54 
     55 GLenum UniformComponentType(GLenum type)
     56 {
     57     switch(type)
     58     {
     59       case GL_BOOL:
     60       case GL_BOOL_VEC2:
     61       case GL_BOOL_VEC3:
     62       case GL_BOOL_VEC4:
     63           return GL_BOOL;
     64       case GL_FLOAT:
     65       case GL_FLOAT_VEC2:
     66       case GL_FLOAT_VEC3:
     67       case GL_FLOAT_VEC4:
     68       case GL_FLOAT_MAT2:
     69       case GL_FLOAT_MAT3:
     70       case GL_FLOAT_MAT4:
     71           return GL_FLOAT;
     72       case GL_INT:
     73       case GL_SAMPLER_2D:
     74       case GL_SAMPLER_CUBE:
     75       case GL_INT_VEC2:
     76       case GL_INT_VEC3:
     77       case GL_INT_VEC4:
     78           return GL_INT;
     79       default:
     80           UNREACHABLE();
     81     }
     82 
     83     return GL_NONE;
     84 }
     85 
     86 size_t UniformTypeSize(GLenum type)
     87 {
     88     switch(type)
     89     {
     90       case GL_BOOL:  return sizeof(GLboolean);
     91       case GL_FLOAT: return sizeof(GLfloat);
     92       case GL_INT:   return sizeof(GLint);
     93     }
     94 
     95     return UniformTypeSize(UniformComponentType(type)) * UniformComponentCount(type);
     96 }
     97 
     98 int VariableRowCount(GLenum type)
     99 {
    100     switch (type)
    101     {
    102       case GL_NONE:
    103         return 0;
    104       case GL_BOOL:
    105       case GL_FLOAT:
    106       case GL_INT:
    107       case GL_BOOL_VEC2:
    108       case GL_FLOAT_VEC2:
    109       case GL_INT_VEC2:
    110       case GL_INT_VEC3:
    111       case GL_FLOAT_VEC3:
    112       case GL_BOOL_VEC3:
    113       case GL_BOOL_VEC4:
    114       case GL_FLOAT_VEC4:
    115       case GL_INT_VEC4:
    116         return 1;
    117       case GL_FLOAT_MAT2:
    118         return 2;
    119       case GL_FLOAT_MAT3:
    120         return 3;
    121       case GL_FLOAT_MAT4:
    122         return 4;
    123       default:
    124         UNREACHABLE();
    125     }
    126 
    127     return 0;
    128 }
    129 
    130 int VariableColumnCount(GLenum type)
    131 {
    132     switch (type)
    133     {
    134       case GL_NONE:
    135         return 0;
    136       case GL_BOOL:
    137       case GL_FLOAT:
    138       case GL_INT:
    139         return 1;
    140       case GL_BOOL_VEC2:
    141       case GL_FLOAT_VEC2:
    142       case GL_INT_VEC2:
    143       case GL_FLOAT_MAT2:
    144         return 2;
    145       case GL_INT_VEC3:
    146       case GL_FLOAT_VEC3:
    147       case GL_BOOL_VEC3:
    148       case GL_FLOAT_MAT3:
    149         return 3;
    150       case GL_BOOL_VEC4:
    151       case GL_FLOAT_VEC4:
    152       case GL_INT_VEC4:
    153       case GL_FLOAT_MAT4:
    154         return 4;
    155       default:
    156         UNREACHABLE();
    157     }
    158 
    159     return 0;
    160 }
    161 
    162 int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize)
    163 {
    164     ASSERT(allocationSize <= bitsSize);
    165 
    166     unsigned int mask = std::numeric_limits<unsigned int>::max() >> (std::numeric_limits<unsigned int>::digits - allocationSize);
    167 
    168     for (unsigned int i = 0; i < bitsSize - allocationSize + 1; i++)
    169     {
    170         if ((*bits & mask) == 0)
    171         {
    172             *bits |= mask;
    173             return i;
    174         }
    175 
    176         mask <<= 1;
    177     }
    178 
    179     return -1;
    180 }
    181 
    182 GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment)
    183 {
    184     ASSERT(alignment > 0 && isPow2(alignment));
    185 
    186     GLsizei rawPitch = ComputePixelSize(format, type) * width;
    187     return (rawPitch + alignment - 1) & ~(alignment - 1);
    188 }
    189 
    190 GLsizei ComputeCompressedPitch(GLsizei width, GLenum format)
    191 {
    192     switch (format)
    193     {
    194       case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
    195       case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
    196         break;
    197       default:
    198         return 0;
    199     }
    200 
    201     ASSERT(width % 4 == 0);
    202 
    203     return 8 * width / 4;
    204 }
    205 
    206 GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format)
    207 {
    208     switch (format)
    209     {
    210       case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
    211       case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
    212         break;
    213       default:
    214         return 0;
    215     }
    216 
    217     return 8 * (GLsizei)ceil((float)width / 4.0f) * (GLsizei)ceil((float)height / 4.0f);
    218 }
    219 
    220 bool IsCompressed(GLenum format)
    221 {
    222     if(format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
    223        format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
    224     {
    225         return true;
    226     }
    227     else
    228     {
    229         return false;
    230     }
    231 }
    232 
    233 // Returns the size, in bytes, of a single texel in an Image
    234 int ComputePixelSize(GLenum format, GLenum type)
    235 {
    236     switch (type)
    237     {
    238       case GL_UNSIGNED_BYTE:
    239         switch (format)
    240         {
    241           case GL_ALPHA:           return sizeof(unsigned char);
    242           case GL_LUMINANCE:       return sizeof(unsigned char);
    243           case GL_LUMINANCE_ALPHA: return sizeof(unsigned char) * 2;
    244           case GL_RGB:             return sizeof(unsigned char) * 3;
    245           case GL_RGBA:            return sizeof(unsigned char) * 4;
    246           case GL_BGRA_EXT:        return sizeof(unsigned char) * 4;
    247           default: UNREACHABLE();
    248         }
    249         break;
    250       case GL_UNSIGNED_SHORT_4_4_4_4:
    251       case GL_UNSIGNED_SHORT_5_5_5_1:
    252       case GL_UNSIGNED_SHORT_5_6_5:
    253         return sizeof(unsigned short);
    254       case GL_FLOAT:
    255         switch (format)
    256         {
    257           case GL_ALPHA:           return sizeof(float);
    258           case GL_LUMINANCE:       return sizeof(float);
    259           case GL_LUMINANCE_ALPHA: return sizeof(float) * 2;
    260           case GL_RGB:             return sizeof(float) * 3;
    261           case GL_RGBA:            return sizeof(float) * 4;
    262           default: UNREACHABLE();
    263         }
    264         break;
    265       case GL_HALF_FLOAT_OES:
    266         switch (format)
    267         {
    268           case GL_ALPHA:           return sizeof(unsigned short);
    269           case GL_LUMINANCE:       return sizeof(unsigned short);
    270           case GL_LUMINANCE_ALPHA: return sizeof(unsigned short) * 2;
    271           case GL_RGB:             return sizeof(unsigned short) * 3;
    272           case GL_RGBA:            return sizeof(unsigned short) * 4;
    273           default: UNREACHABLE();
    274         }
    275         break;
    276       default: UNREACHABLE();
    277     }
    278 
    279     return 0;
    280 }
    281 
    282 bool IsCubemapTextureTarget(GLenum target)
    283 {
    284     return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
    285 }
    286 
    287 bool IsTextureTarget(GLenum target)
    288 {
    289     return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target);
    290 }
    291 
    292 // Verify that format/type are one of the combinations from table 3.4.
    293 bool CheckTextureFormatType(GLenum format, GLenum type)
    294 {
    295     switch (type)
    296     {
    297       case GL_UNSIGNED_BYTE:
    298         switch (format)
    299         {
    300           case GL_RGBA:
    301           case GL_BGRA_EXT:
    302           case GL_RGB:
    303           case GL_ALPHA:
    304           case GL_LUMINANCE:
    305           case GL_LUMINANCE_ALPHA:
    306             return true;
    307 
    308           default:
    309             return false;
    310         }
    311 
    312       case GL_FLOAT:
    313       case GL_HALF_FLOAT_OES:
    314         switch (format)
    315         {
    316           case GL_RGBA:
    317           case GL_RGB:
    318           case GL_ALPHA:
    319           case GL_LUMINANCE:
    320           case GL_LUMINANCE_ALPHA:
    321             return true;
    322 
    323           default:
    324             return false;
    325         }
    326 
    327       case GL_UNSIGNED_SHORT_4_4_4_4:
    328       case GL_UNSIGNED_SHORT_5_5_5_1:
    329         return (format == GL_RGBA);
    330 
    331       case GL_UNSIGNED_SHORT_5_6_5:
    332         return (format == GL_RGB);
    333 
    334       default:
    335         return false;
    336     }
    337 }
    338 
    339 bool IsColorRenderable(GLenum internalformat)
    340 {
    341     switch (internalformat)
    342     {
    343       case GL_RGBA4:
    344       case GL_RGB5_A1:
    345       case GL_RGB565:
    346       case GL_RGB8_OES:
    347       case GL_RGBA8_OES:
    348         return true;
    349       case GL_DEPTH_COMPONENT16:
    350       case GL_STENCIL_INDEX8:
    351       case GL_DEPTH24_STENCIL8_OES:
    352         return false;
    353       default:
    354         UNIMPLEMENTED();
    355     }
    356 
    357     return false;
    358 }
    359 
    360 bool IsDepthRenderable(GLenum internalformat)
    361 {
    362     switch (internalformat)
    363     {
    364       case GL_DEPTH_COMPONENT16:
    365       case GL_DEPTH24_STENCIL8_OES:
    366         return true;
    367       case GL_STENCIL_INDEX8:
    368       case GL_RGBA4:
    369       case GL_RGB5_A1:
    370       case GL_RGB565:
    371       case GL_RGB8_OES:
    372       case GL_RGBA8_OES:
    373         return false;
    374       default:
    375         UNIMPLEMENTED();
    376     }
    377 
    378     return false;
    379 }
    380 
    381 bool IsStencilRenderable(GLenum internalformat)
    382 {
    383     switch (internalformat)
    384     {
    385       case GL_STENCIL_INDEX8:
    386       case GL_DEPTH24_STENCIL8_OES:
    387         return true;
    388       case GL_RGBA4:
    389       case GL_RGB5_A1:
    390       case GL_RGB565:
    391       case GL_RGB8_OES:
    392       case GL_RGBA8_OES:
    393       case GL_DEPTH_COMPONENT16:
    394         return false;
    395       default:
    396         UNIMPLEMENTED();
    397     }
    398 
    399     return false;
    400 }
    401 
    402 }
    403 
    404 namespace es2dx
    405 {
    406 
    407 D3DCMPFUNC ConvertComparison(GLenum comparison)
    408 {
    409     D3DCMPFUNC d3dComp = D3DCMP_ALWAYS;
    410     switch (comparison)
    411     {
    412       case GL_NEVER:    d3dComp = D3DCMP_NEVER;        break;
    413       case GL_ALWAYS:   d3dComp = D3DCMP_ALWAYS;       break;
    414       case GL_LESS:     d3dComp = D3DCMP_LESS;         break;
    415       case GL_LEQUAL:   d3dComp = D3DCMP_LESSEQUAL;    break;
    416       case GL_EQUAL:    d3dComp = D3DCMP_EQUAL;        break;
    417       case GL_GREATER:  d3dComp = D3DCMP_GREATER;      break;
    418       case GL_GEQUAL:   d3dComp = D3DCMP_GREATEREQUAL; break;
    419       case GL_NOTEQUAL: d3dComp = D3DCMP_NOTEQUAL;     break;
    420       default: UNREACHABLE();
    421     }
    422 
    423     return d3dComp;
    424 }
    425 
    426 D3DCOLOR ConvertColor(gl::Color color)
    427 {
    428     return D3DCOLOR_RGBA(gl::unorm<8>(color.red),
    429                          gl::unorm<8>(color.green),
    430                          gl::unorm<8>(color.blue),
    431                          gl::unorm<8>(color.alpha));
    432 }
    433 
    434 D3DBLEND ConvertBlendFunc(GLenum blend)
    435 {
    436     D3DBLEND d3dBlend = D3DBLEND_ZERO;
    437 
    438     switch (blend)
    439     {
    440       case GL_ZERO:                     d3dBlend = D3DBLEND_ZERO;           break;
    441       case GL_ONE:                      d3dBlend = D3DBLEND_ONE;            break;
    442       case GL_SRC_COLOR:                d3dBlend = D3DBLEND_SRCCOLOR;       break;
    443       case GL_ONE_MINUS_SRC_COLOR:      d3dBlend = D3DBLEND_INVSRCCOLOR;    break;
    444       case GL_DST_COLOR:                d3dBlend = D3DBLEND_DESTCOLOR;      break;
    445       case GL_ONE_MINUS_DST_COLOR:      d3dBlend = D3DBLEND_INVDESTCOLOR;   break;
    446       case GL_SRC_ALPHA:                d3dBlend = D3DBLEND_SRCALPHA;       break;
    447       case GL_ONE_MINUS_SRC_ALPHA:      d3dBlend = D3DBLEND_INVSRCALPHA;    break;
    448       case GL_DST_ALPHA:                d3dBlend = D3DBLEND_DESTALPHA;      break;
    449       case GL_ONE_MINUS_DST_ALPHA:      d3dBlend = D3DBLEND_INVDESTALPHA;   break;
    450       case GL_CONSTANT_COLOR:           d3dBlend = D3DBLEND_BLENDFACTOR;    break;
    451       case GL_ONE_MINUS_CONSTANT_COLOR: d3dBlend = D3DBLEND_INVBLENDFACTOR; break;
    452       case GL_CONSTANT_ALPHA:           d3dBlend = D3DBLEND_BLENDFACTOR;    break;
    453       case GL_ONE_MINUS_CONSTANT_ALPHA: d3dBlend = D3DBLEND_INVBLENDFACTOR; break;
    454       case GL_SRC_ALPHA_SATURATE:       d3dBlend = D3DBLEND_SRCALPHASAT;    break;
    455       default: UNREACHABLE();
    456     }
    457 
    458     return d3dBlend;
    459 }
    460 
    461 D3DBLENDOP ConvertBlendOp(GLenum blendOp)
    462 {
    463     D3DBLENDOP d3dBlendOp = D3DBLENDOP_ADD;
    464 
    465     switch (blendOp)
    466     {
    467       case GL_FUNC_ADD:              d3dBlendOp = D3DBLENDOP_ADD;         break;
    468       case GL_FUNC_SUBTRACT:         d3dBlendOp = D3DBLENDOP_SUBTRACT;    break;
    469       case GL_FUNC_REVERSE_SUBTRACT: d3dBlendOp = D3DBLENDOP_REVSUBTRACT; break;
    470       default: UNREACHABLE();
    471     }
    472 
    473     return d3dBlendOp;
    474 }
    475 
    476 D3DSTENCILOP ConvertStencilOp(GLenum stencilOp)
    477 {
    478     D3DSTENCILOP d3dStencilOp = D3DSTENCILOP_KEEP;
    479 
    480     switch (stencilOp)
    481     {
    482       case GL_ZERO:      d3dStencilOp = D3DSTENCILOP_ZERO;    break;
    483       case GL_KEEP:      d3dStencilOp = D3DSTENCILOP_KEEP;    break;
    484       case GL_REPLACE:   d3dStencilOp = D3DSTENCILOP_REPLACE; break;
    485       case GL_INCR:      d3dStencilOp = D3DSTENCILOP_INCRSAT; break;
    486       case GL_DECR:      d3dStencilOp = D3DSTENCILOP_DECRSAT; break;
    487       case GL_INVERT:    d3dStencilOp = D3DSTENCILOP_INVERT;  break;
    488       case GL_INCR_WRAP: d3dStencilOp = D3DSTENCILOP_INCR;    break;
    489       case GL_DECR_WRAP: d3dStencilOp = D3DSTENCILOP_DECR;    break;
    490       default: UNREACHABLE();
    491     }
    492 
    493     return d3dStencilOp;
    494 }
    495 
    496 D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap)
    497 {
    498     D3DTEXTUREADDRESS d3dWrap = D3DTADDRESS_WRAP;
    499 
    500     switch (wrap)
    501     {
    502       case GL_REPEAT:            d3dWrap = D3DTADDRESS_WRAP;   break;
    503       case GL_CLAMP_TO_EDGE:     d3dWrap = D3DTADDRESS_CLAMP;  break;
    504       case GL_MIRRORED_REPEAT:   d3dWrap = D3DTADDRESS_MIRROR; break;
    505       default: UNREACHABLE();
    506     }
    507 
    508     return d3dWrap;
    509 }
    510 
    511 D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace)
    512 {
    513     D3DCULL cull = D3DCULL_CCW;
    514     switch (cullFace)
    515     {
    516       case GL_FRONT:
    517         cull = (frontFace == GL_CCW ? D3DCULL_CW : D3DCULL_CCW);
    518         break;
    519       case GL_BACK:
    520         cull = (frontFace == GL_CCW ? D3DCULL_CCW : D3DCULL_CW);
    521         break;
    522       case GL_FRONT_AND_BACK:
    523         cull = D3DCULL_NONE; // culling will be handled during draw
    524         break;
    525       default: UNREACHABLE();
    526     }
    527 
    528     return cull;
    529 }
    530 
    531 DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha)
    532 {
    533     return (red   ? D3DCOLORWRITEENABLE_RED   : 0) |
    534            (green ? D3DCOLORWRITEENABLE_GREEN : 0) |
    535            (blue  ? D3DCOLORWRITEENABLE_BLUE  : 0) |
    536            (alpha ? D3DCOLORWRITEENABLE_ALPHA : 0);
    537 }
    538 
    539 D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter)
    540 {
    541     D3DTEXTUREFILTERTYPE d3dMagFilter = D3DTEXF_POINT;
    542     switch (magFilter)
    543     {
    544       case GL_NEAREST: d3dMagFilter = D3DTEXF_POINT;  break;
    545       case GL_LINEAR:  d3dMagFilter = D3DTEXF_LINEAR; break;
    546       default: UNREACHABLE();
    547     }
    548 
    549     return d3dMagFilter;
    550 }
    551 
    552 void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter)
    553 {
    554     switch (minFilter)
    555     {
    556       case GL_NEAREST:
    557         *d3dMinFilter = D3DTEXF_POINT;
    558         *d3dMipFilter = D3DTEXF_NONE;
    559         break;
    560       case GL_LINEAR:
    561         *d3dMinFilter = D3DTEXF_LINEAR;
    562         *d3dMipFilter = D3DTEXF_NONE;
    563         break;
    564       case GL_NEAREST_MIPMAP_NEAREST:
    565         *d3dMinFilter = D3DTEXF_POINT;
    566         *d3dMipFilter = D3DTEXF_POINT;
    567         break;
    568       case GL_LINEAR_MIPMAP_NEAREST:
    569         *d3dMinFilter = D3DTEXF_LINEAR;
    570         *d3dMipFilter = D3DTEXF_POINT;
    571         break;
    572       case GL_NEAREST_MIPMAP_LINEAR:
    573         *d3dMinFilter = D3DTEXF_POINT;
    574         *d3dMipFilter = D3DTEXF_LINEAR;
    575         break;
    576       case GL_LINEAR_MIPMAP_LINEAR:
    577         *d3dMinFilter = D3DTEXF_LINEAR;
    578         *d3dMipFilter = D3DTEXF_LINEAR;
    579         break;
    580       default:
    581         *d3dMinFilter = D3DTEXF_POINT;
    582         *d3dMipFilter = D3DTEXF_NONE;
    583         UNREACHABLE();
    584     }
    585 }
    586 
    587 unsigned int GetStencilSize(D3DFORMAT stencilFormat)
    588 {
    589     switch(stencilFormat)
    590     {
    591       case D3DFMT_D24FS8:
    592       case D3DFMT_D24S8:
    593         return 8;
    594       case D3DFMT_D24X4S4:
    595         return 4;
    596       case D3DFMT_D15S1:
    597         return 1;
    598       case D3DFMT_D16_LOCKABLE:
    599       case D3DFMT_D32:
    600       case D3DFMT_D24X8:
    601       case D3DFMT_D32F_LOCKABLE:
    602       case D3DFMT_D16:
    603         return 0;
    604 //      case D3DFMT_D32_LOCKABLE:  return 0;   // DirectX 9Ex only
    605 //      case D3DFMT_S8_LOCKABLE:   return 8;   // DirectX 9Ex only
    606       default: UNREACHABLE();
    607     }
    608     return 0;
    609 }
    610 
    611 unsigned int GetAlphaSize(D3DFORMAT colorFormat)
    612 {
    613     switch (colorFormat)
    614     {
    615       case D3DFMT_A16B16G16R16F:
    616         return 16;
    617       case D3DFMT_A32B32G32R32F:
    618         return 32;
    619       case D3DFMT_A2R10G10B10:
    620         return 2;
    621       case D3DFMT_A8R8G8B8:
    622         return 8;
    623       case D3DFMT_A1R5G5B5:
    624         return 1;
    625       case D3DFMT_X8R8G8B8:
    626       case D3DFMT_R5G6B5:
    627         return 0;
    628       default: UNREACHABLE();
    629     }
    630     return 0;
    631 }
    632 
    633 unsigned int GetRedSize(D3DFORMAT colorFormat)
    634 {
    635     switch (colorFormat)
    636     {
    637       case D3DFMT_A16B16G16R16F:
    638         return 16;
    639       case D3DFMT_A32B32G32R32F:
    640         return 32;
    641       case D3DFMT_A2R10G10B10:
    642         return 10;
    643       case D3DFMT_A8R8G8B8:
    644       case D3DFMT_X8R8G8B8:
    645         return 8;
    646       case D3DFMT_A1R5G5B5:
    647       case D3DFMT_R5G6B5:
    648         return 5;
    649       default: UNREACHABLE();
    650     }
    651     return 0;
    652 }
    653 
    654 unsigned int GetGreenSize(D3DFORMAT colorFormat)
    655 {
    656     switch (colorFormat)
    657     {
    658       case D3DFMT_A16B16G16R16F:
    659         return 16;
    660       case D3DFMT_A32B32G32R32F:
    661         return 32;
    662       case D3DFMT_A2R10G10B10:
    663         return 10;
    664       case D3DFMT_A8R8G8B8:
    665       case D3DFMT_X8R8G8B8:
    666         return 8;
    667       case D3DFMT_A1R5G5B5:
    668         return 5;
    669       case D3DFMT_R5G6B5:
    670         return 6;
    671       default: UNREACHABLE();
    672     }
    673     return 0;
    674 }
    675 
    676 unsigned int GetBlueSize(D3DFORMAT colorFormat)
    677 {
    678     switch (colorFormat)
    679     {
    680       case D3DFMT_A16B16G16R16F:
    681         return 16;
    682       case D3DFMT_A32B32G32R32F:
    683         return 32;
    684       case D3DFMT_A2R10G10B10:
    685         return 10;
    686       case D3DFMT_A8R8G8B8:
    687       case D3DFMT_X8R8G8B8:
    688         return 8;
    689       case D3DFMT_A1R5G5B5:
    690       case D3DFMT_R5G6B5:
    691         return 5;
    692       default: UNREACHABLE();
    693     }
    694     return 0;
    695 }
    696 
    697 unsigned int GetDepthSize(D3DFORMAT depthFormat)
    698 {
    699     switch (depthFormat)
    700     {
    701       case D3DFMT_D16_LOCKABLE:  return 16;
    702       case D3DFMT_D32:           return 32;
    703       case D3DFMT_D15S1:         return 15;
    704       case D3DFMT_D24S8:         return 24;
    705       case D3DFMT_D24X8:         return 24;
    706       case D3DFMT_D24X4S4:       return 24;
    707       case D3DFMT_D16:           return 16;
    708       case D3DFMT_D32F_LOCKABLE: return 32;
    709       case D3DFMT_D24FS8:        return 24;
    710     //case D3DFMT_D32_LOCKABLE:  return 32;   // D3D9Ex only
    711     //case D3DFMT_S8_LOCKABLE:   return 0;    // D3D9Ex only
    712       default:
    713         UNREACHABLE();
    714     }
    715     return 0;
    716 }
    717 
    718 bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount,
    719                           D3DPRIMITIVETYPE *d3dPrimitiveType, int *d3dPrimitiveCount)
    720 {
    721     switch (primitiveType)
    722     {
    723       case GL_POINTS:
    724         *d3dPrimitiveType = D3DPT_POINTLIST;
    725         *d3dPrimitiveCount = elementCount;
    726         break;
    727       case GL_LINES:
    728         *d3dPrimitiveType = D3DPT_LINELIST;
    729         *d3dPrimitiveCount = elementCount / 2;
    730         break;
    731       case GL_LINE_LOOP:
    732         *d3dPrimitiveType = D3DPT_LINESTRIP;
    733         *d3dPrimitiveCount = elementCount - 1;   // D3D doesn't support line loops, so we draw the last line separately
    734         break;
    735       case GL_LINE_STRIP:
    736         *d3dPrimitiveType = D3DPT_LINESTRIP;
    737         *d3dPrimitiveCount = elementCount - 1;
    738         break;
    739       case GL_TRIANGLES:
    740         *d3dPrimitiveType = D3DPT_TRIANGLELIST;
    741         *d3dPrimitiveCount = elementCount / 3;
    742         break;
    743       case GL_TRIANGLE_STRIP:
    744         *d3dPrimitiveType = D3DPT_TRIANGLESTRIP;
    745         *d3dPrimitiveCount = elementCount - 2;
    746         break;
    747       case GL_TRIANGLE_FAN:
    748         *d3dPrimitiveType = D3DPT_TRIANGLEFAN;
    749         *d3dPrimitiveCount = elementCount - 2;
    750         break;
    751       default:
    752         return false;
    753     }
    754 
    755     return true;
    756 }
    757 
    758 D3DFORMAT ConvertRenderbufferFormat(GLenum format)
    759 {
    760     switch (format)
    761     {
    762       case GL_RGBA4:
    763       case GL_RGB5_A1:
    764       case GL_RGBA8_OES:            return D3DFMT_A8R8G8B8;
    765       case GL_RGB565:               return D3DFMT_R5G6B5;
    766       case GL_RGB8_OES:             return D3DFMT_X8R8G8B8;
    767       case GL_DEPTH_COMPONENT16:
    768       case GL_STENCIL_INDEX8:
    769       case GL_DEPTH24_STENCIL8_OES: return D3DFMT_D24S8;
    770       default: UNREACHABLE();       return D3DFMT_A8R8G8B8;
    771     }
    772 }
    773 
    774 GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type)
    775 {
    776     if (type == D3DMULTISAMPLE_NONMASKABLE)
    777         return 0;
    778     else
    779         return type;
    780 }
    781 
    782 D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples)
    783 {
    784     if (samples <= 1)
    785         return D3DMULTISAMPLE_NONE;
    786     else
    787         return (D3DMULTISAMPLE_TYPE)samples;
    788 }
    789 
    790 }
    791 
    792 namespace dx2es
    793 {
    794 
    795 GLenum ConvertBackBufferFormat(D3DFORMAT format)
    796 {
    797     switch (format)
    798     {
    799       case D3DFMT_A4R4G4B4: return GL_RGBA4;
    800       case D3DFMT_A8R8G8B8: return GL_RGBA8_OES;
    801       case D3DFMT_A1R5G5B5: return GL_RGB5_A1;
    802       case D3DFMT_R5G6B5:   return GL_RGB565;
    803       case D3DFMT_X8R8G8B8: return GL_RGB8_OES;
    804       default:
    805         UNREACHABLE();
    806     }
    807 
    808     return GL_RGBA4;
    809 }
    810 
    811 GLenum ConvertDepthStencilFormat(D3DFORMAT format)
    812 {
    813     switch (format)
    814     {
    815       case D3DFMT_D16:
    816       case D3DFMT_D24X8:
    817         return GL_DEPTH_COMPONENT16;
    818       case D3DFMT_D24S8:
    819         return GL_DEPTH24_STENCIL8_OES;
    820       default:
    821         UNREACHABLE();
    822     }
    823 
    824     return GL_DEPTH24_STENCIL8_OES;
    825 }
    826 
    827 }
    828