Vulkan: Einheitliche Puffer versus Push-Konstanten für statische Daten

8

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:

  1. Gleichmäßige Puffer können viel größer sein als Push-Konstanten.
  2. UBOs verwenden std140, PCs verwenden std430.
  3. 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?

haasn
quelle
Willkommen auf der Computer Graphics Stack Exchange-Website! Ich bin mit Vulkan nicht vertraut, aber es scheint, dass die Verwendung eines UBO in Ihrem Fall effizienter wäre (Sie können versuchen, die Leistungen beider Ansätze in einem Beispielprogramm zu vergleichen). Welche Grafik-APIs kennen Sie? Auch Sie könnten an dieser GDC 2012 Präsentation interessiert sein: Werfen Sie nicht alles weg: Effizientes
Wip
Aus der Vulkan-Dokumentation : Während ein UBO einen Block Videospeicher auf der GPU zuweist (den Sie zu einem späteren Zeitpunkt aktualisieren können), verwendet die Push-Konstante keinen Videospeicher (weshalb er bei jedem Draw / Compute-Aufruf bereitgestellt werden muss). Andernfalls weiß der Shader nicht, welchen Wert er verwenden soll. Ich denke, es wird in einem anderen kurzfristigen, schnellen Speicherbereich auf der GPU gespeichert, obwohl die Details möglicherweise von Ihrem GPU-Anbieter abhängen.
Wischen Sie den

Antworten:

8

UBOs können jederzeit mit vkCmdUpdateBuffer aktualisiert werden

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.

Nicol Bolas
quelle
2

Ich habe 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.

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.

Was ist, wenn ich zB einen float random_seed habe, den ich jedes Mal aktualisiere, wenn der Shader ausgeführt wird?

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.

vazgriz
quelle