Are effect parameter pools supposed to be this.. disorganized?

Started by
4 comments, last by Drakex 18 years, 8 months ago
Why isn't there some kind of central location from which I can set all the shared parameters that are in an effect pool? That is, say I have two effects, both of which have a "shared float4x4 MatWorld". If I create them with the same effect pool, that parameter is shared. But why do I have to set it in one of the effects? Why doesn't ID3DXEffectPool expose functionality to see what parameters it holds so I can set the parameter once from one central location? Sure, it gets you some extra speed to use an effect pool, but if the idea is to make it so you only have to set it once, why should you have to keep track of which effects share which parameters, when the ID3DXEffectPool is doing it for your behind the scenes? Either it's a badly-thought-out feature or I'm doing something wrong!
_______________________________________________________________________Hoo-rah.
Advertisement
Perhaps you could make a dummy effect which uses all the same shared parameters, and use that to set them.

Just curious, why do you think there's a speed boost from using an effect pool?
Well, I'd assume it's faster than looping through 15 effects and setting the "View" matrix 15 times. Unless, of course, that's just what the ID3DXEffectPool is doing. I figured it'd do something more elegant. If not, then I won't worry about it too much.

I'm already using a dummy effect for parameters which will show up in all effects (like world, view, proj) and setting them once in that effect, but I'd like to make it possible to have "generic" shared parameters, for maybe three or four effects that share some parameters, but not normal parameters that show up in every effect. Just as a sort of convenience, instead of having to set the same parameter four times in four different effects.
_______________________________________________________________________Hoo-rah.
Quote:Original post by Drakex
Well, I'd assume it's faster than looping through 15 effects and setting the "View" matrix 15 times. Unless, of course, that's just what the ID3DXEffectPool is doing. I figured it'd do something more elegant. If not, then I won't worry about it too much.


Yeah, I would assume it is doing something better than that; it probably has a single value that the other effects can reference...But the thing I am thinking is that it still will be calling SetXXConstant for each effect, every time you Begin() it, whether or not the parameters are shared, and that is what you really want to avoid.

Anyway maybe you should avoid using the effect system for this stuff and just upload constants into registers. The nice thing about that is that the upload only happens once and you can use the value in any shader, so it is more efficient. The downside is you have to do a bit more work managing a register layout, but in practice I think it's simpler than using the effect system. You can use the "register" keyword in HLSL to force values to specific registers; just be sure they aren't being clobbered by other HLSL programs.
Quote:Original post by ganchmaster
Quote:Original post by Drakex
Well, I'd assume it's faster than looping through 15 effects and setting the "View" matrix 15 times. Unless, of course, that's just what the ID3DXEffectPool is doing. I figured it'd do something more elegant. If not, then I won't worry about it too much.


Yeah, I would assume it is doing something better than that; it probably has a single value that the other effects can reference...But the thing I am thinking is that it still will be calling SetXXConstant for each effect, every time you Begin() it, whether or not the parameters are shared, and that is what you really want to avoid.


While it's true that Set*Constant() still needs to be called on the device for every constant, there are two things effect pools help:

1. if two different shaders use the *same* register for a shared variable, and that variable has the same value across both invokations (e.g. the projection matrix), then Set*Constant() only needs to be called once on the device; without an effect pool, it would likely be done twice.

2. the work inside the D3DX effect system to manage the current value for a variable is greatly reduced (since effects have some runtime scriptability, the work that goes on is less trivial than you'd think - it can show up pretty high on profiling if you're hammering the effect system).


Quote:Anyway maybe you should avoid using the effect system for this stuff and just upload constants into registers. The nice thing about that is that the upload only happens once and you can use the value in any shader, so it is more efficient. The downside is you have to do a bit more work managing a register layout, but in practice I think it's simpler than using the effect system. You can use the "register" keyword in HLSL to force values to specific registers; just be sure they aren't being clobbered by other HLSL programs.


Managing register layout whilst keeping things flexible (particularly if you just want to "drop in" external shaders) can quickly become a pain.

If you decide D3DX Effects aren't for you (perhaps you don't need the scriptability for example), and you just want to manage the mapping between named HLSL variables and hardware constant registers, I'd definately recommend checking out the ID3DXConstantTable interface before writing your own or forcing specific register bindings.

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

Thanks for the help guys. I think I'll just leave the shared params alone for a little while, and if I notice a bottleneck in setting multiple params, I'll look into what you've suggested!
_______________________________________________________________________Hoo-rah.

This topic is closed to new replies.

Advertisement