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