QRhi Class
Beschleunigte Abstraktion der 2D/3D-Grafik-API. Mehr...
| Überschrift: | #include <rhi/qrhi.h> |
| CMake: | find_package(Qt6 REQUIRED COMPONENTS GuiPrivate) target_link_libraries(mytarget PRIVATE Qt6::GuiPrivate) |
| qmake: | QT += gui-private |
| Seit: | Qt 6.6 |
- Liste aller Mitglieder, einschließlich geerbter Mitglieder
- QRhi ist Teil von „Rendering in 3D“.
Öffentliche Typen
(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 } |
Öffentliche Funktionen
| ~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 |
Statische öffentliche Mitglieder
| 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) |
Verwandte Nicht-Mitglieder
(since 6.7) | QRhiShaderResourceBindingSet |
Ausführliche Beschreibung
Die Qt-Rendering-Hardware-Schnittstelle ist eine Abstraktion für hardwarebeschleunigte Grafik-APIs wie OpenGL, OpenGL ES, Direct3D, Metal und Vulkan.
Warnung: Die QRhi-Klassenfamilie im Qt GUI-Modul, einschließlich „ QShader “ und „ QShaderDescription “, bietet nur eingeschränkte Kompatibilitätsgarantien. Für diese Klassen gibt es keine Garantien hinsichtlich der Quellcode- oder Binärkompatibilität, was bedeutet, dass die API nur mit der Qt-Version garantiert funktioniert, auf deren Grundlage die Anwendung entwickelt wurde. Änderungen, die zu einer Inkompatibilität auf Quellcodeebene führen, sollen jedoch auf ein Minimum beschränkt bleiben und werden nur in Minor-Releases (6.7, 6.8 usw.) vorgenommen. Um diese Klassen in einer Anwendung zu verwenden, verknüpfen Sie mit „ Qt::GuiPrivate “ (bei Verwendung von CMake) und binden Sie die Header mit dem Präfix „ rhi “ ein, zum Beispiel „ #include <rhi/qrhi.h> “.
Jede QRhi-Instanz wird von einem Backend für eine bestimmte Grafik-API unterstützt. Die Auswahl des Backends erfolgt zur Laufzeit und obliegt der Anwendung oder Bibliothek, die die QRhi-Instanz erstellt. Einige Backends sind auf mehreren Plattformen verfügbar (OpenGL, Vulkan, Null), während plattformspezifische APIs nur bei Ausführung auf der jeweiligen Plattform verfügbar sind (Metal unter macOS/iOS, Direct3D unter Windows).
Derzeit sind folgende Backends verfügbar:
- OpenGL 2.1 / OpenGL ES 2.0 oder neuer. Einige Erweiterungen und neuere Funktionen der Kernspezifikation werden genutzt, sofern vorhanden, beispielsweise um Multisample-Framebuffer oder Compute-Shader zu aktivieren. Der Betrieb in Core-Profile-Kontexten wird ebenfalls unterstützt. Bei Bedarf können Anwendungen zur Laufzeit die „ feature flags “ abfragen, um zu prüfen, welche Funktionen im OpenGL-Kontext, der dem QRhi zugrunde liegt, nicht unterstützt werden. Das OpenGL-Backend baut auf QOpenGLContext, QOpenGLFunctions und der zugehörigen plattformübergreifenden Infrastruktur des Moduls „ Qt GUI “ auf.
- Direct3D 11.2 und neuer (mit DXGI 1.3 und neuer), unter Verwendung von Shader Model 5.0 oder neuer. Wenn die D3D-Laufzeitumgebung keine Unterstützung für 11.2-Funktionen oder Shader Model 5.0 bietet, schlägt die Initialisierung mit einem beschleunigten Grafikgerät fehl, die Verwendung des Software-Adapters ist jedoch weiterhin möglich.
- Direct3D 12 unter Windows 10 Version 1703 und neuer, mit Shader Model 5.0 oder neuer. Qt setzt das Vorhandensein von ID3D12Device2 voraus, daher ist mindestens Windows 10 Version 1703 erforderlich. Das D3D12-Gerät wird standardmäßig mit der Angabe eines Mindest-Feature-Levels von „
D3D_FEATURE_LEVEL_11_0“ erstellt. - Metal 1.2 oder neuer.
- Vulkan 1.0 oder neuer, optional unter Nutzung einiger Funktionen der Vulkan-1.1-Stufe.
- Null, ein „Dummy“-Backend, das überhaupt keine Grafikaufrufe ausführt.
Damit Shader-Code in Qt-Anwendungen und -Bibliotheken einmalig geschrieben werden kann, sollen alle Shader in einer einzigen Sprache verfasst werden, die anschließend in SPIR-V kompiliert wird. Daraus werden dann Versionen für verschiedene Shading-Sprachen generiert, zusammen mit Reflexionsinformationen (Eingaben, Ausgaben, Shader-Ressourcen). Dies wird anschließend in einfach und effizient serialisierbare „ QShader “-Instanzen verpackt. Die Compiler und Werkzeuge zur Generierung solcher Shader sind nicht Teil von QRhi und des Moduls „ Qt GUI “, wohl aber die Kernklassen zur Verwendung solcher Shader: „ QShader “ und „ QShaderDescription “. Die APIs und Werkzeuge zur Durchführung der Kompilierung und Übersetzung sind Teil des Qt-Moduls „ Shader Tools “.
Im „RHI Window Example“ finden Sie ein Einführungsbeispiel für die Erstellung einer portablen, plattformübergreifenden Anwendung, die mithilfe von QRhi beschleunigtes 3D-Rendering auf einem „ QWindow “ durchführt.
Ein Einblick in die API
Um einen schnellen Überblick über die API anhand eines kurzen, aber vollständigen Beispiels zu geben, das keine fensterbezogenen Einstellungen erfordert, finden Sie im Folgenden eine vollständige, ausführbare plattformübergreifende Anwendung, die 20 Frames außerhalb des Bildschirms rendert und anschließend die erzeugten Bilder in Dateien speichert, nachdem die Texturinhalte von der GPU zurückgelesen wurden. Ein Beispiel für das Rendern auf dem Bildschirm, bei dem die Einrichtung eines „ QWindow “ und einer Swapchain erforderlich ist, finden Sie im RHI-Fenster-Beispiel.
Der Kürze halber erfolgt die Initialisierung von QRhi plattformabhängig: Der hier gezeigte Beispielcode wählt unter Windows Direct 3D 12, unter macOS und iOS Metal und in allen anderen Fällen Vulkan. OpenGL und Direct 3D 11 werden von dieser Anwendung nie verwendet, die Unterstützung dafür könnte jedoch mit wenigen zusätzlichen Zeilen implementiert werden.
#include <QGuiApplication>
#include <QImage>
#include <QFile>
#include <rhi/qrhi.h>
int main(int argc, 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, ¶ms));
#elif QT_CONFIG(metal)
QRhiMetalInitParams params;
rhi.reset(QRhi::create(QRhi::Metal, ¶ms));
#elif QT_CONFIG(vulkan)
inst.setExtensions(QRhiVulkanInitParams::preferredInstanceExtensions());
if (inst.create()) {
QRhiVulkanInitParams params;
params.inst = &inst;
rhi.reset(QRhi::create(QRhi::Vulkan, ¶ms));
} else {
qFatal("Failed to create Vulkan instance");
}
#endif
if (rhi)
qDebug() << rhi->backendName() << rhi->driverInfo();
sonst
qFatal("Failed to initialize RHI");
float rotation = 0.0f;
float opacity = 1.0f;
int opacityDir = 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 float vertexData[] = { // Y nach oben, gegen den Uhrzeigersinn
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 auto getShader = [](const QString&name) {
QFile f(name);
return f.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 (int frame = 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();
const QRhiCommandBuffer::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<const uchar*>(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;
}Das Ergebnis der Anwendung sind 20 PNG Bilder (frame0.png – frame19.png). Diese enthalten ein rotierendes Dreieck mit variierender Deckkraft vor einem grünen Hintergrund.
Es wird erwartet, dass die Vertex- und Fragment-Shader verarbeitet und in „ .qsb “-Dateien gepackt werden. Der Vulkan-kompatible GLSL-Quellcode lautet wie folgt:
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);
}Um diese Shader manuell zu kompilieren und in verschiedene Zielformate (SPIR-V, HLSL, MSL, GLSL) zu transpilieren sowie die .qsb -Dateien zu generieren, die die Anwendung zur Laufzeit lädt, führen Sie qsb --qt6 color.vert -o color.vert.qsb und qsb --qt6 color.frag -o color.frag.qsb aus. Alternativ bietet das Qt-Modul „ Shader Tools “ eine Integration in das CMake-Build-System, nämlich die CMake-Funktion „ qt_add_shaders() “, mit der dasselbe bereits während der Build-Phase erreicht werden kann.
Sicherheitsaspekte
Alle von QRhi und verwandten Klassen wie QShader verarbeiteten Daten gelten als vertrauenswürdige Inhalte.
Warnung: Anwendungsentwicklern wird empfohlen, die möglichen Auswirkungen sorgfältig abzuwägen, bevor sie die Einbindung von benutzerdefinierten Inhalten zulassen, die nicht Teil der Anwendung sind und sich nicht unter der Kontrolle der Entwickler befinden. (Dies umfasst alle Vertex-/Index-Daten, Shader, Pipeline- und Draw-Call-Parameter usw.)
Grundlagen des Designs
Ein QRhi kann nicht direkt instanziiert werden. Verwenden Sie stattdessen die Funktion „ create()“. Löschen Sie die QRhi-Instanz wie gewohnt, um das Grafikgerät freizugeben.
Ressourcen
Instanzen von Klassen, die von ` QRhiResource` abgeleitet sind, wie beispielsweise ` QRhiBuffer`, ` QRhiTexture` usw., kapseln null, eine oder mehrere native Grafikressourcen. Instanzen solcher Klassen werden immer über die ` new `-Funktionen des QRhi erstellt, wie beispielsweise ` newBuffer()`, ` newTexture()`, ` newTextureRenderTarget()` und ` newSwapChain()`.
QRhiBuffer *vbuf = rhi->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, sizeof(vertexData));
if (!vbuf->create()) { error(); }
// ...
delete vbuf;- Der von Funktionen wie newBuffer() zurückgegebene Wert gehört immer dem Aufrufer.
- Das bloße Erstellen einer Instanz einer Unterklasse von ` QRhiResource ` führt niemals zur Zuweisung oder Initialisierung nativer Ressourcen. Dies geschieht erst beim Aufruf der Funktion `
create()` einer Unterklasse, zum Beispiel ` QRhiBuffer::create()` oder ` QRhiTexture::create()`. - Ausnahmen bilden QRhiTextureRenderTarget::newCompatibleRenderPassDescriptor(), QRhiSwapChain::newCompatibleRenderPassDescriptor() und QRhiRenderPassDescriptor::newCompatibleRenderPassDescriptor(). Für diese gibt es keinen
create()-Aufruf, und das zurückgegebene Objekt ist sofort aktiv. - Die Ressourcenobjekte selbst werden als unveränderlich behandelt: Sobald für eine Ressource „ create()“ aufgerufen wurde, hat das Ändern von Parametern über die Setter, wie z. B. „ QRhiTexture::setPixelSize()“, keine Auswirkungen, es sei denn, die zugrunde liegende native Ressource wird freigegeben und „
create()“ erneut aufgerufen. Weitere Informationen zur Wiederverwendung von Ressourcen finden Sie in den folgenden Abschnitten. - Die Freigabe der zugrunde liegenden nativen Ressourcen wird durch den Destruktor von ` QRhiResource ` oder durch den Aufruf von ` QRhiResource::destroy()` geplant. Backends stellen Freigabeanforderungen häufig in eine Warteschlange und verschieben deren Ausführung auf einen nicht näher bestimmten Zeitpunkt; dies bleibt für die Anwendungen verborgen. Auf diese Weise müssen sich Anwendungen keine Gedanken über die Freigabe nativer Ressourcen machen, die möglicherweise noch von einem laufenden Frame genutzt werden.
- Beachten Sie, dass dies nicht bedeutet, dass ein „ QRhiResource “ innerhalb eines Frames (d. h. im Abschnitt zwischen „ beginFrame()“ und „ endFrame()“) beliebig mit „destroy()“ oder „delete“ freigegeben werden kann. Generell müssen alle referenzierten „ QRhiResource “-Objekte unverändert bleiben, bis der Frame durch den Aufruf von „ endFrame()“ übermittelt wird. Um dies zu vereinfachen, wird „ QRhiResource::deleteLater()“ als Hilfsfunktion bereitgestellt.
Befehlspuffer und verzögerte Befehlsausführung
Unabhängig vom Aufbau und den Fähigkeiten der zugrunde liegenden Grafik-API implementieren alle QRhi-Backends Befehlspuffer in gewissem Umfang. Keine der Funktionen „ QRhiCommandBuffer “ gibt direkt einen nativen Bind- oder Draw-Befehl (wie z. B. ` glDrawElements`) aus. Befehle werden immer in einer Warteschlange gespeichert, die entweder nativ ist oder vom QRhi-Backend bereitgestellt wird. Der Befehlspuffer wird übermittelt, sodass die Ausführung erst nach dem Aufruf von ` QRhi::endFrame()` oder ` QRhi::finish()` beginnt.
Diese verzögerte Ausführung hat Konsequenzen für bestimmte Objekttypen. Wenn beispielsweise innerhalb eines Frames mehrfach in einen dynamischen Puffer geschrieben wird – sofern solche Puffer auf für den Host sichtbarem Speicher basieren –, führt dies dazu, dass die Ergebnisse aller Schreibvorgänge für alle Zeichenaufrufe im Befehlspuffer des Frames sichtbar sind, unabhängig davon, wann die Aktualisierung des dynamischen Puffers im Verhältnis zu einem Zeichenaufruf aufgezeichnet wurde.
Darüber hinaus müssen Instanzen von Unterklassen von ` QRhiResource ` innerhalb eines Frames, in dem sie in irgendeiner Weise referenziert werden, als unveränderlich behandelt werden. Erstellen Sie alle Ressourcen im Voraus, bevor Sie mit der Aufzeichnung von Befehlen für den nächsten Frame beginnen. Die Wiederverwendung einer ` QRhiResource `-Instanz innerhalb eines Frames (durch Aufruf von ` create() ` und anschließender erneuter Referenzierung im selben ` beginFrame - endFrame `-Abschnitt) sollte vermieden werden, da dies je nach Backend zu unerwarteten Ergebnissen führen kann.
Als allgemeine Regel gilt, dass alle referenzierten „ QRhiResource “-Objekte gültig und unverändert bleiben müssen, bis der Frame durch den Aufruf von ` endFrame()` übermittelt wird. Andererseits ist der Aufruf von ` destroy()` oder das Löschen des ` QRhiResource ` nach dem Absenden des Frames immer sicher, unabhängig vom Status der zugrunde liegenden nativen Ressourcen (die möglicherweise noch von der GPU genutzt werden – dies wird jedoch intern abgewickelt).
Im Gegensatz zu APIs wie OpenGL können Befehle vom Typ „Upload“ und „Copy“ nicht mit Zeichenbefehlen gemischt werden. Ein typischer Renderer folgt einer Abfolge, die in etwa wie folgt aussieht:
- Ressourcen (neu) erstellen
- Frame starten
- Uploads und Kopiervorgänge aufzeichnen/ausführen
- Aufzeichnung eines Render-Passes starten
- Draw-Calls aufzeichnen
- Render-Pass beenden
- Frame beenden
Die Aufzeichnung von Operationen vom Typ „Kopie“ erfolgt über ` QRhiResourceUpdateBatch`. Solche Operationen werden in der Regel mit ` beginPass()` bestätigt.
Bei der Arbeit mit älteren, für OpenGL entwickelten Rendering-Engines erfordert die Migration zu QRhi oft eine Neugestaltung: Weg von einem einzigen „ render “-Schritt (der Kopieren und Hochladen, das Leeren von Puffern sowie das Auslösen von Draw-Calls – alles in einem Schritt – durchführt) hin zu einer klar getrennten, zweiphasiges prepare - render -Schema, bei dem der Schritt „ render “ lediglich einen Renderpass startet und Draw-Calls aufzeichnet, während die gesamte Ressourcenerstellung sowie die Einreihung von Aktualisierungen, Uploads und Kopien bereits zuvor im Schritt „ prepare “ erfolgt.
QRhi erlaubt derzeit nicht das freie Erstellen und Übermitteln von Befehlspuffern. Dies könnte in Zukunft bis zu einem gewissen Grad aufgehoben werden, insbesondere wenn Compute-Unterstützung eingeführt wird, aber das Modell klar definierter „ frame-start “- und „ frame-end “-Punkte in Kombination mit einem dedizierten „Frame“-Befehlspuffer, bei dem „ frame-end “ die Darstellung impliziert, wird die primäre Arbeitsweise bleiben, da dies am besten zu den verschiedenen UI-Technologien von Qt XML passt.
Threading
Eine QRhi-Instanz und die zugehörigen Ressourcen können in jedem beliebigen Thread erstellt und verwendet werden, ihre Nutzung muss sich jedoch auf diesen einen Thread beschränken. Beim Rendern in mehrere QWindows innerhalb einer Anwendung ist es oft ratsam, für jedes Fenster einen eigenen Thread und eine eigene QRhi-Instanz zu verwenden, da dadurch Probleme mit unerwarteter Drosselung vermieden werden können, die durch das Anzeigen in mehreren Fenstern verursacht werden. Konzeptionell entspricht dies dann der Funktionsweise der Thread-basierten Render-Schleife der „ Qt Quick “-Szenengrafik bei der direkten Arbeit mit OpenGL: ein Thread pro Fenster, ein „ QOpenGLContext “ pro Thread. Beim Umstieg auf QRhi wird „ QOpenGLContext “ durch QRhi ersetzt, was die Migration unkompliziert macht.
Bei extern erstellten nativen Objekten, wie beispielsweise über QRhiGles2NativeHandles übergebenen OpenGL-Kontexten, ist es Aufgabe der Anwendung, sicherzustellen, dass diese nicht von anderen Threads missbraucht werden.
Ressourcen können nicht zwischen QRhi-Instanzen gemeinsam genutzt werden. Dies ist eine bewusste Entscheidung, da QRhi die meisten Aufgaben im Zusammenhang mit Warteschlangen, Befehlspuffern und der Ressourcensynchronisation verbirgt und keine API dafür bereitstellt. Die sichere und effiziente parallele Nutzung von Grafikressourcen durch mehrere Threads hängt jedoch mit diesen Konzepten zusammen und ist daher ein Thema, das derzeit außerhalb des Anwendungsbereichs liegt, aber möglicherweise in Zukunft eingeführt wird.
Hinweis: Das Metal-Backend erfordert, dass im Render-Thread ein Autorelease-Pool verfügbar ist, der idealerweise jede Iteration der Render-Schleife umschließt. Dies erfordert keine Maßnahmen seitens der QRhi-Nutzer beim Rendern im Haupt- (GUI-)Thread, wird jedoch wichtig, wenn ein separater, dedizierter Render-Thread verwendet wird.
Ressourcensynchronisation
QRhi stellt keine APIs für Ressourcenbarrieren oder Bildlayout-Übergänge bereit. Eine solche Synchronisation erfolgt implizit durch die Backends, sofern dies möglich ist (z. B. bei Vulkan), indem die Ressourcennutzung nach Bedarf verfolgt wird. Puffer- und Bildbarrieren werden vor dem Render- oder Rechenvorgang für die Anwendung transparent eingefügt.
Hinweis: Es wird erwartet, dassRessourcen innerhalb eines Render- oder Rechen-Durchgangs während dieses Durchgangs an eine einzige Verwendung gebunden sind. Beispielsweise kann ein Puffer als Vertex-, Index-, Uniform- oder Speicherpuffer verwendet werden, jedoch nicht als Kombination dieser Verwendungsarten innerhalb eines einzelnen Durchgangs. Es ist jedoch völlig zulässig, einen Puffer beispielsweise in einem Rechen-Durchgang als Speicherpuffer und anschließend in einem Render-Durchgang als Vertex-Puffer zu verwenden, vorausgesetzt, der Puffer wurde bei seiner Erstellung für beide Verwendungszwecke deklariert.
Hinweis: Bei Texturen gilt diese Regel in bestimmten Fällen weniger streng, da die Verwendung von zwei Unterressourcen (typischerweise zwei verschiedene Mip-Ebenen) derselben Textur für unterschiedliche Zugriffsarten (eine zum Laden, eine zum Speichern) sogar innerhalb desselben Durchgangs unterstützt wird.
Wiederverwendung von Ressourcen
Aus Sicht des Benutzers ist ein „ QRhiResource “ unmittelbar nach dem Aufruf von ` QRhiResource::destroy()` wiederverwendbar. Mit Ausnahme von Swapchains führt der Aufruf von ` create() ` auf ein bereits erstelltes Objekt implizit einen ` destroy()` aus. Dies bietet eine praktische Abkürzung zur Wiederverwendung einer „ QRhiResource “-Instanz mit unterschiedlichen Parametern, wobei im Hintergrund ein neues natives Grafikobjekt verwendet wird.
Die Bedeutung der Wiederverwendung desselben Objekts liegt darin, dass manche Objekte auf andere Objekte verweisen: So kann beispielsweise ein „ QRhiShaderResourceBindings “ auf Instanzen von „ QRhiBuffer “, „ QRhiTexture “ und „ QRhiSampler “ verweisen. Wenn in einem späteren Frame die Größe eines dieser Puffer angepasst oder ein Sampler-Parameter geändert werden muss, würde das Löschen und Erstellen eines komplett neuen „ QRhiBuffer “ oder „ QRhiSampler “ alle Verweise auf die alte Instanz ungültig machen. Indem man lediglich die entsprechenden Parameter über ` QRhiBuffer::setSize()` oder Ähnliches ändert und anschließend ` QRhiBuffer::create()` aufruft, funktioniert alles wie erwartet, und es besteht keinerlei Notwendigkeit, den ` QRhiShaderResourceBindings ` anzutasten – auch wenn die Wahrscheinlichkeit groß ist, dass hinter den Kulissen der ` QRhiBuffer ` nun durch einen völlig neuen nativen Puffer gestützt wird.
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 bietet denselben Vertrag: Der Aufruf von ` QRhiCommandBuffer::beginPass()` ist sicher, selbst wenn eine der mit dem Render-Target verbundenen Texturen oder Renderbuffer seit der Erstellung des Render-Target-Objekts neu aufgebaut wurde (durch Aufruf von ` create() ` darauf). Dies ermöglicht es der Anwendung, die Größe einer Textur anzupassen, indem sie eine neue Pixelgröße für die „ QRhiTexture “ festlegt und ` create()` aufruft. Dadurch wird im Hintergrund eine völlig neue native Texturressource erstellt, ohne dass die „ QRhiTextureRenderTarget “ aktualisiert werden muss, da dies implizit in `beginPass()` erfolgt.
Objekte im Pool
Neben Ressourcen gibt es auch gepoolte Objekte, wie beispielsweise „ QRhiResourceUpdateBatch “. Eine Instanz wird über eine „ next “-Funktion abgerufen, wie zum Beispiel „ nextResourceUpdateBatch()“. Der Aufrufer ist in diesem Fall nicht Eigentümer der zurückgegebenen Instanz. Die einzig zulässige Vorgehensweise besteht hier darin, Funktionen auf dem „ QRhiResourceUpdateBatch “ aufzurufen und diesen anschließend an „ QRhiCommandBuffer::beginPass()“ oder „ QRhiCommandBuffer::endPass()“ zu übergeben. Diese Funktionen sorgen dafür, dass der Batch an den Pool zurückgegeben wird. Alternativ kann ein Batch durch Aufruf von „ QRhiResourceUpdateBatch::release()“ „abgebrochen“ und ohne Verarbeitung an den Pool zurückgegeben werden.
Ein typisches Muster sieht daher wie folgt aus:
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);Besonderheiten von Swapchains
QRhiSwapChain weist aufgrund der besonderen Eigenschaften von Swapchains einige spezielle Semantiken auf.
- Es gibt kein `
create()`, sondern stattdessen ` QRhiSwapChain::createOrResize()`. Der wiederholte Aufruf dieser Funktion ist nicht dasselbe wie der Aufruf von ` QRhiSwapChain::destroy()`, gefolgt von ` QRhiSwapChain::createOrResize()`. Dies liegt daran, dass Swapchains oft über Mechanismen verfügen, um Fälle zu handhaben, in denen Puffer in ihrer Größe angepasst werden müssen – und zwar auf eine Weise, die effizienter ist als das brutale Löschen und Neuanlegen von Grund auf. - Ein aktives „ QRhiSwapChain “ muss durch den Aufruf von ` destroy()` oder durch das Löschen des Objekts freigegeben werden, bevor das zugrunde liegende `QPlatformWindow` von ` QWindow` und damit das zugehörige native Fensterobjekt gelöscht wird. Dies sollte nicht aufgeschoben werden, da das Freigeben der Swapchain problematisch werden kann (und bei einigen APIs, wie z. B. Vulkan, ausdrücklich untersagt ist), wenn das native Fenster nicht mehr vorhanden ist, beispielsweise weil das `QPlatformWindow` beim Abrufen eines ` QWindow::close()` zerstört wurde. Daher muss die Freigabe der Swapchain immer dann erfolgen, wenn das Ziel- QWindow, das Ereignis „ QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed “ sendet. Wenn das Ereignis nicht vor der Zerstörung des „ QWindow “ eintrifft – was bei Verwendung von „ QCoreApplication::quit()“ passieren kann –, dann sollte nach Beendigung der Ereignisschleife „QWindow::handle()“ überprüft und die Freigabe der Swapchain aufgerufen werden, sofern der Wert nicht null ist (was bedeutet, dass das zugrunde liegende native Fenster noch vorhanden ist).
Eigentumsverhältnisse
Generell gilt: Es findet keine Eigentumsübertragung statt. Das Erstellen eines QRhi mit einem bereits vorhandenen Grafikgerät bedeutet nicht, dass das QRhi das Eigentum an dem Geräteobjekt übernimmt. Ebenso wird das Eigentum nicht abgetreten, wenn ein Geräte- oder Texturobjekt über ` QRhi::nativeHandles()` oder ` QRhiTexture::nativeTexture()` „exportiert“ wird. Vor allem führt die Übergabe von Zeigern in Strukturen und über Setter nicht zu einer Eigentumsübertragung.
Fehlerbehebung und Profiling
Fehlerberichterstattung
Funktionen wie ` QRhi::create()` und die ` create() `-Memberfunktionen der Ressourcenklassen (z. B. ` QRhiBuffer::create()`) zeigen Fehler anhand des Rückgabewerts an (jeweils `nullptr ` oder ` false`). Bei der Arbeit mit ` QShader` gibt ` QShader::fromSerialized()` einen ungültigen ` QShader ` zurück (für den ` isValid()` ` false` zurückgibt), wenn die an die Funktion übergebenen Daten nicht erfolgreich deserialisiert werden können. Einige Funktionen, insbesondere beginFrame(), melden unter Umständen auch „Soft-Fehler“ wie beispielsweise FrameOpSwapChainOutOfDate, die keinen nicht behebbaren Fehler anzeigen, sondern vielmehr als Aufforderung zum „späteren erneuten Versuch“ zu verstehen sind.
Warnungen und Fehler können jederzeit über ` qWarning()` in die Debug-Ausgabe geschrieben werden. Es ist daher stets ratsam, die Ausgabe der Anwendung zu überprüfen.
Zusätzliche Debug-Meldungen können über die folgenden Protokollierungskategorien aktiviert werden. Meldungen aus diesen Kategorien werden standardmäßig nicht ausgegeben, es sei denn, sie wurden explizit über ` QLoggingCategory ` oder die Umgebungsvariable ` QT_LOGGING_RULES ` aktiviert. Für eine bessere Interoperabilität mit Qt Quick aktiviert die Umgebungsvariable ` QSG_INFO ` ebenfalls diese Debug-Ausgaben.
qt.rhi.general
Darüber hinaus können Anwendungen die Werte von ` QRhi backend name ` und ` graphics device information ` aus einem erfolgreich initialisierten QRhi abfragen. Diese können dann bei Bedarf auch in Produktionsversionen an den Benutzer ausgegeben oder in den Anwendungsprotokollen gespeichert werden.
Untersuchung von Darstellungsproblemen
Wenn die Renderergebnisse nicht den Erwartungen entsprechen oder die Anwendung Probleme aufweist, sollten Sie stets in Betracht ziehen, die Debug- und Validierungsfunktionen der nativen 3D-APIs zu nutzen. QRhi selbst verfügt nur über begrenzte Fehlerprüfungen, da es nicht sinnvoll ist, den bereits vorhandenen, umfangreichen Funktionsumfang der zugrunde liegenden Schichten zu replizieren.
- Bei Vulkan fällt die Steuerung der Vulkan-Validierungsschichten nicht in den Umfang von QRhi, sondern kann durch die Konfiguration des „ QVulkanInstance “ mit den entsprechenden Schichten erreicht werden. Rufen Sie beispielsweise „
instance.setLayers({ "VK_LAYER_KHRONOS_validation" });“ auf, bevor Sie „ create()“ auf dem „ QVulkanInstance “ aufrufen. (Beachten Sie, dass dies voraussetzt, dass die Validierungsschichten tatsächlich installiert und verfügbar sind, z. B. aus dem Vulkan-SDK.) Standardmäßig leitet „ QVulkanInstance “ die Vulkan-Debug-Meldungen praktischerweise an „ qDebug “ weiter, was bedeutet, dass die Validierungsmeldungen genau wie andere Qt-Warnungen ausgegeben werden. - Bei Direct 3D 11 und 12 kann ein Grafikgerät mit aktivierter Debug-Ebene angefordert werden, indem das Flag „
enableDebugLayer“ in der entsprechenden Funktion „ init params struct “ gesetzt wird. Bei Direct 3D 12 werden die Meldungen dann über „ qDebug “ ausgegeben, genau wie die Vulkan-Validierungsmeldungen, sofern die Debug-Ebene Meldungs-Callbacks unterstützt. Andernfalls – und immer bei Direct 3D 11 – erscheinen die Meldungen in der Debug-Ausgabe, die im Meldungsfenster von „ Qt Creator “ oder über ein Tool wie DebugView sichtbar ist. - Bei Metal liegt die Steuerung der Metal-Validierung außerhalb des Anwendungsbereichs von QRhi. Um die Validierung zu aktivieren, führen Sie die Anwendung stattdessen mit der gesetzten Umgebungsvariablen „
METAL_DEVICE_WRAPPER_TYPE=1“ aus oder starten Sie die Anwendung innerhalb von XCode. In modernen XCode- und macOS-Versionen gibt es möglicherweise weitere Einstellungen und Umgebungsvariablen. Siehe beispielsweise diese Seite.
Frame-Aufnahmen und Leistungsprofilierung
Eine Qt-Anwendung, die mit QRhi in ein Fenster rendert und dabei im Hintergrund auf eine 3D-API zurückgreift, unterscheidet sich – zumindest aus Sicht der Fensterverwaltung und der Grafikpipeline – nicht von anderen (Nicht-Qt-)Anwendungen, die dieselbe 3D-API verwenden. Das bedeutet, dass Tools und Vorgehensweisen zum Debuggen und Profiling von Anwendungen mit 3D-Grafiken, wie beispielsweise Spiele, auch auf eine solche Qt-Anwendung anwendbar sind.
Hier einige Beispiele für Tools, die Einblicke in die internen Rendering-Abläufe von Qt-Anwendungen bieten, die QRhi nutzen – darunter auch Projekte auf Basis von „ Qt Quick “ und „ Qt Quick 3D “:
- RenderDoc ermöglicht unter Windows und Linux die Aufnahme von Frames sowie die Analyse der aufgezeichneten Befehle und des Pipeline-Zustands für Anwendungen, die OpenGL, Vulkan, D3D11 oder D3D12 nutzen. Wenn man herausfinden möchte, warum bestimmte Teile der 3D-Szene nicht wie erwartet angezeigt werden, ist RenderDoc oft eine schnelle und effiziente Möglichkeit, die Pipeline-Stufen und den zugehörigen Status zu überprüfen und den fehlenden oder falschen Wert zu entdecken. Es ist zudem ein Tool, das bei der Entwicklung von Qt selbst aktiv eingesetzt wird.
- Für NVIDIA-basierte Systeme bietet Nsight Graphics ein Grafik-Debugger-Tool unter Windows und Linux. Neben der Untersuchung der Befehle im Frame und in der Pipeline ermöglichen die herstellerspezifischen Tools die Betrachtung von Timings und Informationen zur Hardware-Leistung – etwas, das einfache Frame-Aufnahmen nicht bieten können.
- Für AMD-basierte Systeme kann der Radeon GPU Profiler genutzt werden, um tiefere Einblicke in das Rendering der Anwendung und deren Leistung zu gewinnen.
- Overlays, die Live-Leistungsdaten anzeigen, können ebenfalls sehr nützlich sein und sind oft der Implementierung einfacher Bild-pro-Sekunde-Zähler innerhalb der Anwendung selbst vorzuziehen, da sie zuverlässiger sind und mehr Informationen liefern. Ein Beispiel hierfür ist PresentMon, das Grafikhardware verschiedener Hersteller unterstützt.
- Da QRhi Direct 3D 12 unterstützt, ist auch die Verwendung von PIX, einem Tool zur Leistungsoptimierung und Fehlerbehebung für DirectX-12-Spiele unter Windows, eine Option.
- Unter macOS kann der XCode Metal-Debugger verwendet werden, um Frame-Aufnahmen zu erstellen und zu analysieren, Leistungsdetails zu untersuchen und Shader zu debuggen. In macOS 13 ist es zudem möglich, ein Overlay zu aktivieren, das die Bildrate und weitere Informationen für jedes Metal-basierte Fenster anzeigt, indem die Umgebungsvariable „
MTL_HUD_ENABLED=1“ gesetzt wird.
Auf mobilen und eingebetteten Plattformen stehen möglicherweise hersteller- und plattformspezifische Tools zur Verfügung, die vom GPU- oder SoC-Hersteller bereitgestellt werden und die eine Leistungsprofilierung von Anwendungen unter Verwendung von OpenGL ES oder Vulkan ermöglichen.
Beachten Sie beim Aufzeichnen von Frames, dass Objekte und Befehlsgruppen über Debug-Marker benannt werden können, sofern „ debug markers were enabled “ für den QRhi und die verwendete Grafik-API dies unterstützen. Um den Befehlsstrom mit Anmerkungen zu versehen, rufen Sie „ debugMarkBegin()“, „ debugMarkEnd()“ und/oder „ debugMarkMsg()“ auf. Dies kann insbesondere bei größeren Frames mit mehreren Render-Durchläufen nützlich sein. Ressourcen werden benannt, indem „ setName “ () vor „ create “ () aufgerufen wird.
Um grundlegende Zeitmessungen auf der CPU- und GPU-Seite innerhalb der Anwendung durchzuführen, können „ QElapsedTimer “ und „ QRhiCommandBuffer::lastCompletedGpuTime()“ verwendet werden. Letzteres ist derzeit nur mit ausgewählten Grafik-APIs verfügbar und erfordert die Aktivierung über das Flag „ QRhi::EnableTimestamps “.
Überprüfung auf Ressourcenlecks
Wenn ein QRhi-Objekt zerstört wird, ohne dass alle daraus erstellten Puffer, Texturen und anderen Ressourcen ordnungsgemäß zerstört werden, werden diesbezügliche Warnungen in die Debug-Ausgabe geschrieben, sofern es sich um einen Debug-Build der Anwendung handelt oder die Umgebungsvariable ` QT_RHI_LEAK_CHECK ` auf einen Wert ungleich Null gesetzt ist. Dies ist eine einfache Möglichkeit, Designprobleme im Zusammenhang mit dem Ressourcenmanagement innerhalb der Rendering-Logik der Anwendung aufzudecken. Beachten Sie jedoch, dass einige Plattformen und zugrunde liegende Grafik-APIs möglicherweise ebenfalls eigene Zuordnungen und eine eigene Erkennung von Ressourcenlecks durchführen, über die Qt keine direkte Kontrolle hat. Bei der Verwendung von Vulkan kann der Speicherzuordner beispielsweise in Debug-Builds fehlgeschlagene Assertions auslösen, wenn Ressourcen, die Grafik-Speicherzuordnungen besitzen, nicht vor dem QRhi zerstört werden. Darüber hinaus gibt die Vulkan-Validierungsschicht, sofern sie aktiviert ist, Warnungen zu nativen Grafikressourcen aus, die nicht freigegeben wurden. In ähnlicher Weise können bei Direct 3D Warnungen zu nicht freigegebenen COM-Objekten ausgegeben werden, wenn die Anwendung das QRhi und seine Ressourcen nicht in der richtigen Reihenfolge zerstört.
Siehe auch „RHI-Fenster-Beispiel“, QRhiCommandBuffer, QRhiResourceUpdateBatch, QRhiShaderResourceBindings, QShader, QRhiBuffer, QRhiTexture, QRhiRenderBuffer, QRhiSampler, QRhiTextureRenderTarget, QRhiGraphicsPipeline, QRhiComputePipeline und QRhiSwapChain.
Dokumentation zu Mitgliedstypen
[alias, since 6.10] QRhi::AdapterList
Synonym für „ QVector “ <QRhiAdapter *>.
Diese `typedef`-Definition wurde in Qt 6.10 eingeführt.
enum QRhi::BeginFrameFlag
flags QRhi::BeginFrameFlags
Flag-Werte für „ QRhi::beginFrame “ ()
Der Typ „BeginFrameFlags“ ist ein typedef für QFlags<BeginFrameFlag>. Er speichert eine OR-Kombination von BeginFrameFlag-Werten.
enum QRhi::EndFrameFlag
flags QRhi::EndFrameFlags
Flag-Werte für „ QRhi::endFrame “ ()
| Konstante | Wert | Beschreibung |
|---|---|---|
QRhi::SkipPresent | 1 << 0 | Gibt an, dass kein „present“-Befehl in die Warteschlange gestellt oder kein „swapBuffers“-Aufruf durchgeführt werden soll. Auf diese Weise wird kein Bild dargestellt. Es wird nicht empfohlen, mehrere Frames zu generieren, bei denen dieses Flag gesetzt ist (außer beispielsweise zu Benchmark-Zwecken – beachten Sie jedoch, dass sich Backends beim Warten auf die Befehlsausführung ohne Darstellung unterschiedlich verhalten können, sodass die Ergebnisse untereinander nicht vergleichbar sind) |
Der Typ „EndFrameFlags“ ist ein `typedef` für ` QFlags<EndFrameFlag>`. Er speichert eine OR-Kombination von „EndFrameFlag“-Werten.
enum QRhi::Feature
Flag-Werte, die angeben, welche Funktionen vom aktuell verwendeten Backend unterstützt werden.
| Konstante | Wert | Beschreibung |
|---|---|---|
QRhi::MultisampleTexture | 1 | Gibt an, dass Texturen mit einer Sample-Anzahl größer als 1 unterstützt werden. In der Praxis wird diese Funktion bei OpenGL ES-Versionen älter als 3.1 und bei OpenGL älter als 3.0 nicht unterstützt. |
QRhi::MultisampleRenderBuffer | 2 | Gibt an, dass Renderbuffer mit einer Sample-Anzahl größer als 1 unterstützt werden. In der Praxis wird diese Funktion von OpenGL ES 2.0 nicht unterstützt und möglicherweise auch nicht von OpenGL 2.x, sofern die entsprechenden Erweiterungen nicht vorhanden sind. |
QRhi::DebugMarkers | 3 | Gibt an, dass Debug-Marker-Gruppen (und damit „ QRhiCommandBuffer::debugMarkBegin()“) unterstützt werden. |
QRhi::Timestamps | 4 | Gibt an, dass Zeitstempel für Befehlspuffer unterstützt werden. Relevant für ` QRhiCommandBuffer::lastCompletedGpuTime()`. Es ist zu erwarten, dass dies bei Metal, Vulkan, Direct 3D 11 und 12 sowie bei OpenGL-Kontexten der Version 3.3 oder höher unterstützt wird. Bei einigen dieser APIs ist die Unterstützung für Zeitstempelabfragen jedoch technisch optional, weshalb nicht garantiert werden kann, dass diese Funktion bei jeder Implementierung dieser APIs stets unterstützt wird. |
QRhi::Instancing | 5 | Gibt an, dass instanziertes Zeichnen unterstützt wird. In der Praxis wird diese Funktion bei OpenGL ES 2.0 und OpenGL 3.2 oder älter nicht unterstützt. |
QRhi::CustomInstanceStepRate | 6 | Gibt an, dass andere Instanz-Schrittraten als 1 unterstützt werden. In der Praxis wird diese Funktion bei OpenGL grundsätzlich nicht unterstützt. Darüber hinaus führt die Ausführung mit Vulkan 1.0 ohne VK_EXT_vertex_attribute_divisor ebenfalls dazu, dass für diese Funktion „false“ gemeldet wird. |
QRhi::PrimitiveRestart | 7 | Gibt an, dass der Neustart der Zusammenstellung von Primitiven beim Auftreten eines Indexwerts von 0xFFFF (IndexUInt16) oder 0xFFFFFFFF (IndexUInt32) aktiviert ist, zumindest für bestimmte Primitivtopologien. „ QRhi “ versucht, dies bei allen Backends zu aktivieren, doch in einigen Fällen wird dies nicht unterstützt. Eine dynamische Steuerung des „primitive restart“ ist nicht möglich, da bei einigen APIs der „primitive restart“ mit einem festen Index immer aktiviert ist. Anwendungen müssen davon ausgehen, dass, wann immer diese Funktion als unterstützt gemeldet wird, die oben genannten Indexwerte may je nach Topologie besonders behandelt werden müssen. Die einzigen beiden Topologien, bei denen garantiert ist, dass sich der „primitive restart“ über alle Backends hinweg identisch verhält, sofern diese Funktion als unterstützt gemeldet wird, sind LineStrip und TriangleStrip. |
QRhi::NonDynamicUniformBuffers | 8 | Gibt an, dass das Anlegen von Puffern mit der Verwendung „ UniformBuffer “ und den Typen „ Immutable “ oder „ Static “ unterstützt wird. Wird dies als nicht unterstützt gemeldet, müssen einheitliche (konstante) Puffer als „ Dynamic “ angelegt werden. (Was ohnehin empfohlen wird.) |
QRhi::NonFourAlignedEffectiveIndexBufferOffset | 9 | Gibt an, dass effektive Indexpuffer-Offsets (indexOffset + firstIndex * indexComponentSize), die nicht 4-Byte-ausgerichtet sind, unterstützt werden. Wird dies nicht unterstützt, kann der Versuch, einen drawIndexed() mit einem nicht ausgerichteten effektiven Offset auszuführen, zu nicht spezifiziertem Verhalten führen. Dies ist insbesondere für Metal relevant, wo dies als nicht unterstützt gemeldet wird. |
QRhi::NPOTTextureRepeat | 10 | Gibt an, dass der „ Repeat “-Wrap-Modus und die Mipmap-Filtermodi für Texturen mit einer Größe unterstützt werden, die keine Potenz von zwei ist. In der Praxis kann dieser Wert nur bei OpenGL ES 2.0-Implementierungen ohne „ GL_OES_texture_npot “ den Wert „false“ annehmen. |
QRhi::RedOrAlpha8IsRed | 11 | Gibt an, dass das „ RED_OR_ALPHA8 “-Format auf ein einkomponentiges 8-Bit- red -Format abgebildet wird. Dies ist bei allen Backends außer OpenGL der Fall, wenn entweder OpenGL ES oder ein Nicht-Core-Profil-Kontext verwendet wird. Stattdessen wird „ GL_ALPHA “ verwendet, ein einkomponentiges 8-Bit- alpha -Format. Die Verwendung des speziellen Texturformats ermöglicht einen einzigen Codepfad für die Erstellung von Texturen, wobei es dem Backend überlassen bleibt, das tatsächliche Format zu bestimmen, während das Feature-Flag dazu genutzt werden kann, die geeignete Shader-Variante für das Abtasten der Textur auszuwählen. |
QRhi::ElementIndexUint | 12 | Gibt an, dass 32-Bit-Elemente vom Typ „unsigned integer“ im Indexpuffer unterstützt werden. In der Praxis trifft dies überall zu, außer bei der Ausführung auf reinen OpenGL ES 2.0-Implementierungen ohne die erforderliche Erweiterung. Wenn der Wert „false“ ist, werden im Indexpuffer nur 16-Bit-Elemente vom Typ „unsigned integer“ unterstützt. |
QRhi::Compute | 13 | Gibt an, dass Compute-Shader, Bildladen/-speichern und Speicherpuffer unterstützt werden. OpenGL-Versionen älter als 4.3 und OpenGL ES-Versionen älter als 3.1 bieten keine Compute-Unterstützung. |
QRhi::WideLines | 14 | Gibt an, dass Linien mit einer Breite ungleich 1 unterstützt werden. Wird dies als nicht unterstützt gemeldet, wird die im Grafik-Pipeline-Status festgelegte Linienbreite ignoriert. Bei einigen Backends (D3D11, D3D12, Metal) kann dieser Wert immer „false“ sein. Bei Vulkan hängt der Wert von der jeweiligen Implementierung ab. Bei OpenGL werden breite Linien in Core-Profile-Kontexten nicht unterstützt. |
QRhi::VertexShaderPointSize | 15 | Gibt an, dass die Größe der gerasterten Punkte, die über ` gl_PointSize ` im Vertex-Shader festgelegt wurde, berücksichtigt wird. Wenn dies als nicht unterstützt gemeldet wird, wird das Zeichnen von Punkten mit einer Größe ungleich 1 nicht unterstützt. Die Einstellung von ` gl_PointSize ` im Shader ist dann zwar weiterhin gültig, wird aber ignoriert. (Beispielsweise wird bei der Generierung von HLSL die Zuweisung stillschweigend aus dem generierten Code entfernt.) Beachten Sie, dass einige APIs (Metal, Vulkan) verlangen, dass die Punktgröße beim Zeichnen von Punkten explizit im Shader festgelegt wird, selbst wenn die Größe 1 beträgt, da sie nicht automatisch auf 1 zurückgreifen. |
QRhi::BaseVertex | 16 | Gibt an, dass „ drawIndexed()“ das Argument „ vertexOffset “ unterstützt. Wird „nicht unterstützt“ gemeldet, wird der Wert von „vertexOffset“ bei einem indizierten Zeichnungsbefehl ignoriert. In der Praxis wird diese Funktion von OpenGL- und OpenGL ES-Versionen unter 3.2 sowie von Metal auf älteren iOS-Geräten, einschließlich des iOS-Simulators, nicht unterstützt. |
QRhi::BaseInstance | 17 | Gibt an, dass instanzierte Zeichnungsbefehle das Argument „ firstInstance “ unterstützen. Wird dies als nicht unterstützt gemeldet, wird der „firstInstance“-Wert ignoriert und die Instanz-ID beginnt bei 0. In der Praxis wird diese Funktion bei Metal auf älteren iOS-Geräten, einschließlich des iOS-Simulators, sowie bei allen OpenGL-Versionen nicht unterstützt. Letzteres ist darauf zurückzuführen, dass OpenGL ES Draw-Aufrufe mit einer Basisinstanz überhaupt nicht unterstützt. Derzeit implementiert das OpenGL-Backend von QRhi diese Funktionalität auch für OpenGL (Nicht-ES) nicht, da portable Anwendungen sich in der Praxis aufgrund von GLES nicht auf eine Basisinstanz ungleich Null verlassen können. Sollte die Anwendung dennoch darauf zurückgreifen, sollte sie auch die Funktion `InstanceIndexIncludesBaseInstance` berücksichtigen. |
QRhi::TriangleFanTopology | 18 | Gibt an, dass „ QRhiGraphicsPipeline::setTopology()“ „ QRhiGraphicsPipeline::TriangleFan “ unterstützt. In der Praxis wird diese Funktion bei Metal und Direct 3D 11/12 nicht unterstützt. |
QRhi::ReadBackNonUniformBuffer | 19 | Gibt an, dass „ reading buffer contents “ für „ QRhiBuffer “-Instanzen mit einer anderen Verwendung als „UniformBuffer“ unterstützt wird. In der Praxis wird diese Funktion unter OpenGL ES 2.0 nicht unterstützt. |
QRhi::ReadBackNonBaseMipLevel | 20 | Gibt an, dass die Angabe einer anderen Mip-Stufe als 0 beim Zurücklesen von Texturinhalten unterstützt wird. Wird dies nicht unterstützt, führt die Angabe einer Stufe ungleich Null in ` QRhiReadbackDescription ` dazu, dass ein Bild mit ausschließlich Nullen zurückgegeben wird. In der Praxis wird diese Funktion bei OpenGL ES 2.0 nicht unterstützt. |
QRhi::TexelFetch | 21 | Gibt an, dass „texelFetch()“ und „textureLod()“ in Shadern verfügbar sind. In der Praxis wird dies in OpenGL ES 2.0- und OpenGL 2.x-Kontexten als nicht unterstützt gemeldet, da GLSL 100 es und Versionen vor 130 diese Funktionen nicht unterstützen. |
QRhi::RenderToNonBaseMipLevel | 22 | Gibt an, dass die Angabe einer anderen Mip-Stufe als 0 beim Erstellen eines ` QRhiTextureRenderTarget ` mit einem ` QRhiTexture ` als Farbanhang unterstützt wird. Wenn dies nicht unterstützt wird, schlägt ` create()` fehl, sobald die Ziel-Mip-Stufe ungleich Null ist. In der Praxis wird diese Funktion unter OpenGL ES 2.0 nicht unterstützt. |
QRhi::IntAttributes | 23 | Gibt an, dass die Angabe von Eingabeattributen mit vorzeichenbehafteten und vorzeichenlosen Ganzzahltypen für eine Shader-Pipeline unterstützt wird. Wird dies nicht unterstützt, wird die Funktion „ QRhiGraphicsPipeline::create()“ zwar erfolgreich ausgeführt, es wird jedoch eine Warnmeldung angezeigt, und die Werte der Zielattribute sind fehlerhaft. In der Praxis wird diese Funktion unter OpenGL ES 2.0 und OpenGL 2.x nicht unterstützt. |
QRhi::ScreenSpaceDerivatives | 24 | Gibt an, dass Funktionen wie dFdx(), dFdy() und fwidth() in Shadern unterstützt werden. In der Praxis wird diese Funktion unter OpenGL ES 2.0 ohne die Erweiterung GL_OES_standard_derivatives nicht unterstützt. |
QRhi::ReadBackAnyTextureFormat | 25 | Gibt an, dass das Zurücklesen von Textur-Inhalten für alle QRhiTexture::Format voraussichtlich funktioniert. Bei anderen Backends als OpenGL ist zu erwarten, dass für diese Funktion „true“ zurückgegeben wird. Wird „false“ gemeldet – was typischerweise bei OpenGL der Fall ist –, wird nur die Unterstützung der Formate QRhiTexture::RGBA8 und QRhiTexture::BGRA8 für das Zurücklesen garantiert. Darüber hinaus wird bei OpenGL – nicht jedoch bei OpenGL ES – auch das Zurücklesen der Formate „ QRhiTexture::R8 “ und „ QRhiTexture::RED_OR_ALPHA8 “ mit 1 Byte pro Komponente unterstützt. Das Zurücklesen der Gleitkommaformate „ QRhiTexture::RGBA16F “ und „RGBA32F“ kann bei OpenGL ebenfalls funktionieren, sofern die Implementierung diese unterstützt; „ QRhi “ kann hierfür jedoch keine Garantie geben, wie durch dieses Flag angezeigt wird. |
QRhi::PipelineCacheDataLoadSave | 26 | Gibt an, dass die Funktionen „ pipelineCacheData()“ und „ setPipelineCacheData()“ funktionsfähig sind. Wenn diese nicht unterstützt werden, führen die Funktionen keine Aktion aus, der abgerufene Blob ist immer leer, und somit sind keine Vorteile zu erwarten, wenn der Inhalt des Pipeline-Caches abgerufen und bei einem späteren Durchlauf der Anwendung erneut geladen wird. |
QRhi::ImageDataStride | 27 | Gibt an, dass die Angabe eines benutzerdefinierten Strides (Zeilelänge) für Rohbilddaten beim Hochladen von Texturen unterstützt wird. Wenn dies nicht unterstützt wird (was passieren kann, wenn die zugrunde liegende API OpenGL ES 2.0 ohne Unterstützung für GL_UNPACK_ROW_LENGTH ist), darf QRhiTextureSubresourceUploadDescription::setDataStride() nicht verwendet werden. |
QRhi::RenderBufferImport | 28 | Gibt an, dass ` QRhiRenderBuffer::createFrom()` unterstützt wird. Für die meisten Grafik-APIs ist dies nicht sinnvoll, da ` QRhiRenderBuffer ` Texturobjekte intern kapseln, genau wie ` QRhiTexture`. Bei OpenGL existieren Renderbuffer-Objekte jedoch als separater Objekttyp in der API, und in bestimmten Umgebungen (beispielsweise wenn man ein Renderbuffer-Objekt mit einem EGLImage-Objekt verknüpfen möchte) ist es wichtig, das Einbinden eines bestehenden OpenGL-Renderbuffer-Objekts in ein ` QRhiRenderBuffer` zu ermöglichen. |
QRhi::ThreeDimensionalTextures | 29 | Gibt an, dass 3D-Texturen unterstützt werden. In der Praxis wird diese Funktion bei OpenGL- und OpenGL ES-Versionen unter 3.0 nicht unterstützt. |
QRhi::RenderTo3DTextureSlice | 30 | Gibt an, dass das Rendern in einen Ausschnitt einer 3D-Textur unterstützt wird. Dies wird unter Vulkan 1.0 möglicherweise nicht unterstützt, da es auf VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT beruht, einer Funktion von Vulkan 1.1. |
QRhi::TextureArrays | 31 | Gibt an, dass Textur-Arrays unterstützt werden und ` QRhi::newTextureArray()` funktionsfähig ist. Beachten Sie, dass auch wenn Textur-Arrays nicht unterstützt werden, Arrays von Texturen dennoch verfügbar sind, da es sich hierbei um zwei voneinander unabhängige Funktionen handelt. |
QRhi::Tessellation | 32 | Gibt an, dass die Tessellationssteuerungs- und -auswertungsphasen unterstützt werden. Wenn dies als unterstützt gemeldet wird, kann die Topologie eines „ QRhiGraphicsPipeline “ auf „ Patches “ gesetzt werden, die Anzahl der Kontrollpunkte kann über „ setPatchControlPointCount()“ festgelegt werden und Shader für die Tessellationssteuerung und -auswertung können in der Liste „ QRhiShaderStage “ angegeben werden. Tessellations-Shader weisen Portabilitätsprobleme zwischen verschiedenen APIs auf (beispielsweise ist die Übersetzung von GLSL/SPIR-V in HLSL aufgrund der Struktur von Hull-Shadern problematisch, während Metal eine etwas andere Tessellations-Pipeline verwendet als andere), weshalb auch dann noch unerwartete Probleme auftreten können, wenn die grundlegende Funktionalität in allen zugrunde liegenden APIs implementiert ist. Insbesondere bei Direct 3D müssen handgeschriebene HLSL-Hull- und Domain-Shader jeweils in jeden „ QShader “ für die Tessellationssteuerungs- und -auswertungsphase eingefügt werden, da qsb diese nicht aus SPIR-V generieren kann. Beachten Sie, dass eine Isolinien-Tessellation vermieden werden sollte, da sie nicht von allen Backends unterstützt wird. Die maximale Anzahl an Patch-Kontrollpunkten, die zwischen Backends portierbar ist, beträgt 32. |
QRhi::GeometryShader | 33 | Gibt an, dass die Geometrie-Shader-Phase unterstützt wird. Bei Unterstützung kann ein Geometrie-Shader in der Liste „ QRhiShaderStage “ angegeben werden. Geometrie-Shader gelten in „ QRhi “ als experimentelle Funktion und werden voraussichtlich nur von Vulkan, Direct 3D 11 und 12, OpenGL (3.2+) sowie OpenGL ES (3.2+) unterstützt, vorausgesetzt, die Implementierung meldet dies zur Laufzeit als unterstützt. Ab Qt 6.11 werden Geometrie-Shader automatisch in HLSL übersetzt, sodass keine manuelle Einbindung von handgeschriebenen HLSL-Geometrie-Shadern mehr erforderlich ist (beachten Sie jedoch, dass gl_in und Ausdrücke wie gl_in[0].gl_Position nicht unterstützt werden; sondern übergeben Sie die Position stattdessen als Ausgabevariable aus dem Vertex-Shader). Geometrie-Shader werden mit Metal nicht unterstützt. |
QRhi::TextureArrayRange | 34 | Gibt an, dass es bei „ texture arrays “ möglich ist, einen Bereich anzugeben, der den Shadern zur Verfügung gestellt wird. Normalerweise werden alle Array-Ebenen freigegeben, und es obliegt dem Shader, die Ebene auszuwählen (über die dritte Koordinate, die bei der Abtastung der „ sampler2DArray “ an „texture()“ übergeben wird). Sofern unterstützt, hat der Aufruf von `QRhiTexture::setArrayRangeStart()` und `QRhiTexture::setArrayRangeLength()` vor ` building ` oder ` importing ` der nativen Textur eine Wirkung und führt dazu, dass nur der angegebene Bereich aus dem Array ausgewählt wird. Dies ist in besonderen Fällen erforderlich, beispielsweise bei der Arbeit mit beschleunigter Videodekodierung und Direct 3D 11, da ein Textur-Array, das sowohl „ D3D11_BIND_DECODER “ als auch „ D3D11_BIND_SHADER_RESOURCE “ enthält, nur dann als Shader-Ressource verwendet werden kann, wenn eine einzelne Array-Ebene ausgewählt ist. Beachten Sie, dass all dies nur gilt, wenn die Textur als „ QRhiShaderResourceBinding::SampledTexture “- oder „ QRhiShaderResourceBinding::Texture “-Shader-Ressource verwendet wird, und nicht mit dem Laden/Speichern von Bildern kompatibel ist. Diese Funktion ist nur bei einigen Backends verfügbar, da sie sich nicht gut auf alle Grafik-APIs abbilden lässt, und sie ist ohnehin nur zur Unterstützung von Sonderfällen gedacht. In der Praxis ist davon auszugehen, dass diese Funktion von Direct3D 11/12 und Vulkan unterstützt wird. |
QRhi::NonFillPolygonMode | 35 | Gibt an, dass die Einstellung eines anderen PolygonMode als dem Standardwert „Fill“ für „ QRhiGraphicsPipeline “ unterstützt wird. Ein häufiger Anwendungsfall für die Umstellung auf den Modus „Line“ ist die Darstellung als Drahtgittermodell. Dies ist jedoch keine Kernfunktion von OpenGL ES und bei Vulkan optional; außerdem bieten einige mobile GPUs diese Funktion möglicherweise nicht an. |
QRhi::OneDimensionalTextures | 36 | Gibt an, dass 1D-Texturen unterstützt werden. In der Praxis wird diese Funktion unter OpenGL ES nicht unterstützt. |
QRhi::OneDimensionalTextureMipmaps | 37 | Gibt an, dass die Erzeugung von 1D-Textur-Mipmaps unterstützt wird. In der Praxis wird diese Funktion auf Backends nicht unterstützt, die keine Unterstützung für „OneDimensionalTextures“, Metal und Direct 3D 12 melden. |
QRhi::HalfAttributes | 38 | Gibt an, dass die Angabe von Eingabeattributen mit Gleitkommatypen mit halber Genauigkeit (16 Bit) für eine Shader-Pipeline unterstützt wird. Wenn dies nicht unterstützt wird, wird ` QRhiGraphicsPipeline::create()` zwar erfolgreich ausgeführt, es wird jedoch eine Warnmeldung angezeigt, und die Werte der Zielattribute sind fehlerhaft. In der Praxis wird diese Funktion in einigen OpenGL ES 2.0- und OpenGL 2.x-Implementierungen nicht unterstützt. Beachten Sie, dass Direct3D 11/12 zwar Eingabeattribute mit halber Genauigkeit unterstützt, den Typ `half3` jedoch nicht. Die D3D-Backends geben `half3`-Attribute als `half4` weiter. Um plattformübergreifende Kompatibilität zu gewährleisten, sollten `half3`-Eingaben auf 8 Byte aufgefüllt werden. |
QRhi::RenderToOneDimensionalTexture | 39 | Gibt an, dass 1D-Textur-Renderziele unterstützt werden. In der Praxis wird diese Funktion auf Backends, die keine Unterstützung für „OneDimensionalTextures“ melden, sowie bei Metal nicht unterstützt. |
QRhi::ThreeDimensionalTextureMipmaps | 40 | Gibt an, dass die Erzeugung von 3D-Textur-Mipmaps unterstützt wird. Dies wird in der Regel von allen Backends ab Qt 6.10 unterstützt. |
QRhi::MultiView | 41 | Gibt an, dass Multiview (siehe z. B. VK_KHR_multiview ) unterstützt wird. Bei OpenGL ES 2.0, Direct 3D 11 und OpenGL(ES)-Implementierungen ohne „ GL_OVR_multiview2 “ wird diese Funktion nicht unterstützt. Bei Vulkan 1.1 und neuer sowie bei Direct 3D 12 wird Multiview in der Regel unterstützt. Wenn dies als unterstützt gemeldet wird, ermöglicht die Erstellung eines „ QRhiTextureRenderTarget “ mit einem „ QRhiColorAttachment “, der auf ein Texturarray verweist und bei dem „ multiViewCount “ gesetzt ist, die Aufzeichnung eines Render-Passes, der Multiview-Rendering verwendet. Zudem muss jede in diesem Render-Durchgang verwendete „ QRhiGraphicsPipeline “ die Eigenschaft „ the same view count set “ aufweisen. Beachten Sie, dass Multiview nur in Kombination mit 2D-Textur-Arrays verfügbar ist. Es kann nicht zur Optimierung des Renderings in einzelne Texturen (z. B. zwei für das linke und rechte Auge) verwendet werden. Vielmehr ist das Ziel eines Multiview-Render-Passes immer ein Textur-Array, wobei automatisch auf die Ebene (Array-Element) gerendert wird, die der jeweiligen Ansicht entspricht. Daher setzt diese Funktion auch Textur-Arrays voraus. Multiview-Rendering wird in Kombination mit Tessellation oder Geometrie-Shadern nicht unterstützt. Weitere Details zum Multiview-Rendering finden Sie unter QRhiColorAttachment::setMultiViewCount(). Dieser Enum-Wert wurde in Qt 6.7 eingeführt. |
QRhi::TextureViewFormat | 42 | Gibt an, dass die Einstellung eines „ view format “ für ein „ QRhiTexture “ wirksam ist. Wenn dies als unterstützt gemeldet wird, ändert die Einstellung des Lese- (Sampling) oder Schreib- (Render-Ziel / Bild-Lade-Speicher) Ansichtsmodus das Anzeigeformat der Textur. Wenn dies nicht unterstützt wird, hat die Einstellung eines Ansichtsformats keine Auswirkung. Beachten Sie, dass Qt keine Kenntnis von oder Kontrolle über die Formatkompatibilität oder die Regeln zur Ressourcenanzeige in der zugrunde liegenden 3D-API und deren Implementierung hat. Die Übergabe ungeeigneter, inkompatibler Formate kann zu Fehlern und nicht spezifiziertem Verhalten führen. Diese Funktion dient in erster Linie dazu, das „Casting“ von Rendering-Ergebnissen in eine im sRGB-Format erstellte Textur in ein Nicht-sRGB-Format zu ermöglichen, um die unerwünschte lineare-zu-sRGB-Konvertierung bei Shader-Schreibvorgängen zu vermeiden. Andere Arten des Castings funktionieren je nach zugrunde liegender API möglicherweise oder auch nicht. Derzeit implementiert für Vulkan und Direct 3D 12. Bei D3D12 ist die Funktion nur verfügbar, wenn „ CastingFullyTypedFormatSupported “ unterstützt wird, siehe https://microsoft.github.io/DirectX-Specs/d3d/RelaxedCasting.html (beachten Sie, dass „ QRhi “ stets vollständig typisierte Formate für Texturen verwendet). Dieser Enum-Wert wurde in Qt 6.8 eingeführt. |
QRhi::ResolveDepthStencil | 43 | Gibt an, dass das Auflösen einer Multisample-Tiefen- oder Tiefen-Stencil-Textur unterstützt wird. Andernfalls ist „ setting a depth resolve texture “ nicht funktionsfähig und muss vermieden werden. Direct 3D 11 und 12 bieten keine Unterstützung für das Auflösen von Tiefen-/Tiefen-Stencil-Formaten, weshalb diese Funktion dort niemals unterstützt wird. Vulkan 1.0 verfügt über keine API, um das Auflösen eines Depth-Stencil-Anhangs anzufordern. Daher wird diese Funktion bei Vulkan erst ab Version 1.2 unterstützt sowie bei 1.1-Implementierungen, sofern die entsprechenden Erweiterungen vorhanden sind. Diese Funktion ist für den seltenen Fall vorgesehen, in dem eine Auflösung in eine Nicht-Multisample-Tiefentextur erforderlich wird, beispielsweise beim Rendern in eine von OpenXR bereitgestellte Tiefentextur (XR_KHR_composition_layer_depth). Dieser Enum-Wert wurde in Qt 6.8 eingeführt. |
QRhi::VariableRateShading | 44 | Gibt an, dass „Variable Rate Shading“ pro Zeichnungsvorgang (pro Pipeline) unterstützt wird. Wenn dies als unterstützt gemeldet wird, ist ` QRhiCommandBuffer::setShadingRate()` funktionsfähig und wirkt sich auf ` QRhiGraphicsPipeline `-Objekte aus, die in ihren Flags ` QRhiGraphicsPipeline::UsesShadingRate ` deklariert haben. Rufen Sie ` QRhi::supportedShadingRates()` auf, um zu prüfen, welche Raten unterstützt werden. (1x1 wird immer unterstützt, weitere typische Werte sind 2x2, 1x2, 2x1, 2x4, 4x2, 4x4). Es ist davon auszugehen, dass diese Funktion von Direct 3D 12 und Vulkan unterstützt wird, vorausgesetzt, die zur Laufzeit verwendete Implementierung und GPU unterstützen VRS. Dieser Enum-Wert wurde in Qt 6.9 eingeführt. |
QRhi::VariableRateShadingMap | 45 | Gibt an, dass eine bildbasierte Festlegung der Shading-Rate möglich ist. Das „Bild“ ist nicht zwangsläufig eine Textur, sondern kann je nach zugrunde liegendem Backend und Grafik-API zur Laufzeit auch ein natives 3D-API-Objekt sein. In der Praxis ist davon auszugehen, dass diese Funktion von Direct 3D 12, Vulkan und Metal unterstützt wird, vorausgesetzt, die GPU ist modern genug, um VRS zu unterstützen. Um zu prüfen, ob bildbasiertes VRS im D3D12-/Vulkan-Stil unterstützt wird, verwenden Sie stattdessen „VariableRateShadingMapWithTexture“. Wenn diese Funktion als unterstützt gemeldet wird, gibt es zwei Möglichkeiten: Ist „VariableRateShadingMapWithTexture“ ebenfalls wahr, dann verwendet „ QRhiShadingRateMap “ „ QRhiTexture “-Objekte über die Überladung von „createFrom()“, die ein „ QRhiTexture “-Argument akzeptiert. Ist „VariableRateShadingMapWithTexture“ falsch, dann verwendet „ QRhiShadingRateMap “ einen anderen Typ nativer Objekte, beispielsweise eine „MTLRasterizationRateMap“ im Fall von Metal. Verwenden Sie in diesem Fall die Überladung von `createFrom()`, die ein `NativeShadingRateMap`-Objekt erwartet. Dieser Enum-Wert wurde in Qt 6.9 eingeführt. |
QRhi::VariableRateShadingMapWithTexture | 46 | Gibt an, dass die bildbasierte Festlegung der Shading-Rate über reguläre Texturen unterstützt wird. In der Praxis wird dies möglicherweise von Direct 3D 12 und Vulkan unterstützt. Dieser Enum-Wert wurde in Qt 6.9 eingeführt. |
QRhi::PerRenderTargetBlending | 47 | Gibt an, dass das Blending pro Renderziel unterstützt wird, d. h., verschiedene Renderziele im MRT-Framebuffer können unterschiedliche Blending-Modi haben. In der Praxis ist davon auszugehen, dass dies überall unterstützt wird, außer bei OpenGL ES, wo es nur bei GLES-3.2-Implementierungen verfügbar ist. Dieser Enum-Wert wurde in Qt 6.9 eingeführt. |
QRhi::SampleVariables | 48 | Gibt an, dass die Variablen `gl_SampleID`, `gl_SamplePosition`, `gl_SampleMaskIn` und `gl_SampleMask` in Fragment-Shadern verfügbar sind. In der Praxis ist davon auszugehen, dass dies überall unterstützt wird, außer bei OpenGL ES, wo es nur bei GLES 3.2-Implementierungen verfügbar ist. Dieser Enum-Wert wurde in Qt 6.9 eingeführt. |
QRhi::InstanceIndexIncludesBaseInstance | 49 | Gibt an, dass „ gl_InstanceIndex “ die Basisinstanz (das Argument „ firstInstance “ in Draw-Aufrufen) in seinem Wert enthält. Wenn diese Funktion nicht unterstützt wird, „BaseInstance“ jedoch schon, bedeutet dies, dass „ gl_InstanceIndex “ immer bei 0 beginnt und nicht beim Basiswert. In der Praxis trifft dies derzeit auf Direct 3D 11 und 12 zu. Bei Vulkan und Metal wird erwartet, dass diese Funktion stets als unterstützt gemeldet wird. Dieser Enum-Wert wurde in Qt 6.11 eingeführt. |
QRhi::DepthClamp (since Qt 6.11) | 50 | Gibt an, dass die Aktivierung des Depth Clamping unterstützt wird. Wird dies als nicht unterstützt gemeldet – was bei OpenGL ES, OpenGL-Versionen vor 3.2 ohne die entsprechende Erweiterung sowie bei Metal auf dem iOS-Simulator der Fall ist –, hat der Aufruf von ` QRhiGraphicsPipeline::setDepthClamp()` mit dem Argument ` true ` keine Wirkung. |
QRhi::DrawIndirect (since Qt 6.12) | 51 | Gibt an, dass die Funktionen ` drawIndirect()` und ` drawIndexedIndirect()` verfügbar sind. In der Praxis ist davon auszugehen, dass dies überall unterstützt wird, außer bei OpenGL ES < 3.1. |
QRhi::DrawIndirectMulti (since Qt 6.12) | 52 | Gibt an, dass ein `drawCount > 1` vom Backend in den Funktionen ` drawIndirect()` und ` drawIndexedIndirect()` nativ unterstützt wird. Andernfalls werden mehrere Zeichenaufrufe von der RHI auf der CPU ausgegeben. In der Praxis ist davon auszugehen, dass dies unter Vulkan 1.1+, OpenGL 4.3+ und D3D12 unterstützt wird. |
QRhi::ShaderDrawParameters (since Qt 6.12) | 53 | Gibt an, dass die integrierten Variablen „ gl_BaseInstance “, „ gl_BaseVertex “ und „ gl_DrawID “ in Shadern verfügbar sind. In der Praxis ist davon auszugehen, dass dies unter Vulkan 1.1+ sowie bei Desktop-OpenGL 4.6 oder GL_ARB_shader_draw_parameters unterstützt wird. |
enum QRhi::Flag
flags QRhi::Flags
Beschreibt, welche Sonderfunktionen aktiviert werden sollen.
| Konstante | Wert | Beschreibung |
|---|---|---|
QRhi::EnableDebugMarkers | 1 << 0 | Aktiviert Debug-Marker-Gruppen. Ohne diese Einstellung stehen Funktionen zur Frame-Fehlersuche – wie das Erstellen von Debug-Gruppen und das Anzeigen benutzerdefinierter Ressourcennamen in externen GPU-Debugging-Tools – nicht zur Verfügung, und Funktionen wie ` QRhiCommandBuffer::debugMarkBegin()` werden zu No-Ops. Vermeiden Sie die Aktivierung in Produktionsbuilds, da dies zu einer geringfügigen Beeinträchtigung der Leistung führen kann. Hat keine Auswirkung, wenn die Funktion „ QRhi::DebugMarkers “ nicht als unterstützt gemeldet wird. |
QRhi::EnableTimestamps | 1 << 3 | Aktiviert die Erfassung von GPU-Zeitstempeln. Wenn diese Option nicht gesetzt ist, gibt ` QRhiCommandBuffer::lastCompletedGpuTime()` immer 0 zurück. Aktivieren Sie diese Option nur bei Bedarf, da je nach der zugrunde liegenden Grafik-API ein geringer Mehraufwand entstehen kann (z. B. durch Zeitstempelabfragen). Hat keine Auswirkung, wenn die Funktion „ QRhi::Timestamps “ nicht als unterstützt gemeldet wird. |
QRhi::PreferSoftwareRenderer | 1 << 1 | Gibt an, dass Backends vorrangig einen Adapter oder ein physisches Gerät wählen sollten, das per Software auf der CPU rendert. Bei Direct3D steht beispielsweise typischerweise ein „Basic Render Driver“-Adapter mit der Funktion ` DXGI_ADAPTER_FLAG_SOFTWARE` zur Verfügung. Durch Setzen dieses Flags wird das Backend angewiesen, diesen Adapter allen anderen vorzuziehen, sofern kein spezifischer Adapter durch andere backend-spezifische Mittel erzwungen wurde. Bei Vulkan entspricht dies der Bevorzugung physischer Geräte mit VK_PHYSICAL_DEVICE_TYPE_CPU. Ist dies nicht verfügbar oder lässt sich nicht feststellen, ob ein Adapter/Gerät softwarebasiert ist, wird dieses Flag ignoriert. Es kann auch bei Grafik-APIs ignoriert werden, die kein Konzept und keine Mittel zur Auflistung von Adaptern/Geräten haben. |
QRhi::EnablePipelineCacheDataSave | 1 << 2 | Ermöglicht das Abrufen des Pipeline-Cache-Inhalts, sofern zutreffend. Ist das Flag nicht gesetzt, gibt ` pipelineCacheData()` immer einen leeren Blob zurück. Bei Backends, bei denen das Abrufen und Wiederherstellen des Pipeline-Cache-Inhalts nicht unterstützt wird, hat das Flag keine Auswirkung und die serialisierten Cache-Daten sind immer leer. Das Flag bietet einen Opt-in-Mechanismus, da der Aufwand für die Pflege der zugehörigen Datenstrukturen bei einigen Backends nicht unerheblich ist. Bei Vulkan entspricht diese Funktion direkt VkPipelineCache, vkGetPipelineCacheData und VkPipelineCacheCreateInfo::pInitialData. Bei Direct3D 11 gibt es keinen echten Pipeline-Cache, aber die Ergebnisse von HLSL->DXBC-Kompilierungen werden gespeichert und können über diesen Mechanismus serialisiert bzw. deserialisiert werden. Dadurch lässt sich bei zukünftigen Ausführungen der Anwendungen der zeitaufwändige Aufruf von `D3DCompile()` für Shader überspringen, die als HLSL-Quellcode statt als offline vorkompilierter Bytecode vorliegen. Dies kann zu einer erheblichen Verkürzung der Start- und Ladezeiten führen, wenn viele HLSL-Quellcodes kompiliert werden müssen. Bei OpenGL wird der „Pipeline-Cache“ durch das Abrufen und Laden von Shader-Programm-Binärdateien simuliert (sofern vom Treiber unterstützt). Bei OpenGL gibt es zusätzliche, festplattenbasierte Caching-Mechanismen für Shader-/Programm-Binärdateien, die von Qt bereitgestellt werden. Das Schreiben in diese Caches kann deaktiviert werden, wenn dieses Flag gesetzt ist, da das Speichern von Programm-Binärdateien in mehreren Caches nicht sinnvoll ist. |
QRhi::SuppressSmokeTestWarnings | 1 << 4 | Gibt an, dass bei Backends, bei denen dies relevant ist, bestimmte, nicht schwerwiegende Fehler von „ QRhi::create()“ keine „ qWarning()“-Aufrufe auslösen sollten. Bei D3D11 beispielsweise führt die Übergabe dieses Flags dazu, dass eine Reihe von Warnmeldungen (die aufgrund eines Fehlers bei „ QRhi::create()“ erscheinen) stattdessen als Debug-Ausgaben unter der häufig verwendeten Protokollierungskategorie „ qt.rhi.general “ kategorisiert werden. Dies kann von Engines wie Qt Quick genutzt werden, die über eine Fallback-Logik verfügen, d. h., sie wiederholen den Aufruf von ` create()` mit einem anderen Satz von Flags (z. B. `PreferSoftwareRenderer`), um die bedingungslosen Warnungen aus der Ausgabe auszublenden, die angezeigt würden, wenn der erste Versuch mit ` create()` fehlgeschlagen wäre. |
Der Typ „Flags“ ist ein typedef für QFlags<Flag>. Er speichert eine ODER-Kombination von Flag-Werten.
enum QRhi::FrameOpResult
Beschreibt das Ergebnis von Operationen, bei denen ein „Soft-Fehler“ auftreten kann.
| Konstante | Wert | Beschreibung |
|---|---|---|
QRhi::FrameOpSuccess | 0 | Erfolg |
QRhi::FrameOpError | 1 | Nicht näher bezeichneter Fehler |
QRhi::FrameOpSwapChainOutOfDate | 2 | Die Swapchain befindet sich intern in einem inkonsistenten Zustand. Dies lässt sich möglicherweise beheben, indem Sie versuchen, den Vorgang (z. B. ` beginFrame()`) später zu wiederholen. |
QRhi::FrameOpDeviceLost | 3 | Das Grafikgerät ging verloren. Dies lässt sich möglicherweise beheben, indem Sie den Vorgang (z. B. ` beginFrame()`) wiederholen, nachdem Sie alle Objekte, die auf nativen Grafikressourcen basieren, freigegeben und neu initialisiert haben. Siehe ` isDeviceLost()`. |
enum QRhi::Implementation
Beschreibt, welches API-spezifische Backend von einer „ QRhi “-Instanz verwendet wird.
| Konstante | Wert |
|---|---|
QRhi::Null | 0 |
QRhi::Vulkan | 1 |
QRhi::OpenGLES2 | 2 |
QRhi::D3D11 | 3 |
QRhi::D3D12 | 5 |
QRhi::Metal | 4 |
enum QRhi::ResourceLimit
Beschreibt die Ressourcenbeschränkung für die Abfrage.
| Konstante | Wert | Beschreibung |
|---|---|---|
QRhi::TextureSizeMin | 1 | Mindestbreite und -höhe der Textur. Der Wert beträgt in der Regel 1. Die Mindestgröße der Textur wird flexibel gehandhabt, d. h., beim Versuch, eine Textur mit einer leeren Größe zu erstellen, wird stattdessen eine Textur mit der Mindestgröße erstellt. |
QRhi::TextureSizeMax | 2 | Maximale Breite und Höhe der Textur. Dies hängt von der Grafik-API und manchmal auch von der Plattform oder der Implementierung ab. In der Regel liegt der Wert im Bereich von 4096 bis 16384. Der Versuch, Texturen zu erstellen, die größer als dieser Wert sind, schlägt voraussichtlich fehl. |
QRhi::MaxColorAttachments | 3 | Die maximale Anzahl von Farb-Attachments für ein „ QRhiTextureRenderTarget “, falls mehrere Render-Targets unterstützt werden. Wenn MRT nicht unterstützt wird, beträgt der Wert 1. Andernfalls liegt dieser Wert in der Regel bei 8; beachten Sie jedoch, dass OpenGL lediglich 4 als Mindestwert vorschreibt und einige OpenGL ES-Implementierungen genau diesen Wert bereitstellen. |
QRhi::FramesInFlight | 4 | Die Anzahl der Frames, die das Backend „in Bearbeitung“ halten darf: Bei Backends wie Vulkan oder Metal liegt es in der Verantwortung von „ QRhi “, zu blockieren, wenn ein neuer Frame gestartet wird und festgestellt wird, dass die CPU bereits N - 1 Frames vor der GPU liegt (da der in Frame Nr. current – N übergebene Befehlspuffer noch nicht abgeschlossen ist). Der Wert N wird von hier zurückgegeben und beträgt typischerweise 2. Dies kann für Anwendungen relevant sein, die das Rendern direkt über die Grafik-API integrieren, da solcher Rendering-Code möglicherweise eine doppelte (wenn der Wert 2 ist) Pufferung für Ressourcen wie beispielsweise Puffer durchführen möchte, ähnlich wie bei den „ QRhi “-Backends selbst. Der aktuelle Frame-Slot-Index (ein Wert im Bereich von 0, 1, …, N-1, der dann von vorne beginnt) kann über ` QRhi::currentFrameSlot()` abgerufen werden. Der Wert beträgt 1 für Backends, bei denen die Grafik-API keine solche Low-Level-Steuerung über den Befehlsübermittlungsprozess bietet. Beachten Sie, dass Pipelining auch dann noch stattfinden kann, wenn dieser Wert 1 ist (einige Backends, wie z. B. D3D11, sind so konzipiert, dass sie versuchen, dies zu ermöglichen, beispielsweise durch Verwendung einer Aktualisierungsstrategie für Uniform-Puffer, die die Pipeline nicht blockiert), aber dies wird dann nicht von ` QRhi ` gesteuert und spiegelt sich daher hier in der API nicht wider. |
QRhi::MaxAsyncReadbackFrames | 5 | Die Anzahl der „ submitted “-Frames (einschließlich desjenigen, der das Readback enthält), nach deren Ablauf die vollständige Ausführung eines asynchronen Textur- oder Puffer-Readbacks bei ` starting a new frame` garantiert ist. |
QRhi::MaxThreadGroupsPerDimension | 6 | Die maximale Anzahl an Compute-Work-/Thread-Gruppen, die verteilt werden können. Tatsächlich der Maximalwert für die Argumente von ` QRhiCommandBuffer::dispatch()`. Typischerweise 65535. |
QRhi::MaxThreadsPerThreadGroup | 7 | Die maximale Anzahl von Aufrufen in einer einzelnen lokalen Arbeitsgruppe oder, anders ausgedrückt, die maximale Anzahl von Threads in einer Thread-Gruppe. Dies entspricht dem maximalen Wert für das Produkt aus local_size_x, local_size_y und local_size_z im Compute-Shader. Typische Werte sind 128, 256, 512, 1024 oder 1536. Beachten Sie, dass sowohl OpenGL ES als auch Vulkan lediglich 128 als erforderliche Mindestgrenze für Implementierungen festlegen. Während dies bei Vulkan selten vorkommt, unterstützen einige OpenGL ES 3.1-Implementierungen für mobile/eingebettete Geräte nur den in der Spezifikation vorgeschriebenen Mindestwert. |
QRhi::MaxThreadGroupX | 8 | Die maximale Größe einer Work-/Thread-Gruppe in der X-Dimension. Entspricht effektiv dem Maximalwert von „ local_size_x “ im Compute-Shader. Typischerweise 256 oder 1024. |
QRhi::MaxThreadGroupY | 9 | Die maximale Größe einer Work-/Thread-Gruppe in der Y-Dimension. Entspricht dem Maximalwert von „ local_size_y “ im Compute-Shader. Typischerweise 256 oder 1024. |
QRhi::MaxThreadGroupZ | 10 | Die maximale Größe einer Work-/Thread-Gruppe in der Z-Dimension. Entspricht dem Maximalwert von „ local_size_z “ im Compute-Shader. In der Regel 64 oder 256. |
QRhi::TextureArraySizeMax | 11 | Maximale Größe des Textur-Arrays. Liegt typischerweise im Bereich von 256 bis 2048. Der Versuch, „ create a texture array “ mit mehr Elementen auszuführen, schlägt wahrscheinlich fehl. |
QRhi::MaxUniformBufferRange | 12 | Die Anzahl der Bytes, die gleichzeitig aus einem Uniform-Puffer an die Shader übergeben werden können. Bei OpenGL ES 2.0- und 3.0-Implementierungen kann dieser Wert bis zu 3.584 Byte betragen (224 Vektoren mit vier Komponenten und 32 Bit pro Komponente). Ansonsten beträgt der Wert typischerweise 16.384 (1.024 „vec4“) oder 65.536 (4.096 „vec4“). |
QRhi::MaxVertexInputs | 13 | Die Anzahl der Eingabeattribute für den Vertex-Shader. Die Position in einem „ QRhiVertexInputAttribute “ muss im Bereich [0, MaxVertexInputs-1] liegen. Bei OpenGL ES 2.0 kann der Wert bis zu 8 betragen. Ansonsten liegen typische Werte bei 16, 31 oder 32. |
QRhi::MaxVertexOutputs | 14 | Die maximale Anzahl der Ausgänge (4-Komponenten-Vektor- out -Variablen) aus dem Vertex-Shader. Der Wert kann bei OpenGL ES 2.0 bis zu 8 betragen und bei OpenGL ES 3.0 sowie einigen Metal-Geräten bis zu 15. Ansonsten liegt ein typischer Wert bei 32. |
QRhi::ShadingRateImageTileSize | 15 | Die Kachelgröße für Shading-Rate-Texturen. 0, wenn die QRhi::VariableRateShadingMapWithTexture -Funktion nicht unterstützt wird. Andernfalls ein Wert wie beispielsweise 16, der eine Kachelgröße von 16x16 angibt. Jedes Byte in der (R8UI)-Shading-Rate-Textur definiert dann die Shading-Rate für eine Kachel von 16x16 Pixeln. Weitere Informationen finden Sie unter QRhiShadingRateMap. |
Dokumentation der Member-Funktionen
[noexcept] QRhi::~QRhi()
Destruktor. Löscht das Backend und gibt Ressourcen frei.
void QRhi::addCleanupCallback(const QRhi::CleanupCallback &callback)
Registriert eine ` callback `-Instanz, die aufgerufen wird, wenn die ` QRhi `-Instanz zerstört wird.
Der Callback wird ausgeführt, solange die Grafikressource noch verfügbar ist. Dies bietet der Anwendung die Möglichkeit, „ QRhiResource “-Instanzen, die zum „ QRhi “ gehören, ordnungsgemäß freizugeben. Dies ist besonders nützlich für die Verwaltung der Lebensdauer von Ressourcen, die in Objekten vom Typ „ cache “ gespeichert sind, wobei der Cache „QRhiResources“ oder Objekte enthält, die „QRhiResources“ enthalten.
Siehe auch ~QRhi().
void QRhi::addCleanupCallback(const void *key, const QRhi::CleanupCallback &callback)
Registriert „ callback “, damit diese Funktion aufgerufen wird, wenn „ QRhi “ zerstört wird. Diese Überladung nimmt einen undurchsichtigen Zeiger „ key “ entgegen, der sicherstellt, dass ein bestimmter Callback nur einmal registriert (und somit aufgerufen) wird.
Dies ist eine überladene Funktion.
Siehe auch ` removeCleanupCallback()`.
QRhi::Implementation QRhi::backend() const
Gibt den Backend-Typ für dieses „ QRhi “ zurück.
const char *QRhi::backendName() const
Gibt den Backend-Typ als Zeichenfolge für diese ` QRhi` zurück.
[static] const char *QRhi::backendName(QRhi::Implementation impl)
Gibt einen beschreibenden Namen für das Backend „ impl “ zurück, in der Regel den Namen der verwendeten 3D-API.
QRhi::FrameOpResult QRhi::beginFrame(QRhiSwapChain *swapChain, QRhi::BeginFrameFlags flags = {})
Startet einen neuen Frame, der auf den nächsten verfügbaren Puffer von „ swapChain “ abzielt.
Ein Frame besteht aus Ressourcenaktualisierungen und einem oder mehreren Render- und Rechen-Durchläufen.
flags kann bestimmte Sonderfälle angeben.
Das allgemeine Schema für das Rendern in eine „ QWindow “ mithilfe einer Swapchain:
- Erstellen Sie eine Swapchain.
- Rufen Sie ` QRhiSwapChain::createOrResize()` auf, sobald sich die Oberflächengröße gegenüber zuvor geändert hat.
- Rufen Sie „ QRhiSwapChain::destroy()“ auf „ QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed “ auf.
- Anschließend bei jedem Frame:
beginFrame(sc); updates = nextResourceUpdateBatch(); updates->... QRhiCommandBuffer *cb = sc->currentFrameCommandBuffer(); cb->beginPass(sc->currentFrameRenderTarget(), colorClear, dsClear, updates); ... cb->endPass(); ... // more passes as necessary endFrame(sc);
Gibt bei Erfolg ` QRhi::FrameOpSuccess ` zurück, bei einem Fehler einen anderen Wert von ` QRhi::FrameOpResult `. Einige dieser Fehler sollten als „weiche“ Fehler behandelt werden, bei denen es heißt: „Später erneut versuchen“: Wenn ` QRhi::FrameOpSwapChainOutOfDate ` zurückgegeben wird, muss die Swapchain durch Aufruf von ` QRhiSwapChain::createOrResize()` in der Größe angepasst oder aktualisiert werden. Die Anwendung sollte dann versuchen, einen neuen Frame zu generieren. „ QRhi::FrameOpDeviceLost “ bedeutet, dass das Grafikgerät verloren gegangen ist; dies lässt sich jedoch möglicherweise beheben, indem alle Ressourcen, einschließlich des „ QRhi “ selbst, freigegeben und anschließend alle Ressourcen neu erstellt werden. Weitere Informationen finden Sie unter „ isDeviceLost()“.
Siehe auch endFrame(), beginOffscreenFrame() und isDeviceLost().
QRhi::FrameOpResult QRhi::beginOffscreenFrame(QRhiCommandBuffer **cb, QRhi::BeginFrameFlags flags = {})
Startet einen neuen Offscreen-Frame. Stellt einen Befehlspuffer bereit, der sich zur Aufzeichnung von Rendering-Befehlen in „ cb “ eignet. „ flags “ wird verwendet, um bestimmte Sonderfälle anzugeben, genau wie bei „ beginFrame()“.
Hinweis: Die in *cb gespeicherte „ QRhiCommandBuffer “ gehört nicht dem Aufrufer.
Das Rendern ohne Swapchain ist ebenfalls möglich. Ein typischer Anwendungsfall ist der Einsatz in vollständig Offscreen-basierten Anwendungen, z. B. zur Erzeugung von Bildsequenzen durch Rendern und Zurücklesen, ohne jemals ein Fenster anzuzeigen.
Die Verwendung in On-Screen-Anwendungen (also „ beginFrame “, „ endFrame “, „beginOffscreenFrame“, „ endOffscreenFrame “, „ beginFrame “, …) ist ebenfalls möglich.
Wenn ein Readback über ` texture ` oder ` buffer ` geplant wurde, verhindern Offscreen-Frames, dass die CPU möglicherweise einen weiteren Frame generiert, während die GPU noch den vorherigen verarbeitet. Dies hat den Nebeneffekt, dass bei geplanten Readbacks die Ergebnisse garantiert verfügbar sind, sobald ` endOffscreenFrame()` zurückkehrt. Bei Frames, die auf eine Swapchain abzielen, ist dies nicht der Fall: Dort wird die GPU potenziell besser ausgelastet, doch die Arbeit mit Readback-Operationen erfordert mehr Sorgfalt seitens der Anwendung, da endFrame() – im Gegensatz zu endOffscreenFrame() – nicht garantiert, dass die Ergebnisse des Readbacks zu diesem Zeitpunkt verfügbar sind.
Das Grundgerüst für das Rendern eines Frames ohne Swapchain und das anschließende Zurücklesen des Frame-Inhalts könnte wie folgt aussehen:
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 rbResultSiehe auch endOffscreenFrame() und beginFrame().
QMatrix4x4 QRhi::clipSpaceCorrMatrix() const
Gibt eine Matrix zurück, mit der Anwendungen weiterhin OpenGL-spezifische Vertexdaten und perspektivische Projektionsmatrizen (wie beispielsweise die von QMatrix4x4::perspective() generierten) verwenden können, unabhängig vom aktiven Backend von QRhi.
In einem typischen Renderer können, sobald this_matrix * mvp anstelle von lediglich mvp verwendet wird, Vertex-Daten mit Y-Achse nach oben und Viewports mit einem Tiefenbereich von 0 bis 1 verwendet werden, ohne dass berücksichtigt werden muss, welches Backend (und damit welche Grafik-API) zur Laufzeit zum Einsatz kommt. Auf diese Weise lassen sich Verzweigungen auf Basis von ` isYUpInNDC()` und ` isClipDepthZeroToOne()` vermeiden (auch wenn eine solche Logik bei der Implementierung bestimmter fortgeschrittener Grafiktechniken dennoch erforderlich werden kann).
Auf dieser Seite finden Sie eine Erörterung des Themas aus der Perspektive von Vulkan.
[static] QRhi *QRhi::create(QRhi::Implementation impl, QRhiInitParams *params, QRhi::Flags flags, QRhiNativeHandles *importDevice, QRhiAdapter *adapter)
Gibt eine neue Instanz von ` QRhi ` zurück, deren Backend für die durch ` impl ` angegebene Grafik-API die angegebene ` flags` verwendet. Gibt ` nullptr ` zurück, wenn die Funktion fehlschlägt.
params muss auf eine Instanz einer der backend-spezifischen Unterklassen von ` QRhiInitParams` verweisen, wie beispielsweise ` QRhiVulkanInitParams`, ` QRhiMetalInitParams`, ` QRhiD3D11InitParams`, ` QRhiD3D12InitParams` oder ` QRhiGles2InitParams`. Beispiele zum Erstellen eines ` QRhi` finden Sie in den Beschreibungen dieser Klassen.
QRhi Implementiert grundsätzlich keine Fallback-Logik: Wenn die angegebene API nicht initialisiert werden kann, schlägt `create()` fehl, wobei die Backends Warnungen in der Debug-Ausgabe ausgeben. Die Clients von ` QRhi`, zum Beispiel ` Qt Quick`, können jedoch je nach Plattform zusätzliche Logik bereitstellen, die einen Fallback auf eine andere als die angeforderte API ermöglicht. Wenn lediglich geprüft werden soll, ob die Initialisierung beim späteren Aufruf von `create()` erfolgreich wäre, ist es vorzuziehen, ` probe()` anstelle von `create()` zu verwenden, da bei einigen Backends das Abfragen auf eine schlankere Weise implementiert werden kann als bei `create()`, das eine vollständige Initialisierung der Infrastruktur durchführt und verschwenderisch ist, wenn diese ` QRhi `-Instanz anschließend sofort verworfen wird.
importDevice Ermöglicht die Verwendung eines bereits vorhandenen Grafikgeräts, ohne dass QRhi ein eigenes erstellt. Wenn dieser Parameter nicht null ist, muss er auf eine Instanz einer der Unterklassen von QRhiNativeHandles verweisen: QRhiVulkanNativeHandles, QRhiD3D11NativeHandles, QRhiD3D12NativeHandles, QRhiMetalNativeHandles, QRhiGles2NativeHandles. Die genauen Details und die Semantik hängen vom Backend und der zugrunde liegenden Grafik-API ab.
Die Angabe eines „ QRhiAdapter “ in „ adapter “ bietet eine transparente, API-übergreifende Alternative zur Übergabe eines „ VkPhysicalDevice “ über „ QRhiVulkanNativeHandles “ oder einer Adapter-LUID über „ QRhiD3D12NativeHandles “. Die Eigentumsrechte an „ adapter “ werden nicht übernommen. Weitere Informationen zu diesem Ansatz finden Sie unter „ enumerateAdapters()“.
Hinweis: importDevice und adapter können nicht gleichzeitig angegeben werden.
Siehe auch probe().
[static] QRhi *QRhi::create(QRhi::Implementation impl, QRhiInitParams *params, QRhi::Flags flags = {}, QRhiNativeHandles *importDevice = nullptr)
Entspricht create(impl, params, flags, importDevice, nullptr).
Dies ist eine überladene Funktion.
int QRhi::currentFrameSlot() const
Gibt während der Aufzeichnung eines Frames den aktuellen Frame-Slot-Index zurück. Der Wert ist nicht definiert, wenn die Funktion außerhalb eines aktiven Frames aufgerufen wird (d. h. wenn isRecordingFrame() auf „ false “ gesetzt ist).
Bei Backends wie Vulkan oder Metal liegt es in der Verantwortung des „ QRhi “-Backends, bei jedem Start eines neuen Frames zu blockieren, wenn festgestellt wird, dass die CPU der GPU bereits FramesInFlight - 1 Frames voraus ist (da der im Frame Nr. current – FramesInFlight übermittelte Befehlspuffer noch nicht abgeschlossen ist).
Ressourcen, die sich zwischen den Frames tendenziell ändern (wie beispielsweise das native Pufferobjekt, das einem QRhiBuffer vom Typ QRhiBuffer::Dynamic zugrunde liegt), existieren in mehreren Versionen, sodass jeder Frame – der übermittelt werden kann, während ein vorheriger noch verarbeitet wird – mit einer eigenen Kopie arbeitet. Dadurch wird vermieden, dass die Pipeline bei der Vorbereitung des Frames angehalten werden muss. (Der Inhalt einer Ressource, die möglicherweise noch auf der GPU genutzt wird, sollte nicht verändert werden; jedoch würde ein ständiges Warten auf den Abschluss des vorherigen Frames die GPU-Auslastung und letztlich die Leistung und Effizienz verringern.)
Konzeptionell ähnelt dies in gewisser Weise den „Copy-on-Write“-Verfahren, die von einigen C++-Containern und anderen Typen verwendet werden. Es könnte auch dem ähneln, was eine OpenGL- oder Direct 3D 11-Implementierung intern für bestimmte Objekttypen durchführt.
In der Praxis wird eine solche doppelte (oder dreifache) Pufferung von Ressourcen in den Backends von Vulkan, Metal und ähnlichen „ QRhi “-Backends dadurch realisiert, dass hinter einem „ QRhiResource “ eine feste Anzahl nativer Ressourcen (wie z. B. VkBuffer) slots bereitgestellt wird. Diese können dann durch einen Frame-Slot-Index indiziert werden, der von 0, 1, …, FramesInFlight-1 verläuft und dann wieder von vorne beginnt.
All dies wird für die Nutzer von QRhi transparent verwaltet. Anwendungen, die das Rendering direkt über die Grafik-API integrieren, möchten jedoch möglicherweise eine ähnliche Doppel- oder Dreifachpufferung ihrer eigenen Grafikressourcen durchführen. Dies lässt sich am einfachsten erreichen, indem man die Werte für die maximale Anzahl an in Bearbeitung befindlichen Frames (abrufbar über ` resourceLimit()`) und den aktuellen Frame- (Slot-)Index (von dieser Funktion zurückgegeben) kennt.
Siehe auch isRecordingFrame(), beginFrame() und endFrame().
QRhiDriverInfo QRhi::driverInfo() const
Gibt Metadaten für das Grafikgerät zurück, das von dieser erfolgreich initialisierten „ QRhi “-Instanz verwendet wird.
QRhi::FrameOpResult QRhi::endFrame(QRhiSwapChain *swapChain, QRhi::EndFrameFlags flags = {})
Beendet, übergibt und präsentiert einen Frame, der im letzten Aufruf von ` beginFrame()` auf ` swapChain` gestartet wurde.
Die doppelte (oder dreifache) Pufferung wird intern von „ QRhiSwapChain “ und „ QRhi “ verwaltet.
flags kann optional verwendet werden, um das Verhalten in bestimmter Weise zu ändern. Durch die Übergabe von ` QRhi::SkipPresent ` wird das Einreihen des `Present`-Befehls oder der Aufruf von `swapBuffers` übersprungen.
Gibt bei Erfolg QRhi::FrameOpSuccess zurück, bei einem Fehler einen anderen Wert von QRhi::FrameOpResult. Einige dieser Fehler sollten als „weiche“ Fehler vom Typ „Später erneut versuchen“ behandelt werden: Wenn QRhi::FrameOpSwapChainOutOfDate zurückgegeben wird, muss die Swapchain durch den Aufruf von QRhiSwapChain::createOrResize() in der Größe angepasst oder aktualisiert werden. Die Anwendung sollte dann versuchen, einen neuen Frame zu generieren. „ QRhi::FrameOpDeviceLost “ bedeutet, dass das Grafikgerät verloren gegangen ist; dies lässt sich jedoch möglicherweise beheben, indem alle Ressourcen, einschließlich der „ QRhi “ selbst, freigegeben und anschließend alle Ressourcen neu erstellt werden. Weitere Informationen finden Sie unter „ isDeviceLost()“.
Siehe auch beginFrame() und isDeviceLost().
QRhi::FrameOpResult QRhi::endOffscreenFrame(QRhi::EndFrameFlags flags = {})
Beendet den Vorgang, übermittelt die Daten und wartet gegebenenfalls auf den Offscreen-Frame.
Im Gegensatz zu „ endFrame()“ blockiert diese Funktion und wartet auf den Abschluss der GPU-seitigen Arbeit, wenn aktive Puffer- oder Textur-Readbacks vorliegen.
flags wird derzeit nicht verwendet.
Siehe auch ` beginOffscreenFrame()`.
[static, since 6.10] QRhi::AdapterList QRhi::enumerateAdapters(QRhi::Implementation impl, QRhiInitParams *params, QRhiNativeHandles *nativeHandles = nullptr)
Gibt die Liste der vorhandenen Adapter (physische Geräte) zurück oder eine leere Liste, wenn diese Steuerungsmöglichkeit bei der angegebenen Grafik-API nicht verfügbar ist.
Bei Backends, bei denen eine solche Steuerungsmöglichkeit nicht verfügbar ist, ist die zurückgegebene Liste immer leer. Eine leere Liste bedeutet daher nicht, dass sich keine Grafikgeräte im System befinden, sondern dass keine detaillierte Steuerung hinsichtlich der Auswahl des zu verwendenden Geräts möglich ist.
Bei Backends für Direct 3D 11, Direct 3D 12 und Vulkan ist davon auszugehen, dass sie die Aufzählung von Adaptern vollständig unterstützen. Bei anderen Backends ist dies möglicherweise nicht der Fall. Das Backend wird durch ` impl` angegeben. Ein von dieser Funktion zurückgegebenes ` QRhiAdapter ` darf nur in einem Aufruf von ` create()` mit demselben ` impl` verwendet werden. Einige zugrunde liegende APIs können weitere Einschränkungen aufweisen; insbesondere bei Vulkan ist das ` QRhiAdapter ` auf das ` QVulkanInstance ` festgelegt (`VkInstance`).
Vom Aufrufer wird erwartet, dass er die Objekte „ QRhiAdapter “ in der Liste löscht. Abgesehen von der Abfrage von „ info()“ besteht der einzige Zweck dieser Objekte darin, an „ create()“ oder die entsprechenden Funktionen in höheren Schichten wie „ Qt Quick “ übergeben zu werden.
Der folgende, speziell für Vulkan geschriebene Codeausschnitt zeigt, wie man die verfügbaren physikalischen Geräte auflistet und die Erstellung eines „ QRhi “ für das ausgewählte Gerät anfordert. Dies entspricht in der Praxis der Übergabe eines „ VkPhysicalDevice “ über ein „ QRhiVulkanNativeHandles “ an „ create()“, erfordert jedoch auf der Anwendungsseite weniger API-spezifischen Code:
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);Die Übergabe von ` params ` ist aufgrund der Konzeption einiger der zugrunde liegenden Grafik-APIs erforderlich. Insbesondere bei Vulkan muss die ` QVulkanInstance ` angegeben werden, da ohne diese keine Aufzählung möglich ist. Andere Felder im backend-spezifischen ` params ` werden von dieser Funktion nicht tatsächlich verwendet.
nativeHandles ist optional. Wenn es angegeben wird, muss es sich um ein gültiges ` QRhiD3D11NativeHandles`, ` QRhiD3D12NativeHandles` oder ` QRhiVulkanNativeHandles` handeln, ähnlich wie bei ` create()`. Im Gegensatz zu ` create()` werden jedoch nur die Felder für das physische Gerät (im Fall von Vulkan) oder die Adapter-LUID (im Fall von D3D) verwendet; alle anderen Felder werden ignoriert. Dies kann genutzt werden, um die Ergebnisse auf einen bestimmten Adapter zu beschränken. Die zurückgegebene Liste enthält in diesem Fall 1 oder 0 Elemente.
Beachten Sie, dass die Implementierung der Funktion `looksGood()` im vorherigen Codeausschnitt keine plattformspezifische Filterung auf Basis der tatsächlichen Adapter- bzw. physischen Geräte-Identität durchführen kann, wie beispielsweise die Adapter-LUID unter Windows oder das `VkPhysicalDevice` bei Vulkan. Dies liegt daran, dass ` QRhiDriverInfo ` keine plattformspezifischen Daten enthält. Verwenden Sie stattdessen ` nativeHandles `, um die Ergebnisse bereits innerhalb von `enumerateAdapters()` gefiltert zu erhalten.
Die folgenden beiden Codeausschnitte, die Direct 3D 12 als Beispiel verwenden, sind in der Praxis gleichwertig:
// „enumerateAdapters“-basierter Ansatz ab Qt 6.10
QRhiD3D12InitParams initParams;
QRhiD3D12NativeHandles nativeHandles;
nativeHandles.adapterLuidLow = luid.LowPart; // LUID wurde von irgendwoher abgerufen, nun an Qt übergeben
nativeHandles.adapterLuidHigh = luid.HighPart;
QRhi::AdapterList adapters = QRhi::enumerateAdapters(QRhi::D3D12, &initParams, &nativeHandles);
if (adapters.isEmpty()) { qWarning(„Der angeforderte Adapter wurde nicht gefunden“); }
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);Diese Funktion wurde in Qt 6.10 eingeführt.
Siehe auch „ create()“.
QRhi::FrameOpResult QRhi::finish()
Wartet, bis alle Aufgaben in der Grafikwarteschlange (sofern vorhanden) abgeschlossen sind, und führt anschließend alle zurückgestellten Operationen aus, wie z. B. das Abschließen von Readbacks und das Freigeben von Ressourcen. Kann innerhalb und außerhalb eines Frames aufgerufen werden, jedoch nicht innerhalb eines Passes. Innerhalb eines Frames bedeutet dies, dass alle Aufgaben im Befehlspuffer übermittelt werden.
Hinweis: Vermeiden Sie diese Funktion. Ein Fall, in dem sie erforderlich sein könnte, ist, wenn die Ergebnisse eines in die Warteschlange gestellten Readbacks in einem Swapchain-basierten Frame zu einem festgelegten Zeitpunkt benötigt werden und daher das Warten auf die Ergebnisse erwünscht ist.
bool QRhi::isClipDepthZeroToOne() const
Gibt „ true “ zurück, wenn die zugrunde liegende Grafik-API im Clip-Raum den Tiefenbereich [0, 1] verwendet.
false In der Praxis gilt dies nur für OpenGL, da OpenGL einen Tiefenbereich von [-1, 1] nach der Projektion verwendet. (Nicht zu verwechseln mit der durch `glDepthRange()` gesteuerten NDC-zu-Fenster-Zuordnung, die einen Bereich von [0, 1] verwendet, sofern dies nicht durch die ` QRhiViewport` überschrieben wird.) In einigen OpenGL-Versionen konnte glClipControl() verwendet werden, um dies zu ändern, aber das OpenGL-Backend von QRhi verwendet diese Funktion nicht, da sie in OpenGL ES oder OpenGL-Versionen unter 4.5 nicht verfügbar ist.
Hinweis: ` clipSpaceCorrMatrix()` enthält die entsprechende Anpassung in der zurückgegebenen Matrix. Daher müssen viele Nutzer von „ QRhi “ keine weiteren Maßnahmen ergreifen, abgesehen von der Vormultiplikation ihrer Projektionsmatrizen mit „ clipSpaceCorrMatrix()“. Einige Grafiktechniken, wie beispielsweise bestimmte Arten des Shadow-Mappings, beinhalten jedoch die Verarbeitung und Ausgabe von Tiefenwerten in den Shadern. Diese müssen den Wert dieser Funktion abfragen und entsprechend berücksichtigen.
bool QRhi::isDeviceLost() const
Gibt „true“ zurück, wenn das Grafikgerät verloren gegangen ist.
Der Verlust des Geräts wird in der Regel in den Funktionen „ beginFrame()“, „ endFrame()“ oder „ QRhiSwapChain::createOrResize()“ erkannt, abhängig vom Backend und den zugrunde liegenden nativen APIs. Am häufigsten ist „ endFrame()“, da dort die Darstellung erfolgt. Bei einigen Backends kann auch „ QRhiSwapChain::createOrResize()“ aufgrund eines Geräteverlusts fehlschlagen. Daher wird diese Funktion als generische Möglichkeit bereitgestellt, um zu prüfen, ob bei einem vorherigen Vorgang ein Geräteverlust erkannt wurde.
Wenn das Gerät verloren gegangen ist, sollten keine weiteren Operationen über die ` QRhi` durchgeführt werden. Stattdessen sollten alle ` QRhi `-Ressourcen freigegeben und anschließend die ` QRhi` zerstört werden. Anschließend kann versucht werden, eine neue ` QRhi ` zu erstellen. Bei Erfolg müssen alle Grafikressourcen neu initialisiert werden. Ist dies nicht der Fall, versuchen Sie es später erneut – und wiederholen Sie den Vorgang so oft wie nötig.
Während einfache Anwendungen den Verlust eines Geräts möglicherweise ignorieren, kann es auf den gängigen Desktop-Plattformen aus verschiedenen Gründen zu einem Geräteverlust kommen, darunter das physische Trennen der Grafikkarte, das Deaktivieren des Geräts oder des Treibers, die Deinstallation oder Aktualisierung des Grafiktreibers oder Fehler, die zu einem Reset des Grafikgeräts führen. Einige dieser Ereignisse können auch unter völlig normalen Umständen auftreten; so ist beispielsweise die Aktualisierung des Grafiktreibers auf eine neuere Version eine gängige Aufgabe, die jederzeit während der Ausführung einer Qt-Anwendung stattfinden kann. Benutzer erwarten durchaus, dass Anwendungen dies überstehen, selbst wenn die Anwendung aktiv eine API wie OpenGL oder Direct3D nutzt.
Von den Qt-eigenen Frameworks, die auf QRhi aufbauen, wie beispielsweise Qt Quick, kann erwartet werden, dass sie den Verlust eines Geräts verarbeiten und geeignete Maßnahmen ergreifen. Sind die Daten für Grafikressourcen wie Texturen und Puffer auf der CPU-Seite noch verfügbar, ist ein solches Ereignis auf Anwendungsebene möglicherweise gar nicht wahrnehmbar, da die Grafikressourcen dann nahtlos neu initialisiert werden können. Von Anwendungen und Bibliotheken, die direkt mit QRhi arbeiten, wird jedoch erwartet, dass sie darauf vorbereitet sind, Situationen eines Geräteverlusts selbst zu prüfen und zu bewältigen.
Hinweis: Bei OpenGL müssen Anwendungen sich möglicherweise für Benachrichtigungen über Kontext-Resets anmelden, indem sie „ QSurfaceFormat::ResetNotification “ auf dem „ QOpenGLContext “ setzen. Dies geschieht in der Regel durch Aktivieren des Flags in „ QRhiGles2InitParams::format “. Beachten Sie jedoch, dass einige Systeme auch dann Kontext-Resets auslösen können, wenn dieses Flag nicht gesetzt ist.
bool QRhi::isFeatureSupported(QRhi::Feature feature) const
Gibt „ true “ zurück, wenn die angegebene „ feature “ unterstützt wird
bool QRhi::isRecordingFrame() const
Gibt „true“ zurück, wenn ein aktiver Frame vorhanden ist, d. h., wenn ein Aufruf von „ beginFrame()“ (oder „ beginOffscreenFrame()“) erfolgte, ohne dass bisher ein entsprechender Aufruf von „ endFrame()“ (oder „ endOffscreenFrame()“) stattgefunden hat.
Siehe auch currentFrameSlot(), beginFrame() und endFrame().
bool QRhi::isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags = {}) const
Gibt „ true “ zurück, wenn die angegebene Textur format, die durch flags modifiziert wurde, unterstützt wird.
Die Abfrage wird sowohl für unkomprimierte als auch für komprimierte Formate unterstützt.
bool QRhi::isYUpInFramebuffer() const
Gibt „ true “ zurück, wenn bei der zugrunde liegenden Grafik-API die Y-Achse in Framebuffern und Bildern nach oben zeigt.
In der Praxis ist dies nur für OpenGL der Wert „ true “.
bool QRhi::isYUpInNDC() const
Gibt „ true “ zurück, wenn die zugrunde liegende Grafik-API in ihrem normalisierten Gerätekordinatensystem die Y-Achse nach oben ausrichtet.
In der Praxis ist dies nur für Vulkan der Fall: ` false `.
Hinweis: ` clipSpaceCorrMatrix()` berücksichtigt die entsprechende Anpassung (damit die Y-Achse nach oben zeigt) in der zurückgegebenen Matrix.
bool QRhi::makeThreadLocalNativeContextCurrent()
Bei OpenGL wird dadurch der OpenGL-Kontext im aktuellen Thread als aktueller festgelegt. Bei anderen Backends hat die Funktion keine Auswirkung.
Der Aufruf dieser Funktion ist typischerweise im Qt-Framework-Code relevant, wenn sichergestellt werden muss, dass externer OpenGL-Code, der von der Anwendung bereitgestellt wird, weiterhin wie zuvor bei direkter Nutzung von OpenGL ausgeführt werden kann, solange der ` QRhi ` das OpenGL-Backend verwendet.
Gibt bei einem Fehler „false“ zurück, ähnlich wie „ QOpenGLContext::makeCurrent()“. Wenn der Vorgang fehlgeschlagen ist, kann „ isDeviceLost()“ aufgerufen werden, um festzustellen, ob ein Kontextverlust vorliegt. Eine solche Überprüfung entspricht der Überprüfung über „ QOpenGLContext::isValid()“.
Siehe auch QOpenGLContext::makeCurrent() und QOpenGLContext::isValid().
[static] int QRhi::mipLevelsForSize(const QSize &size)
Gibt die Anzahl der Mip-Stufen für eine bestimmte „ size “ zurück.
const QRhiNativeHandles *QRhi::nativeHandles()
Gibt einen Zeiger auf die backend-spezifische Sammlung nativer Objekte für das Gerät, den Kontext und ähnliche vom Backend verwendete Konzepte zurück.
Wandeln Sie den Zeiger je nach Bedarf in „ QRhiVulkanNativeHandles “, „ QRhiD3D11NativeHandles “, „ QRhiD3D12NativeHandles “, „ QRhiGles2NativeHandles “ oder „ QRhiMetalNativeHandles “ um.
Hinweis: Es erfolgtkeine Eigentumsübertragung, weder für den zurückgegebenen Zeiger noch für native Objekte.
QRhiBuffer *QRhi::newBuffer(QRhiBuffer::Type type, QRhiBuffer::UsageFlags usage, quint32 size)
Gibt einen neuen Puffer mit den angegebenen Werten für „ type “, „ usage “ und „ size “ zurück.
Hinweis: Einige Kombinationen aus usage und type werden möglicherweise nicht von allen Backends unterstützt. Siehe UsageFlags und the feature flags.
Hinweis: Backends können Puffer zuweisen, die größer sind als size. Dies geschieht für Anwendungen transparent, sodass es keine besonderen Einschränkungen hinsichtlich des Werts von size gibt. QRhiBuffer::size() gibt immer den Wert zurück, der in size angefordert wurde.
Siehe auch QRhiResource::destroy().
QRhiComputePipeline *QRhi::newComputePipeline()
Gibt eine neue Compute-Pipeline-Ressource zurück.
Hinweis: „Compute“ ist nur verfügbar, wenn die Funktion „ Compute “ als unterstützt gemeldet wird.
Siehe auch „ QRhiResource::destroy“ ().
QRhiGraphicsPipeline *QRhi::newGraphicsPipeline()
Gibt eine neue Grafik-Pipeline-Ressource zurück.
Siehe auch „ QRhiResource::destroy()“.
QRhiRenderBuffer *QRhi::newRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize, int sampleCount = 1, QRhiRenderBuffer::Flags flags = {}, QRhiTexture::Format backingFormatHint = QRhiTexture::UnknownFormat)
Gibt einen neuen Renderbuffer mit den angegebenen Werten für „ type “, „ pixelSize “, „ sampleCount “ und „ flags “ zurück.
Wenn „ backingFormatHint “ auf ein anderes Texturformat als „ QRhiTexture::UnknownFormat “ gesetzt ist, kann es vom Backend verwendet werden, um zu entscheiden, welches Format für den Speicher hinter dem Renderbuffer verwendet werden soll.
Hinweis: „ backingFormatHint “ spielt typischerweise dann eine Rolle, wenn Multisampling und Fließkomma-Texturformate im Spiel sind: Das Rendern in ein Multisample- QRhiRenderBuffer und die anschließende Auflösung in ein Nicht-RGBA8- QRhiTexture bedeutet (bei einigen Grafik-APIs), dass der Speicher, auf dem der QRhiRenderBuffer basiert, das passende Nicht-RGBA8-Format verwendet. Das bedeutet, dass die Übergabe eines Formats wie QRhiTexture::RGBA32F wichtig ist, da Backends standardmäßig in der Regel QRhiTexture::RGBA8 wählen, was später zu Fehlern führen würde, da versucht wird, eine Multisample-Auflösung von RGBA8 nach RGBA32F in den Farb-Attachments des QRhiTextureRenderTarget einzurichten.
Siehe auch 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)
Gibt einen neuen Sampler mit dem angegebenen Vergrößerungsfilter magFilter, dem Verkleinerungsfilter minFilter, dem Mipmapping-Modus mipmapMode sowie den Adressierungs- (Wrap-)Modi addressU, addressV und addressW zurück.
Hinweis: Wird „ mipmapMode “ auf einen anderen Wert als „ None “gesetzt , bedeutet dies, dass Bilder für alle relevanten Mip-Ebenen entweder über „ texture uploads “ oder durch Aufruf von „ generateMips()“ für die mit diesem Sampler verwendete Textur bereitgestellt werden müssen. Der Versuch, den Sampler mit einer Textur zu verwenden, die keine Daten für alle relevanten Mip-Stufen enthält, führt zu Renderfehlern, wobei das genaue Verhalten von der zugrunde liegenden Grafik-API abhängt.
Siehe auch ` QRhiResource::destroy()`.
QRhiShaderResourceBindings *QRhi::newShaderResourceBindings()
Gibt eine neue Shader-Ressourcen-Bindungs-Sammlungsressource zurück.
Siehe auch „ QRhiResource::destroy()“.
[since 6.9] QRhiShadingRateMap *QRhi::newShadingRateMap()
Gibt ein neues Shading-Rate-Map-Objekt zurück.
Diese Funktion wurde in Qt 6.9 eingeführt.
QRhiSwapChain *QRhi::newSwapChain()
Gibt eine neue Swapchain zurück.
Siehe auch QRhiResource::destroy() und QRhiSwapChain::createOrResize().
QRhiTexture *QRhi::newTexture(QRhiTexture::Format format, const QSize &pixelSize, int sampleCount = 1, QRhiTexture::Flags flags = {})
Gibt eine neue 1D- oder 2D-Textur mit den angegebenen Werten für „ format “, „ pixelSize “, „ sampleCount “ und „ flags “ zurück.
Bei einer 1D-Textur muss das Flag „ QRhiTexture::OneDimensional “ in „ flags “ gesetzt sein. Diese Funktion setzt dieses Flag implizit, wenn die Höhe von „ pixelSize “ 0 ist.
Hinweis: „ format “ legt das gewünschte interne und externe Format fest, was bedeutet, dass die in die Textur hochzuladenden Daten in einem kompatiblen Format vorliegen müssen, während die native Textur dieses Format intern verwenden kann (was jedoch zumindest im Fall von OpenGL nicht garantiert ist).
Hinweis: 1D-Texturen funktionieren nur, wenn die Funktion „ OneDimensionalTextures “ zur Laufzeit als unterstützt gemeldet wird. Außerdem funktionieren Mipmaps auf 1D-Texturen nur, wenn die Funktion „ OneDimensionalTextureMipmaps “ zur Laufzeit gemeldet wird.
Siehe auch ` QRhiResource::destroy()`.
QRhiTexture *QRhi::newTexture(QRhiTexture::Format format, int width, int height, int depth, int sampleCount = 1, QRhiTexture::Flags flags = {})
Gibt eine neue 1D-, 2D- oder 3D-Textur mit den angegebenen Werten für „ format “, „ width “, „ height “, „ depth “, „ sampleCount “ und „ flags “ zurück.
Diese Überladung eignet sich für 3D-Texturen, da sie die Angabe von „ depth “ ermöglicht. Bei einer 3D-Textur muss „ QRhiTexture::ThreeDimensional “ in „ flags “ gesetzt sein; bei Verwendung dieser Überladung kann dies jedoch weggelassen werden, da das Flag implizit gesetzt wird, sobald „ depth “ größer als 0 ist. Für 1D-, 2D- und Würfeltexturen sollte „ depth “ auf 0 gesetzt werden.
Bei einer 1D-Textur muss „ QRhiTexture::OneDimensional “ in „ flags “ gesetzt sein. Diese Überladung setzt dieses Flag implizit, wenn sowohl „ height “ als auch „ depth “ den Wert 0 haben.
Hinweis: 3D-Texturen funktionieren nur, wenn die Funktion „ ThreeDimensionalTextures “ zur Laufzeit als unterstützt gemeldet wird.
Hinweis: 1D-Texturen funktionieren nur, wenn die Funktion „ OneDimensionalTextures “ zur Laufzeit als unterstützt gemeldet wird. Außerdem funktionieren Mipmaps bei 1D-Texturen nur, wenn die Funktion „ OneDimensionalTextureMipmaps “ zur Laufzeit gemeldet wird.
Dies ist eine überladene Funktion.
QRhiTexture *QRhi::newTextureArray(QRhiTexture::Format format, int arraySize, const QSize &pixelSize, int sampleCount = 1, QRhiTexture::Flags flags = {})
Gibt ein neues 1D- oder 2D-Textur-Array mit den angegebenen Werten für „ format “, „ arraySize “, „ pixelSize “, „ sampleCount “ und „ flags “ zurück.
Diese Funktion legt „ QRhiTexture::TextureArray “ implizit in „ flags “ fest.
Bei einem 1D-Textur-Array muss „ QRhiTexture::OneDimensional “ in „ flags “ gesetzt sein. Diese Funktion setzt dieses Flag implizit, wenn die Höhe von „ pixelSize “ 0 ist.
Hinweis: VerwechselnSie Textur-Arrays nicht mit Arrays von Texturen. Ein mit dieser Funktion erstelltes „ QRhiTexture “ kann mit 1D- oder 2D-Array-Samplern im Shader verwendet werden, zum Beispiel: layout(binding = 1) uniform sampler2DArray texArr;. Arrays von Texturen beziehen sich auf eine Liste von Texturen, die dem Shader über QRhiShaderResourceBinding::sampledTextures() und eine Anzahl > 1 zur Verfügung gestellt und im Shader beispielsweise wie folgt deklariert werden: layout(binding = 1) uniform sampler2D textures[4];
Hinweis: Dies funktioniert nur, wenn die Funktion „ TextureArrays “ zur Laufzeit als unterstützt gemeldet wird.
Hinweis: 1D-Texturen funktionieren nur, wenn die Funktion „ OneDimensionalTextures “ zur Laufzeit als unterstützt gemeldet wird. Außerdem funktionieren Mipmaps auf 1D-Texturen nur, wenn die Funktion „ OneDimensionalTextureMipmaps “ zur Laufzeit gemeldet wird.
Siehe auch ` newTexture()`.
QRhiTextureRenderTarget *QRhi::newTextureRenderTarget(const QRhiTextureRenderTargetDescription &desc, QRhiTextureRenderTarget::Flags flags = {})
Gibt ein neues Textur-Renderziel zurück, dessen Farb- und Tiefen-/Stencil-Anhänge in ` desc` angegeben sind und das die angegebene ` flags` enthält.
Siehe auch QRhiResource::destroy().
QRhiResourceUpdateBatch *QRhi::nextResourceUpdateBatch()
Gibt einen verfügbaren, leeren Batch zurück, in dem Operationen vom Typ „Kopie“ protokolliert werden können.
Hinweis: Der Rückgabewert gehört nicht dem Aufrufer und darf niemals zerstört werden. Stattdessen wird der Batch zur Wiederverwendung an den Pool zurückgegeben, indem er an ` QRhiCommandBuffer::beginPass()`, ` QRhiCommandBuffer::endPass()` oder ` QRhiCommandBuffer::resourceUpdate()` übergeben wird oder indem ` QRhiResourceUpdateBatch::release()` darauf aufgerufen wird.
Hinweis: Kann auch außerhalb von ` beginFrame()` und ` endFrame()` aufgerufen werden, da eine Batch-Instanz lediglich selbstständig Daten sammelt und keine Operationen ausführt.
Da keine Bindung an einen aufgezeichneten Frame besteht, ist beispielsweise die folgende Abfolge zulässig:
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();Warnung: Die maximale Anzahl von Batches pro „ QRhi “ beträgt 64. Wenn dieses Limit erreicht ist, gibt die Funktion „null“ zurück, bis ein Batch an den Pool zurückgegeben wird.
QByteArray QRhi::pipelineCacheData()
Gibt einen binären Daten-Blob zurück, der Daten enthält, die von den während der Laufzeit dieses QRhi erfolgreich erstellten QRhiGraphicsPipeline und QRhiComputePipeline gesammelt wurden.
Durch das Speichern und anschließende Neuladen der Cache-Daten bei nachfolgenden Ausführungen derselben Anwendung lassen sich die Erstellungszeiten für Pipelines und Shader potenziell verkürzen. Was genau der Cache und seine serialisierte Version enthalten, ist nicht festgelegt, hängt immer vom verwendeten Backend ab und ist in einigen Fällen auch von der jeweiligen Implementierung der Grafik-API abhängig.
Wenn das „ PipelineCacheDataLoadSave “ als nicht unterstützt gemeldet wird, ist das zurückgegebene „ QByteArray “ leer.
Wurde das Flag „ EnablePipelineCacheDataSave “ beim Aufruf von ` create()` nicht angegeben, kann das zurückgegebene ` QByteArray ` leer sein, selbst wenn die Funktion „ PipelineCacheDataLoadSave “ unterstützt wird.
Sind die zurückgegebenen Daten nicht leer, sind sie stets spezifisch für die Qt-Version und das „ QRhi “-Backend. Zudem besteht in manchen Fällen eine starke Abhängigkeit vom Grafikgerät und der genau verwendeten Treiberversion. ` QRhi ` sorgt für das Hinzufügen der entsprechenden Header und Sicherheitsvorkehrungen, die gewährleisten, dass die Daten stets sicher an ` setPipelineCacheData()` übergeben werden können; daher wird der Versuch, Daten aus einem Lauf mit einer anderen Treiberversion zu laden, sicher und reibungslos abgewickelt.
Hinweis: Der Aufruf von ` releaseCachedResources()` kann je nach Backend dazu führen, dass die gesammelten Pipeline-Daten gelöscht werden. Ein nachfolgender Aufruf dieser Funktion gibt dann möglicherweise keine Daten mehr zurück.
Weitere Details zu dieser Funktion finden Sie unter EnablePipelineCacheDataSave.
Hinweis: Minimieren Sie die Anzahl der Aufrufe dieser Funktion. Das Abrufen des Blobs ist nicht immer ein ressourcenschonender Vorgang, daher sollte diese Funktion nur selten aufgerufen werden, idealerweise nur einmal, z. B. beim Schließen der Anwendung.
Siehe auch setPipelineCacheData(), create() und isFeatureSupported().
[static] bool QRhi::probe(QRhi::Implementation impl, QRhiInitParams *params)
Gibt „true“ zurück, wenn davon ausgegangen werden kann, dass der Aufruf von ` create()` erfolgreich ist, wenn die angegebenen ` impl ` und ` params` aufgerufen werden.
Bei einigen Backends entspricht dies dem Aufruf von ` create()`, der Überprüfung des Rückgabewerts und dem anschließenden Löschen des resultierenden ` QRhi`.
Bei anderen, insbesondere bei Metal, gibt es möglicherweise eine spezielle Prüfimplementierung, die ein leichteres Testen ermöglicht, ohne die Debug-Ausgabe bei Fehlern mit Warnungen zu überladen.
Siehe auch ` create()`.
void QRhi::releaseCachedResources()
Versucht, Ressourcen in den Caches des Backends freizugeben. Dies kann sowohl CPU- als auch GPU-Ressourcen umfassen. Es werden nur Speicher und Ressourcen berücksichtigt, die automatisch neu erstellt werden können. Wenn beispielsweise die Implementierung von „ QRhiGraphicsPipeline “ im Backend einen Cache mit den Ergebnissen der Shader-Kompilierung verwaltet, führt der Aufruf dieser Funktion dazu, dass dieser Cache geleert wird, wodurch möglicherweise Speicher und Grafikressourcen freigegeben werden.
Der Aufruf dieser Funktion ist in Umgebungen mit begrenzten Ressourcen sinnvoll, in denen ab einem bestimmten Punkt ein minimaler Ressourcenverbrauch auf Kosten der Leistung gewährleistet werden muss.
void QRhi::removeCleanupCallback(const void *key)
Hebt die Registrierung des Callbacks mit „ key “ auf. Wenn kein Cleanup-Callback mit „ key “ registriert wurde, führt die Funktion keine Aktion aus. Callbacks, die ohne Schlüssel registriert wurden, können nicht entfernt werden.
Siehe auch addCleanupCallback().
int QRhi::resourceLimit(QRhi::ResourceLimit limit) const
Gibt den Wert für die angegebene Ressource limit zurück.
Es wird davon ausgegangen, dass die Werte bei der Initialisierung von den Backends abgefragt werden, sodass der Aufruf dieser Funktion nur einen geringen Aufwand darstellt.
void QRhi::setPipelineCacheData(const QByteArray &data)
Lädt „ data “ in den Pipeline-Cache, sofern zutreffend.
Wenn „ PipelineCacheDataLoadSave “ als nicht unterstützt gemeldet wird, kann die Funktion gefahrlos aufgerufen werden, hat jedoch keine Auswirkung.
Der von ` pipelineCacheData()` zurückgegebene Blob ist immer spezifisch für die Qt-Version, das „ QRhi “-Backend und in manchen Fällen auch für das Grafikgerät sowie eine bestimmte Version des Grafiktreibers. ` QRhi ` sorgt für das Hinzufügen des entsprechenden Headers und für Sicherheitsvorkehrungen, die gewährleisten, dass die Daten stets sicher an diese Funktion übergeben werden können. Bei einer Nichtübereinstimmung, z. B. weil der Treiber auf eine neuere Version aktualisiert wurde oder weil die Daten von einem anderen „ QRhi “-Backend generiert wurden, wird eine Warnung ausgegeben und „ data “ sicher ignoriert.
Bei Vulkan entspricht dies direkt dem `VkPipelineCache`. Der Aufruf dieser Funktion erstellt ein neues Vulkan-Pipeline-Cache-Objekt, dessen Anfangsdaten aus ` data` stammen. Das Pipeline-Cache-Objekt wird dann von allen nachfolgend erstellten ` QRhiGraphicsPipeline `- und ` QRhiComputePipeline `-Objekten verwendet, wodurch die Erstellung der Pipeline potenziell beschleunigt wird.
Bei anderen APIs gibt es keinen eigentlichen Pipeline-Cache, jedoch stellen sie möglicherweise einen Cache mit Bytecode aus Shader-Kompilierungen (D3D) oder Programm-Binärdateien (OpenGL) bereit. In Anwendungen, die zur Laufzeit zahlreiche Shader-Kompilierungen aus dem Quellcode durchführen, kann dies bei nachfolgenden Durchläufen zu einer erheblichen Leistungssteigerung führen, wenn der „Pipeline-Cache“ mithilfe dieser Funktion aus einem früheren Durchlauf vorab befüllt wurde.
Hinweis: QRhi kann keine Garantie dafür geben, dass „ data “ Auswirkungen auf die Leistung bei der Erstellung von Pipelines und Shadern hat. Bei APIs wie Vulkan liegt es im Ermessen des Treibers, zu entscheiden, ob „ data “ für einen bestimmten Zweck verwendet oder ignoriert wird.
Weitere Details zu dieser Funktion finden Sie unter EnablePipelineCacheDataSave.
Hinweis: Dieser von QRhi bereitgestellte Mechanismus ist unabhängig vom eventuellen internen Caching-Mechanismus des Treibers. Das bedeutet, dass je nach Grafik-API und deren Implementierung die genauen Auswirkungen des Abrufens und anschließenden erneuten Ladens von data nicht vorhersehbar sind. Eine Leistungssteigerung ist möglicherweise überhaupt nicht erkennbar, falls bereits andere Caching-Mechanismen aktiv sind, auf die Qt keinen Einfluss hat.
Hinweis: Minimieren Sie die Anzahl der Aufrufe dieser Funktion. Das Laden des Blobs ist nicht immer ein ressourcenschonender Vorgang, daher sollte diese Funktion nur selten aufgerufen werden, idealerweise nur einmal, z. B. beim Start der Anwendung.
Warnung: Serialisierte Pipeline-Cache-Daten gelten als vertrauenswürdiger Inhalt. Qt führt eine gründliche Analyse des Headers und der Metadaten durch, die in ` data` enthalten sind; Anwendungsentwicklern wird jedoch empfohlen, niemals Daten aus nicht vertrauenswürdigen Quellen zu übergeben.
Siehe auch ` pipelineCacheData()` und ` isFeatureSupported()`.
[since 6.9] void QRhi::setQueueSubmitParams(QRhiNativeHandles *params)
In Verbindung mit Backends und Grafik-APIs, sofern zutreffend, ermöglicht diese Funktion die Übergabe zusätzlicher Argumente bei der nächsten Übermittlung von Befehlen an die Grafikbefehlswarteschlange.
Insbesondere bei Vulkan ermöglicht dies die Übergabe einer Liste von Vulkan-Semaphor-Objekten an ` vkQueueSubmit() `, auf deren Signale gewartet und die signalisiert werden sollen. ` params ` muss dabei ein ` QRhiVulkanQueueSubmitParams` sein. Dies ist in bestimmten fortgeschrittenen Anwendungsfällen unerlässlich, beispielsweise bei der Ausführung nativer Vulkan-Aufrufe, bei denen auf `VkSemaphores` gewartet und diese signalisiert werden müssen, die vom benutzerdefinierten Vulkan-Rendering- oder Rechencode der Anwendung verwaltet werden. Darüber hinaus ermöglicht dies auch die Angabe zusätzlicher Semaphoren, auf die bei der nächsten „ vkQueuePresentKHR() “-Aufgabe gewartet werden soll.
Hinweis: Diese Funktion wirkt sich nur auf die nächste Warteschlangenübermittlung aus, die in ` endFrame()`, ` endOffscreenFrame()` oder ` finish()` erfolgt. Das Einreihen von `present` erfolgt in ` endFrame()`.
Bei vielen anderen Backends ist die Implementierung dieser Funktion eine No-Op.
Diese Funktion wurde in Qt 6.9 eingeführt.
[static] QSize QRhi::sizeForMipLevel(int mipLevel, const QSize &baseLevelSize)
Gibt die Größe des Texturbildes für ein bestimmtes ` mipLevel` zurück, berechnet auf der Grundlage der in ` baseLevelSize` angegebenen Größe der Ebene 0.
QRhiStats QRhi::statistics() const
Erfasst und gibt Statistiken zu den Zugriffszeiten und der Zuweisung von Grafikressourcen zurück.
Daten zur Speicherzuweisung sind nur bei einigen Backends verfügbar, bei denen solche Vorgänge unter der Kontrolle von Qt stehen. Bei Grafik-APIs, bei denen keine Kontrolle auf niedrigerer Ebene über die Zuweisung von Speicherressourcen besteht, wird dies niemals unterstützt, und alle relevanten Felder in den Ergebnissen sind 0.
Insbesondere bei Vulkan sind die Werte stets gültig und werden aus der zugrunde liegenden Speicherzuweisungsbibliothek abgefragt. Dies gibt Aufschluss über den Speicherbedarf der aktiven Puffer und Texturen.
Das Gleiche gilt für Direct 3D 12. Zusätzlich zu den Statistiken der Speicherzuweisungsbibliothek enthält das Ergebnis hier auch ein Feld „ totalUsageBytes “, das die Gesamtgröße einschließlich zusätzlicher Ressourcen angibt, die nicht unter der Kontrolle der Speicherzuweisungsbibliothek stehen (Swapchain-Puffer, Descriptor-Heaps usw.), wie von DXGI gemeldet.
Die Werte entsprechen der Summe aller verwendeten Speichertypen (d. h. Grafik- und Systemspeicher im Falle einer diskreten GPU).
Zusätzliche Daten, wie beispielsweise die Gesamtzeit in Millisekunden, die für die Erstellung von Grafik- und Rechenpipelines aufgewendet wurde (was in der Regel Shader-Kompilierung oder Cache-Abfragen und potenziell rechenintensive Vorgänge umfasst), sind bei den meisten Backends verfügbar.
Hinweis: Die für Operationen wie die Erstellung von Pipelines benötigte Zeit kann durch verschiedene Faktoren beeinflusst werden. Die Ergebnisse sollten nicht zwischen verschiedenen Backends verglichen werden, da sich das Konzept der „Pipelines“ und die genauen Abläufe im Hintergrund – beispielsweise bei einem Aufruf von ` QRhiGraphicsPipeline::create()` – zwischen den Grafik-APIs und deren Implementierungen stark unterscheiden.
Hinweis: Darüber hinaus werden viele Treiber wahrscheinlich verschiedene Caching-Strategien für Shader, Programme und Pipelines einsetzen (unabhängig von Qt-eigenen, ähnlichen Funktionen wie ` setPipelineCacheData()` oder dem OpenGL-spezifischen Programm-Binär-Disk-Cache). Da dieses interne Verhalten für den API-Client transparent ist, haben Qt und QRhi keine Kenntnis von oder Kontrolle über die genaue Caching-Strategie, die Persistenz oder die Ungültigmachung der zwischengespeicherten Daten usw. Beim Auswerten von Zeitmessungen, wie z. B. der für die Erstellung der Pipeline benötigten Zeit, sollte das mögliche Vorhandensein und das nicht spezifizierte Verhalten von Caching-Mechanismen auf Treiber-Ebene berücksichtigt werden.
QList<int> QRhi::supportedSampleCounts() const
Gibt die Liste der unterstützten Sample-Zahlen zurück.
Ein typisches Beispiel wäre (1, 2, 4, 8).
Bei manchen Backends ist diese Liste der unterstützten Werte im Voraus festgelegt, während bei anderen die (physikalischen) Geräteeigenschaften angeben, was zur Laufzeit unterstützt wird.
Siehe auch QRhiRenderBuffer::setSampleCount(), QRhiTexture::setSampleCount(), QRhiGraphicsPipeline::setSampleCount() und QRhiSwapChain::setSampleCount().
[since 6.9] QList<QSize> QRhi::supportedShadingRates(int sampleCount) const
Gibt die Liste der unterstützten variablen Schattierungsraten für die angegebene „ sampleCount “ zurück.
1x1 wird immer unterstützt.
Diese Funktion wurde in Qt 6.9 eingeführt.
QThread *QRhi::thread() const
Gibt den Thread zurück, auf dem die Funktion „ QRhi “ aufgerufen wurde initialized.
int QRhi::ubufAligned(int v) const
Gibt den Wert (in der Regel einen Offset) „ v “ zurück, der an die durch „ ubufAlignment()“ angegebene einheitliche Pufferausrichtung angepasst ist.
int QRhi::ubufAlignment() const
Gibt den minimalen Offset für die Ausrichtung eines einheitlichen Puffers in Byte zurück. Dieser beträgt in der Regel 256.
Der Versuch, einen Bereich des einheitlichen Puffers mit einem Offset zu binden, der nicht an diesen Wert ausgerichtet ist, führt je nach Backend und der zugrunde liegenden Grafik-API zu Fehlern.
Siehe auch „ ubufAligned()“.
[static] QRhiSwapChainProxyData QRhi::updateSwapChainProxyData(QRhi::Implementation impl, QWindow *window)
Erzeugt und gibt eine ` QRhiSwapChainProxyData `-Struktur zurück, die undurchsichtige Daten enthält, die für das Backend und die Grafik-API spezifisch sind, die durch ` impl` angegeben werden. ` window ` ist die ` QWindow `, auf die eine Swapchain abzielt.
Die zurückgegebene Struktur kann an ` QRhiSwapChain::setProxyData()` übergeben werden. Dies ist in Rendering-Systemen mit Threads sinnvoll: Diese statische Funktion soll – im Gegensatz zu allen Operationen unter ` QRhi ` – im Haupt- (GUI-)Thread aufgerufen, anschließend an den Thread übertragen werden, der mit dem ` QRhi ` und dem ` QRhiSwapChain ` arbeitet, und schließlich an die Swapchain weitergeleitet werden. Dies ermöglicht native Plattformabfragen, deren Aufruf nur im Hauptthread sicher ist – beispielsweise die Abfrage des `CAMetalLayer` aus einer `NSView` –, sowie die anschließende Weitergabe der Daten an die ` QRhiSwapChain `, die im Rendering-Thread ausgeführt wird. Im Metal-Beispiel löst der Zugriff auf `view.layer` in einem dedizierten Rendering-Thread eine Warnung im Xcode-Thread-Checker aus. Mit dem Daten-Proxy-Mechanismus wird dies vermieden.
Wenn keine Threads beteiligt sind, ist das Erstellen und Weiterleiten des „ QRhiSwapChainProxyData “ nicht erforderlich: Es ist gewährleistet, dass Backends alles Notwendige selbst abfragen können, und wenn sich alles auf dem Haupt- (GUI-)Thread befindet, sollte dies ausreichen.
Hinweis: „ impl “ sollte mit dem Wert übereinstimmen, mit dem „ QRhi “ erstellt wurde. Beispielsweise liefert der Aufruf von „ QRhi::Metal “ auf einer Nicht-Apple-Plattform keine brauchbaren Daten.
Verwandte Nicht-Mitglieder
[alias, since 6.7] QRhiShaderResourceBindingSet
Synonym für „ QRhiShaderResourceBindings “.
Diese Typdefinition wurde in Qt 6.7 eingeführt.
© 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.