10#include <QtCore/QElapsedTimer>
11#include <QtCore/QtNumeric>
13#include <QtGui/QGuiApplication>
15#include <private/qnumeric_p.h>
33#define DECLARE_DEBUG_VAR(variable)
34 static bool debug_ ## variable()
35 { static bool value = qgetenv("QSG_RENDERER_DEBUG").contains(QT_STRINGIFY(variable)); return value; }
46#undef DECLARE_DEBUG_VAR
48#define QSGNODE_TRAVERSE(NODE) for (QSGNode *child = NODE->firstChild(); child; child = child->nextSibling())
49#define SHADOWNODE_TRAVERSE(NODE) for (Node *child = NODE->firstChild(); child; child = child->sibling())
53 static int sizes[] = {
55 sizeof(
unsigned char),
57 sizeof(
unsigned short),
66 Q_ASSERT(type >= QSGGeometry::ByteType && type <= QSGGeometry::DoubleType);
67 return sizes[type - QSGGeometry::ByteType];
78static bool isTranslate(
const QMatrix4x4 &m) {
return m.flags() <= QMatrix4x4::Translation; }
79static bool isScale(
const QMatrix4x4 &m) {
return m.flags() <= QMatrix4x4::Scale; }
80static bool is2DSafe(
const QMatrix4x4 &m) {
return m.flags() < QMatrix4x4::Rotation; }
96 return (v + byteAlign - 1) & ~(byteAlign - 1);
102 case QSGGeometry::FloatType:
103 if (a.tupleSize == 4)
104 return QRhiVertexInputAttribute::Float4;
105 if (a.tupleSize == 3)
106 return QRhiVertexInputAttribute::Float3;
107 if (a.tupleSize == 2)
108 return QRhiVertexInputAttribute::Float2;
109 if (a.tupleSize == 1)
110 return QRhiVertexInputAttribute::Float;
112 case QSGGeometry::UnsignedByteType:
113 if (a.tupleSize == 4)
114 return QRhiVertexInputAttribute::UNormByte4;
115 if (a.tupleSize == 2)
116 return QRhiVertexInputAttribute::UNormByte2;
117 if (a.tupleSize == 1)
118 return QRhiVertexInputAttribute::UNormByte;
123 qWarning(
"Unsupported attribute type 0x%x with %d components", a.type, a.tupleSize);
124 Q_UNREACHABLE_RETURN(QRhiVertexInputAttribute::Float);
130 const QSGMaterialShaderPrivate *sd = QSGMaterialShaderPrivate::get(s);
131 if (!sd->vertexShader) {
132 qWarning(
"No vertex shader in QSGMaterialShader %p", s);
133 return QRhiVertexInputLayout();
136 const int attrCount = geometry->attributeCount();
137 QVarLengthArray<QRhiVertexInputAttribute, 8> inputAttributes;
138 inputAttributes.reserve(attrCount + 1);
140 for (
int i = 0; i < attrCount; ++i) {
141 const QSGGeometry::Attribute &a = geometry->attributes()[i];
142 if (!sd->vertexShader->vertexInputLocations.contains(a.position)) {
143 qWarning(
"Vertex input %d is present in material but not in shader. This is wrong.",
146 inputAttributes.append(QRhiVertexInputAttribute(VERTEX_BUFFER_BINDING, a.position, qsg_vertexInputFormat(a), offset));
147 offset += a.tupleSize * size_of_type(a.type);
150 inputAttributes.append(QRhiVertexInputAttribute(ZORDER_BUFFER_BINDING, sd->vertexShader->qt_order_attrib_location,
151 QRhiVertexInputAttribute::Float, 0));
155 QVarLengthArray<QRhiVertexInputBinding, 2> inputBindings;
156 inputBindings.append(QRhiVertexInputBinding(geometry->sizeOfVertex()));
158 inputBindings.append(QRhiVertexInputBinding(
sizeof(
float)));
161 inputLayout.setBindings(inputBindings.cbegin(), inputBindings.cend());
162 inputLayout.setAttributes(inputAttributes.cbegin(), inputAttributes.cend());
169 switch (geometry->indexType()) {
170 case QSGGeometry::UnsignedShortType:
171 return QRhiCommandBuffer::IndexUInt16;
173 case QSGGeometry::UnsignedIntType:
174 return QRhiCommandBuffer::IndexUInt32;
177 Q_UNREACHABLE_RETURN(QRhiCommandBuffer::IndexUInt16);
183 QRhiGraphicsPipeline::Topology topology = QRhiGraphicsPipeline::Triangles;
184 switch (geomDrawMode) {
185 case QSGGeometry::DrawPoints:
186 topology = QRhiGraphicsPipeline::Points;
188 case QSGGeometry::DrawLines:
189 topology = QRhiGraphicsPipeline::Lines;
191 case QSGGeometry::DrawLineStrip:
192 topology = QRhiGraphicsPipeline::LineStrip;
194 case QSGGeometry::DrawTriangles:
195 topology = QRhiGraphicsPipeline::Triangles;
197 case QSGGeometry::DrawTriangleStrip:
198 topology = QRhiGraphicsPipeline::TriangleStrip;
201 qWarning(
"Primitive topology 0x%x not supported", geomDrawMode);
209 material->setFlag(QSGMaterial::MultiView2, multiViewCount == 2);
210 material->setFlag(QSGMaterial::MultiView3, multiViewCount == 3);
211 material->setFlag(QSGMaterial::MultiView4, multiViewCount == 4);
215 const QSGGeometry *geometry,
216 QSGRendererInterface::RenderMode renderMode,
221 QSGMaterialType *type = material->type();
222 ShaderKey key = { type, renderMode, multiViewCount };
223 Shader *shader = rewrittenShaders.value(key,
nullptr);
228 QSGMaterialShader *s =
static_cast<QSGMaterialShader *>(material->createShader(renderMode));
229 context->initializeRhiShader(s, QShader::BatchableVertexShader);
230 shader->materialShader = s;
231 shader->inputLayout = calculateVertexInputLayout(s, geometry,
true);
232 QSGMaterialShaderPrivate *sD = QSGMaterialShaderPrivate::get(s);
234 { QRhiShaderStage::Vertex, sD->shader(QShader::VertexStage), QShader::BatchableVertexShader },
235 { QRhiShaderStage::Fragment, sD->shader(QShader::FragmentStage) }
238 shader->lastOpacity = 0;
240 rewrittenShaders[key] = shader;
244ShaderManager::Shader *
ShaderManager::prepareMaterialNoRewrite(QSGMaterial *material,
245 const QSGGeometry *geometry,
246 QSGRendererInterface::RenderMode renderMode,
251 QSGMaterialType *type = material->type();
252 ShaderKey key = { type, renderMode, multiViewCount };
253 Shader *shader = stockShaders.value(key,
nullptr);
258 QSGMaterialShader *s =
static_cast<QSGMaterialShader *>(material->createShader(renderMode));
259 context->initializeRhiShader(s, QShader::StandardShader);
260 shader->materialShader = s;
261 shader->inputLayout = calculateVertexInputLayout(s, geometry,
false);
262 QSGMaterialShaderPrivate *sD = QSGMaterialShaderPrivate::get(s);
264 { QRhiShaderStage::Vertex, sD->shader(QShader::VertexStage) },
265 { QRhiShaderStage::Fragment, sD->shader(QShader::FragmentStage) }
268 shader->lastOpacity = 0;
270 stockShaders[key] = shader;
277 qDeleteAll(stockShaders);
278 stockShaders.clear();
279 qDeleteAll(rewrittenShaders);
280 rewrittenShaders.clear();
282 qDeleteAll(pipelineCache);
283 pipelineCache.clear();
291 for (ShaderManager::Shader *sms : std::as_const(stockShaders)) {
292 QSGMaterialShader *s = sms->materialShader;
294 QSGMaterialShaderPrivate *sd = QSGMaterialShaderPrivate::get(s);
295 sd->clearCachedRendererData();
298 for (ShaderManager::Shader *sms : std::as_const(rewrittenShaders)) {
299 QSGMaterialShader *s = sms->materialShader;
301 QSGMaterialShaderPrivate *sd = QSGMaterialShaderPrivate::get(s);
302 sd->clearCachedRendererData();
309 static int extraIndent = 0;
312 QByteArray ind(indent + extraIndent + 10,
' ');
315 qDebug(
"%s - no info", ind.constData());
318 for (QSet<Node *>::const_iterator it = i->subRoots.constBegin();
319 it != i->subRoots.constEnd(); ++it) {
320 qDebug() << ind.constData() <<
"-" << *it;
321 qsg_dumpShadowRoots((*it)->rootInfo(), indent);
330#ifndef QT_NO_DEBUG_OUTPUT
331 static int indent = 0;
334 QByteArray ind(indent,
' ');
336 if (n->type() == QSGNode::ClipNodeType || n->isBatchRoot) {
337 qDebug() << ind.constData() <<
"[X]" << n->sgNode << Qt::hex << uint(n->sgNode->flags());
341 d << ind.constData() <<
"[ ]" << n->sgNode << Qt::hex << uint(n->sgNode->flags());
342 if (n->type() == QSGNode::GeometryNodeType)
343 d <<
"order" << Qt::dec << n->element()->order;
361 m_combined_matrix_stack.add(&m_identityMatrix);
362 m_rootMatrices.add(m_identityMatrix);
367 m_current_clip =
nullptr;
370 m_transformChange = 0;
373 Node *sn = renderer->m_nodes.value(n, 0);
376 if (Q_UNLIKELY(debug_roots()))
379 if (Q_UNLIKELY(debug_build())) {
380 qDebug(
"Updater::updateStates()");
381 if (sn->dirtyState & (QSGNode::DirtyNodeAdded << 16))
382 qDebug(
" - nodes have been added");
383 if (sn->dirtyState & (QSGNode::DirtyMatrix << 16))
384 qDebug(
" - transforms have changed");
385 if (sn->dirtyState & (QSGNode::DirtyOpacity << 16))
386 qDebug(
" - opacity has changed");
387 if (uint(sn->dirtyState) & uint(QSGNode::DirtyForceUpdate << 16))
388 qDebug(
" - forceupdate");
392 renderer->m_visualizer->visualizeChangesPrepare(sn);
399 if (m_added == 0 && n->dirtyState == 0 && m_force_update == 0 && m_transformChange == 0 && m_opacityChange == 0)
403 if (n->dirtyState & QSGNode::DirtyNodeAdded)
406 int force = m_force_update;
407 if (n->dirtyState & QSGNode::DirtyForceUpdate)
411 case QSGNode::OpacityNodeType:
414 case QSGNode::TransformNodeType:
417 case QSGNode::GeometryNodeType:
420 case QSGNode::ClipNodeType:
423 case QSGNode::RenderNodeType:
425 n->renderNodeElement()->root = m_roots.last();
433 m_force_update = force;
441 QSGClipNode *cn =
static_cast<QSGClipNode *>(n->sgNode);
443 if (m_roots.last() && m_added > 0)
444 renderer->registerBatchRoot(n, m_roots.last());
446 cn->setRendererClipList(m_current_clip);
449 m_rootMatrices.add(m_rootMatrices.last() * *m_combined_matrix_stack.last());
450 extra->matrix = m_rootMatrices.last();
451 cn->setRendererMatrix(&extra->matrix);
452 m_combined_matrix_stack << &m_identityMatrix;
456 m_current_clip = cn->clipList();
457 m_rootMatrices.pop_back();
458 m_combined_matrix_stack.pop_back();
464 QSGOpacityNode *on =
static_cast<QSGOpacityNode *>(n->sgNode);
466 qreal combined = m_opacity_stack.last() * on->opacity();
467 on->setCombinedOpacity(combined);
468 m_opacity_stack.add(combined);
470 if (m_added == 0 && n->dirtyState & QSGNode::DirtyOpacity) {
471 bool was = n->isOpaque;
474 renderer->m_rebuild = Renderer::FullRebuild;
486 m_opacity_stack.pop_back();
491 bool popMatrixStack =
false;
492 bool popRootStack =
false;
493 bool dirty = n->dirtyState & QSGNode::DirtyMatrix;
495 QSGTransformNode *tn =
static_cast<QSGTransformNode *>(n->sgNode);
497 if (n->isBatchRoot) {
498 if (m_added > 0 && m_roots.last())
499 renderer->registerBatchRoot(n, m_roots.last());
500 tn->setCombinedMatrix(m_rootMatrices.last() * *m_combined_matrix_stack.last() * tn->matrix());
505 if (!n->becameBatchRoot && m_added == 0 && m_force_update == 0 && m_opacityChange == 0 && dirty && (n->dirtyState & ~QSGNode::DirtyMatrix) == 0) {
507 for (QSet<Node *>::const_iterator it = info->subRoots.constBegin();
508 it != info->subRoots.constEnd(); ++it) {
514 n->becameBatchRoot =
false;
516 m_combined_matrix_stack.add(&m_identityMatrix);
518 m_rootMatrices.add(tn->combinedMatrix());
520 popMatrixStack =
true;
522 }
else if (!tn->matrix().isIdentity()) {
523 tn->setCombinedMatrix(*m_combined_matrix_stack.last() * tn->matrix());
524 m_combined_matrix_stack.add(&tn->combinedMatrix());
525 popMatrixStack =
true;
527 tn->setCombinedMatrix(*m_combined_matrix_stack.last());
538 m_combined_matrix_stack.pop_back();
541 m_rootMatrices.pop_back();
547 QSGGeometryNode *gn =
static_cast<QSGGeometryNode *>(n->sgNode);
549 gn->setRendererMatrix(m_combined_matrix_stack.last());
550 gn->setRendererClipList(m_current_clip);
551 gn->setInheritedOpacity(m_opacity_stack.last());
555 e->root = m_roots.last();
556 e->translateOnlyToRoot = isTranslate(*gn->matrix());
560 while (info !=
nullptr) {
563 renderer->m_rebuild |= Renderer::BuildRenderLists;
565 renderer->m_rebuild |= Renderer::BuildRenderListsForTaggedRoots;
566 renderer->m_taggedRoots << e
->root;
574 renderer->m_rebuild |= Renderer::FullRebuild;
577 if (m_transformChange) {
579 e->translateOnlyToRoot = isTranslate(*gn->matrix());
581 if (m_opacityChange) {
584 renderer->invalidateBatchAndOverlappingRenderOrders(e
->batch);
598 if (n->type() == QSGNode::TransformNodeType)
599 m =
static_cast<QSGTransformNode *>(n->sgNode)->matrix() * m;
605 if (node->type() == QSGNode::ClipNodeType) {
608 Q_ASSERT(node->type() == QSGNode::TransformNodeType);
609 static_cast<QSGTransformNode *>(node->sgNode)->setCombinedMatrix(m);
612 for (QSet<Node *>::const_iterator it = info->subRoots.constBegin();
613 it != info->subRoots.constEnd(); ++it) {
621 for (
int a=0; a<g->attributeCount(); ++a) {
622 const QSGGeometry::Attribute &attr = g->attributes()[a];
623 if (attr.isVertexCoordinate && attr.tupleSize == 2 && attr.type == QSGGeometry::FloatType) {
626 vaOffset += attr.tupleSize * size_of_type(attr.type);
634 const float *m = matrix.constData();
635 if (isScale(matrix)) {
655 set(FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX);
665 Q_ASSERT(!boundsComputed);
666 boundsComputed =
true;
668 QSGGeometry *g = node->geometry();
669 int offset = qsg_positionAttribute(g);
672 bounds.set(-FLT_MAX, -FLT_MAX, FLT_MAX, FLT_MAX);
676 bounds.set(FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX);
677 char *vd = (
char *) g->vertexData() + offset;
678 for (
int i=0; i<g->vertexCount(); ++i) {
680 vd += g->sizeOfVertex();
682 bounds.map(*node->matrix());
684 if (!qt_is_finite(bounds.tl.x) || bounds.tl.x == FLT_MAX)
685 bounds.tl.x = -FLT_MAX;
686 if (!qt_is_finite(bounds.tl.y) || bounds.tl.y == FLT_MAX)
687 bounds.tl.y = -FLT_MAX;
688 if (!qt_is_finite(bounds.br.x) || bounds.br.x == -FLT_MAX)
689 bounds.br.x = FLT_MAX;
690 if (!qt_is_finite(bounds.br.y) || bounds.br.y == -FLT_MAX)
691 bounds.br.y = FLT_MAX;
696 boundsOutsideFloatRange = bounds.isOutsideFloatRange();
703 while (n && (n == e || n->removed))
711 QSGMaterial *m = e->node->activeMaterial();
712 QSGMaterial *nm = n->node->activeMaterial();
713 return (nm->type() == m->type() && nm->viewCount() == m->viewCount() && nm->compare(m) == 0)
719
720
721
722
726 Q_ASSERT_X(e,
"Batch::geometryWasChanged",
"Batch is expected to 'valid' at this time");
728 while (e && (e->node == gn || e->removed))
730 if (!e || e->node->geometry()->attributes() == gn->geometry()->attributes()) {
764
765
766
785 only &= e->translateOnlyToRoot;
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
811 if (e->boundsOutsideFloatRange)
813 if (!is2DSafe(*e->node->matrix()))
834 for (
int i=0; i<batches.size(); ++i) {
835 sum += qsg_countNodesInBatch(batches.at(i));
862#if defined(QSGBATCHRENDERER_INVALIDATE_WEDGED_NODES)
901 qDebug(
"Batch thresholds: nodes: %d vertices: %d srb pool: %d buffer pool: %d",
920 qsg_wipeBuffer(&batch->vbo);
921 qsg_wipeBuffer(&batch->ibo);
923 batch->stencilClipState.reset();
1349#ifndef QT_NO_DEBUG_OUTPUT
1354 debug <<
"Geometry";
1356 debug <<
"Material";
1366 debug <<
"SubtreeBlocked";
1368 debug <<
"ForceUpdate";
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1574 for (
int i=0; i<renderList.size(); ++i) {
1575 Element *e = renderList.at(i);
1576 if (e && !e->removed) {
1585 for (
int i=0; i<orphans.size(); ++i) {
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1693#if defined(QSGBATCHRENDERER_INVALIDATE_WEDGED_NODES)
1722
1723
1756 for (
int j =
i - 1;
j >= 0; --
j) {
1795#if defined(QSGBATCHRENDERER_INVALIDATE_WEDGED_NODES)
1809
1810
1811
1812
1813
1814
1815
1816
1817
1871#if !defined(QSGBATCHRENDERER_INVALIDATE_WEDGED_NODES)
1905
1906
1907
1908
1925 case QSGGeometry::DrawTriangleStrip:
1932 case QSGGeometry::DrawLines:
1934 return iCount - (iCount % 2);
1935 case QSGGeometry::DrawTriangles:
1937 return iCount - (iCount % 3);
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
2066 if (node->type() == QSGNode::TransformNodeType)
2067 return static_cast<QSGTransformNode *>(node->sgNode)->combinedMatrix();
2068 Q_ASSERT(node->type() == QSGNode::ClipNodeType);
2069 QSGClipNode *c =
static_cast<QSGClipNode *>(node->sgNode);
2070 return *c->matrix();
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2236 Q_ASSERT_X(
false,
"uploadBatch (unmerged)",
"uint index with ushort effective index - cannot happen");
2244#ifndef QT_NO_DEBUG_OUTPUT
2250 dump <<
" --- " <<
i <<
": ";
2260 dump << *(
const float *)(
vd +
offset +
t *
sizeof(
float)) <<
" ";
2264 dump << *(
const unsigned char *)(
vd +
offset +
t *
sizeof(
unsigned char)) <<
" ";
2362 qWarning(
"Failed to build stencil clip pipeline");
2481 qWarning(
"Failed to build stencil clip vertex buffer");
2499 qWarning(
"Failed to build stencil clip index buffer");
2517 qWarning(
"Failed to build stencil clip uniform buffer");
2530 qWarning(
"Failed to build stencil clip srb");
2554 qWarning(
"updateClipState: Clip list entries have different primitive topologies, this is not currently supported.");
2556 qWarning(
"updateClipState: Clip list entries have different vertex input layouts, this is must not happen.");
2638 }
else if (
i == 1) {
2667 return f == QRhiGraphicsPipeline::ConstantColor
2668 || f == QRhiGraphicsPipeline::OneMinusConstantColor
2669 || f == QRhiGraphicsPipeline::ConstantAlpha
2670 || f == QRhiGraphicsPipeline::OneMinusConstantAlpha;
2781 qWarning(
"Failed to build graphics pipeline state");
2794static QRhiSampler *
newSampler(QRhi *rhi,
const QSGSamplerDescription &desc)
2796 QRhiSampler::Filter magFilter;
2797 QRhiSampler::Filter minFilter;
2798 QRhiSampler::Filter mipmapMode;
2799 QRhiSampler::AddressMode u;
2800 QRhiSampler::AddressMode v;
2802 switch (desc.filtering) {
2803 case QSGTexture::None:
2805 case QSGTexture::Nearest:
2806 magFilter = minFilter = QRhiSampler::Nearest;
2808 case QSGTexture::Linear:
2809 magFilter = minFilter = QRhiSampler::Linear;
2813 magFilter = minFilter = QRhiSampler::Nearest;
2817 switch (desc.mipmapFiltering) {
2818 case QSGTexture::None:
2819 mipmapMode = QRhiSampler::None;
2821 case QSGTexture::Nearest:
2822 mipmapMode = QRhiSampler::Nearest;
2824 case QSGTexture::Linear:
2825 mipmapMode = QRhiSampler::Linear;
2829 mipmapMode = QRhiSampler::None;
2833 switch (desc.horizontalWrap) {
2834 case QSGTexture::Repeat:
2835 u = QRhiSampler::Repeat;
2837 case QSGTexture::ClampToEdge:
2838 u = QRhiSampler::ClampToEdge;
2840 case QSGTexture::MirroredRepeat:
2841 u = QRhiSampler::Mirror;
2845 u = QRhiSampler::ClampToEdge;
2849 switch (desc.verticalWrap) {
2850 case QSGTexture::Repeat:
2851 v = QRhiSampler::Repeat;
2853 case QSGTexture::ClampToEdge:
2854 v = QRhiSampler::ClampToEdge;
2856 case QSGTexture::MirroredRepeat:
2857 v = QRhiSampler::Mirror;
2861 v = QRhiSampler::ClampToEdge;
2865 return rhi->newSampler(magFilter, minFilter, mipmapMode, u, v);
2889 Q_ASSERT(
int(QSGMaterialShader::GraphicsPipelineState::OneMinusSrc1Alpha) ==
int(QRhiGraphicsPipeline::OneMinusSrc1Alpha));
2890 Q_ASSERT(
int(QSGMaterialShader::GraphicsPipelineState::BlendOp::Max) ==
int(QRhiGraphicsPipeline::Max));
2891 Q_ASSERT(
int(QSGMaterialShader::GraphicsPipelineState::A) ==
int(QRhiGraphicsPipeline::A));
2892 Q_ASSERT(
int(QSGMaterialShader::GraphicsPipelineState::CullBack) ==
int(QRhiGraphicsPipeline::Back));
2893 Q_ASSERT(
int(QSGMaterialShader::GraphicsPipelineState::Line) ==
int(QRhiGraphicsPipeline::Line));
2894 dst->srcColor = QSGMaterialShader::GraphicsPipelineState::BlendFactor(src->srcColor);
2895 dst->dstColor = QSGMaterialShader::GraphicsPipelineState::BlendFactor(src->dstColor);
2903 dst->separateBlendFactors =
false;
2905 dst->srcAlpha = QSGMaterialShader::GraphicsPipelineState::BlendFactor(src->srcAlpha);
2906 dst->dstAlpha = QSGMaterialShader::GraphicsPipelineState::BlendFactor(src->dstAlpha);
2908 dst->opColor = QSGMaterialShader::GraphicsPipelineState::BlendOp(src->opColor);
2909 dst->opAlpha = QSGMaterialShader::GraphicsPipelineState::BlendOp(src->opAlpha);
2911 dst->colorWrite = QSGMaterialShader::GraphicsPipelineState::ColorMask(
int(src->colorWrite));
2913 dst->cullMode = QSGMaterialShader::GraphicsPipelineState::CullMode(src->cullMode);
2914 dst->polygonMode = QSGMaterialShader::GraphicsPipelineState::PolygonMode(src->polygonMode);
2918 QSGMaterialShader::GraphicsPipelineState *src)
2921 dst->srcColor = QRhiGraphicsPipeline::BlendFactor(src->srcColor);
2922 dst->dstColor = QRhiGraphicsPipeline::BlendFactor(src->dstColor);
2923 if (src->separateBlendFactors) {
2924 dst->srcAlpha = QRhiGraphicsPipeline::BlendFactor(src->srcAlpha);
2925 dst->dstAlpha = QRhiGraphicsPipeline::BlendFactor(src->dstAlpha);
2927 dst->srcAlpha = dst->srcColor;
2928 dst->dstAlpha = dst->dstColor;
2930 dst->opColor = QRhiGraphicsPipeline::BlendOp(src->opColor);
2931 dst->opAlpha = QRhiGraphicsPipeline::BlendOp(src->opAlpha);
2932 dst->colorWrite = QRhiGraphicsPipeline::ColorMask(
int(src->colorWrite));
2933 dst->cullMode = QRhiGraphicsPipeline::CullMode(src->cullMode);
2934 dst->polygonMode = QRhiGraphicsPipeline::PolygonMode(src->polygonMode);
2986 qWarning(
"No QSGTexture provided from updateSampledImage(). This is wrong.");
3008 qWarning(
"QSGTexture anisotropy levels are not currently supported");
3020 qWarning(
"Failed to build sampler");
3135 Q_ASSERT_X(
false,
"updateMaterialDynamicData",
"No srb action set, this cannot happen");
3175#ifndef QT_NO_DEBUG_OUTPUT
3276 qDebug(
"QSGMaterial::updateState triggered an error (merged), batch will be skipped:");
3283 qFatal(
"Aborting: scene graph is invalid...");
3325 qWarning(
"Line widths other than 1 are not supported by the graphics API");
3333 qWarning(
"Point size is not controllable by QSGGeometry. "
3334 "Set gl_PointSize from the vertex shader instead.");
3498 qDebug(
"QSGMaterial::updateState() triggered an error (unmerged), batch will be skipped:");
3501 qFatal(
"Aborting: scene graph is invalid...");
3710 qWarning(
"prepareRenderPass() called with an already prepared render pass context");
3734 type +=
" renderlists";
3741 qDebug() <<
"Renderer::render()" <<
this <<
type;
3756 qDebug(
"Opaque render lists %s:", (
complete ?
"(complete)" :
"(partial)"));
3761 qDebug(
"Alpha render list %s:",
complete ?
"(complete)" :
"(partial)");
3786 qDebug(
"Opaque Batches:");
3794 qDebug(
"Alpha Batches:");
3937#if defined(QSGBATCHRENDERER_INVALIDATE_WEDGED_NODES)
3979 qWarning(
"recordRenderPass() called without a prepared render pass context");
4036 qDebug(
" -> times: build: %d, prepare(opaque/alpha): %d/%d, sorting: %d, upload(opaque/alpha): %d/%d, record rendering: %d",
4194 else if (
mode ==
"clip")
4196 else if (
mode ==
"overdraw")
4198 else if (
mode ==
"batches")
4200 else if (
mode ==
"changes")
4213 && a.depthFunc == b.depthFunc
4215 && a.srcColor == b.srcColor
4216 && a.dstColor == b.dstColor
4217 && a.srcAlpha == b.srcAlpha
4218 && a.dstAlpha == b.dstAlpha
4219 && a.opColor == b.opColor
4220 && a.opAlpha == b.opAlpha
4221 && a.colorWrite == b.colorWrite
4222 && a.cullMode == b.cullMode
4226 && a.drawMode == b.drawMode
4228 && a.polygonMode == b.polygonMode
4255 return a.state == b.state
4256 && a
.sms->materialShader == b
.sms->materialShader
4257 && a.renderTargetDescription == b.renderTargetDescription
4258 && a.srbLayoutDescription == b.srbLayoutDescription;
4268 return qHash(k.state, seed)
4269 ^ qHash(k.sms->materialShader)
4270 ^ k.extra.renderTargetDescriptionHash
4271 ^ k.extra.srbLayoutDescriptionHash;
4276 return a.type == b.type
4277 && a.renderMode == b.renderMode
4288 return qHash(k.type, seed) ^
int(k.renderMode) ^ k.multiViewCount;
4301#define QSGNODE_DIRTY_PARENT (QSGNode::DirtyNodeAdded
4302 | QSGNode::DirtyOpacity
4303 | QSGNode::DirtyMatrix
4304 | QSGNode::DirtyNodeRemoved)
4309 uint selfDirty = n->dirtyState | parentChanges;
4310 if (n->type() == QSGNode::GeometryNodeType && selfDirty != 0)
4311 m_visualizeChangeSet.insert(n, selfDirty);
4313 visualizeChangesPrepare(child, childDirty);
4321#include "moc_qsgbatchrenderer_p.cpp"
void clearCachedRendererData()
void updateRootTransforms(Node *n, Node *root, const QMatrix4x4 &combined)
void visitClipNode(Node *n)
void updateStates(QSGNode *n) override
void visitOpacityNode(Node *n)
void updateRootTransforms(Node *n)
void visitTransformNode(Node *n)
void visitGeometryNode(Node *n)
Visualizer(Renderer *renderer)
VisualizeMode m_visualizeMode
const int ZORDER_BUFFER_BINDING
static void qsg_wipeBuffer(Buffer *buffer)
static void rendererToMaterialGraphicsState(QSGMaterialShader::GraphicsPipelineState *dst, GraphicsState *src)
size_t qHash(const GraphicsState &s, size_t seed) noexcept
static QRhiVertexInputLayout calculateVertexInputLayout(const QSGMaterialShader *s, const QSGGeometry *geometry, bool batchable)
static void qsg_addBackOrphanedElements(QDataBuffer< Element * > &orphans, QDataBuffer< Element * > &renderList)
bool operator!=(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKey &b) noexcept
const float VIEWPORT_MIN_DEPTH
QSGMaterial::Flag QSGMaterial_FullMatrix
bool qsg_sort_batch_decreasing_order(Batch *a, Batch *b)
bool operator==(const ShaderKey &a, const ShaderKey &b) noexcept
bool operator==(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKey &b) noexcept
bool operator!=(const ShaderKey &a, const ShaderKey &b) noexcept
static void qsg_wipeBatch(Batch *batch)
static QRhiSampler * newSampler(QRhi *rhi, const QSGSamplerDescription &desc)
QRhiVertexInputAttribute::Format qsg_vertexInputFormat(const QSGGeometry::Attribute &a)
QMatrix4x4 qsg_matrixForRoot(Node *node)
bool qsg_sort_batch_increasing_order(Batch *a, Batch *b)
static void qsg_addOrphanedElements(QDataBuffer< Element * > &orphans, const QDataBuffer< Element * > &renderList)
void qsg_setMultiViewFlagsOnMaterial(QSGMaterial *material, int multiViewCount)
const float VIEWPORT_MAX_DEPTH
int qsg_positionAttribute(QSGGeometry *g)
static int size_of_type(int type)
static bool isTranslate(const QMatrix4x4 &m)
static int qsg_countNodesInBatches(const QDataBuffer< Batch * > &batches)
static float calculateElementZOrder(const Element *e, qreal zRange)
static int qsg_fixIndexCount(int iCount, int drawMode)
bool qsg_sort_element_increasing_order(Element *a, Element *b)
static void materialToRendererGraphicsState(GraphicsState *dst, QSGMaterialShader::GraphicsPipelineState *src)
static bool needsBlendConstant(QRhiGraphicsPipeline::BlendFactor f)
const int VERTEX_BUFFER_BINDING
const uint DYNAMIC_VERTEX_INDEX_BUFFER_THRESHOLD
static int qsg_countNodesInBatch(const Batch *batch)
bool operator==(const GraphicsState &a, const GraphicsState &b) noexcept
QRhiCommandBuffer::IndexFormat qsg_indexFormat(const QSGGeometry *geometry)
bool operator!=(const GraphicsState &a, const GraphicsState &b) noexcept
bool qsg_sort_element_decreasing_order(Element *a, Element *b)
size_t qHash(const ShaderKey &k, size_t seed) noexcept
void qsg_dumpShadowRoots(BatchRootInfo *i, int indent)
void qsg_dumpShadowRoots(Node *n)
static bool isScale(const QMatrix4x4 &m)
static bool is2DSafe(const QMatrix4x4 &m)
QRhiGraphicsPipeline::Topology qsg_topology(int geomDrawMode)
size_t qHash(const GraphicsPipelineStateKey &k, size_t seed) noexcept
Int aligned(Int v, Int byteAlign)
const quint32 DEFAULT_BUFFER_POOL_SIZE_LIMIT
bool qsg_sort_batch_is_valid(Batch *a, Batch *b)
Q_CORE_EXPORT QDebug operator<<(QDebug debug, QDir::Filters filters)
#define DECLARE_DEBUG_VAR(variable)
QDebug Q_QUICK_EXPORT operator<<(QDebug debug, const QQuickWindow *item)
#define QSGNODE_DIRTY_PARENT
int qt_sg_envInt(const char *name, int defaultValue)
QT_BEGIN_NAMESPACE Q_QUICK_EXPORT bool qsg_test_and_clear_material_failure()
#define SHADOWNODE_TRAVERSE(NODE)
#define QSGNODE_TRAVERSE(NODE)
bool geometryWasChanged(QSGGeometryNode *gn)
void cleanupRemovedElements()
bool isTranslateOnlyToRoot() const
bool isSafeToBatch() const
BatchCompatibility isMaterialCompatible(Element *e) const
const ShaderManagerShader * sms
BatchRootInfo * rootInfo() const
ClipBatchRootInfo * clipInfo() const
Element * element() const
void operator|=(const Pt &pt)
void map(const QMatrix4x4 &m)
bool stencilEnabled() const override
QRect scissorRect() const override
const QMatrix4x4 * projectionMatrix() const override
const QRegion * clipRegion() const override
bool scissorEnabled() const override
int stencilValue() const override
const QMatrix4x4 * m_projectionMatrix