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