示例#1
0
//---------------------------------------------------------------------
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;
}
示例#5
0
    //---------------------------------------------------------------------
    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();
        }
    }

}