//--------------------------------------------------------------------- bool D3D11TextureManager::isHardwareFilteringSupported(TextureType ttype, PixelFormat format, int usage, bool preciseFormatOnly) { if (!preciseFormatOnly) format = getNativeFormat(ttype, format, usage); D3D11RenderSystem* rs = static_cast<D3D11RenderSystem*>( Root::getSingleton().getRenderSystem()); return rs->_checkTextureFilteringSupported(ttype, format, usage); }
//--------------------------------------------------------------------- HRESULT D3D11RenderWindowHwnd::_createSwapChainImpl(IDXGIDeviceN* pDXGIDevice) { ZeroMemory( &mSwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC_N) ); DXGI_FORMAT format = DXGI_FORMAT_R8G8B8A8_UNORM; mSwapChainDesc.BufferDesc.Width = mWidth; mSwapChainDesc.BufferDesc.Height = mHeight; mSwapChainDesc.BufferDesc.Format = format; mSwapChainDesc.BufferDesc.RefreshRate.Numerator=0; mSwapChainDesc.BufferDesc.RefreshRate.Denominator = 0; mSwapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; mSwapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; mSwapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH ; // triple buffer if VSync is on mSwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; mSwapChainDesc.BufferCount = mVSync ? 2 : 1; mSwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD ; mSwapChainDesc.OutputWindow = mHWnd; mSwapChainDesc.Windowed = !mIsFullScreen; D3D11RenderSystem* rsys = static_cast<D3D11RenderSystem*>(Root::getSingleton().getRenderSystem()); rsys->determineFSAASettings(mFSAA, mFSAAHint, format, &mFSAAType); mSwapChainDesc.SampleDesc.Count = mFSAAType.Count; mSwapChainDesc.SampleDesc.Quality = mFSAAType.Quality; if (!mVSync && !mIsFullScreen) { // NB not using vsync in windowed mode in D3D11 can cause jerking at low // frame rates no matter what buffering modes are used (odd - perhaps a // timer issue in D3D11 since GL doesn't suffer from this) // low is < 200fps in this context LogManager::getSingleton().logMessage("D3D11 : WARNING - " "disabling VSync in windowed mode can cause timing issues at lower " "frame rates, turn VSync on if you observe this problem."); } HRESULT hr; // Create swap chain hr = mpDXGIFactory->CreateSwapChain(pDXGIDevice, &mSwapChainDesc, &mpSwapChain); if (FAILED(hr)) { // Try a second time, may fail the first time due to back buffer count, // which will be corrected by the runtime hr = mpDXGIFactory->CreateSwapChain(pDXGIDevice, &mSwapChainDesc, &mpSwapChain); } return hr; }
//--------------------------------------------------------------------- void D3D11RenderWindowBase::_destroySizeDependedD3DResources() { SAFE_RELEASE(mpBackBuffer); SAFE_RELEASE(mRenderTargetView); // delete manual depth buffer (depth buffer view non-owning wrapper) DepthBuffer* depthBuf = this->getDepthBuffer(); detachDepthBuffer(); D3D11RenderSystem* rsys = static_cast<D3D11RenderSystem*>(Root::getSingleton().getRenderSystem()); rsys->_removeManualDepthBuffer(depthBuf); delete depthBuf; SAFE_RELEASE(mDepthStencilView); }
//--------------------------------------------------------------------- HRESULT D3D11RenderWindowCoreWindow::_createSwapChainImpl(IDXGIDeviceN* pDXGIDevice) { DXGI_FORMAT format = DXGI_FORMAT_B8G8R8A8_UNORM; mSwapChainDesc.Width = 0; // Use automatic sizing. mSwapChainDesc.Height = 0; mSwapChainDesc.Format = format; mSwapChainDesc.Stereo = false; // triple buffer if VSync is on mSwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; #if (OGRE_PLATFORM == OGRE_PLATFORM_WINRT) && (OGRE_WINRT_TARGET_TYPE == PHONE) mSwapChainDesc.BufferCount = 1; // WP8: One buffer. mSwapChainDesc.Scaling = DXGI_SCALING_STRETCH; // WP8: Must be stretch scaling mode. mSwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; // WP8: No swap effect. #else mSwapChainDesc.BufferCount = 2; // Use two buffers to enable flip effect. mSwapChainDesc.Scaling = DXGI_SCALING_NONE; // Otherwise stretch would be used by default. mSwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // MS recommends using this swap effect for all applications. #endif mSwapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; D3D11RenderSystem* rsys = static_cast<D3D11RenderSystem*>(Root::getSingleton().getRenderSystem()); rsys->determineFSAASettings(mFSAA, mFSAAHint, format, &mFSAAType); mSwapChainDesc.SampleDesc.Count = mFSAAType.Count; mSwapChainDesc.SampleDesc.Quality = mFSAAType.Quality; // Create swap chain HRESULT hr = mpDXGIFactory->CreateSwapChainForCoreWindow(pDXGIDevice, reinterpret_cast<IUnknown*>(mCoreWindow.Get()), &mSwapChainDesc, NULL, &mpSwapChain); if (FAILED(hr)) { // Try a second time, may fail the first time due to back buffer count, // which will be corrected by the runtime hr = mpDXGIFactory->CreateSwapChainForCoreWindow(pDXGIDevice, reinterpret_cast<IUnknown*>(mCoreWindow.Get()), &mSwapChainDesc, NULL, &mpSwapChain); } if (FAILED(hr)) return hr; // Ensure that DXGI does not queue more than one frame at a time. This both reduces // latency and ensures that the application will only render after each VSync, minimizing // power consumption. hr = pDXGIDevice->SetMaximumFrameLatency(1); return hr; }
//--------------------------------------------------------------------- D3D11_TEXTURE_ADDRESS_MODE D3D11Mappings::get(TextureAddressingMode tam) { D3D11RenderSystem* rsys = static_cast<D3D11RenderSystem*>(Root::getSingleton().getRenderSystem()); if (rsys->_getFeatureLevel() == D3D_FEATURE_LEVEL_9_1) return D3D11_TEXTURE_ADDRESS_WRAP; //return D3D11_TEXTURE_ADDRESS_WRAP; switch( tam ) { case TAM_WRAP: return D3D11_TEXTURE_ADDRESS_WRAP; case TAM_MIRROR: return D3D11_TEXTURE_ADDRESS_MIRROR; case TAM_CLAMP: return D3D11_TEXTURE_ADDRESS_CLAMP; case TAM_BORDER: return D3D11_TEXTURE_ADDRESS_BORDER; } return D3D11_TEXTURE_ADDRESS_WRAP; }
//--------------------------------------------------------------------- void D3D11RenderWindowBase::_createSizeDependedD3DResources(void) { assert(mpBackBuffer && !mRenderTargetView && !mDepthStencilView); HRESULT hr; // get the backbuffer desc D3D11_TEXTURE2D_DESC BBDesc; mpBackBuffer->GetDesc( &BBDesc ); // create the render target view D3D11_RENDER_TARGET_VIEW_DESC RTVDesc; ZeroMemory( &RTVDesc, sizeof(RTVDesc) ); RTVDesc.Format = BBDesc.Format; RTVDesc.ViewDimension = mFSAA ? D3D11_RTV_DIMENSION_TEXTURE2DMS : D3D11_RTV_DIMENSION_TEXTURE2D; RTVDesc.Texture2D.MipSlice = 0; hr = mDevice->CreateRenderTargetView( mpBackBuffer, &RTVDesc, &mRenderTargetView ); if( FAILED(hr) ) { String errorDescription = mDevice.getErrorDescription(hr); OGRE_EXCEPT_EX(Exception::ERR_RENDERINGAPI_ERROR, hr, "Unable to create rendertagert view\nError Description:" + errorDescription, "D3D11RenderWindow::_createSizeDependedD3DResources"); } if( mDepthBufferPoolId != DepthBuffer::POOL_NO_DEPTH ) { // Create depth stencil texture ID3D11Texture2D* pDepthStencil = NULL; D3D11_TEXTURE2D_DESC descDepth; descDepth.Width = BBDesc.Width; descDepth.Height = BBDesc.Height; descDepth.MipLevels = 1; descDepth.ArraySize = 1; descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; descDepth.SampleDesc.Count = mFSAAType.Count; descDepth.SampleDesc.Quality = mFSAAType.Quality; descDepth.Usage = D3D11_USAGE_DEFAULT; descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL; descDepth.CPUAccessFlags = 0; descDepth.MiscFlags = 0; hr = mDevice->CreateTexture2D( &descDepth, NULL, &pDepthStencil ); if( FAILED(hr) || mDevice.isError()) { String errorDescription = mDevice.getErrorDescription(hr); OGRE_EXCEPT_EX(Exception::ERR_RENDERINGAPI_ERROR, hr, "Unable to create depth texture\nError Description:" + errorDescription, "D3D11RenderWindow::_createSizeDependedD3DResources"); } // Create the depth stencil view D3D11_DEPTH_STENCIL_VIEW_DESC descDSV; ZeroMemory( &descDSV, sizeof(D3D11_DEPTH_STENCIL_VIEW_DESC) ); descDSV.Format = descDepth.Format; descDSV.ViewDimension = mFSAA ? D3D11_DSV_DIMENSION_TEXTURE2DMS : D3D11_DSV_DIMENSION_TEXTURE2D; descDSV.Texture2D.MipSlice = 0; hr = mDevice->CreateDepthStencilView( pDepthStencil, &descDSV, &mDepthStencilView ); SAFE_RELEASE(pDepthStencil); if( FAILED(hr) ) { String errorDescription = mDevice.getErrorDescription(hr); OGRE_EXCEPT_EX(Exception::ERR_RENDERINGAPI_ERROR, hr, "Unable to create depth stencil view\nError Description:" + errorDescription, "D3D11RenderWindow::_createSizeDependedD3DResources"); } D3D11RenderSystem* rsys = static_cast<D3D11RenderSystem*>(Root::getSingleton().getRenderSystem()); DepthBuffer *depthBuf = rsys->_addManualDepthBuffer( mDepthStencilView, mWidth, mHeight, mFSAAType.Count, mFSAAType.Quality ); //Don't forget we want this window to use _this_ depth buffer this->attachDepthBuffer( depthBuf ); } }
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { D3D11RenderSystem* rsys = static_cast<D3D11RenderSystem*>(Core::getSingleton().getRenderSystem()); return rsys->MsgProc(hwnd, msg, wParam, lParam); }
//--------------------------------------------------------------------- void D3D11RenderWindow::createD3DResources(void) { if (mIsSwapChain && mDevice.isNull()) { OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Secondary window has not been given the device from the primary!", "D3D11RenderWindow::createD3DResources"); } ZeroMemory( &md3dpp, sizeof(DXGI_SWAP_CHAIN_DESC) ); md3dpp.Windowed = !mIsFullScreen; md3dpp.SwapEffect = DXGI_SWAP_EFFECT_DISCARD ; // triple buffer if VSync is on md3dpp.BufferCount = mVSync ? 2 : 1; md3dpp.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; md3dpp.OutputWindow = mHWnd; md3dpp.BufferDesc.Width = mWidth; md3dpp.BufferDesc.Height = mHeight; md3dpp.BufferDesc.RefreshRate.Numerator=0; md3dpp.BufferDesc.RefreshRate.Denominator = 0; if (mIsFullScreen) { md3dpp.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; md3dpp.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; md3dpp.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH ; } md3dpp.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; D3D11RenderSystem* rsys = static_cast<D3D11RenderSystem*>(Root::getSingleton().getRenderSystem()); rsys->determineFSAASettings(mFSAA, mFSAAHint, md3dpp.BufferDesc.Format, &mFSAAType); if (mVSync) { // md3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; } else { // NB not using vsync in windowed mode in D3D11 can cause jerking at low // frame rates no matter what buffering modes are used (odd - perhaps a // timer issue in D3D11 since GL doesn't suffer from this) // low is < 200fps in this context if (!mIsFullScreen) { LogManager::getSingleton().logMessage("D3D11 : WARNING - " "disabling VSync in windowed mode can cause timing issues at lower " "frame rates, turn VSync on if you observe this problem."); } // md3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; } md3dpp.SampleDesc.Count = mFSAAType.Count; md3dpp.SampleDesc.Quality = mFSAAType.Quality; if (mIsSwapChain) { HRESULT hr; // get the dxgi device IDXGIDevice1* pDXGIDevice = NULL; hr = mDevice->QueryInterface( __uuidof(IDXGIDevice1), (void**)&pDXGIDevice ); if( FAILED(hr) ) { OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to create a DXGIDevice for the swap chain", "D3D11RenderWindow::createD3DResources"); } // Create swap chain hr = mpDXGIFactory->CreateSwapChain( pDXGIDevice,&md3dpp,&mpSwapChain); if (FAILED(hr)) { // Try a second time, may fail the first time due to back buffer count, // which will be corrected by the runtime hr = mpDXGIFactory->CreateSwapChain(pDXGIDevice,&md3dpp,&mpSwapChain); } if (FAILED(hr)) { OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to create an additional swap chain", "D3D11RenderWindow::createD3DResources"); } // Additional swap chains need their own depth buffer // to support resizing them hr = mpSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), (LPVOID*)&mpBackBuffer ); if( FAILED(hr) ) { OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to Get Back Buffer for swap chain", "D3D11RenderWindow::createD3DResources"); } // get the backbuffer desc D3D11_TEXTURE2D_DESC BBDesc; mpBackBuffer->GetDesc( &BBDesc ); // create the render target view D3D11_RENDER_TARGET_VIEW_DESC RTVDesc; ZeroMemory( &RTVDesc, sizeof(RTVDesc) ); RTVDesc.Format = BBDesc.Format; RTVDesc.ViewDimension = mFSAA ? D3D11_RTV_DIMENSION_TEXTURE2DMS : D3D11_RTV_DIMENSION_TEXTURE2D; RTVDesc.Texture2D.MipSlice = 0; hr = mDevice->CreateRenderTargetView( mpBackBuffer, &RTVDesc, &mRenderTargetView ); if( FAILED(hr) ) { String errorDescription = mDevice.getErrorDescription(); OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to create rendertagert view\nError Description:" + errorDescription, "D3D11RenderWindow::createD3DResources"); } if( mDepthBufferPoolId != DepthBuffer::POOL_NO_DEPTH ) { // get the backbuffer // Create depth stencil texture ID3D11Texture2D* pDepthStencil = NULL; D3D11_TEXTURE2D_DESC descDepth; descDepth.Width = mWidth; descDepth.Height = mHeight; descDepth.MipLevels = 1; descDepth.ArraySize = 1; descDepth.Format = DXGI_FORMAT_R32_TYPELESS; descDepth.SampleDesc.Count = mFSAAType.Count; descDepth.SampleDesc.Quality = mFSAAType.Quality; descDepth.Usage = D3D11_USAGE_DEFAULT; descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL; descDepth.CPUAccessFlags = 0; descDepth.MiscFlags = 0; hr = mDevice->CreateTexture2D( &descDepth, NULL, &pDepthStencil ); if( FAILED(hr) || mDevice.isError()) { String errorDescription = mDevice.getErrorDescription(hr); OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to create depth texture\nError Description:" + errorDescription, "D3D11RenderWindow::createD3DResources"); } // Create the depth stencil view D3D11_DEPTH_STENCIL_VIEW_DESC descDSV; ZeroMemory( &descDSV, sizeof(D3D11_DEPTH_STENCIL_VIEW_DESC) ); descDSV.Format = DXGI_FORMAT_D32_FLOAT; descDSV.ViewDimension = mFSAA ? D3D11_DSV_DIMENSION_TEXTURE2DMS : D3D11_DSV_DIMENSION_TEXTURE2D; descDSV.Texture2D.MipSlice = 0; hr = mDevice->CreateDepthStencilView( pDepthStencil, &descDSV, &mDepthStencilView ); SAFE_RELEASE( pDepthStencil ); if( FAILED(hr) ) { String errorDescription = mDevice.getErrorDescription(); OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to create depth stencil view\nError Description:" + errorDescription, "D3D11RenderWindow::createD3DResources"); } DepthBuffer *depthBuf = rsys->_addManualDepthBuffer( mDepthStencilView, mWidth, mHeight, mFSAAType.Count, mFSAAType.Quality ); //Don't forget we want this window to use _this_ depth buffer this->attachDepthBuffer( depthBuf ); } else { // mpRenderZBuffer = 0; } } /*else { if (!mDevice) { // We haven't created the device yet, this must be the first time // Do we want to preserve the FPU mode? Might be useful for scientific apps DWORD extraFlags = 0; ConfigOptionMap& options = Root::getSingleton().getRenderSystem()->getConfigOptions(); ConfigOptionMap::iterator opti = options.find("Floating-point mode"); if (opti != options.end() && opti->second.currentValue == "Consistent") extraFlags |= D3DCREATE_FPU_PRESERVE; #if OGRE_THREAD_SUPPORT extraFlags |= D3DCREATE_MULTITHREADED; #endif // Set default settings (use the one Ogre discovered as a default) UINT adapterToUse = mDriver->getAdapterNumber(); if (mUseNVPerfHUD) { // Look for 'NVIDIA NVPerfHUD' adapter (<= v4) // or 'NVIDIA PerfHUD' (v5) // If it is present, override default settings for (UINT adapter=0; adapter < mDriver->getD3D()->GetAdapterCount(); ++adapter) { D3DADAPTER_IDENTIFIER9 identifier; HRESULT res; res = mDriver->getD3D()->GetAdapterIdentifier(adapter,0,&identifier); if (strstr(identifier.Description,"PerfHUD") != 0) { adapterToUse = adapter; devType = D3DDEVTYPE_REF; break; } } } hr = pD3D->CreateDevice(adapterToUse, devType, mHWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING | extraFlags, &md3dpp, &mDevice ); if (FAILED(hr)) { // Try a second time, may fail the first time due to back buffer count, // which will be corrected down to 1 by the runtime hr = pD3D->CreateDevice( adapterToUse, devType, mHWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING | extraFlags, &md3dpp, &mDevice ); } if( FAILED( hr ) ) { hr = pD3D->CreateDevice( adapterToUse, devType, mHWnd, D3DCREATE_MIXED_VERTEXPROCESSING | extraFlags, &md3dpp, &mDevice ); if( FAILED( hr ) ) { hr = pD3D->CreateDevice( adapterToUse, devType, mHWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING | extraFlags, &md3dpp, &mDevice ); } } // TODO: make this a bit better e.g. go from pure vertex processing to software if( FAILED( hr ) ) { destroy(); OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to create Direct3D9 Device: " + Root::getSingleton().getErrorDescription(hr), "D3D11RenderWindow::createD3DResources" ); } } // update device in driver mDriver->setD3DDevice( mDevice ); // Store references to buffers for convenience mDevice->GetDepthStencilSurface( &mpRenderZBuffer ); // release immediately so we don't hog them mpRenderZBuffer->Release(); } */ }
//----------------------------------------------------------------------------- void D3D11HardwarePixelBuffer::blitFromMemory(const PixelBox &src, const Image::Box &dstBox) { bool isDds = false; switch(mFormat) { case PF_DXT1: case PF_DXT2: case PF_DXT3: case PF_DXT4: case PF_DXT5: isDds = true; break; default: break; } if (isDds && (dstBox.getWidth() % 4 != 0 || dstBox.getHeight() % 4 != 0 )) { return; } // for scoped deletion of conversion buffer MemoryDataStreamPtr buf; PixelBox converted = src; D3D11_BOX dstBoxDx11 = OgreImageBoxToDx11Box(dstBox); dstBoxDx11.front = 0; dstBoxDx11.back = converted.getDepth(); // convert to pixelbuffer's native format if necessary if (src.format != mFormat) { buf.bind(new MemoryDataStream( PixelUtil::getMemorySize(src.getWidth(), src.getHeight(), src.getDepth(), mFormat))); converted = PixelBox(src.getWidth(), src.getHeight(), src.getDepth(), mFormat, buf->getPtr()); PixelUtil::bulkPixelConversion(src, converted); } if (mUsage & HBU_DYNAMIC) { size_t sizeinbytes; if (PixelUtil::isCompressed(converted.format)) { // D3D wants the width of one row of cells in bytes if (converted.format == PF_DXT1) { // 64 bits (8 bytes) per 4x4 block sizeinbytes = std::max<size_t>(1, converted.getWidth() / 4) * std::max<size_t>(1, converted.getHeight() / 4) * 8; } else { // 128 bits (16 bytes) per 4x4 block sizeinbytes = std::max<size_t>(1, converted.getWidth() / 4) * std::max<size_t>(1, converted.getHeight() / 4) * 16; } } else { sizeinbytes = converted.getHeight() * converted.getWidth() * PixelUtil::getNumElemBytes(converted.format); } const Ogre::PixelBox &locked = lock(dstBox, HBL_DISCARD); memcpy(locked.data, converted.data, sizeinbytes); unlock(); } else { size_t rowWidth; if (PixelUtil::isCompressed(converted.format)) { // D3D wants the width of one row of cells in bytes if (converted.format == PF_DXT1) { // 64 bits (8 bytes) per 4x4 block rowWidth = (converted.rowPitch / 4) * 8; } else { // 128 bits (16 bytes) per 4x4 block rowWidth = (converted.rowPitch / 4) * 16; } } else { rowWidth = converted.rowPitch * PixelUtil::getNumElemBytes(converted.format); } switch(mParentTexture->getTextureType()) { case TEX_TYPE_1D: { D3D11RenderSystem* rsys = reinterpret_cast<D3D11RenderSystem*>(Root::getSingleton().getRenderSystem()); if (rsys->_getFeatureLevel() >= D3D_FEATURE_LEVEL_10_0) { mDevice.GetImmediateContext()->UpdateSubresource( mParentTexture->GetTex1D(), 0, &dstBoxDx11, converted.data, rowWidth, 0 ); if (mDevice.isError()) { String errorDescription = mDevice.getErrorDescription(); OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "D3D11 device cannot update 1d subresource\nError Description:" + errorDescription, "D3D11HardwarePixelBuffer::blitFromMemory"); } break; // For Feature levels that do not support 1D textures, revert to creating a 2D texture. } } case TEX_TYPE_CUBE_MAP: case TEX_TYPE_2D: { mDevice.GetImmediateContext()->UpdateSubresource( mParentTexture->GetTex2D(), D3D11CalcSubresource(static_cast<UINT>(mSubresourceIndex), mFace, mParentTexture->getNumMipmaps()+1), &dstBoxDx11, converted.data, rowWidth, 0 ); if (mDevice.isError()) { String errorDescription = mDevice.getErrorDescription(); OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "D3D11 device cannot update 2d subresource\nError Description:" + errorDescription, "D3D11HardwarePixelBuffer::blitFromMemory"); } } break; case TEX_TYPE_2D_ARRAY: { mDevice.GetImmediateContext()->UpdateSubresource( mParentTexture->GetTex2D(), D3D11CalcSubresource(static_cast<UINT>(mSubresourceIndex), src.front, mParentTexture->getNumMipmaps()+1), &dstBoxDx11, converted.data, rowWidth, 0 ); if (mDevice.isError()) { String errorDescription = mDevice.getErrorDescription(); OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "D3D11 device cannot update 2d array subresource\nError Description:" + errorDescription, "D3D11HardwarePixelBuffer::blitFromMemory"); } } break; case TEX_TYPE_3D: { // copied from dx9 size_t sliceWidth; if (PixelUtil::isCompressed(converted.format)) { // D3D wants the width of one slice of cells in bytes if (converted.format == PF_DXT1) { // 64 bits (8 bytes) per 4x4 block sliceWidth = (converted.slicePitch / 16) * 8; } else { // 128 bits (16 bytes) per 4x4 block sliceWidth = (converted.slicePitch / 16) * 16; } } else { sliceWidth = converted.slicePitch * PixelUtil::getNumElemBytes(converted.format); } mDevice.GetImmediateContext()->UpdateSubresource( mParentTexture->GetTex3D(), static_cast<UINT>(mSubresourceIndex), &dstBoxDx11, converted.data, rowWidth, sliceWidth ); if (mDevice.isError()) { String errorDescription = mDevice.getErrorDescription(); OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "D3D11 device cannot update 3d subresource\nError Description:" + errorDescription, "D3D11HardwarePixelBuffer::blitFromMemory"); } } break; } if (!isDds) { _genMipmaps(); } } }