Práctica recomendada para establecer parámetros de efectos en XNA

13

Quiero preguntar si hay una mejor práctica para configurar Effectparámetros en XNA. O en otras palabras, qué sucede exactamente cuando llamo pass.Apply(). Me puedo imaginar múltiples escenarios:

  1. Cada vez que Applyse llama, todos los parámetros de efectos se transfieren a la GPU y, por lo tanto, no tiene una influencia real con qué frecuencia configuro un parámetro.
  2. Cada vez que Applyse llama, solo se transfieren los parámetros que se restablecieron. Por lo tanto, debe evitarse el almacenamiento en caché de las operaciones Set que realmente no establecen un nuevo valor.
  3. Cada vez que Applyse llama, solo se transfieren los parámetros que se modificaron. Por lo tanto, el almacenamiento en caché de las operaciones Set es inútil
  4. Toda esta pregunta no tiene arranque porque ninguna de las formas mencionadas tiene un impacto notable en el rendimiento del juego.

Entonces, la pregunta final: ¿es útil implementar algún almacenamiento en caché de la operación de configuración como:

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

Agradeciendo de antemano.

0xBADF00D
fuente
Agregué la etiqueta DirectX, sobre la base de que esta es una funcionalidad de nivel inferior que XNA.
Andrew Russell
He encontrado pruebas de que el tema en cuestión es MUY viable. Parece que si es inteligente con la forma en que configura sus parámetros de efecto, puede aumentar el número de llamadas de extracción (es decir, qué tan rápido se procesan en la CPU) más de dos veces. Todavía estoy en el proceso de probar esto, puedes leer mi pregunta aquí: gamedev.stackexchange.com/questions/66932/…
cubrman

Respuestas:

8

Todo esto sucede en el lado de la CPU, por lo que si el almacenamiento en caché fuera una característica útil, entonces especularía que el controlador de gráficos lo implementaría por sí mismo. Agregar su propia capa de almacenamiento en caché es innecesario.

Tengo entendido que cada vez que configura un parámetro, y cada vez que llama Apply, estas llamadas se transfieren a DirectX en su mayoría tal cual, y a su vez se transmiten al controlador de GPU en modo de usuario tal cual. El controlador de modo de usuario puede hacer lo que quiera . Los tres escenarios son posibles.

(Debido a que el escenario # 2 es una posibilidad, probablemente sea mejor no correr deliberadamente reestableciendo parámetros que no cambian).

Para ser honesto, no estoy muy seguro de lo que hace un conductor típico. Principalmente porque nunca ha surgido como un problema. Nunca he oído hablar de alguien que tenga la configuración de parámetros de efecto como un cuello de botella. Tal vez podría ser, en teoría. Pero hay muchas cosas más comunes de las que preocuparse .

Ciertamente, no comience a implementar optimizaciones como esta sin medir su rendimiento y comprender lo que está sucediendo.

Además, comparar un Matrixcon ==es un vudú malo. A Matrixestá formado por floats, y las comparaciones de igualdad de punto flotante son propensas al fracaso en muchos casos.

Y, en general, el patrón if(x != y) x = y;es más lento que simplemente x = y.

Andrew Russell
fuente
Punto interesante que el conductor debería preocuparse por esto. Gracias por el enlace (y re-enlaces).
0xBADF00D
Recientemente me encontré con el ejemplo de instancias de geometría de msdn . Restablecer los mismos renderizados (con los mismos valores) varias veces por cuadro ralentiza significativamente el proceso de renderizado dos o tres veces. Por lo tanto, el procesamiento por lotes de estado es deferencialmente útil. Lamentablemente, no estoy seguro de si esta situación se aplica también a la configuración de parámetros de efectos. Pero me gustaría compartir mi información.
0xBADF00D
4

Una cosa interesante que encontré sobre este tema.

De msdn:

Puede usar la propiedad indexada Parámetros en Effect para acceder a cualquier parámetro de efecto, pero esto es más lento que usar EffectParameters. Por esta razón, debe crear un EffectParameter para cada parámetro de efecto que cambie con frecuencia.

y

Crear y asignar una instancia de EffectParameter para cada técnica en su Efecto es significativamente más rápido que usar la propiedad indexada Parámetros en Effect.

Eso significa que _effect.Parameters["xWorld"].SetValue(value);es notablemente más lento quewordlParam.SetValue(value);

Entonces, probablemente debería almacenar en caché parámetros como este:

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

Pero no he encontrado ningún punto de referencia real.

Fuentes:

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
fuente
Acabo de probar esto en el emulador Monogame y WP: puedo confirmar que, de hecho, hay una diferencia significativa (entre el 5-15% en mi caso). ¿Hay más trucos que ayuden en el rendimiento?
Konrad