expensive calls

What are the most expensive calls in the render process

- Effect.CurrentTechnique  = something

- Effect.Begin

- Effect.Parameters["xy"] = something

- switching vertex or index buffers

I am just wondering which calls I should avoid to repeat if possible/or where is room for optimization...

I understand of course that generally you should make as few calls as possible and do as much as possible in one call. But with XNA and the GameComponents the art is I guess to find the balance between OO-Design and maximum performance, so I just need to know where I have to tackle.



Answer this question

expensive calls

  • Jim Perry

    OK, so as an example, if I would have 1000 GameComponents (just an example ;)) and each and everyone of them would do this:

    public override void Update()
    {
    // set effect parameters
    this.effect.Parameter["WorldViewProjection"] = ...;
    this.effect.Parameter["Translation"] = ...;
    this.effect.Parameter["Light"] = ...;
    }

    and

    public override void Draw()
    {
    foreach (Subset subset in this.subsets)
    {
    // set index and vertex buffer
    ...
    this.effect.CurrentTechnique = this.effect.Techniques["posnorm"];
    this.effect.Begin(...);
    foreach (EffectPass pass in this.effect.CurrentTechnique.Passes)
    {
    // .. draw indexed primitives
    }
    this.effect.End();
    }
    }

    Would gain much performance if I rip the component wise drawing and updating appart (if all of them use the same drawing technique and effect parameters). Then I would have to sort them by drawing technique and effect parameters and have a drawing method outside that calls the draw indexed primitives for each pass on each of the objects. Considering such an extreme scenario, would that optimization have significant impact Would it be worth it for 100 game components What do you think


  • kirank_gh

    All of the Effect related calls you listed are generally set together when you switch effects.

    In general, the cost of changing Effects (including setting parameters etc) is more expensive than switching index of vertex buffers.

    If you have the choice, minimize Effect changes.

    My engine for example, sorts the draw operations in order to minimize Effect changes (and other state changes), and it achieves about 5 times better performance than if each object just applies it's own effects when rendering. (Which is the way Model drawing is usually implemented.)

  • grumbs

    Good idea! Thanks for that!


  • ReneeC

    I would say, write the code you need to write as well as you can, see what kind of performance you get then optimize as necessary.

  • Jonathan Clark

    I don't recommend you perform that optimization. However, if you do optimize the drawing (minimize Effect changes and other state changes) you will make rendering speed between 2 and 5 times faster. If your card supports "instancing" and you implement that, you will increase performance way more than that even.

    Is it worth it to you Probably not, especially if you only have 100 objects.

    Do you have to rip apart your nice object oriented update and draw methods to do it No, not really.

    Here's what I do:

    MyObject.Draw(Context c)
    {
    c.Effect = myEffect
    c.WorldViewProjection = myWorldViewProjection
    c.Translation = myTranslation
    c.Light = myLight
    c.VertexBuffer[0] = myVertexBuffer;
    c.Indexbuffer = myIndexBuffer;
    c.DrawIndexedPrimitives(myParameters...);
    }

    Just as simple as your code. Here's the difference: I use my "Context" abstraction, and it doesn't actually perform rendering immediately, it just captures all of the call information and stores it. Later when it needs to be flushed, it efficiently renders all solid object (using a single Effect.Begin/End pair for each effect) and then depth sorts the transparent objects so they appear correctly, then renders them.



  • expensive calls