8#include <private/qsgmaterialshader_p.h>
15#define QSGNODE_TRAVERSE(NODE) for (QSGNode *child = NODE->firstChild(); child; child = child->nextSibling())
16#define SHADOWNODE_TRAVERSE(NODE) for (Node *child = NODE->firstChild(); child; child = child->sibling())
17#define QSGNODE_DIRTY_PARENT (QSGNode::DirtyNodeAdded
18 | QSGNode::DirtyOpacity
19 | QSGNode::DirtyMatrix
20 | QSGNode::DirtyNodeRemoved)
39 m_pipelines.releaseResources();
41 m_fade.releaseResources();
43 m_changeVis.releaseResources();
44 m_batchVis.releaseResources();
45 m_clipVis.releaseResources();
46 m_overdrawVis.releaseResources();
58 if (!m_vs.isValid()) {
59 m_vs = QSGMaterialShaderPrivate::loadShader(
60 QLatin1String(
":/qt-project.org/scenegraph/shaders_ng/visualization.vert.qsb"));
61 m_fs = QSGMaterialShaderPrivate::loadShader(
62 QLatin1String(
":/qt-project.org/scenegraph/shaders_ng/visualization.frag.qsb"));
65 m_fade.prepare(
this, m_renderer->m_rhi, m_renderer->m_resourceUpdates, m_renderer->renderTarget().rpDesc);
67 const bool forceUintIndex =
m_renderer->m_uint32IndexForRhi;
70 case VisualizeBatches:
71 m_batchVis.prepare(m_renderer->m_opaqueBatches, m_renderer->m_alphaBatches,
73 m_renderer->m_rhi, m_renderer->m_resourceUpdates,
76 case VisualizeClipping:
77 m_clipVis.prepare(m_renderer->rootNode(),
this,
78 m_renderer->m_rhi, m_renderer->m_resourceUpdates);
80 case VisualizeChanges:
81 m_changeVis.prepare(m_renderer->m_nodes.value(m_renderer->rootNode()),
83 m_renderer->m_rhi, m_renderer->m_resourceUpdates);
84 m_visualizeChangeSet.clear();
86 case VisualizeOverdraw:
87 m_overdrawVis.prepare(m_renderer->m_nodes.value(m_renderer->rootNode()),
89 m_renderer->m_rhi, m_renderer->m_resourceUpdates);
102 QRhiCommandBuffer *cb =
m_renderer->renderTarget().cb;
106 case VisualizeBatches:
107 m_batchVis.render(cb);
109 case VisualizeClipping:
110 m_clipVis.render(cb);
112 case VisualizeChanges:
113 m_changeVis.render(cb);
115 case VisualizeOverdraw:
116 m_overdrawVis.render(cb);
124void RhiVisualizer::recordDrawCalls(
const QVector<DrawCall> &drawCalls,
125 QRhiCommandBuffer *cb,
126 QRhiShaderResourceBindings *srb,
129 for (
const DrawCall &dc : drawCalls) {
130 QRhiGraphicsPipeline *ps = m_pipelines.pipeline(
this, m_renderer->m_rhi, srb, m_renderer->renderTarget().rpDesc,
131 dc.vertex.topology, dc.vertex.format, dc.vertex.stride,
135 cb->setGraphicsPipeline(ps);
136 QRhiCommandBuffer::DynamicOffset dynofs(0, dc.buf.ubufOffset);
137 cb->setShaderResources(srb, 1, &dynofs);
138 QRhiCommandBuffer::VertexInput vb(dc.buf.vbuf, dc.buf.vbufOffset);
139 if (dc.index.count) {
140 cb->setVertexInput(0, 1, &vb, dc.buf.ibuf, dc.buf.ibufOffset, dc.index.format);
141 cb->drawIndexed(dc.index.count);
143 cb->setVertexInput(0, 1, &vb);
144 cb->draw(dc.vertex.count);
153 QRhi *rhi, QRhiResourceUpdateBatch *u, QRhiRenderPassDescriptor *rpDesc)
155 this->visualizer = visualizer;
158 float v[] = { -1, 1, 1, 1, -1, -1, 1, -1 };
159 vbuf = rhi->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer,
sizeof(v));
162 u->uploadStaticBuffer(vbuf, v);
166 ubuf = rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, DrawCall::UBUF_SIZE);
169 float bgOpacity = 0.8f;
173 u->updateDynamicBuffer(ubuf, 0, 64, ident.constData());
174 u->updateDynamicBuffer(ubuf, 64, 64, ident.constData());
175 float color[4] = { 0.0f, 0.0f, 0.0f, bgOpacity };
176 u->updateDynamicBuffer(ubuf, 128, 16, color);
177 float pattern = 0.0f;
178 u->updateDynamicBuffer(ubuf, 144, 4, &pattern);
179 qint32 projection = 0;
180 u->updateDynamicBuffer(ubuf, 148, 4, &projection);
184 srb = rhi->newShaderResourceBindings();
185 srb->setBindings({ QRhiShaderResourceBinding::uniformBuffer(0, ubufVisibility, ubuf) });
191 ps = rhi->newGraphicsPipeline();
192 ps->setTopology(QRhiGraphicsPipeline::TriangleStrip);
193 QRhiGraphicsPipeline::TargetBlend blend;
195 ps->setTargetBlends({ blend });
196 ps->setShaderStages({ { QRhiShaderStage::Vertex, visualizer->m_vs },
197 { QRhiShaderStage::Fragment, visualizer->m_fs } });
199 inputLayout.setBindings({ { 2 *
sizeof(
float) } });
200 inputLayout.setAttributes({ { 0, 0, QRhiVertexInputAttribute::Float2, 0 } });
201 ps->setVertexInputLayout(inputLayout);
202 ps->setShaderResourceBindings(srb);
203 ps->setRenderPassDescriptor(rpDesc);
226 cb->setGraphicsPipeline(ps);
227 cb->setViewport(visualizer
->m_renderer->m_pstate.viewport);
228 cb->setShaderResources();
229 QRhiCommandBuffer::VertexInput vb(vbuf, 0);
230 cb->setVertexInput(0, 1, &vb);
236 dc->vertex.topology = qsg_topology(g->drawingMode(), rhi);
237 dc->vertex.format = qsg_vertexInputFormat(g->attributes()[0]);
238 dc->vertex.count = g->vertexCount();
239 dc->vertex.stride = g->sizeOfVertex();
241 dc->vertex.data = g->vertexData();
243 dc->index.format = forceUintIndex ? QRhiCommandBuffer::IndexUInt32 : qsg_indexFormat(g);
244 dc->index.count = g->indexCount();
245 dc->index.stride = forceUintIndex ?
sizeof(quint32) : g->sizeOfIndex();
246 if (withData && g->indexCount())
247 dc->index.data = g->indexData();
250static inline uint
aligned(uint v, uint byteAlign)
252 return (v + byteAlign - 1) & ~(byteAlign - 1);
255static bool ensureBuffer(QRhi *rhi, QRhiBuffer **buf, QRhiBuffer::UsageFlags usage, quint32 newSize)
258 *buf = rhi->newBuffer(QRhiBuffer::Dynamic, usage, newSize);
259 if (!(*buf)->create())
261 }
else if ((*buf)->size() < newSize) {
262 (*buf)->setSize(newSize);
263 if (!(*buf)->create())
271 QRhiShaderResourceBindings *srb,
272 QRhiRenderPassDescriptor *rpDesc,
273 QRhiGraphicsPipeline::Topology topology,
274 QRhiVertexInputAttribute::Format vertexFormat,
275 quint32 vertexStride,
278 for (
int i = 0, ie = pipelines.size(); i != ie; ++i) {
279 const Pipeline &p(pipelines.at(i));
280 if (p.topology == topology && p.format == vertexFormat && p.stride == vertexStride)
284 QRhiGraphicsPipeline *ps = rhi->newGraphicsPipeline();
285 ps->setTopology(topology);
286 QRhiGraphicsPipeline::TargetBlend blend;
290 blend.srcColor = QRhiGraphicsPipeline::One;
291 blend.dstColor = QRhiGraphicsPipeline::One;
292 blend.srcAlpha = QRhiGraphicsPipeline::One;
293 blend.dstAlpha = QRhiGraphicsPipeline::One;
295 ps->setTargetBlends({ blend });
296 ps->setShaderStages({ { QRhiShaderStage::Vertex, visualizer->m_vs },
297 { QRhiShaderStage::Fragment, visualizer->m_fs } });
299 inputLayout.setBindings({ { vertexStride } });
300 inputLayout.setAttributes({ { 0, 0, vertexFormat, 0 } });
301 ps->setVertexInputLayout(inputLayout);
302 ps->setShaderResourceBindings(srb);
303 ps->setRenderPassDescriptor(rpDesc);
308 p.topology = topology;
309 p.format = vertexFormat;
310 p.stride = vertexStride;
319 for (
int i = 0, ie = pipelines.size(); i != ie; ++i)
320 delete pipelines.at(i).ps;
327 if (n->type() == QSGNode::GeometryNodeType && n->element()->batch && visualizer->m_visualizeChangeSet.contains(n)) {
328 const uint dirty = visualizer->m_visualizeChangeSet.value(n);
330 const QColor color = QColor::fromHsvF((visualizer->m_randomGenerator.generate() & 1023) / 1023.0f, 0.3f, 1.0f).toRgb();
331 const float alpha = 0.5f;
333 QMatrix4x4 matrix = visualizer
->m_renderer->m_current_projection_matrix[0];
334 if (n->element()->batch->root)
335 matrix = matrix * qsg_matrixForRoot(n->element()->batch->root);
337 QSGGeometryNode *gn =
static_cast<QSGGeometryNode *>(n->sgNode);
338 matrix = matrix * *gn->matrix();
340 QSGGeometry *g = gn->geometry();
341 if (g->attributeCount() >= 1) {
343 memcpy(dc.uniforms
.data, matrix.constData(), 64);
345 memcpy(dc.uniforms
.data + 64, rotation.constData(), 64);
347 float(color.redF()) * alpha,
348 float(color.greenF()) * alpha,
349 float(color.blueF()) * alpha,
352 memcpy(dc.uniforms
.data + 128, c, 16);
353 float pattern = tinted ? 0.5f : 0.0f;
354 memcpy(dc.uniforms
.data + 144, &pattern, 4);
355 qint32 projection = 0;
356 memcpy(dc.uniforms
.data + 148, &projection, 4);
358 fillVertexIndex(&dc, g,
true,
false, visualizer
->m_renderer->m_rhi);
359 drawCalls.append(dc);
374 QRhi *rhi, QRhiResourceUpdateBatch *u)
376 this->visualizer = visualizer;
381 if (drawCalls.isEmpty())
384 const int ubufAlign = rhi->ubufAlignment();
388 for (RhiVisualizer::DrawCall &dc : drawCalls) {
389 dc.buf.vbufOffset = aligned(vbufOffset, 4);
390 vbufOffset = dc.buf.vbufOffset + dc.vertex.count * dc.vertex.stride;
392 dc.buf.ibufOffset = aligned(ibufOffset, 4);
393 ibufOffset = dc.buf.ibufOffset + dc.index.count * dc.index.stride;
395 dc.buf.ubufOffset = aligned(ubufOffset, ubufAlign);
396 ubufOffset = dc.buf.ubufOffset + DrawCall::UBUF_SIZE;
399 ensureBuffer(rhi, &vbuf, QRhiBuffer::VertexBuffer, vbufOffset);
401 ensureBuffer(rhi, &ibuf, QRhiBuffer::IndexBuffer, ibufOffset);
402 const int ubufSize = ubufOffset;
403 ensureBuffer(rhi, &ubuf, QRhiBuffer::UniformBuffer, ubufSize);
405 for (RhiVisualizer::DrawCall &dc : drawCalls) {
406 u->updateDynamicBuffer(vbuf, dc.buf.vbufOffset, dc.vertex.count * dc.vertex.stride, dc.vertex.data);
408 if (dc.index.count) {
409 u->updateDynamicBuffer(ibuf, dc.buf.ibufOffset, dc.index.count * dc.index.stride, dc.index.data);
412 u->updateDynamicBuffer(ubuf, dc.buf.ubufOffset, DrawCall::UBUF_SIZE, dc.uniforms.data);
416 srb = rhi->newShaderResourceBindings();
417 srb->setBindings({ QRhiShaderResourceBinding::uniformBufferWithDynamicOffset(0, ubufVisibility, ubuf, DrawCall::UBUF_SIZE) });
440 visualizer->recordDrawCalls(drawCalls, cb, srb);
448 QMatrix4x4 matrix(visualizer
->m_renderer->m_current_projection_matrix[0]);
450 matrix = matrix * qsg_matrixForRoot(b->root);
455 memcpy(dc.uniforms
.data + 64, rotation.constData(), 64);
457 const QColor color = QColor::fromHsvF((visualizer->m_randomGenerator.generate() & 1023) / 1023.0, 1.0, 1.0).toRgb();
461 float(color.greenF()),
462 float(color.blueF()),
465 memcpy(dc.uniforms
.data + 128, c, 16);
467 float pattern = b->merged ? 0.0f : 1.0f;
468 memcpy(dc.uniforms
.data + 144, &pattern, 4);
470 qint32 projection = 0;
471 memcpy(dc.uniforms
.data + 148, &projection, 4);
474 memcpy(dc.uniforms
.data, matrix.constData(), 64);
476 QSGGeometryNode *gn = b
->first->node;
477 QSGGeometry *g = gn->geometry();
479 fillVertexIndex(&dc, g,
false, forceUintIndex, visualizer
->m_renderer->m_rhi);
481 for (
int ds = 0; ds < b->drawSets.size(); ++ds) {
482 const DrawSet &set = b->drawSets.at(ds);
483 dc.buf
.vbuf = b->vbo.buf;
485 dc.buf
.ibuf = b->ibo.buf;
488 drawCalls.append(dc);
496 QSGGeometryNode *gn = e->node;
497 QSGGeometry *g = gn->geometry();
499 QMatrix4x4 m = matrix * *gn->matrix();
500 memcpy(dc.uniforms
.data, m.constData(), 64);
502 fillVertexIndex(&dc, g,
false, forceUintIndex, visualizer
->m_renderer->m_rhi);
504 dc.buf
.vbuf = b->vbo.buf;
506 if (g->indexCount()) {
507 dc.buf
.ibuf = b->ibo.buf;
511 drawCalls.append(dc);
513 vOffset += dc.vertex.count * dc.vertex.stride;
514 iOffset += dc.index.count * dc.index.stride;
521void RhiVisualizer::BatchVis::prepare(
const QDataBuffer<Batch *> &opaqueBatches,
const QDataBuffer<Batch *> &alphaBatches,
523 QRhi *rhi, QRhiResourceUpdateBatch *u,
526 this->visualizer = visualizer;
527 this->forceUintIndex = forceUintIndex;
531 for (
int i = 0; i < opaqueBatches.size(); ++i)
532 gather(opaqueBatches.at(i));
533 for (
int i = 0; i < alphaBatches.size(); ++i)
534 gather(alphaBatches.at(i));
536 if (drawCalls.isEmpty())
539 const int ubufAlign = rhi->ubufAlignment();
541 for (RhiVisualizer::DrawCall &dc : drawCalls) {
542 dc.buf.ubufOffset = aligned(ubufOffset, ubufAlign);
543 ubufOffset = dc.buf.ubufOffset + DrawCall::UBUF_SIZE;
546 const int ubufSize = ubufOffset;
547 ensureBuffer(rhi, &ubuf, QRhiBuffer::UniformBuffer, ubufSize);
549 for (RhiVisualizer::DrawCall &dc : drawCalls)
550 u->updateDynamicBuffer(ubuf, dc.buf.ubufOffset, DrawCall::UBUF_SIZE, dc.uniforms.data);
553 srb = rhi->newShaderResourceBindings();
554 srb->setBindings({ QRhiShaderResourceBinding::uniformBufferWithDynamicOffset(0, ubufVisibility, ubuf, DrawCall::UBUF_SIZE) });
571 visualizer->recordDrawCalls(drawCalls, cb, srb);
576 if (node->type() == QSGNode::ClipNodeType) {
577 QSGClipNode *clipNode =
static_cast<QSGClipNode *>(node);
578 QMatrix4x4 matrix = visualizer
->m_renderer->m_current_projection_matrix[0];
579 if (clipNode->matrix())
580 matrix = matrix * *clipNode->matrix();
582 QSGGeometry *g = clipNode->geometry();
583 if (g->attributeCount() >= 1) {
585 memcpy(dc.uniforms
.data, matrix.constData(), 64);
587 memcpy(dc.uniforms
.data + 64, rotation.constData(), 64);
588 float c[4] = { 0.2f, 0.0f, 0.0f, 0.2f };
589 memcpy(dc.uniforms
.data + 128, c, 16);
590 float pattern = 0.5f;
591 memcpy(dc.uniforms
.data + 144, &pattern, 4);
592 qint32 projection = 0;
593 memcpy(dc.uniforms
.data + 148, &projection, 4);
594 fillVertexIndex(&dc, g,
true,
false, visualizer
->m_renderer->m_rhi);
595 drawCalls.append(dc);
605 QRhi *rhi, QRhiResourceUpdateBatch *u)
607 this->visualizer = visualizer;
612 if (drawCalls.isEmpty())
615 const int ubufAlign = rhi->ubufAlignment();
619 for (RhiVisualizer::DrawCall &dc : drawCalls) {
620 dc.buf.vbufOffset = aligned(vbufOffset, 4);
621 vbufOffset = dc.buf.vbufOffset + dc.vertex.count * dc.vertex.stride;
623 dc.buf.ibufOffset = aligned(ibufOffset, 4);
624 ibufOffset = dc.buf.ibufOffset + dc.index.count * dc.index.stride;
626 dc.buf.ubufOffset = aligned(ubufOffset, ubufAlign);
627 ubufOffset = dc.buf.ubufOffset + DrawCall::UBUF_SIZE;
630 ensureBuffer(rhi, &vbuf, QRhiBuffer::VertexBuffer, vbufOffset);
632 ensureBuffer(rhi, &ibuf, QRhiBuffer::IndexBuffer, ibufOffset);
633 const int ubufSize = ubufOffset;
634 ensureBuffer(rhi, &ubuf, QRhiBuffer::UniformBuffer, ubufSize);
636 for (RhiVisualizer::DrawCall &dc : drawCalls) {
637 u->updateDynamicBuffer(vbuf, dc.buf.vbufOffset, dc.vertex.count * dc.vertex.stride, dc.vertex.data);
639 if (dc.index.count) {
640 u->updateDynamicBuffer(ibuf, dc.buf.ibufOffset, dc.index.count * dc.index.stride, dc.index.data);
643 u->updateDynamicBuffer(ubuf, dc.buf.ubufOffset, DrawCall::UBUF_SIZE, dc.uniforms.data);
647 srb = rhi->newShaderResourceBindings();
648 srb->setBindings({ QRhiShaderResourceBinding::uniformBufferWithDynamicOffset(0, ubufVisibility, ubuf, DrawCall::UBUF_SIZE) });
671 visualizer->recordDrawCalls(drawCalls, cb, srb);
676 if (n->type() == QSGNode::GeometryNodeType && n->element()->batch) {
677 QMatrix4x4 matrix = visualizer
->m_renderer->m_current_projection_matrix[0];
681 if (n->element()->batch->root)
682 matrix = matrix * qsg_matrixForRoot(n->element()->batch->root);
684 QSGGeometryNode *gn =
static_cast<QSGGeometryNode *>(n->sgNode);
685 matrix = matrix * *gn->matrix();
687 QSGGeometry *g = gn->geometry();
688 if (g->attributeCount() >= 1) {
690 memcpy(dc.uniforms
.data, matrix.constData(), 64);
691 memcpy(dc.uniforms.data + 64, rotation.constData(), 64);
694 const float ca = 0.33f;
696 c[0] = ca * 0.3f; c[1] = ca * 1.0f; c[2] = ca * 0.3f; c[3] = ca;
698 c[0] = ca * 1.0f; c[1] = ca * 0.3f; c[2] = ca * 0.3f; c[3] = ca;
700 memcpy(dc.uniforms
.data + 128, c, 16);
701 float pattern = 0.0f;
702 memcpy(dc.uniforms
.data + 144, &pattern, 4);
703 qint32 projection = 1;
704 memcpy(dc.uniforms
.data + 148, &projection, 4);
706 fillVertexIndex(&dc, g,
true,
false, visualizer
->m_renderer->m_rhi);
707 drawCalls.append(dc);
717 QRhi *rhi, QRhiResourceUpdateBatch *u)
719 this->visualizer = visualizer;
721 step +=
float(
M_PI * 2 / 1000.0);
722 if (step >
float(
M_PI * 2))
725 const float yfix = rhi->isYUpInNDC() ? 1.0f : -1.0f;
726 rotation.setToIdentity();
727 rotation.translate(0.0f, 0.5f * yfix, 4.0f);
728 rotation.scale(2.0f, 2.0f, 1.0f);
729 rotation.rotate(-30.0f * yfix, 1.0f, 0.0f, 0.0f);
730 rotation.rotate(80.0f * std::sin(step), 0.0f, 1.0f, 0.0f);
731 rotation.translate(0.0f, 0.0f, -1.0f);
751 -1, -1, 0, -1, -1, 1,
756 box.vbuf = rhi->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer,
sizeof(v));
757 if (!box.vbuf->create())
759 u->uploadStaticBuffer(box.vbuf, v);
763 box.ubuf = rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, DrawCall::UBUF_SIZE);
764 if (!box.ubuf->create())
767 u->updateDynamicBuffer(box.ubuf, 0, 64, ident.constData());
768 float color[4] = { 0.5f, 0.5f, 1.0f, 1.0f };
769 u->updateDynamicBuffer(box.ubuf, 128, 16, color);
770 float pattern = 0.0f;
771 u->updateDynamicBuffer(box.ubuf, 144, 4, &pattern);
772 qint32 projection = 1;
773 u->updateDynamicBuffer(box.ubuf, 148, 4, &projection);
776 u->updateDynamicBuffer(box.ubuf, 64, 64, rotation.constData());
779 box.srb = rhi->newShaderResourceBindings();
780 box.srb->setBindings({ QRhiShaderResourceBinding::uniformBuffer(0, ubufVisibility, box.ubuf) });
781 if (!box.srb->create())
786 box.ps = rhi->newGraphicsPipeline();
787 box.ps->setTopology(QRhiGraphicsPipeline::Lines);
788 box.ps->setLineWidth(2);
789 QRhiGraphicsPipeline::TargetBlend blend;
791 blend.srcColor = QRhiGraphicsPipeline::One;
792 blend.dstColor = QRhiGraphicsPipeline::One;
793 blend.srcAlpha = QRhiGraphicsPipeline::One;
794 blend.dstAlpha = QRhiGraphicsPipeline::One;
795 box.ps->setTargetBlends({ blend });
796 box.ps->setShaderStages({ { QRhiShaderStage::Vertex, visualizer->m_vs },
797 { QRhiShaderStage::Fragment, visualizer->m_fs } });
799 inputLayout.setBindings({ { 3 *
sizeof(
float) } });
800 inputLayout.setAttributes({ { 0, 0, QRhiVertexInputAttribute::Float3, 0 } });
801 box.ps->setVertexInputLayout(inputLayout);
802 box.ps->setShaderResourceBindings(box.srb);
803 box.ps->setRenderPassDescriptor(visualizer->m_renderer->renderTarget().rpDesc);
804 if (!box.ps->create())
808 if (drawCalls.isEmpty())
811 const int ubufAlign = rhi->ubufAlignment();
815 for (RhiVisualizer::DrawCall &dc : drawCalls) {
816 dc.buf.vbufOffset = aligned(vbufOffset, 4);
817 vbufOffset = dc.buf.vbufOffset + dc.vertex.count * dc.vertex.stride;
819 dc.buf.ibufOffset = aligned(ibufOffset, 4);
820 ibufOffset = dc.buf.ibufOffset + dc.index.count * dc.index.stride;
822 dc.buf.ubufOffset = aligned(ubufOffset, ubufAlign);
823 ubufOffset = dc.buf.ubufOffset + DrawCall::UBUF_SIZE;
826 ensureBuffer(rhi, &vbuf, QRhiBuffer::VertexBuffer, vbufOffset);
828 ensureBuffer(rhi, &ibuf, QRhiBuffer::IndexBuffer, ibufOffset);
829 const int ubufSize = ubufOffset;
830 ensureBuffer(rhi, &ubuf, QRhiBuffer::UniformBuffer, ubufSize);
832 for (RhiVisualizer::DrawCall &dc : drawCalls) {
833 u->updateDynamicBuffer(vbuf, dc.buf.vbufOffset, dc.vertex.count * dc.vertex.stride, dc.vertex.data);
835 if (dc.index.count) {
836 u->updateDynamicBuffer(ibuf, dc.buf.ibufOffset, dc.index.count * dc.index.stride, dc.index.data);
839 u->updateDynamicBuffer(ubuf, dc.buf.ubufOffset, DrawCall::UBUF_SIZE, dc.uniforms.data);
843 srb = rhi->newShaderResourceBindings();
844 srb->setBindings({ QRhiShaderResourceBinding::uniformBufferWithDynamicOffset(0, ubufVisibility, ubuf, DrawCall::UBUF_SIZE) });
877void RhiVisualizer::OverdrawVis::render(QRhiCommandBuffer *cb)
879 cb->setGraphicsPipeline(box.ps);
880 cb->setShaderResources();
881 QRhiCommandBuffer::VertexInput vb(box.vbuf, 0);
882 cb->setVertexInput(0, 1, &vb);
885 visualizer->recordDrawCalls(drawCalls, cb, srb,
true);
void releaseResources() override
void prepareVisualize() override
void visualize() override
RhiVisualizer(Renderer *renderer)
Visualizer(Renderer *renderer)
VisualizeMode m_visualizeMode
static bool ensureBuffer(QRhi *rhi, QRhiBuffer **buf, QRhiBuffer::UsageFlags usage, quint32 newSize)
QRhiVertexInputAttribute::Format qsg_vertexInputFormat(const QSGGeometry::Attribute &a)
QRhiGraphicsPipeline::Topology qsg_topology(int geomDrawMode, QRhi *rhi)
QMatrix4x4 qsg_matrixForRoot(Node *node)
static void fillVertexIndex(RhiVisualizer::DrawCall *dc, QSGGeometry *g, bool withData, bool forceUintIndex, QRhi *rhi)
const QRhiShaderResourceBinding::StageFlags ubufVisibility
QRhiCommandBuffer::IndexFormat qsg_indexFormat(const QSGGeometry *geometry)
static uint aligned(uint v, uint byteAlign)
#define QSGNODE_DIRTY_PARENT
#define SHADOWNODE_TRAVERSE(NODE)
#define QSGNODE_TRAVERSE(NODE)
Element * element() const