Vulkan: tampons uniformes contre constantes push pour les données statiques

8

J'ai du mal à comprendre la différence conceptuelle entre les tampons uniformes et les constantes push. D'après ce que je peux recueillir en lisant les spécifications, les principales différences sont les suivantes:

  1. Les tampons uniformes peuvent être beaucoup plus grands que les constantes push.
  2. Les UBO utilisent std140, les PC utilisent std430.
  3. Les UBO peuvent être mis à jour à tout moment avec vkCmdUpdateBuffer (ou mappage d'hôte) et conserver leurs valeurs sinon les PC doivent être repoussés pour chaque passage de rendu. (Ce qui m'a surpris - sur la base du nom. Je pensais que je mettrais littéralement à jour les constantes dans le pipeline en place et que ces changements persistent)

Dans mon scénario, j'ai environ 200 octets de données que je pense être presque constants . Autrement dit, je les changerai très rarement. Serait-il préférable (en supposant que la taille le permette) d'utiliser des constantes push même si je dois les renvoyer dans chaque tampon de commande? Ou serait-il préférable d'utiliser un UBO de 200 octets et de le mettre à jour rarement avec vkCmdUpdatebuffer?

Aussi. que faire si j'ai par exemple un float random_seedque je mettrai à jour à chaque exécution du shader? En supposant que j'ai déjà un UBO, serait-il préférable de regrouper cela avec l'UBO, même si le reste de l'UBO est constant, ou est-ce que je gagnerais à utiliser des constantes push pour spécifiquement cette variable, afin que je puisse éviter d'avoir à vkCmdUpdateBuffer avant chaque passage de rendu?

haasn
la source
Bienvenue sur le site Exchange Graphics Stack Exchange! Je ne connais pas Vulkan mais il semble que l'utilisation d'un UBO serait plus efficace dans votre cas (vous pouvez essayer de comparer les performances des deux approches dans un exemple de programme). Quelles API graphiques connaissez-vous? Vous pourriez également être intéressé par cette présentation de GDC 2012: Don't Throw it all Away: Efficient Buffer Management
wip
D'après la documentation de Vulkan : alors qu'un UBO alloue un bloc de mémoire vidéo sur le GPU (que vous pouvez mettre à jour ultérieurement), la constante de poussée n'utilise pas de mémoire vidéo (c'est pourquoi elle doit être fournie lors de chaque appel de dessin / calcul, sinon le shader ne saurait pas quelle valeur utiliser). Je suppose qu'il est stocké dans une autre zone de stockage rapide à court terme sur le GPU, bien que les détails puissent dépendre de votre fournisseur de GPU.
essuyer

Réponses:

8

Les UBO peuvent être mis à jour à tout moment avec vkCmdUpdateBuffer

D'après la spécification: "vkCmdUpdateBuffer n'est autorisé qu'en dehors d'une passe de rendu." Donc, "à tout moment" n'est pas le cas.

Même s'il était autorisé à l'intérieur d'une passe de rendu, il s'agit toujours d'une opération de transfert. Ce qui signifie que vous devez synchroniser le transfert de mémoire avec les commandes qui l'utilisent. Ce qui ralentit les performances.

Pour la chose générale Push Constant vs Uniform, utilisez votre jugement. Par «jugement», je veux juste dire comment ils fonctionnent. Les constantes push vous permettent de modifier leurs données à tout moment sans effectuer de processus lourds comme les opérations de mémoire, la synchronisation ou la modification de l'état du descripteur. De toute évidence, ils sont destinés à modifier fréquemment les données. Quelle est la fréquence de "fréquemment"? Eh bien, c'est un jugement.

A défaut, profilez la différence de performances.

Nicol Bolas
la source
2

J'ai environ 200 octets de données que je m'attends à ce qu'ils soient généralement constants. Autrement dit, je les changerai très rarement.

Si les données changent rarement, vous pouvez utiliser des constantes de spécialisation . Ils sont définis lors de la création du pipeline et un nouveau pipeline doit être créé si vous devez modifier les valeurs. Pour un événement peu fréquent, comme un redimensionnement de fenêtre, cela peut être un coût acceptable.

que faire si j'ai par exemple un float random_seed que je mettrai à jour à chaque exécution du shader?

C'est un cas d'utilisation parfait pour les constantes push. Vous pouvez conserver toutes les autres données dans l'UBO (ou dans les constantes de spécialisation) et modifier cette valeur avec VkCmdPushConstants.

vazgriz
la source