Jump to content
  • Advertisement
Sign in to follow this  
Hawkblood

Mapping a loaded resource fails

This topic is 783 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have been trying to get my head around DX11, but some things don't make sense. I can load and display textures. I can create, set the data within the texture, and display those textures. I can't seem to lock (map) a loaded texture to save my life!

 

This is the relevant line for loading (this part works fine):

D3DX11CreateShaderResourceViewFromFileW(ge->Graphics.dev, filename, NULL, NULL, &m_texture, NULL);

Then I try to get to the data:

	HRESULT hr;
	ID3D11Resource *ppResource=NULL;
	gGE.TextureList[Texture].m_texture->GetResource(&ppResource);
	ID3D11Texture2D *pTexture=NULL;
	pTexture=reinterpret_cast<ID3D11Texture2D*>( ppResource );
	D3D11_MAPPED_SUBRESOURCE mappedrec;
	hr=gGE.Graphics.devcon->Map(pTexture,0,D3D11_MAP_READ,NULL,&mappedrec);
	if (FAILED(hr)) MessageBoxW(ghWnd,L"Texture Map",L"mapping failed",MB_OK);

It fails when I try to Map the subresource. Does anyone have example code or can tell me what I'm doing wrong?

Share this post


Link to post
Share on other sites
Advertisement

E_INVALIDARG

 

That doesn't help...... It has something to do with the way DX11 does resources.

Here is what I'm wanting to do:

 

-load a texture from the disk

-make a "collision map" by sampling the alpha channel.

 

I'm using the texture as a sprite for purposes of a GUI. I don't want to have to deal with only rectangular buttons so I need a collision map for the mouse.

Share this post


Link to post
Share on other sites

You pass a NULL D3DX11_IMAGE_LOAD_INFO struct when loading the image. Instead, make one of these so you can add some extra options to how the texture is created. Specifically, you want to set the Usage and CpuAccessFlags fields.

 

However... if you want to load this image data to the CPU, then D3DX11CreateShaderResourceViewFromFileW is a bad way to go about it. This function loads the image data to the CPU, copies it to the GPU, and throws away the CPU copy... then you go and ask D3D11 to copy the data from the GPU back to the CPU for you to read... which is possible, but requires these extra creation options I mentioned above, which will disable the driver from optimizing the GPU memory location/format of this texture...

 

It would be better to use a different image loading library.

Share this post


Link to post
Share on other sites

*****SOLUTION******

	HRESULT hr;
	ID3D11Resource *ppResource;
	gGE.TextureList[Texture].m_texture->GetResource(&ppResource);
	D3D11_RESOURCE_DIMENSION pResourceDimension;
	ppResource->GetType(&pResourceDimension);

	auto txt=reinterpret_cast<ID3D11Texture2D*>( ppResource );

	D3D11_TEXTURE2D_DESC desc;
	txt->GetDesc(&desc);
	desc.Usage = D3D11_USAGE_STAGING;
	desc.BindFlags = 0;
	desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
	
	ID3D11Texture2D *pTexture = NULL;
	hr=gGE.Graphics.dev->CreateTexture2D( &desc, NULL, &pTexture );
	if (hr==D3DERR_INVALIDCALL) MessageBoxW(ghWnd,L"Texture Map",L"D3DERR_INVALIDCALL",MB_OK);
	if (hr==E_FAIL) MessageBoxW(ghWnd,L"Texture Map",L"E_FAIL",MB_OK);
	if (hr==E_INVALIDARG) MessageBoxW(ghWnd,L"Texture Map",L"E_INVALIDARG",MB_OK);
	if (hr==E_OUTOFMEMORY) MessageBoxW(ghWnd,L"Texture Map",L"E_OUTOFMEMORY",MB_OK);
	if (hr==E_NOTIMPL) MessageBoxW(ghWnd,L"Texture Map",L"E_NOTIMPL",MB_OK);
	if (hr==S_FALSE) MessageBoxW(ghWnd,L"Texture Map",L"S_FALSE",MB_OK);
	gGE.Graphics.devcon->CopyResource(pTexture,txt);
	D3D11_MAPPED_SUBRESOURCE mappedrec;
	hr=gGE.Graphics.devcon->Map(pTexture,0,D3D11_MAP_READ,NULL,&mappedrec);
	if (FAILED(hr)) MessageBoxW(ghWnd,L"Texture Map",L"mapping failed",MB_OK);

	sx=gGE.TextureList[Texture].Width;
	sy=gGE.TextureList[Texture].Height;
	UINT W=UINT(sx);
	UINT H=UINT(sy);

	CollisionMap=new byte*[W];
	for (UINT i=0;i<W;i++) CollisionMap[i]=new byte[H];
	
	COLOR *C=(COLOR*)mappedrec.pData;
	for (UINT x=0;x<W;x++){
		for (UINT y=0;y<H;y++){
			UINT Loc=(y*W)+x;
			CollisionMap[x][y]=C[Loc].a;

		}
	}
	gGE.Graphics.devcon->Unmap(pTexture,0);
	pTexture->Release();

The key was in the D3D11_TEXTURE2D_DESC. I had to set the BindFlags to 0 because everything else gave me errors. I suppose that's right. The other two parameters I found from reading LOTS of Microsoft DX11 pages. Also, if you set :

desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ|D3D11_CPU_ACCESS_WRITE;

 

and

hr=gGE.Graphics.devcon->Map(pTexture,0,D3D11_MAP_READ_WRITE,NULL,&mappedrec);

you can do both read and write to that texture (resource)......

 

 

 

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!