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();
60 QLatin1String(
":/qt-project.org/scenegraph/shaders_ng/visualization.vert.qsb"));
62 QLatin1String(
":/qt-project.org/scenegraph/shaders_ng/visualization.frag.qsb"));
67 const bool forceUintIndex =
m_renderer->m_uint32IndexForRhi;
107 m_batchVis.render(
cb);
110 m_clipVis.render(
cb);
113 m_changeVis.render(
cb);
116 m_overdrawVis.render(
cb);
129 for (
const DrawCall &dc : drawCalls) {
131 dc.vertex.topology, dc.vertex.format, dc.vertex.stride,
135 cb->setGraphicsPipeline(ps);
137 cb->setShaderResources(srb, 1, &dynofs);
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);
155 this->visualizer = visualizer;
158 float v[] = { -1, 1, 1, 1, -1, -1, 1, -1 };
169 float bgOpacity = 0.8f;
175 float color[4] = { 0.0f, 0.0f, 0.0f, bgOpacity };
199 inputLayout.
setBindings({ { 2 *
sizeof(float) } });
209void RhiVisualizer::Fade::releaseResources()
226 cb->setGraphicsPipeline(ps);
227 cb->setViewport(visualizer->m_renderer->m_pstate.viewport);
228 cb->setShaderResources();
230 cb->setVertexInput(0, 1, &vb);
246 if (withData &&
g->indexCount())
252 return (
v + byteAlign - 1) & ~(byteAlign - 1);
259 if (!(*buf)->create())
261 }
else if ((*buf)->size() < newSize) {
263 if (!(*buf)->create())
280 if (
p.topology == topology &&
p.format == vertexFormat &&
p.stride == vertexStride)
308 p.topology = topology;
309 p.format = vertexFormat;
310 p.stride = vertexStride;
317void RhiVisualizer::PipelineCache::releaseResources()
325void RhiVisualizer::ChangeVis::gather(
Node *
n)
328 const uint dirty = visualizer->m_visualizeChangeSet.value(
n);
331 const float alpha = 0.5f;
334 if (
n->element()->batch->root)
341 if (
g->attributeCount() >= 1) {
343 memcpy(dc.uniforms.data,
matrix.constData(), 64);
345 memcpy(dc.uniforms.data + 64, rotation.
constData(), 64);
352 memcpy(dc.uniforms.data + 128,
c, 16);
353 float pattern = tinted ? 0.5f : 0.0f;
354 memcpy(dc.uniforms.data + 144, &
pattern, 4);
356 memcpy(dc.uniforms.data + 148, &projection, 4);
373void RhiVisualizer::ChangeVis::prepare(
Node *
n, RhiVisualizer *visualizer,
376 this->visualizer = visualizer;
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;
402 const int ubufSize = ubufOffset;
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);
423void RhiVisualizer::ChangeVis::releaseResources()
440 visualizer->recordDrawCalls(drawCalls,
cb, srb);
443void RhiVisualizer::BatchVis::gather(Batch *
b)
445 if (
b->positionAttribute != 0)
455 memcpy(dc.uniforms.data + 64, rotation.
constData(), 64);
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);
471 memcpy(dc.uniforms.data + 148, &projection, 4);
474 memcpy(dc.uniforms.data,
matrix.constData(), 64);
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;
484 dc.buf.vbufOffset =
set.vertices;
485 dc.buf.ibuf =
b->ibo.buf;
486 dc.buf.ibufOffset =
set.indices;
487 dc.index.count =
set.indexCount;
491 Element *
e =
b->first;
500 memcpy(dc.uniforms.data,
m.constData(), 64);
504 dc.buf.vbuf =
b->vbo.buf;
505 dc.buf.vbufOffset = vOffset;
506 if (
g->indexCount()) {
507 dc.buf.ibuf =
b->ibo.buf;
508 dc.buf.ibufOffset = iOffset;
513 vOffset += dc.vertex.count * dc.vertex.stride;
514 iOffset += dc.index.count * dc.index.stride;
522 RhiVisualizer *visualizer,
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));
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;
549 for (RhiVisualizer::DrawCall &dc : drawCalls)
550 u->updateDynamicBuffer(ubuf, dc.
buf.ubufOffset, DrawCall::
UBUF_SIZE, dc.uniforms.
data);
560void RhiVisualizer::BatchVis::releaseResources()
571 visualizer->recordDrawCalls(drawCalls,
cb, srb);
574void RhiVisualizer::ClipVis::gather(
QSGNode *node)
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);
591 memcpy(dc.uniforms.data + 144, &
pattern, 4);
593 memcpy(dc.uniforms.data + 148, &projection, 4);
604void RhiVisualizer::ClipVis::prepare(
QSGNode *node, RhiVisualizer *visualizer,
607 this->visualizer = visualizer;
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;
633 const int ubufSize = ubufOffset;
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);
654void RhiVisualizer::ClipVis::releaseResources()
671 visualizer->recordDrawCalls(drawCalls,
cb, srb);
674void RhiVisualizer::OverdrawVis::gather(
Node *
n)
678 matrix(2, 2) = visualizer->m_renderer->m_zRange;
679 matrix(2, 3) = 1.0f -
n->element()->order * visualizer->m_renderer->m_zRange;
681 if (
n->element()->batch->root)
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;
695 if (
n->element()->batch->isOpaque) {
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);
702 memcpy(dc.uniforms.data + 144, &
pattern, 4);
704 memcpy(dc.uniforms.data + 148, &projection, 4);
716void RhiVisualizer::OverdrawVis::prepare(
Node *
n, RhiVisualizer *visualizer,
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;
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);
751 -1, -1, 0, -1, -1, 1,
757 if (!
box.vbuf->create())
764 if (!
box.ubuf->create())
768 float color[4] = { 0.5f, 0.5f, 1.0f, 1.0f };
781 if (!
box.srb->create())
788 box.ps->setLineWidth(2);
795 box.ps->setTargetBlends({ blend });
799 inputLayout.
setBindings({ { 3 *
sizeof(float) } });
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())
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;
829 const int ubufSize = ubufOffset;
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);
850void RhiVisualizer::OverdrawVis::releaseResources()
879 cb->setGraphicsPipeline(
box.ps);
880 cb->setShaderResources();
882 cb->setVertexInput(0, 1, &vb);
885 visualizer->recordDrawCalls(drawCalls,
cb, srb,
true);
The QColor class provides colors based on RGB, HSV or CMYK values.
QColor toRgb() const noexcept
Create and returns an RGB QColor based on this color.
static QColor fromHsvF(float h, float s, float v, float a=1.0)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool isEmpty() const noexcept
void append(parameter_type t)
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
void rotate(float angle, const QVector3D &vector)
Multiples this matrix by another that rotates coordinates through angle degrees about vector.
void scale(const QVector3D &vector)
Multiplies this matrix by another that scales coordinates by the components of vector.
void setToIdentity()
Sets this matrix to the identity.
const float * constData() const
Returns a constant pointer to the raw data of this matrix.
void translate(const QVector3D &vector)
Multiplies this matrix by another that translates coordinates by the components of vector.
void setSize(quint32 sz)
Sets the size of the buffer in bytes.
QPair< QRhiBuffer *, quint32 > VertexInput
Synonym for QPair<QRhiBuffer *, quint32>.
QPair< int, quint32 > DynamicOffset
Synonym for QPair<int, quint32>.
IndexFormat
Specifies the index data type.
void setTargetBlends(std::initializer_list< TargetBlend > list)
Sets the list of render target blend settings.
void setShaderResourceBindings(QRhiShaderResourceBindings *srb)
Associates with srb describing the resource binding layout and the resources (QRhiBuffer,...
void setVertexInputLayout(const QRhiVertexInputLayout &layout)
Specifies the vertex input layout.
void setShaderStages(std::initializer_list< QRhiShaderStage > list)
Sets the list of shader stages.
void setRenderPassDescriptor(QRhiRenderPassDescriptor *desc)
Associates with the specified QRhiRenderPassDescriptor desc.
void setTopology(Topology t)
Sets the primitive topology t.
Topology
Specifies the primitive topology.
virtual bool create()=0
Creates the corresponding native graphics resources.
void updateDynamicBuffer(QRhiBuffer *buf, quint32 offset, quint32 size, const void *data)
Enqueues updating a region of a QRhiBuffer buf created with the type QRhiBuffer::Dynamic.
void uploadStaticBuffer(QRhiBuffer *buf, quint32 offset, quint32 size, const void *data)
Enqueues updating a region of a QRhiBuffer buf created with the type QRhiBuffer::Immutable or QRhiBuf...
static QRhiShaderResourceBinding uniformBufferWithDynamicOffset(int binding, StageFlags stage, QRhiBuffer *buf, quint32 size)
static QRhiShaderResourceBinding uniformBuffer(int binding, StageFlags stage, QRhiBuffer *buf)
void setBindings(std::initializer_list< QRhiShaderResourceBinding > list)
Sets the list of bindings.
QRhiBuffer * newBuffer(QRhiBuffer::Type type, QRhiBuffer::UsageFlags usage, quint32 size)
QRhiShaderResourceBindings * newShaderResourceBindings()
QRhiGraphicsPipeline * newGraphicsPipeline()
int ubufAlignment() const
QSGRootNode * rootNode() const
Returns the root of the QSGNode scene.
const QSGGeometry * geometry() const
Returns this node's geometry.
const QMatrix4x4 * matrix() const
Will be set during rendering to contain transformation of the geometry for that rendering pass.
void releaseResources() override
void prepareVisualize() override
void visualize() override
RhiVisualizer(Renderer *renderer)
QHash< Node *, uint > m_visualizeChangeSet
VisualizeMode m_visualizeMode
The QSGClipNode class implements the clipping functionality in the scene graph.
The QSGGeometryNode class is used for all rendered content in the scene graph.
The QSGGeometry class provides low-level storage for graphics primitives in the \l{Qt Quick Scene Gra...
static QShader loadShader(const QString &filename)
\group qtquick-scenegraph-nodes \title Qt Quick Scene Graph Node classes
NodeType type() const
Returns the type of this node.
QRhiRenderPassDescriptor * rpDesc
const QSGRenderTarget & renderTarget() const
static bool ensureBuffer(QRhi *rhi, QRhiBuffer **buf, QRhiBuffer::UsageFlags usage, quint32 newSize)
QRhiVertexInputAttribute::Format qsg_vertexInputFormat(const QSGGeometry::Attribute &a)
QMatrix4x4 qsg_matrixForRoot(Node *node)
const QRhiShaderResourceBinding::StageFlags ubufVisibility
QRhiCommandBuffer::IndexFormat qsg_indexFormat(const QSGGeometry *geometry)
static void fillVertexIndex(RhiVisualizer::DrawCall *dc, QSGGeometry *g, bool withData, bool forceUintIndex)
QRhiGraphicsPipeline::Topology qsg_topology(int geomDrawMode)
Int aligned(Int v, Int byteAlign)
Combined button and popup list for selecting options.
static const int UBUF_SIZE
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLenum GLsizei const GLchar * buf
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLsizei const GLint * box
GLfloat GLfloat GLfloat alpha
GLsizeiptr const void GLenum usage
#define QSGNODE_DIRTY_PARENT
#define SHADOWNODE_TRAVERSE(NODE)
#define QSGNODE_TRAVERSE(NODE)
SSL_CTX int(* cb)(SSL *ssl, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
QLatin1StringView QLatin1String
QFuture< QSet< QChar > > set
[10]
QSvgRenderer * renderer
[0]
QRhiVertexInputAttribute::Format format
QRhiGraphicsPipeline::Topology topology
struct QSGBatchRenderer::RhiVisualizer::DrawCall::@690 vertex
struct QSGBatchRenderer::RhiVisualizer::DrawCall::@691 index
The QSGGeometry::Attribute describes a single vertex attribute in a QSGGeometry.