Jump to content

  • Log In with Google      Sign In   
  • Create Account

DirectX11 mip mapping


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
31 replies to this topic

#1 Visje   Members   -  Reputation: 109

Like
0Likes
Like

Posted 06 September 2012 - 04:10 AM

Hey everyone,

I'm working on a game with DirectX11 and I need to apply a mip mapping on my textures when they get far from the camera (I actually have a menu with a lot of textures far from the camera and the mip mapping doesn't seem to be applied because the framerate is quite low...)

I've searched for 3 days how I could do this and I found many solutions but none of them seems to work...

I have this piece of code that create a texture, and I can show you other pieces if required :

D3D11_TEXTURE2D_DESC textureDesc;	   
	    ZeroMemory( &textureDesc, sizeof(textureDesc) );
	    textureDesc.Width = width;
	    textureDesc.Height = height;
	    textureDesc.MipLevels = 1;
	    textureDesc.ArraySize = 1;
	    textureDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
	    textureDesc.SampleDesc.Count = 1;
	    textureDesc.Usage = D3D11_USAGE_DEFAULT;
	    textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
	    textureDesc.CPUAccessFlags = 0;
	    textureDesc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS;
When I try to change the MipLevels value to 0 or another value, I get an error...

My question is : What should I do to get the mip mapping to work ? Do you have any clue, any idea.

Sorry for my average english I'm french Posted Image

Thanks a lot !

Sponsor:

#2 kauna   Crossbones+   -  Reputation: 2515

Like
0Likes
Like

Posted 06 September 2012 - 05:14 AM

Are you using correct sampler states in the pixel shaders?

Cheers!

#3 Hodgman   Moderators   -  Reputation: 30388

Like
2Likes
Like

Posted 06 September 2012 - 05:36 AM

When I try to change the MipLevels value to another value, I get an error...

What is the error?

#4 Visje   Members   -  Reputation: 109

Like
0Likes
Like

Posted 06 September 2012 - 05:49 AM

@Kauna :
In the Pixel Shader, I'm using this Sampler :
SamplerState simpleSampler : register(s0);

and later on... in the main of the PS
float4 texelColor = simpleTexture.Sample(simpleSampler, input.tex);
return texelColor;


@Hodgman :
The error is in french but you may recognize something, here it is :
Exception non gérée à 0x71F9E85C (nvwgf2um.dll) dans Direct3DApp1.exe : 0xC0000005 : Violation d'accès lors de la lecture de l'emplacement 0xCCCCCCCC.
It says, acces violation while writing at 0xCCCCCCCC

Edited by Visje, 06 September 2012 - 05:49 AM.


#5 kauna   Crossbones+   -  Reputation: 2515

Like
0Likes
Like

Posted 06 September 2012 - 05:54 AM

SamplerState simpleSampler : register(s0);


Have you defined the sampler in the program side?

Cheers!

#6 Visje   Members   -  Reputation: 109

Like
0Likes
Like

Posted 06 September 2012 - 06:05 AM

Yep, here it is :

D3D11_SAMPLER_DESC samplerDesc;
ZeroMemory(&samplerDesc, sizeof(samplerDesc));
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
samplerDesc.MaxAnisotropy = 0;
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_BORDER;
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_BORDER;
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_BORDER;
samplerDesc.MipLODBias = 0.0f;
samplerDesc.MinLOD = 0;
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
samplerDesc.BorderColor[0] = 0.0f;
samplerDesc.BorderColor[1] = 0.0f;
samplerDesc.BorderColor[2] = 0.0f;
samplerDesc.BorderColor[3] = 0.0f;


Maybe the mipmaps are beeing generated but I can't notice any difference... that should increase the framerate normally :/

Edited by Visje, 06 September 2012 - 06:29 AM.


#7 Erik Rufelt   Crossbones+   -  Reputation: 3480

Like
2Likes
Like

Posted 06 September 2012 - 07:00 AM

Do you check the HRESULT value when trying to create the texture?
It might return failure, and your crash could occur later when you try to use the uninitialized object.

