tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

renderer11_utils.cpp (97657B)


      1 //
      2 // Copyright 2012 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 "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
     11 
     12 #include <versionhelpers.h>
     13 #include <algorithm>
     14 
     15 #include "common/debug.h"
     16 #include "libANGLE/Buffer.h"
     17 #include "libANGLE/Context.h"
     18 #include "libANGLE/Framebuffer.h"
     19 #include "libANGLE/Program.h"
     20 #include "libANGLE/State.h"
     21 #include "libANGLE/VertexArray.h"
     22 #include "libANGLE/formatutils.h"
     23 #include "libANGLE/renderer/d3d/BufferD3D.h"
     24 #include "libANGLE/renderer/d3d/FramebufferD3D.h"
     25 #include "libANGLE/renderer/d3d/d3d11/Context11.h"
     26 #include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
     27 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
     28 #include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
     29 #include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
     30 #include "libANGLE/renderer/driver_utils.h"
     31 #include "libANGLE/renderer/dxgi_support_table.h"
     32 #include "platform/FeaturesD3D_autogen.h"
     33 #include "platform/PlatformMethods.h"
     34 
     35 namespace rx
     36 {
     37 
     38 namespace d3d11_gl
     39 {
     40 namespace
     41 {
     42 // TODO(xinghua.cao@intel.com): Get a more accurate limit.
     43 static D3D_FEATURE_LEVEL kMinimumFeatureLevelForES31 = D3D_FEATURE_LEVEL_11_0;
     44 
     45 // Helper functor for querying DXGI support. Saves passing the parameters repeatedly.
     46 class DXGISupportHelper : angle::NonCopyable
     47 {
     48  public:
     49    DXGISupportHelper(ID3D11Device *device, D3D_FEATURE_LEVEL featureLevel)
     50        : mDevice(device), mFeatureLevel(featureLevel)
     51    {}
     52 
     53    bool query(DXGI_FORMAT dxgiFormat, UINT supportMask)
     54    {
     55        if (dxgiFormat == DXGI_FORMAT_UNKNOWN)
     56            return false;
     57 
     58        auto dxgiSupport = d3d11::GetDXGISupport(dxgiFormat, mFeatureLevel);
     59 
     60        UINT supportedBits = dxgiSupport.alwaysSupportedFlags;
     61 
     62        if ((dxgiSupport.optionallySupportedFlags & supportMask) != 0)
     63        {
     64            UINT formatSupport;
     65            if (SUCCEEDED(mDevice->CheckFormatSupport(dxgiFormat, &formatSupport)))
     66            {
     67                supportedBits |= (formatSupport & supportMask);
     68            }
     69            else
     70            {
     71                // TODO(jmadill): find out why we fail this call sometimes in FL9_3
     72                // ERR() << "Error checking format support for format 0x" << std::hex << dxgiFormat;
     73            }
     74        }
     75 
     76        return ((supportedBits & supportMask) == supportMask);
     77    }
     78 
     79  private:
     80    ID3D11Device *mDevice;
     81    D3D_FEATURE_LEVEL mFeatureLevel;
     82 };
     83 
     84 gl::TextureCaps GenerateTextureFormatCaps(gl::Version maxClientVersion,
     85                                          GLenum internalFormat,
     86                                          ID3D11Device *device,
     87                                          const Renderer11DeviceCaps &renderer11DeviceCaps)
     88 {
     89    gl::TextureCaps textureCaps;
     90 
     91    DXGISupportHelper support(device, renderer11DeviceCaps.featureLevel);
     92    const d3d11::Format &formatInfo = d3d11::Format::Get(internalFormat, renderer11DeviceCaps);
     93 
     94    const gl::InternalFormat &internalFormatInfo = gl::GetSizedInternalFormatInfo(internalFormat);
     95 
     96    UINT texSupportMask = D3D11_FORMAT_SUPPORT_TEXTURE2D;
     97    if (internalFormatInfo.depthBits == 0 && internalFormatInfo.stencilBits == 0)
     98    {
     99        texSupportMask |= D3D11_FORMAT_SUPPORT_TEXTURECUBE;
    100        if (maxClientVersion.major > 2)
    101        {
    102            texSupportMask |= D3D11_FORMAT_SUPPORT_TEXTURE3D;
    103        }
    104    }
    105 
    106    textureCaps.texturable = support.query(formatInfo.texFormat, texSupportMask);
    107    textureCaps.filterable =
    108        support.query(formatInfo.srvFormat, D3D11_FORMAT_SUPPORT_SHADER_SAMPLE);
    109    textureCaps.textureAttachment =
    110        (support.query(formatInfo.rtvFormat, D3D11_FORMAT_SUPPORT_RENDER_TARGET)) ||
    111        (support.query(formatInfo.dsvFormat, D3D11_FORMAT_SUPPORT_DEPTH_STENCIL));
    112    textureCaps.renderbuffer = textureCaps.textureAttachment;
    113    textureCaps.blendable    = textureCaps.renderbuffer;
    114 
    115    DXGI_FORMAT renderFormat = DXGI_FORMAT_UNKNOWN;
    116    if (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN)
    117    {
    118        renderFormat = formatInfo.dsvFormat;
    119    }
    120    else if (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN)
    121    {
    122        renderFormat = formatInfo.rtvFormat;
    123    }
    124    if (renderFormat != DXGI_FORMAT_UNKNOWN &&
    125        support.query(renderFormat, D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET))
    126    {
    127        // Assume 1x
    128        textureCaps.sampleCounts.insert(1);
    129 
    130        for (unsigned int sampleCount = 2; sampleCount <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT;
    131             sampleCount *= 2)
    132        {
    133            UINT qualityCount = 0;
    134            if (SUCCEEDED(device->CheckMultisampleQualityLevels(renderFormat, sampleCount,
    135                                                                &qualityCount)))
    136            {
    137                // Assume we always support lower sample counts
    138                if (qualityCount == 0)
    139                {
    140                    break;
    141                }
    142                textureCaps.sampleCounts.insert(sampleCount);
    143            }
    144        }
    145    }
    146 
    147    return textureCaps;
    148 }
    149 
    150 bool GetNPOTTextureSupport(D3D_FEATURE_LEVEL featureLevel)
    151 {
    152    switch (featureLevel)
    153    {
    154        case D3D_FEATURE_LEVEL_11_1:
    155        case D3D_FEATURE_LEVEL_11_0:
    156        case D3D_FEATURE_LEVEL_10_1:
    157        case D3D_FEATURE_LEVEL_10_0:
    158            return true;
    159 
    160        // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx
    161        case D3D_FEATURE_LEVEL_9_3:
    162        case D3D_FEATURE_LEVEL_9_2:
    163        case D3D_FEATURE_LEVEL_9_1:
    164            return false;
    165 
    166        default:
    167            UNREACHABLE();
    168            return false;
    169    }
    170 }
    171 
    172 float GetMaximumAnisotropy(D3D_FEATURE_LEVEL featureLevel)
    173 {
    174    switch (featureLevel)
    175    {
    176        case D3D_FEATURE_LEVEL_11_1:
    177        case D3D_FEATURE_LEVEL_11_0:
    178            return D3D11_MAX_MAXANISOTROPY;
    179 
    180        case D3D_FEATURE_LEVEL_10_1:
    181        case D3D_FEATURE_LEVEL_10_0:
    182            return D3D10_MAX_MAXANISOTROPY;
    183 
    184        // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx
    185        case D3D_FEATURE_LEVEL_9_3:
    186        case D3D_FEATURE_LEVEL_9_2:
    187            return 16;
    188 
    189        case D3D_FEATURE_LEVEL_9_1:
    190            return D3D_FL9_1_DEFAULT_MAX_ANISOTROPY;
    191 
    192        default:
    193            UNREACHABLE();
    194            return 0;
    195    }
    196 }
    197 
    198 bool GetOcclusionQuerySupport(D3D_FEATURE_LEVEL featureLevel)
    199 {
    200    switch (featureLevel)
    201    {
    202        case D3D_FEATURE_LEVEL_11_1:
    203        case D3D_FEATURE_LEVEL_11_0:
    204        case D3D_FEATURE_LEVEL_10_1:
    205        case D3D_FEATURE_LEVEL_10_0:
    206            return true;
    207 
    208        // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx
    209        // ID3D11Device::CreateQuery
    210        case D3D_FEATURE_LEVEL_9_3:
    211        case D3D_FEATURE_LEVEL_9_2:
    212            return true;
    213        case D3D_FEATURE_LEVEL_9_1:
    214            return false;
    215 
    216        default:
    217            UNREACHABLE();
    218            return false;
    219    }
    220 }
    221 
    222 bool GetEventQuerySupport(D3D_FEATURE_LEVEL featureLevel)
    223 {
    224    // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx
    225    // ID3D11Device::CreateQuery
    226 
    227    switch (featureLevel)
    228    {
    229        case D3D_FEATURE_LEVEL_11_1:
    230        case D3D_FEATURE_LEVEL_11_0:
    231        case D3D_FEATURE_LEVEL_10_1:
    232        case D3D_FEATURE_LEVEL_10_0:
    233        case D3D_FEATURE_LEVEL_9_3:
    234        case D3D_FEATURE_LEVEL_9_2:
    235        case D3D_FEATURE_LEVEL_9_1:
    236            return true;
    237 
    238        default:
    239            UNREACHABLE();
    240            return false;
    241    }
    242 }
    243 
    244 bool GetInstancingSupport(D3D_FEATURE_LEVEL featureLevel)
    245 {
    246    // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx
    247    // ID3D11Device::CreateInputLayout
    248 
    249    switch (featureLevel)
    250    {
    251        case D3D_FEATURE_LEVEL_11_1:
    252        case D3D_FEATURE_LEVEL_11_0:
    253        case D3D_FEATURE_LEVEL_10_1:
    254        case D3D_FEATURE_LEVEL_10_0:
    255            return true;
    256 
    257        // Feature Level 9_3 supports instancing, but slot 0 in the input layout must not be
    258        // instanced.
    259        // D3D9 has a similar restriction, where stream 0 must not be instanced.
    260        // This restriction can be worked around by remapping any non-instanced slot to slot
    261        // 0.
    262        // This works because HLSL uses shader semantics to match the vertex inputs to the
    263        // elements in the input layout, rather than the slots.
    264        // Note that we only support instancing via ANGLE_instanced_array on 9_3, since 9_3
    265        // doesn't support OpenGL ES 3.0
    266        case D3D_FEATURE_LEVEL_9_3:
    267            return true;
    268 
    269        case D3D_FEATURE_LEVEL_9_2:
    270        case D3D_FEATURE_LEVEL_9_1:
    271            return false;
    272 
    273        default:
    274            UNREACHABLE();
    275            return false;
    276    }
    277 }
    278 
    279 bool GetFramebufferMultisampleSupport(D3D_FEATURE_LEVEL featureLevel)
    280 {
    281    switch (featureLevel)
    282    {
    283        case D3D_FEATURE_LEVEL_11_1:
    284        case D3D_FEATURE_LEVEL_11_0:
    285        case D3D_FEATURE_LEVEL_10_1:
    286        case D3D_FEATURE_LEVEL_10_0:
    287            return true;
    288 
    289        case D3D_FEATURE_LEVEL_9_3:
    290        case D3D_FEATURE_LEVEL_9_2:
    291        case D3D_FEATURE_LEVEL_9_1:
    292            return false;
    293 
    294        default:
    295            UNREACHABLE();
    296            return false;
    297    }
    298 }
    299 
    300 bool GetFramebufferBlitSupport(D3D_FEATURE_LEVEL featureLevel)
    301 {
    302    switch (featureLevel)
    303    {
    304        case D3D_FEATURE_LEVEL_11_1:
    305        case D3D_FEATURE_LEVEL_11_0:
    306        case D3D_FEATURE_LEVEL_10_1:
    307        case D3D_FEATURE_LEVEL_10_0:
    308            return true;
    309 
    310        case D3D_FEATURE_LEVEL_9_3:
    311        case D3D_FEATURE_LEVEL_9_2:
    312        case D3D_FEATURE_LEVEL_9_1:
    313            return false;
    314 
    315        default:
    316            UNREACHABLE();
    317            return false;
    318    }
    319 }
    320 
    321 bool GetDerivativeInstructionSupport(D3D_FEATURE_LEVEL featureLevel)
    322 {
    323    // http://msdn.microsoft.com/en-us/library/windows/desktop/bb509588.aspx states that
    324    // shader model
    325    // ps_2_x is required for the ddx (and other derivative functions).
    326 
    327    // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx states that
    328    // feature level
    329    // 9.3 supports shader model ps_2_x.
    330 
    331    switch (featureLevel)
    332    {
    333        case D3D_FEATURE_LEVEL_11_1:
    334        case D3D_FEATURE_LEVEL_11_0:
    335        case D3D_FEATURE_LEVEL_10_1:
    336        case D3D_FEATURE_LEVEL_10_0:
    337        case D3D_FEATURE_LEVEL_9_3:
    338            return true;
    339        case D3D_FEATURE_LEVEL_9_2:
    340        case D3D_FEATURE_LEVEL_9_1:
    341            return false;
    342 
    343        default:
    344            UNREACHABLE();
    345            return false;
    346    }
    347 }
    348 
    349 bool GetShaderTextureLODSupport(D3D_FEATURE_LEVEL featureLevel)
    350 {
    351    switch (featureLevel)
    352    {
    353        case D3D_FEATURE_LEVEL_11_1:
    354        case D3D_FEATURE_LEVEL_11_0:
    355        case D3D_FEATURE_LEVEL_10_1:
    356        case D3D_FEATURE_LEVEL_10_0:
    357            return true;
    358 
    359        case D3D_FEATURE_LEVEL_9_3:
    360        case D3D_FEATURE_LEVEL_9_2:
    361        case D3D_FEATURE_LEVEL_9_1:
    362            return false;
    363 
    364        default:
    365            UNREACHABLE();
    366            return false;
    367    }
    368 }
    369 
    370 int GetMaximumSimultaneousRenderTargets(D3D_FEATURE_LEVEL featureLevel)
    371 {
    372    // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx
    373    // ID3D11Device::CreateInputLayout
    374 
    375    switch (featureLevel)
    376    {
    377        case D3D_FEATURE_LEVEL_11_1:
    378        case D3D_FEATURE_LEVEL_11_0:
    379            return D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT;
    380 
    381        case D3D_FEATURE_LEVEL_10_1:
    382        case D3D_FEATURE_LEVEL_10_0:
    383            return D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT;
    384 
    385        case D3D_FEATURE_LEVEL_9_3:
    386            return D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT;
    387        case D3D_FEATURE_LEVEL_9_2:
    388        case D3D_FEATURE_LEVEL_9_1:
    389            return D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT;
    390 
    391        default:
    392            UNREACHABLE();
    393            return 0;
    394    }
    395 }
    396 
    397 int GetMaximum2DTextureSize(D3D_FEATURE_LEVEL featureLevel)
    398 {
    399    switch (featureLevel)
    400    {
    401        case D3D_FEATURE_LEVEL_11_1:
    402        case D3D_FEATURE_LEVEL_11_0:
    403            return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
    404 
    405        case D3D_FEATURE_LEVEL_10_1:
    406        case D3D_FEATURE_LEVEL_10_0:
    407            return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION;
    408 
    409        case D3D_FEATURE_LEVEL_9_3:
    410            return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION;
    411        case D3D_FEATURE_LEVEL_9_2:
    412        case D3D_FEATURE_LEVEL_9_1:
    413            return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION;
    414 
    415        default:
    416            UNREACHABLE();
    417            return 0;
    418    }
    419 }
    420 
    421 int GetMaximumCubeMapTextureSize(D3D_FEATURE_LEVEL featureLevel)
    422 {
    423    switch (featureLevel)
    424    {
    425        case D3D_FEATURE_LEVEL_11_1:
    426        case D3D_FEATURE_LEVEL_11_0:
    427            return D3D11_REQ_TEXTURECUBE_DIMENSION;
    428 
    429        case D3D_FEATURE_LEVEL_10_1:
    430        case D3D_FEATURE_LEVEL_10_0:
    431            return D3D10_REQ_TEXTURECUBE_DIMENSION;
    432 
    433        case D3D_FEATURE_LEVEL_9_3:
    434            return D3D_FL9_3_REQ_TEXTURECUBE_DIMENSION;
    435        case D3D_FEATURE_LEVEL_9_2:
    436        case D3D_FEATURE_LEVEL_9_1:
    437            return D3D_FL9_1_REQ_TEXTURECUBE_DIMENSION;
    438 
    439        default:
    440            UNREACHABLE();
    441            return 0;
    442    }
    443 }
    444 
    445 int GetMaximum2DTextureArraySize(D3D_FEATURE_LEVEL featureLevel)
    446 {
    447    switch (featureLevel)
    448    {
    449        case D3D_FEATURE_LEVEL_11_1:
    450        case D3D_FEATURE_LEVEL_11_0:
    451            return D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION;
    452 
    453        case D3D_FEATURE_LEVEL_10_1:
    454        case D3D_FEATURE_LEVEL_10_0:
    455            return D3D10_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION;
    456 
    457        case D3D_FEATURE_LEVEL_9_3:
    458        case D3D_FEATURE_LEVEL_9_2:
    459        case D3D_FEATURE_LEVEL_9_1:
    460            return 0;
    461 
    462        default:
    463            UNREACHABLE();
    464            return 0;
    465    }
    466 }
    467 
    468 int GetMaximum3DTextureSize(D3D_FEATURE_LEVEL featureLevel)
    469 {
    470    switch (featureLevel)
    471    {
    472        case D3D_FEATURE_LEVEL_11_1:
    473        case D3D_FEATURE_LEVEL_11_0:
    474            return D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION;
    475 
    476        case D3D_FEATURE_LEVEL_10_1:
    477        case D3D_FEATURE_LEVEL_10_0:
    478            return D3D10_REQ_TEXTURE3D_U_V_OR_W_DIMENSION;
    479 
    480        case D3D_FEATURE_LEVEL_9_3:
    481        case D3D_FEATURE_LEVEL_9_2:
    482        case D3D_FEATURE_LEVEL_9_1:
    483            return D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION;
    484 
    485        default:
    486            UNREACHABLE();
    487            return 0;
    488    }
    489 }
    490 
    491 int GetMaximumViewportSize(D3D_FEATURE_LEVEL featureLevel)
    492 {
    493    switch (featureLevel)
    494    {
    495        case D3D_FEATURE_LEVEL_11_1:
    496        case D3D_FEATURE_LEVEL_11_0:
    497            return D3D11_VIEWPORT_BOUNDS_MAX;
    498 
    499        case D3D_FEATURE_LEVEL_10_1:
    500        case D3D_FEATURE_LEVEL_10_0:
    501            return D3D10_VIEWPORT_BOUNDS_MAX;
    502 
    503        // No constants for D3D11 Feature Level 9 viewport size limits, use the maximum
    504        // texture sizes
    505        case D3D_FEATURE_LEVEL_9_3:
    506            return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION;
    507        case D3D_FEATURE_LEVEL_9_2:
    508        case D3D_FEATURE_LEVEL_9_1:
    509            return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION;
    510 
    511        default:
    512            UNREACHABLE();
    513            return 0;
    514    }
    515 }
    516 
    517 int GetMaximumDrawIndexedIndexCount(D3D_FEATURE_LEVEL featureLevel)
    518 {
    519    // D3D11 allows up to 2^32 elements, but we report max signed int for convenience since
    520    // that's what's
    521    // returned from glGetInteger
    522    static_assert(D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32,
    523                  "Unexpected D3D11 constant value.");
    524    static_assert(D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32,
    525                  "Unexpected D3D11 constant value.");
    526 
    527    switch (featureLevel)
    528    {
    529        case D3D_FEATURE_LEVEL_11_1:
    530        case D3D_FEATURE_LEVEL_11_0:
    531        case D3D_FEATURE_LEVEL_10_1:
    532        case D3D_FEATURE_LEVEL_10_0:
    533            return std::numeric_limits<GLint>::max();
    534 
    535        case D3D_FEATURE_LEVEL_9_3:
    536        case D3D_FEATURE_LEVEL_9_2:
    537            return D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT;
    538        case D3D_FEATURE_LEVEL_9_1:
    539            return D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT;
    540 
    541        default:
    542            UNREACHABLE();
    543            return 0;
    544    }
    545 }
    546 
    547 int GetMaximumDrawVertexCount(D3D_FEATURE_LEVEL featureLevel)
    548 {
    549    // D3D11 allows up to 2^32 elements, but we report max signed int for convenience since
    550    // that's what's
    551    // returned from glGetInteger
    552    static_assert(D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32, "Unexpected D3D11 constant value.");
    553    static_assert(D3D10_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32, "Unexpected D3D11 constant value.");
    554 
    555    switch (featureLevel)
    556    {
    557        case D3D_FEATURE_LEVEL_11_1:
    558        case D3D_FEATURE_LEVEL_11_0:
    559        case D3D_FEATURE_LEVEL_10_1:
    560        case D3D_FEATURE_LEVEL_10_0:
    561            return std::numeric_limits<GLint>::max();
    562 
    563        case D3D_FEATURE_LEVEL_9_3:
    564        case D3D_FEATURE_LEVEL_9_2:
    565            return D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT;
    566        case D3D_FEATURE_LEVEL_9_1:
    567            return D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT;
    568 
    569        default:
    570            UNREACHABLE();
    571            return 0;
    572    }
    573 }
    574 
    575 int GetMaximumVertexInputSlots(D3D_FEATURE_LEVEL featureLevel)
    576 {
    577    switch (featureLevel)
    578    {
    579        case D3D_FEATURE_LEVEL_11_1:
    580        case D3D_FEATURE_LEVEL_11_0:
    581            return D3D11_STANDARD_VERTEX_ELEMENT_COUNT;
    582 
    583        case D3D_FEATURE_LEVEL_10_1:
    584            return D3D10_1_STANDARD_VERTEX_ELEMENT_COUNT;
    585        case D3D_FEATURE_LEVEL_10_0:
    586            return D3D10_STANDARD_VERTEX_ELEMENT_COUNT;
    587 
    588        // From http://http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx
    589        // "Max Input Slots"
    590        case D3D_FEATURE_LEVEL_9_3:
    591        case D3D_FEATURE_LEVEL_9_2:
    592        case D3D_FEATURE_LEVEL_9_1:
    593            return 16;
    594 
    595        default:
    596            UNREACHABLE();
    597            return 0;
    598    }
    599 }
    600 
    601 int GetMaximumVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel)
    602 {
    603    switch (featureLevel)
    604    {
    605        case D3D_FEATURE_LEVEL_11_1:
    606        case D3D_FEATURE_LEVEL_11_0:
    607            return D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT;
    608 
    609        case D3D_FEATURE_LEVEL_10_1:
    610        case D3D_FEATURE_LEVEL_10_0:
    611            return D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT;
    612 
    613        // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx
    614        // ID3D11DeviceContext::VSSetConstantBuffers
    615        case D3D_FEATURE_LEVEL_9_3:
    616        case D3D_FEATURE_LEVEL_9_2:
    617        case D3D_FEATURE_LEVEL_9_1:
    618            return 255 - d3d11_gl::GetReservedVertexUniformVectors(featureLevel);
    619 
    620        default:
    621            UNREACHABLE();
    622            return 0;
    623    }
    624 }
    625 
    626 int GetMaximumVertexUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
    627 {
    628    switch (featureLevel)
    629    {
    630        case D3D_FEATURE_LEVEL_11_1:
    631        case D3D_FEATURE_LEVEL_11_0:
    632            return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT -
    633                   d3d11::RESERVED_CONSTANT_BUFFER_SLOT_COUNT;
    634 
    635        case D3D_FEATURE_LEVEL_10_1:
    636        case D3D_FEATURE_LEVEL_10_0:
    637            return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT -
    638                   d3d11::RESERVED_CONSTANT_BUFFER_SLOT_COUNT;
    639 
    640        // Uniform blocks not supported on D3D11 Feature Level 9
    641        case D3D_FEATURE_LEVEL_9_3:
    642        case D3D_FEATURE_LEVEL_9_2:
    643        case D3D_FEATURE_LEVEL_9_1:
    644            return 0;
    645 
    646        default:
    647            UNREACHABLE();
    648            return 0;
    649    }
    650 }
    651 
    652 int GetReservedVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel)
    653 {
    654    // According to The OpenGL ES Shading Language specifications
    655    // (Language Version 1.00 section 10.16, Language Version 3.10 section 12.21)
    656    // built-in special variables (e.g. gl_FragCoord, or gl_PointCoord)
    657    // which are statically used in the shader should be included in the variable packing
    658    // algorithm.
    659    // Therefore, we should not reserve output vectors for them.
    660 
    661    switch (featureLevel)
    662    {
    663        // We must reserve one output vector for dx_Position.
    664        // We also reserve one for gl_Position, which we unconditionally output on Feature
    665        // Levels 10_0+,
    666        // even if it's unused in the shader (e.g. for transform feedback). TODO: This could
    667        // be improved.
    668        case D3D_FEATURE_LEVEL_11_1:
    669        case D3D_FEATURE_LEVEL_11_0:
    670        case D3D_FEATURE_LEVEL_10_1:
    671        case D3D_FEATURE_LEVEL_10_0:
    672            return 2;
    673 
    674        // Just reserve dx_Position on Feature Level 9, since we don't ever need to output
    675        // gl_Position.
    676        case D3D_FEATURE_LEVEL_9_3:
    677        case D3D_FEATURE_LEVEL_9_2:
    678        case D3D_FEATURE_LEVEL_9_1:
    679            return 1;
    680 
    681        default:
    682            UNREACHABLE();
    683            return 0;
    684    }
    685 }
    686 
    687 int GetMaximumVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel)
    688 {
    689    static_assert(gl::IMPLEMENTATION_MAX_VARYING_VECTORS == D3D11_VS_OUTPUT_REGISTER_COUNT,
    690                  "Unexpected D3D11 constant value.");
    691 
    692    switch (featureLevel)
    693    {
    694        case D3D_FEATURE_LEVEL_11_1:
    695        case D3D_FEATURE_LEVEL_11_0:
    696            return D3D11_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel);
    697 
    698        case D3D_FEATURE_LEVEL_10_1:
    699            return D3D10_1_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel);
    700        case D3D_FEATURE_LEVEL_10_0:
    701            return D3D10_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel);
    702 
    703        // Use Shader Model 2.X limits
    704        case D3D_FEATURE_LEVEL_9_3:
    705        case D3D_FEATURE_LEVEL_9_2:
    706        case D3D_FEATURE_LEVEL_9_1:
    707            return 8 - GetReservedVertexOutputVectors(featureLevel);
    708 
    709        default:
    710            UNREACHABLE();
    711            return 0;
    712    }
    713 }
    714 
    715 int GetMaximumVertexTextureUnits(D3D_FEATURE_LEVEL featureLevel)
    716 {
    717    switch (featureLevel)
    718    {
    719        case D3D_FEATURE_LEVEL_11_1:
    720        case D3D_FEATURE_LEVEL_11_0:
    721            return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT;
    722 
    723        case D3D_FEATURE_LEVEL_10_1:
    724        case D3D_FEATURE_LEVEL_10_0:
    725            return D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT;
    726 
    727        // Vertex textures not supported on D3D11 Feature Level 9 according to
    728        // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx
    729        // ID3D11DeviceContext::VSSetSamplers and ID3D11DeviceContext::VSSetShaderResources
    730        case D3D_FEATURE_LEVEL_9_3:
    731        case D3D_FEATURE_LEVEL_9_2:
    732        case D3D_FEATURE_LEVEL_9_1:
    733            return 0;
    734 
    735        default:
    736            UNREACHABLE();
    737            return 0;
    738    }
    739 }
    740 
    741 int GetMaximumPixelUniformVectors(D3D_FEATURE_LEVEL featureLevel)
    742 {
    743    // TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass
    744    switch (featureLevel)
    745    {
    746        case D3D_FEATURE_LEVEL_11_1:
    747        case D3D_FEATURE_LEVEL_11_0:
    748            return 1024;  // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT;
    749 
    750        case D3D_FEATURE_LEVEL_10_1:
    751        case D3D_FEATURE_LEVEL_10_0:
    752            return 1024;  // D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT;
    753 
    754        // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx
    755        // ID3D11DeviceContext::PSSetConstantBuffers
    756        case D3D_FEATURE_LEVEL_9_3:
    757        case D3D_FEATURE_LEVEL_9_2:
    758        case D3D_FEATURE_LEVEL_9_1:
    759            return 32 - d3d11_gl::GetReservedFragmentUniformVectors(featureLevel);
    760 
    761        default:
    762            UNREACHABLE();
    763            return 0;
    764    }
    765 }
    766 
    767 int GetMaximumPixelUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
    768 {
    769    switch (featureLevel)
    770    {
    771        case D3D_FEATURE_LEVEL_11_1:
    772        case D3D_FEATURE_LEVEL_11_0:
    773            return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT -
    774                   d3d11::RESERVED_CONSTANT_BUFFER_SLOT_COUNT;
    775 
    776        case D3D_FEATURE_LEVEL_10_1:
    777        case D3D_FEATURE_LEVEL_10_0:
    778            return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT -
    779                   d3d11::RESERVED_CONSTANT_BUFFER_SLOT_COUNT;
    780 
    781        // Uniform blocks not supported on D3D11 Feature Level 9
    782        case D3D_FEATURE_LEVEL_9_3:
    783        case D3D_FEATURE_LEVEL_9_2:
    784        case D3D_FEATURE_LEVEL_9_1:
    785            return 0;
    786 
    787        default:
    788            UNREACHABLE();
    789            return 0;
    790    }
    791 }
    792 
    793 int GetMaximumPixelInputVectors(D3D_FEATURE_LEVEL featureLevel)
    794 {
    795    switch (featureLevel)
    796    {
    797        case D3D_FEATURE_LEVEL_11_1:
    798        case D3D_FEATURE_LEVEL_11_0:
    799            return D3D11_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel);
    800 
    801        case D3D_FEATURE_LEVEL_10_1:
    802        case D3D_FEATURE_LEVEL_10_0:
    803            return D3D10_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel);
    804 
    805        // Use Shader Model 2.X limits
    806        case D3D_FEATURE_LEVEL_9_3:
    807            return 8 - GetReservedVertexOutputVectors(featureLevel);
    808        case D3D_FEATURE_LEVEL_9_2:
    809        case D3D_FEATURE_LEVEL_9_1:
    810            return 8 - GetReservedVertexOutputVectors(featureLevel);
    811 
    812        default:
    813            UNREACHABLE();
    814            return 0;
    815    }
    816 }
    817 
    818 int GetMaximumPixelTextureUnits(D3D_FEATURE_LEVEL featureLevel)
    819 {
    820    switch (featureLevel)
    821    {
    822        case D3D_FEATURE_LEVEL_11_1:
    823        case D3D_FEATURE_LEVEL_11_0:
    824            return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT;
    825 
    826        case D3D_FEATURE_LEVEL_10_1:
    827        case D3D_FEATURE_LEVEL_10_0:
    828            return D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT;
    829 
    830        // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx
    831        // ID3D11DeviceContext::PSSetShaderResources
    832        case D3D_FEATURE_LEVEL_9_3:
    833        case D3D_FEATURE_LEVEL_9_2:
    834        case D3D_FEATURE_LEVEL_9_1:
    835            return 16;
    836 
    837        default:
    838            UNREACHABLE();
    839            return 0;
    840    }
    841 }
    842 
    843 std::array<GLint, 3> GetMaxComputeWorkGroupCount(D3D_FEATURE_LEVEL featureLevel)
    844 {
    845    switch (featureLevel)
    846    {
    847        case D3D_FEATURE_LEVEL_11_1:
    848        case D3D_FEATURE_LEVEL_11_0:
    849            return {{D3D11_CS_DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION,
    850                     D3D11_CS_DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION,
    851                     D3D11_CS_DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION}};
    852        default:
    853            return {{0, 0, 0}};
    854    }
    855 }
    856 
    857 std::array<GLint, 3> GetMaxComputeWorkGroupSize(D3D_FEATURE_LEVEL featureLevel)
    858 {
    859    switch (featureLevel)
    860    {
    861        case D3D_FEATURE_LEVEL_11_1:
    862        case D3D_FEATURE_LEVEL_11_0:
    863            return {{D3D11_CS_THREAD_GROUP_MAX_X, D3D11_CS_THREAD_GROUP_MAX_Y,
    864                     D3D11_CS_THREAD_GROUP_MAX_Z}};
    865        default:
    866            return {{0, 0, 0}};
    867    }
    868 }
    869 
    870 int GetMaxComputeWorkGroupInvocations(D3D_FEATURE_LEVEL featureLevel)
    871 {
    872    switch (featureLevel)
    873    {
    874        case D3D_FEATURE_LEVEL_11_1:
    875        case D3D_FEATURE_LEVEL_11_0:
    876            return D3D11_CS_THREAD_GROUP_MAX_THREADS_PER_GROUP;
    877        default:
    878            return 0;
    879    }
    880 }
    881 
    882 int GetMaxComputeSharedMemorySize(D3D_FEATURE_LEVEL featureLevel)
    883 {
    884    switch (featureLevel)
    885    {
    886        // In D3D11 the maximum total size of all variables with the groupshared storage class is
    887        // 32kb.
    888        // https://docs.microsoft.com/en-us/windows/desktop/direct3dhlsl/dx-graphics-hlsl-variable-syntax
    889        case D3D_FEATURE_LEVEL_11_1:
    890        case D3D_FEATURE_LEVEL_11_0:
    891            return 32768;
    892        default:
    893            return 0;
    894    }
    895 }
    896 
    897 int GetMaximumComputeUniformVectors(D3D_FEATURE_LEVEL featureLevel)
    898 {
    899    switch (featureLevel)
    900    {
    901        case D3D_FEATURE_LEVEL_11_1:
    902        case D3D_FEATURE_LEVEL_11_0:
    903            return D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT;
    904        default:
    905            return 0;
    906    }
    907 }
    908 
    909 int GetMaximumComputeUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
    910 {
    911    switch (featureLevel)
    912    {
    913        case D3D_FEATURE_LEVEL_11_1:
    914        case D3D_FEATURE_LEVEL_11_0:
    915            return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT -
    916                   d3d11::RESERVED_CONSTANT_BUFFER_SLOT_COUNT;
    917        default:
    918            return 0;
    919    }
    920 }
    921 
    922 int GetMaximumComputeTextureUnits(D3D_FEATURE_LEVEL featureLevel)
    923 {
    924    switch (featureLevel)
    925    {
    926        case D3D_FEATURE_LEVEL_11_1:
    927        case D3D_FEATURE_LEVEL_11_0:
    928            return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT;
    929        default:
    930            return 0;
    931    }
    932 }
    933 
    934 void SetUAVRelatedResourceLimits(D3D_FEATURE_LEVEL featureLevel, gl::Caps *caps)
    935 {
    936    ASSERT(caps);
    937 
    938    GLuint reservedUAVsForAtomicCounterBuffers = 0u;
    939 
    940    // For pixel shaders, the render targets and unordered access views share the same resource
    941    // slots when being written out.
    942    // https://msdn.microsoft.com/en-us/library/windows/desktop/ff476465(v=vs.85).aspx
    943    GLuint maxNumRTVsAndUAVs = 0u;
    944 
    945    switch (featureLevel)
    946    {
    947        case D3D_FEATURE_LEVEL_11_1:
    948            // Currently we allocate 4 UAV slots for atomic counter buffers on feature level 11_1.
    949            reservedUAVsForAtomicCounterBuffers = 4u;
    950            maxNumRTVsAndUAVs                   = D3D11_1_UAV_SLOT_COUNT;
    951            break;
    952        case D3D_FEATURE_LEVEL_11_0:
    953            // Currently we allocate 1 UAV slot for atomic counter buffers on feature level 11_0.
    954            reservedUAVsForAtomicCounterBuffers = 1u;
    955            maxNumRTVsAndUAVs                   = D3D11_PS_CS_UAV_REGISTER_COUNT;
    956            break;
    957        default:
    958            return;
    959    }
    960 
    961    // Set limits on atomic counter buffers in fragment shaders and compute shaders.
    962    caps->maxCombinedAtomicCounterBuffers = reservedUAVsForAtomicCounterBuffers;
    963    caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Compute] =
    964        reservedUAVsForAtomicCounterBuffers;
    965    caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Fragment] =
    966        reservedUAVsForAtomicCounterBuffers;
    967    caps->maxAtomicCounterBufferBindings = reservedUAVsForAtomicCounterBuffers;
    968 
    969    // Setting MAX_COMPUTE_ATOMIC_COUNTERS to a conservative number of 1024 * the number of UAV
    970    // reserved for atomic counters. It could theoretically be set to max buffer size / 4 but that
    971    // number could cause problems.
    972    caps->maxCombinedAtomicCounters = reservedUAVsForAtomicCounterBuffers * 1024;
    973    caps->maxShaderAtomicCounters[gl::ShaderType::Compute] = caps->maxCombinedAtomicCounters;
    974 
    975    // See
    976    // https://docs.microsoft.com/en-us/windows/desktop/direct3d11/overviews-direct3d-11-resources-limits
    977    // Resource size (in MB) for any of the preceding resources is min(max(128,0.25f * (amount of
    978    // dedicated VRAM)), 2048) MB. So we set it to 128MB to keep same with GL backend.
    979    caps->maxShaderStorageBlockSize =
    980        D3D11_REQ_RESOURCE_SIZE_IN_MEGABYTES_EXPRESSION_A_TERM * 1024 * 1024;
    981 
    982    // Allocate the remaining slots for images and shader storage blocks.
    983    // The maximum number of fragment shader outputs depends on the current context version, so we
    984    // will not set it here. See comments in Context11::initialize().
    985    caps->maxCombinedShaderOutputResources =
    986        maxNumRTVsAndUAVs - reservedUAVsForAtomicCounterBuffers;
    987 
    988    // Set limits on images and shader storage blocks in fragment shaders and compute shaders.
    989    caps->maxCombinedShaderStorageBlocks                   = caps->maxCombinedShaderOutputResources;
    990    caps->maxShaderStorageBlocks[gl::ShaderType::Compute]  = caps->maxCombinedShaderOutputResources;
    991    caps->maxShaderStorageBlocks[gl::ShaderType::Fragment] = caps->maxCombinedShaderOutputResources;
    992    caps->maxShaderStorageBufferBindings                   = caps->maxCombinedShaderOutputResources;
    993 
    994    caps->maxImageUnits                                    = caps->maxCombinedShaderOutputResources;
    995    caps->maxCombinedImageUniforms                         = caps->maxCombinedShaderOutputResources;
    996    caps->maxShaderImageUniforms[gl::ShaderType::Compute]  = caps->maxCombinedShaderOutputResources;
    997    caps->maxShaderImageUniforms[gl::ShaderType::Fragment] = caps->maxCombinedShaderOutputResources;
    998 
    999    // On feature level 11_1, UAVs are also available in vertex shaders and geometry shaders.
   1000    if (featureLevel == D3D_FEATURE_LEVEL_11_1)
   1001    {
   1002        caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Vertex] =
   1003            caps->maxCombinedAtomicCounterBuffers;
   1004        caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Geometry] =
   1005            caps->maxCombinedAtomicCounterBuffers;
   1006 
   1007        caps->maxShaderImageUniforms[gl::ShaderType::Vertex] =
   1008            caps->maxCombinedShaderOutputResources;
   1009        caps->maxShaderStorageBlocks[gl::ShaderType::Vertex] =
   1010            caps->maxCombinedShaderOutputResources;
   1011        caps->maxShaderImageUniforms[gl::ShaderType::Geometry] =
   1012            caps->maxCombinedShaderOutputResources;
   1013        caps->maxShaderStorageBlocks[gl::ShaderType::Geometry] =
   1014            caps->maxCombinedShaderOutputResources;
   1015    }
   1016 }
   1017 
   1018 int GetMinimumTexelOffset(D3D_FEATURE_LEVEL featureLevel)
   1019 {
   1020    switch (featureLevel)
   1021    {
   1022        case D3D_FEATURE_LEVEL_11_1:
   1023        case D3D_FEATURE_LEVEL_11_0:
   1024            return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE;
   1025 
   1026        case D3D_FEATURE_LEVEL_10_1:
   1027        case D3D_FEATURE_LEVEL_10_0:
   1028            return D3D10_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE;
   1029 
   1030        // Sampling functions with offsets are not available below shader model 4.0.
   1031        case D3D_FEATURE_LEVEL_9_3:
   1032        case D3D_FEATURE_LEVEL_9_2:
   1033        case D3D_FEATURE_LEVEL_9_1:
   1034            return 0;
   1035 
   1036        default:
   1037            UNREACHABLE();
   1038            return 0;
   1039    }
   1040 }
   1041 
   1042 int GetMaximumTexelOffset(D3D_FEATURE_LEVEL featureLevel)
   1043 {
   1044    switch (featureLevel)
   1045    {
   1046        case D3D_FEATURE_LEVEL_11_1:
   1047        case D3D_FEATURE_LEVEL_11_0:
   1048            return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE;
   1049        case D3D_FEATURE_LEVEL_10_1:
   1050        case D3D_FEATURE_LEVEL_10_0:
   1051            return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE;
   1052 
   1053        // Sampling functions with offsets are not available below shader model 4.0.
   1054        case D3D_FEATURE_LEVEL_9_3:
   1055        case D3D_FEATURE_LEVEL_9_2:
   1056        case D3D_FEATURE_LEVEL_9_1:
   1057            return 0;
   1058 
   1059        default:
   1060            UNREACHABLE();
   1061            return 0;
   1062    }
   1063 }
   1064 
   1065 int GetMinimumTextureGatherOffset(D3D_FEATURE_LEVEL featureLevel)
   1066 {
   1067    switch (featureLevel)
   1068    {
   1069        // https://docs.microsoft.com/en-us/windows/desktop/direct3dhlsl/gather4-po--sm5---asm-
   1070        case D3D_FEATURE_LEVEL_11_1:
   1071        case D3D_FEATURE_LEVEL_11_0:
   1072            return -32;
   1073 
   1074        case D3D_FEATURE_LEVEL_10_1:
   1075        case D3D_FEATURE_LEVEL_10_0:
   1076        case D3D_FEATURE_LEVEL_9_3:
   1077        case D3D_FEATURE_LEVEL_9_2:
   1078        case D3D_FEATURE_LEVEL_9_1:
   1079            return 0;
   1080 
   1081        default:
   1082            UNREACHABLE();
   1083            return 0;
   1084    }
   1085 }
   1086 
   1087 int GetMaximumTextureGatherOffset(D3D_FEATURE_LEVEL featureLevel)
   1088 {
   1089    switch (featureLevel)
   1090    {
   1091        // https://docs.microsoft.com/en-us/windows/desktop/direct3dhlsl/gather4-po--sm5---asm-
   1092        case D3D_FEATURE_LEVEL_11_1:
   1093        case D3D_FEATURE_LEVEL_11_0:
   1094            return 31;
   1095 
   1096        case D3D_FEATURE_LEVEL_10_1:
   1097        case D3D_FEATURE_LEVEL_10_0:
   1098        case D3D_FEATURE_LEVEL_9_3:
   1099        case D3D_FEATURE_LEVEL_9_2:
   1100        case D3D_FEATURE_LEVEL_9_1:
   1101            return 0;
   1102 
   1103        default:
   1104            UNREACHABLE();
   1105            return 0;
   1106    }
   1107 }
   1108 
   1109 size_t GetMaximumConstantBufferSize(D3D_FEATURE_LEVEL featureLevel)
   1110 {
   1111    // Returns a size_t despite the limit being a GLuint64 because size_t is the maximum
   1112    // size of
   1113    // any buffer that could be allocated.
   1114 
   1115    const size_t bytesPerComponent = 4 * sizeof(float);
   1116 
   1117    switch (featureLevel)
   1118    {
   1119        case D3D_FEATURE_LEVEL_11_1:
   1120        case D3D_FEATURE_LEVEL_11_0:
   1121            return D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent;
   1122 
   1123        case D3D_FEATURE_LEVEL_10_1:
   1124        case D3D_FEATURE_LEVEL_10_0:
   1125            return D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent;
   1126 
   1127        // Limits from http://msdn.microsoft.com/en-us/library/windows/desktop/ff476501.aspx
   1128        // remarks section
   1129        case D3D_FEATURE_LEVEL_9_3:
   1130        case D3D_FEATURE_LEVEL_9_2:
   1131        case D3D_FEATURE_LEVEL_9_1:
   1132            return 4096 * bytesPerComponent;
   1133 
   1134        default:
   1135            UNREACHABLE();
   1136            return 0;
   1137    }
   1138 }
   1139 
   1140 int GetMaximumStreamOutputBuffers(D3D_FEATURE_LEVEL featureLevel)
   1141 {
   1142    switch (featureLevel)
   1143    {
   1144        case D3D_FEATURE_LEVEL_11_1:
   1145        case D3D_FEATURE_LEVEL_11_0:
   1146            return D3D11_SO_BUFFER_SLOT_COUNT;
   1147 
   1148        case D3D_FEATURE_LEVEL_10_1:
   1149            return D3D10_1_SO_BUFFER_SLOT_COUNT;
   1150        case D3D_FEATURE_LEVEL_10_0:
   1151            return D3D10_SO_BUFFER_SLOT_COUNT;
   1152 
   1153        case D3D_FEATURE_LEVEL_9_3:
   1154        case D3D_FEATURE_LEVEL_9_2:
   1155        case D3D_FEATURE_LEVEL_9_1:
   1156            return 0;
   1157 
   1158        default:
   1159            UNREACHABLE();
   1160            return 0;
   1161    }
   1162 }
   1163 
   1164 int GetMaximumStreamOutputInterleavedComponents(D3D_FEATURE_LEVEL featureLevel)
   1165 {
   1166    switch (featureLevel)
   1167    {
   1168        case D3D_FEATURE_LEVEL_11_1:
   1169        case D3D_FEATURE_LEVEL_11_0:
   1170 
   1171        case D3D_FEATURE_LEVEL_10_1:
   1172        case D3D_FEATURE_LEVEL_10_0:
   1173            return GetMaximumVertexOutputVectors(featureLevel) * 4;
   1174 
   1175        case D3D_FEATURE_LEVEL_9_3:
   1176        case D3D_FEATURE_LEVEL_9_2:
   1177        case D3D_FEATURE_LEVEL_9_1:
   1178            return 0;
   1179 
   1180        default:
   1181            UNREACHABLE();
   1182            return 0;
   1183    }
   1184 }
   1185 
   1186 int GetMaximumStreamOutputSeparateComponents(D3D_FEATURE_LEVEL featureLevel)
   1187 {
   1188    switch (featureLevel)
   1189    {
   1190        case D3D_FEATURE_LEVEL_11_1:
   1191        case D3D_FEATURE_LEVEL_11_0:
   1192            return GetMaximumStreamOutputInterleavedComponents(featureLevel) /
   1193                   GetMaximumStreamOutputBuffers(featureLevel);
   1194 
   1195        // D3D 10 and 10.1 only allow one output per output slot if an output slot other
   1196        // than zero is used.
   1197        case D3D_FEATURE_LEVEL_10_1:
   1198        case D3D_FEATURE_LEVEL_10_0:
   1199            return 4;
   1200 
   1201        case D3D_FEATURE_LEVEL_9_3:
   1202        case D3D_FEATURE_LEVEL_9_2:
   1203        case D3D_FEATURE_LEVEL_9_1:
   1204            return 0;
   1205 
   1206        default:
   1207            UNREACHABLE();
   1208            return 0;
   1209    }
   1210 }
   1211 
   1212 int GetMaximumRenderToBufferWindowSize(D3D_FEATURE_LEVEL featureLevel)
   1213 {
   1214    switch (featureLevel)
   1215    {
   1216        case D3D_FEATURE_LEVEL_11_1:
   1217        case D3D_FEATURE_LEVEL_11_0:
   1218            return D3D11_REQ_RENDER_TO_BUFFER_WINDOW_WIDTH;
   1219        case D3D_FEATURE_LEVEL_10_1:
   1220        case D3D_FEATURE_LEVEL_10_0:
   1221            return D3D10_REQ_RENDER_TO_BUFFER_WINDOW_WIDTH;
   1222 
   1223        // REQ_RENDER_TO_BUFFER_WINDOW_WIDTH not supported on D3D11 Feature Level 9,
   1224        // use the maximum texture sizes
   1225        case D3D_FEATURE_LEVEL_9_3:
   1226            return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION;
   1227        case D3D_FEATURE_LEVEL_9_2:
   1228        case D3D_FEATURE_LEVEL_9_1:
   1229            return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION;
   1230 
   1231        default:
   1232            UNREACHABLE();
   1233            return 0;
   1234    }
   1235 }
   1236 
   1237 IntelDriverVersion GetIntelDriverVersion(const Optional<LARGE_INTEGER> driverVersion)
   1238 {
   1239    if (!driverVersion.valid())
   1240        return IntelDriverVersion(0);
   1241 
   1242    DWORD lowPart = driverVersion.value().LowPart;
   1243    return IntelDriverVersion(HIWORD(lowPart) * 10000 + LOWORD(lowPart));
   1244 }
   1245 
   1246 }  // anonymous namespace
   1247 
   1248 unsigned int GetReservedVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel)
   1249 {
   1250    switch (featureLevel)
   1251    {
   1252        case D3D_FEATURE_LEVEL_11_1:
   1253        case D3D_FEATURE_LEVEL_11_0:
   1254        case D3D_FEATURE_LEVEL_10_1:
   1255        case D3D_FEATURE_LEVEL_10_0:
   1256            return 0;
   1257 
   1258        case D3D_FEATURE_LEVEL_9_3:
   1259        case D3D_FEATURE_LEVEL_9_2:
   1260        case D3D_FEATURE_LEVEL_9_1:
   1261            return 3;  // dx_ViewAdjust, dx_ViewCoords and dx_ViewScale
   1262 
   1263        default:
   1264            UNREACHABLE();
   1265            return 0;
   1266    }
   1267 }
   1268 
   1269 unsigned int GetReservedFragmentUniformVectors(D3D_FEATURE_LEVEL featureLevel)
   1270 {
   1271    switch (featureLevel)
   1272    {
   1273        case D3D_FEATURE_LEVEL_11_1:
   1274        case D3D_FEATURE_LEVEL_11_0:
   1275        case D3D_FEATURE_LEVEL_10_1:
   1276        case D3D_FEATURE_LEVEL_10_0:
   1277            return 0;
   1278 
   1279        case D3D_FEATURE_LEVEL_9_3:
   1280        case D3D_FEATURE_LEVEL_9_2:
   1281        case D3D_FEATURE_LEVEL_9_1:
   1282            return 4;  // dx_ViewCoords, dx_DepthFront, dx_DepthRange, dx_FragCoordOffset
   1283 
   1284        default:
   1285            UNREACHABLE();
   1286            return 0;
   1287    }
   1288 }
   1289 
   1290 gl::Version GetMaximumClientVersion(const Renderer11DeviceCaps &caps)
   1291 {
   1292    switch (caps.featureLevel)
   1293    {
   1294        case D3D_FEATURE_LEVEL_11_1:
   1295        case D3D_FEATURE_LEVEL_11_0:
   1296            return gl::Version(3, 1);
   1297        case D3D_FEATURE_LEVEL_10_1:
   1298            return gl::Version(3, 0);
   1299 
   1300        case D3D_FEATURE_LEVEL_10_0:
   1301            if (caps.allowES3OnFL10_0)
   1302            {
   1303                return gl::Version(3, 0);
   1304            }
   1305            else
   1306            {
   1307                return gl::Version(2, 0);
   1308            }
   1309        case D3D_FEATURE_LEVEL_9_3:
   1310        case D3D_FEATURE_LEVEL_9_2:
   1311        case D3D_FEATURE_LEVEL_9_1:
   1312            return gl::Version(2, 0);
   1313 
   1314        default:
   1315            UNREACHABLE();
   1316            return gl::Version(0, 0);
   1317    }
   1318 }
   1319 
   1320 D3D_FEATURE_LEVEL GetMinimumFeatureLevelForES31()
   1321 {
   1322    return kMinimumFeatureLevelForES31;
   1323 }
   1324 
   1325 unsigned int GetMaxViewportAndScissorRectanglesPerPipeline(D3D_FEATURE_LEVEL featureLevel)
   1326 {
   1327    switch (featureLevel)
   1328    {
   1329        case D3D_FEATURE_LEVEL_11_1:
   1330        case D3D_FEATURE_LEVEL_11_0:
   1331            return D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
   1332        case D3D_FEATURE_LEVEL_10_1:
   1333        case D3D_FEATURE_LEVEL_10_0:
   1334        case D3D_FEATURE_LEVEL_9_3:
   1335        case D3D_FEATURE_LEVEL_9_2:
   1336        case D3D_FEATURE_LEVEL_9_1:
   1337            return 1;
   1338        default:
   1339            UNREACHABLE();
   1340            return 0;
   1341    }
   1342 }
   1343 
   1344 bool IsMultiviewSupported(D3D_FEATURE_LEVEL featureLevel)
   1345 {
   1346    // The ANGLE_multiview extension can always be supported in D3D11 through geometry shaders.
   1347    switch (featureLevel)
   1348    {
   1349        case D3D_FEATURE_LEVEL_11_1:
   1350        case D3D_FEATURE_LEVEL_11_0:
   1351            return true;
   1352        default:
   1353            return false;
   1354    }
   1355 }
   1356 
   1357 int GetMaxSampleMaskWords(D3D_FEATURE_LEVEL featureLevel)
   1358 {
   1359    switch (featureLevel)
   1360    {
   1361        // D3D10+ only allows 1 sample mask.
   1362        case D3D_FEATURE_LEVEL_11_1:
   1363        case D3D_FEATURE_LEVEL_11_0:
   1364        case D3D_FEATURE_LEVEL_10_1:
   1365        case D3D_FEATURE_LEVEL_10_0:
   1366            return 1;
   1367        case D3D_FEATURE_LEVEL_9_3:
   1368        case D3D_FEATURE_LEVEL_9_2:
   1369        case D3D_FEATURE_LEVEL_9_1:
   1370            return 0;
   1371        default:
   1372            UNREACHABLE();
   1373            return 0;
   1374    }
   1375 }
   1376 
   1377 bool HasTextureBufferSupport(ID3D11Device *device, const Renderer11DeviceCaps &renderer11DeviceCaps)
   1378 {
   1379    if (renderer11DeviceCaps.featureLevel < D3D_FEATURE_LEVEL_11_0)
   1380        return false;
   1381 
   1382    if (!renderer11DeviceCaps.supportsTypedUAVLoadAdditionalFormats)
   1383        return false;
   1384 
   1385    // https://docs.microsoft.com/en-us/windows/win32/direct3d12/typed-unordered-access-view-loads
   1386    // we don't need to check the typed store. from the spec,
   1387    // https://microsoft.github.io/DirectX-Specs/d3d/archive/D3D11_3_FunctionalSpec.htm#FormatList
   1388    // all the following format support typed stored.
   1389    // According to spec,
   1390    // https://www.khronos.org/registry/OpenGL-Refpages/es3/html/glBindImageTexture.xhtml the
   1391    // required image unit format are GL_RGBA32F, GL_RGBA32UI, GL_RGBA32I, GL_RGBA16F, GL_RGBA16UI,
   1392    // GL_RGBA16I, GL_RGBA8, GL_RGBAUI, GL_RGBA8I, GL_RGBA8_SNORM, GL_R32F, GL_R32UI, GL_R32I,
   1393    const std::array<DXGI_FORMAT, 2> &optionalFormats = {
   1394        DXGI_FORMAT_R32G32B32A32_FLOAT,  // test for GL_RGBA32(UIF), GL_RGBA16(UIF),
   1395                                         // GL_RGBA8(UIUnorm)
   1396        DXGI_FORMAT_R8G8B8A8_SNORM,      // test for GL_RGBA8_SNORM,
   1397    };
   1398 
   1399    for (DXGI_FORMAT dxgiFormat : optionalFormats)
   1400    {
   1401        D3D11_FEATURE_DATA_FORMAT_SUPPORT FormatSupport = {dxgiFormat, 0};
   1402        if (!SUCCEEDED(device->CheckFeatureSupport(D3D11_FEATURE_FORMAT_SUPPORT, &FormatSupport,
   1403                                                   sizeof(FormatSupport))))
   1404        {
   1405            WARN() << "Error checking typed load support for format 0x" << std::hex << dxgiFormat;
   1406            return false;
   1407        }
   1408        if ((FormatSupport.OutFormatSupport & D3D11_FORMAT_SUPPORT2_UAV_TYPED_LOAD) == 0)
   1409            return false;
   1410    }
   1411    return true;
   1412 }
   1413 
   1414 void GenerateCaps(ID3D11Device *device,
   1415                  ID3D11DeviceContext *deviceContext,
   1416                  const Renderer11DeviceCaps &renderer11DeviceCaps,
   1417                  const angle::FeaturesD3D &features,
   1418                  const char *description,
   1419                  gl::Caps *caps,
   1420                  gl::TextureCapsMap *textureCapsMap,
   1421                  gl::Extensions *extensions,
   1422                  gl::Limitations *limitations)
   1423 {
   1424    D3D_FEATURE_LEVEL featureLevel  = renderer11DeviceCaps.featureLevel;
   1425    const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats();
   1426    for (GLenum internalFormat : allFormats)
   1427    {
   1428        gl::TextureCaps textureCaps =
   1429            GenerateTextureFormatCaps(GetMaximumClientVersion(renderer11DeviceCaps), internalFormat,
   1430                                      device, renderer11DeviceCaps);
   1431        textureCapsMap->insert(internalFormat, textureCaps);
   1432    }
   1433 
   1434    // GL core feature limits
   1435    // Reserve MAX_UINT for D3D11's primitive restart.
   1436    caps->maxElementIndex  = static_cast<GLint64>(std::numeric_limits<unsigned int>::max() - 1);
   1437    caps->max3DTextureSize = GetMaximum3DTextureSize(featureLevel);
   1438    caps->max2DTextureSize = GetMaximum2DTextureSize(featureLevel);
   1439    caps->maxCubeMapTextureSize = GetMaximumCubeMapTextureSize(featureLevel);
   1440    caps->maxArrayTextureLayers = GetMaximum2DTextureArraySize(featureLevel);
   1441 
   1442    // Unimplemented, set to minimum required
   1443    caps->maxLODBias = 2.0f;
   1444 
   1445    // No specific limits on render target size, maximum 2D texture size is equivalent
   1446    caps->maxRenderbufferSize = caps->max2DTextureSize;
   1447 
   1448    // Maximum draw buffers and color attachments are the same, max color attachments could
   1449    // eventually be increased to 16
   1450    caps->maxDrawBuffers      = GetMaximumSimultaneousRenderTargets(featureLevel);
   1451    caps->maxColorAttachments = GetMaximumSimultaneousRenderTargets(featureLevel);
   1452 
   1453    // D3D11 has the same limit for viewport width and height
   1454    caps->maxViewportWidth  = GetMaximumViewportSize(featureLevel);
   1455    caps->maxViewportHeight = caps->maxViewportWidth;
   1456 
   1457    // Choose a reasonable maximum, enforced in the shader.
   1458    caps->minAliasedPointSize = 1.0f;
   1459    caps->maxAliasedPointSize = 1024.0f;
   1460 
   1461    // Wide lines not supported
   1462    caps->minAliasedLineWidth = 1.0f;
   1463    caps->maxAliasedLineWidth = 1.0f;
   1464 
   1465    // Primitive count limits
   1466    caps->maxElementsIndices  = GetMaximumDrawIndexedIndexCount(featureLevel);
   1467    caps->maxElementsVertices = GetMaximumDrawVertexCount(featureLevel);
   1468 
   1469    // Program and shader binary formats (no supported shader binary formats)
   1470    caps->programBinaryFormats.push_back(GL_PROGRAM_BINARY_ANGLE);
   1471 
   1472    caps->vertexHighpFloat.setIEEEFloat();
   1473    caps->vertexMediumpFloat.setIEEEFloat();
   1474    caps->vertexLowpFloat.setIEEEFloat();
   1475    caps->fragmentHighpFloat.setIEEEFloat();
   1476    caps->fragmentMediumpFloat.setIEEEFloat();
   1477    caps->fragmentLowpFloat.setIEEEFloat();
   1478 
   1479    // 32-bit integers are natively supported
   1480    caps->vertexHighpInt.setTwosComplementInt(32);
   1481    caps->vertexMediumpInt.setTwosComplementInt(32);
   1482    caps->vertexLowpInt.setTwosComplementInt(32);
   1483    caps->fragmentHighpInt.setTwosComplementInt(32);
   1484    caps->fragmentMediumpInt.setTwosComplementInt(32);
   1485    caps->fragmentLowpInt.setTwosComplementInt(32);
   1486 
   1487    // We do not wait for server fence objects internally, so report a max timeout of zero.
   1488    caps->maxServerWaitTimeout = 0;
   1489 
   1490    // Vertex shader limits
   1491    caps->maxVertexAttributes     = GetMaximumVertexInputSlots(featureLevel);
   1492    caps->maxVertexUniformVectors = GetMaximumVertexUniformVectors(featureLevel);
   1493    if (features.skipVSConstantRegisterZero.enabled)
   1494    {
   1495        caps->maxVertexUniformVectors -= 1;
   1496    }
   1497    caps->maxShaderUniformComponents[gl::ShaderType::Vertex] = caps->maxVertexUniformVectors * 4;
   1498    caps->maxShaderUniformBlocks[gl::ShaderType::Vertex] =
   1499        GetMaximumVertexUniformBlocks(featureLevel);
   1500    caps->maxVertexOutputComponents = GetMaximumVertexOutputVectors(featureLevel) * 4;
   1501    caps->maxShaderTextureImageUnits[gl::ShaderType::Vertex] =
   1502        GetMaximumVertexTextureUnits(featureLevel);
   1503 
   1504    // Vertex Attribute Bindings are emulated on D3D11.
   1505    caps->maxVertexAttribBindings = caps->maxVertexAttributes;
   1506    // Experimental testing confirmed there is no explicit limit on maximum buffer offset in D3D11.
   1507    caps->maxVertexAttribRelativeOffset = std::numeric_limits<GLint>::max();
   1508    // Experimental testing confirmed 2048 is the maximum stride that D3D11 can support on all
   1509    // platforms.
   1510    caps->maxVertexAttribStride = 2048;
   1511 
   1512    // Fragment shader limits
   1513    caps->maxFragmentUniformVectors = GetMaximumPixelUniformVectors(featureLevel);
   1514    caps->maxShaderUniformComponents[gl::ShaderType::Fragment] =
   1515        caps->maxFragmentUniformVectors * 4;
   1516    caps->maxShaderUniformBlocks[gl::ShaderType::Fragment] =
   1517        GetMaximumPixelUniformBlocks(featureLevel);
   1518    caps->maxFragmentInputComponents = GetMaximumPixelInputVectors(featureLevel) * 4;
   1519    caps->maxShaderTextureImageUnits[gl::ShaderType::Fragment] =
   1520        GetMaximumPixelTextureUnits(featureLevel);
   1521    caps->minProgramTexelOffset = GetMinimumTexelOffset(featureLevel);
   1522    caps->maxProgramTexelOffset = GetMaximumTexelOffset(featureLevel);
   1523 
   1524    // Compute shader limits
   1525    caps->maxComputeWorkGroupCount       = GetMaxComputeWorkGroupCount(featureLevel);
   1526    caps->maxComputeWorkGroupSize        = GetMaxComputeWorkGroupSize(featureLevel);
   1527    caps->maxComputeWorkGroupInvocations = GetMaxComputeWorkGroupInvocations(featureLevel);
   1528    caps->maxComputeSharedMemorySize     = GetMaxComputeSharedMemorySize(featureLevel);
   1529    caps->maxShaderUniformComponents[gl::ShaderType::Compute] =
   1530        GetMaximumComputeUniformVectors(featureLevel) * 4;
   1531    caps->maxShaderUniformBlocks[gl::ShaderType::Compute] =
   1532        GetMaximumComputeUniformBlocks(featureLevel);
   1533    caps->maxShaderTextureImageUnits[gl::ShaderType::Compute] =
   1534        GetMaximumComputeTextureUnits(featureLevel);
   1535 
   1536    SetUAVRelatedResourceLimits(featureLevel, caps);
   1537 
   1538    // Aggregate shader limits
   1539    caps->maxUniformBufferBindings = caps->maxShaderUniformBlocks[gl::ShaderType::Vertex] +
   1540                                     caps->maxShaderUniformBlocks[gl::ShaderType::Fragment];
   1541    caps->maxUniformBlockSize = static_cast<GLuint64>(GetMaximumConstantBufferSize(featureLevel));
   1542 
   1543    // TODO(oetuaho): Get a more accurate limit. For now using the minimum requirement for GLES 3.1.
   1544    caps->maxUniformLocations = 1024;
   1545 
   1546    // With DirectX 11.1, constant buffer offset and size must be a multiple of 16 constants of 16
   1547    // bytes each.
   1548    // https://msdn.microsoft.com/en-us/library/windows/desktop/hh404649%28v=vs.85%29.aspx
   1549    // With DirectX 11.0, we emulate UBO offsets using copies of ranges of the UBO however
   1550    // we still keep the same alignment as 11.1 for consistency.
   1551    caps->uniformBufferOffsetAlignment = 256;
   1552 
   1553    caps->maxCombinedUniformBlocks = caps->maxShaderUniformBlocks[gl::ShaderType::Vertex] +
   1554                                     caps->maxShaderUniformBlocks[gl::ShaderType::Fragment];
   1555 
   1556    // A shader storage block will be translated to a structure in HLSL. So We reference the HLSL
   1557    // structure packing rules
   1558    // https://msdn.microsoft.com/en-us/library/windows/desktop/bb509632(v=vs.85).aspx. The
   1559    // resulting size of any structure will always be evenly divisible by sizeof(four-component
   1560    // vector).
   1561    caps->shaderStorageBufferOffsetAlignment = 16;
   1562 
   1563    for (gl::ShaderType shaderType : gl::AllShaderTypes())
   1564    {
   1565        caps->maxCombinedShaderUniformComponents[shaderType] =
   1566            static_cast<GLint64>(caps->maxShaderUniformBlocks[shaderType]) *
   1567                static_cast<GLint64>(caps->maxUniformBlockSize / 4) +
   1568            static_cast<GLint64>(caps->maxShaderUniformComponents[shaderType]);
   1569    }
   1570 
   1571    caps->maxVaryingComponents         = GetMaximumVertexOutputVectors(featureLevel) * 4;
   1572    caps->maxVaryingVectors            = GetMaximumVertexOutputVectors(featureLevel);
   1573    caps->maxCombinedTextureImageUnits = caps->maxShaderTextureImageUnits[gl::ShaderType::Vertex] +
   1574                                         caps->maxShaderTextureImageUnits[gl::ShaderType::Fragment];
   1575 
   1576    // Transform feedback limits
   1577    caps->maxTransformFeedbackInterleavedComponents =
   1578        GetMaximumStreamOutputInterleavedComponents(featureLevel);
   1579    caps->maxTransformFeedbackSeparateAttributes = GetMaximumStreamOutputBuffers(featureLevel);
   1580    caps->maxTransformFeedbackSeparateComponents =
   1581        GetMaximumStreamOutputSeparateComponents(featureLevel);
   1582 
   1583    // Defer the computation of multisample limits to Context::updateCaps() where max*Samples values
   1584    // are determined according to available sample counts for each individual format.
   1585    caps->maxSamples             = std::numeric_limits<GLint>::max();
   1586    caps->maxColorTextureSamples = std::numeric_limits<GLint>::max();
   1587    caps->maxDepthTextureSamples = std::numeric_limits<GLint>::max();
   1588    caps->maxIntegerSamples      = std::numeric_limits<GLint>::max();
   1589 
   1590    // Sample mask words limits
   1591    caps->maxSampleMaskWords = GetMaxSampleMaskWords(featureLevel);
   1592 
   1593    // Framebuffer limits
   1594    caps->maxFramebufferSamples = std::numeric_limits<GLint>::max();
   1595    caps->maxFramebufferWidth   = GetMaximumRenderToBufferWindowSize(featureLevel);
   1596    caps->maxFramebufferHeight  = caps->maxFramebufferWidth;
   1597 
   1598    // Texture gather offset limits
   1599    caps->minProgramTextureGatherOffset = GetMinimumTextureGatherOffset(featureLevel);
   1600    caps->maxProgramTextureGatherOffset = GetMaximumTextureGatherOffset(featureLevel);
   1601 
   1602    caps->maxTextureAnisotropy        = GetMaximumAnisotropy(featureLevel);
   1603    caps->queryCounterBitsTimeElapsed = 64;
   1604    caps->queryCounterBitsTimestamp = 0;  // Timestamps cannot be supported due to D3D11 limitations
   1605    caps->maxDualSourceDrawBuffers  = 1;
   1606 
   1607    // GL extension support
   1608    extensions->setTextureExtensionSupport(*textureCapsMap);
   1609 
   1610    // Explicitly disable GL_OES_compressed_ETC1_RGB8_texture because it's emulated and never
   1611    // becomes core. WebGL doesn't want to expose it unless there is native support.
   1612    extensions->compressedETC1RGB8TextureOES    = false;
   1613    extensions->compressedETC1RGB8SubTextureEXT = false;
   1614 
   1615    extensions->elementIndexUintOES = true;
   1616    extensions->getProgramBinaryOES = true;
   1617    extensions->rgb8Rgba8OES        = true;
   1618    extensions->readFormatBgraEXT   = true;
   1619    extensions->pixelBufferObjectNV = true;
   1620    extensions->mapbufferOES        = true;
   1621    extensions->mapBufferRangeEXT   = true;
   1622    extensions->textureNpotOES      = GetNPOTTextureSupport(featureLevel);
   1623    extensions->drawBuffersEXT      = GetMaximumSimultaneousRenderTargets(featureLevel) > 1;
   1624    extensions->drawBuffersIndexedEXT =
   1625        (renderer11DeviceCaps.featureLevel >= D3D_FEATURE_LEVEL_10_1);
   1626    extensions->drawBuffersIndexedOES       = extensions->drawBuffersIndexedEXT;
   1627    extensions->textureStorageEXT           = true;
   1628    extensions->textureFilterAnisotropicEXT = true;
   1629    extensions->occlusionQueryBooleanEXT    = GetOcclusionQuerySupport(featureLevel);
   1630    extensions->fenceNV                     = GetEventQuerySupport(featureLevel);
   1631    extensions->disjointTimerQueryEXT       = true;
   1632    extensions->robustnessEXT               = true;
   1633    // Direct3D guarantees to return zero for any resource that is accessed out of bounds.
   1634    // See https://msdn.microsoft.com/en-us/library/windows/desktop/ff476332(v=vs.85).aspx
   1635    // and https://msdn.microsoft.com/en-us/library/windows/desktop/ff476900(v=vs.85).aspx
   1636    extensions->robustBufferAccessBehaviorKHR = true;
   1637    extensions->blendMinmaxEXT                = true;
   1638    // https://docs.microsoft.com/en-us/windows/desktop/direct3ddxgi/format-support-for-direct3d-11-0-feature-level-hardware
   1639    extensions->floatBlendEXT               = true;
   1640    extensions->framebufferBlitANGLE        = GetFramebufferBlitSupport(featureLevel);
   1641    extensions->framebufferBlitNV           = extensions->framebufferBlitANGLE;
   1642    extensions->framebufferMultisampleANGLE = GetFramebufferMultisampleSupport(featureLevel);
   1643    extensions->instancedArraysANGLE        = GetInstancingSupport(featureLevel);
   1644    extensions->instancedArraysEXT          = GetInstancingSupport(featureLevel);
   1645    extensions->packReverseRowOrderANGLE    = true;
   1646    extensions->standardDerivativesOES      = GetDerivativeInstructionSupport(featureLevel);
   1647    extensions->shaderTextureLodEXT         = GetShaderTextureLODSupport(featureLevel);
   1648    extensions->fragDepthEXT                = true;
   1649    extensions->multiviewOVR                = IsMultiviewSupported(featureLevel);
   1650    extensions->multiview2OVR               = IsMultiviewSupported(featureLevel);
   1651    if (extensions->multiviewOVR || extensions->multiview2OVR)
   1652    {
   1653        caps->maxViews = std::min(static_cast<GLuint>(GetMaximum2DTextureArraySize(featureLevel)),
   1654                                  GetMaxViewportAndScissorRectanglesPerPipeline(featureLevel));
   1655    }
   1656    extensions->textureUsageANGLE = true;  // This could be false since it has no effect in D3D11
   1657    extensions->discardFramebufferEXT               = true;
   1658    extensions->translatedShaderSourceANGLE         = true;
   1659    extensions->fboRenderMipmapOES                  = true;
   1660    extensions->debugMarkerEXT                      = true;
   1661    extensions->EGLImageOES                         = true;
   1662    extensions->EGLImageExternalOES                 = true;
   1663    extensions->EGLImageExternalWrapModesEXT        = true;
   1664    extensions->EGLImageExternalEssl3OES            = true;
   1665    extensions->EGLStreamConsumerExternalNV         = true;
   1666    extensions->unpackSubimageEXT                   = true;
   1667    extensions->packSubimageNV                      = true;
   1668    extensions->lossyEtcDecodeANGLE                 = true;
   1669    extensions->syncQueryCHROMIUM                   = GetEventQuerySupport(featureLevel);
   1670    extensions->copyTextureCHROMIUM                 = true;
   1671    extensions->copyCompressedTextureCHROMIUM       = true;
   1672    extensions->textureStorageMultisample2dArrayOES = true;
   1673    extensions->multiviewMultisampleANGLE =
   1674        ((extensions->multiviewOVR || extensions->multiview2OVR) &&
   1675         extensions->textureStorageMultisample2dArrayOES);
   1676    extensions->copyTexture3dANGLE      = true;
   1677    extensions->textureBorderClampOES   = true;
   1678    extensions->multiDrawIndirectEXT    = true;
   1679    extensions->textureMultisampleANGLE = true;
   1680    extensions->provokingVertexANGLE    = true;
   1681    extensions->blendFuncExtendedEXT    = true;
   1682    // http://anglebug.com/4926
   1683    extensions->texture3DOES                             = false;
   1684    extensions->baseInstanceEXT                          = true;
   1685    extensions->baseVertexBaseInstanceANGLE              = true;
   1686    extensions->baseVertexBaseInstanceShaderBuiltinANGLE = true;
   1687    extensions->drawElementsBaseVertexOES                = true;
   1688    extensions->drawElementsBaseVertexEXT                = true;
   1689    if (!strstr(description, "Adreno"))
   1690    {
   1691        extensions->multisampledRenderToTextureEXT = true;
   1692    }
   1693    extensions->videoTextureWEBGL = true;
   1694 
   1695    // D3D11 cannot support reading depth texture as a luminance texture.
   1696    // It treats it as a red-channel-only texture.
   1697    extensions->depthTextureOES = false;
   1698 
   1699    // readPixels on depth & stencil not working with D3D11 backend.
   1700    extensions->readDepthNV         = false;
   1701    extensions->readStencilNV       = false;
   1702    extensions->depthBufferFloat2NV = false;
   1703 
   1704    // GL_EXT_clip_control
   1705    extensions->clipControlEXT = (renderer11DeviceCaps.featureLevel >= D3D_FEATURE_LEVEL_9_3);
   1706 
   1707    // GL_KHR_parallel_shader_compile
   1708    extensions->parallelShaderCompileKHR = true;
   1709 
   1710    // GL_EXT_texture_buffer
   1711    extensions->textureBufferEXT = HasTextureBufferSupport(device, renderer11DeviceCaps);
   1712 
   1713    // GL_OES_texture_buffer
   1714    extensions->textureBufferOES = extensions->textureBufferEXT;
   1715 
   1716    // ANGLE_shader_pixel_local_storage -- fragment shader UAVs appear in D3D 11.0.
   1717    extensions->shaderPixelLocalStorageANGLE = (featureLevel >= D3D_FEATURE_LEVEL_11_0);
   1718    extensions->shaderPixelLocalStorageCoherentANGLE =
   1719        renderer11DeviceCaps.supportsRasterizerOrderViews;
   1720 
   1721    // D3D11 Feature Level 10_0+ uses SV_IsFrontFace in HLSL to emulate gl_FrontFacing.
   1722    // D3D11 Feature Level 9_3 doesn't support SV_IsFrontFace, and has no equivalent, so can't
   1723    // support gl_FrontFacing.
   1724    limitations->noFrontFacingSupport =
   1725        (renderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3);
   1726 
   1727    // D3D11 Feature Level 9_3 doesn't support alpha-to-coverage
   1728    limitations->noSampleAlphaToCoverageSupport =
   1729        (renderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3);
   1730 
   1731    // D3D11 Feature Levels 9_3 and below do not support non-constant loop indexing and require
   1732    // additional
   1733    // pre-validation of the shader at compile time to produce a better error message.
   1734    limitations->shadersRequireIndexedLoopValidation =
   1735        (renderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3);
   1736 
   1737    // D3D11 has no concept of separate masks and refs for front and back faces in the depth stencil
   1738    // state.
   1739    limitations->noSeparateStencilRefsAndMasks = true;
   1740 
   1741    // D3D11 cannot support constant color and alpha blend funcs together
   1742    limitations->noSimultaneousConstantColorAndAlphaBlendFunc = true;
   1743 
   1744    // D3D11 does not support multiple transform feedback outputs writing to the same buffer.
   1745    limitations->noDoubleBoundTransformFeedbackBuffers = true;
   1746 
   1747    // D3D11 does not support vertex attribute aliasing
   1748    limitations->noVertexAttributeAliasing = true;
   1749 
   1750    // D3D11 does not support compressed textures where the base mip level is not a multiple of 4
   1751    limitations->compressedBaseMipLevelMultipleOfFour = true;
   1752 
   1753    if (extensions->textureBufferAny())
   1754    {
   1755        caps->maxTextureBufferSize = 1 << D3D11_REQ_BUFFER_RESOURCE_TEXEL_COUNT_2_TO_EXP;
   1756        // this maybe touble for RGB32 format.
   1757        caps->textureBufferOffsetAlignment = 16;
   1758    }
   1759 
   1760 #ifdef ANGLE_ENABLE_WINDOWS_UWP
   1761    // Setting a non-zero divisor on attribute zero doesn't work on certain Windows Phone 8-era
   1762    // devices. We should prevent developers from doing this on ALL Windows Store devices. This will
   1763    // maintain consistency across all Windows devices. We allow non-zero divisors on attribute zero
   1764    // if the Client Version >= 3, since devices affected by this issue don't support ES3+.
   1765    limitations->attributeZeroRequiresZeroDivisorInEXT = true;
   1766 #endif
   1767 }
   1768 
   1769 }  // namespace d3d11_gl
   1770 
   1771 namespace gl_d3d11
   1772 {
   1773 
   1774 D3D11_BLEND ConvertBlendFunc(GLenum glBlend, bool isAlpha)
   1775 {
   1776    D3D11_BLEND d3dBlend = D3D11_BLEND_ZERO;
   1777 
   1778    switch (glBlend)
   1779    {
   1780        case GL_ZERO:
   1781            d3dBlend = D3D11_BLEND_ZERO;
   1782            break;
   1783        case GL_ONE:
   1784            d3dBlend = D3D11_BLEND_ONE;
   1785            break;
   1786        case GL_SRC_COLOR:
   1787            d3dBlend = (isAlpha ? D3D11_BLEND_SRC_ALPHA : D3D11_BLEND_SRC_COLOR);
   1788            break;
   1789        case GL_ONE_MINUS_SRC_COLOR:
   1790            d3dBlend = (isAlpha ? D3D11_BLEND_INV_SRC_ALPHA : D3D11_BLEND_INV_SRC_COLOR);
   1791            break;
   1792        case GL_DST_COLOR:
   1793            d3dBlend = (isAlpha ? D3D11_BLEND_DEST_ALPHA : D3D11_BLEND_DEST_COLOR);
   1794            break;
   1795        case GL_ONE_MINUS_DST_COLOR:
   1796            d3dBlend = (isAlpha ? D3D11_BLEND_INV_DEST_ALPHA : D3D11_BLEND_INV_DEST_COLOR);
   1797            break;
   1798        case GL_SRC_ALPHA:
   1799            d3dBlend = D3D11_BLEND_SRC_ALPHA;
   1800            break;
   1801        case GL_ONE_MINUS_SRC_ALPHA:
   1802            d3dBlend = D3D11_BLEND_INV_SRC_ALPHA;
   1803            break;
   1804        case GL_DST_ALPHA:
   1805            d3dBlend = D3D11_BLEND_DEST_ALPHA;
   1806            break;
   1807        case GL_ONE_MINUS_DST_ALPHA:
   1808            d3dBlend = D3D11_BLEND_INV_DEST_ALPHA;
   1809            break;
   1810        case GL_CONSTANT_COLOR:
   1811            d3dBlend = D3D11_BLEND_BLEND_FACTOR;
   1812            break;
   1813        case GL_ONE_MINUS_CONSTANT_COLOR:
   1814            d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR;
   1815            break;
   1816        case GL_CONSTANT_ALPHA:
   1817            d3dBlend = D3D11_BLEND_BLEND_FACTOR;
   1818            break;
   1819        case GL_ONE_MINUS_CONSTANT_ALPHA:
   1820            d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR;
   1821            break;
   1822        case GL_SRC_ALPHA_SATURATE:
   1823            d3dBlend = D3D11_BLEND_SRC_ALPHA_SAT;
   1824            break;
   1825        case GL_SRC1_COLOR_EXT:
   1826            d3dBlend = (isAlpha ? D3D11_BLEND_SRC1_ALPHA : D3D11_BLEND_SRC1_COLOR);
   1827            break;
   1828        case GL_SRC1_ALPHA_EXT:
   1829            d3dBlend = D3D11_BLEND_SRC1_ALPHA;
   1830            break;
   1831        case GL_ONE_MINUS_SRC1_COLOR_EXT:
   1832            d3dBlend = (isAlpha ? D3D11_BLEND_INV_SRC1_ALPHA : D3D11_BLEND_INV_SRC1_COLOR);
   1833            break;
   1834        case GL_ONE_MINUS_SRC1_ALPHA_EXT:
   1835            d3dBlend = D3D11_BLEND_INV_SRC1_ALPHA;
   1836            break;
   1837        default:
   1838            UNREACHABLE();
   1839    }
   1840 
   1841    return d3dBlend;
   1842 }
   1843 
   1844 D3D11_BLEND_OP ConvertBlendOp(GLenum glBlendOp)
   1845 {
   1846    D3D11_BLEND_OP d3dBlendOp = D3D11_BLEND_OP_ADD;
   1847 
   1848    switch (glBlendOp)
   1849    {
   1850        case GL_FUNC_ADD:
   1851            d3dBlendOp = D3D11_BLEND_OP_ADD;
   1852            break;
   1853        case GL_FUNC_SUBTRACT:
   1854            d3dBlendOp = D3D11_BLEND_OP_SUBTRACT;
   1855            break;
   1856        case GL_FUNC_REVERSE_SUBTRACT:
   1857            d3dBlendOp = D3D11_BLEND_OP_REV_SUBTRACT;
   1858            break;
   1859        case GL_MIN:
   1860            d3dBlendOp = D3D11_BLEND_OP_MIN;
   1861            break;
   1862        case GL_MAX:
   1863            d3dBlendOp = D3D11_BLEND_OP_MAX;
   1864            break;
   1865        default:
   1866            UNREACHABLE();
   1867    }
   1868 
   1869    return d3dBlendOp;
   1870 }
   1871 
   1872 UINT8 ConvertColorMask(bool red, bool green, bool blue, bool alpha)
   1873 {
   1874    UINT8 mask = 0;
   1875    if (red)
   1876    {
   1877        mask |= D3D11_COLOR_WRITE_ENABLE_RED;
   1878    }
   1879    if (green)
   1880    {
   1881        mask |= D3D11_COLOR_WRITE_ENABLE_GREEN;
   1882    }
   1883    if (blue)
   1884    {
   1885        mask |= D3D11_COLOR_WRITE_ENABLE_BLUE;
   1886    }
   1887    if (alpha)
   1888    {
   1889        mask |= D3D11_COLOR_WRITE_ENABLE_ALPHA;
   1890    }
   1891    return mask;
   1892 }
   1893 
   1894 D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, gl::CullFaceMode cullMode)
   1895 {
   1896    D3D11_CULL_MODE cull = D3D11_CULL_NONE;
   1897 
   1898    if (cullEnabled)
   1899    {
   1900        switch (cullMode)
   1901        {
   1902            case gl::CullFaceMode::Front:
   1903                cull = D3D11_CULL_FRONT;
   1904                break;
   1905            case gl::CullFaceMode::Back:
   1906                cull = D3D11_CULL_BACK;
   1907                break;
   1908            case gl::CullFaceMode::FrontAndBack:
   1909                cull = D3D11_CULL_NONE;
   1910                break;
   1911            default:
   1912                UNREACHABLE();
   1913        }
   1914    }
   1915    else
   1916    {
   1917        cull = D3D11_CULL_NONE;
   1918    }
   1919 
   1920    return cull;
   1921 }
   1922 
   1923 D3D11_COMPARISON_FUNC ConvertComparison(GLenum comparison)
   1924 {
   1925    D3D11_COMPARISON_FUNC d3dComp = D3D11_COMPARISON_NEVER;
   1926    switch (comparison)
   1927    {
   1928        case GL_NEVER:
   1929            d3dComp = D3D11_COMPARISON_NEVER;
   1930            break;
   1931        case GL_ALWAYS:
   1932            d3dComp = D3D11_COMPARISON_ALWAYS;
   1933            break;
   1934        case GL_LESS:
   1935            d3dComp = D3D11_COMPARISON_LESS;
   1936            break;
   1937        case GL_LEQUAL:
   1938            d3dComp = D3D11_COMPARISON_LESS_EQUAL;
   1939            break;
   1940        case GL_EQUAL:
   1941            d3dComp = D3D11_COMPARISON_EQUAL;
   1942            break;
   1943        case GL_GREATER:
   1944            d3dComp = D3D11_COMPARISON_GREATER;
   1945            break;
   1946        case GL_GEQUAL:
   1947            d3dComp = D3D11_COMPARISON_GREATER_EQUAL;
   1948            break;
   1949        case GL_NOTEQUAL:
   1950            d3dComp = D3D11_COMPARISON_NOT_EQUAL;
   1951            break;
   1952        default:
   1953            UNREACHABLE();
   1954    }
   1955 
   1956    return d3dComp;
   1957 }
   1958 
   1959 D3D11_DEPTH_WRITE_MASK ConvertDepthMask(bool depthWriteEnabled)
   1960 {
   1961    return depthWriteEnabled ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
   1962 }
   1963 
   1964 UINT8 ConvertStencilMask(GLuint stencilmask)
   1965 {
   1966    return static_cast<UINT8>(stencilmask);
   1967 }
   1968 
   1969 D3D11_STENCIL_OP ConvertStencilOp(GLenum stencilOp)
   1970 {
   1971    D3D11_STENCIL_OP d3dStencilOp = D3D11_STENCIL_OP_KEEP;
   1972 
   1973    switch (stencilOp)
   1974    {
   1975        case GL_ZERO:
   1976            d3dStencilOp = D3D11_STENCIL_OP_ZERO;
   1977            break;
   1978        case GL_KEEP:
   1979            d3dStencilOp = D3D11_STENCIL_OP_KEEP;
   1980            break;
   1981        case GL_REPLACE:
   1982            d3dStencilOp = D3D11_STENCIL_OP_REPLACE;
   1983            break;
   1984        case GL_INCR:
   1985            d3dStencilOp = D3D11_STENCIL_OP_INCR_SAT;
   1986            break;
   1987        case GL_DECR:
   1988            d3dStencilOp = D3D11_STENCIL_OP_DECR_SAT;
   1989            break;
   1990        case GL_INVERT:
   1991            d3dStencilOp = D3D11_STENCIL_OP_INVERT;
   1992            break;
   1993        case GL_INCR_WRAP:
   1994            d3dStencilOp = D3D11_STENCIL_OP_INCR;
   1995            break;
   1996        case GL_DECR_WRAP:
   1997            d3dStencilOp = D3D11_STENCIL_OP_DECR;
   1998            break;
   1999        default:
   2000            UNREACHABLE();
   2001    }
   2002 
   2003    return d3dStencilOp;
   2004 }
   2005 
   2006 D3D11_FILTER ConvertFilter(GLenum minFilter,
   2007                           GLenum magFilter,
   2008                           float maxAnisotropy,
   2009                           GLenum comparisonMode)
   2010 {
   2011    bool comparison = comparisonMode != GL_NONE;
   2012 
   2013    if (maxAnisotropy > 1.0f)
   2014    {
   2015        return D3D11_ENCODE_ANISOTROPIC_FILTER(static_cast<D3D11_COMPARISON_FUNC>(comparison));
   2016    }
   2017    else
   2018    {
   2019        D3D11_FILTER_TYPE dxMin = D3D11_FILTER_TYPE_POINT;
   2020        D3D11_FILTER_TYPE dxMip = D3D11_FILTER_TYPE_POINT;
   2021        switch (minFilter)
   2022        {
   2023            case GL_NEAREST:
   2024                dxMin = D3D11_FILTER_TYPE_POINT;
   2025                dxMip = D3D11_FILTER_TYPE_POINT;
   2026                break;
   2027            case GL_LINEAR:
   2028                dxMin = D3D11_FILTER_TYPE_LINEAR;
   2029                dxMip = D3D11_FILTER_TYPE_POINT;
   2030                break;
   2031            case GL_NEAREST_MIPMAP_NEAREST:
   2032                dxMin = D3D11_FILTER_TYPE_POINT;
   2033                dxMip = D3D11_FILTER_TYPE_POINT;
   2034                break;
   2035            case GL_LINEAR_MIPMAP_NEAREST:
   2036                dxMin = D3D11_FILTER_TYPE_LINEAR;
   2037                dxMip = D3D11_FILTER_TYPE_POINT;
   2038                break;
   2039            case GL_NEAREST_MIPMAP_LINEAR:
   2040                dxMin = D3D11_FILTER_TYPE_POINT;
   2041                dxMip = D3D11_FILTER_TYPE_LINEAR;
   2042                break;
   2043            case GL_LINEAR_MIPMAP_LINEAR:
   2044                dxMin = D3D11_FILTER_TYPE_LINEAR;
   2045                dxMip = D3D11_FILTER_TYPE_LINEAR;
   2046                break;
   2047            default:
   2048                UNREACHABLE();
   2049        }
   2050 
   2051        D3D11_FILTER_TYPE dxMag = D3D11_FILTER_TYPE_POINT;
   2052        switch (magFilter)
   2053        {
   2054            case GL_NEAREST:
   2055                dxMag = D3D11_FILTER_TYPE_POINT;
   2056                break;
   2057            case GL_LINEAR:
   2058                dxMag = D3D11_FILTER_TYPE_LINEAR;
   2059                break;
   2060            default:
   2061                UNREACHABLE();
   2062        }
   2063 
   2064        return D3D11_ENCODE_BASIC_FILTER(dxMin, dxMag, dxMip,
   2065                                         static_cast<D3D11_COMPARISON_FUNC>(comparison));
   2066    }
   2067 }
   2068 
   2069 D3D11_TEXTURE_ADDRESS_MODE ConvertTextureWrap(GLenum wrap)
   2070 {
   2071    switch (wrap)
   2072    {
   2073        case GL_REPEAT:
   2074            return D3D11_TEXTURE_ADDRESS_WRAP;
   2075        case GL_CLAMP_TO_EDGE:
   2076            return D3D11_TEXTURE_ADDRESS_CLAMP;
   2077        case GL_CLAMP_TO_BORDER:
   2078            return D3D11_TEXTURE_ADDRESS_BORDER;
   2079        case GL_MIRRORED_REPEAT:
   2080            return D3D11_TEXTURE_ADDRESS_MIRROR;
   2081        default:
   2082            UNREACHABLE();
   2083    }
   2084 
   2085    return D3D11_TEXTURE_ADDRESS_WRAP;
   2086 }
   2087 
   2088 UINT ConvertMaxAnisotropy(float maxAnisotropy, D3D_FEATURE_LEVEL featureLevel)
   2089 {
   2090    return static_cast<UINT>(std::min(maxAnisotropy, d3d11_gl::GetMaximumAnisotropy(featureLevel)));
   2091 }
   2092 
   2093 D3D11_QUERY ConvertQueryType(gl::QueryType type)
   2094 {
   2095    switch (type)
   2096    {
   2097        case gl::QueryType::AnySamples:
   2098        case gl::QueryType::AnySamplesConservative:
   2099            return D3D11_QUERY_OCCLUSION;
   2100        case gl::QueryType::TransformFeedbackPrimitivesWritten:
   2101            return D3D11_QUERY_SO_STATISTICS;
   2102        case gl::QueryType::TimeElapsed:
   2103            // Two internal queries are also created for begin/end timestamps
   2104            return D3D11_QUERY_TIMESTAMP_DISJOINT;
   2105        case gl::QueryType::CommandsCompleted:
   2106            return D3D11_QUERY_EVENT;
   2107        default:
   2108            UNREACHABLE();
   2109            return D3D11_QUERY_EVENT;
   2110    }
   2111 }
   2112 
   2113 // Get the D3D11 write mask covering all color channels of a given format
   2114 UINT8 GetColorMask(const gl::InternalFormat &format)
   2115 {
   2116    return ConvertColorMask(format.redBits > 0, format.greenBits > 0, format.blueBits > 0,
   2117                            format.alphaBits > 0);
   2118 }
   2119 
   2120 }  // namespace gl_d3d11
   2121 
   2122 namespace d3d11
   2123 {
   2124 
   2125 ANGLED3D11DeviceType GetDeviceType(ID3D11Device *device)
   2126 {
   2127    // Note that this function returns an ANGLED3D11DeviceType rather than a D3D_DRIVER_TYPE value,
   2128    // since it is difficult to tell Software and Reference devices apart
   2129 
   2130    IDXGIDevice *dxgiDevice     = nullptr;
   2131    IDXGIAdapter *dxgiAdapter   = nullptr;
   2132    IDXGIAdapter2 *dxgiAdapter2 = nullptr;
   2133 
   2134    ANGLED3D11DeviceType retDeviceType = ANGLE_D3D11_DEVICE_TYPE_UNKNOWN;
   2135 
   2136    HRESULT hr = device->QueryInterface(__uuidof(IDXGIDevice), (void **)&dxgiDevice);
   2137    if (SUCCEEDED(hr))
   2138    {
   2139        hr = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void **)&dxgiAdapter);
   2140        if (SUCCEEDED(hr))
   2141        {
   2142            std::wstring adapterString;
   2143            HRESULT adapter2hr =
   2144                dxgiAdapter->QueryInterface(__uuidof(dxgiAdapter2), (void **)&dxgiAdapter2);
   2145            if (SUCCEEDED(adapter2hr))
   2146            {
   2147                // On D3D_FEATURE_LEVEL_9_*, IDXGIAdapter::GetDesc returns "Software Adapter"
   2148                // for the description string. Try to use IDXGIAdapter2::GetDesc2 to get the
   2149                // actual hardware values if possible.
   2150                DXGI_ADAPTER_DESC2 adapterDesc2;
   2151                dxgiAdapter2->GetDesc2(&adapterDesc2);
   2152                adapterString = std::wstring(adapterDesc2.Description);
   2153            }
   2154            else
   2155            {
   2156                DXGI_ADAPTER_DESC adapterDesc;
   2157                dxgiAdapter->GetDesc(&adapterDesc);
   2158                adapterString = std::wstring(adapterDesc.Description);
   2159            }
   2160 
   2161            // Both Reference and Software adapters will be 'Software Adapter'
   2162            const bool isSoftwareDevice =
   2163                (adapterString.find(std::wstring(L"Software Adapter")) != std::string::npos);
   2164            const bool isNullDevice = (adapterString == L"");
   2165            const bool isWARPDevice =
   2166                (adapterString.find(std::wstring(L"Basic Render")) != std::string::npos);
   2167 
   2168            if (isSoftwareDevice || isNullDevice)
   2169            {
   2170                ASSERT(!isWARPDevice);
   2171                retDeviceType = ANGLE_D3D11_DEVICE_TYPE_SOFTWARE_REF_OR_NULL;
   2172            }
   2173            else if (isWARPDevice)
   2174            {
   2175                retDeviceType = ANGLE_D3D11_DEVICE_TYPE_WARP;
   2176            }
   2177            else
   2178            {
   2179                retDeviceType = ANGLE_D3D11_DEVICE_TYPE_HARDWARE;
   2180            }
   2181        }
   2182    }
   2183 
   2184    SafeRelease(dxgiDevice);
   2185    SafeRelease(dxgiAdapter);
   2186    SafeRelease(dxgiAdapter2);
   2187 
   2188    return retDeviceType;
   2189 }
   2190 
   2191 void MakeValidSize(bool isImage,
   2192                   DXGI_FORMAT format,
   2193                   GLsizei *requestWidth,
   2194                   GLsizei *requestHeight,
   2195                   int *levelOffset)
   2196 {
   2197    const DXGIFormatSize &dxgiFormatInfo = d3d11::GetDXGIFormatSizeInfo(format);
   2198    bool validFormat                     = format != DXGI_FORMAT_UNKNOWN;
   2199    bool validImage                      = isImage && validFormat;
   2200 
   2201    int upsampleCount = 0;
   2202    // Don't expand the size of full textures that are at least (blockWidth x blockHeight) already.
   2203    if (validImage || *requestWidth < static_cast<GLsizei>(dxgiFormatInfo.blockWidth) ||
   2204        *requestHeight < static_cast<GLsizei>(dxgiFormatInfo.blockHeight))
   2205    {
   2206        while (*requestWidth % dxgiFormatInfo.blockWidth != 0 ||
   2207               *requestHeight % dxgiFormatInfo.blockHeight != 0)
   2208        {
   2209            *requestWidth <<= 1;
   2210            *requestHeight <<= 1;
   2211            upsampleCount++;
   2212        }
   2213    }
   2214    else if (validFormat)
   2215    {
   2216        if (*requestWidth % dxgiFormatInfo.blockWidth != 0)
   2217        {
   2218            *requestWidth = roundUp(*requestWidth, static_cast<GLsizei>(dxgiFormatInfo.blockWidth));
   2219        }
   2220 
   2221        if (*requestHeight % dxgiFormatInfo.blockHeight != 0)
   2222        {
   2223            *requestHeight =
   2224                roundUp(*requestHeight, static_cast<GLsizei>(dxgiFormatInfo.blockHeight));
   2225        }
   2226    }
   2227 
   2228    if (levelOffset)
   2229    {
   2230        *levelOffset = upsampleCount;
   2231    }
   2232 }
   2233 
   2234 angle::Result GenerateInitialTextureData(
   2235    const gl::Context *context,
   2236    GLint internalFormat,
   2237    const Renderer11DeviceCaps &renderer11DeviceCaps,
   2238    GLuint width,
   2239    GLuint height,
   2240    GLuint depth,
   2241    GLuint mipLevels,
   2242    gl::TexLevelArray<D3D11_SUBRESOURCE_DATA> *outSubresourceData)
   2243 {
   2244    const d3d11::Format &d3dFormatInfo = d3d11::Format::Get(internalFormat, renderer11DeviceCaps);
   2245    ASSERT(d3dFormatInfo.dataInitializerFunction != nullptr);
   2246 
   2247    const d3d11::DXGIFormatSize &dxgiFormatInfo =
   2248        d3d11::GetDXGIFormatSizeInfo(d3dFormatInfo.texFormat);
   2249 
   2250    using CheckedSize        = angle::CheckedNumeric<size_t>;
   2251    CheckedSize rowPitch     = CheckedSize(dxgiFormatInfo.pixelBytes) * CheckedSize(width);
   2252    CheckedSize depthPitch   = rowPitch * CheckedSize(height);
   2253    CheckedSize maxImageSize = depthPitch * CheckedSize(depth);
   2254 
   2255    Context11 *context11 = GetImplAs<Context11>(context);
   2256    ANGLE_CHECK_GL_ALLOC(context11, maxImageSize.IsValid());
   2257 
   2258    angle::MemoryBuffer *scratchBuffer = nullptr;
   2259    ANGLE_CHECK_GL_ALLOC(context11,
   2260                         context->getScratchBuffer(maxImageSize.ValueOrDie(), &scratchBuffer));
   2261 
   2262    d3dFormatInfo.dataInitializerFunction(width, height, depth, scratchBuffer->data(),
   2263                                          rowPitch.ValueOrDie(), depthPitch.ValueOrDie());
   2264 
   2265    for (unsigned int i = 0; i < mipLevels; i++)
   2266    {
   2267        unsigned int mipWidth  = std::max(width >> i, 1U);
   2268        unsigned int mipHeight = std::max(height >> i, 1U);
   2269 
   2270        using CheckedUINT         = angle::CheckedNumeric<UINT>;
   2271        CheckedUINT mipRowPitch   = CheckedUINT(dxgiFormatInfo.pixelBytes) * CheckedUINT(mipWidth);
   2272        CheckedUINT mipDepthPitch = mipRowPitch * CheckedUINT(mipHeight);
   2273 
   2274        ANGLE_CHECK_GL_ALLOC(context11, mipRowPitch.IsValid() && mipDepthPitch.IsValid());
   2275 
   2276        outSubresourceData->at(i).pSysMem          = scratchBuffer->data();
   2277        outSubresourceData->at(i).SysMemPitch      = mipRowPitch.ValueOrDie();
   2278        outSubresourceData->at(i).SysMemSlicePitch = mipDepthPitch.ValueOrDie();
   2279    }
   2280 
   2281    return angle::Result::Continue;
   2282 }
   2283 
   2284 UINT GetPrimitiveRestartIndex()
   2285 {
   2286    return std::numeric_limits<UINT>::max();
   2287 }
   2288 
   2289 void SetPositionTexCoordVertex(PositionTexCoordVertex *vertex, float x, float y, float u, float v)
   2290 {
   2291    vertex->x = x;
   2292    vertex->y = y;
   2293    vertex->u = u;
   2294    vertex->v = v;
   2295 }
   2296 
   2297 void SetPositionLayerTexCoord3DVertex(PositionLayerTexCoord3DVertex *vertex,
   2298                                      float x,
   2299                                      float y,
   2300                                      unsigned int layer,
   2301                                      float u,
   2302                                      float v,
   2303                                      float s)
   2304 {
   2305    vertex->x = x;
   2306    vertex->y = y;
   2307    vertex->l = layer;
   2308    vertex->u = u;
   2309    vertex->v = v;
   2310    vertex->s = s;
   2311 }
   2312 
   2313 BlendStateKey::BlendStateKey()
   2314 {
   2315    memset(this, 0, sizeof(BlendStateKey));
   2316    blendStateExt = gl::BlendStateExt();
   2317 }
   2318 
   2319 BlendStateKey::BlendStateKey(const BlendStateKey &other)
   2320 {
   2321    memcpy(this, &other, sizeof(BlendStateKey));
   2322 }
   2323 
   2324 bool operator==(const BlendStateKey &a, const BlendStateKey &b)
   2325 {
   2326    return memcmp(&a, &b, sizeof(BlendStateKey)) == 0;
   2327 }
   2328 
   2329 bool operator!=(const BlendStateKey &a, const BlendStateKey &b)
   2330 {
   2331    return !(a == b);
   2332 }
   2333 
   2334 RasterizerStateKey::RasterizerStateKey()
   2335 {
   2336    memset(this, 0, sizeof(RasterizerStateKey));
   2337 }
   2338 
   2339 bool operator==(const RasterizerStateKey &a, const RasterizerStateKey &b)
   2340 {
   2341    return memcmp(&a, &b, sizeof(RasterizerStateKey)) == 0;
   2342 }
   2343 
   2344 bool operator!=(const RasterizerStateKey &a, const RasterizerStateKey &b)
   2345 {
   2346    return !(a == b);
   2347 }
   2348 
   2349 HRESULT SetDebugName(ID3D11DeviceChild *resource,
   2350                     const char *internalName,
   2351                     const std::string *khrDebugName)
   2352 {
   2353    // Prepend ANGLE to separate names from other components in the same process.
   2354    std::string d3dName = "ANGLE";
   2355    bool sendNameToD3D  = false;
   2356    if (internalName && internalName[0] != '\0')
   2357    {
   2358        d3dName += std::string("_") + internalName;
   2359        sendNameToD3D = true;
   2360    }
   2361    if (khrDebugName && !khrDebugName->empty())
   2362    {
   2363        d3dName += std::string("_") + *khrDebugName;
   2364        sendNameToD3D = true;
   2365    }
   2366    // If both internalName and khrDebugName are empty, avoid sending the string to d3d.
   2367    if (sendNameToD3D)
   2368    {
   2369        return resource->SetPrivateData(WKPDID_D3DDebugObjectName,
   2370                                        static_cast<UINT>(d3dName.size()), d3dName.c_str());
   2371    }
   2372    return S_OK;
   2373 }
   2374 
   2375 // Keep this in cpp file where it has visibility of Renderer11.h, otherwise calling
   2376 // allocateResource is only compatible with Clang and MSVS, which support calling a
   2377 // method on a forward declared class in a template.
   2378 template <ResourceType ResourceT>
   2379 angle::Result LazyResource<ResourceT>::resolveImpl(d3d::Context *context,
   2380                                                   Renderer11 *renderer,
   2381                                                   const GetDescType<ResourceT> &desc,
   2382                                                   GetInitDataType<ResourceT> *initData,
   2383                                                   const char *name)
   2384 {
   2385    if (!mResource.valid())
   2386    {
   2387        ANGLE_TRY(renderer->allocateResource(context, desc, initData, &mResource));
   2388        mResource.setInternalName(name);
   2389    }
   2390    return angle::Result::Continue;
   2391 }
   2392 
   2393 template angle::Result LazyResource<ResourceType::BlendState>::resolveImpl(
   2394    d3d::Context *context,
   2395    Renderer11 *renderer,
   2396    const D3D11_BLEND_DESC &desc,
   2397    void *initData,
   2398    const char *name);
   2399 template angle::Result LazyResource<ResourceType::ComputeShader>::resolveImpl(
   2400    d3d::Context *context,
   2401    Renderer11 *renderer,
   2402    const ShaderData &desc,
   2403    void *initData,
   2404    const char *name);
   2405 template angle::Result LazyResource<ResourceType::GeometryShader>::resolveImpl(
   2406    d3d::Context *context,
   2407    Renderer11 *renderer,
   2408    const ShaderData &desc,
   2409    const std::vector<D3D11_SO_DECLARATION_ENTRY> *initData,
   2410    const char *name);
   2411 template angle::Result LazyResource<ResourceType::InputLayout>::resolveImpl(
   2412    d3d::Context *context,
   2413    Renderer11 *renderer,
   2414    const InputElementArray &desc,
   2415    const ShaderData *initData,
   2416    const char *name);
   2417 template angle::Result LazyResource<ResourceType::PixelShader>::resolveImpl(d3d::Context *context,
   2418                                                                            Renderer11 *renderer,
   2419                                                                            const ShaderData &desc,
   2420                                                                            void *initData,
   2421                                                                            const char *name);
   2422 template angle::Result LazyResource<ResourceType::VertexShader>::resolveImpl(d3d::Context *context,
   2423                                                                             Renderer11 *renderer,
   2424                                                                             const ShaderData &desc,
   2425                                                                             void *initData,
   2426                                                                             const char *name);
   2427 
   2428 LazyInputLayout::LazyInputLayout(const D3D11_INPUT_ELEMENT_DESC *inputDesc,
   2429                                 size_t inputDescLen,
   2430                                 const BYTE *byteCode,
   2431                                 size_t byteCodeLen,
   2432                                 const char *debugName)
   2433    : mInputDesc(inputDesc, inputDescLen), mByteCode(byteCode, byteCodeLen), mDebugName(debugName)
   2434 {}
   2435 
   2436 LazyInputLayout::~LazyInputLayout() {}
   2437 
   2438 angle::Result LazyInputLayout::resolve(d3d::Context *context, Renderer11 *renderer)
   2439 {
   2440    return resolveImpl(context, renderer, mInputDesc, &mByteCode, mDebugName);
   2441 }
   2442 
   2443 LazyBlendState::LazyBlendState(const D3D11_BLEND_DESC &desc, const char *debugName)
   2444    : mDesc(desc), mDebugName(debugName)
   2445 {}
   2446 
   2447 angle::Result LazyBlendState::resolve(d3d::Context *context, Renderer11 *renderer)
   2448 {
   2449    return resolveImpl(context, renderer, mDesc, nullptr, mDebugName);
   2450 }
   2451 
   2452 void InitializeFeatures(const Renderer11DeviceCaps &deviceCaps,
   2453                        const DXGI_ADAPTER_DESC &adapterDesc,
   2454                        angle::FeaturesD3D *features)
   2455 {
   2456    bool isNvidia          = IsNvidia(adapterDesc.VendorId);
   2457    bool isIntel           = IsIntel(adapterDesc.VendorId);
   2458    bool isSkylake         = false;
   2459    bool isBroadwell       = false;
   2460    bool isHaswell         = false;
   2461    bool isIvyBridge       = false;
   2462    bool isSandyBridge     = false;
   2463    bool isAMD             = IsAMD(adapterDesc.VendorId);
   2464    bool isFeatureLevel9_3 = (deviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3);
   2465 
   2466    IntelDriverVersion capsVersion = IntelDriverVersion(0);
   2467    if (isIntel)
   2468    {
   2469        capsVersion = d3d11_gl::GetIntelDriverVersion(deviceCaps.driverVersion);
   2470 
   2471        isSkylake     = IsSkylake(adapterDesc.DeviceId);
   2472        isBroadwell   = IsBroadwell(adapterDesc.DeviceId);
   2473        isHaswell     = IsHaswell(adapterDesc.DeviceId);
   2474        isIvyBridge   = IsIvyBridge(adapterDesc.DeviceId);
   2475        isSandyBridge = IsSandyBridge(adapterDesc.DeviceId);
   2476    }
   2477 
   2478    if (isNvidia)
   2479    {
   2480        // TODO(jmadill): Narrow problematic driver range.
   2481        bool driverVersionValid = deviceCaps.driverVersion.valid();
   2482        if (driverVersionValid)
   2483        {
   2484            WORD part1 = HIWORD(deviceCaps.driverVersion.value().LowPart);
   2485            WORD part2 = LOWORD(deviceCaps.driverVersion.value().LowPart);
   2486 
   2487            // Disable the workaround to fix a second driver bug on newer NVIDIA.
   2488            ANGLE_FEATURE_CONDITION(
   2489                features, depthStencilBlitExtraCopy,
   2490                (part1 <= 13u && part2 < 6881) && isNvidia && driverVersionValid);
   2491        }
   2492        else
   2493        {
   2494            ANGLE_FEATURE_CONDITION(features, depthStencilBlitExtraCopy,
   2495                                    isNvidia && !driverVersionValid);
   2496        }
   2497    }
   2498 
   2499    ANGLE_FEATURE_CONDITION(features, mrtPerfWorkaround, true);
   2500    ANGLE_FEATURE_CONDITION(features, zeroMaxLodWorkaround, isFeatureLevel9_3);
   2501    ANGLE_FEATURE_CONDITION(features, useInstancedPointSpriteEmulation, isFeatureLevel9_3);
   2502    ANGLE_FEATURE_CONDITION(features, allowES3OnFL100, false);
   2503 
   2504    // TODO(jmadill): Disable workaround when we have a fixed compiler DLL.
   2505    ANGLE_FEATURE_CONDITION(features, expandIntegerPowExpressions, true);
   2506 
   2507    ANGLE_FEATURE_CONDITION(features, flushAfterEndingTransformFeedback, isNvidia);
   2508    ANGLE_FEATURE_CONDITION(features, getDimensionsIgnoresBaseLevel, isNvidia);
   2509    ANGLE_FEATURE_CONDITION(features, skipVSConstantRegisterZero, isNvidia);
   2510    ANGLE_FEATURE_CONDITION(features, forceAtomicValueResolution, isNvidia);
   2511 
   2512    ANGLE_FEATURE_CONDITION(features, preAddTexelFetchOffsets, isIntel);
   2513    ANGLE_FEATURE_CONDITION(features, useSystemMemoryForConstantBuffers, isIntel);
   2514 
   2515    // ClearView on Skylake seems to incorrectly clear with unaligned rects (edge has saw tooth
   2516    // pattern instead of straight).
   2517    ANGLE_FEATURE_CONDITION(features, scissoredClearArtifacts, isIntel && isSkylake);
   2518 
   2519    ANGLE_FEATURE_CONDITION(features, callClearTwice,
   2520                            isIntel && isSkylake && capsVersion >= IntelDriverVersion(160000) &&
   2521                                capsVersion < IntelDriverVersion(164771));
   2522    ANGLE_FEATURE_CONDITION(features, emulateIsnanFloat,
   2523                            isIntel && isSkylake && capsVersion >= IntelDriverVersion(160000) &&
   2524                                capsVersion < IntelDriverVersion(164542));
   2525    ANGLE_FEATURE_CONDITION(features, rewriteUnaryMinusOperator,
   2526                            isIntel && (isBroadwell || isHaswell) &&
   2527                                capsVersion >= IntelDriverVersion(150000) &&
   2528                                capsVersion < IntelDriverVersion(154624));
   2529 
   2530    ANGLE_FEATURE_CONDITION(features, addMockTextureNoRenderTarget,
   2531                            isIntel && capsVersion >= IntelDriverVersion(160000) &&
   2532                                capsVersion < IntelDriverVersion(164815));
   2533 
   2534    // Haswell drivers occasionally corrupt (small?) (vertex?) texture data uploads for 128bit
   2535    // formats.
   2536    ANGLE_FEATURE_CONDITION(features, setDataFasterThanImageUpload, true);
   2537    ANGLE_FEATURE_CONDITION(features, setDataFasterThanImageUploadOn128bitFormats,
   2538                            !(isIvyBridge || isBroadwell || isHaswell));
   2539 
   2540    ANGLE_FEATURE_CONDITION(features, emulateClearViewAfterDualSourceBlending, isSandyBridge);
   2541 
   2542    ANGLE_FEATURE_CONDITION(features, disableB5G6R5Support,
   2543                            (isIntel && capsVersion >= IntelDriverVersion(150000) &&
   2544                             capsVersion < IntelDriverVersion(154539)) ||
   2545                                isAMD);
   2546 
   2547    // TODO(jmadill): Disable when we have a fixed driver version.
   2548    // The tiny stencil texture workaround involves using CopySubresource or UpdateSubresource on a
   2549    // depth stencil texture.  This is not allowed until feature level 10.1 but since it is not
   2550    // possible to support ES3 on these devices, there is no need for the workaround to begin with
   2551    // (anglebug.com/1572).
   2552    ANGLE_FEATURE_CONDITION(features, emulateTinyStencilTextures,
   2553                            isAMD && !(deviceCaps.featureLevel < D3D_FEATURE_LEVEL_10_1));
   2554 
   2555    // If the VPAndRTArrayIndexFromAnyShaderFeedingRasterizer feature is not available, we have to
   2556    // select the viewport / RT array index in the geometry shader.
   2557    ANGLE_FEATURE_CONDITION(features, selectViewInGeometryShader,
   2558                            !deviceCaps.supportsVpRtIndexWriteFromVertexShader);
   2559 
   2560    // NVidia drivers have no trouble clearing textures without showing corruption.
   2561    // Intel and AMD drivers that have trouble have been blocklisted by Chromium. In the case of
   2562    // Intel, they've been blocklisted to the DX9 runtime.
   2563    ANGLE_FEATURE_CONDITION(features, allowClearForRobustResourceInit, true);
   2564 
   2565    // Allow translating uniform block to StructuredBuffer on Windows 10. This is targeted
   2566    // to work around a slow fxc compile performance issue with dynamic uniform indexing.
   2567    ANGLE_FEATURE_CONDITION(features, allowTranslateUniformBlockToStructuredBuffer,
   2568                            IsWin10OrGreater());
   2569 }
   2570 
   2571 void InitializeFrontendFeatures(const DXGI_ADAPTER_DESC &adapterDesc,
   2572                                angle::FrontendFeatures *features)
   2573 {
   2574    bool isAMD = IsAMD(adapterDesc.VendorId);
   2575 
   2576    ANGLE_FEATURE_CONDITION(features, forceDepthAttachmentInitOnClear, isAMD);
   2577 }
   2578 
   2579 void InitConstantBufferDesc(D3D11_BUFFER_DESC *constantBufferDescription, size_t byteWidth)
   2580 {
   2581    constantBufferDescription->ByteWidth           = static_cast<UINT>(byteWidth);
   2582    constantBufferDescription->Usage               = D3D11_USAGE_DYNAMIC;
   2583    constantBufferDescription->BindFlags           = D3D11_BIND_CONSTANT_BUFFER;
   2584    constantBufferDescription->CPUAccessFlags      = D3D11_CPU_ACCESS_WRITE;
   2585    constantBufferDescription->MiscFlags           = 0;
   2586    constantBufferDescription->StructureByteStride = 0;
   2587 }
   2588 
   2589 }  // namespace d3d11
   2590 
   2591 // TextureHelper11 implementation.
   2592 TextureHelper11::TextureHelper11() : mFormatSet(nullptr), mSampleCount(0) {}
   2593 
   2594 TextureHelper11::TextureHelper11(TextureHelper11 &&toCopy) : TextureHelper11()
   2595 {
   2596    *this = std::move(toCopy);
   2597 }
   2598 
   2599 TextureHelper11::TextureHelper11(const TextureHelper11 &other)
   2600    : mFormatSet(other.mFormatSet), mExtents(other.mExtents), mSampleCount(other.mSampleCount)
   2601 {
   2602    mData = other.mData;
   2603 }
   2604 
   2605 TextureHelper11::~TextureHelper11() {}
   2606 
   2607 void TextureHelper11::getDesc(D3D11_TEXTURE2D_DESC *desc) const
   2608 {
   2609    static_cast<ID3D11Texture2D *>(mData->object)->GetDesc(desc);
   2610 }
   2611 
   2612 void TextureHelper11::getDesc(D3D11_TEXTURE3D_DESC *desc) const
   2613 {
   2614    static_cast<ID3D11Texture3D *>(mData->object)->GetDesc(desc);
   2615 }
   2616 
   2617 void TextureHelper11::getDesc(D3D11_BUFFER_DESC *desc) const
   2618 {
   2619    static_cast<ID3D11Buffer *>(mData->object)->GetDesc(desc);
   2620 }
   2621 
   2622 void TextureHelper11::initDesc(const D3D11_TEXTURE2D_DESC &desc2D)
   2623 {
   2624    mData->resourceType = ResourceType::Texture2D;
   2625    mExtents.width      = static_cast<int>(desc2D.Width);
   2626    mExtents.height     = static_cast<int>(desc2D.Height);
   2627    mExtents.depth      = 1;
   2628    mSampleCount        = desc2D.SampleDesc.Count;
   2629 }
   2630 
   2631 void TextureHelper11::initDesc(const D3D11_TEXTURE3D_DESC &desc3D)
   2632 {
   2633    mData->resourceType = ResourceType::Texture3D;
   2634    mExtents.width      = static_cast<int>(desc3D.Width);
   2635    mExtents.height     = static_cast<int>(desc3D.Height);
   2636    mExtents.depth      = static_cast<int>(desc3D.Depth);
   2637    mSampleCount        = 1;
   2638 }
   2639 
   2640 void TextureHelper11::initDesc(const D3D11_BUFFER_DESC &descBuffer)
   2641 {
   2642    mData->resourceType = ResourceType::Buffer;
   2643    mExtents.width      = static_cast<int>(descBuffer.ByteWidth);
   2644    mExtents.height     = 1;
   2645    mExtents.depth      = 1;
   2646    mSampleCount        = 1;
   2647 }
   2648 
   2649 TextureHelper11 &TextureHelper11::operator=(TextureHelper11 &&other)
   2650 {
   2651    std::swap(mData, other.mData);
   2652    std::swap(mExtents, other.mExtents);
   2653    std::swap(mFormatSet, other.mFormatSet);
   2654    std::swap(mSampleCount, other.mSampleCount);
   2655    return *this;
   2656 }
   2657 
   2658 TextureHelper11 &TextureHelper11::operator=(const TextureHelper11 &other)
   2659 {
   2660    mData        = other.mData;
   2661    mExtents     = other.mExtents;
   2662    mFormatSet   = other.mFormatSet;
   2663    mSampleCount = other.mSampleCount;
   2664    return *this;
   2665 }
   2666 
   2667 bool TextureHelper11::operator==(const TextureHelper11 &other) const
   2668 {
   2669    return mData->object == other.mData->object;
   2670 }
   2671 
   2672 bool TextureHelper11::operator!=(const TextureHelper11 &other) const
   2673 {
   2674    return mData->object != other.mData->object;
   2675 }
   2676 
   2677 bool UsePresentPathFast(const Renderer11 *renderer,
   2678                        const gl::FramebufferAttachment *framebufferAttachment)
   2679 {
   2680    if (framebufferAttachment == nullptr)
   2681    {
   2682        return false;
   2683    }
   2684 
   2685    return (framebufferAttachment->type() == GL_FRAMEBUFFER_DEFAULT &&
   2686            renderer->presentPathFastEnabled());
   2687 }
   2688 
   2689 bool UsePrimitiveRestartWorkaround(bool primitiveRestartFixedIndexEnabled,
   2690                                   gl::DrawElementsType type)
   2691 {
   2692    // We should never have to deal with primitive restart workaround issue with GL_UNSIGNED_INT
   2693    // indices, since we restrict it via MAX_ELEMENT_INDEX.
   2694    return (!primitiveRestartFixedIndexEnabled && type == gl::DrawElementsType::UnsignedShort);
   2695 }
   2696 
   2697 IndexStorageType ClassifyIndexStorage(const gl::State &glState,
   2698                                      const gl::Buffer *elementArrayBuffer,
   2699                                      gl::DrawElementsType elementType,
   2700                                      gl::DrawElementsType destElementType,
   2701                                      unsigned int offset)
   2702 {
   2703    // No buffer bound means we are streaming from a client pointer.
   2704    if (!elementArrayBuffer || !IsOffsetAligned(elementType, offset))
   2705    {
   2706        return IndexStorageType::Dynamic;
   2707    }
   2708 
   2709    // The buffer can be used directly if the storage supports it and no translation needed.
   2710    BufferD3D *bufferD3D = GetImplAs<BufferD3D>(elementArrayBuffer);
   2711    if (bufferD3D->supportsDirectBinding() && destElementType == elementType)
   2712    {
   2713        return IndexStorageType::Direct;
   2714    }
   2715 
   2716    // Use a static copy when available.
   2717    StaticIndexBufferInterface *staticBuffer = bufferD3D->getStaticIndexBuffer();
   2718    if (staticBuffer != nullptr)
   2719    {
   2720        return IndexStorageType::Static;
   2721    }
   2722 
   2723    // Static buffer not available, fall back to streaming.
   2724    return IndexStorageType::Dynamic;
   2725 }
   2726 
   2727 bool SwizzleRequired(const gl::TextureState &textureState)
   2728 {
   2729    // When sampling stencil, a swizzle is needed to move the stencil channel from G to R.
   2730    return textureState.swizzleRequired() || textureState.isStencilMode();
   2731 }
   2732 
   2733 gl::SwizzleState GetEffectiveSwizzle(const gl::TextureState &textureState)
   2734 {
   2735    const gl::SwizzleState &swizzle = textureState.getSwizzleState();
   2736    if (textureState.isStencilMode())
   2737    {
   2738        // Per GL semantics, the stencil value should be in the red channel, while D3D11 formats
   2739        // leave stencil in the green channel. So copy the stencil value from green to all
   2740        // components requesting red. Green and blue become zero; alpha becomes one.
   2741        std::unordered_map<GLenum, GLenum> map = {{GL_RED, GL_GREEN}, {GL_GREEN, GL_ZERO},
   2742                                                  {GL_BLUE, GL_ZERO}, {GL_ALPHA, GL_ONE},
   2743                                                  {GL_ZERO, GL_ZERO}, {GL_ONE, GL_ONE}};
   2744 
   2745        return gl::SwizzleState(map[swizzle.swizzleRed], map[swizzle.swizzleGreen],
   2746                                map[swizzle.swizzleBlue], map[swizzle.swizzleAlpha]);
   2747    }
   2748    return swizzle;
   2749 }
   2750 
   2751 }  // namespace rx