diff options
Diffstat (limited to 'gfx/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp')
-rwxr-xr-x | gfx/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp | 444 |
1 files changed, 444 insertions, 0 deletions
diff --git a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp new file mode 100755 index 000000000..a042f447d --- /dev/null +++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp @@ -0,0 +1,444 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// RenderTarget11.cpp: Implements a DX11-specific wrapper for ID3D11View pointers +// retained by Renderbuffers. + +#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" + +#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" +#include "libANGLE/renderer/d3d/d3d11/SwapChain11.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" + +namespace rx +{ + +namespace +{ +bool GetTextureProperties(ID3D11Resource *resource, unsigned int *mipLevels, unsigned int *samples) +{ + ID3D11Texture1D *texture1D = d3d11::DynamicCastComObject<ID3D11Texture1D>(resource); + if (texture1D) + { + D3D11_TEXTURE1D_DESC texDesc; + texture1D->GetDesc(&texDesc); + SafeRelease(texture1D); + + *mipLevels = texDesc.MipLevels; + *samples = 0; + + return true; + } + + ID3D11Texture2D *texture2D = d3d11::DynamicCastComObject<ID3D11Texture2D>(resource); + if (texture2D) + { + D3D11_TEXTURE2D_DESC texDesc; + texture2D->GetDesc(&texDesc); + SafeRelease(texture2D); + + *mipLevels = texDesc.MipLevels; + *samples = texDesc.SampleDesc.Count > 1 ? texDesc.SampleDesc.Count : 0; + + return true; + } + + ID3D11Texture3D *texture3D = d3d11::DynamicCastComObject<ID3D11Texture3D>(resource); + if (texture3D) + { + D3D11_TEXTURE3D_DESC texDesc; + texture3D->GetDesc(&texDesc); + SafeRelease(texture3D); + + *mipLevels = texDesc.MipLevels; + *samples = 0; + + return true; + } + + return false; +} + +unsigned int GetRTVSubresourceIndex(ID3D11Resource *resource, ID3D11RenderTargetView *view) +{ + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + view->GetDesc(&rtvDesc); + + unsigned int mipSlice = 0; + unsigned int arraySlice = 0; + + switch (rtvDesc.ViewDimension) + { + case D3D11_RTV_DIMENSION_TEXTURE1D: + mipSlice = rtvDesc.Texture1D.MipSlice; + arraySlice = 0; + break; + + case D3D11_RTV_DIMENSION_TEXTURE1DARRAY: + mipSlice = rtvDesc.Texture1DArray.MipSlice; + arraySlice = rtvDesc.Texture1DArray.FirstArraySlice; + break; + + case D3D11_RTV_DIMENSION_TEXTURE2D: + mipSlice = rtvDesc.Texture2D.MipSlice; + arraySlice = 0; + break; + + case D3D11_RTV_DIMENSION_TEXTURE2DARRAY: + mipSlice = rtvDesc.Texture2DArray.MipSlice; + arraySlice = rtvDesc.Texture2DArray.FirstArraySlice; + break; + + case D3D11_RTV_DIMENSION_TEXTURE2DMS: + mipSlice = 0; + arraySlice = 0; + break; + + case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY: + mipSlice = 0; + arraySlice = rtvDesc.Texture2DMSArray.FirstArraySlice; + break; + + case D3D11_RTV_DIMENSION_TEXTURE3D: + mipSlice = rtvDesc.Texture3D.MipSlice; + arraySlice = 0; + break; + + case D3D11_RTV_DIMENSION_UNKNOWN: + case D3D11_RTV_DIMENSION_BUFFER: + UNIMPLEMENTED(); + break; + + default: + UNREACHABLE(); + break; + } + + unsigned int mipLevels, samples; + GetTextureProperties(resource, &mipLevels, &samples); + + return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels); +} + +unsigned int GetDSVSubresourceIndex(ID3D11Resource *resource, ID3D11DepthStencilView *view) +{ + D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; + view->GetDesc(&dsvDesc); + + unsigned int mipSlice = 0; + unsigned int arraySlice = 0; + + switch (dsvDesc.ViewDimension) + { + case D3D11_DSV_DIMENSION_TEXTURE1D: + mipSlice = dsvDesc.Texture1D.MipSlice; + arraySlice = 0; + break; + + case D3D11_DSV_DIMENSION_TEXTURE1DARRAY: + mipSlice = dsvDesc.Texture1DArray.MipSlice; + arraySlice = dsvDesc.Texture1DArray.FirstArraySlice; + break; + + case D3D11_DSV_DIMENSION_TEXTURE2D: + mipSlice = dsvDesc.Texture2D.MipSlice; + arraySlice = 0; + break; + + case D3D11_DSV_DIMENSION_TEXTURE2DARRAY: + mipSlice = dsvDesc.Texture2DArray.MipSlice; + arraySlice = dsvDesc.Texture2DArray.FirstArraySlice; + break; + + case D3D11_DSV_DIMENSION_TEXTURE2DMS: + mipSlice = 0; + arraySlice = 0; + break; + + case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY: + mipSlice = 0; + arraySlice = dsvDesc.Texture2DMSArray.FirstArraySlice; + break; + + case D3D11_DSV_DIMENSION_UNKNOWN: + UNIMPLEMENTED(); + break; + + default: + UNREACHABLE(); + break; + } + + unsigned int mipLevels, samples; + GetTextureProperties(resource, &mipLevels, &samples); + + return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels); +} + +GLenum GetSurfaceRTFormat(bool depth, SwapChain11 *swapChain) +{ + return (depth ? swapChain->getDepthBufferInternalFormat() + : swapChain->getRenderTargetInternalFormat()); +} + +const d3d11::Format &GetSurfaceFormatSet(bool depth, SwapChain11 *swapChain, Renderer11 *renderer) +{ + return d3d11::Format::Get(GetSurfaceRTFormat(depth, swapChain), + renderer->getRenderer11DeviceCaps()); +} + +} // anonymous namespace + +RenderTarget11::RenderTarget11(const d3d11::Format &formatSet) : mFormatSet(formatSet) +{ +} + +RenderTarget11::~RenderTarget11() +{ + signalDirty(); +} + +void RenderTarget11::signalDirty() +{ + mBroadcastChannel.signal(); + + // Clear the list. We can't do this in the receiver because it would mutate during iteration. + mBroadcastChannel.reset(); +} + +TextureRenderTarget11::TextureRenderTarget11(ID3D11RenderTargetView *rtv, + ID3D11Resource *resource, + ID3D11ShaderResourceView *srv, + ID3D11ShaderResourceView *blitSRV, + GLenum internalFormat, + const d3d11::Format &formatSet, + GLsizei width, + GLsizei height, + GLsizei depth, + GLsizei samples) + : RenderTarget11(formatSet), + mWidth(width), + mHeight(height), + mDepth(depth), + mInternalFormat(internalFormat), + mSamples(samples), + mSubresourceIndex(0), + mTexture(resource), + mRenderTarget(rtv), + mDepthStencil(NULL), + mShaderResource(srv), + mBlitShaderResource(blitSRV) +{ + if (mTexture) + { + mTexture->AddRef(); + } + + if (mRenderTarget) + { + mRenderTarget->AddRef(); + } + + if (mShaderResource) + { + mShaderResource->AddRef(); + } + + if (mBlitShaderResource) + { + mBlitShaderResource->AddRef(); + } + + if (mRenderTarget && mTexture) + { + mSubresourceIndex = GetRTVSubresourceIndex(mTexture, mRenderTarget); + } + ASSERT(mFormatSet.formatID != angle::Format::ID::NONE || mWidth == 0 || mHeight == 0); +} + +TextureRenderTarget11::TextureRenderTarget11(ID3D11DepthStencilView *dsv, + ID3D11Resource *resource, + ID3D11ShaderResourceView *srv, + GLenum internalFormat, + const d3d11::Format &formatSet, + GLsizei width, + GLsizei height, + GLsizei depth, + GLsizei samples) + : RenderTarget11(formatSet), + mWidth(width), + mHeight(height), + mDepth(depth), + mInternalFormat(internalFormat), + mSamples(samples), + mSubresourceIndex(0), + mTexture(resource), + mRenderTarget(NULL), + mDepthStencil(dsv), + mShaderResource(srv), + mBlitShaderResource(nullptr) +{ + if (mTexture) + { + mTexture->AddRef(); + } + + if (mDepthStencil) + { + mDepthStencil->AddRef(); + } + + if (mShaderResource) + { + mShaderResource->AddRef(); + } + + if (mDepthStencil && mTexture) + { + mSubresourceIndex = GetDSVSubresourceIndex(mTexture, mDepthStencil); + } + ASSERT(mFormatSet.formatID != angle::Format::ID::NONE || mWidth == 0 || mHeight == 0); +} + +TextureRenderTarget11::~TextureRenderTarget11() +{ + SafeRelease(mTexture); + SafeRelease(mRenderTarget); + SafeRelease(mDepthStencil); + SafeRelease(mShaderResource); + SafeRelease(mBlitShaderResource); +} + +ID3D11Resource *TextureRenderTarget11::getTexture() const +{ + return mTexture; +} + +ID3D11RenderTargetView *TextureRenderTarget11::getRenderTargetView() const +{ + return mRenderTarget; +} + +ID3D11DepthStencilView *TextureRenderTarget11::getDepthStencilView() const +{ + return mDepthStencil; +} + +ID3D11ShaderResourceView *TextureRenderTarget11::getShaderResourceView() const +{ + return mShaderResource; +} + +ID3D11ShaderResourceView *TextureRenderTarget11::getBlitShaderResourceView() const +{ + return mBlitShaderResource; +} + +GLsizei TextureRenderTarget11::getWidth() const +{ + return mWidth; +} + +GLsizei TextureRenderTarget11::getHeight() const +{ + return mHeight; +} + +GLsizei TextureRenderTarget11::getDepth() const +{ + return mDepth; +} + +GLenum TextureRenderTarget11::getInternalFormat() const +{ + return mInternalFormat; +} + +GLsizei TextureRenderTarget11::getSamples() const +{ + return mSamples; +} + +unsigned int TextureRenderTarget11::getSubresourceIndex() const +{ + return mSubresourceIndex; +} + +SurfaceRenderTarget11::SurfaceRenderTarget11(SwapChain11 *swapChain, + Renderer11 *renderer, + bool depth) + : RenderTarget11(GetSurfaceFormatSet(depth, swapChain, renderer)), + mSwapChain(swapChain), + mDepth(depth) +{ + ASSERT(mSwapChain); +} + +SurfaceRenderTarget11::~SurfaceRenderTarget11() +{ +} + +GLsizei SurfaceRenderTarget11::getWidth() const +{ + return mSwapChain->getWidth(); +} + +GLsizei SurfaceRenderTarget11::getHeight() const +{ + return mSwapChain->getHeight(); +} + +GLsizei SurfaceRenderTarget11::getDepth() const +{ + return 1; +} + +GLenum SurfaceRenderTarget11::getInternalFormat() const +{ + return GetSurfaceRTFormat(mDepth, mSwapChain); +} + +GLsizei SurfaceRenderTarget11::getSamples() const +{ + // Our EGL surfaces do not support multisampling. + return 0; +} + +ID3D11Resource *SurfaceRenderTarget11::getTexture() const +{ + return (mDepth ? mSwapChain->getDepthStencilTexture() : mSwapChain->getOffscreenTexture()); +} + +ID3D11RenderTargetView *SurfaceRenderTarget11::getRenderTargetView() const +{ + return (mDepth ? NULL : mSwapChain->getRenderTarget()); +} + +ID3D11DepthStencilView *SurfaceRenderTarget11::getDepthStencilView() const +{ + return (mDepth ? mSwapChain->getDepthStencil() : NULL); +} + +ID3D11ShaderResourceView *SurfaceRenderTarget11::getShaderResourceView() const +{ + return (mDepth ? mSwapChain->getDepthStencilShaderResource() + : mSwapChain->getRenderTargetShaderResource()); +} + +ID3D11ShaderResourceView *SurfaceRenderTarget11::getBlitShaderResourceView() const +{ + // The SurfaceRenderTargetView format should always be such that the normal SRV works for blits. + return getShaderResourceView(); +} + +unsigned int SurfaceRenderTarget11::getSubresourceIndex() const +{ + return 0; +} + +} // namespace rx |