Home | History | Annotate | Download | only in renderer
      1 #include "precompiled.h"
      2 //
      3 // Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
      4 // Use of this source code is governed by a BSD-style license that can be
      5 // found in the LICENSE file.
      6 //
      7 
      8 // renderer9_utils.cpp: Conversion functions and other utility routines
      9 // specific to the D3D9 renderer.
     10 
     11 #include "libGLESv2/renderer/renderer9_utils.h"
     12 #include "libGLESv2/mathutil.h"
     13 #include "libGLESv2/Context.h"
     14 
     15 #include "common/debug.h"
     16 
     17 namespace gl_d3d9
     18 {
     19 
     20 D3DCMPFUNC ConvertComparison(GLenum comparison)
     21 {
     22     D3DCMPFUNC d3dComp = D3DCMP_ALWAYS;
     23     switch (comparison)
     24     {
     25       case GL_NEVER:    d3dComp = D3DCMP_NEVER;        break;
     26       case GL_ALWAYS:   d3dComp = D3DCMP_ALWAYS;       break;
     27       case GL_LESS:     d3dComp = D3DCMP_LESS;         break;
     28       case GL_LEQUAL:   d3dComp = D3DCMP_LESSEQUAL;    break;
     29       case GL_EQUAL:    d3dComp = D3DCMP_EQUAL;        break;
     30       case GL_GREATER:  d3dComp = D3DCMP_GREATER;      break;
     31       case GL_GEQUAL:   d3dComp = D3DCMP_GREATEREQUAL; break;
     32       case GL_NOTEQUAL: d3dComp = D3DCMP_NOTEQUAL;     break;
     33       default: UNREACHABLE();
     34     }
     35 
     36     return d3dComp;
     37 }
     38 
     39 D3DCOLOR ConvertColor(gl::Color color)
     40 {
     41     return D3DCOLOR_RGBA(gl::unorm<8>(color.red),
     42                          gl::unorm<8>(color.green),
     43                          gl::unorm<8>(color.blue),
     44                          gl::unorm<8>(color.alpha));
     45 }
     46 
     47 D3DBLEND ConvertBlendFunc(GLenum blend)
     48 {
     49     D3DBLEND d3dBlend = D3DBLEND_ZERO;
     50 
     51     switch (blend)
     52     {
     53       case GL_ZERO:                     d3dBlend = D3DBLEND_ZERO;           break;
     54       case GL_ONE:                      d3dBlend = D3DBLEND_ONE;            break;
     55       case GL_SRC_COLOR:                d3dBlend = D3DBLEND_SRCCOLOR;       break;
     56       case GL_ONE_MINUS_SRC_COLOR:      d3dBlend = D3DBLEND_INVSRCCOLOR;    break;
     57       case GL_DST_COLOR:                d3dBlend = D3DBLEND_DESTCOLOR;      break;
     58       case GL_ONE_MINUS_DST_COLOR:      d3dBlend = D3DBLEND_INVDESTCOLOR;   break;
     59       case GL_SRC_ALPHA:                d3dBlend = D3DBLEND_SRCALPHA;       break;
     60       case GL_ONE_MINUS_SRC_ALPHA:      d3dBlend = D3DBLEND_INVSRCALPHA;    break;
     61       case GL_DST_ALPHA:                d3dBlend = D3DBLEND_DESTALPHA;      break;
     62       case GL_ONE_MINUS_DST_ALPHA:      d3dBlend = D3DBLEND_INVDESTALPHA;   break;
     63       case GL_CONSTANT_COLOR:           d3dBlend = D3DBLEND_BLENDFACTOR;    break;
     64       case GL_ONE_MINUS_CONSTANT_COLOR: d3dBlend = D3DBLEND_INVBLENDFACTOR; break;
     65       case GL_CONSTANT_ALPHA:           d3dBlend = D3DBLEND_BLENDFACTOR;    break;
     66       case GL_ONE_MINUS_CONSTANT_ALPHA: d3dBlend = D3DBLEND_INVBLENDFACTOR; break;
     67       case GL_SRC_ALPHA_SATURATE:       d3dBlend = D3DBLEND_SRCALPHASAT;    break;
     68       default: UNREACHABLE();
     69     }
     70 
     71     return d3dBlend;
     72 }
     73 
     74 D3DBLENDOP ConvertBlendOp(GLenum blendOp)
     75 {
     76     D3DBLENDOP d3dBlendOp = D3DBLENDOP_ADD;
     77 
     78     switch (blendOp)
     79     {
     80       case GL_FUNC_ADD:              d3dBlendOp = D3DBLENDOP_ADD;         break;
     81       case GL_FUNC_SUBTRACT:         d3dBlendOp = D3DBLENDOP_SUBTRACT;    break;
     82       case GL_FUNC_REVERSE_SUBTRACT: d3dBlendOp = D3DBLENDOP_REVSUBTRACT; break;
     83       default: UNREACHABLE();
     84     }
     85 
     86     return d3dBlendOp;
     87 }
     88 
     89 D3DSTENCILOP ConvertStencilOp(GLenum stencilOp)
     90 {
     91     D3DSTENCILOP d3dStencilOp = D3DSTENCILOP_KEEP;
     92 
     93     switch (stencilOp)
     94     {
     95       case GL_ZERO:      d3dStencilOp = D3DSTENCILOP_ZERO;    break;
     96       case GL_KEEP:      d3dStencilOp = D3DSTENCILOP_KEEP;    break;
     97       case GL_REPLACE:   d3dStencilOp = D3DSTENCILOP_REPLACE; break;
     98       case GL_INCR:      d3dStencilOp = D3DSTENCILOP_INCRSAT; break;
     99       case GL_DECR:      d3dStencilOp = D3DSTENCILOP_DECRSAT; break;
    100       case GL_INVERT:    d3dStencilOp = D3DSTENCILOP_INVERT;  break;
    101       case GL_INCR_WRAP: d3dStencilOp = D3DSTENCILOP_INCR;    break;
    102       case GL_DECR_WRAP: d3dStencilOp = D3DSTENCILOP_DECR;    break;
    103       default: UNREACHABLE();
    104     }
    105 
    106     return d3dStencilOp;
    107 }
    108 
    109 D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap)
    110 {
    111     D3DTEXTUREADDRESS d3dWrap = D3DTADDRESS_WRAP;
    112 
    113     switch (wrap)
    114     {
    115       case GL_REPEAT:            d3dWrap = D3DTADDRESS_WRAP;   break;
    116       case GL_CLAMP_TO_EDGE:     d3dWrap = D3DTADDRESS_CLAMP;  break;
    117       case GL_MIRRORED_REPEAT:   d3dWrap = D3DTADDRESS_MIRROR; break;
    118       default: UNREACHABLE();
    119     }
    120 
    121     return d3dWrap;
    122 }
    123 
    124 D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace)
    125 {
    126     D3DCULL cull = D3DCULL_CCW;
    127     switch (cullFace)
    128     {
    129       case GL_FRONT:
    130         cull = (frontFace == GL_CCW ? D3DCULL_CW : D3DCULL_CCW);
    131         break;
    132       case GL_BACK:
    133         cull = (frontFace == GL_CCW ? D3DCULL_CCW : D3DCULL_CW);
    134         break;
    135       case GL_FRONT_AND_BACK:
    136         cull = D3DCULL_NONE; // culling will be handled during draw
    137         break;
    138       default: UNREACHABLE();
    139     }
    140 
    141     return cull;
    142 }
    143 
    144 D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace)
    145 {
    146     D3DCUBEMAP_FACES face = D3DCUBEMAP_FACE_POSITIVE_X;
    147 
    148     switch (cubeFace)
    149     {
    150       case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
    151         face = D3DCUBEMAP_FACE_POSITIVE_X;
    152         break;
    153       case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
    154         face = D3DCUBEMAP_FACE_NEGATIVE_X;
    155         break;
    156       case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
    157         face = D3DCUBEMAP_FACE_POSITIVE_Y;
    158         break;
    159       case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
    160         face = D3DCUBEMAP_FACE_NEGATIVE_Y;
    161         break;
    162       case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
    163         face = D3DCUBEMAP_FACE_POSITIVE_Z;
    164         break;
    165       case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
    166         face = D3DCUBEMAP_FACE_NEGATIVE_Z;
    167         break;
    168       default: UNREACHABLE();
    169     }
    170 
    171     return face;
    172 }
    173 
    174 DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha)
    175 {
    176     return (red   ? D3DCOLORWRITEENABLE_RED   : 0) |
    177            (green ? D3DCOLORWRITEENABLE_GREEN : 0) |
    178            (blue  ? D3DCOLORWRITEENABLE_BLUE  : 0) |
    179            (alpha ? D3DCOLORWRITEENABLE_ALPHA : 0);
    180 }
    181 
    182 D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy)
    183 {
    184     if (maxAnisotropy > 1.0f)
    185     {
    186         return D3DTEXF_ANISOTROPIC;
    187     }
    188 
    189     D3DTEXTUREFILTERTYPE d3dMagFilter = D3DTEXF_POINT;
    190     switch (magFilter)
    191     {
    192       case GL_NEAREST: d3dMagFilter = D3DTEXF_POINT;  break;
    193       case GL_LINEAR:  d3dMagFilter = D3DTEXF_LINEAR; break;
    194       default: UNREACHABLE();
    195     }
    196 
    197     return d3dMagFilter;
    198 }
    199 
    200 void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter, float maxAnisotropy)
    201 {
    202     switch (minFilter)
    203     {
    204       case GL_NEAREST:
    205         *d3dMinFilter = D3DTEXF_POINT;
    206         *d3dMipFilter = D3DTEXF_NONE;
    207         break;
    208       case GL_LINEAR:
    209         *d3dMinFilter = D3DTEXF_LINEAR;
    210         *d3dMipFilter = D3DTEXF_NONE;
    211         break;
    212       case GL_NEAREST_MIPMAP_NEAREST:
    213         *d3dMinFilter = D3DTEXF_POINT;
    214         *d3dMipFilter = D3DTEXF_POINT;
    215         break;
    216       case GL_LINEAR_MIPMAP_NEAREST:
    217         *d3dMinFilter = D3DTEXF_LINEAR;
    218         *d3dMipFilter = D3DTEXF_POINT;
    219         break;
    220       case GL_NEAREST_MIPMAP_LINEAR:
    221         *d3dMinFilter = D3DTEXF_POINT;
    222         *d3dMipFilter = D3DTEXF_LINEAR;
    223         break;
    224       case GL_LINEAR_MIPMAP_LINEAR:
    225         *d3dMinFilter = D3DTEXF_LINEAR;
    226         *d3dMipFilter = D3DTEXF_LINEAR;
    227         break;
    228       default:
    229         *d3dMinFilter = D3DTEXF_POINT;
    230         *d3dMipFilter = D3DTEXF_NONE;
    231         UNREACHABLE();
    232     }
    233 
    234     if (maxAnisotropy > 1.0f)
    235     {
    236         *d3dMinFilter = D3DTEXF_ANISOTROPIC;
    237     }
    238 }
    239 
    240 D3DFORMAT ConvertRenderbufferFormat(GLenum format)
    241 {
    242     switch (format)
    243     {
    244       case GL_NONE:                 return D3DFMT_NULL;
    245       case GL_RGBA4:
    246       case GL_RGB5_A1:
    247       case GL_RGBA8_OES:            return D3DFMT_A8R8G8B8;
    248       case GL_RGB565:               return D3DFMT_R5G6B5;
    249       case GL_RGB8_OES:             return D3DFMT_X8R8G8B8;
    250       case GL_DEPTH_COMPONENT16:
    251       case GL_STENCIL_INDEX8:
    252       case GL_DEPTH24_STENCIL8_OES: return D3DFMT_D24S8;
    253       default: UNREACHABLE();       return D3DFMT_A8R8G8B8;
    254     }
    255 }
    256 
    257 D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples)
    258 {
    259     if (samples <= 1)
    260         return D3DMULTISAMPLE_NONE;
    261     else
    262         return (D3DMULTISAMPLE_TYPE)samples;
    263 }
    264 
    265 }
    266 
    267 namespace d3d9_gl
    268 {
    269 
    270 unsigned int GetStencilSize(D3DFORMAT stencilFormat)
    271 {
    272     if (stencilFormat == D3DFMT_INTZ)
    273     {
    274         return 8;
    275     }
    276     switch(stencilFormat)
    277     {
    278       case D3DFMT_D24FS8:
    279       case D3DFMT_D24S8:
    280         return 8;
    281       case D3DFMT_D24X4S4:
    282         return 4;
    283       case D3DFMT_D15S1:
    284         return 1;
    285       case D3DFMT_D16_LOCKABLE:
    286       case D3DFMT_D32:
    287       case D3DFMT_D24X8:
    288       case D3DFMT_D32F_LOCKABLE:
    289       case D3DFMT_D16:
    290         return 0;
    291     //case D3DFMT_D32_LOCKABLE:  return 0;   // DirectX 9Ex only
    292     //case D3DFMT_S8_LOCKABLE:   return 8;   // DirectX 9Ex only
    293       default:
    294         return 0;
    295     }
    296 }
    297 
    298 unsigned int GetAlphaSize(D3DFORMAT colorFormat)
    299 {
    300     switch (colorFormat)
    301     {
    302       case D3DFMT_A16B16G16R16F:
    303         return 16;
    304       case D3DFMT_A32B32G32R32F:
    305         return 32;
    306       case D3DFMT_A2R10G10B10:
    307         return 2;
    308       case D3DFMT_A8R8G8B8:
    309         return 8;
    310       case D3DFMT_A1R5G5B5:
    311         return 1;
    312       case D3DFMT_X8R8G8B8:
    313       case D3DFMT_R5G6B5:
    314         return 0;
    315       default:
    316         return 0;
    317     }
    318 }
    319 
    320 GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type)
    321 {
    322     if (type == D3DMULTISAMPLE_NONMASKABLE)
    323         return 0;
    324     else
    325         return type;
    326 }
    327 
    328 bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format)
    329 {
    330     switch (d3dformat)
    331     {
    332       case D3DFMT_L8:
    333         return (format == GL_LUMINANCE);
    334       case D3DFMT_A8L8:
    335         return (format == GL_LUMINANCE_ALPHA);
    336       case D3DFMT_DXT1:
    337         return (format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT || format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT);
    338       case D3DFMT_DXT3:
    339         return (format == GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE);
    340       case D3DFMT_DXT5:
    341         return (format == GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE);
    342       case D3DFMT_A8R8G8B8:
    343       case D3DFMT_A16B16G16R16F:
    344       case D3DFMT_A32B32G32R32F:
    345         return (format == GL_RGBA || format == GL_BGRA_EXT);
    346       case D3DFMT_X8R8G8B8:
    347         return (format == GL_RGB);
    348       default:
    349         if (d3dformat == D3DFMT_INTZ && gl::IsDepthTexture(format))
    350             return true;
    351         return false;
    352     }
    353 }
    354 
    355 GLenum ConvertBackBufferFormat(D3DFORMAT format)
    356 {
    357     switch (format)
    358     {
    359       case D3DFMT_A4R4G4B4: return GL_RGBA4;
    360       case D3DFMT_A8R8G8B8: return GL_RGBA8_OES;
    361       case D3DFMT_A1R5G5B5: return GL_RGB5_A1;
    362       case D3DFMT_R5G6B5:   return GL_RGB565;
    363       case D3DFMT_X8R8G8B8: return GL_RGB8_OES;
    364       default:
    365         UNREACHABLE();
    366     }
    367 
    368     return GL_RGBA4;
    369 }
    370 
    371 GLenum ConvertDepthStencilFormat(D3DFORMAT format)
    372 {
    373     if (format == D3DFMT_INTZ)
    374     {
    375         return GL_DEPTH24_STENCIL8_OES;
    376     }
    377     switch (format)
    378     {
    379       case D3DFMT_D16:
    380       case D3DFMT_D24X8:
    381         return GL_DEPTH_COMPONENT16;
    382       case D3DFMT_D24S8:
    383         return GL_DEPTH24_STENCIL8_OES;
    384       case D3DFMT_UNKNOWN:
    385         return GL_NONE;
    386       default:
    387         UNREACHABLE();
    388     }
    389 
    390     return GL_DEPTH24_STENCIL8_OES;
    391 }
    392 
    393 GLenum ConvertRenderTargetFormat(D3DFORMAT format)
    394 {
    395     if (format == D3DFMT_INTZ)
    396     {
    397         return GL_DEPTH24_STENCIL8_OES;
    398     }
    399 
    400     switch (format)
    401     {
    402       case D3DFMT_A4R4G4B4: return GL_RGBA4;
    403       case D3DFMT_A8R8G8B8: return GL_RGBA8_OES;
    404       case D3DFMT_A1R5G5B5: return GL_RGB5_A1;
    405       case D3DFMT_R5G6B5:   return GL_RGB565;
    406       case D3DFMT_X8R8G8B8: return GL_RGB8_OES;
    407       case D3DFMT_D16:
    408       case D3DFMT_D24X8:
    409         return GL_DEPTH_COMPONENT16;
    410       case D3DFMT_D24S8:
    411         return GL_DEPTH24_STENCIL8_OES;
    412       case D3DFMT_UNKNOWN:
    413         return GL_NONE;
    414       default:
    415         UNREACHABLE();
    416     }
    417 
    418     return GL_RGBA4;
    419 }
    420 
    421 GLenum GetEquivalentFormat(D3DFORMAT format)
    422 {
    423     if (format == D3DFMT_INTZ)
    424         return GL_DEPTH24_STENCIL8_OES;
    425     if (format == D3DFMT_NULL)
    426         return GL_NONE;
    427 
    428     switch (format)
    429     {
    430       case D3DFMT_A4R4G4B4:             return GL_RGBA4;
    431       case D3DFMT_A8R8G8B8:             return GL_RGBA8_OES;
    432       case D3DFMT_A1R5G5B5:             return GL_RGB5_A1;
    433       case D3DFMT_R5G6B5:               return GL_RGB565;
    434       case D3DFMT_X8R8G8B8:             return GL_RGB8_OES;
    435       case D3DFMT_D16:                  return GL_DEPTH_COMPONENT16;
    436       case D3DFMT_D24S8:                return GL_DEPTH24_STENCIL8_OES;
    437       case D3DFMT_UNKNOWN:              return GL_NONE;
    438       case D3DFMT_DXT1:                 return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
    439       case D3DFMT_DXT3:                 return GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE;
    440       case D3DFMT_DXT5:                 return GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE;
    441       case D3DFMT_A32B32G32R32F:        return GL_RGBA32F_EXT;
    442       case D3DFMT_A16B16G16R16F:        return GL_RGBA16F_EXT;
    443       case D3DFMT_L8:                   return GL_LUMINANCE8_EXT;
    444       case D3DFMT_A8L8:                 return GL_LUMINANCE8_ALPHA8_EXT;
    445       default:              UNREACHABLE();
    446         return GL_NONE;
    447     }
    448 }
    449 
    450 }
    451 
    452 namespace d3d9
    453 {
    454 
    455 bool IsCompressedFormat(D3DFORMAT surfaceFormat)
    456 {
    457     switch(surfaceFormat)
    458     {
    459       case D3DFMT_DXT1:
    460       case D3DFMT_DXT2:
    461       case D3DFMT_DXT3:
    462       case D3DFMT_DXT4:
    463       case D3DFMT_DXT5:
    464         return true;
    465       default:
    466         return false;
    467     }
    468 }
    469 
    470 size_t ComputeRowSize(D3DFORMAT format, unsigned int width)
    471 {
    472     if (format == D3DFMT_INTZ)
    473     {
    474         return 4 * width;
    475     }
    476     switch (format)
    477     {
    478       case D3DFMT_L8:
    479           return 1 * width;
    480       case D3DFMT_A8L8:
    481           return 2 * width;
    482       case D3DFMT_X8R8G8B8:
    483       case D3DFMT_A8R8G8B8:
    484         return 4 * width;
    485       case D3DFMT_A16B16G16R16F:
    486         return 8 * width;
    487       case D3DFMT_A32B32G32R32F:
    488         return 16 * width;
    489       case D3DFMT_DXT1:
    490         return 8 * ((width + 3) / 4);
    491       case D3DFMT_DXT3:
    492       case D3DFMT_DXT5:
    493         return 16 * ((width + 3) / 4);
    494       default:
    495         UNREACHABLE();
    496         return 0;
    497     }
    498 }
    499 
    500 }
    501