Home | History | Annotate | Download | only in renderer
      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 //
      7 
      8 // RenderTarget11.cpp: Implements a DX11-specific wrapper for ID3D11View pointers
      9 // retained by Renderbuffers.
     10 
     11 #include "libGLESv2/renderer/RenderTarget11.h"
     12 #include "libGLESv2/renderer/Renderer11.h"
     13 
     14 #include "libGLESv2/renderer/renderer11_utils.h"
     15 #include "libGLESv2/main.h"
     16 
     17 namespace rx
     18 {
     19 
     20 static unsigned int getRTVSubresourceIndex(ID3D11Texture2D *texture, ID3D11RenderTargetView *view)
     21 {
     22     D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
     23     view->GetDesc(&rtvDesc);
     24 
     25     D3D11_TEXTURE2D_DESC texDesc;
     26     texture->GetDesc(&texDesc);
     27 
     28     unsigned int mipSlice = 0;
     29     unsigned int arraySlice = 0;
     30     unsigned int mipLevels = texDesc.MipLevels;
     31 
     32     switch (rtvDesc.ViewDimension)
     33     {
     34       case D3D11_RTV_DIMENSION_TEXTURE1D:
     35         mipSlice = rtvDesc.Texture1D.MipSlice;
     36         arraySlice = 0;
     37         break;
     38 
     39       case D3D11_RTV_DIMENSION_TEXTURE1DARRAY:
     40         mipSlice = rtvDesc.Texture1DArray.MipSlice;
     41         arraySlice = rtvDesc.Texture1DArray.FirstArraySlice;
     42         break;
     43 
     44       case D3D11_RTV_DIMENSION_TEXTURE2D:
     45         mipSlice = rtvDesc.Texture2D.MipSlice;
     46         arraySlice = 0;
     47         break;
     48 
     49       case D3D11_RTV_DIMENSION_TEXTURE2DARRAY:
     50         mipSlice = rtvDesc.Texture2DArray.MipSlice;
     51         arraySlice = rtvDesc.Texture2DArray.FirstArraySlice;
     52         break;
     53 
     54       case D3D11_RTV_DIMENSION_TEXTURE2DMS:
     55         mipSlice = 0;
     56         arraySlice = 0;
     57         break;
     58 
     59       case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY:
     60         mipSlice = 0;
     61         arraySlice = rtvDesc.Texture2DMSArray.FirstArraySlice;
     62         break;
     63 
     64       case D3D11_RTV_DIMENSION_TEXTURE3D:
     65         mipSlice = rtvDesc.Texture3D.MipSlice;
     66         arraySlice = 0;
     67         break;
     68 
     69       case D3D11_RTV_DIMENSION_UNKNOWN:
     70       case D3D11_RTV_DIMENSION_BUFFER:
     71         UNIMPLEMENTED();
     72         break;
     73 
     74       default:
     75         UNREACHABLE();
     76         break;
     77     }
     78 
     79     return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels);
     80 }
     81 
     82 static unsigned int getDSVSubresourceIndex(ID3D11Texture2D *texture, ID3D11DepthStencilView *view)
     83 {
     84     D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
     85     view->GetDesc(&dsvDesc);
     86 
     87     D3D11_TEXTURE2D_DESC texDesc;
     88     texture->GetDesc(&texDesc);
     89 
     90     unsigned int mipSlice = 0;
     91     unsigned int arraySlice = 0;
     92     unsigned int mipLevels = texDesc.MipLevels;
     93 
     94     switch (dsvDesc.ViewDimension)
     95     {
     96       case D3D11_DSV_DIMENSION_TEXTURE1D:
     97         mipSlice = dsvDesc.Texture1D.MipSlice;
     98         arraySlice = 0;
     99         break;
    100 
    101       case D3D11_DSV_DIMENSION_TEXTURE1DARRAY:
    102         mipSlice = dsvDesc.Texture1DArray.MipSlice;
    103         arraySlice = dsvDesc.Texture1DArray.FirstArraySlice;
    104         break;
    105 
    106       case D3D11_DSV_DIMENSION_TEXTURE2D:
    107         mipSlice = dsvDesc.Texture2D.MipSlice;
    108         arraySlice = 0;
    109         break;
    110 
    111       case D3D11_DSV_DIMENSION_TEXTURE2DARRAY:
    112         mipSlice = dsvDesc.Texture2DArray.MipSlice;
    113         arraySlice = dsvDesc.Texture2DArray.FirstArraySlice;
    114         break;
    115 
    116       case D3D11_DSV_DIMENSION_TEXTURE2DMS:
    117         mipSlice = 0;
    118         arraySlice = 0;
    119         break;
    120 
    121       case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY:
    122         mipSlice = 0;
    123         arraySlice = dsvDesc.Texture2DMSArray.FirstArraySlice;
    124         break;
    125 
    126       case D3D11_RTV_DIMENSION_UNKNOWN:
    127         UNIMPLEMENTED();
    128         break;
    129 
    130       default:
    131         UNREACHABLE();
    132         break;
    133     }
    134 
    135     return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels);
    136 }
    137 
    138 RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, ID3D11Texture2D *tex, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height)
    139 {
    140     mRenderer = Renderer11::makeRenderer11(renderer);
    141     mTexture = tex;
    142     mRenderTarget = rtv;
    143     mDepthStencil = NULL;
    144     mShaderResource = srv;
    145     mSubresourceIndex = 0;
    146 
    147     if (mRenderTarget && mTexture)
    148     {
    149         D3D11_RENDER_TARGET_VIEW_DESC desc;
    150         mRenderTarget->GetDesc(&desc);
    151 
    152         D3D11_TEXTURE2D_DESC texDesc;
    153         mTexture->GetDesc(&texDesc);
    154 
    155         mSubresourceIndex = getRTVSubresourceIndex(mTexture, mRenderTarget);
    156         mWidth = width;
    157         mHeight = height;
    158         mSamples = (texDesc.SampleDesc.Count > 1) ? texDesc.SampleDesc.Count : 0;
    159 
    160         mInternalFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format);
    161         mActualFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format);
    162     }
    163 }
    164 
    165 RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, ID3D11Texture2D *tex, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height)
    166 {
    167     mRenderer = Renderer11::makeRenderer11(renderer);
    168     mTexture = tex;
    169     mRenderTarget = NULL;
    170     mDepthStencil = dsv;
    171     mShaderResource = srv;
    172     mSubresourceIndex = 0;
    173 
    174     if (mDepthStencil && mTexture)
    175     {
    176         D3D11_DEPTH_STENCIL_VIEW_DESC desc;
    177         mDepthStencil->GetDesc(&desc);
    178 
    179         D3D11_TEXTURE2D_DESC texDesc;
    180         mTexture->GetDesc(&texDesc);
    181 
    182         mSubresourceIndex = getDSVSubresourceIndex(mTexture, mDepthStencil);
    183         mWidth = width;
    184         mHeight = height;
    185         mSamples = (texDesc.SampleDesc.Count > 1) ? texDesc.SampleDesc.Count : 0;
    186 
    187         mInternalFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format);
    188         mActualFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format);
    189     }
    190 }
    191 
    192 RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height, GLenum format, GLsizei samples, bool depth)
    193 {
    194     mRenderer = Renderer11::makeRenderer11(renderer);
    195     mTexture = NULL;
    196     mRenderTarget = NULL;
    197     mDepthStencil = NULL;
    198     mShaderResource = NULL;
    199 
    200     DXGI_FORMAT requestedFormat = gl_d3d11::ConvertRenderbufferFormat(format);
    201 
    202     int supportedSamples = mRenderer->getNearestSupportedSamples(requestedFormat, samples);
    203     if (supportedSamples < 0)
    204     {
    205         gl::error(GL_OUT_OF_MEMORY);
    206         return;
    207     }
    208 
    209     if (width > 0 && height > 0)
    210     {
    211         // Create texture resource
    212         D3D11_TEXTURE2D_DESC desc;
    213         desc.Width = width;
    214         desc.Height = height;
    215         desc.MipLevels = 1;
    216         desc.ArraySize = 1;
    217         desc.Format = requestedFormat;
    218         desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples;
    219         desc.SampleDesc.Quality = 0;
    220         desc.Usage = D3D11_USAGE_DEFAULT;
    221         desc.CPUAccessFlags = 0;
    222         desc.MiscFlags = 0;
    223         desc.BindFlags = (depth ? D3D11_BIND_DEPTH_STENCIL : (D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE));
    224 
    225         ID3D11Device *device = mRenderer->getDevice();
    226         HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
    227 
    228         if (result == E_OUTOFMEMORY)
    229         {
    230             gl::error(GL_OUT_OF_MEMORY);
    231             return;
    232         }
    233         ASSERT(SUCCEEDED(result));
    234 
    235         if (depth)
    236         {
    237             D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
    238             dsvDesc.Format = requestedFormat;
    239             dsvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_DSV_DIMENSION_TEXTURE2D : D3D11_DSV_DIMENSION_TEXTURE2DMS;
    240             dsvDesc.Texture2D.MipSlice = 0;
    241             dsvDesc.Flags = 0;
    242             result = device->CreateDepthStencilView(mTexture, &dsvDesc, &mDepthStencil);
    243 
    244             if (result == E_OUTOFMEMORY)
    245             {
    246                 mTexture->Release();
    247                 mTexture = NULL;
    248                 gl::error(GL_OUT_OF_MEMORY);
    249             }
    250             ASSERT(SUCCEEDED(result));
    251         }
    252         else
    253         {
    254             D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
    255             rtvDesc.Format = requestedFormat;
    256             rtvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS;
    257             rtvDesc.Texture2D.MipSlice = 0;
    258             result = device->CreateRenderTargetView(mTexture, &rtvDesc, &mRenderTarget);
    259 
    260             if (result == E_OUTOFMEMORY)
    261             {
    262                 mTexture->Release();
    263                 mTexture = NULL;
    264                 gl::error(GL_OUT_OF_MEMORY);
    265                 return;
    266             }
    267             ASSERT(SUCCEEDED(result));
    268 
    269             D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
    270             srvDesc.Format = requestedFormat;
    271             srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS;
    272             srvDesc.Texture2D.MostDetailedMip = 0;
    273             srvDesc.Texture2D.MipLevels = 1;
    274             result = device->CreateShaderResourceView(mTexture, &srvDesc, &mShaderResource);
    275 
    276             if (result == E_OUTOFMEMORY)
    277             {
    278                 mTexture->Release();
    279                 mTexture = NULL;
    280                 mRenderTarget->Release();
    281                 mRenderTarget = NULL;
    282                 gl::error(GL_OUT_OF_MEMORY);
    283                 return;
    284             }
    285             ASSERT(SUCCEEDED(result));
    286         }
    287     }
    288 
    289     mWidth = width;
    290     mHeight = height;
    291     mInternalFormat = format;
    292     mSamples = supportedSamples;
    293     mActualFormat = d3d11_gl::ConvertTextureInternalFormat(requestedFormat);
    294     mSubresourceIndex = D3D11CalcSubresource(0, 0, 1);
    295 }
    296 
    297 RenderTarget11::~RenderTarget11()
    298 {
    299     if (mTexture)
    300     {
    301         mTexture->Release();
    302         mTexture = NULL;
    303     }
    304 
    305     if (mRenderTarget)
    306     {
    307         mRenderTarget->Release();
    308         mRenderTarget = NULL;
    309     }
    310 
    311     if (mDepthStencil)
    312     {
    313         mDepthStencil->Release();
    314         mDepthStencil = NULL;
    315     }
    316 
    317     if (mShaderResource)
    318     {
    319         mShaderResource->Release();
    320         mShaderResource = NULL;
    321     }
    322 }
    323 
    324 RenderTarget11 *RenderTarget11::makeRenderTarget11(RenderTarget *target)
    325 {
    326     ASSERT(HAS_DYNAMIC_TYPE(rx::RenderTarget11*, target));
    327     return static_cast<rx::RenderTarget11*>(target);
    328 }
    329 
    330 ID3D11Texture2D *RenderTarget11::getTexture() const
    331 {
    332     return mTexture;
    333 }
    334 
    335 ID3D11RenderTargetView *RenderTarget11::getRenderTargetView() const
    336 {
    337     return mRenderTarget;
    338 }
    339 
    340 ID3D11DepthStencilView *RenderTarget11::getDepthStencilView() const
    341 {
    342     return mDepthStencil;
    343 }
    344 
    345 ID3D11ShaderResourceView *RenderTarget11::getShaderResourceView() const
    346 {
    347     return mShaderResource;
    348 }
    349 
    350 unsigned int RenderTarget11::getSubresourceIndex() const
    351 {
    352     return mSubresourceIndex;
    353 }
    354 
    355 }
    356