QRhi Class
가속화된 2D/3D 그래픽 API 추상화. 더 보기...
Header: | #include <rhi/qrhi.h> |
CMake: | find_package(Qt6 REQUIRED COMPONENTS Gui) target_link_libraries(mytarget PRIVATE Qt6::GuiPrivate) |
qmake: | QT += gui-private |
이후: | Qt 6.6 |
- 상속된 멤버를 포함한 모든 멤버 목록
- QRhi는 3D 렌더링의 일부입니다.
공용 유형
enum | BeginFrameFlag { } |
flags | BeginFrameFlags |
enum | EndFrameFlag { SkipPresent } |
flags | EndFrameFlags |
enum | Feature { MultisampleTexture, MultisampleRenderBuffer, DebugMarkers, Timestamps, Instancing, …, ResolveDepthStencil } |
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, …, MaxVertexOutputs } |
공용 함수
~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() |
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 | runCleanup() |
void | setPipelineCacheData(const QByteArray &data) |
QRhiStats | statistics() const |
QList<int> | supportedSampleCounts() const |
QThread * | thread() const |
int | ubufAligned(int v) const |
int | ubufAlignment() const |
정적 공용 멤버
const char * | backendName(QRhi::Implementation impl) |
QRhi * | create(QRhi::Implementation impl, QRhiInitParams *params, QRhi::Flags flags = {}, QRhiNativeHandles *importDevice = 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) |
관련 비회원
(since 6.7) | QRhiShaderResourceBindingSet |
상세 설명
Qt 렌더링 하드웨어 인터페이스는 OpenGL, OpenGL ES, Direct3D, Metal, Vulkan과 같은 하드웨어 가속 그래픽 API를 위한 추상화입니다.
경고: QShader 및 QShaderDescription 을 포함한 Qt GUI 모듈의 QRhi 클래스 제품군은 제한된 호환성을 보장합니다. 이러한 클래스에 대한 소스 또는 바이너리 호환성 보장은 없으므로 API는 애플리케이션이 개발된 Qt 버전에서만 작동하도록 보장됩니다. 그러나 소스와 호환되지 않는 변경은 최소한으로 유지하는 것을 목표로 하며 마이너 릴리스(6.7, 6.8 등)에서만 이루어질 것입니다. 애플리케이션에서 이러한 클래스를 사용하려면 Qt::GuiPrivate
(CMake를 사용하는 경우)에 링크하고 헤더에 rhi
접두사(예: #include <rhi/qrhi.h>
)를 포함하세요.
각 QRhi 인스턴스는 특정 그래픽 API용 백엔드에 의해 지원됩니다. 백엔드 선택은 런타임 선택 사항이며 QRhi 인스턴스를 생성하는 애플리케이션 또는 라이브러리에 달려 있습니다. 일부 백엔드는 여러 플랫폼에서 사용할 수 있는 반면(OpenGL, Vulkan, Null), 특정 플랫폼에 특정한 API는 해당 플랫폼에서 실행할 때만 사용할 수 있습니다(macOS/iOS의 경우 Metal, Windows의 경우 Direct3D).
현재 사용 가능한 백엔드는 다음과 같습니다:
- OpenGL 2.1 / OpenGL ES 2.0 이상. 일부 확장 기능과 최신 핵심 사양 기능은 멀티샘플 프레임버퍼 또는 컴퓨팅 셰이더 활성화와 같은 경우에 사용됩니다. 코어 프로파일 컨텍스트에서의 작동도 지원됩니다. 필요한 경우 애플리케이션은 런타임에 feature flags 를 쿼리하여 QRhi를 뒷받침하는 OpenGL 컨텍스트에서 지원되지 않는 기능을 확인할 수 있습니다. OpenGL 백엔드는 QOpenGLContext, QOpenGLFunctions, 그리고 Qt GUI 모듈의 관련 크로스 플랫폼 인프라를 기반으로 구축됩니다.
- 셰이더 모델 5.0 이상을 사용하는 Direct3D 11.2 이상(DXGI 1.3 이상 포함). D3D 런타임이 11.2 기능 또는 셰이더 모델 5.0을 지원하지 않는 경우 가속 그래픽 장치를 사용한 초기화는 실패하지만 소프트웨어 어댑터를 사용하는 것은 여전히 옵션입니다.
- Windows 10 버전 1703 이상에서 Direct3D 12, 셰이더 모델 5.0 이상. Qt를 사용하려면 ID3D12Device2가 있어야 하므로 Windows 10 버전 1703 이상이 필요합니다. D3D12 디바이스는 기본적으로 최소 기능 수준을
D3D_FEATURE_LEVEL_11_0
로 지정하여 생성됩니다. - Metal 1.2 이상.
- 벌칸 1.0 이상, 선택적으로 일부 벌칸 1.1 수준의 기능을 활용합니다.
- Null, 그래픽 호출을 전혀 발행하지 않는 "더미" 백엔드.
Qt 애플리케이션과 라이브러리에서 셰이더 코드를 한 번만 작성할 수 있도록 모든 셰이더는 단일 언어로 작성된 다음 SPIR-V로 컴파일되어야 합니다. 그런 다음 다양한 셰이딩 언어에 대한 버전이 리플렉션 정보(입력, 출력, 셰이더 리소스)와 함께 생성됩니다. 그런 다음 쉽고 효율적으로 직렬화할 수 있는 QShader 인스턴스로 패키징됩니다. 이러한 셰이더를 생성하는 컴파일러와 도구는 QRhi와 Qt GUI 모듈의 일부가 아니지만, 셰이더를 사용하기 위한 핵심 클래스인 QShader 과 QShaderDescription 는 포함되어 있습니다. 컴파일 및 번역을 수행하기 위한 API와 도구는 Qt Shader Tools 모듈의 일부입니다.
QRhi를 사용하여 QWindow 에서 가속화된 3D 렌더링을 수행하는 휴대용 크로스 플랫폼 애플리케이션을 만드는 입문용 예제는 RHI 창 예제를 참조하세요.
API에 대한 인상
창 관련 설정이 포함되지 않은 짧지만 완전한 예제를 통해 API를 빠르게 살펴보기 위해 다음은 화면 밖에서 20프레임을 렌더링한 다음 GPU에서 텍스처 콘텐츠를 다시 읽은 후 생성된 이미지를 파일에 저장하는 실행 가능한 완전한 크로스 플랫폼 애플리케이션입니다. QWindow 및 스왑체인을 설정한 후 화면에서 렌더링하는 예제는 RHI 창 예제를 참조하세요.
간결성을 위해 QRhi의 초기화는 플랫폼에 따라 이루어집니다. 여기 샘플 코드는 Windows에서는 Direct 3D 12를, macOS 및 iOS에서는 Metal을, 그 외에는 Vulkan을 선택합니다. OpenGL과 Direct 3D 11은 이 애플리케이션에서 사용되지 않지만 몇 줄만 추가하면 해당 지원을 도입할 수 있습니다.
#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;#endifstd::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(); else 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::렌더타겟 | 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 up, CCW0. 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, 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::버텍스 스테이지 | QRhiShaderResourceBinding::FragmentStage,ubuf.get()) }); srb->create(); std::unique_ptr<QRhiGraphicsPipeline> ps(rhi->newGraphicsPipeline()); QRhiGraphicsPipeline::TargetBlend premulAlphaBlend; 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 = image.mirrored(); image.save(QString::asprintf("frame%d.png", frame)); } return 0; }
적용 결과는 20개의 PNG
이미지(frame0.png - frame19.png)입니다. 여기에는 녹색 배경 위에 다양한 불투명도를 가진 회전하는 삼각형이 포함되어 있습니다.
버텍스 및 프래그먼트 셰이더는 처리되어 .qsb
파일로 패키징될 것으로 예상됩니다. 벌칸 호환 GLSL 소스 코드는 다음과 같습니다:
color.vert
#version 440 layout(location = 0) in vec4 position; layout(location = 1) in vec3 color; layout(location = 0) out vec3 v_color; layout(std140, binding = 0) uniform buf { mat4 mvp; float opacity; }; void main() { v_color = color; gl_Position = mvp * position; }
color.frag
#version 440 layout(location = 0) in vec3 v_color; layout(location = 0) out vec4 fragColor; layout(std140, binding = 0) uniform buf { mat4 mvp; float opacity; }; void main() { fragColor = vec4(v_color * opacity, opacity); }
이러한 셰이더를 수동으로 컴파일하고 여러 타깃(SPIR-V, HLSL, MSL, GLSL)으로 트랜스파일하고 런타임에 애플리케이션이 로드하는 .qsb
파일을 생성하려면 qsb --qt6 color.vert -o color.vert.qsb
및 qsb --qt6 color.frag -o color.frag.qsb
을 실행합니다. 또는 Qt Shader Tools 모듈은 빌드 시 동일한 작업을 수행할 수 있는 qt_add_shaders()
CMake 함수를 위한 빌드 시스템 통합을 제공합니다.
디자인 기초
QRhi는 직접 인스턴스화할 수 없습니다. 대신 create() 함수를 사용하세요. 그래픽 장치를 해제하려면 QRhi 인스턴스를 정상적으로 삭제합니다.
리소스
QRhiResource 에서 파생된 클래스 인스턴스(예: QRhiBuffer, QRhiTexture 등)는 0개, 1개 또는 그 이상의 기본 그래픽 리소스를 캡슐화합니다. 이러한 클래스의 인스턴스는 항상 newBuffer(), newTexture(), newTextureRenderTarget(), newSwapChain()와 같은 QRhi의 new
함수를 통해 생성됩니다.
QRhiBuffer *vbuf = rhi->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, sizeof(vertexData)); if (!vbuf->create()) { error(); } // ... delete vbuf;
- newBuffer() 등의 함수에서 반환되는 값은 항상 호출자가 소유합니다.
- QRhiResource 서브클래스의 인스턴스를 생성하는 것만으로는 네이티브 리소스를 할당하거나 초기화하지 않습니다. 이는 하위 클래스의
create()
함수(예: QRhiBuffer::create() 또는 QRhiTexture::create()를 호출할 때만 수행됩니다. - QRhiTextureRenderTarget::newCompatibleRenderPassDescriptor(), QRhiSwapChain::newCompatibleRenderPassDescriptor() 및 QRhiRenderPassDescriptor::newCompatibleRenderPassDescriptor()는 예외입니다. 이러한 경우
create()
연산이 없으며 반환된 객체는 즉시 활성화됩니다. - 리소스 객체 자체는 변경 불가능한 것으로 취급됩니다. 리소스에 create()가 호출된 후에는 기본 네이티브 리소스가 해제되고
create()
가 다시 호출되지 않는 한 QRhiTexture::setPixelSize()와 같은 설정자를 통해 매개 변수를 변경해도 아무런 영향을 미치지 않습니다. 아래 섹션에서 리소스 재사용에 대해 자세히 알아보세요. - 기본 네이티브 리소스는 QRhiResource 소멸자 또는 QRhiResource::destroy()를 호출하여 릴리스하도록 예약됩니다. 백엔드는 종종 릴리스 요청을 대기열에 넣고 실행을 지정되지 않은 시간으로 연기하는데, 이는 애플리케이션에 숨겨집니다. 이렇게 하면 애플리케이션은 인플라이트 프레임에서 아직 사용 중인 네이티브 리소스를 릴리스하는 것에 대해 걱정할 필요가 없습니다.
- 그렇다고 해서 프레임 내에서(즉, beginFrame() - endFrame() 섹션에서) QRhiResource 을 자유롭게 파괴()'하거나 삭제할 수 있다는 의미는 아닙니다. 일반적으로 참조된 모든 QRhiResource 객체는 endFrame()을 호출하여 프레임을 제출할 때까지 변경되지 않은 상태로 유지되어야 합니다. 이 문제를 완화하기 위해 QRhiResource::deleteLater()가 편의상 제공됩니다.
명령 버퍼 및 지연된 명령 실행
기본 그래픽 API의 설계와 기능에 관계없이 모든 QRhi 백엔드는 일정 수준의 명령 버퍼를 구현합니다. QRhiCommandBuffer 함수는 네이티브 바인드 또는 그리기 명령(예: glDrawElements
)을 직접 실행하지 않습니다. 명령은 항상 기본 또는 QRhi 백엔드에서 제공하는 대기열에 기록됩니다. 명령 버퍼가 제출되므로 QRhi::endFrame() 또는 QRhi::finish()에서만 실행이 시작됩니다.
지연된 특성은 일부 유형의 객체에 영향을 미칩니다. 예를 들어, 동적 버퍼가 호스트 가시 메모리에 의해 뒷받침되는 경우 프레임 내에서 동적 버퍼에 여러 번 쓰면 동적 버퍼 업데이트가 드로우 호출과 관련하여 언제 기록되었는지와 관계없이 모든 쓰기 결과가 프레임의 모든 명령 버퍼에 표시되게 됩니다.
또한 QRhiResource 서브클래스의 인스턴스는 어떤 식으로든 참조되는 프레임 내에서 불변으로 처리되어야 합니다. 다음 프레임에 대한 명령 기록을 시작하기 전에 모든 리소스를 미리 생성하세요. 한 프레임 내에서 QRhiResource 인스턴스를 재사용( create()
호출 후 동일한 beginFrame - endFrame
섹션에서 다시 참조)하는 것은 백엔드에 따라 예기치 않은 결과를 초래할 수 있으므로 피해야 합니다.
일반적으로 참조된 모든 QRhiResource 객체는 endFrame()을 호출하여 프레임을 제출할 때까지 유효하고 수정되지 않은 상태로 유지되어야 합니다. 반면에 destroy()를 호출하거나 QRhiResource 을 삭제하는 것은 기본 네이티브 리소스(GPU에서 여전히 사용 중일 수 있지만 내부적으로 처리됨)의 상태와 관계없이 프레임이 제출된 후에는 항상 안전합니다.
OpenGL과 같은 API와 달리 업로드 및 복사 유형의 명령은 그리기 명령과 혼합할 수 없습니다. 일반적인 렌더러는 다음과 유사한 시퀀스를 포함합니다:
- 리소스 (재)생성
- 프레임 시작
- 업로드 및 사본 기록/발행
- 렌더 패스 기록 시작
- 드로우 호출 기록
- 렌더 패스 종료
- 프레임 종료
레코딩 복사 유형의 작업은 QRhiResourceUpdateBatch 을 통해 이루어집니다. 이러한 작업은 일반적으로 beginPass()에서 커밋됩니다.
OpenGL용으로 설계된 레거시 렌더링 엔진으로 작업할 때 QRhi로 마이그레이션하려면 단일 render
단계(복사 및 업로드, 버퍼 지우기, 드로우 호출을 모두 함께 수행)에서 명확하게 분리된 두 단계 prepare
- render
설정으로 재설계하는 경우가 많습니다. render
단계는 렌더패스를 시작하고 드로우 호출만 기록하고, 업데이트, 업로드 및 복사의 모든 리소스 생성 및 대기열은 prepare
단계에서 미리 이루어집니다.
QRhi는 현재 명령 버퍼를 자유롭게 생성하고 제출하는 것을 허용하지 않습니다. 이는 향후 컴퓨팅 지원이 도입되면 어느 정도 해제될 수 있지만, 잘 정의된 frame-start
및 frame-end
포인트와 전용 "프레임" 명령 버퍼( frame-end
제시를 의미)가 결합된 모델은 Qt의 다양한 UI 기술에 가장 적합하기 때문에 기본 운영 방식으로 유지될 것입니다.
스레딩
QRhi 인스턴스와 관련 리소스는 모든 스레드에서 생성 및 사용할 수 있지만 모든 사용은 해당 단일 스레드로 제한되어야 합니다. 애플리케이션에서 여러 QWindows에 렌더링할 때 각 창에 전용 스레드와 QRhi 인스턴스를 사용하면 여러 창에 프레젠테이션할 때 발생하는 예기치 않은 스로틀링 문제를 방지할 수 있으므로 권장되는 경우가 많습니다. 개념적으로 이는 OpenGL로 직접 작업할 때 Qt Quick 씬 그래프의 스레드 렌더 루프가 작동하는 방식(각 창마다 하나의 스레드, 각 스레드마다 하나의 QOpenGLContext )과 동일합니다. QRhi로 전환할 때 QOpenGLContext 는 QRhi로 대체되므로 마이그레이션이 간단합니다.
QRhiGles2NativeHandles 을 통해 전달된 OpenGL 컨텍스트와 같이 외부에서 생성된 네이티브 오브젝트의 경우 다른 스레드에서 오용되지 않도록 하는 것은 애플리케이션의 책임입니다.
QRhi 인스턴스 간에는 리소스를 공유할 수 없습니다. 이는 의도적인 선택으로 QRhi는 대부분의 대기열, 명령 버퍼 및 리소스 동기화 관련 작업을 숨기고 이에 대한 API를 제공하지 않기 때문입니다. 그러나 여러 스레드에서 그래픽 리소스를 안전하고 효율적으로 동시에 사용하는 것은 이러한 개념과 연관되어 있으므로 현재는 적용 범위를 벗어난 주제이지만 향후 도입될 수 있습니다.
참고: Metal 백엔드에서는 렌더링 스레드에서 자동 릴리스 풀을 사용할 수 있어야 하며, 렌더링 루프의 각 반복을 래핑하는 것이 이상적입니다. 이는 메인(GUI) 스레드에서 렌더링할 때는 QRhi 사용자의 작업이 필요하지 않지만 별도의 전용 렌더링 스레드를 사용할 때는 중요해집니다.
리소스 동기화
QRhi는 리소스 배리어 또는 이미지 레이아웃 전환을 위한 API를 노출하지 않습니다. 이러한 동기화는 필요에 따라 리소스 사용량을 추적하여 해당되는 경우(예: Vulkan) 백엔드에서 암시적으로 수행됩니다. 버퍼 및 이미지 배리어는 렌더링 또는 계산 패스가 애플리케이션에 투명하게 전달되기 전에 삽입됩니다.
참고: 렌더링 또는 계산 패스 내의 리소스는 해당 패스 동안 단일 사용량에 바인딩되어야 합니다. 예를 들어 버퍼는 버텍스, 인덱스, 유니폼 또는 스토리지 버퍼로 사용할 수 있지만 단일 패스 내에서 이러한 버퍼를 조합하여 사용할 수는 없습니다. 그러나 예를 들어 버퍼를 생성할 때 두 가지 용도를 모두 선언했다고 가정하면 컴퓨팅 패스에서는 스토리지 버퍼로 사용한 다음 렌더링 패스에서는 버텍스 버퍼로 사용하는 것은 괜찮습니다.
참고: 텍스처는 동일한 패스 내에서도 동일한 텍스처의 두 하위 리소스(일반적으로 두 개의 다른 밉 레벨)를 서로 다른 액세스(하나는 로드용, 하나는 저장용)에 사용하는 것이 지원되므로 특정 경우에는 이 규칙이 완화됩니다.
리소스 재사용
사용자 관점에서 보면 QRhiResource::destroy()을 호출한 직후 QRhiResource 을 재사용할 수 있습니다. 스왑체인을 제외하고, 이미 생성된 객체에서 create()
을 호출하면 암시적으로 destroy()
이 수행됩니다. 이는 다른 매개변수를 사용하여 QRhiResource 인스턴스를 재사용할 수 있는 편리한 단축키를 제공하며, 그 아래에 새로운 기본 그래픽 객체가 생성됩니다.
동일한 객체를 재사용하는 것의 중요성은 일부 객체가 다른 객체를 참조한다는 사실에 있습니다. 예를 들어 QRhiShaderResourceBindings 은 QRhiBuffer, QRhiTexture, QRhiSampler 인스턴스를 참조할 수 있습니다. 이후 프레임에서 이러한 버퍼 중 하나의 크기를 조정하거나 샘플러 파라미터를 변경해야 하는 경우, 완전히 새로운 QRhiBuffer 또는 QRhiSampler 을 파괴하고 생성하면 이전 인스턴스에 대한 모든 참조가 무효화됩니다. QRhiBuffer::setSize () 등을 통해 적절한 매개변수를 변경한 다음 QRhiBuffer::create()을 호출하면 모든 것이 예상대로 작동하고 QRhiShaderResourceBindings 을 전혀 건드릴 필요가 없지만, 내부적으로 QRhiBuffer 이 완전히 새로운 기본 버퍼로 지원될 가능성이 높습니다.
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 렌더 대상 객체를 생성한 이후 렌더 대상의 관련 텍스처 또는 렌더버퍼 중 하나가 재구축( create()
호출)된 경우에도 QRhiCommandBuffer::beginPass()를 호출하는 것이 안전합니다. 이렇게 하면 애플리케이션이 QRhiTexture 에서 새 픽셀 크기를 설정하고 create()을 호출하여 텍스처 크기를 조정할 수 있으므로 QRhiTextureRenderTarget 을 업데이트할 필요 없이 그 아래에 완전히 새로운 기본 텍스처 리소스를 생성할 수 있으며, 이는 startPass()에서 암시적으로 수행됩니다.
풀 오브젝트
리소스 외에도 QRhiResourceUpdateBatch 와 같은 풀링된 오브젝트도 있습니다. 인스턴스는 nextResourceUpdateBatch()와 같은 next
함수를 통해 검색됩니다. 이 경우 호출자는 반환된 인스턴스를 소유하지 않습니다. 여기서 유효한 유일한 작동 방식은 QRhiResourceUpdateBatch 에서 함수를 호출한 다음 QRhiCommandBuffer::beginPass() 또는 QRhiCommandBuffer::endPass()로 전달하는 것입니다. 이러한 함수는 배치를 풀에 반환하는 작업을 처리합니다. 또는 QRhiResourceUpdateBatch::release()를 호출하여 배치를 "취소"하고 처리하지 않고 풀로 반환할 수도 있습니다.
일반적인 패턴은 이렇습니다:
QRhiResourceUpdateBatch *resUpdates = rhi->nextResourceUpdateBatch(); // ... resUpdates->updateDynamicBuffer(ubuf, 0, 64, mvp.constData()); if (!image.isNull()) { resUpdates->uploadTexture(texture, image); image = QImage(); } // ... QRhiCommandBuffer *cb = m_sc->currentFrameCommandBuffer(); // note the last argument cb->beginPass(swapchain->currentFrameRenderTarget(), clearCol, clearDs, resUpdates);
스왑체인 특성
QRhiSwapChain 에는 스왑체인의 고유한 특성으로 인해 몇 가지 특별한 의미가 있습니다.
create()
가 아니라 QRhiSwapChain::createOrResize()가 있습니다. 이 함수를 반복적으로 호출하는 것은 QRhiSwapChain::destroy() 다음에 QRhiSwapChain::createOrResize()를 호출하는 것과는 다릅니다. 스왑체인에는 버퍼 크기를 조정해야 하는 경우, 처음부터 무차별적으로 파괴하고 다시 생성하는 것보다 더 효율적인 방식으로 처리할 수 있는 방법이 있기 때문입니다.- 활성 QRhiSwapChain 은 destroy()을 호출하거나 객체를 파괴하여 해제해야 QWindow 의 기본 QPlatformWindow 및 관련 네이티브 창 객체가 파괴됩니다. 예를 들어 QWindow::close() 수신 시 QPlatformWindow가 파괴되어 네이티브 창이 더 이상 존재하지 않는 경우 스왑체인 릴리스가 문제가 될 수 있으므로(그리고 Vulkan과 같은 일부 API에서는 명시적으로 허용되지 않음) 릴리스를 연기해서는 안 됩니다. 따라서 스왑체인 릴리스는 대상 QWindow 가 QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed 이벤트를 보낼 때마다 발생해야 합니다. 이벤트가 QCoreApplication::quit() 사용 시 발생할 수 있는 QWindow 파괴 전에 도착하지 않으면 이벤트 루프가 종료된 후 QWindow::handle()를 확인하고 null이 아닌 경우(기본 네이티브 창이 여전히 존재한다는 의미) 스왑체인 릴리즈를 호출합니다.
소유권
일반적인 규칙은 소유권 이전이 없다는 것입니다. 이미 존재하는 그래픽 디바이스로 QRhi를 생성한다고 해서 QRhi가 디바이스 오브젝트의 소유권을 가져가는 것은 아닙니다. 마찬가지로 QRhi::nativeHandles() 또는 QRhiTexture::nativeTexture()을 통해 디바이스 또는 텍스처 오브젝트를 "내보내기"하는 경우에도 소유권이 이전되지 않습니다. 가장 중요한 것은 구조체와 세터를 통해 포인터를 전달해도 소유권이 이전되지 않는다는 점입니다.
문제 해결 및 프로파일링
오류 보고
QRhi::create() 및 리소스 클래스의 create()
멤버 함수(예: QRhiBuffer::create())와 같은 함수는 반환 값(각각nullptr
또는 false
)으로 실패를 나타냅니다. QShader , QShader::fromSerialized()는 함수에 전달된 데이터를 성공적으로 역직렬화할 수 없는 경우 잘못된 QShader ( isValid()는 false
)를 반환합니다. 특히 beginFrame()와 같은 일부 함수는 복구할 수 없는 오류를 나타내는 것이 아니라 "나중에 다시 시도"라는 응답으로 간주해야 하는 FrameOpSwapChainOutOfDate 과 같은 "소프트 실패"를 보고할 수도 있습니다.
경고 및 오류는 qWarning()를 통해 언제든지 디버그 출력에 인쇄될 수 있습니다. 따라서 항상 애플리케이션의 출력을 검사하는 것이 좋습니다.
다음 로깅 카테고리를 통해 추가 디버그 메시지를 활성화할 수 있습니다. QLoggingCategory 또는 QT_LOGGING_RULES
환경 변수를 통해 명시적으로 활성화하지 않는 한 이러한 범주의 메시지는 기본적으로 인쇄되지 않습니다. Qt Quick 와의 상호 운용성을 높이기 위해 환경 변수 QSG_INFO
에서도 이러한 디버그 출력을 활성화할 수 있습니다.
qt.rhi.general
또한 애플리케이션은 성공적으로 초기화된 QRhi에서 QRhi backend name 및 graphics device information 을 쿼리할 수 있습니다. 그런 다음 원하는 경우 프로덕션 빌드에서도 사용자에게 인쇄하거나 애플리케이션 로그에 저장할 수 있습니다.
렌더링 문제 조사
렌더링 결과가 예상과 다르거나 애플리케이션에 문제가 발생하면 항상 네이티브 3D API의 디버그 및 유효성 검사 기능을 사용해 확인해 보세요. 기본 레이어에 이미 존재하는 방대한 양의 기능을 복제하는 것은 합리적이지 않으므로 QRhi 자체의 오류 검사 기능은 제한적입니다.
- 벌칸의 경우, 벌칸 유효성 검사 레이어를 제어하는 것은 QRhi의 범위에 속하지 않으며, 적절한 레이어로 QVulkanInstance 을 구성하여 달성할 수 있습니다. 예를 들어, QVulkanInstance 에서 create()을 호출하기 전에
instance.setLayers({ "VK_LAYER_KHRONOS_validation" });
을 호출합니다(이 경우 유효성 검사 레이어가 실제로 설치되어 있고 사용 가능하다고 가정합니다.) 기본적으로 QVulkanInstance 은 Vulkan 디버그 메시지를 qDebug 로 편리하게 리디렉션하므로 유효성 검사 메시지는 다른 Qt 경고와 마찬가지로 인쇄됩니다. - Direct 3D 11 및 12에서는 해당 init params struct 에서
enableDebugLayer
플래그를 토글하여 디버그 레이어가 활성화된 그래픽 디바이스를 요청할 수 있습니다. 메시지는 디버그 출력에 표시되며, Qt Creator 의 메시지 패널 또는 DebugView와 같은 도구를 통해 볼 수 있습니다. - 메탈의 경우, 메탈 유효성 검사 제어는 QRhi의 범위를 벗어납니다. 대신 유효성 검사를 활성화하려면 환경 변수
METAL_DEVICE_WRAPPER_TYPE=1
를 설정한 상태에서 애플리케이션을 실행하거나 XCode 내에서 애플리케이션을 실행하세요. 최신 XCode 및 macOS 버전에는 추가 설정 및 환경 변수가 있을 수도 있습니다. 예를 들어 이 페이지를 참조하세요.
프레임 캡처 및 성능 프로파일링
내부적으로 3D API에 의존하면서 QRhi를 사용하여 창에 렌더링하는 Qt 애플리케이션은 적어도 윈도우 및 그래픽 파이프라인 관점에서 볼 때 동일한 3D API를 사용하는 다른 (비-Qt) 애플리케이션과 다르지 않습니다. 즉, 게임과 같은 3D 그래픽이 포함된 애플리케이션의 디버깅 및 프로파일링을 위한 도구와 관행은 모두 이러한 Qt 애플리케이션에도 적용됩니다.
QRhi를 사용하는 Qt 애플리케이션의 렌더링 내부에 대한 통찰력을 제공할 수 있는 몇 가지 도구의 예로는 Qt Quick 및 Qt Quick 3D 기반 프로젝트도 있습니다:
- RenderDoc을 사용하면 프레임 캡처를 수행하고 기록된 명령어와 파이프라인 상태를 Windows 및 Linux에서 OpenGL, Vulkan, D3D11 또는 D3D12를 사용하는 애플리케이션에 대한 인트로스펙트를 수행할 수 있습니다. 3D 씬의 일부가 예상대로 표시되지 않는 이유를 파악하려고 할 때 RenderDoc은 파이프라인 단계와 관련 상태를 확인하고 누락되거나 잘못된 값을 발견하는 빠르고 효율적인 방법인 경우가 많습니다. 또한 Qt 자체 개발 시에도 활발하게 사용되는 툴입니다.
- NVIDIA 기반 시스템의 경우 엔사이트 그래픽스는 Windows와 Linux에서 그래픽 디버거 도구를 제공합니다. 프레임과 파이프라인의 명령을 조사하는 것 외에도 공급업체별 도구를 사용하면 단순한 프레임 캡처로는 제공하지 못하는 타이밍 및 하드웨어 성능 정보를 확인할 수 있습니다.
- AMD 기반 시스템의 경우 Radeon GPU 프로파일러를 사용하여 애플리케이션의 렌더링과 성능에 대한 심층적인 인사이트를 얻을 수 있습니다.
- QRhi는 Direct 3D 12를 지원하므로 Windows에서 DirectX 12 게임용 성능 튜닝 및 디버깅 툴인 PIX를 사용하는 것도 옵션입니다.
- macOS에서는 XCode Metal 디버거를 사용하여 프레임 캡처 및 인사이트, 성능 세부 정보 조사, 셰이더 디버깅을 수행할 수 있습니다. macOS 13에서는 환경 변수
MTL_HUD_ENABLED=1
를 설정하여 Metal 기반 창에 프레임 속도 및 기타 정보를 표시하는 오버레이를 활성화할 수도 있습니다.
모바일 및 임베디드 플랫폼에서는 GPU 또는 SoC 공급업체에서 제공하는 공급업체 및 플랫폼별 툴을 사용하여 OpenGL ES 또는 Vulkan을 사용하는 애플리케이션의 성능 프로파일링을 수행할 수 있습니다.
프레임을 캡처할 때 디버그 마커를 통해 개체와 명령 그룹의 이름을 지정할 수 있으며, QRhi의 경우 debug markers were enabled, 사용 중인 그래픽 API가 이를 지원하는 경우에만 가능합니다. 명령 스트림에 주석을 달려면 debugMarkBegin(), debugMarkEnd() 및/또는 debugMarkMsg()를 호출하세요. 이는 렌더링 패스가 여러 개 있는 큰 프레임에서 특히 유용할 수 있습니다. 리소스는 create() 앞에 setName()를 호출하여 이름을 지정합니다.
애플리케이션 내에서 CPU 및 GPU 측의 기본 타이밍 측정을 수행하려면 QElapsedTimer 및 QRhiCommandBuffer::lastCompletedGpuTime()을 사용할 수 있습니다. 후자는 현재 일부 그래픽 API에서만 사용할 수 있으며 QRhi::EnableTimestamps 플래그를 통해 옵트인해야 합니다.
리소스 유출 검사
QRhi 오브젝트에서 생성된 모든 버퍼, 텍스처 및 기타 리소스를 제대로 소멸하지 않고 소멸할 경우 애플리케이션이 디버그 빌드이거나 QT_RHI_LEAK_CHECK
환경 변수가 0이 아닌 값으로 설정된 경우 디버그 출력에 이에 대한 경고가 인쇄됩니다. 이는 애플리케이션 렌더링 로직 내에서 리소스 처리와 관련된 디자인 문제를 발견할 수 있는 간단한 방법입니다. 그러나 일부 플랫폼과 기본 그래픽 API는 자체 할당 및 리소스 누수 감지를 수행할 수 있으며, 이 경우 Qt가 직접 제어할 수 없다는 점에 유의하십시오. 예를 들어, Vulkan을 사용할 때 그래픽 메모리 할당을 소유한 리소스가 QRhi 이전에 소멸되지 않으면 메모리 할당자가 디버그 빌드에서 실패 어설션을 발생시킬 수 있습니다. 또한 Vulkan 유효성 검사 레이어가 활성화되면 해제되지 않은 네이티브 그래픽 리소스에 대한 경고를 발행합니다. 마찬가지로 Direct 3D를 사용하면 애플리케이션이 QRhi와 해당 리소스를 올바른 순서로 소멸하지 않으면 해제되지 않은 COM 오브젝트에 대한 경고가 출력될 수 있습니다.
RHI 창 예제, QRhiCommandBuffer, QRhiResourceUpdateBatch, QRhiShaderResourceBindings, QShader, QRhiBuffer, QRhiTexture, QRhiRenderBuffer, QRhiSampler, QRhiTextureRenderTarget, QRhiGraphicsPipeline, QRhiComputePipeline, QRhiSwapChain 을참조하십시오 .
멤버 유형 문서
열거형 QRhi::BeginFrameFlag
플래그 QRhi::BeginFrameFlags
QRhi::beginFrame()에 대한 플래그 값
BeginFrameFlags 형은 QFlags<BeginFrameFlag>에 대한 typedef입니다. BeginFrameFlag 값의 OR 조합을 저장합니다.
열거형 QRhi::EndFrameFlag
플래그 QRhi::EndFrameFlags
QRhi::endFrame()에 대한 플래그 값
상수 | 값 | 설명 |
---|---|---|
QRhi::SkipPresent | 1 << 0 | 현재 명령을 대기열에 넣지 않거나 swapBuffers 호출을 하지 않도록 지정합니다. 이렇게 하면 이미지가 표시되지 않습니다. 이 플래그가 모두 설정된 여러 프레임을 생성하는 것은 권장되지 않습니다(예를 들어 벤치마킹 목적이 아니라면, 프레젠테이션 없이 명령 완료를 기다릴 때 백엔드가 다르게 동작할 수 있으므로 서로 결과를 비교할 수 없습니다). |
EndFrameFlags 유형은 QFlags<EndFrameFlag>에 대한 typedef입니다. 이 유형은 EndFrameFlag 값의 OR 조합을 저장합니다.
enum QRhi::Feature
현재 사용 중인 백엔드에서 지원되는 기능을 나타내는 플래그 값입니다.
상수 | 값 | 설명 |
---|---|---|
QRhi::MultisampleTexture | 1 | 샘플 수가 1보다 큰 텍스처가 지원됨을 나타냅니다. 실제로 이 기능은 3.1 이전 OpenGL ES 버전과 3.0 이전 OpenGL에서는 지원되지 않습니다. |
QRhi::MultisampleRenderBuffer | 2 | 샘플 수가 1보다 큰 렌더버퍼가 지원됨을 나타냅니다. 실제로 이 기능은 OpenGL ES 2.0에서는 지원되지 않으며, 관련 확장이 없는 경우 OpenGL 2.x에서도 지원되지 않을 수 있습니다. |
QRhi::DebugMarkers | 3 | 디버그 마커 그룹(따라서 QRhiCommandBuffer::debugMarkBegin())이 지원됨을 나타냅니다. |
QRhi::Timestamps | 4 | 명령 버퍼 타임스탬프가 지원됨을 나타냅니다. QRhiCommandBuffer::lastCompletedGpuTime ()와 관련이 있습니다. 이 기능은 버전 3.3 이상의 Metal, Vulkan, Direct 3D 11 및 12, OpenGL 컨텍스트에서 지원될 것으로 예상할 수 있습니다. 그러나 이러한 API 중 일부는 타임스탬프 쿼리 지원이 기술적으로 선택 사항이므로 모든 구현에서 이 기능이 항상 지원된다고 보장할 수는 없습니다. |
QRhi::Instancing | 5 | 인스턴스화된 드로잉이 지원됨을 나타냅니다. 실제로 이 기능은 OpenGL ES 2.0 및 OpenGL 3.2 이상에서는 지원되지 않습니다. |
QRhi::CustomInstanceStepRate | 6 | 1 이외의 인스턴스 단계 속도가 지원됨을 나타냅니다. 실제로 이 기능은 OpenGL에서 항상 지원되지 않습니다. 또한 VK_EXT_vertex_attribute_divisor 없이 Vulkan 1.0으로 실행하면 이 기능에 대해서도 거짓을 보고하게 됩니다. |
QRhi::PrimitiveRestart | 7 | 적어도 특정 프리미티브 토폴로지에서 0xFFFF(IndexUInt16) 또는 0xFFFFFF(IndexUInt32)의 인덱스 값을 만나면 프리미티브 어셈블리를 다시 시작하는 것이 활성화되어 있음을 나타냅니다. QRhi 은 모든 백엔드에서 이 기능을 활성화하려고 시도하지만 일부 경우 지원되지 않을 수 있습니다. 일부 API에서는 고정 인덱스의 프리미티브 재시작이 항상 켜져 있기 때문에 프리미티브 재시작을 동적으로 제어할 수 없습니다. 애플리케이션은 이 기능이 지원되는 것으로 보고될 때마다 토폴로지에 따라 위에서 언급한 인덱스 값 may 이 특별하게 취급된다고 가정해야 합니다. 이 기능이 지원되는 것으로 보고되는 한, 기본 재시작이 백엔드에서 동일하게 작동하도록 보장되는 유일한 두 토폴로지는 LineStrip 와 TriangleStrip 입니다. |
QRhi::NonDynamicUniformBuffers | 8 | UniformBuffer 사용법과 Immutable 또는 Static 유형으로 버퍼를 만드는 것이 지원됨을 나타냅니다. 지원되지 않는 것으로 보고되면 균일한(상수) 버퍼를 Dynamic 으로 생성해야 합니다(이와 관계없이 권장됨). |
QRhi::NonFourAlignedEffectiveIndexBufferOffset | 9 | 4바이트 정렬이 아닌 유효 인덱스 버퍼 오프셋(indexOffset + firstIndex * indexComponentSize )이 지원됨을 나타냅니다. 지원되지 않는 경우 정렬되지 않은 유효 오프셋으로 drawIndexed()를 발행하려고 하면 지정되지 않은 동작이 발생할 수 있습니다. 특히 지원되지 않는 것으로 보고되는 Metal과 관련이 있습니다. |
QRhi::NPOTTextureRepeat | 10 | Repeat 랩 모드 및 밉맵 필터링 모드가 2의 거듭제곱이 아닌 크기의 텍스처에 대해 지원됨을 나타냅니다. 실제로는 GL_OES_texture_npot 이 없는 OpenGL ES 2.0 구현에서만 거짓일 수 있습니다. |
QRhi::RedOrAlpha8IsRed | 11 | RED_OR_ALPHA8 형식이 하나의 컴포넌트 8비트 red 형식에 매핑됨을 나타냅니다. 이는 OpenGL ES 또는 비핵심 프로파일 컨텍스트를 사용할 때 OpenGL을 제외한 모든 백엔드에 해당됩니다. 대신 원 컴포넌트 8비트 alpha 형식인 GL_ALPHA 이 사용됩니다. 특수 텍스처 형식을 사용하면 텍스처 생성을 위한 단일 코드 경로를 사용하여 백엔드에서 실제 형식을 결정할 수 있으며, 기능 플래그를 사용하여 텍스처 샘플링에 적합한 셰이더 변형을 선택할 수 있습니다. |
QRhi::ElementIndexUint | 12 | 인덱스 버퍼에서 32비트 부호 없는 정수 요소가 지원됨을 나타냅니다. 실제로는 필요한 확장 없이 일반 OpenGL ES 2.0 구현에서 실행하는 경우를 제외하고는 모든 경우에 해당됩니다. false이면 인덱스 버퍼에서 16비트 부호 없는 요소만 지원됩니다. |
QRhi::Compute | 13 | 컴퓨팅 셰이더, 이미지 로드/저장 및 스토리지 버퍼가 지원됨을 나타냅니다. 4.3 이전 OpenGL 및 3.1 이전 OpenGL ES는 계산을 지원하지 않습니다. |
QRhi::WideLines | 14 | 너비가 1이 아닌 선이 지원됨을 나타냅니다. 지원되지 않는 것으로 보고되면 그래픽 파이프라인 상태에 설정된 선 너비가 무시됩니다. 일부 백엔드(D3D11, D3D12, Metal)에서는 항상 거짓일 수 있습니다. Vulkan의 경우 값은 구현에 따라 다릅니다. OpenGL에서는 코어 프로파일 컨텍스트에서 넓은 선이 지원되지 않습니다. |
QRhi::VertexShaderPointSize | 15 | 버텍스 셰이더에서 gl_PointSize 을 통해 설정된 래스터화된 포인트의 크기가 고려됨을 나타냅니다. 지원되지 않는 것으로 보고되면 1 이외의 크기로 점을 그리는 것이 지원되지 않습니다. 셰이더에서 gl_PointSize 을 설정해도 여전히 유효하지만 무시됩니다. (예: HLSL 생성 시 생성된 코드에서 해당 할당이 자동으로 삭제됨) 일부 API(Metal, Vulkan)는 크기가 1인 경우에도 자동으로 기본값이 1로 설정되지 않으므로 포인트를 그릴 때마다 셰이더에서 포인트 크기를 명시적으로 설정해야 한다는 점에 유의하세요. |
QRhi::BaseVertex | 16 | drawIndexed()가 vertexOffset 인수를 지원함을 나타냅니다. 지원되지 않는 것으로 보고되면 인덱싱된 그리기의 vertexOffset 값은 무시됩니다. 실제로 이 기능은 OpenGL 및 OpenGL ES 3.2 미만 버전과 iOS 시뮬레이터를 포함한 구형 iOS 기기의 Metal에서는 지원되지 않습니다. |
QRhi::BaseInstance | 17 | 인스턴스화된 그리기 명령이 firstInstance 인수를 지원함을 나타냅니다. 지원되지 않는 것으로 보고되면 첫 번째 인스턴스 값은 무시되고 인스턴스 ID는 0부터 시작됩니다. 실제로 이 기능은 OpenGL 및 iOS 시뮬레이터를 포함한 구형 iOS 기기의 Metal에서 지원되지 않습니다. |
QRhi::TriangleFanTopology | 18 | QRhiGraphicsPipeline::setTopology()가 QRhiGraphicsPipeline::TriangleFan 을 지원함을 나타냅니다. 실제로 이 기능은 Metal 및 Direct 3D 11/12에서는 지원되지 않습니다. |
QRhi::ReadBackNonUniformBuffer | 19 | UniformBuffer와 다른 사용법을 사용하는 QRhiBuffer 인스턴스에 대해 reading buffer contents 이 지원됨을 나타냅니다. 실제로 이 기능은 OpenGL ES 2.0에서는 지원되지 않습니다. |
QRhi::ReadBackNonBaseMipLevel | 20 | 텍스처 콘텐츠를 다시 읽을 때 0 이외의 밉 레벨을 지정하는 것이 지원됨을 나타냅니다. 지원되지 않는 경우 QRhiReadbackDescription 에 0이 아닌 레벨을 지정하면 모두 0인 이미지가 반환됩니다. 실제로 이 기능은 OpenGL ES 2.0에서는 지원되지 않습니다. |
QRhi::TexelFetch | 21 | 셰이더에서 텍셀 페치() 및 텍스처 로드()를 사용할 수 있음을 나타냅니다. 실제로는 OpenGL ES 2.0 및 OpenGL 2.x 컨텍스트에서 지원되지 않는 것으로 보고되는데, 이는 OpenGL 100 es 및 130 이전 버전이 이러한 함수를 지원하지 않기 때문입니다. |
QRhi::RenderToNonBaseMipLevel | 22 | QRhiTexture 을 색으로 첨부하여 QRhiTextureRenderTarget 을 만들 때 0 이외의 밉 레벨을 지정하는 것이 지원됨을 나타냅니다. 지원되지 않는 경우 대상 밉 레벨이 0이 아닐 때마다 create()는 실패합니다. 실제로 이 기능은 OpenGL ES 2.0에서는 지원되지 않습니다. |
QRhi::IntAttributes | 23 | 셰이더 파이프라인에 부호 및 부호 없는 정수 유형으로 입력 어트리뷰트를 지정하는 것이 지원됨을 나타냅니다. 지원되지 않는 경우 build()는 성공하지만 경고 메시지만 표시되고 대상 어트리뷰트 값이 손상됩니다. 실제로 이 기능은 OpenGL ES 2.0 및 OpenGL 2.x에서 지원되지 않습니다. |
QRhi::ScreenSpaceDerivatives | 24 | 셰이더에서 dFdx(), dFdy(), fwidth() 등의 함수가 지원됨을 나타냅니다. 실제로 이 기능은 GL_OES_standard_derivatives 확장이 없는 OpenGL ES 2.0에서는 지원되지 않습니다. |
QRhi::ReadBackAnyTextureFormat | 25 | 텍스처 콘텐츠 읽기가 모든 QRhiTexture::Format 에서 작동할 수 있음을 나타냅니다. OpenGL 이외의 백엔드에서는 이 기능에 대해 참을 반환할 것으로 예상할 수 있습니다. OpenGL에서 일반적으로 발생하는 거짓으로 보고되면 QRhiTexture::RGBA8 및 QRhiTexture::BGRA8 형식만 읽기백이 지원되도록 보장됩니다. 또한 OpenGL ES가 아닌 OpenGL의 경우 컴포넌트당 1바이트 형식 QRhiTexture::R8 및 QRhiTexture::RED_OR_ALPHA8 읽기 기능도 지원됩니다. 부동 소수점 형식 QRhiTexture::RGBA16F 및 RGBA32F 읽기백은 구현에서 이를 지원하는 경우 OpenGL에서도 작동할 수 있지만, QRhi 은 이 플래그에 표시된 것처럼 보장할 수 없습니다. |
QRhi::PipelineCacheDataLoadSave | 26 | pipelineCacheData() 및 setPipelineCacheData() 함수가 작동함을 나타냅니다. 지원되지 않는 경우 함수는 아무런 작업도 수행하지 않으며, 검색된 블롭은 항상 비어 있으므로 애플리케이션의 후속 실행 중에 파이프라인 캐시 콘텐츠를 검색하고 다시 로드해도 아무런 이점을 기대할 수 없습니다. |
QRhi::ImageDataStride | 27 | 텍스처 업로드에서 원시 이미지 데이터에 대한 사용자 지정 보폭(행 길이)을 지정하는 것이 지원됨을 나타냅니다. 지원되지 않는 경우(기본 API가 GL_UNPACK_ROW_LENGTH를 지원하지 않는 OpenGL ES 2.0일 때 발생할 수 있음) QRhiTextureSubresourceUploadDescription::setDataStride()를 사용해서는 안 됩니다. |
QRhi::RenderBufferImport | 28 | QRhiRenderBuffer::createFrom()가 지원됨을 나타냅니다. QRhiRenderBuffer 은 QRhiTexture 과 같이 내부적으로 텍스처 객체를 캡슐화하므로 대부분의 그래픽 API에서는 이 방법이 적절하지 않습니다. 그러나 OpenGL의 경우 렌더버퍼 객체는 API에서 별도의 객체 유형으로 존재하며, 특정 환경(예: 렌더버퍼 객체를 EGLImage 객체에 연결하려는 경우)에서는 기존 OpenGL 렌더버퍼 객체를 QRhiRenderBuffer 로 래핑할 수 있도록 허용하는 것이 중요합니다. |
QRhi::ThreeDimensionalTextures | 29 | 3D 텍스처가 지원됨을 나타냅니다. 실제로 이 기능은 OpenGL 및 OpenGL ES 3.0 미만 버전에서는 지원되지 않습니다. |
QRhi::RenderTo3DTextureSlice | 30 | 3D 텍스처의 슬라이스로 렌더링이 지원됨을 나타냅니다. 이 기능은 Vulkan 1.1 기능인 VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT에 의존하기 때문에 Vulkan 1.0에서는 지원되지 않을 수 있습니다. |
QRhi::TextureArrays | 31 | 텍스처 배열이 지원되고 QRhi::newTextureArray()가 작동함을 나타냅니다. 텍스처 배열이 지원되지 않는 경우에도 텍스처 배열은 두 가지 독립적인 기능이므로 여전히 사용할 수 있습니다. |
QRhi::Tessellation | 32 | 테셀레이션 제어 및 평가 단계가 지원됨을 나타냅니다. 지원되는 것으로 보고되면 QRhiGraphicsPipeline 의 토폴로지는 Patches 으로 설정할 수 있고, 제어 포인트 수는 setPatchControlPointCount()를 통해 설정할 수 있으며, 테셀레이션 제어 및 평가를 위한 셰이더는 QRhiShaderStage 목록에서 지정할 수 있습니다. 테셀레이션 셰이더는 API 간 이식성 문제가 있으므로(예를 들어, GLSL/SPIR-V를 HLSL로 변환하는 것은 헐 셰이더의 구조 방식 때문에 문제가 되는 반면, Metal은 다른 셰이더와 다소 다른 테셀레이션 파이프라인을 사용합니다) 기본 기능이 모든 기반 API에서 구현되어 있어도 예기치 않은 문제가 여전히 발생할 수 있습니다. 특히 Direct 3D의 경우, 테셀레이션 제어 및 평가 단계에서는 각각 수작업으로 작성된 HLSL 헐과 도메인 셰이더를 qsb에서 생성할 수 없으므로 각각 QShader 에 주입해야 합니다. 아이솔라인 테셀레이션은 모든 백엔드에서 지원되지 않으므로 피해야 합니다. 백엔드 간에 이식 가능한 최대 패치 제어점 수는 32개입니다. |
QRhi::GeometryShader | 33 | 지오메트리 셰이더 스테이지가 지원됨을 나타냅니다. 지원되는 경우 지오메트리 셰이더는 QRhiShaderStage 목록에서 지정할 수 있습니다. 지오메트리 셰이더는 QRhi 에서 실험적 기능으로 간주되며, 구현이 런타임에 지원되는 것으로 보고하는 경우 Vulkan, Direct 3D, OpenGL(3.2+) 및 OpenGL ES(3.2+)에서만 지원될 것으로 예상할 수 있습니다. 지오메트리 셰이더는 API 간 이식성 문제가 있으므로 범용 솔루션을 보장할 수 없습니다. 메탈에서는 절대 지원되지 않습니다. 반면 Direct 3D에서는 qsb가 SPIR-V에서 이를 생성할 수 없으므로 지오메트리 단계에 대해 손으로 쓴 HLSL 지오메트리 셰이더를 각 QShader 에 주입해야 합니다. |
QRhi::TextureArrayRange | 34 | texture arrays 에 대해 셰이더에 노출되는 범위를 지정할 수 있음을 나타냅니다. 일반적으로 모든 배열 레이어가 노출되며 레이어를 선택하는 것은 셰이더의 몫입니다( sampler2DArray 샘플링 시 texture()에 전달되는 세 번째 좌표를 통해). 지원되는 경우, 네이티브 텍스처가 building 또는 importing 앞에 QRhiTexture::setArrayRangeStart() 및 QRhiTexture::setArrayRangeLength()를 호출하면 효과가 발생하여 배열에서 지정된 범위만 선택하게 됩니다. 이는 가속 비디오 디코딩 및 Direct 3D 11로 작업할 때와 같은 특수한 경우에 필요한데, D3D11_BIND_DECODER 및 D3D11_BIND_SHADER_RESOURCE 이 모두 포함된 텍스처 배열은 단일 배열 레이어가 선택된 경우에만 셰이더 리소스로 사용할 수 있기 때문입니다. 이 모든 기능은 텍스처가 QRhiShaderResourceBinding::SampledTexture 또는 QRhiShaderResourceBinding::Texture 셰이더 리소스로 사용되는 경우에만 적용되며 이미지 로드/스토어와 호환되지 않는다는 점에 유의하세요. 이 기능은 모든 그래픽 API에 잘 매핑되지 않기 때문에 일부 백엔드에서만 사용할 수 있으며, 어쨌든 특수한 경우에만 지원하기 위한 것입니다. 실제로 이 기능은 Direct3D 11/12 및 Vulkan에서 지원될 것으로 예상할 수 있습니다. |
QRhi::NonFillPolygonMode | 35 | 기본 채우기 이외의 폴리곤 모드 설정이 QRhiGraphicsPipeline 에 대해 지원됨을 나타냅니다. 모드를 선으로 변경하는 일반적인 사용 사례는 와이어프레임 렌더링을 얻기 위한 것입니다. 그러나 이 기능은 핵심 OpenGL ES 기능으로 제공되지 않으며, Vulkan에서는 선택 사항이며 일부 모바일 GPU에서는 이 기능을 제공하지 않을 수도 있습니다. |
QRhi::OneDimensionalTextures | 36 | 1D 텍스처가 지원됨을 나타냅니다. 실제로 이 기능은 OpenGL ES에서 지원되지 않습니다. |
QRhi::OneDimensionalTextureMipmaps | 37 | 1D 텍스처 밉맵 생성이 지원됨을 나타냅니다. 실제로 이 기능은 원디멘셔널 텍스처, 메탈, 다이렉트 3D 12에 대한 지원을 보고하지 않는 백엔드에서는 지원되지 않습니다. |
QRhi::HalfAttributes | 38 | 셰이더 파이프라인에 반정밀도(16비트) 부동 소수점 유형으로 입력 어트리뷰트를 지정하는 것이 지원됨을 나타냅니다. 지원되지 않는 경우 빌드()는 성공하지만 경고 메시지만 표시되고 대상 어트리뷰트 값이 손상됩니다. 실제로 이 기능은 일부 OpenGL ES 2.0 및 OpenGL 2.x 구현에서는 지원되지 않습니다. Direct3D 11/12는 반정밀도 입력 속성을 지원하지만 반3 유형은 지원하지 않습니다. D3D 백엔드는 half3 어트리뷰트를 half4로 전달합니다. 플랫폼 간 호환성을 보장하기 위해 반값3 입력은 8바이트로 패딩해야 합니다. |
QRhi::RenderToOneDimensionalTexture | 39 | 1D 텍스처 렌더 타깃이 지원됨을 나타냅니다. 실제로 이 기능은 원디멘셔널 텍스처 및 메탈에 대한 지원을 보고하지 않는 백엔드에서는 지원되지 않습니다. |
QRhi::ThreeDimensionalTextureMipmaps | 40 | 3D 텍스처 밉맵 생성이 지원됨을 나타냅니다. 실제로 이 기능은 Direct 3D 12에서는 지원되지 않습니다. |
QRhi::MultiView | 41 | 멀티뷰(예: VK_KHR_multiview )가 지원됨을 나타냅니다. OpenGL ES 2.0, Direct 3D 11 및 GL_OVR_multiview2 없는 OpenGL(ES) 구현에서는 이 기능이 지원되지 않습니다. Vulkan 1.1 이상 및 Direct 3D 12에서는 일반적으로 멀티뷰가 지원됩니다. 지원되는 것으로 보고된 경우 텍스처 배열을 참조하고 multiViewCount 가 설정된 QRhiColorAttachment 을 사용하여 QRhiTextureRenderTarget 을 생성하면 멀티뷰 렌더링을 사용하는 렌더 패스를 기록할 수 있습니다. 또한 해당 렌더 패스에 사용된 QRhiGraphicsPipeline 에는 the same view count set 이 있어야 합니다. 멀티뷰는 2D 텍스처 배열과 함께만 사용할 수 있다는 점에 유의하세요. 렌더링을 개별 텍스처(예: 왼쪽 눈과 오른쪽 눈의 경우 두 개)로 최적화하는 데는 사용할 수 없습니다. 그 대신 멀티뷰 렌더 패스의 대상은 항상 텍스처 배열이며 각 뷰에 해당하는 레이어(배열 요소)로 자동 렌더링됩니다. 따라서 이 기능은 TextureArrays도 의미합니다. 멀티뷰 렌더링은 테셀레이션 또는 지오메트리 셰이더와 함께 지원되지 않습니다. 멀티뷰 렌더링에 대한 자세한 내용은 QRhiColorAttachment::setMultiViewCount()를 참조하십시오. 이 열거형 값은 Qt 6.7에 도입되었습니다. |
QRhi::TextureViewFormat | 42 | QRhiTexture 에 view format 을 설정하는 것이 유효함을 나타냅니다. 지원되는 것으로 보고되면 읽기(샘플링) 또는 쓰기(렌더 대상/이미지 로드-저장) 보기 모드를 설정하면 텍스처의 보기 형식이 변경됩니다. 지원되지 않는 경우 보기 형식을 설정해도 아무런 효과가 없습니다. Qt는 기본 3D API와 그 구현에서 형식 호환성이나 리소스 뷰 규칙에 대한 지식이나 제어권이 없습니다. 부적합하고 호환되지 않는 형식을 전달하면 오류 및 지정되지 않은 동작이 발생할 수 있습니다. 이는 주로 셰이더 쓰기 시 원치 않는 선형->sRGB 변환을 피하기 위해 sRGB 포맷으로 생성된 텍스처를 비 sRGB로 '캐스팅'하여 렌더링할 수 있도록 하기 위해 제공됩니다. 다른 유형의 캐스팅은 기본 API에 따라 작동할 수도 있고 작동하지 않을 수도 있습니다. 현재 Vulkan 및 Direct 3D 12에 구현되어 있습니다. D3D12에서는 CastingFullyTypedFormatSupported 가 지원되는 경우에만 이 기능을 사용할 수 있습니다( https://microsoft.github.io/DirectX-Specs/d3d/RelaxedCasting.html 참조, QRhi 는 항상 텍스처에 완전한 형식의 형식을 사용합니다.) 이 열거형 값은 Qt 6.8에 도입되었습니다. |
QRhi::ResolveDepthStencil | 43 | 멀티샘플 뎁스 또는 뎁스 스텐실 텍스처의 해상도가 지원됨을 나타냅니다. 그렇지 않으면 setting a depth resolve texture 은 작동하지 않으므로 피해야 합니다. Direct 3D 11 및 12는 뎁스/뎁스 스텐실 형식의 해상도를 지원하지 않으므로 이 기능은 해당 형식에서는 지원되지 않습니다. 벌칸 1.0에는 뎁스 스텐실 어태치먼트의 해상도를 요청하는 API가 없습니다. 따라서 이 기능은 Vulkan 1.2 이상 및 적절한 확장 기능이 있는 1.1 구현에서만 지원됩니다. 이 기능은 멀티샘플이 아닌 뎁스 텍스처로 해상해야 하는 드문 경우, 예를 들어 OpenXR에서 제공하는 뎁스 텍스처(XR_KHR_composition_layer_depth)로 렌더링할 때를 위해 제공됩니다. 이 열거형 값은 Qt 6.8에 도입되었습니다. |
enum QRhi::Flag
flags QRhi::Flags
활성화할 특수 기능을 설명합니다.
상수 | 값 | 설명 |
---|---|---|
QRhi::EnableDebugMarkers | 1 << 0 | 디버그 마커 그룹을 활성화합니다. 이 프레임이 없으면 외부 GPU 디버깅 도구에서 디버그 그룹 및 사용자 지정 리소스 이름을 표시하는 등의 디버깅 기능을 사용할 수 없으며 QRhiCommandBuffer::debugMarkBegin()와 같은 기능이 작동하지 않습니다. 성능에 약간의 영향을 줄 수 있으므로 프로덕션 빌드에서는 활성화하지 마세요. QRhi::DebugMarkers 기능이 지원되지 않는 것으로 보고된 경우에는 효과가 없습니다. |
QRhi::EnableTimestamps | 1 << 3 | GPU 타임스탬프 수집을 활성화합니다. 설정하지 않으면 QRhiCommandBuffer::lastCompletedGpuTime()는 항상 0을 반환합니다. 기본 그래픽 API에 따라 소량의 추가 작업(예: 타임스탬프 쿼리)이 필요할 수 있으므로 필요한 경우에만 이 옵션을 활성화합니다. QRhi::Timestamps 기능이 지원되지 않는 것으로 보고된 경우에는 효과가 없습니다. |
QRhi::PreferSoftwareRenderer | 1 << 1 | 백엔드에서 CPU의 소프트웨어에서 렌더링하는 어댑터 또는 물리적 장치를 선택하는 것을 선호해야 함을 나타냅니다. 예를 들어 Direct3D의 경우 일반적으로 DXGI_ADAPTER_FLAG_SOFTWARE 에서 사용할 수 있는 "기본 렌더 드라이버" 어댑터가 있습니다. 이 플래그를 설정하면 다른 백엔드 전용 수단에 의해 특정 어댑터가 강제되지 않는 한 백엔드에서 다른 어댑터보다 해당 어댑터를 선택하도록 요청합니다. 벌칸에서는 VK_PHYSICAL_DEVICE_TYPE_CPU 를 사용하는 물리적 장치를 선호하는 것으로 매핑됩니다. 사용할 수 없거나 어댑터/장치가 소프트웨어 기반인지 여부를 결정할 수 없는 경우 이 플래그는 무시됩니다. 어댑터/장치를 열거하는 개념과 수단이 없는 그래픽 API의 경우에도 무시될 수 있습니다. |
QRhi::EnablePipelineCacheDataSave | 1 << 2 | 해당되는 경우 파이프라인 캐시 콘텐츠 검색을 활성화합니다. 설정하지 않으면 pipelineCacheData()는 항상 빈 블롭을 반환합니다. 파이프라인 캐시 콘텐츠 검색 및 복원이 지원되지 않는 백엔드에서는 플래그가 아무런 영향을 미치지 않으며 직렬화된 캐시 데이터는 항상 비어 있습니다. 일부 백엔드에서는 관련 데이터 구조를 유지하는 데 드는 비용이 적지 않기 때문에 플래그는 옵트인 메커니즘을 제공합니다. Vulkan에서는 이 기능이 VkPipelineCache, vkGetPipelineCacheData 및 VkPipelineCacheCreateInfo::pInitialData에 직접 매핑됩니다. Direct3D 11에는 실제 파이프라인 캐시가 없지만 HLSL->DXBC 컴파일 결과가 저장되며 이 메커니즘을 통해 직렬화/역직렬화할 수 있습니다. 따라서 오프라인으로 미리 컴파일된 바이트코드 대신 HLSL 소스와 함께 제공되는 셰이더의 경우 향후 애플리케이션 실행 시 시간이 많이 소요되는 D3DCompile()을 건너뛸 수 있습니다. 이렇게 하면 HLSL 소스 컴파일이 많이 발생하는 경우 시작 및 로드 시간이 크게 향상될 수 있습니다. OpenGL을 사용하면 셰이더 프로그램 바이너리를 검색하고 로드하여 "파이프라인 캐시"를 시뮬레이션합니다(드라이버에서 지원하는 경우). OpenGL에는 Qt에서 제공하는 셰이더/프로그램 바이너리를 위한 추가적인 디스크 기반 캐싱 메커니즘이 있습니다. 프로그램 바이너리를 여러 캐시에 저장하는 것은 적절하지 않으므로 이 플래그를 설정할 때마다 해당 캐시에 대한 쓰기가 비활성화될 수 있습니다. |
QRhi::SuppressSmokeTestWarnings | 1 << 4 | 관련 백엔드에서 치명적이지 않은 특정 QRhi::create() 실패가 qWarning() 호출을 생성해서는 안 됨을 나타냅니다. 예를 들어 D3D11에서 이 플래그를 전달하면 QRhi::create() 실패로 인해 표시되는 여러 경고 메시지가 일반적으로 사용되는 qt.rhi.general 로깅 카테고리로 분류된 디버그 프린트가 됩니다. 이 기능은 폴백 로직이 있는 Qt Quick 와 같은 엔진에서 사용할 수 있습니다. 즉, 첫 번째 create() 시도가 실패했을 때 출력되는 무조건적인 경고를 숨기기 위해 다른 플래그 세트(예: PreferSoftwareRenderer)로 create() 호출을 다시 시도하는 것입니다. |
Flags 유형은 QFlags<Flag>에 대한 typedef입니다. 플래그 값의 OR 조합을 저장합니다.
enum QRhi::FrameOpResult
소프트 장애가 발생할 수 있는 작업의 결과를 설명합니다.
Constant | 값 | 설명 |
---|---|---|
QRhi::FrameOpSuccess | 0 | 성공 |
QRhi::FrameOpError | 1 | 지정되지 않은 오류 |
QRhi::FrameOpSwapChainOutOfDate | 2 | 스왑체인이 내부적으로 일관되지 않은 상태입니다. 나중에 beginFrame() 등의 작업을 반복하면 복구할 수 있습니다. |
QRhi::FrameOpDeviceLost | 3 | 그래픽 장치가 손실되었습니다. 네이티브 그래픽 리소스가 지원하는 모든 객체를 해제하고 다시 초기화한 후 beginFrame() 등의 작업을 반복하면 복구할 수 있습니다. isDeviceLost ()를 참조하세요. |
enum QRhi::Implementation
QRhi 인스턴스에서 사용하는 그래픽 API별 백엔드를 설명합니다.
Constant | Value |
---|---|
QRhi::Null | 0 |
QRhi::Vulkan | 1 |
QRhi::OpenGLES2 | 2 |
QRhi::D3D11 | 3 |
QRhi::D3D12 | 5 |
QRhi::Metal | 4 |
enum QRhi::ResourceLimit
쿼리할 리소스 제한을 설명합니다.
상수 | 값 | 설명 |
---|---|---|
QRhi::TextureSizeMin | 1 | 최소 텍스처 너비와 높이입니다. 일반적으로 1입니다. 최소 텍스처 크기는 정상적으로 처리되므로 크기가 비어 있는 텍스처를 만들려고 시도하면 대신 최소 크기의 텍스처가 생성됩니다. |
QRhi::TextureSizeMax | 2 | 최대 텍스처 너비 및 높이. 이는 그래픽 API에 따라 다르며 때로는 플랫폼이나 구현에 따라 달라집니다. 일반적으로 이 값은 4096 - 16384 범위입니다. 이보다 큰 텍스처를 만들려고 하면 실패할 것으로 예상됩니다. |
QRhi::MaxColorAttachments | 3 | 여러 렌더링 타겟이 지원되는 경우 QRhiTextureRenderTarget 에 대한 최대 색상 첨부 수입니다. MRT가 지원되지 않는 경우 이 값은 1입니다. 그렇지 않으면 일반적으로 8이지만 OpenGL은 최소값으로 4만을 요구하며 일부 OpenGL ES 구현에서는 이를 제공한다는 사실에 유의하세요. |
QRhi::FramesInFlight | 4 | 백엔드가 "비행 중"으로 유지할 수 있는 프레임 수: Vulkan 또는 Metal과 같은 백엔드에서는 새 프레임을 시작하고 CPU가 이미 GPU보다 N - 1 프레임 앞서 있는 경우(프레임 번호 current - N 에 제출된 명령 버퍼가 아직 완료되지 않았기 때문에) 차단하는 것은 QRhi 의 책임입니다. 여기서 반환되는 값 N은 일반적으로 2입니다. 이러한 렌더링 코드는 QRhi 백엔드 자체와 유사하게 버퍼와 같은 리소스에 대해 이중(값이 2인 경우) 버퍼링을 수행할 수 있으므로 그래픽 API와 직접 수행되는 렌더링을 통합하는 애플리케이션과 관련이 있을 수 있습니다. 현재 프레임 슬롯 인덱스(0, 1, ..., N-1로 실행된 후 감싸는 값)는 QRhi::currentFrameSlot()에서 검색할 수 있습니다. 그래픽 API가 명령 제출 프로세스에 대한 낮은 수준의 제어를 제공하지 않는 백엔드의 경우 이 값은 1입니다. 이 값이 1인 경우에도 파이프라인이 발생할 수 있지만(예를 들어 D3D11과 같은 일부 백엔드는 파이프라인을 지연시키지 않는 균일한 버퍼에 대한 업데이트 전략을 사용하여 이를 활성화하도록 설계됨), 이는 QRhi 에서 제어되지 않으므로 여기서는 API에 반영되지 않는다는 점에 유의하세요. |
QRhi::MaxAsyncReadbackFrames | 5 | 비동기 텍스처 또는 버퍼 읽기백이 starting a new frame 에서 완료되도록 보장되는 submitted 프레임 수(읽기백이 포함된 프레임 포함)입니다. |
QRhi::MaxThreadGroupsPerDimension | 6 | 디스패치할 수 있는 최대 계산 작업/스레드 그룹 수입니다. 사실상 QRhiCommandBuffer::dispatch() 인수의 최대값입니다. 일반적으로 65535입니다. |
QRhi::MaxThreadsPerThreadGroup | 7 | 단일 로컬 작업 그룹의 최대 호출 수 또는 다른 용어로 스레드 그룹의 최대 스레드 수입니다. 사실상 컴퓨트 셰이더에서 local_size_x , local_size_y , local_size_z 의 곱의 최대값입니다. 일반적인 값은 128, 256, 512, 1024 또는 1536입니다. OpenGL ES와 벌칸 모두 구현에 필요한 최소값으로 128만 지정하고 있다는 점에 유의하세요. Vulkan의 경우 흔하지는 않지만, 모바일/임베디드 디바이스를 위한 일부 OpenGL ES 3.1 구현은 사양에서 요구하는 최소값만 지원합니다. |
QRhi::MaxThreadGroupX | 8 | X 차원에서 작업/스레드 그룹의 최대 크기입니다. 사실상 컴퓨트 셰이더에서 local_size_x 의 최대 값입니다. 일반적으로 256 또는 1024입니다. |
QRhi::MaxThreadGroupY | 9 | Y 차원에서의 작업/스레드 그룹의 최대 크기입니다. 실제로는 컴퓨트 셰이더에서 local_size_y 의 최대값입니다. 일반적으로 256 또는 1024입니다. |
QRhi::MaxThreadGroupZ | 10 | Z 차원에서의 작업/스레드 그룹의 최대 크기입니다. 실제로는 컴퓨트 셰이더에서 local_size_z 의 최대 값입니다. 일반적으로 64 또는 256입니다. |
QRhi::TextureArraySizeMax | 11 | 최대 텍스처 배열 크기. 일반적으로 256 - 2048 범위입니다. 더 많은 요소로 create a texture array 을 시도하면 실패할 가능성이 높습니다. |
QRhi::MaxUniformBufferRange | 12 | 균일 버퍼에서 셰이더로 한 번에 노출될 수 있는 바이트 수입니다. OpenGL ES 2.0 및 3.0 구현에서는 3584바이트(4개 구성 요소 224개, 구성 요소 벡터당 32비트)까지 낮을 수 있습니다. 그 외의 경우에는 일반적으로 16384(1024벡4초) 또는 65536(4096벡4초)입니다. |
QRhi::MaxVertexInputs | 13 | 버텍스 셰이더에 대한 입력 어트리뷰트 수입니다. QRhiVertexInputAttribute 의 위치는 [0, MaxVertexInputs-1] 범위 내에 있어야 합니다. OpenGL ES 2.0의 경우 이 값은 8까지 낮을 수 있습니다. 그 외의 경우 일반적인 값은 16, 31 또는 32입니다. |
QRhi::MaxVertexOutputs | 14 | 버텍스 셰이더의 최대 출력 수(4개의 컴포넌트 벡터 out 변수)입니다. 이 값은 OpenGL ES 2.0에서는 8, OpenGL ES 3.0 및 일부 Metal 디바이스에서는 15까지 낮아질 수 있습니다. 그 외의 경우 일반적인 값은 32입니다. |
멤버 함수 문서
[noexcept]
QRhi::~QRhi()
디스트럭터. 백엔드를 파괴하고 리소스를 해제합니다.
void QRhi::addCleanupCallback(const QRhi::CleanupCallback &callback)
QRhi 이 소멸되거나 runCleanup()가 호출될 때 호출되는 callback 을 등록합니다.
콜백은 그래픽 리소스를 계속 사용할 수 있는 상태에서 실행되므로 애플리케이션이 QRhi 에 속한 QRhiResource 인스턴스를 깨끗하게 해제할 수 있습니다. 이는 캐시가 QRhiResources 또는 QRhiResources를 포함하는 객체를 보유하는 cache
유형의 객체에 저장된 리소스의 수명을 관리할 때 특히 유용합니다.
runCleanup() 및 ~QRhi()도 참조하세요 .
void QRhi::addCleanupCallback(const void *key, const QRhi::CleanupCallback &callback)
이 함수는 오버로드된 함수입니다.
QRhi 이 소멸되거나 runCleanup()가 호출될 때 호출되도록 callback 을 등록합니다. 이 오버로드는 지정된 콜백이 한 번만 등록(소위 호출)되도록 하는 데 사용되는 불투명 포인터 key 를 받습니다.
removeCleanupCallback()도 참조하세요 .
QRhi::Implementation QRhi::backend() const
이 QRhi 에 대한 백엔드 유형을 반환합니다.
const char *QRhi::backendName() const
이 QRhi 에 대한 백엔드 유형을 문자열로 반환합니다.
[static]
const char *QRhi::backendName(QRhi::Implementation impl)
백엔드의 친숙한 이름 impl(일반적으로 사용 중인 3D API의 이름)을 반환합니다.
QRhi::FrameOpResult QRhi::beginFrame(QRhiSwapChain *swapChain, QRhi::BeginFrameFlags flags = {})
다음 사용 가능한 버퍼 swapChain 를 대상으로 새 프레임을 시작합니다.
프레임은 리소스 업데이트와 하나 이상의 렌더링 및 계산 패스로 구성됩니다.
flags 는 특정 특수한 경우를 나타낼 수 있습니다.
스왑체인을 사용하여 QWindow 로 렌더링하는 높은 수준의 패턴입니다:
- 스왑체인을 생성합니다.
- 표면 크기가 이전과 다를 때마다 QRhiSwapChain::createOrResize()를 호출합니다.
- QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed 에서 QRhiSwapChain::destroy()를 호출합니다.
- 그런 다음 모든 프레임에서:
beginFrame(sc); updates = nextResourceUpdateBatch(); updates->... QRhiCommandBuffer *cb = sc->currentFrameCommandBuffer(); cb->beginPass(sc->currentFrameRenderTarget(), colorClear, dsClear, updates); ... cb->endPass(); ... // more passes as necessary endFrame(sc);
성공하면 QRhi::FrameOpSuccess 를 반환하고 실패하면 다른 QRhi::FrameOpResult 값을 반환합니다. 이 중 일부는 "나중에 다시 시도" 유형의 부드러운 오류로 처리해야 합니다: QRhi::FrameOpSwapChainOutOfDate 가 반환되면 QRhiSwapChain::createOrResize()를 호출하여 스왑체인의 크기를 조정하거나 업데이트해야 합니다. QRhi::FrameOpDeviceLost 은 그래픽 장치가 손실되었음을 의미하지만 QRhi 자체를 포함한 모든 리소스를 해제하고 모든 리소스를 다시 생성하면 복구할 수 있습니다. 자세한 내용은 isDeviceLost()를 참조하세요.
endFrame(), beginOffscreenFrame() 및 isDeviceLost()도 참조하세요 .
QRhi::FrameOpResult QRhi::beginOffscreenFrame(QRhiCommandBuffer **cb, QRhi::BeginFrameFlags flags = {})
새 오프스크린 프레임을 시작합니다. cb 에 렌더링 명령을 기록하는 데 적합한 명령 버퍼를 제공합니다. flags 은 beginFrame()와 마찬가지로 특정 특수한 경우를 나타내는 데 사용됩니다.
참고: *cb에 저장된 QRhiCommandBuffer 은 호출자가 소유하지 않습니다.
스왑체인 없이 렌더링하는 것도 가능합니다. 일반적인 사용 사례는 창을 표시하지 않고 렌더링하고 다시 읽어 이미지 시퀀스를 생성하는 등 완전히 화면 밖 애플리케이션에서 사용하는 것입니다.
화면 내 애플리케이션(예: beginFrame, endFrame, beginOffscreenFrame, endOffscreenFrame, beginFrame, ...)에서도 사용할 수 있지만 병렬성이 저하되므로 드물게만 사용해야 합니다.
오프스크린 프레임은 GPU가 이전 프레임을 처리하는 동안 CPU가 잠재적으로 다른 프레임을 생성하지 못하게 합니다. 이로 인해 읽기백이 예약된 경우 endOffscreenFrame()가 반환되면 결과를 사용할 수 있다는 부작용이 있습니다. 스왑체인을 대상으로 하는 프레임은 그렇지 않습니다. 이 경우 GPU를 더 잘 활용할 수 있지만 endFrame()는 endOffscreenFrame()와 달리 그 시점에서 읽기백의 결과를 사용할 수 있다는 보장이 없기 때문에 애플리케이션에서 읽기백 작업을 할 때는 더 많은 주의가 필요합니다.
스왑체인 없이 프레임을 렌더링한 다음 프레임 내용을 다시 읽어오는 골격은 다음과 같습니다:
QRhiReadbackResult rbResult; QRhiCommandBuffer *cb; rhi->beginOffscreenFrame(&cb); cb->beginPass(rt, colorClear, dsClear); // ... u = nextResourceUpdateBatch(); u->readBackTexture(rb, &rbResult); cb->endPass(u); rhi->endOffscreenFrame(); // image data available in rbResult
endOffscreenFrame() 및 beginFrame()도 참조하세요 .
QMatrix4x4 QRhi::clipSpaceCorrMatrix() const
활성 QRhi 백엔드에 관계없이 애플리케이션이 OpenGL 대상 버텍스 데이터와 원근 투영 행렬(예: QMatrix4x4::perspective()에서 생성된 행렬)을 계속 사용할 수 있도록 하는 데 사용할 수 있는 행렬을 반환합니다.
일반적인 렌더러에서 mvp
대신 this_matrix * mvp
을 사용하면 런타임에 어떤 백엔드(따라서 그래픽 API)를 사용할지 고려하지 않고도 Y가 위로 향한 버텍스 데이터와 깊이 범위가 0~1인 뷰포트를 사용할 수 있습니다. 이렇게 하면 isYUpInNDC() 및 isClipDepthZeroToOne()에 기반한 분기를 피할 수 있습니다(특정 고급 그래픽 기술을 구현할 때 이러한 로직이 여전히 필요할 수 있음).
벌칸 관점에서 이 주제에 대한 논의는 이 페이지를 참조하세요.
[static]
QRhi *QRhi::create(QRhi::Implementation impl, QRhiInitParams *params, QRhi::Flags flags = {}, QRhiNativeHandles *importDevice = nullptr)
impl 에서 지정한 그래픽 API의 백엔드가 있는 새 QRhi 인스턴스를 flags 로 반환합니다. 함수가 실패하면 nullptr
를 반환합니다.
params 는 QRhiVulkanInitParams, QRhiMetalInitParams, QRhiD3D11InitParams, QRhiD3D12InitParams, QRhiGles2InitParams 와 같은 QRhiInitParams 의 백엔드별 서브클래스 중 하나의 인스턴스를 가리켜야 합니다. QRhi 를 만드는 예제는 이 클래스를 참조하세요.
QRhi 는 설계상 폴백 로직을 구현하지 않습니다. 지정된 API를 초기화할 수 없는 경우 백엔드에서 디버그 출력에 경고를 출력하면서 create()가 실패합니다. 그러나 QRhi 의 클라이언트(예: Qt Quick)는 플랫폼에 따라 요청된 것과 다른 API로 폴백할 수 있는 추가 로직을 제공할 수 있습니다. 나중에 create()를 호출할 때 초기화가 성공하는지 테스트하는 것이 목적이라면, 일부 백엔드에서는 인프라의 전체 초기화를 수행하고 해당 QRhi 인스턴스가 즉시 버려지는 경우 낭비되는 create()와 달리 프로빙을 더 가벼운 방식으로 구현할 수 있으므로 create() 대신 probe()를 사용하는 것이 바람직합니다.
importDevice 를 사용하면 QRhi 를 새로 만들지 않고도 이미 존재하는 그래픽 장치를 사용할 수 있습니다. 이 매개변수는 null이 아닌 경우, QRhiNativeHandles 의 서브클래스 중 하나의 인스턴스를 가리켜야 합니다: QRhiVulkanNativeHandles, QRhiD3D11NativeHandles, QRhiD3D12NativeHandles, QRhiMetalNativeHandles, QRhiGles2NativeHandles. 정확한 세부 사항과 의미는 백엔드 및 기본 그래픽 API에 따라 다릅니다.
probe()도 참조하세요 .
int QRhi::currentFrameSlot() const
프레임을 녹화하는 동안 현재 프레임 슬롯 인덱스를 반환합니다. 활성 프레임 외부에서 호출될 때(즉, isRecordingFrame()가 false
인 경우) 지정되지 않습니다.
벌칸이나 메탈과 같은 백엔드의 경우, 새 프레임을 시작하고 CPU가 이미 GPU보다 FramesInFlight - 1
프레임 앞서 있는 경우(프레임 번호 current
- FramesInFlight
에 제출된 명령 버퍼가 아직 완료되지 않았기 때문에) 이를 차단하는 것은 QRhi 백엔드의 책임입니다.
프레임 간에 변경되는 경향이 있는 리소스(예: 유형이 QRhiBuffer::Dynamic 인 QRhiBuffer 을 지원하는 기본 버퍼 객체)는 여러 버전으로 존재하므로 이전 프레임이 처리되는 동안 제출할 수 있는 각 프레임은 자체 복사본으로 작동하므로 프레임 준비 시 파이프라인을 중단할 필요가 없습니다. (GPU에서 아직 사용 중인 리소스의 콘텐츠는 건드리지 않아야 하지만, 이전 프레임이 완료될 때까지 항상 기다리면 GPU 사용률이 감소하고 궁극적으로 성능과 효율성이 저하됩니다.)
개념적으로 이것은 일부 C++ 컨테이너 및 기타 유형에서 사용하는 복사-온-쓰기 방식과 다소 유사합니다. 또한 특정 유형의 오브젝트에 대해 OpenGL 또는 Direct 3D 11 구현이 내부적으로 수행하는 것과 유사할 수도 있습니다.
실제로 이러한 이중(또는 삼중) 버퍼링 리소스는 Vulkan, Metal 및 이와 유사한 QRhi 백엔드에서 QRhiResource 뒤에 고정된 수의 기본 리소스(예: VkBuffer) slots
를 배치하여 구현됩니다. 그런 다음 0, 1, ..., FramesInFlight-1로 실행되는 프레임 슬롯 인덱스로 색인한 다음 래핑할 수 있습니다.
이 모든 것은 QRhi 사용자에게 투명하게 관리됩니다. 그러나 렌더링을 그래픽 API와 직접 통합하는 애플리케이션은 자체 그래픽 리소스에 대해 유사한 이중 또는 삼중 버퍼링을 수행하고자 할 수 있습니다. 이 경우 최대 인플라이트 프레임 수( resourceLimit()를 통해 검색 가능)와 현재 프레임(슬롯) 인덱스(이 함수에서 반환됨)의 값을 알면 가장 쉽게 수행할 수 있습니다.
isRecordingFrame(), beginFrame() 및 endFrame()도 참조하세요 .
QRhiDriverInfo QRhi::driverInfo() const
성공적으로 초기화된 QRhi 인스턴스에서 사용하는 그래픽 장치의 메타데이터를 반환합니다.
QRhi::FrameOpResult QRhi::endFrame(QRhiSwapChain *swapChain, QRhi::EndFrameFlags flags = {})
마지막 beginFrame()에서 시작된 프레임을 종료하고, 커밋하고, swapChain 에 표시합니다.
이중(또는 삼중) 버퍼링은 내부적으로 QRhiSwapChain 와 QRhi 에서 관리합니다.
flags 를 선택적으로 사용하여 특정 방식으로 동작을 변경할 수 있습니다. QRhi::SkipPresent 을 전달하면 Present 명령을 대기열에 넣거나 swapBuffers를 호출하는 것을 건너뜁니다.
성공하면 QRhi::FrameOpSuccess, 실패하면 다른 QRhi::FrameOpResult 값을 반환합니다. 이 중 일부는 "나중에 다시 시도" 유형의 소프트 에러로 처리해야 합니다: QRhi::FrameOpSwapChainOutOfDate 가 반환되면 QRhiSwapChain::createOrResize()를 호출하여 스왑체인의 크기를 조정하거나 업데이트해야 합니다. QRhi::FrameOpDeviceLost 은 그래픽 장치가 손실되었음을 의미하지만 QRhi 자체를 포함한 모든 리소스를 해제하고 모든 리소스를 다시 생성하면 복구할 수 있습니다. 자세한 내용은 isDeviceLost()를 참조하세요.
beginFrame() 및 isDeviceLost()도 참조하세요 .
QRhi::FrameOpResult QRhi::endOffscreenFrame(QRhi::EndFrameFlags flags = {})
종료, 제출 및 화면 밖 프레임을 기다립니다.
flags 현재 사용되지 않습니다.
beginOffscreenFrame()도 참조하세요 .
QRhi::FrameOpResult QRhi::finish()
그래픽 대기열의 모든 작업(해당되는 경우)이 완료될 때까지 기다린 다음 읽기 백 및 리소스 릴리스 완료와 같은 모든 지연된 작업을 실행합니다. 프레임 안팎에서 호출할 수 있지만 패스 안에서는 호출할 수 없습니다. 프레임 내부에서는 명령 버퍼에 작업을 제출하는 것을 의미합니다.
참고: 이 함수는 사용하지 마세요. 이 함수가 필요할 수 있는 한 가지 경우는 스왑체인 기반 프레임에서 큐에 대기 중인 읽기백의 결과가 고정된 특정 시점에 필요하므로 결과를 기다려야 할 때입니다.
bool QRhi::isClipDepthZeroToOne() const
기본 그래픽 API가 클립 공간에서 깊이 범위 [0, 1]을 사용하는 경우 true
을 반환합니다.
OpenGL은 포스트 프로젝션 깊이 범위를 [-1, 1]로 사용하기 때문에 실제로는 OpenGL 전용 false
입니다. ( QRhiViewport 에서 재정의하지 않는 한 [0, 1] 범위를 사용하는 glDepthRange()로 제어되는 NDC-윈도우 매핑과 혼동하지 마세요.) 일부 OpenGL 버전에서는 glClipControl()을 사용하여 이를 변경할 수 있지만 QRhi 의 OpenGL 백엔드에서는 이 기능을 사용할 수 없으므로 OpenGL ES 또는 4.5 미만의 OpenGL 버전에서는 이 함수를 사용하지 않습니다.
참고: clipSpaceCorrMatrix()는 반환되는 행렬에 해당 조정값을 포함합니다. 따라서 QRhi 사용자는 clipSpaceCorrMatrix()로 투영 행렬을 미리 곱하는 것 외에 다른 조치를 취할 필요가 없습니다. 그러나 일부 그래픽 기술, 예를 들어 일부 유형의 섀도 매핑에는 셰이더에서 깊이 값을 작업하고 출력하는 작업이 포함됩니다. 이러한 경우 이 함수의 값을 적절히 쿼리하고 고려해야 합니다.
bool QRhi::isDeviceLost() const
그래픽 디바이스가 분실된 경우 true를 반환합니다.
장치 분실은 일반적으로 백엔드 및 기본 네이티브 API에 따라 beginFrame(), endFrame() 또는 QRhiSwapChain::createOrResize()에서 감지됩니다. 프레젠테이션이 이루어지는 곳이기 때문에 endFrame()가 가장 일반적입니다. 일부 백엔드의 경우 QRhiSwapChain::createOrResize()도 디바이스 손실로 인해 실패할 수 있습니다. 따라서 이 함수는 이전 작업에서 디바이스 분실이 감지되었는지 확인하는 일반적인 방법으로 제공됩니다.
장치가 손실된 경우 QRhi 을 통해 더 이상 작업을 수행하지 말고 QRhi 리소스를 모두 해제하고 QRhi 을 파괴한 다음 새 QRhi 생성을 시도해야 합니다. 성공하면 모든 그래픽 리소스를 다시 초기화해야 합니다. 그렇지 않은 경우 나중에 반복해서 다시 시도하세요.
간단한 애플리케이션에서는 장치 손실에 대해 신경 쓰지 않을 수 있지만, 일반적으로 사용되는 데스크톱 플랫폼에서는 그래픽 어댑터의 물리적 분리, 장치 또는 드라이버 비활성화, 그래픽 드라이버 제거 또는 업그레이드, 그래픽 장치 재설정으로 이어지는 오류 등 다양한 이유로 인해 장치 손실이 발생할 수 있습니다. 이 중 일부는 완전히 정상적인 상황에서도 발생할 수 있는데, 예를 들어 그래픽 드라이버를 최신 버전으로 업그레이드하는 것은 Qt 애플리케이션이 실행 중일 때 언제든지 발생할 수 있는 일반적인 작업입니다. 사용자는 애플리케이션이 OpenGL이나 Direct3D와 같은 API를 적극적으로 사용하는 경우에도 애플리케이션이 이러한 상황을 견뎌낼 수 있을 것으로 기대할 수 있습니다.
QRhi, 예를 들어 Qt Quick 과 같은 Qt의 자체 프레임워크는 장치 손실이 발생하면 이를 처리하고 적절한 조치를 취할 것으로 기대할 수 있습니다. 텍스처 및 버퍼와 같은 그래픽 리소스에 대한 데이터가 CPU 측에서 계속 사용 가능한 경우 그래픽 리소스를 원활하게 다시 초기화할 수 있으므로 이러한 이벤트가 애플리케이션 수준에서 전혀 눈에 띄지 않을 수 있습니다. 그러나 QRhi 에서 직접 작업하는 애플리케이션과 라이브러리는 디바이스 손실 상황을 스스로 확인하고 처리할 수 있도록 준비해야 합니다.
참고: OpenGL을 사용하는 애플리케이션은 QOpenGLContext 에서 QSurfaceFormat::ResetNotification 을 설정하여 컨텍스트 재설정 알림을 선택해야 할 수 있습니다. 이는 일반적으로 QRhiGles2InitParams::format 에서 플래그를 활성화하여 수행할 수 있습니다. 그러나 일부 시스템에서는 이 플래그를 설정하지 않은 경우에도 컨텍스트 재설정 상황이 발생할 수 있다는 점에 유의하세요.
bool QRhi::isFeatureSupported(QRhi::Feature feature) const
지정된 feature 이 지원되는 경우 true
을 반환합니다.
bool QRhi::isRecordingFrame() const
활성 프레임이 있을 때, 즉 아직 해당 endFrame() (또는 endOffscreenFrame())가 없는 beginFrame() (또는 beginOffscreenFrame())가 있을 때 true를 반환합니다.
currentFrameSlot(), beginFrame() 및 endFrame()도 참조하세요 .
bool QRhi::isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags = {}) const
flags 에서 수정한 지정된 텍스처 format 가 지원되는 경우 true
를 반환합니다.
이 쿼리는 비압축 형식과 압축 형식 모두에 대해 지원됩니다.
bool QRhi::isYUpInFramebuffer() const
기본 그래픽 API의 프레임버퍼와 이미지에서 Y축이 위를 가리키는 경우 true
를 반환합니다.
실제로는 OpenGL 전용으로 true
입니다.
bool QRhi::isYUpInNDC() const
기본 그래픽 API의 정규화된 디바이스 좌표계에서 Y축이 위를 가리키면 true
을 반환합니다.
실제로는 Vulkan의 경우 false
입니다.
참고: clipSpaceCorrMatrix()는 반환되는 행렬에 해당 조정(Y축이 위를 가리키도록)을 포함합니다.
bool QRhi::makeThreadLocalNativeContextCurrent()
OpenGL을 사용하면 현재 스레드에서 OpenGL 컨텍스트가 최신 상태가 됩니다. 이 함수는 다른 백엔드에는 영향을 미치지 않습니다.
이 함수를 호출하는 것은 일반적으로 Qt 프레임워크 코드에서 응용 프로그램에서 제공하는 외부 OpenGL 코드가 OpenGL을 직접 사용하는 이전과 마찬가지로 실행될 수 있도록 해야 할 때, QRhi 가 OpenGL 백엔드를 사용하는 한 관련이 있습니다.
실패하면 QOpenGLContext::makeCurrent()와 유사하게 false를 반환합니다. 작업이 실패하면 isDeviceLost()를 호출하여 컨텍스트 손실 상황이 발생했는지 확인할 수 있습니다. 이러한 확인은 QOpenGLContext::isValid()를 통한 확인과 동일합니다.
QOpenGLContext::makeCurrent() 및 QOpenGLContext::isValid()도 참조하세요 .
[static]
int QRhi::mipLevelsForSize(const QSize &size)
주어진 size 에 대한 밉 레벨 수를 반환합니다.
const QRhiNativeHandles *QRhi::nativeHandles()
백엔드에서 사용하는 장치, 컨텍스트 및 유사한 개념에 대한 백엔드별 네이티브 객체 컬렉션에 대한 포인터를 반환합니다.
QRhiVulkanNativeHandles, QRhiD3D11NativeHandles, QRhiD3D12NativeHandles, QRhiGles2NativeHandles, 또는 QRhiMetalNativeHandles 로 적절히 캐스팅합니다.
참고: 반환된 포인터나 네이티브 객체 모두 소유권이 이전되지 않습니다.
QRhiBuffer *QRhi::newBuffer(QRhiBuffer::Type type, QRhiBuffer::UsageFlags usage, quint32 size)
지정된 type, usage, size 으로 새 버퍼를 반환합니다.
참고: 일부 usage 및 type 조합은 모든 백엔드에서 지원되지 않을 수 있습니다. UsageFlags 및 the feature flags 을 참조하세요.
참고: 백엔드는 size 보다 큰 버퍼를 할당하도록 선택할 수 있습니다. 이는 애플리케이션에 투명하게 수행되므로 size 값에 특별한 제한이 없습니다. QRhiBuffer::size()는 항상 size 에서 요청된 값을 다시 반환합니다.
QRhiResource::destroy()도 참조하세요 .
QRhiComputePipeline *QRhi::newComputePipeline()
새 컴퓨팅 파이프라인 리소스를 반환합니다.
참고: Compute는 Compute 기능이 지원되는 것으로 보고된 경우에만 사용할 수 있습니다.
QRhiResource::destroy()도 참조하세요 .
QRhiGraphicsPipeline *QRhi::newGraphicsPipeline()
새 그래픽 파이프라인 리소스를 반환합니다.
QRhiResource::destroy()도 참조하세요 .
QRhiRenderBuffer *QRhi::newRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize, int sampleCount = 1, QRhiRenderBuffer::Flags flags = {}, QRhiTexture::Format backingFormatHint = QRhiTexture::UnknownFormat)
지정된 type, pixelSize, sampleCount, flags 으로 새 렌더버퍼를 반환합니다.
backingFormatHint 가 QRhiTexture::UnknownFormat 이외의 텍스처 포맷으로 설정된 경우 백엔드에서 렌더버퍼를 뒷받침하는 스토리지에 사용할 포맷을 결정하는 데 사용할 수 있습니다.
참고: backingFormatHint 는 일반적으로 멀티샘플링 및 부동 소수점 텍스처 형식과 관련된 경우 관련성이 높아집니다. 멀티샘플 QRhiRenderBuffer 로 렌더링한 다음 비RGBA8 QRhiTexture 로 리졸브하면 (일부 그래픽 API의 경우) QRhiRenderBuffer 을 뒷받침하는 스토리지가 일치하는 비RGBA8 포맷을 사용한다는 의미입니다. 즉, 백엔드는 일반적으로 기본적으로 QRhiTexture::RGBA8 을 선택하기 때문에 QRhiTexture::RGBA32F 과 같은 형식을 전달하는 것이 중요하며, 나중에 QRhiTextureRenderTarget 의 색상 어태치먼트에서 RGBA8->RGBA32F 멀티 샘플 해상도를 설정하려고 시도하면 중단될 수 있습니다.
QRhiResource::destroy()도 참조하세요 .
QRhiSampler *QRhi::newSampler(QRhiSampler::Filter magFilter, QRhiSampler::Filter minFilter, QRhiSampler::Filter mipmapMode, QRhiSampler::AddressMode addressU, QRhiSampler::AddressMode addressV, QRhiSampler::AddressMode addressW = QRhiSampler::Repeat)
지정된 확대 필터 magFilter, 축소 필터 minFilter, 밉매핑 모드 mipmapMode, 주소 지정(랩) 모드 addressU, addressV, addressW 를 포함한 새 샘플러를 반환합니다.
참고: mipmapMode 를 None
이외의 값으로 설정하면 모든 관련 밉 레벨에 대한 이미지가 texture uploads 를 통해 제공되거나 이 샘플러에 사용되는 텍스처에서 generateMips()를 호출하여 제공됨을 의미합니다. 모든 관련 밉 레벨에 대한 데이터가 없는 텍스처로 샘플러를 사용하려고 하면 렌더링 오류가 발생하며, 정확한 동작은 기본 그래픽 API에 따라 달라집니다.
QRhiResource::destroy()도 참조하세요 .
QRhiShaderResourceBindings *QRhi::newShaderResourceBindings()
새 셰이더 리소스 바인딩 컬렉션 리소스를 반환합니다.
QRhiResource::destroy()도 참조하십시오 .
QRhiSwapChain *QRhi::newSwapChain()
새 스왑체인을 반환합니다.
QRhiResource::destroy() 및 QRhiSwapChain::createOrResize()도 참조하세요 .
QRhiTexture *QRhi::newTexture(QRhiTexture::Format format, const QSize &pixelSize, int sampleCount = 1, QRhiTexture::Flags flags = {})
지정된 format, pixelSize, sampleCount, flags 으로 새 1D 또는 2D 텍스처를 반환합니다.
1D 텍스처 배열에는 flags 에 QRhiTexture::OneDimensional 가 설정되어 있어야 합니다. pixelSize 높이가 0이면 이 함수는 이 플래그를 암시적으로 설정합니다.
참고: format 은 요청된 내부 및 외부 형식을 지정하므로 텍스처에 업로드할 데이터는 호환되는 형식이어야 하며, 네이티브 텍스처는 내부적으로 이 형식을 사용할 수 있지만(적어도 OpenGL의 경우 반드시 그렇다는 보장은 없음) 이 형식을 사용해야 합니다.
참고: 1D 텍스처는 런타임에 OneDimensionalTextures 기능이 지원되는 것으로 보고된 경우에만 작동합니다. 또한 1D 텍스처의 밉맵은 런타임에 OneDimensionalTextureMipmaps 기능이 보고된 경우에만 작동합니다.
QRhiResource::destroy()도 참조하세요 .
QRhiTexture *QRhi::newTexture(QRhiTexture::Format format, int width, int height, int depth, int sampleCount = 1, QRhiTexture::Flags flags = {})
지정된 format, width, height, depth, sampleCount, flags 를 사용하여 새로운 1D, 2D 또는 3D 텍스처를 반환합니다.
이 오버로드는 depth 를 지정할 수 있기 때문에 3D 텍스처에 적합합니다. 3D 텍스처에는 flags 에 QRhiTexture::ThreeDimensional 가 설정되어 있어야 하지만 depth 가 0보다 클 때마다 플래그가 암시적으로 설정되므로 이 오버로드를 사용하면 생략할 수 있습니다. 1D, 2D 및 큐브 텍스처의 경우 depth 를 0으로 설정해야 합니다.
1D 텍스처는 flags 에 QRhiTexture::OneDimensional 가 설정되어 있어야 합니다. height 와 depth 이 모두 0이면 이 오버로드는 이 플래그를 암시적으로 설정합니다.
참고: 3D 텍스처는 런타임에 ThreeDimensionalTextures 기능이 지원되는 것으로 보고된 경우에만 작동합니다.
참고: 1D 텍스처는 런타임에 OneDimensionalTextures 기능이 지원되는 것으로 보고된 경우에만 작동합니다. 또한 1D 텍스처의 밉맵은 런타임에 OneDimensionalTextureMipmaps 기능이 보고된 경우에만 작동합니다.
이는 오버로드된 함수입니다.
QRhiTexture *QRhi::newTextureArray(QRhiTexture::Format format, int arraySize, const QSize &pixelSize, int sampleCount = 1, QRhiTexture::Flags flags = {})
지정된 format, arraySize, pixelSize, sampleCount, flags 로 새 1D 또는 2D 텍스처 배열을 반환합니다.
이 함수는 flags 에 QRhiTexture::TextureArray 를 암시적으로 설정합니다.
1D 텍스처 배열에는 flags 에 QRhiTexture::OneDimensional 가 설정되어 있어야 합니다. 이 함수는 pixelSize 높이가 0인 경우 이 플래그를 암시적으로 설정합니다.
참고: 텍스처 배열을 텍스처 배열과 혼동하지 마세요. 이 함수로 생성된 QRhiTexture 은 셰이더의 1D 또는 2D 배열 샘플러(예: layout(binding = 1) uniform sampler2DArray texArr;
)와 함께 사용할 수 있습니다. 텍스처 배열은 QRhiShaderResourceBinding::sampledTextures() 및 카운트 > 1을 통해 셰이더에 노출되는 텍스처 목록을 의미하며, 예를 들어 다음과 같이 셰이더에 선언됩니다: layout(binding = 1) uniform sampler2D textures[4];
참고: 이 기능은 런타임에 TextureArrays 기능이 지원되는 것으로 보고된 경우에만 작동합니다.
참고: 1D 텍스처는 런타임에 OneDimensionalTextures 기능이 지원되는 것으로 보고된 경우에만 작동합니다. 또한 1D 텍스처의 밉맵은 런타임에 OneDimensionalTextureMipmaps 기능이 보고된 경우에만 작동합니다.
newTexture()도 참조하세요 .
QRhiTextureRenderTarget *QRhi::newTextureRenderTarget(const QRhiTextureRenderTargetDescription &desc, QRhiTextureRenderTarget::Flags flags = {})
desc 에 지정된 색상 및 뎁스/스텐실 첨부 파일과 지정된 flags 을 사용하여 새 텍스처 렌더링 타깃을 반환합니다.
QRhiResource::destroy()도 참조하십시오 .
QRhiResourceUpdateBatch *QRhi::nextResourceUpdateBatch()
복사 유형의 작업을 기록할 수 있는 사용 가능한 빈 배치를 반환합니다.
참고: 반환 값은 호출자가 소유하지 않으며 절대 파기해서는 안 됩니다. 대신 QRhiCommandBuffer::beginPass(), QRhiCommandBuffer::endPass() 또는 QRhiCommandBuffer::resourceUpdate()로 전달하거나 QRhiResourceUpdateBatch::release()을 호출하여 재사용할 수 있도록 배치 풀을 반환합니다.
참고: 배치 인스턴스는 자체적으로 데이터를 수집할 뿐 어떤 작업도 수행하지 않으므로 beginFrame() - endFrame() 외부에서도 호출할 수 있습니다.
기록 중인 프레임에 묶여 있지 않기 때문에 예를 들어 다음 순서가 유효합니다:
rhi->beginFrame(swapchain); QRhiResourceUpdateBatch *u = rhi->nextResourceUpdateBatch(); u->uploadStaticBuffer(buf, data); // ... do not commit the batch rhi->endFrame(); // u stays valid (assuming buf stays valid as well) rhi->beginFrame(swapchain); swapchain->currentFrameCommandBuffer()->resourceUpdate(u); // ... draw with buf rhi->endFrame();
경고: QRhi 당 최대 배치 수는 64개입니다. 이 제한에 도달하면 함수는 배치가 풀에 반환될 때까지 null을 반환합니다.
QByteArray QRhi::pipelineCacheData()
이 QRhi 의 수명 기간 동안 성공적으로 생성된 QRhiGraphicsPipeline 및 QRhiComputePipeline 에서 수집한 데이터가 포함된 바이너리 데이터 블롭을 반환합니다.
저장한 다음 이후 동일한 애플리케이션을 실행할 때 캐시 데이터를 다시 로드하면 파이프라인 및 셰이더 생성 시간을 줄일 수 있습니다. 캐시 및 직렬화된 버전에 정확히 무엇이 포함되는지는 명시되어 있지 않으며, 항상 사용되는 백엔드에 따라 다르며 경우에 따라서는 그래픽 API의 특정 구현에 따라 달라질 수 있습니다.
PipelineCacheDataLoadSave 가 지원되지 않는 것으로 보고되면 반환된 QByteArray 은 비어 있습니다.
create() 호출 시 EnablePipelineCacheDataSave 플래그가 지정되지 않은 경우 PipelineCacheDataLoadSave 기능이 지원되는 경우에도 반환된 QByteArray 이 비어 있을 수 있습니다.
반환된 데이터가 비어 있지 않은 경우, 항상 Qt 버전과 QRhi 백엔드에 따라 다릅니다. 또한 그래픽 장치 및 사용된 정확한 드라이버 버전에 대한 종속성이 강한 경우도 있습니다. QRhi 은 적절한 헤더를 추가하고 데이터를 항상 setPipelineCacheData()에 안전하게 전달할 수 있도록 안전장치를 처리하므로 다른 버전의 드라이버에서 실행된 데이터를 로드하려는 시도가 안전하고 정상적으로 처리됩니다.
참고: releaseCachedResources()를 호출하면 백엔드에 따라 수집된 파이프라인 데이터가 지워질 수 있습니다. 이후 이 함수를 호출하면 데이터가 반환되지 않을 수 있습니다.
이 기능에 대한 자세한 내용은 EnablePipelineCacheDataSave 을 참조하세요.
참고: 이 함수에 대한 호출 횟수를 최소화하세요. 블롭을 검색하는 것이 항상 저렴한 작업은 아니므로 이 함수는 낮은 빈도(예: 애플리케이션을 닫을 때 한 번만 호출하는 것이 이상적)로만 호출해야 합니다.
setPipelineCacheData(), create() 및 isFeatureSupported()도 참조하세요 .
[static]
bool QRhi::probe(QRhi::Implementation impl, QRhiInitParams *params)
주어진 impl 및 params 을 호출했을 때 create()가 성공할 것으로 예상할 수 있으면 true를 반환합니다.
일부 백엔드의 경우 이는 create()를 호출하고 반환값을 확인한 다음 결과 QRhi 을 삭제하는 것과 같습니다.
다른 경우, 특히 Metal의 경우 특정 프로빙 구현이 있을 수 있으며, 이를 통해 실패 시 경고로 디버그 출력을 오염시키지 않고 보다 가벼운 방식으로 테스트할 수 있습니다.
create()도 참조하세요 .
void QRhi::releaseCachedResources()
백엔드의 캐시에서 리소스를 해제하려고 시도합니다. 여기에는 CPU 및 GPU 리소스가 모두 포함될 수 있습니다. 자동으로 재생성할 수 있는 메모리와 리소스만 범위에 포함됩니다. 예를 들어 백엔드의 QRhiGraphicsPipeline 구현이 셰이더 컴파일 결과의 캐시를 유지하는 경우 이 함수를 호출하면 해당 캐시가 비워져 메모리와 그래픽 리소스를 확보할 수 있습니다.
이 함수를 호출하는 것은 특정 시점에서 성능을 희생하더라도 리소스 사용량을 최소화해야 하는 리소스 제약 환경에서 유용합니다.
void QRhi::removeCleanupCallback(const void *key)
콜백을 key 으로 등록 취소합니다. key 에 정리 콜백이 등록되지 않은 경우 이 함수는 아무 작업도 수행하지 않습니다. 키 없이 등록된 콜백은 제거할 수 없습니다.
addCleanupCallback()도 참조하세요 .
int QRhi::resourceLimit(QRhi::ResourceLimit limit) const
지정된 리소스의 값을 반환합니다 limit.
이 값은 초기화 시 백엔드에서 쿼리할 것으로 예상되므로 이 함수를 호출하는 것은 가벼운 작업입니다.
void QRhi::runCleanup()
등록된 모든 정리 함수를 호출합니다. 그런 다음 정리 콜백 목록을 지웁니다. 일반적으로 QRhi 을 삭제하면 이 작업이 자동으로 수행되지만 때로는 캐시된 비필수 리소스를 모두 해제하기 위해 정리를 트리거하는 것이 유용할 수 있습니다.
addCleanupCallback()도 참조하세요 .
void QRhi::setPipelineCacheData(const QByteArray &data)
해당되는 경우 data 을 파이프라인 캐시에 로드합니다.
PipelineCacheDataLoadSave 이 지원되지 않는 것으로 보고되면 이 함수는 호출해도 안전하지만 아무런 효과가 없습니다.
pipelineCacheData()가 반환하는 블롭은 항상 Qt 버전, QRhi 백엔드, 경우에 따라 그래픽 디바이스 및 지정된 그래픽 드라이버 버전에 따라 다릅니다. QRhi 은 적절한 헤더를 추가하고 데이터를 항상 이 함수에 안전하게 전달할 수 있도록 안전장치를 처리합니다. 드라이버가 최신 버전으로 업그레이드되었거나 데이터가 다른 QRhi 백엔드에서 생성되어 불일치하는 경우 경고가 표시되고 data 은 안전하게 무시됩니다.
Vulkan에서는 이 함수가 VkPipelineCache에 직접 매핑됩니다. 이 함수를 호출하면 data 에서 초기 데이터를 가져온 새 Vulkan 파이프라인 캐시 객체가 생성됩니다. 그러면 이후 생성되는 모든 QRhiGraphicsPipeline 및 QRhiComputePipeline 객체에서 파이프라인 캐시 객체를 사용하므로 잠재적으로 파이프라인 생성을 가속화할 수 있습니다.
다른 API의 경우 실제 파이프라인 캐시는 없지만 셰이더 컴파일(D3D) 또는 프로그램 바이너리(OpenGL)의 바이트코드가 포함된 캐시를 제공할 수 있습니다. 런타임에 소스에서 셰이더 컴파일을 많이 수행하는 애플리케이션의 경우 이 기능을 사용하여 '파이프라인 캐시'를 이전 실행에서 미리 시드하면 후속 실행에서 상당한 성능 향상을 제공할 수 있습니다.
QRhi 참고: data 이 파이프라인 및 셰이더 생성 성능에 영향을 미친다는 보장은 없습니다. Vulkan과 같은 API의 경우 data 을 어떤 용도로 사용할지 또는 무시할지는 드라이버가 결정합니다.
이 기능에 대한 자세한 내용은 EnablePipelineCacheDataSave 을 참조하세요.
참고: QRhi 에서 제공하는 이 메커니즘은 드라이버의 자체 내부 캐싱 메커니즘(있는 경우)과는 독립적입니다. 즉, 그래픽 API와 그 구현에 따라 data 를 검색한 후 다시 로드할 때의 정확한 효과를 예측할 수 없습니다. Qt가 제어할 수 없는 다른 캐싱 메커니즘이 이미 활성화되어 있는 경우 성능 개선 효과가 전혀 나타나지 않을 수도 있습니다.
참고: 이 함수에 대한 호출 횟수를 최소화하세요. 블롭을 로드하는 것이 항상 저렴한 작업은 아니므로 이 함수는 낮은 빈도, 즉 애플리케이션을 시작할 때와 같이 한 번만 호출하는 것이 이상적입니다.
pipelineCacheData() 및 isFeatureSupported()도 참조하세요 .
[static]
QSize QRhi::sizeForMipLevel(int mipLevel, const QSize &baseLevelSize)
주어진 mipLevel 에 대한 텍스처 이미지 크기를 반환하며, baseLevelSize 에 주어진 레벨 0 크기를 기준으로 계산합니다.
QRhiStats QRhi::statistics() const
그래픽 리소스의 타이밍과 할당에 대한 통계를 수집하고 반환합니다.
메모리 할당에 대한 데이터는 해당 작업이 Qt의 제어 하에 있는 일부 백엔드에서만 사용할 수 있습니다. 리소스 메모리 할당에 대한 하위 수준 제어가 없는 그래픽 API에서는 이 기능이 지원되지 않으며 결과의 모든 관련 필드는 0입니다.
특히 Vulkan에서는 값이 항상 유효하며 기본 메모리 할당자 라이브러리에서 쿼리됩니다. 이를 통해 활성 버퍼와 텍스처의 메모리 요구 사항을 파악할 수 있습니다.
Direct 3D 12도 마찬가지입니다. 여기에는 메모리 할당자 라이브러리의 통계 외에도 메모리 할당자 라이브러리가 제어하지 않는 추가 리소스(스왑체인 버퍼, 디스크립터 힙 등)를 포함한 총 크기를 보고하는 totalUsageBytes
필드도 포함되어 있습니다(DXGI에서 보고).
이 값은 사용된 모든 유형의 메모리를 합친 값에 해당합니다. (예: 디스크리트 GPU의 경우 비디오 + 시스템).
그래픽 및 컴퓨팅 파이프라인 생성에 소요된 총 시간(밀리초)과 같은 추가 데이터(일반적으로 셰이더 컴파일 또는 캐시 조회, 잠재적으로 비용이 많이 드는 프로세싱이 포함됨)는 대부분의 백엔드에서 사용할 수 있습니다.
참고: 파이프라인 생성과 같은 작업의 경과 시간은 다양한 요인에 의해 영향을 받을 수 있습니다. 예를 들어 QRhiGraphicsPipeline::create()를 호출하는 동안 "파이프라인"의 개념과 내부에서 정확히 어떤 일이 일어나는지는 그래픽 API와 그 구현에 따라 크게 다르므로 서로 다른 백엔드 간에 결과를 비교해서는 안 됩니다.
참고: 또한 많은 드라이버가 셰이더, 프로그램, 파이프라인에 대해 다양한 캐싱 전략을 사용할 가능성이 높습니다. ( setPipelineCacheData() 또는 OpenGL 전용 프로그램 바이너리 디스크 캐시와 같은 Qt 자체의 유사한 기능과는 별개로). 이러한 내부 동작은 API 클라이언트에게 투명하기 때문에 Qt와 QRhi 는 정확한 캐싱 전략, 지속성, 캐시된 데이터의 무효화 등에 대한 지식이나 제어가 없습니다. 파이프라인 생성에 소요되는 시간과 같은 타이밍을 읽을 때는 드라이버 수준 캐싱 메커니즘의 잠재적 존재와 지정되지 않은 동작을 염두에 두어야 합니다.
QList<int> QRhi::supportedSampleCounts() const
지원되는 샘플 개수 목록을 반환합니다.
일반적인 예는 (1, 2, 4, 8)입니다.
일부 백엔드에서는 지원되는 값 목록이 미리 고정되어 있는 반면, 다른 백엔드에서는 (물리적) 장치 속성이 런타임에 지원되는 항목을 나타냅니다.
QRhiRenderBuffer::setSampleCount(), QRhiTexture::setSampleCount(), QRhiGraphicsPipeline::setSampleCount() 및 QRhiSwapChain::setSampleCount()도 참조하세요 .
QThread *QRhi::thread() const
QRhi 이 initialized 이었던 스레드를 반환합니다.
int QRhi::ubufAligned(int v) const
ubufAlignment()에 의해 지정된 균일한 버퍼 정렬에 맞춰 정렬된 값(일반적으로 오프셋)을 v 반환합니다.
int QRhi::ubufAlignment() const
최소 균일한 버퍼 오프셋 정렬을 바이트 단위로 반환합니다. 이 값은 일반적으로 256입니다.
이 값에 맞지 않는 오프셋으로 균일한 버퍼 영역을 바인딩하려고 하면 백엔드 및 기본 그래픽 API에 따라 실패로 이어질 수 있습니다.
ubufAligned()도 참조하세요 .
[static]
QRhiSwapChainProxyData QRhi::updateSwapChainProxyData(QRhi::Implementation impl, QWindow *window)
impl 에 지정된 백엔드 및 그래픽 API와 관련된 불투명 데이터를 포함하는 QRhiSwapChainProxyData 구조체를 생성하고 반환합니다. window 는 스왑체인이 타겟팅하는 QWindow 입니다.
반환된 구조체는 QRhiSwapChain::setProxyData()로 전달할 수 있습니다. 이 정적 함수는 모든 QRhi 연산과 달리 메인(gui) 스레드에서 호출된 다음 QRhi 및 QRhiSwapChain 작업하는 스레드로 전송되어 스왑체인에 전달될 것으로 예상되므로 스레드 렌더링 시스템에서 의미가 있습니다. 이를 통해 메인 스레드에서만 호출되는 것이 안전한 네이티브 플랫폼 쿼리를 수행할 수 있습니다(예: NSView에서 CAMetalLayer를 쿼리한 다음 렌더링 스레드에 있는 QRhiSwapChain 에 데이터를 전달). Metal 예제에서 전용 렌더링 스레드에서 view.layer 액세스를 수행하면 Xcode 스레드 검사기에 경고가 표시됩니다. 데이터 프록시 메커니즘을 사용하면 이 문제를 방지할 수 있습니다.
스레드가 관여하지 않는 경우 QRhiSwapChainProxyData 을 생성하여 전달할 필요가 없습니다. 백엔드는 필요한 모든 것을 자체적으로 쿼리할 수 있으며 모든 것이 메인(GUI) 스레드에 있는 경우 이것으로 충분합니다.
참고: impl 은 QRhi 이 생성된 것과 일치해야 합니다. 예를 들어, Apple 이외의 플랫폼에서 QRhi::Metal 으로 호출하면 유용한 데이터가 생성되지 않습니다.
관련 비회원
[alias, since 6.7]
QRhiShaderResourceBindingSet
QRhiShaderResourceBindings 의 동의어.
이 typedef는 Qt 6.7에서 도입되었습니다.
© 2025 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.