Home | History | Annotate | Download | only in d3d11
      1 //
      2 // Copyright (c) 2012-2014 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 // renderer11_utils.cpp: Conversion functions and other utility routines
      8 // specific to the D3D11 renderer.
      9 
     10 #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
     11 #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
     12 #include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
     13 #include "libGLESv2/ProgramBinary.h"
     14 #include "libGLESv2/Framebuffer.h"
     15 
     16 #include "common/debug.h"
     17 
     18 #include <algorithm>
     19 
     20 namespace rx
     21 {
     22 
     23 namespace gl_d3d11
     24 {
     25 
     26 D3D11_BLEND ConvertBlendFunc(GLenum glBlend, bool isAlpha)
     27 {
     28     D3D11_BLEND d3dBlend = D3D11_BLEND_ZERO;
     29 
     30     switch (glBlend)
     31     {
     32       case GL_ZERO:                     d3dBlend = D3D11_BLEND_ZERO;                break;
     33       case GL_ONE:                      d3dBlend = D3D11_BLEND_ONE;                 break;
     34       case GL_SRC_COLOR:                d3dBlend = (isAlpha ? D3D11_BLEND_SRC_ALPHA : D3D11_BLEND_SRC_COLOR);           break;
     35       case GL_ONE_MINUS_SRC_COLOR:      d3dBlend = (isAlpha ? D3D11_BLEND_INV_SRC_ALPHA : D3D11_BLEND_INV_SRC_COLOR);   break;
     36       case GL_DST_COLOR:                d3dBlend = (isAlpha ? D3D11_BLEND_DEST_ALPHA : D3D11_BLEND_DEST_COLOR);         break;
     37       case GL_ONE_MINUS_DST_COLOR:      d3dBlend = (isAlpha ? D3D11_BLEND_INV_DEST_ALPHA : D3D11_BLEND_INV_DEST_COLOR); break;
     38       case GL_SRC_ALPHA:                d3dBlend = D3D11_BLEND_SRC_ALPHA;           break;
     39       case GL_ONE_MINUS_SRC_ALPHA:      d3dBlend = D3D11_BLEND_INV_SRC_ALPHA;       break;
     40       case GL_DST_ALPHA:                d3dBlend = D3D11_BLEND_DEST_ALPHA;          break;
     41       case GL_ONE_MINUS_DST_ALPHA:      d3dBlend = D3D11_BLEND_INV_DEST_ALPHA;      break;
     42       case GL_CONSTANT_COLOR:           d3dBlend = D3D11_BLEND_BLEND_FACTOR;        break;
     43       case GL_ONE_MINUS_CONSTANT_COLOR: d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR;    break;
     44       case GL_CONSTANT_ALPHA:           d3dBlend = D3D11_BLEND_BLEND_FACTOR;        break;
     45       case GL_ONE_MINUS_CONSTANT_ALPHA: d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR;    break;
     46       case GL_SRC_ALPHA_SATURATE:       d3dBlend = D3D11_BLEND_SRC_ALPHA_SAT;       break;
     47       default: UNREACHABLE();
     48     }
     49 
     50     return d3dBlend;
     51 }
     52 
     53 D3D11_BLEND_OP ConvertBlendOp(GLenum glBlendOp)
     54 {
     55     D3D11_BLEND_OP d3dBlendOp = D3D11_BLEND_OP_ADD;
     56 
     57     switch (glBlendOp)
     58     {
     59       case GL_FUNC_ADD:              d3dBlendOp = D3D11_BLEND_OP_ADD;           break;
     60       case GL_FUNC_SUBTRACT:         d3dBlendOp = D3D11_BLEND_OP_SUBTRACT;      break;
     61       case GL_FUNC_REVERSE_SUBTRACT: d3dBlendOp = D3D11_BLEND_OP_REV_SUBTRACT;  break;
     62       case GL_MIN:                   d3dBlendOp = D3D11_BLEND_OP_MIN;           break;
     63       case GL_MAX:                   d3dBlendOp = D3D11_BLEND_OP_MAX;           break;
     64       default: UNREACHABLE();
     65     }
     66 
     67     return d3dBlendOp;
     68 }
     69 
     70 UINT8 ConvertColorMask(bool red, bool green, bool blue, bool alpha)
     71 {
     72     UINT8 mask = 0;
     73     if (red)
     74     {
     75         mask |= D3D11_COLOR_WRITE_ENABLE_RED;
     76     }
     77     if (green)
     78     {
     79         mask |= D3D11_COLOR_WRITE_ENABLE_GREEN;
     80     }
     81     if (blue)
     82     {
     83         mask |= D3D11_COLOR_WRITE_ENABLE_BLUE;
     84     }
     85     if (alpha)
     86     {
     87         mask |= D3D11_COLOR_WRITE_ENABLE_ALPHA;
     88     }
     89     return mask;
     90 }
     91 
     92 D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, GLenum cullMode)
     93 {
     94     D3D11_CULL_MODE cull = D3D11_CULL_NONE;
     95 
     96     if (cullEnabled)
     97     {
     98         switch (cullMode)
     99         {
    100           case GL_FRONT:            cull = D3D11_CULL_FRONT;    break;
    101           case GL_BACK:             cull = D3D11_CULL_BACK;     break;
    102           case GL_FRONT_AND_BACK:   cull = D3D11_CULL_NONE;     break;
    103           default: UNREACHABLE();
    104         }
    105     }
    106     else
    107     {
    108         cull = D3D11_CULL_NONE;
    109     }
    110 
    111     return cull;
    112 }
    113 
    114 D3D11_COMPARISON_FUNC ConvertComparison(GLenum comparison)
    115 {
    116     D3D11_COMPARISON_FUNC d3dComp = D3D11_COMPARISON_NEVER;
    117     switch (comparison)
    118     {
    119       case GL_NEVER:    d3dComp = D3D11_COMPARISON_NEVER;           break;
    120       case GL_ALWAYS:   d3dComp = D3D11_COMPARISON_ALWAYS;          break;
    121       case GL_LESS:     d3dComp = D3D11_COMPARISON_LESS;            break;
    122       case GL_LEQUAL:   d3dComp = D3D11_COMPARISON_LESS_EQUAL;      break;
    123       case GL_EQUAL:    d3dComp = D3D11_COMPARISON_EQUAL;           break;
    124       case GL_GREATER:  d3dComp = D3D11_COMPARISON_GREATER;         break;
    125       case GL_GEQUAL:   d3dComp = D3D11_COMPARISON_GREATER_EQUAL;   break;
    126       case GL_NOTEQUAL: d3dComp = D3D11_COMPARISON_NOT_EQUAL;       break;
    127       default: UNREACHABLE();
    128     }
    129 
    130     return d3dComp;
    131 }
    132 
    133 D3D11_DEPTH_WRITE_MASK ConvertDepthMask(bool depthWriteEnabled)
    134 {
    135     return depthWriteEnabled ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
    136 }
    137 
    138 UINT8 ConvertStencilMask(GLuint stencilmask)
    139 {
    140     return static_cast<UINT8>(stencilmask);
    141 }
    142 
    143 D3D11_STENCIL_OP ConvertStencilOp(GLenum stencilOp)
    144 {
    145     D3D11_STENCIL_OP d3dStencilOp = D3D11_STENCIL_OP_KEEP;
    146 
    147     switch (stencilOp)
    148     {
    149       case GL_ZERO:      d3dStencilOp = D3D11_STENCIL_OP_ZERO;      break;
    150       case GL_KEEP:      d3dStencilOp = D3D11_STENCIL_OP_KEEP;      break;
    151       case GL_REPLACE:   d3dStencilOp = D3D11_STENCIL_OP_REPLACE;   break;
    152       case GL_INCR:      d3dStencilOp = D3D11_STENCIL_OP_INCR_SAT;  break;
    153       case GL_DECR:      d3dStencilOp = D3D11_STENCIL_OP_DECR_SAT;  break;
    154       case GL_INVERT:    d3dStencilOp = D3D11_STENCIL_OP_INVERT;    break;
    155       case GL_INCR_WRAP: d3dStencilOp = D3D11_STENCIL_OP_INCR;      break;
    156       case GL_DECR_WRAP: d3dStencilOp = D3D11_STENCIL_OP_DECR;      break;
    157       default: UNREACHABLE();
    158     }
    159 
    160     return d3dStencilOp;
    161 }
    162 
    163 D3D11_FILTER ConvertFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy, GLenum comparisonMode)
    164 {
    165     bool comparison = comparisonMode != GL_NONE;
    166 
    167     if (maxAnisotropy > 1.0f)
    168     {
    169         return D3D11_ENCODE_ANISOTROPIC_FILTER(static_cast<D3D11_COMPARISON_FUNC>(comparison));
    170     }
    171     else
    172     {
    173         D3D11_FILTER_TYPE dxMin = D3D11_FILTER_TYPE_POINT;
    174         D3D11_FILTER_TYPE dxMip = D3D11_FILTER_TYPE_POINT;
    175         switch (minFilter)
    176         {
    177           case GL_NEAREST:                dxMin = D3D11_FILTER_TYPE_POINT;  dxMip = D3D11_FILTER_TYPE_POINT;  break;
    178           case GL_LINEAR:                 dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_POINT;  break;
    179           case GL_NEAREST_MIPMAP_NEAREST: dxMin = D3D11_FILTER_TYPE_POINT;  dxMip = D3D11_FILTER_TYPE_POINT;  break;
    180           case GL_LINEAR_MIPMAP_NEAREST:  dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_POINT;  break;
    181           case GL_NEAREST_MIPMAP_LINEAR:  dxMin = D3D11_FILTER_TYPE_POINT;  dxMip = D3D11_FILTER_TYPE_LINEAR; break;
    182           case GL_LINEAR_MIPMAP_LINEAR:   dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_LINEAR; break;
    183           default:                        UNREACHABLE();
    184         }
    185 
    186         D3D11_FILTER_TYPE dxMag = D3D11_FILTER_TYPE_POINT;
    187         switch (magFilter)
    188         {
    189           case GL_NEAREST: dxMag = D3D11_FILTER_TYPE_POINT;  break;
    190           case GL_LINEAR:  dxMag = D3D11_FILTER_TYPE_LINEAR; break;
    191           default:         UNREACHABLE();
    192         }
    193 
    194         return D3D11_ENCODE_BASIC_FILTER(dxMin, dxMag, dxMip, static_cast<D3D11_COMPARISON_FUNC>(comparison));
    195     }
    196 }
    197 
    198 D3D11_TEXTURE_ADDRESS_MODE ConvertTextureWrap(GLenum wrap)
    199 {
    200     switch (wrap)
    201     {
    202       case GL_REPEAT:          return D3D11_TEXTURE_ADDRESS_WRAP;
    203       case GL_CLAMP_TO_EDGE:   return D3D11_TEXTURE_ADDRESS_CLAMP;
    204       case GL_MIRRORED_REPEAT: return D3D11_TEXTURE_ADDRESS_MIRROR;
    205       default:                 UNREACHABLE();
    206     }
    207 
    208     return D3D11_TEXTURE_ADDRESS_WRAP;
    209 }
    210 
    211 D3D11_QUERY ConvertQueryType(GLenum queryType)
    212 {
    213     switch (queryType)
    214     {
    215       case GL_ANY_SAMPLES_PASSED_EXT:
    216       case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:   return D3D11_QUERY_OCCLUSION;
    217       case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: return D3D11_QUERY_SO_STATISTICS;
    218       default: UNREACHABLE();                        return D3D11_QUERY_EVENT;
    219     }
    220 }
    221 
    222 }
    223 
    224 
    225 namespace d3d11_gl
    226 {
    227 
    228 static gl::TextureCaps GenerateTextureFormatCaps(GLenum internalFormat, ID3D11Device *device)
    229 {
    230     gl::TextureCaps textureCaps;
    231 
    232     const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat);
    233 
    234     UINT formatSupport;
    235     if (SUCCEEDED(device->CheckFormatSupport(formatInfo.texFormat, &formatSupport)))
    236     {
    237         const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat);
    238         if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
    239         {
    240             textureCaps.texturable = ((formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0);
    241         }
    242         else
    243         {
    244             textureCaps.texturable = ((formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0) &&
    245                                      ((formatSupport & D3D11_FORMAT_SUPPORT_TEXTURECUBE) != 0) &&
    246                                      ((formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE3D) != 0);
    247         }
    248     }
    249 
    250     if (SUCCEEDED(device->CheckFormatSupport(formatInfo.renderFormat, &formatSupport)) &&
    251         ((formatSupport & D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET) != 0))
    252     {
    253         for (size_t sampleCount = 1; sampleCount <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; sampleCount++)
    254         {
    255             UINT qualityCount = 0;
    256             if (SUCCEEDED(device->CheckMultisampleQualityLevels(formatInfo.renderFormat, sampleCount, &qualityCount)) &&
    257                 qualityCount > 0)
    258             {
    259                 textureCaps.sampleCounts.insert(sampleCount);
    260             }
    261         }
    262     }
    263 
    264     textureCaps.filterable = SUCCEEDED(device->CheckFormatSupport(formatInfo.srvFormat, &formatSupport)) &&
    265                              ((formatSupport & D3D11_FORMAT_SUPPORT_SHADER_SAMPLE)) != 0;
    266     textureCaps.renderable = (SUCCEEDED(device->CheckFormatSupport(formatInfo.rtvFormat, &formatSupport)) &&
    267                               ((formatSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET)) != 0) ||
    268                              (SUCCEEDED(device->CheckFormatSupport(formatInfo.dsvFormat, &formatSupport)) &&
    269                               ((formatSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL) != 0));
    270 
    271     return textureCaps;
    272 }
    273 
    274 static bool GetNPOTTextureSupport(D3D_FEATURE_LEVEL featureLevel)
    275 {
    276     switch (featureLevel)
    277     {
    278       case D3D_FEATURE_LEVEL_11_1:
    279       case D3D_FEATURE_LEVEL_11_0:
    280       case D3D_FEATURE_LEVEL_10_1:
    281       case D3D_FEATURE_LEVEL_10_0: return true;
    282 
    283         // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx
    284       case D3D_FEATURE_LEVEL_9_3:
    285       case D3D_FEATURE_LEVEL_9_2:
    286       case D3D_FEATURE_LEVEL_9_1:  return false;
    287 
    288       default: UNREACHABLE();      return false;
    289     }
    290 }
    291 
    292 static float GetMaximumAnisotropy(D3D_FEATURE_LEVEL featureLevel)
    293 {
    294     switch (featureLevel)
    295     {
    296       case D3D_FEATURE_LEVEL_11_1:
    297       case D3D_FEATURE_LEVEL_11_0: return D3D11_MAX_MAXANISOTROPY;
    298 
    299       case D3D_FEATURE_LEVEL_10_1:
    300       case D3D_FEATURE_LEVEL_10_0: return D3D10_MAX_MAXANISOTROPY;
    301 
    302         // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx
    303       case D3D_FEATURE_LEVEL_9_3:
    304       case D3D_FEATURE_LEVEL_9_2:  return 16;
    305 
    306       case D3D_FEATURE_LEVEL_9_1:  return D3D_FL9_1_DEFAULT_MAX_ANISOTROPY;
    307 
    308       default: UNREACHABLE();      return 0;
    309     }
    310 }
    311 
    312 static bool GetOcclusionQuerySupport(D3D_FEATURE_LEVEL featureLevel)
    313 {
    314     switch (featureLevel)
    315     {
    316       case D3D_FEATURE_LEVEL_11_1:
    317       case D3D_FEATURE_LEVEL_11_0:
    318       case D3D_FEATURE_LEVEL_10_1:
    319       case D3D_FEATURE_LEVEL_10_0: return true;
    320 
    321         // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx ID3D11Device::CreateQuery
    322       case D3D_FEATURE_LEVEL_9_3:
    323       case D3D_FEATURE_LEVEL_9_2:  return true;
    324       case D3D_FEATURE_LEVEL_9_1:  return false;
    325 
    326       default: UNREACHABLE();      return false;
    327     }
    328 }
    329 
    330 static bool GetEventQuerySupport(D3D_FEATURE_LEVEL featureLevel)
    331 {
    332     // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx ID3D11Device::CreateQuery
    333 
    334     switch (featureLevel)
    335     {
    336       case D3D_FEATURE_LEVEL_11_1:
    337       case D3D_FEATURE_LEVEL_11_0:
    338       case D3D_FEATURE_LEVEL_10_1:
    339       case D3D_FEATURE_LEVEL_10_0:
    340       case D3D_FEATURE_LEVEL_9_3:
    341       case D3D_FEATURE_LEVEL_9_2:
    342       case D3D_FEATURE_LEVEL_9_1:  return true;
    343 
    344       default: UNREACHABLE();      return false;
    345     }
    346 }
    347 
    348 static bool GetInstancingSupport(D3D_FEATURE_LEVEL featureLevel)
    349 {
    350     // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx ID3D11Device::CreateInputLayout
    351 
    352     switch (featureLevel)
    353     {
    354       case D3D_FEATURE_LEVEL_11_1:
    355       case D3D_FEATURE_LEVEL_11_0:
    356       case D3D_FEATURE_LEVEL_10_1:
    357       case D3D_FEATURE_LEVEL_10_0:
    358       case D3D_FEATURE_LEVEL_9_3:  return true;
    359 
    360       case D3D_FEATURE_LEVEL_9_2:
    361       case D3D_FEATURE_LEVEL_9_1:  return false;
    362 
    363       default: UNREACHABLE();      return false;
    364     }
    365 }
    366 
    367 static bool GetDerivativeInstructionSupport(D3D_FEATURE_LEVEL featureLevel)
    368 {
    369     // http://msdn.microsoft.com/en-us/library/windows/desktop/bb509588.aspx states that shader model
    370     // ps_2_x is required for the ddx (and other derivative functions).
    371 
    372     // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx states that feature level
    373     // 9.3 supports shader model ps_2_x.
    374 
    375     switch (featureLevel)
    376     {
    377       case D3D_FEATURE_LEVEL_11_1:
    378       case D3D_FEATURE_LEVEL_11_0:
    379       case D3D_FEATURE_LEVEL_10_1:
    380       case D3D_FEATURE_LEVEL_10_0:
    381       case D3D_FEATURE_LEVEL_9_3:  return true;
    382       case D3D_FEATURE_LEVEL_9_2:
    383       case D3D_FEATURE_LEVEL_9_1:  return false;
    384 
    385       default: UNREACHABLE();      return false;
    386     }
    387 }
    388 
    389 static size_t GetMaximumSimultaneousRenderTargets(D3D_FEATURE_LEVEL featureLevel)
    390 {
    391     // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx ID3D11Device::CreateInputLayout
    392 
    393     switch (featureLevel)
    394     {
    395       case D3D_FEATURE_LEVEL_11_1:
    396       case D3D_FEATURE_LEVEL_11_0: return D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT;
    397 
    398       case D3D_FEATURE_LEVEL_10_1:
    399       case D3D_FEATURE_LEVEL_10_0: return D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT;
    400 
    401       case D3D_FEATURE_LEVEL_9_3:  return D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT;
    402       case D3D_FEATURE_LEVEL_9_2:
    403       case D3D_FEATURE_LEVEL_9_1:  return D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT;
    404 
    405       default: UNREACHABLE();      return 0;
    406     }
    407 }
    408 
    409 static size_t GetMaximum2DTextureSize(D3D_FEATURE_LEVEL featureLevel)
    410 {
    411     switch (featureLevel)
    412     {
    413       case D3D_FEATURE_LEVEL_11_1:
    414       case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
    415 
    416       case D3D_FEATURE_LEVEL_10_1:
    417       case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION;
    418 
    419       case D3D_FEATURE_LEVEL_9_3:  return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION;
    420       case D3D_FEATURE_LEVEL_9_2:
    421       case D3D_FEATURE_LEVEL_9_1:  return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION;
    422 
    423       default: UNREACHABLE();      return 0;
    424     }
    425 }
    426 
    427 static size_t GetMaximumCubeMapTextureSize(D3D_FEATURE_LEVEL featureLevel)
    428 {
    429     switch (featureLevel)
    430     {
    431       case D3D_FEATURE_LEVEL_11_1:
    432       case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURECUBE_DIMENSION;
    433 
    434       case D3D_FEATURE_LEVEL_10_1:
    435       case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURECUBE_DIMENSION;
    436 
    437       case D3D_FEATURE_LEVEL_9_3:  return D3D_FL9_3_REQ_TEXTURECUBE_DIMENSION;
    438       case D3D_FEATURE_LEVEL_9_2:
    439       case D3D_FEATURE_LEVEL_9_1:  return D3D_FL9_1_REQ_TEXTURECUBE_DIMENSION;
    440 
    441       default: UNREACHABLE();      return 0;
    442     }
    443 }
    444 
    445 static size_t GetMaximum2DTextureArraySize(D3D_FEATURE_LEVEL featureLevel)
    446 {
    447     switch (featureLevel)
    448     {
    449       case D3D_FEATURE_LEVEL_11_1:
    450       case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION;
    451 
    452       case D3D_FEATURE_LEVEL_10_1:
    453       case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION;
    454 
    455       case D3D_FEATURE_LEVEL_9_3:
    456       case D3D_FEATURE_LEVEL_9_2:
    457       case D3D_FEATURE_LEVEL_9_1:  return 0;
    458 
    459       default: UNREACHABLE();      return 0;
    460     }
    461 }
    462 
    463 static size_t GetMaximum3DTextureSize(D3D_FEATURE_LEVEL featureLevel)
    464 {
    465     switch (featureLevel)
    466     {
    467       case D3D_FEATURE_LEVEL_11_1:
    468       case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION;
    469 
    470       case D3D_FEATURE_LEVEL_10_1:
    471       case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE3D_U_V_OR_W_DIMENSION;
    472 
    473       case D3D_FEATURE_LEVEL_9_3:
    474       case D3D_FEATURE_LEVEL_9_2:
    475       case D3D_FEATURE_LEVEL_9_1:  return D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION;
    476 
    477       default: UNREACHABLE();      return 0;
    478     }
    479 }
    480 
    481 static size_t GetMaximumViewportSize(D3D_FEATURE_LEVEL featureLevel)
    482 {
    483     switch (featureLevel)
    484     {
    485       case D3D_FEATURE_LEVEL_11_1:
    486       case D3D_FEATURE_LEVEL_11_0: return D3D11_VIEWPORT_BOUNDS_MAX;
    487 
    488       case D3D_FEATURE_LEVEL_10_1:
    489       case D3D_FEATURE_LEVEL_10_0: return D3D10_VIEWPORT_BOUNDS_MAX;
    490 
    491         // No constants for D3D9 viewport size limits, use the maximum texture sizes
    492       case D3D_FEATURE_LEVEL_9_3:  return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION;
    493       case D3D_FEATURE_LEVEL_9_2:
    494       case D3D_FEATURE_LEVEL_9_1:  return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION;
    495 
    496       default: UNREACHABLE();      return 0;
    497     }
    498 }
    499 
    500 static size_t GetMaximumDrawIndexedIndexCount(D3D_FEATURE_LEVEL featureLevel)
    501 {
    502     // D3D11 allows up to 2^32 elements, but we report max signed int for convenience since that's what's
    503     // returned from glGetInteger
    504     META_ASSERT(D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32);
    505     META_ASSERT(D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32);
    506 
    507     switch (featureLevel)
    508     {
    509       case D3D_FEATURE_LEVEL_11_1:
    510       case D3D_FEATURE_LEVEL_11_0:
    511       case D3D_FEATURE_LEVEL_10_1:
    512       case D3D_FEATURE_LEVEL_10_0: return std::numeric_limits<GLint>::max();
    513 
    514       case D3D_FEATURE_LEVEL_9_3:
    515       case D3D_FEATURE_LEVEL_9_2:  return D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT;
    516       case D3D_FEATURE_LEVEL_9_1:  return D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT;
    517 
    518       default: UNREACHABLE();      return 0;
    519     }
    520 }
    521 
    522 static size_t GetMaximumDrawVertexCount(D3D_FEATURE_LEVEL featureLevel)
    523 {
    524     // D3D11 allows up to 2^32 elements, but we report max signed int for convenience since that's what's
    525     // returned from glGetInteger
    526     META_ASSERT(D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32);
    527     META_ASSERT(D3D10_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32);
    528 
    529     switch (featureLevel)
    530     {
    531       case D3D_FEATURE_LEVEL_11_1:
    532       case D3D_FEATURE_LEVEL_11_0:
    533       case D3D_FEATURE_LEVEL_10_1:
    534       case D3D_FEATURE_LEVEL_10_0: return std::numeric_limits<GLint>::max();
    535 
    536       case D3D_FEATURE_LEVEL_9_3:
    537       case D3D_FEATURE_LEVEL_9_2:  return D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT;
    538       case D3D_FEATURE_LEVEL_9_1:  return D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT;
    539 
    540       default: UNREACHABLE();      return 0;
    541     }
    542 }
    543 
    544 static size_t GetMaximumVertexInputSlots(D3D_FEATURE_LEVEL featureLevel)
    545 {
    546     switch (featureLevel)
    547     {
    548       case D3D_FEATURE_LEVEL_11_1:
    549       case D3D_FEATURE_LEVEL_11_0: return D3D11_STANDARD_VERTEX_ELEMENT_COUNT;
    550 
    551       case D3D_FEATURE_LEVEL_10_1: return D3D10_1_STANDARD_VERTEX_ELEMENT_COUNT;
    552       case D3D_FEATURE_LEVEL_10_0: return D3D10_STANDARD_VERTEX_ELEMENT_COUNT;
    553 
    554       // From http://http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx "Max Input Slots"
    555       case D3D_FEATURE_LEVEL_9_3:
    556       case D3D_FEATURE_LEVEL_9_2:
    557       case D3D_FEATURE_LEVEL_9_1:  return 16;
    558 
    559       default: UNREACHABLE();      return 0;
    560     }
    561 }
    562 
    563 static size_t GetMaximumVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel)
    564 {
    565     // TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass
    566     switch (featureLevel)
    567     {
    568       case D3D_FEATURE_LEVEL_11_1:
    569       case D3D_FEATURE_LEVEL_11_0: return 1024; // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT;
    570 
    571       case D3D_FEATURE_LEVEL_10_1:
    572       case D3D_FEATURE_LEVEL_10_0: return 1024; // D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT;
    573 
    574       // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx ID3D11DeviceContext::VSSetConstantBuffers
    575       case D3D_FEATURE_LEVEL_9_3:
    576       case D3D_FEATURE_LEVEL_9_2:
    577       case D3D_FEATURE_LEVEL_9_1:  return 255;
    578 
    579       default: UNREACHABLE();      return 0;
    580     }
    581 }
    582 
    583 static size_t GetReservedVertexUniformBuffers()
    584 {
    585     // Reserve one buffer for the application uniforms, and one for driver uniforms
    586     return 2;
    587 }
    588 
    589 static size_t GetMaximumVertexUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
    590 {
    591     switch (featureLevel)
    592     {
    593       case D3D_FEATURE_LEVEL_11_1:
    594       case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedVertexUniformBuffers();
    595 
    596       case D3D_FEATURE_LEVEL_10_1:
    597       case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedVertexUniformBuffers();
    598 
    599       // Uniform blocks not supported in D3D9 feature levels
    600       case D3D_FEATURE_LEVEL_9_3:
    601       case D3D_FEATURE_LEVEL_9_2:
    602       case D3D_FEATURE_LEVEL_9_1:  return 0;
    603 
    604       default: UNREACHABLE();      return 0;
    605     }
    606 }
    607 
    608 static size_t GetReservedVertexOutputVectors()
    609 {
    610     // We potentially reserve varyings for gl_Position, dx_Position, gl_FragCoord and gl_PointSize
    611     return 4;
    612 }
    613 
    614 static size_t GetMaximumVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel)
    615 {
    616     META_ASSERT(gl::IMPLEMENTATION_MAX_VARYING_VECTORS == D3D11_VS_OUTPUT_REGISTER_COUNT);
    617 
    618     switch (featureLevel)
    619     {
    620       case D3D_FEATURE_LEVEL_11_1:
    621       case D3D_FEATURE_LEVEL_11_0: return D3D11_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors();
    622 
    623       case D3D_FEATURE_LEVEL_10_1: return D3D10_1_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors();
    624       case D3D_FEATURE_LEVEL_10_0: return D3D10_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors();
    625 
    626       // Use D3D9 SM3 and SM2 limits
    627       case D3D_FEATURE_LEVEL_9_3:  return 10 - GetReservedVertexOutputVectors();
    628       case D3D_FEATURE_LEVEL_9_2:
    629       case D3D_FEATURE_LEVEL_9_1:  return 8 - GetReservedVertexOutputVectors();
    630 
    631       default: UNREACHABLE();      return 0;
    632     }
    633 }
    634 
    635 static size_t GetMaximumVertexTextureUnits(D3D_FEATURE_LEVEL featureLevel)
    636 {
    637     switch (featureLevel)
    638     {
    639       case D3D_FEATURE_LEVEL_11_1:
    640       case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT;
    641 
    642       case D3D_FEATURE_LEVEL_10_1:
    643       case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT;
    644 
    645       // Vertex textures not supported in D3D9 feature levels according to
    646       // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx
    647       // ID3D11DeviceContext::VSSetSamplers and ID3D11DeviceContext::VSSetShaderResources
    648       case D3D_FEATURE_LEVEL_9_3:
    649       case D3D_FEATURE_LEVEL_9_2:
    650       case D3D_FEATURE_LEVEL_9_1:  return 0;
    651 
    652       default: UNREACHABLE();      return 0;
    653     }
    654 }
    655 
    656 static size_t GetMaximumPixelUniformVectors(D3D_FEATURE_LEVEL featureLevel)
    657 {
    658     // TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass
    659     switch (featureLevel)
    660     {
    661       case D3D_FEATURE_LEVEL_11_1:
    662       case D3D_FEATURE_LEVEL_11_0: return 1024; // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT;
    663 
    664       case D3D_FEATURE_LEVEL_10_1:
    665       case D3D_FEATURE_LEVEL_10_0: return 1024; // D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT;
    666 
    667       // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx ID3D11DeviceContext::PSSetConstantBuffers
    668       case D3D_FEATURE_LEVEL_9_3:
    669       case D3D_FEATURE_LEVEL_9_2:
    670       case D3D_FEATURE_LEVEL_9_1:  return 32;
    671 
    672       default: UNREACHABLE();      return 0;
    673     }
    674 }
    675 
    676 static size_t GetReservedPixelUniformBuffers()
    677 {
    678     // Reserve one buffer for the application uniforms, and one for driver uniforms
    679     return 2;
    680 }
    681 
    682 static size_t GetMaximumPixelUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
    683 {
    684     switch (featureLevel)
    685     {
    686       case D3D_FEATURE_LEVEL_11_1:
    687       case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedPixelUniformBuffers();
    688 
    689       case D3D_FEATURE_LEVEL_10_1:
    690       case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedPixelUniformBuffers();
    691 
    692       // Uniform blocks not supported in D3D9 feature levels
    693       case D3D_FEATURE_LEVEL_9_3:
    694       case D3D_FEATURE_LEVEL_9_2:
    695       case D3D_FEATURE_LEVEL_9_1:  return 0;
    696 
    697       default: UNREACHABLE();      return 0;
    698     }
    699 }
    700 
    701 static size_t GetMaximumPixelInputVectors(D3D_FEATURE_LEVEL featureLevel)
    702 {
    703     switch (featureLevel)
    704     {
    705       case D3D_FEATURE_LEVEL_11_1:
    706       case D3D_FEATURE_LEVEL_11_0: return D3D11_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors();
    707 
    708       case D3D_FEATURE_LEVEL_10_1:
    709       case D3D_FEATURE_LEVEL_10_0: return D3D10_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors();
    710 
    711       // Use D3D9 SM3 and SM2 limits
    712       case D3D_FEATURE_LEVEL_9_3:  return 10 - GetReservedVertexOutputVectors();
    713       case D3D_FEATURE_LEVEL_9_2:
    714       case D3D_FEATURE_LEVEL_9_1:  return 8 - GetReservedVertexOutputVectors();
    715 
    716       default: UNREACHABLE();      return 0;
    717     }
    718 }
    719 
    720 static size_t GetMaximumPixelTextureUnits(D3D_FEATURE_LEVEL featureLevel)
    721 {
    722     switch (featureLevel)
    723     {
    724       case D3D_FEATURE_LEVEL_11_1:
    725       case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT;
    726 
    727       case D3D_FEATURE_LEVEL_10_1:
    728       case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT;
    729 
    730       // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx ID3D11DeviceContext::PSSetShaderResources
    731       case D3D_FEATURE_LEVEL_9_3:
    732       case D3D_FEATURE_LEVEL_9_2:
    733       case D3D_FEATURE_LEVEL_9_1:  return 16;
    734 
    735       default: UNREACHABLE();      return 0;
    736     }
    737 }
    738 
    739 static int GetMinimumTexelOffset(D3D_FEATURE_LEVEL featureLevel)
    740 {
    741     switch (featureLevel)
    742     {
    743       case D3D_FEATURE_LEVEL_11_1:
    744       case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE;
    745 
    746       case D3D_FEATURE_LEVEL_10_1:
    747       case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE;
    748 
    749       // Sampling functions with offsets are not available below shader model 4.0.
    750       case D3D_FEATURE_LEVEL_9_3:
    751       case D3D_FEATURE_LEVEL_9_2:
    752       case D3D_FEATURE_LEVEL_9_1:  return 0;
    753 
    754       default: UNREACHABLE();      return 0;
    755     }
    756 }
    757 
    758 static int GetMaximumTexelOffset(D3D_FEATURE_LEVEL featureLevel)
    759 {
    760     switch (featureLevel)
    761     {
    762       case D3D_FEATURE_LEVEL_11_1:
    763       case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE;
    764       case D3D_FEATURE_LEVEL_10_1:
    765       case D3D_FEATURE_LEVEL_10_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE;
    766 
    767       // Sampling functions with offsets are not available below shader model 4.0.
    768       case D3D_FEATURE_LEVEL_9_3:
    769       case D3D_FEATURE_LEVEL_9_2:
    770       case D3D_FEATURE_LEVEL_9_1:  return 0;
    771 
    772       default: UNREACHABLE();      return 0;
    773     }
    774 }
    775 
    776 static size_t GetMaximumConstantBufferSize(D3D_FEATURE_LEVEL featureLevel)
    777 {
    778     // Returns a size_t despite the limit being a GLuint64 because size_t is the maximum size of
    779     // any buffer that could be allocated.
    780 
    781     const size_t bytesPerComponent = 4 * sizeof(float);
    782 
    783     switch (featureLevel)
    784     {
    785       case D3D_FEATURE_LEVEL_11_1:
    786       case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent;
    787 
    788       case D3D_FEATURE_LEVEL_10_1:
    789       case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent;
    790 
    791       // Limits from http://msdn.microsoft.com/en-us/library/windows/desktop/ff476501.aspx remarks section
    792       case D3D_FEATURE_LEVEL_9_3:
    793       case D3D_FEATURE_LEVEL_9_2:
    794       case D3D_FEATURE_LEVEL_9_1:  return 4096 * bytesPerComponent;
    795 
    796       default: UNREACHABLE();      return 0;
    797     }
    798 }
    799 
    800 static size_t GetMaximumStreamOutputBuffers(D3D_FEATURE_LEVEL featureLevel)
    801 {
    802     switch (featureLevel)
    803     {
    804       case D3D_FEATURE_LEVEL_11_1:
    805       case D3D_FEATURE_LEVEL_11_0: return D3D11_SO_BUFFER_SLOT_COUNT;
    806 
    807       case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SO_BUFFER_SLOT_COUNT;
    808       case D3D_FEATURE_LEVEL_10_0: return D3D10_SO_BUFFER_SLOT_COUNT;
    809 
    810       case D3D_FEATURE_LEVEL_9_3:
    811       case D3D_FEATURE_LEVEL_9_2:
    812       case D3D_FEATURE_LEVEL_9_1:  return 0;
    813 
    814       default: UNREACHABLE();      return 0;
    815     }
    816 }
    817 
    818 static size_t GetMaximumStreamOutputInterleavedComponenets(D3D_FEATURE_LEVEL featureLevel)
    819 {
    820     switch (featureLevel)
    821     {
    822       case D3D_FEATURE_LEVEL_11_1:
    823       case D3D_FEATURE_LEVEL_11_0:
    824 
    825       case D3D_FEATURE_LEVEL_10_1:
    826       case D3D_FEATURE_LEVEL_10_0: return GetMaximumVertexOutputVectors(featureLevel) * 4;
    827 
    828       case D3D_FEATURE_LEVEL_9_3:
    829       case D3D_FEATURE_LEVEL_9_2:
    830       case D3D_FEATURE_LEVEL_9_1:  return 0;
    831 
    832       default: UNREACHABLE();      return 0;
    833     }
    834 }
    835 
    836 static size_t GetMaximumStreamOutputSeparateCompeonents(D3D_FEATURE_LEVEL featureLevel)
    837 {
    838     switch (featureLevel)
    839     {
    840       case D3D_FEATURE_LEVEL_11_1:
    841       case D3D_FEATURE_LEVEL_11_0: return GetMaximumStreamOutputInterleavedComponenets(featureLevel) /
    842                                           GetMaximumStreamOutputBuffers(featureLevel);
    843 
    844 
    845       // D3D 10 and 10.1 only allow one output per output slot if an output slot other than zero is used.
    846       case D3D_FEATURE_LEVEL_10_1:
    847       case D3D_FEATURE_LEVEL_10_0: return 4;
    848 
    849       case D3D_FEATURE_LEVEL_9_3:
    850       case D3D_FEATURE_LEVEL_9_2:
    851       case D3D_FEATURE_LEVEL_9_1:  return 0;
    852 
    853       default: UNREACHABLE();      return 0;
    854     }
    855 }
    856 
    857 void GenerateCaps(ID3D11Device *device, gl::Caps *caps, gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions)
    858 {
    859     GLuint maxSamples = 0;
    860     const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats();
    861     for (gl::FormatSet::const_iterator internalFormat = allFormats.begin(); internalFormat != allFormats.end(); ++internalFormat)
    862     {
    863         gl::TextureCaps textureCaps = GenerateTextureFormatCaps(*internalFormat, device);
    864         textureCapsMap->insert(*internalFormat, textureCaps);
    865 
    866         maxSamples = std::max(maxSamples, textureCaps.getMaxSamples());
    867 
    868         if (gl::GetInternalFormatInfo(*internalFormat).compressed)
    869         {
    870             caps->compressedTextureFormats.push_back(*internalFormat);
    871         }
    872     }
    873 
    874     D3D_FEATURE_LEVEL featureLevel = device->GetFeatureLevel();
    875 
    876     // GL core feature limits
    877     caps->maxElementIndex = static_cast<GLint64>(std::numeric_limits<unsigned int>::max());
    878     caps->max3DTextureSize = GetMaximum3DTextureSize(featureLevel);
    879     caps->max2DTextureSize = GetMaximum2DTextureSize(featureLevel);
    880     caps->maxCubeMapTextureSize = GetMaximumCubeMapTextureSize(featureLevel);
    881     caps->maxArrayTextureLayers = GetMaximum2DTextureArraySize(featureLevel);
    882 
    883     // Unimplemented, set to minimum required
    884     caps->maxLODBias = 2.0f;
    885 
    886     // No specific limits on render target size, maximum 2D texture size is equivalent
    887     caps->maxRenderbufferSize = caps->max2DTextureSize;
    888 
    889     // Maximum draw buffers and color attachments are the same, max color attachments could eventually be
    890     // increased to 16
    891     caps->maxDrawBuffers = GetMaximumSimultaneousRenderTargets(featureLevel);
    892     caps->maxColorAttachments = GetMaximumSimultaneousRenderTargets(featureLevel);
    893 
    894     // D3D11 has the same limit for viewport width and height
    895     caps->maxViewportWidth = GetMaximumViewportSize(featureLevel);
    896     caps->maxViewportHeight = caps->maxViewportWidth;
    897 
    898     // Choose a reasonable maximum, enforced in the shader.
    899     caps->minAliasedPointSize = 1.0f;
    900     caps->maxAliasedPointSize = 1024.0f;
    901 
    902     // Wide lines not supported
    903     caps->minAliasedLineWidth = 1.0f;
    904     caps->maxAliasedLineWidth = 1.0f;
    905 
    906     // Primitive count limits
    907     caps->maxElementsIndices = GetMaximumDrawIndexedIndexCount(featureLevel);
    908     caps->maxElementsVertices = GetMaximumDrawVertexCount(featureLevel);
    909 
    910     // Program and shader binary formats (no supported shader binary formats)
    911     caps->programBinaryFormats.push_back(GL_PROGRAM_BINARY_ANGLE);
    912 
    913     // We do not wait for server fence objects internally, so report a max timeout of zero.
    914     caps->maxServerWaitTimeout = 0;
    915 
    916     // Vertex shader limits
    917     caps->maxVertexAttributes = GetMaximumVertexInputSlots(featureLevel);
    918     caps->maxVertexUniformComponents = GetMaximumVertexUniformVectors(featureLevel) * 4;
    919     caps->maxVertexUniformVectors = GetMaximumVertexUniformVectors(featureLevel);
    920     caps->maxVertexUniformBlocks = GetMaximumVertexUniformBlocks(featureLevel);
    921     caps->maxVertexOutputComponents = GetMaximumVertexOutputVectors(featureLevel) * 4;
    922     caps->maxVertexTextureImageUnits = GetMaximumVertexTextureUnits(featureLevel);
    923 
    924     // Fragment shader limits
    925     caps->maxFragmentUniformComponents = GetMaximumPixelUniformVectors(featureLevel) * 4;
    926     caps->maxFragmentUniformVectors = GetMaximumPixelUniformVectors(featureLevel);
    927     caps->maxFragmentUniformBlocks = GetMaximumPixelUniformBlocks(featureLevel);
    928     caps->maxFragmentInputComponents = GetMaximumPixelInputVectors(featureLevel) * 4;
    929     caps->maxTextureImageUnits = GetMaximumPixelTextureUnits(featureLevel);
    930     caps->minProgramTexelOffset = GetMinimumTexelOffset(featureLevel);
    931     caps->maxProgramTexelOffset = GetMaximumTexelOffset(featureLevel);
    932 
    933     // Aggregate shader limits
    934     caps->maxUniformBufferBindings = caps->maxVertexUniformBlocks + caps->maxFragmentUniformBlocks;
    935     caps->maxUniformBlockSize = GetMaximumConstantBufferSize(featureLevel);
    936 
    937     // Setting a large alignment forces uniform buffers to bind with zero offset
    938     caps->uniformBufferOffsetAlignment = static_cast<GLuint>(std::numeric_limits<GLint>::max());
    939 
    940     caps->maxCombinedUniformBlocks = caps->maxVertexUniformBlocks + caps->maxFragmentUniformBlocks;
    941     caps->maxCombinedVertexUniformComponents = (static_cast<GLint64>(caps->maxVertexUniformBlocks) * static_cast<GLint64>(caps->maxUniformBlockSize / 4)) +
    942                                                static_cast<GLint64>(caps->maxVertexUniformComponents);
    943     caps->maxCombinedFragmentUniformComponents = (static_cast<GLint64>(caps->maxFragmentUniformBlocks) * static_cast<GLint64>(caps->maxUniformBlockSize / 4)) +
    944                                                  static_cast<GLint64>(caps->maxFragmentUniformComponents);
    945     caps->maxVaryingComponents = GetMaximumVertexOutputVectors(featureLevel) * 4;
    946     caps->maxVaryingVectors = GetMaximumVertexOutputVectors(featureLevel);
    947     caps->maxCombinedTextureImageUnits = caps->maxVertexTextureImageUnits + caps->maxTextureImageUnits;
    948 
    949     // Transform feedback limits
    950     caps->maxTransformFeedbackInterleavedComponents = GetMaximumStreamOutputInterleavedComponenets(featureLevel);
    951     caps->maxTransformFeedbackSeparateAttributes = GetMaximumStreamOutputBuffers(featureLevel);
    952     caps->maxTransformFeedbackSeparateComponents = GetMaximumStreamOutputSeparateCompeonents(featureLevel);
    953 
    954     // GL extension support
    955     extensions->setTextureExtensionSupport(*textureCapsMap);
    956     extensions->elementIndexUint = true;
    957     extensions->packedDepthStencil = true;
    958     extensions->getProgramBinary = true;
    959     extensions->rgb8rgba8 = true;
    960     extensions->readFormatBGRA = true;
    961     extensions->pixelBufferObject = true;
    962     extensions->mapBuffer = true;
    963     extensions->mapBufferRange = true;
    964     extensions->textureNPOT = GetNPOTTextureSupport(featureLevel);
    965     extensions->drawBuffers = GetMaximumSimultaneousRenderTargets(featureLevel) > 1;
    966     extensions->textureStorage = true;
    967     extensions->textureFilterAnisotropic = true;
    968     extensions->maxTextureAnisotropy = GetMaximumAnisotropy(featureLevel);
    969     extensions->occlusionQueryBoolean = GetOcclusionQuerySupport(featureLevel);
    970     extensions->fence = GetEventQuerySupport(featureLevel);
    971     extensions->timerQuery = false; // Unimplemented
    972     extensions->robustness = true;
    973     extensions->blendMinMax = true;
    974     extensions->framebufferBlit = true;
    975     extensions->framebufferMultisample = true;
    976     extensions->maxSamples = maxSamples;
    977     extensions->instancedArrays = GetInstancingSupport(featureLevel);
    978     extensions->packReverseRowOrder = true;
    979     extensions->standardDerivatives = GetDerivativeInstructionSupport(featureLevel);
    980     extensions->shaderTextureLOD = true;
    981     extensions->fragDepth = true;
    982     extensions->textureUsage = true; // This could be false since it has no effect in D3D11
    983     extensions->translatedShaderSource = true;
    984 }
    985 
    986 }
    987 
    988 namespace d3d11
    989 {
    990 
    991 void MakeValidSize(bool isImage, DXGI_FORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset)
    992 {
    993     const DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(format);
    994 
    995     int upsampleCount = 0;
    996     // Don't expand the size of full textures that are at least (blockWidth x blockHeight) already.
    997     if (isImage || *requestWidth  < static_cast<GLsizei>(dxgiFormatInfo.blockWidth) ||
    998                    *requestHeight < static_cast<GLsizei>(dxgiFormatInfo.blockHeight))
    999     {
   1000         while (*requestWidth % dxgiFormatInfo.blockWidth != 0 || *requestHeight % dxgiFormatInfo.blockHeight != 0)
   1001         {
   1002             *requestWidth <<= 1;
   1003             *requestHeight <<= 1;
   1004             upsampleCount++;
   1005         }
   1006     }
   1007     *levelOffset = upsampleCount;
   1008 }
   1009 
   1010 void GenerateInitialTextureData(GLint internalFormat, GLuint width, GLuint height, GLuint depth,
   1011                                 GLuint mipLevels, std::vector<D3D11_SUBRESOURCE_DATA> *outSubresourceData,
   1012                                 std::vector< std::vector<BYTE> > *outData)
   1013 {
   1014     const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(internalFormat);
   1015     ASSERT(d3dFormatInfo.dataInitializerFunction != NULL);
   1016 
   1017     const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(d3dFormatInfo.texFormat);
   1018 
   1019     outSubresourceData->resize(mipLevels);
   1020     outData->resize(mipLevels);
   1021 
   1022     for (unsigned int i = 0; i < mipLevels; i++)
   1023     {
   1024         unsigned int mipWidth = std::max(width >> i, 1U);
   1025         unsigned int mipHeight = std::max(height >> i, 1U);
   1026         unsigned int mipDepth = std::max(depth >> i, 1U);
   1027 
   1028         unsigned int rowWidth = dxgiFormatInfo.pixelBytes * mipWidth;
   1029         unsigned int imageSize = rowWidth * height;
   1030 
   1031         outData->at(i).resize(rowWidth * mipHeight * mipDepth);
   1032         d3dFormatInfo.dataInitializerFunction(mipWidth, mipHeight, mipDepth, outData->at(i).data(), rowWidth, imageSize);
   1033 
   1034         outSubresourceData->at(i).pSysMem = outData->at(i).data();
   1035         outSubresourceData->at(i).SysMemPitch = rowWidth;
   1036         outSubresourceData->at(i).SysMemSlicePitch = imageSize;
   1037     }
   1038 }
   1039 
   1040 void SetPositionTexCoordVertex(PositionTexCoordVertex* vertex, float x, float y, float u, float v)
   1041 {
   1042     vertex->x = x;
   1043     vertex->y = y;
   1044     vertex->u = u;
   1045     vertex->v = v;
   1046 }
   1047 
   1048 void SetPositionLayerTexCoord3DVertex(PositionLayerTexCoord3DVertex* vertex, float x, float y,
   1049                                       unsigned int layer, float u, float v, float s)
   1050 {
   1051     vertex->x = x;
   1052     vertex->y = y;
   1053     vertex->l = layer;
   1054     vertex->u = u;
   1055     vertex->v = v;
   1056     vertex->s = s;
   1057 }
   1058 
   1059 HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name)
   1060 {
   1061 #if defined(_DEBUG)
   1062     return resource->SetPrivateData(WKPDID_D3DDebugObjectName, strlen(name), name);
   1063 #else
   1064     return S_OK;
   1065 #endif
   1066 }
   1067 
   1068 RenderTarget11 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment)
   1069 {
   1070     RenderTarget *renderTarget = rx::GetAttachmentRenderTarget(attachment);
   1071     return RenderTarget11::makeRenderTarget11(renderTarget);
   1072 }
   1073 
   1074 }
   1075 
   1076 }
   1077