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