gfx/angle/src/libGLESv2/renderer/TextureStorage11.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 #include "precompiled.h"
     2 //
     3 // Copyright (c) 2012 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 //
     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.
    11 #include "libGLESv2/renderer/TextureStorage11.h"
    13 #include "libGLESv2/renderer/Renderer11.h"
    14 #include "libGLESv2/renderer/RenderTarget11.h"
    15 #include "libGLESv2/renderer/SwapChain11.h"
    16 #include "libGLESv2/renderer/renderer11_utils.h"
    18 #include "libGLESv2/utilities.h"
    19 #include "libGLESv2/main.h"
    21 namespace rx
    22 {
    24 TextureStorage11::TextureStorage11(Renderer *renderer, UINT bindFlags)
    25     : mBindFlags(bindFlags),
    26       mLodOffset(0),
    27       mMipLevels(0),
    28       mTexture(NULL),
    29       mTextureFormat(DXGI_FORMAT_UNKNOWN),
    30       mShaderResourceFormat(DXGI_FORMAT_UNKNOWN),
    31       mRenderTargetFormat(DXGI_FORMAT_UNKNOWN),
    32       mDepthStencilFormat(DXGI_FORMAT_UNKNOWN),
    33       mSRV(NULL),
    34       mTextureWidth(0),
    35       mTextureHeight(0)
    36 {
    37     mRenderer = Renderer11::makeRenderer11(renderer);
    38 }
    40 TextureStorage11::~TextureStorage11()
    41 {
    42 }
    44 TextureStorage11 *TextureStorage11::makeTextureStorage11(TextureStorage *storage)
    45 {
    46     ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11*, storage));
    47     return static_cast<TextureStorage11*>(storage);
    48 }
    50 DWORD TextureStorage11::GetTextureBindFlags(DXGI_FORMAT format, GLenum glusage, bool forceRenderable)
    51 {
    52     UINT bindFlags = D3D11_BIND_SHADER_RESOURCE;
    54     if (d3d11::IsDepthStencilFormat(format))
    55     {
    56         bindFlags |= D3D11_BIND_DEPTH_STENCIL;
    57     }
    58     else if(forceRenderable || (TextureStorage11::IsTextureFormatRenderable(format) && (glusage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE)))
    59     {
    60         bindFlags |= D3D11_BIND_RENDER_TARGET;
    61     }
    62     return bindFlags;
    63 }
    65 bool TextureStorage11::IsTextureFormatRenderable(DXGI_FORMAT format)
    66 {
    67     switch(format)
    68     {
    69       case DXGI_FORMAT_R8G8B8A8_UNORM:
    70       case DXGI_FORMAT_A8_UNORM:
    71       case DXGI_FORMAT_R32G32B32A32_FLOAT:
    72       case DXGI_FORMAT_R16G16B16A16_FLOAT:
    73       case DXGI_FORMAT_B8G8R8A8_UNORM:
    74       case DXGI_FORMAT_R8_UNORM:
    75       case DXGI_FORMAT_R8G8_UNORM:
    76       case DXGI_FORMAT_R16_FLOAT:
    77       case DXGI_FORMAT_R16G16_FLOAT:
    78         return true;
    79       case DXGI_FORMAT_BC1_UNORM:
    80       case DXGI_FORMAT_BC2_UNORM: 
    81       case DXGI_FORMAT_BC3_UNORM:
    82       case DXGI_FORMAT_R32G32B32_FLOAT: // not renderable on all devices
    83         return false;
    84       default:
    85         UNREACHABLE();
    86         return false;
    87     }
    88 }
    90 UINT TextureStorage11::getBindFlags() const
    91 {
    92     return mBindFlags;
    93 }
    95 ID3D11Texture2D *TextureStorage11::getBaseTexture() const
    96 {
    97     return mTexture;
    98 }
   100 int TextureStorage11::getLodOffset() const
   101 {
   102     return mLodOffset;
   103 }
   105 bool TextureStorage11::isRenderTarget() const
   106 {
   107     return (mBindFlags & (D3D11_BIND_RENDER_TARGET | D3D11_BIND_DEPTH_STENCIL)) != 0;
   108 }
   110 bool TextureStorage11::isManaged() const
   111 {
   112     return false;
   113 }
   115 int TextureStorage11::levelCount()
   116 {
   117     int levels = 0;
   118     if (getBaseTexture())
   119     {
   120         levels = mMipLevels - getLodOffset();
   121     }
   122     return levels;
   123 }
   125 UINT TextureStorage11::getSubresourceIndex(int level, int faceIndex)
   126 {
   127     UINT index = 0;
   128     if (getBaseTexture())
   129     {
   130         index = D3D11CalcSubresource(level, faceIndex, mMipLevels);
   131     }
   132     return index;
   133 }
   135 bool TextureStorage11::updateSubresourceLevel(ID3D11Texture2D *srcTexture, unsigned int sourceSubresource,
   136                                               int level, int face, GLint xoffset, GLint yoffset,
   137                                               GLsizei width, GLsizei height)
   138 {
   139     if (srcTexture)
   140     {
   141         // Round up the width and height to the nearest multiple of dimension alignment
   142         unsigned int dimensionAlignment = d3d11::GetTextureFormatDimensionAlignment(mTextureFormat);
   143         width = width + dimensionAlignment - 1 - (width - 1) % dimensionAlignment;
   144         height = height + dimensionAlignment - 1 - (height - 1) % dimensionAlignment;
   146         D3D11_BOX srcBox;
   147         srcBox.left = xoffset;
   148         srcBox.top = yoffset;
   149         srcBox.right = xoffset + width;
   150         srcBox.bottom = yoffset + height;
   151         srcBox.front = 0;
   152         srcBox.back = 1;
   154         ID3D11DeviceContext *context = mRenderer->getDeviceContext();
   156         ASSERT(getBaseTexture());
   157         context->CopySubresourceRegion(getBaseTexture(), getSubresourceIndex(level + mLodOffset, face),
   158                                        xoffset, yoffset, 0, srcTexture, sourceSubresource, &srcBox);
   159         return true;
   160     }
   162     return false;
   163 }
   165 void TextureStorage11::generateMipmapLayer(RenderTarget11 *source, RenderTarget11 *dest)
   166 {
   167     if (source && dest)
   168     {
   169         ID3D11ShaderResourceView *sourceSRV = source->getShaderResourceView();
   170         ID3D11RenderTargetView *destRTV = dest->getRenderTargetView();
   172         if (sourceSRV && destRTV)
   173         {
   174             gl::Rectangle sourceArea;
   175             sourceArea.x = 0;
   176             sourceArea.y = 0;
   177             sourceArea.width = source->getWidth();
   178             sourceArea.height = source->getHeight();
   180             gl::Rectangle destArea;
   181             destArea.x = 0;
   182             destArea.y = 0;
   183             destArea.width = dest->getWidth();
   184             destArea.height = dest->getHeight();
   186             mRenderer->copyTexture(sourceSRV, sourceArea, source->getWidth(), source->getHeight(),
   187                                    destRTV, destArea, dest->getWidth(), dest->getHeight(),
   188                                    GL_RGBA);
   189         }
   190     }
   191 }
   193 TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapchain)
   194     : TextureStorage11(renderer, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE)
   195 {
   196     mTexture = swapchain->getOffscreenTexture();
   197     mSRV = swapchain->getRenderTargetShaderResource();
   199     for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
   200     {
   201         mRenderTarget[i] = NULL;
   202     }
   204     D3D11_TEXTURE2D_DESC texDesc;
   205     mTexture->GetDesc(&texDesc);
   206     mMipLevels = texDesc.MipLevels;
   207     mTextureFormat = texDesc.Format;
   208     mTextureWidth = texDesc.Width;
   209     mTextureHeight = texDesc.Height;
   211     D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
   212     mSRV->GetDesc(&srvDesc);
   213     mShaderResourceFormat = srvDesc.Format;
   215     ID3D11RenderTargetView* offscreenRTV = swapchain->getRenderTarget();
   216     D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
   217     offscreenRTV->GetDesc(&rtvDesc);
   218     mRenderTargetFormat = rtvDesc.Format;
   219     offscreenRTV->Release();
   221     mDepthStencilFormat = DXGI_FORMAT_UNKNOWN;
   222 }
   224 TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height)
   225     : TextureStorage11(renderer, GetTextureBindFlags(gl_d3d11::ConvertTextureFormat(internalformat), usage, forceRenderable))
   226 {
   227     for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
   228     {
   229         mRenderTarget[i] = NULL;
   230     }
   232     DXGI_FORMAT convertedFormat = gl_d3d11::ConvertTextureFormat(internalformat);
   233     if (d3d11::IsDepthStencilFormat(convertedFormat))
   234     {
   235         mTextureFormat = d3d11::GetDepthTextureFormat(convertedFormat);
   236         mShaderResourceFormat = d3d11::GetDepthShaderResourceFormat(convertedFormat);
   237         mDepthStencilFormat = convertedFormat;
   238         mRenderTargetFormat = DXGI_FORMAT_UNKNOWN;
   239     }
   240     else
   241     {
   242         mTextureFormat = convertedFormat;
   243         mShaderResourceFormat = convertedFormat;
   244         mDepthStencilFormat = DXGI_FORMAT_UNKNOWN;
   245         mRenderTargetFormat = convertedFormat;
   246     }
   248     // if the width or height is not positive this should be treated as an incomplete texture
   249     // we handle that here by skipping the d3d texture creation
   250     if (width > 0 && height > 0)
   251     {
   252         // adjust size if needed for compressed textures
   253         gl::MakeValidSize(false, gl::IsCompressed(internalformat), &width, &height, &mLodOffset);
   255         ID3D11Device *device = mRenderer->getDevice();
   257         D3D11_TEXTURE2D_DESC desc;
   258         desc.Width = width;      // Compressed texture size constraints?
   259         desc.Height = height;
   260         desc.MipLevels = (levels > 0) ? levels + mLodOffset : 0;
   261         desc.ArraySize = 1;
   262         desc.Format = mTextureFormat;
   263         desc.SampleDesc.Count = 1;
   264         desc.SampleDesc.Quality = 0;
   265         desc.Usage = D3D11_USAGE_DEFAULT;
   266         desc.BindFlags = getBindFlags();
   267         desc.CPUAccessFlags = 0;
   268         desc.MiscFlags = 0;
   270         HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
   272         // this can happen from windows TDR
   273         if (d3d11::isDeviceLostError(result))
   274         {
   275             mRenderer->notifyDeviceLost();
   276             gl::error(GL_OUT_OF_MEMORY);
   277         }
   278         else if (FAILED(result))
   279         {
   280             ASSERT(result == E_OUTOFMEMORY);
   281             ERR("Creating image failed.");
   282             gl::error(GL_OUT_OF_MEMORY);
   283         }
   284         else
   285         {
   286             mTexture->GetDesc(&desc);
   287             mMipLevels = desc.MipLevels;
   288             mTextureWidth = desc.Width;
   289             mTextureHeight = desc.Height;
   290         }
   291     }
   292 }
   294 TextureStorage11_2D::~TextureStorage11_2D()
   295 {
   296     if (mTexture)
   297     {
   298         mTexture->Release();
   299         mTexture = NULL;
   300     }
   302     if (mSRV)
   303     {
   304         mSRV->Release();
   305         mSRV = NULL;
   306     }
   308     for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
   309     {
   310         delete mRenderTarget[i];
   311         mRenderTarget[i] = NULL;
   312     }
   313 }
   315 TextureStorage11_2D *TextureStorage11_2D::makeTextureStorage11_2D(TextureStorage *storage)
   316 {
   317     ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_2D*, storage));
   318     return static_cast<TextureStorage11_2D*>(storage);
   319 }
   321 RenderTarget *TextureStorage11_2D::getRenderTarget(int level)
   322 {
   323     if (level >= 0 && level < static_cast<int>(mMipLevels))
   324     {
   325         if (!mRenderTarget[level])
   326         {
   327             ID3D11Device *device = mRenderer->getDevice();
   328             HRESULT result;
   330             D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
   331             srvDesc.Format = mShaderResourceFormat;
   332             srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
   333             srvDesc.Texture2D.MostDetailedMip = level;
   334             srvDesc.Texture2D.MipLevels = 1;
   336             ID3D11ShaderResourceView *srv;
   337             result = device->CreateShaderResourceView(mTexture, &srvDesc, &srv);
   339             if (result == E_OUTOFMEMORY)
   340             {
   341                 return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
   342             }
   343             ASSERT(SUCCEEDED(result));
   345             if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
   346             {
   347                 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
   348                 rtvDesc.Format = mRenderTargetFormat;
   349                 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
   350                 rtvDesc.Texture2D.MipSlice = level;
   352                 ID3D11RenderTargetView *rtv;
   353                 result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
   355                 if (result == E_OUTOFMEMORY)
   356                 {
   357                     srv->Release();
   358                     return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
   359                 }
   360                 ASSERT(SUCCEEDED(result));
   362                 // RenderTarget11 expects to be the owner of the resources it is given but TextureStorage11
   363                 // also needs to keep a reference to the texture.
   364                 mTexture->AddRef();
   366                 mRenderTarget[level] = new RenderTarget11(mRenderer, rtv, mTexture, srv,
   367                                                           std::max(mTextureWidth >> level, 1U),
   368                                                           std::max(mTextureHeight >> level, 1U));
   369             }
   370             else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN)
   371             {
   372                 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
   373                 dsvDesc.Format = mDepthStencilFormat;
   374                 dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
   375                 dsvDesc.Texture2D.MipSlice = level;
   376                 dsvDesc.Flags = 0;
   378                 ID3D11DepthStencilView *dsv;
   379                 result = device->CreateDepthStencilView(mTexture, &dsvDesc, &dsv);
   381                 if (result == E_OUTOFMEMORY)
   382                 {
   383                     srv->Release();
   384                     return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
   385                 }
   386                 ASSERT(SUCCEEDED(result));
   388                 // RenderTarget11 expects to be the owner of the resources it is given but TextureStorage11
   389                 // also needs to keep a reference to the texture.
   390                 mTexture->AddRef();
   392                 mRenderTarget[level] = new RenderTarget11(mRenderer, dsv, mTexture, srv,
   393                                                           std::max(mTextureWidth >> level, 1U),
   394                                                           std::max(mTextureHeight >> level, 1U));
   395             }
   396             else
   397             {
   398                 UNREACHABLE();
   399             }
   400         }
   402         return mRenderTarget[level];
   403     }
   404     else
   405     {
   406         return NULL;
   407     }
   408 }
   410 ID3D11ShaderResourceView *TextureStorage11_2D::getSRV()
   411 {
   412     if (!mSRV)
   413     {
   414         ID3D11Device *device = mRenderer->getDevice();
   416         D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
   417         srvDesc.Format = mShaderResourceFormat;
   418         srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
   419         srvDesc.Texture2D.MipLevels = (mMipLevels == 0 ? -1 : mMipLevels);
   420         srvDesc.Texture2D.MostDetailedMip = 0;
   422         HRESULT result = device->CreateShaderResourceView(mTexture, &srvDesc, &mSRV);
   424         if (result == E_OUTOFMEMORY)
   425         {
   426             return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11ShaderResourceView*>(NULL));
   427         }
   428         ASSERT(SUCCEEDED(result));
   429     }
   431     return mSRV;
   432 }
   434 void TextureStorage11_2D::generateMipmap(int level)
   435 {
   436     RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(level - 1));
   437     RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(level));
   439     generateMipmapLayer(source, dest);
   440 }
   442 TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size)
   443     : TextureStorage11(renderer, GetTextureBindFlags(gl_d3d11::ConvertTextureFormat(internalformat), usage, forceRenderable))
   444 {
   445     for (unsigned int i = 0; i < 6; i++)
   446     {
   447         for (unsigned int j = 0; j < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; j++)
   448         {
   449             mRenderTarget[i][j] = NULL;
   450         }
   451     }
   453     DXGI_FORMAT convertedFormat = gl_d3d11::ConvertTextureFormat(internalformat);
   454     if (d3d11::IsDepthStencilFormat(convertedFormat))
   455     {
   456         mTextureFormat = d3d11::GetDepthTextureFormat(convertedFormat);
   457         mShaderResourceFormat = d3d11::GetDepthShaderResourceFormat(convertedFormat);
   458         mDepthStencilFormat = convertedFormat;
   459         mRenderTargetFormat = DXGI_FORMAT_UNKNOWN;
   460     }
   461     else
   462     {
   463         mTextureFormat = convertedFormat;
   464         mShaderResourceFormat = convertedFormat;
   465         mDepthStencilFormat = DXGI_FORMAT_UNKNOWN;
   466         mRenderTargetFormat = convertedFormat;
   467     }
   469     // if the size is not positive this should be treated as an incomplete texture
   470     // we handle that here by skipping the d3d texture creation
   471     if (size > 0)
   472     {
   473         // adjust size if needed for compressed textures
   474         int height = size;
   475         gl::MakeValidSize(false, gl::IsCompressed(internalformat), &size, &height, &mLodOffset);
   477         ID3D11Device *device = mRenderer->getDevice();
   479         D3D11_TEXTURE2D_DESC desc;
   480         desc.Width = size;
   481         desc.Height = size;
   482         desc.MipLevels = (levels > 0) ? levels + mLodOffset : 0;
   483         desc.ArraySize = 6;
   484         desc.Format = mTextureFormat;
   485         desc.SampleDesc.Count = 1;
   486         desc.SampleDesc.Quality = 0;
   487         desc.Usage = D3D11_USAGE_DEFAULT;
   488         desc.BindFlags = getBindFlags();
   489         desc.CPUAccessFlags = 0;
   490         desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
   492         HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
   494         if (FAILED(result))
   495         {
   496             ASSERT(result == E_OUTOFMEMORY);
   497             ERR("Creating image failed.");
   498             gl::error(GL_OUT_OF_MEMORY);
   499         }
   500         else
   501         {
   502             mTexture->GetDesc(&desc);
   503             mMipLevels = desc.MipLevels;
   504             mTextureWidth = desc.Width;
   505             mTextureHeight = desc.Height;
   506         }
   507     }
   508 }
   510 TextureStorage11_Cube::~TextureStorage11_Cube()
   511 {
   512     if (mTexture)
   513     {
   514         mTexture->Release();
   515         mTexture = NULL;
   516     }
   518     if (mSRV)
   519     {
   520         mSRV->Release();
   521         mSRV = NULL;
   522     }
   524     for (unsigned int i = 0; i < 6; i++)
   525     {
   526         for (unsigned int j = 0; j < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; j++)
   527         {
   528             delete mRenderTarget[i][j];
   529             mRenderTarget[i][j] = NULL;
   530         }
   531     }
   532 }
   534 TextureStorage11_Cube *TextureStorage11_Cube::makeTextureStorage11_Cube(TextureStorage *storage)
   535 {
   536     ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_Cube*, storage));
   537     return static_cast<TextureStorage11_Cube*>(storage);
   538 }
   540 RenderTarget *TextureStorage11_Cube::getRenderTarget(GLenum faceTarget, int level)
   541 {
   542     unsigned int faceIdx = gl::TextureCubeMap::faceIndex(faceTarget);
   543     if (level >= 0 && level < static_cast<int>(mMipLevels))
   544     {
   545         if (!mRenderTarget[faceIdx][level])
   546         {
   547             ID3D11Device *device = mRenderer->getDevice();
   548             HRESULT result;
   550             D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
   551             srvDesc.Format = mShaderResourceFormat;
   552             srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
   553             srvDesc.Texture2DArray.MostDetailedMip = level;
   554             srvDesc.Texture2DArray.MipLevels = 1;
   555             srvDesc.Texture2DArray.FirstArraySlice = faceIdx;
   556             srvDesc.Texture2DArray.ArraySize = 1;
   558             ID3D11ShaderResourceView *srv;
   559             result = device->CreateShaderResourceView(mTexture, &srvDesc, &srv);
   561             if (result == E_OUTOFMEMORY)
   562             {
   563                 return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
   564             }
   565             ASSERT(SUCCEEDED(result));
   567             if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
   568             {
   569                 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
   570                 rtvDesc.Format = mRenderTargetFormat;
   571                 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
   572                 rtvDesc.Texture2DArray.MipSlice = level;
   573                 rtvDesc.Texture2DArray.FirstArraySlice = faceIdx;
   574                 rtvDesc.Texture2DArray.ArraySize = 1;
   576                 ID3D11RenderTargetView *rtv;
   577                 result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
   579                 if (result == E_OUTOFMEMORY)
   580                 {
   581                     srv->Release();
   582                     return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
   583                 }
   584                 ASSERT(SUCCEEDED(result));
   586                 // RenderTarget11 expects to be the owner of the resources it is given but TextureStorage11
   587                 // also needs to keep a reference to the texture.
   588                 mTexture->AddRef();
   590                 mRenderTarget[faceIdx][level] = new RenderTarget11(mRenderer, rtv, mTexture, srv,
   591                                                                    std::max(mTextureWidth >> level, 1U),
   592                                                                    std::max(mTextureHeight >> level, 1U));
   593             }
   594             else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN)
   595             {
   596                 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
   597                 dsvDesc.Format = mRenderTargetFormat;
   598                 dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
   599                 dsvDesc.Texture2DArray.MipSlice = level;
   600                 dsvDesc.Texture2DArray.FirstArraySlice = faceIdx;
   601                 dsvDesc.Texture2DArray.ArraySize = 1;
   603                 ID3D11DepthStencilView *dsv;
   604                 result = device->CreateDepthStencilView(mTexture, &dsvDesc, &dsv);
   606                 if (result == E_OUTOFMEMORY)
   607                 {
   608                     srv->Release();
   609                     return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
   610                 }
   611                 ASSERT(SUCCEEDED(result));
   613                 // RenderTarget11 expects to be the owner of the resources it is given but TextureStorage11
   614                 // also needs to keep a reference to the texture.
   615                 mTexture->AddRef();
   617                 mRenderTarget[faceIdx][level] = new RenderTarget11(mRenderer, dsv, mTexture, srv,
   618                                                                    std::max(mTextureWidth >> level, 1U),
   619                                                                    std::max(mTextureHeight >> level, 1U));
   620             }
   621             else
   622             {
   623                 UNREACHABLE();
   624             }
   625         }
   627         return mRenderTarget[faceIdx][level];
   628     }
   629     else
   630     {
   631         return NULL;
   632     }
   633 }
   635 ID3D11ShaderResourceView *TextureStorage11_Cube::getSRV()
   636 {
   637     if (!mSRV)
   638     {
   639         ID3D11Device *device = mRenderer->getDevice();
   641         D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
   642         srvDesc.Format = mShaderResourceFormat;
   643         srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
   644         srvDesc.TextureCube.MipLevels = (mMipLevels == 0 ? -1 : mMipLevels);
   645         srvDesc.TextureCube.MostDetailedMip = 0;
   647         HRESULT result = device->CreateShaderResourceView(mTexture, &srvDesc, &mSRV);
   649         if (result == E_OUTOFMEMORY)
   650         {
   651             return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11ShaderResourceView*>(NULL));
   652         }
   653         ASSERT(SUCCEEDED(result));
   654     }
   656     return mSRV;
   657 }
   659 void TextureStorage11_Cube::generateMipmap(int face, int level)
   660 {
   661     RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level - 1));
   662     RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level));
   664     generateMipmapLayer(source, dest);
   665 }
   667 }

mercurial