Sign in to follow this  
scippie

D3D10, can't generate mipmaps on texture

Recommended Posts

scippie    116
Hi, I created a texture with some noise in system memory, it's an array of 256x256 floats. When I create a 2d texture from it with only one mipmap level, everything works fine, but if I try 0 (automatically create all levels), or something else, I get the invalid arguments error. I noticed that this is because I need to fill in multiple initial data buffers instead of one, but that's just the point, I don't want to, I want directx to generate all the subresources for me like it would when loading a texture from file. So how does one create an automatically mipmapped texture from one memory buffer? There is a function GenerateMips that should automatically generate the mipmaps, so why doesn't it do the job? So here is the code:
D3D10_SUBRESOURCE_DATA initData;
initData.pSysMem = data; // is a float[256*256]
initData.SysMemPitch = dim.width * texSize; // texSize = sizeof(float)
initData.SysMemSlicePitch = 0;

D3D10_TEXTURE2D_DESC texDesc;
texDesc.Width = dim.width; // 256
texDesc.Height = dim.height; // 256
texDesc.SampleDesc.Count = 1;
texDesc.SampleDesc.Quality = 0;
texDesc.MipLevels = mipLevels; // 1 works fine, something else doesn't
texDesc.Format = fmt; // DXGI_FORMAT_R32_FLOAT
texDesc.Usage = usagem; // D3D10_USAGE_DEFAULT
texDesc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
if (mipLevels != 1)
	texDesc.BindFlags |= D3D10_BIND_RENDER_TARGET;
texDesc.CPUAccessFlags = 0;
texDesc.MiscFlags = (mipLevels != 1? D3D10_RESOURCE_MISC_GENERATE_MIPS: 0);
texDesc.ArraySize = 1;

ID3D10Texture2D* tex = 0;
HRESULT hr = m_pD3DDev->CreateTexture2D(&texDesc, &initData, &tex);
if (FAILED(hr))
	throw EGfx(L"Could not create 2d texture");

D3D10_SHADER_RESOURCE_VIEW_DESC viewDesc;
viewDesc.Format = texDesc.Format;
viewDesc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D;
viewDesc.Texture2D.MipLevels = texDesc.MipLevels;
viewDesc.Texture2D.MostDetailedMip = 0;

ID3D10ShaderResourceView *view = 0;
hr = m_pD3DDev->CreateShaderResourceView(tex, &viewDesc, &view);
if (FAILED(hr))
	throw EGfx(L"Could not create resource view for 2d texture");

m_pD3DDev->GenerateMips(view);

tex->Release();
return view;

Does anyone know the answer? D.

Share this post


Link to post
Share on other sites
Erik Rufelt    5901
Don't use init-data, but pass NULL for that argument to CreateTexture2D. Then update the first mip-map level with UpdateSubresource, and generate the rest with GenerateMips. This can also be used to change the texture later, without having to re-create it.

Share this post


Link to post
Share on other sites
scippie    116
Of course! Somehow that seems like causing extra work behind the scene but it probably doesn't matter. Instead of sending the data immediately when the memory is allocated, it is sent later and the shader will do the downscaling.

Thank you for reminding me of this possibility!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this