Downscaling texture via mipmap

Copied from Computer Graphics SE.


I am implementing a post-processing effect in my DirectX 11 pet renderer. The post-processing pass is implemented by rendering a full-screen quad covered with texture containing original rendered image, which works as it should, but I have problems with downscaling the texture.

The non-processed testing scene looks like this (three very bright emmissive spheres):

enter image description here

I see no problem at this stage, but when I run the first post-processing pass, which just down-scales the image by the factor of 8 using the texture sampler, the result is very flickery (up-scaled for clarity):

enter image description here

I expected a mipmap would solve or at least reduce the flickering, but it didn’t change a thing. What am I doing wrong?

RenderDoc Update

After investigating the issue using RenderDoc I found that the mipmap is being generated successfully and it’s third level looks like this:

enter image description here

However, the output of the down-scaling pass looks like this:

enter image description here

As if the sampler didn’t use the mipmap at all. Don’t get distracted by coloured object instead almost white ones. I lowered the sphere brightness a bit while investigating the bug.

Even if I choose the mipmap level explicitly

float4 vColor = s0.SampleLevel(LinearSampler, Input.Tex, 3); 

it changes nothing :-/

RenderDoc also says “LOD Clamp 0-0” for the used sampler. What is it? Couldn’t this be the problem?

DirectX details

Samplers

D3D11_SAMPLER_DESC descSampler; ZeroMemory(&descSampler, sizeof(descSampler)); descSampler.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; descSampler.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; descSampler.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;  descSampler.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; mDevice->CreateSamplerState(&descSampler, &mSamplerStateLinear);  descSampler.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; hr = mDevice->CreateSamplerState(&descSampler, &mSamplerStatePoint); 

…are set right before rendering the screen quad

ID3D11SamplerState* aSamplers[] = { mSamplerStatePoint, mSamplerStateLinear }; mImmediateContext->PSSetSamplers(0, 2, aSamplers); 

…and used within the down-scaling PS shader

SamplerState PointSampler  : register (s0); SamplerState LinearSampler : register (s1);  Texture2D s0 : register(t0);  float4 Pass1PS(QUAD_VS_OUTPUT Input) : SV_TARGET {     return s0.Sample(LinearSampler, Input.Tex); } 

Texture

D3D11_TEXTURE2D_DESC descTex; ZeroMemory(&descTex, sizeof(D3D11_TEXTURE2D_DESC)); descTex.ArraySize = 1; descTex.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE; descTex.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS; descTex.Usage = D3D11_USAGE_DEFAULT; descTex.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; descTex.Width  = width; descTex.Height = height; descTex.MipLevels = 0; descTex.SampleDesc.Count = 1; device->CreateTexture2D(&descTex, nullptr, &tex); 

…it’s render target view

D3D11_RENDER_TARGET_VIEW_DESC descRTV; descRTV.Format = descTex.Format; descRTV.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; descRTV.Texture2D.MipSlice = 0; device->CreateRenderTargetView(tex, &descRTV, &rtv); 

…it’s shader resource view

D3D11_SHADER_RESOURCE_VIEW_DESC descSRV; ZeroMemory(&descSRV, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC)); descSRV.Format = descTex.Format; descSRV.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; descSRV.Texture2D.MipLevels = (UINT)-1; descSRV.Texture2D.MostDetailedMip = 0; device->CreateShaderResourceView(tex, &descSRV, &srv); 

Explicit generation of mipmap is called after the scene was rendered into the texture and another texture was set as a render target.

ID3D11RenderTargetView* aRTViews[1] = { mPass1Buff.GetRTV() }; mImmediateContext->OMSetRenderTargets(1, aRTViews, nullptr);  mImmediateContext->GenerateMips(mPass0Buff.GetSRV());  ID3D11ShaderResourceView* aSRViews[1] = { mPass0Buff.GetSRV() }; mImmediateContext->PSSetShaderResources(0, 1, aSRViews); 

The code is compiled in debug and the D3D device was created with D3D11_CREATE_DEVICE_DEBUG flag and I get no runtime errors on the console.