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