DDS, D3D11 renderSystem and Intel Hd

Discussion area about developing or extending OGRE, adding plugins for it or building applications on it. No newbie questions please, use the Help forum for that.
Crashy
Google Summer of Code Student
Google Summer of Code Student
Posts: 1005
Joined: Wed Jan 08, 2003 9:15 pm
Location: Lyon, France
x 49

DDS, D3D11 renderSystem and Intel Hd

Post by Crashy »

Hi,

I'm using the D3D11 Render System and I'm having troubles with DDS textures and the Intel HD hardware.

The facts (I'm talking about RAM, not VRAM) :
  • With tga textures, when I reach the main menu of my game, the memory usage is around 600 MB, as I'm pre-loading almost all textures of the game to avoid long loading time between levels.
  • With dds DXT5 textures, the memory usage reaches 1200 MB ! :shock: Any level fails to load
  • Hacking the render system, disabling the call of D3D11Texture::_loadDDS and using the standard "loadImage" function, the memory usage is around 250 MB, witch is better. But the textures have some artifacts (inverted colours, bad pixel alignment, etc).
I don't have such memory consumption on nVidia or AMD hardware, but using DDS still takes more memory than using TGA, wich is not what I may expect from a compressed format.

I've spent the whole day looking for the cause of the completely crazy memory usage of the DDS files when using"_loadDDS", and I still have no clue.

I'm so desperate that now I'll surely work on fixing the DDS texture loading with the "loadImage" function, but I'm not satisfied with that.


Thanks for any hint !
Follow la Moustache on Twitter or on Facebook
Image
User avatar
Kojack
OGRE Moderator
OGRE Moderator
Posts: 7157
Joined: Sun Jan 25, 2004 7:35 am
Location: Brisbane, Australia
x 535

Re: DDS, D3D11 renderSystem and Intel Hd

Post by Kojack »

What Intel gpu is this on? Maybe it doesn't have compressed texture support so Ogre needs to expand the DXT textures to raw.

DXT5 should take 25% of the memory of a TGA file.
Crashy
Google Summer of Code Student
Google Summer of Code Student
Posts: 1005
Joined: Wed Jan 08, 2003 9:15 pm
Location: Lyon, France
x 49

Re: DDS, D3D11 renderSystem and Intel Hd

Post by Crashy »

This is a Intel Hd 4600, when debugging I saw that it is DXT-capable, as all the HD 4xxxx series.
Follow la Moustache on Twitter or on Facebook
Image
Crashy
Google Summer of Code Student
Google Summer of Code Student
Posts: 1005
Joined: Wed Jan 08, 2003 9:15 pm
Location: Lyon, France
x 49

Re: DDS, D3D11 renderSystem and Intel Hd

Post by Crashy »

Okay, with the help of a (not so) old guru, I've found the cause.

In fact D3DX11CreateTextureFromMemory is creating the resource in the RAM by default, and eventually a copy in VRAM if needed.
To fix that, I've changed to _loadds function to create the resource with D3DX11CreateTextureFromMemory, but as a temporary resource.
Then I create the "final" texture, copy the resource and release the temporary one. Now the memory usage is around 300MB where it previously was 1200MB.

Here is the modified function:

Code: Select all

    void D3D11Texture::_loadDDS(DataStreamPtr &dstream)
    {
        HRESULT hr;

        MemoryDataStream memStream(dstream,true);

        D3DX11_IMAGE_LOAD_INFO loadInfo;
        loadInfo.Usage          = D3D11Mappings::_getUsage(mUsage);
        loadInfo.CpuAccessFlags = D3D11Mappings::_getAccessFlags(mUsage);
        if(mUsage & TU_DYNAMIC)
        {
            loadInfo.MipLevels = 1;
        }
		
        // TO DO: check cpu access flags and use loadInfo only when it is needed.
        // this is the first try

		ID3D11Resource 	*mpTempTex;	
        // Load the Texture
        if (loadInfo.CpuAccessFlags == D3D11_CPU_ACCESS_WRITE)
        {	
			hr = D3DX11CreateTextureFromMemory( mDevice.get(), 
                memStream.getPtr(),
                memStream.size(),
                &loadInfo,
                NULL, 
                &mpTempTex, 
                NULL );
        }
        else
        {
		     hr = D3DX11CreateTextureFromMemory( mDevice.get(), 
                memStream.getPtr(),
                memStream.size(),
                NULL,
                NULL, 
                &mpTempTex, 
                NULL );
        }
        if( FAILED( hr ) )
        {
            LogManager::getSingleton().logMessage("D3D11 : " + mName + " Could not be loaded");
            return;
        }   

        D3D11_RESOURCE_DIMENSION dimension;
        mpTempTex->GetType(&dimension);

        switch (dimension)
        {
        case D3D11_RESOURCE_DIMENSION_TEXTURE1D:
            {
				
				ID3D11Texture1D *temp1DTex;
				_queryInterface<ID3D11Resource, ID3D11Texture1D>(mpTempTex, &temp1DTex);

                D3D11_TEXTURE1D_DESC desc;
                temp1DTex->GetDesc(&desc);
				mSrcWidth = desc.Width; 
				mSrcHeight = 1; 
				
				//create the real final texture
				hr = mDevice->CreateTexture1D(	
				&desc,
				NULL,// data pointer
				&mp1DTex);		
                
				mDevice.GetImmediateContext()->CopyResource (mp1DTex,mpTempTex);
				SAFE_RELEASE(mpTempTex);
				SAFE_RELEASE(temp1DTex); 
				
				//assign the texture
				 _queryInterface<ID3D11Texture1D,ID3D11Resource>(mp1DTex,&mpTex);

                mFormat = D3D11Mappings::_getPF(desc.Format);
				mSrcFormat = mFormat;
               
                _create2DResourceView();
            }                   
            break;
        case D3D11_RESOURCE_DIMENSION_TEXTURE2D:
            {
				ID3D11Texture2D *temp2DTex;
				_queryInterface<ID3D11Resource, ID3D11Texture2D>(mpTempTex, &temp2DTex);

                D3D11_TEXTURE2D_DESC desc;
                temp2DTex->GetDesc(&desc);
				mSrcWidth = desc.Width; 
				mSrcHeight = desc.Height; 
				
				//create the real final texture
				hr = mDevice->CreateTexture2D(	
				&desc,
				NULL,// data pointer
				&mp2DTex);		
                
				mDevice.GetImmediateContext()->CopyResource (mp2DTex,mpTempTex);
				SAFE_RELEASE(mpTempTex);
				SAFE_RELEASE(temp2DTex); 
				
				//assign the texture
				 _queryInterface<ID3D11Texture2D,ID3D11Resource>(mp2DTex,&mpTex);

                mFormat = D3D11Mappings::_getPF(desc.Format);
				mSrcFormat = mFormat;
                
                if(desc.ArraySize % 6 == 0 && desc.MiscFlags & D3D11_RESOURCE_MISC_TEXTURECUBE)
                    mTextureType = TEX_TYPE_CUBE_MAP; //2darray cubemap
                else if(desc.ArraySize > 1)
                    mTextureType = TEX_TYPE_2D_ARRAY;
                else
                    mTextureType = TEX_TYPE_2D;

                _create2DResourceView();
				
            }
            break;
        case D3D11_RESOURCE_DIMENSION_TEXTURE3D:
            {

				ID3D11Texture3D *temp3DTex;
				_queryInterface<ID3D11Resource, ID3D11Texture3D>(mpTempTex, &temp3DTex);


                D3D11_TEXTURE3D_DESC desc;
                temp3DTex->GetDesc(&desc);
				mSrcWidth = desc.Width; 
				mSrcHeight = desc.Height; 
				mSrcDepth = desc.Depth;

				//create the real final texture
				hr = mDevice->CreateTexture3D(	
				&desc,
				NULL,// data pointer
				&mp3DTex);	

				mDevice.GetImmediateContext()->CopyResource (mp3DTex,mpTempTex);
				SAFE_RELEASE(mpTempTex);
				SAFE_RELEASE(temp3DTex); 

				//assign the texture
				 _queryInterface<ID3D11Texture3D,ID3D11Resource>(mp3DTex,&mpTex);

                mFormat = D3D11Mappings::_getPF(desc.Format);
				mSrcFormat = mFormat;
                mTextureType = TEX_TYPE_3D;

                _create3DResourceView();
            }
            break;
        }
    }
I don't have time right now but I'll submit a patch for it soon.
Follow la Moustache on Twitter or on Facebook
Image