このページでは

QRhi Class

2D/3DグラフィックスAPIの抽象化を加速。詳細...

ヘッダー: #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 以降

パブリック型

(since 6.10) AdapterList
enum BeginFrameFlag { }
flags BeginFrameFlags
enum EndFrameFlag { SkipPresent }
flags EndFrameFlags
enum Feature { MultisampleTexture, MultisampleRenderBuffer, DebugMarkers, Timestamps, Instancing, …, ShaderDrawParameters }
enum Flag { EnableDebugMarkers, EnableTimestamps, PreferSoftwareRenderer, EnablePipelineCacheDataSave, SuppressSmokeTestWarnings }
flags Flags
enum FrameOpResult { FrameOpSuccess, FrameOpError, FrameOpSwapChainOutOfDate, FrameOpDeviceLost }
enum Implementation { Null, Vulkan, OpenGLES2, D3D11, D3D12, Metal }
enum ResourceLimit { TextureSizeMin, TextureSizeMax, MaxColorAttachments, FramesInFlight, MaxAsyncReadbackFrames, …, ShadingRateImageTileSize }

パブリック関数

~QRhi()
void addCleanupCallback(const QRhi::CleanupCallback &callback)
void addCleanupCallback(const void *key, const QRhi::CleanupCallback &callback)
QRhi::Implementation backend() const
const char *backendName() const
QRhi::FrameOpResult beginFrame(QRhiSwapChain *swapChain, QRhi::BeginFrameFlags flags = {})
QRhi::FrameOpResult beginOffscreenFrame(QRhiCommandBuffer **cb, QRhi::BeginFrameFlags flags = {})
QMatrix4x4 clipSpaceCorrMatrix() const
int currentFrameSlot() const
QRhiDriverInfo driverInfo() const
QRhi::FrameOpResult endFrame(QRhiSwapChain *swapChain, QRhi::EndFrameFlags flags = {})
QRhi::FrameOpResult endOffscreenFrame(QRhi::EndFrameFlags flags = {})
QRhi::FrameOpResult finish()
bool isClipDepthZeroToOne() const
bool isDeviceLost() const
bool isFeatureSupported(QRhi::Feature feature) const
bool isRecordingFrame() const
bool isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags = {}) const
bool isYUpInFramebuffer() const
bool isYUpInNDC() const
bool makeThreadLocalNativeContextCurrent()
const QRhiNativeHandles *nativeHandles()
QRhiBuffer *newBuffer(QRhiBuffer::Type type, QRhiBuffer::UsageFlags usage, quint32 size)
QRhiComputePipeline *newComputePipeline()
QRhiGraphicsPipeline *newGraphicsPipeline()
QRhiRenderBuffer *newRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize, int sampleCount = 1, QRhiRenderBuffer::Flags flags = {}, QRhiTexture::Format backingFormatHint = QRhiTexture::UnknownFormat)
QRhiSampler *newSampler(QRhiSampler::Filter magFilter, QRhiSampler::Filter minFilter, QRhiSampler::Filter mipmapMode, QRhiSampler::AddressMode addressU, QRhiSampler::AddressMode addressV, QRhiSampler::AddressMode addressW = QRhiSampler::Repeat)
QRhiShaderResourceBindings *newShaderResourceBindings()
(since 6.9) QRhiShadingRateMap *newShadingRateMap()
QRhiSwapChain *newSwapChain()
QRhiTexture *newTexture(QRhiTexture::Format format, const QSize &pixelSize, int sampleCount = 1, QRhiTexture::Flags flags = {})
QRhiTexture *newTexture(QRhiTexture::Format format, int width, int height, int depth, int sampleCount = 1, QRhiTexture::Flags flags = {})
QRhiTexture *newTextureArray(QRhiTexture::Format format, int arraySize, const QSize &pixelSize, int sampleCount = 1, QRhiTexture::Flags flags = {})
QRhiTextureRenderTarget *newTextureRenderTarget(const QRhiTextureRenderTargetDescription &desc, QRhiTextureRenderTarget::Flags flags = {})
QRhiResourceUpdateBatch *nextResourceUpdateBatch()
QByteArray pipelineCacheData()
void releaseCachedResources()
void removeCleanupCallback(const void *key)
int resourceLimit(QRhi::ResourceLimit limit) const
void setPipelineCacheData(const QByteArray &data)
(since 6.9) void setQueueSubmitParams(QRhiNativeHandles *params)
QRhiStats statistics() const
QList<int> supportedSampleCounts() const
(since 6.9) QList<QSize> supportedShadingRates(int sampleCount) const
QThread *thread() const
int ubufAligned(int v) const
int ubufAlignment() const

静的パブリックメンバー

const char *backendName(QRhi::Implementation impl)
QRhi *create(QRhi::Implementation impl, QRhiInitParams *params, QRhi::Flags flags, QRhiNativeHandles *importDevice, QRhiAdapter *adapter)
QRhi *create(QRhi::Implementation impl, QRhiInitParams *params, QRhi::Flags flags = {}, QRhiNativeHandles *importDevice = nullptr)
(since 6.10) QRhi::AdapterList enumerateAdapters(QRhi::Implementation impl, QRhiInitParams *params, QRhiNativeHandles *nativeHandles = nullptr)
int mipLevelsForSize(const QSize &size)
bool probe(QRhi::Implementation impl, QRhiInitParams *params)
QSize sizeForMipLevel(int mipLevel, const QSize &baseLevelSize)
QRhiSwapChainProxyData updateSwapChainProxyData(QRhi::Implementation impl, QWindow *window)

詳細説明

Qt レンダリング・ハードウェア・インターフェースは、OpenGL、OpenGL ES、Direct3D、Metal、Vulkan などのハードウェアアクセラレーション対応グラフィックス API を抽象化したものです。

警告: Qt GUI モジュールに含まれる QRhi クラスのファミリー (QShader およびQShaderDescription を含む)は 、互換性の保証が限定的です。これらのクラスについては、ソースおよびバイナリの互換性が保証されていません。つまり、API が動作することが保証されるのは、アプリケーションの開発元となった Qt バージョンでのみです。 ただし、ソース互換性を損なう変更は最小限に抑えるよう努めており、マイナーリリース(6.7、6.8など)でのみ行われます。アプリケーションでこれらのクラスを使用するには、(CMakeを使用している場合は)Qt::GuiPrivate にリンクし、rhi というプレフィックスが付いたヘッダー(例:#include <rhi/qrhi.h> )をインクルードしてください。

各 QRhi インスタンスは、特定のグラフィックス API 用のバックエンドによって支えられています。バックエンドの選択は実行時に行われ、QRhi インスタンスを作成するアプリケーションまたはライブラリに委ねられます。 一部のバックエンド(OpenGL、Vulkan、Null)は複数のプラットフォームで利用可能ですが、特定のプラットフォーム固有のAPIは、そのプラットフォーム上で実行している場合にのみ利用可能です(macOS/iOS上のMetal、Windows上のDirect3Dなど)。

現在利用可能なバックエンドは以下の通りです:

  • OpenGL 2.1 / OpenGL ES 2.0 以降。マルチサンプル・フレームバッファやコンピュート・シェーダーを有効にするなど、一部の拡張機能や新しいコア仕様の機能が利用可能です(存在する場合)。コアプロファイル・コンテキストでの動作もサポートされています。 必要に応じて、アプリケーションは実行時にfeature flags を照会し、QRhiを裏付けするOpenGLコンテキストでサポートされていない機能の有無を確認できます。OpenGLバックエンドは、QOpenGLContext 、QOpenGLFunctions 、およびQt GUI モジュールの関連するクロスプラットフォームインフラストラクチャに基づいて構築されています。
  • Direct3D 11.2 以降(DXGI 1.3 以降を含む)、Shader Model 5.0 以降を使用。 D3D ランタイムが 11.2 の機能または Shader Model 5.0 をサポートしていない場合、アクセラレーション対応のグラフィックスデバイスを使用した初期化は失敗しますが、ソフトウェアアダプタを使用することは依然として可能です。
  • Windows 10 バージョン 1703 以降での Direct3D 12、Shader Model 5.0 以降。 Qt では ID3D12Device2 が必要であるため、Windows 10 バージョン 1703 以上が必須となります。D3D12 デバイスは、デフォルトで最小機能レベルをD3D_FEATURE_LEVEL_11_0 として指定して作成されます。
  • Metal 1.2 以降。
  • Vulkan 1.0 以降。オプションで、Vulkan 1.1 レベルの機能の一部を利用することも可能です。
  • Null:グラフィックス呼び出しを一切行わない「ダミー」バックエンド。

Qtアプリケーションやライブラリにおいてシェーダーコードを一度記述するだけで済むようにするため、すべてのシェーダーは単一の言語で記述され、その後SPIR-Vにコンパイルされることが想定されています。そこから、リフレクション情報(入力、出力、シェーダーリソース)とともに、さまざまなシェーディング言語用のバージョンが生成されます。 これらは、簡単かつ効率的にシリアライズ可能なQShader インスタンスにパックされます。このようなシェーダーを生成するためのコンパイラやツールは、QRhiおよびQt GUI モジュールには含まれていませんが、これらのシェーダーを使用するためのコアクラスであるQShader およびQShaderDescription は含まれています。コンパイルおよび変換を行うためのAPIやツールは、QtのShader Tools モジュールの一部です。

QRhi を使用して、QWindow 上で高速化された 3D レンダリングを行う、移植性のあるクロスプラットフォームアプリケーションを作成する入門例については、「RHI Window Example」を参照してください。

APIの概要

ウィンドウ関連の設定を必要としない、簡潔かつ完全なサンプルを通じてAPIの概要を素早く把握していただくために、以下に、オフスクリーンで20フレームをレンダリングし、GPUからテクスチャの内容を読み戻した後、生成された画像をファイルに保存する、完全かつ実行可能なクロスプラットフォームアプリケーションを示します。 画面上にレンダリングする例(QWindow およびスワップチェーンの設定が必要)については、「RHI Window Example」を参照してください。

簡潔にするため、QRhiの初期化はプラットフォームに基づいて行われます。このサンプルコードでは、WindowsではDirect 3D 12、macOSおよびiOSではMetal、それ以外の場合はVulkanが選択されます。このアプリケーションではOpenGLやDirect 3D 11は一切使用されませんが、数行のコードを追加するだけでそれらのサポートを導入することも可能です。

#include <QGuiApplication>
#include <QImage>
#include <QFile>
#include <rhi/qrhi.h>

intmain(intargc, char**argv)
{
    QGuiApplication app(argc,argv);

#if QT_CONFIG(vulkan)
    QVulkanInstance inst;
#endif
    std::unique_ptr<QRhi>rhi;
#if defined(Q_OS_WIN)
    QRhiD3D12InitParams params;
    rhi.reset(QRhi::create(QRhi::D3D12, &params));
#elif QT_CONFIG(metal)
    QRhiMetalInitParams params;
    rhi.reset(QRhi::create(QRhi::Metal, &params));
#elif QT_CONFIG(vulkan)
    inst.setExtensions(QRhiVulkanInitParams::preferredInstanceExtensions());
    if(inst.create()) {
        QRhiVulkanInitParams params;
        params.inst= &inst;
        rhi.reset(QRhi::create(QRhi::Vulkan, &params));
    }else{
        qFatal("Failed to create Vulkan instance");
    }
#endif
    if(rhi)
        qDebug() << rhi->backendName() << rhi->driverInfo();
   else
        qFatal("Failed to initialize RHI");

   floatrotation= 0.0f;
    floatopacity= 1.0f;
    intopacityDir= 1;

    std::unique_ptr<QRhiTexture>tex(rhi->newTexture(QRhiTexture::RGBA8,
                                                     QSize(1280, 720),
                                                     1,
                                                     QRhiTexture::RenderTarget|QRhiTexture::UsedAsTransferSource));
    tex->create();
    std::unique_ptr<QRhiTextureRenderTarget>rt(rhi->newTextureRenderTarget({ tex.get() }));
    std::unique_ptr<QRhiRenderPassDescriptor>rp(rt->newCompatibleRenderPassDescriptor());
    rt->setRenderPassDescriptor(rp.get());
    rt->create();

    QMatrix4x4 viewProjection= rhi->clipSpaceCorrMatrix();
    viewProjection.perspective(45.0f, 1280 / 720.f, 0.01f, 1000.0f);
    viewProjection.translate(0, 0,-4);

    static floatvertexData[] ={// Y軸上向き、反時計回り
        0.0f,   0.5f,     1.0f, 0.0f, 0.0f,
       -0.5f,-0.5f,     0.0f, 1.0f, 0.0f,
        0.5f, -0.5f,     0.0f, 0.0f, 1.0f,
    };

    std::unique_ptr<QRhiBuffer>vbuf(rhi->newBuffer(QRhiBuffer::Immutable,
                                                    QRhiBuffer::VertexBuffer,
                                                    sizeof(vertexData)));
    vbuf->create();

    std::unique_ptr<QRhiBuffer>ubuf(rhi->newBuffer(QRhiBuffer::Dynamic,
                                                    QRhiBuffer::UniformBuffer,
                                                    64 + 4));
    ubuf->create();

    std::unique_ptr<QRhiShaderResourceBindings>srb(rhi->newShaderResourceBindings());
    srb->setBindings({
        QRhiShaderResourceBinding::uniformBuffer(0,
                                                 QRhiShaderResourceBinding::VertexStage|QRhiShaderResourceBinding::FragmentStage,
                                                 ubuf.get())
    });
    srb->create();

    std::unique_ptr<QRhiGraphicsPipeline>ps(rhi->newGraphicsPipeline());
    QRhiGraphicsPipeline::TargetBlendpremulAlphaBlend;
    premulAlphaBlend.enable= true;
    ps->setTargetBlends({ premulAlphaBlend });
    static autogetShader= [](constQString&name) {
        QFile f(name);
        returnf.open(QIODevice::ReadOnly)?QShader::fromSerialized(f.readAll()) : QShader();
    };
    ps->setShaderStages({
        { QRhiShaderStage::Vertex,getShader(QLatin1String("color.vert.qsb")) },
        { QRhiShaderStage::Fragment,getShader(QLatin1String("color.frag.qsb")) }
    });
    QRhiVertexInputLayout inputLayout;
    inputLayout.setBindings({
        {5 * sizeof(float) }
    });
    inputLayout.setAttributes({
        {0, 0,QRhiVertexInputAttribute::Float2, 0},
        {0, 1,QRhiVertexInputAttribute::Float3, 2 * sizeof(float) }
    });
    ps->setVertexInputLayout(inputLayout);
    ps->setShaderResourceBindings(srb.get());
    ps->setRenderPassDescriptor(rp.get());
    ps->create();

    QRhiCommandBuffer*cb;
    for(intframe= 0; frame< 20;++frame) {
        rhi->beginOffscreenFrame(&cb);

        QRhiResourceUpdateBatch*u = rhi->nextResourceUpdateBatch();
        if(frame== 0)
            u->uploadStaticBuffer(vbuf.get(),vertexData);

        QMatrix4x4 mvp=viewProjection;
        mvp.rotate(rotation, 0, 1, 0);
        u->updateDynamicBuffer(ubuf.get(), 0, 64,mvp.constData());
        rotation+= 5.0f;

        u->updateDynamicBuffer(ubuf.get(), 64, 4, &opacity);
        opacity+=opacityDir* 0.2f;
        if(opacity< 0.0f||opacity> 1.0f) {
            opacityDir*=-1;
            opacity= qBound(0.0f,opacity, 1.0f);
        }

        cb->beginPass(rt.get(), Qt::green,{1.0f, 0},u);
        cb->setGraphicsPipeline(ps.get());
        cb->setViewport({0, 0, 1280, 720});
        cb->setShaderResources();
        constQRhiCommandBuffer::VertexInput vbufBinding(vbuf.get(), 0);
        cb->setVertexInput(0, 1, &vbufBinding);
        cb->draw(3);
        QRhiReadbackResult readbackResult;
        u= rhi->nextResourceUpdateBatch();
        u->readBackTexture({ tex.get() }, &readbackResult);
        cb->endPass(u);

        rhi->endOffscreenFrame();

        QImage image(reinterpret_cast<constuchar*>(readbackResult.data.constData()),
                     readbackResult.pixelSize.width(),
                     readbackResult.pixelSize.height(),
                     QImage::Format_RGBA8888_Premultiplied);
        if(rhi->isYUpInFramebuffer())
            image.flip();
        image.save(QString::asprintf("frame%d.png",frame));
    }

    return 0;
}

このアプリケーションの実行結果は、20枚のPNG 画像(frame0.png~frame19.png)です。これらには、緑色の背景の上に不透明度が変化する回転する三角形が含まれています。

頂点シェーダーとフラグメントシェーダーは処理され、.qsb ファイルにパッケージ化されることが想定されています。Vulkan互換のGLSLソースコードは以下の通りです:

color.vert

#version 440

layout(location = 0) in vec4 position;
layout(location = 1) in vec3 color;
layout(location = 0) out vec3 v_color;

layout(std140, binding = 0) uniform buf {
    mat4 mvp;
    float opacity;
};

void main()
{
    v_color = color;
    gl_Position = mvp * position;
}

color.frag

#version 440

layout(location = 0) in vec3 v_color;
layout(location = 0) out vec4 fragColor;

layout(std140, binding = 0) uniform buf {
    mat4 mvp;
    float opacity;
};

void main()
{
    fragColor = vec4(v_color * opacity, opacity);
}

これらのシェーダーを手動でコンパイルおよびトランスパイルして、複数のターゲット(SPIR-V、HLSL、MSL、GLSL)に変換し、アプリケーションが実行時に読み込む.qsb ファイルを生成するには、qsb --qt6 color.vert -o color.vert.qsb およびqsb --qt6 color.frag -o color.frag.qsb を実行してください。あるいは、QtのShader Tools モジュールが提供するCMake用ビルドシステム統合機能であるqt_add_shaders() というCMake関数を使用すれば、ビルド時に同様の処理を行うことができます。

セキュリティに関する考慮事項

QRhi およびQShader などの関連クラスが扱うすべてのデータは、信頼できるコンテンツとみなされます。

警告:アプリケーション開発者は 、アプリケーションの一部ではなく、かつ開発者の管理下にないユーザー提供のコンテンツの取り込みを許可する前に、その潜在的な影響を慎重に検討することを推奨します。(これには、すべての頂点/インデックスデータ、シェーダー、パイプラインおよびドローコールのパラメータなどが含まれます。)

設計の基礎

QRhiは直接インスタンス化することはできません。代わりに、create()関数を使用してください。グラフィックスデバイスを解放するには、QRhiインスタンスを通常通り削除してください。

リソース

QRhiResource を継承するクラスのインスタンス(例:QRhiBuffer 、QRhiTexture など)は、0個、1個、またはそれ以上のネイティブグラフィックスリソースをカプセル化しています。これらのクラスのインスタンスは、常にQRhiのnew 関数(例:newBuffer()、newTexture()、newTextureRenderTarget()、newSwapChain()など)を介して作成されます。

QRhiBuffer *vbuf = rhi->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, sizeof(vertexData));
if (!vbuf->create()) { error(); }
// ...
delete vbuf;
  • newBuffer() などの関数から返される値は、常に呼び出し元が所有します。
  • QRhiResource のサブクラスのインスタンスを作成するだけでは、ネイティブリソースは一切割り当てられず、初期化もされません。これは、サブクラスのcreate() 関数(例:QRhiBuffer::create() やQRhiTexture::create())が呼び出された場合にのみ行われます。
  • 例外となるのは、QRhiTextureRenderTarget::newCompatibleRenderPassDescriptor()、QRhiSwapChain::newCompatibleRenderPassDescriptor()、およびQRhiRenderPassDescriptor::newCompatibleRenderPassDescriptor() です。これらにはcreate() 操作がなく、返されたオブジェクトは即座に有効になります。
  • リソースオブジェクト自体は不変として扱われます。リソースに対して一度create() が呼び出されると、QRhiTexture::setPixelSize() などのセッターを介してパラメータを変更しても、基盤となるネイティブリソースが解放され、create() が再度呼び出されない限り、何の効果もありません。リソースの再利用については、以下のセクションで詳しく説明します。
  • 基盤となるネイティブリソースの解放は、QRhiResource のデストラクタ、またはQRhiResource::destroy()の呼び出しによってスケジュールされます。バックエンドはしばしば解放要求をキューに入れ、その実行を未指定の時点に延期しますが、これはアプリケーションからは隠蔽されています。これにより、アプリケーションは、処理中のフレームによってまだ使用されている可能性のあるネイティブリソースの解放について心配する必要がなくなります。
  • ただし、これはQRhiResource がフレーム内(つまり、beginFrame() -endFrame()のセクション内)で自由にdestroy()されたり削除されたりできることを意味するわけではないことに注意してください。原則として、参照されているすべてのQRhiResource オブジェクトは、endFrame()の呼び出しによってフレームがサブミットされるまで変更されてはなりません。これを容易にするために、QRhiResource::deleteLater()が便宜上提供されています。