What feature level are you running at?
http://msdn.microsoft.com/en-us/library/windows/desktop/cc627090%28v=vs.85%29.aspx lists B8G8R8A8 as optional for auto-generation of mipmaps, though it seems required on feature level 11.. Check the related pages linked at the menu on that page to check your feature level and supported formats.

#8 Visje   Members   -  Reputation: 109

Like
0Likes
Like

Posted 06 September 2012 - 07:16 AM

I Get the same error with the HRESULT :/

I don't know the feature level i'm running at, actually, what is a "feature level" ?
If I change the format, the colors become very odd depending on the format.

Edited by Visje, 06 September 2012 - 07:27 AM.


#9 Erik Rufelt   Crossbones+   -  Reputation: 3480

Like
0Likes
Like

Posted 06 September 2012 - 07:36 AM

If you change B8G8R8A8 to R8G8B8A8, does it work correctly?
If so, the format is the problem.
You can find your feature level by using ID3D11Device::GetFeatureLevel.

#10 Visje   Members   -  Reputation: 109

Like
0Likes
Like

Posted 06 September 2012 - 07:52 AM

If I change B8G8R8A8 to R8G8B8A8, it works but the colors are all "browny"

My feature level is : D3D_FEATURE_LEVEL_11_0 (45056)

#11 Erik Rufelt   Crossbones+   -  Reputation: 3480

Like
0Likes
Like

Posted 06 September 2012 - 08:11 AM

I see. That means B8G8R8A8 is not supported. When you change to R8G8B8A8 everything blue becomes red, and vice versa, which causes your colors to mismatch. This can however be fixed by changing how you load your source data or how you define your colors.
(In particular .BMP files are usually BGR instead of RGB.. I believe TGA too.. not sure).

A very fast "fix" to test it out is to change your shader that you use to draw the mipmapped resource to return some color.bgra to swizzle the color.

To investigate the format problem more closely, read the introduction here http://msdn.microsof...5(v=vs.85).aspx and try the CheckFormatSupport function.
Also, try using the D3D11_CREATE_DEVICE_BGRA_SUPPORT flag (http://msdn.microsof...7(v=vs.85).aspx) when creating your device.

Edited by Erik Rufelt, 06 September 2012 - 08:14 AM.


#12 Visje   Members   -  Reputation: 109

Like
0Likes
Like

Posted 06 September 2012 - 08:15 AM

Do you think that the mip mapping will work when the format will be changed ?? Will I be able to change the MipLevels value ?

Thanks a lot for your help :)

#13 Erik Rufelt   Crossbones+   -  Reputation: 3480

Like
0Likes
Like

Posted 06 September 2012 - 08:34 AM

I assumed you had already done that and seen it working with R8G8B8A8. If that's not the case, you're kindof back where you started. Posted Image But try it out.

The first most important part is to check the HRESULT return code from CreateTexture2D, using if(FAILED(hResult)) error() or similar. If you get an error from that then proceed checking the device format support and options.

If you do not get an error from CreateTexture2D (when MipLevels is 0), then your problem lies elsewhere and you can probably ignore my previous posts.

Edited by Erik Rufelt, 06 September 2012 - 08:35 AM.


#14 Visje   Members   -  Reputation: 109

Like
0Likes
Like

Posted 06 September 2012 - 08:47 AM

I actually already have the "D3D11_CREATE_DEVICE_BGRA_SUPPORT" flag.
I changed the format to R8G8B8A8 and did the quick fix in the Pixel Shader, the game works fine but I still get an error when I set MipLevels to 0, I'll try with the HRESULT.

Just for info, I'm working on a Metro app.

#15 Visje   Members   -  Reputation: 109

Like
0Likes
Like

Posted 06 September 2012 - 08:54 AM

I did this :
HRESULT hr = m_d3dDevice->CreateTexture2D(
			    &textureDesc,
			    &initialData,
			    &texture2D
			    );
but I get an error inside "CreateTexture2D", thus I cannot check the error code of HRESULT :/

