예제 #1
0
/*-------------------------------------------
	main関数
--------------------------------------------*/
int wmain(int argc, WCHAR* argv[])
{
	HRESULT hr;

	// ロケールを設定
	_wsetlocale(LC_ALL, L"Japanese");

	// **********************************************************
	// Direct3D11デバイスの作成
	hr = CreateDevice();

	// **********************************************************
	// コンピュート・シェーダの作成
	if (SUCCEEDED(hr))
		hr = CreateShader();

	// **********************************************************
	// 定数バッファの作成
	if (SUCCEEDED(hr))
		hr = CreateCBuffer();

	// **********************************************************
	// リソースの作成
	if (SUCCEEDED(hr))
		hr = CreateResource();

	// **********************************************************
	// シェーダ リソース ビューの作成
	if (SUCCEEDED(hr))
		hr = CreateSRV();

	// **********************************************************
	// アンオーダード・アクセス・ビューの作成
	if (SUCCEEDED(hr))
		hr = CreateUAV();

	// **********************************************************
	// コンピュート・シェーダを使った演算
	if (SUCCEEDED(hr))
		ComputeShader();

	// **********************************************************
	// 開放
	SAFE_RELEASE(g_pUAV[1]);
	SAFE_RELEASE(g_pUAV[0]);
	SAFE_RELEASE(g_pSRV[1]);
	SAFE_RELEASE(g_pSRV[0]);
	SAFE_RELEASE(g_pReadBackBuffer);
	SAFE_RELEASE(g_pBuffer[1]);
	SAFE_RELEASE(g_pBuffer[0]);
	SAFE_RELEASE(g_pCBuffer);
	SAFE_RELEASE(g_pComputeShader);
	SAFE_RELEASE(g_pImmediateContext);
	SAFE_RELEASE(g_pD3DDevice);

	return 0;
}
예제 #2
0
	//------------------------------------------------------------------------------------
	D3D11Texture::D3D11Texture(uint32 width, uint32 height, uint32 depth, ePixelFormat format, uint32 usage, bool bMipMap)
		: Texture(eTextureType_3D, width, height, depth, format, usage, bMipMap)
		, m_pTexture2D(nullptr)
		, m_pTexture3D(nullptr)
		, m_pRTV(nullptr)
		, m_pSRV(nullptr)
		, m_pDSV(nullptr)
		, m_pTexStaging(nullptr)
	{
		ZeroMemory(m_pRTV_slices, sizeof(m_pRTV_slices));

		HRESULT hr = S_OK;
		const DXGI_FORMAT dxformat = ConvertToDXFormat(m_texFormat);

		CD3D11_TEXTURE3D_DESC desc(dxformat, width, height, depth, 1);

		// Validate usage
		_AST(!((m_usage&eTextureUsage_WriteOnly) && (m_usage&eTextureUsage_ReadWrite)) && "Invalid usage!");

		// Assign usage
		if (m_usage & eTextureUsage_WriteOnly)
		{
			desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
			desc.Usage = D3D11_USAGE_DYNAMIC;
		}
		else if (m_usage & eTextureUsage_ReadWrite)
		{
			desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
			desc.Usage = D3D11_USAGE_STAGING;
			desc.BindFlags = 0;
		}

		if (m_usage & eTextureUsage_RenderTarget)
		{
			desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
		}

		V(g_pRenderSys->GetDevice()->CreateTexture3D(&desc, nullptr, &m_pTexture3D));

		CreateSRV();

		// Create RTV
		if (m_usage & eTextureUsage_RenderTarget)
		{
			_AST(depth <= 32);

			for (uint32 i = 0; i < depth; ++i)
			{
				CD3D11_RENDER_TARGET_VIEW_DESC rtvDesc(D3D11_RTV_DIMENSION_TEXTURE3D, dxformat, 0, i, 1);
				V(g_pRenderSys->GetDevice()->CreateRenderTargetView(m_pTexture3D, &rtvDesc, &m_pRTV_slices[i]));
			}
		}
	}