コマンドバッファとコマンドの実行の延期

基盤となるグラフィックス API の設計や機能にかかわらず、すべての QRhi バックエンドは、ある程度のコマンドバッファを実装しています。QRhiCommandBuffer の関数では、ネイティブのバインドや描画コマンド(glDrawElements など)を直接発行することはありません。コマンドは常に、ネイティブのキュー、またはQRhiバックエンドが提供するキューのいずれかに記録されます。コマンドバッファはサブミットされるため、QRhi::endFrame()またはQRhi::finish()が呼び出されて初めて実行が開始されます。

この遅延実行の性質は、一部の種類のオブジェクトに影響を及ぼします。 たとえば、フレーム内で動的バッファに複数回書き込みを行う場合、そのバッファがホストから可視なメモリをバックエンドとしていると、動的バッファの更新がドローコールに対していつ記録されたかに関係なく、そのフレームのコマンドバッファ内のすべてのドローコールから、すべての書き込みの結果が可視になってしまうことになります。

さらに、QRhiResource のサブクラスのインスタンスは、何らかの形で参照されるフレーム内では不変として扱わなければなりません。 次のフレームのコマンドの記録を開始する前に、すべてのリソースを事前に作成してください。フレーム内でQRhiResource インスタンスを再利用すること(create() を呼び出した後、同じbeginFrame - endFrame セクション内で再度参照すること)は、バックエンドによっては予期しない結果につながる可能性があるため、避けるべきです。

一般的なルールとして、参照されているすべてのQRhiResource オブジェクトは、endFrame()を呼び出してフレームを送信するまで、有効な状態を維持し、変更されないようにする必要があります。 一方、destroy() を呼び出したり、QRhiResource を削除したりすることは、フレームが送信されれば、基盤となるネイティブリソースの状態(GPU によってまだ使用されている可能性がありますが、これは内部で処理されます)にかかわらず、常に安全です。

OpenGL のような API とは異なり、アップロードやコピーといった種類のコマンドを、描画コマンドと混在させることはできません。一般的なレンダラーでは、次のようなシーケンスが使用されます:

  • リソースの(再)作成
  • フレームの開始
  • アップロードおよびコピーの記録/発行
  • レンダリングパスの記録を開始
  • ドローコールの記録
  • レンダリングパスの終了
  • フレーム終了

操作のコピータイプの記録は、QRhiResourceUpdateBatch を通じて行われます。このような操作は通常、beginPass() でコミットされます。

OpenGL向けに設計されたレガシーなレンダリングエンジンを扱う場合、QRhiへの移行には、多くの場合、単一のrender ステップ(コピーやアップロード、バッファのクリア、ドローコールの発行がすべて混在して行われる)から、明確に分離された、 2段階のprepare -render 構成へと再設計することがよくあります。この構成では、render ステップはレンダーパスを開始し、ドローコールを記録するのみであり、すべてのリソースの作成や更新、アップロード、コピーのキューイングは、その前のprepare ステップで行われます。

QRhiでは現時点では、コマンドバッファを自由に作成・送信することはできません。 これは将来、特にコンピュートサポートが導入された場合、ある程度緩和される可能性がありますが、明確に定義されたframe-start およびframe-end ポイントのモデルと、frame-end がプレゼンテーションを意味する専用の「フレーム」コマンドバッファを組み合わせた方式は、Qt のさまざまな UI テクノロジーに最も適しているため、今後も主要な動作方法として残っていくでしょう。

スレッド処理

QRhiインスタンスおよび関連するリソースは、どのスレッド上でも作成・使用できますが、その使用はすべてその単一のスレッドに限定されなければなりません。アプリケーション内で複数のQWindowにレンダリングを行う場合、各ウィンドウに専用のスレッドとQRhiインスタンスを用意することが推奨されることがよくあります。これにより、複数のウィンドウへのプレゼンテーションによって引き起こされる予期せぬスロットリングの問題を解消できるからです。 概念的には、これはQt Quick のシーングラフがOpenGLを直接扱う際のスレッド化されたレンダリングループの動作と同じです。つまり、ウィンドウごとに1つのスレッド、スレッドごとに1つのQOpenGLContext です。QRhiに移行する際、QOpenGLContext はQRhiに置き換えられるため、移行は簡単に行えます。

QRhiGles2NativeHandles 経由で渡される OpenGL コンテキストなど、外部で作成されたネイティブオブジェクトについては、他のスレッドによって誤用されないよう確保するのはアプリケーション側の責任となります。

リソースは、QRhiインスタンス間で共有できません。これは意図的な設計です。QRhiは、キュー、コマンドバッファ、およびリソースの同期に関連するタスクのほとんどを隠蔽しており、それらに関するAPIを提供していないためです。 しかし、複数のスレッドからのグラフィックスリソースの安全かつ効率的な並行使用は、これらの概念と密接に関連しているため、現時点では本ドキュメントの範囲外ですが、将来的に導入される可能性があります。

注:Metalバックエンドでは 、レンダリングスレッド上でオートリリースポールが利用可能であることが必要であり、理想的にはレンダリングループの各反復をラップする必要があります。これは、メイン(GUI)スレッド上でレンダリングを行う場合、QRhiのユーザーによる特別な操作を必要としませんが、独立した専用のレンダリングスレッドを使用する場合は重要になります。

リソースの同期

QRhiは、リソースバリアや画像レイアウトの遷移に関するAPIを公開していません。このような同期は、該当する場合(Vulkanなど)、バックエンドによって、必要に応じてリソースの使用状況を追跡することで暗黙的に行われます。バッファおよび画像のバリアは、アプリケーションに対して透過的に、レンダリングパスまたはコンピュートパスの前に挿入されます。

注: レンダリングパスまたはコンピュートパス内のリソースは 、そのパス中は単一の用途にのみバインドされることが想定されています。 たとえば、バッファは頂点バッファ、インデックスバッファ、ユニフォームバッファ、またはストレージバッファとして使用できますが、1つのパス内でこれらを組み合わせて使用することはできません。ただし、作成時に両方の用途が宣言されているバッファであれば、たとえば、コンピュートパスではストレージバッファとして使用し、レンダリングパスでは頂点バッファとして使用することは全く問題ありません。

注:テクスチャについては 、特定のケースにおいてこのルールが緩和されています。これは、同じテクスチャの 2 つのサブリソース(通常は 2 つの異なるミップレベル)を、異なるアクセス(1 つは読み込み用、もう 1 つは書き込み用)に使用することが、同じパス内でもサポートされているためです。

リソースの再利用

ユーザーの観点からは、QRhiResource はQRhiResource::destroy()を呼び出した直後から再利用可能です。スワップチェーンを除き、既に作成済みのオブジェクトに対してcreate() を呼び出すと、暗黙的にdestroy() が実行されます。これにより、異なるパラメータでQRhiResource インスタンスを再利用するための便利なショートカットが提供され、その下には新しいネイティブグラフィックスオブジェクトが使用されます。

同じオブジェクトを再利用することの重要性は、一部のオブジェクトが他のオブジェクトを参照しているという事実にあります。例えば、QRhiShaderResourceBindings は、QRhiBuffer 、QRhiTexture 、およびQRhiSampler の各インスタンスを参照することができます。後のフレームで、これらのバッファのいずれかのサイズを変更したり、サンプラーのパラメータを変更したりする必要がある場合、QRhiBuffer やQRhiSampler を完全に破棄して新しいものを作成してしまうと、古いインスタンスへのすべての参照が無効になってしまいます。QRhiBuffer::setSize() などを介して適切なパラメータを変更し、その後QRhiBuffer::create() を呼び出すだけで、すべてが期待通りに動作します。内部的にはQRhiBuffer が完全に新しいネイティブバッファで裏付けられている可能性が高いにもかかわらず、QRhiShaderResourceBindings には一切手を加える必要はありません。

QRhiBuffer *ubuf = rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 256);
ubuf->create();

QRhiShaderResourceBindings *srb = rhi->newShaderResourceBindings()
srb->setBindings({
    QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage, ubuf)
});
srb->create();

// ...

// now in a later frame we need to grow the buffer to a larger size
ubuf->setSize(512);
ubuf->create(); // same as ubuf->destroy(); ubuf->create();

// srb needs no changes whatsoever, any references in it to ubuf
// stay valid. When it comes to internal details, such as that
// ubuf may now be backed by a completely different native buffer
// resource, that is is recognized and handled automatically by the
// next setShaderResources().

QRhiTextureRenderTarget は同じ契約を提供します。つまり、QRhiCommandBuffer::beginPass() の呼び出しは、レンダリングターゲットオブジェクトの作成以降に、関連付けられたテクスチャやレンダーバッファのいずれかが(create() を呼び出すことで)再構築された場合でも安全です。 これにより、アプリケーションは、QRhiTexture に新しいピクセルサイズを設定し、create()を呼び出すことで、テクスチャのサイズを変更できるようになります。これにより、内部でまったく新しいネイティブテクスチャリソースが作成されますが、QRhiTextureRenderTarget を更新する必要はありません。更新はbeginPass()内で暗黙的に行われるためです。

プールされたオブジェクト

リソースに加え、QRhiResourceUpdateBatch などのプールされたオブジェクトも存在します。インスタンスは、nextResourceUpdateBatch()などのnext 関数を介して取得されます。この場合、呼び出し元は返されたインスタンスを所有しません。 ここで有効な操作方法は、QRhiResourceUpdateBatch に対して関数を呼び出した後、それをQRhiCommandBuffer::beginPass()またはQRhiCommandBuffer::endPass()に渡すことだけです。これらの関数は、バッチをプールに返す処理を自動的に行います。あるいは、QRhiResourceUpdateBatch::release()を呼び出すことで、バッチを「キャンセル」し、処理を行わずにプールに返すこともできます。

したがって、典型的なパターンは次のようになります:

QRhiResourceUpdateBatch *resUpdates = rhi->nextResourceUpdateBatch();
// ...
resUpdates->updateDynamicBuffer(ubuf, 0, 64, mvp.constData());
if (!image.isNull()) {
    resUpdates->uploadTexture(texture, image);
    image = QImage();
}
// ...
QRhiCommandBuffer *cb = m_sc->currentFrameCommandBuffer();
// note the last argument
cb->beginPass(swapchain->currentFrameRenderTarget(), clearCol, clearDs, resUpdates);

スワップチェーンの特記事項

QRhiSwapChain には、スワップチェーン特有の性質に起因するいくつかの特別なセマンティクスがあります。

  • create() はなく、代わりにQRhiSwapChain::createOrResize() が用意されています。この関数を繰り返し呼び出すことは、QRhiSwapChain::destroy() を呼び出した後にQRhiSwapChain::createOrResize() を呼び出すこととは異なります。これは、スワップチェーンでは、バッファのサイズ変更が必要な場合、単純に破壊して一から再作成するよりも効率的な方法で処理できる仕組みがしばしば備わっているためです。
  • アクティブなQRhiSwapChain は、QWindow の基盤となるQPlatformWindow、ひいては関連するネイティブウィンドウオブジェクトが破棄される前に、destroy()を呼び出すか、オブジェクトを破棄することで解放する必要があります。 この処理を先延ばしにしてはなりません。なぜなら、例えばQWindow::close()の取得時にQPlatformWindowが破棄されたなどしてネイティブウィンドウがもはや存在しなくなった場合、スワップチェーンの解放が問題を引き起こす可能性があるからです(また、Vulkanなどの一部のAPIでは、明示的に禁止されています)。 したがって、対象のQWindow がQPlatformSurfaceEvent::SurfaceAboutToBeDestroyed イベントを送信した際には、必ずスワップチェーンを解放する必要があります。QWindow が破棄される前にイベントが届かない場合(QCoreApplication::quit()を使用している場合に発生し得ます)、イベントループが終了した後にQWindow::handle()を確認し、値がnullでない場合(つまり、基になるネイティブウィンドウがまだ存在している場合)、スワップチェーンの解放を呼び出してください。

