QRhiBuffer Class
버텍스, 인덱스 또는 균일(상수) 버퍼 리소스. 더 보기...
| 헤더: | #include <rhi/qrhi.h> |
| CMake: | find_package(Qt6 REQUIRED COMPONENTS GuiPrivate) target_link_libraries(mytarget PRIVATE Qt6::GuiPrivate) |
| qmake: | QT += gui-private |
| 다음부터: | Qt 6.6부터 |
| 상속받음: | QRhiResource |
공개 타입
| struct | NativeBuffer |
| enum | Type { Immutable, Static, Dynamic } |
| enum | UsageFlag { VertexBuffer, IndexBuffer, UniformBuffer, StorageBuffer, IndirectBuffer } |
| flags | UsageFlags |
공개 함수
| virtual char * | beginFullDynamicBufferUpdateForCurrentFrame() |
| virtual bool | create() = 0 |
| virtual void | endFullDynamicBufferUpdateForCurrentFrame() |
| virtual QRhiBuffer::NativeBuffer | nativeBuffer() |
| void | setSize(quint32 sz) |
| void | setType(QRhiBuffer::Type t) |
| void | setUsage(QRhiBuffer::UsageFlags u) |
| quint32 | size() const |
| QRhiBuffer::Type | type() const |
| QRhiBuffer::UsageFlags | usage() const |
재구현된 공용 함수
| virtual QRhiResource::Type | resourceType() const override |
상세 설명
참고: 이는 호환성 보장이 제한된 RHI API입니다. 자세한 내용은 QRhi 를 참조하십시오.
QRhiBuffer는 0개, 1개 또는 그 이상의 네이티브 버퍼 객체(예: VkBuffer 또는 MTLBuffer)를 캡슐화합니다. 일부 그래픽 API 및 백엔드에서는 특정 유형의 버퍼가 네이티브 버퍼 객체를 전혀 사용하지 않을 수도 있지만(예: 균일 버퍼 객체가 사용되지 않는 OpenGL), 이는 QRhiBuffer API 사용자에게는 투명하게 처리됩니다. 마찬가지로, GPU 파이프라인을 중단시키지 않고 프레임별 콘텐츠 업데이트를 효율적으로 수행하기 위해 일부 유형의 버퍼가 내부적으로 두 개 또는 세 개의 네이티브 버퍼를 사용할 수 있다는 사실은 애플리케이션과 라이브러리에서는 대부분 감지할 수 없습니다.
QRhiBuffer 인스턴스는 항상 the QRhi's newBuffer() function 를 호출하여 생성됩니다. 이 호출은 네이티브 그래픽 리소스를 생성하지 않습니다. 리소스를 생성하려면 유형, 사용 플래그, 크기 등 적절한 옵션을 설정한 후 create()를 호출해야 하지만, 대부분의 경우 이러한 옵션은 newBuffer()에 전달된 인자를 기반으로 이미 설정되어 있습니다.
사용 예
GLSL 유니폼 블록에 단일 mat4 멤버가 포함된 셰이더용 유니폼 버퍼를 생성하고 그 내용을 업데이트하려면:
QRhiBuffer *ubuf = rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 64);
if (!ubuf->create()) { error(); }
QRhiResourceUpdateBatch *batch = rhi->nextResourceUpdateBatch();
QMatrix4x4 mvp;
// ... set up the modelview-projection matrix
batch->updateDynamicBuffer(ubuf, 0, 64, mvp.constData());
// ...
commandBuffer->resourceUpdate(batch); // or, alternatively, pass 'batch' to a beginPass() call버텍스 데이터가 포함된 버퍼를 생성하는 예시:
const float vertices[] = { -1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 1.0f };
QRhiBuffer *vbuf = rhi->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, sizeof(vertices));
if (!vbuf->create()) { error(); }
QRhiResourceUpdateBatch *batch = rhi->nextResourceUpdateBatch();
batch->uploadStaticBuffer(vbuf, vertices);
// ...
commandBuffer->resourceUpdate(batch); // or, alternatively, pass 'batch' to a beginPass() call인덱스 버퍼:
static const quint16 indices[] = { 0, 1, 2 };
QRhiBuffer *ibuf = rhi->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::IndexBuffer, sizeof(indices));
if (!ibuf->create()) { error(); }
QRhiResourceUpdateBatch *batch = rhi->nextResourceUpdateBatch();
batch->uploadStaticBuffer(ibuf, indices);
// ...
commandBuffer->resourceUpdate(batch); // or, alternatively, pass 'batch' to a beginPass() call일반적인 패턴
create()를 호출하면, 이전에 create()가 성공적으로 호출된 경우 기존 네이티브 리소스가 모두 파기됩니다. 해당 네이티브 리소스가 처리 중인 프레임에서 여전히 사용 중이라면(즉, GPU가 여전히 해당 리소스를 읽을 가능성이 있는 경우), 해당 리소스의 파기는 자동으로 연기됩니다. 따라서 이미 초기화된 버퍼의 크기를 안전하게 늘리기 위한 매우 일반적이고 편리한 패턴은 다음과 같습니다. 실제로는 이 과정에서 내부적으로 기존 네이티브 리소스 세트를 모두 해제하고 완전히 새로운 세트를 생성하므로, 반드시 효율적인 작업은 아닙니다. 하지만 buf 객체 자체를 파괴하지 않음으로써 다른 데이터 구조(예: QRhiBuffer가 참조되는 모든 QRhiShaderResourceBinding ) 내의 해당 객체에 대한 모든 참조가 유효한 상태로 유지되므로, 다른 대안들보다 더 편리하고 여전히 빠릅니다.
if (buf->size() < newSize) {
buf->setSize(newSize);
if (!buf->create()) { error(); }
}
// continue using buf, fill it with new data유니폼 버퍼를 다룰 때, 효율성을 위해 여러 드로우 호출의 데이터를 단일 버퍼로 결합해야 할 때가 있습니다. 정렬 요구 사항을 유의하십시오. 일부 그래픽 API에서는 유니폼 버퍼의 오프셋이 256바이트 단위로 정렬되어야 합니다. 이는 ` QRhiShaderResourceBinding `와 ` setShaderResources()`에 전달되는 동적 오프셋 모두에 적용됩니다. 이식성 있는 코드를 작성하려면 ubufAlignment() 및 ubufAligned() 함수를 사용하십시오. 예를 들어, 다음은 동일한 파이프라인과 지오메트리를 사용하되, 바인딩 포인트 0에서 노출되는 유니폼 버퍼의 데이터는 서로 다른 여러 개의 (N) 드로우 호출을 발행하는 개요입니다. 이는 버퍼가 uniformBufferWithDynamicOffset()을 통해 노출된다고 가정하며, 이를 통해 QRhiCommandBuffer::DynamicOffset 목록을 setShaderResources()에 전달할 수 있습니다.
const int N = 2;
const int UB_SIZE = 64 + 4; // assuming a uniform block with { mat4 matrix; float opacity; }
const int ONE_UBUF_SIZE = rhi->ubufAligned(UB_SIZE);
const int TOTAL_UBUF_SIZE = N * ONE_UBUF_SIZE;
QRhiBuffer *ubuf = rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, TOTAL_UBUF_SIZE);
if (!ubuf->create()) { error(); }
QRhiResourceUpdateBatch *batch = rhi->nextResourceUpdateBatch();
for (int i = 0; i < N; ++i) {
batch->updateDynamicBuffer(ubuf, i * ONE_UBUF_SIZE, 64, matrix.constData());
batch->updateDynamicBuffer(ubuf, i * ONE_UBUF_SIZE + 64, 4, &opacity);
}
// ...
// beginPass(), set pipeline, etc., and then:
for (int i = 0; i < N; ++i) {
QRhiCommandBuffer::DynamicOffset dynOfs[] = { { 0, i * ONE_UBUF_SIZE } };
cb->setShaderResources(srb, 1, dynOfs);
cb->draw(36);
}QRhiResourceUpdateBatch, QRhi 및 QRhiCommandBuffer도 참조하십시오 .
멤버 유형 문서
enum QRhiBuffer::Type
버퍼 리소스의 저장 유형을 지정합니다.
| 상수 | 값 | 설명 |
|---|---|---|
QRhiBuffer::Immutable | 0 | 초기 업로드 이후 데이터가 절대 변경되지 않을 것으로 예상됨을 나타냅니다. 내부적으로 이러한 버퍼 리소스는 일반적으로 (해당되는 시스템에서) 디바이스 로컬(GPU) 메모리에 배치됩니다. 새로운 데이터를 업로드하는 것은 가능하지만, 비용이 많이 들 수 있습니다. 업로드는 일반적으로 호스트에서 볼 수 있는 별도의 스테이징 버퍼로 복사하는 방식으로 이루어지며, 여기서 GPU 버퍼 간 복사 명령이 실행되어 실제 GPU 전용 버퍼로 데이터가 복사됩니다. |
QRhiBuffer::Static | 1 | 데이터가 드물게만 변경될 것으로 예상됨을 나타냅니다. 일반적으로 해당되는 경우 디바이스 로컬(GPU) 메모리에 배치됩니다. 업로드에 호스트 가시 스테이징 버퍼가 사용되는 백엔드의 경우, ‘불변(Immutable)’ 유형과 달리 이 유형에 대해서는 스테이징 버퍼가 유지되므로, 후속 업로드 시 성능 저하가 발생하지 않습니다. 빈번한 업데이트, 특히 연속된 프레임에서의 업데이트는 피해야 합니다. |
QRhiBuffer::Dynamic | 2 | 데이터가 빈번하게 변경될 것으로 예상됨을 나타냅니다. 대용량 버퍼에는 권장되지 않습니다. 일반적으로 그래픽 파이프라인을 중단시키지 않고 변경할 수 있도록 호스트 가시 메모리에 2개의 복사본으로 백업됩니다. 이중 버퍼링은 애플리케이션에 투명하게 관리되며, 여기서는 어떤 형태로도 API에 노출되지 않습니다. 이는 ‘ UniformBuffer ’ 용도로 사용되는 버퍼에 권장되는 유형이며, 일부 백엔드의 경우 유일하게 가능한 유형입니다. |
enum QRhiBuffer::UsageFlag
flags QRhiBuffer::UsageFlags
버퍼의 사용 방식을 지정하는 플래그 값.
| 상수 | 값 | 설명 |
|---|---|---|
QRhiBuffer::VertexBuffer | 1 << 0 | 버텍스 버퍼. 이를 통해 ` QRhiBuffer `를 ` setVertexInput()`에서 사용할 수 있습니다. |
QRhiBuffer::IndexBuffer | 1 << 1 | 인덱스 버퍼. 이를 통해 ` QRhiBuffer `를 ` setVertexInput()`에서 사용할 수 있습니다. |
QRhiBuffer::UniformBuffer | 1 << 2 | 유니폼 버퍼(상수 버퍼라고도 함). 이를 통해 QRhiBuffer 를 UniformBuffer()와 함께 사용할 수 있습니다. NonDynamicUniformBuffers 가 지원되지 않는 것으로 보고된 경우, 이 사용법은 Dynamic 유형과만 결합할 수 있습니다. |
QRhiBuffer::StorageBuffer | 1 << 3 | 저장 버퍼입니다. 이를 통해 QRhiBuffer 를 BufferLoad, BufferStore 또는 BufferLoadStore 와 함께 사용할 수 있습니다. 이 사용법은 Immutable 또는 Static 유형과만 결합할 수 있으며, Compute feature 가 지원된다고 보고될 때만 사용할 수 있습니다. |
QRhiBuffer::IndirectBuffer (since Qt 6.12) | 1 << 4 | 간접 드로우 버퍼. 이를 통해 QRhiBuffer 를 drawIndirect() 및 drawIndexedIndirect()에서 사용할 수 있습니다. 이 사용법은 Immutable 또는 Static 유형과만 결합할 수 있습니다. Dynamic 유형과의 결합은 D3D11에서 지원되지 않으며, 이 경우 create()이 실패합니다. 또한 이 사용법은 compute shaders 를 지원하는 백엔드에서 StorageBuffer와 결합할 수 있으며, 이를 통해 컴퓨트 셰이더가 간접 드로우 명령을 생성하고 간접 드로우 호출에서 이를 사용할 수 있게 됩니다. |
UsageFlags 유형은 QFlags<UsageFlag>에 대한 typedef입니다. 이 유형은 UsageFlag 값들의 OR 조합을 저장합니다.
멤버 함수 문서
[virtual] char *QRhiBuffer::beginFullDynamicBufferUpdateForCurrentFrame()
호스트에서 볼 수 있는 버퍼 데이터가 포함된 메모리 블록에 대한 포인터를 반환합니다.
이는 매 프레임마다 전체 내용(또는 적어도 현재 프레임에서 셰이더가 읽는 모든 영역)이 변경되며, 데이터 복사량이 많아 ` QRhiResourceUpdateBatch` 기반 업데이트 메커니즘이 너무 부담스럽게 느껴지는 중대형 동적 균일 버퍼를 위한 지름길입니다.
이 함수를 호출한 후에는, 이 버퍼에 의존하는 렌더링 또는 컴퓨트 패스를 기록하기 전에 반드시 endFullDynamicUniformBufferUpdateForCurrentFrame()을 호출해야 합니다.
경고: 이 방법을 통해 데이터를업데이트하는 것은 ` QRhiResourceUpdateBatch` 기반 업데이트 및 리드백과 호환되지 않습니다. 동일한 버퍼에 대해 두 가지 업데이트 모델을 결합하려고 시도할 경우 예기치 않은 동작이 발생할 수 있습니다. 마찬가지로, 백엔드에 따라 이 직접적인 방식으로 업데이트된 데이터가 ` readBackBuffer operations`에서 인식되지 않을 수도 있습니다.
경고: 이 방법을 통해 버퍼 데이터를 업데이트할때는 매 프레임마다 업데이트를 수행해야 합니다. 그렇지 않으면 리소스에 대해 더블 또는 트리플 버퍼링을 수행하는 백엔드에서 예기치 않은 동작이 발생할 수 있습니다.
경고: 일부 백엔드는 이 함수를 호출할 때 버퍼의 이전 내용이 손실되는 전략을 채택할 수 있으므로, 이 방식으로는부분 업데이트가 불가능합니다. 데이터는 현재 준비 중인 프레임에서 셰이더가 읽는 모든 영역에 기록되어야 합니다.
경고: 이 함수는 프레임을 기록하는 동안, 즉 ` QRhi::beginFrame()`와 ` QRhi::endFrame()` 사이에서만 호출할 수 있습니다.
경고: 이 함수는 동적 버퍼에서만 호출할 수 있습니다.
[pure virtual] bool QRhiBuffer::create()
해당 네이티브 그래픽 리소스를 생성합니다. 이전에 destroy() 호출 없이 create()를 호출하여 이미 리소스가 존재하는 경우, 먼저 destroy()가 암시적으로 호출됩니다.
성공 시 true 을 반환하고, 그래픽 작업이 실패한 경우 false 을 반환합니다. 반환 값과 관계없이 destroy()을 호출하는 것은 항상 안전합니다.
[virtual] void QRhiBuffer::endFullDynamicBufferUpdateForCurrentFrame()
beginFullDynamicBufferUpdateForCurrentFrame()에서 반환된 메모리 블록 내의 버퍼 데이터 전체가 업데이트되었을 때 호출됩니다.
[virtual] QRhiBuffer::NativeBuffer QRhiBuffer::nativeBuffer()
이 버퍼에 대한 기본 네이티브 리소스를 반환합니다. 백엔드에서 기본 네이티브 리소스의 노출을 지원하지 않는 경우, 반환된 값은 비어 있습니다.
QRhiBuffer 는 사용 중인 type() 및 QRhi 백엔드에 따라 여러 네이티브 버퍼 객체로 구성될 수 있습니다. 이 경우, 반환된 구조체의 objects 배열에 모든 네이티브 버퍼 객체가 포함되며, slotCount는 네이티브 버퍼 객체의 수를 나타냅니다. 또한 recording a frame, QRhi::currentFrameSlot()를 사용하여, 기록 중인 프레임 내에서 이 QRhiBuffer 에서 읽기 또는 쓰기 작업을 수행할 때 QRhi 가 어떤 네이티브 버퍼를 사용하는지 확인할 수 있습니다.
경우에 따라 QRhiBuffer 는 네이티브 버퍼 객체로 전혀 뒷받침되지 않을 수 있습니다. 이 경우 slotCount는 0으로 설정되며 유효한 네이티브 객체가 반환되지 않습니다. 이는 오류가 아니며, 특정 유형이나 용도의 QRhiBuffer에 대해 해당 백엔드가 네이티브 버퍼를 사용하지 않는 경우 완전히 유효한 동작입니다.
참고: QRhi 백엔드는 다양한 버퍼 업데이트 전략을 사용할 수 있다는 점에유의하십시오 . 이미지 데이터를 업로드할 때 항상 명령 버퍼에 버퍼-투-이미지(또는 이와 유사한) 복사 명령을 기록하는 텍스처와 달리, 버퍼(특히 Dynamic 및 UniformBuffer 유형)는 매우 다양한 방식으로 작동할 수 있습니다. 예를 들어, 사용 유형이 ` UniformBuffer `인 ` QRhiBuffer `의 경우, 특정 백엔드 및 그래픽 API에서 유니폼 버퍼를 사용하지 않거나 지원하지 않는다면 네이티브 버퍼 객체로 뒷받침되지 않을 수도 있습니다. 또한 버퍼에 데이터가 기록되는 방식과 사용되는 백업 메모리의 유형에도 차이가 있습니다. 호스트 가시 메모리로 백업되는 버퍼의 경우, 이 함수를 호출하면 반환된 모든 네이티브 버퍼에 대해 보류 중인 호스트 쓰기 작업이 실행되도록 보장됩니다.
QRhi::currentFrameSlot() 및 QRhi::FramesInFlight도 참조하십시오 .
[override virtual] QRhiResource::Type QRhiBuffer::resourceType() const
QRhiResource::resourceType() const를 재구현합니다.
리소스 유형을 반환합니다.
void QRhiBuffer::setSize(quint32 sz)
버퍼의 크기를 바이트 단위로 설정합니다. 크기는 일반적으로 ` QRhi::newBuffer()`에서 지정되므로, 이 함수는 크기를 변경해야 할 때만 사용됩니다. 다른 설정 함수와 마찬가지로, 이 크기는 ` create()`를 호출할 때만 적용되며, 이미 생성된 버퍼의 경우 내부적으로 기존 네이티브 리소스를 해제하고 새로운 리소스를 생성하는 과정을 거칩니다.
백엔드는 정렬 요구 사항을 충족하기 위해 sz 보다 큰 버퍼를 할당할 수 있습니다. 이는 애플리케이션에 노출되지 않으며, size()는 항상 sz 에서 요청된 크기를 반환합니다.
size()도 참조하십시오 .
void QRhiBuffer::setType(QRhiBuffer::Type t)
버퍼의 유형을 ` t`로 설정합니다.
type()도 참조하십시오 .
void QRhiBuffer::setUsage(QRhiBuffer::UsageFlags u)
버퍼의 사용 플래그를 u 로 설정합니다.
usage()도 참조하십시오 .
quint32 QRhiBuffer::size() const
버퍼의 크기를 바이트 단위로 반환합니다.
이 값은 항상 setSize() 또는 QRhi::newBuffer()에 전달된 값과 동일합니다. 내부적으로는 기본 그래픽 API에서 요구하는 경우 네이티브 버퍼의 크기가 더 클 수 있습니다.
setSize()도 참조하십시오 .
QRhiBuffer::Type QRhiBuffer::type() const
버퍼 유형을 반환합니다.
setType()도 참조하십시오 .
QRhiBuffer::UsageFlags QRhiBuffer::usage() const
버퍼의 사용 플래그를 반환합니다.
setUsage()도 참조하십시오 .
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.