예제 #3
0
void BufferD3D11Impl::CreateViewInternal( const BufferViewDesc &OrigViewDesc, IBufferView **ppView, bool bIsDefaultView )
{
    VERIFY( ppView != nullptr, "Null pointer provided" );
    if( !ppView )return;
    VERIFY( *ppView == nullptr, "Overwriting reference to existing object may cause memory leaks" );

    *ppView = nullptr;

    try
    {
        auto *pDeviceD3D11Impl = ValidatedCast<RenderDeviceD3D11Impl>(GetDevice());
        auto &BuffViewAllocator = pDeviceD3D11Impl->GetBuffViewObjAllocator();
        VERIFY( &BuffViewAllocator == &m_dbgBuffViewAllocator, "Buff view allocator does not match allocator provided at buffer initialization" );

        BufferViewDesc ViewDesc = OrigViewDesc;
        if( ViewDesc.ViewType == BUFFER_VIEW_UNORDERED_ACCESS )
        {
            CComPtr<ID3D11UnorderedAccessView> pUAV;
            CreateUAV( ViewDesc, &pUAV );
            *ppView = NEW_RC_OBJ(BuffViewAllocator, "BufferViewD3D11Impl instance",  BufferViewD3D11Impl, bIsDefaultView ? this : nullptr)
                                ( pDeviceD3D11Impl, ViewDesc, this, pUAV, bIsDefaultView );
        }
        else if( ViewDesc.ViewType == BUFFER_VIEW_SHADER_RESOURCE )
        {
			CComPtr<ID3D11ShaderResourceView> pSRV;
            CreateSRV( ViewDesc, &pSRV );
            *ppView = NEW_RC_OBJ(BuffViewAllocator, "BufferViewD3D11Impl instance",  BufferViewD3D11Impl, bIsDefaultView ? this : nullptr)
                                (pDeviceD3D11Impl, ViewDesc, this, pSRV, bIsDefaultView );
        }

        if( !bIsDefaultView && *ppView )
            (*ppView)->AddRef();
    }
    catch( const std::runtime_error & )
    {
        const auto *ViewTypeName = GetBufferViewTypeLiteralName(OrigViewDesc.ViewType);
        LOG_ERROR("Failed to create view \"", OrigViewDesc.Name ? OrigViewDesc.Name : "", "\" (", ViewTypeName, ") for buffer \"", m_Desc.Name, "\"" );
    }
}
void BufferD3D12Impl::CreateViewInternal( const BufferViewDesc &OrigViewDesc, IBufferView **ppView, bool bIsDefaultView )
{
    VERIFY( ppView != nullptr, "Null pointer provided" );
    if( !ppView )return;
    VERIFY( *ppView == nullptr, "Overwriting reference to existing object may cause memory leaks" );

    *ppView = nullptr;

    try
    {
        auto *pDeviceD3D12Impl = ValidatedCast<RenderDeviceD3D12Impl>(GetDevice());
        auto &BuffViewAllocator = pDeviceD3D12Impl->GetBuffViewObjAllocator();
        VERIFY( &BuffViewAllocator == &m_dbgBuffViewAllocator, "Buff view allocator does not match allocator provided at buffer initialization" );

        BufferViewDesc ViewDesc = OrigViewDesc;
        if( ViewDesc.ViewType == BUFFER_VIEW_UNORDERED_ACCESS )
        {
            auto UAVHandleAlloc = pDeviceD3D12Impl->AllocateDescriptor(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
            CreateUAV( ViewDesc, UAVHandleAlloc.GetCpuHandle() );
            *ppView = NEW(BuffViewAllocator, "BufferViewD3D12Impl instance", BufferViewD3D12Impl, GetDevice(), ViewDesc, this, std::move(UAVHandleAlloc), bIsDefaultView );
        }
        else if( ViewDesc.ViewType == BUFFER_VIEW_SHADER_RESOURCE )
        {
			auto SRVHandleAlloc = pDeviceD3D12Impl->AllocateDescriptor(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
            CreateSRV( ViewDesc, SRVHandleAlloc.GetCpuHandle() );
            *ppView = NEW(BuffViewAllocator, "BufferViewD3D12Impl instance", BufferViewD3D12Impl, GetDevice(), ViewDesc, this, std::move(SRVHandleAlloc), bIsDefaultView );
        }

        if( !bIsDefaultView && *ppView )
            (*ppView)->AddRef();
    }
    catch( const std::runtime_error & )
    {
        const auto *ViewTypeName = GetBufferViewTypeLiteralName(OrigViewDesc.ViewType);
        LOG_ERROR("Failed to create view \"", OrigViewDesc.Name ? OrigViewDesc.Name : "", "\" (", ViewTypeName, ") for buffer \"", m_Desc.Name, "\"" )
    }
}
예제 #5
0
	//--------------------------------------------------------------------------
	D3D11Texture::D3D11Texture(const STRING& filename, eTextureType type, uint32 usage, bool bSRGB)
		: Texture(type, 0, 0, 0, ePF_Unknown, usage, true)
		, m_pTexture2D(nullptr)
		, m_pTexture3D(nullptr)
		, m_pRTV(nullptr)
		, m_pSRV(nullptr)
		, m_pDSV(nullptr)
		, m_pTexStaging(nullptr)
	{
		////////////////////////////////////////////////////////////////
		////////////// Load texture
		HRESULT hr = S_OK;
		D3DX11_IMAGE_LOAD_INFO loadInfo;
		loadInfo.MipLevels = 0;
		loadInfo.BindFlags = 0;
		loadInfo.Format = DXGI_FORMAT_FROM_FILE;
		ID3D11Resource** pTex = nullptr;

		switch (GetTextureType())
		{
		case eTextureType_2D:
			{
				pTex = (ID3D11Resource**)&m_pTexture2D;

				if (usage & eTextureUsage_ReadWrite)
				{
					loadInfo.Usage = D3D11_USAGE_STAGING;
					loadInfo.CpuAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
				}
			}
			break;

		case eTextureType_CubeMap:
			{
				loadInfo.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
				pTex = (ID3D11Resource**)&m_pTexture2D;
			}
			break;

		case eTextureType_3D:
			{
				pTex = (ID3D11Resource**)&m_pTexture3D;
			}
			break;

		default: _AST(0);
		}

		if (filename.find(".dds") != STRING::npos)
		{
			if (usage & eTextureUsage_ReadWrite)
			{
				V(DirectX::CreateDDSTextureFromFileEx(g_pRenderSys->GetDevice(), EngineToUnicode(filename).c_str(),
					4096, D3D11_USAGE_STAGING, 0, D3D11_CPU_ACCESS_READ, 0, bSRGB, pTex, nullptr));
			} 
			else
			{
				V(DirectX::CreateDDSTextureFromFileEx(g_pRenderSys->GetDevice(), EngineToUnicode(filename).c_str(),
					4096, D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, bSRGB, pTex, &m_pSRV));
			}
		} 
		else
		{
			V(D3DX11CreateTextureFromFileA(g_pRenderSys->GetDevice(), filename.c_str(), &loadInfo, nullptr, pTex, nullptr));

			if (!(usage & eTextureUsage_ReadWrite))
			{
				CreateSRV();
			}
		}

		// Store texture dimension and format
		switch (GetTextureType())
		{
		case eTextureType_2D:
		case eTextureType_CubeMap:
			{
				D3D11_TEXTURE2D_DESC desc;
				m_pTexture2D->GetDesc(&desc);

				m_width = desc.Width;
				m_height = desc.Height;

				m_texFormat = ConvertFromDXFormat(desc.Format);
			}
			break;

		case eTextureType_3D:
			{
				D3D11_TEXTURE3D_DESC desc;
				m_pTexture3D->GetDesc(&desc);

				m_width = desc.Width;
				m_height = desc.Height;

				m_texFormat = ConvertFromDXFormat(desc.Format);
			}
			break;

		default: _AST(0);
		}
	}
예제 #6
0
	//------------------------------------------------------------------------------------
	void D3D11Texture::_CreateManual(const char* pTexData)
	{
		HRESULT hr = S_OK;
		const DXGI_FORMAT dxformat = ConvertToDXFormat(m_texFormat);
		const DWORD bytesPerPixel = GetBytesPerPixelFromFormat(m_texFormat);

		DWORD pitch = bytesPerPixel * m_width;
		char* tmpBuf = (char*)pTexData;

		if (!pTexData)
		{
			tmpBuf = new char[pitch * m_height];
			ZeroMemory(tmpBuf, pitch * m_height * sizeof(char));
		}

		D3D11_SUBRESOURCE_DATA subData;
		D3D11_SUBRESOURCE_DATA* subDataArray = nullptr;
		subData.pSysMem = tmpBuf;
		subData.SysMemPitch = pitch;

		CD3D11_TEXTURE2D_DESC desc(dxformat, m_width, m_height);

		if (m_bMipMap)
		{
			int wid = m_width, hei = m_height;
			// Get mipmap level
			desc.MipLevels = 1;
			while((wid > 1) || (hei > 1))
			{
				wid = Max(wid / 2, 1);
				hei = Max(hei / 2, 1);
				++desc.MipLevels;
			}

			// Not correct mipmap data, just make room for later D3DX11FilterTexture
			subDataArray = new D3D11_SUBRESOURCE_DATA[desc.MipLevels];
			for (size_t i=0; i<desc.MipLevels; ++i)
			{
				subDataArray[i].pSysMem = tmpBuf;
				subDataArray[i].SysMemPitch = pitch;
			}
		}
		else
		{
			desc.MipLevels = 1;
			subDataArray = &subData;
		}

		// Validate usage
		_AST(!((m_usage&eTextureUsage_WriteOnly)&&(m_usage&eTextureUsage_ReadWrite)) && "Invalid usage!");

		if (m_usage & eTextureUsage_RenderTarget)
		{
			desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;

			if (m_usage & eTextureUsage_AutoGenMips)
			{
				desc.MiscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS;
			}
		}

		if (GetTextureType() == eTextureType_CubeMap)
		{
			desc.MiscFlags |= D3D11_RESOURCE_MISC_TEXTURECUBE;
			desc.ArraySize = 6;
		}

		// Assign usage
		if (m_usage & eTextureUsage_WriteOnly)
		{
			desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
			desc.Usage = D3D11_USAGE_DYNAMIC;
		}
		else if (m_usage & eTextureUsage_ReadWrite)
		{
			D3D11_TEXTURE2D_DESC descStaging = desc;
			descStaging.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
			descStaging.Usage = D3D11_USAGE_STAGING;
			descStaging.BindFlags = 0;

			g_pRenderSys->GetDevice()->CreateTexture2D(&descStaging, subDataArray, &m_pTexStaging);
		}

		if (m_usage & eTextureUsage_Depth)
		{
			desc.Usage			= D3D11_USAGE_DEFAULT;
			desc.BindFlags		= D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE;

			g_pRenderSys->GetDevice()->CreateTexture2D(&desc, nullptr, &m_pTexture2D);
		}
		else
		{
			g_pRenderSys->GetDevice()->CreateTexture2D(&desc, subDataArray, &m_pTexture2D);
		}

		if(!pTexData)
		{
			SAFE_DELETE_ARRAY(tmpBuf);
		}

		_AST(SUCCEEDED(hr) && "Create texture failed!");

		// Generate mipmap levels
		if (m_bMipMap && !(m_usage & eTextureUsage_RenderTarget))
		{
			V(D3DX11FilterTexture(g_pRenderSys->GetDeviceContext(), m_pTexture2D, 0, D3DX11_DEFAULT));
		}

		// Create SRV
		CreateSRV();

		// Create DSV
		if (m_usage & eTextureUsage_Depth)
		{
			CreateDSV();
		}

		// Create RTV
		if (m_usage & eTextureUsage_RenderTarget)
		{
			CreateRTV();
		}
	}
예제 #7
0
	//------------------------------------------------------------------------------------
	D3D11Texture::D3D11Texture(const StringVector& vecTexNames, bool bSRGB)
		: Texture(eTextureType_TextureArray, 0, 0, 0, ePF_Unknown, 0, true)
		, m_pTexture2D(nullptr)
		, m_pTexture3D(nullptr)
		, m_pRTV(nullptr)
		, m_pSRV(nullptr)
		, m_pDSV(nullptr)
		, m_pTexStaging(nullptr)
	{
		_AST(!vecTexNames.empty());

		HRESULT hr = S_OK;
		// First load all texture elements
		std::vector<ID3D11Texture2D*> vecTexs(vecTexNames.size());
		for (size_t i=0; i<vecTexNames.size(); ++i)
		{
			D3DX11_IMAGE_LOAD_INFO loadInfo;
			loadInfo.Width  = D3DX11_FROM_FILE;
			loadInfo.Height = D3DX11_FROM_FILE;
			loadInfo.Depth  = D3DX11_FROM_FILE;
			loadInfo.FirstMipLevel = 0;
			loadInfo.BindFlags = 0;
			loadInfo.Usage = D3D11_USAGE_STAGING;	// Local res
			loadInfo.MipLevels = 0;
			loadInfo.CpuAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
			loadInfo.MiscFlags = 0;
			loadInfo.Format = DXGI_FORMAT_FROM_FILE;
			loadInfo.Filter = D3DX11_FILTER_NONE;
			loadInfo.MipFilter = D3DX11_FILTER_LINEAR;
			loadInfo.pSrcInfo  = 0;

			if (vecTexNames[i].find(".dds") != STRING::npos)
			{
				V(DirectX::CreateDDSTextureFromFileEx(g_pRenderSys->GetDevice(), EngineToUnicode(vecTexNames[i]).c_str(),
					4096, D3D11_USAGE_STAGING, 0, D3D11_CPU_ACCESS_READ, 0, bSRGB, (ID3D11Resource**)&vecTexs[i], nullptr));
			}
			else
			{
				V(D3DX11CreateTextureFromFileA(g_pRenderSys->GetDevice(), vecTexNames[i].c_str(),
					&loadInfo, nullptr, (ID3D11Resource**)&vecTexs[i], nullptr));
			}
			
		}

		// Then create the texture array object
		D3D11_TEXTURE2D_DESC texElementDesc;
		vecTexs[0]->GetDesc(&texElementDesc);

		// Store dimension and format
		m_width = texElementDesc.Width;
		m_height = texElementDesc.Height;

		m_texFormat = ConvertFromDXFormat(texElementDesc.Format);

		D3D11_TEXTURE2D_DESC texArrayDesc;
		texArrayDesc.Width              = texElementDesc.Width;
		texArrayDesc.Height             = texElementDesc.Height;
		texArrayDesc.MipLevels          = texElementDesc.MipLevels;
		texArrayDesc.ArraySize          = vecTexs.size();
		texArrayDesc.Format             = texElementDesc.Format;
		texArrayDesc.SampleDesc.Count   = 1;
		texArrayDesc.SampleDesc.Quality = 0;
		texArrayDesc.Usage              = D3D11_USAGE_DEFAULT;
		texArrayDesc.BindFlags          = D3D11_BIND_SHADER_RESOURCE;
		texArrayDesc.CPUAccessFlags     = 0;
		texArrayDesc.MiscFlags          = 0;

		V(g_pRenderSys->GetDevice()->CreateTexture2D(&texArrayDesc, 0, &m_pTexture2D));

		// Fill texture array data
		ID3D11DeviceContext* dc = g_pRenderSys->GetDeviceContext();

		for(size_t texElement=0; texElement<vecTexs.size(); ++texElement)
		{
			vecTexs[texElement]->GetDesc(&texElementDesc);

			for(UINT mipLevel = 0; mipLevel < texElementDesc.MipLevels; ++mipLevel)
			{
				D3D11_MAPPED_SUBRESOURCE mappedTex2D;
				V(dc->Map(vecTexs[texElement], mipLevel, D3D11_MAP_READ, 0, &mappedTex2D));

				dc->UpdateSubresource(m_pTexture2D, 
					D3D11CalcSubresource(mipLevel, texElement, texElementDesc.MipLevels),
					0, mappedTex2D.pData, mappedTex2D.RowPitch, mappedTex2D.DepthPitch);

				dc->Unmap(vecTexs[texElement], mipLevel);
			}
		}

		CreateSRV();

		for(size_t i=0; i<vecTexs.size(); ++i)
			vecTexs[i]->Release();
	}
예제 #8
0
//--------------------------------------------------------------------------
D3D11Texture::D3D11Texture(const STRING& filename, eTextureType type, uint32 usage)
    :m_pTexture2D(nullptr)
    ,m_pTexture3D(nullptr)
    ,m_pRenderSystem(g_env.pRenderSystem)
    ,m_rtView(nullptr)
    ,m_pSRV(nullptr)
    ,m_pDSV(nullptr)
    ,m_usage(usage)
    ,m_texType(type)
    ,m_width(0)
    ,m_height(0)
    ,m_bMipMap(true)
{
    m_pd3dDevice = m_pRenderSystem->GetDevice();
    if (m_pd3dDevice)
        m_pd3dDevice->AddRef();

    ////////////////////////////////////////////////////////////////
    ////////////// Load texture
    HRESULT hr = S_OK;
    D3DX11_IMAGE_LOAD_INFO loadInfo;
    loadInfo.MipLevels = 0;
    ID3D11Resource** pTex = nullptr;

    switch (GetTextureType())
    {
    case eTextureType_2D:
    {
        pTex = (ID3D11Resource**)&m_pTexture2D;
    }
    break;

    case eTextureType_CubeMap:
    {
        loadInfo.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
        pTex = (ID3D11Resource**)&m_pTexture2D;
    }
    break;

    case eTextureType_3D:
    {
        pTex = (ID3D11Resource**)&m_pTexture3D;
    }
    break;

    default:
        assert(0);
    }

    V(D3DX11CreateTextureFromFileA(m_pd3dDevice, filename.c_str(), &loadInfo, nullptr,pTex, nullptr));

    // Create SRV
    CreateSRV();

    // Store texture dimension and format
    switch (GetTextureType())
    {
    case eTextureType_2D:
    case eTextureType_CubeMap:
    {
        D3D11_TEXTURE2D_DESC desc;
        m_pTexture2D->GetDesc(&desc);

        m_width = desc.Width;
        m_height = desc.Height;

        m_texFormat = ConvertFromDXFormat(desc.Format);
    }
    break;

    case eTextureType_3D:
    {
        D3D11_TEXTURE3D_DESC desc;
        m_pTexture3D->GetDesc(&desc);

        m_width = desc.Width;
        m_height = desc.Height;

        m_texFormat = ConvertFromDXFormat(desc.Format);
    }
    break;

    default:
        assert(0);
    }
}
예제 #9
0
//------------------------------------------------------------------------------------
D3D11Texture::D3D11Texture( const StringVector& vecTexNames )
    :m_pTexture2D(nullptr)
    ,m_pTexture3D(nullptr)
    ,m_pRenderSystem(g_env.pRenderSystem)
    ,m_rtView(nullptr)
    ,m_pSRV(nullptr)
    ,m_pDSV(nullptr)
    ,m_usage(0)
    ,m_texType(eTextureType_TextureArray)
    ,m_bMipMap(true)
{
    m_pd3dDevice = m_pRenderSystem->GetDevice();
    if (m_pd3dDevice)
        m_pd3dDevice->AddRef();

    assert(!vecTexNames.empty());

    HRESULT hr = S_OK;
    // First load all texture elements
    std::vector<ID3D11Texture2D*> vecTexs(vecTexNames.size());
    for (size_t i=0; i<vecTexNames.size(); ++i)
    {
        D3DX11_IMAGE_LOAD_INFO loadInfo;
        loadInfo.Width  = D3DX11_FROM_FILE;
        loadInfo.Height = D3DX11_FROM_FILE;
        loadInfo.Depth  = D3DX11_FROM_FILE;
        loadInfo.FirstMipLevel = 0;
        loadInfo.BindFlags = 0;
        loadInfo.Usage = D3D11_USAGE_STAGING;	// Local res
        loadInfo.MipLevels = 0;
        loadInfo.CpuAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
        loadInfo.MiscFlags = 0;
        loadInfo.Format = DXGI_FORMAT_FROM_FILE;
        loadInfo.Filter = D3DX11_FILTER_NONE;
        loadInfo.MipFilter = D3DX11_FILTER_LINEAR;
        loadInfo.pSrcInfo  = 0;

        V(D3DX11CreateTextureFromFileA(m_pRenderSystem->GetDevice(), vecTexNames[i].c_str(),
                                       &loadInfo, nullptr, (ID3D11Resource**)&vecTexs[i], nullptr));
    }

    // Then create the texture array object
    D3D11_TEXTURE2D_DESC texElementDesc;
    vecTexs[0]->GetDesc(&texElementDesc);

    // Store dimension and format
    m_width = texElementDesc.Width;
    m_height = texElementDesc.Height;

    m_texFormat = ConvertFromDXFormat(texElementDesc.Format);

    D3D11_TEXTURE2D_DESC texArrayDesc;
    texArrayDesc.Width              = texElementDesc.Width;
    texArrayDesc.Height             = texElementDesc.Height;
    texArrayDesc.MipLevels          = texElementDesc.MipLevels;
    texArrayDesc.ArraySize          = vecTexs.size();
    texArrayDesc.Format             = texElementDesc.Format;
    texArrayDesc.SampleDesc.Count   = 1;
    texArrayDesc.SampleDesc.Quality = 0;
    texArrayDesc.Usage              = D3D11_USAGE_DEFAULT;
    texArrayDesc.BindFlags          = D3D11_BIND_SHADER_RESOURCE;
    texArrayDesc.CPUAccessFlags     = 0;
    texArrayDesc.MiscFlags          = 0;

    V(m_pRenderSystem->GetDevice()->CreateTexture2D( &texArrayDesc, 0, &m_pTexture2D));

    // Fill texture array data
    ID3D11DeviceContext* dc = m_pRenderSystem->GetDeviceContext();

    for(size_t texElement=0; texElement<vecTexs.size(); ++texElement)
    {
        for(UINT mipLevel = 0; mipLevel < texElementDesc.MipLevels; ++mipLevel)
        {
            D3D11_MAPPED_SUBRESOURCE mappedTex2D;
            V(dc->Map(vecTexs[texElement], mipLevel, D3D11_MAP_READ, 0, &mappedTex2D));

            dc->UpdateSubresource(m_pTexture2D,
                                  D3D11CalcSubresource(mipLevel, texElement, texElementDesc.MipLevels),
                                  0, mappedTex2D.pData, mappedTex2D.RowPitch, mappedTex2D.DepthPitch);

            dc->Unmap(vecTexs[texElement], mipLevel);
        }
    }

    CreateSRV();

    for(size_t i=0; i<vecTexs.size(); ++i)
        vecTexs[i]->Release();
}