13
\$\begingroup\$

I want to ask if there is a best practice for setting Effect parameters in XNA. Or in other words, what exactly happens when I call pass.Apply(). I can imagine multiple scenarios:

  1. Each time Apply is called, all effect parameters are transferred to the GPU and therefor it has no real influence how often I set a parameter.
  2. Each time Apply is called, only the parameters that got reset are transferred. So caching Set-operations that don't actually set a new value should be avoided.
  3. Each time Apply is called, only the parameters that got changed are transferred. So caching Set-operations is useless.
  4. This whole questions is bootless because no one of the mentions ways has any noteworthy impact on game performance.

So the final question: Is it useful to implement some caching of set operation like:

private Matrix _world;
public Matrix World
{
    get{ return _world; }
    set 
    {
        if (value == world) return;
        _effect.Parameters["xWorld"].SetValue(value);
        _world = value;
    }
}

Thanking you in anticipation.

\$\endgroup\$
2
  • \$\begingroup\$ I added the DirectX tag, on the basis that this is lower-level functionality than XNA. \$\endgroup\$ Oct 15, 2012 at 13:20
  • \$\begingroup\$ I have found proof that the topic at hand is VERY viable. It looks like if you are clever with how you set your effect parameters, you can increase the number of draw calls (that is how fast they are processed on the CPU) more than twice. I am still in the process of testing this, you can read my question here: gamedev.stackexchange.com/questions/66932/… \$\endgroup\$
    – cubrman
    Dec 9, 2013 at 10:45

2 Answers 2

8
\$\begingroup\$

This all happens on the CPU side, so if caching were a useful feature, then I would speculate that the graphics driver would implement it itself. Adding your own caching layer is unnecessary.

My understanding is that whenever you set a parameter, and whenever you call Apply, these calls are passed to DirectX largely as-is, and in turn passed to the user-mode GPU driver as-is. The user-mode driver can then do whatever the hell it wants. All three of your scenarios are possible.

(Because scenario #2 is a possibility, it's probably best not to run around deliberately re-setting parameters that don't change.)

To be honest, I'm not really sure what a typical driver does. Mostly because it's never really come up as an issue. I've never heard of anyone having effect-parameter setting as a bottleneck. Maybe it could be, in theory. But there are so many more common things to worry about.

Certainly don't start implementing optimisations like this without measuring your performance and understanding what's going on.

Also, comparing a Matrix with == is bad voodoo. A Matrix is made up of floats, and floating-point equality comparisons are prone to failure in many cases.

And, generally speaking, the pattern if(x != y) x = y; is slower than simply x = y.

\$\endgroup\$
2
  • \$\begingroup\$ Interesting point that driver should care about this. Thanks for the link (and re-links). \$\endgroup\$
    – 0xBADF00D
    Oct 15, 2012 at 14:36
  • \$\begingroup\$ I recently came across the geometry instancing example from msdn. Resetting the same renderstates (with same values) multiple times per frame significantly slows down the rendering process by two or three times. So state batching is deferentially useful. Unfortunately I'm not sure weather this situation applies to setting effect parameters, too. But I would like to share my information. \$\endgroup\$
    – 0xBADF00D
    Nov 21, 2012 at 10:07
4
\$\begingroup\$

One interesting thing I found about this topic.

From msdn:

You can use the Parameters indexed property on Effect to access any effect parameter, but this is slower than using EffectParameters. For this reason, you should create an EffectParameter for each effect parameter that changes frequently.

and

Creating and assigning a EffectParameter instance for each technique in your Effect is significantly faster than using the Parameters indexed property on Effect.

That means that _effect.Parameters["xWorld"].SetValue(value); is noticeably slower than wordlParam.SetValue(value);

So you should probably cache parameters like this:

public EffectParameter wordlParam;
wordlParam = _effect.Parameters["xWorld"];

But I haven't found any actual benchmarks.

Sources:

http://msdn.microsoft.com/en-us/library/Microsoft.Xna.Framework.Graphics.EffectParameter%28v=xnagamestudio.40%29.aspx http://msdn.microsoft.com/en-us/library/bb976060%28v=xnagamestudio.31%29.aspx

\$\endgroup\$
1
  • \$\begingroup\$ Just tested this on Monogame and WP emulator - I can confirm that indeed, there is a significant difference (between 5-15% in my case). Are there any more such tricks that help in performance? \$\endgroup\$
    – Konrad
    Aug 25, 2015 at 18:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .