From 520d2118ef06bf790328be32205229a9dde08343 Mon Sep 17 00:00:00 2001 From: Arthur Fernandes Date: Tue, 14 Jan 2025 12:23:07 -0300 Subject: [PATCH] D3D11: _create2DTex() with mSurface. --- OgreMain/include/OgreTexture.h | 4 +- OgreMain/include/OgreTextureManager.h | 21 +- OgreMain/src/OgreTextureManager.cpp | 35 - .../Direct3D11/include/OgreD3D11Texture.h | 4 +- .../src/OgreD3D11HardwarePixelBuffer.cpp | 2 - .../Direct3D11/src/OgreD3D11Texture.cpp | 1065 ++++++++--------- 6 files changed, 521 insertions(+), 610 deletions(-) diff --git a/OgreMain/include/OgreTexture.h b/OgreMain/include/OgreTexture.h index e3dc9590e39..d0132893081 100644 --- a/OgreMain/include/OgreTexture.h +++ b/OgreMain/include/OgreTexture.h @@ -109,8 +109,6 @@ namespace Ogre { TEX_TYPE_2D_ARRAY = 5, /// GLES2 only OES texture type TEX_TYPE_EXTERNAL_OES = 6, - /// 2D texture, used when you already have a surface - TEX_TYPE_2D_WITH_SURFACE = 7 }; /** Enum identifying special mipmap numbers @@ -150,7 +148,7 @@ namespace Ogre { /** Sets the surface when you already have one */ - void setSurface(void* surface) { mSurface = surface; } + virtual void _setSurface(void* surface) { mSurface = surface; } /** Gets the surface */ diff --git a/OgreMain/include/OgreTextureManager.h b/OgreMain/include/OgreTextureManager.h index 61af7dbd7b2..9f414b2c149 100644 --- a/OgreMain/include/OgreTextureManager.h +++ b/OgreMain/include/OgreTextureManager.h @@ -262,13 +262,7 @@ namespace Ogre { TextureType texType, uint width, uint height, uint depth, int numMipmaps, PixelFormat format, int usage = TU_DEFAULT, ManualResourceLoader* loader = 0, bool hwGammaCorrection = false, uint fsaa = 0, const String& fsaaHint = BLANKSTRING); - - TexturePtr createManualWithSurface(const String& name, const String& group, TextureType texType, uint width, - uint height, uint depth, int numMipmaps, PixelFormat format, - int usage = TU_DEFAULT, void* surface = nullptr, - ManualResourceLoader* loader = 0, bool hwGammaCorrection = false, - uint fsaa = 0, const String& fsaaHint = BLANKSTRING); - + /** @overload */ TexturePtr createManual(const String & name, const String& group, @@ -278,18 +272,7 @@ namespace Ogre { { return createManual(name, group, texType, width, height, 1, numMipmaps, format, usage, loader, hwGammaCorrection, fsaa, fsaaHint); - } - - TexturePtr createManualWithSurface(const String& name, const String& group, TextureType texType, uint width, - uint height, int numMipmaps, PixelFormat format, int usage = TU_DEFAULT, - void* surface = nullptr, ManualResourceLoader* loader = 0, - bool hwGammaCorrection = false, uint fsaa = 0, - const String& fsaaHint = BLANKSTRING) - { - return createManualWithSurface(name, group, texType, width, height, 1, numMipmaps, format, usage, surface, - loader, hwGammaCorrection, fsaa, fsaaHint); - } - + } /** Sets preferred bit depth for integer pixel format textures. @param bits Number of bits. Available values: 0, 16 and 32, where 0 (the default) means keep diff --git a/OgreMain/src/OgreTextureManager.cpp b/OgreMain/src/OgreTextureManager.cpp index 3855719e6f1..001cbd0992d 100644 --- a/OgreMain/src/OgreTextureManager.cpp +++ b/OgreMain/src/OgreTextureManager.cpp @@ -216,41 +216,6 @@ namespace Ogre { return ret; } //----------------------------------------------------------------------- - TexturePtr TextureManager::createManualWithSurface(const String& name, const String& group, TextureType texType, - uint width, uint height, uint depth, int numMipmaps, - PixelFormat format, int usage, void* surface, - ManualResourceLoader* loader, bool hwGamma, uint fsaa, - const String& fsaaHint) - { - TexturePtr ret; - - OgreAssert(width && height && depth, "total size of texture must not be zero"); - - // Check for texture support - const auto caps = Root::getSingleton().getRenderSystem()->getCapabilities(); - if (((texType == TEX_TYPE_3D) && !caps->hasCapability(RSC_TEXTURE_3D)) || - ((texType == TEX_TYPE_2D_ARRAY) && !caps->hasCapability(RSC_TEXTURE_2D_ARRAY))) - return ret; - - ret = create(name, group, true, loader); - - if (!ret) - return ret; - - ret->setSurface(surface); - ret->setTextureType(texType); - ret->setWidth(width); - ret->setHeight(height); - ret->setDepth(depth); - ret->setNumMipmaps((numMipmaps == MIP_DEFAULT) ? mDefaultNumMipmaps : static_cast(numMipmaps)); - ret->setFormat(format); - ret->setUsage(usage); - ret->setHardwareGammaEnabled(hwGamma); - ret->setFSAA(fsaa, fsaaHint); - ret->createInternalResources(); - return ret; - } - //----------------------------------------------------------------------- void TextureManager::setPreferredIntegerBitDepth(ushort bits, bool reloadTextures) { mPreferredIntegerBitDepth = bits; diff --git a/RenderSystems/Direct3D11/include/OgreD3D11Texture.h b/RenderSystems/Direct3D11/include/OgreD3D11Texture.h index 99c3e436b25..3a0a2db03e4 100644 --- a/RenderSystems/Direct3D11/include/OgreD3D11Texture.h +++ b/RenderSystems/Direct3D11/include/OgreD3D11Texture.h @@ -93,9 +93,7 @@ namespace Ogre { /// internal method, create a blank normal 1D Dtexture void _create1DTex(); /// internal method, create a blank normal 2D texture - void _create2DTex(); - /// internal method, use a normal 2D texture - void _create2DTexWithSurface(); + void _create2DTex(); /// internal method, create a blank cube texture void _create3DTex(); diff --git a/RenderSystems/Direct3D11/src/OgreD3D11HardwarePixelBuffer.cpp b/RenderSystems/Direct3D11/src/OgreD3D11HardwarePixelBuffer.cpp index 81dfe250f53..a4179f41e3c 100644 --- a/RenderSystems/Direct3D11/src/OgreD3D11HardwarePixelBuffer.cpp +++ b/RenderSystems/Direct3D11/src/OgreD3D11HardwarePixelBuffer.cpp @@ -52,7 +52,6 @@ namespace Ogre { case TEX_TYPE_1D: return "1D texture"; case TEX_TYPE_CUBE_MAP: return "cube map texture"; case TEX_TYPE_2D: return "2D texture"; - case TEX_TYPE_2D_WITH_SURFACE: return "2D texture with surface"; case TEX_TYPE_2D_ARRAY: return "2D texture array"; case TEX_TYPE_3D: return "3D texture"; default: return "texture"; @@ -482,7 +481,6 @@ namespace Ogre { } break; case TEX_TYPE_2D: - case TEX_TYPE_2D_WITH_SURFACE: case TEX_TYPE_CUBE_MAP: case TEX_TYPE_2D_ARRAY: { diff --git a/RenderSystems/Direct3D11/src/OgreD3D11Texture.cpp b/RenderSystems/Direct3D11/src/OgreD3D11Texture.cpp index f31e4b63c1c..7e8cbeca912 100644 --- a/RenderSystems/Direct3D11/src/OgreD3D11Texture.cpp +++ b/RenderSystems/Direct3D11/src/OgreD3D11Texture.cpp @@ -26,296 +26,200 @@ THE SOFTWARE. ----------------------------------------------------------------------------- */ #include "OgreD3D11Texture.h" +#include "OgreD3D11DepthBuffer.h" +#include "OgreD3D11Device.h" #include "OgreD3D11HardwarePixelBuffer.h" #include "OgreD3D11Mappings.h" -#include "OgreD3D11Device.h" #include "OgreD3D11RenderSystem.h" -#include "OgreD3D11DepthBuffer.h" -#include "OgreRoot.h" -#include "OgreLogManager.h" #include "OgreException.h" +#include "OgreLogManager.h" +#include "OgreRoot.h" -namespace Ogre +namespace Ogre +{ +//--------------------------------------------------------------------- +D3D11Texture::D3D11Texture(ResourceManager* creator, const String& name, ResourceHandle handle, const String& group, + bool isManual, ManualResourceLoader* loader, D3D11Device& device) + : Texture(creator, name, handle, group, isManual, loader), mDevice(device), mAutoMipMapGeneration(false) { - //--------------------------------------------------------------------- - D3D11Texture::D3D11Texture(ResourceManager* creator, const String& name, - ResourceHandle handle, const String& group, bool isManual, - ManualResourceLoader* loader, D3D11Device & device) - :Texture(creator, name, handle, group, isManual, loader), - mDevice(device), - mAutoMipMapGeneration(false) + mFSAAType.Count = 1; + mFSAAType.Quality = 0; +} +//--------------------------------------------------------------------- +D3D11Texture::~D3D11Texture() { unload(); } +//--------------------------------------------------------------------- +void D3D11Texture::notifyDeviceLost(D3D11Device* device) { unloadImpl(); } +//--------------------------------------------------------------------- +void D3D11Texture::notifyDeviceRestored(D3D11Device* device) +{ + if (isManuallyLoaded()) { - mFSAAType.Count = 1; - mFSAAType.Quality = 0; + preLoadImpl(); + createInternalResourcesImpl(); + if (mLoader != NULL) + mLoader->loadResource(this); + postLoadImpl(); } - //--------------------------------------------------------------------- - D3D11Texture::~D3D11Texture() + else { - unload(); + preLoadImpl(); + loadImpl(); + postLoadImpl(); } - //--------------------------------------------------------------------- - void D3D11Texture::notifyDeviceLost(D3D11Device* device) +} +//--------------------------------------------------------------------- +void D3D11Texture::copyToTexture(TexturePtr& target) +{ + // check if this & target are the same format and type + // blitting from or to cube textures is not supported yet + if (target->getUsage() != this->getUsage() || target->getTextureType() != this->getTextureType()) { - unloadImpl(); + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Src. and dest. textures must be of same type and must have the same usage !!!", + "D3D11Texture::copyToTexture"); } - //--------------------------------------------------------------------- - void D3D11Texture::notifyDeviceRestored(D3D11Device* device) - { - if(isManuallyLoaded()) - { - preLoadImpl(); - createInternalResourcesImpl(); - if (mLoader != NULL) - mLoader->loadResource(this); - postLoadImpl(); - } - else - { - preLoadImpl(); - loadImpl(); - postLoadImpl(); - } - } - //--------------------------------------------------------------------- - void D3D11Texture::copyToTexture(TexturePtr& target) - { - // check if this & target are the same format and type - // blitting from or to cube textures is not supported yet - if (target->getUsage() != this->getUsage() || - target->getTextureType() != this->getTextureType()) - { - OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, - "Src. and dest. textures must be of same type and must have the same usage !!!", - "D3D11Texture::copyToTexture" ); - } + D3D11Texture* other; + // get the target + other = static_cast(target.get()); - D3D11Texture *other; - // get the target - other = static_cast< D3D11Texture * >( target.get() ); - - mDevice.GetImmediateContext()->CopyResource(other->getTextureResource(), mpTex.Get()); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot copy resource\nError Description:" + errorDescription, - "D3D11Texture::copyToTexture"); - } - - } - //--------------------------------------------------------------------- - void D3D11Texture::freeInternalResourcesImpl() + mDevice.GetImmediateContext()->CopyResource(other->getTextureResource(), mpTex.Get()); + if (mDevice.isError()) { - mpTex.Reset(); - mpShaderResourceView.Reset(); - mpUnorderedAccessView.Reset(); - mp1DTex.Reset(); - mp2DTex.Reset(); - mp3DTex.Reset(); + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot copy resource\nError Description:" + errorDescription, + "D3D11Texture::copyToTexture"); } - - //--------------------------------------------------------------------- - void D3D11Texture::createInternalResourcesImpl(void) +} +//--------------------------------------------------------------------- +void D3D11Texture::freeInternalResourcesImpl() +{ + mpTex.Reset(); + mpShaderResourceView.Reset(); + mpUnorderedAccessView.Reset(); + mp1DTex.Reset(); + mp2DTex.Reset(); + mp3DTex.Reset(); +} + +//--------------------------------------------------------------------- +void D3D11Texture::createInternalResourcesImpl(void) +{ + // If mSrcWidth and mSrcHeight are zero, the requested extents have probably been set + // through setWidth and setHeight, which set mWidth and mHeight. Take those values. + if (mSrcWidth == 0 || mSrcHeight == 0) { - // If mSrcWidth and mSrcHeight are zero, the requested extents have probably been set - // through setWidth and setHeight, which set mWidth and mHeight. Take those values. - if(mSrcWidth == 0 || mSrcHeight == 0) { - mSrcWidth = mWidth; - mSrcHeight = mHeight; - } - - mFormat = D3D11Mappings::_getClosestSupportedPF(mFormat); - - // Choose closest supported D3D format - mD3DFormat = D3D11Mappings::_getGammaFormat(D3D11Mappings::_getPF(mFormat), isHardwareGammaEnabled()); - - mFSAAType.Count = 1; - mFSAAType.Quality = 0; - if((mUsage & TU_RENDERTARGET) != 0 && (mUsage & TU_DYNAMIC) == 0) - { - D3D11RenderSystem* rsys = static_cast(Root::getSingleton().getRenderSystem()); - // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150%28v=vs.85%29.aspx#ID3D11Device_CreateTexture2D - // 10Level9, When using D3D11_BIND_SHADER_RESOURCE, SampleDesc.Count must be 1. - if(rsys->_getFeatureLevel() >= D3D_FEATURE_LEVEL_10_0 || (mUsage & TU_NOT_SAMPLED)) - rsys->determineFSAASettings(mFSAA, mFSAAHint, mD3DFormat, &mFSAAType); - } - - // load based on tex.type - switch (this->getTextureType()) - { - case TEX_TYPE_1D: - { - D3D11RenderSystem* rs = (D3D11RenderSystem*)Root::getSingleton().getRenderSystem(); - if(rs->_getFeatureLevel() >= D3D_FEATURE_LEVEL_10_0) - { - this->_create1DTex(); - break; // For Feature levels that do not support 1D textures, revert to creating a 2D texture. - } - } - case TEX_TYPE_2D: - case TEX_TYPE_CUBE_MAP: - case TEX_TYPE_2D_ARRAY: - this->_create2DTex(); - break; - case TEX_TYPE_2D_WITH_SURFACE: - this->_create2DTexWithSurface(); - break; - case TEX_TYPE_3D: - this->_create3DTex(); - break; - default: - this->unloadImpl(); - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Unknown texture type", "D3D11Texture::createInternalResources" ); - } + mSrcWidth = mWidth; + mSrcHeight = mHeight; } - //--------------------------------------------------------------------- - void D3D11Texture::_create1DTex() - { - // we must have those defined here - assert(mSrcWidth > 0 || mSrcHeight > 0); - // determine total number of mipmaps including main one (d3d11 convention) - UINT numMips = (mNumMipmaps == MIP_UNLIMITED || (1U << mNumMipmaps) > mSrcWidth) ? 0 : mNumMipmaps + 1; - - D3D11_TEXTURE1D_DESC desc; - desc.Width = static_cast(mSrcWidth); - desc.MipLevels = numMips; - desc.ArraySize = 1; - desc.Format = mD3DFormat; - desc.Usage = D3D11Mappings::_getUsage(_getTextureUsage()); - desc.BindFlags = D3D11Mappings::_getTextureBindFlags(mD3DFormat, _getTextureUsage()); - desc.CPUAccessFlags = D3D11Mappings::_getAccessFlags(_getTextureUsage()); - desc.MiscFlags = D3D11Mappings::_getTextureMiscFlags(desc.BindFlags, getTextureType(), _getTextureUsage()); + mFormat = D3D11Mappings::_getClosestSupportedPF(mFormat); - // create the texture - HRESULT hr = mDevice->CreateTexture1D( - &desc, - NULL, - mp1DTex.ReleaseAndGetAddressOf()); // data pointer - // check result and except if failed - if (FAILED(hr) || mDevice.isError()) - { - this->unloadImpl(); - String errorDescription = mDevice.getErrorDescription(hr); - OGRE_EXCEPT_EX(Exception::ERR_RENDERINGAPI_ERROR, hr, - "Error creating texture\nError Description:" + errorDescription, - "D3D11Texture::_create1DTex" ); - } + // Choose closest supported D3D format + mD3DFormat = D3D11Mappings::_getGammaFormat(D3D11Mappings::_getPF(mFormat), isHardwareGammaEnabled()); - _queryInterface(mp1DTex, &mpTex); - _create1DResourceView(); - } - //--------------------------------------------------------------------- - void D3D11Texture::_create1DResourceView() + mFSAAType.Count = 1; + mFSAAType.Quality = 0; + if ((mUsage & TU_RENDERTARGET) != 0 && (mUsage & TU_DYNAMIC) == 0) { - // set final tex. attributes from tex. description - // they may differ from the source image !!! - HRESULT hr; - D3D11_TEXTURE1D_DESC desc; - - // set final tex. attributes from tex. description - // they may differ from the source image !!! - mp1DTex->GetDesc(&desc); - mNumMipmaps = desc.MipLevels - 1; - - ZeroMemory( &mSRVDesc, sizeof(mSRVDesc) ); - mSRVDesc.Format = desc.Format; - mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D; - mSRVDesc.Texture1D.MipLevels = desc.MipLevels; - OGRE_CHECK_DX_ERROR( - (desc.BindFlags & D3D11_BIND_SHADER_RESOURCE) - ? mDevice->CreateShaderResourceView(mp1DTex.Get(), &mSRVDesc, - mpShaderResourceView.ReleaseAndGetAddressOf()) - : S_FALSE); - - this->_setFinalAttributes(desc.Width, 1, 1, D3D11Mappings::_getPF(desc.Format), desc.MiscFlags); + D3D11RenderSystem* rsys = static_cast(Root::getSingleton().getRenderSystem()); + // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150%28v=vs.85%29.aspx#ID3D11Device_CreateTexture2D + // 10Level9, When using D3D11_BIND_SHADER_RESOURCE, SampleDesc.Count must be 1. + if (rsys->_getFeatureLevel() >= D3D_FEATURE_LEVEL_10_0 || (mUsage & TU_NOT_SAMPLED)) + rsys->determineFSAASettings(mFSAA, mFSAAHint, mD3DFormat, &mFSAAType); } - //--------------------------------------------------------------------- - inline bool IsPowerOfTwo(unsigned int n) { return ((n&(n-1))==0); } - //--------------------------------------------------------------------- - void D3D11Texture::_create2DTex() - { - // we must have those defined here - assert(mSrcWidth > 0 || mSrcHeight > 0); - - // determine total number of mipmaps including main one (d3d11 convention) - UINT numMips = (mNumMipmaps == MIP_UNLIMITED || (1U << mNumMipmaps) > std::max(mSrcWidth, mSrcHeight)) ? 0 : mNumMipmaps + 1; - if(D3D11Mappings::_isBinaryCompressedFormat(mD3DFormat) && numMips > 1) - numMips = std::max(1U, numMips - 2); - - D3D11_TEXTURE2D_DESC desc; - desc.Width = static_cast(mSrcWidth); - desc.Height = static_cast(mSrcHeight); - desc.MipLevels = numMips; - desc.ArraySize = mDepth == 0 ? 1 : mDepth; - desc.Format = mD3DFormat; - desc.SampleDesc = mFSAAType; - desc.Usage = D3D11Mappings::_getUsage(_getTextureUsage()); - desc.BindFlags = D3D11Mappings::_getTextureBindFlags(mD3DFormat, _getTextureUsage()); - desc.CPUAccessFlags = D3D11Mappings::_getAccessFlags(_getTextureUsage()); - desc.MiscFlags = D3D11Mappings::_getTextureMiscFlags(desc.BindFlags, getTextureType(), _getTextureUsage()); - - if (PixelUtil::isDepth(mFormat)) - { - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_DEPTH_STENCIL; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.CPUAccessFlags = 0; - desc.MiscFlags = 0; - } - - if (this->getTextureType() == TEX_TYPE_CUBE_MAP) - { - desc.ArraySize = 6; - } + // load based on tex.type + switch (this->getTextureType()) + { + case TEX_TYPE_1D: + { D3D11RenderSystem* rs = (D3D11RenderSystem*)Root::getSingleton().getRenderSystem(); - if(rs->_getFeatureLevel() < D3D_FEATURE_LEVEL_10_0) + if (rs->_getFeatureLevel() >= D3D_FEATURE_LEVEL_10_0) { - // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150%28v=vs.85%29.aspx#ID3D11Device_CreateTexture2D - // ...If MipCount > 1, Dimensions must be integral power of two... - if(!IsPowerOfTwo(desc.Width) || !IsPowerOfTwo(desc.Height)) - { - desc.MipLevels = 1; - } - -#if 0 - // there seems to be a Microsoft bug that crash if you do GenerateMips in a level less then D3D_FEATURE_LEVEL_10_0 - // is this still true or addressed by the code above? - desc.MipLevels = 1; -#endif - } - - // create the texture - HRESULT hr = mDevice->CreateTexture2D( - &desc, - NULL,// data pointer - mp2DTex.ReleaseAndGetAddressOf()); - // check result and except if failed - if (FAILED(hr) || mDevice.isError()) - { - this->unloadImpl(); - String errorDescription = mDevice.getErrorDescription(hr); - OGRE_EXCEPT_EX(Exception::ERR_RENDERINGAPI_ERROR, hr, - "Error creating texture\nError Description:" + errorDescription, - "D3D11Texture::_create2DTex" ); + this->_create1DTex(); + break; // For Feature levels that do not support 1D textures, revert to creating a 2D texture. } - - //set the base texture we'll use in the render system - _queryInterface(mp2DTex, &mpTex); - - _create2DResourceView(); } - //---------------------------------------------------------------------------- - /// - /// Initializes a Direct3D 11 2D texture surface by querying interfaces, retrieving a shared handle, and creating a - /// render target view. - /// - void D3D11Texture::_create2DTexWithSurface() + case TEX_TYPE_2D: + case TEX_TYPE_CUBE_MAP: + case TEX_TYPE_2D_ARRAY: + this->_create2DTex(); + break; + case TEX_TYPE_3D: + this->_create3DTex(); + break; + default: + this->unloadImpl(); + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Unknown texture type", "D3D11Texture::createInternalResources"); + } +} +//--------------------------------------------------------------------- +void D3D11Texture::_create1DTex() +{ + // we must have those defined here + assert(mSrcWidth > 0 || mSrcHeight > 0); + + // determine total number of mipmaps including main one (d3d11 convention) + UINT numMips = (mNumMipmaps == MIP_UNLIMITED || (1U << mNumMipmaps) > mSrcWidth) ? 0 : mNumMipmaps + 1; + + D3D11_TEXTURE1D_DESC desc; + desc.Width = static_cast(mSrcWidth); + desc.MipLevels = numMips; + desc.ArraySize = 1; + desc.Format = mD3DFormat; + desc.Usage = D3D11Mappings::_getUsage(_getTextureUsage()); + desc.BindFlags = D3D11Mappings::_getTextureBindFlags(mD3DFormat, _getTextureUsage()); + desc.CPUAccessFlags = D3D11Mappings::_getAccessFlags(_getTextureUsage()); + desc.MiscFlags = D3D11Mappings::_getTextureMiscFlags(desc.BindFlags, getTextureType(), _getTextureUsage()); + + // create the texture + HRESULT hr = mDevice->CreateTexture1D(&desc, NULL, + mp1DTex.ReleaseAndGetAddressOf()); // data pointer + // check result and except if failed + if (FAILED(hr) || mDevice.isError()) { - if (!mSurface) - throw std::runtime_error("Invalid resource provided."); + this->unloadImpl(); + String errorDescription = mDevice.getErrorDescription(hr); + OGRE_EXCEPT_EX(Exception::ERR_RENDERINGAPI_ERROR, hr, + "Error creating texture\nError Description:" + errorDescription, "D3D11Texture::_create1DTex"); + } + _queryInterface(mp1DTex, &mpTex); + _create1DResourceView(); +} +//--------------------------------------------------------------------- +void D3D11Texture::_create1DResourceView() +{ + // set final tex. attributes from tex. description + // they may differ from the source image !!! + HRESULT hr; + D3D11_TEXTURE1D_DESC desc; + + // set final tex. attributes from tex. description + // they may differ from the source image !!! + mp1DTex->GetDesc(&desc); + mNumMipmaps = desc.MipLevels - 1; + + ZeroMemory(&mSRVDesc, sizeof(mSRVDesc)); + mSRVDesc.Format = desc.Format; + mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D; + mSRVDesc.Texture1D.MipLevels = desc.MipLevels; + OGRE_CHECK_DX_ERROR( + (desc.BindFlags & D3D11_BIND_SHADER_RESOURCE) + ? mDevice->CreateShaderResourceView(mp1DTex.Get(), &mSRVDesc, mpShaderResourceView.ReleaseAndGetAddressOf()) + : S_FALSE); + + this->_setFinalAttributes(desc.Width, 1, 1, D3D11Mappings::_getPF(desc.Format), desc.MiscFlags); +} +//--------------------------------------------------------------------- +inline bool IsPowerOfTwo(unsigned int n) { return ((n & (n - 1)) == 0); } +//--------------------------------------------------------------------- +void D3D11Texture::_create2DTex() +{ + if (NULL != mSurface) + { HRESULT hr = S_OK; IUnknown* pUnk = (IUnknown*)mSurface; @@ -369,334 +273,399 @@ namespace Ogre if (FAILED(hr)) throw std::runtime_error("Failed to create ID3D11RenderTargetView. Verify that the texture is valid, " "properly initialized, and compatible with RenderTargetView creation."); - - _queryInterface(mp2DTex, &mpTex); - - _create2DResourceView(); } - //---------------------------------------------------------------------------- - void D3D11Texture::_create2DResourceView() - { - // set final tex. attributes from tex. description - // they may differ from the source image !!! - HRESULT hr; - D3D11_TEXTURE2D_DESC desc; - mp2DTex->GetDesc(&desc); - mNumMipmaps = desc.MipLevels - 1; - - ZeroMemory( &mSRVDesc, sizeof(mSRVDesc) ); - mSRVDesc.Format = desc.Format == DXGI_FORMAT_R32_TYPELESS ? DXGI_FORMAT_R32_FLOAT : desc.Format; - - switch(this->getTextureType()) - { - case TEX_TYPE_CUBE_MAP: - mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; - mSRVDesc.TextureCube.MipLevels = desc.MipLevels; - mSRVDesc.TextureCube.MostDetailedMip = 0; - break; - - case TEX_TYPE_2D_ARRAY: - if (mFSAAType.Count > 1) - { - mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY; - mSRVDesc.Texture2DMSArray.FirstArraySlice = 0; - mSRVDesc.Texture2DMSArray.ArraySize = desc.ArraySize; - } - else - { - mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; - mSRVDesc.Texture2DArray.MostDetailedMip = 0; - mSRVDesc.Texture2DArray.MipLevels = desc.MipLevels; - mSRVDesc.Texture2DArray.FirstArraySlice = 0; - mSRVDesc.Texture2DArray.ArraySize = desc.ArraySize; - } - break; - - case TEX_TYPE_2D: - case TEX_TYPE_2D_WITH_SURFACE: - case TEX_TYPE_1D: // For Feature levels that do not support 1D textures, revert to creating a 2D texture. - if (mFSAAType.Count > 1) - { - mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS; - } - else - { - mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - mSRVDesc.Texture2D.MostDetailedMip = 0; - mSRVDesc.Texture2D.MipLevels = desc.MipLevels; - } - break; - } - - OGRE_CHECK_DX_ERROR( - (desc.BindFlags & D3D11_BIND_SHADER_RESOURCE) - ? mDevice->CreateShaderResourceView(mp2DTex.Get(), &mSRVDesc, - mpShaderResourceView.ReleaseAndGetAddressOf()) - : S_FALSE); - - this->_setFinalAttributes(desc.Width, desc.Height, desc.ArraySize / getNumFaces(), D3D11Mappings::_getPF(desc.Format), desc.MiscFlags); - } - - void D3D11Texture::createShaderAccessPoint(uint bindPoint, TextureAccess access, int mipmapLevel, - int textureArrayIndex, PixelFormat format) - { - if(mpUnorderedAccessView) - return; - D3D11_UNORDERED_ACCESS_VIEW_DESC descUAV; - descUAV.Format = mD3DFormat; - descUAV.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D; - descUAV.Texture2D.MipSlice = static_cast( mipmapLevel ); - - mDevice->CreateUnorderedAccessView( mp2DTex.Get(), &descUAV, mpUnorderedAccessView.ReleaseAndGetAddressOf() ); - } - //--------------------------------------------------------------------- - void D3D11Texture::_create3DTex() + else { // we must have those defined here - assert(mWidth > 0 && mHeight > 0 && mDepth>0); + assert(mSrcWidth > 0 || mSrcHeight > 0); // determine total number of mipmaps including main one (d3d11 convention) - UINT numMips = (mNumMipmaps == MIP_UNLIMITED || (1U << mNumMipmaps) > std::max(std::max(mSrcWidth, mSrcHeight), mDepth)) ? 0 : mNumMipmaps + 1; + UINT numMips = (mNumMipmaps == MIP_UNLIMITED || (1U << mNumMipmaps) > std::max(mSrcWidth, mSrcHeight)) + ? 0 + : mNumMipmaps + 1; + if (D3D11Mappings::_isBinaryCompressedFormat(mD3DFormat) && numMips > 1) + numMips = std::max(1U, numMips - 2); - D3D11_TEXTURE3D_DESC desc; - desc.Width = static_cast(mSrcWidth); - desc.Height = static_cast(mSrcHeight); - desc.Depth = static_cast(mDepth); - desc.MipLevels = numMips; - desc.Format = mD3DFormat; - desc.Usage = D3D11Mappings::_getUsage(_getTextureUsage()); - desc.BindFlags = D3D11Mappings::_getTextureBindFlags(mD3DFormat, _getTextureUsage()); + D3D11_TEXTURE2D_DESC desc; + desc.Width = static_cast(mSrcWidth); + desc.Height = static_cast(mSrcHeight); + desc.MipLevels = numMips; + desc.ArraySize = mDepth == 0 ? 1 : mDepth; + desc.Format = mD3DFormat; + desc.SampleDesc = mFSAAType; + desc.Usage = D3D11Mappings::_getUsage(_getTextureUsage()); + desc.BindFlags = D3D11Mappings::_getTextureBindFlags(mD3DFormat, _getTextureUsage()); + desc.CPUAccessFlags = D3D11Mappings::_getAccessFlags(_getTextureUsage()); + desc.MiscFlags = D3D11Mappings::_getTextureMiscFlags(desc.BindFlags, getTextureType(), _getTextureUsage()); - D3D11RenderSystem* rsys = static_cast(Root::getSingleton().getRenderSystem()); - if (rsys->_getFeatureLevel() < D3D_FEATURE_LEVEL_10_0) - desc.BindFlags &= ~D3D11_BIND_RENDER_TARGET; + if (PixelUtil::isDepth(mFormat)) + { + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_DEPTH_STENCIL; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + } + + if (this->getTextureType() == TEX_TYPE_CUBE_MAP) + { + desc.ArraySize = 6; + } + + D3D11RenderSystem* rs = (D3D11RenderSystem*)Root::getSingleton().getRenderSystem(); + if (rs->_getFeatureLevel() < D3D_FEATURE_LEVEL_10_0) + { + // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150%28v=vs.85%29.aspx#ID3D11Device_CreateTexture2D + // ...If MipCount > 1, Dimensions must be integral power of two... + if (!IsPowerOfTwo(desc.Width) || !IsPowerOfTwo(desc.Height)) + { + desc.MipLevels = 1; + } - desc.CPUAccessFlags = D3D11Mappings::_getAccessFlags(_getTextureUsage()); - desc.MiscFlags = 0; +#if 0 + // there seems to be a Microsoft bug that crash if you do GenerateMips in a level less then D3D_FEATURE_LEVEL_10_0 + // is this still true or addressed by the code above? + desc.MipLevels = 1; +#endif + } // create the texture - HRESULT hr = mDevice->CreateTexture3D( - &desc, - NULL, - mp3DTex.ReleaseAndGetAddressOf()); // data pointer + HRESULT hr = mDevice->CreateTexture2D(&desc, + NULL, // data pointer + mp2DTex.ReleaseAndGetAddressOf()); // check result and except if failed if (FAILED(hr) || mDevice.isError()) { this->unloadImpl(); String errorDescription = mDevice.getErrorDescription(hr); - OGRE_EXCEPT_EX(Exception::ERR_RENDERINGAPI_ERROR, hr, - "Error creating texture\nError Description:" + errorDescription, - "D3D11Texture::_create3DTex" ); + OGRE_EXCEPT_EX(Exception::ERR_RENDERINGAPI_ERROR, hr, + "Error creating texture\nError Description:" + errorDescription, + "D3D11Texture::_create2DTex"); } - - _queryInterface(mp3DTex, &mpTex); - _create3DResourceView(); } - //------------------------------------------------------------------------------- - void D3D11Texture::_create3DResourceView() - { - // set final tex. attributes from tex. description - // they may differ from the source image !!! - HRESULT hr; - D3D11_TEXTURE3D_DESC desc; - mp3DTex->GetDesc(&desc); - mNumMipmaps = desc.MipLevels - 1; - - ZeroMemory( &mSRVDesc, sizeof(mSRVDesc) ); - mSRVDesc.Format = desc.Format; - mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; - mSRVDesc.Texture3D.MostDetailedMip = 0; - mSRVDesc.Texture3D.MipLevels = desc.MipLevels; - OGRE_CHECK_DX_ERROR( - (desc.BindFlags & D3D11_BIND_SHADER_RESOURCE) - ? mDevice->CreateShaderResourceView(mp3DTex.Get(), &mSRVDesc, - mpShaderResourceView.ReleaseAndGetAddressOf()) - : S_FALSE); - this->_setFinalAttributes(desc.Width, desc.Height, desc.Depth, D3D11Mappings::_getPF(desc.Format), desc.MiscFlags); - } - //------------------------------------------------------------------------------- - void D3D11Texture::_setFinalAttributes(unsigned long width, unsigned long height, - unsigned long depth, PixelFormat format, UINT miscflags) - { - // set target texture attributes - mHeight = height; - mWidth = width; - mDepth = depth; - mFormat = format; - mAutoMipMapGeneration = miscflags & D3D11_RESOURCE_MISC_GENERATE_MIPS; - - // Update size (the final size, including temp space because in consumed memory) - // this is needed in Resource class - mSize = calculateSize(); - - // say to the world what we are doing - if (mWidth != mSrcWidth || - mHeight != mSrcHeight) - { - LogManager::getSingleton().logMessage("D3D11: ***** Dimensions altered by the render system"); - LogManager::getSingleton().logMessage("D3D11: ***** Source image dimensions : " + StringConverter::toString(mSrcWidth) + "x" + StringConverter::toString(mSrcHeight)); - LogManager::getSingleton().logMessage("D3D11: ***** Texture dimensions : " + StringConverter::toString(mWidth) + "x" + StringConverter::toString(mHeight)); - } + // set the base texture we'll use in the render system + _queryInterface(mp2DTex, &mpTex); - // Create list of subsurfaces for getBuffer() - _createSurfaceList(); - } - //--------------------------------------------------------------------- - void D3D11Texture::_createSurfaceList(void) - { - // Create new list of surfaces - mSurfaceList.clear(); - size_t depth = mDepth; + _create2DResourceView(); +} +//---------------------------------------------------------------------------- +void D3D11Texture::_create2DResourceView() +{ + // set final tex. attributes from tex. description + // they may differ from the source image !!! + HRESULT hr; + D3D11_TEXTURE2D_DESC desc; + mp2DTex->GetDesc(&desc); + mNumMipmaps = desc.MipLevels - 1; + + ZeroMemory(&mSRVDesc, sizeof(mSRVDesc)); + mSRVDesc.Format = desc.Format == DXGI_FORMAT_R32_TYPELESS ? DXGI_FORMAT_R32_FLOAT : desc.Format; - for(size_t face=0; facegetTextureType()) + { + case TEX_TYPE_CUBE_MAP: + mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; + mSRVDesc.TextureCube.MipLevels = desc.MipLevels; + mSRVDesc.TextureCube.MostDetailedMip = 0; + break; + + case TEX_TYPE_2D_ARRAY: + if (mFSAAType.Count > 1) { - size_t width = mWidth; - size_t height = mHeight; - for(size_t mip=0; mip<=mNumMipmaps; ++mip) - { - - D3D11HardwarePixelBuffer *buffer; - buffer = new D3D11HardwarePixelBuffer( - this, // parentTexture - mDevice, // device - mip, - width, - height, - depth, - face, - mFormat, - (HardwareBuffer::Usage)mUsage - ); - - mSurfaceList.push_back(HardwarePixelBufferSharedPtr(buffer)); - - if(width > 1) width /= 2; - if(height > 1) height /= 2; - if(depth > 1 && getTextureType() != TEX_TYPE_2D_ARRAY) depth /= 2; - } + mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY; + mSRVDesc.Texture2DMSArray.FirstArraySlice = 0; + mSRVDesc.Texture2DMSArray.ArraySize = desc.ArraySize; } - } - //--------------------------------------------------------------------- - // D3D11RenderTexture - //--------------------------------------------------------------------- - void D3D11RenderTexture::rebind( D3D11HardwarePixelBuffer *buffer ) - { - mBuffer = buffer; - mWidth = (unsigned int) mBuffer->getWidth(); - mHeight = (unsigned int) mBuffer->getHeight(); - - ID3D11Resource * pBackBuffer = buffer->getParentTexture()->getTextureResource(); - - D3D11_RENDER_TARGET_VIEW_DESC RTVDesc; - ZeroMemory( &RTVDesc, sizeof(RTVDesc) ); - - RTVDesc.Format = buffer->getParentTexture()->getShaderResourceViewDesc().Format; - switch(buffer->getParentTexture()->getShaderResourceViewDesc().ViewDimension) + else { - case D3D11_SRV_DIMENSION_BUFFER: - RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_BUFFER; - break; - case D3D11_SRV_DIMENSION_TEXTURE1D: - RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1D; - break; - case D3D11_SRV_DIMENSION_TEXTURE1DARRAY: - RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1DARRAY; - break; - case D3D11_SRV_DIMENSION_TEXTURECUBE: - RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; - RTVDesc.Texture2DArray.FirstArraySlice = buffer->getFace(); - RTVDesc.Texture2DArray.ArraySize = 1; - break; - case D3D11_SRV_DIMENSION_TEXTURE2D: - RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; - break; - case D3D11_SRV_DIMENSION_TEXTURE2DARRAY: - RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; - RTVDesc.Texture2DArray.FirstArraySlice = mZOffset; - RTVDesc.Texture2DArray.ArraySize = 1; - break; - case D3D11_SRV_DIMENSION_TEXTURE2DMS: - RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; - break; - case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY: - RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY; - RTVDesc.Texture2DArray.FirstArraySlice = mZOffset; - RTVDesc.Texture2DArray.ArraySize = 1; - break; - case D3D11_SRV_DIMENSION_TEXTURE3D: - RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; - RTVDesc.Texture3D.FirstWSlice = mZOffset; - RTVDesc.Texture3D.WSize = 1; - break; - default: - assert(false); + mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; + mSRVDesc.Texture2DArray.MostDetailedMip = 0; + mSRVDesc.Texture2DArray.MipLevels = desc.MipLevels; + mSRVDesc.Texture2DArray.FirstArraySlice = 0; + mSRVDesc.Texture2DArray.ArraySize = desc.ArraySize; } + break; - if (!PixelUtil::isDepth(mBuffer->getFormat())) + case TEX_TYPE_2D: + case TEX_TYPE_1D: // For Feature levels that do not support 1D textures, revert to creating a 2D texture. + if (mFSAAType.Count > 1) { - OGRE_CHECK_DX_ERROR(mDevice->CreateRenderTargetView(pBackBuffer, &RTVDesc, - mRenderTargetView.ReleaseAndGetAddressOf())); - return; + mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS; } - - // also create DSV for depth textures - D3D11_TEXTURE2D_DESC BBDesc; - getSurface()->GetDesc(&BBDesc); - - // Create the depth stencil view - D3D11_DEPTH_STENCIL_VIEW_DESC descDSV = {}; - descDSV.Format = DXGI_FORMAT_D32_FLOAT; - descDSV.ViewDimension = (BBDesc.SampleDesc.Count > 1) ? D3D11_DSV_DIMENSION_TEXTURE2DMS : D3D11_DSV_DIMENSION_TEXTURE2D; - descDSV.Flags = 0 /* D3D11_DSV_READ_ONLY_DEPTH | D3D11_DSV_READ_ONLY_STENCIL */; // TODO: Allows bind depth buffer as depth view AND texture simultaneously. - descDSV.Texture2D.MipSlice = 0; - - ID3D11DepthStencilView *depthStencilView; - OGRE_CHECK_DX_ERROR(mDevice->CreateDepthStencilView(pBackBuffer, &descDSV, &depthStencilView )); - - D3D11RenderSystem* rs = (D3D11RenderSystem*)Root::getSingleton().getRenderSystem(); - mDepthBuffer = - new D3D11DepthBuffer(DepthBuffer::POOL_NO_DEPTH, rs, depthStencilView, mWidth, mHeight, - BBDesc.SampleDesc.Count, BBDesc.SampleDesc.Quality, false); - mDepthBuffer->_notifyRenderTargetAttached(this); + else + { + mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + mSRVDesc.Texture2D.MostDetailedMip = 0; + mSRVDesc.Texture2D.MipLevels = desc.MipLevels; + } + break; } - uint D3D11RenderTexture::getNumberOfViews() const { return PixelUtil::isDepth(mBuffer->getFormat()) ? 0 : 1; } + OGRE_CHECK_DX_ERROR( + (desc.BindFlags & D3D11_BIND_SHADER_RESOURCE) + ? mDevice->CreateShaderResourceView(mp2DTex.Get(), &mSRVDesc, mpShaderResourceView.ReleaseAndGetAddressOf()) + : S_FALSE); - ID3D11Texture2D* D3D11RenderTexture::getSurface(uint index) const - { - return index == 0 ? static_cast(mBuffer)->getParentTexture()->GetTex2D() - : NULL; - } + this->_setFinalAttributes(desc.Width, desc.Height, desc.ArraySize / getNumFaces(), + D3D11Mappings::_getPF(desc.Format), desc.MiscFlags); +} - ID3D11RenderTargetView* D3D11RenderTexture::getRenderTargetView(uint index) const +void D3D11Texture::createShaderAccessPoint(uint bindPoint, TextureAccess access, int mipmapLevel, int textureArrayIndex, + PixelFormat format) +{ + if (mpUnorderedAccessView) + return; + D3D11_UNORDERED_ACCESS_VIEW_DESC descUAV; + descUAV.Format = mD3DFormat; + descUAV.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D; + descUAV.Texture2D.MipSlice = static_cast(mipmapLevel); + + mDevice->CreateUnorderedAccessView(mp2DTex.Get(), &descUAV, mpUnorderedAccessView.ReleaseAndGetAddressOf()); +} +//--------------------------------------------------------------------- +void D3D11Texture::_create3DTex() +{ + // we must have those defined here + assert(mWidth > 0 && mHeight > 0 && mDepth > 0); + + // determine total number of mipmaps including main one (d3d11 convention) + UINT numMips = + (mNumMipmaps == MIP_UNLIMITED || (1U << mNumMipmaps) > std::max(std::max(mSrcWidth, mSrcHeight), mDepth)) + ? 0 + : mNumMipmaps + 1; + + D3D11_TEXTURE3D_DESC desc; + desc.Width = static_cast(mSrcWidth); + desc.Height = static_cast(mSrcHeight); + desc.Depth = static_cast(mDepth); + desc.MipLevels = numMips; + desc.Format = mD3DFormat; + desc.Usage = D3D11Mappings::_getUsage(_getTextureUsage()); + desc.BindFlags = D3D11Mappings::_getTextureBindFlags(mD3DFormat, _getTextureUsage()); + + D3D11RenderSystem* rsys = static_cast(Root::getSingleton().getRenderSystem()); + if (rsys->_getFeatureLevel() < D3D_FEATURE_LEVEL_10_0) + desc.BindFlags &= ~D3D11_BIND_RENDER_TARGET; + + desc.CPUAccessFlags = D3D11Mappings::_getAccessFlags(_getTextureUsage()); + desc.MiscFlags = 0; + + // create the texture + HRESULT hr = mDevice->CreateTexture3D(&desc, NULL, + mp3DTex.ReleaseAndGetAddressOf()); // data pointer + // check result and except if failed + if (FAILED(hr) || mDevice.isError()) { - return index == 0 ? mRenderTargetView.Get() : NULL; + this->unloadImpl(); + String errorDescription = mDevice.getErrorDescription(hr); + OGRE_EXCEPT_EX(Exception::ERR_RENDERINGAPI_ERROR, hr, + "Error creating texture\nError Description:" + errorDescription, "D3D11Texture::_create3DTex"); } - D3D11RenderTexture::D3D11RenderTexture( const String &name, D3D11HardwarePixelBuffer *buffer, uint32 zoffset, D3D11Device & device ) - : RenderTexture(buffer, zoffset) - , mDevice(device) + _queryInterface(mp3DTex, &mpTex); + _create3DResourceView(); +} +//------------------------------------------------------------------------------- +void D3D11Texture::_create3DResourceView() +{ + // set final tex. attributes from tex. description + // they may differ from the source image !!! + HRESULT hr; + D3D11_TEXTURE3D_DESC desc; + mp3DTex->GetDesc(&desc); + mNumMipmaps = desc.MipLevels - 1; + + ZeroMemory(&mSRVDesc, sizeof(mSRVDesc)); + mSRVDesc.Format = desc.Format; + mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; + mSRVDesc.Texture3D.MostDetailedMip = 0; + mSRVDesc.Texture3D.MipLevels = desc.MipLevels; + OGRE_CHECK_DX_ERROR( + (desc.BindFlags & D3D11_BIND_SHADER_RESOURCE) + ? mDevice->CreateShaderResourceView(mp3DTex.Get(), &mSRVDesc, mpShaderResourceView.ReleaseAndGetAddressOf()) + : S_FALSE); + + this->_setFinalAttributes(desc.Width, desc.Height, desc.Depth, D3D11Mappings::_getPF(desc.Format), desc.MiscFlags); +} +//------------------------------------------------------------------------------- +void D3D11Texture::_setFinalAttributes(unsigned long width, unsigned long height, unsigned long depth, + PixelFormat format, UINT miscflags) +{ + // set target texture attributes + mHeight = height; + mWidth = width; + mDepth = depth; + mFormat = format; + mAutoMipMapGeneration = miscflags & D3D11_RESOURCE_MISC_GENERATE_MIPS; + + // Update size (the final size, including temp space because in consumed memory) + // this is needed in Resource class + mSize = calculateSize(); + + // say to the world what we are doing + if (mWidth != mSrcWidth || mHeight != mSrcHeight) { - mName = name; - rebind(buffer); + LogManager::getSingleton().logMessage("D3D11: ***** Dimensions altered by the render system"); + LogManager::getSingleton().logMessage( + "D3D11: ***** Source image dimensions : " + StringConverter::toString(mSrcWidth) + "x" + + StringConverter::toString(mSrcHeight)); + LogManager::getSingleton().logMessage("D3D11: ***** Texture dimensions : " + StringConverter::toString(mWidth) + + "x" + StringConverter::toString(mHeight)); } - //--------------------------------------------------------------------- - D3D11RenderTexture::~D3D11RenderTexture() + + // Create list of subsurfaces for getBuffer() + _createSurfaceList(); +} +//--------------------------------------------------------------------- +void D3D11Texture::_createSurfaceList(void) +{ + // Create new list of surfaces + mSurfaceList.clear(); + size_t depth = mDepth; + + for (size_t face = 0; face < getNumFaces(); ++face) { - if (mDepthBuffer && PixelUtil::isDepth (mBuffer->getFormat ())) - delete mDepthBuffer; + size_t width = mWidth; + size_t height = mHeight; + for (size_t mip = 0; mip <= mNumMipmaps; ++mip) + { + + D3D11HardwarePixelBuffer* buffer; + buffer = + new D3D11HardwarePixelBuffer(this, // parentTexture + mDevice, // device + mip, width, height, depth, face, mFormat, (HardwareBuffer::Usage)mUsage); + + mSurfaceList.push_back(HardwarePixelBufferSharedPtr(buffer)); + + if (width > 1) + width /= 2; + if (height > 1) + height /= 2; + if (depth > 1 && getTextureType() != TEX_TYPE_2D_ARRAY) + depth /= 2; + } } +} +//--------------------------------------------------------------------- +// D3D11RenderTexture +//--------------------------------------------------------------------- +void D3D11RenderTexture::rebind(D3D11HardwarePixelBuffer* buffer) +{ + mBuffer = buffer; + mWidth = (unsigned int)mBuffer->getWidth(); + mHeight = (unsigned int)mBuffer->getHeight(); + + ID3D11Resource* pBackBuffer = buffer->getParentTexture()->getTextureResource(); - //--------------------------------------------------------------------- - void D3D11RenderTexture::notifyDeviceLost(D3D11Device* device) + D3D11_RENDER_TARGET_VIEW_DESC RTVDesc; + ZeroMemory(&RTVDesc, sizeof(RTVDesc)); + + RTVDesc.Format = buffer->getParentTexture()->getShaderResourceViewDesc().Format; + switch (buffer->getParentTexture()->getShaderResourceViewDesc().ViewDimension) { + case D3D11_SRV_DIMENSION_BUFFER: + RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_BUFFER; + break; + case D3D11_SRV_DIMENSION_TEXTURE1D: + RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1D; + break; + case D3D11_SRV_DIMENSION_TEXTURE1DARRAY: + RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1DARRAY; + break; + case D3D11_SRV_DIMENSION_TEXTURECUBE: + RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + RTVDesc.Texture2DArray.FirstArraySlice = buffer->getFace(); + RTVDesc.Texture2DArray.ArraySize = 1; + break; + case D3D11_SRV_DIMENSION_TEXTURE2D: + RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + break; + case D3D11_SRV_DIMENSION_TEXTURE2DARRAY: + RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + RTVDesc.Texture2DArray.FirstArraySlice = mZOffset; + RTVDesc.Texture2DArray.ArraySize = 1; + break; + case D3D11_SRV_DIMENSION_TEXTURE2DMS: + RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; + break; + case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY: + RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY; + RTVDesc.Texture2DArray.FirstArraySlice = mZOffset; + RTVDesc.Texture2DArray.ArraySize = 1; + break; + case D3D11_SRV_DIMENSION_TEXTURE3D: + RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; + RTVDesc.Texture3D.FirstWSlice = mZOffset; + RTVDesc.Texture3D.WSize = 1; + break; + default: + assert(false); } - //--------------------------------------------------------------------- - void D3D11RenderTexture::notifyDeviceRestored(D3D11Device* device) + + if (!PixelUtil::isDepth(mBuffer->getFormat())) { - rebind(static_cast(mBuffer)); + OGRE_CHECK_DX_ERROR( + mDevice->CreateRenderTargetView(pBackBuffer, &RTVDesc, mRenderTargetView.ReleaseAndGetAddressOf())); + return; } - //--------------------------------------------------------------------- - void D3D11RenderTexture::doFlush() { mDevice.Flush(); } -} \ No newline at end of file + + // also create DSV for depth textures + D3D11_TEXTURE2D_DESC BBDesc; + getSurface()->GetDesc(&BBDesc); + + // Create the depth stencil view + D3D11_DEPTH_STENCIL_VIEW_DESC descDSV = {}; + descDSV.Format = DXGI_FORMAT_D32_FLOAT; + descDSV.ViewDimension = + (BBDesc.SampleDesc.Count > 1) ? D3D11_DSV_DIMENSION_TEXTURE2DMS : D3D11_DSV_DIMENSION_TEXTURE2D; + descDSV.Flags = + 0 /* D3D11_DSV_READ_ONLY_DEPTH | D3D11_DSV_READ_ONLY_STENCIL */; // TODO: Allows bind depth buffer as depth view + // AND texture simultaneously. + descDSV.Texture2D.MipSlice = 0; + + ID3D11DepthStencilView* depthStencilView; + OGRE_CHECK_DX_ERROR(mDevice->CreateDepthStencilView(pBackBuffer, &descDSV, &depthStencilView)); + + D3D11RenderSystem* rs = (D3D11RenderSystem*)Root::getSingleton().getRenderSystem(); + mDepthBuffer = new D3D11DepthBuffer(DepthBuffer::POOL_NO_DEPTH, rs, depthStencilView, mWidth, mHeight, + BBDesc.SampleDesc.Count, BBDesc.SampleDesc.Quality, false); + mDepthBuffer->_notifyRenderTargetAttached(this); +} + +uint D3D11RenderTexture::getNumberOfViews() const { return PixelUtil::isDepth(mBuffer->getFormat()) ? 0 : 1; } + +ID3D11Texture2D* D3D11RenderTexture::getSurface(uint index) const +{ + return index == 0 ? static_cast(mBuffer)->getParentTexture()->GetTex2D() : NULL; +} + +ID3D11RenderTargetView* D3D11RenderTexture::getRenderTargetView(uint index) const +{ + return index == 0 ? mRenderTargetView.Get() : NULL; +} + +D3D11RenderTexture::D3D11RenderTexture(const String& name, D3D11HardwarePixelBuffer* buffer, uint32 zoffset, + D3D11Device& device) + : RenderTexture(buffer, zoffset), mDevice(device) +{ + mName = name; + rebind(buffer); +} +//--------------------------------------------------------------------- +D3D11RenderTexture::~D3D11RenderTexture() +{ + if (mDepthBuffer && PixelUtil::isDepth(mBuffer->getFormat())) + delete mDepthBuffer; +} + +//--------------------------------------------------------------------- +void D3D11RenderTexture::notifyDeviceLost(D3D11Device* device) {} +//--------------------------------------------------------------------- +void D3D11RenderTexture::notifyDeviceRestored(D3D11Device* device) +{ + rebind(static_cast(mBuffer)); +} +//--------------------------------------------------------------------- +void D3D11RenderTexture::doFlush() { mDevice.Flush(); } +} // namespace Ogre \ No newline at end of file