所有権

一般的なルールとして、所有権の移転は行われません。既存のグラフィックスデバイスを使用して QRhi を作成しても、QRhi がそのデバイスオブジェクトの所有権を取得するわけではありません。同様に、QRhi::nativeHandles() やQRhiTexture::nativeTexture() を通じてデバイスやテクスチャオブジェクトを「エクスポート」しても、所有権は譲渡されません。最も重要な点として、構造体内やセッターを介してポインタを渡しても、所有権は移転されません。

トラブルシューティングとプロファイリング

エラー報告

QRhi::create() や、リソースクラスのcreate() メンバ関数(例:QRhiBuffer::create())などの関数は、戻り値(それぞれnullptr またはfalse )によって失敗を示します。QShader を使用する場合、関数に渡されたデータのデシリアライズに失敗すると、QShader::fromSerialized() は無効なQShader を返し(この場合、isValid() はfalse を返します)。 一部の関数、特にbeginFrame() は、FrameOpSwapChainOutOfDate のような「ソフトエラー」を報告する場合があります。これは回復不可能なエラーを示すものではなく、むしろ「後で再試行してください」という応答として捉えるべきものです。

警告やエラーは、qWarning() を通じて、いつでもデバッグ出力に出力される可能性があります。したがって、アプリケーションの出力を常に確認することをお勧めします。

追加のデバッグメッセージは、以下のロギングカテゴリを通じて有効にできます。これらのカテゴリからのメッセージは、QLoggingCategory または環境変数QT_LOGGING_RULES を通じて明示的に有効にされない限り、デフォルトでは出力されません。Qt Quick との相互運用性を高めるため、環境変数QSG_INFO でもこれらのデバッグ出力を有効にできます。

  • qt.rhi.general

さらに、アプリケーションは、正常に初期化された QRhi からQRhi backend name およびgraphics device information を照会できます。これにより、必要に応じて、本番環境のビルドであっても、ユーザーに表示したり、アプリケーションログに保存したりすることができます。

レンダリングの問題の調査

レンダリング結果が期待通りでない場合や、アプリケーションで問題が発生している場合は、常にネイティブ 3D API のデバッグおよび検証機能による確認を検討してください。QRhi 自体には、基盤となるレイヤーにすでに存在する膨大な機能を再現することは現実的ではないため、エラーチェック機能は限定的です。

  • Vulkan の場合、Vulkan バリデーションレイヤーの制御は QRhi の範囲外ですが、QVulkanInstance を適切なレイヤーで構成することで実現できます。 たとえば、QVulkanInstance 上でcreate()を呼び出す前に、instance.setLayers({ "VK_LAYER_KHRONOS_validation" }); を呼び出します。(これは、検証レイヤーが実際にインストールされ、利用可能であることを前提としています。例:Vulkan SDKから)デフォルトでは、QVulkanInstance はVulkanのデバッグメッセージをqDebug に便利にリダイレクトするため、検証メッセージは他のQt警告と同様に表示されます。
  • Direct 3D 11 および 12 では、適切な `init params struct` 内の `enableDebugLayer ` フラグを切り替えることで、デバッグレイヤーが有効なグラフィックスデバイスを要求できます。Direct 3D 12 の場合、デバッグレイヤーがメッセージコールバックをサポートしている限り、メッセージは Vulkan の検証メッセージと同様に `qDebug` 経由で出力されます。 それ以外の場合、およびDirect 3D 11では常に、メッセージはデバッグ出力に表示されます。この出力は、Qt Creator のメッセージパネル、またはDebugViewなどのツールで確認できます。
  • Metal については、Metal 検証の制御は QRhi の範囲外です。代わりに、検証を有効にするには、環境変数 `METAL_DEVICE_WRAPPER_TYPE=1 ` を設定してアプリケーションを実行するか、XCode 内でアプリケーションを実行してください。最新の XCode および macOS バージョンでは、さらに他の設定や環境変数がある可能性があります。例えば、こちらのページを参照してください。

フレームキャプチャとパフォーマンスプロファイリング

内部で3D APIを利用しつつ、QRhiを使用してウィンドウにレンダリングを行うQtアプリケーションは、少なくともウィンドウシステムおよびグラフィックスパイプラインの観点からは、同じ3D APIを使用する他の(Qt以外の)アプリケーションと何ら変わりません。 つまり、ゲームなどの3Dグラフィックスを扱うアプリケーションのデバッグやプロファイリングのためのツールや手法は、このようなQtアプリケーションにもすべて適用されます。

QRhiを使用するQtアプリケーションのレンダリング内部を分析できるツールの例をいくつか挙げます。これには、Qt Quick やQt Quick の3Dベースのプロジェクトも含まれます:

  • RenderDocを使用すると、Windows および Linux 上で、OpenGL、Vulkan、D3D11、または D3D12 を使用するアプリケーションのフレームキャプチャを取得し、記録されたコマンドやパイプラインの状態を詳細に分析することができます。 3D シーンの一部が期待通りに表示されない原因を突き止めようとする際、RenderDoc を使用すれば、パイプラインの各ステージや関連する状態を迅速かつ効率的に確認し、欠落している値や誤った値を発見することができます。また、これは Qt 自体の開発においても積極的に活用されているツールです。
  • NVIDIAベースのシステムでは、Nsight GraphicsがWindowsおよびLinux上でグラフィックスデバッガツールを提供しています。フレーム内のコマンドやパイプラインの調査に加え、ベンダー固有のツールを使用することで、単純なフレームキャプチャでは得られないタイミング情報やハードウェアのパフォーマンス情報を確認することができます。
  • AMDベースのシステムでは、Radeon GPU Profilerを使用することで、アプリケーションのレンダリングとそのパフォーマンスについてより深い洞察を得ることができます。
  • リアルタイムのパフォーマンス情報を表示するオーバーレイも非常に有用であり、信頼性が高く、より多くの情報を表示できるため、アプリケーション自体に単純なフレームレートカウンターを実装するよりも好まれることがよくあります。その一例として、複数のベンダーのグラフィックスハードウェアをサポートするPresentMon が挙げられます。
  • QRhiはDirect 3D 12をサポートしているため、Windows上のDirectX 12ゲーム向けのパフォーマンスチューニングおよびデバッグツールであるPIXを使用することも選択肢の一つです。
  • macOSでは、XCodeのMetalデバッガーを使用して、フレームキャプチャの取得や分析を行い、パフォーマンスの詳細を調査したり、シェーダーをデバッグしたりできます。また、macOS 13では、環境変数MTL_HUD_ENABLED=1 を設定することで、Metalベースのウィンドウについてフレームレートやその他の情報を表示するオーバーレイを有効にすることも可能です。

モバイルおよび組み込みプラットフォームでは、GPU または SoC ベンダーが提供する、ベンダーやプラットフォーム固有のツールが利用可能であり、OpenGL ES や Vulkan を使用したアプリケーションのパフォーマンスプロファイリングを行うことができます。

フレームをキャプチャする際は、QRhiのdebug markers were enabled が設定されており、かつ使用中のグラフィックスAPIがこれをサポートしている限り、デバッグマーカーを使用してオブジェクトやコマンドのグループに名前を付けることができる点に注意してください。コマンドストリームに注釈を付けるには、debugMarkBegin()、debugMarkEnd()、および/またはdebugMarkMsg()を呼び出します。これは、複数のレンダリングパスを含む大規模なフレームで特に役立ちます。 リソースの命名は、create() を呼び出す前に、setName() を呼び出すことで行います。

アプリケーション内で CPU および GPU 側の基本的なタイミング測定を行うには、QElapsedTimer およびQRhiCommandBuffer::lastCompletedGpuTime() を使用できます。後者は現時点では一部のグラフィックス API でのみ利用可能であり、QRhi::EnableTimestamps フラグを指定して有効にする必要があります。

リソースリークのチェック

QRhi オブジェクトから作成されたすべてのバッファ、テクスチャ、およびその他のリソースを適切に破棄せずに QRhi オブジェクトを破棄すると、アプリケーションがデバッグビルドである場合、または環境変数 `QT_RHI_LEAK_CHECK ` が 0 以外の値に設定されている場合、これに関する警告がデバッグ出力に表示されます。これは、アプリケーションのレンダリングロジック内におけるリソース処理に関する設計上の問題を発見するための簡単な方法です。 ただし、一部のプラットフォームや基盤となるグラフィックスAPIでは、Qtが直接制御できない独自の割り当てやリソースリーク検出が行われる場合があることに注意してください。たとえば、Vulkanを使用する場合、グラフィックスメモリの割り当てを所有するリソースがQRhiより前に破棄されていないと、デバッグビルド時にメモリアロケータがアサーション違反を発生させることがあります。 さらに、Vulkan 検証レイヤーが有効になっている場合、解放されていないネイティブグラフィックスリソースについて警告が出力されます。同様に、Direct 3D においても、アプリケーションが QRhi およびそのリソースを正しい順序で破棄しなかった場合、解放されていない COM オブジェクトに関する警告が出力されることがあります。

関連項目: RHI ウィンドウの例、QRhiCommandBuffer 、QRhiResourceUpdateBatch 、QRhiShaderResourceBindings 、QShader 、QRhiBuffer 、QRhiTexture 、QRhiRenderBuffer 、QRhiSampler 、QRhiTextureRenderTarget 、QRhiGraphicsPipeline 、QRhiComputePipeline 、およびQRhiSwapChain 。

メンバータイプのドキュメント

[alias, since 6.10] QRhi::AdapterList

QVector<QRhiAdapter *> の同義語。

このtypedefはQt 6.10で導入されました。

enum QRhi::BeginFrameFlag
flags QRhi::BeginFrameFlags

QRhi::beginFrame() のフラグ値

BeginFrameFlags 型は、QFlags<BeginFrameFlag> の typedef です。この型は、BeginFrameFlag 値の論理和(OR)を格納します。

enum QRhi::EndFrameFlag
flags QRhi::EndFrameFlags

QRhi::endFrame() のフラグ値

定数値説明
QRhi::SkipPresent1 << 0presentコマンドをキューに追加しないこと、またはswapBuffersの呼び出しを行わないことを指定します。これにより、画像は表示されません。 このフラグがすべて設定された状態で複数のフレームを生成することは推奨されません(ただし、例えばベンチマーク目的の場合は例外です。ただし、表示を行わずにコマンドの完了を待つ場合、バックエンドによって動作が異なる可能性があるため、結果の比較はできないことに注意してください)。

EndFrameFlags 型は、QFlags<EndFrameFlag> の typedef です。EndFrameFlag 値の論理和(OR)を格納します。

enum QRhi::Feature

現在使用中のバックエンドがどの機能をサポートしているかを示すフラグ値。

