Sign in to follow this  

Redundant SetSamplerState when using Effects

This topic is 2849 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, We use Unmanaged Direct3D9 in C++, and we're trying to start using Effects. Now we have only one problem: redundant SetSamplerStates and SetRenderStates. This is because we set the D3D device's states. Then, when we render the effects, on each render cycle, the .fx saves it states, uses the device's, and then sets its states again. Therefore, it the device and the fx have states in common, redundancy ensues. Is there a way to avoid this? I read somewhere that setting states is quite expensive, performance-wise.

Share this post


Link to post
Share on other sites
The performance overhead depends on how many times you call it. You generally have to start getting into the high hundreds/thousands before it gets really bad. You can use PIX to tell you how many times you call it per frame, and you can use tools like NVPerfHUD to tell you how much time you're spending in the driver each frame.

If you want to prevent redundant state calls, you have to implement ID3DXEffectStateManager and pass it to your effect. There's a sample in the SDK called "StateManager" with a stock implementation that you can use.

Share this post


Link to post
Share on other sites
I'm not so sure but I think the driver takes care of (optimizes away) redundant state changes, so you only should really care about sorting your rendering order by texture or shader to minimize "actual" state changes. But again, I'm not so sure.

Share this post


Link to post
Share on other sites
Quote:
Original post by Amr0
I'm not so sure but I think the driver takes care of (optimizes away) redundant state changes, so you only should really care about sorting your rendering order by texture or shader to minimize "actual" state changes. But again, I'm not so sure.


No you definitely can't rely on that. And even if you could, it wouldn't matter since what you're trying to avoid is going into the driver at all (since user-mode to kernel-mode transitions are so slow).

Share this post


Link to post
Share on other sites
Apparently, both the driver and the Direct3D runtime will try to optimize. This talks about accurate D3D profiling and is a good read actually. This part is relevant I think:
Quote:
Optimizations in the runtime and/or the driver are designed to speed up rendering by reducing the amount of work required. The following are a couple of state change optimizations that may pollute profile averages:
* A driver (or the runtime) could save a state change as a local state. Because the driver could operate in a "lazy" algorithm (postponing work until it is absolutely necessary), work associated with some state changes could get delayed.
* The runtime (or a driver) may remove state changes by optimizing. An example of this might be to remove a redundant state change that disables lighting because lighting has previously been disabled.


But here it says "could" and "may", supporting what MJP said about it being unreliable, but perhaps in practice it just might be "reliable enough" in a lot of cases. Again, I'm not sure and I'm rather just mentioning things in hopes for informative comments since the subject is of interest to me.

Share this post


Link to post
Share on other sites
The problem with relying on driver optimizations is that if you have to go to the driver, you've lost. Driver optimizations might spare you any GPU overhead that results from state changes, but because of the nature of drivers any time you go into the driver you pay a hefty penalty. Thus for DX9 the fastest path is to make sure you only go into the driver when you really need to, and this is done pretty easily by filtering out redundant calls. It's pretty easy to do...you just store the states you set into a bunch of variables and do a compare before actually doing any DX calls.

In DX10 and above things are different since the IHV's have to provide a user-mode driver and a kernel-mode driver, which allows the user-mode portion to perform a lot of filtering and optimizations without hitting the driver so much.

Share this post


Link to post
Share on other sites
Quote:
Original post by Amr0
Silly me, somehow I completely forgot about this yesterday: D3DX Effects State Management. Cool useful article.


We don't change states after initialization, so just turning off that flag works fine for us. Anyway, that's a very interesting article. I knew this was important, the guy got a 38% speedup by eliminating redundant state setting. Thanks guys!

Share this post


Link to post
Share on other sites

This topic is 2849 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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