Vulkan: Buffers uniformes versus constantes de inserción para datos estáticos

8

Estoy luchando por entender la diferencia conceptual entre buffers uniformes y constantes de empuje. De lo que puedo deducir leyendo las especificaciones, las principales diferencias son:

  1. Los amortiguadores uniformes pueden ser mucho más grandes que las constantes de empuje.
  2. Las UBO usan std140, las PC usan std430.
  3. Los UBO se pueden actualizar en cualquier momento con vkCmdUpdateBuffer (o mapeo de host) y persisten sus valores; de lo contrario, las PC deben volver a presionarse para cada paso de renderizado. (Lo que me sorprendió, según el nombre. Pensé que literalmente estaría actualizando constantes en la tubería en el lugar, y que esos cambios persistieran)

En mi escenario, tengo alrededor de ~ 200 bytes de datos que espero sean en su mayoría constantes . Es decir, los cambiaré con poca frecuencia. ¿Sería mejor (suponiendo que el tamaño lo permita) usar constantes de inserción aunque tenga que volver a enviarlas en cada búfer de comando? ¿O sería mejor usar un UBO de 200 bytes y solo actualizarlo con poca frecuencia con vkCmdUpdatebuffer?

También. ¿Qué sucede si tengo, por ejemplo, un float random_seedque actualizaré cada vez que se ejecute el sombreador? Suponiendo que ya tengo un UBO, ¿sería mejor agruparlo con el UBO, a pesar de que el resto del UBO es constante, o obtendría un beneficio al usar constantes de empuje específicamente para esta variable, así puedo evitar tener que vkCmdUpdateBuffer antes de cada pase de renderizado?

haasn
fuente
¡Bienvenido al sitio de intercambio de pila de gráficos por computadora! No estoy familiarizado con Vulkan, pero parece que usar un UBO sería más eficiente en su caso (puede intentar comparar el rendimiento de ambos enfoques en un programa de muestra). ¿Con qué API gráficas estás familiarizado? También te puede interesar esta presentación de GDC 2012: No lo tires todo: Gestión eficiente del búfer
wip
De la documentación de Vulkan : mientras que un UBO asigna un bloque de memoria de video en la GPU (que puede actualizar en un momento posterior), Push Constant no usa memoria de video (es por eso que debe proporcionarse durante cada llamada de sorteo / cálculo, o de lo contrario el sombreador no sabría qué valor usar). Supongo que se almacena en otro área de almacenamiento rápido a corto plazo en la GPU, aunque los detalles pueden depender de su proveedor de GPU.
wip

Respuestas:

8

Los UBO se pueden actualizar en cualquier momento con vkCmdUpdateBuffer

De la especificación: "vkCmdUpdateBuffer solo se permite fuera de un pase de representación". Entonces "en cualquier momento" no es el caso.

Incluso si se permitiera dentro de un pase de representación, sigue siendo una operación de transferencia. Lo que significa que necesita sincronizar la transferencia de memoria con los comandos que la usan. Lo que ralentiza el rendimiento.

Para lo general de Push Constant vs. Uniform, usa tu criterio. Por "juicio", me refiero a solo mirar cómo funcionan. Las constantes de inserción le permiten cambiar sus datos en cualquier momento sin realizar procesos pesados ​​como operaciones de memoria, sincronización o alterar el estado del descriptor. Claramente, son para datos que cambian con frecuencia. ¿Con qué frecuencia es "con frecuencia"? Bueno, eso es una decisión judicial.

De lo contrario, perfile la diferencia de rendimiento.

Nicol Bolas
fuente
2

Tengo alrededor de ~ 200 bytes de datos que espero sean en su mayoría constantes. Es decir, los cambiaré con poca frecuencia.

Si los datos cambian con poca frecuencia, puede utilizar las constantes de especialización . Se establecen cuando se crea la tubería, y se debe crear una nueva tubería si necesita cambiar los valores. Para un evento poco frecuente, como el cambio de tamaño de una ventana, este puede ser un costo aceptable.

¿Qué sucede si tengo, por ejemplo, un float random_seed que actualizaré cada vez que se ejecute el sombreador?

Es un caso de uso perfecto para Push Constants. Puede mantener todos los demás datos en el UBO (o en las constantes de especialización) y cambiar este valor con VkCmdPushConstants.

vazgriz
fuente