定数値説明
QRhi::MultisampleTexture1サンプル数が 1 より大きいテクスチャがサポートされていることを示します。実際には、OpenGL ES 3.1 より前のバージョンおよび OpenGL 3.0 より前のバージョンでは、この機能はサポートされません。
QRhi::MultisampleRenderBuffer2サンプル数が 1 より大きいレンダリングバッファがサポートされていることを示します。実際には、この機能は OpenGL ES 2.0 ではサポートされず、関連する拡張機能が存在しない限り、OpenGL 2.x でもサポートされない可能性があります。
QRhi::DebugMarkers3デバッグマーカーグループ(およびQRhiCommandBuffer::debugMarkBegin ())がサポートされていることを示します。
QRhi::Timestamps4コマンドバッファのタイムスタンプがサポートされていることを示します。QRhiCommandBuffer::lastCompletedGpuTime() に関連します。これは、Metal、Vulkan、Direct 3D 11 および 12、ならびにバージョン 3.3 以降の OpenGL コンテキストでサポートされていると予想されます。 ただし、これらのAPIの一部では、タイムスタンプクエリのサポートは技術的にオプションであるため、それらのすべての実装でこの機能が常にサポートされるとは保証できません。
QRhi::Instancing5インスタンス化された描画がサポートされていることを示します。実際には、OpenGL ES 2.0 および OpenGL 3.2 以前では、この機能はサポートされません。
QRhi::CustomInstanceStepRate61 以外のインスタンスステップレートがサポートされていることを示します。実際には、OpenGL ではこの機能は常にサポートされません。また、VK_EXT_vertex_attribute_divisor を使用せずに Vulkan 1.0 を実行した場合も、この機能について false と報告されます。
QRhi::PrimitiveRestart7少なくとも特定のプリミティブトポロジーにおいて、インデックス値 0xFFFF (IndexUInt16) または 0xFFFFFFFF (IndexUInt32) に遭遇した際にプリミティブの組み立てを再開する機能が有効であることを示します。QRhi はすべてのバックエンドでこの機能を有効にしようとしますが、場合によってはサポートされないことがあります。 一部のAPIでは、固定インデックスによるプリミティブ再起動が常に有効になっているため、プリミティブ再起動を動的に制御することはできません。 アプリケーションは、この機能がサポートされていると報告されている場合は、トポロジに応じて、上記のインデックス値may が特別に扱われることを前提とする必要があります。この機能がサポートされていると報告されている限り、バックエンド間でプリミティブ再起動の挙動が同一であることが保証されるトポロジは、LineStrip およびTriangleStrip の 2 つだけです。
QRhi::NonDynamicUniformBuffers8UniformBuffer の使用法およびImmutable またはStatic の型を持つバッファの作成がサポートされていることを示します。サポートされていないと報告された場合、均一(定数)バッファはDynamic として作成する必要があります(いずれにせよ、これが推奨されます)。
QRhi::NonFourAlignedEffectiveIndexBufferOffset94バイトアラインされていない有効インデックスバッファオフセット(indexOffset + firstIndex * indexComponentSize )がサポートされていることを示します。サポートされていない場合、アラインされていない有効オフセットを使用してdrawIndexed() を発行しようとすると、未定義の挙動を引き起こす可能性があります。これは特に Metal に関連しており、Metal ではこれが「サポートされていない」と報告されます。
QRhi::NPOTTextureRepeat102の冪乗サイズではないテクスチャに対して、Repeat のラップモードおよびミップマップフィルタリングモードがサポートされていることを示します。実際には、GL_OES_texture_npot をサポートしていないOpenGL ES 2.0の実装においてのみ、この値がfalseとなる可能性があります。
QRhi::RedOrAlpha8IsRed11RED_OR_ALPHA8 形式が、1成分の8ビットred 形式にマッピングされることを示します。これは、OpenGL ESまたは非コアプロファイルコンテキストを使用する場合、OpenGLを除くすべてのバックエンドに当てはまります。 その場合、代わりにGL_ALPHA 、つまり1コンポーネントの8ビットalpha 形式が使用される。この特別なテクスチャ形式を使用することで、テクスチャ作成のための単一のコードパスを維持しつつ、実際の形式の決定はバックエンドに委ね、機能フラグを使用してテクスチャのサンプリングに適したシェーダーバリアントを選択することが可能になる。
QRhi::ElementIndexUint12インデックスバッファで 32 ビットの符号なし整数要素がサポートされていることを示します。実際には、必要な拡張機能を持たない標準の OpenGL ES 2.0 実装上で実行する場合を除き、どこでもこれが当てはまります。false の場合、インデックスバッファでは 16 ビットの符号なし要素のみがサポートされます。
QRhi::Compute13コンピュートシェーダー、画像のロード/ストア、およびストレージバッファがサポートされていることを示します。OpenGL 4.3 以前および OpenGL ES 3.1 以前では、コンピュート機能はサポートされていません。
QRhi::WideLines14幅が 1 以外の線がサポートされていることを示します。サポートされていないと報告された場合、グラフィックスパイプライン状態で設定された線の幅は無視されます。一部のバックエンド(D3D11、D3D12、Metal)では、これは常に false になる場合があります。 Vulkan では、この値は実装によって異なります。OpenGL では、コアプロファイルコンテキストでは幅の広い線はサポートされていません。
QRhi::VertexShaderPointSize15頂点シェーダー内のgl_PointSize を介して設定されたラスタライズされた点のサイズが考慮されることを示します。非対応と報告された場合、サイズが1以外の点の描画はサポートされません。その場合でも、シェーダー内でgl_PointSize を設定することは有効ですが、無視されます。 (例えば、HLSLを生成する場合、生成されたコードからこの代入は黙って削除されます)一部のAPI(Metal、Vulkan)では、サイズが1の場合であっても、自動的に1にデフォルト設定されないため、点を描画する際は常にシェーダー内で点サイズを明示的に設定する必要があることに注意してください。
QRhi::BaseVertex16drawIndexed() がvertexOffset 引数をサポートしていることを示します。サポートされていないと報告された場合、インデックス付き描画における vertexOffset の値は無視されます。実際には、OpenGL および OpenGL ES バージョン 3.2 未満、ならびに iOS シミュレータを含む旧式の iOS デバイス上の Metal では、この機能はサポートされません。
QRhi::BaseInstance17インスタンス化された描画コマンドが `firstInstance ` 引数をサポートしていることを示します。 非対応と報告された場合、firstInstanceの値は無視され、インスタンスIDは0から始まります。実際には、iOSシミュレータを含む古いiOSデバイス上のMetalおよびすべてのバージョンのOpenGLでは、この機能はサポートされません。後者の理由は、OpenGL ESがベースインスタンスを持つ描画呼び出しをまったくサポートしていないためです。 現在、QRhi のOpenGLバックエンドも、OpenGL(非ES)向けのこの機能を実装していません。これは、GLESの影響により、ポータブルなアプリケーションが実際にはゼロ以外のベースインスタンスに依存できないためです。それでもアプリケーションでこれを行うことを選択する場合は、InstanceIndexIncludesBaseInstance機能についても認識しておく必要があります。
QRhi::TriangleFanTopology18QRhiGraphicsPipeline::setTopology()がQRhiGraphicsPipeline::TriangleFan をサポートしていることを示します。実際には、この機能はMetalおよびDirect 3D 11/12ではサポートされません。
QRhi::ReadBackNonUniformBuffer19reading buffer contents が、UniformBufferとは異なる用途のQRhiBuffer インスタンスに対してサポートされていることを示します。実際には、この機能はOpenGL ES 2.0ではサポートされません。
QRhi::ReadBackNonBaseMipLevel20テクスチャの内容を読み戻す際に、0 以外のミップレベルを指定することがサポートされていることを示します。サポートされていない場合、QRhiReadbackDescription で 0 以外のレベルを指定すると、すべてのピクセルが 0 の画像が返されます。実際には、この機能は OpenGL ES 2.0 ではサポートされません。
QRhi::TexelFetch21シェーダー内で texelFetch() および textureLod() が利用可能であることを示します。実際には、GLSL 100 es およびバージョン 130 以前ではこれらの関数がサポートされていないため、OpenGL ES 2.0 および OpenGL 2.x コンテキストでは、この機能はサポートされていないと報告されます。
QRhi::RenderToNonBaseMipLevel22QRhiTexture をカラーアタッチメントとしてQRhiTextureRenderTarget を作成する際、0以外のミップレベルを指定することがサポートされていることを示します。サポートされていない場合、ターゲットのミップレベルが0でないときはいつでもcreate()が失敗します。実際には、この機能はOpenGL ES 2.0ではサポートされません。
QRhi::IntAttributes23シェーダーパイプラインに対して、符号付きおよび符号なし整数型の入力属性を指定することがサポートされていることを示します。サポートされていない場合、QRhiGraphicsPipeline::create() は成功しますが、警告メッセージが表示され、ターゲット属性の値は破損します。実際には、この機能は OpenGL ES 2.0 および OpenGL 2.x ではサポートされません。
QRhi::ScreenSpaceDerivatives24シェーダーにおいて、dFdx()、dFdy()、fwidth() などの関数がサポートされていることを示します。実際には、GL_OES_standard_derivatives 拡張機能がない OpenGL ES 2.0 では、この機能はサポートされません。
QRhi::ReadBackAnyTextureFormat25QRhiTexture::Format のいずれに対しても、テクスチャ内容の読み出しが機能することが期待できることを示します。OpenGL以外のバックエンドでは、この機能に対してtrueが返されることが期待されます。falseと報告された場合(通常はOpenGLで発生します)、読み出しについてはQRhiTexture::RGBA8 およびQRhiTexture::BGRA8 のフォーマットのみがサポートされることが保証されます。 さらに、OpenGL(OpenGL ESを除く)では、コンポーネントあたり1バイトのフォーマットであるQRhiTexture::R8 およびQRhiTexture::RED_OR_ALPHA8 の読み戻しもサポートされています。OpenGLでは、実装がこれらをサポートしている限り、浮動小数点フォーマットであるQRhiTexture::RGBA16F および RGBA32F の読み戻しも機能する可能性がありますが、このフラグが示すように、QRhi については保証できません。
QRhi::PipelineCacheDataLoadSave26pipelineCacheData() およびsetPipelineCacheData() 関数が機能することを示します。サポートされていない場合、これらの関数は何の処理も行わず、取得される blob は常に空になります。したがって、パイプラインキャッシュの内容を取得し、その後のアプリケーション実行時に再読み込みを行っても、何のメリットも期待できません。
QRhi::ImageDataStride27テクスチャアップロードにおいて、生画像データに対してカスタムストライド(行長)を指定することがサポートされていることを示します。サポートされていない場合(基盤となるAPIがGL_UNPACK_ROW_LENGTHをサポートしていないOpenGL ES 2.0である場合など)、QRhiTextureSubresourceUploadDescription::setDataStride() を使用してはなりません。
QRhi::RenderBufferImport28QRhiRenderBuffer::createFrom() がサポートされていることを示します。ほとんどのグラフィックス API では、QRhiRenderBuffer がQRhiTexture と同様に内部でテクスチャオブジェクトをカプセル化しているため、これは意味をなしません。 しかし、OpenGL では、レンダーバッファオブジェクトは API 内で独立したオブジェクトタイプとして存在しており、特定の環境(例えば、レンダーバッファオブジェクトを EGLImage オブジェクトに関連付けたい場合など)では、既存の OpenGL レンダーバッファオブジェクトをQRhiRenderBuffer でラップできるようにすることが重要です。
QRhi::ThreeDimensionalTextures293Dテクスチャがサポートされていることを示します。実際には、OpenGLおよびOpenGL ESのバージョン3.0未満では、この機能はサポートされません。
QRhi::RenderTo3DTextureSlice303Dテクスチャ内のスライスへのレンダリングがサポートされていることを示します。これは、Vulkan 1.1の機能であるVK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BITに依存しているため、Vulkan 1.0ではサポートされない可能性があります。
QRhi::TextureArrays31テクスチャ配列がサポートされており、QRhi::newTextureArray() が機能することを示します。なお、テクスチャ配列がサポートされていない場合でも、テクスチャの配列は利用可能です。これらは2つの独立した機能であるためです。
QRhi::Tessellation32テッセレーションの制御ステージおよび評価ステージがサポートされていることを示します。サポートされていると報告された場合、QRhiGraphicsPipeline のトポロジーをPatches に設定でき、制御点数はsetPatchControlPointCount()を介して設定でき、テッセレーションの制御および評価用のシェーダーをQRhiShaderStage リストで指定できます。 テッセレーションシェーダーには、API間の移植性の問題があります(例えば、ハルシェーダーの構造上の理由からGLSL/SPIR-VをHLSLに変換するのは困難ですが、Metalは他のAPIとは多少異なるテッセレーションパイプラインを使用しています)。そのため、基本的な機能はすべての基盤となるAPIで実装されているにもかかわらず、予期せぬ問題が発生する可能性があります。 特に Direct 3D の場合、qsb は SPIR-V からこれらを生成できないため、テッセレーション制御および評価の各段階において、手書きの HLSL ハルシェーダーおよびドメインシェーダーを、それぞれ各 `QShader ` に注入する必要があります。なお、アイソライン・テッセレーションはすべてのバックエンドでサポートされるわけではないため、避けるべきであることに注意してください。 バックエンド間で移植可能なパッチ制御ポイントの最大数は 32 です。
QRhi::GeometryShader33ジオメトリシェーダステージがサポートされていることを示します。サポートされている場合、QRhiShaderStage リストでジオメトリシェーダを指定できます。 ジオメトリシェーダーは、QRhi では実験的な機能とみなされており、実行時に実装がサポートされていると報告されることを前提として、Vulkan、Direct 3D 11 および 12、OpenGL (3.2 以上)、OpenGL ES (3.2 以上) でのみサポートされるものと予想されます。 Qt 6.11 以降、ジオメトリシェーダーは自動的に HLSL に変換されるため、手動で記述した HLSL ジオメトリシェーダーを挿入する必要はなくなりました(ただし、gl_in や gl_in[0].gl_Position などの式はサポートされていない点に注意してください。 代わりに、頂点シェーダーから出力変数として位置を渡してください)。Metal ではジオメトリシェーダーはサポートされていません。
QRhi::TextureArrayRange34texture arrays において、シェーダーに公開される範囲を指定できることを示します。通常、すべての配列レイヤーが公開されており、どのレイヤーを選択するかはシェーダーに委ねられます(sampler2DArray をサンプリングする際、texture() に渡される 3 番目の座標を介して)。 サポートされている場合、building またはimporting を呼び出す前にQRhiTexture::setArrayRangeStart()およびQRhiTexture::setArrayRangeLength()を呼び出すと、ネイティブテクスチャに効果が生じ、配列から指定された範囲のみが選択されるようになります。 これは、アクセラレーションされたビデオデコードや Direct 3D 11 を使用する場合など、特殊なケースで必要となります。これは、D3D11_BIND_DECODER とD3D11_BIND_SHADER_RESOURCE の両方が設定されたテクスチャ配列は、単一の配列レイヤーが選択されている場合にのみシェーダーリソースとして使用できるためです。 なお、これらはすべて、テクスチャがQRhiShaderResourceBinding::SampledTexture またはQRhiShaderResourceBinding::Texture のシェーダーリソースとして使用される場合にのみ適用され、画像のロード/ストアとは互換性がありません。この機能は、すべてのグラフィックスAPIにうまくマッピングされないため、一部のバックエンドでのみ利用可能であり、いずれにせよ特殊なケースへの対応を目的としたものです。 実際には、この機能はDirect3D 11/12およびVulkanでサポートされることが予想されます。
QRhi::NonFillPolygonMode35QRhiGraphicsPipeline において、デフォルトのFill以外のPolygonModeの設定がサポートされていることを示します。モードをLineに変更する一般的なユースケースは、ワイヤーフレームレンダリングを実現することです。ただし、これはOpenGL ESのコア機能としては利用できず、Vulkanではオプション機能であり、一部のモバイルGPUではこの機能が提供されていない場合があります。
QRhi::OneDimensionalTextures361Dテクスチャがサポートされていることを示します。実際には、OpenGL ESではこの機能はサポートされません。
QRhi::OneDimensionalTextureMipmaps371次元テクスチャのミップマップ生成がサポートされていることを示します。実際には、OneDimensionalTexturesのサポートを報告していないバックエンド、Metal、およびDirect 3D 12では、この機能はサポートされません。
QRhi::HalfAttributes38シェーダーパイプラインに対して、半精度(16ビット)浮動小数点型で入力属性を指定することがサポートされていることを示します。サポートされていない場合、QRhiGraphicsPipeline::create() は成功しますが、警告メッセージが表示され、ターゲット属性の値は破損します。 実際には、一部の OpenGL ES 2.0 および OpenGL 2.x の実装では、この機能はサポートされません。 Direct3D 11/12 は半精度の入力属性をサポートしていますが、half3 型はサポートしていない点に注意してください。D3D バックエンドは、half3 属性を half4 として渡します。クロスプラットフォームの互換性を確保するには、half3 入力を 8 バイトにパディングする必要があります。
QRhi::RenderToOneDimensionalTexture391Dテクスチャのレンダリングターゲットがサポートされていることを示します。実際には、OneDimensionalTexturesのサポートを報告しないバックエンドおよびMetalでは、この機能はサポートされません。
QRhi::ThreeDimensionalTextureMipmaps403Dテクスチャのミップマップ生成がサポートされていることを示します。これは通常、Qt 6.10以降のすべてのバックエンドでサポートされています。
QRhi::MultiView41マルチビュー(例:VK_KHR_multiview)がサポートされていることを示します。OpenGL ES 2.0、Direct 3D 11、およびGL_OVR_multiview2 を持たないOpenGL (ES)実装では、この機能はサポートされません。 Vulkan 1.1以降およびDirect 3D 12では、通常、マルチビューがサポートされています。サポートされていると報告された場合、テクスチャ配列を参照し、multiViewCount が設定されたQRhiColorAttachment を持つQRhiTextureRenderTarget を作成することで、マルチビューレンダリングを使用するレンダーパスの記録が可能になります。 さらに、そのレンダリングパスで使用されるすべてのQRhiGraphicsPipeline は、the same view count set を設定している必要があります。なお、マルチビューは2Dテクスチャ配列と組み合わせてのみ利用可能です。個別のテクスチャ(例:左右の眼用の2つ)へのレンダリングを最適化するために使用することはできません。 むしろ、マルチビュー・レンダリング・パスのターゲットは常にテクスチャ配列であり、各ビューに対応するレイヤー(配列要素)に自動的にレンダリングされます。したがって、この機能にはテクスチャ配列も含まれます。 マルチビューレンダリングは、テッセレーションやジオメトリシェーダーとの併用ではサポートされていません。マルチビューレンダリングの詳細については、QRhiColorAttachment::setMultiViewCount() を参照してください。この列挙型値は Qt 6.7 で導入されました。
QRhi::TextureViewFormat42QRhiTexture に対してview format を設定することが有効であることを示します。サポートされていると報告された場合、読み取り(サンプリング)または書き込み(レンダリングターゲット/画像のロード・ストア)のビューモードを設定すると、テクスチャのビュー形式が変更されます。サポートされていない場合、ビュー形式の設定は効果を持ちません。 Qt 3Dは、基盤となる3D APIおよびその実装におけるフォーマットの互換性やリソースの表示ルールについて、認識も制御もできないことに注意してください。不適切または互換性のないフォーマットを渡すと、エラーや未定義の挙動を引き起こす可能性があります。 この機能は主に、sRGB 形式で作成されたテクスチャへのレンダリングを非 sRGB 形式に「キャスト」し、シェーダーの書き込み時に不要な線形→sRGB 変換を回避するために提供されています。その他の種類のキャストについては、基盤となる API によって機能する場合と機能しない場合があります。現在、Vulkan および Direct 3D 12 で実装されています。 D3D12 では、CastingFullyTypedFormatSupported がサポートされている場合にのみこの機能を利用できます。https://microsoft.github.io/DirectX-Specs/d3d/RelaxedCasting.html を参照してください(なお、QRhi では、テクスチャには常に完全型指定されたフォーマットが使用されることに注意してください)。この列挙型値は Qt 6.8 で導入されました。
QRhi::ResolveDepthStencil43マルチサンプル深度または深度-ステンシルテクスチャの解決がサポートされていることを示します。そうでない場合、setting a depth resolve texture は機能せず、使用を避ける必要があります。Direct 3D 11および12は深度/深度-ステンシル形式の解決をサポートしていないため、これらのバージョンではこの機能は決してサポートされません。 Vulkan 1.0 には、深度・ステンシルアタッチメントの解決を要求する API がありません。したがって、Vulkan では、この機能は Vulkan 1.2 以降、および適切な拡張機能が実装されている 1.1 実装でのみサポートされます。 この機能は、OpenXR が提供する深度テクスチャ(XR_KHR_composition_layer_depth)へのレンダリング時など、マルチサンプルではない深度テクスチャへの解決が必要となる稀なケースに備えて提供されています。この列挙型値は Qt 6.8 で導入されました。
QRhi::VariableRateShading44描画ごと(パイプラインごと)の可変レートシェーディングがサポートされていることを示します。サポートされていると報告された場合、QRhiCommandBuffer::setShadingRate() は機能し、フラグでQRhiGraphicsPipeline::UsesShadingRate を宣言したQRhiGraphicsPipeline オブジェクトに対して効果を発揮します。QRhi::supportedShadingRates() を呼び出して、どのレートがサポートされているかを確認してください。(1x1 は常にサポートされており、その他の一般的な値としては 2x2、1x2、2x1、2x4、4x2、4x4 があります)。 実行時に使用される実装およびGPUがVRSをサポートしていることを前提として、この機能はDirect 3D 12およびVulkanでサポートされることが期待されます。この列挙型値はQt 6.9で導入されました。
QRhi::VariableRateShadingMap45シェーディングレートの画像ベースの指定が可能であることを示します。「画像」は必ずしもテクスチャである必要はなく、実行時の基盤となるバックエンドやグラフィックスAPIによっては、ネイティブな3D APIオブジェクトである場合もあります。 実際には、GPUがVRSをサポートできるほど最新のものであることを前提として、この機能はDirect 3D 12、Vulkan、およびMetalでサポートされることが期待されます。D3D12/Vulkanスタイルの画像ベースのVRSがサポートされているかどうかを確認するには、代わりにVariableRateShadingMapWithTextureを使用してください。 この機能がサポートされていると報告された場合、2つの可能性があります。VariableRateShadingMapWithTextureもtrueである場合、QRhiShadingRateMap は、QRhiTexture 引数を取るcreateFrom()オーバーロードを介してQRhiTexture オブジェクトを消費します。 VariableRateShadingMapWithTextureがfalseの場合、QRhiShadingRateMap は他の種類のネイティブオブジェクト(例えば、Metalの場合はMTLRasterizationRateMapなど)を使用します。この場合は、NativeShadingRateMapを引数とするcreateFrom()のオーバーロードを使用してください。この列挙値はQt 6.9で導入されました。
QRhi::VariableRateShadingMapWithTexture46通常のテクスチャを介した、画像ベースのシェーディングレートの指定がサポートされていることを示します。実際には、Direct 3D 12 および Vulkan でサポートされる可能性があります。この列挙値は Qt 6.9 で導入されました。
QRhi::PerRenderTargetBlending47レンダリングターゲットごとのブレンディングがサポートされていることを示します。つまり、MRTフレームバッファ内の異なるレンダリングターゲットで異なるブレンディングモードを設定できます。実際には、OpenGL ESを除くすべての環境でサポートされていると予想されます。OpenGL ESでは、GLES 3.2実装でのみ利用可能です。この列挙型値はQt 6.9で導入されました。
QRhi::SampleVariables48gl_SampleID、gl_SamplePosition、gl_SampleMaskIn、および gl_SampleMask 変数がフラグメントシェーダーで使用可能であることを示します。 実際には、OpenGL ES を除くすべての環境でサポートされていると見込まれます。OpenGL ES では、GLES 3.2 実装でのみ利用可能です。この列挙型値は Qt 6.9 で導入されました。
QRhi::InstanceIndexIncludesBaseInstance49gl_InstanceIndex の値にベースインスタンス(描画呼び出しにおけるfirstInstance 引数)が含まれていることを示します。この機能がサポートされていないが、BaseInstanceがサポートされている場合、gl_InstanceIndex は常に0から始まり、ベース値からは始まらないことを示します。 実際には、現時点では Direct 3D 11 および 12 でこの状況になります。Vulkan および Metal では、この機能は常にサポートされていると報告されることが予想されます。この列挙型値は Qt 6.11 で導入されました。
QRhi::DepthClamp (since Qt 6.11)50深度クランプの有効化がサポートされていることを示します。サポートされていないと報告された場合(OpenGL ES、関連する拡張機能がない OpenGL 3.2 以前のバージョン、および iOS シミュレータ上の Metal ではこの状態になります)、引数に `true ` を指定して `QRhiGraphicsPipeline::setDepthClamp()` を呼び出しても効果はありません。
QRhi::DrawIndirect (since Qt 6.12)51drawIndirect() およびdrawIndexedIndirect() 関数が利用可能であることを示します。実際には、OpenGL ES 3.1 未満を除き、あらゆる環境でサポートされていると見込まれます。
QRhi::DrawIndirectMulti (since Qt 6.12)52drawIndirect() およびdrawIndexedIndirect() において、バックエンドが drawCount > 1 をネイティブにサポートしていることを示します。そうでない場合、RHI によって CPU 上で複数の描画呼び出しが発行されます。実際には、Vulkan 1.1 以降、OpenGL 4.3 以降、および D3D12 でサポートされていると予想されます。
QRhi::ShaderDrawParameters (since Qt 6.12)53gl_BaseInstance 、gl_BaseVertex 、およびgl_DrawID の組み込み変数がシェーダーで使用可能であることを示します。実際には、Vulkan 1.1 以降、およびデスクトップ版 OpenGL 4.6 またはGL_ARB_shader_draw_parameters でサポートされていると予想されます。

