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:
- Los amortiguadores uniformes pueden ser mucho más grandes que las constantes de empuje.
- Las UBO usan std140, las PC usan std430.
- 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_seed
que 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?
Respuestas:
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.
fuente
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.
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
.fuente