11#include <QtCore/QElapsedTimer>
12#include <QtCore/QtNumeric>
14#include <QtGui/QGuiApplication>
16#include <private/qnumeric_p.h>
21#include <QtQuick/private/qsgnode_p.h>
32#define DECLARE_DEBUG_VAR(variable)
33 static bool debug_ ## variable()
34 { static bool value = qgetenv("QSG_RENDERER_DEBUG").contains(QT_STRINGIFY(variable)); return value; }
45#undef DECLARE_DEBUG_VAR
47#define QSGNODE_TRAVERSE(NODE) for (QSGNode *child = NODE->firstChild(); child; child = child->nextSibling())
48#define SHADOWNODE_TRAVERSE(NODE) for (Node *child = NODE->firstChild(); child; child = child->sibling())
52 static int sizes[] = {
54 sizeof(
unsigned char),
56 sizeof(
unsigned short),
65 Q_ASSERT(type >= QSGGeometry::ByteType && type <= QSGGeometry::DoubleType);
66 return sizes[type - QSGGeometry::ByteType];
76static bool isTranslate(
const QMatrix4x4 &m) {
return m.flags() <= QMatrix4x4::Translation; }
77static bool isScale(
const QMatrix4x4 &m) {
return m.flags() <= QMatrix4x4::Scale; }
78static bool is2DSafe(
const QMatrix4x4 &m) {
return m.flags() < QMatrix4x4::Rotation; }
97 return (v + byteAlign - 1) & ~(byteAlign - 1);
103 case QSGGeometry::FloatType:
104 if (a.tupleSize == 4)
105 return QRhiVertexInputAttribute::Float4;
106 if (a.tupleSize == 3)
107 return QRhiVertexInputAttribute::Float3;
108 if (a.tupleSize == 2)
109 return QRhiVertexInputAttribute::Float2;
110 if (a.tupleSize == 1)
111 return QRhiVertexInputAttribute::Float;
113 case QSGGeometry::UnsignedByteType:
114 if (a.tupleSize == 4)
115 return QRhiVertexInputAttribute::UNormByte4;
116 if (a.tupleSize == 2)
117 return QRhiVertexInputAttribute::UNormByte2;
118 if (a.tupleSize == 1)
119 return QRhiVertexInputAttribute::UNormByte;
124 qWarning(
"Unsupported attribute type 0x%x with %d components", a.type, a.tupleSize);
125 Q_UNREACHABLE_RETURN(QRhiVertexInputAttribute::Float);
131 const QSGMaterialShaderPrivate *sd = QSGMaterialShaderPrivate::get(s);
132 if (!sd->vertexShader) {
133 qWarning(
"No vertex shader in QSGMaterialShader %p", s);
134 return QRhiVertexInputLayout();
137 const int attrCount = geometry->attributeCount();
138 QVarLengthArray<QRhiVertexInputAttribute, 8> inputAttributes;
139 inputAttributes.reserve(attrCount + 1);
141 for (
int i = 0; i < attrCount; ++i) {
142 const QSGGeometry::Attribute &a = geometry->attributes()[i];
143 if (!sd->vertexShader->vertexInputLocations.contains(a.position)) {
144 qWarning(
"Vertex input %d is present in material but not in shader. This is wrong.",
147 inputAttributes.append(QRhiVertexInputAttribute(
VERTEX_BUFFER_BINDING, a.position, qsg_vertexInputFormat(a), offset));
148 offset += a.tupleSize * size_of_type(a.type);
151 inputAttributes.append(QRhiVertexInputAttribute(
ZORDER_BUFFER_BINDING, sd->vertexShader->qt_order_attrib_location,
152 QRhiVertexInputAttribute::Float, 0));
156 QVarLengthArray<QRhiVertexInputBinding, 2> inputBindings;
157 inputBindings.append(QRhiVertexInputBinding(geometry->sizeOfVertex()));
159 inputBindings.append(QRhiVertexInputBinding(
sizeof(
float)));
162 inputLayout.setBindings(inputBindings.cbegin(), inputBindings.cend());
163 inputLayout.setAttributes(inputAttributes.cbegin(), inputAttributes.cend());
170 switch (geometry->indexType()) {
171 case QSGGeometry::UnsignedShortType:
172 return QRhiCommandBuffer::IndexUInt16;
174 case QSGGeometry::UnsignedIntType:
175 return QRhiCommandBuffer::IndexUInt32;
178 Q_UNREACHABLE_RETURN(QRhiCommandBuffer::IndexUInt16);
184 QRhiGraphicsPipeline::Topology topology = QRhiGraphicsPipeline::Triangles;
185 switch (geomDrawMode) {
186 case QSGGeometry::DrawPoints:
187 topology = QRhiGraphicsPipeline::Points;
189 case QSGGeometry::DrawLines:
190 topology = QRhiGraphicsPipeline::Lines;
192 case QSGGeometry::DrawLineStrip:
193 topology = QRhiGraphicsPipeline::LineStrip;
195 case QSGGeometry::DrawTriangles:
196 topology = QRhiGraphicsPipeline::Triangles;
198 case QSGGeometry::DrawTriangleStrip:
199 topology = QRhiGraphicsPipeline::TriangleStrip;
201 case QSGGeometry::DrawTriangleFan:
203 static bool triangleFanSupported =
false;
204 static bool triangleFanSupportChecked =
false;
205 if (!triangleFanSupportChecked) {
206 triangleFanSupportChecked =
true;
207 triangleFanSupported = rhi->isFeatureSupported(QRhi::TriangleFanTopology);
209 if (triangleFanSupported) {
210 topology = QRhiGraphicsPipeline::TriangleFan;
216 qWarning(
"Primitive topology 0x%x not supported", geomDrawMode);
224 material->setFlag(QSGMaterial::MultiView2, multiViewCount == 2);
225 material->setFlag(QSGMaterial::MultiView3, multiViewCount == 3);
226 material->setFlag(QSGMaterial::MultiView4, multiViewCount == 4);
230 const QSGGeometry *geometry,
231 QSGRendererInterface::RenderMode renderMode,
236 QSGMaterialType *type = material->type();
237 ShaderKey key = { type, renderMode, multiViewCount };
238 Shader *shader = rewrittenShaders.value(key,
nullptr);
243 QSGMaterialShader *s =
static_cast<QSGMaterialShader *>(material->createShader(renderMode));
244 context->initializeRhiShader(s, QShader::BatchableVertexShader);
245 shader->materialShader = s;
246 shader->inputLayout = calculateVertexInputLayout(s, geometry,
true);
247 QSGMaterialShaderPrivate *sD = QSGMaterialShaderPrivate::get(s);
249 { QRhiShaderStage::Vertex, sD->shader(QShader::VertexStage), QShader::BatchableVertexShader },
250 { QRhiShaderStage::Fragment, sD->shader(QShader::FragmentStage) }
253 shader->lastOpacity = 0;
255 rewrittenShaders[key] = shader;
259ShaderManager::Shader *
ShaderManager::prepareMaterialNoRewrite(QSGMaterial *material,
260 const QSGGeometry *geometry,
261 QSGRendererInterface::RenderMode renderMode,
266 QSGMaterialType *type = material->type();
267 ShaderKey key = { type, renderMode, multiViewCount };
268 Shader *shader = stockShaders.value(key,
nullptr);
273 QSGMaterialShader *s =
static_cast<QSGMaterialShader *>(material->createShader(renderMode));
274 context->initializeRhiShader(s, QShader::StandardShader);
275 shader->materialShader = s;
276 shader->inputLayout = calculateVertexInputLayout(s, geometry,
false);
277 QSGMaterialShaderPrivate *sD = QSGMaterialShaderPrivate::get(s);
279 { QRhiShaderStage::Vertex, sD->shader(QShader::VertexStage) },
280 { QRhiShaderStage::Fragment, sD->shader(QShader::FragmentStage) }
283 shader->lastOpacity = 0;
285 stockShaders[key] = shader;
292 qDeleteAll(stockShaders);
293 stockShaders.clear();
294 qDeleteAll(rewrittenShaders);
295 rewrittenShaders.clear();
297 qDeleteAll(pipelineCache);
298 pipelineCache.clear();
306 for (ShaderManager::Shader *sms : std::as_const(stockShaders)) {
307 QSGMaterialShader *s = sms->materialShader;
309 QSGMaterialShaderPrivate *sd = QSGMaterialShaderPrivate::get(s);
310 sd->clearCachedRendererData();
313 for (ShaderManager::Shader *sms : std::as_const(rewrittenShaders)) {
314 QSGMaterialShader *s = sms->materialShader;
316 QSGMaterialShaderPrivate *sd = QSGMaterialShaderPrivate::get(s);
317 sd->clearCachedRendererData();
324 static int extraIndent = 0;
327 QByteArray ind(indent + extraIndent + 10,
' ');
330 qDebug(
"%s - no info", ind.constData());
333 for (QSet<Node *>::const_iterator it = i->subRoots.constBegin();
334 it != i->subRoots.constEnd(); ++it) {
335 qDebug() << ind.constData() <<
"-" << *it;
336 qsg_dumpShadowRoots((*it)->rootInfo(), indent);
345#ifndef QT_NO_DEBUG_OUTPUT
346 static int indent = 0;
349 QByteArray ind(indent,
' ');
351 if (n->type() == QSGNode::ClipNodeType || n->isBatchRoot) {
352 qDebug() << ind.constData() <<
"[X]" << n->sgNode << Qt::hex << uint(n->sgNode->flags());
356 d << ind.constData() <<
"[ ]" << n->sgNode << Qt::hex << uint(n->sgNode->flags());
357 if (n->type() == QSGNode::GeometryNodeType)
358 d <<
"order" << Qt::dec << n->element()->order;
376 m_combined_matrix_stack.add(&m_identityMatrix);
377 m_rootMatrices.add(m_identityMatrix);
382 m_current_clip =
nullptr;
385 m_transformChange = 0;
388 Node *sn = renderer->m_nodes.value(n, 0);
391 if (Q_UNLIKELY(debug_roots()))
394 if (Q_UNLIKELY(debug_build())) {
395 qDebug(
"Updater::updateStates()");
396 if (sn->dirtyState & (QSGNode::DirtyNodeAdded << 16))
397 qDebug(
" - nodes have been added");
398 if (sn->dirtyState & (QSGNode::DirtyMatrix << 16))
399 qDebug(
" - transforms have changed");
400 if (sn->dirtyState & (QSGNode::DirtyOpacity << 16))
401 qDebug(
" - opacity has changed");
402 if (uint(sn->dirtyState) & uint(QSGNode::DirtyForceUpdate << 16))
403 qDebug(
" - forceupdate");
407 renderer->m_visualizer->visualizeChangesPrepare(sn);
414 if (m_added == 0 && n->dirtyState == 0 && m_force_update == 0 && m_transformChange == 0 && m_opacityChange == 0)
418 if (n->dirtyState & QSGNode::DirtyNodeAdded)
421 int force = m_force_update;
422 if (n->dirtyState & QSGNode::DirtyForceUpdate)
426 case QSGNode::OpacityNodeType:
429 case QSGNode::TransformNodeType:
432 case QSGNode::GeometryNodeType:
435 case QSGNode::ClipNodeType:
438 case QSGNode::RenderNodeType:
448 m_force_update = force;
456 QSGClipNode *cn =
static_cast<QSGClipNode *>(n->sgNode);
458 if (m_roots.last() && m_added > 0)
459 renderer->registerBatchRoot(n, m_roots.last());
461 cn->setRendererClipList(m_current_clip);
464 m_rootMatrices.add(m_rootMatrices.last() * *m_combined_matrix_stack.last());
465 extra->matrix = m_rootMatrices.last();
466 cn->setRendererMatrix(&extra->matrix);
467 m_combined_matrix_stack << &m_identityMatrix;
471 m_current_clip = cn->clipList();
472 m_rootMatrices.pop_back();
473 m_combined_matrix_stack.pop_back();
479 QSGOpacityNode *on =
static_cast<QSGOpacityNode *>(n->sgNode);
481 qreal combined = m_opacity_stack.last() * on->opacity();
482 on->setCombinedOpacity(combined);
483 m_opacity_stack.add(combined);
485 if (m_added == 0 && n->dirtyState & QSGNode::DirtyOpacity) {
486 bool was = n->isOpaque;
489 renderer->m_rebuild = Renderer::FullRebuild;
501 m_opacity_stack.pop_back();
506 bool popMatrixStack =
false;
507 bool popRootStack =
false;
508 bool dirty = n->dirtyState & QSGNode::DirtyMatrix;
510 QSGTransformNode *tn =
static_cast<QSGTransformNode *>(n->sgNode);
512 if (n->isBatchRoot) {
513 if (m_added > 0 && m_roots.last())
514 renderer->registerBatchRoot(n, m_roots.last());
515 tn->setCombinedMatrix(m_rootMatrices.last() * *m_combined_matrix_stack.last() * tn->matrix());
520 if (!n->becameBatchRoot && m_added == 0 && m_force_update == 0 && m_opacityChange == 0 && dirty && (n->dirtyState & ~QSGNode::DirtyMatrix) == 0) {
522 for (QSet<Node *>::const_iterator it = info->subRoots.constBegin();
523 it != info->subRoots.constEnd(); ++it) {
529 n->becameBatchRoot =
false;
531 m_combined_matrix_stack.add(&m_identityMatrix);
533 m_rootMatrices.add(tn->combinedMatrix());
535 popMatrixStack =
true;
537 }
else if (!tn->matrix().isIdentity()) {
538 tn->setCombinedMatrix(*m_combined_matrix_stack.last() * tn->matrix());
539 m_combined_matrix_stack.add(&tn->combinedMatrix());
540 popMatrixStack =
true;
542 tn->setCombinedMatrix(*m_combined_matrix_stack.last());
553 m_combined_matrix_stack.pop_back();
556 m_rootMatrices.pop_back();
562 QSGGeometryNode *gn =
static_cast<QSGGeometryNode *>(n->sgNode);
564 gn->setRendererMatrix(m_combined_matrix_stack.last());
565 gn->setRendererClipList(m_current_clip);
566 gn->setInheritedOpacity(m_opacity_stack.last());
571 e->translateOnlyToRoot = isTranslate(*gn->matrix());
575 while (info !=
nullptr) {
578 renderer->m_rebuild |= Renderer::BuildRenderLists;
580 renderer->m_rebuild |= Renderer::BuildRenderListsForTaggedRoots;
581 renderer->m_taggedRoots << e
->root;
589 renderer->m_rebuild |= Renderer::FullRebuild;
592 if (m_transformChange) {
594 e->translateOnlyToRoot = isTranslate(*gn->matrix());
596 if (m_opacityChange) {
599 renderer->invalidateBatchAndOverlappingRenderOrders(e
->batch);
613 if (n->type() == QSGNode::TransformNodeType)
614 m =
static_cast<QSGTransformNode *>(n->sgNode)->matrix() * m;
620 if (node->type() == QSGNode::ClipNodeType) {
621 static_cast<ClipBatchRootInfo *>(info)->matrix = m;
623 Q_ASSERT(node->type() == QSGNode::TransformNodeType);
624 static_cast<QSGTransformNode *>(node->sgNode)->setCombinedMatrix(m);
627 for (QSet<Node *>::const_iterator it = info->subRoots.constBegin();
628 it != info->subRoots.constEnd(); ++it) {
636 for (
int a=0; a<g->attributeCount(); ++a) {
637 const QSGGeometry::Attribute &attr = g->attributes()[a];
638 if (attr.isVertexCoordinate && attr.tupleSize == 2 && attr.type == QSGGeometry::FloatType) {
641 vaOffset += attr.tupleSize * size_of_type(attr.type);
649 const float *m = matrix.constData();
650 if (isScale(matrix)) {
670 set(FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX);
680 Q_ASSERT(!boundsComputed);
681 boundsComputed =
true;
683 QSGGeometry *g = node->geometry();
684 int offset = qsg_positionAttribute(g);
687 bounds.set(-FLT_MAX, -FLT_MAX, FLT_MAX, FLT_MAX);
691 bounds.set(FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX);
692 char *vd = (
char *) g->vertexData() + offset;
693 for (
int i=0; i<g->vertexCount(); ++i) {
695 vd += g->sizeOfVertex();
697 bounds.map(*node->matrix());
699 if (!qt_is_finite(bounds.tl.x) || bounds.tl.x == FLT_MAX)
701 if (!qt_is_finite(bounds.tl.y) || bounds.tl.y == FLT_MAX)
703 if (!qt_is_finite(bounds.br.x) || bounds.br.x == -FLT_MAX)
705 if (!qt_is_finite(bounds.br.y) || bounds.br.y == -FLT_MAX)
711 boundsOutsideFloatRange = bounds.isOutsideFloatRange();
718 while (n && (n == e || n->removed))
726 QSGMaterial *m = e->node->activeMaterial();
727 QSGMaterial *nm = n->node->activeMaterial();
728 return (nm->type() == m->type() && nm->viewCount() == m->viewCount() && nm->compare(m) == 0)
734
735
736
737
741 Q_ASSERT_X(e,
"Batch::geometryWasChanged",
"Batch is expected to 'valid' at this time");
743 while (e && (e->node == gn || e->removed))
745 if (!e || e->node->geometry()->attributes() == gn->geometry()->attributes()) {
779
780
781
800 only &= e->translateOnlyToRoot;
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
826 if (e->boundsOutsideFloatRange)
828 if (!is2DSafe(*e->node->matrix()))
849 for (
int i=0; i<batches.size(); ++i) {
850 sum += qsg_countNodesInBatch(batches.at(i));
877#if defined(QSGBATCHRENDERER_INVALIDATE_WEDGED_NODES)
922 qDebug(
"Batch thresholds: nodes: %d vertices: %d srb pool: %d buffer pool: %d",
941 qsg_wipeBuffer(&batch->vbo);
942 qsg_wipeBuffer(&batch->ibo);
943 batch->stencilClipState.reset();
1375#ifndef QT_NO_DEBUG_OUTPUT
1380 debug <<
"Geometry";
1382 debug <<
"Material";
1392 debug <<
"SubtreeBlocked";
1394 debug <<
"ForceUpdate";
1409#if defined(QSGBATCHRENDERER_INVALIDATE_WEDGED_NODES)
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1612 for (
int i=0; i<renderList.size(); ++i) {
1613 Element *e = renderList.at(i);
1614 if (e && !e->removed) {
1623 for (
int i=0; i<orphans.size(); ++i) {
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1731#if defined(QSGBATCHRENDERER_INVALIDATE_WEDGED_NODES)
1760
1761
1798 for (
int j =
i - 1;
j >= 0; --
j) {
1840#if defined(QSGBATCHRENDERER_INVALIDATE_WEDGED_NODES)
1854
1855
1856
1857
1858
1859
1860
1861
1862
1916#if !defined(QSGBATCHRENDERER_INVALIDATE_WEDGED_NODES)
1951
1952
1953
1954
1971 case QSGGeometry::DrawTriangleStrip:
1978 case QSGGeometry::DrawLines:
1980 return iCount - (iCount % 2);
1981 case QSGGeometry::DrawTriangles:
1983 return iCount - (iCount % 3);
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2112 if (node->type() == QSGNode::TransformNodeType)
2113 return static_cast<QSGTransformNode *>(node->sgNode)->combinedMatrix();
2114 Q_ASSERT(node->type() == QSGNode::ClipNodeType);
2115 QSGClipNode *c =
static_cast<QSGClipNode *>(node->sgNode);
2116 return *c->matrix();
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2282 Q_ASSERT_X(
false,
"uploadBatch (unmerged)",
"uint index with ushort effective index - cannot happen");
2290#ifndef QT_NO_DEBUG_OUTPUT
2296 dump <<
" --- " <<
i <<
": ";
2306 dump << *(
const float *)(
vd +
offset +
t *
sizeof(
float)) <<
" ";
2310 dump << *(
const unsigned char *)(
vd +
offset +
t *
sizeof(
unsigned char)) <<
" ";
2408 qWarning(
"Failed to build stencil clip pipeline");
2527 qWarning(
"Failed to build stencil clip vertex buffer");
2545 qWarning(
"Failed to build stencil clip index buffer");
2563 qWarning(
"Failed to build stencil clip uniform buffer");
2576 qWarning(
"Failed to build stencil clip srb");
2600 qWarning(
"updateClipState: Clip list entries have different primitive topologies, this is not currently supported.");
2602 qWarning(
"updateClipState: Clip list entries have different vertex input layouts, this is must not happen.");
2684 }
else if (
i == 1) {
2713 return f == QRhiGraphicsPipeline::ConstantColor
2714 || f == QRhiGraphicsPipeline::OneMinusConstantColor
2715 || f == QRhiGraphicsPipeline::ConstantAlpha
2716 || f == QRhiGraphicsPipeline::OneMinusConstantAlpha;
2828 qWarning(
"Failed to build graphics pipeline state");
2841static QRhiSampler *
newSampler(QRhi *rhi,
const QSGSamplerDescription &desc)
2843 QRhiSampler::Filter magFilter;
2844 QRhiSampler::Filter minFilter;
2845 QRhiSampler::Filter mipmapMode;
2846 QRhiSampler::AddressMode u;
2847 QRhiSampler::AddressMode v;
2849 switch (desc.filtering) {
2850 case QSGTexture::None:
2852 case QSGTexture::Nearest:
2853 magFilter = minFilter = QRhiSampler::Nearest;
2855 case QSGTexture::Linear:
2856 magFilter = minFilter = QRhiSampler::Linear;
2860 magFilter = minFilter = QRhiSampler::Nearest;
2864 switch (desc.mipmapFiltering) {
2865 case QSGTexture::None:
2866 mipmapMode = QRhiSampler::None;
2868 case QSGTexture::Nearest:
2869 mipmapMode = QRhiSampler::Nearest;
2871 case QSGTexture::Linear:
2872 mipmapMode = QRhiSampler::Linear;
2876 mipmapMode = QRhiSampler::None;
2880 switch (desc.horizontalWrap) {
2881 case QSGTexture::Repeat:
2882 u = QRhiSampler::Repeat;
2884 case QSGTexture::ClampToEdge:
2885 u = QRhiSampler::ClampToEdge;
2887 case QSGTexture::MirroredRepeat:
2888 u = QRhiSampler::Mirror;
2892 u = QRhiSampler::ClampToEdge;
2896 switch (desc.verticalWrap) {
2897 case QSGTexture::Repeat:
2898 v = QRhiSampler::Repeat;
2900 case QSGTexture::ClampToEdge:
2901 v = QRhiSampler::ClampToEdge;
2903 case QSGTexture::MirroredRepeat:
2904 v = QRhiSampler::Mirror;
2908 v = QRhiSampler::ClampToEdge;
2912 return rhi->newSampler(magFilter, minFilter, mipmapMode, u, v);
2936 Q_ASSERT(
int(QSGMaterialShader::GraphicsPipelineState::OneMinusSrc1Alpha) ==
int(QRhiGraphicsPipeline::OneMinusSrc1Alpha));
2937 Q_ASSERT(
int(QSGMaterialShader::GraphicsPipelineState::BlendOp::Max) ==
int(QRhiGraphicsPipeline::Max));
2938 Q_ASSERT(
int(QSGMaterialShader::GraphicsPipelineState::A) ==
int(QRhiGraphicsPipeline::A));
2939 Q_ASSERT(
int(QSGMaterialShader::GraphicsPipelineState::CullBack) ==
int(QRhiGraphicsPipeline::Back));
2940 Q_ASSERT(
int(QSGMaterialShader::GraphicsPipelineState::Line) ==
int(QRhiGraphicsPipeline::Line));
2941 dst->srcColor = QSGMaterialShader::GraphicsPipelineState::BlendFactor(src->srcColor);
2942 dst->dstColor = QSGMaterialShader::GraphicsPipelineState::BlendFactor(src->dstColor);
2950 dst->separateBlendFactors =
false;
2952 dst->srcAlpha = QSGMaterialShader::GraphicsPipelineState::BlendFactor(src->srcAlpha);
2953 dst->dstAlpha = QSGMaterialShader::GraphicsPipelineState::BlendFactor(src->dstAlpha);
2955 dst->opColor = QSGMaterialShader::GraphicsPipelineState::BlendOp(src->opColor);
2956 dst->opAlpha = QSGMaterialShader::GraphicsPipelineState::BlendOp(src->opAlpha);
2958 dst->colorWrite = QSGMaterialShader::GraphicsPipelineState::ColorMask(
int(src->colorWrite));
2960 dst->cullMode = QSGMaterialShader::GraphicsPipelineState::CullMode(src->cullMode);
2961 dst->polygonMode = QSGMaterialShader::GraphicsPipelineState::PolygonMode(src->polygonMode);
2965 QSGMaterialShader::GraphicsPipelineState *src)
2968 dst->srcColor = QRhiGraphicsPipeline::BlendFactor(src->srcColor);
2969 dst->dstColor = QRhiGraphicsPipeline::BlendFactor(src->dstColor);
2970 if (src->separateBlendFactors) {
2971 dst->srcAlpha = QRhiGraphicsPipeline::BlendFactor(src->srcAlpha);
2972 dst->dstAlpha = QRhiGraphicsPipeline::BlendFactor(src->dstAlpha);
2974 dst->srcAlpha = dst->srcColor;
2975 dst->dstAlpha = dst->dstColor;
2977 dst->opColor = QRhiGraphicsPipeline::BlendOp(src->opColor);
2978 dst->opAlpha = QRhiGraphicsPipeline::BlendOp(src->opAlpha);
2979 dst->colorWrite = QRhiGraphicsPipeline::ColorMask(
int(src->colorWrite));
2980 dst->cullMode = QRhiGraphicsPipeline::CullMode(src->cullMode);
2981 dst->polygonMode = QRhiGraphicsPipeline::PolygonMode(src->polygonMode);
3076 qWarning(
"No QSGTexture provided from updateSampledImage(). This is wrong.");
3098 qWarning(
"QSGTexture anisotropy levels are not currently supported");
3110 qWarning(
"Failed to build sampler");
3225 Q_ASSERT_X(
false,
"updateMaterialDynamicData",
"No srb action set, this cannot happen");
3267#ifndef QT_NO_DEBUG_OUTPUT
3376 qWarning(
"Line widths other than 1 are not supported by the graphics API");
3384 qWarning(
"Point size is not controllable by QSGGeometry. "
3385 "Set gl_PointSize from the vertex shader instead.");
3728 qWarning(
"prepareRenderPass() called with an already prepared render pass context");
3752 type +=
" renderlists";
3759 qDebug() <<
"Renderer::render()" <<
this <<
type;
3774 qDebug(
"Opaque render lists %s:", (
complete ?
"(complete)" :
"(partial)"));
3779 qDebug(
"Alpha render list %s:",
complete ?
"(complete)" :
"(partial)");
3804 qDebug(
"Opaque Batches:");
3812 qDebug(
"Alpha Batches:");
3975#if defined(QSGBATCHRENDERER_INVALIDATE_WEDGED_NODES)
4027 qWarning(
"recordRenderPass() called without a prepared render pass context");
4084 qDebug(
" -> times: build: %d, prepare(opaque/alpha): %d/%d, sorting: %d, upload(opaque/alpha): %d/%d, record rendering: %d",
4250 else if (
mode ==
"clip")
4252 else if (
mode ==
"overdraw")
4254 else if (
mode ==
"batches")
4256 else if (
mode ==
"changes")
4269 && a.depthFunc == b.depthFunc
4271 && a.srcColor == b.srcColor
4272 && a.dstColor == b.dstColor
4273 && a.srcAlpha == b.srcAlpha
4274 && a.dstAlpha == b.dstAlpha
4275 && a.opColor == b.opColor
4276 && a.opAlpha == b.opAlpha
4277 && a.colorWrite == b.colorWrite
4278 && a.cullMode == b.cullMode
4282 && a.drawMode == b.drawMode
4284 && a.polygonMode == b.polygonMode
4311 return a.state == b.state
4312 && a
.sms->materialShader == b
.sms->materialShader
4313 && a.renderTargetDescription == b.renderTargetDescription
4314 && a.srbLayoutDescription == b.srbLayoutDescription;
4324 return qHash(k.state, seed)
4325 ^ qHash(k.sms->materialShader)
4326 ^ k.extra.renderTargetDescriptionHash
4327 ^ k.extra.srbLayoutDescriptionHash;
4332 return a.type == b.type
4333 && a.renderMode == b.renderMode
4344 return qHash(k.type, seed) ^
int(k.renderMode) ^ k.multiViewCount;
4357#define QSGNODE_DIRTY_PARENT (QSGNode::DirtyNodeAdded
4358 | QSGNode::DirtyOpacity
4359 | QSGNode::DirtyMatrix
4360 | QSGNode::DirtyNodeRemoved)
4365 uint selfDirty = n->dirtyState | parentChanges;
4366 if (n->type() == QSGNode::GeometryNodeType && selfDirty != 0)
4367 m_visualizeChangeSet.insert(n, selfDirty);
4369 visualizeChangesPrepare(child, childDirty);
4377#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)
QRhiGraphicsPipeline::Topology qsg_topology(int geomDrawMode, QRhi *rhi)
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)
const quint32 MIN_UNIFORM_BUFFER_SIZE
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)
const int UNIFORM_BUFFER_SHRINK_FRAMES
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)
size_t qHash(const GraphicsPipelineStateKey &k, size_t seed) noexcept
Int aligned(Int v, Int byteAlign)
const quint32 DEFAULT_BUFFER_POOL_SIZE_LIMIT
Q_CORE_EXPORT QDebug operator<<(QDebug debug, QDir::Filters filters)
#define DECLARE_DEBUG_VAR(variable)
#define QSGNODE_DIRTY_PARENT
QT_BEGIN_NAMESPACE int qt_sg_envInt(const char *name, int defaultValue)
#define SHADOWNODE_TRAVERSE(NODE)
#define QSGNODE_TRAVERSE(NODE)
bool geometryWasChanged(QSGGeometryNode *gn)
bool isSafeToBatch() const
void cleanupRemovedElements()
BatchCompatibility isMaterialCompatible(Element *e) const
bool isTranslateOnlyToRoot() const
const ShaderManagerShader * sms
BatchRootInfo * rootInfo() const
ClipBatchRootInfo * clipInfo() const
RenderNodeElement * renderNodeElement() const
Element * element() const
void operator|=(const Pt &pt)
void set(float left, float top, float right, float bottom)
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