enum QRhi::Flag
flags QRhi::Flags

有効にするべき特別な機能について説明します。

定数値説明
QRhi::EnableDebugMarkers1 << 0デバッグマーカーグループを有効にします。これを設定しない場合、外部の GPU デバッグツールでデバッググループやカスタムリソース名を表示するなどのフレームデバッグ機能は利用できず、QRhiCommandBuffer::debugMarkBegin() などの関数は何もしない(no-op)状態になります。パフォーマンスにわずかな影響が生じる可能性があるため、本番ビルドでの有効化は避けてください。QRhi::DebugMarkers 機能がサポートされていると報告されていない場合は、効果はありません。
QRhi::EnableTimestamps1 << 3GPU タイムスタンプの収集を有効にします。設定されていない場合、QRhiCommandBuffer::lastCompletedGpuTime() は常に 0 を返します。基盤となるグラフィックス API によっては、わずかな追加処理(例:タイムスタンプの照会)が発生する可能性があるため、必要な場合のみ有効にしてください。QRhi::Timestamps 機能がサポートされていると報告されていない場合は、効果はありません。
QRhi::PreferSoftwareRenderer1 << 1バックエンドが、CPU上でソフトウェアレンダリングを行うアダプタまたは物理デバイスを優先的に選択すべきであることを示します。たとえば、Direct3Dでは通常、DXGI_ADAPTER_FLAG_SOFTWARE に対応した「Basic Render Driver」アダプタが利用可能です。このフラグを設定すると、他のバックエンド固有の手段によって特定のアダプタが強制されていない限り、バックエンドに対して他のどのアダプタよりもそのアダプタを選択するよう要求します。 Vulkan では、これはVK_PHYSICAL_DEVICE_TYPE_CPU を持つ物理デバイスを優先することに対応します。利用できない場合、またはアダプタ/デバイスがソフトウェアベースであるかどうかを判断できない場合、このフラグは無視されます。また、アダプタ/デバイスの列挙に関する概念や手段を持たないグラフィックス API においても、このフラグは無視される場合があります。
QRhi::EnablePipelineCacheDataSave1 << 2該当する場合、パイプラインキャッシュの内容を取得できるようにします。設定されていない場合、pipelineCacheData() は常に空のブロブを返します。パイプラインキャッシュ内容の取得および復元がサポートされていないバックエンドでは、このフラグは効果を持たず、シリアライズされたキャッシュデータは常に空になります。 一部のバックエンドでは、関連するデータ構造を維持するためのコストが決して小さくないため、このフラグはオプトイン方式を採用しています。Vulkan では、この機能は VkPipelineCache、vkGetPipelineCacheData、および VkPipelineCacheCreateInfo::pInitialData に直接対応しています。 Direct3D 11 には実際のパイプラインキャッシュは存在しませんが、HLSL から DXBC へのコンパイル結果は保存されており、このメカニズムを介してシリアライズ/デシリアライズが可能です。 これにより、オフラインで事前コンパイルされたバイトコードではなく、HLSLソースを伴うシェーダーについて、アプリケーションの今後の実行時に時間のかかる D3DCompile() をスキップできるようになります。HLSLソースのコンパイルが頻繁に行われる場合、これにより起動時間や読み込み時間が大幅に短縮されます。 OpenGL では、(ドライバがサポートしている場合)シェーダプログラムのバイナリを取得して読み込むことで、「パイプラインキャッシュ」がシミュレートされます。 Qt OpenGL では、シェーダー/プログラムバイナリ用の追加のディスクベースのキャッシュメカニズムが提供されています。プログラムバイナリを複数のキャッシュに保存することは合理的ではないため、このフラグが設定されている場合は、それらへの書き込みが無効になる場合があります。
QRhi::SuppressSmokeTestWarnings1 << 4これは、これが関連するバックエンドにおいて、特定の致命的ではないQRhi::create()の失敗が、qWarning()の呼び出しを引き起こさないことを示します。たとえば、D3D11の場合、このフラグを指定すると、QRhi::create()の失敗によって表示される多くの警告メッセージが、代わりに一般的に使用されるqt.rhi.general ロギングカテゴリの下でデバッグ出力として分類されるようになります。 これは、フォールバックロジック(つまり、最初のcreate() の呼び出しが失敗した際に出力される無条件の警告を隠すために、異なるフラグセット(例:PreferSoftwareRenderer)を使用してcreate() の呼び出しを再試行する)を備えたエンジン(Qt Quick など)で使用できます。

Flags 型はQFlags<Flag> の typedef です。これは、Flag 値の OR 組み合わせを格納します。

enum QRhi::FrameOpResult

ソフト障害が発生する可能性のある演算の結果について説明します。

定数値説明
QRhi::FrameOpSuccess0成功
QRhi::FrameOpError1未指定のエラー
QRhi::FrameOpSwapChainOutOfDate2スワップチェーンが内部的に不整合な状態になっています。後で操作(例:beginFrame()) を再実行することで回復できる場合があります。
QRhi::FrameOpDeviceLost3グラフィックスデバイスが失われました。ネイティブグラフィックスリソースを基盤とするすべてのオブジェクトを解放し、再初期化した後、操作(例:beginFrame())を再度実行することで、この状態を回復できる場合があります。isDeviceLost() を参照してください。

enum QRhi::Implementation

QRhi インスタンスでどのグラフィックスAPI固有のバックエンドが使用されるかを指定します。

定数値
QRhi::Null0
QRhi::Vulkan1
QRhi::OpenGLES22
QRhi::D3D113
QRhi::D3D125
QRhi::Metal4

enum QRhi::ResourceLimit

クエリのリソース制限について説明します。

定数値説明
QRhi::TextureSizeMin1テクスチャの最小幅と高さ。通常は 1 です。最小テクスチャサイズは適切に処理されます。つまり、サイズが空のテクスチャを作成しようとすると、代わりに最小サイズのテクスチャが作成されます。
QRhi::TextureSizeMax2テクスチャの最大幅および高さ。これはグラフィックス API によって異なり、場合によってはプラットフォームや実装によっても異なります。通常、値は 4096 ~ 16384 の範囲です。これより大きなテクスチャを作成しようとすると、失敗すると予想されます。
QRhi::MaxColorAttachments3複数のレンダリングターゲットがサポートされている場合、QRhiTextureRenderTarget に対するカラーアタッチメントの最大数。MRTがサポートされていない場合、値は1になります。それ以外の場合は通常8ですが、OpenGLが規定する最小値は4であり、一部のOpenGL ES実装ではその値しか提供されない点に注意してください。
QRhi::FramesInFlight4バックエンドが「処理中」として保持できるフレーム数。VulkanやMetalのようなバックエンドの場合、新しいフレームを開始する際に、CPUがGPUよりN - 1 フレーム先を行っている(フレーム番号current ~N で送信されたコマンドバッファがまだ完了していないため)ことが判明した場合は、QRhi がブロックする責任を負います。 値 N はここから返されるもので、通常は 2 です。これは、グラフィックス API を直接使用してレンダリングを行うアプリケーションに関連する可能性があります。そのようなレンダリングコードでは、QRhi バックエンド自体と同様に、バッファなどのリソースに対して(値が 2 の場合)ダブルバッファリングを実行したい場合があるためです。 現在のフレームスロットインデックス(0、1、…、N-1と連番で、その後ループする値)は、QRhi::currentFrameSlot() から取得できます。グラフィックスAPIがコマンド送信プロセスに対してこのような低レベルの制御を提供しないバックエンドの場合、この値は1になります。 なお、この値が1の場合でもパイプライン処理が行われる可能性があることに注意してください(D3D11などの一部のバックエンドは、例えばパイプラインを停止させないユニフォームバッファの更新戦略を使用するなどして、これを有効にしようと設計されています)。ただし、その場合はQRhi によって制御されないため、このAPIには反映されません。
QRhi::MaxAsyncReadbackFrames5starting a new frame の呼び出し時に、非同期のテクスチャまたはバッファの読み出しが確実に完了するまでの、submitted フレーム数(読み出しを含むフレームを含む)。
QRhi::MaxThreadGroupsPerDimension6ディスパッチ可能なコンピュート・ワークグループ/スレッドグループの最大数。実質的には、QRhiCommandBuffer::dispatch() の引数の最大値となります。通常は 65535 です。
QRhi::MaxThreadsPerThreadGroup7単一のローカルワークグループにおける呼び出しの最大数。別の言い方をすれば、スレッドグループ内のスレッドの最大数です。 実質的には、コンピュートシェーダーにおけるlocal_size_x 、local_size_y 、およびlocal_size_z の積の最大値となります。一般的な値は 128、256、512、1024、または 1536 です。 OpenGL ESとVulkanの両方において、実装に必要な最小値として128のみが規定されている点に注意してください。Vulkanでは珍しいですが、モバイル/組み込みデバイス向けのOpenGL ES 3.1実装の中には、仕様で義務付けられた最小値のみをサポートしているものがあります。
QRhi::MaxThreadGroupX8X 方向におけるワークグループ/スレッドグループの最大サイズ。実質的には、コンピュートシェーダーにおける `local_size_x ` の最大値に相当します。通常は 256 または 1024 です。
QRhi::MaxThreadGroupY9Y次元におけるワークグループ/スレッドグループの最大サイズ。実質的には、コンピュートシェーダーにおけるlocal_size_y の最大値に相当します。通常は256または1024です。
QRhi::MaxThreadGroupZ10Z次元におけるワークグループ/スレッドグループの最大サイズ。実質的には、コンピュートシェーダーにおけるlocal_size_z の最大値に相当します。通常は64または256です。
QRhi::TextureArraySizeMax11テクスチャ配列の最大サイズ。通常、256~2048の範囲です。これより多くの要素でcreate a texture array を実行しようとすると、失敗する可能性が高いです。
QRhi::MaxUniformBufferRange12ユニフォームバッファからシェーダに対して一度に公開できるバイト数。OpenGL ES 2.0 および 3.0 の実装では、これが 3584 バイト(4 成分、各成分 32 ビットのベクトル 224 本分)まで低くなる場合があります。 それ以外の場合、値は通常 16384(1024 個の vec4)または 65536(4096 個の vec4)です。
QRhi::MaxVertexInputs13頂点シェーダーへの入力属性の数。QRhiVertexInputAttribute 内の位置は、[0, MaxVertexInputs-1] の範囲内である必要があります。OpenGL ES 2.0 では、この値は 8 まで低くなる場合があります。それ以外の環境では、一般的な値は 16、31、または 32 です。
QRhi::MaxVertexOutputs14頂点シェーダーからの出力の最大数(4成分ベクトルのout 変数)。OpenGL ES 2.0では8まで、OpenGL ES 3.0および一部のMetalデバイスでは15まで可能です。それ以外の場合、一般的な値は32です。
QRhi::ShadingRateImageTileSize15シェーディングレートテクスチャのタイルサイズ。QRhi::VariableRateShadingMapWithTexture 機能がサポートされていない場合は0。 それ以外の場合は、例えば16x16のタイルサイズを示す16などの値になります。(R8UI)シェーディングレートテクスチャの各バイトは、16x16ピクセルのタイルに対するシェーディングレートを定義します。詳細については、QRhiShadingRateMap を参照してください。

メンバ関数のドキュメント

[noexcept] QRhi::~QRhi()

デストラクタ。バックエンドを破棄し、リソースを解放します。

void QRhi::addCleanupCallback(const QRhi::CleanupCallback &callback)

