11#include <QtCore/QElapsedTimer>
12#include <QtCore/QtNumeric>
14#include <QtGui/QGuiApplication>
16#include <private/qnumeric_p.h>
30#define DECLARE_DEBUG_VAR(variable)
31 static bool debug_ ## variable()
32 { static bool value = qgetenv("QSG_RENDERER_DEBUG").contains(QT_STRINGIFY(variable)); return value; }
43#undef DECLARE_DEBUG_VAR
45#define QSGNODE_TRAVERSE(NODE) for (QSGNode *child = NODE->firstChild(); child; child = child->nextSibling())
46#define SHADOWNODE_TRAVERSE(NODE) for (Node *child = NODE->firstChild(); child; child = child->sibling())
50 static int sizes[] = {
52 sizeof(
unsigned char),
54 sizeof(
unsigned short),
63 Q_ASSERT(type >= QSGGeometry::ByteType && type <= QSGGeometry::DoubleType);
64 return sizes[type - QSGGeometry::ByteType];
74static bool isTranslate(
const QMatrix4x4 &m) {
return m.flags() <= QMatrix4x4::Translation; }
75static bool isScale(
const QMatrix4x4 &m) {
return m.flags() <= QMatrix4x4::Scale; }
76static bool is2DSafe(
const QMatrix4x4 &m) {
return m.flags() < QMatrix4x4::Rotation; }
92 return (v + byteAlign - 1) & ~(byteAlign - 1);
98 case QSGGeometry::FloatType:
100 return QRhiVertexInputAttribute::Float4;
101 if (a.tupleSize == 3)
102 return QRhiVertexInputAttribute::Float3;
103 if (a.tupleSize == 2)
104 return QRhiVertexInputAttribute::Float2;
105 if (a.tupleSize == 1)
106 return QRhiVertexInputAttribute::Float;
108 case QSGGeometry::UnsignedByteType:
109 if (a.tupleSize == 4)
110 return QRhiVertexInputAttribute::UNormByte4;
111 if (a.tupleSize == 2)
112 return QRhiVertexInputAttribute::UNormByte2;
113 if (a.tupleSize == 1)
114 return QRhiVertexInputAttribute::UNormByte;
119 qWarning(
"Unsupported attribute type 0x%x with %d components", a.type, a.tupleSize);
120 Q_UNREACHABLE_RETURN(QRhiVertexInputAttribute::Float);
126 const QSGMaterialShaderPrivate *sd = QSGMaterialShaderPrivate::get(s);
127 if (!sd->vertexShader) {
128 qWarning(
"No vertex shader in QSGMaterialShader %p", s);
129 return QRhiVertexInputLayout();
132 const int attrCount = geometry->attributeCount();
133 QVarLengthArray<QRhiVertexInputAttribute, 8> inputAttributes;
134 inputAttributes.reserve(attrCount + 1);
136 for (
int i = 0; i < attrCount; ++i) {
137 const QSGGeometry::Attribute &a = geometry->attributes()[i];
138 if (!sd->vertexShader->vertexInputLocations.contains(a.position)) {
139 qWarning(
"Vertex input %d is present in material but not in shader. This is wrong.",
142 inputAttributes.append(QRhiVertexInputAttribute(
VERTEX_BUFFER_BINDING, a.position, qsg_vertexInputFormat(a), offset));
143 offset += a.tupleSize * size_of_type(a.type);
146 inputAttributes.append(QRhiVertexInputAttribute(
ZORDER_BUFFER_BINDING, sd->vertexShader->qt_order_attrib_location,
147 QRhiVertexInputAttribute::Float, 0));
151 QVarLengthArray<QRhiVertexInputBinding, 2> inputBindings;
152 inputBindings.append(QRhiVertexInputBinding(geometry->sizeOfVertex()));
154 inputBindings.append(QRhiVertexInputBinding(
sizeof(
float)));
157 inputLayout.setBindings(inputBindings.cbegin(), inputBindings.cend());
158 inputLayout.setAttributes(inputAttributes.cbegin(), inputAttributes.cend());
165 switch (geometry->indexType()) {
166 case QSGGeometry::UnsignedShortType:
167 return QRhiCommandBuffer::IndexUInt16;
169 case QSGGeometry::UnsignedIntType:
170 return QRhiCommandBuffer::IndexUInt32;
173 Q_UNREACHABLE_RETURN(QRhiCommandBuffer::IndexUInt16);
179 QRhiGraphicsPipeline::Topology topology = QRhiGraphicsPipeline::Triangles;
180 switch (geomDrawMode) {
181 case QSGGeometry::DrawPoints:
182 topology = QRhiGraphicsPipeline::Points;
184 case QSGGeometry::DrawLines:
185 topology = QRhiGraphicsPipeline::Lines;
187 case QSGGeometry::DrawLineStrip:
188 topology = QRhiGraphicsPipeline::LineStrip;
190 case QSGGeometry::DrawTriangles:
191 topology = QRhiGraphicsPipeline::Triangles;
193 case QSGGeometry::DrawTriangleStrip:
194 topology = QRhiGraphicsPipeline::TriangleStrip;
196 case QSGGeometry::DrawTriangleFan:
198 static bool triangleFanSupported =
false;
199 static bool triangleFanSupportChecked =
false;
200 if (!triangleFanSupportChecked) {
201 triangleFanSupportChecked =
true;
202 triangleFanSupported = rhi->isFeatureSupported(QRhi::TriangleFanTopology);
204 if (triangleFanSupported) {
205 topology = QRhiGraphicsPipeline::TriangleFan;
211 qWarning(
"Primitive topology 0x%x not supported", geomDrawMode);
219 material->setFlag(QSGMaterial::MultiView2, multiViewCount == 2);
220 material->setFlag(QSGMaterial::MultiView3, multiViewCount == 3);
221 material->setFlag(QSGMaterial::MultiView4, multiViewCount == 4);
225 const QSGGeometry *geometry,
226 QSGRendererInterface::RenderMode renderMode,
231 QSGMaterialType *type = material->type();
232 ShaderKey key = { type, renderMode, multiViewCount };
233 Shader *shader = rewrittenShaders.value(key,
nullptr);
238 QSGMaterialShader *s =
static_cast<QSGMaterialShader *>(material->createShader(renderMode));
239 context->initializeRhiShader(s, QShader::BatchableVertexShader);
240 shader->materialShader = s;
241 shader->inputLayout = calculateVertexInputLayout(s, geometry,
true);
242 QSGMaterialShaderPrivate *sD = QSGMaterialShaderPrivate::get(s);
244 { QRhiShaderStage::Vertex, sD->shader(QShader::VertexStage), QShader::BatchableVertexShader },
245 { QRhiShaderStage::Fragment, sD->shader(QShader::FragmentStage) }
248 shader->lastOpacity = 0;
250 rewrittenShaders[key] = shader;
254ShaderManager::Shader *
ShaderManager::prepareMaterialNoRewrite(QSGMaterial *material,
255 const QSGGeometry *geometry,
256 QSGRendererInterface::RenderMode renderMode,
261 QSGMaterialType *type = material->type();
262 ShaderKey key = { type, renderMode, multiViewCount };
263 Shader *shader = stockShaders.value(key,
nullptr);
268 QSGMaterialShader *s =
static_cast<QSGMaterialShader *>(material->createShader(renderMode));
269 context->initializeRhiShader(s, QShader::StandardShader);
270 shader->materialShader = s;
271 shader->inputLayout = calculateVertexInputLayout(s, geometry,
false);
272 QSGMaterialShaderPrivate *sD = QSGMaterialShaderPrivate::get(s);
274 { QRhiShaderStage::Vertex, sD->shader(QShader::VertexStage) },
275 { QRhiShaderStage::Fragment, sD->shader(QShader::FragmentStage) }
278 shader->lastOpacity = 0;
280 stockShaders[key] = shader;
287 qDeleteAll(stockShaders);
288 stockShaders.clear();
289 qDeleteAll(rewrittenShaders);
290 rewrittenShaders.clear();
292 qDeleteAll(pipelineCache);
293 pipelineCache.clear();
301 for (ShaderManager::Shader *sms : std::as_const(stockShaders)) {
302 QSGMaterialShader *s = sms->materialShader;
304 QSGMaterialShaderPrivate *sd = QSGMaterialShaderPrivate::get(s);
305 sd->clearCachedRendererData();
308 for (ShaderManager::Shader *sms : std::as_const(rewrittenShaders)) {
309 QSGMaterialShader *s = sms->materialShader;
311 QSGMaterialShaderPrivate *sd = QSGMaterialShaderPrivate::get(s);
312 sd->clearCachedRendererData();
319 static int extraIndent = 0;
322 QByteArray ind(indent + extraIndent + 10,
' ');
325 qDebug(
"%s - no info", ind.constData());
328 for (QSet<Node *>::const_iterator it = i->subRoots.constBegin();
329 it != i->subRoots.constEnd(); ++it) {
330 qDebug() << ind.constData() <<
"-" << *it;
331 qsg_dumpShadowRoots((*it)->rootInfo(), indent);
340#ifndef QT_NO_DEBUG_OUTPUT
341 static int indent = 0;
344 QByteArray ind(indent,
' ');
346 if (n->type() == QSGNode::ClipNodeType || n->isBatchRoot) {
347 qDebug() << ind.constData() <<
"[X]" << n->sgNode << Qt::hex << uint(n->sgNode->flags());
351 d << ind.constData() <<
"[ ]" << n->sgNode << Qt::hex << uint(n->sgNode->flags());
352 if (n->type() == QSGNode::GeometryNodeType)
353 d <<
"order" << Qt::dec << n->element()->order;
371 m_combined_matrix_stack.add(&m_identityMatrix);
372 m_rootMatrices.add(m_identityMatrix);
377 m_current_clip =
nullptr;
380 m_transformChange = 0;
383 Node *sn = renderer->m_nodes.value(n, 0);
386 if (Q_UNLIKELY(debug_roots()))
389 if (Q_UNLIKELY(debug_build())) {
390 qDebug(
"Updater::updateStates()");
391 if (sn->dirtyState & (QSGNode::DirtyNodeAdded << 16))
392 qDebug(
" - nodes have been added");
393 if (sn->dirtyState & (QSGNode::DirtyMatrix << 16))
394 qDebug(
" - transforms have changed");
395 if (sn->dirtyState & (QSGNode::DirtyOpacity << 16))
396 qDebug(
" - opacity has changed");
397 if (uint(sn->dirtyState) & uint(QSGNode::DirtyForceUpdate << 16))
398 qDebug(
" - forceupdate");
402 renderer->m_visualizer->visualizeChangesPrepare(sn);
409 if (m_added == 0 && n->dirtyState == 0 && m_force_update == 0 && m_transformChange == 0 && m_opacityChange == 0)
413 if (n->dirtyState & QSGNode::DirtyNodeAdded)
416 int force = m_force_update;
417 if (n->dirtyState & QSGNode::DirtyForceUpdate)
421 case QSGNode::OpacityNodeType:
424 case QSGNode::TransformNodeType:
427 case QSGNode::GeometryNodeType:
430 case QSGNode::ClipNodeType:
433 case QSGNode::RenderNodeType:
435 n->renderNodeElement()->root = m_roots.last();
443 m_force_update = force;
451 QSGClipNode *cn =
static_cast<QSGClipNode *>(n->sgNode);
453 if (m_roots.last() && m_added > 0)
454 renderer->registerBatchRoot(n, m_roots.last());
456 cn->setRendererClipList(m_current_clip);
459 m_rootMatrices.add(m_rootMatrices.last() * *m_combined_matrix_stack.last());
460 extra->matrix = m_rootMatrices.last();
461 cn->setRendererMatrix(&extra->matrix);
462 m_combined_matrix_stack << &m_identityMatrix;
466 m_current_clip = cn->clipList();
467 m_rootMatrices.pop_back();
468 m_combined_matrix_stack.pop_back();
474 QSGOpacityNode *on =
static_cast<QSGOpacityNode *>(n->sgNode);
476 qreal combined = m_opacity_stack.last() * on->opacity();
477 on->setCombinedOpacity(combined);
478 m_opacity_stack.add(combined);
480 if (m_added == 0 && n->dirtyState & QSGNode::DirtyOpacity) {
481 bool was = n->isOpaque;
484 renderer->m_rebuild = Renderer::FullRebuild;
496 m_opacity_stack.pop_back();
501 bool popMatrixStack =
false;
502 bool popRootStack =
false;
503 bool dirty = n->dirtyState & QSGNode::DirtyMatrix;
505 QSGTransformNode *tn =
static_cast<QSGTransformNode *>(n->sgNode);
507 if (n->isBatchRoot) {
508 if (m_added > 0 && m_roots.last())
509 renderer->registerBatchRoot(n, m_roots.last());
510 tn->setCombinedMatrix(m_rootMatrices.last() * *m_combined_matrix_stack.last() * tn->matrix());
515 if (!n->becameBatchRoot && m_added == 0 && m_force_update == 0 && m_opacityChange == 0 && dirty && (n->dirtyState & ~QSGNode::DirtyMatrix) == 0) {
517 for (QSet<Node *>::const_iterator it = info->subRoots.constBegin();
518 it != info->subRoots.constEnd(); ++it) {
524 n->becameBatchRoot =
false;
526 m_combined_matrix_stack.add(&m_identityMatrix);
528 m_rootMatrices.add(tn->combinedMatrix());
530 popMatrixStack =
true;
532 }
else if (!tn->matrix().isIdentity()) {
533 tn->setCombinedMatrix(*m_combined_matrix_stack.last() * tn->matrix());
534 m_combined_matrix_stack.add(&tn->combinedMatrix());
535 popMatrixStack =
true;
537 tn->setCombinedMatrix(*m_combined_matrix_stack.last());
548 m_combined_matrix_stack.pop_back();
551 m_rootMatrices.pop_back();
557 QSGGeometryNode *gn =
static_cast<QSGGeometryNode *>(n->sgNode);
559 gn->setRendererMatrix(m_combined_matrix_stack.last());
560 gn->setRendererClipList(m_current_clip);
561 gn->setInheritedOpacity(m_opacity_stack.last());
565 e->root = m_roots.last();
566 e->translateOnlyToRoot = isTranslate(*gn->matrix());
570 while (info !=
nullptr) {
573 renderer->m_rebuild |= Renderer::BuildRenderLists;
575 renderer->m_rebuild |= Renderer::BuildRenderListsForTaggedRoots;
576 renderer->m_taggedRoots << e
->root;
584 renderer->m_rebuild |= Renderer::FullRebuild;
587 if (m_transformChange) {
589 e->translateOnlyToRoot = isTranslate(*gn->matrix());
591 if (m_opacityChange) {
594 renderer->invalidateBatchAndOverlappingRenderOrders(e
->batch);
608 if (n->type() == QSGNode::TransformNodeType)
609 m =
static_cast<QSGTransformNode *>(n->sgNode)->matrix() * m;
615 if (node->type() == QSGNode::ClipNodeType) {
616 static_cast<ClipBatchRootInfo *>(info)->matrix = m;
618 Q_ASSERT(node->type() == QSGNode::TransformNodeType);
619 static_cast<QSGTransformNode *>(node->sgNode)->setCombinedMatrix(m);
622 for (QSet<Node *>::const_iterator it = info->subRoots.constBegin();
623 it != info->subRoots.constEnd(); ++it) {
631 for (
int a=0; a<g->attributeCount(); ++a) {
632 const QSGGeometry::Attribute &attr = g->attributes()[a];
633 if (attr.isVertexCoordinate && attr.tupleSize == 2 && attr.type == QSGGeometry::FloatType) {
636 vaOffset += attr.tupleSize * size_of_type(attr.type);
644 const float *m = matrix.constData();
645 if (isScale(matrix)) {
665 set(FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX);
675 Q_ASSERT(!boundsComputed);
676 boundsComputed =
true;
678 QSGGeometry *g = node->geometry();
679 int offset = qsg_positionAttribute(g);
682 bounds.set(-FLT_MAX, -FLT_MAX, FLT_MAX, FLT_MAX);
686 bounds.set(FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX);
687 char *vd = (
char *) g->vertexData() + offset;
688 for (
int i=0; i<g->vertexCount(); ++i) {
690 vd += g->sizeOfVertex();
692 bounds.map(*node->matrix());
694 if (!qt_is_finite(bounds.tl.x) || bounds.tl.x == FLT_MAX)
695 bounds.tl.x = -FLT_MAX;
696 if (!qt_is_finite(bounds.tl.y) || bounds.tl.y == FLT_MAX)
697 bounds.tl.y = -FLT_MAX;
698 if (!qt_is_finite(bounds.br.x) || bounds.br.x == -FLT_MAX)
699 bounds.br.x = FLT_MAX;
700 if (!qt_is_finite(bounds.br.y) || bounds.br.y == -FLT_MAX)
701 bounds.br.y = FLT_MAX;
706 boundsOutsideFloatRange = bounds.isOutsideFloatRange();
713 while (n && (n == e || n->removed))
721 QSGMaterial *m = e->node->activeMaterial();
722 QSGMaterial *nm = n->node->activeMaterial();
723 return (nm->type() == m->type() && nm->viewCount() == m->viewCount() && nm->compare(m) == 0)
729
730
731
732
736 Q_ASSERT_X(e,
"Batch::geometryWasChanged",
"Batch is expected to 'valid' at this time");
738 while (e && (e->node == gn || e->removed))
740 if (!e || e->node->geometry()->attributes() == gn->geometry()->attributes()) {
774
775
776
795 only &= e->translateOnlyToRoot;
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
821 if (e->boundsOutsideFloatRange)
823 if (!is2DSafe(*e->node->matrix()))
844 for (
int i=0; i<batches.size(); ++i) {
845 sum += qsg_countNodesInBatch(batches.at(i));
872#if defined(QSGBATCHRENDERER_INVALIDATE_WEDGED_NODES)
917 qDebug(
"Batch thresholds: nodes: %d vertices: %d srb pool: %d buffer pool: %d",
936 qsg_wipeBuffer(&batch->vbo);
937 qsg_wipeBuffer(&batch->ibo);
939 batch->stencilClipState.reset();
1365#ifndef QT_NO_DEBUG_OUTPUT
1370 debug <<
"Geometry";
1372 debug <<
"Material";
1382 debug <<
"SubtreeBlocked";
1384 debug <<
"ForceUpdate";
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1590 for (
int i=0; i<renderList.size(); ++i) {
1591 Element *e = renderList.at(i);
1592 if (e && !e->removed) {
1601 for (
int i=0; i<orphans.size(); ++i) {
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1709#if defined(QSGBATCHRENDERER_INVALIDATE_WEDGED_NODES)
1738
1739
1776 for (
int j =
i - 1;
j >= 0; --
j) {
1817#if defined(QSGBATCHRENDERER_INVALIDATE_WEDGED_NODES)
1831
1832
1833
1834
1835
1836
1837
1838
1839
1893#if !defined(QSGBATCHRENDERER_INVALIDATE_WEDGED_NODES)
1927
1928
1929
1930
1947 case QSGGeometry::DrawTriangleStrip:
1954 case QSGGeometry::DrawLines:
1956 return iCount - (iCount % 2);
1957 case QSGGeometry::DrawTriangles:
1959 return iCount - (iCount % 3);
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
2088 if (node->type() == QSGNode::TransformNodeType)
2089 return static_cast<QSGTransformNode *>(node->sgNode)->combinedMatrix();
2090 Q_ASSERT(node->type() == QSGNode::ClipNodeType);
2091 QSGClipNode *c =
static_cast<QSGClipNode *>(node->sgNode);
2092 return *c->matrix();
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2258 Q_ASSERT_X(
false,
"uploadBatch (unmerged)",
"uint index with ushort effective index - cannot happen");
2266#ifndef QT_NO_DEBUG_OUTPUT
2272 dump <<
" --- " <<
i <<
": ";
2282 dump << *(
const float *)(
vd +
offset +
t *
sizeof(
float)) <<
" ";
2286 dump << *(
const unsigned char *)(
vd +
offset +
t *
sizeof(
unsigned char)) <<
" ";
2384 qWarning(
"Failed to build stencil clip pipeline");
2503 qWarning(
"Failed to build stencil clip vertex buffer");
2521 qWarning(
"Failed to build stencil clip index buffer");
2539 qWarning(
"Failed to build stencil clip uniform buffer");
2552 qWarning(
"Failed to build stencil clip srb");
2576 qWarning(
"updateClipState: Clip list entries have different primitive topologies, this is not currently supported.");
2578 qWarning(
"updateClipState: Clip list entries have different vertex input layouts, this is must not happen.");
2660 }
else if (
i == 1) {
2689 return f == QRhiGraphicsPipeline::ConstantColor
2690 || f == QRhiGraphicsPipeline::OneMinusConstantColor
2691 || f == QRhiGraphicsPipeline::ConstantAlpha
2692 || f == QRhiGraphicsPipeline::OneMinusConstantAlpha;
2804 qWarning(
"Failed to build graphics pipeline state");
2817static QRhiSampler *
newSampler(QRhi *rhi,
const QSGSamplerDescription &desc)
2819 QRhiSampler::Filter magFilter;
2820 QRhiSampler::Filter minFilter;
2821 QRhiSampler::Filter mipmapMode;
2822 QRhiSampler::AddressMode u;
2823 QRhiSampler::AddressMode v;
2825 switch (desc.filtering) {
2826 case QSGTexture::None:
2828 case QSGTexture::Nearest:
2829 magFilter = minFilter = QRhiSampler::Nearest;
2831 case QSGTexture::Linear:
2832 magFilter = minFilter = QRhiSampler::Linear;
2836 magFilter = minFilter = QRhiSampler::Nearest;
2840 switch (desc.mipmapFiltering) {
2841 case QSGTexture::None:
2842 mipmapMode = QRhiSampler::None;
2844 case QSGTexture::Nearest:
2845 mipmapMode = QRhiSampler::Nearest;
2847 case QSGTexture::Linear:
2848 mipmapMode = QRhiSampler::Linear;
2852 mipmapMode = QRhiSampler::None;
2856 switch (desc.horizontalWrap) {
2857 case QSGTexture::Repeat:
2858 u = QRhiSampler::Repeat;
2860 case QSGTexture::ClampToEdge:
2861 u = QRhiSampler::ClampToEdge;
2863 case QSGTexture::MirroredRepeat:
2864 u = QRhiSampler::Mirror;
2868 u = QRhiSampler::ClampToEdge;
2872 switch (desc.verticalWrap) {
2873 case QSGTexture::Repeat:
2874 v = QRhiSampler::Repeat;
2876 case QSGTexture::ClampToEdge:
2877 v = QRhiSampler::ClampToEdge;
2879 case QSGTexture::MirroredRepeat:
2880 v = QRhiSampler::Mirror;
2884 v = QRhiSampler::ClampToEdge;
2888 return rhi->newSampler(magFilter, minFilter, mipmapMode, u, v);
2912 Q_ASSERT(
int(QSGMaterialShader::GraphicsPipelineState::OneMinusSrc1Alpha) ==
int(QRhiGraphicsPipeline::OneMinusSrc1Alpha));
2913 Q_ASSERT(
int(QSGMaterialShader::GraphicsPipelineState::BlendOp::Max) ==
int(QRhiGraphicsPipeline::Max));
2914 Q_ASSERT(
int(QSGMaterialShader::GraphicsPipelineState::A) ==
int(QRhiGraphicsPipeline::A));
2915 Q_ASSERT(
int(QSGMaterialShader::GraphicsPipelineState::CullBack) ==
int(QRhiGraphicsPipeline::Back));
2916 Q_ASSERT(
int(QSGMaterialShader::GraphicsPipelineState::Line) ==
int(QRhiGraphicsPipeline::Line));
2917 dst->srcColor = QSGMaterialShader::GraphicsPipelineState::BlendFactor(src->srcColor);
2918 dst->dstColor = QSGMaterialShader::GraphicsPipelineState::BlendFactor(src->dstColor);
2926 dst->separateBlendFactors =
false;
2928 dst->srcAlpha = QSGMaterialShader::GraphicsPipelineState::BlendFactor(src->srcAlpha);
2929 dst->dstAlpha = QSGMaterialShader::GraphicsPipelineState::BlendFactor(src->dstAlpha);
2931 dst->opColor = QSGMaterialShader::GraphicsPipelineState::BlendOp(src->opColor);
2932 dst->opAlpha = QSGMaterialShader::GraphicsPipelineState::BlendOp(src->opAlpha);
2934 dst->colorWrite = QSGMaterialShader::GraphicsPipelineState::ColorMask(
int(src->colorWrite));
2936 dst->cullMode = QSGMaterialShader::GraphicsPipelineState::CullMode(src->cullMode);
2937 dst->polygonMode = QSGMaterialShader::GraphicsPipelineState::PolygonMode(src->polygonMode);
2941 QSGMaterialShader::GraphicsPipelineState *src)
2944 dst->srcColor = QRhiGraphicsPipeline::BlendFactor(src->srcColor);
2945 dst->dstColor = QRhiGraphicsPipeline::BlendFactor(src->dstColor);
2946 if (src->separateBlendFactors) {
2947 dst->srcAlpha = QRhiGraphicsPipeline::BlendFactor(src->srcAlpha);
2948 dst->dstAlpha = QRhiGraphicsPipeline::BlendFactor(src->dstAlpha);
2950 dst->srcAlpha = dst->srcColor;
2951 dst->dstAlpha = dst->dstColor;
2953 dst->opColor = QRhiGraphicsPipeline::BlendOp(src->opColor);
2954 dst->opAlpha = QRhiGraphicsPipeline::BlendOp(src->opAlpha);
2955 dst->colorWrite = QRhiGraphicsPipeline::ColorMask(
int(src->colorWrite));
2956 dst->cullMode = QRhiGraphicsPipeline::CullMode(src->cullMode);
2957 dst->polygonMode = QRhiGraphicsPipeline::PolygonMode(src->polygonMode);
3009 qWarning(
"No QSGTexture provided from updateSampledImage(). This is wrong.");
3031 qWarning(
"QSGTexture anisotropy levels are not currently supported");
3043 qWarning(
"Failed to build sampler");
3158 Q_ASSERT_X(
false,
"updateMaterialDynamicData",
"No srb action set, this cannot happen");
3198#ifndef QT_NO_DEBUG_OUTPUT
3335 qWarning(
"Line widths other than 1 are not supported by the graphics API");
3343 qWarning(
"Point size is not controllable by QSGGeometry. "
3344 "Set gl_PointSize from the vertex shader instead.");
3715 qWarning(
"prepareRenderPass() called with an already prepared render pass context");
3739 type +=
" renderlists";
3746 qDebug() <<
"Renderer::render()" <<
this <<
type;
3761 qDebug(
"Opaque render lists %s:", (
complete ?
"(complete)" :
"(partial)"));
3766 qDebug(
"Alpha render list %s:",
complete ?
"(complete)" :
"(partial)");
3791 qDebug(
"Opaque Batches:");
3799 qDebug(
"Alpha Batches:");
3942#if defined(QSGBATCHRENDERER_INVALIDATE_WEDGED_NODES)
3984 qWarning(
"recordRenderPass() called without a prepared render pass context");
4041 qDebug(
" -> times: build: %d, prepare(opaque/alpha): %d/%d, sorting: %d, upload(opaque/alpha): %d/%d, record rendering: %d",
4207 else if (
mode ==
"clip")
4209 else if (
mode ==
"overdraw")
4211 else if (
mode ==
"batches")
4213 else if (
mode ==
"changes")
4226 && a.depthFunc == b.depthFunc
4228 && a.srcColor == b.srcColor
4229 && a.dstColor == b.dstColor
4230 && a.srcAlpha == b.srcAlpha
4231 && a.dstAlpha == b.dstAlpha
4232 && a.opColor == b.opColor
4233 && a.opAlpha == b.opAlpha
4234 && a.colorWrite == b.colorWrite
4235 && a.cullMode == b.cullMode
4239 && a.drawMode == b.drawMode
4241 && a.polygonMode == b.polygonMode
4268 return a.state == b.state
4269 && a
.sms->materialShader == b
.sms->materialShader
4270 && a.renderTargetDescription == b.renderTargetDescription
4271 && a.srbLayoutDescription == b.srbLayoutDescription;
4281 return qHash(k.state, seed)
4282 ^ qHash(k.sms->materialShader)
4283 ^ k.extra.renderTargetDescriptionHash
4284 ^ k.extra.srbLayoutDescriptionHash;
4289 return a.type == b.type
4290 && a.renderMode == b.renderMode
4301 return qHash(k.type, seed) ^
int(k.renderMode) ^ k.multiViewCount;
4314#define QSGNODE_DIRTY_PARENT (QSGNode::DirtyNodeAdded
4315 | QSGNode::DirtyOpacity
4316 | QSGNode::DirtyMatrix
4317 | QSGNode::DirtyNodeRemoved)
4322 uint selfDirty = n->dirtyState | parentChanges;
4323 if (n->type() == QSGNode::GeometryNodeType && selfDirty != 0)
4324 m_visualizeChangeSet.insert(n, selfDirty);
4326 visualizeChangesPrepare(child, childDirty);
4334#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)
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)
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
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