Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qssgrhiquadrenderer.cpp
Go to the documentation of this file.
1// Copyright (C) 2008-2012 NVIDIA Corporation.
2// Copyright (C) 2020 The Qt Company Ltd.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
4// Qt-Security score:significant reason:default
5
6
7#include <QtQuick3DRuntimeRender/private/qssgrhiquadrenderer_p.h>
8#include <QtQuick3DUtils/private/qquick3dprofiler_p.h>
9
10QT_BEGIN_NAMESPACE
11
12static const QVector3D g_fullScreenRectFaces[] = {
13 QVector3D(-1, -1, 0),
14 QVector3D(-1, 1, 0),
15 QVector3D(1, 1, 0),
16 QVector3D(1, -1, 0),
17
18 QVector3D(-1, -1, 1),
19 QVector3D(-1, 1, 1),
20 QVector3D(1, 1, 1),
21 QVector3D(1, -1, 1),
22
23 QVector3D(-1, -1, -1),
24 QVector3D(-1, 1, -1),
25 QVector3D(1, 1, -1),
26 QVector3D(1, -1, -1),
27};
28
30 QVector2D(0, 0),
31 QVector2D(0, 1),
32 QVector2D(1, 1),
33 QVector2D(1, 0)
34};
35
36static const quint16 g_rectIndex[] = {
37 0, 1, 2, 0, 2, 3, // front face - 0, 1, 2, 3
38 0, 4, 5, 0, 5, 1, // left face - 0, 4, 5, 1
39 1, 5, 6, 1, 6, 2, // top face - 1, 5, 6, 2
40 3, 2, 6, 3, 6, 7, // right face - 3, 2, 6, 7
41 0, 3, 7, 0, 7, 4, // bottom face - 0, 3, 7, 4
42 7, 6, 5, 7, 5, 4 // back face - 7, 6, 5, 4
43};
44
45void QSSGRhiQuadRenderer::ensureBuffers(QSSGRhiContext *rhiCtx, QRhiResourceUpdateBatch *rub)
46{
47 if (!m_vbuf) {
48 constexpr int vertexCount = 8;
49 m_vbuf = std::make_shared<QSSGRhiBuffer>(*rhiCtx,
50 QRhiBuffer::Immutable,
51 QRhiBuffer::VertexBuffer,
52 quint32(5 * sizeof(float)),
53 5 * vertexCount * sizeof(float));
54 m_vbuf->buffer()->setName(QByteArrayLiteral("quad vertex buffer"));
55 float buf[5 * vertexCount];
56 float *p = buf;
57 for (int i = 0; i < vertexCount; ++i) {
58 *p++ = g_fullScreenRectFaces[i].x();
59 *p++ = g_fullScreenRectFaces[i].y();
60 *p++ = g_fullScreenRectFaces[i].z();
61 *p++ = g_fullScreenRectUVs[i % 4].x();
62 *p++ = g_fullScreenRectUVs[i % 4].y();
63 }
64 rub->uploadStaticBuffer(m_vbuf->buffer(), buf);
65 }
66 if (!m_ibuf) {
67 m_ibuf = std::make_shared<QSSGRhiBuffer>(*rhiCtx,
68 QRhiBuffer::Immutable,
69 QRhiBuffer::IndexBuffer,
70 0,
71 6 * sizeof(quint16),
72 QRhiCommandBuffer::IndexUInt16);
73 m_ibuf->buffer()->setName(QByteArrayLiteral("quad index buffer"));
74 const quint16 buf[] = { 0, 1, 2, 0, 2, 3 };
75 rub->uploadStaticBuffer(m_ibuf->buffer(), buf);
76 }
77}
78
79void QSSGRhiQuadRenderer::prepareQuad(QSSGRhiContext *rhiCtx, QRhiResourceUpdateBatch *maybeRub)
80{
81 QRhiResourceUpdateBatch *rub = maybeRub ? maybeRub : rhiCtx->rhi()->nextResourceUpdateBatch();
82 ensureBuffers(rhiCtx, rub);
83 rhiCtx->commandBuffer()->resourceUpdate(rub);
84}
85
86void QSSGRhiQuadRenderer::recordRenderQuad(QSSGRhiContext *rhiCtx,
87 QSSGRhiGraphicsPipelineState *ps, QRhiShaderResourceBindings *srb,
88 QRhiRenderPassDescriptor *rpDesc, Flags flags)
89{
90 // ps must have viewport and shaderPipeline set already
91 auto &ia = QSSGRhiInputAssemblerStatePrivate::get(*ps);
92 if (flags.testFlag(UvCoords)) {
93 ia.inputLayout.setAttributes({
94 { 0, 0, QRhiVertexInputAttribute::Float3, 0 },
95 { 0, 1, QRhiVertexInputAttribute::Float2, 3 * sizeof(float) }
96 });
97 ia.inputs << QSSGRhiInputAssemblerState::PositionSemantic << QSSGRhiInputAssemblerState::TexCoord0Semantic;
98 } else {
99 ia.inputLayout.setAttributes({ { 0, 0, QRhiVertexInputAttribute::Float3, 0 } });
100 ia.inputs << QSSGRhiInputAssemblerState::PositionSemantic;
101 }
102 ia.inputLayout.setBindings({ 5 * sizeof(float) });
103 ia.topology = QRhiGraphicsPipeline::Triangles;
104
105 ps->flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::DepthTestEnabled, flags.testFlag(DepthTest));
106 ps->flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::DepthWriteEnabled, flags.testFlag(DepthWrite));
107 ps->cullMode = QRhiGraphicsPipeline::None;
108 if (flags.testFlag(PremulBlend)) {
109 ps->flags |= QSSGRhiGraphicsPipelineState::Flag::BlendEnabled;
110 ps->targetBlend[0].srcColor = QRhiGraphicsPipeline::One;
111 ps->targetBlend[0].dstColor = QRhiGraphicsPipeline::OneMinusSrcAlpha;
112 ps->targetBlend[0].srcAlpha = QRhiGraphicsPipeline::One;
113 ps->targetBlend[0].dstAlpha = QRhiGraphicsPipeline::OneMinusSrcAlpha;
114 } else { // set to default, since we may not have had a renderable previously
115 ps->targetBlend[0].srcColor = QRhiGraphicsPipeline::SrcAlpha;
116 ps->targetBlend[0].dstColor = QRhiGraphicsPipeline::OneMinusSrcAlpha;
117 ps->targetBlend[0].srcAlpha = QRhiGraphicsPipeline::One;
118 ps->targetBlend[0].dstAlpha = QRhiGraphicsPipeline::OneMinusSrcAlpha;
119 }
120
121 QSSGRhiContextPrivate *rhiCtxD = QSSGRhiContextPrivate::get(rhiCtx);
122 QRhiGraphicsPipeline *pipeline = rhiCtxD->pipeline(*ps, rpDesc, srb);
123 // Make sure that we were able to create the pipeline before trying to use it
124 // When GraphicsPipeline creation fails it should return nullptr and print a warning
125 if (!pipeline)
126 return;
127
128 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
129 cb->setGraphicsPipeline(pipeline);
130 cb->setShaderResources(srb);
131 cb->setViewport(ps->viewport);
132
133 quint32 vertexOffset = flags.testAnyFlags(RenderBehind) ? 5 * 4 * sizeof(float) : 0;
134
135 QRhiCommandBuffer::VertexInput vb(m_vbuf->buffer(), vertexOffset);
136 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderCall);
137 cb->setVertexInput(0, 1, &vb, m_ibuf->buffer(), m_ibuf->indexFormat());
138 cb->drawIndexed(6);
139 QSSGRHICTX_STAT(rhiCtx, drawIndexed(6, 1));
140 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderCall, 36llu | (1llu << 32), QByteArrayLiteral("render_quad"));
141}
142
143void QSSGRhiQuadRenderer::recordRenderQuadPass(QSSGRhiContext *rhiCtx,
144 QSSGRhiGraphicsPipelineState *ps, QRhiShaderResourceBindings *srb,
145 QRhiTextureRenderTarget *rt, Flags flags)
146{
147 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
148 cb->beginPass(rt, Qt::black, { 1.0f, 0 }, nullptr, rhiCtx->commonPassFlags());
149 QSSGRHICTX_STAT(rhiCtx, beginRenderPass(rt));
150 recordRenderQuad(rhiCtx, ps, srb, rt->renderPassDescriptor(), flags);
151 cb->endPass();
152 QSSGRHICTX_STAT(rhiCtx, endRenderPass());
153}
154
155void QSSGRhiCubeRenderer::prepareCube(QSSGRhiContext *rhiCtx, QRhiResourceUpdateBatch *maybeRub)
156{
157 QRhiResourceUpdateBatch *rub = maybeRub ? maybeRub : rhiCtx->rhi()->nextResourceUpdateBatch();
158 ensureBuffers(rhiCtx, rub);
159 rhiCtx->commandBuffer()->resourceUpdate(rub);
160}
161
162//### The flags UvCoords and RenderBehind are ignored
163void QSSGRhiCubeRenderer::recordRenderCube(QSSGRhiContext *rhiCtx, QSSGRhiGraphicsPipelineState *ps, QRhiShaderResourceBindings *srb, QRhiRenderPassDescriptor *rpDesc, QSSGRhiQuadRenderer::Flags flags)
164{
165 auto &ia = QSSGRhiInputAssemblerStatePrivate::get(*ps);
166 // ps must have viewport and shaderPipeline set already
167 ia.inputLayout.setAttributes({ { 0, 0, QRhiVertexInputAttribute::Float3, 0 } });
168 ia.inputs << QSSGRhiInputAssemblerState::PositionSemantic;
169 ia.inputLayout.setBindings({ 3 * sizeof(float) });
170 ia.topology = QRhiGraphicsPipeline::Triangles;
171
172 ps->flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::DepthTestEnabled, flags.testFlag(QSSGRhiQuadRenderer::DepthTest));
173 ps->flags.setFlag(QSSGRhiGraphicsPipelineState::Flag::DepthWriteEnabled, flags.testFlag(QSSGRhiQuadRenderer::DepthWrite));
174 ps->cullMode = QRhiGraphicsPipeline::None;
175 if (flags.testFlag(QSSGRhiQuadRenderer::PremulBlend)) {
176 ps->flags |= QSSGRhiGraphicsPipelineState::Flag::BlendEnabled;
177 ps->targetBlend[0].srcColor = QRhiGraphicsPipeline::One;
178 ps->targetBlend[0].dstColor = QRhiGraphicsPipeline::OneMinusSrcAlpha;
179 ps->targetBlend[0].srcAlpha = QRhiGraphicsPipeline::One;
180 ps->targetBlend[0].dstAlpha = QRhiGraphicsPipeline::OneMinusSrcAlpha;
181 } else { // set to default, since we may not have had a renderable previously
182 ps->targetBlend[0].srcColor = QRhiGraphicsPipeline::SrcAlpha;
183 ps->targetBlend[0].dstColor = QRhiGraphicsPipeline::OneMinusSrcAlpha;
184 ps->targetBlend[0].srcAlpha = QRhiGraphicsPipeline::One;
185 ps->targetBlend[0].dstAlpha = QRhiGraphicsPipeline::OneMinusSrcAlpha;
186 }
187
188 QSSGRhiContextPrivate *rhiCtxD = QSSGRhiContextPrivate::get(rhiCtx);
189 QRhiGraphicsPipeline *pipeline = rhiCtxD->pipeline(*ps, rpDesc, srb);
190 // Make sure that we were able to create the pipeline before trying to use it
191 // When GraphicsPipeline creation fails it should return nullptr and print a warning
192 if (!pipeline)
193 return;
194
195 QRhiCommandBuffer *cb = rhiCtx->commandBuffer();
196 cb->setGraphicsPipeline(pipeline);
197 cb->setShaderResources(srb);
198 cb->setViewport(ps->viewport);
199
200 QRhiCommandBuffer::VertexInput vb(m_vbuf->buffer(), 0);
201 Q_QUICK3D_PROFILE_START(QQuick3DProfiler::Quick3DRenderCall);
202 cb->setVertexInput(0, 1, &vb, m_ibuf->buffer(), m_ibuf->indexFormat());
203 cb->drawIndexed(36);
204 QSSGRHICTX_STAT(rhiCtx, drawIndexed(36, 1));
205 Q_QUICK3D_PROFILE_END_WITH_STRING(QQuick3DProfiler::Quick3DRenderCall, 36, QByteArrayLiteral("render_cube"));
206}
207
208void QSSGRhiCubeRenderer::ensureBuffers(QSSGRhiContext *rhiCtx, QRhiResourceUpdateBatch *rub)
209{
210 if (!m_vbuf) {
211 constexpr int vertexCount = 8;
212 m_vbuf = std::make_shared<QSSGRhiBuffer>(*rhiCtx,
213 QRhiBuffer::Immutable,
214 QRhiBuffer::VertexBuffer,
215 quint32(3 * sizeof(float)),
216 3 * vertexCount * sizeof(float));
217 m_vbuf->buffer()->setName(QByteArrayLiteral("cube vertex buffer"));
218
219 float buf[3 * vertexCount];
220 float *p = buf;
221 for (int i = 0; i < vertexCount; ++i) {
222 *p++ = g_fullScreenRectFaces[4 + i].x();
223 *p++ = g_fullScreenRectFaces[4 + i].y();
224 *p++ = g_fullScreenRectFaces[4 + i].z();
225 }
226 rub->uploadStaticBuffer(m_vbuf->buffer(), buf);
227 }
228 if (!m_ibuf) {
229 m_ibuf = std::make_shared<QSSGRhiBuffer>(*rhiCtx,
230 QRhiBuffer::Immutable,
231 QRhiBuffer::IndexBuffer,
232 0,
233 sizeof(g_rectIndex),
234 QRhiCommandBuffer::IndexUInt16);
235 m_ibuf->buffer()->setName(QByteArrayLiteral("cube index buffer"));
236 rub->uploadStaticBuffer(m_ibuf->buffer(), g_rectIndex);
237 }
238}
239
240QT_END_NAMESPACE
static const quint16 g_rectIndex[]
static const QVector2D g_fullScreenRectUVs[]