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