Meilleure pratique pour définir les paramètres d'effet dans XNA

13

Je veux demander s'il existe une meilleure pratique pour définir les Effectparamètres dans XNA. Ou en d'autres termes, que se passe-t-il exactement lorsque j'appelle pass.Apply(). Je peux imaginer plusieurs scénarios:

  1. Chaque fois que vous Applyappelez, tous les paramètres d'effet sont transférés vers le GPU et il n'a donc aucune influence réelle sur la fréquence à laquelle je règle un paramètre.
  2. À chaque Applyappel, seuls les paramètres réinitialisés sont transférés. Il faut donc éviter la mise en cache des opérations Set qui ne définissent pas réellement de nouvelle valeur.
  3. A chaque Applyappel, seuls les paramètres modifiés sont transférés. La mise en cache des opérations Set est donc inutile.
  4. Toute cette question est sans démarrage car aucun des moyens mentionnés n'a un impact notable sur les performances du jeu.

Donc, la dernière question: est-il utile d'implémenter une mise en cache de l'opération d'ensemble comme:

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

Merci d'avance.

0xBADF00D
la source
J'ai ajouté la balise DirectX, car il s'agit d'une fonctionnalité de niveau inférieur à XNA.
Andrew Russell
J'ai trouvé la preuve que le sujet traité est TRÈS viable. Il semble que si vous êtes intelligent avec la façon dont vous définissez vos paramètres d'effet, vous pouvez augmenter le nombre d'appels de tirage (c'est-à-dire la vitesse à laquelle ils sont traités sur le CPU) plus de deux fois. Je suis toujours en train de tester cela, vous pouvez lire ma question ici: gamedev.stackexchange.com/questions/66932/…
cubrman

Réponses:

8

Tout cela se produit du côté du processeur, donc si la mise en cache était une fonctionnalité utile, je suppose que le pilote graphique l'implémenterait lui-même. L'ajout de votre propre couche de mise en cache n'est pas nécessaire.

D'après ce que je comprends, chaque fois que vous définissez un paramètre et chaque fois que vous appelez Apply, ces appels sont transmis à DirectX en grande partie tels quels, et à leur tour transmis au pilote de GPU en mode utilisateur tel quel . Le pilote en mode utilisateur peut alors faire ce qu'il veut . Vos trois scénarios sont possibles.

(Parce que le scénario # 2 est une possibilité, il est probablement préférable de ne pas contourner délibérément les paramètres qui ne changent pas.)

Pour être honnête, je ne suis pas vraiment sûr de ce que fait un conducteur typique. Surtout parce que ce n'est jamais vraiment un problème. Je n'ai jamais entendu parler de quelqu'un ayant le réglage des paramètres d'effet comme goulot d'étranglement. Peut-être que ça pourrait l'être, en théorie. Mais il y a tellement de choses plus communes à se soucier .

Ne commencez certainement pas à implémenter de telles optimisations sans mesurer vos performances et comprendre ce qui se passe.

De plus, comparer un Matrixavec ==est un mauvais vaudou. A Matrixest composé de floats, et les comparaisons d'égalité à virgule flottante sont sujettes à l'échec dans de nombreux cas.

Et, d'une manière générale, le modèle if(x != y) x = y;est plus lent que simplement x = y.

Andrew Russell
la source
Point intéressant que le conducteur devrait se soucier de cela. Merci pour le lien (et les liens).
0xBADF00D
J'ai récemment rencontré l'exemple d'instanciation de la géométrie de msdn . La réinitialisation des mêmes rendus (avec les mêmes valeurs) plusieurs fois par image ralentit considérablement le processus de rendu de deux ou trois fois. Par conséquent, le traitement par lots d'état est utile avec déférence. Malheureusement, je ne suis pas sûr que cette situation s'applique également au réglage des paramètres d'effet. Mais je voudrais partager mes informations.
0xBADF00D
4

Une chose intéressante que j'ai trouvée sur ce sujet.

De msdn:

Vous pouvez utiliser la propriété indexée Parameters sur Effect pour accéder à n'importe quel paramètre d'effet, mais cela est plus lent que d'utiliser EffectParameters. Pour cette raison, vous devez créer un EffectParameter pour chaque paramètre d'effet qui change fréquemment.

et

La création et l'affectation d'une instance EffectParameter pour chaque technique de votre effet est beaucoup plus rapide que l'utilisation de la propriété indexée Paramètres sur Effect.

Cela signifie que _effect.Parameters["xWorld"].SetValue(value);c'est nettement plus lent quewordlParam.SetValue(value);

Vous devez donc probablement mettre en cache des paramètres comme celui-ci:

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

Mais je n'ai trouvé aucun repère réel.

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

zigzag
la source
Je viens de tester cela sur Monogame et l'émulateur WP - je peux confirmer qu'en effet, il y a une différence significative (entre 5-15% dans mon cas). Existe-t-il d'autres astuces de ce type qui améliorent les performances?
Konrad