Home | History | Annotate | Download | only in d3d11
      1 //
      2 // Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 
      7 // RenderTarget11.cpp: Implements a DX11-specific wrapper for ID3D11View pointers
      8 // retained by Renderbuffers.
      9 
     10 #include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
     11 #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
     12 #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
     13 #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
     14 #include "libGLESv2/main.h"
     15 
     16 namespace rx
     17 {
     18 
     19 static bool getTextureProperties(ID3D11Resource *resource, unsigned int *mipLevels, unsigned int *samples)
     20 {
     21     ID3D11Texture1D *texture1D = d3d11::DynamicCastComObject<ID3D11Texture1D>(resource);
     22     if (texture1D)
     23     {
     24         D3D11_TEXTURE1D_DESC texDesc;
     25         texture1D->GetDesc(&texDesc);
     26         SafeRelease(texture1D);
     27 
     28         *mipLevels = texDesc.MipLevels;
     29         *samples = 0;
     30 
     31         return true;
     32     }
     33 
     34     ID3D11Texture2D *texture2D = d3d11::DynamicCastComObject<ID3D11Texture2D>(resource);
     35     if (texture2D)
     36     {
     37         D3D11_TEXTURE2D_DESC texDesc;
     38         texture2D->GetDesc(&texDesc);
     39         SafeRelease(texture2D);
     40 
     41         *mipLevels = texDesc.MipLevels;
     42         *samples = texDesc.SampleDesc.Count > 1 ? texDesc.SampleDesc.Count : 0;
     43 
     44         return true;
     45     }
     46 
     47     ID3D11Texture3D *texture3D = d3d11::DynamicCastComObject<ID3D11Texture3D>(resource);
     48     if (texture3D)
     49     {
     50         D3D11_TEXTURE3D_DESC texDesc;
     51         texture3D->GetDesc(&texDesc);
     52         SafeRelease(texture3D);
     53 
     54         *mipLevels = texDesc.MipLevels;
     55         *samples = 0;
     56 
     57         return true;
     58     }
     59 
     60     return false;
     61 }
     62 
     63 static unsigned int getRTVSubresourceIndex(ID3D11Resource *resource, ID3D11RenderTargetView *view)
     64 {
     65     D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
     66     view->GetDesc(&rtvDesc);
     67 
     68     unsigned int mipSlice = 0;
     69     unsigned int arraySlice = 0;
     70 
     71     switch (rtvDesc.ViewDimension)
     72     {
     73       case D3D11_RTV_DIMENSION_TEXTURE1D:
     74         mipSlice = rtvDesc.Texture1D.MipSlice;
     75         arraySlice = 0;
     76         break;
     77 
     78       case D3D11_RTV_DIMENSION_TEXTURE1DARRAY:
     79         mipSlice = rtvDesc.Texture1DArray.MipSlice;
     80         arraySlice = rtvDesc.Texture1DArray.FirstArraySlice;
     81         break;
     82 
     83       case D3D11_RTV_DIMENSION_TEXTURE2D:
     84         mipSlice = rtvDesc.Texture2D.MipSlice;
     85         arraySlice = 0;
     86         break;
     87 
     88       case D3D11_RTV_DIMENSION_TEXTURE2DARRAY:
     89         mipSlice = rtvDesc.Texture2DArray.MipSlice;
     90         arraySlice = rtvDesc.Texture2DArray.FirstArraySlice;
     91         break;
     92 
     93       case D3D11_RTV_DIMENSION_TEXTURE2DMS:
     94         mipSlice = 0;
     95         arraySlice = 0;
     96         break;
     97 
     98       case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY:
     99         mipSlice = 0;
    100         arraySlice = rtvDesc.Texture2DMSArray.FirstArraySlice;
    101         break;
    102 
    103       case D3D11_RTV_DIMENSION_TEXTURE3D:
    104         mipSlice = rtvDesc.Texture3D.MipSlice;
    105         arraySlice = 0;
    106         break;
    107 
    108       case D3D11_RTV_DIMENSION_UNKNOWN:
    109       case D3D11_RTV_DIMENSION_BUFFER:
    110         UNIMPLEMENTED();
    111         break;
    112 
    113       default:
    114         UNREACHABLE();
    115         break;
    116     }
    117 
    118     unsigned int mipLevels, samples;
    119     getTextureProperties(resource,  &mipLevels, &samples);
    120 
    121     return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels);
    122 }
    123 
    124 static unsigned int getDSVSubresourceIndex(ID3D11Resource *resource, ID3D11DepthStencilView *view)
    125 {
    126     D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
    127     view->GetDesc(&dsvDesc);
    128 
    129     unsigned int mipSlice = 0;
    130     unsigned int arraySlice = 0;
    131 
    132     switch (dsvDesc.ViewDimension)
    133     {
    134       case D3D11_DSV_DIMENSION_TEXTURE1D:
    135         mipSlice = dsvDesc.Texture1D.MipSlice;
    136         arraySlice = 0;
    137         break;
    138 
    139       case D3D11_DSV_DIMENSION_TEXTURE1DARRAY:
    140         mipSlice = dsvDesc.Texture1DArray.MipSlice;
    141         arraySlice = dsvDesc.Texture1DArray.FirstArraySlice;
    142         break;
    143 
    144       case D3D11_DSV_DIMENSION_TEXTURE2D:
    145         mipSlice = dsvDesc.Texture2D.MipSlice;
    146         arraySlice = 0;
    147         break;
    148 
    149       case D3D11_DSV_DIMENSION_TEXTURE2DARRAY:
    150         mipSlice = dsvDesc.Texture2DArray.MipSlice;
    151         arraySlice = dsvDesc.Texture2DArray.FirstArraySlice;
    152         break;
    153 
    154       case D3D11_DSV_DIMENSION_TEXTURE2DMS:
    155         mipSlice = 0;
    156         arraySlice = 0;
    157         break;
    158 
    159       case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY:
    160         mipSlice = 0;
    161         arraySlice = dsvDesc.Texture2DMSArray.FirstArraySlice;
    162         break;
    163 
    164       case D3D11_DSV_DIMENSION_UNKNOWN:
    165         UNIMPLEMENTED();
    166         break;
    167 
    168       default:
    169         UNREACHABLE();
    170         break;
    171     }
    172 
    173     unsigned int mipLevels, samples;
    174     getTextureProperties(resource, &mipLevels, &samples);
    175 
    176     return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels);
    177 }
    178 
    179 RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, ID3D11Resource *resource,
    180                                ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height, GLsizei depth)
    181 {
    182     mRenderer = Renderer11::makeRenderer11(renderer);
    183 
    184     mTexture = resource;
    185     if (mTexture)
    186     {
    187         mTexture->AddRef();
    188     }
    189 
    190     mRenderTarget = rtv;
    191     if (mRenderTarget)
    192     {
    193         mRenderTarget->AddRef();
    194     }
    195 
    196     mDepthStencil = NULL;
    197 
    198     mShaderResource = srv;
    199     if (mShaderResource)
    200     {
    201         mShaderResource->AddRef();
    202     }
    203 
    204     mSubresourceIndex = 0;
    205 
    206     if (mRenderTarget && mTexture)
    207     {
    208         D3D11_RENDER_TARGET_VIEW_DESC desc;
    209         mRenderTarget->GetDesc(&desc);
    210 
    211         unsigned int mipLevels, samples;
    212         getTextureProperties(mTexture, &mipLevels, &samples);
    213 
    214         mSubresourceIndex = getRTVSubresourceIndex(mTexture, mRenderTarget);
    215         mWidth = width;
    216         mHeight = height;
    217         mDepth = depth;
    218         mSamples = samples;
    219 
    220         const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(desc.Format);
    221         mInternalFormat = dxgiFormatInfo.internalFormat;
    222         mActualFormat = dxgiFormatInfo.internalFormat;
    223     }
    224 }
    225 
    226 RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, ID3D11Resource *resource,
    227                                ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height, GLsizei depth)
    228 {
    229     mRenderer = Renderer11::makeRenderer11(renderer);
    230 
    231     mTexture = resource;
    232     if (mTexture)
    233     {
    234         mTexture->AddRef();
    235     }
    236 
    237     mRenderTarget = NULL;
    238 
    239     mDepthStencil = dsv;
    240     if (mDepthStencil)
    241     {
    242         mDepthStencil->AddRef();
    243     }
    244 
    245     mShaderResource = srv;
    246     if (mShaderResource)
    247     {
    248         mShaderResource->AddRef();
    249     }
    250 
    251     mSubresourceIndex = 0;
    252 
    253     if (mDepthStencil && mTexture)
    254     {
    255         D3D11_DEPTH_STENCIL_VIEW_DESC desc;
    256         mDepthStencil->GetDesc(&desc);
    257 
    258         unsigned int mipLevels, samples;
    259         getTextureProperties(mTexture, &mipLevels, &samples);
    260 
    261         mSubresourceIndex = getDSVSubresourceIndex(mTexture, mDepthStencil);
    262         mWidth = width;
    263         mHeight = height;
    264         mDepth = depth;
    265         mSamples = samples;
    266 
    267         const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(desc.Format);
    268         mInternalFormat = dxgiFormatInfo.internalFormat;
    269         mActualFormat = dxgiFormatInfo.internalFormat;
    270     }
    271 }
    272 
    273 RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height, GLenum internalFormat, GLsizei samples)
    274 {
    275     mRenderer = Renderer11::makeRenderer11(renderer);
    276     mTexture = NULL;
    277     mRenderTarget = NULL;
    278     mDepthStencil = NULL;
    279     mShaderResource = NULL;
    280 
    281     const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat);
    282     const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(formatInfo.texFormat);
    283 
    284     const gl::TextureCaps &textureCaps = mRenderer->getRendererTextureCaps().get(internalFormat);
    285     GLuint supportedSamples = textureCaps.getNearestSamples(samples);
    286 
    287     if (width > 0 && height > 0)
    288     {
    289         // Create texture resource
    290         D3D11_TEXTURE2D_DESC desc;
    291         desc.Width = width;
    292         desc.Height = height;
    293         desc.MipLevels = 1;
    294         desc.ArraySize = 1;
    295         desc.Format = formatInfo.texFormat;
    296         desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples;
    297         desc.SampleDesc.Quality = 0;
    298         desc.Usage = D3D11_USAGE_DEFAULT;
    299         desc.CPUAccessFlags = 0;
    300         desc.MiscFlags = 0;
    301 
    302         // If a rendertarget or depthstencil format exists for this texture format,
    303         // we'll flag it to allow binding that way. Shader resource views are a little
    304         // more complicated.
    305         bool bindRTV = false, bindDSV = false, bindSRV = false;
    306         bindRTV = (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN);
    307         bindDSV = (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN);
    308         if (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN)
    309         {
    310             // Multisample targets flagged for binding as depth stencil cannot also be
    311             // flagged for binding as SRV, so make certain not to add the SRV flag for
    312             // these targets.
    313             bindSRV = !(formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN && desc.SampleDesc.Count > 1);
    314         }
    315 
    316         desc.BindFlags = (bindRTV ? D3D11_BIND_RENDER_TARGET   : 0) |
    317                          (bindDSV ? D3D11_BIND_DEPTH_STENCIL   : 0) |
    318                          (bindSRV ? D3D11_BIND_SHADER_RESOURCE : 0);
    319 
    320         ID3D11Device *device = mRenderer->getDevice();
    321         ID3D11Texture2D *texture = NULL;
    322         HRESULT result = device->CreateTexture2D(&desc, NULL, &texture);
    323         mTexture = texture;
    324 
    325         if (result == E_OUTOFMEMORY)
    326         {
    327             gl::error(GL_OUT_OF_MEMORY);
    328             return;
    329         }
    330         ASSERT(SUCCEEDED(result));
    331 
    332         if (bindSRV)
    333         {
    334             D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
    335             srvDesc.Format = formatInfo.srvFormat;
    336             srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS;
    337             srvDesc.Texture2D.MostDetailedMip = 0;
    338             srvDesc.Texture2D.MipLevels = 1;
    339             result = device->CreateShaderResourceView(mTexture, &srvDesc, &mShaderResource);
    340 
    341             if (result == E_OUTOFMEMORY)
    342             {
    343                 SafeRelease(mTexture);
    344                 gl::error(GL_OUT_OF_MEMORY);
    345                 return;
    346             }
    347             ASSERT(SUCCEEDED(result));
    348         }
    349 
    350         if (bindDSV)
    351         {
    352             D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
    353             dsvDesc.Format = formatInfo.dsvFormat;
    354             dsvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_DSV_DIMENSION_TEXTURE2D : D3D11_DSV_DIMENSION_TEXTURE2DMS;
    355             dsvDesc.Texture2D.MipSlice = 0;
    356             dsvDesc.Flags = 0;
    357             result = device->CreateDepthStencilView(mTexture, &dsvDesc, &mDepthStencil);
    358 
    359             if (result == E_OUTOFMEMORY)
    360             {
    361                 SafeRelease(mTexture);
    362                 SafeRelease(mShaderResource);
    363                 gl::error(GL_OUT_OF_MEMORY);
    364                 return;
    365             }
    366             ASSERT(SUCCEEDED(result));
    367         }
    368 
    369         if (bindRTV)
    370         {
    371             D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
    372             rtvDesc.Format = formatInfo.rtvFormat;
    373             rtvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS;
    374             rtvDesc.Texture2D.MipSlice = 0;
    375             result = device->CreateRenderTargetView(mTexture, &rtvDesc, &mRenderTarget);
    376 
    377             if (result == E_OUTOFMEMORY)
    378             {
    379                 SafeRelease(mTexture);
    380                 SafeRelease(mShaderResource);
    381                 SafeRelease(mDepthStencil);
    382                 gl::error(GL_OUT_OF_MEMORY);
    383                 return;
    384             }
    385             ASSERT(SUCCEEDED(result));
    386 
    387             if (formatInfo.dataInitializerFunction != NULL)
    388             {
    389                 ID3D11DeviceContext *context = mRenderer->getDeviceContext();
    390 
    391                 const float clearValues[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
    392                 context->ClearRenderTargetView(mRenderTarget, clearValues);
    393             }
    394         }
    395     }
    396 
    397 
    398     mWidth = width;
    399     mHeight = height;
    400     mDepth = 1;
    401     mInternalFormat = internalFormat;
    402     mSamples = supportedSamples;
    403     mActualFormat = dxgiFormatInfo.internalFormat;
    404     mSubresourceIndex = D3D11CalcSubresource(0, 0, 1);
    405 }
    406 
    407 RenderTarget11::~RenderTarget11()
    408 {
    409     SafeRelease(mTexture);
    410     SafeRelease(mRenderTarget);
    411     SafeRelease(mDepthStencil);
    412     SafeRelease(mShaderResource);
    413 }
    414 
    415 RenderTarget11 *RenderTarget11::makeRenderTarget11(RenderTarget *target)
    416 {
    417     ASSERT(HAS_DYNAMIC_TYPE(rx::RenderTarget11*, target));
    418     return static_cast<rx::RenderTarget11*>(target);
    419 }
    420 
    421 void RenderTarget11::invalidate(GLint x, GLint y, GLsizei width, GLsizei height)
    422 {
    423     // Currently a no-op
    424 }
    425 
    426 ID3D11Resource *RenderTarget11::getTexture() const
    427 {
    428     return mTexture;
    429 }
    430 
    431 ID3D11RenderTargetView *RenderTarget11::getRenderTargetView() const
    432 {
    433     return mRenderTarget;
    434 }
    435 
    436 ID3D11DepthStencilView *RenderTarget11::getDepthStencilView() const
    437 {
    438     return mDepthStencil;
    439 }
    440 
    441 ID3D11ShaderResourceView *RenderTarget11::getShaderResourceView() const
    442 {
    443     return mShaderResource;
    444 }
    445 
    446 unsigned int RenderTarget11::getSubresourceIndex() const
    447 {
    448     return mSubresourceIndex;
    449 }
    450 
    451 }
    452