Visual Studio 2010 hat einen Profiler eingebaut.
Den Hinweis mit den Debug-Primitives möchte ich unterstreichen. Den Hinweis zur Vorsortierung nach States umso mehr. Bei mir sieht das grade so aus:
Pro Renderjob wird nur zwischen Einzelobjekt, Einzel-Objekt mit Bones oder Objektgruppe per Instancing. Die Unterscheidung beeinflusst aber nur die Wahl der Vertex-Deklaration und ein paar Zeilen im VertexShader, der Rest ist auch gleich. Trotzdem empfiehlt es sich, nach diesen Gruppen zuerst zu sortieren, da ein Wechsel der Vertex-Deklaration mit das teuerste unter den Treiberaufgaben ist. Wir hatten sogar zwischendurch mal einen Modus, wo selbst Einzelobjekte per Einzel-Instancing gezeichnet wurden, was nochmal ein paar Prozent Performance gebracht hat.
Ich rate dringend davon ab, ein Sprite als einzelnen DrawCall zu rendern. Das wäre genauso albern wie jeden Punkt in der Punktwolke einzeln zu rendern. Sammle alle ähnlichen Sprites, packe sie in einen dynamischen VertexBuffer, und render sie auf einmal. Punktwolken und Linien würde ich ebenso zur Laufzeit erst sammeln und dann in einem Rutsch rendern. Mach Dir eine einfache DrawLine( Start, Ziel, Farbe)-Funktion, die die Engine alle sammelt und nach allem Kram dann rendert. Das ist ein wertvolles Debug-Werkzeug. Abgesehen davon rendert man in einem Spiel einfach nie Linien oder Punktwolken - den Teil kannst Du Dir meines Erachtens sparen.
Außerdem empfehle ich noch ein schlichtes Layer-System. Mach nicht nur eine Renderjob-Queue, die Du dann sortierst und abarbeitest, mach ein Dutzend und erlaube dem Aufrufer, dass er die Wunsch-Queue angibt. Das ist schnell gemacht, erweist sich auf lange Sicht aber durchaus als nützlich.