Sur cette page

QRhiBuffer Class

Ressource de tampon de sommets, d'index ou uniforme (constante). En savoir plus...

En-tête : #include <rhi/qrhi.h>
CMake : find_package(Qt6 REQUIRED COMPONENTS GuiPrivate)
target_link_libraries(mytarget PRIVATE Qt6::GuiPrivate)
qmake : QT += gui-private
Depuis : Qt 6.6
Hérite de : QRhiResource

Types publics

struct NativeBuffer
enum Type { Immutable, Static, Dynamic }
enum UsageFlag { VertexBuffer, IndexBuffer, UniformBuffer, StorageBuffer, IndirectBuffer }
flags UsageFlags

Fonctions publiques

virtual char *beginFullDynamicBufferUpdateForCurrentFrame()
virtual bool create() = 0
virtual void endFullDynamicBufferUpdateForCurrentFrame()
virtual QRhiBuffer::NativeBuffer nativeBuffer()
void setSize(quint32 sz)
void setType(QRhiBuffer::Type t)
void setUsage(QRhiBuffer::UsageFlags u)
quint32 size() const
QRhiBuffer::Type type() const
QRhiBuffer::UsageFlags usage() const

Fonctions publiques réimplémentées

virtual QRhiResource::Type resourceType() const override

Description détaillée

Remarque : il s’agit d’une API RHI dont la compatibilité n’est pas entièrement garantie ; pour plus de détails, consultez QRhi.

Un QRhiBuffer encapsule zéro, un ou plusieurs objets tampons natifs (tels que VkBuffer ou MTLBuffer). Avec certaines API graphiques et certains backends, certains types de tampons peuvent ne pas utiliser du tout d’objet tampon natif (par exemple OpenGL si les objets tampons uniformes ne sont pas utilisés), mais cela est transparent pour l’utilisateur de l’API QRhiBuffer. De même, le fait que certains types de tampons puissent utiliser deux ou trois tampons natifs en arrière-plan, afin de permettre une mise à jour efficace du contenu à chaque image sans bloquer le pipeline du GPU, est pratiquement invisible pour les applications et les bibliothèques.

Une instance de QRhiBuffer est toujours créée en appelant ` the QRhi's newBuffer() function`. Cela ne crée aucune ressource graphique native. Pour ce faire, appelez ` create()` après avoir défini les options appropriées, telles que le type, les indicateurs d'utilisation et la taille, bien que dans la plupart des cas, celles-ci soient déjà définies en fonction des arguments passés à ` newBuffer()`.

Exemple d’utilisation

Pour créer un tampon « uniform » pour un shader dont le bloc « uniform » GLSL contient un seul élément de type ` mat4 `, et mettre à jour son contenu :

QRhiBuffer *ubuf = rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 64);
if (!ubuf->create()) { error(); }
QRhiResourceUpdateBatch *batch = rhi->nextResourceUpdateBatch();
QMatrix4x4 mvp;
// ... set up the modelview-projection matrix
batch->updateDynamicBuffer(ubuf, 0, 64, mvp.constData());
// ...
commandBuffer->resourceUpdate(batch); // or, alternatively, pass 'batch' to a beginPass() call

Exemple de création d’un tampon contenant des données de sommets :

const float vertices[] = { -1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 1.0f };
QRhiBuffer *vbuf = rhi->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, sizeof(vertices));
if (!vbuf->create()) { error(); }
QRhiResourceUpdateBatch *batch = rhi->nextResourceUpdateBatch();
batch->uploadStaticBuffer(vbuf, vertices);
// ...
commandBuffer->resourceUpdate(batch); // or, alternatively, pass 'batch' to a beginPass() call

Un tampon d’index :

static const quint16 indices[] = { 0, 1, 2 };
QRhiBuffer *ibuf = rhi->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::IndexBuffer, sizeof(indices));
if (!ibuf->create()) { error(); }
QRhiResourceUpdateBatch *batch = rhi->nextResourceUpdateBatch();
batch->uploadStaticBuffer(ibuf, indices);
// ...
commandBuffer->resourceUpdate(batch); // or, alternatively, pass 'batch' to a beginPass() call

Modèles courants