QRhi が破棄された際に呼び出されるcallback を登録します。

このコールバックは、グラフィックリソースがまだ利用可能な状態で実行されるため、アプリケーションはQRhi に属するQRhiResource インスタンスを適切に解放することができます。これは、cache 型のオブジェクトに格納されたリソースのライフサイクルを管理する際に特に有用です。この種のオブジェクトのキャッシュには、QRhiResourceまたはQRhiResourceを含むオブジェクトが保持されています。

~QRhi()も参照してください 。

void QRhi::addCleanupCallback(const void *key, const QRhi::CleanupCallback &callback)

QRhi が破棄される際に呼び出されるcallback を登録します。このオーバーロードは、指定されたコールバックが1回だけ登録(および呼び出し)されることを保証するために使用される不透明ポインタkey を受け取ります。

これはオーバーロードされた関数です。

removeCleanupCallback()も参照してください 。

QRhi::Implementation QRhi::backend() const

このQRhi のバックエンド型を返します。

const char *QRhi::backendName() const

このQRhi のバックエンド型を文字列として返します。

[static] const char *QRhi::backendName(QRhi::Implementation impl)

バックエンド `impl` の識別名を返します。通常、これは使用中の 3D API の名前になります。

QRhi::FrameOpResult QRhi::beginFrame(QRhiSwapChain *swapChain, QRhi::BeginFrameFlags flags = {})

swapChain の次に利用可能なバッファを対象として、新しいフレームを開始します。

フレームは、リソースの更新と、1つ以上のレンダリングパスおよび演算パスで構成されます。

flags は、特定の特殊なケースを示すことがあります。

スワップチェーンを使用してQWindow にレンダリングする大まかな手順は次のとおりです。

  • スワップチェーンを作成します。
  • サーフェスのサイズが以前と異なる場合は、QRhiSwapChain::createOrResize() を呼び出します。
  • QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed 上でQRhiSwapChain::destroy()を呼び出します。
  • その後、各フレームごとに:
    beginFrame(sc);
    updates = nextResourceUpdateBatch();
    updates->...
    QRhiCommandBuffer *cb = sc->currentFrameCommandBuffer();
    cb->beginPass(sc->currentFrameRenderTarget(), colorClear, dsClear, updates);
    ...
    cb->endPass();
    ... // more passes as necessary
    endFrame(sc);

成功した場合はQRhi::FrameOpSuccess を返し、失敗した場合は別のQRhi::FrameOpResult 値を返します。これらのうちいくつかは、ソフトな「後で再試行」タイプのエラーとして扱う必要があります。QRhi::FrameOpSwapChainOutOfDate が返された場合、QRhiSwapChain::createOrResize()を呼び出してスワップチェーンのサイズ変更または更新を行う必要があります。 その後、アプリケーションは新しいフレームの生成を試みる必要があります。QRhi::FrameOpDeviceLost が返された場合は、グラフィックスデバイスが失われたことを意味しますが、QRhi 自体を含むすべてのリソースを解放し、その後すべてのリソースを再作成することで回復できる場合もあります。詳細については、isDeviceLost()を参照してください。

endFrame()、beginOffscreenFrame()、およびisDeviceLost()も参照してください 。

QRhi::FrameOpResult QRhi::beginOffscreenFrame(QRhiCommandBuffer **cb, QRhi::BeginFrameFlags flags = {})

新しいオフスクリーンフレームを開始します。cb でレンダリングコマンドを記録するのに適したコマンドバッファを提供します。flags は、beginFrame()と同様に、特定の特殊なケースを示すために使用されます。

注: *cb に格納されたQRhiCommandBuffer は 、呼び出し元が所有するものではありません。

スワップチェーンを使用しないレンダリングも可能です。典型的な使用例は、完全にオフスクリーンのアプリケーションでの使用です。例えば、ウィンドウを表示することなく、レンダリングと読み取りを繰り返して画像シーケンスを生成する場合などです。

オンスクリーン・アプリケーションでの使用(つまり、beginFrame 、endFrame 、beginOffscreenFrame、endOffscreenFrame 、beginFrame など)も可能です。

texture やbuffer による読み戻しがスケジュールされている場合、オフスクリーンフレームでは、GPU が前のフレームを処理している間に CPU が別のフレームを生成してしまう可能性を排除します。これにより、読み戻しがスケジュールされていれば、endOffscreenFrame() が返った時点で結果が確実に利用可能になるという副次的な効果があります。 一方、スワップチェーンをターゲットとするフレームの場合はそうではありません。そこではGPUの利用効率が向上する可能性がありますが、endFrame()はendOffscreenFrame()とは異なり、その時点でリードバックの結果が利用可能であることを保証しないため、リードバック操作を扱う際にはアプリケーション側でより細心の注意が必要です。

スワップチェーンを使用せずにフレームをレンダリングし、その後フレームの内容を読み戻す処理の骨子は、次のようなものになります:

QRhiReadbackResult rbResult;
QRhiCommandBuffer *cb;
rhi->beginOffscreenFrame(&cb);
cb->beginPass(rt, colorClear, dsClear);
// ...
u = nextResourceUpdateBatch();
u->readBackTexture(rb, &rbResult);
cb->endPass(u);
rhi->endOffscreenFrame();
// image data available in rbResult

endOffscreenFrame() およびbeginFrame()も参照してください 。

QMatrix4x4 QRhi::clipSpaceCorrMatrix() const

アクティブなQRhi バックエンドに関係なく、アプリケーションがOpenGL向けの頂点データや透視投影行列(QMatrix4x4::perspective()によって生成されるものなど)を引き続き使用できるようにするための行列を返します。

一般的なレンダラーでは、単に `mvp` ではなく `this_matrix * mvp ` を使用することで、実行時にどのバックエンド(ひいてはどのグラフィックス API)が使用されるかを考慮することなく、Y 軸が上向きの頂点データや深度範囲 0 ~ 1 のビューポートを使用できるようになります。 これにより、isYUpInNDC() やisClipDepthZeroToOne() に基づく分岐を回避できます(ただし、特定の高度なグラフィックス技術を実装する際には、依然としてそのようなロジックが必要になる場合があります)。

Vulkanの観点からのこのトピックに関する議論については、こちらのページを参照してください。

[static] QRhi *QRhi::create(QRhi::Implementation impl, QRhiInitParams *params, QRhi::Flags flags, QRhiNativeHandles *importDevice, QRhiAdapter *adapter)

impl で指定されたグラフィックス API のバックエンドと、指定されたflags を持つ新しいQRhi インスタンスを返します。関数が失敗した場合は、nullptr を返します。

params は、`QRhiInitParams`のバックエンド固有のサブクラス(例:QRhiVulkanInitParams 、QRhiMetalInitParams 、QRhiD3D11InitParams 、QRhiD3D12InitParams 、QRhiGles2InitParams など)のいずれかのインスタンスを指している必要があります。`QRhi`の作成例については、これらのクラスを参照してください。

QRhi 設計上、いかなるフォールバックロジックも実装されていません。指定されたAPIを初期化できない場合、create()は失敗し、バックエンドによってデバッグ出力に警告が出力されます。ただし、QRhi のクライアント(例:Qt Quick )は、プラットフォームに応じて、要求されたものとは異なるAPIにフォールバックすることを可能にする追加のロジックを提供する場合があります。 単に、後ほど `create()` を呼び出した際に初期化が成功するかどうかをテストしたいだけの場合、`create()` ではなく `probe()` を使用することを推奨します。これは、一部のバックエンドでは、インフラストラクチャの完全な初期化を行う `create()` と比べて、` ()` の方がプローブ処理をより軽量に実装できるためです。また、QRhi のインスタンスがすぐに破棄されてしまう場合、`create()` はリソースの無駄遣いとなります。

importDevice これにより、QRhi が独自のグラフィックスデバイスを作成することなく、既存のグラフィックスデバイスを使用できるようになります。nullでない場合、このパラメータはQRhiNativeHandles のサブクラスのいずれか(QRhiVulkanNativeHandles 、QRhiD3D11NativeHandles 、QRhiD3D12NativeHandles 、QRhiMetalNativeHandles 、QRhiGles2NativeHandles )のインスタンスを指す必要があります。具体的な詳細や意味論は、バックエンドおよび基盤となるグラフィックスAPIによって異なります。

adapter でQRhiAdapter を指定することは、QRhiVulkanNativeHandles を介してVkPhysicalDevice を渡す方法や、QRhiD3D12NativeHandles を介してアダプタLUIDを渡す方法に代わる、透過的でAPIを横断する代替手段となります。adapter の所有権は取得されません。このアプローチの詳細については、enumerateAdapters()を参照してください。

注: importDevice とadapter を同時に指定することはできません。

probe()も参照してください 。

[static] QRhi *QRhi::create(QRhi::Implementation impl, QRhiInitParams *params, QRhi::Flags flags = {}, QRhiNativeHandles *importDevice = nullptr)

create(impl,params,flags,importDevice,nullptr) と同等です。

これはオーバーロードされた関数です。

int QRhi::currentFrameSlot() const

フレームの記録中に、現在のフレームスロットのインデックスを返します。アクティブなフレーム外で呼び出された場合(つまり、isRecordingFrame()がfalse の場合)、未定義となります。

VulkanやMetalなどのバックエンドでは、新しいフレームを開始する際に、CPUがGPUよりFramesInFlight - 1 フレーム先を行っていることが判明した場合(フレーム番号current ~FramesInFlight で送信されたコマンドバッファがまだ完了していないため)、QRhi バックエンドがブロックする責任を負います。

フレーム間で変化しやすいリソース(例えば、タイプQRhiBuffer::Dynamic のQRhiBuffer を裏付けするネイティブバッファオブジェクトなど)は、複数のバージョンが存在します。これにより、前のフレームがまだ処理中の間に送信される可能性のある各フレームは、独自のコピーを使用して動作するため、フレームの準備時にパイプラインを停止させる必要がなくなります。 (GPU上でまだ使用中のリソースの内容には手を加えるべきではありませんが、単に前のフレームが終了するのを常に待っているだけでは、GPUの利用率が低下し、最終的にはパフォーマンスと効率が低下してしまいます。)

概念的には、これは一部のC++コンテナやその他の型で使用される「コピー・オン・ライト(copy-on-write)」方式に多少似ています。また、OpenGLやDirect 3D 11の実装が、特定の種類のオブジェクトに対して内部的に実行している処理にも類似している可能性があります。

実際には、このような二重(または三重)バッファリングリソースは、Vulkan、Metal、および類似のQRhi バックエンドにおいて、QRhiResource の背後に固定数のネイティブリソース(VkBufferなど)slots を配置することで実現されています。 これにより、0、1、…、FramesInFlight-1と連番するフレームスロットインデックスで参照可能となり、その後インデックスはループします。

これらすべては、QRhi のユーザーに対して透過的に管理されます。ただし、グラフィックス API を使用して直接レンダリングを行うアプリケーションでは、独自のグラフィックスリソースに対して同様のダブルバッファリングやトリプルバッファリングを実行したい場合があります。 これは、処理中のフレームの最大数(resourceLimit() を通じて取得可能)と現在のフレーム(スロット)インデックス(この関数によって返される)の値を把握することで、最も簡単に実現できます。

isRecordingFrame()、beginFrame()、およびendFrame()も参照してください 。

QRhiDriverInfo QRhi::driverInfo() const

正常に初期化されたこのQRhi インスタンスで使用されているグラフィックスデバイスのメタデータを返します。

QRhi::FrameOpResult QRhi::endFrame(QRhiSwapChain *swapChain, QRhi::EndFrameFlags flags = {})

swapChain 上で、前回のbeginFrame() で開始されたフレームを終了、コミット、および提示します。

ダブル(またはトリプル)バッファリングは、QRhiSwapChain およびQRhi によって内部的に管理されます。

flags オプションで、特定の動作を変更するために使用できます。QRhi::SkipPresent を渡すと、Presentコマンドのキューへの追加やswapBuffersの呼び出しがスキップされます。

成功した場合はQRhi::FrameOpSuccess を返し、失敗した場合は別のQRhi::FrameOpResult の値を返します。これらのうちいくつかは、ソフトな「後で再試行」タイプのエラーとして扱う必要があります。QRhi::FrameOpSwapChainOutOfDate が返された場合、QRhiSwapChain::createOrResize() を呼び出してスワップチェーンのサイズ変更または更新を行う必要があります。 その後、アプリケーションは新しいフレームの生成を試みる必要があります。QRhi::FrameOpDeviceLost が返された場合は、グラフィックスデバイスが失われたことを意味しますが、QRhi 自体を含むすべてのリソースを解放し、その後すべてのリソースを再作成することで回復できる場合もあります。詳細については、isDeviceLost()を参照してください。

beginFrame() およびisDeviceLost()も参照してください 。

QRhi::FrameOpResult QRhi::endOffscreenFrame(QRhi::EndFrameFlags flags = {})

オフスクリーンフレームを終了、送信し、場合によってはその完了を待機します。

endFrame() とは異なり、この関数は、アクティブなバッファまたはテクスチャのリードバックがある場合、GPU 側の処理が完了するまでブロックして待機します。

flags は現在使用されていません。

beginOffscreenFrame()も参照してください 。

[static, since 6.10] QRhi::AdapterList QRhi::enumerateAdapters(QRhi::Implementation impl, QRhiInitParams *params, QRhiNativeHandles *nativeHandles = nullptr)

存在するアダプタ(物理デバイス)のリストを返します。指定されたグラフィックスAPIでそのような制御が利用できない場合は、空のリストを返します。

このレベルの制御が利用できないバックエンドの場合、返されるリストは常に空になります。したがって、リストが空であることは、システムにグラフィックスデバイスが存在しないことを示すものではなく、どのデバイスを使用するかを選択するためのきめ細かな制御が利用できないことを意味します。

Direct 3D 11、Direct 3D 12、および Vulkan 用のバックエンドは、アダプタの列挙を完全にサポートしていると予想されます。その他のバックエンドではサポートされていない場合があります。 バックエンドは `impl` で指定されます。この関数から返される `QRhiAdapter ` は、同じ `impl` を持つ `create()` 呼び出しでのみ使用しなければなりません。一部の基盤となるAPIにはさらなる制限がある場合があり、特にVulkanでは、`QRhiAdapter ` が `QVulkanInstance ` (VkInstance) に指定されています。

呼び出し元は、リスト内のQRhiAdapter オブジェクトを破棄することが期待されます。info()のクエリを除き、これらのオブジェクトの唯一の目的は、create()、あるいはQt Quick などの上位レイヤーの対応する関数に渡されることです。

Vulkan向けに特別に作成された以下のコードスニペットは、利用可能な物理デバイスを列挙し、選択したデバイスに対してQRhi の作成を要求する方法を示しています。これは実際には、QRhiVulkanNativeHandles を経由してVkPhysicalDevice をcreate()に渡すことと同等ですが、アプリケーション側でAPI固有のコードを記述する量を減らすことができます:

QRhiVulkanInitParams initParams;
initParams.inst= &vulkanInstance;
QRhi::AdapterList adapters=QRhi::enumerateAdapters(QRhi::Vulkan, &initParams);
QRhiAdapter*chosenAdapter =nullptr;
for(QRhiAdapter*adapter: adapters) {
    if(looksGood(adapter->info())) {
        chosenAdapter=adapter;
        break;
    }
}
QRhi*rhi =QRhi::create(QRhi::Vulkan, &initParams,{},nullptr,chosenAdapter);
qDeleteAll(adapters);

params の引数指定は、基盤となるグラフィックス API の設計上の理由により必須となっています。特に Vulkan の場合、QVulkanInstance を指定する必要があります。これは、これを指定しないと列挙処理が行えないためです。バックエンド固有のparams にあるその他のフィールドは、この関数では実際には使用されません。

nativeHandles はオプションです。指定する場合、create()と同様に、有効なQRhiD3D11NativeHandles 、QRhiD3D12NativeHandles 、またはQRhiVulkanNativeHandles でなければなりません。ただし、create()とは異なり、物理デバイス(Vulkanの場合)またはアダプタLUID(D3Dの場合)のフィールドのみが使用され、その他のフィールドはすべて無視されます。これにより、結果を特定のアダプタに限定することができます。 この場合、返されるリストには1つまたは0つの要素が含まれます。

