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