QRhiBuffer Class
頂点、インデックス、またはユニフォーム(定数)バッファリソース。詳細...
| ヘッダー: | #include <rhi/qrhi.h> |
| CMake: | find_package(Qt6 REQUIRED COMPONENTS GuiPrivate) target_link_libraries(mytarget PRIVATE Qt6::GuiPrivate) |
| qmake: | QT += gui-private |
| 以下のように: | Qt 6.6 |
| 継承元: | QRhiResource |
パブリック型
| struct | NativeBuffer |
| enum | Type { Immutable, Static, Dynamic } |
| enum | UsageFlag { VertexBuffer, IndexBuffer, UniformBuffer, StorageBuffer, IndirectBuffer } |
| flags | UsageFlags |
パブリック関数
| 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 |
再実装されたパブリック関数
| virtual QRhiResource::Type | resourceType() const override |
詳細な説明
注:これは 互換性の保証が限定的な RHI API です。詳細については、QRhi を参照してください。
QRhiBuffer は、0 個、1 個、またはそれ以上のネイティブバッファオブジェクト(VkBuffer やMTLBuffer など)をカプセル化します。 一部のグラフィックス API やバックエンドでは、特定のタイプのバッファがネイティブバッファオブジェクトをまったく使用しない場合がありますが(たとえば、ユニフォームバッファオブジェクトが使用されていない OpenGL など)、これは QRhiBuffer API のユーザーには透過的です。 同様に、GPU パイプラインを停止させることなくフレームごとのコンテンツ更新を効率的に行うために、一部のタイプのバッファが内部で 2 つまたは 3 つのネイティブバッファを使用しているという事実も、アプリケーションやライブラリからはほとんど認識されません。
QRhiBuffer インスタンスは、常にthe QRhi's newBuffer() function を呼び出すことで作成されます。これにより、ネイティブのグラフィックスリソースは作成されません。ネイティブのグラフィックスリソースを作成するには、タイプ、使用フラグ、サイズなどの適切なオプションを設定した後、create()を呼び出します。ただし、ほとんどの場合、これらのオプションはnewBuffer()に渡された引数に基づいてすでに設定されています。
使用例
GLSLのuniformブロックに単一のmat4 メンバーが含まれるシェーダー用のユニフォームバッファを作成し、その内容を更新するには:
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頂点データを含むバッファを作成する例:
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インデックス・バッファ:
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一般的なパターン
create() の呼び出しは、create() が以前に正常に呼び出されていた場合、既存のネイティブリソースをすべて破棄します。 それらのネイティブリソースが、処理中のフレームによってまだ使用されている場合(つまり、GPUによってまだ読み込まれている可能性がある場合)、それらのリソースの破棄は自動的に延期されます。したがって、すでに初期化済みのバッファのサイズを安全に拡大するための、非常に一般的で便利なパターンは以下の通りです。 実際には、これにより内部でネイティブリソースのセット全体が破棄され、新しいセットが作成されるため、必ずしも低コストな操作とは言えませんが、buf オブジェクト自体を破棄しないことで、他のデータ構造(例えば、QRhiBufferが参照されている任意のQRhiShaderResourceBinding など)におけるそのオブジェクトへのすべての参照が有効なままであるため、他の方法よりも便利で高速です。
if (buf->size() < newSize) {
buf->setSize(newSize);
if (!buf->create()) { error(); }
}
// continue using buf, fill it with new dataユニフォームバッファを扱う際、効率上の理由から、複数のドローコールのデータを単一のバッファに結合する必要がある場合があります。アラインメント要件に注意してください。一部のグラフィックスAPIでは、ユニフォームバッファのオフセットを256バイト単位にアラインする必要があります。これは、QRhiShaderResourceBinding およびsetShaderResources()に渡される動的オフセットの両方に適用されます。 移植性の高いコードを作成するには、ubufAlignment() およびubufAligned() 関数を使用してください。例として、以下は、同じパイプラインとジオメトリを使用しつつ、バインディングポイント 0 で公開されるユニフォームバッファ内のデータのみが異なる、複数の (N) ドローコールを発行するための概要です。これは、バッファがuniformBufferWithDynamicOffset() を通じて公開されていることを前提としており、これにより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);
}QRhiResourceUpdateBatch 、QRhi 、およびQRhiCommandBufferも参照してください 。
メンバ型のドキュメント
enum QRhiBuffer::Type
バッファリソースのストレージタイプを指定します。
| 定数 | 値 | 説明 |
|---|---|---|
QRhiBuffer::Immutable | 0 | 初期アップロード後、データが一切変更されることがないことを示します。内部的には、このようなバッファリソースは通常、デバイスローカル(GPU)メモリに配置されます(該当するシステムの場合)。 新しいデータのアップロードは可能ですが、コストがかかる場合があります。アップロードは通常、ホストから可視な別のステージングバッファにコピーを行い、そこから GPU バッファ間コピーが実行されて、実際の GPU 専用のバッファにデータが転送されるという方式で行われます。 |
QRhiBuffer::Static | 1 | データがめったに変更されないことが予想されることを示します。通常、適用可能なシステムでは、デバイスローカル(GPU)メモリに配置されます。 アップロードにホスト可視のステージングバッファが使用されるバックエンドでは、Immutableとは異なり、このタイプの場合、ステージングバッファが保持されるため、その後のアップロードでパフォーマンスが低下することはありません。頻繁な更新、特に連続するフレームでの更新は避けるべきです。 |
QRhiBuffer::Dynamic | 2 | データが頻繁に変更されると予想されることを示します。大きなバッファには推奨されません。通常、グラフィックスパイプラインを停止させることなく変更を可能にするため、ホスト可視メモリに 2 つのコピーが保持されます。 ダブルバッファリングはアプリケーションに対して透過的に管理され、このAPIではいかなる形でも公開されません。これは、「UniformBuffer 」用途のバッファに対して推奨されるタイプであり、一部のバックエンドでは唯一利用可能なタイプです。 |
enum QRhiBuffer::UsageFlag
flags QRhiBuffer::UsageFlags
バッファの使用方法を指定するためのフラグ値。
| 定数 | 値 | 説明 |
|---|---|---|
QRhiBuffer::VertexBuffer | 1 << 0 | 頂点バッファ。これにより、QRhiBuffer をsetVertexInput()で使用できるようになります。 |
QRhiBuffer::IndexBuffer | 1 << 1 | インデックスバッファ。これにより、QRhiBuffer をsetVertexInput()で使用できるようになります。 |
QRhiBuffer::UniformBuffer | 1 << 2 | ユニフォームバッファ(定数バッファとも呼ばれる)。これにより、QRhiBuffer をUniformBuffer()と組み合わせて使用できるようになります。NonDynamicUniformBuffers がサポートされていないと報告された場合、この使用法はDynamic型とのみ組み合わせることができます。 |
QRhiBuffer::StorageBuffer | 1 << 3 | ストレージバッファ。これにより、QRhiBuffer をBufferLoad 、BufferStore 、またはBufferLoadStore と組み合わせて使用できます。この使用法は、ImmutableまたはStatic型とのみ組み合わせることができ、Compute feature がサポートされていると報告された場合にのみ利用可能です。 |
QRhiBuffer::IndirectBuffer (since Qt 6.12) | 1 << 4 | 間接描画バッファ。これにより、QRhiBuffer をdrawIndirect()およびdrawIndexedIndirect()で使用できるようになります。この使用法は、ImmutableまたはStatic型と組み合わせることができます。D3D11ではDynamic型との組み合わせはサポートされておらず、その場合create()は失敗します。 また、compute shaders をサポートするバックエンドでは、この使用法をStorageBufferと組み合わせることができ、これによりコンピュートシェーダーによって間接描画コマンドが生成され、間接描画コールによって消費されるようになります。 |
UsageFlags 型はQFlags<UsageFlag> の typedef です。これは、UsageFlag 値の論理和(OR)の組み合わせを格納します。
メンバ関数のドキュメント
[virtual] char *QRhiBuffer::beginFullDynamicBufferUpdateForCurrentFrame()
ホストから可視なバッファデータが格納されたメモリブロックへのポインタを返します。
これは、フレームごとに内容全体(あるいは少なくとも現在のフレームでシェーダーによって読み込まれるすべての領域)が変更され、QRhiResourceUpdateBatch に基づく更新メカニズムではデータコピーの量が多すぎて負荷が高すぎると判断される、中規模から大規模の動的ユニフォームバッファに対するショートカットです。
この関数を呼び出した後は、このバッファに依存するレンダリングパスやコンピュートパスを記録する前に、必ず endFullDynamicUniformBufferUpdateForCurrentFrame() を呼び出す必要があります。
警告: この方法によるデータの更新は 、QRhiResourceUpdateBatch ベースの更新およびリードバックとは互換性がありません。同じバッファに対してこれら 2 つの更新モデルを組み合わせて使用しようとすると、予期しない動作が発生する可能性があります。同様に、この直接的な方法で更新されたデータは、バックエンドによってはreadBackBuffer operations から参照できない場合があります。
警告: この方法でバッファデータを更新する場合 、更新はすべてのフレームで行う必要があります。そうしないと、リソースのダブルバッファリングやトリプルバッファリングを行うバックエンドで予期しない動作が発生する可能性があります。
警告: 一部のバックエンドでは、この関数の呼び出し時にバッファの以前の内容が失われるような処理を採用している場合があるため、この手法では部分的な 更新はできません。データは、現在準備中のフレームでシェーダーによって読み込まれるすべての領域に書き込まなければなりません。
警告:この関数は 、フレームの記録中、つまりQRhi::beginFrame()とQRhi::endFrame()の間にのみ呼び出すことができます。
警告:この関数は 、ダイナミックバッファに対してのみ呼び出すことができます。
[pure virtual] bool QRhiBuffer::create()
対応するネイティブグラフィックスリソースを作成します。以前にdestroy() を伴わない create() が実行された結果、すでにリソースが存在する場合、まず暗黙的にdestroy() が呼び出されます。
成功した場合はtrue を返し、グラフィックス操作が失敗した場合はfalse を返します。戻り値にかかわらず、destroy()を呼び出すことは常に安全です。
[virtual] void QRhiBuffer::endFullDynamicBufferUpdateForCurrentFrame()
beginFullDynamicBufferUpdateForCurrentFrame() から返されたメモリブロック内のバッファデータの全内容が更新されたときに呼び出されます。
[virtual] QRhiBuffer::NativeBuffer QRhiBuffer::nativeBuffer()
このバッファの基盤となるネイティブリソースを返します。バックエンドが基盤となるネイティブリソースの公開をサポートしていない場合、返される値は空になります。
QRhiBuffer は、使用されているtype()およびQRhi バックエンドによっては、複数のネイティブバッファオブジェクトによって裏付けられている場合があります。 その場合は、それらがすべて、返される構造体の objects 配列に返され、slotCount にはネイティブバッファオブジェクトの数が指定されます。recording a frame である間、QRhi::currentFrameSlot() を使用すると、記録中のフレーム内で、このQRhiBuffer からの読み取りまたは書き込み操作に対して、QRhi がどのネイティブバッファを使用しているかを確認できます。
場合によっては、QRhiBuffer がネイティブバッファオブジェクトによってまったく裏付けられていないこともあります。この場合、slotCountは0に設定され、有効なネイティブオブジェクトは返されません。これはエラーではなく、特定のタイプや使用方法のQRhiBufferに対して、そのバックエンドがネイティブバッファを使用しない場合には、完全に有効な動作です。
注: QRhi のバックエンドは、さまざまなバッファ更新戦略を採用している可能性があることに注意してください 。テクスチャの場合、画像データのアップロードは常にコマンドバッファへの「バッファから画像へのコピー」(または類似の)コマンドの記録を意味しますが、バッファ、特にDynamicおよびUniformBuffer のものは、さまざまな方法で動作する可能性があります。 たとえば、使用タイプがUniformBuffer であるQRhiBuffer は、特定のバックエンドやグラフィックスAPIでユニフォームバッファが使用されていない、あるいはサポートされていない場合、ネイティブのバッファオブジェクトをバックエンドとして持たないことさえあります。 また、バッファへのデータの書き込み方法や、使用されるバッキングメモリのタイプにも違いがあります。ホスト可視メモリをバッキングとするバッファの場合、この関数を呼び出すことで、返されたすべてのネイティブバッファに対して、保留中のホスト書き込みが確実に実行されることが保証されます。
QRhi::currentFrameSlot() およびQRhi::FramesInFlightも参照してください 。
[override virtual] QRhiResource::Type QRhiBuffer::resourceType() const
QRhiResource::resourceType() const を再実装します。
リソースの型を返します。
void QRhiBuffer::setSize(quint32 sz)
バッファのサイズをバイト単位で設定します。通常、サイズは `QRhi::newBuffer()` で指定されるため、この関数はサイズを変更する必要がある場合にのみ使用されます。他のセッターと同様、このサイズ設定は `create()` を呼び出したときにのみ有効になります。また、すでに作成済みのバッファの場合、内部的には以前のネイティブリソースを解放し、新しいリソースを作成する処理が行われます。
バックエンドは、アライメント要件を満たすために、sz で指定されたサイズよりも大きなバッファを割り当てる場合があります。これはアプリケーションからは隠蔽されており、size() は常にsz で要求されたサイズを報告します。
size()も参照してください 。
void QRhiBuffer::setType(QRhiBuffer::Type t)
バッファのタイプを「t 」に設定します。
type()も参照してください 。
void QRhiBuffer::setUsage(QRhiBuffer::UsageFlags u)
バッファの使用フラグを `u` に設定します。
usage()も参照してください 。
quint32 QRhiBuffer::size() const
バッファのサイズをバイト単位で返します。
これは常に、setSize() またはQRhi::newBuffer() に渡された値となります。内部的には、基盤となるグラフィックス API によって必要とされる場合、ネイティブバッファのサイズがこれより大きくなる可能性があります。
setSize()も参照してください 。
QRhiBuffer::Type QRhiBuffer::type() const
バッファの型を返します。
setType()も参照してください 。
QRhiBuffer::UsageFlags QRhiBuffer::usage() const
バッファの使用フラグを返します。
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.