Un appel à ` create()` détruit toutes les ressources natives existantes si ` create()` a été appelé avec succès auparavant. Si ces ressources natives sont encore utilisées par une image en cours de traitement (c’est-à-dire s’il est possible qu’elles soient encore lues par le GPU), leur destruction est automatiquement reportée. Ainsi, le modèle suivant est très courant et pratique pour augmenter en toute sécurité la taille d’un tampon déjà initialisé. En pratique, cela supprime et crée un tout nouvel ensemble de ressources natives en arrière-plan ; il ne s’agit donc pas nécessairement d’une opération peu coûteuse, mais elle est plus pratique et tout de même plus rapide que les alternatives, car en ne détruisant pas l’objet ` buf ` lui-même, toutes les références à celui-ci restent valides dans d’autres structures de données (par exemple, dans tout ` QRhiShaderResourceBinding ` à partir duquel le `QRhiBuffer` est référencé).

if (buf->size() < newSize) {
    buf->setSize(newSize);
    if (!buf->create()) { error(); }
}
// continue using buf, fill it with new data

Lorsque vous travaillez avec des tampons uniformes, il est parfois nécessaire, pour des raisons d’efficacité, de regrouper les données de plusieurs appels de dessin dans un seul tampon. Tenez compte des contraintes d’alignement : avec certaines API graphiques, les décalages d’un tampon uniforme doivent être alignés sur 256 octets. Cela s’applique aussi bien à QRhiShaderResourceBinding qu’aux décalages dynamiques passés à setShaderResources(). Utilisez les fonctions ubufAlignment() et ubufAligned() pour créer du code portable. À titre d’exemple, voici un schéma permettant d’émettre plusieurs appels de dessin (N) avec le même pipeline et la même géométrie, mais avec des données différentes dans les tampons uniformes exposés au point de liaison 0. Cela suppose que le tampon soit exposé via uniformBufferWithDynamicOffset(), ce qui permet de passer une liste QRhiCommandBuffer::DynamicOffset à setShaderResources().

const int N = 2;
const int UB_SIZE = 64 + 4; // assuming a uniform block with { mat4 matrix; float opacity; }
const int ONE_UBUF_SIZE = rhi->ubufAligned(UB_SIZE);
const int TOTAL_UBUF_SIZE = N * ONE_UBUF_SIZE;
QRhiBuffer *ubuf = rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, TOTAL_UBUF_SIZE);
if (!ubuf->create()) { error(); }
QRhiResourceUpdateBatch *batch = rhi->nextResourceUpdateBatch();
for (int i = 0; i < N; ++i) {
    batch->updateDynamicBuffer(ubuf, i * ONE_UBUF_SIZE, 64, matrix.constData());
    batch->updateDynamicBuffer(ubuf, i * ONE_UBUF_SIZE + 64, 4, &opacity);
}
// ...
// beginPass(), set pipeline, etc., and then:
for (int i = 0; i < N; ++i) {
    QRhiCommandBuffer::DynamicOffset dynOfs[] = { { 0, i * ONE_UBUF_SIZE } };
    cb->setShaderResources(srb, 1, dynOfs);
    cb->draw(36);
}

Voir également QRhiResourceUpdateBatch, QRhi et QRhiCommandBuffer.

Documentation sur les types de membres

enum QRhiBuffer::Type

Spécifie le type de stockage de la ressource tampon.

ConstanteValeurDescription
QRhiBuffer::Immutable0Indique que les données ne devraient plus jamais changer après le chargement initial. En arrière-plan, ces ressources de tampon sont généralement placées dans la mémoire locale du périphérique (GPU) (sur les systèmes où cela est applicable). Le chargement de nouvelles données est possible, mais peut s’avérer coûteux. Le chargement s’effectue généralement par copie vers un tampon intermédiaire distinct, visible par l’hôte, à partir duquel une copie de tampon à tampon est effectuée vers le tampon propre au GPU.
QRhiBuffer::Static1Indique que les données ne devraient changer que rarement. Généralement stockées dans la mémoire locale du périphérique (GPU), le cas échéant. Sur les backends où des tampons de transit visibles par l’hôte sont utilisés pour le chargement, ces tampons sont conservés pour ce type de données, contrairement au type « Immutable », de sorte que les chargements ultérieurs ne subissent pas de perte de performances. Les mises à jour fréquentes, en particulier celles sur des images consécutives, doivent être évitées.
QRhiBuffer::Dynamic2Indique que les données sont censées changer fréquemment. Non recommandé pour les grands tampons. Généralement adossé à la mémoire visible de l’hôte en deux copies afin de permettre les modifications sans bloquer le pipeline graphique. La gestion du double tampon s’effectue de manière transparente pour les applications et n’est en aucun cas exposée dans l’API. Il s’agit du type recommandé et, avec certains backends, du seul type possible pour les tampons destinés à une utilisation en mode « UniformBuffer ».

