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