antlersoft
antlersoft

Reputation: 14751

Can't get texture.Sample to work, although I can get texture.Load to work fine in Direct 3d 11 shader

In my HLSL for Direct3d 11 app, I'm having a problem where the texture.Sample intrinsic always return 0. I know my data and parameters are correct because if I use texture.Load instead of Sample the value returned is correct.

Here are my declarations:

extern Texture2D<float> texMask;

SamplerState TextureSampler : register (s2);

Here is the code in my pixel shader that works-- this confirms that my texture is available correctly to the shader and my texcoord values are correct:

float maskColor = texMask.Load(int3(8192*texcoord.x, 4096*texcoord.y, 0));

If I substitute for this the following line, maskColor is always 0, and I can't figure out why.

float maskColor = texMask.Sample(TextureSampler, texcoord);

TextureSampler has the default state values; texMask is defined with 1 mip level.

I've also tried:

float maskColor = texMask.SampleLevel(TextureSampler, texcoord, 0);

and that also always returns 0.

C++ code for setting up sampler:

D3D11_SAMPLER_DESC sd;
ZeroMemory(&sd, sizeof(D3D11_SAMPLER_DESC));
sd.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
sd.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
sd.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
ID3D11SamplerState* pSampler;
dev->CreateSamplerState(&sd, &pSampler);

devcon->PSSetSamplers(2, 1, &pSampler);

Upvotes: 1

Views: 2354

Answers (2)

Zalerinian
Zalerinian

Reputation: 121

Forgive me for reviving such an old post, but I figured it important to add another possible cause for this sort of issue for others, and this post is the most relevant place I could find to post in.

I, too, had an issue where the HLSL Sample function would always return 0, but only on specific textures, and not on others. I checked, ensured the texture was properly bound, and that the color values should not have been 0, and still was left wondering why I was always getting 0 back for this one specific texture, but not others used in the same shader pass. The Load function worked fine, but then I lost the nice features that samplers give us.

As it turns out, in my case, I had accidentally created this texture's description as:

D3D11_TEXTURE2D_DESC desc;
desc.Width = _width;
desc.Height = _height;
desc.MipLevels = 0; // <- Bad!
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R16G16B16A16_FLOAT;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;

This worked and created a texture that was visible and renderable, however what happens when defining MipLevels to 0, is that DirectX generates an entire mip chain for that texture. Me being me, however, I forgot this while working on my project further, and while DirectX may generate the textures for the mip chain, drawing to the texture does not cascade through all the levels of the chain (which does make sense, I suppose).

Now, I suppose it's important to note that I'm still new to the whole graphics programming thing, if that wasn't already obvious enough. I have absolutely no idea what mip level, or combination of mip levels, the regular Sample function uses. But I can say that in my case, it didn't happen to be level 0. Maybe it will for a smaller mip chain, but this texture in particular had 12 levels in total, with which only level 0 had any actual color information drawn to it. Using the Load function, or SampleLevel to explicitly access mip level 0 worked fine. As I do not need, nor want, the texture I'm trying to sample to have a mip chain, I simply changed it's description to fix it.

Upvotes: 3

antlersoft
antlersoft

Reputation: 14751

I found my problem -- I needed to specify a register for the texture as well as the sampler in my HLSL. I can't find any documentation anywhere that describes why this is necessary, but it did fix my problem.

Upvotes: 0

Related Questions