gfx/angle/src/libGLESv2/renderer/Renderer11.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 #include "precompiled.h"
     2 //
     3 // Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
     4 // Use of this source code is governed by a BSD-style license that can be
     5 // found in the LICENSE file.
     6 //
     8 // Renderer11.cpp: Implements a back-end specific class for the D3D11 renderer.
    10 #include "libGLESv2/main.h"
    11 #include "libGLESv2/utilities.h"
    12 #include "libGLESv2/Buffer.h"
    13 #include "libGLESv2/ProgramBinary.h"
    14 #include "libGLESv2/Framebuffer.h"
    15 #include "libGLESv2/Renderbuffer.h"
    16 #include "libGLESv2/renderer/Renderer11.h"
    17 #include "libGLESv2/renderer/RenderTarget11.h"
    18 #include "libGLESv2/renderer/renderer11_utils.h"
    19 #include "libGLESv2/renderer/ShaderExecutable11.h"
    20 #include "libGLESv2/renderer/SwapChain11.h"
    21 #include "libGLESv2/renderer/Image11.h"
    22 #include "libGLESv2/renderer/VertexBuffer11.h"
    23 #include "libGLESv2/renderer/IndexBuffer11.h"
    24 #include "libGLESv2/renderer/BufferStorage11.h"
    25 #include "libGLESv2/renderer/VertexDataManager.h"
    26 #include "libGLESv2/renderer/IndexDataManager.h"
    27 #include "libGLESv2/renderer/TextureStorage11.h"
    28 #include "libGLESv2/renderer/Query11.h"
    29 #include "libGLESv2/renderer/Fence11.h"
    31 #include "libGLESv2/renderer/shaders/compiled/passthrough11vs.h"
    32 #include "libGLESv2/renderer/shaders/compiled/passthroughrgba11ps.h"
    33 #include "libGLESv2/renderer/shaders/compiled/passthroughrgb11ps.h"
    34 #include "libGLESv2/renderer/shaders/compiled/passthroughlum11ps.h"
    35 #include "libGLESv2/renderer/shaders/compiled/passthroughlumalpha11ps.h"
    37 #include "libGLESv2/renderer/shaders/compiled/clear11vs.h"
    38 #include "libGLESv2/renderer/shaders/compiled/clearsingle11ps.h"
    39 #include "libGLESv2/renderer/shaders/compiled/clearmultiple11ps.h"
    41 #include "libEGL/Display.h"
    43 #ifdef _DEBUG
    44 // this flag enables suppressing some spurious warnings that pop up in certain WebGL samples
    45 // and conformance tests. to enable all warnings, remove this define.
    46 #define ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS 1
    47 #endif
    49 namespace rx
    50 {
    51 static const DXGI_FORMAT RenderTargetFormats[] =
    52     {
    53         DXGI_FORMAT_B8G8R8A8_UNORM,
    54         DXGI_FORMAT_R8G8B8A8_UNORM
    55     };
    57 static const DXGI_FORMAT DepthStencilFormats[] =
    58     {
    59         DXGI_FORMAT_UNKNOWN,
    60         DXGI_FORMAT_D24_UNORM_S8_UINT,
    61         DXGI_FORMAT_D16_UNORM
    62     };
    64 enum
    65 {
    66     MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 = 16
    67 };
    69 Renderer11::Renderer11(egl::Display *display, HDC hDc) : Renderer(display), mDc(hDc)
    70 {
    71     mVertexDataManager = NULL;
    72     mIndexDataManager = NULL;
    74     mLineLoopIB = NULL;
    75     mTriangleFanIB = NULL;
    77     mCopyResourcesInitialized = false;
    78     mCopyVB = NULL;
    79     mCopySampler = NULL;
    80     mCopyIL = NULL;
    81     mCopyVS = NULL;
    82     mCopyRGBAPS = NULL;
    83     mCopyRGBPS = NULL;
    84     mCopyLumPS = NULL;
    85     mCopyLumAlphaPS = NULL;
    87     mClearResourcesInitialized = false;
    88     mClearVB = NULL;
    89     mClearIL = NULL;
    90     mClearVS = NULL;
    91     mClearSinglePS = NULL;
    92     mClearMultiplePS = NULL;
    93     mClearScissorRS = NULL;
    94     mClearNoScissorRS = NULL;
    96     mSyncQuery = NULL;
    98     mD3d11Module = NULL;
    99     mDxgiModule = NULL;
   101     mDeviceLost = false;
   103     mMaxSupportedSamples = 0;
   105     mDevice = NULL;
   106     mDeviceContext = NULL;
   107     mDxgiAdapter = NULL;
   108     mDxgiFactory = NULL;
   110     mDriverConstantBufferVS = NULL;
   111     mDriverConstantBufferPS = NULL;
   113     mBGRATextureSupport = false;
   115     mIsGeometryShaderActive = false;
   116 }
   118 Renderer11::~Renderer11()
   119 {
   120     release();
   121 }
   123 Renderer11 *Renderer11::makeRenderer11(Renderer *renderer)
   124 {
   125     ASSERT(HAS_DYNAMIC_TYPE(rx::Renderer11*, renderer));
   126     return static_cast<rx::Renderer11*>(renderer);
   127 }
   129 #ifndef __d3d11_1_h__
   130 #define D3D11_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET ((D3D11_MESSAGE_ID)3146081)
   131 #endif
   133 EGLint Renderer11::initialize()
   134 {
   135     if (!initializeCompiler())
   136     {
   137         return EGL_NOT_INITIALIZED;
   138     }
   140     mDxgiModule = LoadLibrary(TEXT("dxgi.dll"));
   141     mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
   143     if (mD3d11Module == NULL || mDxgiModule == NULL)
   144     {
   145         ERR("Could not load D3D11 or DXGI library - aborting!\n");
   146         return EGL_NOT_INITIALIZED;
   147     }
   149     // create the D3D11 device
   150     ASSERT(mDevice == NULL);
   151     PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice");
   153     if (D3D11CreateDevice == NULL)
   154     {
   155         ERR("Could not retrieve D3D11CreateDevice address - aborting!\n");
   156         return EGL_NOT_INITIALIZED;
   157     }
   159     D3D_FEATURE_LEVEL featureLevels[] =
   160     {
   161         D3D_FEATURE_LEVEL_11_0,
   162         D3D_FEATURE_LEVEL_10_1,
   163         D3D_FEATURE_LEVEL_10_0,
   164     };
   166     HRESULT result = S_OK;
   168 #ifdef _DEBUG
   169     result = D3D11CreateDevice(NULL,
   170                                D3D_DRIVER_TYPE_HARDWARE,
   171                                NULL,
   172                                D3D11_CREATE_DEVICE_DEBUG,
   173                                featureLevels,
   174                                ArraySize(featureLevels),
   175                                D3D11_SDK_VERSION,
   176                                &mDevice,
   177                                &mFeatureLevel,
   178                                &mDeviceContext);
   180     if (!mDevice || FAILED(result))
   181     {
   182         ERR("Failed creating Debug D3D11 device - falling back to release runtime.\n");
   183     }
   185     if (!mDevice || FAILED(result))
   186 #endif
   187     {
   188         result = D3D11CreateDevice(NULL,
   189                                    D3D_DRIVER_TYPE_HARDWARE,
   190                                    NULL,
   191                                    0,
   192                                    featureLevels,
   193                                    ArraySize(featureLevels),
   194                                    D3D11_SDK_VERSION,
   195                                    &mDevice,
   196                                    &mFeatureLevel,
   197                                    &mDeviceContext);
   199         if (!mDevice || FAILED(result))
   200         {
   201             ERR("Could not create D3D11 device - aborting!\n");
   202             return EGL_NOT_INITIALIZED;   // Cleanup done by destructor through glDestroyRenderer
   203         }
   204     }
   206     IDXGIDevice *dxgiDevice = NULL;
   207     result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
   209     if (FAILED(result))
   210     {
   211         ERR("Could not query DXGI device - aborting!\n");
   212         return EGL_NOT_INITIALIZED;
   213     }
   215     result = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&mDxgiAdapter);
   217     if (FAILED(result))
   218     {
   219         ERR("Could not retrieve DXGI adapter - aborting!\n");
   220         return EGL_NOT_INITIALIZED;
   221     }
   223     dxgiDevice->Release();
   225     mDxgiAdapter->GetDesc(&mAdapterDescription);
   226     memset(mDescription, 0, sizeof(mDescription));
   227     wcstombs(mDescription, mAdapterDescription.Description, sizeof(mDescription) - 1);
   229     result = mDxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&mDxgiFactory);
   231     if (!mDxgiFactory || FAILED(result))
   232     {
   233         ERR("Could not create DXGI factory - aborting!\n");
   234         return EGL_NOT_INITIALIZED;
   235     }
   237     // Disable some spurious D3D11 debug warnings to prevent them from flooding the output log
   238 #if defined(ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS) && defined(_DEBUG)
   239     ID3D11InfoQueue *infoQueue;
   240     result = mDevice->QueryInterface(__uuidof(ID3D11InfoQueue),  (void **)&infoQueue);
   242     if (SUCCEEDED(result))
   243     {
   244         D3D11_MESSAGE_ID hideMessages[] =
   245         {
   246             D3D11_MESSAGE_ID_DEVICE_OMSETRENDERTARGETS_HAZARD,
   247             D3D11_MESSAGE_ID_DEVICE_PSSETSHADERRESOURCES_HAZARD,
   248             D3D11_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET
   249         };
   251         D3D11_INFO_QUEUE_FILTER filter = {0};
   252         filter.DenyList.NumIDs = ArraySize(hideMessages);
   253         filter.DenyList.pIDList = hideMessages;
   255         infoQueue->AddStorageFilterEntries(&filter);
   257         infoQueue->Release();
   258     }
   259 #endif
   261     unsigned int maxSupportedSamples = 0;
   262     unsigned int rtFormatCount = ArraySize(RenderTargetFormats);
   263     unsigned int dsFormatCount = ArraySize(DepthStencilFormats);
   264     for (unsigned int i = 0; i < rtFormatCount + dsFormatCount; ++i)
   265     {
   266         DXGI_FORMAT format = (i < rtFormatCount) ? RenderTargetFormats[i] : DepthStencilFormats[i - rtFormatCount];
   267         if (format != DXGI_FORMAT_UNKNOWN)
   268         {
   269             UINT formatSupport;
   270             result = mDevice->CheckFormatSupport(format, &formatSupport);
   271             if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET))
   272             {
   273                 MultisampleSupportInfo supportInfo;
   275                 for (unsigned int j = 1; j <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; j++)
   276                 {
   277                     result = mDevice->CheckMultisampleQualityLevels(format, j, &supportInfo.qualityLevels[j - 1]);
   278                     if (SUCCEEDED(result) && supportInfo.qualityLevels[j - 1] > 0)
   279                     {
   280                         maxSupportedSamples = std::max(j, maxSupportedSamples);
   281                     }
   282                     else
   283                     {
   284                         supportInfo.qualityLevels[j - 1] = 0;
   285                     }
   286                 }
   288                 mMultisampleSupportMap.insert(std::make_pair(format, supportInfo));
   289             }
   290         }
   291     }
   292     mMaxSupportedSamples = maxSupportedSamples;
   294     initializeDevice();
   296     // BGRA texture support is optional in feature levels 10 and 10_1
   297     UINT formatSupport;
   298     result = mDevice->CheckFormatSupport(DXGI_FORMAT_B8G8R8A8_UNORM, &formatSupport);
   299     if (FAILED(result))
   300     {
   301         ERR("Error checking BGRA format support: 0x%08X", result);
   302     }
   303     else
   304     {
   305         const int flags = (D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_RENDER_TARGET);
   306         mBGRATextureSupport = (formatSupport & flags) == flags;
   307     }
   309     // Check floating point texture support
   310     static const unsigned int requiredTextureFlags = D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_TEXTURECUBE;
   311     static const unsigned int requiredRenderableFlags = D3D11_FORMAT_SUPPORT_RENDER_TARGET;
   312     static const unsigned int requiredFilterFlags = D3D11_FORMAT_SUPPORT_SHADER_SAMPLE;
   314     DXGI_FORMAT float16Formats[] =
   315     {
   316         DXGI_FORMAT_R16_FLOAT,
   317         DXGI_FORMAT_R16G16_FLOAT,
   318         DXGI_FORMAT_R16G16B16A16_FLOAT,
   319     };
   321     DXGI_FORMAT float32Formats[] =
   322     {
   323         DXGI_FORMAT_R32_FLOAT,
   324         DXGI_FORMAT_R32G32_FLOAT,
   325         DXGI_FORMAT_R32G32B32_FLOAT,
   326         DXGI_FORMAT_R32G32B32A32_FLOAT,
   327     };
   329     mFloat16TextureSupport = true;
   330     mFloat16FilterSupport = true;
   331     mFloat16RenderSupport = true;
   332     for (unsigned int i = 0; i < ArraySize(float16Formats); i++)
   333     {
   334         if (SUCCEEDED(mDevice->CheckFormatSupport(float16Formats[i], &formatSupport)))
   335         {
   336             mFloat16TextureSupport = mFloat16TextureSupport && (formatSupport & requiredTextureFlags) == requiredTextureFlags;
   337             mFloat16FilterSupport = mFloat16FilterSupport && (formatSupport & requiredFilterFlags) == requiredFilterFlags;
   338             mFloat16RenderSupport = mFloat16RenderSupport && (formatSupport & requiredRenderableFlags) == requiredRenderableFlags;
   339         }
   340         else
   341         {
   342             mFloat16TextureSupport = false;
   343             mFloat16RenderSupport = false;
   344             mFloat16FilterSupport = false;
   345         }
   346     }
   348     mFloat32TextureSupport = true;
   349     mFloat32FilterSupport = true;
   350     mFloat32RenderSupport = true;
   351     for (unsigned int i = 0; i < ArraySize(float32Formats); i++)
   352     {
   353         if (SUCCEEDED(mDevice->CheckFormatSupport(float32Formats[i], &formatSupport)))
   354         {
   355             mFloat32TextureSupport = mFloat32TextureSupport && (formatSupport & requiredTextureFlags) == requiredTextureFlags;
   356             mFloat32FilterSupport = mFloat32FilterSupport && (formatSupport & requiredFilterFlags) == requiredFilterFlags;
   357             mFloat32RenderSupport = mFloat32RenderSupport && (formatSupport & requiredRenderableFlags) == requiredRenderableFlags;
   358         }
   359         else
   360         {
   361             mFloat32TextureSupport = false;
   362             mFloat32FilterSupport = false;
   363             mFloat32RenderSupport = false;
   364         }
   365     }
   367     // Check compressed texture support
   368     const unsigned int requiredCompressedTextureFlags = D3D11_FORMAT_SUPPORT_TEXTURE2D;
   370     if (SUCCEEDED(mDevice->CheckFormatSupport(DXGI_FORMAT_BC1_UNORM, &formatSupport)))
   371     {
   372         mDXT1TextureSupport = (formatSupport & requiredCompressedTextureFlags) == requiredCompressedTextureFlags;
   373     }
   374     else
   375     {
   376         mDXT1TextureSupport = false;
   377     }
   379     if (SUCCEEDED(mDevice->CheckFormatSupport(DXGI_FORMAT_BC3_UNORM, &formatSupport)))
   380     {
   381         mDXT3TextureSupport = (formatSupport & requiredCompressedTextureFlags) == requiredCompressedTextureFlags;
   382     }
   383     else
   384     {
   385         mDXT3TextureSupport = false;
   386     }
   388     if (SUCCEEDED(mDevice->CheckFormatSupport(DXGI_FORMAT_BC5_UNORM, &formatSupport)))
   389     {
   390         mDXT5TextureSupport = (formatSupport & requiredCompressedTextureFlags) == requiredCompressedTextureFlags;
   391     }
   392     else
   393     {
   394         mDXT5TextureSupport = false;
   395     }
   397     // Check depth texture support
   398     DXGI_FORMAT depthTextureFormats[] =
   399     {
   400         DXGI_FORMAT_D16_UNORM,
   401         DXGI_FORMAT_D24_UNORM_S8_UINT,
   402     };
   404     static const unsigned int requiredDepthTextureFlags = D3D11_FORMAT_SUPPORT_DEPTH_STENCIL |
   405                                                           D3D11_FORMAT_SUPPORT_TEXTURE2D;
   407     mDepthTextureSupport = true;
   408     for (unsigned int i = 0; i < ArraySize(depthTextureFormats); i++)
   409     {
   410         if (SUCCEEDED(mDevice->CheckFormatSupport(depthTextureFormats[i], &formatSupport)))
   411         {
   412             mDepthTextureSupport = mDepthTextureSupport && ((formatSupport & requiredDepthTextureFlags) == requiredDepthTextureFlags);
   413         }
   414         else
   415         {
   416             mDepthTextureSupport = false;
   417         }
   418     }
   420     return EGL_SUCCESS;
   421 }
   423 // do any one-time device initialization
   424 // NOTE: this is also needed after a device lost/reset
   425 // to reset the scene status and ensure the default states are reset.
   426 void Renderer11::initializeDevice()
   427 {
   428     mStateCache.initialize(mDevice);
   429     mInputLayoutCache.initialize(mDevice, mDeviceContext);
   431     ASSERT(!mVertexDataManager && !mIndexDataManager);
   432     mVertexDataManager = new VertexDataManager(this);
   433     mIndexDataManager = new IndexDataManager(this);
   435     markAllStateDirty();
   436 }
   438 int Renderer11::generateConfigs(ConfigDesc **configDescList)
   439 {
   440     unsigned int numRenderFormats = ArraySize(RenderTargetFormats);
   441     unsigned int numDepthFormats = ArraySize(DepthStencilFormats);
   442     (*configDescList) = new ConfigDesc[numRenderFormats * numDepthFormats];
   443     int numConfigs = 0;
   445     for (unsigned int formatIndex = 0; formatIndex < numRenderFormats; formatIndex++)
   446     {
   447         for (unsigned int depthStencilIndex = 0; depthStencilIndex < numDepthFormats; depthStencilIndex++)
   448         {
   449             DXGI_FORMAT renderTargetFormat = RenderTargetFormats[formatIndex];
   451             UINT formatSupport = 0;
   452             HRESULT result = mDevice->CheckFormatSupport(renderTargetFormat, &formatSupport);
   454             if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET))
   455             {
   456                 DXGI_FORMAT depthStencilFormat = DepthStencilFormats[depthStencilIndex];
   458                 bool depthStencilFormatOK = true;
   460                 if (depthStencilFormat != DXGI_FORMAT_UNKNOWN)
   461                 {
   462                     UINT formatSupport = 0;
   463                     result = mDevice->CheckFormatSupport(depthStencilFormat, &formatSupport);
   464                     depthStencilFormatOK = SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL);
   465                 }
   467                 if (depthStencilFormatOK)
   468                 {
   469                     ConfigDesc newConfig;
   470                     newConfig.renderTargetFormat = d3d11_gl::ConvertBackBufferFormat(renderTargetFormat);
   471                     newConfig.depthStencilFormat = d3d11_gl::ConvertDepthStencilFormat(depthStencilFormat);
   472                     newConfig.multiSample = 0;     // FIXME: enumerate multi-sampling
   473                     newConfig.fastConfig = true;   // Assume all DX11 format conversions to be fast
   475                     (*configDescList)[numConfigs++] = newConfig;
   476                 }
   477             }
   478         }
   479     }
   481     return numConfigs;
   482 }
   484 void Renderer11::deleteConfigs(ConfigDesc *configDescList)
   485 {
   486     delete [] (configDescList);
   487 }
   489 void Renderer11::sync(bool block)
   490 {
   491     if (block)
   492     {
   493         HRESULT result;
   495         if (!mSyncQuery)
   496         {
   497             D3D11_QUERY_DESC queryDesc;
   498             queryDesc.Query = D3D11_QUERY_EVENT;
   499             queryDesc.MiscFlags = 0;
   501             result = mDevice->CreateQuery(&queryDesc, &mSyncQuery);
   502             ASSERT(SUCCEEDED(result));
   503         }
   505         mDeviceContext->End(mSyncQuery);
   506         mDeviceContext->Flush();
   508         do
   509         {
   510             result = mDeviceContext->GetData(mSyncQuery, NULL, 0, D3D11_ASYNC_GETDATA_DONOTFLUSH);
   512             // Keep polling, but allow other threads to do something useful first
   513             Sleep(0);
   515             if (testDeviceLost(true))
   516             {
   517                 return;
   518             }
   519         }
   520         while (result == S_FALSE);
   521     }
   522     else
   523     {
   524         mDeviceContext->Flush();
   525     }
   526 }
   528 SwapChain *Renderer11::createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
   529 {
   530     return new rx::SwapChain11(this, window, shareHandle, backBufferFormat, depthBufferFormat);
   531 }
   533 void Renderer11::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState)
   534 {
   535     if (type == gl::SAMPLER_PIXEL)
   536     {
   537         if (index < 0 || index >= gl::MAX_TEXTURE_IMAGE_UNITS)
   538         {
   539             ERR("Pixel shader sampler index %i is not valid.", index);
   540             return;
   541         }
   543         if (mForceSetPixelSamplerStates[index] || memcmp(&samplerState, &mCurPixelSamplerStates[index], sizeof(gl::SamplerState)) != 0)
   544         {
   545             ID3D11SamplerState *dxSamplerState = mStateCache.getSamplerState(samplerState);
   547             if (!dxSamplerState)
   548             {
   549                 ERR("NULL sampler state returned by RenderStateCache::getSamplerState, setting the default"
   550                     "sampler state for pixel shaders at slot %i.", index);
   551             }
   553             mDeviceContext->PSSetSamplers(index, 1, &dxSamplerState);
   555             mCurPixelSamplerStates[index] = samplerState;
   556         }
   558         mForceSetPixelSamplerStates[index] = false;
   559     }
   560     else if (type == gl::SAMPLER_VERTEX)
   561     {
   562         if (index < 0 || index >= (int)getMaxVertexTextureImageUnits())
   563         {
   564             ERR("Vertex shader sampler index %i is not valid.", index);
   565             return;
   566         }
   568         if (mForceSetVertexSamplerStates[index] || memcmp(&samplerState, &mCurVertexSamplerStates[index], sizeof(gl::SamplerState)) != 0)
   569         {
   570             ID3D11SamplerState *dxSamplerState = mStateCache.getSamplerState(samplerState);
   572             if (!dxSamplerState)
   573             {
   574                 ERR("NULL sampler state returned by RenderStateCache::getSamplerState, setting the default"
   575                     "sampler state for vertex shaders at slot %i.", index);
   576             }
   578             mDeviceContext->VSSetSamplers(index, 1, &dxSamplerState);
   580             mCurVertexSamplerStates[index] = samplerState;
   581         }
   583         mForceSetVertexSamplerStates[index] = false;
   584     }
   585     else UNREACHABLE();
   586 }
   588 void Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *texture)
   589 {
   590     ID3D11ShaderResourceView *textureSRV = NULL;
   591     unsigned int serial = 0;
   592     bool forceSetTexture = false;
   594     if (texture)
   595     {
   596         TextureStorageInterface *texStorage = texture->getNativeTexture();
   597         if (texStorage)
   598         {
   599             TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage->getStorageInstance());
   600             textureSRV = storage11->getSRV();
   601         }
   603         // If we get NULL back from getSRV here, something went wrong in the texture class and we're unexpectedly
   604         // missing the shader resource view
   605         ASSERT(textureSRV != NULL);
   607         serial = texture->getTextureSerial();
   608         forceSetTexture = texture->hasDirtyImages();
   609     }
   611     if (type == gl::SAMPLER_PIXEL)
   612     {
   613         if (index < 0 || index >= gl::MAX_TEXTURE_IMAGE_UNITS)
   614         {
   615             ERR("Pixel shader sampler index %i is not valid.", index);
   616             return;
   617         }
   619         if (forceSetTexture || mCurPixelTextureSerials[index] != serial)
   620         {
   621             mDeviceContext->PSSetShaderResources(index, 1, &textureSRV);
   622         }
   624         mCurPixelTextureSerials[index] = serial;
   625     }
   626     else if (type == gl::SAMPLER_VERTEX)
   627     {
   628         if (index < 0 || index >= (int)getMaxVertexTextureImageUnits())
   629         {
   630             ERR("Vertex shader sampler index %i is not valid.", index);
   631             return;
   632         }
   634         if (forceSetTexture || mCurVertexTextureSerials[index] != serial)
   635         {
   636             mDeviceContext->VSSetShaderResources(index, 1, &textureSRV);
   637         }
   639         mCurVertexTextureSerials[index] = serial;
   640     }
   641     else UNREACHABLE();
   642 }
   644 void Renderer11::setRasterizerState(const gl::RasterizerState &rasterState)
   645 {
   646     if (mForceSetRasterState || memcmp(&rasterState, &mCurRasterState, sizeof(gl::RasterizerState)) != 0)
   647     {
   648         ID3D11RasterizerState *dxRasterState = mStateCache.getRasterizerState(rasterState, mScissorEnabled,
   649                                                                               mCurDepthSize);
   650         if (!dxRasterState)
   651         {
   652             ERR("NULL rasterizer state returned by RenderStateCache::getRasterizerState, setting the default"
   653                 "rasterizer state.");
   654         }
   656         mDeviceContext->RSSetState(dxRasterState);
   658         mCurRasterState = rasterState;
   659     }
   661     mForceSetRasterState = false;
   662 }
   664 void Renderer11::setBlendState(const gl::BlendState &blendState, const gl::Color &blendColor,
   665                                unsigned int sampleMask)
   666 {
   667     if (mForceSetBlendState ||
   668         memcmp(&blendState, &mCurBlendState, sizeof(gl::BlendState)) != 0 ||
   669         memcmp(&blendColor, &mCurBlendColor, sizeof(gl::Color)) != 0 ||
   670         sampleMask != mCurSampleMask)
   671     {
   672         ID3D11BlendState *dxBlendState = mStateCache.getBlendState(blendState);
   673         if (!dxBlendState)
   674         {
   675             ERR("NULL blend state returned by RenderStateCache::getBlendState, setting the default "
   676                 "blend state.");
   677         }
   679         float blendColors[4] = {0.0f};
   680         if (blendState.sourceBlendRGB != GL_CONSTANT_ALPHA && blendState.sourceBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA &&
   681             blendState.destBlendRGB != GL_CONSTANT_ALPHA && blendState.destBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA)
   682         {
   683             blendColors[0] = blendColor.red;
   684             blendColors[1] = blendColor.green;
   685             blendColors[2] = blendColor.blue;
   686             blendColors[3] = blendColor.alpha;
   687         }
   688         else
   689         {
   690             blendColors[0] = blendColor.alpha;
   691             blendColors[1] = blendColor.alpha;
   692             blendColors[2] = blendColor.alpha;
   693             blendColors[3] = blendColor.alpha;
   694         }
   696         mDeviceContext->OMSetBlendState(dxBlendState, blendColors, sampleMask);
   698         mCurBlendState = blendState;
   699         mCurBlendColor = blendColor;
   700         mCurSampleMask = sampleMask;
   701     }
   703     mForceSetBlendState = false;
   704 }
   706 void Renderer11::setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
   707                                       int stencilBackRef, bool frontFaceCCW)
   708 {
   709     if (mForceSetDepthStencilState ||
   710         memcmp(&depthStencilState, &mCurDepthStencilState, sizeof(gl::DepthStencilState)) != 0 ||
   711         stencilRef != mCurStencilRef || stencilBackRef != mCurStencilBackRef)
   712     {
   713         if (depthStencilState.stencilWritemask != depthStencilState.stencilBackWritemask ||
   714             stencilRef != stencilBackRef ||
   715             depthStencilState.stencilMask != depthStencilState.stencilBackMask)
   716         {
   717             ERR("Separate front/back stencil writemasks, reference values, or stencil mask values are "
   718                 "invalid under WebGL.");
   719             return gl::error(GL_INVALID_OPERATION);
   720         }
   722         ID3D11DepthStencilState *dxDepthStencilState = mStateCache.getDepthStencilState(depthStencilState);
   723         if (!dxDepthStencilState)
   724         {
   725             ERR("NULL depth stencil state returned by RenderStateCache::getDepthStencilState, "
   726                 "setting the default depth stencil state.");
   727         }
   729         mDeviceContext->OMSetDepthStencilState(dxDepthStencilState, static_cast<UINT>(stencilRef));
   731         mCurDepthStencilState = depthStencilState;
   732         mCurStencilRef = stencilRef;
   733         mCurStencilBackRef = stencilBackRef;
   734     }
   736     mForceSetDepthStencilState = false;
   737 }
   739 void Renderer11::setScissorRectangle(const gl::Rectangle &scissor, bool enabled)
   740 {
   741     if (mForceSetScissor || memcmp(&scissor, &mCurScissor, sizeof(gl::Rectangle)) != 0 ||
   742         enabled != mScissorEnabled)
   743     {
   744         if (enabled)
   745         {
   746             D3D11_RECT rect;
   747             rect.left = std::max(0, scissor.x);
   748             rect.top = std::max(0, scissor.y);
   749             rect.right = scissor.x + std::max(0, scissor.width);
   750             rect.bottom = scissor.y + std::max(0, scissor.height);
   752             mDeviceContext->RSSetScissorRects(1, &rect);
   753         }
   755         if (enabled != mScissorEnabled)
   756         {
   757             mForceSetRasterState = true;
   758         }
   760         mCurScissor = scissor;
   761         mScissorEnabled = enabled;
   762     }
   764     mForceSetScissor = false;
   765 }
   767 bool Renderer11::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, 
   768                              bool ignoreViewport)
   769 {
   770     gl::Rectangle actualViewport = viewport;
   771     float actualZNear = gl::clamp01(zNear);
   772     float actualZFar = gl::clamp01(zFar);
   773     if (ignoreViewport)
   774     {
   775         actualViewport.x = 0;
   776         actualViewport.y = 0;
   777         actualViewport.width = mRenderTargetDesc.width;
   778         actualViewport.height = mRenderTargetDesc.height;
   779         actualZNear = 0.0f;
   780         actualZFar = 1.0f;
   781     }
   783     // Get D3D viewport bounds, which depends on the feature level
   784     const Range& viewportBounds = getViewportBounds();
   786     // Clamp width and height first to the gl maximum, then clamp further if we extend past the D3D maximum bounds
   787     D3D11_VIEWPORT dxViewport;
   788     dxViewport.TopLeftX = gl::clamp(actualViewport.x, viewportBounds.start, viewportBounds.end);
   789     dxViewport.TopLeftY = gl::clamp(actualViewport.y, viewportBounds.start, viewportBounds.end);
   790     dxViewport.Width = gl::clamp(actualViewport.width, 0, getMaxViewportDimension());
   791     dxViewport.Height = gl::clamp(actualViewport.height, 0, getMaxViewportDimension());
   792     dxViewport.Width = std::min((int)dxViewport.Width, viewportBounds.end - static_cast<int>(dxViewport.TopLeftX));
   793     dxViewport.Height = std::min((int)dxViewport.Height, viewportBounds.end - static_cast<int>(dxViewport.TopLeftY));
   794     dxViewport.MinDepth = actualZNear;
   795     dxViewport.MaxDepth = actualZFar;
   797     if (dxViewport.Width <= 0 || dxViewport.Height <= 0)
   798     {
   799         return false;   // Nothing to render
   800     }
   802     bool viewportChanged = mForceSetViewport || memcmp(&actualViewport, &mCurViewport, sizeof(gl::Rectangle)) != 0 ||
   803                            actualZNear != mCurNear || actualZFar != mCurFar;
   805     if (viewportChanged)
   806     {
   807         mDeviceContext->RSSetViewports(1, &dxViewport);
   809         mCurViewport = actualViewport;
   810         mCurNear = actualZNear;
   811         mCurFar = actualZFar;
   813         mPixelConstants.viewCoords[0] = actualViewport.width  * 0.5f;
   814         mPixelConstants.viewCoords[1] = actualViewport.height * 0.5f;
   815         mPixelConstants.viewCoords[2] = actualViewport.x + (actualViewport.width  * 0.5f);
   816         mPixelConstants.viewCoords[3] = actualViewport.y + (actualViewport.height * 0.5f);
   818         mPixelConstants.depthFront[0] = (actualZFar - actualZNear) * 0.5f;
   819         mPixelConstants.depthFront[1] = (actualZNear + actualZFar) * 0.5f;
   821         mVertexConstants.depthRange[0] = actualZNear;
   822         mVertexConstants.depthRange[1] = actualZFar;
   823         mVertexConstants.depthRange[2] = actualZFar - actualZNear;
   825         mPixelConstants.depthRange[0] = actualZNear;
   826         mPixelConstants.depthRange[1] = actualZFar;
   827         mPixelConstants.depthRange[2] = actualZFar - actualZNear;
   828     }
   830     mForceSetViewport = false;
   831     return true;
   832 }
   834 bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count)
   835 {
   836     D3D11_PRIMITIVE_TOPOLOGY primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
   838     GLsizei minCount = 0;
   840     switch (mode)
   841     {
   842       case GL_POINTS:         primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST;   minCount = 1; break;
   843       case GL_LINES:          primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINELIST;      minCount = 2; break;
   844       case GL_LINE_LOOP:      primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;     minCount = 2; break;
   845       case GL_LINE_STRIP:     primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;     minCount = 2; break;
   846       case GL_TRIANGLES:      primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;  minCount = 3; break;
   847       case GL_TRIANGLE_STRIP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; minCount = 3; break;
   848           // emulate fans via rewriting index buffer
   849       case GL_TRIANGLE_FAN:   primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;  minCount = 3; break;
   850       default:
   851         return gl::error(GL_INVALID_ENUM, false);
   852     }
   854     if (primitiveTopology != mCurrentPrimitiveTopology)
   855     {
   856         mDeviceContext->IASetPrimitiveTopology(primitiveTopology);
   857         mCurrentPrimitiveTopology = primitiveTopology;
   858     }
   860     return count >= minCount;
   861 }
   863 bool Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer)
   864 {
   865     // Get the color render buffer and serial
   866     // Also extract the render target dimensions and view
   867     unsigned int renderTargetWidth = 0;
   868     unsigned int renderTargetHeight = 0;
   869     GLenum renderTargetFormat = 0;
   870     unsigned int renderTargetSerials[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {0};
   871     ID3D11RenderTargetView* framebufferRTVs[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {NULL};
   872     bool missingColorRenderTarget = true;
   874     for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
   875     {
   876         const GLenum drawBufferState = framebuffer->getDrawBufferState(colorAttachment);
   878         if (framebuffer->getColorbufferType(colorAttachment) != GL_NONE && drawBufferState != GL_NONE)
   879         {
   880             // the draw buffer must be either "none", "back" for the default buffer or the same index as this color (in order)
   881             ASSERT(drawBufferState == GL_BACK || drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + colorAttachment));
   883             gl::Renderbuffer *colorbuffer = framebuffer->getColorbuffer(colorAttachment);
   885             if (!colorbuffer)
   886             {
   887                 ERR("render target pointer unexpectedly null.");
   888                 return false;
   889             }
   891             // check for zero-sized default framebuffer, which is a special case.
   892             // in this case we do not wish to modify any state and just silently return false.
   893             // this will not report any gl error but will cause the calling method to return.
   894             if (colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0)
   895             {
   896                 return false;
   897             }
   899             renderTargetSerials[colorAttachment] = colorbuffer->getSerial();
   901             // Extract the render target dimensions and view
   902             RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget());
   903             if (!renderTarget)
   904             {
   905                 ERR("render target pointer unexpectedly null.");
   906                 return false;
   907             }
   909             framebufferRTVs[colorAttachment] = renderTarget->getRenderTargetView();
   910             if (!framebufferRTVs[colorAttachment])
   911             {
   912                 ERR("render target view pointer unexpectedly null.");
   913                 return false;
   914             }
   916             if (missingColorRenderTarget)
   917             {
   918                 renderTargetWidth = colorbuffer->getWidth();
   919                 renderTargetHeight = colorbuffer->getHeight();
   920                 renderTargetFormat = colorbuffer->getActualFormat();
   921                 missingColorRenderTarget = false;
   922             }
   923         }
   924     }
   926     // Get the depth stencil render buffer and serials
   927     gl::Renderbuffer *depthStencil = NULL;
   928     unsigned int depthbufferSerial = 0;
   929     unsigned int stencilbufferSerial = 0;
   930     if (framebuffer->getDepthbufferType() != GL_NONE)
   931     {
   932         depthStencil = framebuffer->getDepthbuffer();
   933         if (!depthStencil)
   934         {
   935             ERR("Depth stencil pointer unexpectedly null.");
   936             SafeRelease(framebufferRTVs);
   937             return false;
   938         }
   940         depthbufferSerial = depthStencil->getSerial();
   941     }
   942     else if (framebuffer->getStencilbufferType() != GL_NONE)
   943     {
   944         depthStencil = framebuffer->getStencilbuffer();
   945         if (!depthStencil)
   946         {
   947             ERR("Depth stencil pointer unexpectedly null.");
   948             SafeRelease(framebufferRTVs);
   949             return false;
   950         }
   952         stencilbufferSerial = depthStencil->getSerial();
   953     }
   955     // Extract the depth stencil sizes and view
   956     unsigned int depthSize = 0;
   957     unsigned int stencilSize = 0;
   958     ID3D11DepthStencilView* framebufferDSV = NULL;
   959     if (depthStencil)
   960     {
   961         RenderTarget11 *depthStencilRenderTarget = RenderTarget11::makeRenderTarget11(depthStencil->getDepthStencil());
   962         if (!depthStencilRenderTarget)
   963         {
   964             ERR("render target pointer unexpectedly null.");
   965             SafeRelease(framebufferRTVs);
   966             return false;
   967         }
   969         framebufferDSV = depthStencilRenderTarget->getDepthStencilView();
   970         if (!framebufferDSV)
   971         {
   972             ERR("depth stencil view pointer unexpectedly null.");
   973             SafeRelease(framebufferRTVs);
   974             return false;
   975         }
   977         // If there is no render buffer, the width, height and format values come from
   978         // the depth stencil
   979         if (missingColorRenderTarget)
   980         {
   981             renderTargetWidth = depthStencil->getWidth();
   982             renderTargetHeight = depthStencil->getHeight();
   983             renderTargetFormat = depthStencil->getActualFormat();
   984         }
   986         depthSize = depthStencil->getDepthSize();
   987         stencilSize = depthStencil->getStencilSize();
   988     }
   990     // Apply the render target and depth stencil
   991     if (!mRenderTargetDescInitialized || !mDepthStencilInitialized ||
   992         memcmp(renderTargetSerials, mAppliedRenderTargetSerials, sizeof(renderTargetSerials)) != 0 ||
   993         depthbufferSerial != mAppliedDepthbufferSerial ||
   994         stencilbufferSerial != mAppliedStencilbufferSerial)
   995     {
   996         mDeviceContext->OMSetRenderTargets(getMaxRenderTargets(), framebufferRTVs, framebufferDSV);
   998         mRenderTargetDesc.width = renderTargetWidth;
   999         mRenderTargetDesc.height = renderTargetHeight;
  1000         mRenderTargetDesc.format = renderTargetFormat;
  1001         mForceSetViewport = true;
  1002         mForceSetScissor = true;
  1004         if (!mDepthStencilInitialized || depthSize != mCurDepthSize)
  1006             mCurDepthSize = depthSize;
  1007             mForceSetRasterState = true;
  1010         mCurStencilSize = stencilSize;
  1012         for (unsigned int rtIndex = 0; rtIndex < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; rtIndex++)
  1014             mAppliedRenderTargetSerials[rtIndex] = renderTargetSerials[rtIndex];
  1016         mAppliedDepthbufferSerial = depthbufferSerial;
  1017         mAppliedStencilbufferSerial = stencilbufferSerial;
  1018         mRenderTargetDescInitialized = true;
  1019         mDepthStencilInitialized = true;
  1022     return true;
  1025 GLenum Renderer11::applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances)
  1027     TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS];
  1028     GLenum err = mVertexDataManager->prepareVertexData(vertexAttributes, programBinary, first, count, attributes, instances);
  1029     if (err != GL_NO_ERROR)
  1031         return err;
  1034     return mInputLayoutCache.applyVertexBuffers(attributes, programBinary);
  1037 GLenum Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
  1039     GLenum err = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo);
  1041     if (err == GL_NO_ERROR)
  1043         if (indexInfo->storage)
  1045             if (indexInfo->serial != mAppliedStorageIBSerial || indexInfo->startOffset != mAppliedIBOffset)
  1047                 BufferStorage11 *storage = BufferStorage11::makeBufferStorage11(indexInfo->storage);
  1048                 IndexBuffer11* indexBuffer = IndexBuffer11::makeIndexBuffer11(indexInfo->indexBuffer);
  1050                 mDeviceContext->IASetIndexBuffer(storage->getBuffer(), indexBuffer->getIndexFormat(), indexInfo->startOffset);
  1052                 mAppliedIBSerial = 0;
  1053                 mAppliedStorageIBSerial = storage->getSerial();
  1054                 mAppliedIBOffset = indexInfo->startOffset;
  1057         else if (indexInfo->serial != mAppliedIBSerial || indexInfo->startOffset != mAppliedIBOffset)
  1059             IndexBuffer11* indexBuffer = IndexBuffer11::makeIndexBuffer11(indexInfo->indexBuffer);
  1061             mDeviceContext->IASetIndexBuffer(indexBuffer->getBuffer(), indexBuffer->getIndexFormat(), indexInfo->startOffset);
  1063             mAppliedIBSerial = indexInfo->serial;
  1064             mAppliedStorageIBSerial = 0;
  1065             mAppliedIBOffset = indexInfo->startOffset;
  1069     return err;
  1072 void Renderer11::drawArrays(GLenum mode, GLsizei count, GLsizei instances)
  1074     if (mode == GL_LINE_LOOP)
  1076         drawLineLoop(count, GL_NONE, NULL, 0, NULL);
  1078     else if (mode == GL_TRIANGLE_FAN)
  1080         drawTriangleFan(count, GL_NONE, NULL, 0, NULL, instances);
  1082     else if (instances > 0)
  1084         mDeviceContext->DrawInstanced(count, instances, 0, 0);
  1086     else
  1088         mDeviceContext->Draw(count, 0);
  1092 void Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances)
  1094     if (mode == GL_LINE_LOOP)
  1096         drawLineLoop(count, type, indices, indexInfo.minIndex, elementArrayBuffer);
  1098     else if (mode == GL_TRIANGLE_FAN)
  1100         drawTriangleFan(count, type, indices, indexInfo.minIndex, elementArrayBuffer, instances);
  1102     else if (instances > 0)
  1104         mDeviceContext->DrawIndexedInstanced(count, instances, 0, -static_cast<int>(indexInfo.minIndex), 0);
  1106     else
  1108         mDeviceContext->DrawIndexed(count, 0, -static_cast<int>(indexInfo.minIndex));
  1112 void Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer)
  1114     // Get the raw indices for an indexed draw
  1115     if (type != GL_NONE && elementArrayBuffer)
  1117         gl::Buffer *indexBuffer = elementArrayBuffer;
  1118         BufferStorage *storage = indexBuffer->getStorage();
  1119         intptr_t offset = reinterpret_cast<intptr_t>(indices);
  1120         indices = static_cast<const GLubyte*>(storage->getData()) + offset;
  1123     if (!mLineLoopIB)
  1125         mLineLoopIB = new StreamingIndexBufferInterface(this);
  1126         if (!mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT))
  1128             delete mLineLoopIB;
  1129             mLineLoopIB = NULL;
  1131             ERR("Could not create a 32-bit looping index buffer for GL_LINE_LOOP.");
  1132             return gl::error(GL_OUT_OF_MEMORY);
  1136     // Checked by Renderer11::applyPrimitiveType
  1137     ASSERT(count >= 0);
  1139     if (static_cast<unsigned int>(count) + 1 > (std::numeric_limits<unsigned int>::max() / sizeof(unsigned int)))
  1141         ERR("Could not create a 32-bit looping index buffer for GL_LINE_LOOP, too many indices required.");
  1142         return gl::error(GL_OUT_OF_MEMORY);
  1145     const unsigned int spaceNeeded = (static_cast<unsigned int>(count) + 1) * sizeof(unsigned int);
  1146     if (!mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT))
  1148         ERR("Could not reserve enough space in looping index buffer for GL_LINE_LOOP.");
  1149         return gl::error(GL_OUT_OF_MEMORY);
  1152     void* mappedMemory = NULL;
  1153     unsigned int offset;
  1154     if (!mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset))
  1156         ERR("Could not map index buffer for GL_LINE_LOOP.");
  1157         return gl::error(GL_OUT_OF_MEMORY);
  1160     unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory);
  1161     unsigned int indexBufferOffset = offset;
  1163     switch (type)
  1165       case GL_NONE:   // Non-indexed draw
  1166         for (int i = 0; i < count; i++)
  1168             data[i] = i;
  1170         data[count] = 0;
  1171         break;
  1172       case GL_UNSIGNED_BYTE:
  1173         for (int i = 0; i < count; i++)
  1175             data[i] = static_cast<const GLubyte*>(indices)[i];
  1177         data[count] = static_cast<const GLubyte*>(indices)[0];
  1178         break;
  1179       case GL_UNSIGNED_SHORT:
  1180         for (int i = 0; i < count; i++)
  1182             data[i] = static_cast<const GLushort*>(indices)[i];
  1184         data[count] = static_cast<const GLushort*>(indices)[0];
  1185         break;
  1186       case GL_UNSIGNED_INT:
  1187         for (int i = 0; i < count; i++)
  1189             data[i] = static_cast<const GLuint*>(indices)[i];
  1191         data[count] = static_cast<const GLuint*>(indices)[0];
  1192         break;
  1193       default: UNREACHABLE();
  1196     if (!mLineLoopIB->unmapBuffer())
  1198         ERR("Could not unmap index buffer for GL_LINE_LOOP.");
  1199         return gl::error(GL_OUT_OF_MEMORY);
  1202     if (mAppliedIBSerial != mLineLoopIB->getSerial() || mAppliedIBOffset != indexBufferOffset)
  1204         IndexBuffer11 *indexBuffer = IndexBuffer11::makeIndexBuffer11(mLineLoopIB->getIndexBuffer());
  1206         mDeviceContext->IASetIndexBuffer(indexBuffer->getBuffer(), indexBuffer->getIndexFormat(), indexBufferOffset);
  1207         mAppliedIBSerial = mLineLoopIB->getSerial();
  1208         mAppliedStorageIBSerial = 0;
  1209         mAppliedIBOffset = indexBufferOffset;
  1212     mDeviceContext->DrawIndexed(count + 1, 0, -minIndex);
  1215 void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer, int instances)
  1217     // Get the raw indices for an indexed draw
  1218     if (type != GL_NONE && elementArrayBuffer)
  1220         gl::Buffer *indexBuffer = elementArrayBuffer;
  1221         BufferStorage *storage = indexBuffer->getStorage();
  1222         intptr_t offset = reinterpret_cast<intptr_t>(indices);
  1223         indices = static_cast<const GLubyte*>(storage->getData()) + offset;
  1226     if (!mTriangleFanIB)
  1228         mTriangleFanIB = new StreamingIndexBufferInterface(this);
  1229         if (!mTriangleFanIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT))
  1231             delete mTriangleFanIB;
  1232             mTriangleFanIB = NULL;
  1234             ERR("Could not create a scratch index buffer for GL_TRIANGLE_FAN.");
  1235             return gl::error(GL_OUT_OF_MEMORY);
  1239     // Checked by Renderer11::applyPrimitiveType
  1240     ASSERT(count >= 3);
  1242     const unsigned int numTris = count - 2;
  1244     if (numTris > (std::numeric_limits<unsigned int>::max() / (sizeof(unsigned int) * 3)))
  1246         ERR("Could not create a scratch index buffer for GL_TRIANGLE_FAN, too many indices required.");
  1247         return gl::error(GL_OUT_OF_MEMORY);
  1250     const unsigned int spaceNeeded = (numTris * 3) * sizeof(unsigned int);
  1251     if (!mTriangleFanIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT))
  1253         ERR("Could not reserve enough space in scratch index buffer for GL_TRIANGLE_FAN.");
  1254         return gl::error(GL_OUT_OF_MEMORY);
  1257     void* mappedMemory = NULL;
  1258     unsigned int offset;
  1259     if (!mTriangleFanIB->mapBuffer(spaceNeeded, &mappedMemory, &offset))
  1261         ERR("Could not map scratch index buffer for GL_TRIANGLE_FAN.");
  1262         return gl::error(GL_OUT_OF_MEMORY);
  1265     unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory);
  1266     unsigned int indexBufferOffset = offset;
  1268     switch (type)
  1270       case GL_NONE:   // Non-indexed draw
  1271         for (unsigned int i = 0; i < numTris; i++)
  1273             data[i*3 + 0] = 0;
  1274             data[i*3 + 1] = i + 1;
  1275             data[i*3 + 2] = i + 2;
  1277         break;
  1278       case GL_UNSIGNED_BYTE:
  1279         for (unsigned int i = 0; i < numTris; i++)
  1281             data[i*3 + 0] = static_cast<const GLubyte*>(indices)[0];
  1282             data[i*3 + 1] = static_cast<const GLubyte*>(indices)[i + 1];
  1283             data[i*3 + 2] = static_cast<const GLubyte*>(indices)[i + 2];
  1285         break;
  1286       case GL_UNSIGNED_SHORT:
  1287         for (unsigned int i = 0; i < numTris; i++)
  1289             data[i*3 + 0] = static_cast<const GLushort*>(indices)[0];
  1290             data[i*3 + 1] = static_cast<const GLushort*>(indices)[i + 1];
  1291             data[i*3 + 2] = static_cast<const GLushort*>(indices)[i + 2];
  1293         break;
  1294       case GL_UNSIGNED_INT:
  1295         for (unsigned int i = 0; i < numTris; i++)
  1297             data[i*3 + 0] = static_cast<const GLuint*>(indices)[0];
  1298             data[i*3 + 1] = static_cast<const GLuint*>(indices)[i + 1];
  1299             data[i*3 + 2] = static_cast<const GLuint*>(indices)[i + 2];
  1301         break;
  1302       default: UNREACHABLE();
  1305     if (!mTriangleFanIB->unmapBuffer())
  1307         ERR("Could not unmap scratch index buffer for GL_TRIANGLE_FAN.");
  1308         return gl::error(GL_OUT_OF_MEMORY);
  1311     if (mAppliedIBSerial != mTriangleFanIB->getSerial() || mAppliedIBOffset != indexBufferOffset)
  1313         IndexBuffer11 *indexBuffer = IndexBuffer11::makeIndexBuffer11(mTriangleFanIB->getIndexBuffer());
  1315         mDeviceContext->IASetIndexBuffer(indexBuffer->getBuffer(), indexBuffer->getIndexFormat(), indexBufferOffset);
  1316         mAppliedIBSerial = mTriangleFanIB->getSerial();
  1317         mAppliedStorageIBSerial = 0;
  1318         mAppliedIBOffset = indexBufferOffset;
  1321     if (instances > 0)
  1323         mDeviceContext->DrawIndexedInstanced(numTris * 3, instances, 0, -minIndex, 0);
  1325     else
  1327         mDeviceContext->DrawIndexed(numTris * 3, 0, -minIndex);
  1331 void Renderer11::applyShaders(gl::ProgramBinary *programBinary)
  1333     unsigned int programBinarySerial = programBinary->getSerial();
  1334     const bool updateProgramState = (programBinarySerial != mAppliedProgramBinarySerial);
  1336     if (updateProgramState)
  1338         ShaderExecutable *vertexExe = programBinary->getVertexExecutable();
  1339         ShaderExecutable *pixelExe = programBinary->getPixelExecutable();
  1341         ID3D11VertexShader *vertexShader = NULL;
  1342         if (vertexExe) vertexShader = ShaderExecutable11::makeShaderExecutable11(vertexExe)->getVertexShader();
  1344         ID3D11PixelShader *pixelShader = NULL;
  1345         if (pixelExe) pixelShader = ShaderExecutable11::makeShaderExecutable11(pixelExe)->getPixelShader();
  1347         mDeviceContext->PSSetShader(pixelShader, NULL, 0);
  1348         mDeviceContext->VSSetShader(vertexShader, NULL, 0);
  1350         programBinary->dirtyAllUniforms();
  1352         mAppliedProgramBinarySerial = programBinarySerial;
  1355     // Only use the geometry shader currently for point sprite drawing
  1356     const bool usesGeometryShader = (programBinary->usesGeometryShader() && mCurRasterState.pointDrawMode);
  1358     if (updateProgramState || usesGeometryShader != mIsGeometryShaderActive)
  1360         if (usesGeometryShader)
  1362             ShaderExecutable *geometryExe = programBinary->getGeometryExecutable();
  1363             ID3D11GeometryShader *geometryShader = ShaderExecutable11::makeShaderExecutable11(geometryExe)->getGeometryShader();
  1364             mDeviceContext->GSSetShader(geometryShader, NULL, 0);
  1366         else
  1368             mDeviceContext->GSSetShader(NULL, NULL, 0);
  1371         mIsGeometryShaderActive = usesGeometryShader;
  1375 void Renderer11::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray)
  1377     ShaderExecutable11 *vertexExecutable = ShaderExecutable11::makeShaderExecutable11(programBinary->getVertexExecutable());
  1378     ShaderExecutable11 *pixelExecutable = ShaderExecutable11::makeShaderExecutable11(programBinary->getPixelExecutable());
  1380     unsigned int totalRegisterCountVS = 0;
  1381     unsigned int totalRegisterCountPS = 0;
  1383     bool vertexUniformsDirty = false;
  1384     bool pixelUniformsDirty = false;
  1386     for (gl::UniformArray::const_iterator uniform_iterator = uniformArray->begin(); uniform_iterator != uniformArray->end(); uniform_iterator++)
  1388         const gl::Uniform *uniform = *uniform_iterator;
  1390         if (uniform->vsRegisterIndex >= 0)
  1392             totalRegisterCountVS += uniform->registerCount;
  1393             vertexUniformsDirty = vertexUniformsDirty || uniform->dirty;
  1396         if (uniform->psRegisterIndex >= 0)
  1398             totalRegisterCountPS += uniform->registerCount;
  1399             pixelUniformsDirty = pixelUniformsDirty || uniform->dirty;
  1403     ID3D11Buffer *vertexConstantBuffer = vertexExecutable->getConstantBuffer(mDevice, totalRegisterCountVS);
  1404     ID3D11Buffer *pixelConstantBuffer = pixelExecutable->getConstantBuffer(mDevice, totalRegisterCountPS);
  1406     float (*mapVS)[4] = NULL;
  1407     float (*mapPS)[4] = NULL;
  1409     if (totalRegisterCountVS > 0 && vertexUniformsDirty)
  1411         D3D11_MAPPED_SUBRESOURCE map = {0};
  1412         HRESULT result = mDeviceContext->Map(vertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
  1413         ASSERT(SUCCEEDED(result));
  1414         mapVS = (float(*)[4])map.pData;
  1417     if (totalRegisterCountPS > 0 && pixelUniformsDirty)
  1419         D3D11_MAPPED_SUBRESOURCE map = {0};
  1420         HRESULT result = mDeviceContext->Map(pixelConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
  1421         ASSERT(SUCCEEDED(result));
  1422         mapPS = (float(*)[4])map.pData;
  1425     for (gl::UniformArray::iterator uniform_iterator = uniformArray->begin(); uniform_iterator != uniformArray->end(); uniform_iterator++)
  1427         gl::Uniform *uniform = *uniform_iterator;
  1429         if (uniform->type !=  GL_SAMPLER_2D && uniform->type != GL_SAMPLER_CUBE)
  1431             if (uniform->vsRegisterIndex >= 0 && mapVS)
  1433                 memcpy(mapVS + uniform->vsRegisterIndex, uniform->data, uniform->registerCount * sizeof(float[4]));
  1436             if (uniform->psRegisterIndex >= 0 && mapPS)
  1438                 memcpy(mapPS + uniform->psRegisterIndex, uniform->data, uniform->registerCount * sizeof(float[4]));
  1442         uniform->dirty = false;
  1445     if (mapVS)
  1447         mDeviceContext->Unmap(vertexConstantBuffer, 0);
  1450     if (mapPS)
  1452         mDeviceContext->Unmap(pixelConstantBuffer, 0);
  1455     if (mCurrentVertexConstantBuffer != vertexConstantBuffer)
  1457         mDeviceContext->VSSetConstantBuffers(0, 1, &vertexConstantBuffer);
  1458         mCurrentVertexConstantBuffer = vertexConstantBuffer;
  1461     if (mCurrentPixelConstantBuffer != pixelConstantBuffer)
  1463         mDeviceContext->PSSetConstantBuffers(0, 1, &pixelConstantBuffer);
  1464         mCurrentPixelConstantBuffer = pixelConstantBuffer;
  1467     // Driver uniforms
  1468     if (!mDriverConstantBufferVS)
  1470         D3D11_BUFFER_DESC constantBufferDescription = {0};
  1471         constantBufferDescription.ByteWidth = sizeof(dx_VertexConstants);
  1472         constantBufferDescription.Usage = D3D11_USAGE_DEFAULT;
  1473         constantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
  1474         constantBufferDescription.CPUAccessFlags = 0;
  1475         constantBufferDescription.MiscFlags = 0;
  1476         constantBufferDescription.StructureByteStride = 0;
  1478         HRESULT result = mDevice->CreateBuffer(&constantBufferDescription, NULL, &mDriverConstantBufferVS);
  1479         ASSERT(SUCCEEDED(result));
  1481         mDeviceContext->VSSetConstantBuffers(1, 1, &mDriverConstantBufferVS);
  1484     if (!mDriverConstantBufferPS)
  1486         D3D11_BUFFER_DESC constantBufferDescription = {0};
  1487         constantBufferDescription.ByteWidth = sizeof(dx_PixelConstants);
  1488         constantBufferDescription.Usage = D3D11_USAGE_DEFAULT;
  1489         constantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
  1490         constantBufferDescription.CPUAccessFlags = 0;
  1491         constantBufferDescription.MiscFlags = 0;
  1492         constantBufferDescription.StructureByteStride = 0;
  1494         HRESULT result = mDevice->CreateBuffer(&constantBufferDescription, NULL, &mDriverConstantBufferPS);
  1495         ASSERT(SUCCEEDED(result));
  1497         mDeviceContext->PSSetConstantBuffers(1, 1, &mDriverConstantBufferPS);
  1500     if (memcmp(&mVertexConstants, &mAppliedVertexConstants, sizeof(dx_VertexConstants)) != 0)
  1502         mDeviceContext->UpdateSubresource(mDriverConstantBufferVS, 0, NULL, &mVertexConstants, 16, 0);
  1503         memcpy(&mAppliedVertexConstants, &mVertexConstants, sizeof(dx_VertexConstants));
  1506     if (memcmp(&mPixelConstants, &mAppliedPixelConstants, sizeof(dx_PixelConstants)) != 0)
  1508         mDeviceContext->UpdateSubresource(mDriverConstantBufferPS, 0, NULL, &mPixelConstants, 16, 0);
  1509         memcpy(&mAppliedPixelConstants, &mPixelConstants, sizeof(dx_PixelConstants));
  1512     // needed for the point sprite geometry shader
  1513     if (mCurrentGeometryConstantBuffer != mDriverConstantBufferPS)
  1515         mDeviceContext->GSSetConstantBuffers(0, 1, &mDriverConstantBufferPS);
  1516         mCurrentGeometryConstantBuffer = mDriverConstantBufferPS;
  1520 void Renderer11::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer)
  1522      bool alphaUnmasked = (gl::GetAlphaSize(mRenderTargetDesc.format) == 0) || clearParams.colorMaskAlpha;
  1523      bool needMaskedColorClear = (clearParams.mask & GL_COLOR_BUFFER_BIT) &&
  1524                                  !(clearParams.colorMaskRed && clearParams.colorMaskGreen &&
  1525                                    clearParams.colorMaskBlue && alphaUnmasked);
  1527      unsigned int stencilUnmasked = 0x0;
  1528      if (frameBuffer->hasStencil())
  1530          unsigned int stencilSize = gl::GetStencilSize(frameBuffer->getStencilbuffer()->getActualFormat());
  1531          stencilUnmasked = (0x1 << stencilSize) - 1;
  1533      bool needMaskedStencilClear = (clearParams.mask & GL_STENCIL_BUFFER_BIT) &&
  1534                                    (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked;
  1536      bool needScissoredClear = mScissorEnabled && (mCurScissor.x > 0 || mCurScissor.y > 0 ||
  1537                                                    mCurScissor.x + mCurScissor.width < mRenderTargetDesc.width ||
  1538                                                    mCurScissor.y + mCurScissor.height < mRenderTargetDesc.height);
  1540      if (needMaskedColorClear || needMaskedStencilClear || needScissoredClear)
  1542          maskedClear(clearParams, frameBuffer->usingExtendedDrawBuffers());
  1544      else
  1546          if (clearParams.mask & GL_COLOR_BUFFER_BIT)
  1548              for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
  1550                  if (frameBuffer->isEnabledColorAttachment(colorAttachment))
  1552                      gl::Renderbuffer *renderbufferObject = frameBuffer->getColorbuffer(colorAttachment);
  1553                      if (renderbufferObject)
  1555                         RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(renderbufferObject->getRenderTarget());
  1556                         if (!renderTarget)
  1558                             ERR("render target pointer unexpectedly null.");
  1559                             return;
  1562                         ID3D11RenderTargetView *framebufferRTV = renderTarget->getRenderTargetView();
  1563                         if (!framebufferRTV)
  1565                             ERR("render target view pointer unexpectedly null.");
  1566                             return;
  1569                         const float clearValues[4] = { clearParams.colorClearValue.red,
  1570                                                        clearParams.colorClearValue.green,
  1571                                                        clearParams.colorClearValue.blue,
  1572                                                        clearParams.colorClearValue.alpha };
  1573                         mDeviceContext->ClearRenderTargetView(framebufferRTV, clearValues);
  1578         if (clearParams.mask & GL_DEPTH_BUFFER_BIT || clearParams.mask & GL_STENCIL_BUFFER_BIT)
  1580             gl::Renderbuffer *renderbufferObject = frameBuffer->getDepthOrStencilbuffer();
  1581             if (renderbufferObject)
  1583                 RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(renderbufferObject->getDepthStencil());
  1584                 if (!renderTarget)
  1586                     ERR("render target pointer unexpectedly null.");
  1587                     return;
  1590                 ID3D11DepthStencilView *framebufferDSV = renderTarget->getDepthStencilView();
  1591                 if (!framebufferDSV)
  1593                     ERR("depth stencil view pointer unexpectedly null.");
  1594                     return;
  1597                 UINT clearFlags = 0;
  1598                 if (clearParams.mask & GL_DEPTH_BUFFER_BIT)
  1600                     clearFlags |= D3D11_CLEAR_DEPTH;
  1602                 if (clearParams.mask & GL_STENCIL_BUFFER_BIT)
  1604                     clearFlags |= D3D11_CLEAR_STENCIL;
  1607                 float depthClear = gl::clamp01(clearParams.depthClearValue);
  1608                 UINT8 stencilClear = clearParams.stencilClearValue & 0x000000FF;
  1610                 mDeviceContext->ClearDepthStencilView(framebufferDSV, clearFlags, depthClear, stencilClear);
  1616 void Renderer11::maskedClear(const gl::ClearParameters &clearParams, bool usingExtendedDrawBuffers)
  1618     HRESULT result;
  1620     if (!mClearResourcesInitialized)
  1622         ASSERT(!mClearVB && !mClearVS && !mClearSinglePS && !mClearMultiplePS && !mClearScissorRS && !mClearNoScissorRS);
  1624         D3D11_BUFFER_DESC vbDesc;
  1625         vbDesc.ByteWidth = sizeof(d3d11::PositionDepthColorVertex) * 4;
  1626         vbDesc.Usage = D3D11_USAGE_DYNAMIC;
  1627         vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
  1628         vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
  1629         vbDesc.MiscFlags = 0;
  1630         vbDesc.StructureByteStride = 0;
  1632         result = mDevice->CreateBuffer(&vbDesc, NULL, &mClearVB);
  1633         ASSERT(SUCCEEDED(result));
  1634         d3d11::SetDebugName(mClearVB, "Renderer11 masked clear vertex buffer");
  1636         D3D11_INPUT_ELEMENT_DESC quadLayout[] =
  1638             { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT,    0,  0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
  1639             { "COLOR",    0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
  1640         };
  1642         result = mDevice->CreateInputLayout(quadLayout, 2, g_VS_Clear, sizeof(g_VS_Clear), &mClearIL);
  1643         ASSERT(SUCCEEDED(result));
  1644         d3d11::SetDebugName(mClearIL, "Renderer11 masked clear input layout");
  1646         result = mDevice->CreateVertexShader(g_VS_Clear, sizeof(g_VS_Clear), NULL, &mClearVS);
  1647         ASSERT(SUCCEEDED(result));
  1648         d3d11::SetDebugName(mClearVS, "Renderer11 masked clear vertex shader");
  1650         result = mDevice->CreatePixelShader(g_PS_ClearSingle, sizeof(g_PS_ClearSingle), NULL, &mClearSinglePS);
  1651         ASSERT(SUCCEEDED(result));
  1652         d3d11::SetDebugName(mClearSinglePS, "Renderer11 masked clear pixel shader (1 RT)");
  1654         result = mDevice->CreatePixelShader(g_PS_ClearMultiple, sizeof(g_PS_ClearMultiple), NULL, &mClearMultiplePS);
  1655         ASSERT(SUCCEEDED(result));
  1656         d3d11::SetDebugName(mClearMultiplePS, "Renderer11 masked clear pixel shader (MRT)");
  1658         D3D11_RASTERIZER_DESC rsScissorDesc;
  1659         rsScissorDesc.FillMode = D3D11_FILL_SOLID;
  1660         rsScissorDesc.CullMode = D3D11_CULL_NONE;
  1661         rsScissorDesc.FrontCounterClockwise = FALSE;
  1662         rsScissorDesc.DepthBias = 0;
  1663         rsScissorDesc.DepthBiasClamp = 0.0f;
  1664         rsScissorDesc.SlopeScaledDepthBias = 0.0f;
  1665         rsScissorDesc.DepthClipEnable = FALSE;
  1666         rsScissorDesc.ScissorEnable = TRUE;
  1667         rsScissorDesc.MultisampleEnable = FALSE;
  1668         rsScissorDesc.AntialiasedLineEnable = FALSE;
  1670         result = mDevice->CreateRasterizerState(&rsScissorDesc, &mClearScissorRS);
  1671         ASSERT(SUCCEEDED(result));
  1672         d3d11::SetDebugName(mClearScissorRS, "Renderer11 masked clear scissor rasterizer state");
  1674         D3D11_RASTERIZER_DESC rsNoScissorDesc;
  1675         rsNoScissorDesc.FillMode = D3D11_FILL_SOLID;
  1676         rsNoScissorDesc.CullMode = D3D11_CULL_NONE;
  1677         rsNoScissorDesc.FrontCounterClockwise = FALSE;
  1678         rsNoScissorDesc.DepthBias = 0;
  1679         rsNoScissorDesc.DepthBiasClamp = 0.0f;
  1680         rsNoScissorDesc.SlopeScaledDepthBias = 0.0f;
  1681         rsNoScissorDesc.DepthClipEnable = FALSE;
  1682         rsNoScissorDesc.ScissorEnable = FALSE;
  1683         rsNoScissorDesc.MultisampleEnable = FALSE;
  1684         rsNoScissorDesc.AntialiasedLineEnable = FALSE;
  1686         result = mDevice->CreateRasterizerState(&rsNoScissorDesc, &mClearNoScissorRS);
  1687         ASSERT(SUCCEEDED(result));
  1688         d3d11::SetDebugName(mClearNoScissorRS, "Renderer11 masked clear no scissor rasterizer state");
  1690         mClearResourcesInitialized = true;
  1693     // Prepare the depth stencil state to write depth values if the depth should be cleared
  1694     // and stencil values if the stencil should be cleared
  1695     gl::DepthStencilState glDSState;
  1696     glDSState.depthTest = (clearParams.mask & GL_DEPTH_BUFFER_BIT) != 0;
  1697     glDSState.depthFunc = GL_ALWAYS;
  1698     glDSState.depthMask = (clearParams.mask & GL_DEPTH_BUFFER_BIT) != 0;
  1699     glDSState.stencilTest = (clearParams.mask & GL_STENCIL_BUFFER_BIT) != 0;
  1700     glDSState.stencilFunc = GL_ALWAYS;
  1701     glDSState.stencilMask = 0;
  1702     glDSState.stencilFail = GL_REPLACE;
  1703     glDSState.stencilPassDepthFail = GL_REPLACE;
  1704     glDSState.stencilPassDepthPass = GL_REPLACE;
  1705     glDSState.stencilWritemask = clearParams.stencilWriteMask;
  1706     glDSState.stencilBackFunc = GL_ALWAYS;
  1707     glDSState.stencilBackMask = 0;
  1708     glDSState.stencilBackFail = GL_REPLACE;
  1709     glDSState.stencilBackPassDepthFail = GL_REPLACE;
  1710     glDSState.stencilBackPassDepthPass = GL_REPLACE;
  1711     glDSState.stencilBackWritemask = clearParams.stencilWriteMask;
  1713     int stencilClear = clearParams.stencilClearValue & 0x000000FF;
  1715     ID3D11DepthStencilState *dsState = mStateCache.getDepthStencilState(glDSState);
  1717     // Prepare the blend state to use a write mask if the color buffer should be cleared
  1718     gl::BlendState glBlendState;
  1719     glBlendState.blend = false;
  1720     glBlendState.sourceBlendRGB = GL_ONE;
  1721     glBlendState.destBlendRGB = GL_ZERO;
  1722     glBlendState.sourceBlendAlpha = GL_ONE;
  1723     glBlendState.destBlendAlpha = GL_ZERO;
  1724     glBlendState.blendEquationRGB = GL_FUNC_ADD;
  1725     glBlendState.blendEquationAlpha = GL_FUNC_ADD;
  1726     glBlendState.colorMaskRed = (clearParams.mask & GL_COLOR_BUFFER_BIT) ? clearParams.colorMaskRed : false;
  1727     glBlendState.colorMaskGreen = (clearParams.mask & GL_COLOR_BUFFER_BIT) ? clearParams.colorMaskGreen : false;
  1728     glBlendState.colorMaskBlue = (clearParams.mask & GL_COLOR_BUFFER_BIT) ? clearParams.colorMaskBlue : false;
  1729     glBlendState.colorMaskAlpha = (clearParams.mask & GL_COLOR_BUFFER_BIT) ? clearParams.colorMaskAlpha : false;
  1730     glBlendState.sampleAlphaToCoverage = false;
  1731     glBlendState.dither = false;
  1733     static const float blendFactors[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
  1734     static const UINT sampleMask = 0xFFFFFFFF;
  1736     ID3D11BlendState *blendState = mStateCache.getBlendState(glBlendState);
  1738     // Set the vertices
  1739     D3D11_MAPPED_SUBRESOURCE mappedResource;
  1740     result = mDeviceContext->Map(mClearVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
  1741     if (FAILED(result))
  1743         ERR("Failed to map masked clear vertex buffer, HRESULT: 0x%X.", result);
  1744         return;
  1747     d3d11::PositionDepthColorVertex *vertices = reinterpret_cast<d3d11::PositionDepthColorVertex*>(mappedResource.pData);
  1749     float depthClear = gl::clamp01(clearParams.depthClearValue);
  1750     d3d11::SetPositionDepthColorVertex(&vertices[0], -1.0f,  1.0f, depthClear, clearParams.colorClearValue);
  1751     d3d11::SetPositionDepthColorVertex(&vertices[1], -1.0f, -1.0f, depthClear, clearParams.colorClearValue);
  1752     d3d11::SetPositionDepthColorVertex(&vertices[2],  1.0f,  1.0f, depthClear, clearParams.colorClearValue);
  1753     d3d11::SetPositionDepthColorVertex(&vertices[3],  1.0f, -1.0f, depthClear, clearParams.colorClearValue);
  1755     mDeviceContext->Unmap(mClearVB, 0);
  1757     // Apply state
  1758     mDeviceContext->OMSetBlendState(blendState, blendFactors, sampleMask);
  1759     mDeviceContext->OMSetDepthStencilState(dsState, stencilClear);
  1760     mDeviceContext->RSSetState(mScissorEnabled ? mClearScissorRS : mClearNoScissorRS);
  1762     // Apply shaders
  1763     ID3D11PixelShader *pixelShader = usingExtendedDrawBuffers ? mClearMultiplePS : mClearSinglePS;
  1765     mDeviceContext->IASetInputLayout(mClearIL);
  1766     mDeviceContext->VSSetShader(mClearVS, NULL, 0);
  1767     mDeviceContext->PSSetShader(pixelShader, NULL, 0);
  1768     mDeviceContext->GSSetShader(NULL, NULL, 0);
  1770     // Apply vertex buffer
  1771     static UINT stride = sizeof(d3d11::PositionDepthColorVertex);
  1772     static UINT startIdx = 0;
  1773     mDeviceContext->IASetVertexBuffers(0, 1, &mClearVB, &stride, &startIdx);
  1774     mDeviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
  1776     // Draw the clear quad
  1777     mDeviceContext->Draw(4, 0);
  1779     // Clean up
  1780     markAllStateDirty();
  1783 void Renderer11::markAllStateDirty()
  1785     for (unsigned int rtIndex = 0; rtIndex < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; rtIndex++)
  1787         mAppliedRenderTargetSerials[rtIndex] = 0;
  1789     mAppliedDepthbufferSerial = 0;
  1790     mAppliedStencilbufferSerial = 0;
  1791     mDepthStencilInitialized = false;
  1792     mRenderTargetDescInitialized = false;
  1794     for (int i = 0; i < gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; i++)
  1796         mForceSetVertexSamplerStates[i] = true;
  1797         mCurVertexTextureSerials[i] = 0;
  1799     for (int i = 0; i < gl::MAX_TEXTURE_IMAGE_UNITS; i++)
  1801         mForceSetPixelSamplerStates[i] = true;
  1802         mCurPixelTextureSerials[i] = 0;
  1805     mForceSetBlendState = true;
  1806     mForceSetRasterState = true;
  1807     mForceSetDepthStencilState = true;
  1808     mForceSetScissor = true;
  1809     mForceSetViewport = true;
  1811     mAppliedIBSerial = 0;
  1812     mAppliedStorageIBSerial = 0;
  1813     mAppliedIBOffset = 0;
  1815     mAppliedProgramBinarySerial = 0;
  1816     memset(&mAppliedVertexConstants, 0, sizeof(dx_VertexConstants));
  1817     memset(&mAppliedPixelConstants, 0, sizeof(dx_PixelConstants));
  1819     mInputLayoutCache.markDirty();
  1821     mCurrentVertexConstantBuffer = NULL;
  1822     mCurrentPixelConstantBuffer = NULL;
  1823     mCurrentGeometryConstantBuffer = NULL;
  1825     mCurrentPrimitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
  1828 void Renderer11::releaseDeviceResources()
  1830     mStateCache.clear();
  1831     mInputLayoutCache.clear();
  1833     delete mVertexDataManager;
  1834     mVertexDataManager = NULL;
  1836     delete mIndexDataManager;
  1837     mIndexDataManager = NULL;
  1839     delete mLineLoopIB;
  1840     mLineLoopIB = NULL;
  1842     delete mTriangleFanIB;
  1843     mTriangleFanIB = NULL;
  1845     SafeRelease(mCopyVB);
  1846     SafeRelease(mCopySampler);
  1847     SafeRelease(mCopyIL);
  1848     SafeRelease(mCopyIL);
  1849     SafeRelease(mCopyVS);
  1850     SafeRelease(mCopyRGBAPS);
  1851     SafeRelease(mCopyRGBPS);
  1852     SafeRelease(mCopyLumPS);
  1853     SafeRelease(mCopyLumAlphaPS);
  1855     mCopyResourcesInitialized = false;
  1857     SafeRelease(mClearVB);
  1858     SafeRelease(mClearIL);
  1859     SafeRelease(mClearVS);
  1860     SafeRelease(mClearSinglePS);
  1861     SafeRelease(mClearMultiplePS);
  1862     SafeRelease(mClearScissorRS);
  1863     SafeRelease(mClearNoScissorRS);
  1865     mClearResourcesInitialized = false;
  1867     SafeRelease(mDriverConstantBufferVS);
  1868     SafeRelease(mDriverConstantBufferPS);
  1869     SafeRelease(mSyncQuery);
  1872 void Renderer11::notifyDeviceLost()
  1874     mDeviceLost = true;
  1875     mDisplay->notifyDeviceLost();
  1878 bool Renderer11::isDeviceLost()
  1880     return mDeviceLost;
  1883 // set notify to true to broadcast a message to all contexts of the device loss
  1884 bool Renderer11::testDeviceLost(bool notify)
  1886     bool isLost = false;
  1888     // GetRemovedReason is used to test if the device is removed
  1889     HRESULT result = mDevice->GetDeviceRemovedReason();
  1890     isLost = d3d11::isDeviceLostError(result);
  1892     if (isLost)
  1894         // Log error if this is a new device lost event
  1895         if (mDeviceLost == false)
  1897             ERR("The D3D11 device was removed: 0x%08X", result);
  1900         // ensure we note the device loss --
  1901         // we'll probably get this done again by notifyDeviceLost
  1902         // but best to remember it!
  1903         // Note that we don't want to clear the device loss status here
  1904         // -- this needs to be done by resetDevice
  1905         mDeviceLost = true;
  1906         if (notify)
  1908             notifyDeviceLost();
  1912     return isLost;
  1915 bool Renderer11::testDeviceResettable()
  1917     // determine if the device is resettable by creating a dummy device
  1918     PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice");
  1920     if (D3D11CreateDevice == NULL)
  1922         return false;
  1925     D3D_FEATURE_LEVEL featureLevels[] =
  1927         D3D_FEATURE_LEVEL_11_0,
  1928         D3D_FEATURE_LEVEL_10_1,
  1929         D3D_FEATURE_LEVEL_10_0,
  1930     };
  1932     ID3D11Device* dummyDevice;
  1933     D3D_FEATURE_LEVEL dummyFeatureLevel;
  1934     ID3D11DeviceContext* dummyContext;
  1936     HRESULT result = D3D11CreateDevice(NULL,
  1937                                        D3D_DRIVER_TYPE_HARDWARE,
  1938                                        NULL,
  1939                                        #if defined(_DEBUG)
  1940                                        D3D11_CREATE_DEVICE_DEBUG,
  1941                                        #else
  1942                                        0,
  1943                                        #endif
  1944                                        featureLevels,
  1945                                        ArraySize(featureLevels),
  1946                                        D3D11_SDK_VERSION,
  1947                                        &dummyDevice,
  1948                                        &dummyFeatureLevel,
  1949                                        &dummyContext);
  1951     if (!mDevice || FAILED(result))
  1953         return false;
  1956     dummyContext->Release();
  1957     dummyDevice->Release();
  1959     return true;
  1962 void Renderer11::release()
  1964     releaseDeviceResources();
  1966     if (mDxgiFactory)
  1968         mDxgiFactory->Release();
  1969         mDxgiFactory = NULL;
  1972     if (mDxgiAdapter)
  1974         mDxgiAdapter->Release();
  1975         mDxgiAdapter = NULL;
  1978     if (mDeviceContext)
  1980         mDeviceContext->ClearState();
  1981         mDeviceContext->Flush();
  1982         mDeviceContext->Release();
  1983         mDeviceContext = NULL;
  1986     if (mDevice)
  1988         mDevice->Release();
  1989         mDevice = NULL;
  1992     if (mD3d11Module)
  1994         FreeLibrary(mD3d11Module);
  1995         mD3d11Module = NULL;
  1998     if (mDxgiModule)
  2000         FreeLibrary(mDxgiModule);
  2001         mDxgiModule = NULL;
  2005 bool Renderer11::resetDevice()
  2007     // recreate everything
  2008     release();
  2009     EGLint result = initialize();
  2011     if (result != EGL_SUCCESS)
  2013         ERR("Could not reinitialize D3D11 device: %08X", result);
  2014         return false;
  2017     mDeviceLost = false;
  2019     return true;
  2022 DWORD Renderer11::getAdapterVendor() const
  2024     return mAdapterDescription.VendorId;
  2027 std::string Renderer11::getRendererDescription() const
  2029     std::ostringstream rendererString;
  2031     rendererString << mDescription;
  2032     rendererString << " Direct3D11";
  2034     rendererString << " vs_" << getMajorShaderModel() << "_" << getMinorShaderModel();
  2035     rendererString << " ps_" << getMajorShaderModel() << "_" << getMinorShaderModel();
  2037     return rendererString.str();
  2040 GUID Renderer11::getAdapterIdentifier() const
  2042     // Use the adapter LUID as our adapter ID
  2043     // This number is local to a machine is only guaranteed to be unique between restarts
  2044     META_ASSERT(sizeof(LUID) <= sizeof(GUID));
  2045     GUID adapterId = {0};
  2046     memcpy(&adapterId, &mAdapterDescription.AdapterLuid, sizeof(LUID));
  2047     return adapterId;
  2050 bool Renderer11::getBGRATextureSupport() const
  2052     return mBGRATextureSupport;
  2055 bool Renderer11::getDXT1TextureSupport()
  2057     return mDXT1TextureSupport;
  2060 bool Renderer11::getDXT3TextureSupport()
  2062     return mDXT3TextureSupport;
  2065 bool Renderer11::getDXT5TextureSupport()
  2067     return mDXT5TextureSupport;
  2070 bool Renderer11::getDepthTextureSupport() const
  2072     return mDepthTextureSupport;
  2075 bool Renderer11::getFloat32TextureSupport(bool *filtering, bool *renderable)
  2077     *renderable = mFloat32RenderSupport;
  2078     *filtering = mFloat32FilterSupport;
  2079     return mFloat32TextureSupport;
  2082 bool Renderer11::getFloat16TextureSupport(bool *filtering, bool *renderable)
  2084     *renderable = mFloat16RenderSupport;
  2085     *filtering = mFloat16FilterSupport;
  2086     return mFloat16TextureSupport;
  2089 bool Renderer11::getLuminanceTextureSupport()
  2091     return false;
  2094 bool Renderer11::getLuminanceAlphaTextureSupport()
  2096     return false;
  2099 bool Renderer11::getTextureFilterAnisotropySupport() const
  2101     return true;
  2104 float Renderer11::getTextureMaxAnisotropy() const
  2106     switch (mFeatureLevel)
  2108       case D3D_FEATURE_LEVEL_11_0:
  2109         return D3D11_MAX_MAXANISOTROPY;
  2110       case D3D_FEATURE_LEVEL_10_1:
  2111       case D3D_FEATURE_LEVEL_10_0:
  2112         return D3D10_MAX_MAXANISOTROPY;
  2113       default: UNREACHABLE();
  2114         return 0;
  2118 bool Renderer11::getEventQuerySupport()
  2120     return true;
  2123 Range Renderer11::getViewportBounds() const
  2125     switch (mFeatureLevel)
  2127       case D3D_FEATURE_LEVEL_11_0:
  2128         return Range(D3D11_VIEWPORT_BOUNDS_MIN, D3D11_VIEWPORT_BOUNDS_MAX);
  2129       case D3D_FEATURE_LEVEL_10_1:
  2130       case D3D_FEATURE_LEVEL_10_0:
  2131         return Range(D3D10_VIEWPORT_BOUNDS_MIN, D3D10_VIEWPORT_BOUNDS_MAX);
  2132       default: UNREACHABLE();
  2133         return Range(0, 0);
  2137 unsigned int Renderer11::getMaxVertexTextureImageUnits() const
  2139     META_ASSERT(MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 <= gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
  2140     switch (mFeatureLevel)
  2142       case D3D_FEATURE_LEVEL_11_0:
  2143       case D3D_FEATURE_LEVEL_10_1:
  2144       case D3D_FEATURE_LEVEL_10_0:
  2145         return MAX_TEXTURE_IMAGE_UNITS_VTF_SM4;
  2146       default: UNREACHABLE();
  2147         return 0;
  2151 unsigned int Renderer11::getMaxCombinedTextureImageUnits() const
  2153     return gl::MAX_TEXTURE_IMAGE_UNITS + getMaxVertexTextureImageUnits();
  2156 unsigned int Renderer11::getReservedVertexUniformVectors() const
  2158     return 0;   // Driver uniforms are stored in a separate constant buffer
  2161 unsigned int Renderer11::getReservedFragmentUniformVectors() const
  2163     return 0;   // Driver uniforms are stored in a separate constant buffer
  2166 unsigned int Renderer11::getMaxVertexUniformVectors() const
  2168     META_ASSERT(MAX_VERTEX_UNIFORM_VECTORS_D3D11 <= D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT);
  2169     ASSERT(mFeatureLevel >= D3D_FEATURE_LEVEL_10_0);
  2170     return MAX_VERTEX_UNIFORM_VECTORS_D3D11;
  2173 unsigned int Renderer11::getMaxFragmentUniformVectors() const
  2175     META_ASSERT(MAX_FRAGMENT_UNIFORM_VECTORS_D3D11 <= D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT);
  2176     ASSERT(mFeatureLevel >= D3D_FEATURE_LEVEL_10_0);
  2177     return MAX_FRAGMENT_UNIFORM_VECTORS_D3D11;
  2180 unsigned int Renderer11::getMaxVaryingVectors() const
  2182     META_ASSERT(gl::IMPLEMENTATION_MAX_VARYING_VECTORS == D3D11_VS_OUTPUT_REGISTER_COUNT);
  2183     switch (mFeatureLevel)
  2185       case D3D_FEATURE_LEVEL_11_0:
  2186         return D3D11_VS_OUTPUT_REGISTER_COUNT;
  2187       case D3D_FEATURE_LEVEL_10_1:
  2188       case D3D_FEATURE_LEVEL_10_0:
  2189         return D3D10_VS_OUTPUT_REGISTER_COUNT;
  2190       default: UNREACHABLE();
  2191         return 0;
  2195 bool Renderer11::getNonPower2TextureSupport() const
  2197     switch (mFeatureLevel)
  2199       case D3D_FEATURE_LEVEL_11_0:
  2200       case D3D_FEATURE_LEVEL_10_1:
  2201       case D3D_FEATURE_LEVEL_10_0:
  2202         return true;
  2203       default: UNREACHABLE();
  2204         return false;
  2208 bool Renderer11::getOcclusionQuerySupport() const
  2210     switch (mFeatureLevel)
  2212       case D3D_FEATURE_LEVEL_11_0:
  2213       case D3D_FEATURE_LEVEL_10_1:
  2214       case D3D_FEATURE_LEVEL_10_0:
  2215         return true;
  2216       default: UNREACHABLE();
  2217         return false;
  2221 bool Renderer11::getInstancingSupport() const
  2223     switch (mFeatureLevel)
  2225       case D3D_FEATURE_LEVEL_11_0:
  2226       case D3D_FEATURE_LEVEL_10_1:
  2227       case D3D_FEATURE_LEVEL_10_0:
  2228         return true;
  2229       default: UNREACHABLE();
  2230         return false;
  2234 bool Renderer11::getShareHandleSupport() const
  2236     // We only currently support share handles with BGRA surfaces, because
  2237     // chrome needs BGRA. Once chrome fixes this, we should always support them.
  2238     // PIX doesn't seem to support using share handles, so disable them.
  2239     return getBGRATextureSupport() && !gl::perfActive();
  2242 bool Renderer11::getDerivativeInstructionSupport() const
  2244     switch (mFeatureLevel)
  2246       case D3D_FEATURE_LEVEL_11_0:
  2247       case D3D_FEATURE_LEVEL_10_1:
  2248       case D3D_FEATURE_LEVEL_10_0:
  2249         return true;
  2250       default: UNREACHABLE();
  2251         return false;
  2255 bool Renderer11::getPostSubBufferSupport() const
  2257     // D3D11 does not support present with dirty rectangles until D3D11.1 and DXGI 1.2.
  2258     return false;
  2261 int Renderer11::getMajorShaderModel() const
  2263     switch (mFeatureLevel)
  2265       case D3D_FEATURE_LEVEL_11_0: return D3D11_SHADER_MAJOR_VERSION;   // 5
  2266       case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SHADER_MAJOR_VERSION; // 4
  2267       case D3D_FEATURE_LEVEL_10_0: return D3D10_SHADER_MAJOR_VERSION;   // 4
  2268       default: UNREACHABLE();      return 0;
  2272 int Renderer11::getMinorShaderModel() const
  2274     switch (mFeatureLevel)
  2276       case D3D_FEATURE_LEVEL_11_0: return D3D11_SHADER_MINOR_VERSION;   // 0
  2277       case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SHADER_MINOR_VERSION; // 1
  2278       case D3D_FEATURE_LEVEL_10_0: return D3D10_SHADER_MINOR_VERSION;   // 0
  2279       default: UNREACHABLE();      return 0;
  2283 float Renderer11::getMaxPointSize() const
  2285     // choose a reasonable maximum. we enforce this in the shader.
  2286     // (nb: on a Radeon 2600xt, DX9 reports a 256 max point size)
  2287     return 1024.0f;
  2290 int Renderer11::getMaxViewportDimension() const
  2292     // Maximum viewport size must be at least as large as the largest render buffer (or larger).
  2293     // In our case return the maximum texture size, which is the maximum render buffer size.
  2294     META_ASSERT(D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION * 2 - 1 <= D3D11_VIEWPORT_BOUNDS_MAX);
  2295     META_ASSERT(D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION * 2 - 1 <= D3D10_VIEWPORT_BOUNDS_MAX);
  2297     switch (mFeatureLevel)
  2299       case D3D_FEATURE_LEVEL_11_0: 
  2300         return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;   // 16384
  2301       case D3D_FEATURE_LEVEL_10_1:
  2302       case D3D_FEATURE_LEVEL_10_0: 
  2303         return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION;   // 8192
  2304       default: UNREACHABLE();      
  2305         return 0;
  2309 int Renderer11::getMaxTextureWidth() const
  2311     switch (mFeatureLevel)
  2313       case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;   // 16384
  2314       case D3D_FEATURE_LEVEL_10_1:
  2315       case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION;   // 8192
  2316       default: UNREACHABLE();      return 0;
  2320 int Renderer11::getMaxTextureHeight() const
  2322     switch (mFeatureLevel)
  2324       case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;   // 16384
  2325       case D3D_FEATURE_LEVEL_10_1:
  2326       case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION;   // 8192
  2327       default: UNREACHABLE();      return 0;
  2331 bool Renderer11::get32BitIndexSupport() const
  2333     switch (mFeatureLevel)
  2335       case D3D_FEATURE_LEVEL_11_0: 
  2336       case D3D_FEATURE_LEVEL_10_1:
  2337       case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP >= 32;   // true
  2338       default: UNREACHABLE();      return false;
  2342 int Renderer11::getMinSwapInterval() const
  2344     return 0;
  2347 int Renderer11::getMaxSwapInterval() const
  2349     return 4;
  2352 int Renderer11::getMaxSupportedSamples() const
  2354     return mMaxSupportedSamples;
  2357 int Renderer11::getNearestSupportedSamples(DXGI_FORMAT format, unsigned int requested) const
  2359     if (requested == 0)
  2361         return 0;
  2364     MultisampleSupportMap::const_iterator iter = mMultisampleSupportMap.find(format);
  2365     if (iter != mMultisampleSupportMap.end())
  2367         const MultisampleSupportInfo& info = iter->second;
  2368         for (unsigned int i = requested - 1; i < D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; i++)
  2370             if (info.qualityLevels[i] > 0)
  2372                 return i + 1;
  2377     return -1;
  2380 unsigned int Renderer11::getMaxRenderTargets() const
  2382     META_ASSERT(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT <= gl::IMPLEMENTATION_MAX_DRAW_BUFFERS);
  2383     META_ASSERT(D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT <= gl::IMPLEMENTATION_MAX_DRAW_BUFFERS);
  2385     switch (mFeatureLevel)
  2387       case D3D_FEATURE_LEVEL_11_0:
  2388         return D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT;  // 8
  2389       case D3D_FEATURE_LEVEL_10_1:
  2390       case D3D_FEATURE_LEVEL_10_0:
  2391         return D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT;  // 8
  2392       default:
  2393         UNREACHABLE();
  2394         return 1;
  2398 bool Renderer11::copyToRenderTarget(TextureStorageInterface2D *dest, TextureStorageInterface2D *source)
  2400     if (source && dest)
  2402         TextureStorage11_2D *source11 = TextureStorage11_2D::makeTextureStorage11_2D(source->getStorageInstance());
  2403         TextureStorage11_2D *dest11 = TextureStorage11_2D::makeTextureStorage11_2D(dest->getStorageInstance());
  2405         mDeviceContext->CopyResource(dest11->getBaseTexture(), source11->getBaseTexture());
  2406         return true;
  2409     return false;
  2412 bool Renderer11::copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureStorageInterfaceCube *source)
  2414     if (source && dest)
  2416         TextureStorage11_Cube *source11 = TextureStorage11_Cube::makeTextureStorage11_Cube(source->getStorageInstance());
  2417         TextureStorage11_Cube *dest11 = TextureStorage11_Cube::makeTextureStorage11_Cube(dest->getStorageInstance());
  2419         mDeviceContext->CopyResource(dest11->getBaseTexture(), source11->getBaseTexture());
  2420         return true;
  2423     return false;
  2426 bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
  2427                            GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level)
  2429     gl::Renderbuffer *colorbuffer = framebuffer->getReadColorbuffer();
  2430     if (!colorbuffer)
  2432         ERR("Failed to retrieve the color buffer from the frame buffer.");
  2433         return gl::error(GL_OUT_OF_MEMORY, false);
  2436     RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget());
  2437     if (!sourceRenderTarget)
  2439         ERR("Failed to retrieve the render target from the frame buffer.");
  2440         return gl::error(GL_OUT_OF_MEMORY, false);
  2443     ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
  2444     if (!source)
  2446         ERR("Failed to retrieve the render target view from the render target.");
  2447         return gl::error(GL_OUT_OF_MEMORY, false);
  2450     TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage->getStorageInstance());
  2451     if (!storage11)
  2453         ERR("Failed to retrieve the texture storage from the destination.");
  2454         return gl::error(GL_OUT_OF_MEMORY, false);
  2457     RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(level));
  2458     if (!destRenderTarget)
  2460         ERR("Failed to retrieve the render target from the destination storage.");
  2461         return gl::error(GL_OUT_OF_MEMORY, false);
  2464     ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView();
  2465     if (!dest)
  2467         ERR("Failed to retrieve the render target view from the destination render target.");
  2468         return gl::error(GL_OUT_OF_MEMORY, false);
  2471     gl::Rectangle destRect;
  2472     destRect.x = xoffset;
  2473     destRect.y = yoffset;
  2474     destRect.width = sourceRect.width;
  2475     destRect.height = sourceRect.height;
  2477     bool ret = copyTexture(source, sourceRect, sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(),
  2478                            dest, destRect, destRenderTarget->getWidth(), destRenderTarget->getHeight(), destFormat);
  2480     return ret;
  2483 bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
  2484                            GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level)
  2486     gl::Renderbuffer *colorbuffer = framebuffer->getReadColorbuffer();
  2487     if (!colorbuffer)
  2489         ERR("Failed to retrieve the color buffer from the frame buffer.");
  2490         return gl::error(GL_OUT_OF_MEMORY, false);
  2493     RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget());
  2494     if (!sourceRenderTarget)
  2496         ERR("Failed to retrieve the render target from the frame buffer.");
  2497         return gl::error(GL_OUT_OF_MEMORY, false);
  2500     ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
  2501     if (!source)
  2503         ERR("Failed to retrieve the render target view from the render target.");
  2504         return gl::error(GL_OUT_OF_MEMORY, false);
  2507     TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage->getStorageInstance());
  2508     if (!storage11)
  2510         ERR("Failed to retrieve the texture storage from the destination.");
  2511         return gl::error(GL_OUT_OF_MEMORY, false);
  2514     RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(target, level));
  2515     if (!destRenderTarget)
  2517         ERR("Failed to retrieve the render target from the destination storage.");
  2518         return gl::error(GL_OUT_OF_MEMORY, false);
  2521     ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView();
  2522     if (!dest)
  2524         ERR("Failed to retrieve the render target view from the destination render target.");
  2525         return gl::error(GL_OUT_OF_MEMORY, false);
  2528     gl::Rectangle destRect;
  2529     destRect.x = xoffset;
  2530     destRect.y = yoffset;
  2531     destRect.width = sourceRect.width;
  2532     destRect.height = sourceRect.height;
  2534     bool ret = copyTexture(source, sourceRect, sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(),
  2535                            dest, destRect, destRenderTarget->getWidth(), destRenderTarget->getHeight(), destFormat);
  2537     return ret;
  2540 bool Renderer11::copyTexture(ID3D11ShaderResourceView *source, const gl::Rectangle &sourceArea, unsigned int sourceWidth, unsigned int sourceHeight,
  2541                              ID3D11RenderTargetView *dest, const gl::Rectangle &destArea, unsigned int destWidth, unsigned int destHeight, GLenum destFormat)
  2543     HRESULT result;
  2545     if (!mCopyResourcesInitialized)
  2547         ASSERT(!mCopyVB && !mCopySampler && !mCopyIL && !mCopyVS && !mCopyRGBAPS && !mCopyRGBPS && !mCopyLumPS && !mCopyLumAlphaPS);
  2549         D3D11_BUFFER_DESC vbDesc;
  2550         vbDesc.ByteWidth = sizeof(d3d11::PositionTexCoordVertex) * 4;
  2551         vbDesc.Usage = D3D11_USAGE_DYNAMIC;
  2552         vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
  2553         vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
  2554         vbDesc.MiscFlags = 0;
  2555         vbDesc.StructureByteStride = 0;
  2557         result = mDevice->CreateBuffer(&vbDesc, NULL, &mCopyVB);
  2558         ASSERT(SUCCEEDED(result));
  2559         d3d11::SetDebugName(mCopyVB, "Renderer11 copy texture vertex buffer");
  2561         D3D11_SAMPLER_DESC samplerDesc;
  2562         samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
  2563         samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
  2564         samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
  2565         samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
  2566         samplerDesc.MipLODBias = 0.0f;
  2567         samplerDesc.MaxAnisotropy = 0;
  2568         samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
  2569         samplerDesc.BorderColor[0] = 0.0f;
  2570         samplerDesc.BorderColor[1] = 0.0f;
  2571         samplerDesc.BorderColor[2] = 0.0f;
  2572         samplerDesc.BorderColor[3] = 0.0f;
  2573         samplerDesc.MinLOD = 0.0f;
  2574         samplerDesc.MaxLOD = 0.0f;
  2576         result = mDevice->CreateSamplerState(&samplerDesc, &mCopySampler);
  2577         ASSERT(SUCCEEDED(result));
  2578         d3d11::SetDebugName(mCopySampler, "Renderer11 copy sampler");
  2580         D3D11_INPUT_ELEMENT_DESC quadLayout[] =
  2582             { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
  2583             { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 },
  2584         };
  2586         result = mDevice->CreateInputLayout(quadLayout, 2, g_VS_Passthrough, sizeof(g_VS_Passthrough), &mCopyIL);
  2587         ASSERT(SUCCEEDED(result));
  2588         d3d11::SetDebugName(mCopyIL, "Renderer11 copy texture input layout");
  2590         result = mDevice->CreateVertexShader(g_VS_Passthrough, sizeof(g_VS_Passthrough), NULL, &mCopyVS);
  2591         ASSERT(SUCCEEDED(result));
  2592         d3d11::SetDebugName(mCopyVS, "Renderer11 copy texture vertex shader");
  2594         result = mDevice->CreatePixelShader(g_PS_PassthroughRGBA, sizeof(g_PS_PassthroughRGBA), NULL, &mCopyRGBAPS);
  2595         ASSERT(SUCCEEDED(result));
  2596         d3d11::SetDebugName(mCopyRGBAPS, "Renderer11 copy texture RGBA pixel shader");
  2598         result = mDevice->CreatePixelShader(g_PS_PassthroughRGB, sizeof(g_PS_PassthroughRGB), NULL, &mCopyRGBPS);
  2599         ASSERT(SUCCEEDED(result));
  2600         d3d11::SetDebugName(mCopyRGBPS, "Renderer11 copy texture RGB pixel shader");
  2602         result = mDevice->CreatePixelShader(g_PS_PassthroughLum, sizeof(g_PS_PassthroughLum), NULL, &mCopyLumPS);
  2603         ASSERT(SUCCEEDED(result));
  2604         d3d11::SetDebugName(mCopyLumPS, "Renderer11 copy texture luminance pixel shader");
  2606         result = mDevice->CreatePixelShader(g_PS_PassthroughLumAlpha, sizeof(g_PS_PassthroughLumAlpha), NULL, &mCopyLumAlphaPS);
  2607         ASSERT(SUCCEEDED(result));
  2608         d3d11::SetDebugName(mCopyLumAlphaPS, "Renderer11 copy texture luminance alpha pixel shader");
  2610         mCopyResourcesInitialized = true;
  2613     // Verify the source and destination area sizes
  2614     if (sourceArea.x < 0 || sourceArea.x + sourceArea.width > static_cast<int>(sourceWidth) ||
  2615         sourceArea.y < 0 || sourceArea.y + sourceArea.height > static_cast<int>(sourceHeight) ||
  2616         destArea.x < 0 || destArea.x + destArea.width > static_cast<int>(destWidth) ||
  2617         destArea.y < 0 || destArea.y + destArea.height > static_cast<int>(destHeight))
  2619         return gl::error(GL_INVALID_VALUE, false);
  2622     // Set vertices
  2623     D3D11_MAPPED_SUBRESOURCE mappedResource;
  2624     result = mDeviceContext->Map(mCopyVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
  2625     if (FAILED(result))
  2627         ERR("Failed to map vertex buffer for texture copy, HRESULT: 0x%X.", result);
  2628         return gl::error(GL_OUT_OF_MEMORY, false);
  2631     d3d11::PositionTexCoordVertex *vertices = static_cast<d3d11::PositionTexCoordVertex*>(mappedResource.pData);
  2633     // Create a quad in homogeneous coordinates
  2634     float x1 = (destArea.x / float(destWidth)) * 2.0f - 1.0f;
  2635     float y1 = ((destHeight - destArea.y - destArea.height) / float(destHeight)) * 2.0f - 1.0f;
  2636     float x2 = ((destArea.x + destArea.width) / float(destWidth)) * 2.0f - 1.0f;
  2637     float y2 = ((destHeight - destArea.y) / float(destHeight)) * 2.0f - 1.0f;
  2639     float u1 = sourceArea.x / float(sourceWidth);
  2640     float v1 = sourceArea.y / float(sourceHeight);
  2641     float u2 = (sourceArea.x + sourceArea.width) / float(sourceWidth);
  2642     float v2 = (sourceArea.y + sourceArea.height) / float(sourceHeight);
  2644     d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, u1, v2);
  2645     d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v1);
  2646     d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v2);
  2647     d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v1);
  2649     mDeviceContext->Unmap(mCopyVB, 0);
  2651     static UINT stride = sizeof(d3d11::PositionTexCoordVertex);
  2652     static UINT startIdx = 0;
  2653     mDeviceContext->IASetVertexBuffers(0, 1, &mCopyVB, &stride, &startIdx);
  2655     // Apply state
  2656     mDeviceContext->OMSetBlendState(NULL, NULL, 0xFFFFFFF);
  2657     mDeviceContext->OMSetDepthStencilState(NULL, 0xFFFFFFFF);
  2658     mDeviceContext->RSSetState(NULL);
  2660     // Apply shaders
  2661     mDeviceContext->IASetInputLayout(mCopyIL);
  2662     mDeviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
  2663     mDeviceContext->VSSetShader(mCopyVS, NULL, 0);
  2665     ID3D11PixelShader *ps = NULL;
  2666     switch(destFormat)
  2668       case GL_RGBA:            ps = mCopyRGBAPS;     break;
  2669       case GL_RGB:             ps = mCopyRGBPS;      break;
  2670       case GL_ALPHA:           ps = mCopyRGBAPS;     break;
  2671       case GL_BGRA_EXT:        ps = mCopyRGBAPS;     break;
  2672       case GL_LUMINANCE:       ps = mCopyLumPS;      break;
  2673       case GL_LUMINANCE_ALPHA: ps = mCopyLumAlphaPS; break;
  2674       default: UNREACHABLE();  ps = NULL;            break;
  2677     mDeviceContext->PSSetShader(ps, NULL, 0);
  2678     mDeviceContext->GSSetShader(NULL, NULL, 0);
  2680     // Unset the currently bound shader resource to avoid conflicts
  2681     static ID3D11ShaderResourceView *const nullSRV = NULL;
  2682     mDeviceContext->PSSetShaderResources(0, 1, &nullSRV);
  2684     // Apply render target
  2685     setOneTimeRenderTarget(dest);
  2687     // Set the viewport
  2688     D3D11_VIEWPORT viewport;
  2689     viewport.TopLeftX = 0;
  2690     viewport.TopLeftY = 0;
  2691     viewport.Width = destWidth;
  2692     viewport.Height = destHeight;
  2693     viewport.MinDepth = 0.0f;
  2694     viewport.MaxDepth = 1.0f;
  2695     mDeviceContext->RSSetViewports(1, &viewport);
  2697     // Apply textures
  2698     mDeviceContext->PSSetShaderResources(0, 1, &source);
  2699     mDeviceContext->PSSetSamplers(0, 1, &mCopySampler);
  2701     // Draw the quad
  2702     mDeviceContext->Draw(4, 0);
  2704     // Unbind textures and render targets and vertex buffer
  2705     mDeviceContext->PSSetShaderResources(0, 1, &nullSRV);
  2707     unapplyRenderTargets();
  2709     UINT zero = 0;
  2710     ID3D11Buffer *const nullBuffer = NULL;
  2711     mDeviceContext->IASetVertexBuffers(0, 1, &nullBuffer, &zero, &zero);
  2713     markAllStateDirty();
  2715     return true;
  2718 void Renderer11::unapplyRenderTargets()
  2720     setOneTimeRenderTarget(NULL);
  2723 void Renderer11::setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView)
  2725     ID3D11RenderTargetView *rtvArray[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {NULL};
  2727     rtvArray[0] = renderTargetView;
  2729     mDeviceContext->OMSetRenderTargets(getMaxRenderTargets(), rtvArray, NULL);
  2731     // Do not preserve the serial for this one-time-use render target
  2732     for (unsigned int rtIndex = 0; rtIndex < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; rtIndex++)
  2734         mAppliedRenderTargetSerials[rtIndex] = 0;
  2738 RenderTarget *Renderer11::createRenderTarget(SwapChain *swapChain, bool depth)
  2740     SwapChain11 *swapChain11 = SwapChain11::makeSwapChain11(swapChain);
  2741     RenderTarget11 *renderTarget = NULL;
  2743     if (depth)
  2745         // Note: depth stencil may be NULL for 0 sized surfaces
  2746         renderTarget = new RenderTarget11(this, swapChain11->getDepthStencil(),
  2747                                           swapChain11->getDepthStencilTexture(), NULL,
  2748                                           swapChain11->getWidth(), swapChain11->getHeight());
  2750     else
  2752         // Note: render target may be NULL for 0 sized surfaces
  2753         renderTarget = new RenderTarget11(this, swapChain11->getRenderTarget(),
  2754                                           swapChain11->getOffscreenTexture(),
  2755                                           swapChain11->getRenderTargetShaderResource(),
  2756                                           swapChain11->getWidth(), swapChain11->getHeight());
  2758     return renderTarget;
  2761 RenderTarget *Renderer11::createRenderTarget(int width, int height, GLenum format, GLsizei samples, bool depth)
  2763     RenderTarget11 *renderTarget = new RenderTarget11(this, width, height, format, samples, depth);
  2764     return renderTarget;
  2767 ShaderExecutable *Renderer11::loadExecutable(const void *function, size_t length, rx::ShaderType type)
  2769     ShaderExecutable11 *executable = NULL;
  2771     switch (type)
  2773       case rx::SHADER_VERTEX:
  2775             ID3D11VertexShader *vshader = NULL;
  2776             HRESULT result = mDevice->CreateVertexShader(function, length, NULL, &vshader);
  2777             ASSERT(SUCCEEDED(result));
  2779             if (vshader)
  2781                 executable = new ShaderExecutable11(function, length, vshader);
  2784         break;
  2785       case rx::SHADER_PIXEL:
  2787             ID3D11PixelShader *pshader = NULL;
  2788             HRESULT result = mDevice->CreatePixelShader(function, length, NULL, &pshader);
  2789             ASSERT(SUCCEEDED(result));
  2791             if (pshader)
  2793                 executable = new ShaderExecutable11(function, length, pshader);
  2796         break;
  2797       case rx::SHADER_GEOMETRY:
  2799             ID3D11GeometryShader *gshader = NULL;
  2800             HRESULT result = mDevice->CreateGeometryShader(function, length, NULL, &gshader);
  2801             ASSERT(SUCCEEDED(result));
  2803             if (gshader)
  2805                 executable = new ShaderExecutable11(function, length, gshader);
  2808         break;
  2809       default:
  2810         UNREACHABLE();
  2811         break;
  2814     return executable;
  2817 ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type)
  2819     const char *profile = NULL;
  2821     switch (type)
  2823       case rx::SHADER_VERTEX:
  2824         profile = "vs_4_0";
  2825         break;
  2826       case rx::SHADER_PIXEL:
  2827         profile = "ps_4_0";
  2828         break;
  2829       case rx::SHADER_GEOMETRY:
  2830         profile = "gs_4_0";
  2831         break;
  2832       default:
  2833         UNREACHABLE();
  2834         return NULL;
  2837     ID3DBlob *binary = (ID3DBlob*)compileToBinary(infoLog, shaderHLSL, profile, D3DCOMPILE_OPTIMIZATION_LEVEL0, false);
  2838     if (!binary)
  2839         return NULL;
  2841     ShaderExecutable *executable = loadExecutable((DWORD *)binary->GetBufferPointer(), binary->GetBufferSize(), type);
  2842     binary->Release();
  2844     return executable;
  2847 VertexBuffer *Renderer11::createVertexBuffer()
  2849     return new VertexBuffer11(this);
  2852 IndexBuffer *Renderer11::createIndexBuffer()
  2854     return new IndexBuffer11(this);
  2857 BufferStorage *Renderer11::createBufferStorage()
  2859     return new BufferStorage11(this);
  2862 QueryImpl *Renderer11::createQuery(GLenum type)
  2864     return new Query11(this, type);
  2867 FenceImpl *Renderer11::createFence()
  2869     return new Fence11(this);
  2872 bool Renderer11::getRenderTargetResource(gl::Renderbuffer *colorbuffer, unsigned int *subresourceIndex, ID3D11Texture2D **resource)
  2874     ASSERT(colorbuffer != NULL);
  2876     RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget());
  2877     if (renderTarget)
  2879         *subresourceIndex = renderTarget->getSubresourceIndex();
  2881         ID3D11RenderTargetView *colorBufferRTV = renderTarget->getRenderTargetView();
  2882         if (colorBufferRTV)
  2884             ID3D11Resource *textureResource = NULL;
  2885             colorBufferRTV->GetResource(&textureResource);
  2887             if (textureResource)
  2889                 HRESULT result = textureResource->QueryInterface(IID_ID3D11Texture2D, (void**)resource);
  2890                 textureResource->Release();
  2892                 if (SUCCEEDED(result))
  2894                     return true;
  2896                 else
  2898                     ERR("Failed to extract the ID3D11Texture2D from the render target resource, "
  2899                         "HRESULT: 0x%X.", result);
  2905     return false;
  2908 bool Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
  2909                           bool blitRenderTarget, bool blitDepthStencil)
  2911     if (blitRenderTarget)
  2913         gl::Renderbuffer *readBuffer = readTarget->getReadColorbuffer();
  2915         if (!readBuffer)
  2917             ERR("Failed to retrieve the read buffer from the read framebuffer.");
  2918             return gl::error(GL_OUT_OF_MEMORY, false);
  2921         RenderTarget *readRenderTarget = readBuffer->getRenderTarget();
  2923         for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
  2925             if (drawTarget->isEnabledColorAttachment(colorAttachment))
  2927                 gl::Renderbuffer *drawBuffer = drawTarget->getColorbuffer(colorAttachment);
  2929                 if (!drawBuffer)
  2931                     ERR("Failed to retrieve the draw buffer from the draw framebuffer.");
  2932                     return gl::error(GL_OUT_OF_MEMORY, false);
  2935                 RenderTarget *drawRenderTarget = drawBuffer->getRenderTarget();
  2937                 if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, false))
  2939                     return false;
  2945     if (blitDepthStencil)
  2947         gl::Renderbuffer *readBuffer = readTarget->getDepthOrStencilbuffer();
  2948         gl::Renderbuffer *drawBuffer = drawTarget->getDepthOrStencilbuffer();
  2950         if (!readBuffer)
  2952             ERR("Failed to retrieve the read depth-stencil buffer from the read framebuffer.");
  2953             return gl::error(GL_OUT_OF_MEMORY, false);
  2956         if (!drawBuffer)
  2958             ERR("Failed to retrieve the draw depth-stencil buffer from the draw framebuffer.");
  2959             return gl::error(GL_OUT_OF_MEMORY, false);
  2962         RenderTarget *readRenderTarget = readBuffer->getDepthStencil();
  2963         RenderTarget *drawRenderTarget = drawBuffer->getDepthStencil();
  2965         if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, true))
  2967             return false;
  2971     return true;
  2974 void Renderer11::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
  2975                             GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels)
  2977     ID3D11Texture2D *colorBufferTexture = NULL;
  2978     unsigned int subresourceIndex = 0;
  2980     gl::Renderbuffer *colorbuffer = framebuffer->getReadColorbuffer();
  2982     if (colorbuffer && getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture))
  2984         gl::Rectangle area;
  2985         area.x = x;
  2986         area.y = y;
  2987         area.width = width;
  2988         area.height = height;
  2990         readTextureData(colorBufferTexture, subresourceIndex, area, format, type, outputPitch,
  2991                         packReverseRowOrder, packAlignment, pixels);
  2993         colorBufferTexture->Release();
  2994         colorBufferTexture = NULL;
  2998 Image *Renderer11::createImage()
  3000     return new Image11();
  3003 void Renderer11::generateMipmap(Image *dest, Image *src)
  3005     Image11 *dest11 = Image11::makeImage11(dest);
  3006     Image11 *src11 = Image11::makeImage11(src);
  3007     Image11::generateMipmap(dest11, src11);
  3010 TextureStorage *Renderer11::createTextureStorage2D(SwapChain *swapChain)
  3012     SwapChain11 *swapChain11 = SwapChain11::makeSwapChain11(swapChain);
  3013     return new TextureStorage11_2D(this, swapChain11);
  3016 TextureStorage *Renderer11::createTextureStorage2D(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height)
  3018     return new TextureStorage11_2D(this, levels, internalformat, usage, forceRenderable, width, height);
  3021 TextureStorage *Renderer11::createTextureStorageCube(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size)
  3023     return new TextureStorage11_Cube(this, levels, internalformat, usage, forceRenderable, size);
  3026 static inline unsigned int getFastPixelCopySize(DXGI_FORMAT sourceFormat, GLenum destFormat, GLenum destType)
  3028     if (sourceFormat == DXGI_FORMAT_A8_UNORM &&
  3029         destFormat   == GL_ALPHA &&
  3030         destType     == GL_UNSIGNED_BYTE)
  3032         return 1;
  3034     else if (sourceFormat == DXGI_FORMAT_R8G8B8A8_UNORM &&
  3035              destFormat   == GL_RGBA &&
  3036              destType     == GL_UNSIGNED_BYTE)
  3038         return 4;
  3040     else if (sourceFormat == DXGI_FORMAT_B8G8R8A8_UNORM &&
  3041              destFormat   == GL_BGRA_EXT &&
  3042              destType     == GL_UNSIGNED_BYTE)
  3044         return 4;
  3046     else if (sourceFormat == DXGI_FORMAT_R16G16B16A16_FLOAT &&
  3047              destFormat   == GL_RGBA &&
  3048              destType     == GL_HALF_FLOAT_OES)
  3050         return 8;
  3052     else if (sourceFormat == DXGI_FORMAT_R32G32B32_FLOAT &&
  3053              destFormat   == GL_RGB &&
  3054              destType     == GL_FLOAT)
  3056         return 12;
  3058     else if (sourceFormat == DXGI_FORMAT_R32G32B32A32_FLOAT &&
  3059              destFormat   == GL_RGBA &&
  3060              destType     == GL_FLOAT)
  3062         return 16;
  3064     else
  3066         return 0;
  3070 static inline void readPixelColor(const unsigned char *data, DXGI_FORMAT format, unsigned int x,
  3071                                   unsigned int y, int inputPitch, gl::Color *outColor)
  3073     switch (format)
  3075       case DXGI_FORMAT_R8G8B8A8_UNORM:
  3077             unsigned int rgba = *reinterpret_cast<const unsigned int*>(data + 4 * x + y * inputPitch);
  3078             outColor->red =   (rgba & 0x000000FF) * (1.0f / 0x000000FF);
  3079             outColor->green = (rgba & 0x0000FF00) * (1.0f / 0x0000FF00);
  3080             outColor->blue =  (rgba & 0x00FF0000) * (1.0f / 0x00FF0000);
  3081             outColor->alpha = (rgba & 0xFF000000) * (1.0f / 0xFF000000);
  3083         break;
  3085       case DXGI_FORMAT_A8_UNORM:
  3087             outColor->red =   0.0f;
  3088             outColor->green = 0.0f;
  3089             outColor->blue =  0.0f;
  3090             outColor->alpha = *(data + x + y * inputPitch) / 255.0f;
  3092         break;
  3094       case DXGI_FORMAT_R32G32B32A32_FLOAT:
  3096             outColor->red =   *(reinterpret_cast<const float*>(data + 16 * x + y * inputPitch) + 0);
  3097             outColor->green = *(reinterpret_cast<const float*>(data + 16 * x + y * inputPitch) + 1);
  3098             outColor->blue =  *(reinterpret_cast<const float*>(data + 16 * x + y * inputPitch) + 2);
  3099             outColor->alpha = *(reinterpret_cast<const float*>(data + 16 * x + y * inputPitch) + 3);
  3101         break;
  3103       case DXGI_FORMAT_R32G32B32_FLOAT:
  3105             outColor->red =   *(reinterpret_cast<const float*>(data + 12 * x + y * inputPitch) + 0);
  3106             outColor->green = *(reinterpret_cast<const float*>(data + 12 * x + y * inputPitch) + 1);
  3107             outColor->blue =  *(reinterpret_cast<const float*>(data + 12 * x + y * inputPitch) + 2);
  3108             outColor->alpha = 1.0f;
  3110         break;
  3112       case DXGI_FORMAT_R16G16B16A16_FLOAT:
  3114             outColor->red =   gl::float16ToFloat32(*(reinterpret_cast<const unsigned short*>(data + 8 * x + y * inputPitch) + 0));
  3115             outColor->green = gl::float16ToFloat32(*(reinterpret_cast<const unsigned short*>(data + 8 * x + y * inputPitch) + 1));
  3116             outColor->blue =  gl::float16ToFloat32(*(reinterpret_cast<const unsigned short*>(data + 8 * x + y * inputPitch) + 2));
  3117             outColor->alpha = gl::float16ToFloat32(*(reinterpret_cast<const unsigned short*>(data + 8 * x + y * inputPitch) + 3));
  3119         break;
  3121       case DXGI_FORMAT_B8G8R8A8_UNORM:
  3123             unsigned int bgra = *reinterpret_cast<const unsigned int*>(data + 4 * x + y * inputPitch);
  3124             outColor->red =   (bgra & 0x00FF0000) * (1.0f / 0x00FF0000);
  3125             outColor->blue =  (bgra & 0x000000FF) * (1.0f / 0x000000FF);
  3126             outColor->green = (bgra & 0x0000FF00) * (1.0f / 0x0000FF00);
  3127             outColor->alpha = (bgra & 0xFF000000) * (1.0f / 0xFF000000);
  3129         break;
  3131       case DXGI_FORMAT_R8_UNORM:
  3133             outColor->red =   *(data + x + y * inputPitch) / 255.0f;
  3134             outColor->green = 0.0f;
  3135             outColor->blue =  0.0f;
  3136             outColor->alpha = 1.0f;
  3138         break;
  3140       case DXGI_FORMAT_R8G8_UNORM:
  3142             unsigned short rg = *reinterpret_cast<const unsigned short*>(data + 2 * x + y * inputPitch);
  3144             outColor->red =   (rg & 0xFF00) * (1.0f / 0xFF00);
  3145             outColor->green = (rg & 0x00FF) * (1.0f / 0x00FF);
  3146             outColor->blue =  0.0f;
  3147             outColor->alpha = 1.0f;
  3149         break;
  3151       case DXGI_FORMAT_R16_FLOAT:
  3153             outColor->red =   gl::float16ToFloat32(*reinterpret_cast<const unsigned short*>(data + 2 * x + y * inputPitch));
  3154             outColor->green = 0.0f;
  3155             outColor->blue =  0.0f;
  3156             outColor->alpha = 1.0f;
  3158         break;
  3160       case DXGI_FORMAT_R16G16_FLOAT:
  3162             outColor->red =   gl::float16ToFloat32(*(reinterpret_cast<const unsigned short*>(data + 4 * x + y * inputPitch) + 0));
  3163             outColor->green = gl::float16ToFloat32(*(reinterpret_cast<const unsigned short*>(data + 4 * x + y * inputPitch) + 1));
  3164             outColor->blue =  0.0f;
  3165             outColor->alpha = 1.0f;
  3167         break;
  3169       default:
  3170         ERR("ReadPixelColor not implemented for DXGI format %u.", format);
  3171         UNIMPLEMENTED();
  3172         break;
  3176 static inline void writePixelColor(const gl::Color &color, GLenum format, GLenum type, unsigned int x,
  3177                                    unsigned int y, int outputPitch, void *outData)
  3179     unsigned char* byteData = reinterpret_cast<unsigned char*>(outData);
  3180     unsigned short* shortData = reinterpret_cast<unsigned short*>(outData);
  3182     switch (format)
  3184       case GL_RGBA:
  3185         switch (type)
  3187           case GL_UNSIGNED_BYTE:
  3188             byteData[4 * x + y * outputPitch + 0] = static_cast<unsigned char>(255 * color.red   + 0.5f);
  3189             byteData[4 * x + y * outputPitch + 1] = static_cast<unsigned char>(255 * color.green + 0.5f);
  3190             byteData[4 * x + y * outputPitch + 2] = static_cast<unsigned char>(255 * color.blue  + 0.5f);
  3191             byteData[4 * x + y * outputPitch + 3] = static_cast<unsigned char>(255 * color.alpha + 0.5f);
  3192             break;
  3194           default:
  3195             ERR("WritePixelColor not implemented for format GL_RGBA and type 0x%X.", type);
  3196             UNIMPLEMENTED();
  3197             break;
  3199         break;
  3201       case GL_BGRA_EXT:
  3202         switch (type)
  3204           case GL_UNSIGNED_BYTE:
  3205             byteData[4 * x + y * outputPitch + 0] = static_cast<unsigned char>(255 * color.blue  + 0.5f);
  3206             byteData[4 * x + y * outputPitch + 1] = static_cast<unsigned char>(255 * color.green + 0.5f);
  3207             byteData[4 * x + y * outputPitch + 2] = static_cast<unsigned char>(255 * color.red   + 0.5f);
  3208             byteData[4 * x + y * outputPitch + 3] = static_cast<unsigned char>(255 * color.alpha + 0.5f);
  3209             break;
  3211           case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
  3212             // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
  3213             // this type is packed as follows:
  3214             //   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0
  3215             //  --------------------------------------------------------------------------------
  3216             // |       4th         |        3rd         |        2nd        |   1st component   |
  3217             //  --------------------------------------------------------------------------------
  3218             // in the case of BGRA_EXT, B is the first component, G the second, and so forth.
  3219             shortData[x + y * outputPitch / sizeof(unsigned short)] =
  3220                 (static_cast<unsigned short>(15 * color.alpha + 0.5f) << 12) |
  3221                 (static_cast<unsigned short>(15 * color.red   + 0.5f) <<  8) |
  3222                 (static_cast<unsigned short>(15 * color.green + 0.5f) <<  4) |
  3223                 (static_cast<unsigned short>(15 * color.blue  + 0.5f) <<  0);
  3224             break;
  3226           case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
  3227             // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
  3228             // this type is packed as follows:
  3229             //   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0
  3230             //  --------------------------------------------------------------------------------
  3231             // | 4th |          3rd           |           2nd          |      1st component     |
  3232             //  --------------------------------------------------------------------------------
  3233             // in the case of BGRA_EXT, B is the first component, G the second, and so forth.
  3234             shortData[x + y * outputPitch / sizeof(unsigned short)] =
  3235                 (static_cast<unsigned short>(     color.alpha + 0.5f) << 15) |
  3236                 (static_cast<unsigned short>(31 * color.red   + 0.5f) << 10) |
  3237                 (static_cast<unsigned short>(31 * color.green + 0.5f) <<  5) |
  3238                 (static_cast<unsigned short>(31 * color.blue  + 0.5f) <<  0);
  3239             break;
  3241           default:
  3242             ERR("WritePixelColor not implemented for format GL_BGRA_EXT and type 0x%X.", type);
  3243             UNIMPLEMENTED();
  3244             break;
  3246         break;
  3248       case GL_RGB:
  3249         switch (type)
  3251           case GL_UNSIGNED_SHORT_5_6_5:
  3252             shortData[x + y * outputPitch / sizeof(unsigned short)] =
  3253                 (static_cast<unsigned short>(31 * color.blue  + 0.5f) <<  0) |
  3254                 (static_cast<unsigned short>(63 * color.green + 0.5f) <<  5) |
  3255                 (static_cast<unsigned short>(31 * color.red   + 0.5f) << 11);
  3256             break;
  3258           case GL_UNSIGNED_BYTE:
  3259             byteData[3 * x + y * outputPitch + 0] = static_cast<unsigned char>(255 * color.red +   0.5f);
  3260             byteData[3 * x + y * outputPitch + 1] = static_cast<unsigned char>(255 * color.green + 0.5f);
  3261             byteData[3 * x + y * outputPitch + 2] = static_cast<unsigned char>(255 * color.blue +  0.5f);
  3262             break;
  3264           default:
  3265             ERR("WritePixelColor not implemented for format GL_RGB and type 0x%X.", type);
  3266             UNIMPLEMENTED();
  3267             break;
  3269         break;
  3271       default:
  3272         ERR("WritePixelColor not implemented for format 0x%X.", format);
  3273         UNIMPLEMENTED();
  3274         break;
  3278 void Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area,
  3279                                  GLenum format, GLenum type, GLsizei outputPitch, bool packReverseRowOrder,
  3280                                  GLint packAlignment, void *pixels)
  3282     D3D11_TEXTURE2D_DESC textureDesc;
  3283     texture->GetDesc(&textureDesc);
  3285     D3D11_TEXTURE2D_DESC stagingDesc;
  3286     stagingDesc.Width = area.width;
  3287     stagingDesc.Height = area.height;
  3288     stagingDesc.MipLevels = 1;
  3289     stagingDesc.ArraySize = 1;
  3290     stagingDesc.Format = textureDesc.Format;
  3291     stagingDesc.SampleDesc.Count = 1;
  3292     stagingDesc.SampleDesc.Quality = 0;
  3293     stagingDesc.Usage = D3D11_USAGE_STAGING;
  3294     stagingDesc.BindFlags = 0;
  3295     stagingDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
  3296     stagingDesc.MiscFlags = 0;
  3298     ID3D11Texture2D* stagingTex = NULL;
  3299     HRESULT result = mDevice->CreateTexture2D(&stagingDesc, NULL, &stagingTex);
  3300     if (FAILED(result))
  3302         ERR("Failed to create staging texture for readPixels, HRESULT: 0x%X.", result);
  3303         return;
  3306     ID3D11Texture2D* srcTex = NULL;
  3307     if (textureDesc.SampleDesc.Count > 1)
  3309         D3D11_TEXTURE2D_DESC resolveDesc;
  3310         resolveDesc.Width = textureDesc.Width;
  3311         resolveDesc.Height = textureDesc.Height;
  3312         resolveDesc.MipLevels = 1;
  3313         resolveDesc.ArraySize = 1;
  3314         resolveDesc.Format = textureDesc.Format;
  3315         resolveDesc.SampleDesc.Count = 1;
  3316         resolveDesc.SampleDesc.Quality = 0;
  3317         resolveDesc.Usage = D3D11_USAGE_DEFAULT;
  3318         resolveDesc.BindFlags = 0;
  3319         resolveDesc.CPUAccessFlags = 0;
  3320         resolveDesc.MiscFlags = 0;
  3322         result = mDevice->CreateTexture2D(&resolveDesc, NULL, &srcTex);
  3323         if (FAILED(result))
  3325             ERR("Failed to create resolve texture for readPixels, HRESULT: 0x%X.", result);
  3326             stagingTex->Release();
  3327             return;
  3330         mDeviceContext->ResolveSubresource(srcTex, 0, texture, subResource, textureDesc.Format);
  3331         subResource = 0;
  3333     else
  3335         srcTex = texture;
  3336         srcTex->AddRef();
  3339     D3D11_BOX srcBox;
  3340     srcBox.left = area.x;
  3341     srcBox.right = area.x + area.width;
  3342     srcBox.top = area.y;
  3343     srcBox.bottom = area.y + area.height;
  3344     srcBox.front = 0;
  3345     srcBox.back = 1;
  3347     mDeviceContext->CopySubresourceRegion(stagingTex, 0, 0, 0, 0, srcTex, subResource, &srcBox);
  3349     srcTex->Release();
  3350     srcTex = NULL;
  3352     D3D11_MAPPED_SUBRESOURCE mapping;
  3353     mDeviceContext->Map(stagingTex, 0, D3D11_MAP_READ, 0, &mapping);
  3355     unsigned char *source;
  3356     int inputPitch;
  3357     if (packReverseRowOrder)
  3359         source = static_cast<unsigned char*>(mapping.pData) + mapping.RowPitch * (area.height - 1);
  3360         inputPitch = -static_cast<int>(mapping.RowPitch);
  3362     else
  3364         source = static_cast<unsigned char*>(mapping.pData);
  3365         inputPitch = static_cast<int>(mapping.RowPitch);
  3368     unsigned int fastPixelSize = getFastPixelCopySize(textureDesc.Format, format, type);
  3369     if (fastPixelSize != 0)
  3371         unsigned char *dest = static_cast<unsigned char*>(pixels);
  3372         for (int j = 0; j < area.height; j++)
  3374             memcpy(dest + j * outputPitch, source + j * inputPitch, area.width * fastPixelSize);
  3377     else if (textureDesc.Format == DXGI_FORMAT_B8G8R8A8_UNORM &&
  3378              format == GL_RGBA &&
  3379              type == GL_UNSIGNED_BYTE)
  3381         // Fast path for swapping red with blue
  3382         unsigned char *dest = static_cast<unsigned char*>(pixels);
  3384         for (int j = 0; j < area.height; j++)
  3386             for (int i = 0; i < area.width; i++)
  3388                 unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch);
  3389                 *(unsigned int*)(dest + 4 * i + j * outputPitch) =
  3390                     (argb & 0xFF00FF00) |       // Keep alpha and green
  3391                     (argb & 0x00FF0000) >> 16 | // Move red to blue
  3392                     (argb & 0x000000FF) << 16;  // Move blue to red
  3396     else
  3398         gl::Color pixelColor;
  3399         for (int j = 0; j < area.height; j++)
  3401             for (int i = 0; i < area.width; i++)
  3403                 readPixelColor(source, textureDesc.Format, i, j, inputPitch, &pixelColor);
  3404                 writePixelColor(pixelColor, format, type, i, j, outputPitch, pixels);
  3409     mDeviceContext->Unmap(stagingTex, 0);
  3411     stagingTex->Release();
  3412     stagingTex = NULL;
  3415 bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget, 
  3416                                       RenderTarget *drawRenderTarget, bool wholeBufferCopy)
  3418     ASSERT(readRect.width == drawRect.width && readRect.height == drawRect.height);
  3420     RenderTarget11 *drawRenderTarget11 = RenderTarget11::makeRenderTarget11(drawRenderTarget);
  3421     if (!drawRenderTarget)
  3423         ERR("Failed to retrieve the draw render target from the draw framebuffer.");
  3424         return gl::error(GL_OUT_OF_MEMORY, false);
  3427     ID3D11Texture2D *drawTexture = drawRenderTarget11->getTexture();
  3428     unsigned int drawSubresource = drawRenderTarget11->getSubresourceIndex();
  3430     RenderTarget11 *readRenderTarget11 = RenderTarget11::makeRenderTarget11(readRenderTarget);
  3431     if (!readRenderTarget)
  3433         ERR("Failed to retrieve the read render target from the read framebuffer.");
  3434         return gl::error(GL_OUT_OF_MEMORY, false);
  3437     ID3D11Texture2D *readTexture = NULL;
  3438     unsigned int readSubresource = 0;
  3439     if (readRenderTarget->getSamples() > 0)
  3441         readTexture = resolveMultisampledTexture(readRenderTarget11->getTexture(), readRenderTarget11->getSubresourceIndex());
  3442         readSubresource = 0;
  3444     else
  3446         readTexture = readRenderTarget11->getTexture();
  3447         readTexture->AddRef();
  3448         readSubresource = readRenderTarget11->getSubresourceIndex();
  3451     if (!readTexture)
  3453         ERR("Failed to retrieve the read render target view from the read render target.");
  3454         return gl::error(GL_OUT_OF_MEMORY, false);
  3457     D3D11_BOX readBox;
  3458     readBox.left = readRect.x;
  3459     readBox.right = readRect.x + readRect.width;
  3460     readBox.top = readRect.y;
  3461     readBox.bottom = readRect.y + readRect.height;
  3462     readBox.front = 0;
  3463     readBox.back = 1;
  3465     // D3D11 needs depth-stencil CopySubresourceRegions to have a NULL pSrcBox
  3466     // We also require complete framebuffer copies for depth-stencil blit.
  3467     D3D11_BOX *pSrcBox = wholeBufferCopy ? NULL : &readBox;
  3469     mDeviceContext->CopySubresourceRegion(drawTexture, drawSubresource, drawRect.x, drawRect.y, 0,
  3470                                           readTexture, readSubresource, pSrcBox);
  3472     SafeRelease(readTexture);
  3474     return true;
  3477 ID3D11Texture2D *Renderer11::resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource)
  3479     D3D11_TEXTURE2D_DESC textureDesc;
  3480     source->GetDesc(&textureDesc);
  3482     if (textureDesc.SampleDesc.Count > 1)
  3484         D3D11_TEXTURE2D_DESC resolveDesc;
  3485         resolveDesc.Width = textureDesc.Width;
  3486         resolveDesc.Height = textureDesc.Height;
  3487         resolveDesc.MipLevels = 1;
  3488         resolveDesc.ArraySize = 1;
  3489         resolveDesc.Format = textureDesc.Format;
  3490         resolveDesc.SampleDesc.Count = 1;
  3491         resolveDesc.SampleDesc.Quality = 0;
  3492         resolveDesc.Usage = textureDesc.Usage;
  3493         resolveDesc.BindFlags = textureDesc.BindFlags;
  3494         resolveDesc.CPUAccessFlags = 0;
  3495         resolveDesc.MiscFlags = 0;
  3497         ID3D11Texture2D *resolveTexture = NULL;
  3498         HRESULT result = mDevice->CreateTexture2D(&resolveDesc, NULL, &resolveTexture);
  3499         if (FAILED(result))
  3501             ERR("Failed to create a multisample resolve texture, HRESULT: 0x%X.", result);
  3502             return NULL;
  3505         mDeviceContext->ResolveSubresource(resolveTexture, 0, source, subresource, textureDesc.Format);
  3506         return resolveTexture;
  3508     else
  3510         source->AddRef();
  3511         return source;
  3515 bool Renderer11::getLUID(LUID *adapterLuid) const
  3517     adapterLuid->HighPart = 0;
  3518     adapterLuid->LowPart = 0;
  3520     if (!mDxgiAdapter)
  3522         return false;
  3525     DXGI_ADAPTER_DESC adapterDesc;
  3526     if (FAILED(mDxgiAdapter->GetDesc(&adapterDesc)))
  3528         return false;
  3531     *adapterLuid = adapterDesc.AdapterLuid;
  3532     return true;

mercurial