enum QRhiBuffer::UsageFlag
flags QRhiBuffer::UsageFlags

Valeurs des indicateurs permettant de définir l'utilisation du tampon.

ConstanteValeurDescription
QRhiBuffer::VertexBuffer1 << 0Tampon de sommets. Cela permet d’utiliser l’ QRhiBuffer dans la fonction ` setVertexInput()`.
QRhiBuffer::IndexBuffer1 << 1Tampon d'index. Cela permet d'utiliser l'QRhiBuffer dans la fonction ` setVertexInput()`.
QRhiBuffer::UniformBuffer1 << 2Tampon uniforme (également appelé tampon de constantes). Permet d’utiliser l’ QRhiBuffer en combinaison avec la fonction UniformBuffer(). Lorsque la fonction NonDynamicUniformBuffers est signalée comme non prise en charge, cette utilisation ne peut être combinée qu’avec le type Dynamic.
QRhiBuffer::StorageBuffer1 << 3Tampon de stockage. Cela permet d’utiliser l’ QRhiBuffer en combinaison avec BufferLoad, BufferStore ou BufferLoadStore. Cette utilisation ne peut être combinée qu’avec les types Immutable ou Static, et n’est disponible que lorsque l’ Compute feature est signalé comme pris en charge.
QRhiBuffer::IndirectBuffer (since Qt 6.12)1 << 4Tampon de dessin indirect. Cela permet d’utiliser l’ QRhiBuffer dans les fonctions drawIndirect() et drawIndexedIndirect(). Cette utilisation peut être combinée avec les types « Immutable » ou « Static ». La combinaison avec le type « Dynamic » n’est pas prise en charge par D3D11, où la fonction create() échouera. Cette utilisation peut également être combinée avec StorageBuffer sur les backends prenant en charge compute shaders, ce qui permet aux shaders de calcul de générer des commandes de dessin indirectes et à celles-ci d’être utilisées par des appels de dessin indirects.

Le type UsageFlags est un typedef pour QFlags<UsageFlag>. Il stocke une combinaison OR de valeurs UsageFlag.

Documentation des fonctions membres

[virtual] char *QRhiBuffer::beginFullDynamicBufferUpdateForCurrentFrame()

Renvoie un pointeur vers un bloc de mémoire contenant les données du tampon visible par l'hôte.

Il s'agit d'un raccourci destiné aux tampons uniformes dynamiques de taille moyenne à grande dont l'intégralité du contenu (ou au moins toutes les régions lues par les shaders dans l'image en cours) est modifiée à chaque image et pour lesquels le mécanisme de mise à jour basé sur ` QRhiResourceUpdateBatch` est jugé trop lourd en raison du volume de données à copier.

L'appel de cette fonction doit être suivi, au plus tard, d'un appel à endFullDynamicUniformBufferUpdateForCurrentFrame(), avant l'enregistrement de tout passage de rendu ou de calcul s'appuyant sur ce tampon.

Avertissement : la mise à jour des données via cette méthode n’est pas compatible avec les mises à jour et les relectures basées sur ` QRhiResourceUpdateBatch`. Un comportement inattendu peut se produire si l’on tente de combiner les deux modèles de mise à jour pour un même tampon. De même, les données mises à jour de cette manière directe peuvent ne pas être visibles pour ` readBackBuffer operations`, selon le backend.

Avertissement : lors de la mise à jour des données du tampon via cette méthode, la mise à jour doit être effectuée à chaque image, sinon les backends qui effectuent un double ou triple tampon des ressources peuvent présenter un comportement inattendu.

Avertissement : les mises à jourpartielles ne sont pas possibles avec cette approche, car certains backends peuvent adopter une stratégie dans laquelle le contenu précédent du tampon est perdu lors de l’appel de cette fonction. Les données doivent être écrites dans toutes les régions lues par les shaders dans l’image en cours de préparation.

Avertissement : cette fonction ne peut être appelée que lors de l’enregistrement d’une image, c’est-à-dire entre QRhi::beginFrame() et QRhi::endFrame().

Avertissement : cette fonction ne peut être appelée que sur des tampons dynamiques.

[pure virtual] bool QRhiBuffer::create()

Crée les ressources graphiques natives correspondantes. Si des ressources existent déjà en raison d’un appel antérieur à `create()` sans ` destroy()` correspondant, alors la fonction ` destroy()` est d’abord appelée implicitement.

Renvoie ` true ` en cas de réussite, et ` false ` lorsqu’une opération graphique a échoué. Quelle que soit la valeur renvoyée, l’appel à ` destroy()` est toujours sans risque.

