Home | History | Annotate | Download | only in d3d11
      1 #include "precompiled.h"
      2 //
      3 // Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved.
      4 // Use of this source code is governed by a BSD-style license that can be
      5 // found in the LICENSE file.
      6 //
      7 
      8 // Renderer11.cpp: Implements a back-end specific class for the D3D11 renderer.
      9 
     10 #include "libGLESv2/main.h"
     11 #include "common/utilities.h"
     12 #include "libGLESv2/Buffer.h"
     13 #include "libGLESv2/ProgramBinary.h"
     14 #include "libGLESv2/Framebuffer.h"
     15 #include "libGLESv2/RenderBuffer.h"
     16 #include "libGLESv2/renderer/d3d11/Renderer11.h"
     17 #include "libGLESv2/renderer/d3d11/RenderTarget11.h"
     18 #include "libGLESv2/renderer/d3d11/renderer11_utils.h"
     19 #include "libGLESv2/renderer/d3d11/formatutils11.h"
     20 #include "libGLESv2/renderer/d3d11/ShaderExecutable11.h"
     21 #include "libGLESv2/renderer/d3d11/SwapChain11.h"
     22 #include "libGLESv2/renderer/d3d11/Image11.h"
     23 #include "libGLESv2/renderer/d3d11/VertexBuffer11.h"
     24 #include "libGLESv2/renderer/d3d11/IndexBuffer11.h"
     25 #include "libGLESv2/renderer/d3d11/BufferStorage11.h"
     26 #include "libGLESv2/renderer/VertexDataManager.h"
     27 #include "libGLESv2/renderer/IndexDataManager.h"
     28 #include "libGLESv2/renderer/d3d11/TextureStorage11.h"
     29 #include "libGLESv2/renderer/d3d11/Query11.h"
     30 #include "libGLESv2/renderer/d3d11/Fence11.h"
     31 #include "libGLESv2/renderer/d3d11/Blit11.h"
     32 #include "libGLESv2/renderer/d3d11/Clear11.h"
     33 #include "libGLESv2/renderer/d3d11/PixelTransfer11.h"
     34 #include "libEGL/Display.h"
     35 
     36 // Enable ANGLE_SKIP_DXGI_1_2_CHECK if there is not a possibility of using cross-process
     37 // HWNDs or the Windows 7 Platform Update (KB2670838) is expected to be installed.
     38 #ifndef ANGLE_SKIP_DXGI_1_2_CHECK
     39 #define ANGLE_SKIP_DXGI_1_2_CHECK 0
     40 #endif
     41 
     42 #ifdef _DEBUG
     43 // this flag enables suppressing some spurious warnings that pop up in certain WebGL samples
     44 // and conformance tests. to enable all warnings, remove this define.
     45 #define ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS 1
     46 #endif
     47 
     48 namespace rx
     49 {
     50 static const DXGI_FORMAT RenderTargetFormats[] =
     51     {
     52         DXGI_FORMAT_B8G8R8A8_UNORM,
     53         DXGI_FORMAT_R8G8B8A8_UNORM
     54     };
     55 
     56 static const DXGI_FORMAT DepthStencilFormats[] =
     57     {
     58         DXGI_FORMAT_UNKNOWN,
     59         DXGI_FORMAT_D24_UNORM_S8_UINT,
     60         DXGI_FORMAT_D16_UNORM
     61     };
     62 
     63 enum
     64 {
     65     MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 = 16
     66 };
     67 
     68 Renderer11::Renderer11(egl::Display *display, HDC hDc) : Renderer(display), mDc(hDc)
     69 {
     70     mVertexDataManager = NULL;
     71     mIndexDataManager = NULL;
     72 
     73     mLineLoopIB = NULL;
     74     mTriangleFanIB = NULL;
     75 
     76     mBlit = NULL;
     77     mPixelTransfer = NULL;
     78 
     79     mClear = NULL;
     80 
     81     mSyncQuery = NULL;
     82 
     83     mD3d11Module = NULL;
     84     mDxgiModule = NULL;
     85 
     86     mDeviceLost = false;
     87 
     88     mMaxSupportedSamples = 0;
     89 
     90     mDevice = NULL;
     91     mDeviceContext = NULL;
     92     mDxgiAdapter = NULL;
     93     mDxgiFactory = NULL;
     94 
     95     mDriverConstantBufferVS = NULL;
     96     mDriverConstantBufferPS = NULL;
     97 
     98     mBGRATextureSupport = false;
     99 
    100     mAppliedVertexShader = NULL;
    101     mAppliedGeometryShader = NULL;
    102     mCurPointGeometryShader = NULL;
    103     mAppliedPixelShader = NULL;
    104 }
    105 
    106 Renderer11::~Renderer11()
    107 {
    108     release();
    109 }
    110 
    111 Renderer11 *Renderer11::makeRenderer11(Renderer *renderer)
    112 {
    113     ASSERT(HAS_DYNAMIC_TYPE(rx::Renderer11*, renderer));
    114     return static_cast<rx::Renderer11*>(renderer);
    115 }
    116 
    117 #ifndef __d3d11_1_h__
    118 #define D3D11_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET ((D3D11_MESSAGE_ID)3146081)
    119 #endif
    120 
    121 EGLint Renderer11::initialize()
    122 {
    123     if (!mCompiler.initialize())
    124     {
    125         return EGL_NOT_INITIALIZED;
    126     }
    127 
    128     mDxgiModule = LoadLibrary(TEXT("dxgi.dll"));
    129     mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
    130 
    131     if (mD3d11Module == NULL || mDxgiModule == NULL)
    132     {
    133         ERR("Could not load D3D11 or DXGI library - aborting!\n");
    134         return EGL_NOT_INITIALIZED;
    135     }
    136 
    137     // create the D3D11 device
    138     ASSERT(mDevice == NULL);
    139     PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice");
    140 
    141     if (D3D11CreateDevice == NULL)
    142     {
    143         ERR("Could not retrieve D3D11CreateDevice address - aborting!\n");
    144         return EGL_NOT_INITIALIZED;
    145     }
    146 
    147     D3D_FEATURE_LEVEL featureLevels[] =
    148     {
    149         D3D_FEATURE_LEVEL_11_0,
    150         D3D_FEATURE_LEVEL_10_1,
    151         D3D_FEATURE_LEVEL_10_0,
    152     };
    153 
    154     HRESULT result = S_OK;
    155 
    156 #ifdef _DEBUG
    157     result = D3D11CreateDevice(NULL,
    158                                D3D_DRIVER_TYPE_HARDWARE,
    159                                NULL,
    160                                D3D11_CREATE_DEVICE_DEBUG,
    161                                featureLevels,
    162                                ArraySize(featureLevels),
    163                                D3D11_SDK_VERSION,
    164                                &mDevice,
    165                                &mFeatureLevel,
    166                                &mDeviceContext);
    167 
    168     if (!mDevice || FAILED(result))
    169     {
    170         ERR("Failed creating Debug D3D11 device - falling back to release runtime.\n");
    171     }
    172 
    173     if (!mDevice || FAILED(result))
    174 #endif
    175     {
    176         result = D3D11CreateDevice(NULL,
    177                                    D3D_DRIVER_TYPE_HARDWARE,
    178                                    NULL,
    179                                    0,
    180                                    featureLevels,
    181                                    ArraySize(featureLevels),
    182                                    D3D11_SDK_VERSION,
    183                                    &mDevice,
    184                                    &mFeatureLevel,
    185                                    &mDeviceContext);
    186 
    187         if (!mDevice || FAILED(result))
    188         {
    189             ERR("Could not create D3D11 device - aborting!\n");
    190             return EGL_NOT_INITIALIZED;   // Cleanup done by destructor through glDestroyRenderer
    191         }
    192     }
    193 
    194 #if !ANGLE_SKIP_DXGI_1_2_CHECK
    195     // In order to create a swap chain for an HWND owned by another process, DXGI 1.2 is required.
    196     // The easiest way to check is to query for a IDXGIDevice2.
    197     bool requireDXGI1_2 = false;
    198     HWND hwnd = WindowFromDC(mDc);
    199     if (hwnd)
    200     {
    201         DWORD currentProcessId = GetCurrentProcessId();
    202         DWORD wndProcessId;
    203         GetWindowThreadProcessId(hwnd, &wndProcessId);
    204         requireDXGI1_2 = (currentProcessId != wndProcessId);
    205     }
    206     else
    207     {
    208         requireDXGI1_2 = true;
    209     }
    210 
    211     if (requireDXGI1_2)
    212     {
    213         IDXGIDevice2 *dxgiDevice2 = NULL;
    214         result = mDevice->QueryInterface(__uuidof(IDXGIDevice2), (void**)&dxgiDevice2);
    215         if (FAILED(result))
    216         {
    217             ERR("DXGI 1.2 required to present to HWNDs owned by another process.\n");
    218             return EGL_NOT_INITIALIZED;
    219         }
    220         SafeRelease(dxgiDevice2);
    221     }
    222 #endif
    223 
    224     IDXGIDevice *dxgiDevice = NULL;
    225     result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
    226 
    227     if (FAILED(result))
    228     {
    229         ERR("Could not query DXGI device - aborting!\n");
    230         return EGL_NOT_INITIALIZED;
    231     }
    232 
    233     result = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&mDxgiAdapter);
    234 
    235     if (FAILED(result))
    236     {
    237         ERR("Could not retrieve DXGI adapter - aborting!\n");
    238         return EGL_NOT_INITIALIZED;
    239     }
    240 
    241     SafeRelease(dxgiDevice);
    242 
    243     mDxgiAdapter->GetDesc(&mAdapterDescription);
    244     memset(mDescription, 0, sizeof(mDescription));
    245     wcstombs(mDescription, mAdapterDescription.Description, sizeof(mDescription) - 1);
    246 
    247     result = mDxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&mDxgiFactory);
    248 
    249     if (!mDxgiFactory || FAILED(result))
    250     {
    251         ERR("Could not create DXGI factory - aborting!\n");
    252         return EGL_NOT_INITIALIZED;
    253     }
    254 
    255     // Disable some spurious D3D11 debug warnings to prevent them from flooding the output log
    256 #if defined(ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS) && defined(_DEBUG)
    257     ID3D11InfoQueue *infoQueue;
    258     result = mDevice->QueryInterface(__uuidof(ID3D11InfoQueue),  (void **)&infoQueue);
    259 
    260     if (SUCCEEDED(result))
    261     {
    262         D3D11_MESSAGE_ID hideMessages[] =
    263         {
    264             D3D11_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET
    265         };
    266 
    267         D3D11_INFO_QUEUE_FILTER filter = {0};
    268         filter.DenyList.NumIDs = ArraySize(hideMessages);
    269         filter.DenyList.pIDList = hideMessages;
    270 
    271         infoQueue->AddStorageFilterEntries(&filter);
    272         SafeRelease(infoQueue);
    273     }
    274 #endif
    275 
    276     mMaxSupportedSamples = 0;
    277 
    278     const d3d11::DXGIFormatSet &dxgiFormats = d3d11::GetAllUsedDXGIFormats();
    279     for (d3d11::DXGIFormatSet::const_iterator i = dxgiFormats.begin(); i != dxgiFormats.end(); ++i)
    280     {
    281         MultisampleSupportInfo support = getMultisampleSupportInfo(*i);
    282         mMultisampleSupportMap.insert(std::make_pair(*i, support));
    283         mMaxSupportedSamples = std::max(mMaxSupportedSamples, support.maxSupportedSamples);
    284     }
    285 
    286     initializeDevice();
    287 
    288     // BGRA texture support is optional in feature levels 10 and 10_1
    289     UINT formatSupport;
    290     result = mDevice->CheckFormatSupport(DXGI_FORMAT_B8G8R8A8_UNORM, &formatSupport);
    291     if (FAILED(result))
    292     {
    293         ERR("Error checking BGRA format support: 0x%08X", result);
    294     }
    295     else
    296     {
    297         const int flags = (D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_RENDER_TARGET);
    298         mBGRATextureSupport = (formatSupport & flags) == flags;
    299     }
    300 
    301     // Check floating point texture support
    302     static const unsigned int requiredTextureFlags = D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_TEXTURECUBE;
    303     static const unsigned int requiredRenderableFlags = D3D11_FORMAT_SUPPORT_RENDER_TARGET;
    304     static const unsigned int requiredFilterFlags = D3D11_FORMAT_SUPPORT_SHADER_SAMPLE;
    305 
    306     DXGI_FORMAT float16Formats[] =
    307     {
    308         DXGI_FORMAT_R16_FLOAT,
    309         DXGI_FORMAT_R16G16_FLOAT,
    310         DXGI_FORMAT_R16G16B16A16_FLOAT,
    311     };
    312 
    313     DXGI_FORMAT float32Formats[] =
    314     {
    315         DXGI_FORMAT_R32_FLOAT,
    316         DXGI_FORMAT_R32G32_FLOAT,
    317         DXGI_FORMAT_R32G32B32A32_FLOAT,
    318     };
    319 
    320     mFloat16TextureSupport = true;
    321     mFloat16FilterSupport = true;
    322     mFloat16RenderSupport = true;
    323     for (unsigned int i = 0; i < ArraySize(float16Formats); i++)
    324     {
    325         if (SUCCEEDED(mDevice->CheckFormatSupport(float16Formats[i], &formatSupport)))
    326         {
    327             mFloat16TextureSupport = mFloat16TextureSupport && (formatSupport & requiredTextureFlags) == requiredTextureFlags;
    328             mFloat16FilterSupport = mFloat16FilterSupport && (formatSupport & requiredFilterFlags) == requiredFilterFlags;
    329             mFloat16RenderSupport = mFloat16RenderSupport && (formatSupport & requiredRenderableFlags) == requiredRenderableFlags;
    330         }
    331         else
    332         {
    333             mFloat16TextureSupport = false;
    334             mFloat16RenderSupport = false;
    335             mFloat16FilterSupport = false;
    336         }
    337     }
    338 
    339     mFloat32TextureSupport = true;
    340     mFloat32FilterSupport = true;
    341     mFloat32RenderSupport = true;
    342     for (unsigned int i = 0; i < ArraySize(float32Formats); i++)
    343     {
    344         if (SUCCEEDED(mDevice->CheckFormatSupport(float32Formats[i], &formatSupport)))
    345         {
    346             mFloat32TextureSupport = mFloat32TextureSupport && (formatSupport & requiredTextureFlags) == requiredTextureFlags;
    347             mFloat32FilterSupport = mFloat32FilterSupport && (formatSupport & requiredFilterFlags) == requiredFilterFlags;
    348             mFloat32RenderSupport = mFloat32RenderSupport && (formatSupport & requiredRenderableFlags) == requiredRenderableFlags;
    349         }
    350         else
    351         {
    352             mFloat32TextureSupport = false;
    353             mFloat32FilterSupport = false;
    354             mFloat32RenderSupport = false;
    355         }
    356     }
    357 
    358     DXGI_FORMAT rgTextureFormats[] =
    359     {
    360         DXGI_FORMAT_R8_UNORM,
    361         DXGI_FORMAT_R8G8_UNORM,
    362         DXGI_FORMAT_R16_FLOAT,
    363         DXGI_FORMAT_R16G16_FLOAT,
    364         DXGI_FORMAT_R32_FLOAT,
    365         DXGI_FORMAT_R32G32_FLOAT,
    366     };
    367 
    368     mRGTextureSupport = true;
    369     for (unsigned int i = 0; i < ArraySize(rgTextureFormats); i++)
    370     {
    371         if (SUCCEEDED(mDevice->CheckFormatSupport(rgTextureFormats[i], &formatSupport)))
    372         {
    373             mRGTextureSupport = mRGTextureSupport && (formatSupport & requiredTextureFlags) == requiredTextureFlags;
    374             mRGTextureSupport = mRGTextureSupport && (formatSupport & requiredFilterFlags) == requiredFilterFlags;
    375             mRGTextureSupport = mRGTextureSupport && (formatSupport & requiredRenderableFlags) == requiredRenderableFlags;
    376         }
    377         else
    378         {
    379             mRGTextureSupport = false;
    380         }
    381     }
    382 
    383     // Check compressed texture support
    384     const unsigned int requiredCompressedTextureFlags = D3D11_FORMAT_SUPPORT_TEXTURE2D;
    385 
    386     if (SUCCEEDED(mDevice->CheckFormatSupport(DXGI_FORMAT_BC1_UNORM, &formatSupport)))
    387     {
    388         mDXT1TextureSupport = (formatSupport & requiredCompressedTextureFlags) == requiredCompressedTextureFlags;
    389     }
    390     else
    391     {
    392         mDXT1TextureSupport = false;
    393     }
    394 
    395     if (SUCCEEDED(mDevice->CheckFormatSupport(DXGI_FORMAT_BC3_UNORM, &formatSupport)))
    396     {
    397         mDXT3TextureSupport = (formatSupport & requiredCompressedTextureFlags) == requiredCompressedTextureFlags;
    398     }
    399     else
    400     {
    401         mDXT3TextureSupport = false;
    402     }
    403 
    404     if (SUCCEEDED(mDevice->CheckFormatSupport(DXGI_FORMAT_BC5_UNORM, &formatSupport)))
    405     {
    406         mDXT5TextureSupport = (formatSupport & requiredCompressedTextureFlags) == requiredCompressedTextureFlags;
    407     }
    408     else
    409     {
    410         mDXT5TextureSupport = false;
    411     }
    412 
    413     // Check depth texture support
    414     DXGI_FORMAT depthTextureFormats[] =
    415     {
    416         DXGI_FORMAT_D16_UNORM,
    417         DXGI_FORMAT_D24_UNORM_S8_UINT,
    418     };
    419 
    420     static const unsigned int requiredDepthTextureFlags = D3D11_FORMAT_SUPPORT_DEPTH_STENCIL |
    421                                                           D3D11_FORMAT_SUPPORT_TEXTURE2D;
    422 
    423     mDepthTextureSupport = true;
    424     for (unsigned int i = 0; i < ArraySize(depthTextureFormats); i++)
    425     {
    426         if (SUCCEEDED(mDevice->CheckFormatSupport(depthTextureFormats[i], &formatSupport)))
    427         {
    428             mDepthTextureSupport = mDepthTextureSupport && ((formatSupport & requiredDepthTextureFlags) == requiredDepthTextureFlags);
    429         }
    430         else
    431         {
    432             mDepthTextureSupport = false;
    433         }
    434     }
    435 
    436     return EGL_SUCCESS;
    437 }
    438 
    439 // do any one-time device initialization
    440 // NOTE: this is also needed after a device lost/reset
    441 // to reset the scene status and ensure the default states are reset.
    442 void Renderer11::initializeDevice()
    443 {
    444     mStateCache.initialize(mDevice);
    445     mInputLayoutCache.initialize(mDevice, mDeviceContext);
    446 
    447     ASSERT(!mVertexDataManager && !mIndexDataManager);
    448     mVertexDataManager = new VertexDataManager(this);
    449     mIndexDataManager = new IndexDataManager(this);
    450 
    451     ASSERT(!mBlit);
    452     mBlit = new Blit11(this);
    453 
    454     ASSERT(!mClear);
    455     mClear = new Clear11(this);
    456 
    457     ASSERT(!mPixelTransfer);
    458     mPixelTransfer = new PixelTransfer11(this);
    459 
    460     markAllStateDirty();
    461 }
    462 
    463 int Renderer11::generateConfigs(ConfigDesc **configDescList)
    464 {
    465     unsigned int numRenderFormats = ArraySize(RenderTargetFormats);
    466     unsigned int numDepthFormats = ArraySize(DepthStencilFormats);
    467     (*configDescList) = new ConfigDesc[numRenderFormats * numDepthFormats];
    468     int numConfigs = 0;
    469 
    470     for (unsigned int formatIndex = 0; formatIndex < numRenderFormats; formatIndex++)
    471     {
    472         for (unsigned int depthStencilIndex = 0; depthStencilIndex < numDepthFormats; depthStencilIndex++)
    473         {
    474             DXGI_FORMAT renderTargetFormat = RenderTargetFormats[formatIndex];
    475 
    476             UINT formatSupport = 0;
    477             HRESULT result = mDevice->CheckFormatSupport(renderTargetFormat, &formatSupport);
    478 
    479             if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET))
    480             {
    481                 DXGI_FORMAT depthStencilFormat = DepthStencilFormats[depthStencilIndex];
    482 
    483                 bool depthStencilFormatOK = true;
    484 
    485                 if (depthStencilFormat != DXGI_FORMAT_UNKNOWN)
    486                 {
    487                     UINT depthStencilSupport = 0;
    488                     result = mDevice->CheckFormatSupport(depthStencilFormat, &depthStencilSupport);
    489                     depthStencilFormatOK = SUCCEEDED(result) && (depthStencilSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL);
    490                 }
    491 
    492                 if (depthStencilFormatOK)
    493                 {
    494                     // FIXME: parse types from context version
    495                     ASSERT(d3d11_gl::GetInternalFormat(renderTargetFormat, 2) == d3d11_gl::GetInternalFormat(renderTargetFormat, 3));
    496                     ASSERT(d3d11_gl::GetInternalFormat(depthStencilFormat, 2) == d3d11_gl::GetInternalFormat(depthStencilFormat, 3));
    497 
    498                     ConfigDesc newConfig;
    499                     newConfig.renderTargetFormat = d3d11_gl::GetInternalFormat(renderTargetFormat, getCurrentClientVersion());
    500                     newConfig.depthStencilFormat = d3d11_gl::GetInternalFormat(depthStencilFormat, getCurrentClientVersion());
    501                     newConfig.multiSample = 0;     // FIXME: enumerate multi-sampling
    502                     newConfig.fastConfig = true;   // Assume all DX11 format conversions to be fast
    503                     newConfig.es3Capable = true;
    504 
    505                     (*configDescList)[numConfigs++] = newConfig;
    506                 }
    507             }
    508         }
    509     }
    510 
    511     return numConfigs;
    512 }
    513 
    514 void Renderer11::deleteConfigs(ConfigDesc *configDescList)
    515 {
    516     delete [] (configDescList);
    517 }
    518 
    519 void Renderer11::sync(bool block)
    520 {
    521     if (block)
    522     {
    523         HRESULT result;
    524 
    525         if (!mSyncQuery)
    526         {
    527             D3D11_QUERY_DESC queryDesc;
    528             queryDesc.Query = D3D11_QUERY_EVENT;
    529             queryDesc.MiscFlags = 0;
    530 
    531             result = mDevice->CreateQuery(&queryDesc, &mSyncQuery);
    532             ASSERT(SUCCEEDED(result));
    533         }
    534 
    535         mDeviceContext->End(mSyncQuery);
    536         mDeviceContext->Flush();
    537 
    538         do
    539         {
    540             result = mDeviceContext->GetData(mSyncQuery, NULL, 0, D3D11_ASYNC_GETDATA_DONOTFLUSH);
    541 
    542             // Keep polling, but allow other threads to do something useful first
    543             Sleep(0);
    544 
    545             if (testDeviceLost(true))
    546             {
    547                 return;
    548             }
    549         }
    550         while (result == S_FALSE);
    551     }
    552     else
    553     {
    554         mDeviceContext->Flush();
    555     }
    556 }
    557 
    558 SwapChain *Renderer11::createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
    559 {
    560     return new rx::SwapChain11(this, window, shareHandle, backBufferFormat, depthBufferFormat);
    561 }
    562 
    563 void Renderer11::generateSwizzle(gl::Texture *texture)
    564 {
    565     if (texture)
    566     {
    567         TextureStorageInterface *texStorage = texture->getNativeTexture();
    568         if (texStorage)
    569         {
    570             TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage->getStorageInstance());
    571 
    572             storage11->generateSwizzles(texture->getSwizzleRed(), texture->getSwizzleGreen(), texture->getSwizzleBlue(),
    573                                         texture->getSwizzleAlpha());
    574         }
    575     }
    576 }
    577 
    578 void Renderer11::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState)
    579 {
    580     if (type == gl::SAMPLER_PIXEL)
    581     {
    582         if (index < 0 || index >= gl::MAX_TEXTURE_IMAGE_UNITS)
    583         {
    584             ERR("Pixel shader sampler index %i is not valid.", index);
    585             return;
    586         }
    587 
    588         if (mForceSetPixelSamplerStates[index] || memcmp(&samplerState, &mCurPixelSamplerStates[index], sizeof(gl::SamplerState)) != 0)
    589         {
    590             ID3D11SamplerState *dxSamplerState = mStateCache.getSamplerState(samplerState);
    591 
    592             if (!dxSamplerState)
    593             {
    594                 ERR("NULL sampler state returned by RenderStateCache::getSamplerState, setting the default"
    595                     "sampler state for pixel shaders at slot %i.", index);
    596             }
    597 
    598             mDeviceContext->PSSetSamplers(index, 1, &dxSamplerState);
    599 
    600             mCurPixelSamplerStates[index] = samplerState;
    601         }
    602 
    603         mForceSetPixelSamplerStates[index] = false;
    604     }
    605     else if (type == gl::SAMPLER_VERTEX)
    606     {
    607         if (index < 0 || index >= (int)getMaxVertexTextureImageUnits())
    608         {
    609             ERR("Vertex shader sampler index %i is not valid.", index);
    610             return;
    611         }
    612 
    613         if (mForceSetVertexSamplerStates[index] || memcmp(&samplerState, &mCurVertexSamplerStates[index], sizeof(gl::SamplerState)) != 0)
    614         {
    615             ID3D11SamplerState *dxSamplerState = mStateCache.getSamplerState(samplerState);
    616 
    617             if (!dxSamplerState)
    618             {
    619                 ERR("NULL sampler state returned by RenderStateCache::getSamplerState, setting the default"
    620                     "sampler state for vertex shaders at slot %i.", index);
    621             }
    622 
    623             mDeviceContext->VSSetSamplers(index, 1, &dxSamplerState);
    624 
    625             mCurVertexSamplerStates[index] = samplerState;
    626         }
    627 
    628         mForceSetVertexSamplerStates[index] = false;
    629     }
    630     else UNREACHABLE();
    631 }
    632 
    633 void Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *texture)
    634 {
    635     ID3D11ShaderResourceView *textureSRV = NULL;
    636     bool forceSetTexture = false;
    637 
    638     if (texture)
    639     {
    640         TextureStorageInterface *texStorage = texture->getNativeTexture();
    641         if (texStorage)
    642         {
    643             TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage->getStorageInstance());
    644             gl::SamplerState samplerState;
    645             texture->getSamplerState(&samplerState);
    646             textureSRV = storage11->getSRV(samplerState);
    647         }
    648 
    649         // If we get NULL back from getSRV here, something went wrong in the texture class and we're unexpectedly
    650         // missing the shader resource view
    651         ASSERT(textureSRV != NULL);
    652 
    653         forceSetTexture = texture->hasDirtyImages();
    654     }
    655 
    656     if (type == gl::SAMPLER_PIXEL)
    657     {
    658         if (index < 0 || index >= gl::MAX_TEXTURE_IMAGE_UNITS)
    659         {
    660             ERR("Pixel shader sampler index %i is not valid.", index);
    661             return;
    662         }
    663 
    664         if (forceSetTexture || mCurPixelSRVs[index] != textureSRV)
    665         {
    666             mDeviceContext->PSSetShaderResources(index, 1, &textureSRV);
    667         }
    668 
    669         mCurPixelSRVs[index] = textureSRV;
    670     }
    671     else if (type == gl::SAMPLER_VERTEX)
    672     {
    673         if (index < 0 || index >= (int)getMaxVertexTextureImageUnits())
    674         {
    675             ERR("Vertex shader sampler index %i is not valid.", index);
    676             return;
    677         }
    678 
    679         if (forceSetTexture || mCurVertexSRVs[index] != textureSRV)
    680         {
    681             mDeviceContext->VSSetShaderResources(index, 1, &textureSRV);
    682         }
    683 
    684         mCurVertexSRVs[index] = textureSRV;
    685     }
    686     else UNREACHABLE();
    687 }
    688 
    689 bool Renderer11::setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[])
    690 {
    691     for (unsigned int uniformBufferIndex = 0; uniformBufferIndex < gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS; uniformBufferIndex++)
    692     {
    693         const gl::Buffer *uniformBuffer = vertexUniformBuffers[uniformBufferIndex];
    694         if (uniformBuffer)
    695         {
    696             BufferStorage11 *bufferStorage = BufferStorage11::makeBufferStorage11(uniformBuffer->getStorage());
    697             ID3D11Buffer *constantBuffer = bufferStorage->getBuffer(BUFFER_USAGE_UNIFORM);
    698 
    699             if (!constantBuffer)
    700             {
    701                 return false;
    702             }
    703 
    704             if (mCurrentConstantBufferVS[uniformBufferIndex] != bufferStorage->getSerial())
    705             {
    706                 mDeviceContext->VSSetConstantBuffers(getReservedVertexUniformBuffers() + uniformBufferIndex,
    707                                                      1, &constantBuffer);
    708                 mCurrentConstantBufferVS[uniformBufferIndex] = bufferStorage->getSerial();
    709             }
    710         }
    711     }
    712 
    713     for (unsigned int uniformBufferIndex = 0; uniformBufferIndex < gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS; uniformBufferIndex++)
    714     {
    715         const gl::Buffer *uniformBuffer = fragmentUniformBuffers[uniformBufferIndex];
    716         if (uniformBuffer)
    717         {
    718             BufferStorage11 *bufferStorage = BufferStorage11::makeBufferStorage11(uniformBuffer->getStorage());
    719             ID3D11Buffer *constantBuffer = bufferStorage->getBuffer(BUFFER_USAGE_UNIFORM);
    720 
    721             if (!constantBuffer)
    722             {
    723                 return false;
    724             }
    725 
    726             if (mCurrentConstantBufferPS[uniformBufferIndex] != bufferStorage->getSerial())
    727             {
    728                 mDeviceContext->PSSetConstantBuffers(getReservedFragmentUniformBuffers() + uniformBufferIndex,
    729                                                      1, &constantBuffer);
    730                 mCurrentConstantBufferPS[uniformBufferIndex] = bufferStorage->getSerial();
    731             }
    732         }
    733     }
    734 
    735     return true;
    736 }
    737 
    738 void Renderer11::setRasterizerState(const gl::RasterizerState &rasterState)
    739 {
    740     if (mForceSetRasterState || memcmp(&rasterState, &mCurRasterState, sizeof(gl::RasterizerState)) != 0)
    741     {
    742         ID3D11RasterizerState *dxRasterState = mStateCache.getRasterizerState(rasterState, mScissorEnabled);
    743         if (!dxRasterState)
    744         {
    745             ERR("NULL rasterizer state returned by RenderStateCache::getRasterizerState, setting the default"
    746                 "rasterizer state.");
    747         }
    748 
    749         mDeviceContext->RSSetState(dxRasterState);
    750 
    751         mCurRasterState = rasterState;
    752     }
    753 
    754     mForceSetRasterState = false;
    755 }
    756 
    757 void Renderer11::setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
    758                                unsigned int sampleMask)
    759 {
    760     if (mForceSetBlendState ||
    761         memcmp(&blendState, &mCurBlendState, sizeof(gl::BlendState)) != 0 ||
    762         memcmp(&blendColor, &mCurBlendColor, sizeof(gl::ColorF)) != 0 ||
    763         sampleMask != mCurSampleMask)
    764     {
    765         ID3D11BlendState *dxBlendState = mStateCache.getBlendState(framebuffer, blendState);
    766         if (!dxBlendState)
    767         {
    768             ERR("NULL blend state returned by RenderStateCache::getBlendState, setting the default "
    769                 "blend state.");
    770         }
    771 
    772         float blendColors[4] = {0.0f};
    773         if (blendState.sourceBlendRGB != GL_CONSTANT_ALPHA && blendState.sourceBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA &&
    774             blendState.destBlendRGB != GL_CONSTANT_ALPHA && blendState.destBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA)
    775         {
    776             blendColors[0] = blendColor.red;
    777             blendColors[1] = blendColor.green;
    778             blendColors[2] = blendColor.blue;
    779             blendColors[3] = blendColor.alpha;
    780         }
    781         else
    782         {
    783             blendColors[0] = blendColor.alpha;
    784             blendColors[1] = blendColor.alpha;
    785             blendColors[2] = blendColor.alpha;
    786             blendColors[3] = blendColor.alpha;
    787         }
    788 
    789         mDeviceContext->OMSetBlendState(dxBlendState, blendColors, sampleMask);
    790 
    791         mCurBlendState = blendState;
    792         mCurBlendColor = blendColor;
    793         mCurSampleMask = sampleMask;
    794     }
    795 
    796     mForceSetBlendState = false;
    797 }
    798 
    799 void Renderer11::setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
    800                                       int stencilBackRef, bool frontFaceCCW)
    801 {
    802     if (mForceSetDepthStencilState ||
    803         memcmp(&depthStencilState, &mCurDepthStencilState, sizeof(gl::DepthStencilState)) != 0 ||
    804         stencilRef != mCurStencilRef || stencilBackRef != mCurStencilBackRef)
    805     {
    806         if (depthStencilState.stencilWritemask != depthStencilState.stencilBackWritemask ||
    807             stencilRef != stencilBackRef ||
    808             depthStencilState.stencilMask != depthStencilState.stencilBackMask)
    809         {
    810             ERR("Separate front/back stencil writemasks, reference values, or stencil mask values are "
    811                 "invalid under WebGL.");
    812             return gl::error(GL_INVALID_OPERATION);
    813         }
    814 
    815         ID3D11DepthStencilState *dxDepthStencilState = mStateCache.getDepthStencilState(depthStencilState);
    816         if (!dxDepthStencilState)
    817         {
    818             ERR("NULL depth stencil state returned by RenderStateCache::getDepthStencilState, "
    819                 "setting the default depth stencil state.");
    820         }
    821 
    822         // Max D3D11 stencil reference value is 0xFF, corresponding to the max 8 bits in a stencil buffer
    823         // GL specifies we should clamp the ref value to the nearest bit depth when doing stencil ops
    824         META_ASSERT(D3D11_DEFAULT_STENCIL_READ_MASK == 0xFF);
    825         META_ASSERT(D3D11_DEFAULT_STENCIL_WRITE_MASK == 0xFF);
    826         UINT dxStencilRef = std::min<UINT>(stencilRef, 0xFFu);
    827 
    828         mDeviceContext->OMSetDepthStencilState(dxDepthStencilState, dxStencilRef);
    829 
    830         mCurDepthStencilState = depthStencilState;
    831         mCurStencilRef = stencilRef;
    832         mCurStencilBackRef = stencilBackRef;
    833     }
    834 
    835     mForceSetDepthStencilState = false;
    836 }
    837 
    838 void Renderer11::setScissorRectangle(const gl::Rectangle &scissor, bool enabled)
    839 {
    840     if (mForceSetScissor || memcmp(&scissor, &mCurScissor, sizeof(gl::Rectangle)) != 0 ||
    841         enabled != mScissorEnabled)
    842     {
    843         if (enabled)
    844         {
    845             D3D11_RECT rect;
    846             rect.left = std::max(0, scissor.x);
    847             rect.top = std::max(0, scissor.y);
    848             rect.right = scissor.x + std::max(0, scissor.width);
    849             rect.bottom = scissor.y + std::max(0, scissor.height);
    850 
    851             mDeviceContext->RSSetScissorRects(1, &rect);
    852         }
    853 
    854         if (enabled != mScissorEnabled)
    855         {
    856             mForceSetRasterState = true;
    857         }
    858 
    859         mCurScissor = scissor;
    860         mScissorEnabled = enabled;
    861     }
    862 
    863     mForceSetScissor = false;
    864 }
    865 
    866 bool Renderer11::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
    867                              bool ignoreViewport)
    868 {
    869     gl::Rectangle actualViewport = viewport;
    870     float actualZNear = gl::clamp01(zNear);
    871     float actualZFar = gl::clamp01(zFar);
    872     if (ignoreViewport)
    873     {
    874         actualViewport.x = 0;
    875         actualViewport.y = 0;
    876         actualViewport.width = mRenderTargetDesc.width;
    877         actualViewport.height = mRenderTargetDesc.height;
    878         actualZNear = 0.0f;
    879         actualZFar = 1.0f;
    880     }
    881 
    882     // Get D3D viewport bounds, which depends on the feature level
    883     const Range& viewportBounds = getViewportBounds();
    884 
    885     // Clamp width and height first to the gl maximum, then clamp further if we extend past the D3D maximum bounds
    886     D3D11_VIEWPORT dxViewport;
    887     dxViewport.TopLeftX = gl::clamp(actualViewport.x, viewportBounds.start, viewportBounds.end);
    888     dxViewport.TopLeftY = gl::clamp(actualViewport.y, viewportBounds.start, viewportBounds.end);
    889     dxViewport.Width = gl::clamp(actualViewport.width, 0, getMaxViewportDimension());
    890     dxViewport.Height = gl::clamp(actualViewport.height, 0, getMaxViewportDimension());
    891     dxViewport.Width = std::min((int)dxViewport.Width, viewportBounds.end - static_cast<int>(dxViewport.TopLeftX));
    892     dxViewport.Height = std::min((int)dxViewport.Height, viewportBounds.end - static_cast<int>(dxViewport.TopLeftY));
    893     dxViewport.MinDepth = actualZNear;
    894     dxViewport.MaxDepth = actualZFar;
    895 
    896     if (dxViewport.Width <= 0 || dxViewport.Height <= 0)
    897     {
    898         return false;   // Nothing to render
    899     }
    900 
    901     bool viewportChanged = mForceSetViewport || memcmp(&actualViewport, &mCurViewport, sizeof(gl::Rectangle)) != 0 ||
    902                            actualZNear != mCurNear || actualZFar != mCurFar;
    903 
    904     if (viewportChanged)
    905     {
    906         mDeviceContext->RSSetViewports(1, &dxViewport);
    907 
    908         mCurViewport = actualViewport;
    909         mCurNear = actualZNear;
    910         mCurFar = actualZFar;
    911 
    912         mPixelConstants.viewCoords[0] = actualViewport.width  * 0.5f;
    913         mPixelConstants.viewCoords[1] = actualViewport.height * 0.5f;
    914         mPixelConstants.viewCoords[2] = actualViewport.x + (actualViewport.width  * 0.5f);
    915         mPixelConstants.viewCoords[3] = actualViewport.y + (actualViewport.height * 0.5f);
    916 
    917         mPixelConstants.depthFront[0] = (actualZFar - actualZNear) * 0.5f;
    918         mPixelConstants.depthFront[1] = (actualZNear + actualZFar) * 0.5f;
    919 
    920         mVertexConstants.depthRange[0] = actualZNear;
    921         mVertexConstants.depthRange[1] = actualZFar;
    922         mVertexConstants.depthRange[2] = actualZFar - actualZNear;
    923 
    924         mPixelConstants.depthRange[0] = actualZNear;
    925         mPixelConstants.depthRange[1] = actualZFar;
    926         mPixelConstants.depthRange[2] = actualZFar - actualZNear;
    927     }
    928 
    929     mForceSetViewport = false;
    930     return true;
    931 }
    932 
    933 bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count)
    934 {
    935     D3D11_PRIMITIVE_TOPOLOGY primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
    936 
    937     GLsizei minCount = 0;
    938 
    939     switch (mode)
    940     {
    941       case GL_POINTS:         primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST;   minCount = 1; break;
    942       case GL_LINES:          primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINELIST;      minCount = 2; break;
    943       case GL_LINE_LOOP:      primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;     minCount = 2; break;
    944       case GL_LINE_STRIP:     primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;     minCount = 2; break;
    945       case GL_TRIANGLES:      primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;  minCount = 3; break;
    946       case GL_TRIANGLE_STRIP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; minCount = 3; break;
    947           // emulate fans via rewriting index buffer
    948       case GL_TRIANGLE_FAN:   primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;  minCount = 3; break;
    949       default:
    950         return gl::error(GL_INVALID_ENUM, false);
    951     }
    952 
    953     if (primitiveTopology != mCurrentPrimitiveTopology)
    954     {
    955         mDeviceContext->IASetPrimitiveTopology(primitiveTopology);
    956         mCurrentPrimitiveTopology = primitiveTopology;
    957     }
    958 
    959     return count >= minCount;
    960 }
    961 
    962 bool Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer)
    963 {
    964     // Get the color render buffer and serial
    965     // Also extract the render target dimensions and view
    966     unsigned int renderTargetWidth = 0;
    967     unsigned int renderTargetHeight = 0;
    968     GLenum renderTargetFormat = 0;
    969     unsigned int renderTargetSerials[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {0};
    970     ID3D11RenderTargetView* framebufferRTVs[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {NULL};
    971     bool missingColorRenderTarget = true;
    972 
    973     for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
    974     {
    975         const GLenum drawBufferState = framebuffer->getDrawBufferState(colorAttachment);
    976 
    977         if (framebuffer->getColorbufferType(colorAttachment) != GL_NONE && drawBufferState != GL_NONE)
    978         {
    979             // the draw buffer must be either "none", "back" for the default buffer or the same index as this color (in order)
    980             ASSERT(drawBufferState == GL_BACK || drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + colorAttachment));
    981 
    982             gl::FramebufferAttachment *colorbuffer = framebuffer->getColorbuffer(colorAttachment);
    983 
    984             if (!colorbuffer)
    985             {
    986                 ERR("render target pointer unexpectedly null.");
    987                 return false;
    988             }
    989 
    990             // check for zero-sized default framebuffer, which is a special case.
    991             // in this case we do not wish to modify any state and just silently return false.
    992             // this will not report any gl error but will cause the calling method to return.
    993             if (colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0)
    994             {
    995                 return false;
    996             }
    997 
    998             renderTargetSerials[colorAttachment] = colorbuffer->getSerial();
    999 
   1000             // Extract the render target dimensions and view
   1001             RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget());
   1002             if (!renderTarget)
   1003             {
   1004                 ERR("render target pointer unexpectedly null.");
   1005                 return false;
   1006             }
   1007 
   1008             framebufferRTVs[colorAttachment] = renderTarget->getRenderTargetView();
   1009             if (!framebufferRTVs[colorAttachment])
   1010             {
   1011                 ERR("render target view pointer unexpectedly null.");
   1012                 return false;
   1013             }
   1014 
   1015             if (missingColorRenderTarget)
   1016             {
   1017                 renderTargetWidth = colorbuffer->getWidth();
   1018                 renderTargetHeight = colorbuffer->getHeight();
   1019                 renderTargetFormat = colorbuffer->getActualFormat();
   1020                 missingColorRenderTarget = false;
   1021             }
   1022 
   1023             // TODO: Detect if this color buffer is already bound as a texture and unbind it first to prevent
   1024             //       D3D11 warnings.
   1025         }
   1026     }
   1027 
   1028     // Get the depth stencil render buffer and serials
   1029     gl::FramebufferAttachment *depthStencil = NULL;
   1030     unsigned int depthbufferSerial = 0;
   1031     unsigned int stencilbufferSerial = 0;
   1032     if (framebuffer->getDepthbufferType() != GL_NONE)
   1033     {
   1034         depthStencil = framebuffer->getDepthbuffer();
   1035         if (!depthStencil)
   1036         {
   1037             ERR("Depth stencil pointer unexpectedly null.");
   1038             SafeRelease(framebufferRTVs);
   1039             return false;
   1040         }
   1041 
   1042         depthbufferSerial = depthStencil->getSerial();
   1043     }
   1044     else if (framebuffer->getStencilbufferType() != GL_NONE)
   1045     {
   1046         depthStencil = framebuffer->getStencilbuffer();
   1047         if (!depthStencil)
   1048         {
   1049             ERR("Depth stencil pointer unexpectedly null.");
   1050             SafeRelease(framebufferRTVs);
   1051             return false;
   1052         }
   1053 
   1054         stencilbufferSerial = depthStencil->getSerial();
   1055     }
   1056 
   1057     ID3D11DepthStencilView* framebufferDSV = NULL;
   1058     if (depthStencil)
   1059     {
   1060         RenderTarget11 *depthStencilRenderTarget = RenderTarget11::makeRenderTarget11(depthStencil->getDepthStencil());
   1061         if (!depthStencilRenderTarget)
   1062         {
   1063             ERR("render target pointer unexpectedly null.");
   1064             SafeRelease(framebufferRTVs);
   1065             return false;
   1066         }
   1067 
   1068         framebufferDSV = depthStencilRenderTarget->getDepthStencilView();
   1069         if (!framebufferDSV)
   1070         {
   1071             ERR("depth stencil view pointer unexpectedly null.");
   1072             SafeRelease(framebufferRTVs);
   1073             return false;
   1074         }
   1075 
   1076         // If there is no render buffer, the width, height and format values come from
   1077         // the depth stencil
   1078         if (missingColorRenderTarget)
   1079         {
   1080             renderTargetWidth = depthStencil->getWidth();
   1081             renderTargetHeight = depthStencil->getHeight();
   1082             renderTargetFormat = depthStencil->getActualFormat();
   1083         }
   1084     }
   1085 
   1086     // Apply the render target and depth stencil
   1087     if (!mRenderTargetDescInitialized || !mDepthStencilInitialized ||
   1088         memcmp(renderTargetSerials, mAppliedRenderTargetSerials, sizeof(renderTargetSerials)) != 0 ||
   1089         depthbufferSerial != mAppliedDepthbufferSerial ||
   1090         stencilbufferSerial != mAppliedStencilbufferSerial)
   1091     {
   1092         mDeviceContext->OMSetRenderTargets(getMaxRenderTargets(), framebufferRTVs, framebufferDSV);
   1093 
   1094         mRenderTargetDesc.width = renderTargetWidth;
   1095         mRenderTargetDesc.height = renderTargetHeight;
   1096         mRenderTargetDesc.format = renderTargetFormat;
   1097         mForceSetViewport = true;
   1098         mForceSetScissor = true;
   1099         mForceSetBlendState = true;
   1100 
   1101         if (!mDepthStencilInitialized)
   1102         {
   1103             mForceSetRasterState = true;
   1104         }
   1105 
   1106         for (unsigned int rtIndex = 0; rtIndex < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; rtIndex++)
   1107         {
   1108             mAppliedRenderTargetSerials[rtIndex] = renderTargetSerials[rtIndex];
   1109         }
   1110         mAppliedDepthbufferSerial = depthbufferSerial;
   1111         mAppliedStencilbufferSerial = stencilbufferSerial;
   1112         mRenderTargetDescInitialized = true;
   1113         mDepthStencilInitialized = true;
   1114     }
   1115 
   1116     invalidateFramebufferSwizzles(framebuffer);
   1117 
   1118     return true;
   1119 }
   1120 
   1121 GLenum Renderer11::applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[],
   1122                                      GLint first, GLsizei count, GLsizei instances)
   1123 {
   1124     TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS];
   1125     GLenum err = mVertexDataManager->prepareVertexData(vertexAttributes, currentValues, programBinary, first, count, attributes, instances);
   1126     if (err != GL_NO_ERROR)
   1127     {
   1128         return err;
   1129     }
   1130 
   1131     return mInputLayoutCache.applyVertexBuffers(attributes, programBinary);
   1132 }
   1133 
   1134 GLenum Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
   1135 {
   1136     GLenum err = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo);
   1137 
   1138     if (err == GL_NO_ERROR)
   1139     {
   1140         ID3D11Buffer *buffer = NULL;
   1141         DXGI_FORMAT bufferFormat = (indexInfo->indexType == GL_UNSIGNED_INT) ? DXGI_FORMAT_R32_UINT : DXGI_FORMAT_R16_UINT;
   1142 
   1143         if (indexInfo->storage)
   1144         {
   1145             BufferStorage11 *storage = BufferStorage11::makeBufferStorage11(indexInfo->storage);
   1146             buffer = storage->getBuffer(BUFFER_USAGE_INDEX);
   1147         }
   1148         else
   1149         {
   1150             IndexBuffer11* indexBuffer = IndexBuffer11::makeIndexBuffer11(indexInfo->indexBuffer);
   1151             buffer = indexBuffer->getBuffer();
   1152         }
   1153 
   1154         if (buffer != mAppliedIB || bufferFormat != mAppliedIBFormat || indexInfo->startOffset != mAppliedIBOffset)
   1155         {
   1156             mDeviceContext->IASetIndexBuffer(buffer, bufferFormat, indexInfo->startOffset);
   1157 
   1158             mAppliedIB = buffer;
   1159             mAppliedIBFormat = bufferFormat;
   1160             mAppliedIBOffset = indexInfo->startOffset;
   1161         }
   1162     }
   1163 
   1164     return err;
   1165 }
   1166 
   1167 void Renderer11::applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[])
   1168 {
   1169     ID3D11Buffer* d3dBuffers[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
   1170     UINT d3dOffsets[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
   1171     bool requiresUpdate = false;
   1172     for (size_t i = 0; i < gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
   1173     {
   1174         if (transformFeedbackBuffers[i])
   1175         {
   1176             BufferStorage11 *storage = BufferStorage11::makeBufferStorage11(transformFeedbackBuffers[i]->getStorage());
   1177             ID3D11Buffer *buffer = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
   1178 
   1179             d3dBuffers[i] = buffer;
   1180             d3dOffsets[i] = (mAppliedTFBuffers[i] != buffer) ? static_cast<UINT>(offsets[i]) : -1;
   1181         }
   1182         else
   1183         {
   1184             d3dBuffers[i] = NULL;
   1185             d3dOffsets[i] = 0;
   1186         }
   1187 
   1188         if (d3dBuffers[i] != mAppliedTFBuffers[i] || offsets[i] != mAppliedTFOffsets[i])
   1189         {
   1190             requiresUpdate = true;
   1191         }
   1192     }
   1193 
   1194     if (requiresUpdate)
   1195     {
   1196         mDeviceContext->SOSetTargets(ArraySize(d3dBuffers), d3dBuffers, d3dOffsets);
   1197         for (size_t i = 0; i < gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
   1198         {
   1199             mAppliedTFBuffers[i] = d3dBuffers[i];
   1200             mAppliedTFOffsets[i] = offsets[i];
   1201         }
   1202     }
   1203 }
   1204 
   1205 void Renderer11::drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive)
   1206 {
   1207     if (mode == GL_POINTS && transformFeedbackActive)
   1208     {
   1209         // Since point sprites are generated with a geometry shader, too many vertices will
   1210         // be written if transform feedback is active.  To work around this, draw only the points
   1211         // with the stream out shader and no pixel shader to feed the stream out buffers and then
   1212         // draw again with the point sprite geometry shader to rasterize the point sprites.
   1213 
   1214         mDeviceContext->PSSetShader(NULL, NULL, 0);
   1215 
   1216         if (instances > 0)
   1217         {
   1218             mDeviceContext->DrawInstanced(count, instances, 0, 0);
   1219         }
   1220         else
   1221         {
   1222             mDeviceContext->Draw(count, 0);
   1223         }
   1224 
   1225         mDeviceContext->GSSetShader(mCurPointGeometryShader, NULL, 0);
   1226         mDeviceContext->PSSetShader(mAppliedPixelShader, NULL, 0);
   1227 
   1228         if (instances > 0)
   1229         {
   1230             mDeviceContext->DrawInstanced(count, instances, 0, 0);
   1231         }
   1232         else
   1233         {
   1234             mDeviceContext->Draw(count, 0);
   1235         }
   1236 
   1237         mDeviceContext->GSSetShader(mAppliedGeometryShader, NULL, 0);
   1238     }
   1239     else if (mode == GL_LINE_LOOP)
   1240     {
   1241         drawLineLoop(count, GL_NONE, NULL, 0, NULL);
   1242     }
   1243     else if (mode == GL_TRIANGLE_FAN)
   1244     {
   1245         drawTriangleFan(count, GL_NONE, NULL, 0, NULL, instances);
   1246     }
   1247     else if (instances > 0)
   1248     {
   1249         mDeviceContext->DrawInstanced(count, instances, 0, 0);
   1250     }
   1251     else
   1252     {
   1253         mDeviceContext->Draw(count, 0);
   1254     }
   1255 }
   1256 
   1257 void Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
   1258                               gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances)
   1259 {
   1260     if (mode == GL_LINE_LOOP)
   1261     {
   1262         drawLineLoop(count, type, indices, indexInfo.minIndex, elementArrayBuffer);
   1263     }
   1264     else if (mode == GL_TRIANGLE_FAN)
   1265     {
   1266         drawTriangleFan(count, type, indices, indexInfo.minIndex, elementArrayBuffer, instances);
   1267     }
   1268     else if (instances > 0)
   1269     {
   1270         mDeviceContext->DrawIndexedInstanced(count, instances, 0, -static_cast<int>(indexInfo.minIndex), 0);
   1271     }
   1272     else
   1273     {
   1274         mDeviceContext->DrawIndexed(count, 0, -static_cast<int>(indexInfo.minIndex));
   1275     }
   1276 }
   1277 
   1278 void Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer)
   1279 {
   1280     // Get the raw indices for an indexed draw
   1281     if (type != GL_NONE && elementArrayBuffer)
   1282     {
   1283         gl::Buffer *indexBuffer = elementArrayBuffer;
   1284         BufferStorage *storage = indexBuffer->getStorage();
   1285         intptr_t offset = reinterpret_cast<intptr_t>(indices);
   1286         indices = static_cast<const GLubyte*>(storage->getData()) + offset;
   1287     }
   1288 
   1289     if (!mLineLoopIB)
   1290     {
   1291         mLineLoopIB = new StreamingIndexBufferInterface(this);
   1292         if (!mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT))
   1293         {
   1294             delete mLineLoopIB;
   1295             mLineLoopIB = NULL;
   1296 
   1297             ERR("Could not create a 32-bit looping index buffer for GL_LINE_LOOP.");
   1298             return gl::error(GL_OUT_OF_MEMORY);
   1299         }
   1300     }
   1301 
   1302     // Checked by Renderer11::applyPrimitiveType
   1303     ASSERT(count >= 0);
   1304 
   1305     if (static_cast<unsigned int>(count) + 1 > (std::numeric_limits<unsigned int>::max() / sizeof(unsigned int)))
   1306     {
   1307         ERR("Could not create a 32-bit looping index buffer for GL_LINE_LOOP, too many indices required.");
   1308         return gl::error(GL_OUT_OF_MEMORY);
   1309     }
   1310 
   1311     const unsigned int spaceNeeded = (static_cast<unsigned int>(count) + 1) * sizeof(unsigned int);
   1312     if (!mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT))
   1313     {
   1314         ERR("Could not reserve enough space in looping index buffer for GL_LINE_LOOP.");
   1315         return gl::error(GL_OUT_OF_MEMORY);
   1316     }
   1317 
   1318     void* mappedMemory = NULL;
   1319     unsigned int offset;
   1320     if (!mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset))
   1321     {
   1322         ERR("Could not map index buffer for GL_LINE_LOOP.");
   1323         return gl::error(GL_OUT_OF_MEMORY);
   1324     }
   1325 
   1326     unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory);
   1327     unsigned int indexBufferOffset = offset;
   1328 
   1329     switch (type)
   1330     {
   1331       case GL_NONE:   // Non-indexed draw
   1332         for (int i = 0; i < count; i++)
   1333         {
   1334             data[i] = i;
   1335         }
   1336         data[count] = 0;
   1337         break;
   1338       case GL_UNSIGNED_BYTE:
   1339         for (int i = 0; i < count; i++)
   1340         {
   1341             data[i] = static_cast<const GLubyte*>(indices)[i];
   1342         }
   1343         data[count] = static_cast<const GLubyte*>(indices)[0];
   1344         break;
   1345       case GL_UNSIGNED_SHORT:
   1346         for (int i = 0; i < count; i++)
   1347         {
   1348             data[i] = static_cast<const GLushort*>(indices)[i];
   1349         }
   1350         data[count] = static_cast<const GLushort*>(indices)[0];
   1351         break;
   1352       case GL_UNSIGNED_INT:
   1353         for (int i = 0; i < count; i++)
   1354         {
   1355             data[i] = static_cast<const GLuint*>(indices)[i];
   1356         }
   1357         data[count] = static_cast<const GLuint*>(indices)[0];
   1358         break;
   1359       default: UNREACHABLE();
   1360     }
   1361 
   1362     if (!mLineLoopIB->unmapBuffer())
   1363     {
   1364         ERR("Could not unmap index buffer for GL_LINE_LOOP.");
   1365         return gl::error(GL_OUT_OF_MEMORY);
   1366     }
   1367 
   1368     IndexBuffer11 *indexBuffer = IndexBuffer11::makeIndexBuffer11(mLineLoopIB->getIndexBuffer());
   1369     ID3D11Buffer *d3dIndexBuffer = indexBuffer->getBuffer();
   1370     DXGI_FORMAT indexFormat = indexBuffer->getIndexFormat();
   1371 
   1372     if (mAppliedIB != d3dIndexBuffer || mAppliedIBFormat != indexFormat || mAppliedIBOffset != indexBufferOffset)
   1373     {
   1374         mDeviceContext->IASetIndexBuffer(d3dIndexBuffer, indexFormat, indexBufferOffset);
   1375         mAppliedIB = d3dIndexBuffer;
   1376         mAppliedIBFormat = indexFormat;
   1377         mAppliedIBOffset = indexBufferOffset;
   1378     }
   1379 
   1380     mDeviceContext->DrawIndexed(count + 1, 0, -minIndex);
   1381 }
   1382 
   1383 void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer, int instances)
   1384 {
   1385     // Get the raw indices for an indexed draw
   1386     if (type != GL_NONE && elementArrayBuffer)
   1387     {
   1388         gl::Buffer *indexBuffer = elementArrayBuffer;
   1389         BufferStorage *storage = indexBuffer->getStorage();
   1390         intptr_t offset = reinterpret_cast<intptr_t>(indices);
   1391         indices = static_cast<const GLubyte*>(storage->getData()) + offset;
   1392     }
   1393 
   1394     if (!mTriangleFanIB)
   1395     {
   1396         mTriangleFanIB = new StreamingIndexBufferInterface(this);
   1397         if (!mTriangleFanIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT))
   1398         {
   1399             delete mTriangleFanIB;
   1400             mTriangleFanIB = NULL;
   1401 
   1402             ERR("Could not create a scratch index buffer for GL_TRIANGLE_FAN.");
   1403             return gl::error(GL_OUT_OF_MEMORY);
   1404         }
   1405     }
   1406 
   1407     // Checked by Renderer11::applyPrimitiveType
   1408     ASSERT(count >= 3);
   1409 
   1410     const unsigned int numTris = count - 2;
   1411 
   1412     if (numTris > (std::numeric_limits<unsigned int>::max() / (sizeof(unsigned int) * 3)))
   1413     {
   1414         ERR("Could not create a scratch index buffer for GL_TRIANGLE_FAN, too many indices required.");
   1415         return gl::error(GL_OUT_OF_MEMORY);
   1416     }
   1417 
   1418     const unsigned int spaceNeeded = (numTris * 3) * sizeof(unsigned int);
   1419     if (!mTriangleFanIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT))
   1420     {
   1421         ERR("Could not reserve enough space in scratch index buffer for GL_TRIANGLE_FAN.");
   1422         return gl::error(GL_OUT_OF_MEMORY);
   1423     }
   1424 
   1425     void* mappedMemory = NULL;
   1426     unsigned int offset;
   1427     if (!mTriangleFanIB->mapBuffer(spaceNeeded, &mappedMemory, &offset))
   1428     {
   1429         ERR("Could not map scratch index buffer for GL_TRIANGLE_FAN.");
   1430         return gl::error(GL_OUT_OF_MEMORY);
   1431     }
   1432 
   1433     unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory);
   1434     unsigned int indexBufferOffset = offset;
   1435 
   1436     switch (type)
   1437     {
   1438       case GL_NONE:   // Non-indexed draw
   1439         for (unsigned int i = 0; i < numTris; i++)
   1440         {
   1441             data[i*3 + 0] = 0;
   1442             data[i*3 + 1] = i + 1;
   1443             data[i*3 + 2] = i + 2;
   1444         }
   1445         break;
   1446       case GL_UNSIGNED_BYTE:
   1447         for (unsigned int i = 0; i < numTris; i++)
   1448         {
   1449             data[i*3 + 0] = static_cast<const GLubyte*>(indices)[0];
   1450             data[i*3 + 1] = static_cast<const GLubyte*>(indices)[i + 1];
   1451             data[i*3 + 2] = static_cast<const GLubyte*>(indices)[i + 2];
   1452         }
   1453         break;
   1454       case GL_UNSIGNED_SHORT:
   1455         for (unsigned int i = 0; i < numTris; i++)
   1456         {
   1457             data[i*3 + 0] = static_cast<const GLushort*>(indices)[0];
   1458             data[i*3 + 1] = static_cast<const GLushort*>(indices)[i + 1];
   1459             data[i*3 + 2] = static_cast<const GLushort*>(indices)[i + 2];
   1460         }
   1461         break;
   1462       case GL_UNSIGNED_INT:
   1463         for (unsigned int i = 0; i < numTris; i++)
   1464         {
   1465             data[i*3 + 0] = static_cast<const GLuint*>(indices)[0];
   1466             data[i*3 + 1] = static_cast<const GLuint*>(indices)[i + 1];
   1467             data[i*3 + 2] = static_cast<const GLuint*>(indices)[i + 2];
   1468         }
   1469         break;
   1470       default: UNREACHABLE();
   1471     }
   1472 
   1473     if (!mTriangleFanIB->unmapBuffer())
   1474     {
   1475         ERR("Could not unmap scratch index buffer for GL_TRIANGLE_FAN.");
   1476         return gl::error(GL_OUT_OF_MEMORY);
   1477     }
   1478 
   1479     IndexBuffer11 *indexBuffer = IndexBuffer11::makeIndexBuffer11(mTriangleFanIB->getIndexBuffer());
   1480     ID3D11Buffer *d3dIndexBuffer = indexBuffer->getBuffer();
   1481     DXGI_FORMAT indexFormat = indexBuffer->getIndexFormat();
   1482 
   1483     if (mAppliedIB != d3dIndexBuffer || mAppliedIBFormat != indexFormat || mAppliedIBOffset != indexBufferOffset)
   1484     {
   1485         mDeviceContext->IASetIndexBuffer(d3dIndexBuffer, indexFormat, indexBufferOffset);
   1486         mAppliedIB = d3dIndexBuffer;
   1487         mAppliedIBFormat = indexFormat;
   1488         mAppliedIBOffset = indexBufferOffset;
   1489     }
   1490 
   1491     if (instances > 0)
   1492     {
   1493         mDeviceContext->DrawIndexedInstanced(numTris * 3, instances, 0, -minIndex, 0);
   1494     }
   1495     else
   1496     {
   1497         mDeviceContext->DrawIndexed(numTris * 3, 0, -minIndex);
   1498     }
   1499 }
   1500 
   1501 void Renderer11::applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard, bool transformFeedbackActive, const gl::VertexFormat inputLayout[])
   1502 {
   1503     ShaderExecutable *vertexExe = programBinary->getVertexExecutableForInputLayout(inputLayout);
   1504     ShaderExecutable *pixelExe = programBinary->getPixelExecutable();
   1505     ShaderExecutable *geometryExe = programBinary->getGeometryExecutable();
   1506 
   1507     ID3D11VertexShader *vertexShader = (vertexExe ? ShaderExecutable11::makeShaderExecutable11(vertexExe)->getVertexShader() : NULL);
   1508 
   1509     ID3D11PixelShader *pixelShader = NULL;
   1510     // Skip pixel shader if we're doing rasterizer discard.
   1511     if (!rasterizerDiscard)
   1512     {
   1513         pixelShader = (pixelExe ? ShaderExecutable11::makeShaderExecutable11(pixelExe)->getPixelShader() : NULL);
   1514     }
   1515 
   1516     ID3D11GeometryShader *geometryShader = NULL;
   1517     if (transformFeedbackActive)
   1518     {
   1519         geometryShader = (vertexExe ? ShaderExecutable11::makeShaderExecutable11(vertexExe)->getStreamOutShader() : NULL);
   1520     }
   1521     else if (mCurRasterState.pointDrawMode)
   1522     {
   1523         geometryShader = (geometryExe ? ShaderExecutable11::makeShaderExecutable11(geometryExe)->getGeometryShader() : NULL);
   1524     }
   1525 
   1526     bool dirtyUniforms = false;
   1527 
   1528     if (vertexShader != mAppliedVertexShader)
   1529     {
   1530         mDeviceContext->VSSetShader(vertexShader, NULL, 0);
   1531         mAppliedVertexShader = vertexShader;
   1532         dirtyUniforms = true;
   1533     }
   1534 
   1535     if (geometryShader != mAppliedGeometryShader)
   1536     {
   1537         mDeviceContext->GSSetShader(geometryShader, NULL, 0);
   1538         mAppliedGeometryShader = geometryShader;
   1539         dirtyUniforms = true;
   1540     }
   1541 
   1542     if (geometryExe && mCurRasterState.pointDrawMode)
   1543     {
   1544         mCurPointGeometryShader = ShaderExecutable11::makeShaderExecutable11(geometryExe)->getGeometryShader();
   1545     }
   1546     else
   1547     {
   1548         mCurPointGeometryShader = NULL;
   1549     }
   1550 
   1551     if (pixelShader != mAppliedPixelShader)
   1552     {
   1553         mDeviceContext->PSSetShader(pixelShader, NULL, 0);
   1554         mAppliedPixelShader = pixelShader;
   1555         dirtyUniforms = true;
   1556     }
   1557 
   1558     if (dirtyUniforms)
   1559     {
   1560         programBinary->dirtyAllUniforms();
   1561     }
   1562 }
   1563 
   1564 void Renderer11::applyUniforms(const gl::ProgramBinary &programBinary)
   1565 {
   1566     const std::vector<gl::LinkedUniform*> &uniformArray = programBinary.getUniforms();
   1567 
   1568     unsigned int totalRegisterCountVS = 0;
   1569     unsigned int totalRegisterCountPS = 0;
   1570 
   1571     bool vertexUniformsDirty = false;
   1572     bool pixelUniformsDirty = false;
   1573 
   1574     for (size_t uniformIndex = 0; uniformIndex < uniformArray.size(); uniformIndex++)
   1575     {
   1576         const gl::LinkedUniform &uniform = *uniformArray[uniformIndex];
   1577 
   1578         if (uniform.isReferencedByVertexShader() && !uniform.isSampler())
   1579         {
   1580             totalRegisterCountVS += uniform.registerCount;
   1581             vertexUniformsDirty = (vertexUniformsDirty || uniform.dirty);
   1582         }
   1583 
   1584         if (uniform.isReferencedByFragmentShader() && !uniform.isSampler())
   1585         {
   1586             totalRegisterCountPS += uniform.registerCount;
   1587             pixelUniformsDirty = (pixelUniformsDirty || uniform.dirty);
   1588         }
   1589     }
   1590 
   1591     const UniformStorage11 *vertexUniformStorage = UniformStorage11::makeUniformStorage11(&programBinary.getVertexUniformStorage());
   1592     const UniformStorage11 *fragmentUniformStorage = UniformStorage11::makeUniformStorage11(&programBinary.getFragmentUniformStorage());
   1593     ASSERT(vertexUniformStorage);
   1594     ASSERT(fragmentUniformStorage);
   1595 
   1596     ID3D11Buffer *vertexConstantBuffer = vertexUniformStorage->getConstantBuffer();
   1597     ID3D11Buffer *pixelConstantBuffer = fragmentUniformStorage->getConstantBuffer();
   1598 
   1599     float (*mapVS)[4] = NULL;
   1600     float (*mapPS)[4] = NULL;
   1601 
   1602     if (totalRegisterCountVS > 0 && vertexUniformsDirty)
   1603     {
   1604         D3D11_MAPPED_SUBRESOURCE map = {0};
   1605         HRESULT result = mDeviceContext->Map(vertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
   1606         UNUSED_ASSERTION_VARIABLE(result);
   1607         ASSERT(SUCCEEDED(result));
   1608         mapVS = (float(*)[4])map.pData;
   1609     }
   1610 
   1611     if (totalRegisterCountPS > 0 && pixelUniformsDirty)
   1612     {
   1613         D3D11_MAPPED_SUBRESOURCE map = {0};
   1614         HRESULT result = mDeviceContext->Map(pixelConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
   1615         UNUSED_ASSERTION_VARIABLE(result);
   1616         ASSERT(SUCCEEDED(result));
   1617         mapPS = (float(*)[4])map.pData;
   1618     }
   1619 
   1620     for (size_t uniformIndex = 0; uniformIndex < uniformArray.size(); uniformIndex++)
   1621     {
   1622         gl::LinkedUniform *uniform = uniformArray[uniformIndex];
   1623 
   1624         if (!uniform->isSampler())
   1625         {
   1626             unsigned int componentCount = (4 - uniform->registerElement);
   1627 
   1628             // we assume that uniforms from structs are arranged in struct order in our uniforms list. otherwise we would
   1629             // overwrite previously written regions of memory.
   1630 
   1631             if (uniform->isReferencedByVertexShader() && mapVS)
   1632             {
   1633                 memcpy(&mapVS[uniform->vsRegisterIndex][uniform->registerElement], uniform->data, uniform->registerCount * sizeof(float) * componentCount);
   1634             }
   1635 
   1636             if (uniform->isReferencedByFragmentShader() && mapPS)
   1637             {
   1638                 memcpy(&mapPS[uniform->psRegisterIndex][uniform->registerElement], uniform->data, uniform->registerCount * sizeof(float) * componentCount);
   1639             }
   1640         }
   1641     }
   1642 
   1643     if (mapVS)
   1644     {
   1645         mDeviceContext->Unmap(vertexConstantBuffer, 0);
   1646     }
   1647 
   1648     if (mapPS)
   1649     {
   1650         mDeviceContext->Unmap(pixelConstantBuffer, 0);
   1651     }
   1652 
   1653     if (mCurrentVertexConstantBuffer != vertexConstantBuffer)
   1654     {
   1655         mDeviceContext->VSSetConstantBuffers(0, 1, &vertexConstantBuffer);
   1656         mCurrentVertexConstantBuffer = vertexConstantBuffer;
   1657     }
   1658 
   1659     if (mCurrentPixelConstantBuffer != pixelConstantBuffer)
   1660     {
   1661         mDeviceContext->PSSetConstantBuffers(0, 1, &pixelConstantBuffer);
   1662         mCurrentPixelConstantBuffer = pixelConstantBuffer;
   1663     }
   1664 
   1665     // Driver uniforms
   1666     if (!mDriverConstantBufferVS)
   1667     {
   1668         D3D11_BUFFER_DESC constantBufferDescription = {0};
   1669         constantBufferDescription.ByteWidth = sizeof(dx_VertexConstants);
   1670         constantBufferDescription.Usage = D3D11_USAGE_DEFAULT;
   1671         constantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
   1672         constantBufferDescription.CPUAccessFlags = 0;
   1673         constantBufferDescription.MiscFlags = 0;
   1674         constantBufferDescription.StructureByteStride = 0;
   1675 
   1676         HRESULT result = mDevice->CreateBuffer(&constantBufferDescription, NULL, &mDriverConstantBufferVS);
   1677         UNUSED_ASSERTION_VARIABLE(result);
   1678         ASSERT(SUCCEEDED(result));
   1679 
   1680         mDeviceContext->VSSetConstantBuffers(1, 1, &mDriverConstantBufferVS);
   1681     }
   1682 
   1683     if (!mDriverConstantBufferPS)
   1684     {
   1685         D3D11_BUFFER_DESC constantBufferDescription = {0};
   1686         constantBufferDescription.ByteWidth = sizeof(dx_PixelConstants);
   1687         constantBufferDescription.Usage = D3D11_USAGE_DEFAULT;
   1688         constantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
   1689         constantBufferDescription.CPUAccessFlags = 0;
   1690         constantBufferDescription.MiscFlags = 0;
   1691         constantBufferDescription.StructureByteStride = 0;
   1692 
   1693         HRESULT result = mDevice->CreateBuffer(&constantBufferDescription, NULL, &mDriverConstantBufferPS);
   1694         UNUSED_ASSERTION_VARIABLE(result);
   1695         ASSERT(SUCCEEDED(result));
   1696 
   1697         mDeviceContext->PSSetConstantBuffers(1, 1, &mDriverConstantBufferPS);
   1698     }
   1699 
   1700     if (memcmp(&mVertexConstants, &mAppliedVertexConstants, sizeof(dx_VertexConstants)) != 0)
   1701     {
   1702         mDeviceContext->UpdateSubresource(mDriverConstantBufferVS, 0, NULL, &mVertexConstants, 16, 0);
   1703         memcpy(&mAppliedVertexConstants, &mVertexConstants, sizeof(dx_VertexConstants));
   1704     }
   1705 
   1706     if (memcmp(&mPixelConstants, &mAppliedPixelConstants, sizeof(dx_PixelConstants)) != 0)
   1707     {
   1708         mDeviceContext->UpdateSubresource(mDriverConstantBufferPS, 0, NULL, &mPixelConstants, 16, 0);
   1709         memcpy(&mAppliedPixelConstants, &mPixelConstants, sizeof(dx_PixelConstants));
   1710     }
   1711 
   1712     // needed for the point sprite geometry shader
   1713     if (mCurrentGeometryConstantBuffer != mDriverConstantBufferPS)
   1714     {
   1715         mDeviceContext->GSSetConstantBuffers(0, 1, &mDriverConstantBufferPS);
   1716         mCurrentGeometryConstantBuffer = mDriverConstantBufferPS;
   1717     }
   1718 }
   1719 
   1720 void Renderer11::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer)
   1721 {
   1722     mClear->clearFramebuffer(clearParams, frameBuffer);
   1723     invalidateFramebufferSwizzles(frameBuffer);
   1724 }
   1725 
   1726 void Renderer11::markAllStateDirty()
   1727 {
   1728     for (unsigned int rtIndex = 0; rtIndex < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; rtIndex++)
   1729     {
   1730         mAppliedRenderTargetSerials[rtIndex] = 0;
   1731     }
   1732     mAppliedDepthbufferSerial = 0;
   1733     mAppliedStencilbufferSerial = 0;
   1734     mDepthStencilInitialized = false;
   1735     mRenderTargetDescInitialized = false;
   1736 
   1737     for (int i = 0; i < gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; i++)
   1738     {
   1739         mForceSetVertexSamplerStates[i] = true;
   1740         mCurVertexSRVs[i] = NULL;
   1741     }
   1742     for (int i = 0; i < gl::MAX_TEXTURE_IMAGE_UNITS; i++)
   1743     {
   1744         mForceSetPixelSamplerStates[i] = true;
   1745         mCurPixelSRVs[i] = NULL;
   1746     }
   1747 
   1748     mForceSetBlendState = true;
   1749     mForceSetRasterState = true;
   1750     mForceSetDepthStencilState = true;
   1751     mForceSetScissor = true;
   1752     mForceSetViewport = true;
   1753 
   1754     mAppliedIB = NULL;
   1755     mAppliedIBFormat = DXGI_FORMAT_UNKNOWN;
   1756     mAppliedIBOffset = 0;
   1757 
   1758     mAppliedVertexShader = NULL;
   1759     mAppliedGeometryShader = NULL;
   1760     mCurPointGeometryShader = NULL;
   1761     mAppliedPixelShader = NULL;
   1762 
   1763     for (size_t i = 0; i < gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
   1764     {
   1765         mAppliedTFBuffers[i] = NULL;
   1766         mAppliedTFOffsets[i] = 0;
   1767     }
   1768 
   1769     memset(&mAppliedVertexConstants, 0, sizeof(dx_VertexConstants));
   1770     memset(&mAppliedPixelConstants, 0, sizeof(dx_PixelConstants));
   1771 
   1772     mInputLayoutCache.markDirty();
   1773 
   1774     for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS; i++)
   1775     {
   1776         mCurrentConstantBufferVS[i] = -1;
   1777         mCurrentConstantBufferPS[i] = -1;
   1778     }
   1779 
   1780     mCurrentVertexConstantBuffer = NULL;
   1781     mCurrentPixelConstantBuffer = NULL;
   1782     mCurrentGeometryConstantBuffer = NULL;
   1783 
   1784     mCurrentPrimitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
   1785 }
   1786 
   1787 void Renderer11::releaseDeviceResources()
   1788 {
   1789     mStateCache.clear();
   1790     mInputLayoutCache.clear();
   1791 
   1792     SafeDelete(mVertexDataManager);
   1793     SafeDelete(mIndexDataManager);
   1794     SafeDelete(mLineLoopIB);
   1795     SafeDelete(mTriangleFanIB);
   1796     SafeDelete(mBlit);
   1797     SafeDelete(mClear);
   1798     SafeDelete(mPixelTransfer);
   1799 
   1800     SafeRelease(mDriverConstantBufferVS);
   1801     SafeRelease(mDriverConstantBufferPS);
   1802     SafeRelease(mSyncQuery);
   1803 }
   1804 
   1805 void Renderer11::notifyDeviceLost()
   1806 {
   1807     mDeviceLost = true;
   1808     mDisplay->notifyDeviceLost();
   1809 }
   1810 
   1811 bool Renderer11::isDeviceLost()
   1812 {
   1813     return mDeviceLost;
   1814 }
   1815 
   1816 // set notify to true to broadcast a message to all contexts of the device loss
   1817 bool Renderer11::testDeviceLost(bool notify)
   1818 {
   1819     bool isLost = false;
   1820 
   1821     // GetRemovedReason is used to test if the device is removed
   1822     HRESULT result = mDevice->GetDeviceRemovedReason();
   1823     isLost = d3d11::isDeviceLostError(result);
   1824 
   1825     if (isLost)
   1826     {
   1827         // Log error if this is a new device lost event
   1828         if (mDeviceLost == false)
   1829         {
   1830             ERR("The D3D11 device was removed: 0x%08X", result);
   1831         }
   1832 
   1833         // ensure we note the device loss --
   1834         // we'll probably get this done again by notifyDeviceLost
   1835         // but best to remember it!
   1836         // Note that we don't want to clear the device loss status here
   1837         // -- this needs to be done by resetDevice
   1838         mDeviceLost = true;
   1839         if (notify)
   1840         {
   1841             notifyDeviceLost();
   1842         }
   1843     }
   1844 
   1845     return isLost;
   1846 }
   1847 
   1848 bool Renderer11::testDeviceResettable()
   1849 {
   1850     // determine if the device is resettable by creating a dummy device
   1851     PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice");
   1852 
   1853     if (D3D11CreateDevice == NULL)
   1854     {
   1855         return false;
   1856     }
   1857 
   1858     D3D_FEATURE_LEVEL featureLevels[] =
   1859     {
   1860         D3D_FEATURE_LEVEL_11_0,
   1861         D3D_FEATURE_LEVEL_10_1,
   1862         D3D_FEATURE_LEVEL_10_0,
   1863     };
   1864 
   1865     ID3D11Device* dummyDevice;
   1866     D3D_FEATURE_LEVEL dummyFeatureLevel;
   1867     ID3D11DeviceContext* dummyContext;
   1868 
   1869     HRESULT result = D3D11CreateDevice(NULL,
   1870                                        D3D_DRIVER_TYPE_HARDWARE,
   1871                                        NULL,
   1872                                        #if defined(_DEBUG)
   1873                                        D3D11_CREATE_DEVICE_DEBUG,
   1874                                        #else
   1875                                        0,
   1876                                        #endif
   1877                                        featureLevels,
   1878                                        ArraySize(featureLevels),
   1879                                        D3D11_SDK_VERSION,
   1880                                        &dummyDevice,
   1881                                        &dummyFeatureLevel,
   1882                                        &dummyContext);
   1883 
   1884     if (!mDevice || FAILED(result))
   1885     {
   1886         return false;
   1887     }
   1888 
   1889     SafeRelease(dummyContext);
   1890     SafeRelease(dummyDevice);
   1891 
   1892     return true;
   1893 }
   1894 
   1895 void Renderer11::release()
   1896 {
   1897     releaseDeviceResources();
   1898 
   1899     SafeRelease(mDxgiFactory);
   1900     SafeRelease(mDxgiAdapter);
   1901 
   1902     if (mDeviceContext)
   1903     {
   1904         mDeviceContext->ClearState();
   1905         mDeviceContext->Flush();
   1906         SafeRelease(mDeviceContext);
   1907     }
   1908 
   1909     SafeRelease(mDevice);
   1910 
   1911     if (mD3d11Module)
   1912     {
   1913         FreeLibrary(mD3d11Module);
   1914         mD3d11Module = NULL;
   1915     }
   1916 
   1917     if (mDxgiModule)
   1918     {
   1919         FreeLibrary(mDxgiModule);
   1920         mDxgiModule = NULL;
   1921     }
   1922 
   1923     mCompiler.release();
   1924 }
   1925 
   1926 bool Renderer11::resetDevice()
   1927 {
   1928     // recreate everything
   1929     release();
   1930     EGLint result = initialize();
   1931 
   1932     if (result != EGL_SUCCESS)
   1933     {
   1934         ERR("Could not reinitialize D3D11 device: %08X", result);
   1935         return false;
   1936     }
   1937 
   1938     mDeviceLost = false;
   1939 
   1940     return true;
   1941 }
   1942 
   1943 DWORD Renderer11::getAdapterVendor() const
   1944 {
   1945     return mAdapterDescription.VendorId;
   1946 }
   1947 
   1948 std::string Renderer11::getRendererDescription() const
   1949 {
   1950     std::ostringstream rendererString;
   1951 
   1952     rendererString << mDescription;
   1953     rendererString << " Direct3D11";
   1954 
   1955     rendererString << " vs_" << getMajorShaderModel() << "_" << getMinorShaderModel();
   1956     rendererString << " ps_" << getMajorShaderModel() << "_" << getMinorShaderModel();
   1957 
   1958     return rendererString.str();
   1959 }
   1960 
   1961 GUID Renderer11::getAdapterIdentifier() const
   1962 {
   1963     // Use the adapter LUID as our adapter ID
   1964     // This number is local to a machine is only guaranteed to be unique between restarts
   1965     META_ASSERT(sizeof(LUID) <= sizeof(GUID));
   1966     GUID adapterId = {0};
   1967     memcpy(&adapterId, &mAdapterDescription.AdapterLuid, sizeof(LUID));
   1968     return adapterId;
   1969 }
   1970 
   1971 bool Renderer11::getBGRATextureSupport() const
   1972 {
   1973     return mBGRATextureSupport;
   1974 }
   1975 
   1976 bool Renderer11::getDXT1TextureSupport() const
   1977 {
   1978     return mDXT1TextureSupport;
   1979 }
   1980 
   1981 bool Renderer11::getDXT3TextureSupport() const
   1982 {
   1983     return mDXT3TextureSupport;
   1984 }
   1985 
   1986 bool Renderer11::getDXT5TextureSupport() const
   1987 {
   1988     return mDXT5TextureSupport;
   1989 }
   1990 
   1991 bool Renderer11::getDepthTextureSupport() const
   1992 {
   1993     return mDepthTextureSupport;
   1994 }
   1995 
   1996 bool Renderer11::getFloat32TextureSupport() const
   1997 {
   1998     return mFloat32TextureSupport;
   1999 }
   2000 
   2001 bool Renderer11::getFloat32TextureFilteringSupport() const
   2002 {
   2003     return mFloat32FilterSupport;
   2004 }
   2005 
   2006 bool Renderer11::getFloat32TextureRenderingSupport() const
   2007 {
   2008     return mFloat32RenderSupport;
   2009 }
   2010 
   2011 bool Renderer11::getFloat16TextureSupport() const
   2012 {
   2013     return mFloat16TextureSupport;
   2014 }
   2015 
   2016 bool Renderer11::getFloat16TextureFilteringSupport() const
   2017 {
   2018     return mFloat16FilterSupport;
   2019 }
   2020 
   2021 bool Renderer11::getFloat16TextureRenderingSupport() const
   2022 {
   2023     return mFloat16RenderSupport;
   2024 }
   2025 
   2026 bool Renderer11::getRGB565TextureSupport() const
   2027 {
   2028     return false;
   2029 }
   2030 
   2031 bool Renderer11::getLuminanceTextureSupport() const
   2032 {
   2033     return false;
   2034 }
   2035 
   2036 bool Renderer11::getLuminanceAlphaTextureSupport() const
   2037 {
   2038     return false;
   2039 }
   2040 
   2041 bool Renderer11::getRGTextureSupport() const
   2042 {
   2043     return mRGTextureSupport;
   2044 }
   2045 
   2046 bool Renderer11::getTextureFilterAnisotropySupport() const
   2047 {
   2048     return true;
   2049 }
   2050 
   2051 bool Renderer11::getPBOSupport() const
   2052 {
   2053     return true;
   2054 }
   2055 
   2056 float Renderer11::getTextureMaxAnisotropy() const
   2057 {
   2058     switch (mFeatureLevel)
   2059     {
   2060       case D3D_FEATURE_LEVEL_11_0:
   2061         return D3D11_MAX_MAXANISOTROPY;
   2062       case D3D_FEATURE_LEVEL_10_1:
   2063       case D3D_FEATURE_LEVEL_10_0:
   2064         return D3D10_MAX_MAXANISOTROPY;
   2065       default: UNREACHABLE();
   2066         return 0;
   2067     }
   2068 }
   2069 
   2070 bool Renderer11::getEventQuerySupport() const
   2071 {
   2072     return true;
   2073 }
   2074 
   2075 Range Renderer11::getViewportBounds() const
   2076 {
   2077     switch (mFeatureLevel)
   2078     {
   2079       case D3D_FEATURE_LEVEL_11_0:
   2080         return Range(D3D11_VIEWPORT_BOUNDS_MIN, D3D11_VIEWPORT_BOUNDS_MAX);
   2081       case D3D_FEATURE_LEVEL_10_1:
   2082       case D3D_FEATURE_LEVEL_10_0:
   2083         return Range(D3D10_VIEWPORT_BOUNDS_MIN, D3D10_VIEWPORT_BOUNDS_MAX);
   2084       default: UNREACHABLE();
   2085         return Range(0, 0);
   2086     }
   2087 }
   2088 
   2089 unsigned int Renderer11::getMaxVertexTextureImageUnits() const
   2090 {
   2091     META_ASSERT(MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 <= gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
   2092     switch (mFeatureLevel)
   2093     {
   2094       case D3D_FEATURE_LEVEL_11_0:
   2095       case D3D_FEATURE_LEVEL_10_1:
   2096       case D3D_FEATURE_LEVEL_10_0:
   2097         return MAX_TEXTURE_IMAGE_UNITS_VTF_SM4;
   2098       default: UNREACHABLE();
   2099         return 0;
   2100     }
   2101 }
   2102 
   2103 unsigned int Renderer11::getMaxCombinedTextureImageUnits() const
   2104 {
   2105     return gl::MAX_TEXTURE_IMAGE_UNITS + getMaxVertexTextureImageUnits();
   2106 }
   2107 
   2108 unsigned int Renderer11::getReservedVertexUniformVectors() const
   2109 {
   2110     return 0;   // Driver uniforms are stored in a separate constant buffer
   2111 }
   2112 
   2113 unsigned int Renderer11::getReservedFragmentUniformVectors() const
   2114 {
   2115     return 0;   // Driver uniforms are stored in a separate constant buffer
   2116 }
   2117 
   2118 unsigned int Renderer11::getMaxVertexUniformVectors() const
   2119 {
   2120     META_ASSERT(MAX_VERTEX_UNIFORM_VECTORS_D3D11 <= D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT);
   2121     ASSERT(mFeatureLevel >= D3D_FEATURE_LEVEL_10_0);
   2122     return MAX_VERTEX_UNIFORM_VECTORS_D3D11;
   2123 }
   2124 
   2125 unsigned int Renderer11::getMaxFragmentUniformVectors() const
   2126 {
   2127     META_ASSERT(MAX_FRAGMENT_UNIFORM_VECTORS_D3D11 <= D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT);
   2128     ASSERT(mFeatureLevel >= D3D_FEATURE_LEVEL_10_0);
   2129     return MAX_FRAGMENT_UNIFORM_VECTORS_D3D11;
   2130 }
   2131 
   2132 unsigned int Renderer11::getMaxVaryingVectors() const
   2133 {
   2134     META_ASSERT(gl::IMPLEMENTATION_MAX_VARYING_VECTORS == D3D11_VS_OUTPUT_REGISTER_COUNT);
   2135     META_ASSERT(D3D11_VS_OUTPUT_REGISTER_COUNT <= D3D11_PS_INPUT_REGISTER_COUNT);
   2136     META_ASSERT(D3D10_VS_OUTPUT_REGISTER_COUNT <= D3D10_PS_INPUT_REGISTER_COUNT);
   2137     switch (mFeatureLevel)
   2138     {
   2139       case D3D_FEATURE_LEVEL_11_0:
   2140         return D3D11_VS_OUTPUT_REGISTER_COUNT - getReservedVaryings();
   2141       case D3D_FEATURE_LEVEL_10_1:
   2142         return D3D10_1_VS_OUTPUT_REGISTER_COUNT - getReservedVaryings();
   2143       case D3D_FEATURE_LEVEL_10_0:
   2144         return D3D10_VS_OUTPUT_REGISTER_COUNT - getReservedVaryings();
   2145       default: UNREACHABLE();
   2146         return 0;
   2147     }
   2148 }
   2149 
   2150 unsigned int Renderer11::getMaxVertexShaderUniformBuffers() const
   2151 {
   2152     META_ASSERT(gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS >= D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT &&
   2153                 gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS >= D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT);
   2154 
   2155     switch (mFeatureLevel)
   2156     {
   2157       case D3D_FEATURE_LEVEL_11_0:
   2158         return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - getReservedVertexUniformBuffers();
   2159       case D3D_FEATURE_LEVEL_10_1:
   2160       case D3D_FEATURE_LEVEL_10_0:
   2161         return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - getReservedVertexUniformBuffers();
   2162       default: UNREACHABLE();
   2163         return 0;
   2164     }
   2165 }
   2166 
   2167 unsigned int Renderer11::getMaxFragmentShaderUniformBuffers() const
   2168 {
   2169     META_ASSERT(gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS >= D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT &&
   2170                 gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS >= D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT);
   2171 
   2172     switch (mFeatureLevel)
   2173     {
   2174       case D3D_FEATURE_LEVEL_11_0:
   2175         return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - getReservedFragmentUniformBuffers();
   2176       case D3D_FEATURE_LEVEL_10_1:
   2177       case D3D_FEATURE_LEVEL_10_0:
   2178         return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - getReservedFragmentUniformBuffers();
   2179       default: UNREACHABLE();
   2180         return 0;
   2181     }
   2182 }
   2183 
   2184 unsigned int Renderer11::getReservedVertexUniformBuffers() const
   2185 {
   2186     // we reserve one buffer for the application uniforms, and one for driver uniforms
   2187     return 2;
   2188 }
   2189 
   2190 unsigned int Renderer11::getReservedFragmentUniformBuffers() const
   2191 {
   2192     // we reserve one buffer for the application uniforms, and one for driver uniforms
   2193     return 2;
   2194 }
   2195 
   2196 unsigned int Renderer11::getReservedVaryings() const
   2197 {
   2198     // We potentially reserve varyings for gl_Position, _dx_Position, gl_FragCoord and gl_PointSize
   2199     return 4;
   2200 }
   2201 
   2202 
   2203 unsigned int Renderer11::getMaxTransformFeedbackBuffers() const
   2204 {
   2205     META_ASSERT(gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS >= D3D11_SO_BUFFER_SLOT_COUNT &&
   2206                 gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS >= D3D10_SO_BUFFER_SLOT_COUNT);
   2207 
   2208     switch (mFeatureLevel)
   2209     {
   2210       case D3D_FEATURE_LEVEL_11_0:
   2211         return D3D11_SO_BUFFER_SLOT_COUNT;
   2212       case D3D_FEATURE_LEVEL_10_1:
   2213         return D3D10_1_SO_BUFFER_SLOT_COUNT;
   2214       case D3D_FEATURE_LEVEL_10_0:
   2215         return D3D10_SO_BUFFER_SLOT_COUNT;
   2216       default: UNREACHABLE();
   2217         return 0;
   2218     }
   2219 }
   2220 
   2221 unsigned int Renderer11::getMaxTransformFeedbackSeparateComponents() const
   2222 {
   2223     switch (mFeatureLevel)
   2224     {
   2225       case D3D_FEATURE_LEVEL_11_0:
   2226         return getMaxTransformFeedbackInterleavedComponents() / getMaxTransformFeedbackBuffers();
   2227       case D3D_FEATURE_LEVEL_10_1:
   2228       case D3D_FEATURE_LEVEL_10_0:
   2229         // D3D 10 and 10.1 only allow one output per output slot if an output slot other than zero
   2230         // is used.
   2231         return 4;
   2232       default: UNREACHABLE();
   2233         return 0;
   2234     }
   2235 }
   2236 
   2237 unsigned int Renderer11::getMaxTransformFeedbackInterleavedComponents() const
   2238 {
   2239     return (getMaxVaryingVectors() * 4);
   2240 }
   2241 
   2242 unsigned int Renderer11::getMaxUniformBufferSize() const
   2243 {
   2244     // Each component is a 4-element vector of 4-byte units (floats)
   2245     const unsigned int bytesPerComponent = 4 * sizeof(float);
   2246 
   2247     switch (mFeatureLevel)
   2248     {
   2249       case D3D_FEATURE_LEVEL_11_0:
   2250         return D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent;
   2251       case D3D_FEATURE_LEVEL_10_1:
   2252       case D3D_FEATURE_LEVEL_10_0:
   2253         return D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent;
   2254       default: UNREACHABLE();
   2255         return 0;
   2256     }
   2257 }
   2258 
   2259 bool Renderer11::getNonPower2TextureSupport() const
   2260 {
   2261     switch (mFeatureLevel)
   2262     {
   2263       case D3D_FEATURE_LEVEL_11_0:
   2264       case D3D_FEATURE_LEVEL_10_1:
   2265       case D3D_FEATURE_LEVEL_10_0:
   2266         return true;
   2267       default: UNREACHABLE();
   2268         return false;
   2269     }
   2270 }
   2271 
   2272 bool Renderer11::getOcclusionQuerySupport() const
   2273 {
   2274     switch (mFeatureLevel)
   2275     {
   2276       case D3D_FEATURE_LEVEL_11_0:
   2277       case D3D_FEATURE_LEVEL_10_1:
   2278       case D3D_FEATURE_LEVEL_10_0:
   2279         return true;
   2280       default: UNREACHABLE();
   2281         return false;
   2282     }
   2283 }
   2284 
   2285 bool Renderer11::getInstancingSupport() const
   2286 {
   2287     switch (mFeatureLevel)
   2288     {
   2289       case D3D_FEATURE_LEVEL_11_0:
   2290       case D3D_FEATURE_LEVEL_10_1:
   2291       case D3D_FEATURE_LEVEL_10_0:
   2292         return true;
   2293       default: UNREACHABLE();
   2294         return false;
   2295     }
   2296 }
   2297 
   2298 bool Renderer11::getShareHandleSupport() const
   2299 {
   2300     // We only currently support share handles with BGRA surfaces, because
   2301     // chrome needs BGRA. Once chrome fixes this, we should always support them.
   2302     // PIX doesn't seem to support using share handles, so disable them.
   2303     return getBGRATextureSupport() && !gl::perfActive();
   2304 }
   2305 
   2306 bool Renderer11::getDerivativeInstructionSupport() const
   2307 {
   2308     switch (mFeatureLevel)
   2309     {
   2310       case D3D_FEATURE_LEVEL_11_0:
   2311       case D3D_FEATURE_LEVEL_10_1:
   2312       case D3D_FEATURE_LEVEL_10_0:
   2313         return true;
   2314       default: UNREACHABLE();
   2315         return false;
   2316     }
   2317 }
   2318 
   2319 bool Renderer11::getPostSubBufferSupport() const
   2320 {
   2321     // D3D11 does not support present with dirty rectangles until D3D11.1 and DXGI 1.2.
   2322     return false;
   2323 }
   2324 
   2325 int Renderer11::getMaxRecommendedElementsIndices() const
   2326 {
   2327     META_ASSERT(D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32);
   2328     META_ASSERT(D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32);
   2329 
   2330     // D3D11 allows up to 2^32 elements, but we report max signed int for convenience.
   2331     return std::numeric_limits<GLint>::max();
   2332 }
   2333 
   2334 int Renderer11::getMaxRecommendedElementsVertices() const
   2335 {
   2336     META_ASSERT(D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32);
   2337     META_ASSERT(D3D10_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32);
   2338 
   2339     // D3D11 allows up to 2^32 elements, but we report max signed int for convenience.
   2340     return std::numeric_limits<GLint>::max();
   2341 }
   2342 
   2343 int Renderer11::getMajorShaderModel() const
   2344 {
   2345     switch (mFeatureLevel)
   2346     {
   2347       case D3D_FEATURE_LEVEL_11_0: return D3D11_SHADER_MAJOR_VERSION;   // 5
   2348       case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SHADER_MAJOR_VERSION; // 4
   2349       case D3D_FEATURE_LEVEL_10_0: return D3D10_SHADER_MAJOR_VERSION;   // 4
   2350       default: UNREACHABLE();      return 0;
   2351     }
   2352 }
   2353 
   2354 int Renderer11::getMinorShaderModel() const
   2355 {
   2356     switch (mFeatureLevel)
   2357     {
   2358       case D3D_FEATURE_LEVEL_11_0: return D3D11_SHADER_MINOR_VERSION;   // 0
   2359       case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SHADER_MINOR_VERSION; // 1
   2360       case D3D_FEATURE_LEVEL_10_0: return D3D10_SHADER_MINOR_VERSION;   // 0
   2361       default: UNREACHABLE();      return 0;
   2362     }
   2363 }
   2364 
   2365 float Renderer11::getMaxPointSize() const
   2366 {
   2367     // choose a reasonable maximum. we enforce this in the shader.
   2368     // (nb: on a Radeon 2600xt, DX9 reports a 256 max point size)
   2369     return 1024.0f;
   2370 }
   2371 
   2372 int Renderer11::getMaxViewportDimension() const
   2373 {
   2374     // Maximum viewport size must be at least as large as the largest render buffer (or larger).
   2375     // In our case return the maximum texture size, which is the maximum render buffer size.
   2376     META_ASSERT(D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION * 2 - 1 <= D3D11_VIEWPORT_BOUNDS_MAX);
   2377     META_ASSERT(D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION * 2 - 1 <= D3D10_VIEWPORT_BOUNDS_MAX);
   2378 
   2379     switch (mFeatureLevel)
   2380     {
   2381       case D3D_FEATURE_LEVEL_11_0:
   2382         return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;   // 16384
   2383       case D3D_FEATURE_LEVEL_10_1:
   2384       case D3D_FEATURE_LEVEL_10_0:
   2385         return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION;   // 8192
   2386       default: UNREACHABLE();
   2387         return 0;
   2388     }
   2389 }
   2390 
   2391 int Renderer11::getMaxTextureWidth() const
   2392 {
   2393     switch (mFeatureLevel)
   2394     {
   2395       case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;   // 16384
   2396       case D3D_FEATURE_LEVEL_10_1:
   2397       case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION;   // 8192
   2398       default: UNREACHABLE();      return 0;
   2399     }
   2400 }
   2401 
   2402 int Renderer11::getMaxTextureHeight() const
   2403 {
   2404     switch (mFeatureLevel)
   2405     {
   2406       case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;   // 16384
   2407       case D3D_FEATURE_LEVEL_10_1:
   2408       case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION;   // 8192
   2409       default: UNREACHABLE();      return 0;
   2410     }
   2411 }
   2412 
   2413 int Renderer11::getMaxTextureDepth() const
   2414 {
   2415     switch (mFeatureLevel)
   2416     {
   2417       case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION;   // 2048
   2418       case D3D_FEATURE_LEVEL_10_1:
   2419       case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE3D_U_V_OR_W_DIMENSION;   // 2048
   2420       default: UNREACHABLE();      return 0;
   2421     }
   2422 }
   2423 
   2424 int Renderer11::getMaxTextureArrayLayers() const
   2425 {
   2426     switch (mFeatureLevel)
   2427     {
   2428       case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION;   // 2048
   2429       case D3D_FEATURE_LEVEL_10_1:
   2430       case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION;   // 512
   2431       default: UNREACHABLE();      return 0;
   2432     }
   2433 }
   2434 
   2435 bool Renderer11::get32BitIndexSupport() const
   2436 {
   2437     switch (mFeatureLevel)
   2438     {
   2439       case D3D_FEATURE_LEVEL_11_0:
   2440       case D3D_FEATURE_LEVEL_10_1:
   2441       case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP >= 32;   // true
   2442       default: UNREACHABLE();      return false;
   2443     }
   2444 }
   2445 
   2446 int Renderer11::getMinSwapInterval() const
   2447 {
   2448     return 0;
   2449 }
   2450 
   2451 int Renderer11::getMaxSwapInterval() const
   2452 {
   2453     return 4;
   2454 }
   2455 
   2456 int Renderer11::getMaxSupportedSamples() const
   2457 {
   2458     return mMaxSupportedSamples;
   2459 }
   2460 
   2461 GLsizei Renderer11::getMaxSupportedFormatSamples(GLenum internalFormat) const
   2462 {
   2463     DXGI_FORMAT format = gl_d3d11::GetRenderableFormat(internalFormat, getCurrentClientVersion());
   2464     MultisampleSupportMap::const_iterator iter = mMultisampleSupportMap.find(format);
   2465     return (iter != mMultisampleSupportMap.end()) ? iter->second.maxSupportedSamples : 0;
   2466 }
   2467 
   2468 GLsizei Renderer11::getNumSampleCounts(GLenum internalFormat) const
   2469 {
   2470     unsigned int numCounts = 0;
   2471 
   2472     // D3D11 supports multisampling for signed and unsigned format, but ES 3.0 does not
   2473     GLenum componentType = gl::GetComponentType(internalFormat, getCurrentClientVersion());
   2474     if (componentType != GL_INT && componentType != GL_UNSIGNED_INT)
   2475     {
   2476         DXGI_FORMAT format = gl_d3d11::GetRenderableFormat(internalFormat, getCurrentClientVersion());
   2477         MultisampleSupportMap::const_iterator iter = mMultisampleSupportMap.find(format);
   2478 
   2479         if (iter != mMultisampleSupportMap.end())
   2480         {
   2481             const MultisampleSupportInfo& info = iter->second;
   2482             for (int i = 0; i < D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; i++)
   2483             {
   2484                 if (info.qualityLevels[i] > 0)
   2485                 {
   2486                     numCounts++;
   2487                 }
   2488             }
   2489         }
   2490     }
   2491 
   2492     return numCounts;
   2493 }
   2494 
   2495 void Renderer11::getSampleCounts(GLenum internalFormat, GLsizei bufSize, GLint *params) const
   2496 {
   2497     // D3D11 supports multisampling for signed and unsigned format, but ES 3.0 does not
   2498     GLenum componentType = gl::GetComponentType(internalFormat, getCurrentClientVersion());
   2499     if (componentType == GL_INT || componentType == GL_UNSIGNED_INT)
   2500     {
   2501         return;
   2502     }
   2503 
   2504     DXGI_FORMAT format = gl_d3d11::GetRenderableFormat(internalFormat, getCurrentClientVersion());
   2505     MultisampleSupportMap::const_iterator iter = mMultisampleSupportMap.find(format);
   2506 
   2507     if (iter != mMultisampleSupportMap.end())
   2508     {
   2509         const MultisampleSupportInfo& info = iter->second;
   2510         int bufPos = 0;
   2511         for (int i = D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT - 1; i >= 0 && bufPos < bufSize; i--)
   2512         {
   2513             if (info.qualityLevels[i] > 0)
   2514             {
   2515                 params[bufPos++] = i + 1;
   2516             }
   2517         }
   2518     }
   2519 }
   2520 
   2521 int Renderer11::getNearestSupportedSamples(DXGI_FORMAT format, unsigned int requested) const
   2522 {
   2523     if (requested == 0)
   2524     {
   2525         return 0;
   2526     }
   2527 
   2528     MultisampleSupportMap::const_iterator iter = mMultisampleSupportMap.find(format);
   2529     if (iter != mMultisampleSupportMap.end())
   2530     {
   2531         const MultisampleSupportInfo& info = iter->second;
   2532         for (unsigned int i = requested - 1; i < D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; i++)
   2533         {
   2534             if (info.qualityLevels[i] > 0)
   2535             {
   2536                 return i + 1;
   2537             }
   2538         }
   2539     }
   2540 
   2541     return -1;
   2542 }
   2543 
   2544 unsigned int Renderer11::getMaxRenderTargets() const
   2545 {
   2546     META_ASSERT(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT <= gl::IMPLEMENTATION_MAX_DRAW_BUFFERS);
   2547     META_ASSERT(D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT <= gl::IMPLEMENTATION_MAX_DRAW_BUFFERS);
   2548 
   2549     switch (mFeatureLevel)
   2550     {
   2551       case D3D_FEATURE_LEVEL_11_0:
   2552         return D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT;  // 8
   2553       case D3D_FEATURE_LEVEL_10_1:
   2554       case D3D_FEATURE_LEVEL_10_0:
   2555         // Feature level 10.0 and 10.1 cards perform very poorly when the pixel shader
   2556         // outputs to multiple RTs that are not bound.
   2557         // TODO: Remove pixel shader outputs for render targets that are not bound.
   2558         return 1;
   2559       default:
   2560         UNREACHABLE();
   2561         return 1;
   2562     }
   2563 }
   2564 
   2565 bool Renderer11::copyToRenderTarget(TextureStorageInterface2D *dest, TextureStorageInterface2D *source)
   2566 {
   2567     if (source && dest)
   2568     {
   2569         TextureStorage11_2D *source11 = TextureStorage11_2D::makeTextureStorage11_2D(source->getStorageInstance());
   2570         TextureStorage11_2D *dest11 = TextureStorage11_2D::makeTextureStorage11_2D(dest->getStorageInstance());
   2571 
   2572         mDeviceContext->CopyResource(dest11->getResource(), source11->getResource());
   2573 
   2574         dest11->invalidateSwizzleCache();
   2575 
   2576         return true;
   2577     }
   2578 
   2579     return false;
   2580 }
   2581 
   2582 bool Renderer11::copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureStorageInterfaceCube *source)
   2583 {
   2584     if (source && dest)
   2585     {
   2586         TextureStorage11_Cube *source11 = TextureStorage11_Cube::makeTextureStorage11_Cube(source->getStorageInstance());
   2587         TextureStorage11_Cube *dest11 = TextureStorage11_Cube::makeTextureStorage11_Cube(dest->getStorageInstance());
   2588 
   2589         mDeviceContext->CopyResource(dest11->getResource(), source11->getResource());
   2590 
   2591         dest11->invalidateSwizzleCache();
   2592 
   2593         return true;
   2594     }
   2595 
   2596     return false;
   2597 }
   2598 
   2599 bool Renderer11::copyToRenderTarget(TextureStorageInterface3D *dest, TextureStorageInterface3D *source)
   2600 {
   2601     if (source && dest)
   2602     {
   2603         TextureStorage11_3D *source11 = TextureStorage11_3D::makeTextureStorage11_3D(source->getStorageInstance());
   2604         TextureStorage11_3D *dest11 = TextureStorage11_3D::makeTextureStorage11_3D(dest->getStorageInstance());
   2605 
   2606         mDeviceContext->CopyResource(dest11->getResource(), source11->getResource());
   2607 
   2608         dest11->invalidateSwizzleCache();
   2609 
   2610         return true;
   2611     }
   2612 
   2613     return false;
   2614 }
   2615 
   2616 bool Renderer11::copyToRenderTarget(TextureStorageInterface2DArray *dest, TextureStorageInterface2DArray *source)
   2617 {
   2618     if (source && dest)
   2619     {
   2620         TextureStorage11_2DArray *source11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(source->getStorageInstance());
   2621         TextureStorage11_2DArray *dest11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(dest->getStorageInstance());
   2622 
   2623         mDeviceContext->CopyResource(dest11->getResource(), source11->getResource());
   2624 
   2625         dest11->invalidateSwizzleCache();
   2626 
   2627         return true;
   2628     }
   2629 
   2630     return false;
   2631 }
   2632 
   2633 bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
   2634                            GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level)
   2635 {
   2636     gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
   2637     if (!colorbuffer)
   2638     {
   2639         ERR("Failed to retrieve the color buffer from the frame buffer.");
   2640         return gl::error(GL_OUT_OF_MEMORY, false);
   2641     }
   2642 
   2643     RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget());
   2644     if (!sourceRenderTarget)
   2645     {
   2646         ERR("Failed to retrieve the render target from the frame buffer.");
   2647         return gl::error(GL_OUT_OF_MEMORY, false);
   2648     }
   2649 
   2650     ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
   2651     if (!source)
   2652     {
   2653         ERR("Failed to retrieve the render target view from the render target.");
   2654         return gl::error(GL_OUT_OF_MEMORY, false);
   2655     }
   2656 
   2657     TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage->getStorageInstance());
   2658     if (!storage11)
   2659     {
   2660         ERR("Failed to retrieve the texture storage from the destination.");
   2661         return gl::error(GL_OUT_OF_MEMORY, false);
   2662     }
   2663 
   2664     RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(level));
   2665     if (!destRenderTarget)
   2666     {
   2667         ERR("Failed to retrieve the render target from the destination storage.");
   2668         return gl::error(GL_OUT_OF_MEMORY, false);
   2669     }
   2670 
   2671     ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView();
   2672     if (!dest)
   2673     {
   2674         ERR("Failed to retrieve the render target view from the destination render target.");
   2675         return gl::error(GL_OUT_OF_MEMORY, false);
   2676     }
   2677 
   2678     gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
   2679     gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1);
   2680 
   2681     gl::Box destArea(xoffset, yoffset, 0, sourceRect.width, sourceRect.height, 1);
   2682     gl::Extents destSize(destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1);
   2683 
   2684     // Use nearest filtering because source and destination are the same size for the direct
   2685     // copy
   2686     bool ret = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL,
   2687                                   destFormat, GL_NEAREST);
   2688 
   2689     storage11->invalidateSwizzleCacheLevel(level);
   2690 
   2691     return ret;
   2692 }
   2693 
   2694 bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
   2695                            GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level)
   2696 {
   2697     gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
   2698     if (!colorbuffer)
   2699     {
   2700         ERR("Failed to retrieve the color buffer from the frame buffer.");
   2701         return gl::error(GL_OUT_OF_MEMORY, false);
   2702     }
   2703 
   2704     RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget());
   2705     if (!sourceRenderTarget)
   2706     {
   2707         ERR("Failed to retrieve the render target from the frame buffer.");
   2708         return gl::error(GL_OUT_OF_MEMORY, false);
   2709     }
   2710 
   2711     ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
   2712     if (!source)
   2713     {
   2714         ERR("Failed to retrieve the render target view from the render target.");
   2715         return gl::error(GL_OUT_OF_MEMORY, false);
   2716     }
   2717 
   2718     TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage->getStorageInstance());
   2719     if (!storage11)
   2720     {
   2721         ERR("Failed to retrieve the texture storage from the destination.");
   2722         return gl::error(GL_OUT_OF_MEMORY, false);
   2723     }
   2724 
   2725     RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTargetFace(target, level));
   2726     if (!destRenderTarget)
   2727     {
   2728         ERR("Failed to retrieve the render target from the destination storage.");
   2729         return gl::error(GL_OUT_OF_MEMORY, false);
   2730     }
   2731 
   2732     ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView();
   2733     if (!dest)
   2734     {
   2735         ERR("Failed to retrieve the render target view from the destination render target.");
   2736         return gl::error(GL_OUT_OF_MEMORY, false);
   2737     }
   2738 
   2739     gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
   2740     gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1);
   2741 
   2742     gl::Box destArea(xoffset, yoffset, 0, sourceRect.width, sourceRect.height, 1);
   2743     gl::Extents destSize(destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1);
   2744 
   2745     // Use nearest filtering because source and destination are the same size for the direct
   2746     // copy
   2747     bool ret = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL,
   2748                                   destFormat, GL_NEAREST);
   2749 
   2750     storage11->invalidateSwizzleCacheLevel(level);
   2751 
   2752     return ret;
   2753 }
   2754 
   2755 bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
   2756                            GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface3D *storage, GLint level)
   2757 {
   2758     gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
   2759     if (!colorbuffer)
   2760     {
   2761         ERR("Failed to retrieve the color buffer from the frame buffer.");
   2762         return gl::error(GL_OUT_OF_MEMORY, false);
   2763     }
   2764 
   2765     RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget());
   2766     if (!sourceRenderTarget)
   2767     {
   2768         ERR("Failed to retrieve the render target from the frame buffer.");
   2769         return gl::error(GL_OUT_OF_MEMORY, false);
   2770     }
   2771 
   2772     ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
   2773     if (!source)
   2774     {
   2775         ERR("Failed to retrieve the render target view from the render target.");
   2776         return gl::error(GL_OUT_OF_MEMORY, false);
   2777     }
   2778 
   2779     TextureStorage11_3D *storage11 = TextureStorage11_3D::makeTextureStorage11_3D(storage->getStorageInstance());
   2780     if (!storage11)
   2781     {
   2782         ERR("Failed to retrieve the texture storage from the destination.");
   2783         return gl::error(GL_OUT_OF_MEMORY, false);
   2784     }
   2785 
   2786     RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTargetLayer(level, zOffset));
   2787     if (!destRenderTarget)
   2788     {
   2789         ERR("Failed to retrieve the render target from the destination storage.");
   2790         return gl::error(GL_OUT_OF_MEMORY, false);
   2791     }
   2792 
   2793     ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView();
   2794     if (!dest)
   2795     {
   2796         ERR("Failed to retrieve the render target view from the destination render target.");
   2797         return gl::error(GL_OUT_OF_MEMORY, false);
   2798     }
   2799 
   2800     gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
   2801     gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1);
   2802 
   2803     gl::Box destArea(xoffset, yoffset, 0, sourceRect.width, sourceRect.height, 1);
   2804     gl::Extents destSize(destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1);
   2805 
   2806     // Use nearest filtering because source and destination are the same size for the direct
   2807     // copy
   2808     bool ret = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL,
   2809                                   destFormat, GL_NEAREST);
   2810 
   2811     storage11->invalidateSwizzleCacheLevel(level);
   2812 
   2813     return ret;
   2814 }
   2815 
   2816 bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
   2817                            GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface2DArray *storage, GLint level)
   2818 {
   2819     gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
   2820     if (!colorbuffer)
   2821     {
   2822         ERR("Failed to retrieve the color buffer from the frame buffer.");
   2823         return gl::error(GL_OUT_OF_MEMORY, false);
   2824     }
   2825 
   2826     RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget());
   2827     if (!sourceRenderTarget)
   2828     {
   2829         ERR("Failed to retrieve the render target from the frame buffer.");
   2830         return gl::error(GL_OUT_OF_MEMORY, false);
   2831     }
   2832 
   2833     ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
   2834     if (!source)
   2835     {
   2836         ERR("Failed to retrieve the render target view from the render target.");
   2837         return gl::error(GL_OUT_OF_MEMORY, false);
   2838     }
   2839 
   2840     TextureStorage11_2DArray *storage11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(storage->getStorageInstance());
   2841     if (!storage11)
   2842     {
   2843         SafeRelease(source);
   2844         ERR("Failed to retrieve the texture storage from the destination.");
   2845         return gl::error(GL_OUT_OF_MEMORY, false);
   2846     }
   2847 
   2848     RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTargetLayer(level, zOffset));
   2849     if (!destRenderTarget)
   2850     {
   2851         SafeRelease(source);
   2852         ERR("Failed to retrieve the render target from the destination storage.");
   2853         return gl::error(GL_OUT_OF_MEMORY, false);
   2854     }
   2855 
   2856     ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView();
   2857     if (!dest)
   2858     {
   2859         ERR("Failed to retrieve the render target view from the destination render target.");
   2860         return gl::error(GL_OUT_OF_MEMORY, false);
   2861     }
   2862 
   2863     gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
   2864     gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1);
   2865 
   2866     gl::Box destArea(xoffset, yoffset, 0, sourceRect.width, sourceRect.height, 1);
   2867     gl::Extents destSize(destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1);
   2868 
   2869     // Use nearest filtering because source and destination are the same size for the direct
   2870     // copy
   2871     bool ret = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL,
   2872                                   destFormat, GL_NEAREST);
   2873 
   2874     storage11->invalidateSwizzleCacheLevel(level);
   2875 
   2876     return ret;
   2877 }
   2878 
   2879 void Renderer11::unapplyRenderTargets()
   2880 {
   2881     setOneTimeRenderTarget(NULL);
   2882 }
   2883 
   2884 void Renderer11::setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView)
   2885 {
   2886     ID3D11RenderTargetView *rtvArray[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {NULL};
   2887 
   2888     rtvArray[0] = renderTargetView;
   2889 
   2890     mDeviceContext->OMSetRenderTargets(getMaxRenderTargets(), rtvArray, NULL);
   2891 
   2892     // Do not preserve the serial for this one-time-use render target
   2893     for (unsigned int rtIndex = 0; rtIndex < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; rtIndex++)
   2894     {
   2895         mAppliedRenderTargetSerials[rtIndex] = 0;
   2896     }
   2897 }
   2898 
   2899 RenderTarget *Renderer11::createRenderTarget(SwapChain *swapChain, bool depth)
   2900 {
   2901     SwapChain11 *swapChain11 = SwapChain11::makeSwapChain11(swapChain);
   2902     RenderTarget11 *renderTarget = NULL;
   2903 
   2904     if (depth)
   2905     {
   2906         // Note: depth stencil may be NULL for 0 sized surfaces
   2907         renderTarget = new RenderTarget11(this, swapChain11->getDepthStencil(),
   2908                                           swapChain11->getDepthStencilTexture(),
   2909                                           swapChain11->getDepthStencilShaderResource(),
   2910                                           swapChain11->getWidth(), swapChain11->getHeight(), 1);
   2911     }
   2912     else
   2913     {
   2914         // Note: render target may be NULL for 0 sized surfaces
   2915         renderTarget = new RenderTarget11(this, swapChain11->getRenderTarget(),
   2916                                           swapChain11->getOffscreenTexture(),
   2917                                           swapChain11->getRenderTargetShaderResource(),
   2918                                           swapChain11->getWidth(), swapChain11->getHeight(), 1);
   2919     }
   2920     return renderTarget;
   2921 }
   2922 
   2923 RenderTarget *Renderer11::createRenderTarget(int width, int height, GLenum format, GLsizei samples)
   2924 {
   2925     RenderTarget11 *renderTarget = new RenderTarget11(this, width, height, format, samples);
   2926     return renderTarget;
   2927 }
   2928 
   2929 ShaderExecutable *Renderer11::loadExecutable(const void *function, size_t length, rx::ShaderType type,
   2930                                              const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
   2931                                              bool separatedOutputBuffers)
   2932 {
   2933     ShaderExecutable11 *executable = NULL;
   2934     HRESULT result;
   2935 
   2936     switch (type)
   2937     {
   2938       case rx::SHADER_VERTEX:
   2939         {
   2940             ID3D11VertexShader *vertexShader = NULL;
   2941             ID3D11GeometryShader *streamOutShader = NULL;
   2942 
   2943             result = mDevice->CreateVertexShader(function, length, NULL, &vertexShader);
   2944             ASSERT(SUCCEEDED(result));
   2945 
   2946             if (transformFeedbackVaryings.size() > 0)
   2947             {
   2948                 std::vector<D3D11_SO_DECLARATION_ENTRY> soDeclaration;
   2949                 for (size_t i = 0; i < transformFeedbackVaryings.size(); i++)
   2950                 {
   2951                     const gl::LinkedVarying &varying = transformFeedbackVaryings[i];
   2952                     for (size_t j = 0; j < varying.semanticIndexCount; j++)
   2953                     {
   2954                         D3D11_SO_DECLARATION_ENTRY entry = { 0 };
   2955                         entry.Stream = 0;
   2956                         entry.SemanticName = varying.semanticName.c_str();
   2957                         entry.SemanticIndex = varying.semanticIndex + j;
   2958                         entry.StartComponent = 0;
   2959                         entry.ComponentCount = gl::VariableRowCount(type);
   2960                         entry.OutputSlot = (separatedOutputBuffers ? i : 0);
   2961                         soDeclaration.push_back(entry);
   2962                     }
   2963                 }
   2964 
   2965                 result = mDevice->CreateGeometryShaderWithStreamOutput(function, length, soDeclaration.data(), soDeclaration.size(),
   2966                                                                        NULL, 0, 0, NULL, &streamOutShader);
   2967                 ASSERT(SUCCEEDED(result));
   2968             }
   2969 
   2970             if (vertexShader)
   2971             {
   2972                 executable = new ShaderExecutable11(function, length, vertexShader, streamOutShader);
   2973             }
   2974         }
   2975         break;
   2976       case rx::SHADER_PIXEL:
   2977         {
   2978             ID3D11PixelShader *pixelShader = NULL;
   2979 
   2980             result = mDevice->CreatePixelShader(function, length, NULL, &pixelShader);
   2981             ASSERT(SUCCEEDED(result));
   2982 
   2983             if (pixelShader)
   2984             {
   2985                 executable = new ShaderExecutable11(function, length, pixelShader);
   2986             }
   2987         }
   2988         break;
   2989       case rx::SHADER_GEOMETRY:
   2990         {
   2991             ID3D11GeometryShader *geometryShader = NULL;
   2992 
   2993             result = mDevice->CreateGeometryShader(function, length, NULL, &geometryShader);
   2994             ASSERT(SUCCEEDED(result));
   2995 
   2996             if (geometryShader)
   2997             {
   2998                 executable = new ShaderExecutable11(function, length, geometryShader);
   2999             }
   3000         }
   3001         break;
   3002       default:
   3003         UNREACHABLE();
   3004         break;
   3005     }
   3006 
   3007     return executable;
   3008 }
   3009 
   3010 ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type,
   3011                                                   const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
   3012                                                   bool separatedOutputBuffers, D3DWorkaroundType workaround)
   3013 {
   3014     const char *profileType = NULL;
   3015     switch (type)
   3016     {
   3017       case rx::SHADER_VERTEX:
   3018         profileType = "vs";
   3019         break;
   3020       case rx::SHADER_PIXEL:
   3021         profileType = "ps";
   3022         break;
   3023       case rx::SHADER_GEOMETRY:
   3024         profileType = "gs";
   3025         break;
   3026       default:
   3027         UNREACHABLE();
   3028         return NULL;
   3029     }
   3030 
   3031     const char *profileVersion = NULL;
   3032     switch (mFeatureLevel)
   3033     {
   3034       case D3D_FEATURE_LEVEL_11_0:
   3035         profileVersion = "5_0";
   3036         break;
   3037       case D3D_FEATURE_LEVEL_10_1:
   3038         profileVersion = "4_1";
   3039         break;
   3040       case D3D_FEATURE_LEVEL_10_0:
   3041         profileVersion = "4_0";
   3042         break;
   3043       default:
   3044         UNREACHABLE();
   3045         return NULL;
   3046     }
   3047 
   3048     char profile[32];
   3049     snprintf(profile, ArraySize(profile), "%s_%s", profileType, profileVersion);
   3050 
   3051     UINT flags = D3DCOMPILE_OPTIMIZATION_LEVEL0;
   3052 
   3053     if (gl::perfActive())
   3054     {
   3055 #ifndef NDEBUG
   3056         flags = D3DCOMPILE_SKIP_OPTIMIZATION;
   3057 #endif
   3058 
   3059         flags |= D3DCOMPILE_DEBUG;
   3060 
   3061         std::string sourcePath = getTempPath();
   3062         std::string sourceText = std::string("#line 2 \"") + sourcePath + std::string("\"\n\n") + std::string(shaderHLSL);
   3063         writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size());
   3064     }
   3065 
   3066     // Sometimes D3DCompile will fail with the default compilation flags for complicated shaders when it would otherwise pass with alternative options.
   3067     // Try the default flags first and if compilation fails, try some alternatives.
   3068     const UINT extraFlags[] =
   3069     {
   3070         flags,
   3071         flags | D3DCOMPILE_SKIP_VALIDATION,
   3072         flags | D3DCOMPILE_SKIP_OPTIMIZATION
   3073     };
   3074 
   3075     const static char *extraFlagNames[] =
   3076     {
   3077         "default",
   3078         "skip validation",
   3079         "skip optimization"
   3080     };
   3081 
   3082     int attempts = ArraySize(extraFlags);
   3083 
   3084     ID3DBlob *binary = (ID3DBlob*)mCompiler.compileToBinary(infoLog, shaderHLSL, profile, extraFlags, extraFlagNames, attempts);
   3085     if (!binary)
   3086     {
   3087         return NULL;
   3088     }
   3089 
   3090     ShaderExecutable *executable = loadExecutable((DWORD *)binary->GetBufferPointer(), binary->GetBufferSize(), type,
   3091                                                   transformFeedbackVaryings, separatedOutputBuffers);
   3092     SafeRelease(binary);
   3093 
   3094     return executable;
   3095 }
   3096 
   3097 rx::UniformStorage *Renderer11::createUniformStorage(size_t storageSize)
   3098 {
   3099     return new UniformStorage11(this, storageSize);
   3100 }
   3101 
   3102 VertexBuffer *Renderer11::createVertexBuffer()
   3103 {
   3104     return new VertexBuffer11(this);
   3105 }
   3106 
   3107 IndexBuffer *Renderer11::createIndexBuffer()
   3108 {
   3109     return new IndexBuffer11(this);
   3110 }
   3111 
   3112 BufferStorage *Renderer11::createBufferStorage()
   3113 {
   3114     return new BufferStorage11(this);
   3115 }
   3116 
   3117 QueryImpl *Renderer11::createQuery(GLenum type)
   3118 {
   3119     return new Query11(this, type);
   3120 }
   3121 
   3122 FenceImpl *Renderer11::createFence()
   3123 {
   3124     return new Fence11(this);
   3125 }
   3126 
   3127 bool Renderer11::supportsFastCopyBufferToTexture(GLenum internalFormat) const
   3128 {
   3129     int clientVersion = getCurrentClientVersion();
   3130 
   3131     // We only support buffer to texture copies in ES3
   3132     if (clientVersion <= 2)
   3133     {
   3134         return false;
   3135     }
   3136 
   3137     // sRGB formats do not work with D3D11 buffer SRVs
   3138     if (gl::GetColorEncoding(internalFormat, clientVersion) == GL_SRGB)
   3139     {
   3140         return false;
   3141     }
   3142 
   3143     // We cannot support direct copies to non-color-renderable formats
   3144     if (!gl::IsColorRenderingSupported(internalFormat, this))
   3145     {
   3146         return false;
   3147     }
   3148 
   3149     // We skip all 3-channel formats since sometimes format support is missing
   3150     if (gl::GetComponentCount(internalFormat, clientVersion) == 3)
   3151     {
   3152         return false;
   3153     }
   3154 
   3155     // We don't support formats which we can't represent without conversion
   3156     if (getNativeTextureFormat(internalFormat) != internalFormat)
   3157     {
   3158         return false;
   3159     }
   3160 
   3161     return true;
   3162 }
   3163 
   3164 bool Renderer11::fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
   3165                                          GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea)
   3166 {
   3167     ASSERT(supportsFastCopyBufferToTexture(destinationFormat));
   3168     return mPixelTransfer->copyBufferToTexture(unpack, offset, destRenderTarget, destinationFormat, sourcePixelsType, destArea);
   3169 }
   3170 
   3171 bool Renderer11::getRenderTargetResource(gl::FramebufferAttachment *colorbuffer, unsigned int *subresourceIndex, ID3D11Texture2D **resource)
   3172 {
   3173     ASSERT(colorbuffer != NULL);
   3174 
   3175     RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget());
   3176     if (renderTarget)
   3177     {
   3178         *subresourceIndex = renderTarget->getSubresourceIndex();
   3179 
   3180         ID3D11RenderTargetView *colorBufferRTV = renderTarget->getRenderTargetView();
   3181         if (colorBufferRTV)
   3182         {
   3183             ID3D11Resource *textureResource = NULL;
   3184             colorBufferRTV->GetResource(&textureResource);
   3185 
   3186             if (textureResource)
   3187             {
   3188                 HRESULT result = textureResource->QueryInterface(__uuidof(ID3D11Texture2D), (void**)resource);
   3189                 SafeRelease(textureResource);
   3190 
   3191                 if (SUCCEEDED(result))
   3192                 {
   3193                     return true;
   3194                 }
   3195                 else
   3196                 {
   3197                     ERR("Failed to extract the ID3D11Texture2D from the render target resource, "
   3198                         "HRESULT: 0x%X.", result);
   3199                 }
   3200             }
   3201         }
   3202     }
   3203 
   3204     return false;
   3205 }
   3206 
   3207 bool Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
   3208                           const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter)
   3209 {
   3210     if (blitRenderTarget)
   3211     {
   3212         gl::FramebufferAttachment *readBuffer = readTarget->getReadColorbuffer();
   3213 
   3214         if (!readBuffer)
   3215         {
   3216             ERR("Failed to retrieve the read buffer from the read framebuffer.");
   3217             return gl::error(GL_OUT_OF_MEMORY, false);
   3218         }
   3219 
   3220         RenderTarget *readRenderTarget = readBuffer->getRenderTarget();
   3221 
   3222         for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
   3223         {
   3224             if (drawTarget->isEnabledColorAttachment(colorAttachment))
   3225             {
   3226                 gl::FramebufferAttachment *drawBuffer = drawTarget->getColorbuffer(colorAttachment);
   3227 
   3228                 if (!drawBuffer)
   3229                 {
   3230                     ERR("Failed to retrieve the draw buffer from the draw framebuffer.");
   3231                     return gl::error(GL_OUT_OF_MEMORY, false);
   3232                 }
   3233 
   3234                 RenderTarget *drawRenderTarget = drawBuffer->getRenderTarget();
   3235 
   3236                 if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor,
   3237                                           blitRenderTarget, false, false))
   3238                 {
   3239                     return false;
   3240                 }
   3241             }
   3242         }
   3243     }
   3244 
   3245     if (blitDepth || blitStencil)
   3246     {
   3247         gl::FramebufferAttachment *readBuffer = readTarget->getDepthOrStencilbuffer();
   3248         gl::FramebufferAttachment *drawBuffer = drawTarget->getDepthOrStencilbuffer();
   3249 
   3250         if (!readBuffer)
   3251         {
   3252             ERR("Failed to retrieve the read depth-stencil buffer from the read framebuffer.");
   3253             return gl::error(GL_OUT_OF_MEMORY, false);
   3254         }
   3255 
   3256         if (!drawBuffer)
   3257         {
   3258             ERR("Failed to retrieve the draw depth-stencil buffer from the draw framebuffer.");
   3259             return gl::error(GL_OUT_OF_MEMORY, false);
   3260         }
   3261 
   3262         RenderTarget *readRenderTarget = readBuffer->getDepthStencil();
   3263         RenderTarget *drawRenderTarget = drawBuffer->getDepthStencil();
   3264 
   3265         if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor,
   3266                                   false, blitDepth, blitStencil))
   3267         {
   3268             return false;
   3269         }
   3270     }
   3271 
   3272     invalidateFramebufferSwizzles(drawTarget);
   3273 
   3274     return true;
   3275 }
   3276 
   3277 void Renderer11::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
   3278                             GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, void* pixels)
   3279 {
   3280     ID3D11Texture2D *colorBufferTexture = NULL;
   3281     unsigned int subresourceIndex = 0;
   3282 
   3283     gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
   3284 
   3285     if (colorbuffer && getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture))
   3286     {
   3287         gl::Rectangle area;
   3288         area.x = x;
   3289         area.y = y;
   3290         area.width = width;
   3291         area.height = height;
   3292 
   3293         if (pack.pixelBuffer.get() != NULL)
   3294         {
   3295             rx::BufferStorage11 *packBufferStorage = BufferStorage11::makeBufferStorage11(pack.pixelBuffer.get()->getStorage());
   3296             PackPixelsParams packParams(area, format, type, outputPitch, pack, reinterpret_cast<ptrdiff_t>(pixels));
   3297             packBufferStorage->packPixels(colorBufferTexture, subresourceIndex, packParams);
   3298         }
   3299         else
   3300         {
   3301             readTextureData(colorBufferTexture, subresourceIndex, area, format, type, outputPitch, pack, pixels);
   3302         }
   3303 
   3304         SafeRelease(colorBufferTexture);
   3305     }
   3306 }
   3307 
   3308 Image *Renderer11::createImage()
   3309 {
   3310     return new Image11();
   3311 }
   3312 
   3313 void Renderer11::generateMipmap(Image *dest, Image *src)
   3314 {
   3315     Image11 *dest11 = Image11::makeImage11(dest);
   3316     Image11 *src11 = Image11::makeImage11(src);
   3317     Image11::generateMipmap(getCurrentClientVersion(), dest11, src11);
   3318 }
   3319 
   3320 TextureStorage *Renderer11::createTextureStorage2D(SwapChain *swapChain)
   3321 {
   3322     SwapChain11 *swapChain11 = SwapChain11::makeSwapChain11(swapChain);
   3323     return new TextureStorage11_2D(this, swapChain11);
   3324 }
   3325 
   3326 TextureStorage *Renderer11::createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels)
   3327 {
   3328     return new TextureStorage11_2D(this, internalformat, renderTarget, width, height, levels);
   3329 }
   3330 
   3331 TextureStorage *Renderer11::createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels)
   3332 {
   3333     return new TextureStorage11_Cube(this, internalformat, renderTarget, size, levels);
   3334 }
   3335 
   3336 TextureStorage *Renderer11::createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels)
   3337 {
   3338     return new TextureStorage11_3D(this, internalformat, renderTarget, width, height, depth, levels);
   3339 }
   3340 
   3341 TextureStorage *Renderer11::createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels)
   3342 {
   3343     return new TextureStorage11_2DArray(this, internalformat, renderTarget, width, height, depth, levels);
   3344 }
   3345 
   3346 void Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format,
   3347                                  GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, void *pixels)
   3348 {
   3349     ASSERT(area.width >= 0);
   3350     ASSERT(area.height >= 0);
   3351 
   3352     D3D11_TEXTURE2D_DESC textureDesc;
   3353     texture->GetDesc(&textureDesc);
   3354 
   3355     // Clamp read region to the defined texture boundaries, preventing out of bounds reads
   3356     // and reads of uninitialized data.
   3357     gl::Rectangle safeArea;
   3358     safeArea.x      = gl::clamp(area.x, 0, static_cast<int>(textureDesc.Width));
   3359     safeArea.y      = gl::clamp(area.y, 0, static_cast<int>(textureDesc.Height));
   3360     safeArea.width  = gl::clamp(area.width + std::min(area.x, 0), 0,
   3361                                 static_cast<int>(textureDesc.Width) - safeArea.x);
   3362     safeArea.height = gl::clamp(area.height + std::min(area.y, 0), 0,
   3363                                 static_cast<int>(textureDesc.Height) - safeArea.y);
   3364 
   3365     ASSERT(safeArea.x >= 0 && safeArea.y >= 0);
   3366     ASSERT(safeArea.x + safeArea.width  <= static_cast<int>(textureDesc.Width));
   3367     ASSERT(safeArea.y + safeArea.height <= static_cast<int>(textureDesc.Height));
   3368 
   3369     if (safeArea.width == 0 || safeArea.height == 0)
   3370     {
   3371         // no work to do
   3372         return;
   3373     }
   3374 
   3375     D3D11_TEXTURE2D_DESC stagingDesc;
   3376     stagingDesc.Width = safeArea.width;
   3377     stagingDesc.Height = safeArea.height;
   3378     stagingDesc.MipLevels = 1;
   3379     stagingDesc.ArraySize = 1;
   3380     stagingDesc.Format = textureDesc.Format;
   3381     stagingDesc.SampleDesc.Count = 1;
   3382     stagingDesc.SampleDesc.Quality = 0;
   3383     stagingDesc.Usage = D3D11_USAGE_STAGING;
   3384     stagingDesc.BindFlags = 0;
   3385     stagingDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
   3386     stagingDesc.MiscFlags = 0;
   3387 
   3388     ID3D11Texture2D* stagingTex = NULL;
   3389     HRESULT result = mDevice->CreateTexture2D(&stagingDesc, NULL, &stagingTex);
   3390     if (FAILED(result))
   3391     {
   3392         ERR("Failed to create staging texture for readPixels, HRESULT: 0x%X.", result);
   3393         return;
   3394     }
   3395 
   3396     ID3D11Texture2D* srcTex = NULL;
   3397     if (textureDesc.SampleDesc.Count > 1)
   3398     {
   3399         D3D11_TEXTURE2D_DESC resolveDesc;
   3400         resolveDesc.Width = textureDesc.Width;
   3401         resolveDesc.Height = textureDesc.Height;
   3402         resolveDesc.MipLevels = 1;
   3403         resolveDesc.ArraySize = 1;
   3404         resolveDesc.Format = textureDesc.Format;
   3405         resolveDesc.SampleDesc.Count = 1;
   3406         resolveDesc.SampleDesc.Quality = 0;
   3407         resolveDesc.Usage = D3D11_USAGE_DEFAULT;
   3408         resolveDesc.BindFlags = 0;
   3409         resolveDesc.CPUAccessFlags = 0;
   3410         resolveDesc.MiscFlags = 0;
   3411 
   3412         result = mDevice->CreateTexture2D(&resolveDesc, NULL, &srcTex);
   3413         if (FAILED(result))
   3414         {
   3415             ERR("Failed to create resolve texture for readPixels, HRESULT: 0x%X.", result);
   3416             SafeRelease(stagingTex);
   3417             return;
   3418         }
   3419 
   3420         mDeviceContext->ResolveSubresource(srcTex, 0, texture, subResource, textureDesc.Format);
   3421         subResource = 0;
   3422     }
   3423     else
   3424     {
   3425         srcTex = texture;
   3426         srcTex->AddRef();
   3427     }
   3428 
   3429     D3D11_BOX srcBox;
   3430     srcBox.left   = static_cast<UINT>(safeArea.x);
   3431     srcBox.right  = static_cast<UINT>(safeArea.x + safeArea.width);
   3432     srcBox.top    = static_cast<UINT>(safeArea.y);
   3433     srcBox.bottom = static_cast<UINT>(safeArea.y + safeArea.height);
   3434     srcBox.front  = 0;
   3435     srcBox.back   = 1;
   3436 
   3437     mDeviceContext->CopySubresourceRegion(stagingTex, 0, 0, 0, 0, srcTex, subResource, &srcBox);
   3438 
   3439     SafeRelease(srcTex);
   3440 
   3441     PackPixelsParams packParams(safeArea, format, type, outputPitch, pack, 0);
   3442     packPixels(stagingTex, packParams, pixels);
   3443 
   3444     SafeRelease(stagingTex);
   3445 }
   3446 
   3447 void Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams &params, void *pixelsOut)
   3448 {
   3449     D3D11_TEXTURE2D_DESC textureDesc;
   3450     readTexture->GetDesc(&textureDesc);
   3451 
   3452     D3D11_MAPPED_SUBRESOURCE mapping;
   3453     HRESULT hr = mDeviceContext->Map(readTexture, 0, D3D11_MAP_READ, 0, &mapping);
   3454     UNUSED_ASSERTION_VARIABLE(hr);
   3455     ASSERT(SUCCEEDED(hr));
   3456 
   3457     unsigned char *source;
   3458     int inputPitch;
   3459     if (params.pack.reverseRowOrder)
   3460     {
   3461         source = static_cast<unsigned char*>(mapping.pData) + mapping.RowPitch * (params.area.height - 1);
   3462         inputPitch = -static_cast<int>(mapping.RowPitch);
   3463     }
   3464     else
   3465     {
   3466         source = static_cast<unsigned char*>(mapping.pData);
   3467         inputPitch = static_cast<int>(mapping.RowPitch);
   3468     }
   3469 
   3470     GLuint clientVersion = getCurrentClientVersion();
   3471 
   3472     GLenum sourceInternalFormat = d3d11_gl::GetInternalFormat(textureDesc.Format, clientVersion);
   3473     GLenum sourceFormat = gl::GetFormat(sourceInternalFormat, clientVersion);
   3474     GLenum sourceType = gl::GetType(sourceInternalFormat, clientVersion);
   3475 
   3476     GLuint sourcePixelSize = gl::GetPixelBytes(sourceInternalFormat, clientVersion);
   3477 
   3478     if (sourceFormat == params.format && sourceType == params.type)
   3479     {
   3480         unsigned char *dest = static_cast<unsigned char*>(pixelsOut) + params.offset;
   3481         for (int y = 0; y < params.area.height; y++)
   3482         {
   3483             memcpy(dest + y * params.outputPitch, source + y * inputPitch, params.area.width * sourcePixelSize);
   3484         }
   3485     }
   3486     else
   3487     {
   3488         GLenum destInternalFormat = gl::GetSizedInternalFormat(params.format, params.type, clientVersion);
   3489         GLuint destPixelSize = gl::GetPixelBytes(destInternalFormat, clientVersion);
   3490 
   3491         ColorCopyFunction fastCopyFunc = d3d11::GetFastCopyFunction(textureDesc.Format, params.format, params.type);
   3492         if (fastCopyFunc)
   3493         {
   3494             // Fast copy is possible through some special function
   3495             for (int y = 0; y < params.area.height; y++)
   3496             {
   3497                 for (int x = 0; x < params.area.width; x++)
   3498                 {
   3499                     void *dest = static_cast<unsigned char*>(pixelsOut) + params.offset + y * params.outputPitch + x * destPixelSize;
   3500                     void *src = static_cast<unsigned char*>(source) + y * inputPitch + x * sourcePixelSize;
   3501 
   3502                     fastCopyFunc(src, dest);
   3503                 }
   3504             }
   3505         }
   3506         else
   3507         {
   3508             ColorReadFunction readFunc = d3d11::GetColorReadFunction(textureDesc.Format);
   3509             ColorWriteFunction writeFunc = gl::GetColorWriteFunction(params.format, params.type, clientVersion);
   3510 
   3511             unsigned char temp[16]; // Maximum size of any Color<T> type used.
   3512             META_ASSERT(sizeof(temp) >= sizeof(gl::ColorF)  &&
   3513                         sizeof(temp) >= sizeof(gl::ColorUI) &&
   3514                         sizeof(temp) >= sizeof(gl::ColorI));
   3515 
   3516             for (int y = 0; y < params.area.height; y++)
   3517             {
   3518                 for (int x = 0; x < params.area.width; x++)
   3519                 {
   3520                     void *dest = static_cast<unsigned char*>(pixelsOut) + params.offset + y * params.outputPitch + x * destPixelSize;
   3521                     void *src = static_cast<unsigned char*>(source) + y * inputPitch + x * sourcePixelSize;
   3522 
   3523                     // readFunc and writeFunc will be using the same type of color, CopyTexImage
   3524                     // will not allow the copy otherwise.
   3525                     readFunc(src, temp);
   3526                     writeFunc(temp, dest);
   3527                 }
   3528             }
   3529         }
   3530     }
   3531 
   3532     mDeviceContext->Unmap(readTexture, 0);
   3533 }
   3534 
   3535 bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget,
   3536                                       RenderTarget *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor,
   3537                                       bool colorBlit, bool depthBlit, bool stencilBlit)
   3538 {
   3539     // Since blitRenderbufferRect is called for each render buffer that needs to be blitted,
   3540     // it should never be the case that both color and depth/stencil need to be blitted at
   3541     // at the same time.
   3542     ASSERT(colorBlit != (depthBlit || stencilBlit));
   3543 
   3544     bool result = true;
   3545 
   3546     RenderTarget11 *drawRenderTarget11 = RenderTarget11::makeRenderTarget11(drawRenderTarget);
   3547     if (!drawRenderTarget)
   3548     {
   3549         ERR("Failed to retrieve the draw render target from the draw framebuffer.");
   3550         return gl::error(GL_OUT_OF_MEMORY, false);
   3551     }
   3552 
   3553     ID3D11Resource *drawTexture = drawRenderTarget11->getTexture();
   3554     unsigned int drawSubresource = drawRenderTarget11->getSubresourceIndex();
   3555     ID3D11RenderTargetView *drawRTV = drawRenderTarget11->getRenderTargetView();
   3556     ID3D11DepthStencilView *drawDSV = drawRenderTarget11->getDepthStencilView();
   3557 
   3558     RenderTarget11 *readRenderTarget11 = RenderTarget11::makeRenderTarget11(readRenderTarget);
   3559     if (!readRenderTarget)
   3560     {
   3561         ERR("Failed to retrieve the read render target from the read framebuffer.");
   3562         return gl::error(GL_OUT_OF_MEMORY, false);
   3563     }
   3564 
   3565     ID3D11Resource *readTexture = NULL;
   3566     ID3D11ShaderResourceView *readSRV = NULL;
   3567     unsigned int readSubresource = 0;
   3568     if (readRenderTarget->getSamples() > 0)
   3569     {
   3570         ID3D11Resource *unresolvedResource = readRenderTarget11->getTexture();
   3571         ID3D11Texture2D *unresolvedTexture = d3d11::DynamicCastComObject<ID3D11Texture2D>(unresolvedResource);
   3572 
   3573         if (unresolvedTexture)
   3574         {
   3575             readTexture = resolveMultisampledTexture(unresolvedTexture, readRenderTarget11->getSubresourceIndex());
   3576             readSubresource = 0;
   3577 
   3578             SafeRelease(unresolvedTexture);
   3579 
   3580             HRESULT hresult = mDevice->CreateShaderResourceView(readTexture, NULL, &readSRV);
   3581             if (FAILED(hresult))
   3582             {
   3583                 SafeRelease(readTexture);
   3584                 return gl::error(GL_OUT_OF_MEMORY, false);
   3585             }
   3586         }
   3587     }
   3588     else
   3589     {
   3590         readTexture = readRenderTarget11->getTexture();
   3591         readTexture->AddRef();
   3592         readSubresource = readRenderTarget11->getSubresourceIndex();
   3593         readSRV = readRenderTarget11->getShaderResourceView();
   3594         readSRV->AddRef();
   3595     }
   3596 
   3597     if (!readTexture || !readSRV)
   3598     {
   3599         SafeRelease(readTexture);
   3600         SafeRelease(readSRV);
   3601         ERR("Failed to retrieve the read render target view from the read render target.");
   3602         return gl::error(GL_OUT_OF_MEMORY, false);
   3603     }
   3604 
   3605     gl::Extents readSize(readRenderTarget->getWidth(), readRenderTarget->getHeight(), 1);
   3606     gl::Extents drawSize(drawRenderTarget->getWidth(), drawRenderTarget->getHeight(), 1);
   3607 
   3608     bool scissorNeeded = scissor && gl::ClipRectangle(drawRect, *scissor, NULL);
   3609 
   3610     bool wholeBufferCopy = !scissorNeeded &&
   3611                            readRect.x == 0 && readRect.width == readSize.width &&
   3612                            readRect.y == 0 && readRect.height == readSize.height &&
   3613                            drawRect.x == 0 && drawRect.width == drawSize.width &&
   3614                            drawRect.y == 0 && drawRect.height == drawSize.height;
   3615 
   3616     bool stretchRequired = readRect.width != drawRect.width || readRect.height != drawRect.height;
   3617 
   3618     bool flipRequired = readRect.width < 0 || readRect.height < 0 || drawRect.width < 0 || drawRect.height < 0;
   3619 
   3620     bool outOfBounds = readRect.x < 0 || readRect.x + readRect.width > readSize.width ||
   3621                        readRect.y < 0 || readRect.y + readRect.height > readSize.height ||
   3622                        drawRect.x < 0 || drawRect.x + drawRect.width > drawSize.width ||
   3623                        drawRect.y < 0 || drawRect.y + drawRect.height > drawSize.height;
   3624 
   3625     bool hasDepth = gl::GetDepthBits(drawRenderTarget11->getActualFormat(), getCurrentClientVersion()) > 0;
   3626     bool hasStencil = gl::GetStencilBits(drawRenderTarget11->getActualFormat(), getCurrentClientVersion()) > 0;
   3627     bool partialDSBlit = (hasDepth && depthBlit) != (hasStencil && stencilBlit);
   3628 
   3629     if (readRenderTarget11->getActualFormat() == drawRenderTarget->getActualFormat() &&
   3630         !stretchRequired && !outOfBounds && !flipRequired && !partialDSBlit &&
   3631         (!(depthBlit || stencilBlit) || wholeBufferCopy))
   3632     {
   3633         UINT dstX = drawRect.x;
   3634         UINT dstY = drawRect.y;
   3635 
   3636         D3D11_BOX readBox;
   3637         readBox.left = readRect.x;
   3638         readBox.right = readRect.x + readRect.width;
   3639         readBox.top = readRect.y;
   3640         readBox.bottom = readRect.y + readRect.height;
   3641         readBox.front = 0;
   3642         readBox.back = 1;
   3643 
   3644         if (scissorNeeded)
   3645         {
   3646             // drawRect is guaranteed to have positive width and height because stretchRequired is false.
   3647             ASSERT(drawRect.width >= 0 || drawRect.height >= 0);
   3648 
   3649             if (drawRect.x < scissor->x)
   3650             {
   3651                 dstX = scissor->x;
   3652                 readBox.left += (scissor->x - drawRect.x);
   3653             }
   3654             if (drawRect.y < scissor->y)
   3655             {
   3656                 dstY = scissor->y;
   3657                 readBox.top += (scissor->y - drawRect.y);
   3658             }
   3659             if (drawRect.x + drawRect.width > scissor->x + scissor->width)
   3660             {
   3661                 readBox.right -= ((drawRect.x + drawRect.width) - (scissor->x + scissor->width));
   3662             }
   3663             if (drawRect.y + drawRect.height > scissor->y + scissor->height)
   3664             {
   3665                 readBox.bottom -= ((drawRect.y + drawRect.height) - (scissor->y + scissor->height));
   3666             }
   3667         }
   3668 
   3669         // D3D11 needs depth-stencil CopySubresourceRegions to have a NULL pSrcBox
   3670         // We also require complete framebuffer copies for depth-stencil blit.
   3671         D3D11_BOX *pSrcBox = wholeBufferCopy ? NULL : &readBox;
   3672 
   3673         mDeviceContext->CopySubresourceRegion(drawTexture, drawSubresource, dstX, dstY, 0,
   3674                                               readTexture, readSubresource, pSrcBox);
   3675         result = true;
   3676     }
   3677     else
   3678     {
   3679         gl::Box readArea(readRect.x, readRect.y, 0, readRect.width, readRect.height, 1);
   3680         gl::Box drawArea(drawRect.x, drawRect.y, 0, drawRect.width, drawRect.height, 1);
   3681 
   3682         if (depthBlit && stencilBlit)
   3683         {
   3684             result = mBlit->copyDepthStencil(readTexture, readSubresource, readArea, readSize,
   3685                                              drawTexture, drawSubresource, drawArea, drawSize,
   3686                                              scissor);
   3687         }
   3688         else if (depthBlit)
   3689         {
   3690             result = mBlit->copyDepth(readSRV, readArea, readSize, drawDSV, drawArea, drawSize,
   3691                                       scissor);
   3692         }
   3693         else if (stencilBlit)
   3694         {
   3695             result = mBlit->copyStencil(readTexture, readSubresource, readArea, readSize,
   3696                                         drawTexture, drawSubresource, drawArea, drawSize,
   3697                                         scissor);
   3698         }
   3699         else
   3700         {
   3701             GLenum format = gl::GetFormat(drawRenderTarget->getInternalFormat(), getCurrentClientVersion());
   3702             result = mBlit->copyTexture(readSRV, readArea, readSize, drawRTV, drawArea, drawSize,
   3703                                         scissor, format, filter);
   3704         }
   3705     }
   3706 
   3707     SafeRelease(readTexture);
   3708     SafeRelease(readSRV);
   3709 
   3710     return result;
   3711 }
   3712 
   3713 ID3D11Texture2D *Renderer11::resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource)
   3714 {
   3715     D3D11_TEXTURE2D_DESC textureDesc;
   3716     source->GetDesc(&textureDesc);
   3717 
   3718     if (textureDesc.SampleDesc.Count > 1)
   3719     {
   3720         D3D11_TEXTURE2D_DESC resolveDesc;
   3721         resolveDesc.Width = textureDesc.Width;
   3722         resolveDesc.Height = textureDesc.Height;
   3723         resolveDesc.MipLevels = 1;
   3724         resolveDesc.ArraySize = 1;
   3725         resolveDesc.Format = textureDesc.Format;
   3726         resolveDesc.SampleDesc.Count = 1;
   3727         resolveDesc.SampleDesc.Quality = 0;
   3728         resolveDesc.Usage = textureDesc.Usage;
   3729         resolveDesc.BindFlags = textureDesc.BindFlags;
   3730         resolveDesc.CPUAccessFlags = 0;
   3731         resolveDesc.MiscFlags = 0;
   3732 
   3733         ID3D11Texture2D *resolveTexture = NULL;
   3734         HRESULT result = mDevice->CreateTexture2D(&resolveDesc, NULL, &resolveTexture);
   3735         if (FAILED(result))
   3736         {
   3737             ERR("Failed to create a multisample resolve texture, HRESULT: 0x%X.", result);
   3738             return NULL;
   3739         }
   3740 
   3741         mDeviceContext->ResolveSubresource(resolveTexture, 0, source, subresource, textureDesc.Format);
   3742         return resolveTexture;
   3743     }
   3744     else
   3745     {
   3746         source->AddRef();
   3747         return source;
   3748     }
   3749 }
   3750 
   3751 void Renderer11::invalidateFBOAttachmentSwizzles(gl::FramebufferAttachment *attachment, int mipLevel)
   3752 {
   3753     ASSERT(attachment->isTexture());
   3754     TextureStorage *texStorage = attachment->getTextureStorage();
   3755     if (texStorage)
   3756     {
   3757         TextureStorage11 *texStorage11 = TextureStorage11::makeTextureStorage11(texStorage);
   3758         if (!texStorage11)
   3759         {
   3760             ERR("texture storage pointer unexpectedly null.");
   3761             return;
   3762         }
   3763 
   3764         texStorage11->invalidateSwizzleCacheLevel(mipLevel);
   3765     }
   3766 }
   3767 
   3768 void Renderer11::invalidateFramebufferSwizzles(gl::Framebuffer *framebuffer)
   3769 {
   3770     for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
   3771     {
   3772         gl::FramebufferAttachment *attachment = framebuffer->getColorbuffer(colorAttachment);
   3773         if (attachment && attachment->isTexture())
   3774         {
   3775             invalidateFBOAttachmentSwizzles(attachment, framebuffer->getColorbufferMipLevel(colorAttachment));
   3776         }
   3777     }
   3778 
   3779     gl::FramebufferAttachment *depthAttachment = framebuffer->getDepthbuffer();
   3780     if (depthAttachment && depthAttachment->isTexture())
   3781     {
   3782         invalidateFBOAttachmentSwizzles(depthAttachment, framebuffer->getDepthbufferMipLevel());
   3783     }
   3784 
   3785     gl::FramebufferAttachment *stencilAttachment = framebuffer->getStencilbuffer();
   3786     if (stencilAttachment && stencilAttachment->isTexture())
   3787     {
   3788         invalidateFBOAttachmentSwizzles(stencilAttachment, framebuffer->getStencilbufferMipLevel());
   3789     }
   3790 }
   3791 
   3792 bool Renderer11::getLUID(LUID *adapterLuid) const
   3793 {
   3794     adapterLuid->HighPart = 0;
   3795     adapterLuid->LowPart = 0;
   3796 
   3797     if (!mDxgiAdapter)
   3798     {
   3799         return false;
   3800     }
   3801 
   3802     DXGI_ADAPTER_DESC adapterDesc;
   3803     if (FAILED(mDxgiAdapter->GetDesc(&adapterDesc)))
   3804     {
   3805         return false;
   3806     }
   3807 
   3808     *adapterLuid = adapterDesc.AdapterLuid;
   3809     return true;
   3810 }
   3811 
   3812 GLenum Renderer11::getNativeTextureFormat(GLenum internalFormat) const
   3813 {
   3814     int clientVersion = getCurrentClientVersion();
   3815     return d3d11_gl::GetInternalFormat(gl_d3d11::GetTexFormat(internalFormat, clientVersion), clientVersion);
   3816 }
   3817 
   3818 rx::VertexConversionType Renderer11::getVertexConversionType(const gl::VertexFormat &vertexFormat) const
   3819 {
   3820     return gl_d3d11::GetVertexConversionType(vertexFormat);
   3821 }
   3822 
   3823 GLenum Renderer11::getVertexComponentType(const gl::VertexFormat &vertexFormat) const
   3824 {
   3825     return d3d11::GetComponentType(gl_d3d11::GetNativeVertexFormat(vertexFormat));
   3826 }
   3827 
   3828 Renderer11::MultisampleSupportInfo Renderer11::getMultisampleSupportInfo(DXGI_FORMAT format)
   3829 {
   3830     MultisampleSupportInfo supportInfo = { 0 };
   3831 
   3832     UINT formatSupport;
   3833     HRESULT result;
   3834 
   3835     result = mDevice->CheckFormatSupport(format, &formatSupport);
   3836     if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET))
   3837     {
   3838         for (unsigned int i = 1; i <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; i++)
   3839         {
   3840             result = mDevice->CheckMultisampleQualityLevels(format, i, &supportInfo.qualityLevels[i - 1]);
   3841             if (SUCCEEDED(result) && supportInfo.qualityLevels[i - 1] > 0)
   3842             {
   3843                 supportInfo.maxSupportedSamples = std::max(supportInfo.maxSupportedSamples, i);
   3844             }
   3845             else
   3846             {
   3847                 supportInfo.qualityLevels[i - 1] = 0;
   3848             }
   3849         }
   3850     }
   3851 
   3852     return supportInfo;
   3853 }
   3854 
   3855 }
   3856