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