Skip to main content
GameDev.net gamedev.net
🔒 Locked

DirectX11 mip mapping

Started by Visje Sep 6, 2012 at 10:10 AM 30 replies 16.7k views
Original Post
Visje
Visje
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 mellow.png

Thanks a lot !
kauna
kauna
Are you using correct sampler states in the pixel shaders?

Cheers!
Hodgman
Hodgman
When I try to change the MipLevels value to another value, I get an error...
What is the error?
Visje
Visje
@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
kauna
kauna
SamplerState simpleSampler : register(s0);[/quote]

Have you defined the sampler in the program side?

Cheers!
Visje
Visje
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 :/
Erik Rufelt
Erik Rufelt
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.
Visje
Visje
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.
Erik Rufelt
Erik Rufelt
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.
Visje
Visje
If I change B8G8R8A8 to R8G8B8A8, it works but the colors are all "browny"

My feature level is : D3D_FEATURE_LEVEL_11_0 (45056)
Erik Rufelt
Erik Rufelt
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.
Visje
Visje
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
Erik Rufelt
Erik Rufelt
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. smile.png 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.
Visje
Visje
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.
Visje
Visje
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 :/
Erik Rufelt
Erik Rufelt
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.
Visje
Visje
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
MJP
MJP
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.
Visje
Visje
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

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.