[virtual] void QRhiBuffer::endFullDynamicBufferUpdateForCurrentFrame()

À appeler lorsque l'intégralité du contenu des données du tampon a été mise à jour dans le bloc de mémoire renvoyé par la fonction ` beginFullDynamicBufferUpdateForCurrentFrame()`.

[virtual] QRhiBuffer::NativeBuffer QRhiBuffer::nativeBuffer()

Renvoie les ressources natives sous-jacentes de ce tampon. La valeur renvoyée sera vide si l'exposition des ressources natives sous-jacentes n'est pas prise en charge par le backend.

Un objet « QRhiBuffer » peut être adossé à plusieurs objets de tampon natifs, selon les fonctions ` type()` et le backend ` QRhi ` utilisés. Dans ce cas, tous ces objets sont renvoyés dans le tableau `objects` de la structure renvoyée, `slotCount` spécifiant le nombre d’objets de tampon natifs. Bien que ` recording a frame`, ` QRhi::currentFrameSlot()` puisse être utilisé pour déterminer lequel des tampons natifs ` QRhi ` utilise pour les opérations de lecture ou d’écriture à partir de ce ` QRhiBuffer ` au sein de l’image en cours d’enregistrement.

Dans certains cas, un ` QRhiBuffer ` ne sera pas du tout associé à un objet tampon natif. Dans ce cas, `slotCount` sera défini sur 0 et aucun objet natif valide ne sera renvoyé. Il ne s’agit pas d’une erreur, et cela est tout à fait valable lorsqu’un backend donné n’utilise pas de tampons natifs pour les `QRhiBuffers` présentant certains types ou certaines utilisations.

Remarque : sachez que les backends d’ QRhi s peuvent employer diverses stratégies de mise à jour des tampons. Contrairement aux textures, où le chargement de données d’image implique toujours l’enregistrement d’une commande de copie « tampon vers image » (ou similaire) dans le tampon de commandes, les tampons, en particulier les tampons dynamiques et de type « UniformBuffer », peuvent fonctionner de nombreuses manières différentes. Par exemple, un tampon « QRhiBuffer » de type d’utilisation « UniformBuffer » peut ne pas être adossé à un objet tampon natif si les tampons uniformes ne sont pas utilisés ou pris en charge par un backend et une API graphique donnés. Il existe également des différences quant à la manière dont les données sont écrites dans le tampon et au type de mémoire de support utilisé. Pour les tampons adossés à de la mémoire visible par l’hôte, l’appel de cette fonction garantit que les écritures en attente de l’hôte sont exécutées pour tous les tampons natifs renvoyés.

Voir également QRhi::currentFrameSlot() et QRhi::FramesInFlight.

[override virtual] QRhiResource::Type QRhiBuffer::resourceType() const

Réimplémente : ` QRhiResource::resourceType()` const.

Renvoie le type de ressource.

void QRhiBuffer::setSize(quint32 sz)

Définit la taille du tampon en octets. La taille est normalement spécifiée dans ` QRhi::newBuffer()`, cette fonction n’est donc utilisée que lorsque la taille doit être modifiée. Comme pour les autres méthodes de configuration, la taille ne prend effet qu’au moment de l’appel à ` create()`, et pour les tampons déjà créés, cela implique de libérer la ressource native précédente et d’en créer de nouvelles en arrière-plan.

Les backends peuvent choisir d’allouer des tampons plus grands que sz afin de respecter les exigences d’alignement. Ce comportement est masqué aux applications et size() renverra toujours la taille demandée dans sz.

Voir également size().

void QRhiBuffer::setType(QRhiBuffer::Type t)

Définit le type du tampon sur « t ».

Voir aussi type().

void QRhiBuffer::setUsage(QRhiBuffer::UsageFlags u)

Définit les indicateurs d'utilisation du tampon sur « u ».

Voir aussi usage().

quint32 QRhiBuffer::size() const

Renvoie la taille du tampon en octets.

Il s'agit toujours de la valeur qui a été transmise à setSize() ou QRhi::newBuffer(). En interne, les tampons natifs peuvent être plus grands si l'API graphique sous-jacente l'exige.

Voir également setSize().

QRhiBuffer::Type QRhiBuffer::type() const

Renvoie le type du tampon.

Voir aussi setType().

QRhiBuffer::UsageFlags QRhiBuffer::usage() const

Renvoie les indicateurs d'utilisation du tampon.

Voir aussi setUsage().

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.