Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / angle / src / libGLESv2 / renderer / d3d / d3d11 / TextureStorage11.cpp
1 #include "precompiled.h"
2 //
3 // Copyright (c) 2012-2014 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 // TextureStorage11.cpp: Implements the abstract rx::TextureStorage11 class and its concrete derived
9 // classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11 texture.
10
11 #include "libGLESv2/renderer/d3d/d3d11/TextureStorage11.h"
12
13 #include "libGLESv2/renderer/d3d/TextureD3D.h"
14 #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
15 #include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
16 #include "libGLESv2/renderer/d3d/d3d11/SwapChain11.h"
17 #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
18 #include "libGLESv2/renderer/d3d/d3d11/Blit11.h"
19 #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
20
21 #include "common/utilities.h"
22 #include "libGLESv2/main.h"
23
24 namespace rx
25 {
26
27 TextureStorage11::SwizzleCacheValue::SwizzleCacheValue()
28     : swizzleRed(GL_NONE), swizzleGreen(GL_NONE), swizzleBlue(GL_NONE), swizzleAlpha(GL_NONE)
29 {
30 }
31
32 TextureStorage11::SwizzleCacheValue::SwizzleCacheValue(GLenum red, GLenum green, GLenum blue, GLenum alpha)
33     : swizzleRed(red), swizzleGreen(green), swizzleBlue(blue), swizzleAlpha(alpha)
34 {
35 }
36
37 bool TextureStorage11::SwizzleCacheValue::operator==(const SwizzleCacheValue &other) const
38 {
39     return swizzleRed == other.swizzleRed &&
40            swizzleGreen == other.swizzleGreen &&
41            swizzleBlue == other.swizzleBlue &&
42            swizzleAlpha == other.swizzleAlpha;
43 }
44
45 bool TextureStorage11::SwizzleCacheValue::operator!=(const SwizzleCacheValue &other) const
46 {
47     return !(*this == other);
48 }
49
50 TextureStorage11::SRVKey::SRVKey(int baseLevel, int mipLevels, bool swizzle)
51     : baseLevel(baseLevel), mipLevels(mipLevels), swizzle(swizzle)
52 {
53 }
54
55 bool TextureStorage11::SRVKey::operator==(const SRVKey &rhs) const
56 {
57     return baseLevel == rhs.baseLevel &&
58            mipLevels == rhs.mipLevels &&
59            swizzle == rhs.swizzle;
60 }
61
62 TextureStorage11::SRVCache::~SRVCache()
63 {
64     for (size_t i = 0; i < cache.size(); i++)
65     {
66         SafeRelease(cache[i].srv);
67     }
68 }
69
70 ID3D11ShaderResourceView *TextureStorage11::SRVCache::find(const SRVKey &key) const
71 {
72     for (size_t i = 0; i < cache.size(); i++)
73     {
74         if (cache[i].key == key)
75         {
76             return cache[i].srv;
77         }
78     }
79
80     return NULL;
81 }
82
83 ID3D11ShaderResourceView *TextureStorage11::SRVCache::add(const SRVKey &key, ID3D11ShaderResourceView *srv)
84 {
85     SRVPair pair = {key, srv};
86     cache.push_back(pair);
87
88     return srv;
89 }
90
91 TextureStorage11::TextureStorage11(Renderer *renderer, UINT bindFlags)
92     : mBindFlags(bindFlags),
93       mTopLevel(0),
94       mMipLevels(0),
95       mTextureFormat(DXGI_FORMAT_UNKNOWN),
96       mShaderResourceFormat(DXGI_FORMAT_UNKNOWN),
97       mRenderTargetFormat(DXGI_FORMAT_UNKNOWN),
98       mDepthStencilFormat(DXGI_FORMAT_UNKNOWN),
99       mTextureWidth(0),
100       mTextureHeight(0),
101       mTextureDepth(0)
102 {
103     mRenderer = Renderer11::makeRenderer11(renderer);
104
105     for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
106     {
107         mLevelSRVs[i] = NULL;
108     }
109 }
110
111 TextureStorage11::~TextureStorage11()
112 {
113     for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
114     {
115         SafeRelease(mLevelSRVs[level]);
116     }
117 }
118
119 TextureStorage11 *TextureStorage11::makeTextureStorage11(TextureStorage *storage)
120 {
121     ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11*, storage));
122     return static_cast<TextureStorage11*>(storage);
123 }
124
125 DWORD TextureStorage11::GetTextureBindFlags(GLenum internalFormat, bool renderTarget)
126 {
127     UINT bindFlags = 0;
128
129     const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat);
130     if (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN)
131     {
132         bindFlags |= D3D11_BIND_SHADER_RESOURCE;
133     }
134     if (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN)
135     {
136         bindFlags |= D3D11_BIND_DEPTH_STENCIL;
137     }
138     if (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN && renderTarget)
139     {
140         bindFlags |= D3D11_BIND_RENDER_TARGET;
141     }
142
143     return bindFlags;
144 }
145
146 UINT TextureStorage11::getBindFlags() const
147 {
148     return mBindFlags;
149 }
150
151 int TextureStorage11::getTopLevel() const
152 {
153     return mTopLevel;
154 }
155
156 bool TextureStorage11::isRenderTarget() const
157 {
158     return (mBindFlags & (D3D11_BIND_RENDER_TARGET | D3D11_BIND_DEPTH_STENCIL)) != 0;
159 }
160
161 bool TextureStorage11::isManaged() const
162 {
163     return false;
164 }
165
166 int TextureStorage11::getLevelCount() const
167 {
168     return mMipLevels - mTopLevel;
169 }
170
171 int TextureStorage11::getLevelWidth(int mipLevel) const
172 {
173     return std::max(static_cast<int>(mTextureWidth) >> mipLevel, 1);
174 }
175
176 int TextureStorage11::getLevelHeight(int mipLevel) const
177 {
178     return std::max(static_cast<int>(mTextureHeight) >> mipLevel, 1);
179 }
180
181 int TextureStorage11::getLevelDepth(int mipLevel) const
182 {
183     return std::max(static_cast<int>(mTextureDepth) >> mipLevel, 1);
184 }
185
186 UINT TextureStorage11::getSubresourceIndex(int mipLevel, int layerTarget) const
187 {
188     UINT index = 0;
189     if (getResource())
190     {
191         index = D3D11CalcSubresource(mipLevel, layerTarget, mMipLevels);
192     }
193     return index;
194 }
195
196 ID3D11ShaderResourceView *TextureStorage11::getSRV(const gl::SamplerState &samplerState)
197 {
198     bool swizzleRequired = samplerState.swizzleRequired();
199     bool mipmapping = IsMipmapFiltered(samplerState);
200     unsigned int mipLevels = mipmapping ? (samplerState.maxLevel - samplerState.baseLevel) : 1;
201
202     // Make sure there's 'mipLevels' mipmap levels below the base level (offset by the top level,  which corresponds to GL level 0)
203     mipLevels = std::min(mipLevels, mMipLevels - mTopLevel - samplerState.baseLevel);
204
205     if (swizzleRequired)
206     {
207         verifySwizzleExists(samplerState.swizzleRed, samplerState.swizzleGreen, samplerState.swizzleBlue, samplerState.swizzleAlpha);
208     }
209     
210     SRVKey key(samplerState.baseLevel, mipLevels, swizzleRequired);
211     ID3D11ShaderResourceView *srv = srvCache.find(key);
212
213     if(srv)
214     {
215         return srv;
216     }
217
218     DXGI_FORMAT format = (swizzleRequired ? mSwizzleShaderResourceFormat : mShaderResourceFormat);
219     ID3D11Resource *texture = swizzleRequired ? getSwizzleTexture() : getResource();
220
221     srv = createSRV(samplerState.baseLevel, mipLevels, format, texture);
222     
223     return srvCache.add(key, srv);
224 }
225
226 ID3D11ShaderResourceView *TextureStorage11::getSRVLevel(int mipLevel)
227 {
228     if (mipLevel >= 0 && mipLevel < getLevelCount())
229     {
230         if (!mLevelSRVs[mipLevel])
231         {
232             mLevelSRVs[mipLevel] = createSRV(mipLevel, 1, mShaderResourceFormat, getResource());
233         }
234
235         return mLevelSRVs[mipLevel];
236     }
237     else
238     {
239         return NULL;
240     }
241 }
242
243 void TextureStorage11::generateSwizzles(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha)
244 {
245     SwizzleCacheValue swizzleTarget(swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha);
246     for (int level = 0; level < getLevelCount(); level++)
247     {
248         // Check if the swizzle for this level is out of date
249         if (mSwizzleCache[level] != swizzleTarget)
250         {
251             // Need to re-render the swizzle for this level
252             ID3D11ShaderResourceView *sourceSRV = getSRVLevel(level);
253             ID3D11RenderTargetView *destRTV = getSwizzleRenderTarget(level);
254
255             gl::Extents size(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level));
256
257             Blit11 *blitter = mRenderer->getBlitter();
258
259             if (blitter->swizzleTexture(sourceSRV, destRTV, size, swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha))
260             {
261                 mSwizzleCache[level] = swizzleTarget;
262             }
263             else
264             {
265                 ERR("Failed to swizzle texture.");
266             }
267         }
268     }
269 }
270
271 void TextureStorage11::invalidateSwizzleCacheLevel(int mipLevel)
272 {
273     if (mipLevel >= 0 && static_cast<unsigned int>(mipLevel) < ArraySize(mSwizzleCache))
274     {
275         // The default constructor of SwizzleCacheValue has GL_NONE for all channels which is not a
276         // valid swizzle combination
277         mSwizzleCache[mipLevel] = SwizzleCacheValue();
278     }
279 }
280
281 void TextureStorage11::invalidateSwizzleCache()
282 {
283     for (unsigned int mipLevel = 0; mipLevel < ArraySize(mSwizzleCache); mipLevel++)
284     {
285         invalidateSwizzleCacheLevel(mipLevel);
286     }
287 }
288
289 bool TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture, unsigned int sourceSubresource,
290                                               int level, int layerTarget, GLint xoffset, GLint yoffset, GLint zoffset,
291                                               GLsizei width, GLsizei height, GLsizei depth)
292 {
293     if (srcTexture)
294     {
295         invalidateSwizzleCacheLevel(level);
296
297         gl::Extents texSize(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level));
298         gl::Box copyArea(xoffset, yoffset, zoffset, width, height, depth);
299
300         bool fullCopy = copyArea.x == 0 &&
301                         copyArea.y == 0 &&
302                         copyArea.z == 0 &&
303                         copyArea.width  == texSize.width &&
304                         copyArea.height == texSize.height &&
305                         copyArea.depth  == texSize.depth;
306
307         ID3D11Resource *dstTexture = getResource();
308         unsigned int dstSubresource = getSubresourceIndex(level + mTopLevel, layerTarget);
309
310         ASSERT(dstTexture);
311
312         const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat);
313         if (!fullCopy && (dxgiFormatInfo.depthBits > 0 || dxgiFormatInfo.stencilBits > 0))
314         {
315             // CopySubresourceRegion cannot copy partial depth stencils, use the blitter instead
316             Blit11 *blitter = mRenderer->getBlitter();
317
318             return blitter->copyDepthStencil(srcTexture, sourceSubresource, copyArea, texSize,
319                                              dstTexture, dstSubresource, copyArea, texSize,
320                                              NULL);
321         }
322         else
323         {
324             const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat);
325
326             D3D11_BOX srcBox;
327             srcBox.left = copyArea.x;
328             srcBox.top = copyArea.y;
329             srcBox.right = copyArea.x + roundUp((unsigned int)width, dxgiFormatInfo.blockWidth);
330             srcBox.bottom = copyArea.y + roundUp((unsigned int)height, dxgiFormatInfo.blockHeight);
331             srcBox.front = copyArea.z;
332             srcBox.back = copyArea.z + copyArea.depth;
333
334             ID3D11DeviceContext *context = mRenderer->getDeviceContext();
335
336             context->CopySubresourceRegion(dstTexture, dstSubresource, copyArea.x, copyArea.y, copyArea.z,
337                                            srcTexture, sourceSubresource, fullCopy ? NULL : &srcBox);
338             return true;
339         }
340     }
341
342     return false;
343 }
344
345 void TextureStorage11::generateMipmapLayer(RenderTarget11 *source, RenderTarget11 *dest)
346 {
347     if (source && dest)
348     {
349         ID3D11ShaderResourceView *sourceSRV = source->getShaderResourceView();
350         ID3D11RenderTargetView *destRTV = dest->getRenderTargetView();
351
352         if (sourceSRV && destRTV)
353         {
354             gl::Box sourceArea(0, 0, 0, source->getWidth(), source->getHeight(), source->getDepth());
355             gl::Extents sourceSize(source->getWidth(), source->getHeight(), source->getDepth());
356
357             gl::Box destArea(0, 0, 0, dest->getWidth(), dest->getHeight(), dest->getDepth());
358             gl::Extents destSize(dest->getWidth(), dest->getHeight(), dest->getDepth());
359
360             Blit11 *blitter = mRenderer->getBlitter();
361
362             blitter->copyTexture(sourceSRV, sourceArea, sourceSize, destRTV, destArea, destSize, NULL,
363                                  gl::GetInternalFormatInfo(source->getInternalFormat()).format, GL_LINEAR);
364         }
365     }
366 }
367
368 void TextureStorage11::verifySwizzleExists(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha)
369 {
370     SwizzleCacheValue swizzleTarget(swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha);
371     for (unsigned int level = 0; level < mMipLevels; level++)
372     {
373         ASSERT(mSwizzleCache[level] == swizzleTarget);
374     }
375 }
376
377 TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapchain)
378     : TextureStorage11(renderer, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE)
379 {
380     mTexture = swapchain->getOffscreenTexture();
381     mTexture->AddRef();
382     mSwizzleTexture = NULL;
383
384     for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
385     {
386         mRenderTarget[i] = NULL;
387         mSwizzleRenderTargets[i] = NULL;
388     }
389
390     D3D11_TEXTURE2D_DESC texDesc;
391     mTexture->GetDesc(&texDesc);
392     mMipLevels = texDesc.MipLevels;
393     mTextureFormat = texDesc.Format;
394     mTextureWidth = texDesc.Width;
395     mTextureHeight = texDesc.Height;
396     mTextureDepth = 1;
397
398     ID3D11ShaderResourceView *srv = swapchain->getRenderTargetShaderResource();
399     D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
400     srv->GetDesc(&srvDesc);
401     mShaderResourceFormat = srvDesc.Format;
402
403     ID3D11RenderTargetView* offscreenRTV = swapchain->getRenderTarget();
404     D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
405     offscreenRTV->GetDesc(&rtvDesc);
406     mRenderTargetFormat = rtvDesc.Format;
407
408     const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat);
409     const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(dxgiFormatInfo.internalFormat);
410     mSwizzleTextureFormat = formatInfo.swizzleTexFormat;
411     mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
412     mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
413
414     mDepthStencilFormat = DXGI_FORMAT_UNKNOWN;
415 }
416
417 TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels)
418     : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget))
419 {
420     mTexture = NULL;
421     mSwizzleTexture = NULL;
422
423     for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
424     {
425         mRenderTarget[i] = NULL;
426         mSwizzleRenderTargets[i] = NULL;
427     }
428
429     const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
430     mTextureFormat = formatInfo.texFormat;
431     mShaderResourceFormat = formatInfo.srvFormat;
432     mDepthStencilFormat = formatInfo.dsvFormat;
433     mRenderTargetFormat = formatInfo.rtvFormat;
434     mSwizzleTextureFormat = formatInfo.swizzleTexFormat;
435     mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
436     mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
437
438     // if the width or height is not positive this should be treated as an incomplete texture
439     // we handle that here by skipping the d3d texture creation
440     if (width > 0 && height > 0)
441     {
442         // adjust size if needed for compressed textures
443         d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel);
444
445         ID3D11Device *device = mRenderer->getDevice();
446
447         D3D11_TEXTURE2D_DESC desc;
448         desc.Width = width;      // Compressed texture size constraints?
449         desc.Height = height;
450         desc.MipLevels = ((levels > 0) ? (mTopLevel + levels) : 0);
451         desc.ArraySize = 1;
452         desc.Format = mTextureFormat;
453         desc.SampleDesc.Count = 1;
454         desc.SampleDesc.Quality = 0;
455         desc.Usage = D3D11_USAGE_DEFAULT;
456         desc.BindFlags = getBindFlags();
457         desc.CPUAccessFlags = 0;
458         desc.MiscFlags = 0;
459
460         HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
461
462         // this can happen from windows TDR
463         if (d3d11::isDeviceLostError(result))
464         {
465             mRenderer->notifyDeviceLost();
466             gl::error(GL_OUT_OF_MEMORY);
467         }
468         else if (FAILED(result))
469         {
470             ASSERT(result == E_OUTOFMEMORY);
471             ERR("Creating image failed.");
472             gl::error(GL_OUT_OF_MEMORY);
473         }
474         else
475         {
476             mTexture->GetDesc(&desc);
477             mMipLevels = desc.MipLevels;
478             mTextureWidth = desc.Width;
479             mTextureHeight = desc.Height;
480             mTextureDepth = 1;
481         }
482     }
483 }
484
485 TextureStorage11_2D::~TextureStorage11_2D()
486 {
487     SafeRelease(mTexture);
488     SafeRelease(mSwizzleTexture);
489
490     for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
491     {
492         SafeDelete(mRenderTarget[i]);
493         SafeRelease(mSwizzleRenderTargets[i]);
494     }
495 }
496
497 TextureStorage11_2D *TextureStorage11_2D::makeTextureStorage11_2D(TextureStorage *storage)
498 {
499     ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_2D*, storage));
500     return static_cast<TextureStorage11_2D*>(storage);
501 }
502
503 ID3D11Resource *TextureStorage11_2D::getResource() const
504 {
505     return mTexture;
506 }
507
508 RenderTarget *TextureStorage11_2D::getRenderTarget(int level)
509 {
510     if (level >= 0 && level < getLevelCount())
511     {
512         if (!mRenderTarget[level])
513         {
514             ID3D11ShaderResourceView *srv = getSRVLevel(level);
515             if (!srv)
516             {
517                 return NULL;
518             }
519
520             if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
521             {
522                 ID3D11Device *device = mRenderer->getDevice();
523
524                 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
525                 rtvDesc.Format = mRenderTargetFormat;
526                 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
527                 rtvDesc.Texture2D.MipSlice = mTopLevel + level;
528
529                 ID3D11RenderTargetView *rtv;
530                 HRESULT result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
531
532                 if (result == E_OUTOFMEMORY)
533                 {
534                     return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
535                 }
536                 ASSERT(SUCCEEDED(result));
537
538                 mRenderTarget[level] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1);
539
540                 // RenderTarget will take ownership of these resources
541                 SafeRelease(rtv);
542             }
543             else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN)
544             {
545                 ID3D11Device *device = mRenderer->getDevice();
546
547                 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
548                 dsvDesc.Format = mDepthStencilFormat;
549                 dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
550                 dsvDesc.Texture2D.MipSlice = mTopLevel + level;
551                 dsvDesc.Flags = 0;
552
553                 ID3D11DepthStencilView *dsv;
554                 HRESULT result = device->CreateDepthStencilView(mTexture, &dsvDesc, &dsv);
555
556                 if (result == E_OUTOFMEMORY)
557                 {
558                     SafeRelease(srv);
559                     return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
560                 }
561                 ASSERT(SUCCEEDED(result));
562
563                 mRenderTarget[level] = new RenderTarget11(mRenderer, dsv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1);
564
565                 // RenderTarget will take ownership of these resources
566                 SafeRelease(dsv);
567             }
568             else
569             {
570                 UNREACHABLE();
571             }
572         }
573
574         return mRenderTarget[level];
575     }
576     else
577     {
578         return NULL;
579     }
580 }
581
582 ID3D11ShaderResourceView *TextureStorage11_2D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture)
583 {
584     D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
585     srvDesc.Format = format;
586     srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
587     srvDesc.Texture2D.MostDetailedMip = mTopLevel + baseLevel;
588     srvDesc.Texture2D.MipLevels = mipLevels;
589
590     ID3D11ShaderResourceView *SRV = NULL;
591
592     ID3D11Device *device = mRenderer->getDevice();
593     HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, &SRV);
594
595     if (result == E_OUTOFMEMORY)
596     {
597         gl::error(GL_OUT_OF_MEMORY);
598     }
599     ASSERT(SUCCEEDED(result));
600
601     return SRV;
602 }
603
604 void TextureStorage11_2D::generateMipmap(int level)
605 {
606     invalidateSwizzleCacheLevel(level);
607
608     RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(level - 1));
609     RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(level));
610
611     generateMipmapLayer(source, dest);
612 }
613
614 ID3D11Resource *TextureStorage11_2D::getSwizzleTexture()
615 {
616     if (!mSwizzleTexture)
617     {
618         ID3D11Device *device = mRenderer->getDevice();
619
620         D3D11_TEXTURE2D_DESC desc;
621         desc.Width = mTextureWidth;
622         desc.Height = mTextureHeight;
623         desc.MipLevels = mMipLevels;
624         desc.ArraySize = 1;
625         desc.Format = mSwizzleTextureFormat;
626         desc.SampleDesc.Count = 1;
627         desc.SampleDesc.Quality = 0;
628         desc.Usage = D3D11_USAGE_DEFAULT;
629         desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
630         desc.CPUAccessFlags = 0;
631         desc.MiscFlags = 0;
632
633         HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture);
634
635         if (result == E_OUTOFMEMORY)
636         {
637             return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11Texture2D*>(NULL));
638         }
639         ASSERT(SUCCEEDED(result));
640     }
641
642     return mSwizzleTexture;
643 }
644
645 ID3D11RenderTargetView *TextureStorage11_2D::getSwizzleRenderTarget(int mipLevel)
646 {
647     if (mipLevel >= 0 && mipLevel < getLevelCount())
648     {
649         if (!mSwizzleRenderTargets[mipLevel])
650         {
651             ID3D11Resource *swizzleTexture = getSwizzleTexture();
652             if (!swizzleTexture)
653             {
654                 return NULL;
655             }
656
657             ID3D11Device *device = mRenderer->getDevice();
658
659             D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
660             rtvDesc.Format = mSwizzleRenderTargetFormat;
661             rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
662             rtvDesc.Texture2D.MipSlice = mTopLevel + mipLevel;
663
664             HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
665             if (result == E_OUTOFMEMORY)
666             {
667                 return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11RenderTargetView*>(NULL));
668             }
669             ASSERT(SUCCEEDED(result));
670         }
671
672         return mSwizzleRenderTargets[mipLevel];
673     }
674     else
675     {
676         return NULL;
677     }
678 }
679
680 unsigned int TextureStorage11_2D::getTextureLevelDepth(int mipLevel) const
681 {
682     return 1;
683 }
684
685 TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, GLenum internalformat, bool renderTarget, int size, int levels)
686     : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget))
687 {
688     mTexture = NULL;
689     mSwizzleTexture = NULL;
690
691     for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
692     {
693         mSwizzleRenderTargets[level] = NULL;
694         for (unsigned int face = 0; face < 6; face++)
695         {
696             mRenderTarget[face][level] = NULL;
697         }
698     }
699
700     const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
701     mTextureFormat = formatInfo.texFormat;
702     mShaderResourceFormat = formatInfo.srvFormat;
703     mDepthStencilFormat = formatInfo.dsvFormat;
704     mRenderTargetFormat = formatInfo.rtvFormat;
705     mSwizzleTextureFormat = formatInfo.swizzleTexFormat;
706     mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
707     mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
708
709     // if the size is not positive this should be treated as an incomplete texture
710     // we handle that here by skipping the d3d texture creation
711     if (size > 0)
712     {
713         // adjust size if needed for compressed textures
714         int height = size;
715         d3d11::MakeValidSize(false, mTextureFormat, &size, &height, &mTopLevel);
716
717         ID3D11Device *device = mRenderer->getDevice();
718
719         D3D11_TEXTURE2D_DESC desc;
720         desc.Width = size;
721         desc.Height = size;
722         desc.MipLevels = ((levels > 0) ? (mTopLevel + levels) : 0);
723         desc.ArraySize = 6;
724         desc.Format = mTextureFormat;
725         desc.SampleDesc.Count = 1;
726         desc.SampleDesc.Quality = 0;
727         desc.Usage = D3D11_USAGE_DEFAULT;
728         desc.BindFlags = getBindFlags();
729         desc.CPUAccessFlags = 0;
730         desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
731
732         HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
733
734         if (FAILED(result))
735         {
736             ASSERT(result == E_OUTOFMEMORY);
737             ERR("Creating image failed.");
738             gl::error(GL_OUT_OF_MEMORY);
739         }
740         else
741         {
742             mTexture->GetDesc(&desc);
743             mMipLevels = desc.MipLevels;
744             mTextureWidth = desc.Width;
745             mTextureHeight = desc.Height;
746             mTextureDepth = 1;
747         }
748     }
749 }
750
751 TextureStorage11_Cube::~TextureStorage11_Cube()
752 {
753     SafeRelease(mTexture);
754     SafeRelease(mSwizzleTexture);
755
756     for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
757     {
758         SafeRelease(mSwizzleRenderTargets[level]);
759         for (unsigned int face = 0; face < 6; face++)
760         {
761             SafeDelete(mRenderTarget[face][level]);
762         }
763     }
764 }
765
766 TextureStorage11_Cube *TextureStorage11_Cube::makeTextureStorage11_Cube(TextureStorage *storage)
767 {
768     ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_Cube*, storage));
769     return static_cast<TextureStorage11_Cube*>(storage);
770 }
771
772 ID3D11Resource *TextureStorage11_Cube::getResource() const
773 {
774     return mTexture;
775 }
776
777 RenderTarget *TextureStorage11_Cube::getRenderTargetFace(GLenum faceTarget, int level)
778 {
779     if (level >= 0 && level < getLevelCount())
780     {
781         int faceIndex = gl::TextureCubeMap::targetToLayerIndex(faceTarget);
782         if (!mRenderTarget[faceIndex][level])
783         {
784             ID3D11Device *device = mRenderer->getDevice();
785             HRESULT result;
786
787             D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
788             srvDesc.Format = mShaderResourceFormat;
789             srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; // Will be used with Texture2D sampler, not TextureCube
790             srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + level;
791             srvDesc.Texture2DArray.MipLevels = 1;
792             srvDesc.Texture2DArray.FirstArraySlice = faceIndex;
793             srvDesc.Texture2DArray.ArraySize = 1;
794
795             ID3D11ShaderResourceView *srv;
796             result = device->CreateShaderResourceView(mTexture, &srvDesc, &srv);
797
798             if (result == E_OUTOFMEMORY)
799             {
800                 return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
801             }
802             ASSERT(SUCCEEDED(result));
803
804             if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
805             {
806                 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
807                 rtvDesc.Format = mRenderTargetFormat;
808                 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
809                 rtvDesc.Texture2DArray.MipSlice = mTopLevel + level;
810                 rtvDesc.Texture2DArray.FirstArraySlice = faceIndex;
811                 rtvDesc.Texture2DArray.ArraySize = 1;
812
813                 ID3D11RenderTargetView *rtv;
814                 result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
815
816                 if (result == E_OUTOFMEMORY)
817                 {
818                     SafeRelease(srv);
819                     return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
820                 }
821                 ASSERT(SUCCEEDED(result));
822
823                 mRenderTarget[faceIndex][level] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1);
824
825                 // RenderTarget will take ownership of these resources
826                 SafeRelease(rtv);
827                 SafeRelease(srv);
828             }
829             else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN)
830             {
831                 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
832                 dsvDesc.Format = mDepthStencilFormat;
833                 dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
834                 dsvDesc.Flags = 0;
835                 dsvDesc.Texture2DArray.MipSlice = mTopLevel + level;
836                 dsvDesc.Texture2DArray.FirstArraySlice = faceIndex;
837                 dsvDesc.Texture2DArray.ArraySize = 1;
838
839                 ID3D11DepthStencilView *dsv;
840                 result = device->CreateDepthStencilView(mTexture, &dsvDesc, &dsv);
841
842                 if (result == E_OUTOFMEMORY)
843                 {
844                     SafeRelease(srv);
845                     return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
846                 }
847                 ASSERT(SUCCEEDED(result));
848
849                 mRenderTarget[faceIndex][level] = new RenderTarget11(mRenderer, dsv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1);
850
851                 // RenderTarget will take ownership of these resources
852                 SafeRelease(dsv);
853                 SafeRelease(srv);
854             }
855             else
856             {
857                 UNREACHABLE();
858             }
859         }
860
861         return mRenderTarget[faceIndex][level];
862     }
863     else
864     {
865         return NULL;
866     }
867 }
868
869 ID3D11ShaderResourceView *TextureStorage11_Cube::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture)
870 {
871     D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
872     srvDesc.Format = format;
873
874     // Unnormalized integer cube maps are not supported by DX11; we emulate them as an array of six 2D textures
875     const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(format);
876     if (dxgiFormatInfo.componentType == GL_INT || dxgiFormatInfo.componentType == GL_UNSIGNED_INT)
877     {
878         srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
879         srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel;
880         srvDesc.Texture2DArray.MipLevels = 1;
881         srvDesc.Texture2DArray.FirstArraySlice = 0;
882         srvDesc.Texture2DArray.ArraySize = 6;
883     }
884     else
885     {
886         srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
887         srvDesc.TextureCube.MipLevels = mipLevels;
888         srvDesc.TextureCube.MostDetailedMip = mTopLevel + baseLevel;
889     }
890
891     ID3D11ShaderResourceView *SRV = NULL;
892
893     ID3D11Device *device = mRenderer->getDevice();
894     HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, &SRV);
895
896     if (result == E_OUTOFMEMORY)
897     {
898         gl::error(GL_OUT_OF_MEMORY);
899     }
900     ASSERT(SUCCEEDED(result));
901
902     return SRV;
903 }
904
905 void TextureStorage11_Cube::generateMipmap(int faceIndex, int level)
906 {
907     invalidateSwizzleCacheLevel(level);
908
909     RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTargetFace(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level - 1));
910     RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTargetFace(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level));
911
912     generateMipmapLayer(source, dest);
913 }
914
915 ID3D11Resource *TextureStorage11_Cube::getSwizzleTexture()
916 {
917     if (!mSwizzleTexture)
918     {
919         ID3D11Device *device = mRenderer->getDevice();
920
921         D3D11_TEXTURE2D_DESC desc;
922         desc.Width = mTextureWidth;
923         desc.Height = mTextureHeight;
924         desc.MipLevels = mMipLevels;
925         desc.ArraySize = 6;
926         desc.Format = mSwizzleTextureFormat;
927         desc.SampleDesc.Count = 1;
928         desc.SampleDesc.Quality = 0;
929         desc.Usage = D3D11_USAGE_DEFAULT;
930         desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
931         desc.CPUAccessFlags = 0;
932         desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
933
934         HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture);
935
936         if (result == E_OUTOFMEMORY)
937         {
938             return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11Texture2D*>(NULL));
939         }
940         ASSERT(SUCCEEDED(result));
941     }
942
943     return mSwizzleTexture;
944 }
945
946 ID3D11RenderTargetView *TextureStorage11_Cube::getSwizzleRenderTarget(int mipLevel)
947 {
948     if (mipLevel >= 0 && mipLevel < getLevelCount())
949     {
950         if (!mSwizzleRenderTargets[mipLevel])
951         {
952             ID3D11Resource *swizzleTexture = getSwizzleTexture();
953             if (!swizzleTexture)
954             {
955                 return NULL;
956             }
957
958             ID3D11Device *device = mRenderer->getDevice();
959
960             D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
961             rtvDesc.Format = mSwizzleRenderTargetFormat;
962             rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
963             rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
964             rtvDesc.Texture2DArray.FirstArraySlice = 0;
965             rtvDesc.Texture2DArray.ArraySize = 6;
966
967             HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
968
969             if (result == E_OUTOFMEMORY)
970             {
971                 return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11RenderTargetView*>(NULL));
972             }
973             ASSERT(SUCCEEDED(result));
974         }
975
976         return mSwizzleRenderTargets[mipLevel];
977     }
978     else
979     {
980         return NULL;
981     }
982 }
983
984 unsigned int TextureStorage11_Cube::getTextureLevelDepth(int mipLevel) const
985 {
986     return 6;
987 }
988
989 TextureStorage11_3D::TextureStorage11_3D(Renderer *renderer, GLenum internalformat, bool renderTarget,
990                                          GLsizei width, GLsizei height, GLsizei depth, int levels)
991     : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget))
992 {
993     mTexture = NULL;
994     mSwizzleTexture = NULL;
995
996     for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
997     {
998         mLevelRenderTargets[i] = NULL;
999         mSwizzleRenderTargets[i] = NULL;
1000     }
1001
1002     const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
1003     mTextureFormat = formatInfo.texFormat;
1004     mShaderResourceFormat = formatInfo.srvFormat;
1005     mDepthStencilFormat = formatInfo.dsvFormat;
1006     mRenderTargetFormat = formatInfo.rtvFormat;
1007     mSwizzleTextureFormat = formatInfo.swizzleTexFormat;
1008     mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
1009     mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
1010
1011     // If the width, height or depth are not positive this should be treated as an incomplete texture
1012     // we handle that here by skipping the d3d texture creation
1013     if (width > 0 && height > 0 && depth > 0)
1014     {
1015         // adjust size if needed for compressed textures
1016         d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel);
1017
1018         ID3D11Device *device = mRenderer->getDevice();
1019
1020         D3D11_TEXTURE3D_DESC desc;
1021         desc.Width = width;
1022         desc.Height = height;
1023         desc.Depth = depth;
1024         desc.MipLevels = ((levels > 0) ? (mTopLevel + levels) : 0);
1025         desc.Format = mTextureFormat;
1026         desc.Usage = D3D11_USAGE_DEFAULT;
1027         desc.BindFlags = getBindFlags();
1028         desc.CPUAccessFlags = 0;
1029         desc.MiscFlags = 0;
1030
1031         HRESULT result = device->CreateTexture3D(&desc, NULL, &mTexture);
1032
1033         // this can happen from windows TDR
1034         if (d3d11::isDeviceLostError(result))
1035         {
1036             mRenderer->notifyDeviceLost();
1037             gl::error(GL_OUT_OF_MEMORY);
1038         }
1039         else if (FAILED(result))
1040         {
1041             ASSERT(result == E_OUTOFMEMORY);
1042             ERR("Creating image failed.");
1043             gl::error(GL_OUT_OF_MEMORY);
1044         }
1045         else
1046         {
1047             mTexture->GetDesc(&desc);
1048             mMipLevels = desc.MipLevels;
1049             mTextureWidth = desc.Width;
1050             mTextureHeight = desc.Height;
1051             mTextureDepth = desc.Depth;
1052         }
1053     }
1054 }
1055
1056 TextureStorage11_3D::~TextureStorage11_3D()
1057 {
1058     SafeRelease(mTexture);
1059     SafeRelease(mSwizzleTexture);
1060
1061     for (RenderTargetMap::iterator i = mLevelLayerRenderTargets.begin(); i != mLevelLayerRenderTargets.end(); i++)
1062     {
1063         SafeDelete(i->second);
1064     }
1065     mLevelLayerRenderTargets.clear();
1066
1067     for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
1068     {
1069         SafeDelete(mLevelRenderTargets[i]);
1070         SafeRelease(mSwizzleRenderTargets[i]);
1071     }
1072 }
1073
1074 TextureStorage11_3D *TextureStorage11_3D::makeTextureStorage11_3D(TextureStorage *storage)
1075 {
1076     ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_3D*, storage));
1077     return static_cast<TextureStorage11_3D*>(storage);
1078 }
1079
1080 ID3D11Resource *TextureStorage11_3D::getResource() const
1081 {
1082     return mTexture;
1083 }
1084
1085 ID3D11ShaderResourceView *TextureStorage11_3D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture)
1086 {
1087     D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
1088     srvDesc.Format = format;
1089     srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
1090     srvDesc.Texture3D.MostDetailedMip = baseLevel;
1091     srvDesc.Texture3D.MipLevels = mipLevels;
1092
1093     ID3D11ShaderResourceView *SRV = NULL;
1094
1095     ID3D11Device *device = mRenderer->getDevice();
1096     HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, &SRV);
1097
1098     if (result == E_OUTOFMEMORY)
1099     {
1100         gl::error(GL_OUT_OF_MEMORY);
1101     }
1102     ASSERT(SUCCEEDED(result));
1103
1104     return SRV;
1105 }
1106
1107 RenderTarget *TextureStorage11_3D::getRenderTarget(int mipLevel)
1108 {
1109     if (mipLevel >= 0 && mipLevel < getLevelCount())
1110     {
1111         if (!mLevelRenderTargets[mipLevel])
1112         {
1113             ID3D11ShaderResourceView *srv = getSRVLevel(mipLevel);
1114             if (!srv)
1115             {
1116                 return NULL;
1117             }
1118
1119             if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
1120             {
1121                 ID3D11Device *device = mRenderer->getDevice();
1122
1123                 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
1124                 rtvDesc.Format = mRenderTargetFormat;
1125                 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
1126                 rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
1127                 rtvDesc.Texture3D.FirstWSlice = 0;
1128                 rtvDesc.Texture3D.WSize = -1;
1129
1130                 ID3D11RenderTargetView *rtv;
1131                 HRESULT result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
1132
1133                 if (result == E_OUTOFMEMORY)
1134                 {
1135                     SafeRelease(srv);
1136                     return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
1137                 }
1138                 ASSERT(SUCCEEDED(result));
1139
1140                 mLevelRenderTargets[mipLevel] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), getLevelDepth(mipLevel));
1141
1142                 // RenderTarget will take ownership of these resources
1143                 SafeRelease(rtv);
1144             }
1145             else
1146             {
1147                 UNREACHABLE();
1148             }
1149         }
1150
1151         return mLevelRenderTargets[mipLevel];
1152     }
1153     else
1154     {
1155         return NULL;
1156     }
1157 }
1158
1159 RenderTarget *TextureStorage11_3D::getRenderTargetLayer(int mipLevel, int layer)
1160 {
1161     if (mipLevel >= 0 && mipLevel < getLevelCount())
1162     {
1163         LevelLayerKey key(mipLevel, layer);
1164         if (mLevelLayerRenderTargets.find(key) == mLevelLayerRenderTargets.end())
1165         {
1166             ID3D11Device *device = mRenderer->getDevice();
1167             HRESULT result;
1168
1169             // TODO, what kind of SRV is expected here?
1170             ID3D11ShaderResourceView *srv = NULL;
1171
1172             if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
1173             {
1174                 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
1175                 rtvDesc.Format = mRenderTargetFormat;
1176                 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
1177                 rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
1178                 rtvDesc.Texture3D.FirstWSlice = layer;
1179                 rtvDesc.Texture3D.WSize = 1;
1180
1181                 ID3D11RenderTargetView *rtv;
1182                 result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
1183
1184                 if (result == E_OUTOFMEMORY)
1185                 {
1186                     SafeRelease(srv);
1187                     return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
1188                 }
1189                 ASSERT(SUCCEEDED(result));
1190
1191                 mLevelLayerRenderTargets[key] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1);
1192
1193                 // RenderTarget will take ownership of these resources
1194                 SafeRelease(rtv);
1195                 SafeRelease(srv);
1196             }
1197             else
1198             {
1199                 UNREACHABLE();
1200             }
1201         }
1202
1203         return mLevelLayerRenderTargets[key];
1204     }
1205     else
1206     {
1207         return NULL;
1208     }
1209 }
1210
1211 void TextureStorage11_3D::generateMipmap(int level)
1212 {
1213     invalidateSwizzleCacheLevel(level);
1214
1215     RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(level - 1));
1216     RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(level));
1217
1218     generateMipmapLayer(source, dest);
1219 }
1220
1221 ID3D11Resource *TextureStorage11_3D::getSwizzleTexture()
1222 {
1223     if (!mSwizzleTexture)
1224     {
1225         ID3D11Device *device = mRenderer->getDevice();
1226
1227         D3D11_TEXTURE3D_DESC desc;
1228         desc.Width = mTextureWidth;
1229         desc.Height = mTextureHeight;
1230         desc.Depth = mTextureDepth;
1231         desc.MipLevels = mMipLevels;
1232         desc.Format = mSwizzleTextureFormat;
1233         desc.Usage = D3D11_USAGE_DEFAULT;
1234         desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
1235         desc.CPUAccessFlags = 0;
1236         desc.MiscFlags = 0;
1237
1238         HRESULT result = device->CreateTexture3D(&desc, NULL, &mSwizzleTexture);
1239
1240         if (result == E_OUTOFMEMORY)
1241         {
1242             return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11Texture3D*>(NULL));
1243         }
1244         ASSERT(SUCCEEDED(result));
1245     }
1246
1247     return mSwizzleTexture;
1248 }
1249
1250 ID3D11RenderTargetView *TextureStorage11_3D::getSwizzleRenderTarget(int mipLevel)
1251 {
1252     if (mipLevel >= 0 && mipLevel < getLevelCount())
1253     {
1254         if (!mSwizzleRenderTargets[mipLevel])
1255         {
1256             ID3D11Resource *swizzleTexture = getSwizzleTexture();
1257             if (!swizzleTexture)
1258             {
1259                 return NULL;
1260             }
1261
1262             ID3D11Device *device = mRenderer->getDevice();
1263
1264             D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
1265             rtvDesc.Format = mSwizzleRenderTargetFormat;
1266             rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
1267             rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
1268             rtvDesc.Texture3D.FirstWSlice = 0;
1269             rtvDesc.Texture3D.WSize = -1;
1270
1271             HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
1272
1273             if (result == E_OUTOFMEMORY)
1274             {
1275                 return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11RenderTargetView*>(NULL));
1276             }
1277             ASSERT(SUCCEEDED(result));
1278         }
1279
1280         return mSwizzleRenderTargets[mipLevel];
1281     }
1282     else
1283     {
1284         return NULL;
1285     }
1286 }
1287
1288 unsigned int TextureStorage11_3D::getTextureLevelDepth(int mipLevel) const
1289 {
1290     return std::max(mTextureDepth >> mipLevel, 1U);
1291 }
1292
1293
1294 TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer *renderer, GLenum internalformat, bool renderTarget,
1295                                                    GLsizei width, GLsizei height, GLsizei depth, int levels)
1296     : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget))
1297 {
1298     mTexture = NULL;
1299     mSwizzleTexture = NULL;
1300
1301     for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
1302     {
1303         mSwizzleRenderTargets[level] = NULL;
1304     }
1305
1306     const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
1307     mTextureFormat = formatInfo.texFormat;
1308     mShaderResourceFormat = formatInfo.srvFormat;
1309     mDepthStencilFormat = formatInfo.dsvFormat;
1310     mRenderTargetFormat = formatInfo.rtvFormat;
1311     mSwizzleTextureFormat = formatInfo.swizzleTexFormat;
1312     mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
1313     mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
1314
1315     // if the width, height or depth is not positive this should be treated as an incomplete texture
1316     // we handle that here by skipping the d3d texture creation
1317     if (width > 0 && height > 0 && depth > 0)
1318     {
1319         // adjust size if needed for compressed textures
1320         d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel);
1321
1322         ID3D11Device *device = mRenderer->getDevice();
1323
1324         D3D11_TEXTURE2D_DESC desc;
1325         desc.Width = width;
1326         desc.Height = height;
1327         desc.MipLevels = ((levels > 0) ? (mTopLevel + levels) : 0);
1328         desc.ArraySize = depth;
1329         desc.Format = mTextureFormat;
1330         desc.SampleDesc.Count = 1;
1331         desc.SampleDesc.Quality = 0;
1332         desc.Usage = D3D11_USAGE_DEFAULT;
1333         desc.BindFlags = getBindFlags();
1334         desc.CPUAccessFlags = 0;
1335         desc.MiscFlags = 0;
1336
1337         HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
1338
1339         // this can happen from windows TDR
1340         if (d3d11::isDeviceLostError(result))
1341         {
1342             mRenderer->notifyDeviceLost();
1343             gl::error(GL_OUT_OF_MEMORY);
1344         }
1345         else if (FAILED(result))
1346         {
1347             ASSERT(result == E_OUTOFMEMORY);
1348             ERR("Creating image failed.");
1349             gl::error(GL_OUT_OF_MEMORY);
1350         }
1351         else
1352         {
1353             mTexture->GetDesc(&desc);
1354             mMipLevels = desc.MipLevels;
1355             mTextureWidth = desc.Width;
1356             mTextureHeight = desc.Height;
1357             mTextureDepth = desc.ArraySize;
1358         }
1359     }
1360 }
1361
1362 TextureStorage11_2DArray::~TextureStorage11_2DArray()
1363 {
1364     SafeRelease(mTexture);
1365     SafeRelease(mSwizzleTexture);
1366
1367     for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
1368     {
1369         SafeRelease(mSwizzleRenderTargets[level]);
1370     }
1371
1372     for (RenderTargetMap::iterator i = mRenderTargets.begin(); i != mRenderTargets.end(); i++)
1373     {
1374         SafeDelete(i->second);
1375     }
1376     mRenderTargets.clear();
1377 }
1378
1379 TextureStorage11_2DArray *TextureStorage11_2DArray::makeTextureStorage11_2DArray(TextureStorage *storage)
1380 {
1381     ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_2DArray*, storage));
1382     return static_cast<TextureStorage11_2DArray*>(storage);
1383 }
1384
1385 ID3D11Resource *TextureStorage11_2DArray::getResource() const
1386 {
1387     return mTexture;
1388 }
1389
1390 ID3D11ShaderResourceView *TextureStorage11_2DArray::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture)
1391 {
1392     D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
1393     srvDesc.Format = format;
1394     srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
1395     srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel;
1396     srvDesc.Texture2DArray.MipLevels = mipLevels;
1397     srvDesc.Texture2DArray.FirstArraySlice = 0;
1398     srvDesc.Texture2DArray.ArraySize = mTextureDepth;
1399
1400     ID3D11ShaderResourceView *SRV = NULL;
1401
1402     ID3D11Device *device = mRenderer->getDevice();
1403     HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, &SRV);
1404
1405     if (result == E_OUTOFMEMORY)
1406     {
1407         gl::error(GL_OUT_OF_MEMORY);
1408     }
1409     ASSERT(SUCCEEDED(result));
1410
1411     return SRV;
1412 }
1413
1414 RenderTarget *TextureStorage11_2DArray::getRenderTargetLayer(int mipLevel, int layer)
1415 {
1416     if (mipLevel >= 0 && mipLevel < getLevelCount())
1417     {
1418         LevelLayerKey key(mipLevel, layer);
1419         if (mRenderTargets.find(key) == mRenderTargets.end())
1420         {
1421             ID3D11Device *device = mRenderer->getDevice();
1422             HRESULT result;
1423
1424             D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
1425             srvDesc.Format = mShaderResourceFormat;
1426             srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
1427             srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + mipLevel;
1428             srvDesc.Texture2DArray.MipLevels = 1;
1429             srvDesc.Texture2DArray.FirstArraySlice = layer;
1430             srvDesc.Texture2DArray.ArraySize = 1;
1431
1432             ID3D11ShaderResourceView *srv;
1433             result = device->CreateShaderResourceView(mTexture, &srvDesc, &srv);
1434
1435             if (result == E_OUTOFMEMORY)
1436             {
1437                 return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
1438             }
1439             ASSERT(SUCCEEDED(result));
1440
1441             if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
1442             {
1443                 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
1444                 rtvDesc.Format = mRenderTargetFormat;
1445                 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
1446                 rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
1447                 rtvDesc.Texture2DArray.FirstArraySlice = layer;
1448                 rtvDesc.Texture2DArray.ArraySize = 1;
1449
1450                 ID3D11RenderTargetView *rtv;
1451                 result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
1452
1453                 if (result == E_OUTOFMEMORY)
1454                 {
1455                     SafeRelease(srv);
1456                     return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
1457                 }
1458                 ASSERT(SUCCEEDED(result));
1459
1460                 mRenderTargets[key] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1);
1461
1462                 // RenderTarget will take ownership of these resources
1463                 SafeRelease(rtv);
1464                 SafeRelease(srv);
1465             }
1466             else
1467             {
1468                 UNREACHABLE();
1469             }
1470         }
1471
1472         return mRenderTargets[key];
1473     }
1474     else
1475     {
1476         return NULL;
1477     }
1478 }
1479
1480 void TextureStorage11_2DArray::generateMipmap(int level)
1481 {
1482     invalidateSwizzleCacheLevel(level);
1483     for (unsigned int layer = 0; layer < mTextureDepth; layer++)
1484     {
1485         RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTargetLayer(level - 1, layer));
1486         RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTargetLayer(level, layer));
1487
1488         generateMipmapLayer(source, dest);
1489     }
1490 }
1491
1492 ID3D11Resource *TextureStorage11_2DArray::getSwizzleTexture()
1493 {
1494     if (!mSwizzleTexture)
1495     {
1496         ID3D11Device *device = mRenderer->getDevice();
1497
1498         D3D11_TEXTURE2D_DESC desc;
1499         desc.Width = mTextureWidth;
1500         desc.Height = mTextureHeight;
1501         desc.MipLevels = mMipLevels;
1502         desc.ArraySize = mTextureDepth;
1503         desc.Format = mSwizzleTextureFormat;
1504         desc.SampleDesc.Count = 1;
1505         desc.SampleDesc.Quality = 0;
1506         desc.Usage = D3D11_USAGE_DEFAULT;
1507         desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
1508         desc.CPUAccessFlags = 0;
1509         desc.MiscFlags = 0;
1510
1511         HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture);
1512
1513         if (result == E_OUTOFMEMORY)
1514         {
1515             return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11Texture2D*>(NULL));
1516         }
1517         ASSERT(SUCCEEDED(result));
1518     }
1519
1520     return mSwizzleTexture;
1521 }
1522
1523 ID3D11RenderTargetView *TextureStorage11_2DArray::getSwizzleRenderTarget(int mipLevel)
1524 {
1525     if (mipLevel >= 0 && mipLevel < getLevelCount())
1526     {
1527         if (!mSwizzleRenderTargets[mipLevel])
1528         {
1529             ID3D11Resource *swizzleTexture = getSwizzleTexture();
1530             if (!swizzleTexture)
1531             {
1532                 return NULL;
1533             }
1534
1535             ID3D11Device *device = mRenderer->getDevice();
1536
1537             D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
1538             rtvDesc.Format = mSwizzleRenderTargetFormat;
1539             rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
1540             rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
1541             rtvDesc.Texture2DArray.FirstArraySlice = 0;
1542             rtvDesc.Texture2DArray.ArraySize = mTextureDepth;
1543
1544             HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
1545
1546             if (result == E_OUTOFMEMORY)
1547             {
1548                 return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11RenderTargetView*>(NULL));
1549             }
1550             ASSERT(SUCCEEDED(result));
1551         }
1552
1553         return mSwizzleRenderTargets[mipLevel];
1554     }
1555     else
1556     {
1557         return NULL;
1558     }
1559 }
1560
1561 unsigned int TextureStorage11_2DArray::getTextureLevelDepth(int mipLevel) const
1562 {
1563     return mTextureDepth;
1564 }
1565
1566 }