Ich habe Probleme, den konzeptionellen Unterschied zwischen einheitlichen Puffern und Push-Konstanten zu verstehen. Nach dem, was ich durch Lesen der Spezifikation feststellen kann, sind die Hauptunterschiede:
- Gleichmäßige Puffer können viel größer sein als Push-Konstanten.
- UBOs verwenden std140, PCs verwenden std430.
- UBOs können jederzeit mit vkCmdUpdateBuffer (oder Host-Mapping) aktualisiert werden und behalten ihre Werte bei, andernfalls müssen PCs für jeden Renderdurchlauf erneut gepusht werden. (Was mich überraschte - basierend auf dem Namen. Ich dachte, ich würde die Konstanten in der Pipeline buchstäblich aktualisieren und diese Änderungen beibehalten.)
In meinem Szenario habe ich Daten im Wert von ca. 200 Byte, von denen ich erwarte, dass sie größtenteils konstant sind . Das heißt, ich werde sie sehr selten ändern. Wäre es besser (unter der Annahme, dass die Größe dies zulässt) Push-Konstanten zu verwenden, obwohl ich sie in jedem Befehlspuffer erneut senden muss? Oder wäre es besser, ein 200-Byte-UBO zu verwenden und es nur selten mit vkCmdUpdatebuffer zu aktualisieren?
Ebenfalls. Was ist, wenn ich zB eine habe float random_seed
, die ich jedes Mal aktualisiere, wenn der Shader ausgeführt wird? Angenommen, ich habe bereits ein UBO, wäre es besser, dies mit dem UBO zusammenzufassen, obwohl der Rest des UBO konstant ist, oder würde ich einen Vorteil aus der Verwendung von Push-Konstanten für speziell diese Variable ziehen, damit ich dies vermeiden muss vkCmdUpdateBuffer vor jedem Renderdurchlauf?
Antworten:
Aus der Spezifikation: "vkCmdUpdateBuffer ist nur außerhalb eines Renderdurchlaufs zulässig." "Zu jeder Zeit" ist also nicht der Fall.
Selbst wenn es innerhalb eines Renderpasses erlaubt wäre, ist es immer noch ein Übertragungsvorgang. Das heißt, Sie müssen die Speicherübertragung mit den Befehlen synchronisieren, die sie verwenden. Was die Leistung verlangsamt.
Verwenden Sie für die allgemeine Sache Push Constant vs. Uniform Ihr Urteilsvermögen. Mit "Urteil" meine ich nur, wie sie funktionieren. Mit Push-Konstanten können Sie ihre Daten jederzeit ändern, ohne schwere Prozesse wie Speicheroperationen, Synchronisierung oder Änderung des Deskriptorstatus ausführen zu müssen. Sie sind eindeutig für häufig wechselnde Daten gedacht. Wie häufig ist "häufig"? Nun, das ist ein Urteilsspruch.
Wenn dies nicht der Fall ist, profilieren Sie den Leistungsunterschied.
quelle
Wenn sich die Daten selten ändern, können Sie Spezialisierungskonstanten verwenden . Sie werden festgelegt, wenn die Pipeline erstellt wird, und eine neue Pipeline muss erstellt werden, wenn Sie die Werte ändern müssen. Für ein seltenes Ereignis, wie z. B. die Größenänderung eines Fensters, können dies akzeptable Kosten sein.
Das ist ein perfekter Anwendungsfall für Push-Konstanten. Sie können alle anderen Daten im UBO (oder in den Spezialisierungskonstanten) behalten und diesen Wert mit ändern
VkCmdPushConstants
.quelle