Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / third_party / angle / src / libGLESv2 / renderer / d3d / d3d11 / TextureStorage11.cpp
1 //
2 // Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 // TextureStorage11.cpp: Implements the abstract rx::TextureStorage11 class and its concrete derived
8 // classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11 texture.
9
10 #include "libGLESv2/renderer/d3d/d3d11/TextureStorage11.h"
11 #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
12 #include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
13 #include "libGLESv2/renderer/d3d/d3d11/SwapChain11.h"
14 #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
15 #include "libGLESv2/renderer/d3d/d3d11/Blit11.h"
16 #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
17 #include "libGLESv2/renderer/d3d/d3d11/Image11.h"
18 #include "libGLESv2/renderer/d3d/MemoryBuffer.h"
19 #include "libGLESv2/renderer/d3d/TextureD3D.h"
20 #include "libGLESv2/main.h"
21 #include "libGLESv2/ImageIndex.h"
22
23 #include "common/utilities.h"
24
25 namespace rx
26 {
27
28 TextureStorage11::SwizzleCacheValue::SwizzleCacheValue()
29     : swizzleRed(GL_NONE), swizzleGreen(GL_NONE), swizzleBlue(GL_NONE), swizzleAlpha(GL_NONE)
30 {
31 }
32
33 TextureStorage11::SwizzleCacheValue::SwizzleCacheValue(GLenum red, GLenum green, GLenum blue, GLenum alpha)
34     : swizzleRed(red), swizzleGreen(green), swizzleBlue(blue), swizzleAlpha(alpha)
35 {
36 }
37
38 bool TextureStorage11::SwizzleCacheValue::operator==(const SwizzleCacheValue &other) const
39 {
40     return swizzleRed == other.swizzleRed &&
41            swizzleGreen == other.swizzleGreen &&
42            swizzleBlue == other.swizzleBlue &&
43            swizzleAlpha == other.swizzleAlpha;
44 }
45
46 bool TextureStorage11::SwizzleCacheValue::operator!=(const SwizzleCacheValue &other) const
47 {
48     return !(*this == other);
49 }
50
51 TextureStorage11::SRVKey::SRVKey(int baseLevel, int mipLevels, bool swizzle)
52     : baseLevel(baseLevel), mipLevels(mipLevels), swizzle(swizzle)
53 {
54 }
55
56 bool TextureStorage11::SRVKey::operator<(const SRVKey &rhs) const
57 {
58     return std::tie(baseLevel, mipLevels, swizzle) < std::tie(rhs.baseLevel, rhs.mipLevels, rhs.swizzle);
59 }
60
61 TextureStorage11::TextureStorage11(Renderer *renderer, UINT bindFlags)
62     : mBindFlags(bindFlags),
63       mTopLevel(0),
64       mMipLevels(0),
65       mTextureFormat(DXGI_FORMAT_UNKNOWN),
66       mShaderResourceFormat(DXGI_FORMAT_UNKNOWN),
67       mRenderTargetFormat(DXGI_FORMAT_UNKNOWN),
68       mDepthStencilFormat(DXGI_FORMAT_UNKNOWN),
69       mTextureWidth(0),
70       mTextureHeight(0),
71       mTextureDepth(0)
72 {
73     mRenderer = Renderer11::makeRenderer11(renderer);
74
75     for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
76     {
77         mLevelSRVs[i] = NULL;
78     }
79 }
80
81 TextureStorage11::~TextureStorage11()
82 {
83     for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
84     {
85         SafeRelease(mLevelSRVs[level]);
86     }
87
88     for (SRVCache::iterator i = mSrvCache.begin(); i != mSrvCache.end(); i++)
89     {
90         SafeRelease(i->second);
91     }
92     mSrvCache.clear();
93 }
94
95 TextureStorage11 *TextureStorage11::makeTextureStorage11(TextureStorage *storage)
96 {
97     ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11*, storage));
98     return static_cast<TextureStorage11*>(storage);
99 }
100
101 DWORD TextureStorage11::GetTextureBindFlags(GLenum internalFormat, bool renderTarget)
102 {
103     UINT bindFlags = 0;
104
105     const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat);
106     if (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN)
107     {
108         bindFlags |= D3D11_BIND_SHADER_RESOURCE;
109     }
110     if (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN)
111     {
112         bindFlags |= D3D11_BIND_DEPTH_STENCIL;
113     }
114     if (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN && renderTarget)
115     {
116         bindFlags |= D3D11_BIND_RENDER_TARGET;
117     }
118
119     return bindFlags;
120 }
121
122 UINT TextureStorage11::getBindFlags() const
123 {
124     return mBindFlags;
125 }
126
127 int TextureStorage11::getTopLevel() const
128 {
129     return mTopLevel;
130 }
131
132 bool TextureStorage11::isRenderTarget() const
133 {
134     return (mBindFlags & (D3D11_BIND_RENDER_TARGET | D3D11_BIND_DEPTH_STENCIL)) != 0;
135 }
136
137 bool TextureStorage11::isManaged() const
138 {
139     return false;
140 }
141
142 int TextureStorage11::getLevelCount() const
143 {
144     return mMipLevels - mTopLevel;
145 }
146
147 int TextureStorage11::getLevelWidth(int mipLevel) const
148 {
149     return std::max(static_cast<int>(mTextureWidth) >> mipLevel, 1);
150 }
151
152 int TextureStorage11::getLevelHeight(int mipLevel) const
153 {
154     return std::max(static_cast<int>(mTextureHeight) >> mipLevel, 1);
155 }
156
157 int TextureStorage11::getLevelDepth(int mipLevel) const
158 {
159     return std::max(static_cast<int>(mTextureDepth) >> mipLevel, 1);
160 }
161
162 UINT TextureStorage11::getSubresourceIndex(const gl::ImageIndex &index) const
163 {
164     UINT mipSlice = static_cast<UINT>(index.mipIndex + mTopLevel);
165     UINT arraySlice = static_cast<UINT>(index.hasLayer() ? index.layerIndex : 0);
166     UINT subresource = D3D11CalcSubresource(mipSlice, arraySlice, mMipLevels);
167     ASSERT(subresource != std::numeric_limits<UINT>::max());
168     return subresource;
169 }
170
171 gl::Error TextureStorage11::getSRV(const gl::SamplerState &samplerState, ID3D11ShaderResourceView **outSRV)
172 {
173     bool swizzleRequired = samplerState.swizzleRequired();
174     bool mipmapping = gl::IsMipmapFiltered(samplerState);
175     unsigned int mipLevels = mipmapping ? (samplerState.maxLevel - samplerState.baseLevel) : 1;
176
177     // Make sure there's 'mipLevels' mipmap levels below the base level (offset by the top level,  which corresponds to GL level 0)
178     mipLevels = std::min(mipLevels, mMipLevels - mTopLevel - samplerState.baseLevel);
179
180     if (swizzleRequired)
181     {
182         verifySwizzleExists(samplerState.swizzleRed, samplerState.swizzleGreen, samplerState.swizzleBlue, samplerState.swizzleAlpha);
183     }
184
185     SRVKey key(samplerState.baseLevel, mipLevels, swizzleRequired);
186     SRVCache::const_iterator iter = mSrvCache.find(key);
187     if (iter != mSrvCache.end())
188     {
189         *outSRV = iter->second;
190     }
191     else
192     {
193         ID3D11Resource *texture = NULL;
194         if (swizzleRequired)
195         {
196             gl::Error error = getSwizzleTexture(&texture);
197             if (error.isError())
198             {
199                 return error;
200             }
201         }
202         else
203         {
204             gl::Error error = getResource(&texture);
205             if (error.isError())
206             {
207                 return error;
208             }
209         }
210
211         ID3D11ShaderResourceView *srv = NULL;
212         DXGI_FORMAT format = (swizzleRequired ? mSwizzleShaderResourceFormat : mShaderResourceFormat);
213         gl::Error error = createSRV(samplerState.baseLevel, mipLevels, format, texture, &srv);
214         if (error.isError())
215         {
216             return error;
217         }
218
219         mSrvCache.insert(std::make_pair(key, srv));
220         *outSRV = srv;
221     }
222
223     return gl::Error(GL_NO_ERROR);
224 }
225
226 gl::Error TextureStorage11::getSRVLevel(int mipLevel, ID3D11ShaderResourceView **outSRV)
227 {
228     ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
229
230     if (!mLevelSRVs[mipLevel])
231     {
232         ID3D11Resource *resource = NULL;
233         gl::Error error = getResource(&resource);
234         if (error.isError())
235         {
236             return error;
237         }
238
239         error = createSRV(mipLevel, 1, mShaderResourceFormat, resource, &mLevelSRVs[mipLevel]);
240         if (error.isError())
241         {
242             return error;
243         }
244     }
245
246     *outSRV = mLevelSRVs[mipLevel];
247
248     return gl::Error(GL_NO_ERROR);
249 }
250
251 gl::Error TextureStorage11::generateSwizzles(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha)
252 {
253     SwizzleCacheValue swizzleTarget(swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha);
254     for (int level = 0; level < getLevelCount(); level++)
255     {
256         // Check if the swizzle for this level is out of date
257         if (mSwizzleCache[level] != swizzleTarget)
258         {
259             // Need to re-render the swizzle for this level
260             ID3D11ShaderResourceView *sourceSRV = NULL;
261             gl::Error error = getSRVLevel(level, &sourceSRV);
262             if (error.isError())
263             {
264                 return error;
265             }
266
267             ID3D11RenderTargetView *destRTV = NULL;
268             error = getSwizzleRenderTarget(level, &destRTV);
269             if (error.isError())
270             {
271                 return error;
272             }
273
274             gl::Extents size(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level));
275
276             Blit11 *blitter = mRenderer->getBlitter();
277
278             error = blitter->swizzleTexture(sourceSRV, destRTV, size, swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha);
279             if (error.isError())
280             {
281                 return error;
282             }
283
284             mSwizzleCache[level] = swizzleTarget;
285         }
286     }
287
288     return gl::Error(GL_NO_ERROR);
289 }
290
291 void TextureStorage11::invalidateSwizzleCacheLevel(int mipLevel)
292 {
293     if (mipLevel >= 0 && static_cast<unsigned int>(mipLevel) < ArraySize(mSwizzleCache))
294     {
295         // The default constructor of SwizzleCacheValue has GL_NONE for all channels which is not a
296         // valid swizzle combination
297         mSwizzleCache[mipLevel] = SwizzleCacheValue();
298     }
299 }
300
301 void TextureStorage11::invalidateSwizzleCache()
302 {
303     for (unsigned int mipLevel = 0; mipLevel < ArraySize(mSwizzleCache); mipLevel++)
304     {
305         invalidateSwizzleCacheLevel(mipLevel);
306     }
307 }
308
309 gl::Error TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture, unsigned int sourceSubresource,
310                                                    const gl::ImageIndex &index, const gl::Box &copyArea)
311 {
312     ASSERT(srcTexture);
313
314     GLint level = index.mipIndex;
315
316     invalidateSwizzleCacheLevel(level);
317
318     gl::Extents texSize(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level));
319
320     bool fullCopy = copyArea.x == 0 &&
321                     copyArea.y == 0 &&
322                     copyArea.z == 0 &&
323                     copyArea.width  == texSize.width &&
324                     copyArea.height == texSize.height &&
325                     copyArea.depth  == texSize.depth;
326
327     ID3D11Resource *dstTexture = NULL;
328     gl::Error error = getResource(&dstTexture);
329     if (error.isError())
330     {
331         return error;
332     }
333
334     unsigned int dstSubresource = getSubresourceIndex(index);
335
336     ASSERT(dstTexture);
337
338     const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat);
339     if (!fullCopy && (dxgiFormatInfo.depthBits > 0 || dxgiFormatInfo.stencilBits > 0))
340     {
341         // CopySubresourceRegion cannot copy partial depth stencils, use the blitter instead
342         Blit11 *blitter = mRenderer->getBlitter();
343
344         return blitter->copyDepthStencil(srcTexture, sourceSubresource, copyArea, texSize,
345                                          dstTexture, dstSubresource, copyArea, texSize,
346                                          NULL);
347     }
348     else
349     {
350         const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat);
351
352         D3D11_BOX srcBox;
353         srcBox.left = copyArea.x;
354         srcBox.top = copyArea.y;
355         srcBox.right = copyArea.x + roundUp(static_cast<UINT>(copyArea.width), dxgiFormatInfo.blockWidth);
356         srcBox.bottom = copyArea.y + roundUp(static_cast<UINT>(copyArea.height), dxgiFormatInfo.blockHeight);
357         srcBox.front = copyArea.z;
358         srcBox.back = copyArea.z + copyArea.depth;
359
360         ID3D11DeviceContext *context = mRenderer->getDeviceContext();
361
362         context->CopySubresourceRegion(dstTexture, dstSubresource, copyArea.x, copyArea.y, copyArea.z,
363                                        srcTexture, sourceSubresource, fullCopy ? NULL : &srcBox);
364         return gl::Error(GL_NO_ERROR);
365     }
366 }
367
368 gl::Error TextureStorage11::copySubresourceLevel(ID3D11Resource* dstTexture, unsigned int dstSubresource,
369                                                  const gl::ImageIndex &index, const gl::Box &region)
370 {
371     ASSERT(dstTexture);
372
373     ID3D11Resource *srcTexture = NULL;
374     gl::Error error = getResource(&srcTexture);
375     if (error.isError())
376     {
377         return error;
378     }
379
380     ASSERT(srcTexture);
381
382     unsigned int srcSubresource = getSubresourceIndex(index);
383
384     ID3D11DeviceContext *context = mRenderer->getDeviceContext();
385     context->CopySubresourceRegion(dstTexture, dstSubresource, region.x, region.y, region.z,
386                                    srcTexture, srcSubresource, NULL);
387
388     return gl::Error(GL_NO_ERROR);
389 }
390
391 gl::Error TextureStorage11::generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex)
392 {
393     ASSERT(sourceIndex.layerIndex == destIndex.layerIndex);
394
395     invalidateSwizzleCacheLevel(destIndex.mipIndex);
396
397     RenderTarget *source = NULL;
398     gl::Error error = getRenderTarget(sourceIndex, &source);
399     if (error.isError())
400     {
401         return error;
402     }
403
404     RenderTarget *dest = NULL;
405     error = getRenderTarget(destIndex, &dest);
406     if (error.isError())
407     {
408         return error;
409     }
410
411     ID3D11ShaderResourceView *sourceSRV = RenderTarget11::makeRenderTarget11(source)->getShaderResourceView();
412     ID3D11RenderTargetView *destRTV = RenderTarget11::makeRenderTarget11(dest)->getRenderTargetView();
413
414     gl::Box sourceArea(0, 0, 0, source->getWidth(), source->getHeight(), source->getDepth());
415     gl::Extents sourceSize(source->getWidth(), source->getHeight(), source->getDepth());
416
417     gl::Box destArea(0, 0, 0, dest->getWidth(), dest->getHeight(), dest->getDepth());
418     gl::Extents destSize(dest->getWidth(), dest->getHeight(), dest->getDepth());
419
420     Blit11 *blitter = mRenderer->getBlitter();
421     return blitter->copyTexture(sourceSRV, sourceArea, sourceSize, destRTV, destArea, destSize, NULL,
422                                 gl::GetInternalFormatInfo(source->getInternalFormat()).format, GL_LINEAR);
423 }
424
425 void TextureStorage11::verifySwizzleExists(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha)
426 {
427     SwizzleCacheValue swizzleTarget(swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha);
428     for (unsigned int level = 0; level < mMipLevels; level++)
429     {
430         ASSERT(mSwizzleCache[level] == swizzleTarget);
431     }
432 }
433
434 gl::Error TextureStorage11::copyToStorage(TextureStorage *destStorage)
435 {
436     ASSERT(destStorage);
437
438     ID3D11Resource *sourceResouce = NULL;
439     gl::Error error = getResource(&sourceResouce);
440     if (error.isError())
441     {
442         return error;
443     }
444
445     TextureStorage11 *dest11 = TextureStorage11::makeTextureStorage11(destStorage);
446     ID3D11Resource *destResource = NULL;
447     error = dest11->getResource(&destResource);
448     if (error.isError())
449     {
450         return error;
451     }
452
453     ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
454     immediateContext->CopyResource(destResource, sourceResouce);
455
456     dest11->invalidateSwizzleCache();
457
458     return gl::Error(GL_NO_ERROR);
459 }
460
461 gl::Error TextureStorage11::setData(const gl::ImageIndex &index, Image *image, const gl::Box *destBox, GLenum type,
462                                     const gl::PixelUnpackState &unpack, const uint8_t *pixelData)
463 {
464     ID3D11Resource *resource = NULL;
465     gl::Error error = getResource(&resource);
466     if (error.isError())
467     {
468         return error;
469     }
470     ASSERT(resource);
471
472     UINT destSubresource = getSubresourceIndex(index);
473
474     const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(image->getInternalFormat());
475
476     bool fullUpdate = (destBox == NULL || *destBox == gl::Box(0, 0, 0, mTextureWidth, mTextureHeight, mTextureDepth));
477     ASSERT(internalFormatInfo.depthBits == 0 || fullUpdate);
478
479     // TODO(jmadill): Handle compressed formats
480     // Compressed formats have different load syntax, so we'll have to handle them with slightly
481     // different logic. Will implemnent this in a follow-up patch, and ensure we do not use SetData
482     // with compressed formats in the calling logic.
483     ASSERT(!internalFormatInfo.compressed);
484
485     int width = destBox ? destBox->width : static_cast<int>(image->getWidth());
486     int height = destBox ? destBox->height : static_cast<int>(image->getHeight());
487     int depth = destBox ? destBox->depth : static_cast<int>(image->getDepth());
488     UINT srcRowPitch = internalFormatInfo.computeRowPitch(type, width, unpack.alignment);
489     UINT srcDepthPitch = internalFormatInfo.computeDepthPitch(type, width, height, unpack.alignment);
490
491     const d3d11::TextureFormat &d3d11Format = d3d11::GetTextureFormatInfo(image->getInternalFormat());
492     const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(d3d11Format.texFormat);
493
494     size_t outputPixelSize = dxgiFormatInfo.pixelBytes;
495
496     UINT bufferRowPitch = outputPixelSize * width;
497     UINT bufferDepthPitch = bufferRowPitch * height;
498
499     MemoryBuffer conversionBuffer;
500     if (!conversionBuffer.resize(bufferDepthPitch * depth))
501     {
502         return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal buffer.");
503     }
504
505     // TODO: fast path
506     LoadImageFunction loadFunction = d3d11Format.loadFunctions.at(type);
507     loadFunction(width, height, depth,
508                  pixelData, srcRowPitch, srcDepthPitch,
509                  conversionBuffer.data(), bufferRowPitch, bufferDepthPitch);
510
511     ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
512
513     if (!fullUpdate)
514     {
515         ASSERT(destBox);
516
517         D3D11_BOX destD3DBox;
518         destD3DBox.left = destBox->x;
519         destD3DBox.right = destBox->x + destBox->width;
520         destD3DBox.top = destBox->y;
521         destD3DBox.bottom = destBox->y + destBox->height;
522         destD3DBox.front = 0;
523         destD3DBox.back = 1;
524
525         immediateContext->UpdateSubresource(resource, destSubresource,
526                                             &destD3DBox, conversionBuffer.data(),
527                                             bufferRowPitch, bufferDepthPitch);
528     }
529     else
530     {
531         immediateContext->UpdateSubresource(resource, destSubresource,
532                                             NULL, conversionBuffer.data(),
533                                             bufferRowPitch, bufferDepthPitch);
534     }
535
536     return gl::Error(GL_NO_ERROR);
537 }
538
539 TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapchain)
540     : TextureStorage11(renderer, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE),
541       mTexture(swapchain->getOffscreenTexture()),
542       mSwizzleTexture(NULL)
543 {
544     mTexture->AddRef();
545
546     for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
547     {
548         mAssociatedImages[i] = NULL;
549         mRenderTarget[i] = NULL;
550         mSwizzleRenderTargets[i] = NULL;
551     }
552
553     D3D11_TEXTURE2D_DESC texDesc;
554     mTexture->GetDesc(&texDesc);
555     mMipLevels = texDesc.MipLevels;
556     mTextureFormat = texDesc.Format;
557     mTextureWidth = texDesc.Width;
558     mTextureHeight = texDesc.Height;
559     mTextureDepth = 1;
560
561     ID3D11ShaderResourceView *srv = swapchain->getRenderTargetShaderResource();
562     D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
563     srv->GetDesc(&srvDesc);
564     mShaderResourceFormat = srvDesc.Format;
565
566     ID3D11RenderTargetView* offscreenRTV = swapchain->getRenderTarget();
567     D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
568     offscreenRTV->GetDesc(&rtvDesc);
569     mRenderTargetFormat = rtvDesc.Format;
570
571     const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat);
572     const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(dxgiFormatInfo.internalFormat);
573     mSwizzleTextureFormat = formatInfo.swizzleTexFormat;
574     mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
575     mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
576
577     mDepthStencilFormat = DXGI_FORMAT_UNKNOWN;
578
579     initializeSerials(1, 1);
580 }
581
582 TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels)
583     : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget)),
584       mTexture(NULL),
585       mSwizzleTexture(NULL)
586 {
587     for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
588     {
589         mAssociatedImages[i] = NULL;
590         mRenderTarget[i] = NULL;
591         mSwizzleRenderTargets[i] = NULL;
592     }
593
594     const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
595     mTextureFormat = formatInfo.texFormat;
596     mShaderResourceFormat = formatInfo.srvFormat;
597     mDepthStencilFormat = formatInfo.dsvFormat;
598     mRenderTargetFormat = formatInfo.rtvFormat;
599     mSwizzleTextureFormat = formatInfo.swizzleTexFormat;
600     mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
601     mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
602
603     d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel);
604     mMipLevels = mTopLevel + levels;
605     mTextureWidth = width;
606     mTextureHeight = height;
607     mTextureDepth = 1;
608
609     initializeSerials(getLevelCount(), 1);
610 }
611
612 TextureStorage11_2D::~TextureStorage11_2D()
613 {
614     for (unsigned i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
615     {
616         if (mAssociatedImages[i] != NULL)
617         {
618             bool imageAssociationCorrect = mAssociatedImages[i]->isAssociatedStorageValid(this);
619             ASSERT(imageAssociationCorrect);
620
621             if (imageAssociationCorrect)
622             {
623                 // We must let the Images recover their data before we delete it from the TextureStorage.
624                 gl::Error error = mAssociatedImages[i]->recoverFromAssociatedStorage();
625                 if (error.isError())
626                 {
627                     // TODO: Find a way to report this back to the context
628                 }
629             }
630         }
631     }
632
633     SafeRelease(mTexture);
634     SafeRelease(mSwizzleTexture);
635
636     for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
637     {
638         SafeDelete(mRenderTarget[i]);
639         SafeRelease(mSwizzleRenderTargets[i]);
640     }
641 }
642
643 TextureStorage11_2D *TextureStorage11_2D::makeTextureStorage11_2D(TextureStorage *storage)
644 {
645     ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_2D*, storage));
646     return static_cast<TextureStorage11_2D*>(storage);
647 }
648
649 void TextureStorage11_2D::associateImage(Image11* image, const gl::ImageIndex &index)
650 {
651     GLint level = index.mipIndex;
652
653     ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
654
655     if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
656     {
657         mAssociatedImages[level] = image;
658     }
659 }
660
661 bool TextureStorage11_2D::isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage)
662 {
663     GLint level = index.mipIndex;
664
665     if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
666     {
667         // This validation check should never return false. It means the Image/TextureStorage association is broken.
668         bool retValue = (mAssociatedImages[level] == expectedImage);
669         ASSERT(retValue);
670         return retValue;
671     }
672
673     return false;
674 }
675
676 // disassociateImage allows an Image to end its association with a Storage.
677 void TextureStorage11_2D::disassociateImage(const gl::ImageIndex &index, Image11* expectedImage)
678 {
679     GLint level = index.mipIndex;
680
681     ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
682
683     if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
684     {
685         ASSERT(mAssociatedImages[level] == expectedImage);
686
687         if (mAssociatedImages[level] == expectedImage)
688         {
689             mAssociatedImages[level] = NULL;
690         }
691     }
692 }
693
694 // releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association.
695 gl::Error TextureStorage11_2D::releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage)
696 {
697     GLint level = index.mipIndex;
698
699     ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
700
701     if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
702     {
703         // No need to let the old Image recover its data, if it is also the incoming Image.
704         if (mAssociatedImages[level] != NULL && mAssociatedImages[level] != incomingImage)
705         {
706             // Ensure that the Image is still associated with this TextureStorage. This should be true.
707             bool imageAssociationCorrect = mAssociatedImages[level]->isAssociatedStorageValid(this);
708             ASSERT(imageAssociationCorrect);
709
710             if (imageAssociationCorrect)
711             {
712                 // Force the image to recover from storage before its data is overwritten.
713                 // This will reset mAssociatedImages[level] to NULL too.
714                 gl::Error error = mAssociatedImages[level]->recoverFromAssociatedStorage();
715                 if (error.isError())
716                 {
717                     return error;
718                 }
719             }
720         }
721     }
722
723     return gl::Error(GL_NO_ERROR);
724 }
725
726 gl::Error TextureStorage11_2D::getResource(ID3D11Resource **outResource)
727 {
728     // if the width or height is not positive this should be treated as an incomplete texture
729     // we handle that here by skipping the d3d texture creation
730     if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0)
731     {
732         ASSERT(mMipLevels > 0);
733
734         ID3D11Device *device = mRenderer->getDevice();
735
736         D3D11_TEXTURE2D_DESC desc;
737         desc.Width = mTextureWidth;      // Compressed texture size constraints?
738         desc.Height = mTextureHeight;
739         desc.MipLevels = mMipLevels;
740         desc.ArraySize = 1;
741         desc.Format = mTextureFormat;
742         desc.SampleDesc.Count = 1;
743         desc.SampleDesc.Quality = 0;
744         desc.Usage = D3D11_USAGE_DEFAULT;
745         desc.BindFlags = getBindFlags();
746         desc.CPUAccessFlags = 0;
747         desc.MiscFlags = 0;
748
749         HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
750
751         // this can happen from windows TDR
752         if (d3d11::isDeviceLostError(result))
753         {
754             mRenderer->notifyDeviceLost();
755             return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D texture storage, result: 0x%X.", result);
756         }
757         else if (FAILED(result))
758         {
759             ASSERT(result == E_OUTOFMEMORY);
760             return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D texture storage, result: 0x%X.", result);
761         }
762     }
763
764     *outResource = mTexture;
765     return gl::Error(GL_NO_ERROR);
766 }
767
768 gl::Error TextureStorage11_2D::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
769 {
770     ASSERT(!index.hasLayer());
771
772     int level = index.mipIndex;
773     ASSERT(level >= 0 && level < getLevelCount());
774
775     if (!mRenderTarget[level])
776     {
777         ID3D11Resource *texture = NULL;
778         gl::Error error = getResource(&texture);
779         if (error.isError())
780         {
781             return error;
782         }
783
784         ID3D11ShaderResourceView *srv = NULL;
785         error = getSRVLevel(level, &srv);
786         if (error.isError())
787         {
788             return error;
789         }
790
791         if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
792         {
793             ID3D11Device *device = mRenderer->getDevice();
794
795             D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
796             rtvDesc.Format = mRenderTargetFormat;
797             rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
798             rtvDesc.Texture2D.MipSlice = mTopLevel + level;
799
800             ID3D11RenderTargetView *rtv;
801             HRESULT result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv);
802
803             ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
804             if (FAILED(result))
805             {
806                 return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result);
807             }
808
809             mRenderTarget[level] = new RenderTarget11(mRenderer, rtv, texture, srv, getLevelWidth(level), getLevelHeight(level), 1);
810
811             // RenderTarget will take ownership of these resources
812             SafeRelease(rtv);
813         }
814         else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN)
815         {
816             ID3D11Device *device = mRenderer->getDevice();
817
818             D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
819             dsvDesc.Format = mDepthStencilFormat;
820             dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
821             dsvDesc.Texture2D.MipSlice = mTopLevel + level;
822             dsvDesc.Flags = 0;
823
824             ID3D11DepthStencilView *dsv;
825             HRESULT result = device->CreateDepthStencilView(texture, &dsvDesc, &dsv);
826
827             ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
828             if (FAILED(result))
829             {
830                 return gl::Error(GL_OUT_OF_MEMORY,"Failed to create internal depth stencil view for texture storage, result: 0x%X.", result);
831             }
832
833             mRenderTarget[level] = new RenderTarget11(mRenderer, dsv, texture, srv, getLevelWidth(level), getLevelHeight(level), 1);
834
835             // RenderTarget will take ownership of these resources
836             SafeRelease(dsv);
837         }
838         else
839         {
840             UNREACHABLE();
841         }
842     }
843
844     ASSERT(outRT);
845     *outRT = mRenderTarget[level];
846     return gl::Error(GL_NO_ERROR);
847 }
848
849 gl::Error TextureStorage11_2D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
850                                          ID3D11ShaderResourceView **outSRV) const
851 {
852     ASSERT(outSRV);
853
854     D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
855     srvDesc.Format = format;
856     srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
857     srvDesc.Texture2D.MostDetailedMip = mTopLevel + baseLevel;
858     srvDesc.Texture2D.MipLevels = mipLevels;
859
860     ID3D11Device *device = mRenderer->getDevice();
861     HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV);
862
863     ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
864     if (FAILED(result))
865     {
866         return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result);
867     }
868
869     return gl::Error(GL_NO_ERROR);
870 }
871
872 gl::Error TextureStorage11_2D::getSwizzleTexture(ID3D11Resource **outTexture)
873 {
874     ASSERT(outTexture);
875
876     if (!mSwizzleTexture)
877     {
878         ID3D11Device *device = mRenderer->getDevice();
879
880         D3D11_TEXTURE2D_DESC desc;
881         desc.Width = mTextureWidth;
882         desc.Height = mTextureHeight;
883         desc.MipLevels = mMipLevels;
884         desc.ArraySize = 1;
885         desc.Format = mSwizzleTextureFormat;
886         desc.SampleDesc.Count = 1;
887         desc.SampleDesc.Quality = 0;
888         desc.Usage = D3D11_USAGE_DEFAULT;
889         desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
890         desc.CPUAccessFlags = 0;
891         desc.MiscFlags = 0;
892
893         HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture);
894
895         ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
896         if (FAILED(result))
897         {
898             return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result);
899         }
900     }
901
902     *outTexture = mSwizzleTexture;
903     return gl::Error(GL_NO_ERROR);
904 }
905
906 gl::Error TextureStorage11_2D::getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV)
907 {
908     ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
909     ASSERT(outRTV);
910
911     if (!mSwizzleRenderTargets[mipLevel])
912     {
913         ID3D11Resource *swizzleTexture = NULL;
914         gl::Error error = getSwizzleTexture(&swizzleTexture);
915         if (error.isError())
916         {
917             return error;
918         }
919
920         ID3D11Device *device = mRenderer->getDevice();
921
922         D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
923         rtvDesc.Format = mSwizzleRenderTargetFormat;
924         rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
925         rtvDesc.Texture2D.MipSlice = mTopLevel + mipLevel;
926
927         HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
928
929         ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
930         if (FAILED(result))
931         {
932             return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result);
933         }
934     }
935
936     *outRTV = mSwizzleRenderTargets[mipLevel];
937     return gl::Error(GL_NO_ERROR);
938 }
939
940 TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, GLenum internalformat, bool renderTarget, int size, int levels)
941     : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget))
942 {
943     mTexture = NULL;
944     mSwizzleTexture = NULL;
945
946     for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
947     {
948         mSwizzleRenderTargets[level] = NULL;
949         for (unsigned int face = 0; face < CUBE_FACE_COUNT; face++)
950         {
951             mAssociatedImages[face][level] = NULL;
952             mRenderTarget[face][level] = NULL;
953         }
954     }
955
956     const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
957     mTextureFormat = formatInfo.texFormat;
958     mShaderResourceFormat = formatInfo.srvFormat;
959     mDepthStencilFormat = formatInfo.dsvFormat;
960     mRenderTargetFormat = formatInfo.rtvFormat;
961     mSwizzleTextureFormat = formatInfo.swizzleTexFormat;
962     mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
963     mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
964
965     // adjust size if needed for compressed textures
966     int height = size;
967     d3d11::MakeValidSize(false, mTextureFormat, &size, &height, &mTopLevel);
968
969     mMipLevels = mTopLevel + levels;
970     mTextureWidth = size;
971     mTextureHeight = size;
972     mTextureDepth = 1;
973
974     initializeSerials(getLevelCount() * CUBE_FACE_COUNT, CUBE_FACE_COUNT);
975 }
976
977 TextureStorage11_Cube::~TextureStorage11_Cube()
978 {
979     for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
980     {
981         for (unsigned int face = 0; face < CUBE_FACE_COUNT; face++)
982         {
983             if (mAssociatedImages[face][level] != NULL)
984             {
985                 bool imageAssociationCorrect = mAssociatedImages[face][level]->isAssociatedStorageValid(this);
986                 ASSERT(imageAssociationCorrect);
987
988                 if (imageAssociationCorrect)
989                 {
990                     // We must let the Images recover their data before we delete it from the TextureStorage.
991                     mAssociatedImages[face][level]->recoverFromAssociatedStorage();
992                 }
993             }
994         }
995     }
996
997     SafeRelease(mTexture);
998     SafeRelease(mSwizzleTexture);
999
1000     for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
1001     {
1002         SafeRelease(mSwizzleRenderTargets[level]);
1003         for (unsigned int face = 0; face < CUBE_FACE_COUNT; face++)
1004         {
1005             SafeDelete(mRenderTarget[face][level]);
1006         }
1007     }
1008 }
1009
1010 TextureStorage11_Cube *TextureStorage11_Cube::makeTextureStorage11_Cube(TextureStorage *storage)
1011 {
1012     ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_Cube*, storage));
1013     return static_cast<TextureStorage11_Cube*>(storage);
1014 }
1015
1016 void TextureStorage11_Cube::associateImage(Image11* image, const gl::ImageIndex &index)
1017 {
1018     GLint level = index.mipIndex;
1019     GLint layerTarget = index.layerIndex;
1020
1021     ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
1022     ASSERT(0 <= layerTarget && layerTarget < CUBE_FACE_COUNT);
1023
1024     if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
1025     {
1026         if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT)
1027         {
1028             mAssociatedImages[layerTarget][level] = image;
1029         }
1030     }
1031 }
1032
1033 bool TextureStorage11_Cube::isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage)
1034 {
1035     GLint level = index.mipIndex;
1036     GLint layerTarget = index.layerIndex;
1037
1038     if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
1039     {
1040         if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT)
1041         {
1042             // This validation check should never return false. It means the Image/TextureStorage association is broken.
1043             bool retValue = (mAssociatedImages[layerTarget][level] == expectedImage);
1044             ASSERT(retValue);
1045             return retValue;
1046         }
1047     }
1048
1049     return false;
1050 }
1051
1052 // disassociateImage allows an Image to end its association with a Storage.
1053 void TextureStorage11_Cube::disassociateImage(const gl::ImageIndex &index, Image11* expectedImage)
1054 {
1055     GLint level = index.mipIndex;
1056     GLint layerTarget = index.layerIndex;
1057
1058     ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
1059     ASSERT(0 <= layerTarget && layerTarget < CUBE_FACE_COUNT);
1060
1061     if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
1062     {
1063         if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT)
1064         {
1065             ASSERT(mAssociatedImages[layerTarget][level] == expectedImage);
1066
1067             if (mAssociatedImages[layerTarget][level] == expectedImage)
1068             {
1069                 mAssociatedImages[layerTarget][level] = NULL;
1070             }
1071         }
1072     }
1073 }
1074
1075 // releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association.
1076 gl::Error TextureStorage11_Cube::releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage)
1077 {
1078     GLint level = index.mipIndex;
1079     GLint layerTarget = index.layerIndex;
1080
1081     ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
1082     ASSERT(0 <= layerTarget && layerTarget < CUBE_FACE_COUNT);
1083
1084     if ((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
1085     {
1086         if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT)
1087         {
1088             // No need to let the old Image recover its data, if it is also the incoming Image.
1089             if (mAssociatedImages[layerTarget][level] != NULL && mAssociatedImages[layerTarget][level] != incomingImage)
1090             {
1091                 // Ensure that the Image is still associated with this TextureStorage. This should be true.
1092                 bool imageAssociationCorrect = mAssociatedImages[layerTarget][level]->isAssociatedStorageValid(this);
1093                 ASSERT(imageAssociationCorrect);
1094
1095                 if (imageAssociationCorrect)
1096                 {
1097                     // Force the image to recover from storage before its data is overwritten.
1098                     // This will reset mAssociatedImages[level] to NULL too.
1099                     gl::Error error = mAssociatedImages[layerTarget][level]->recoverFromAssociatedStorage();
1100                     if (error.isError())
1101                     {
1102                         return error;
1103                     }
1104                 }
1105             }
1106         }
1107     }
1108
1109     return gl::Error(GL_NO_ERROR);
1110 }
1111
1112 gl::Error TextureStorage11_Cube::getResource(ID3D11Resource **outResource)
1113 {
1114     // if the size is not positive this should be treated as an incomplete texture
1115     // we handle that here by skipping the d3d texture creation
1116     if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0)
1117     {
1118         ASSERT(mMipLevels > 0);
1119
1120         ID3D11Device *device = mRenderer->getDevice();
1121
1122         D3D11_TEXTURE2D_DESC desc;
1123         desc.Width = mTextureWidth;
1124         desc.Height = mTextureHeight;
1125         desc.MipLevels = mMipLevels;
1126         desc.ArraySize = CUBE_FACE_COUNT;
1127         desc.Format = mTextureFormat;
1128         desc.SampleDesc.Count = 1;
1129         desc.SampleDesc.Quality = 0;
1130         desc.Usage = D3D11_USAGE_DEFAULT;
1131         desc.BindFlags = getBindFlags();
1132         desc.CPUAccessFlags = 0;
1133         desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
1134
1135         HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
1136
1137         // this can happen from windows TDR
1138         if (d3d11::isDeviceLostError(result))
1139         {
1140             mRenderer->notifyDeviceLost();
1141             return gl::Error(GL_OUT_OF_MEMORY, "Failed to create cube texture storage, result: 0x%X.", result);
1142         }
1143         else if (FAILED(result))
1144         {
1145             ASSERT(result == E_OUTOFMEMORY);
1146             return gl::Error(GL_OUT_OF_MEMORY, "Failed to create cube texture storage, result: 0x%X.", result);
1147         }
1148     }
1149
1150     *outResource = mTexture;
1151     return gl::Error(GL_NO_ERROR);
1152 }
1153
1154 gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
1155 {
1156     int faceIndex = index.layerIndex;
1157     int level = index.mipIndex;
1158
1159     ASSERT(level >= 0 && level < getLevelCount());
1160     ASSERT(faceIndex >= 0 && faceIndex < CUBE_FACE_COUNT);
1161
1162     if (!mRenderTarget[faceIndex][level])
1163     {
1164         ID3D11Device *device = mRenderer->getDevice();
1165         HRESULT result;
1166
1167         ID3D11Resource *texture = NULL;
1168         gl::Error error = getResource(&texture);
1169         if (error.isError())
1170         {
1171             return error;
1172         }
1173
1174         D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
1175         srvDesc.Format = mShaderResourceFormat;
1176         srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; // Will be used with Texture2D sampler, not TextureCube
1177         srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + level;
1178         srvDesc.Texture2DArray.MipLevels = 1;
1179         srvDesc.Texture2DArray.FirstArraySlice = faceIndex;
1180         srvDesc.Texture2DArray.ArraySize = 1;
1181
1182         ID3D11ShaderResourceView *srv;
1183         result = device->CreateShaderResourceView(texture, &srvDesc, &srv);
1184
1185         ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
1186         if (FAILED(result))
1187         {
1188             return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal shader resource view for texture storage, result: 0x%X.", result);
1189         }
1190
1191         if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
1192         {
1193             D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
1194             rtvDesc.Format = mRenderTargetFormat;
1195             rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
1196             rtvDesc.Texture2DArray.MipSlice = mTopLevel + level;
1197             rtvDesc.Texture2DArray.FirstArraySlice = faceIndex;
1198             rtvDesc.Texture2DArray.ArraySize = 1;
1199
1200             ID3D11RenderTargetView *rtv;
1201             result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv);
1202
1203             ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
1204             if (FAILED(result))
1205             {
1206                 SafeRelease(srv);
1207                 return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result);
1208             }
1209
1210             mRenderTarget[faceIndex][level] = new RenderTarget11(mRenderer, rtv, texture, srv, getLevelWidth(level), getLevelHeight(level), 1);
1211
1212             // RenderTarget will take ownership of these resources
1213             SafeRelease(rtv);
1214             SafeRelease(srv);
1215         }
1216         else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN)
1217         {
1218             D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
1219             dsvDesc.Format = mDepthStencilFormat;
1220             dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
1221             dsvDesc.Flags = 0;
1222             dsvDesc.Texture2DArray.MipSlice = mTopLevel + level;
1223             dsvDesc.Texture2DArray.FirstArraySlice = faceIndex;
1224             dsvDesc.Texture2DArray.ArraySize = 1;
1225
1226             ID3D11DepthStencilView *dsv;
1227             result = device->CreateDepthStencilView(texture, &dsvDesc, &dsv);
1228
1229             ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
1230             if (FAILED(result))
1231             {
1232                 SafeRelease(srv);
1233                 return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal depth stencil view for texture storage, result: 0x%X.", result);
1234             }
1235
1236             mRenderTarget[faceIndex][level] = new RenderTarget11(mRenderer, dsv, texture, srv, getLevelWidth(level), getLevelHeight(level), 1);
1237
1238             // RenderTarget will take ownership of these resources
1239             SafeRelease(dsv);
1240             SafeRelease(srv);
1241         }
1242         else
1243         {
1244             UNREACHABLE();
1245         }
1246     }
1247
1248     ASSERT(outRT);
1249     *outRT = mRenderTarget[faceIndex][level];
1250     return gl::Error(GL_NO_ERROR);
1251 }
1252
1253 gl::Error TextureStorage11_Cube::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
1254                                            ID3D11ShaderResourceView **outSRV) const
1255 {
1256     ASSERT(outSRV);
1257
1258     D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
1259     srvDesc.Format = format;
1260
1261     // Unnormalized integer cube maps are not supported by DX11; we emulate them as an array of six 2D textures
1262     const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(format);
1263     if (dxgiFormatInfo.componentType == GL_INT || dxgiFormatInfo.componentType == GL_UNSIGNED_INT)
1264     {
1265         srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
1266         srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel;
1267         srvDesc.Texture2DArray.MipLevels = 1;
1268         srvDesc.Texture2DArray.FirstArraySlice = 0;
1269         srvDesc.Texture2DArray.ArraySize = CUBE_FACE_COUNT;
1270     }
1271     else
1272     {
1273         srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
1274         srvDesc.TextureCube.MipLevels = mipLevels;
1275         srvDesc.TextureCube.MostDetailedMip = mTopLevel + baseLevel;
1276     }
1277
1278     ID3D11Device *device = mRenderer->getDevice();
1279     HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV);
1280
1281     ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
1282     if (FAILED(result))
1283     {
1284         return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result);
1285     }
1286
1287     return gl::Error(GL_NO_ERROR);
1288 }
1289
1290 gl::Error TextureStorage11_Cube::getSwizzleTexture(ID3D11Resource **outTexture)
1291 {
1292     ASSERT(outTexture);
1293
1294     if (!mSwizzleTexture)
1295     {
1296         ID3D11Device *device = mRenderer->getDevice();
1297
1298         D3D11_TEXTURE2D_DESC desc;
1299         desc.Width = mTextureWidth;
1300         desc.Height = mTextureHeight;
1301         desc.MipLevels = mMipLevels;
1302         desc.ArraySize = CUBE_FACE_COUNT;
1303         desc.Format = mSwizzleTextureFormat;
1304         desc.SampleDesc.Count = 1;
1305         desc.SampleDesc.Quality = 0;
1306         desc.Usage = D3D11_USAGE_DEFAULT;
1307         desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
1308         desc.CPUAccessFlags = 0;
1309         desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
1310
1311         HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture);
1312
1313         ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
1314         if (FAILED(result))
1315         {
1316             return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result);
1317         }
1318     }
1319
1320     *outTexture = mSwizzleTexture;
1321     return gl::Error(GL_NO_ERROR);
1322 }
1323
1324 gl::Error TextureStorage11_Cube::getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV)
1325 {
1326     ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
1327     ASSERT(outRTV);
1328
1329     if (!mSwizzleRenderTargets[mipLevel])
1330     {
1331         ID3D11Resource *swizzleTexture = NULL;
1332         gl::Error error = getSwizzleTexture(&swizzleTexture);
1333         if (error.isError())
1334         {
1335             return error;
1336         }
1337
1338         ID3D11Device *device = mRenderer->getDevice();
1339
1340         D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
1341         rtvDesc.Format = mSwizzleRenderTargetFormat;
1342         rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
1343         rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
1344         rtvDesc.Texture2DArray.FirstArraySlice = 0;
1345         rtvDesc.Texture2DArray.ArraySize = CUBE_FACE_COUNT;
1346
1347         HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
1348
1349         ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
1350         if (FAILED(result))
1351         {
1352             return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result);
1353         }
1354     }
1355
1356     *outRTV = mSwizzleRenderTargets[mipLevel];
1357     return gl::Error(GL_NO_ERROR);
1358 }
1359
1360 TextureStorage11_3D::TextureStorage11_3D(Renderer *renderer, GLenum internalformat, bool renderTarget,
1361                                          GLsizei width, GLsizei height, GLsizei depth, int levels)
1362     : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget))
1363 {
1364     mTexture = NULL;
1365     mSwizzleTexture = NULL;
1366
1367     for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
1368     {
1369         mAssociatedImages[i] = NULL;
1370         mLevelRenderTargets[i] = NULL;
1371         mSwizzleRenderTargets[i] = NULL;
1372     }
1373
1374     const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
1375     mTextureFormat = formatInfo.texFormat;
1376     mShaderResourceFormat = formatInfo.srvFormat;
1377     mDepthStencilFormat = formatInfo.dsvFormat;
1378     mRenderTargetFormat = formatInfo.rtvFormat;
1379     mSwizzleTextureFormat = formatInfo.swizzleTexFormat;
1380     mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
1381     mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
1382
1383     // adjust size if needed for compressed textures
1384     d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel);
1385
1386     mMipLevels = mTopLevel + levels;
1387     mTextureWidth = width;
1388     mTextureHeight = height;
1389     mTextureDepth = depth;
1390
1391     initializeSerials(getLevelCount() * depth, depth);
1392 }
1393
1394 TextureStorage11_3D::~TextureStorage11_3D()
1395 {
1396     for (unsigned i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
1397     {
1398         if (mAssociatedImages[i] != NULL)
1399         {
1400             bool imageAssociationCorrect = mAssociatedImages[i]->isAssociatedStorageValid(this);
1401             ASSERT(imageAssociationCorrect);
1402
1403             if (imageAssociationCorrect)
1404             {
1405                 // We must let the Images recover their data before we delete it from the TextureStorage.
1406                 mAssociatedImages[i]->recoverFromAssociatedStorage();
1407             }
1408         }
1409     }
1410
1411     SafeRelease(mTexture);
1412     SafeRelease(mSwizzleTexture);
1413
1414     for (RenderTargetMap::iterator i = mLevelLayerRenderTargets.begin(); i != mLevelLayerRenderTargets.end(); i++)
1415     {
1416         SafeDelete(i->second);
1417     }
1418     mLevelLayerRenderTargets.clear();
1419
1420     for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
1421     {
1422         SafeDelete(mLevelRenderTargets[i]);
1423         SafeRelease(mSwizzleRenderTargets[i]);
1424     }
1425 }
1426
1427 TextureStorage11_3D *TextureStorage11_3D::makeTextureStorage11_3D(TextureStorage *storage)
1428 {
1429     ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_3D*, storage));
1430     return static_cast<TextureStorage11_3D*>(storage);
1431 }
1432
1433 void TextureStorage11_3D::associateImage(Image11* image, const gl::ImageIndex &index)
1434 {
1435     GLint level = index.mipIndex;
1436
1437     ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
1438
1439     if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
1440     {
1441         mAssociatedImages[level] = image;
1442     }
1443 }
1444
1445 bool TextureStorage11_3D::isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage)
1446 {
1447     GLint level = index.mipIndex;
1448
1449     if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
1450     {
1451         // This validation check should never return false. It means the Image/TextureStorage association is broken.
1452         bool retValue = (mAssociatedImages[level] == expectedImage);
1453         ASSERT(retValue);
1454         return retValue;
1455     }
1456
1457     return false;
1458 }
1459
1460 // disassociateImage allows an Image to end its association with a Storage.
1461 void TextureStorage11_3D::disassociateImage(const gl::ImageIndex &index, Image11* expectedImage)
1462 {
1463     GLint level = index.mipIndex;
1464
1465     ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
1466
1467     if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
1468     {
1469         ASSERT(mAssociatedImages[level] == expectedImage);
1470
1471         if (mAssociatedImages[level] == expectedImage)
1472         {
1473             mAssociatedImages[level] = NULL;
1474         }
1475     }
1476 }
1477
1478 // releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association.
1479 gl::Error TextureStorage11_3D::releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage)
1480 {
1481     GLint level = index.mipIndex;
1482
1483     ASSERT((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS));
1484
1485     if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
1486     {
1487         // No need to let the old Image recover its data, if it is also the incoming Image.
1488         if (mAssociatedImages[level] != NULL && mAssociatedImages[level] != incomingImage)
1489         {
1490             // Ensure that the Image is still associated with this TextureStorage. This should be true.
1491             bool imageAssociationCorrect = mAssociatedImages[level]->isAssociatedStorageValid(this);
1492             ASSERT(imageAssociationCorrect);
1493
1494             if (imageAssociationCorrect)
1495             {
1496                 // Force the image to recover from storage before its data is overwritten.
1497                 // This will reset mAssociatedImages[level] to NULL too.
1498                 gl::Error error = mAssociatedImages[level]->recoverFromAssociatedStorage();
1499                 if (error.isError())
1500                 {
1501                     return error;
1502                 }
1503             }
1504         }
1505     }
1506
1507     return gl::Error(GL_NO_ERROR);
1508 }
1509
1510 gl::Error TextureStorage11_3D::getResource(ID3D11Resource **outResource)
1511 {
1512     // If the width, height or depth are not positive this should be treated as an incomplete texture
1513     // we handle that here by skipping the d3d texture creation
1514     if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0 && mTextureDepth > 0)
1515     {
1516         ASSERT(mMipLevels > 0);
1517
1518         ID3D11Device *device = mRenderer->getDevice();
1519
1520         D3D11_TEXTURE3D_DESC desc;
1521         desc.Width = mTextureWidth;
1522         desc.Height = mTextureHeight;
1523         desc.Depth = mTextureDepth;
1524         desc.MipLevels = mMipLevels;
1525         desc.Format = mTextureFormat;
1526         desc.Usage = D3D11_USAGE_DEFAULT;
1527         desc.BindFlags = getBindFlags();
1528         desc.CPUAccessFlags = 0;
1529         desc.MiscFlags = 0;
1530
1531         HRESULT result = device->CreateTexture3D(&desc, NULL, &mTexture);
1532
1533         // this can happen from windows TDR
1534         if (d3d11::isDeviceLostError(result))
1535         {
1536             mRenderer->notifyDeviceLost();
1537             return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 3D texture storage, result: 0x%X.", result);
1538         }
1539         else if (FAILED(result))
1540         {
1541             ASSERT(result == E_OUTOFMEMORY);
1542             return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 3D texture storage, result: 0x%X.", result);
1543         }
1544     }
1545
1546     *outResource = mTexture;
1547     return gl::Error(GL_NO_ERROR);
1548 }
1549
1550 gl::Error TextureStorage11_3D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
1551                                          ID3D11ShaderResourceView **outSRV) const
1552 {
1553     ASSERT(outSRV);
1554
1555     D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
1556     srvDesc.Format = format;
1557     srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
1558     srvDesc.Texture3D.MostDetailedMip = baseLevel;
1559     srvDesc.Texture3D.MipLevels = mipLevels;
1560
1561     ID3D11Device *device = mRenderer->getDevice();
1562     HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV);
1563
1564     ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
1565     if (FAILED(result))
1566     {
1567         return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result);
1568     }
1569
1570     return gl::Error(GL_NO_ERROR);
1571 }
1572
1573 gl::Error TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
1574 {
1575     int mipLevel = index.mipIndex;
1576     ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
1577
1578     ASSERT(mRenderTargetFormat != DXGI_FORMAT_UNKNOWN);
1579
1580     if (!index.hasLayer())
1581     {
1582         if (!mLevelRenderTargets[mipLevel])
1583         {
1584             ID3D11Resource *texture = NULL;
1585             gl::Error error = getResource(&texture);
1586             if (error.isError())
1587             {
1588                 return error;
1589             }
1590
1591             ID3D11ShaderResourceView *srv = NULL;
1592             error = getSRVLevel(mipLevel, &srv);
1593             if (error.isError())
1594             {
1595                 return error;
1596             }
1597
1598             ID3D11Device *device = mRenderer->getDevice();
1599
1600             D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
1601             rtvDesc.Format = mRenderTargetFormat;
1602             rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
1603             rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
1604             rtvDesc.Texture3D.FirstWSlice = 0;
1605             rtvDesc.Texture3D.WSize = -1;
1606
1607             ID3D11RenderTargetView *rtv;
1608             HRESULT result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv);
1609
1610             ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
1611             if (FAILED(result))
1612             {
1613                 SafeRelease(srv);
1614                 return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result);
1615             }
1616
1617             mLevelRenderTargets[mipLevel] = new RenderTarget11(mRenderer, rtv, texture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), getLevelDepth(mipLevel));
1618
1619             // RenderTarget will take ownership of these resources
1620             SafeRelease(rtv);
1621         }
1622
1623         ASSERT(outRT);
1624         *outRT = mLevelRenderTargets[mipLevel];
1625         return gl::Error(GL_NO_ERROR);
1626     }
1627     else
1628     {
1629         int layer = index.layerIndex;
1630
1631         LevelLayerKey key(mipLevel, layer);
1632         if (mLevelLayerRenderTargets.find(key) == mLevelLayerRenderTargets.end())
1633         {
1634             ID3D11Device *device = mRenderer->getDevice();
1635             HRESULT result;
1636
1637             ID3D11Resource *texture = NULL;
1638             gl::Error error = getResource(&texture);
1639             if (error.isError())
1640             {
1641                 return error;
1642             }
1643
1644             // TODO, what kind of SRV is expected here?
1645             ID3D11ShaderResourceView *srv = NULL;
1646
1647             D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
1648             rtvDesc.Format = mRenderTargetFormat;
1649             rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
1650             rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
1651             rtvDesc.Texture3D.FirstWSlice = layer;
1652             rtvDesc.Texture3D.WSize = 1;
1653
1654             ID3D11RenderTargetView *rtv;
1655             result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv);
1656
1657             ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
1658             if (FAILED(result))
1659             {
1660                 SafeRelease(srv); return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result);
1661             }
1662             ASSERT(SUCCEEDED(result));
1663
1664             mLevelLayerRenderTargets[key] = new RenderTarget11(mRenderer, rtv, texture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1);
1665
1666             // RenderTarget will take ownership of these resources
1667             SafeRelease(rtv);
1668         }
1669
1670         ASSERT(outRT);
1671         *outRT = mLevelLayerRenderTargets[key];
1672         return gl::Error(GL_NO_ERROR);
1673     }
1674 }
1675
1676 gl::Error TextureStorage11_3D::getSwizzleTexture(ID3D11Resource **outTexture)
1677 {
1678     ASSERT(outTexture);
1679
1680     if (!mSwizzleTexture)
1681     {
1682         ID3D11Device *device = mRenderer->getDevice();
1683
1684         D3D11_TEXTURE3D_DESC desc;
1685         desc.Width = mTextureWidth;
1686         desc.Height = mTextureHeight;
1687         desc.Depth = mTextureDepth;
1688         desc.MipLevels = mMipLevels;
1689         desc.Format = mSwizzleTextureFormat;
1690         desc.Usage = D3D11_USAGE_DEFAULT;
1691         desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
1692         desc.CPUAccessFlags = 0;
1693         desc.MiscFlags = 0;
1694
1695         HRESULT result = device->CreateTexture3D(&desc, NULL, &mSwizzleTexture);
1696
1697         ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
1698         if (FAILED(result))
1699         {
1700             return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result);
1701         }
1702     }
1703
1704     *outTexture = mSwizzleTexture;
1705     return gl::Error(GL_NO_ERROR);
1706 }
1707
1708 gl::Error TextureStorage11_3D::getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV)
1709 {
1710     ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
1711     ASSERT(outRTV);
1712
1713     if (!mSwizzleRenderTargets[mipLevel])
1714     {
1715         ID3D11Resource *swizzleTexture = NULL;
1716         gl::Error error = getSwizzleTexture(&swizzleTexture);
1717         if (error.isError())
1718         {
1719             return error;
1720         }
1721
1722         ID3D11Device *device = mRenderer->getDevice();
1723
1724         D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
1725         rtvDesc.Format = mSwizzleRenderTargetFormat;
1726         rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
1727         rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
1728         rtvDesc.Texture3D.FirstWSlice = 0;
1729         rtvDesc.Texture3D.WSize = -1;
1730
1731         HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
1732
1733         ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
1734         if (FAILED(result))
1735         {
1736             return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result);
1737         }
1738     }
1739
1740     *outRTV = mSwizzleRenderTargets[mipLevel];
1741     return gl::Error(GL_NO_ERROR);
1742 }
1743
1744 TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer *renderer, GLenum internalformat, bool renderTarget,
1745                                                    GLsizei width, GLsizei height, GLsizei depth, int levels)
1746     : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget))
1747 {
1748     mTexture = NULL;
1749     mSwizzleTexture = NULL;
1750
1751     for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
1752     {
1753         mSwizzleRenderTargets[level] = NULL;
1754     }
1755
1756     const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
1757     mTextureFormat = formatInfo.texFormat;
1758     mShaderResourceFormat = formatInfo.srvFormat;
1759     mDepthStencilFormat = formatInfo.dsvFormat;
1760     mRenderTargetFormat = formatInfo.rtvFormat;
1761     mSwizzleTextureFormat = formatInfo.swizzleTexFormat;
1762     mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
1763     mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
1764
1765     // adjust size if needed for compressed textures
1766     d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel);
1767
1768     mMipLevels = mTopLevel + levels;
1769     mTextureWidth = width;
1770     mTextureHeight = height;
1771     mTextureDepth = depth;
1772
1773     initializeSerials(getLevelCount() * depth, depth);
1774 }
1775
1776 TextureStorage11_2DArray::~TextureStorage11_2DArray()
1777 {
1778     for (ImageMap::iterator i = mAssociatedImages.begin(); i != mAssociatedImages.end(); i++)
1779     {
1780         bool imageAssociationCorrect = i->second->isAssociatedStorageValid(this);
1781         ASSERT(imageAssociationCorrect);
1782
1783         if (imageAssociationCorrect)
1784         {
1785             // We must let the Images recover their data before we delete it from the TextureStorage.
1786             i->second->recoverFromAssociatedStorage();
1787         }
1788     }
1789     mAssociatedImages.clear();
1790
1791     SafeRelease(mTexture);
1792     SafeRelease(mSwizzleTexture);
1793
1794     for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
1795     {
1796         SafeRelease(mSwizzleRenderTargets[level]);
1797     }
1798
1799     for (RenderTargetMap::iterator i = mRenderTargets.begin(); i != mRenderTargets.end(); i++)
1800     {
1801         SafeDelete(i->second);
1802     }
1803     mRenderTargets.clear();
1804 }
1805
1806 TextureStorage11_2DArray *TextureStorage11_2DArray::makeTextureStorage11_2DArray(TextureStorage *storage)
1807 {
1808     ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_2DArray*, storage));
1809     return static_cast<TextureStorage11_2DArray*>(storage);
1810 }
1811
1812 void TextureStorage11_2DArray::associateImage(Image11* image, const gl::ImageIndex &index)
1813 {
1814     GLint level = index.mipIndex;
1815     GLint layerTarget = index.layerIndex;
1816
1817     ASSERT(0 <= level && level < getLevelCount());
1818
1819     if (0 <= level && level < getLevelCount())
1820     {
1821         LevelLayerKey key(level, layerTarget);
1822         mAssociatedImages[key] = image;
1823     }
1824 }
1825
1826 bool TextureStorage11_2DArray::isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage)
1827 {
1828     GLint level = index.mipIndex;
1829     GLint layerTarget = index.layerIndex;
1830
1831     LevelLayerKey key(level, layerTarget);
1832
1833     // This validation check should never return false. It means the Image/TextureStorage association is broken.
1834     bool retValue = (mAssociatedImages.find(key) != mAssociatedImages.end() && (mAssociatedImages[key] == expectedImage));
1835     ASSERT(retValue);
1836     return retValue;
1837 }
1838
1839 // disassociateImage allows an Image to end its association with a Storage.
1840 void TextureStorage11_2DArray::disassociateImage(const gl::ImageIndex &index, Image11* expectedImage)
1841 {
1842     GLint level = index.mipIndex;
1843     GLint layerTarget = index.layerIndex;
1844
1845     LevelLayerKey key(level, layerTarget);
1846
1847     bool imageAssociationCorrect = (mAssociatedImages.find(key) != mAssociatedImages.end() && (mAssociatedImages[key] == expectedImage));
1848     ASSERT(imageAssociationCorrect);
1849
1850     if (imageAssociationCorrect)
1851     {
1852         mAssociatedImages[key] = NULL;
1853     }
1854 }
1855
1856 // releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association.
1857 gl::Error TextureStorage11_2DArray::releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage)
1858 {
1859     GLint level = index.mipIndex;
1860     GLint layerTarget = index.layerIndex;
1861
1862     LevelLayerKey key(level, layerTarget);
1863
1864     ASSERT(mAssociatedImages.find(key) != mAssociatedImages.end());
1865
1866     if (mAssociatedImages.find(key) != mAssociatedImages.end())
1867     {
1868         if (mAssociatedImages[key] != NULL && mAssociatedImages[key] != incomingImage)
1869         {
1870             // Ensure that the Image is still associated with this TextureStorage. This should be true.
1871             bool imageAssociationCorrect = mAssociatedImages[key]->isAssociatedStorageValid(this);
1872             ASSERT(imageAssociationCorrect);
1873
1874             if (imageAssociationCorrect)
1875             {
1876                 // Force the image to recover from storage before its data is overwritten.
1877                 // This will reset mAssociatedImages[level] to NULL too.
1878                 gl::Error error = mAssociatedImages[key]->recoverFromAssociatedStorage();
1879                 if (error.isError())
1880                 {
1881                     return error;
1882                 }
1883             }
1884         }
1885     }
1886
1887     return gl::Error(GL_NO_ERROR);
1888 }
1889
1890 gl::Error TextureStorage11_2DArray::getResource(ID3D11Resource **outResource)
1891 {
1892     // if the width, height or depth is not positive this should be treated as an incomplete texture
1893     // we handle that here by skipping the d3d texture creation
1894     if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0 && mTextureDepth > 0)
1895     {
1896         ASSERT(mMipLevels > 0);
1897
1898         ID3D11Device *device = mRenderer->getDevice();
1899
1900         D3D11_TEXTURE2D_DESC desc;
1901         desc.Width = mTextureWidth;
1902         desc.Height = mTextureHeight;
1903         desc.MipLevels = mMipLevels;
1904         desc.ArraySize = mTextureDepth;
1905         desc.Format = mTextureFormat;
1906         desc.SampleDesc.Count = 1;
1907         desc.SampleDesc.Quality = 0;
1908         desc.Usage = D3D11_USAGE_DEFAULT;
1909         desc.BindFlags = getBindFlags();
1910         desc.CPUAccessFlags = 0;
1911         desc.MiscFlags = 0;
1912
1913         HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
1914
1915         // this can happen from windows TDR
1916         if (d3d11::isDeviceLostError(result))
1917         {
1918             mRenderer->notifyDeviceLost();
1919             return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D array texture storage, result: 0x%X.", result);
1920         }
1921         else if (FAILED(result))
1922         {
1923             ASSERT(result == E_OUTOFMEMORY);
1924             return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D array texture storage, result: 0x%X.", result);
1925         }
1926     }
1927
1928     *outResource = mTexture;
1929     return gl::Error(GL_NO_ERROR);
1930 }
1931
1932 gl::Error TextureStorage11_2DArray::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
1933                                               ID3D11ShaderResourceView **outSRV) const
1934 {
1935     D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
1936     srvDesc.Format = format;
1937     srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
1938     srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel;
1939     srvDesc.Texture2DArray.MipLevels = mipLevels;
1940     srvDesc.Texture2DArray.FirstArraySlice = 0;
1941     srvDesc.Texture2DArray.ArraySize = mTextureDepth;
1942
1943     ID3D11Device *device = mRenderer->getDevice();
1944     HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV);
1945
1946     ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
1947     if (FAILED(result))
1948     {
1949         return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result);
1950     }
1951
1952     return gl::Error(GL_NO_ERROR);
1953 }
1954
1955 gl::Error TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
1956 {
1957     ASSERT(index.hasLayer());
1958
1959     int mipLevel = index.mipIndex;
1960     int layer = index.layerIndex;
1961
1962     ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
1963
1964     LevelLayerKey key(mipLevel, layer);
1965     if (mRenderTargets.find(key) == mRenderTargets.end())
1966     {
1967         ID3D11Device *device = mRenderer->getDevice();
1968         HRESULT result;
1969
1970         ID3D11Resource *texture = NULL;
1971         gl::Error error = getResource(&texture);
1972         if (error.isError())
1973         {
1974             return error;
1975         }
1976
1977         D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
1978         srvDesc.Format = mShaderResourceFormat;
1979         srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
1980         srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + mipLevel;
1981         srvDesc.Texture2DArray.MipLevels = 1;
1982         srvDesc.Texture2DArray.FirstArraySlice = layer;
1983         srvDesc.Texture2DArray.ArraySize = 1;
1984
1985         ID3D11ShaderResourceView *srv;
1986         result = device->CreateShaderResourceView(texture, &srvDesc, &srv);
1987
1988         ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
1989         if (FAILED(result))
1990         {
1991             return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal shader resource view for texture storage, result: 0x%X.", result);
1992         }
1993
1994         if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
1995         {
1996             D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
1997             rtvDesc.Format = mRenderTargetFormat;
1998             rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
1999             rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
2000             rtvDesc.Texture2DArray.FirstArraySlice = layer;
2001             rtvDesc.Texture2DArray.ArraySize = 1;
2002
2003             ID3D11RenderTargetView *rtv;
2004             result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv);
2005
2006             ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
2007             if (FAILED(result))
2008             {
2009                 SafeRelease(srv);
2010                 return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result);
2011             }
2012
2013             mRenderTargets[key] = new RenderTarget11(mRenderer, rtv, texture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1);
2014
2015             // RenderTarget will take ownership of these resources
2016             SafeRelease(rtv);
2017             SafeRelease(srv);
2018         }
2019         else
2020         {
2021             UNREACHABLE();
2022         }
2023     }
2024
2025     ASSERT(outRT);
2026     *outRT = mRenderTargets[key];
2027     return gl::Error(GL_NO_ERROR);
2028 }
2029
2030 gl::Error TextureStorage11_2DArray::getSwizzleTexture(ID3D11Resource **outTexture)
2031 {
2032     if (!mSwizzleTexture)
2033     {
2034         ID3D11Device *device = mRenderer->getDevice();
2035
2036         D3D11_TEXTURE2D_DESC desc;
2037         desc.Width = mTextureWidth;
2038         desc.Height = mTextureHeight;
2039         desc.MipLevels = mMipLevels;
2040         desc.ArraySize = mTextureDepth;
2041         desc.Format = mSwizzleTextureFormat;
2042         desc.SampleDesc.Count = 1;
2043         desc.SampleDesc.Quality = 0;
2044         desc.Usage = D3D11_USAGE_DEFAULT;
2045         desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
2046         desc.CPUAccessFlags = 0;
2047         desc.MiscFlags = 0;
2048
2049         HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture);
2050
2051         ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
2052         if (FAILED(result))
2053         {
2054             return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result);
2055         }
2056     }
2057
2058     *outTexture = mSwizzleTexture;
2059     return gl::Error(GL_NO_ERROR);
2060 }
2061
2062 gl::Error TextureStorage11_2DArray::getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV)
2063 {
2064     ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
2065     ASSERT(outRTV);
2066
2067     if (!mSwizzleRenderTargets[mipLevel])
2068     {
2069         ID3D11Resource *swizzleTexture = NULL;
2070         gl::Error error = getSwizzleTexture(&swizzleTexture);
2071         if (error.isError())
2072         {
2073             return error;
2074         }
2075
2076         ID3D11Device *device = mRenderer->getDevice();
2077
2078         D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
2079         rtvDesc.Format = mSwizzleRenderTargetFormat;
2080         rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
2081         rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
2082         rtvDesc.Texture2DArray.FirstArraySlice = 0;
2083         rtvDesc.Texture2DArray.ArraySize = mTextureDepth;
2084
2085         HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
2086
2087         ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
2088         if (FAILED(result))
2089         {
2090             return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result);
2091         }
2092     }
2093
2094     *outRTV = mSwizzleRenderTargets[mipLevel];
2095     return gl::Error(GL_NO_ERROR);
2096 }
2097
2098 }