前のコードスニペットでは、looksGood() 関数の実装において、Windows のアダプタ LUID や Vulkan の VkPhysicalDevice など、実際のアダプタ/物理デバイスの識別情報に基づくプラットフォーム固有のフィルタリングを行うことができない点に注意してください。これは、QRhiDriverInfo にプラットフォーム固有のデータが含まれていないためです。 その代わりに、nativeHandles を使用して、enumerateAdapters() 内部ですでにフィルタリングされた結果を取得してください。

Direct 3D 12 を例とした以下の 2 つのコードスニペットは、実際には同等です:

// Qt 6.10 以降の enumerateAdapters ベースのアプローチ
QRhiD3D12InitParams initParams;
QRhiD3D12NativeHandles nativeHandles;
nativeHandles.adapterLuidLow=luid.LowPart;// どこからか LUID を取得し、それを Qt に渡す
nativeHandles.adapterLuidHigh=luid.HighPart;
QRhi::AdapterList adapters=QRhi::enumerateAdapters(QRhi::D3D12, &initParams, &nativeHandles);
if(adapters.isEmpty()) {qWarning("要求されたアダプタが見つかりませんでした");}
QRhi*rhi =QRhi::create(QRhi::D3D12, &initParams,{},nullptr,adapters[0]);
qDeleteAll(adapters);
// traditional approach, more lightweight
QRhiD3D12InitParams initParams;
QRhiD3D12NativeHandles nativeHandles;
nativeHandles.adapterLuidLow = luid.LowPart; // retrieved a LUID from somewhere, now pass it on to Qt
nativeHandles.adapterLuidHigh = luid.HighPart;
QRhi *rhi = QRhi::create(QRhi::D3D12, &initParams, {}, &nativeHandles, nullptr);

この関数は Qt 6.10 で導入されました。

create()も参照してください 。

QRhi::FrameOpResult QRhi::finish()

グラフィックスキュー上の処理(該当する場合)が完了するのを待ち、その後、リードバックの完了やリソースの解放など、すべての遅延処理を実行します。フレームの内外で呼び出すことができますが、パスの内部では呼び出すことはできません。フレーム内での呼び出しは、コマンドバッファ上のすべての処理をサブミットすることを意味します。

注: この関数の使用は避けてください 。この関数が必要となる可能性があるケースとしては、スワップチェーンベースのフレームでキューに登録されたリードバックの結果を、特定の固定された時点で必要とし、その結果を待機したい場合などが挙げられます。

bool QRhi::isClipDepthZeroToOne() const

基となるグラフィックスAPIがクリップ空間で深度範囲 [0, 1] を使用している場合、true を返します。

実際には、OpenGL のみがfalse を返します。これは、OpenGL が投影後の深度範囲 [-1, 1] を使用しているためです。(glDepthRange() によって制御される NDC からウィンドウへのマッピングと混同しないでください。glDepthRange() は、QRhiViewport によって上書きされない限り、範囲 [0, 1] を使用します。) 一部の OpenGL バージョンでは、glClipControl() を使用してこれを変更することができましたが、QRhi の OpenGL バックエンドでは、OpenGL ES や OpenGL 4.5 より前のバージョンではこの関数が利用できないため、この関数は使用されていません。

注: clipSpaceCorrMatrix() は、返される行列にこの調整を反映しています。 したがって、QRhi の多くのユーザーは、投影行列にclipSpaceCorrMatrix()を前乗算する以外に、特別な措置を講じる必要はありません。ただし、一部のグラフィックス技術(特定の種類のシャドウマッピングなど)では、シェーダー内で深度値を処理・出力する必要があります。これらの場合は、この関数の値を適切に照会し、考慮に入れる必要があります。

bool QRhi::isDeviceLost() const

グラフィックデバイスが失われた場合、true を返します。

デバイスの喪失は、バックエンドや基盤となるネイティブ API に応じて、通常、beginFrame()、endFrame()、またはQRhiSwapChain::createOrResize() で検出されます。最も一般的なのはendFrame() です。これは、そこでプレゼンテーションが行われるためです。一部のバックエンドでは、デバイスの喪失によりQRhiSwapChain::createOrResize() も失敗する場合があります。 したがって、この関数は、以前の操作によってデバイスの喪失が検出されたかどうかを確認するための汎用的な手段として提供されています。

デバイスが失われた場合、QRhi を介してそれ以上の操作を行ってはなりません。代わりに、すべてのQRhi リソースを解放し、続いてQRhi を破棄する必要があります。その後、新しいQRhi の作成を試みることができます。成功した場合は、すべてのグラフィックスリソースを再初期化する必要があります。失敗した場合は、後で繰り返し試みてください。

単純なアプリケーションではデバイスの喪失を無視することもあるかもしれませんが、一般的に使用されるデスクトッププラットフォームでは、グラフィックスアダプタの物理的な取り外し、デバイスやドライバの無効化、グラフィックスドライバのアンインストールやアップグレード、あるいはグラフィックスデバイスのリセットにつながるエラーなど、さまざまな理由でデバイスの喪失が発生する可能性があります。 これらのうちいくつかは、ごく通常の状況下でも発生する可能性があります。例えば、グラフィックスドライバの新しいバージョンへのアップグレードは、Qtアプリケーションの実行中にいつでも発生し得る一般的な作業です。ユーザーは、アプリケーションがOpenGLやDirect3DのようなAPIを積極的に使用している場合でも、こうした状況に耐えられることを当然期待するでしょう。

Qt Quick など、QRhi を基盤として構築されたQt独自のフレームワークは、デバイスの喪失が発生した際に適切に対処し、必要な措置を講じることが期待されます。 テクスチャやバッファなどのグラフィックスリソースに関するデータがCPU側でまだ利用可能な場合、グラフィックスリソースはシームレスに再初期化されるため、アプリケーションレベルではそのようなイベントが全く気づかれない可能性があります。ただし、QRhi を直接扱うアプリケーションやライブラリは、デバイス喪失の状況を自らチェックし、対処する準備が整っていることが求められます。

注: OpenGLでは 、アプリケーションは `QOpenGLContext` に対して `QSurfaceFormat::ResetNotification ` を設定することで、コンテキストリセット通知を有効にする必要がある場合があります。これは通常、`QRhiGles2InitParams::format` でフラグを有効にすることで行われます。ただし、このフラグが設定されていない場合でも、一部のシステムではコンテキストリセットが発生する可能性があることに留意してください。

bool QRhi::isFeatureSupported(QRhi::Feature feature) const

指定されたfeature がサポートされている場合、true を返します。

bool QRhi::isRecordingFrame() const

アクティブなフレームが存在する場合、つまり、beginFrame()(またはbeginOffscreenFrame())が実行されたものの、それに対応するendFrame()(またはendOffscreenFrame())がまだ実行されていない場合に、trueを返します。

currentFrameSlot()、beginFrame()、およびendFrame()も参照してください 。

bool QRhi::isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags = {}) const

flags によって変更された指定されたテクスチャformat がサポートされている場合、true を返します。

このクエリは、非圧縮形式と圧縮形式の両方でサポートされています。

bool QRhi::isYUpInFramebuffer() const

基盤となるグラフィックスAPIにおいて、フレームバッファおよび画像内のY軸が上向きになっている場合、true を返します。

実際には、これは OpenGL の場合にのみ `true ` となります。

bool QRhi::isYUpInNDC() const

基盤となるグラフィックスAPIの正規化デバイス座標系において、Y軸が上向きになっている場合、true を返します。

実際には、これは Vulkan の場合のみ `false ` となります。

注: clipSpaceCorrMatrix() は、返される行列に(Y 軸を上向きにするための)対応する調整を含んでいます。

bool QRhi::makeThreadLocalNativeContextCurrent()

OpenGL の場合、これにより現在のスレッドで OpenGL コンテキストがアクティブになります。他のバックエンドでは、この関数は何の効果も持ちません。

この関数の呼び出しは、通常、Qtフレームワークのコードにおいて、QRhi がOpenGLバックエンドを使用している限り、アプリケーションによって提供される外部のOpenGLコードが、以前OpenGLを直接使用していたときと同様に動作し続けることを保証する必要がある場合に重要となります。

QOpenGLContext::makeCurrent()と同様に、失敗した場合はfalseを返します。操作が失敗した場合、isDeviceLost()を呼び出すことで、コンテキストが失われたかどうかを確認できます。この確認は、QOpenGLContext::isValid()による確認と同等です。

QOpenGLContext::makeCurrent() およびQOpenGLContext::isValid()も参照してください 。

[static] int QRhi::mipLevelsForSize(const QSize &size)

指定されたsize のミップレベル数を返します。

const QRhiNativeHandles *QRhi::nativeHandles()

バックエンドが使用するデバイス、コンテキスト、および類似の概念に対応する、バックエンド固有のネイティブオブジェクトのコレクションへのポインタを返します。

必要に応じて、QRhiVulkanNativeHandles 、QRhiD3D11NativeHandles 、QRhiD3D12NativeHandles 、QRhiGles2NativeHandles 、またはQRhiMetalNativeHandles にキャストしてください。

注: 返されるポインタやネイティブオブジェクトのいずれについても、所有権は移転されません 。

QRhiBuffer *QRhi::newBuffer(QRhiBuffer::Type type, QRhiBuffer::UsageFlags usage, quint32 size)

指定されたtype 、usage 、およびsize を持つ新しいバッファを返します。

注: usage とtype の組み合わせによっては、 すべてのバックエンドでサポートされていない場合があります。UsageFlags およびthe feature flags を参照してください。

注:バックエンドによっては 、size よりも大きなバッファを割り当てる場合があります。これはアプリケーションに対して透過的に行われるため、size の値に特別な制限はありません。QRhiBuffer::size() は、常にsize で要求された値を返します。

QRhiResource::destroy()も参照してください 。

QRhiComputePipeline *QRhi::newComputePipeline()

新しいコンピュートパイプラインリソースを返します。

注: コンピュートは 、Compute 機能がサポートされていると報告されている場合にのみ利用可能です。

「QRhiResource::destroy()」も参照してください 。

QRhiGraphicsPipeline *QRhi::newGraphicsPipeline()

新しいグラフィックス・パイプライン・リソースを返します。

QRhiResource::destroy()も参照してください 。

QRhiRenderBuffer *QRhi::newRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize, int sampleCount = 1, QRhiRenderBuffer::Flags flags = {}, QRhiTexture::Format backingFormatHint = QRhiTexture::UnknownFormat)

指定されたtype 、pixelSize 、sampleCount 、およびflags を持つ新しいレンダリングバッファを返します。

backingFormatHint がQRhiTexture::UnknownFormat 以外のテクスチャ形式に設定されている場合、バックエンドはこれに基づいて、レンダリングバッファのストレージバッキングに使用する形式を決定することがあります。

注: backingFormatHint が 重要になるのは、通常、マルチサンプリングや浮動小数点テクスチャ形式が関与する場合です。マルチサンプルQRhiRenderBuffer へのレンダリングを行い、その後非RGBA8のQRhiTexture に変換する場合、(一部のグラフィックスAPIでは)QRhiRenderBuffer のストレージバッキングとして、対応する非RGBA8形式が使用されることになります。 つまり、QRhiTexture::RGBA32F のようなフォーマットを渡すことが重要になります。なぜなら、バックエンドは通常デフォルトでQRhiTexture::RGBA8 を選択するため、QRhiTextureRenderTarget のカラーアタッチメントで RGBA8→RGBA32F のマルチサンプル解決を設定しようとすると、後でエラーが発生してしまうからです。

QRhiResource::destroy()も参照してください 。

QRhiSampler *QRhi::newSampler(QRhiSampler::Filter magFilter, QRhiSampler::Filter minFilter, QRhiSampler::Filter mipmapMode, QRhiSampler::AddressMode addressU, QRhiSampler::AddressMode addressV, QRhiSampler::AddressMode addressW = QRhiSampler::Repeat)

指定された拡大フィルタmagFilter 、縮小フィルタminFilter 、ミップマッピングモードmipmapMode 、およびアドレス指定(ラップ)モードaddressU 、addressV 、addressW を設定した新しいサンプラを返します。

注: mipmapMode をNone 以外の値に設定すると 、関連するすべてのミップレベル用の画像が、texture uploads を介して、またはこのサンプラーで使用されるテクスチャに対してgenerateMips()を呼び出すことによって提供されることになります。 関連するすべてのミップレベルに対するデータを持たないテクスチャでこのサンプラーを使用しようとすると、レンダリングエラーが発生します。その具体的な挙動は、基盤となるグラフィックスAPIによって異なります。

QRhiResource::destroy()も参照してください 。

QRhiShaderResourceBindings *QRhi::newShaderResourceBindings()

新しいシェーダーリソースバインディングコレクションリソースを返します。

QRhiResource::destroy()も参照してください 。

[since 6.9] QRhiShadingRateMap *QRhi::newShadingRateMap()

新しいシェーディングレートマップオブジェクトを返します。

この関数は Qt 6.9 で導入されました。

QRhiSwapChain *QRhi::newSwapChain()

新しいスワップチェーンを返します。

QRhiResource::destroy() およびQRhiSwapChain::createOrResize()も参照してください 。

QRhiTexture *QRhi::newTexture(QRhiTexture::Format format, const QSize &pixelSize, int sampleCount = 1, QRhiTexture::Flags flags = {})

指定されたformat 、pixelSize 、sampleCount 、およびflags を持つ新しい1Dまたは2Dテクスチャを返します。

1次元テクスチャでは、`flags` に `QRhiTexture::OneDimensional ` が設定されている必要があります。`pixelSize ` の高さが 0 の場合、この関数は暗黙的にこのフラグを設定します。

注: format は 、要求される内部および外部フォーマットを指定します。つまり、テクスチャにアップロードされるデータは互換性のあるフォーマットである必要がありますが、ネイティブのテクスチャは内部でこのフォーマットを使用する場合があります(ただし、少なくともOpenGLの場合、それが保証されるわけではありません)。

注:1D テクスチャは、実行時にOneDimensionalTextures 機能がサポートされていると報告された場合にのみ機能します。さらに、1D テクスチャのミップマップは、実行時にOneDimensionalTextureMipmaps 機能が報告された場合にのみ機能します。

QRhiResource::destroy()も参照してください 。

QRhiTexture *QRhi::newTexture(QRhiTexture::Format format, int width, int height, int depth, int sampleCount = 1, QRhiTexture::Flags flags = {})

指定されたformat 、width 、height 、depth 、sampleCount 、およびflags を持つ新しい1D、2D、または3Dテクスチャを返します。

このオーバーロードは、depth を指定できるため、3Dテクスチャに適しています。3Dテクスチャでは、flags でQRhiTexture::ThreeDimensional を設定する必要がありますが、このオーバーロードを使用する場合、depth が0より大きいときは常にこのフラグが暗黙的に設定されるため、省略可能です。1D、2D、およびキューブテクスチャの場合、depth は0に設定する必要があります。

1次元テクスチャの場合、flags でQRhiTexture::OneDimensional を設定する必要があります。height とdepth の両方が0の場合、このオーバーロードは暗黙的にこのフラグを設定します。

注:3D テクスチャは、実行時にThreeDimensionalTextures 機能がサポートされていると報告された場合にのみ機能します。

注:1D テクスチャは、実行時にOneDimensionalTextures 機能がサポートされていると報告された場合にのみ機能します。さらに、1D テクスチャのミップマップは、実行時にOneDimensionalTextureMipmaps 機能が報告された場合にのみ機能します。

これはオーバーロードされた関数です。

QRhiTexture *QRhi::newTextureArray(QRhiTexture::Format format, int arraySize, const QSize &pixelSize, int sampleCount = 1, QRhiTexture::Flags flags = {})

指定されたformat 、arraySize 、pixelSize 、sampleCount 、およびflags を持つ新しい1次元または2次元のテクスチャ配列を返します。

この関数は、flags 内のQRhiTexture::TextureArray を暗黙的に設定します。

1次元テクスチャ配列では、flags でQRhiTexture::OneDimensional が設定されている必要があります。pixelSize の高さが0の場合、この関数は暗黙的にこのフラグを設定します。