#16 Erik Rufelt   Crossbones+   -  Reputation: 3480

Like
2Likes
Like

Posted 06 September 2012 - 09:16 AM

How do you initialize initialData?
D3D is probably expecting you to provide all mip levels, thereby reading past the end of your data.
Skip using initialData and instead upload the first mip-level using UpdateSubResource.

#17 Visje   Members   -  Reputation: 109

Like
0Likes
Like

Posted 06 September 2012 - 09:23 AM

That's how I initialize initialData :
D3D11_SUBRESOURCE_DATA initialData;
ZeroMemory(&initialData, sizeof(initialData));
initialData.pSysMem = bitmapPixels.get();
initialData.SysMemPitch = width * 4;
initialData.SysMemSlicePitch = 0;


"Skip using initialData and instead upload the first mip-level using UpdateSubResource." humm... how can I do that ? :s

Edited by Visje, 06 September 2012 - 09:25 AM.


#18 Erik Rufelt   Crossbones+   -  Reputation: 3480

Like
0Likes
Like

Posted 06 September 2012 - 11:53 AM

Pass NULL to CreateTexture2D and then call ID3D11DeviceContext::UpdateSubresource: http://msdn.microsoft.com/en-us/library/windows/desktop/ff476486(v=vs.85).aspx
Follow the links there and each input is described. Just set the box to (0, width, 0, height, 0, 1) and rowPitch to your sysMemPitch and pass it your data. The subresource should be 0 for the top mip level.

#19 MJP   Moderators   -  Reputation: 11372

Like
0Likes
Like

Posted 06 September 2012 - 12:20 PM

If your texture is static, you want to create it with D3D11_USAGE_IMMUTABLE and not D3D11_USAGE_DEFAULT.

Also when you create a texture with mipmaps and you want to pass it initialization data, you need to pass an array of D3D11_SUBRESOURCE_DATA. The array needs 1 element per subresource, where a subresource is either a mip level or an array slice. So if you have 10 mip levels, you'd need to pass an array of 10 with each one having a pointer to the data for that mip level.

#20 Visje   Members   -  Reputation: 109

Like
0Likes
Like

Posted 07 September 2012 - 03:06 AM

Hi Erik, I passed NULL to CreateTexture2D and all became black as expected, then at each frame I call this codeto render my textures :
m_d3dDeviceContext->UpdateSubresource(
  m_constantBuffer.Get(),
  0,
  nullptr,
  &(m_constantBufferData),
  0,
  0
  );
I don't know if I should put this function just after the createTexture, or if I must change the parameters of it... nvertheless it still is'nt working :/


MJP : I did what you told me but I still got the problem ><, I'm kind of a noob on this one :(
Here's the code if interested :
D3D11_SUBRESOURCE_DATA* initData(new D3D11_SUBRESOURCE_DATA[3 * 3]);
initData[0].pSysMem = bitmapPixels.get();
initData[0].SysMemPitch = width * 4;
initData[0].SysMemSlicePitch = 0;
initData[1].pSysMem = bitmapPixels.get();
initData[1].SysMemPitch = width * 4;
initData[1].SysMemSlicePitch = 0;
initData[2].pSysMem = bitmapPixels.get();
initData[2].SysMemPitch = width * 4;
initData[2].SysMemSlicePitch = 0;
 
 
D3D11_TEXTURE2D_DESC textureDesc;	   
ZeroMemory( &textureDesc, sizeof(textureDesc) );
textureDesc.Width = width;
textureDesc.Height = height;
textureDesc.MipLevels = 0; // PROBLEM WITH THIS
textureDesc.ArraySize = 1;
textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
textureDesc.SampleDesc.Count = 1;
textureDesc.Usage = D3D11_USAGE_IMMUTABLE; // PROBLEM HERE ALSO
textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
textureDesc.CPUAccessFlags = 0;
textureDesc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS;
 
HRESULT hr = m_d3dDevice->CreateTexture2D(
			    &textureDesc,
			    initData,
			    &texture2D
);

Thanks again for your help guys




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS