9#include <private/qsgmaterialshader_p.h>
16#define QSGNODE_TRAVERSE(NODE) for (QSGNode *child = NODE->firstChild(); child; child = child->nextSibling())
17#define SHADOWNODE_TRAVERSE(NODE) for (Node *child = NODE->firstChild(); child; child = child->sibling())
18#define QSGNODE_DIRTY_PARENT (QSGNode::DirtyNodeAdded
19 | QSGNode::DirtyOpacity
20 | QSGNode::DirtyMatrix
21 | QSGNode::DirtyNodeRemoved)
40 m_pipelines.releaseResources();
42 m_fade.releaseResources();
44 m_changeVis.releaseResources();
45 m_batchVis.releaseResources();
46 m_clipVis.releaseResources();
47 m_overdrawVis.releaseResources();
56 if (m_visualizeMode == VisualizeNothing)
59 if (!m_vs.isValid()) {
60 m_vs = QSGMaterialShaderPrivate::loadShader(
61 QLatin1String(
":/qt-project.org/scenegraph/shaders_ng/visualization.vert.qsb"));
62 m_fs = QSGMaterialShaderPrivate::loadShader(
63 QLatin1String(
":/qt-project.org/scenegraph/shaders_ng/visualization.frag.qsb"));
66 m_fade.prepare(
this, m_renderer->m_rhi, m_renderer->m_resourceUpdates, m_renderer->renderTarget().rpDesc);
68 const bool forceUintIndex = m_renderer->m_uint32IndexForRhi;
70 switch (m_visualizeMode) {
71 case VisualizeBatches:
72 m_batchVis.prepare(m_renderer->m_opaqueBatches, m_renderer->m_alphaBatches,
74 m_renderer->m_rhi, m_renderer->m_resourceUpdates,
77 case VisualizeClipping:
78 m_clipVis.prepare(m_renderer->rootNode(),
this,
79 m_renderer->m_rhi, m_renderer->m_resourceUpdates);
81 case VisualizeChanges:
82 m_changeVis.prepare(m_renderer->m_nodes.value(m_renderer->rootNode()),
84 m_renderer->m_rhi, m_renderer->m_resourceUpdates);
85 m_visualizeChangeSet.clear();
87 case VisualizeOverdraw:
88 m_overdrawVis.prepare(m_renderer->m_nodes.value(m_renderer->rootNode()),
90 m_renderer->m_rhi, m_renderer->m_resourceUpdates);
100 if (m_visualizeMode == VisualizeNothing)
103 QRhiCommandBuffer *cb = m_renderer->renderTarget().cb;
106 switch (m_visualizeMode) {
107 case VisualizeBatches:
108 m_batchVis.render(cb);
110 case VisualizeClipping:
111 m_clipVis.render(cb);
113 case VisualizeChanges:
114 m_changeVis.render(cb);
116 case VisualizeOverdraw:
117 m_overdrawVis.render(cb);
125void RhiVisualizer::recordDrawCalls(
const QList<DrawCall> &drawCalls,
126 QRhiCommandBuffer *cb,
127 QRhiShaderResourceBindings *srb,
130 for (
const DrawCall &dc : drawCalls) {
131 QRhiGraphicsPipeline *ps = m_pipelines.pipeline(
this, m_renderer->m_rhi, srb, m_renderer->renderTarget().rpDesc,
132 dc.vertex.topology, dc.vertex.format, dc.vertex.stride,
136 cb->setGraphicsPipeline(ps);
137 QRhiCommandBuffer::DynamicOffset dynofs(0, dc.buf.ubufOffset);
138 cb->setShaderResources(srb, 1, &dynofs);
139 QRhiCommandBuffer::VertexInput vb(dc.buf.vbuf, dc.buf.vbufOffset);
140 if (dc.index.count) {
141 cb->setVertexInput(0, 1, &vb, dc.buf.ibuf, dc.buf.ibufOffset, dc.index.format);
142 cb->drawIndexed(dc.index.count);
144 cb->setVertexInput(0, 1, &vb);
145 cb->draw(dc.vertex.count);
154 QRhi *rhi, QRhiResourceUpdateBatch *u, QRhiRenderPassDescriptor *rpDesc)
156 this->visualizer = visualizer;
159 float v[] = { -1, 1, 1, 1, -1, -1, 1, -1 };
160 vbuf = rhi->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer,
sizeof(v));
163 u->uploadStaticBuffer(vbuf, v);
167 ubuf = rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer,
DrawCall::UBUF_SIZE);
170 float bgOpacity = 0.8f;
174 u->updateDynamicBuffer(ubuf, 0, 64, ident.constData());
175 u->updateDynamicBuffer(ubuf, 64, 64, ident.constData());
176 float color[4] = { 0.0f, 0.0f, 0.0f, bgOpacity };
177 u->updateDynamicBuffer(ubuf, 128, 16, color);
178 float pattern = 0.0f;
179 u->updateDynamicBuffer(ubuf, 144, 4, &pattern);
180 qint32 projection = 0;
181 u->updateDynamicBuffer(ubuf, 148, 4, &projection);
185 srb = rhi->newShaderResourceBindings();
186 srb->setBindings({ QRhiShaderResourceBinding::uniformBuffer(0, ubufVisibility, ubuf) });
192 ps = rhi->newGraphicsPipeline();
193 ps->setTopology(QRhiGraphicsPipeline::TriangleStrip);
194 QRhiGraphicsPipeline::TargetBlend blend;
196 ps->setTargetBlends({ blend });
197 ps->setShaderStages({ { QRhiShaderStage::Vertex, visualizer->m_vs },
198 { QRhiShaderStage::Fragment, visualizer->m_fs } });
200 inputLayout.setBindings({ { 2 *
sizeof(
float) } });
201 inputLayout.setAttributes({ { 0, 0, QRhiVertexInputAttribute::Float2, 0 } });
202 ps->setVertexInputLayout(inputLayout);
203 ps->setShaderResourceBindings(srb);
204 ps->setRenderPassDescriptor(rpDesc);
227 cb->setGraphicsPipeline(ps);
228 cb->setViewport(visualizer->m_renderer->m_pstate.viewport);
229 cb->setShaderResources();
230 QRhiCommandBuffer::VertexInput vb(vbuf, 0);
231 cb->setVertexInput(0, 1, &vb);
237 dc->vertex.topology = qsg_topology(g->drawingMode(), rhi);
238 dc->vertex.format = qsg_vertexInputFormat(g->attributes()[0]);
239 dc->vertex.count = g->vertexCount();
240 dc->vertex.stride = g->sizeOfVertex();
242 dc->vertex.data = g->vertexData();
244 dc->index.format = forceUintIndex ? QRhiCommandBuffer::IndexUInt32 : qsg_indexFormat(g);
245 dc->index.count = g->indexCount();
246 dc->index.stride = forceUintIndex ?
sizeof(quint32) : g->sizeOfIndex();
247 if (withData && g->indexCount())
248 dc->index.data = g->indexData();
251static inline uint
aligned(uint v, uint byteAlign)
253 return (v + byteAlign - 1) & ~(byteAlign - 1);
256static bool ensureBuffer(QRhi *rhi, QRhiBuffer **buf, QRhiBuffer::UsageFlags usage, quint32 newSize)
259 *buf = rhi->newBuffer(QRhiBuffer::Dynamic, usage, newSize);
260 if (!(*buf)->create())
262 }
else if ((*buf)->size() < newSize) {
263 (*buf)->setSize(newSize);
264 if (!(*buf)->create())
272 QRhiShaderResourceBindings *srb,
273 QRhiRenderPassDescriptor *rpDesc,
274 QRhiGraphicsPipeline::Topology topology,
275 QRhiVertexInputAttribute::Format vertexFormat,
276 quint32 vertexStride,
279 for (
int i = 0, ie = pipelines.size(); i != ie; ++i) {
280 const Pipeline &p(pipelines.at(i));
281 if (p.topology == topology && p.format == vertexFormat && p.stride == vertexStride)
285 QRhiGraphicsPipeline *ps = rhi->newGraphicsPipeline();
286 ps->setTopology(topology);
287 QRhiGraphicsPipeline::TargetBlend blend;
291 blend.srcColor = QRhiGraphicsPipeline::One;
292 blend.dstColor = QRhiGraphicsPipeline::One;
293 blend.srcAlpha = QRhiGraphicsPipeline::One;
294 blend.dstAlpha = QRhiGraphicsPipeline::One;
296 ps->setTargetBlends({ blend });
297 ps->setShaderStages({ { QRhiShaderStage::Vertex, visualizer->m_vs },
298 { QRhiShaderStage::Fragment, visualizer->m_fs } });
300 inputLayout.setBindings({ { vertexStride } });
301 inputLayout.setAttributes({ { 0, 0, vertexFormat, 0 } });
302 ps->setVertexInputLayout(inputLayout);
303 ps->setShaderResourceBindings(srb);
304 ps->setRenderPassDescriptor(rpDesc);
309 p.topology = topology;
310 p.format = vertexFormat;
311 p.stride = vertexStride;
320 for (
int i = 0, ie = pipelines.size(); i != ie; ++i)
321 delete pipelines.at(i).ps;
328 if (n->type() == QSGNode::GeometryNodeType && n->element()->batch && visualizer->m_visualizeChangeSet.contains(n)) {
329 const uint dirty = visualizer->m_visualizeChangeSet.value(n);
331 const QColor color = QColor::fromHsvF((visualizer->m_randomGenerator.generate() & 1023) / 1023.0f, 0.3f, 1.0f).toRgb();
332 const float alpha = 0.5f;
334 QMatrix4x4 matrix = visualizer->m_renderer->m_current_projection_matrix[0];
335 if (n->element()->batch->root)
336 matrix = matrix * qsg_matrixForRoot(n->element()->batch->root);
338 QSGGeometryNode *gn =
static_cast<QSGGeometryNode *>(n->sgNode);
339 matrix = matrix * *gn->matrix();
341 QSGGeometry *g = gn->geometry();
342 if (g->attributeCount() >= 1) {
344 memcpy(dc.uniforms
.data, matrix.constData(), 64);
346 memcpy(dc.uniforms
.data + 64, rotation.constData(), 64);
348 float(color.redF()) * alpha,
349 float(color.greenF()) * alpha,
350 float(color.blueF()) * alpha,
353 memcpy(dc.uniforms
.data + 128, c, 16);
354 float pattern = tinted ? 0.5f : 0.0f;
355 memcpy(dc.uniforms
.data + 144, &pattern, 4);
356 qint32 projection = 0;
357 memcpy(dc.uniforms
.data + 148, &projection, 4);
359 fillVertexIndex(&dc, g,
true,
false, visualizer->m_renderer->m_rhi);
360 drawCalls.append(dc);
375 QRhi *rhi, QRhiResourceUpdateBatch *u)
377 this->visualizer = visualizer;
382 if (drawCalls.isEmpty())
385 const int ubufAlign = rhi->ubufAlignment();
389 for (RhiVisualizer::DrawCall &dc : drawCalls) {
390 dc.buf.vbufOffset = aligned(vbufOffset, 4);
391 vbufOffset = dc.buf.vbufOffset + dc.vertex.count * dc.vertex.stride;
393 dc.buf.ibufOffset = aligned(ibufOffset, 4);
394 ibufOffset = dc.buf.ibufOffset + dc.index.count * dc.index.stride;
396 dc.buf.ubufOffset = aligned(ubufOffset, ubufAlign);
397 ubufOffset = dc.buf.ubufOffset + DrawCall::UBUF_SIZE;
400 ensureBuffer(rhi, &vbuf, QRhiBuffer::VertexBuffer, vbufOffset);
402 ensureBuffer(rhi, &ibuf, QRhiBuffer::IndexBuffer, ibufOffset);
403 const int ubufSize = ubufOffset;
404 ensureBuffer(rhi, &ubuf, QRhiBuffer::UniformBuffer, ubufSize);
406 for (RhiVisualizer::DrawCall &dc : drawCalls) {
407 u->updateDynamicBuffer(vbuf, dc.buf.vbufOffset, dc.vertex.count * dc.vertex.stride, dc.vertex.data);
409 if (dc.index.count) {
410 u->updateDynamicBuffer(ibuf, dc.buf.ibufOffset, dc.index.count * dc.index.stride, dc.index.data);
413 u->updateDynamicBuffer(ubuf, dc.buf.ubufOffset, DrawCall::UBUF_SIZE, dc.uniforms.data);
417 srb = rhi->newShaderResourceBindings();
418 srb->setBindings({ QRhiShaderResourceBinding::uniformBufferWithDynamicOffset(0, ubufVisibility, ubuf, DrawCall::UBUF_SIZE) });
441 visualizer->recordDrawCalls(drawCalls, cb, srb);
449 QMatrix4x4 matrix(visualizer->m_renderer->m_current_projection_matrix[0]);
451 matrix = matrix * qsg_matrixForRoot(b->root);
456 memcpy(dc.uniforms
.data + 64, rotation.constData(), 64);
458 const QColor color = QColor::fromHsvF((visualizer->m_randomGenerator.generate() & 1023) / 1023.0, 1.0, 1.0).toRgb();
462 float(color.greenF()),
463 float(color.blueF()),
466 memcpy(dc.uniforms
.data + 128, c, 16);
468 float pattern = b->merged ? 0.0f : 1.0f;
469 memcpy(dc.uniforms
.data + 144, &pattern, 4);
471 qint32 projection = 0;
472 memcpy(dc.uniforms
.data + 148, &projection, 4);
475 memcpy(dc.uniforms
.data, matrix.constData(), 64);
477 QSGGeometryNode *gn = b
->first->node;
478 QSGGeometry *g = gn->geometry();
480 fillVertexIndex(&dc, g,
false, forceUintIndex, visualizer->m_renderer->m_rhi);
482 for (
int ds = 0; ds < b->drawSets.size(); ++ds) {
483 const DrawSet &set = b->drawSets.at(ds);
484 dc.buf
.vbuf = b->vbo.buf;
486 dc.buf
.ibuf = b->ibo.buf;
489 drawCalls.append(dc);
497 QSGGeometryNode *gn = e->node;
498 QSGGeometry *g = gn->geometry();
500 QMatrix4x4 m = matrix * *gn->matrix();
501 memcpy(dc.uniforms
.data, m.constData(), 64);
503 fillVertexIndex(&dc, g,
false, forceUintIndex, visualizer->m_renderer->m_rhi);
505 dc.buf
.vbuf = b->vbo.buf;
507 if (g->indexCount()) {
508 dc.buf
.ibuf = b->ibo.buf;
512 drawCalls.append(dc);
514 vOffset += dc.vertex.count * dc.vertex.stride;
515 iOffset += dc.index.count * dc.index.stride;
522void RhiVisualizer::BatchVis::prepare(
const QDataBuffer<Batch *> &opaqueBatches,
const QDataBuffer<Batch *> &alphaBatches,
524 QRhi *rhi, QRhiResourceUpdateBatch *u,
527 this->visualizer = visualizer;
528 this->forceUintIndex = forceUintIndex;
532 for (
int i = 0; i < opaqueBatches.size(); ++i)
533 gather(opaqueBatches.at(i));
534 for (
int i = 0; i < alphaBatches.size(); ++i)
535 gather(alphaBatches.at(i));
537 if (drawCalls.isEmpty())
540 const int ubufAlign = rhi->ubufAlignment();
542 for (RhiVisualizer::DrawCall &dc : drawCalls) {
543 dc.buf.ubufOffset = aligned(ubufOffset, ubufAlign);
544 ubufOffset = dc.buf.ubufOffset + DrawCall::UBUF_SIZE;
547 const int ubufSize = ubufOffset;
548 ensureBuffer(rhi, &ubuf, QRhiBuffer::UniformBuffer, ubufSize);
550 for (RhiVisualizer::DrawCall &dc : drawCalls)
551 u->updateDynamicBuffer(ubuf, dc.buf.ubufOffset, DrawCall::UBUF_SIZE, dc.uniforms.data);
554 srb = rhi->newShaderResourceBindings();
555 srb->setBindings({ QRhiShaderResourceBinding::uniformBufferWithDynamicOffset(0, ubufVisibility, ubuf, DrawCall::UBUF_SIZE) });
572 visualizer->recordDrawCalls(drawCalls, cb, srb);
577 if (node->type() == QSGNode::ClipNodeType) {
578 QSGClipNode *clipNode =
static_cast<QSGClipNode *>(node);
579 QMatrix4x4 matrix = visualizer->m_renderer->m_current_projection_matrix[0];
580 if (clipNode->matrix())
581 matrix = matrix * *clipNode->matrix();
583 QSGGeometry *g = clipNode->geometry();
584 if (g->attributeCount() >= 1) {
586 memcpy(dc.uniforms
.data, matrix.constData(), 64);
588 memcpy(dc.uniforms
.data + 64, rotation.constData(), 64);
589 float c[4] = { 0.2f, 0.0f, 0.0f, 0.2f };
590 memcpy(dc.uniforms
.data + 128, c, 16);
591 float pattern = 0.5f;
592 memcpy(dc.uniforms
.data + 144, &pattern, 4);
593 qint32 projection = 0;
594 memcpy(dc.uniforms
.data + 148, &projection, 4);
595 fillVertexIndex(&dc, g,
true,
false, visualizer->m_renderer->m_rhi);
596 drawCalls.append(dc);
606 QRhi *rhi, QRhiResourceUpdateBatch *u)
608 this->visualizer = visualizer;
613 if (drawCalls.isEmpty())
616 const int ubufAlign = rhi->ubufAlignment();
620 for (RhiVisualizer::DrawCall &dc : drawCalls) {
621 dc.buf.vbufOffset = aligned(vbufOffset, 4);
622 vbufOffset = dc.buf.vbufOffset + dc.vertex.count * dc.vertex.stride;
624 dc.buf.ibufOffset = aligned(ibufOffset, 4);
625 ibufOffset = dc.buf.ibufOffset + dc.index.count * dc.index.stride;
627 dc.buf.ubufOffset = aligned(ubufOffset, ubufAlign);
628 ubufOffset = dc.buf.ubufOffset + DrawCall::UBUF_SIZE;
631 ensureBuffer(rhi, &vbuf, QRhiBuffer::VertexBuffer, vbufOffset);
633 ensureBuffer(rhi, &ibuf, QRhiBuffer::IndexBuffer, ibufOffset);
634 const int ubufSize = ubufOffset;
635 ensureBuffer(rhi, &ubuf, QRhiBuffer::UniformBuffer, ubufSize);
637 for (RhiVisualizer::DrawCall &dc : drawCalls) {
638 u->updateDynamicBuffer(vbuf, dc.buf.vbufOffset, dc.vertex.count * dc.vertex.stride, dc.vertex.data);
640 if (dc.index.count) {
641 u->updateDynamicBuffer(ibuf, dc.buf.ibufOffset, dc.index.count * dc.index.stride, dc.index.data);
644 u->updateDynamicBuffer(ubuf, dc.buf.ubufOffset, DrawCall::UBUF_SIZE, dc.uniforms.data);
648 srb = rhi->newShaderResourceBindings();
649 srb->setBindings({ QRhiShaderResourceBinding::uniformBufferWithDynamicOffset(0, ubufVisibility, ubuf, DrawCall::UBUF_SIZE) });
672 visualizer->recordDrawCalls(drawCalls, cb, srb);
677 if (n->type() == QSGNode::GeometryNodeType && n->element()->batch) {
678 QMatrix4x4 matrix = visualizer->m_renderer->m_current_projection_matrix[0];
679 matrix(2, 2) = visualizer->m_renderer->m_zRange;
682 if (n->element()->batch->root)
683 matrix = matrix * qsg_matrixForRoot(n->element()->batch->root);
685 QSGGeometryNode *gn =
static_cast<QSGGeometryNode *>(n->sgNode);
686 matrix = matrix * *gn->matrix();
688 QSGGeometry *g = gn->geometry();
689 if (g->attributeCount() >= 1) {
691 memcpy(dc.uniforms
.data, matrix.constData(), 64);
692 memcpy(dc.uniforms
.data + 64, rotation.constData(), 64);
695 const float ca = 0.33f;
697 c[0] = ca * 0.3f; c[1] = ca * 1.0f; c[2] = ca * 0.3f; c[3] = ca;
699 c[0] = ca * 1.0f; c[1] = ca * 0.3f; c[2] = ca * 0.3f; c[3] = ca;
701 memcpy(dc.uniforms
.data + 128, c, 16);
702 float pattern = 0.0f;
703 memcpy(dc.uniforms
.data + 144, &pattern, 4);
704 qint32 projection = 1;
705 memcpy(dc.uniforms
.data + 148, &projection, 4);
707 fillVertexIndex(&dc, g,
true,
false, visualizer->m_renderer->m_rhi);
708 drawCalls.append(dc);
718 QRhi *rhi, QRhiResourceUpdateBatch *u)
720 this->visualizer = visualizer;
722 step +=
float(
M_PI * 2 / 1000.0);
723 if (step >
float(
M_PI * 2))
726 const float yfix = rhi->isYUpInNDC() ? 1.0f : -1.0f;
727 rotation.setToIdentity();
728 rotation.translate(0.0f, 0.5f * yfix, 4.0f);
729 rotation.scale(2.0f, 2.0f, 1.0f);
730 rotation.rotate(-30.0f * yfix, 1.0f, 0.0f, 0.0f);
731 rotation.rotate(80.0f * std::sin(step), 0.0f, 1.0f, 0.0f);
732 rotation.translate(0.0f, 0.0f, -1.0f);
752 -1, -1, 0, -1, -1, 1,
757 box.vbuf = rhi->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer,
sizeof(v));
758 if (!box.vbuf->create())
760 u->uploadStaticBuffer(box.vbuf, v);
764 box.ubuf = rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, DrawCall::UBUF_SIZE);
765 if (!box.ubuf->create())
768 u->updateDynamicBuffer(box.ubuf, 0, 64, ident.constData());
769 float color[4] = { 0.5f, 0.5f, 1.0f, 1.0f };
770 u->updateDynamicBuffer(box.ubuf, 128, 16, color);
771 float pattern = 0.0f;
772 u->updateDynamicBuffer(box.ubuf, 144, 4, &pattern);
773 qint32 projection = 1;
774 u->updateDynamicBuffer(box.ubuf, 148, 4, &projection);
777 u->updateDynamicBuffer(box.ubuf, 64, 64, rotation.constData());
780 box.srb = rhi->newShaderResourceBindings();
781 box.srb->setBindings({ QRhiShaderResourceBinding::uniformBuffer(0, ubufVisibility, box.ubuf) });
782 if (!box.srb->create())
787 box.ps = rhi->newGraphicsPipeline();
788 box.ps->setTopology(QRhiGraphicsPipeline::Lines);
789 box.ps->setLineWidth(2);
790 QRhiGraphicsPipeline::TargetBlend blend;
792 blend.srcColor = QRhiGraphicsPipeline::One;
793 blend.dstColor = QRhiGraphicsPipeline::One;
794 blend.srcAlpha = QRhiGraphicsPipeline::One;
795 blend.dstAlpha = QRhiGraphicsPipeline::One;
796 box.ps->setTargetBlends({ blend });
797 box.ps->setShaderStages({ { QRhiShaderStage::Vertex, visualizer->m_vs },
798 { QRhiShaderStage::Fragment, visualizer->m_fs } });
800 inputLayout.setBindings({ { 3 *
sizeof(
float) } });
801 inputLayout.setAttributes({ { 0, 0, QRhiVertexInputAttribute::Float3, 0 } });
802 box.ps->setVertexInputLayout(inputLayout);
803 box.ps->setShaderResourceBindings(box.srb);
804 box.ps->setRenderPassDescriptor(visualizer->m_renderer->renderTarget().rpDesc);
805 if (!box.ps->create())
809 if (drawCalls.isEmpty())
812 const int ubufAlign = rhi->ubufAlignment();
816 for (RhiVisualizer::DrawCall &dc : drawCalls) {
817 dc.buf.vbufOffset = aligned(vbufOffset, 4);
818 vbufOffset = dc.buf.vbufOffset + dc.vertex.count * dc.vertex.stride;
820 dc.buf.ibufOffset = aligned(ibufOffset, 4);
821 ibufOffset = dc.buf.ibufOffset + dc.index.count * dc.index.stride;
823 dc.buf.ubufOffset = aligned(ubufOffset, ubufAlign);
824 ubufOffset = dc.buf.ubufOffset + DrawCall::UBUF_SIZE;
827 ensureBuffer(rhi, &vbuf, QRhiBuffer::VertexBuffer, vbufOffset);
829 ensureBuffer(rhi, &ibuf, QRhiBuffer::IndexBuffer, ibufOffset);
830 const int ubufSize = ubufOffset;
831 ensureBuffer(rhi, &ubuf, QRhiBuffer::UniformBuffer, ubufSize);
833 for (RhiVisualizer::DrawCall &dc : drawCalls) {
834 u->updateDynamicBuffer(vbuf, dc.buf.vbufOffset, dc.vertex.count * dc.vertex.stride, dc.vertex.data);
836 if (dc.index.count) {
837 u->updateDynamicBuffer(ibuf, dc.buf.ibufOffset, dc.index.count * dc.index.stride, dc.index.data);
840 u->updateDynamicBuffer(ubuf, dc.buf.ubufOffset, DrawCall::UBUF_SIZE, dc.uniforms.data);
844 srb = rhi->newShaderResourceBindings();
845 srb->setBindings({ QRhiShaderResourceBinding::uniformBufferWithDynamicOffset(0, ubufVisibility, ubuf, DrawCall::UBUF_SIZE) });
878void RhiVisualizer::OverdrawVis::render(QRhiCommandBuffer *cb)
880 cb->setGraphicsPipeline(box.ps);
881 cb->setShaderResources();
882 QRhiCommandBuffer::VertexInput vb(box.vbuf, 0);
883 cb->setVertexInput(0, 1, &vb);
886 visualizer->recordDrawCalls(drawCalls, cb, srb,
true);
void releaseResources() override
void prepareVisualize() override
void visualize() override
RhiVisualizer(Renderer *renderer)
Visualizer(Renderer *renderer)
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)
Combined button and popup list for selecting options.
#define QSGNODE_DIRTY_PARENT
#define SHADOWNODE_TRAVERSE(NODE)
#define QSGNODE_TRAVERSE(NODE)
Element * element() const
static const int UBUF_SIZE