using a texture in fx-file causes loads of redundant state changes

Started by
7 comments, last by matches81 17 years, 11 months ago
Hi there! I have come to a quite unexpected problem. Running my app with the debug runtime and debug output maxed I get loads of "ignoring redundant SetSamplerState [...]" warnings. In fact so many that my app is close to freezing. While searching for the source of the problem, I changed the output of the only shader currently used:

//the texture sampler:
texture colorMap;
sampler colorSampler = sampler_state
{
    Texture = (colorMap);
};

//annoying warnings with this one:
return input.col * tex2D(colorSampler, input.uv) * color;

//everything fine with this one:
return input.col * color;
it doesn´t matter whether I set the texture for colorSampler once, every frame or never at all, I still get those warnings, which currently keep me from using the max debug output level. I would really like to get rid of those warnings, but I don´t know how. The warnings are always regarding sampler 0, state 13 to 21, 25, 29 and 30. Any help would be appreciated, thx.
Advertisement
This might not be the solution you're looking for, but you could set the sampler states and textures using the Device directly, working around the Effect management of samplers.

Adding something like this:
sampler s : register(s0);
would bind that sampler to the first Stage in the device. A following call of
Device->SetTexture(0, myTex);
would set the texture on the sampler, and any SetSamplerState call would also apply.
After that, you'd only need to make sure you avoid setting redundant states, and the warning should go away.

This isn't really the right way to do it, but it should at least silence your warning.

If you really want to get down to the root of the problem, I'd guess you were doing something like this:
Effect->BeginPass// Draw objectEffect->EndPassEffect->BeginPass// Draw objectEffect->EndPassEffect->BeginPass// Draw objectEffect->EndPass

Switching to something like this:
Effect->BeginPass
// Draw object
// Draw object
// Draw object
Effect->EndPass

Would be both more efficient and wouldn't give you a warning.

Hope this helps :).
Sirob Yes.» - status: Work-O-Rama.
Thx! Actually I was calling BeginPass / EndPass several times. I changed that now, but I still get those warnings. The funny thing is:
I already got the first bunch of them before I call anything like BeginScene(), Effect->Begin(), BeginPass() or anything telling Direct3D to do anything. I set a break point right at the start of my render function and right before the first frame gets rendered I have the complete set of warnings (see last post for a list of all of them, every one appears once per "set" of warnings) being reported twice.
This confuses me, totally.

the render function atm looks something like this:
Device->Clear(...);Device->BeginScene();for(all shaders){    effect->SetTechnique(...);    effect->Begin(...);    for(all passes)    {       effect->BeginPass(...);       for(all textures)       {          set textures          for(all objects)          {             set world transform and other stuff             effect->CommitChanges();             DrawIndexedPrimitves(...);          }       }       effect->EndPass();    }    effect->End();}Device->EndScene();Device->Present();


that is the structure of my rendering function. I got some kind of scene graph that gets built every frame and contains only objects that are visible. The scene graph is rather simple, as the first level are just nodes for shaders and the second level are texture nodes, which contain all the objects that can be rendered using that shader / texture combination.

Hope someone can help.
Thx!
I noticed another thing about those warnings:
The redundant state changes are repeating and always concerning states 13 to 21, 25, 29 and 30. So I thought I´d have a look and see what sampler states those are. The only one I could find was #13, which seems to have something to do with displacement maps and is calld D3DSAMP_DMAPOFFSET. I don´t ever set that one, just because I don´t do anything with displacement maps.
Concerning the other states I was surprised, because I couldn´t find them in SDK documentation of the D3DSAMPLERSTATETYPES, which I thought that number was referring to. But there is no word about any sampler state with a higher number than 13, so I doubt the D3D warnings are really referring to these. Where can I find info about which state changes are the redundant ones so I might be able to find the real problem with all of this?

Thx for any answer
A few ideas, since you're not getting any takers on this...

1) You're not running Fraps, NVPerfHud, or anything of the sort, right? They might be hooking your DX Begin/End calls for their own use, and causing a couple warnings.

2) Try another shader. Try one you know is good, like the DX "Simple HLSL" sample one. While you're at it, make sure the sample doesn't give the warnings.

Then try your shader in the DX sample. You'll at least know if it's the shader or the code.

3) If all that doesn't get you anywhere, start cutting stuff out. Comment the heck out of your app/shader, until you hit it. Worst case, you'll know roughly where it's coming from.

Hope this helps :).
Sirob Yes.» - status: Work-O-Rama.
Hmm, I have used effects often but had them generate that warning. I would try telling the effect to not save state and then restore it myself and see if that fixes the problem.

Who knows how efficiently they're restoring state anyway, in the worst case the effect might capture every state and restore it afterwards, using hundreds of state setting calls!
Nah, it uses state blocks. Any half-decent GPU these days can handle those pretty well. I'm not trying to say telling DX not to restore state isn't faster - it is, by a lot, but you can't say the Effect interface isn't doing it efficiently. It is :).
I wouldn't normally post this, but I was reading through this "Tom's Blog" or whatever a couple hours ago, and just happened to hit a section on State Blocks :). Quite an interesting read.
Sirob Yes.» - status: Work-O-Rama.
It's great to read 'inside' stuff on D3D like that. I've read Tom's blog before but there's some new stuff on there I haven't seen. Thanks!
I just scanned over Tom's Blog, will take the time to read some more of it tomorrow. Yet I read the part about state blocks.

uhm, well.... calling ID3DXEffect::Begin with D3DXFX_DONOTSAVESTATE seems to cut down the problem quite much. The complete set of warnings is now only reported twice, which are those two sets I´ve mentioned in an earlier post.

Now I´m left with some questions:
Should I stick with using D3DXFX_DONOTSAVESTATE or is there a way around that?
I wasn´t aware that the ID3DXEffect did such a thing, furthermore I know I can set render states, sampler states and so on in an .fx-file. Does the mechanism of ID3DXEffect saving state block restore the states I used before calling Begin(...) at End()?
As I don´t think I will need that many state changes in my app I thought about managing those I do change myself in order to minimize these changes. Can I safely use D3DXFX_DONOTSAVESTATE then? Seems like it would be redundant then.
On the other hand it probably would be beneficial (mainly because it would be simpler) to put all the state changes a shader needs right into the fx-file and let ID3DXEffect do its job. At least if I can get rid of those warnings.

Thx for helping!

PS: erm, yeah, I was running the app with FRAPS sometimes, though the warnings are just the same without FRAPS. I´m currently using it because I didn´t implement any FPS / frametime output yet.
Currently I´m not using NVPerfHud or anything like it, but I think I will start that once the whole thing gets more complicated.

This topic is closed to new replies.

Advertisement