注: テクスチャ配列とテクスチャの配列を混同しないでください 。 この関数によって作成されたQRhiTexture は、シェーダー内の1次元または2次元の配列サンプリング関数で使用可能です。例:layout(binding = 1) uniform sampler2DArray texArr; 。テクスチャの配列とは、QRhiShaderResourceBinding::sampledTextures()を介してシェーダーに公開され、count > 1であるテクスチャのリストを指し、シェーダー内では次のように宣言されます:layout(binding = 1) uniform sampler2D textures[4];

注:これは 、実行時にTextureArrays 機能がサポートされていると報告された場合にのみ機能します。

注:1次元 テクスチャは、実行時にOneDimensionalTextures 機能がサポートされていると報告された場合にのみ機能します。さらに、1次元テクスチャのミップマップは、実行時にOneDimensionalTextureMipmaps 機能が報告された場合にのみ機能します。

newTexture()も参照してください 。

QRhiTextureRenderTarget *QRhi::newTextureRenderTarget(const QRhiTextureRenderTargetDescription &desc, QRhiTextureRenderTarget::Flags flags = {})

desc で指定されたカラーおよび深度/ステンシルアタッチメントを持ち、指定されたflags を持つ新しいテクスチャレンダリングターゲットを返します。

QRhiResource::destroy()も参照してください 。

QRhiResourceUpdateBatch *QRhi::nextResourceUpdateBatch()

操作のコピーを記録できる、利用可能な空のバッチを返します。

注: 戻り値は 呼び出し元が所有するものではなく、決して破棄してはなりません。代わりに、QRhiCommandBuffer::beginPass()、QRhiCommandBuffer::endPass()、またはQRhiCommandBuffer::resourceUpdate() に渡すか、そのバッチに対してQRhiResourceUpdateBatch::release() を呼び出すことで、バッチをプールに戻し、再利用できるようにします。

注: バッチインスタンスはそれ自体でデータを収集するだけで、いかなる操作も行わないため、beginFrame() やendFrame() の外部からも呼び出すことができます 。

録画中のフレームに縛られないため、例えば次のようなシーケンスも有効です:

rhi->beginFrame(swapchain);
QRhiResourceUpdateBatch *u = rhi->nextResourceUpdateBatch();
u->uploadStaticBuffer(buf, data);
// ... do not commit the batch
rhi->endFrame();
// u stays valid (assuming buf stays valid as well)
rhi->beginFrame(swapchain);
swapchain->currentFrameCommandBuffer()->resourceUpdate(u);
// ... draw with buf
rhi->endFrame();

警告: QRhi ごとのバッチの最大数は64です 。この制限に達すると、バッチがプールに戻されるまで、関数はnullを返します。

QByteArray QRhi::pipelineCacheData()

このQRhi のライフタイム中に正常に作成されたQRhiGraphicsPipeline およびQRhiComputePipeline から収集されたデータを含むバイナリデータブロブを返します。

キャッシュデータを保存し、同じアプリケーションのその後の実行でそれを再読み込みすることで、パイプラインおよびシェーダーの作成時間を短縮できる可能性があります。キャッシュおよびそのシリアライズされたバージョンに具体的に何が含まれるかは規定されておらず、常に使用されるバックエンドに依存し、場合によってはグラフィックス API の特定の実装にも依存します。

PipelineCacheDataLoadSave がサポートされていないと報告された場合、返されるQByteArray は空になります。

create() の呼び出し時にEnablePipelineCacheDataSave フラグが指定されなかった場合、PipelineCacheDataLoadSave 機能がサポートされている場合でも、返されるQByteArray は空になることがあります。

返されたデータが空でない場合、そのデータは常に Qt のバージョンおよびQRhi バックエンドに固有のものです。 さらに、場合によっては、グラフィックデバイスや使用されているドライバーの正確なバージョンに強く依存することがあります。QRhi は、適切なヘッダーの追加や、データが常にsetPipelineCacheData() に安全に渡されることを保証する安全策を講じています。そのため、別のバージョンのドライバーでの実行からデータを読み込もうとしても、安全かつ円滑に処理されます。

注: releaseCachedResources() を呼び出すと 、バックエンドによっては、収集されたパイプラインデータがクリアされる場合があります。その場合、この関数をその後呼び出しても、データが返されないことがあります。

この機能の詳細については、EnablePipelineCacheDataSave を参照してください。

注: この関数の呼び出し回数は最小限に抑えてください 。Blob の取得は必ずしも負荷の少ない操作ではないため、この関数の呼び出し頻度は低く抑えるべきであり、理想的にはアプリケーションを終了するときなど、1 回のみとするのが望ましいです。

setPipelineCacheData()、create()、およびisFeatureSupported()も参照してください 。

[static] bool QRhi::probe(QRhi::Implementation impl, QRhiInitParams *params)

指定されたimpl およびparams に対してcreate()を呼び出した際に、その呼び出しが成功すると予想される場合、trueを返します。

一部のバックエンドでは、これはcreate() を呼び出し、その戻り値を確認した後、結果として生成されたQRhi を破棄することと同等です。

その他のバックエンド、特に Metal では、特定のプローブ実装が存在する場合があり、これにより、失敗時の警告でデバッグ出力を汚すことなく、より軽量な方法でテストを行うことができます。

create()も参照してください 。

void QRhi::releaseCachedResources()

バックエンドのキャッシュからリソースを解放しようとします。これには、CPUリソースとGPUリソースの両方が含まれる場合があります。 対象となるのは、自動的に再作成可能なメモリとリソースのみです。例えば、バックエンドのQRhiGraphicsPipeline 実装がシェーダーコンパイル結果のキャッシュを保持している場合、この関数を呼び出すと、そのキャッシュがクリアされ、その結果、メモリとグラフィックスリソースが解放される可能性があります。

この関数の呼び出しは、リソースが制約された環境において、ある時点でパフォーマンスを犠牲にしてでもリソース使用量を最小限に抑える必要がある場合に有効です。

void QRhi::removeCleanupCallback(const void *key)

key を使用してコールバックを登録解除します。key でクリーンアップコールバックが登録されていない場合、この関数は何も行いません。キーなしで登録されたコールバックは削除できません。

addCleanupCallback()も参照してください 。

int QRhi::resourceLimit(QRhi::ResourceLimit limit) const

指定されたリソース `limit` の値を返します。

これらの値は初期化時にバックエンドによって取得されることが想定されているため、この関数の呼び出しは負荷の少ない操作となります。

void QRhi::setPipelineCacheData(const QByteArray &data)

該当する場合、data をパイプラインキャッシュに読み込みます。

PipelineCacheDataLoadSave がサポートされていないと報告された場合、この関数は安全に呼び出すことができますが、何の効果もありません。

pipelineCacheData() によって返される blob は、常に Qt のバージョン、QRhi バックエンド、場合によってはグラフィックデバイスやグラフィックドライバの特定のバージョンに固有のものです。QRhi は、適切なヘッダーを追加し、データが常にこの関数に安全に渡されることを保証する安全策を講じています。 ドライバーが新しいバージョンにアップグレードされた場合や、データが別のQRhi バックエンドから生成された場合など、不一致がある場合は、警告が出力され、data は安全に無視されます。

Vulkan では、これは VkPipelineCache に直接対応します。この関数を呼び出すと、data から初期データを取得した新しい Vulkan パイプラインキャッシュオブジェクトが作成されます。その後、このパイプラインキャッシュオブジェクトは、その後作成されるすべてのQRhiGraphicsPipeline およびQRhiComputePipeline オブジェクトで使用されるため、パイプラインの作成が高速化される可能性があります。

他のAPIには、厳密な意味でのパイプラインキャッシュは存在しませんが、シェーダーコンパイルによるバイトコード(D3D)やプログラムバイナリ(OpenGL)を格納するキャッシュが提供される場合があります。 実行時にソースからのシェーダーコンパイルを頻繁に行うアプリケーションでは、この関数を使用して以前の実行から「パイプラインキャッシュ」を事前に初期化しておけば、その後の実行において大幅なパフォーマンス向上が期待できます。

注: QRhi は 、data がパイプラインおよびシェーダーの生成パフォーマンスに効果をもたらすことを保証するものではありません。VulkanのようなAPIでは、data を何らかの目的で使用するか、あるいは無視するかは、ドライバ次第です。

この機能の詳細については、EnablePipelineCacheDataSave を参照してください。

注: QRhi が提供するこのメカニズムは 、ドライバー独自の内部キャッシュメカニズム(存在する場合)とは独立しています。つまり、グラフィックス API およびその実装によっては、data を取得して再読み込みした際の正確な効果は予測できません。Qt の制御外の他のキャッシュメカニズムがすでに有効になっている場合、パフォーマンスの向上が全く現れない可能性があります。

注: この関数の呼び出し回数は最小限に抑えてください 。blobの読み込みは必ずしも低コストな操作ではないため、この関数は低頻度で呼び出すべきであり、理想的にはアプリケーションの起動時など、1回のみ呼び出すようにしてください。

警告:シリアライズされた パイプラインキャッシュデータは、信頼できるコンテンツであるとみなされます。Qtはdata に含まれるヘッダーおよびメタデータを堅牢に解析しますが、アプリケーション開発者は、信頼できないソースからのデータを絶対に渡さないよう推奨されます。

関連項目: pipelineCacheData() およびisFeatureSupported()。

[since 6.9] void QRhi::setQueueSubmitParams(QRhiNativeHandles *params)

バックエンドやグラフィックスAPI(該当する場合)において、この関数を使用することで、グラフィックスコマンドキューへの次回のコマンド送信時に追加の引数を指定することができます。

特に、Vulkan では、これにより `vkQueueSubmit() ` がシグナルを送信したり待機したりするための Vulkan セマフォオブジェクトのリストを渡すことが可能になります。この場合、params は `QRhiVulkanQueueSubmitParams` でなければなりません。これは、アプリケーションのカスタム Vulkan レンダリングやコンピュートコードが管理する `VkSemaphore` に対して待機やシグナル送信を行う必要があるネイティブ Vulkan 呼び出しを実行する場合など、特定の高度なユースケースにおいて不可欠となります。 さらに、これにより、次のvkQueuePresentKHR() で待機対象とする追加のセマフォを指定することも可能になります。

注:この関数は 、endFrame()、endOffscreenFrame()、またはfinish()で実行される次のキューへの送信にのみ影響します。presentのキューへの追加はendFrame()で行われます。

他の多くのバックエンドでは、この関数の実装はノーオペレーション(何もしない)です。

この関数は Qt 6.9 で導入されました。

[static] QSize QRhi::sizeForMipLevel(int mipLevel, const QSize &baseLevelSize)

指定されたmipLevel のテクスチャ画像サイズを返します。このサイズは、baseLevelSize で指定されたレベル0のサイズに基づいて計算されます。

QRhiStats QRhi::statistics() const

グラフィックスリソースのタイミングや割り当てに関する統計情報を収集し、返します。

メモリ割り当てに関するデータは、そのような操作がQtの管理下にある一部のバックエンドでのみ利用可能です。リソースのメモリ割り当てに対して低レベルでの制御がないグラフィックスAPIでは、これは決してサポートされず、結果内の関連するすべてのフィールドは0となります。

特にVulkanの場合、値は常に有効であり、基盤となるメモリアロケータライブラリから取得されます。これにより、アクティブなバッファやテクスチャのメモリ要件を把握することができます。

Direct 3D 12についても同様です。メモリアロケータライブラリの統計情報に加え、ここでは結果に「totalUsageBytes 」フィールドも含まれます。このフィールドは、DXGIによって報告される、メモリアロケータライブラリの管理下にはない追加リソース(スワップチェーンバッファ、ディスクリプタヒープなど)を含めた合計サイズを示します。

これらの値は、使用されているすべての種類のメモリを合計したものです(つまり、ディスクリートGPUの場合はビデオメモリ+システムメモリ)。

グラフィックスおよびコンピュートパイプラインの生成に費やされた合計時間(ミリ秒単位)など、追加データはほとんどのバックエンドで利用可能です(これには通常、シェーダーのコンパイルやキャッシュのルックアップ、および潜在的に負荷の高い処理が含まれます)。

注: パイプラインの作成などの操作にかかる所要時間は 、さまざまな要因の影響を受ける可能性があります。「パイプライン」という概念や、例えばQRhiGraphicsPipeline::create() の呼び出し中に内部で実際に何が起きているかについては、グラフィックス API やその実装によって大きく異なるため、異なるバックエンド間で結果を比較すべきではありません。

注:さらに 、多くのドライバでは、シェーダ、プログラム、パイプラインに対して様々なキャッシュ戦略を採用している可能性があります(setPipelineCacheData() や OpenGL 独自のプログラムバイナリディスクキャッシュなど、Qt 独自の同様の機能とは独立して)。 このような内部動作はAPIクライアントからは透過的であるため、QtおよびQRhi は、具体的なキャッシュ戦略、キャッシュデータの永続性、無効化などについて認識も制御もできません。パイプラインの生成に要した時間などのタイミングを測定する際は、ドライバレベルのキャッシュメカニズムが存在する可能性や、その仕様が定義されていない動作があることを念頭に置く必要があります。

QList<int> QRhi::supportedSampleCounts() const

サポートされているサンプル数のリストを返します。

典型的な例としては (1, 2, 4, 8) が挙げられます。

バックエンドによっては、サポートされている値のリストが事前に固定されているものもあれば、実行時に(物理)デバイスのプロパティによってサポートされているものが決定されるものもあります。

QRhiRenderBuffer::setSampleCount()、QRhiTexture::setSampleCount()、QRhiGraphicsPipeline::setSampleCount()、およびQRhiSwapChain::setSampleCount()も参照してください 。

[since 6.9] QList<QSize> QRhi::supportedShadingRates(int sampleCount) const

指定されたsampleCount に対してサポートされている可変シェーディング率のリストを返します。

1x1は常にサポートされています。

この関数はQt 6.9で導入されました。

QThread *QRhi::thread() const

QRhi がinitialized されたスレッドを返します。

int QRhi::ubufAligned(int v) const

ubufAlignment() で指定された均一バッファのアラインメントに合わせて整列された値(通常はオフセット)v を返します。

int QRhi::ubufAlignment() const

バイト単位でのユニフォームバッファのオフセットアライメントの最小値を返します。通常、これは 256 です。

この値にアラインされていないオフセットでユニフォームバッファ領域をバインドしようとすると、バックエンドや基盤となるグラフィックスAPIによっては失敗する可能性があります。

ubufAligned()も参照してください 。

[static] QRhiSwapChainProxyData QRhi::updateSwapChainProxyData(QRhi::Implementation impl, QWindow *window)

impl で指定されたバックエンドおよびグラフィックス API に固有の不透明なデータを含む `QRhiSwapChainProxyData ` 構造体を生成して返します。window は、スワップチェーンがターゲットとする `QWindow ` です。

返された構造体は、QRhiSwapChain::setProxyData() に渡すことができます。これはスレッド化されたレンダリングシステムにおいて意味を持ちます。この静的関数は、QRhi のすべての操作とは異なり、メイン(GUI)スレッド上で呼び出され、その後、QRhi およびQRhiSwapChain を扱うスレッドに転送され、スワップチェーンに渡されることが想定されています。 これにより、メインスレッドでのみ安全に呼び出せるネイティブプラットフォームのクエリ(例えば、NSView から CAMetalLayer を取得するクエリなど)を実行し、そのデータをレンダリングスレッド上のQRhiSwapChain に渡すことが可能になります。 Metalの例では、専用のレンダリングスレッド上で`view.layer`にアクセスすると、Xcodeのスレッドチェッカーで警告が発生します。データプロキシの仕組みを用いれば、これを回避できます。

スレッドが関与しない場合、QRhiSwapChainProxyData の生成や引き渡しは不要です。バックエンドは必要な情報を独自に取得できることが保証されており、すべてがメイン(GUI)スレッド上にあるのであれば、それで十分です。

注: impl は 、QRhi が作成された際の設定と一致している必要があります。たとえば、Apple以外のプラットフォームでQRhi::Metal を呼び出しても、有用なデータは生成されません。

関連する非メンバー

[alias, since 6.7] QRhiShaderResourceBindingSet

QRhiShaderResourceBindings の同義語。

この typedef は Qt 6.7 で導入されました。

© 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.