Home | History | Annotate | Download | only in renderer
      1 #include "precompiled.h"
      2 //
      3 // Copyright (c) 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 // renderer11_utils.cpp: Conversion functions and other utility routines
      9 // specific to the D3D11 renderer.
     10 
     11 #include "libGLESv2/renderer/renderer11_utils.h"
     12 
     13 #include "common/debug.h"
     14 
     15 namespace gl_d3d11
     16 {
     17 
     18 D3D11_BLEND ConvertBlendFunc(GLenum glBlend, bool isAlpha)
     19 {
     20     D3D11_BLEND d3dBlend = D3D11_BLEND_ZERO;
     21 
     22     switch (glBlend)
     23     {
     24       case GL_ZERO:                     d3dBlend = D3D11_BLEND_ZERO;                break;
     25       case GL_ONE:                      d3dBlend = D3D11_BLEND_ONE;                 break;
     26       case GL_SRC_COLOR:                d3dBlend = (isAlpha ? D3D11_BLEND_SRC_ALPHA : D3D11_BLEND_SRC_COLOR);           break;
     27       case GL_ONE_MINUS_SRC_COLOR:      d3dBlend = (isAlpha ? D3D11_BLEND_INV_SRC_ALPHA : D3D11_BLEND_INV_SRC_COLOR);   break;
     28       case GL_DST_COLOR:                d3dBlend = (isAlpha ? D3D11_BLEND_DEST_ALPHA : D3D11_BLEND_DEST_COLOR);         break;
     29       case GL_ONE_MINUS_DST_COLOR:      d3dBlend = (isAlpha ? D3D11_BLEND_INV_DEST_ALPHA : D3D11_BLEND_INV_DEST_COLOR); break;
     30       case GL_SRC_ALPHA:                d3dBlend = D3D11_BLEND_SRC_ALPHA;           break;
     31       case GL_ONE_MINUS_SRC_ALPHA:      d3dBlend = D3D11_BLEND_INV_SRC_ALPHA;       break;
     32       case GL_DST_ALPHA:                d3dBlend = D3D11_BLEND_DEST_ALPHA;          break;
     33       case GL_ONE_MINUS_DST_ALPHA:      d3dBlend = D3D11_BLEND_INV_DEST_ALPHA;      break;
     34       case GL_CONSTANT_COLOR:           d3dBlend = D3D11_BLEND_BLEND_FACTOR;        break;
     35       case GL_ONE_MINUS_CONSTANT_COLOR: d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR;    break;
     36       case GL_CONSTANT_ALPHA:           d3dBlend = D3D11_BLEND_BLEND_FACTOR;        break;
     37       case GL_ONE_MINUS_CONSTANT_ALPHA: d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR;    break;
     38       case GL_SRC_ALPHA_SATURATE:       d3dBlend = D3D11_BLEND_SRC_ALPHA_SAT;       break;
     39       default: UNREACHABLE();
     40     }
     41 
     42     return d3dBlend;
     43 }
     44 
     45 D3D11_BLEND_OP ConvertBlendOp(GLenum glBlendOp)
     46 {
     47     D3D11_BLEND_OP d3dBlendOp = D3D11_BLEND_OP_ADD;
     48 
     49     switch (glBlendOp)
     50     {
     51       case GL_FUNC_ADD:              d3dBlendOp = D3D11_BLEND_OP_ADD;           break;
     52       case GL_FUNC_SUBTRACT:         d3dBlendOp = D3D11_BLEND_OP_SUBTRACT;      break;
     53       case GL_FUNC_REVERSE_SUBTRACT: d3dBlendOp = D3D11_BLEND_OP_REV_SUBTRACT;  break;
     54       default: UNREACHABLE();
     55     }
     56 
     57     return d3dBlendOp;
     58 }
     59 
     60 UINT8 ConvertColorMask(bool red, bool green, bool blue, bool alpha)
     61 {
     62     UINT8 mask = 0;
     63     if (red)
     64     {
     65         mask |= D3D11_COLOR_WRITE_ENABLE_RED;
     66     }
     67     if (green)
     68     {
     69         mask |= D3D11_COLOR_WRITE_ENABLE_GREEN;
     70     }
     71     if (blue)
     72     {
     73         mask |= D3D11_COLOR_WRITE_ENABLE_BLUE;
     74     }
     75     if (alpha)
     76     {
     77         mask |= D3D11_COLOR_WRITE_ENABLE_ALPHA;
     78     }
     79     return mask;
     80 }
     81 
     82 D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, GLenum cullMode)
     83 {
     84     D3D11_CULL_MODE cull = D3D11_CULL_NONE;
     85 
     86     if (cullEnabled)
     87     {
     88         switch (cullMode)
     89         {
     90           case GL_FRONT:            cull = D3D11_CULL_FRONT;    break;
     91           case GL_BACK:             cull = D3D11_CULL_BACK;     break;
     92           case GL_FRONT_AND_BACK:   cull = D3D11_CULL_NONE;     break;
     93           default: UNREACHABLE();
     94         }
     95     }
     96     else
     97     {
     98         cull = D3D11_CULL_NONE;
     99     }
    100 
    101     return cull;
    102 }
    103 
    104 D3D11_COMPARISON_FUNC ConvertComparison(GLenum comparison)
    105 {
    106     D3D11_COMPARISON_FUNC d3dComp = D3D11_COMPARISON_NEVER;
    107     switch (comparison)
    108     {
    109       case GL_NEVER:    d3dComp = D3D11_COMPARISON_NEVER;           break;
    110       case GL_ALWAYS:   d3dComp = D3D11_COMPARISON_ALWAYS;          break;
    111       case GL_LESS:     d3dComp = D3D11_COMPARISON_LESS;            break;
    112       case GL_LEQUAL:   d3dComp = D3D11_COMPARISON_LESS_EQUAL;      break;
    113       case GL_EQUAL:    d3dComp = D3D11_COMPARISON_EQUAL;           break;
    114       case GL_GREATER:  d3dComp = D3D11_COMPARISON_GREATER;         break;
    115       case GL_GEQUAL:   d3dComp = D3D11_COMPARISON_GREATER_EQUAL;   break;
    116       case GL_NOTEQUAL: d3dComp = D3D11_COMPARISON_NOT_EQUAL;       break;
    117       default: UNREACHABLE();
    118     }
    119 
    120     return d3dComp;
    121 }
    122 
    123 D3D11_DEPTH_WRITE_MASK ConvertDepthMask(bool depthWriteEnabled)
    124 {
    125     return depthWriteEnabled ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
    126 }
    127 
    128 UINT8 ConvertStencilMask(GLuint stencilmask)
    129 {
    130     return static_cast<UINT8>(stencilmask);
    131 }
    132 
    133 D3D11_STENCIL_OP ConvertStencilOp(GLenum stencilOp)
    134 {
    135     D3D11_STENCIL_OP d3dStencilOp = D3D11_STENCIL_OP_KEEP;
    136 
    137     switch (stencilOp)
    138     {
    139       case GL_ZERO:      d3dStencilOp = D3D11_STENCIL_OP_ZERO;      break;
    140       case GL_KEEP:      d3dStencilOp = D3D11_STENCIL_OP_KEEP;      break;
    141       case GL_REPLACE:   d3dStencilOp = D3D11_STENCIL_OP_REPLACE;   break;
    142       case GL_INCR:      d3dStencilOp = D3D11_STENCIL_OP_INCR_SAT;  break;
    143       case GL_DECR:      d3dStencilOp = D3D11_STENCIL_OP_DECR_SAT;  break;
    144       case GL_INVERT:    d3dStencilOp = D3D11_STENCIL_OP_INVERT;    break;
    145       case GL_INCR_WRAP: d3dStencilOp = D3D11_STENCIL_OP_INCR;      break;
    146       case GL_DECR_WRAP: d3dStencilOp = D3D11_STENCIL_OP_DECR;      break;
    147       default: UNREACHABLE();
    148     }
    149 
    150     return d3dStencilOp;
    151 }
    152 
    153 D3D11_FILTER ConvertFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy)
    154 {
    155     if (maxAnisotropy > 1.0f)
    156     {
    157         return D3D11_ENCODE_ANISOTROPIC_FILTER(false);
    158     }
    159     else
    160     {
    161         D3D11_FILTER_TYPE dxMin = D3D11_FILTER_TYPE_POINT;
    162         D3D11_FILTER_TYPE dxMip = D3D11_FILTER_TYPE_POINT;
    163         switch (minFilter)
    164         {
    165           case GL_NEAREST:                dxMin = D3D11_FILTER_TYPE_POINT;  dxMip = D3D11_FILTER_TYPE_POINT;  break;
    166           case GL_LINEAR:                 dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_POINT;  break;
    167           case GL_NEAREST_MIPMAP_NEAREST: dxMin = D3D11_FILTER_TYPE_POINT;  dxMip = D3D11_FILTER_TYPE_POINT;  break;
    168           case GL_LINEAR_MIPMAP_NEAREST:  dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_POINT;  break;
    169           case GL_NEAREST_MIPMAP_LINEAR:  dxMin = D3D11_FILTER_TYPE_POINT;  dxMip = D3D11_FILTER_TYPE_LINEAR; break;
    170           case GL_LINEAR_MIPMAP_LINEAR:   dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_LINEAR; break;
    171           default:                        UNREACHABLE();
    172         }
    173 
    174         D3D11_FILTER_TYPE dxMag = D3D11_FILTER_TYPE_POINT;
    175         switch (magFilter)
    176         {
    177           case GL_NEAREST: dxMag = D3D11_FILTER_TYPE_POINT;  break;
    178           case GL_LINEAR:  dxMag = D3D11_FILTER_TYPE_LINEAR; break;
    179           default:         UNREACHABLE();
    180         }
    181 
    182         return D3D11_ENCODE_BASIC_FILTER(dxMin, dxMag, dxMip, false);
    183     }
    184 }
    185 
    186 D3D11_TEXTURE_ADDRESS_MODE ConvertTextureWrap(GLenum wrap)
    187 {
    188     switch (wrap)
    189     {
    190       case GL_REPEAT:          return D3D11_TEXTURE_ADDRESS_WRAP;
    191       case GL_CLAMP_TO_EDGE:   return D3D11_TEXTURE_ADDRESS_CLAMP;
    192       case GL_MIRRORED_REPEAT: return D3D11_TEXTURE_ADDRESS_MIRROR;
    193       default:                 UNREACHABLE();
    194     }
    195 
    196     return D3D11_TEXTURE_ADDRESS_WRAP;
    197 }
    198 
    199 FLOAT ConvertMinLOD(GLenum minFilter, unsigned int lodOffset)
    200 {
    201     return (minFilter == GL_NEAREST || minFilter == GL_LINEAR) ? static_cast<float>(lodOffset) : -FLT_MAX;
    202 }
    203 
    204 FLOAT ConvertMaxLOD(GLenum minFilter, unsigned int lodOffset)
    205 {
    206     return (minFilter == GL_NEAREST || minFilter == GL_LINEAR) ? static_cast<float>(lodOffset) : FLT_MAX;
    207 }
    208 
    209 }
    210 
    211 namespace d3d11_gl
    212 {
    213 
    214 GLenum ConvertBackBufferFormat(DXGI_FORMAT format)
    215 {
    216     switch (format)
    217     {
    218       case DXGI_FORMAT_R8G8B8A8_UNORM: return GL_RGBA8_OES;
    219       case DXGI_FORMAT_B8G8R8A8_UNORM: return GL_BGRA8_EXT;
    220       default:
    221         UNREACHABLE();
    222     }
    223 
    224     return GL_RGBA8_OES;
    225 }
    226 
    227 GLenum ConvertDepthStencilFormat(DXGI_FORMAT format)
    228 {
    229     switch (format)
    230     {
    231       case DXGI_FORMAT_UNKNOWN: return GL_NONE;
    232       case DXGI_FORMAT_D16_UNORM: return GL_DEPTH_COMPONENT16;
    233       case DXGI_FORMAT_D24_UNORM_S8_UINT: return GL_DEPTH24_STENCIL8_OES;
    234       default:
    235         UNREACHABLE();
    236     }
    237 
    238     return GL_DEPTH24_STENCIL8_OES;
    239 }
    240 
    241 GLenum ConvertRenderbufferFormat(DXGI_FORMAT format)
    242 {
    243     switch (format)
    244     {
    245       case DXGI_FORMAT_B8G8R8A8_UNORM:
    246         return GL_BGRA8_EXT;
    247       case DXGI_FORMAT_R8G8B8A8_UNORM:
    248         return GL_RGBA8_OES;
    249       case DXGI_FORMAT_D16_UNORM:
    250         return GL_DEPTH_COMPONENT16;
    251       case DXGI_FORMAT_D24_UNORM_S8_UINT:
    252         return GL_DEPTH24_STENCIL8_OES;
    253       default:
    254         UNREACHABLE();
    255     }
    256 
    257     return GL_RGBA8_OES;
    258 }
    259 
    260 GLenum ConvertTextureInternalFormat(DXGI_FORMAT format)
    261 {
    262     switch (format)
    263     {
    264       case DXGI_FORMAT_R8G8B8A8_UNORM:
    265         return GL_RGBA8_OES;
    266       case DXGI_FORMAT_A8_UNORM:
    267         return GL_ALPHA8_EXT;
    268       case DXGI_FORMAT_BC1_UNORM:
    269         return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
    270       case DXGI_FORMAT_BC2_UNORM:
    271         return GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE;
    272       case DXGI_FORMAT_BC3_UNORM:
    273         return GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE;
    274       case DXGI_FORMAT_R32G32B32A32_FLOAT:
    275         return GL_RGBA32F_EXT;
    276       case DXGI_FORMAT_R32G32B32_FLOAT:
    277         return GL_RGB32F_EXT;
    278       case DXGI_FORMAT_R16G16B16A16_FLOAT:
    279         return GL_RGBA16F_EXT;
    280       case DXGI_FORMAT_B8G8R8A8_UNORM:
    281         return GL_BGRA8_EXT;
    282       case DXGI_FORMAT_R8_UNORM:
    283         return GL_R8_EXT;
    284       case DXGI_FORMAT_R8G8_UNORM:
    285         return GL_RG8_EXT;
    286       case DXGI_FORMAT_R16_FLOAT:
    287         return GL_R16F_EXT;
    288       case DXGI_FORMAT_R16G16_FLOAT:
    289         return GL_RG16F_EXT;
    290       case DXGI_FORMAT_D16_UNORM:
    291         return GL_DEPTH_COMPONENT16;
    292       case DXGI_FORMAT_D24_UNORM_S8_UINT:
    293         return GL_DEPTH24_STENCIL8_OES;
    294       case DXGI_FORMAT_UNKNOWN:
    295         return GL_NONE;
    296       default:
    297         UNREACHABLE();
    298     }
    299 
    300     return GL_RGBA8_OES;
    301 }
    302 
    303 }
    304 
    305 namespace gl_d3d11
    306 {
    307 
    308 DXGI_FORMAT ConvertRenderbufferFormat(GLenum format)
    309 {
    310     switch (format)
    311     {
    312       case GL_RGBA4:
    313       case GL_RGB5_A1:
    314       case GL_RGBA8_OES:
    315       case GL_RGB565:
    316       case GL_RGB8_OES:
    317         return DXGI_FORMAT_R8G8B8A8_UNORM;
    318       case GL_BGRA8_EXT:
    319         return DXGI_FORMAT_B8G8R8A8_UNORM;
    320       case GL_DEPTH_COMPONENT16:
    321         return DXGI_FORMAT_D16_UNORM;
    322       case GL_STENCIL_INDEX8:
    323       case GL_DEPTH24_STENCIL8_OES:
    324         return DXGI_FORMAT_D24_UNORM_S8_UINT;
    325       default:
    326         UNREACHABLE();
    327     }
    328 
    329     return DXGI_FORMAT_R8G8B8A8_UNORM;
    330 }
    331 
    332 DXGI_FORMAT ConvertTextureFormat(GLenum internalformat)
    333 {
    334     switch (internalformat)
    335     {
    336       case GL_RGB565:
    337       case GL_RGBA4:
    338       case GL_RGB5_A1:
    339       case GL_RGB8_OES:
    340       case GL_RGBA8_OES:
    341       case GL_LUMINANCE8_EXT:
    342       case GL_LUMINANCE8_ALPHA8_EXT:
    343         return DXGI_FORMAT_R8G8B8A8_UNORM;
    344       case GL_ALPHA8_EXT:
    345         return DXGI_FORMAT_A8_UNORM;
    346       case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
    347       case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
    348         return DXGI_FORMAT_BC1_UNORM;
    349       case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
    350         return DXGI_FORMAT_BC2_UNORM;
    351       case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
    352         return DXGI_FORMAT_BC3_UNORM;
    353       case GL_RGBA32F_EXT:
    354       case GL_ALPHA32F_EXT:
    355       case GL_LUMINANCE_ALPHA32F_EXT:
    356         return DXGI_FORMAT_R32G32B32A32_FLOAT;
    357       case GL_RGB32F_EXT:
    358       case GL_LUMINANCE32F_EXT:
    359         return DXGI_FORMAT_R32G32B32A32_FLOAT;
    360       case GL_RGBA16F_EXT:
    361       case GL_ALPHA16F_EXT:
    362       case GL_LUMINANCE_ALPHA16F_EXT:
    363       case GL_RGB16F_EXT:
    364       case GL_LUMINANCE16F_EXT:
    365         return DXGI_FORMAT_R16G16B16A16_FLOAT;
    366       case GL_BGRA8_EXT:
    367         return DXGI_FORMAT_B8G8R8A8_UNORM;
    368       case GL_R8_EXT:
    369         return DXGI_FORMAT_R8_UNORM;
    370       case GL_RG8_EXT:
    371         return DXGI_FORMAT_R8G8_UNORM;
    372       case GL_R16F_EXT:
    373         return DXGI_FORMAT_R16_FLOAT;
    374       case GL_RG16F_EXT:
    375         return DXGI_FORMAT_R16G16_FLOAT;
    376       case GL_DEPTH_COMPONENT16:
    377         return DXGI_FORMAT_D16_UNORM;
    378       case GL_DEPTH_COMPONENT32_OES:
    379       case GL_DEPTH24_STENCIL8_OES:
    380         return DXGI_FORMAT_D24_UNORM_S8_UINT;
    381       case GL_NONE:
    382         return DXGI_FORMAT_UNKNOWN;
    383       default:
    384         UNREACHABLE();
    385     }
    386 
    387     return DXGI_FORMAT_R8G8B8A8_UNORM;
    388 }
    389 
    390 }
    391 
    392 namespace d3d11
    393 {
    394 
    395 void SetPositionTexCoordVertex(PositionTexCoordVertex* vertex, float x, float y, float u, float v)
    396 {
    397     vertex->x = x;
    398     vertex->y = y;
    399     vertex->u = u;
    400     vertex->v = v;
    401 }
    402 
    403 void SetPositionDepthColorVertex(PositionDepthColorVertex* vertex, float x, float y, float z,
    404                                  const gl::Color &color)
    405 {
    406     vertex->x = x;
    407     vertex->y = y;
    408     vertex->z = z;
    409     vertex->r = color.red;
    410     vertex->g = color.green;
    411     vertex->b = color.blue;
    412     vertex->a = color.alpha;
    413 }
    414 
    415 size_t ComputePixelSizeBits(DXGI_FORMAT format)
    416 {
    417     switch (format)
    418     {
    419       case DXGI_FORMAT_R1_UNORM:
    420         return 1;
    421 
    422       case DXGI_FORMAT_A8_UNORM:
    423       case DXGI_FORMAT_R8_SINT:
    424       case DXGI_FORMAT_R8_SNORM:
    425       case DXGI_FORMAT_R8_TYPELESS:
    426       case DXGI_FORMAT_R8_UINT:
    427       case DXGI_FORMAT_R8_UNORM:
    428         return 8;
    429 
    430       case DXGI_FORMAT_B5G5R5A1_UNORM:
    431       case DXGI_FORMAT_B5G6R5_UNORM:
    432       case DXGI_FORMAT_D16_UNORM:
    433       case DXGI_FORMAT_R16_FLOAT:
    434       case DXGI_FORMAT_R16_SINT:
    435       case DXGI_FORMAT_R16_SNORM:
    436       case DXGI_FORMAT_R16_TYPELESS:
    437       case DXGI_FORMAT_R16_UINT:
    438       case DXGI_FORMAT_R16_UNORM:
    439       case DXGI_FORMAT_R8G8_SINT:
    440       case DXGI_FORMAT_R8G8_SNORM:
    441       case DXGI_FORMAT_R8G8_TYPELESS:
    442       case DXGI_FORMAT_R8G8_UINT:
    443       case DXGI_FORMAT_R8G8_UNORM:
    444         return 16;
    445 
    446       case DXGI_FORMAT_B8G8R8X8_TYPELESS:
    447       case DXGI_FORMAT_B8G8R8X8_UNORM:
    448       case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
    449       case DXGI_FORMAT_D24_UNORM_S8_UINT:
    450       case DXGI_FORMAT_D32_FLOAT:
    451       case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
    452       case DXGI_FORMAT_G8R8_G8B8_UNORM:
    453       case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
    454       case DXGI_FORMAT_R10G10B10A2_TYPELESS:
    455       case DXGI_FORMAT_R10G10B10A2_UINT:
    456       case DXGI_FORMAT_R10G10B10A2_UNORM:
    457       case DXGI_FORMAT_R11G11B10_FLOAT:
    458       case DXGI_FORMAT_R16G16_FLOAT:
    459       case DXGI_FORMAT_R16G16_SINT:
    460       case DXGI_FORMAT_R16G16_SNORM:
    461       case DXGI_FORMAT_R16G16_TYPELESS:
    462       case DXGI_FORMAT_R16G16_UINT:
    463       case DXGI_FORMAT_R16G16_UNORM:
    464       case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
    465       case DXGI_FORMAT_R24G8_TYPELESS:
    466       case DXGI_FORMAT_R32_FLOAT:
    467       case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
    468       case DXGI_FORMAT_R32_SINT:
    469       case DXGI_FORMAT_R32_TYPELESS:
    470       case DXGI_FORMAT_R32_UINT:
    471       case DXGI_FORMAT_R8G8_B8G8_UNORM:
    472       case DXGI_FORMAT_R8G8B8A8_SINT:
    473       case DXGI_FORMAT_R8G8B8A8_SNORM:
    474       case DXGI_FORMAT_R8G8B8A8_TYPELESS:
    475       case DXGI_FORMAT_R8G8B8A8_UINT:
    476       case DXGI_FORMAT_R8G8B8A8_UNORM:
    477       case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
    478       case DXGI_FORMAT_B8G8R8A8_TYPELESS:
    479       case DXGI_FORMAT_B8G8R8A8_UNORM:
    480       case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
    481       case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
    482       case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
    483       case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
    484         return 32;
    485 
    486       case DXGI_FORMAT_R16G16B16A16_FLOAT:
    487       case DXGI_FORMAT_R16G16B16A16_SINT:
    488       case DXGI_FORMAT_R16G16B16A16_SNORM:
    489       case DXGI_FORMAT_R16G16B16A16_TYPELESS:
    490       case DXGI_FORMAT_R16G16B16A16_UINT:
    491       case DXGI_FORMAT_R16G16B16A16_UNORM:
    492       case DXGI_FORMAT_R32G32_FLOAT:
    493       case DXGI_FORMAT_R32G32_SINT:
    494       case DXGI_FORMAT_R32G32_TYPELESS:
    495       case DXGI_FORMAT_R32G32_UINT:
    496       case DXGI_FORMAT_R32G8X24_TYPELESS:
    497         return 64;
    498 
    499       case DXGI_FORMAT_R32G32B32_FLOAT:
    500       case DXGI_FORMAT_R32G32B32_SINT:
    501       case DXGI_FORMAT_R32G32B32_TYPELESS:
    502       case DXGI_FORMAT_R32G32B32_UINT:
    503         return 96;
    504 
    505       case DXGI_FORMAT_R32G32B32A32_FLOAT:
    506       case DXGI_FORMAT_R32G32B32A32_SINT:
    507       case DXGI_FORMAT_R32G32B32A32_TYPELESS:
    508       case DXGI_FORMAT_R32G32B32A32_UINT:
    509         return 128;
    510 
    511       case DXGI_FORMAT_BC1_TYPELESS:
    512       case DXGI_FORMAT_BC1_UNORM:
    513       case DXGI_FORMAT_BC1_UNORM_SRGB:
    514       case DXGI_FORMAT_BC4_SNORM:
    515       case DXGI_FORMAT_BC4_TYPELESS:
    516       case DXGI_FORMAT_BC4_UNORM:
    517         return 4;
    518 
    519       case DXGI_FORMAT_BC2_TYPELESS:
    520       case DXGI_FORMAT_BC2_UNORM:
    521       case DXGI_FORMAT_BC2_UNORM_SRGB:
    522       case DXGI_FORMAT_BC3_TYPELESS:
    523       case DXGI_FORMAT_BC3_UNORM:
    524       case DXGI_FORMAT_BC3_UNORM_SRGB:
    525       case DXGI_FORMAT_BC5_SNORM:
    526       case DXGI_FORMAT_BC5_TYPELESS:
    527       case DXGI_FORMAT_BC5_UNORM:
    528       case DXGI_FORMAT_BC6H_SF16:
    529       case DXGI_FORMAT_BC6H_TYPELESS:
    530       case DXGI_FORMAT_BC6H_UF16:
    531       case DXGI_FORMAT_BC7_TYPELESS:
    532       case DXGI_FORMAT_BC7_UNORM:
    533       case DXGI_FORMAT_BC7_UNORM_SRGB:
    534         return 8;
    535 
    536       default:
    537         return 0;
    538     }
    539 }
    540 
    541 size_t ComputeBlockSizeBits(DXGI_FORMAT format)
    542 {
    543     switch (format)
    544     {
    545       case DXGI_FORMAT_BC1_TYPELESS:
    546       case DXGI_FORMAT_BC1_UNORM:
    547       case DXGI_FORMAT_BC1_UNORM_SRGB:
    548       case DXGI_FORMAT_BC4_SNORM:
    549       case DXGI_FORMAT_BC4_TYPELESS:
    550       case DXGI_FORMAT_BC4_UNORM:
    551       case DXGI_FORMAT_BC2_TYPELESS:
    552       case DXGI_FORMAT_BC2_UNORM:
    553       case DXGI_FORMAT_BC2_UNORM_SRGB:
    554       case DXGI_FORMAT_BC3_TYPELESS:
    555       case DXGI_FORMAT_BC3_UNORM:
    556       case DXGI_FORMAT_BC3_UNORM_SRGB:
    557       case DXGI_FORMAT_BC5_SNORM:
    558       case DXGI_FORMAT_BC5_TYPELESS:
    559       case DXGI_FORMAT_BC5_UNORM:
    560       case DXGI_FORMAT_BC6H_SF16:
    561       case DXGI_FORMAT_BC6H_TYPELESS:
    562       case DXGI_FORMAT_BC6H_UF16:
    563       case DXGI_FORMAT_BC7_TYPELESS:
    564       case DXGI_FORMAT_BC7_UNORM:
    565       case DXGI_FORMAT_BC7_UNORM_SRGB:
    566         return ComputePixelSizeBits(format) * 16;
    567       default:
    568         UNREACHABLE();
    569         return 0;
    570     }
    571 }
    572 
    573 bool IsCompressed(DXGI_FORMAT format)
    574 {
    575     switch (format)
    576     {
    577       case DXGI_FORMAT_BC1_TYPELESS:
    578       case DXGI_FORMAT_BC1_UNORM:
    579       case DXGI_FORMAT_BC1_UNORM_SRGB:
    580       case DXGI_FORMAT_BC4_SNORM:
    581       case DXGI_FORMAT_BC4_TYPELESS:
    582       case DXGI_FORMAT_BC4_UNORM:
    583       case DXGI_FORMAT_BC2_TYPELESS:
    584       case DXGI_FORMAT_BC2_UNORM:
    585       case DXGI_FORMAT_BC2_UNORM_SRGB:
    586       case DXGI_FORMAT_BC3_TYPELESS:
    587       case DXGI_FORMAT_BC3_UNORM:
    588       case DXGI_FORMAT_BC3_UNORM_SRGB:
    589       case DXGI_FORMAT_BC5_SNORM:
    590       case DXGI_FORMAT_BC5_TYPELESS:
    591       case DXGI_FORMAT_BC5_UNORM:
    592       case DXGI_FORMAT_BC6H_SF16:
    593       case DXGI_FORMAT_BC6H_TYPELESS:
    594       case DXGI_FORMAT_BC6H_UF16:
    595       case DXGI_FORMAT_BC7_TYPELESS:
    596       case DXGI_FORMAT_BC7_UNORM:
    597       case DXGI_FORMAT_BC7_UNORM_SRGB:
    598         return true;
    599       case DXGI_FORMAT_UNKNOWN:
    600         UNREACHABLE();
    601         return false;
    602       default:
    603         return false;
    604     }
    605 }
    606 
    607 unsigned int GetTextureFormatDimensionAlignment(DXGI_FORMAT format)
    608 {
    609     switch (format)
    610     {
    611       case DXGI_FORMAT_BC1_TYPELESS:
    612       case DXGI_FORMAT_BC1_UNORM:
    613       case DXGI_FORMAT_BC1_UNORM_SRGB:
    614       case DXGI_FORMAT_BC4_SNORM:
    615       case DXGI_FORMAT_BC4_TYPELESS:
    616       case DXGI_FORMAT_BC4_UNORM:
    617       case DXGI_FORMAT_BC2_TYPELESS:
    618       case DXGI_FORMAT_BC2_UNORM:
    619       case DXGI_FORMAT_BC2_UNORM_SRGB:
    620       case DXGI_FORMAT_BC3_TYPELESS:
    621       case DXGI_FORMAT_BC3_UNORM:
    622       case DXGI_FORMAT_BC3_UNORM_SRGB:
    623       case DXGI_FORMAT_BC5_SNORM:
    624       case DXGI_FORMAT_BC5_TYPELESS:
    625       case DXGI_FORMAT_BC5_UNORM:
    626       case DXGI_FORMAT_BC6H_SF16:
    627       case DXGI_FORMAT_BC6H_TYPELESS:
    628       case DXGI_FORMAT_BC6H_UF16:
    629       case DXGI_FORMAT_BC7_TYPELESS:
    630       case DXGI_FORMAT_BC7_UNORM:
    631       case DXGI_FORMAT_BC7_UNORM_SRGB:
    632         return 4;
    633       case DXGI_FORMAT_UNKNOWN:
    634         UNREACHABLE();
    635         return 1;
    636       default:
    637         return 1;
    638     }
    639 }
    640 
    641 bool IsDepthStencilFormat(DXGI_FORMAT format)
    642 {
    643     switch (format)
    644     {
    645       case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
    646       case DXGI_FORMAT_D32_FLOAT:
    647       case DXGI_FORMAT_D24_UNORM_S8_UINT:
    648       case DXGI_FORMAT_D16_UNORM:
    649         return true;
    650       default:
    651         return false;
    652     }
    653 }
    654 
    655 DXGI_FORMAT GetDepthTextureFormat(DXGI_FORMAT format)
    656 {
    657     switch (format)
    658     {
    659       case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: return DXGI_FORMAT_R32G8X24_TYPELESS;
    660       case DXGI_FORMAT_D32_FLOAT:            return DXGI_FORMAT_R32_TYPELESS;
    661       case DXGI_FORMAT_D24_UNORM_S8_UINT:    return DXGI_FORMAT_R24G8_TYPELESS;
    662       case DXGI_FORMAT_D16_UNORM:            return DXGI_FORMAT_R16_TYPELESS;
    663       default: UNREACHABLE();                return DXGI_FORMAT_UNKNOWN;
    664     }
    665 }
    666 
    667 DXGI_FORMAT GetDepthShaderResourceFormat(DXGI_FORMAT format)
    668 {
    669     switch (format)
    670     {
    671       case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: return DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS;
    672       case DXGI_FORMAT_D32_FLOAT:            return DXGI_FORMAT_R32_UINT;
    673       case DXGI_FORMAT_D24_UNORM_S8_UINT:    return DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
    674       case DXGI_FORMAT_D16_UNORM:            return DXGI_FORMAT_R16_UNORM;
    675       default: UNREACHABLE();                return DXGI_FORMAT_UNKNOWN;
    676     }
    677 }
    678 
    679 HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name)
    680 {
    681 #if defined(_DEBUG)
    682     return resource->SetPrivateData(WKPDID_D3DDebugObjectName, strlen(name), name);
    683 #else
    684     return S_OK;
    685 #endif
    686 }
    687 
    688 }
    689