QtBase  v6.3.1
mrt.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2018 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the examples of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:BSD$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** BSD License Usage
18 ** Alternatively, you may use this file under the terms of the BSD license
19 ** as follows:
20 **
21 ** "Redistribution and use in source and binary forms, with or without
22 ** modification, are permitted provided that the following conditions are
23 ** met:
24 ** * Redistributions of source code must retain the above copyright
25 ** notice, this list of conditions and the following disclaimer.
26 ** * Redistributions in binary form must reproduce the above copyright
27 ** notice, this list of conditions and the following disclaimer in
28 ** the documentation and/or other materials provided with the
29 ** distribution.
30 ** * Neither the name of The Qt Company Ltd nor the names of its
31 ** contributors may be used to endorse or promote products derived
32 ** from this software without specific prior written permission.
33 **
34 **
35 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
46 **
47 ** $QT_END_LICENSE$
48 **
49 ****************************************************************************/
50 
51 #include "../shared/examplefw.h"
52 
53 // Exercises MRT, by attaching 4 textures to a single QRhiTextureRenderTarget.
54 // The fragment shader outputs to all four targets.
55 // The textures are then used to render 4 quads, so their contents can be confirmed.
56 
57 const int ATTCOUNT = 4;
58 
59 static float quadVertexData[] =
60 { // Y up, CCW
61  -0.5f, 0.5f, 0.0f, 0.0f,
62  -0.5f, -0.5f, 0.0f, 1.0f,
63  0.5f, -0.5f, 1.0f, 1.0f,
64  0.5f, 0.5f, 1.0f, 0.0f
65 };
66 
67 static quint16 quadIndexData[] =
68 {
69  0, 1, 2, 0, 2, 3
70 };
71 
72 static float triangleData[] =
73 { // Y up, CCW
74  0.0f, 0.5f, 1.0f, 0.0f, 0.0f,
75  -0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
76  0.5f, -0.5f, 0.0f, 0.0f, 1.0f,
77 };
78 
79 struct {
81  QRhiBuffer *vbuf = nullptr;
82  QRhiBuffer *ibuf = nullptr;
83  QRhiBuffer *ubuf = nullptr;
86  QRhiSampler *sampler = nullptr;
90  struct PerColorBuffer {
91  QRhiTexture *tex = nullptr;
93  };
94  PerColorBuffer colData[ATTCOUNT];
95 
96  QRhiBuffer *triUbuf = nullptr;
99  float triRot = 0;
101 } d;
102 
103 void Window::customInit()
104 {
105  qDebug("Max color attachments: %d", m_r->resourceLimit(QRhi::MaxColorAttachments));
107  qWarning("MRT is not supported");
108 
109  d.vbuf = m_r->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, sizeof(quadVertexData) + sizeof(triangleData));
110  d.vbuf->create();
111  d.releasePool << d.vbuf;
112 
113  d.ibuf = m_r->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::IndexBuffer, sizeof(quadIndexData));
114  d.ibuf->create();
115  d.releasePool << d.ibuf;
116 
117  const int oneRoundedUniformBlockSize = m_r->ubufAligned(68);
118  d.ubuf = m_r->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, oneRoundedUniformBlockSize * ATTCOUNT);
119  d.ubuf->create();
120  d.releasePool << d.ubuf;
121 
124  d.releasePool << d.sampler;
125  d.sampler->create();
126 
127  for (int i = 0; i < ATTCOUNT; ++i) {
129  d.releasePool << tex;
130  tex->create();
131 
133  d.releasePool << srb;
134  srb->setBindings({
136  d.ubuf, i * oneRoundedUniformBlockSize, 68),
138  });
139  srb->create();
140 
141  d.colData[i].tex = tex;
142  d.colData[i].srb = srb;
143  }
144 
147  for (int i = 0; i < ATTCOUNT; ++i)
148  att[i] = QRhiColorAttachment(d.colData[i].tex);
149  rtDesc.setColorAttachments(att, att + ATTCOUNT);
150  d.rt = m_r->newTextureRenderTarget(rtDesc);
151  d.releasePool << d.rt;
152  d.rtRp = d.rt->newCompatibleRenderPassDescriptor();
153  d.releasePool << d.rtRp;
154  d.rt->setRenderPassDescriptor(d.rtRp);
155  d.rt->create();
156 
157  d.ps = m_r->newGraphicsPipeline();
158  d.releasePool << d.ps;
159  d.ps->setShaderStages({
160  { QRhiShaderStage::Vertex, getShader(QLatin1String(":/texture.vert.qsb")) },
161  { QRhiShaderStage::Fragment, getShader(QLatin1String(":/texture.frag.qsb")) }
162  });
163  QRhiVertexInputLayout inputLayout;
164  inputLayout.setBindings({
165  { 4 * sizeof(float) }
166  });
167  inputLayout.setAttributes({
169  { 0, 1, QRhiVertexInputAttribute::Float2, quint32(2 * sizeof(float)) }
170  });
171  d.ps->setVertexInputLayout(inputLayout);
172  d.ps->setShaderResourceBindings(d.colData[0].srb); // all of them are layout-compatible
173  d.ps->setRenderPassDescriptor(m_rp);
174  d.ps->create();
175 
176  d.initialUpdates = m_r->nextResourceUpdateBatch();
177  d.initialUpdates->uploadStaticBuffer(d.vbuf, 0, sizeof(quadVertexData), quadVertexData);
178  d.initialUpdates->uploadStaticBuffer(d.vbuf, sizeof(quadVertexData), sizeof(triangleData), triangleData);
179  d.initialUpdates->uploadStaticBuffer(d.ibuf, quadIndexData);
180 
181  qint32 flip = m_r->isYUpInFramebuffer() ? 1 : 0;
182  for (int i = 0; i < ATTCOUNT; ++i)
183  d.initialUpdates->updateDynamicBuffer(d.ubuf, i * oneRoundedUniformBlockSize + 64, 4, &flip);
184 
185  // triangle
187  d.releasePool << d.triUbuf;
188  d.triUbuf->create();
189 
190  d.triSrb = m_r->newShaderResourceBindings();
191  d.releasePool << d.triSrb;
192  d.triSrb->setBindings({
194  });
195  d.triSrb->create();
196 
197  d.triPs = m_r->newGraphicsPipeline();
198  d.releasePool << d.triPs;
199  d.triPs->setShaderStages({
200  { QRhiShaderStage::Vertex, getShader(QLatin1String(":/mrt.vert.qsb")) },
201  { QRhiShaderStage::Fragment, getShader(QLatin1String(":/mrt.frag.qsb")) }
202  });
203 
204  QRhiGraphicsPipeline::TargetBlend blends[ATTCOUNT]; // defaults to blending == false
205  d.triPs->setTargetBlends(blends, blends + ATTCOUNT);
206 
207  inputLayout.setBindings({
208  { 5 * sizeof(float) }
209  });
210  inputLayout.setAttributes({
212  { 0, 1, QRhiVertexInputAttribute::Float3, quint32(2 * sizeof(float)) }
213  });
214  d.triPs->setVertexInputLayout(inputLayout);
215  d.triPs->setShaderResourceBindings(d.triSrb);
216  d.triPs->setRenderPassDescriptor(d.rtRp);
217  d.triPs->create();
218 
219  d.triBaseMvp = m_r->clipSpaceCorrMatrix();
220  d.triBaseMvp.perspective(45.0f, d.rt->pixelSize().width() / float(d.rt->pixelSize().height()), 0.01f, 1000.0f);
221  d.triBaseMvp.translate(0, 0, -2);
222  float opacity = 1.0f;
223  d.initialUpdates->updateDynamicBuffer(d.triUbuf, 64, 4, &opacity);
224 }
225 
227 {
228  qDeleteAll(d.releasePool);
229  d.releasePool.clear();
230 }
231 
233 {
234  QRhiCommandBuffer *cb = m_sc->currentFrameCommandBuffer();
236  if (d.initialUpdates) {
237  u->merge(d.initialUpdates);
238  d.initialUpdates->release();
239  d.initialUpdates = nullptr;
240  }
241 
242  QMatrix4x4 triMvp = d.triBaseMvp;
243  triMvp.rotate(d.triRot, 0, 1, 0);
244  d.triRot += 1;
245  u->updateDynamicBuffer(d.triUbuf, 0, 64, triMvp.constData());
246 
247  cb->beginPass(d.rt, QColor::fromRgbF(0.5f, 0.2f, 0.0f, 1.0f), { 1.0f, 0 }, u);
248  cb->setGraphicsPipeline(d.triPs);
249  cb->setViewport({ 0, 0, float(d.rt->pixelSize().width()), float(d.rt->pixelSize().height()) });
250  cb->setShaderResources();
251  QRhiCommandBuffer::VertexInput vbufBinding(d.vbuf, quint32(sizeof(quadVertexData)));
252  cb->setVertexInput(0, 1, &vbufBinding);
253  cb->draw(3);
254  cb->endPass();
255 
257  if (d.winProj != m_proj) {
258  d.winProj = m_proj;
259  const int oneRoundedUniformBlockSize = m_r->ubufAligned(68);
260  for (int i = 0; i < ATTCOUNT; ++i) {
261  QMatrix4x4 mvp = m_proj;
262  switch (i) {
263  case 0:
264  mvp.translate(-2.0f, 0, 0);
265  break;
266  case 1:
267  mvp.translate(-0.8f, 0, 0);
268  break;
269  case 2:
270  mvp.translate(0.4f, 0, 0);
271  break;
272  case 3:
273  mvp.translate(1.6f, 0, 0);
274  break;
275  default:
276  Q_UNREACHABLE();
277  break;
278  }
279  u->updateDynamicBuffer(d.ubuf, i * oneRoundedUniformBlockSize, 64, mvp.constData());
280  }
281  }
282 
283  const QSize outputSizeInPixels = m_sc->currentPixelSize();
284  cb->beginPass(m_sc->currentFrameRenderTarget(), m_clearColor, { 1.0f, 0 }, u);
285  cb->setGraphicsPipeline(d.ps);
286  cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) });
287  vbufBinding.second = 0;
288  cb->setVertexInput(0, 1, &vbufBinding, d.ibuf, 0, QRhiCommandBuffer::IndexUInt16);
289  for (int i = 0; i < ATTCOUNT; ++i) {
290  cb->setShaderResources(d.colData[i].srb);
291  cb->drawIndexed(6);
292  }
293  cb->endPass();
294 }
small capitals from c petite p scientific f u
Definition: afcover.h:88
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
static QColor fromRgbF(float r, float g, float b, float a=1.0)
Definition: qcolor.cpp:2424
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal.
Definition: qstring.h:84
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
Definition: qmatrix4x4.h:61
void rotate(float angle, const QVector3D &vector)
const float * constData() const
Definition: qmatrix4x4.h:183
void translate(const QVector3D &vector)
Definition: qmatrix4x4.cpp:965
@ Immutable
Definition: qrhi_p.h:717
@ Dynamic
Definition: qrhi_p.h:719
@ IndexBuffer
Definition: qrhi_p.h:724
@ VertexBuffer
Definition: qrhi_p.h:723
@ UniformBuffer
Definition: qrhi_p.h:725
QPair< QRhiBuffer *, quint32 > VertexInput
Definition: qrhi_p.h:1426
int ubufAligned(int v) const
Definition: qrhi.cpp:6207
int resourceLimit(ResourceLimit limit) const
Definition: qrhi.cpp:6329
QMatrix4x4 clipSpaceCorrMatrix() const
Definition: qrhi.cpp:6299
bool isYUpInFramebuffer() const
Definition: qrhi.cpp:6238
QRhiShaderResourceBindings * newShaderResourceBindings()
Definition: qrhi.cpp:6543
QRhiBuffer * newBuffer(QRhiBuffer::Type type, QRhiBuffer::UsageFlags usage, int size)
Definition: qrhi.cpp:6562
QRhiSampler * newSampler(QRhiSampler::Filter magFilter, QRhiSampler::Filter minFilter, QRhiSampler::Filter mipmapMode, QRhiSampler::AddressMode addressU, QRhiSampler::AddressMode addressV, QRhiSampler::AddressMode addressW=QRhiSampler::Repeat)
Definition: qrhi.cpp:6679
QRhiTextureRenderTarget * newTextureRenderTarget(const QRhiTextureRenderTargetDescription &desc, QRhiTextureRenderTarget::Flags flags={})
Definition: qrhi.cpp:6696
QRhiGraphicsPipeline * newGraphicsPipeline()
Definition: qrhi.cpp:6520
@ MaxColorAttachments
Definition: qrhi_p.h:1607
QRhiTexture * newTexture(QRhiTexture::Format format, const QSize &pixelSize, int sampleCount=1, QRhiTexture::Flags flags={})
Definition: qrhi.cpp:6609
QRhiResourceUpdateBatch * nextResourceUpdateBatch()
Definition: qrhi.cpp:5568
@ ClampToEdge
Definition: qrhi_p.h:884
static QRhiShaderResourceBinding sampledTexture(int binding, StageFlags stage, QRhiTexture *tex, QRhiSampler *sampler)
Definition: qrhi.cpp:3374
static QRhiShaderResourceBinding uniformBuffer(int binding, StageFlags stage, QRhiBuffer *buf)
Definition: qrhi.cpp:3268
void setBindings(std::initializer_list< QRhiShaderResourceBinding > list)
Definition: qrhi_p.h:1052
virtual bool create()=0
@ RenderTarget
Definition: qrhi_p.h:766
virtual bool create()=0
void setColorAttachments(std::initializer_list< QRhiColorAttachment > list)
Definition: qrhi_p.h:504
void setBindings(std::initializer_list< QRhiVertexInputBinding > list)
Definition: qrhi_p.h:257
void setAttributes(std::initializer_list< QRhiVertexInputAttribute > list)
Definition: qrhi_p.h:268
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:55
constexpr int height() const noexcept
Definition: qsize.h:160
constexpr int width() const noexcept
Definition: qsize.h:157
qreal opacity
The opacity of the window in the windowing system.
Definition: qwindow.h:132
std::unique_ptr< QRhiSwapChain > m_sc
Definition: window.h:89
std::unique_ptr< QRhiRenderPassDescriptor > m_rp
Definition: window.h:91
virtual void customRender()
QColor m_clearColor
Definition: examplefw.h:176
QMatrix4x4 m_proj
Definition: window.h:94
virtual void customInit()
QRhi * m_r
Definition: examplefw.h:161
qDeleteAll(list.begin(), list.end())
QShader getShader(const QString &name)
Definition: examplefw.h:86
const int ATTCOUNT
Definition: mrt.cpp:57
QRhiBuffer * ibuf
Definition: mrt.cpp:82
QRhiShaderResourceBindings * triSrb
Definition: mrt.cpp:97
struct @913 d
QRhiBuffer * ubuf
Definition: mrt.cpp:83
QList< QRhiResource * > releasePool
Definition: mrt.cpp:80
float triRot
Definition: mrt.cpp:99
QRhiTextureRenderTarget * rt
Definition: mrt.cpp:84
QRhiRenderPassDescriptor * rtRp
Definition: mrt.cpp:85
QRhiTexture * tex
Definition: mrt.cpp:91
QRhiGraphicsPipeline * triPs
Definition: mrt.cpp:98
QMatrix4x4 triBaseMvp
Definition: mrt.cpp:100
QRhiBuffer * triUbuf
Definition: mrt.cpp:96
QRhiShaderResourceBindings * srb
Definition: mrt.cpp:92
QRhiBuffer * vbuf
Definition: mrt.cpp:81
QMatrix4x4 winProj
Definition: mrt.cpp:89
PerColorBuffer colData[ATTCOUNT]
Definition: mrt.cpp:94
QRhiGraphicsPipeline * ps
Definition: mrt.cpp:87
QRhiResourceUpdateBatch * initialUpdates
Definition: mrt.cpp:88
#define Q_UNREACHABLE()
unsigned int quint32
Definition: qglobal.h:288
unsigned short quint16
Definition: qglobal.h:286
int qint32
Definition: qglobal.h:287
#define qDebug
[1]
Definition: qlogging.h:177
#define qWarning
Definition: qlogging.h:179
GLuint sampler
SSL_CTX int(* cb)(SSL *ssl, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)