10#include <QtCore/QElapsedTimer>
11#include <QtCore/QtNumeric>
13#include <QtGui/QGuiApplication>
15#include <private/qnumeric_p.h>
29#define DECLARE_DEBUG_VAR(variable)
30 static bool debug_ ## variable()
31 { static bool value = qgetenv("QSG_RENDERER_DEBUG").contains(QT_STRINGIFY(variable)); return value; }
42#undef DECLARE_DEBUG_VAR
44#define QSGNODE_TRAVERSE(NODE) for (QSGNode *child = NODE->firstChild(); child; child = child->nextSibling())
45#define SHADOWNODE_TRAVERSE(NODE) for (Node *child = NODE->firstChild(); child; child = child->sibling())
49 static int sizes[] = {
51 sizeof(
unsigned char),
53 sizeof(
unsigned short),
62 Q_ASSERT(type >= QSGGeometry::ByteType && type <= QSGGeometry::DoubleType);
63 return sizes[type - QSGGeometry::ByteType];
73static bool isTranslate(
const QMatrix4x4 &m) {
return m.flags() <= QMatrix4x4::Translation; }
74static bool isScale(
const QMatrix4x4 &m) {
return m.flags() <= QMatrix4x4::Scale; }
75static bool is2DSafe(
const QMatrix4x4 &m) {
return m.flags() < QMatrix4x4::Rotation; }
91 return (v + byteAlign - 1) & ~(byteAlign - 1);
97 case QSGGeometry::FloatType:
99 return QRhiVertexInputAttribute::Float4;
100 if (a.tupleSize == 3)
101 return QRhiVertexInputAttribute::Float3;
102 if (a.tupleSize == 2)
103 return QRhiVertexInputAttribute::Float2;
104 if (a.tupleSize == 1)
105 return QRhiVertexInputAttribute::Float;
107 case QSGGeometry::UnsignedByteType:
108 if (a.tupleSize == 4)
109 return QRhiVertexInputAttribute::UNormByte4;
110 if (a.tupleSize == 2)
111 return QRhiVertexInputAttribute::UNormByte2;
112 if (a.tupleSize == 1)
113 return QRhiVertexInputAttribute::UNormByte;
118 qWarning(
"Unsupported attribute type 0x%x with %d components", a.type, a.tupleSize);
119 Q_UNREACHABLE_RETURN(QRhiVertexInputAttribute::Float);
125 const QSGMaterialShaderPrivate *sd = QSGMaterialShaderPrivate::get(s);
126 if (!sd->vertexShader) {
127 qWarning(
"No vertex shader in QSGMaterialShader %p", s);
128 return QRhiVertexInputLayout();
131 const int attrCount = geometry->attributeCount();
132 QVarLengthArray<QRhiVertexInputAttribute, 8> inputAttributes;
133 inputAttributes.reserve(attrCount + 1);
135 for (
int i = 0; i < attrCount; ++i) {
136 const QSGGeometry::Attribute &a = geometry->attributes()[i];
137 if (!sd->vertexShader->vertexInputLocations.contains(a.position)) {
138 qWarning(
"Vertex input %d is present in material but not in shader. This is wrong.",
141 inputAttributes.append(QRhiVertexInputAttribute(VERTEX_BUFFER_BINDING, a.position, qsg_vertexInputFormat(a), offset));
142 offset += a.tupleSize * size_of_type(a.type);
145 inputAttributes.append(QRhiVertexInputAttribute(ZORDER_BUFFER_BINDING, sd->vertexShader->qt_order_attrib_location,
146 QRhiVertexInputAttribute::Float, 0));
150 QVarLengthArray<QRhiVertexInputBinding, 2> inputBindings;
151 inputBindings.append(QRhiVertexInputBinding(geometry->sizeOfVertex()));
153 inputBindings.append(QRhiVertexInputBinding(
sizeof(
float)));
156 inputLayout.setBindings(inputBindings.cbegin(), inputBindings.cend());
157 inputLayout.setAttributes(inputAttributes.cbegin(), inputAttributes.cend());
164 switch (geometry->indexType()) {
165 case QSGGeometry::UnsignedShortType:
166 return QRhiCommandBuffer::IndexUInt16;
168 case QSGGeometry::UnsignedIntType:
169 return QRhiCommandBuffer::IndexUInt32;
172 Q_UNREACHABLE_RETURN(QRhiCommandBuffer::IndexUInt16);
178 QRhiGraphicsPipeline::Topology topology = QRhiGraphicsPipeline::Triangles;
179 switch (geomDrawMode) {
180 case QSGGeometry::DrawPoints:
181 topology = QRhiGraphicsPipeline::Points;
183 case QSGGeometry::DrawLines:
184 topology = QRhiGraphicsPipeline::Lines;
186 case QSGGeometry::DrawLineStrip:
187 topology = QRhiGraphicsPipeline::LineStrip;
189 case QSGGeometry::DrawTriangles:
190 topology = QRhiGraphicsPipeline::Triangles;
192 case QSGGeometry::DrawTriangleStrip:
193 topology = QRhiGraphicsPipeline::TriangleStrip;
195 case QSGGeometry::DrawTriangleFan:
197 static bool triangleFanSupported =
false;
198 static bool triangleFanSupportChecked =
false;
199 if (!triangleFanSupportChecked) {
200 triangleFanSupportChecked =
true;
201 triangleFanSupported = rhi->isFeatureSupported(QRhi::TriangleFanTopology);
203 if (triangleFanSupported) {
204 topology = QRhiGraphicsPipeline::TriangleFan;
210 qWarning(
"Primitive topology 0x%x not supported", geomDrawMode);
218 material->setFlag(QSGMaterial::MultiView2, multiViewCount == 2);
219 material->setFlag(QSGMaterial::MultiView3, multiViewCount == 3);
220 material->setFlag(QSGMaterial::MultiView4, multiViewCount == 4);
224 const QSGGeometry *geometry,
225 QSGRendererInterface::RenderMode renderMode,
230 QSGMaterialType *type = material->type();
231 ShaderKey key = { type, renderMode, multiViewCount };
232 Shader *shader = rewrittenShaders.value(key,
nullptr);
237 QSGMaterialShader *s =
static_cast<QSGMaterialShader *>(material->createShader(renderMode));
238 context->initializeRhiShader(s, QShader::BatchableVertexShader);
239 shader->materialShader = s;
240 shader->inputLayout = calculateVertexInputLayout(s, geometry,
true);
241 QSGMaterialShaderPrivate *sD = QSGMaterialShaderPrivate::get(s);
243 { QRhiShaderStage::Vertex, sD->shader(QShader::VertexStage), QShader::BatchableVertexShader },
244 { QRhiShaderStage::Fragment, sD->shader(QShader::FragmentStage) }
247 shader->lastOpacity = 0;
249 rewrittenShaders[key] = shader;
253ShaderManager::Shader *
ShaderManager::prepareMaterialNoRewrite(QSGMaterial *material,
254 const QSGGeometry *geometry,
255 QSGRendererInterface::RenderMode renderMode,
260 QSGMaterialType *type = material->type();
261 ShaderKey key = { type, renderMode, multiViewCount };
262 Shader *shader = stockShaders.value(key,
nullptr);
267 QSGMaterialShader *s =
static_cast<QSGMaterialShader *>(material->createShader(renderMode));
268 context->initializeRhiShader(s, QShader::StandardShader);
269 shader->materialShader = s;
270 shader->inputLayout = calculateVertexInputLayout(s, geometry,
false);
271 QSGMaterialShaderPrivate *sD = QSGMaterialShaderPrivate::get(s);
273 { QRhiShaderStage::Vertex, sD->shader(QShader::VertexStage) },
274 { QRhiShaderStage::Fragment, sD->shader(QShader::FragmentStage) }
277 shader->lastOpacity = 0;
279 stockShaders[key] = shader;
286 qDeleteAll(stockShaders);
287 stockShaders.clear();
288 qDeleteAll(rewrittenShaders);
289 rewrittenShaders.clear();
291 qDeleteAll(pipelineCache);
292 pipelineCache.clear();
300 for (ShaderManager::Shader *sms : std::as_const(stockShaders)) {
301 QSGMaterialShader *s = sms->materialShader;
303 QSGMaterialShaderPrivate *sd = QSGMaterialShaderPrivate::get(s);
304 sd->clearCachedRendererData();
307 for (ShaderManager::Shader *sms : std::as_const(rewrittenShaders)) {
308 QSGMaterialShader *s = sms->materialShader;
310 QSGMaterialShaderPrivate *sd = QSGMaterialShaderPrivate::get(s);
311 sd->clearCachedRendererData();
318 static int extraIndent = 0;
321 QByteArray ind(indent + extraIndent + 10,
' ');
324 qDebug(
"%s - no info", ind.constData());
327 for (QSet<Node *>::const_iterator it = i->subRoots.constBegin();
328 it != i->subRoots.constEnd(); ++it) {
329 qDebug() << ind.constData() <<
"-" << *it;
330 qsg_dumpShadowRoots((*it)->rootInfo(), indent);
339#ifndef QT_NO_DEBUG_OUTPUT
340 static int indent = 0;
343 QByteArray ind(indent,
' ');
345 if (n->type() == QSGNode::ClipNodeType || n->isBatchRoot) {
346 qDebug() << ind.constData() <<
"[X]" << n->sgNode << Qt::hex << uint(n->sgNode->flags());
350 d << ind.constData() <<
"[ ]" << n->sgNode << Qt::hex << uint(n->sgNode->flags());
351 if (n->type() == QSGNode::GeometryNodeType)
352 d <<
"order" << Qt::dec << n->element()->order;
370 m_combined_matrix_stack.add(&m_identityMatrix);
371 m_rootMatrices.add(m_identityMatrix);
376 m_current_clip =
nullptr;
379 m_transformChange = 0;
382 Node *sn = renderer->m_nodes.value(n, 0);
385 if (Q_UNLIKELY(debug_roots()))
388 if (Q_UNLIKELY(debug_build())) {
389 qDebug(
"Updater::updateStates()");
390 if (sn->dirtyState & (QSGNode::DirtyNodeAdded << 16))
391 qDebug(
" - nodes have been added");
392 if (sn->dirtyState & (QSGNode::DirtyMatrix << 16))
393 qDebug(
" - transforms have changed");
394 if (sn->dirtyState & (QSGNode::DirtyOpacity << 16))
395 qDebug(
" - opacity has changed");
396 if (uint(sn->dirtyState) & uint(QSGNode::DirtyForceUpdate << 16))
397 qDebug(
" - forceupdate");
401 renderer->m_visualizer->visualizeChangesPrepare(sn);
408 if (m_added == 0 && n->dirtyState == 0 && m_force_update == 0 && m_transformChange == 0 && m_opacityChange == 0)
412 if (n->dirtyState & QSGNode::DirtyNodeAdded)
415 int force = m_force_update;
416 if (n->dirtyState & QSGNode::DirtyForceUpdate)
420 case QSGNode::OpacityNodeType:
423 case QSGNode::TransformNodeType:
426 case QSGNode::GeometryNodeType:
429 case QSGNode::ClipNodeType:
432 case QSGNode::RenderNodeType:
434 n->renderNodeElement()->root = m_roots.last();
442 m_force_update = force;
450 QSGClipNode *cn =
static_cast<QSGClipNode *>(n->sgNode);
452 if (m_roots.last() && m_added > 0)
453 renderer->registerBatchRoot(n, m_roots.last());
455 cn->setRendererClipList(m_current_clip);
458 m_rootMatrices.add(m_rootMatrices.last() * *m_combined_matrix_stack.last());
459 extra->matrix = m_rootMatrices.last();
460 cn->setRendererMatrix(&extra->matrix);
461 m_combined_matrix_stack << &m_identityMatrix;
465 m_current_clip = cn->clipList();
466 m_rootMatrices.pop_back();
467 m_combined_matrix_stack.pop_back();
473 QSGOpacityNode *on =
static_cast<QSGOpacityNode *>(n->sgNode);
475 qreal combined = m_opacity_stack.last() * on->opacity();
476 on->setCombinedOpacity(combined);
477 m_opacity_stack.add(combined);
479 if (m_added == 0 && n->dirtyState & QSGNode::DirtyOpacity) {
480 bool was = n->isOpaque;
483 renderer->m_rebuild = Renderer::FullRebuild;
495 m_opacity_stack.pop_back();
500 bool popMatrixStack =
false;
501 bool popRootStack =
false;
502 bool dirty = n->dirtyState & QSGNode::DirtyMatrix;
504 QSGTransformNode *tn =
static_cast<QSGTransformNode *>(n->sgNode);
506 if (n->isBatchRoot) {
507 if (m_added > 0 && m_roots.last())
508 renderer->registerBatchRoot(n, m_roots.last());
509 tn->setCombinedMatrix(m_rootMatrices.last() * *m_combined_matrix_stack.last() * tn->matrix());
514 if (!n->becameBatchRoot && m_added == 0 && m_force_update == 0 && m_opacityChange == 0 && dirty && (n->dirtyState & ~QSGNode::DirtyMatrix) == 0) {
516 for (QSet<Node *>::const_iterator it = info->subRoots.constBegin();
517 it != info->subRoots.constEnd(); ++it) {
523 n->becameBatchRoot =
false;
525 m_combined_matrix_stack.add(&m_identityMatrix);
527 m_rootMatrices.add(tn->combinedMatrix());
529 popMatrixStack =
true;
531 }
else if (!tn->matrix().isIdentity()) {
532 tn->setCombinedMatrix(*m_combined_matrix_stack.last() * tn->matrix());
533 m_combined_matrix_stack.add(&tn->combinedMatrix());
534 popMatrixStack =
true;
536 tn->setCombinedMatrix(*m_combined_matrix_stack.last());
547 m_combined_matrix_stack.pop_back();
550 m_rootMatrices.pop_back();
556 QSGGeometryNode *gn =
static_cast<QSGGeometryNode *>(n->sgNode);
558 gn->setRendererMatrix(m_combined_matrix_stack.last());
559 gn->setRendererClipList(m_current_clip);
560 gn->setInheritedOpacity(m_opacity_stack.last());
564 e->root = m_roots.last();
565 e->translateOnlyToRoot = isTranslate(*gn->matrix());
569 while (info !=
nullptr) {
572 renderer->m_rebuild |= Renderer::BuildRenderLists;
574 renderer->m_rebuild |= Renderer::BuildRenderListsForTaggedRoots;
575 renderer->m_taggedRoots << e
->root;
583 renderer->m_rebuild |= Renderer::FullRebuild;
586 if (m_transformChange) {
588 e->translateOnlyToRoot = isTranslate(*gn->matrix());
590 if (m_opacityChange) {
593 renderer->invalidateBatchAndOverlappingRenderOrders(e
->batch);
607 if (n->type() == QSGNode::TransformNodeType)
608 m =
static_cast<QSGTransformNode *>(n->sgNode)->matrix() * m;
614 if (node->type() == QSGNode::ClipNodeType) {
617 Q_ASSERT(node->type() == QSGNode::TransformNodeType);
618 static_cast<QSGTransformNode *>(node->sgNode)->setCombinedMatrix(m);
621 for (QSet<Node *>::const_iterator it = info->subRoots.constBegin();
622 it != info->subRoots.constEnd(); ++it) {
630 for (
int a=0; a<g->attributeCount(); ++a) {
631 const QSGGeometry::Attribute &attr = g->attributes()[a];
632 if (attr.isVertexCoordinate && attr.tupleSize == 2 && attr.type == QSGGeometry::FloatType) {
635 vaOffset += attr.tupleSize * size_of_type(attr.type);
643 const float *m = matrix.constData();
644 if (isScale(matrix)) {
664 set(FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX);
674 Q_ASSERT(!boundsComputed);
675 boundsComputed =
true;
677 QSGGeometry *g = node->geometry();
678 int offset = qsg_positionAttribute(g);
681 bounds.set(-FLT_MAX, -FLT_MAX, FLT_MAX, FLT_MAX);
685 bounds.set(FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX);
686 char *vd = (
char *) g->vertexData() + offset;
687 for (
int i=0; i<g->vertexCount(); ++i) {
689 vd += g->sizeOfVertex();
691 bounds.map(*node->matrix());
693 if (!qt_is_finite(bounds.tl.x) || bounds.tl.x == FLT_MAX)
694 bounds.tl.x = -FLT_MAX;
695 if (!qt_is_finite(bounds.tl.y) || bounds.tl.y == FLT_MAX)
696 bounds.tl.y = -FLT_MAX;
697 if (!qt_is_finite(bounds.br.x) || bounds.br.x == -FLT_MAX)
698 bounds.br.x = FLT_MAX;
699 if (!qt_is_finite(bounds.br.y) || bounds.br.y == -FLT_MAX)
700 bounds.br.y = FLT_MAX;
705 boundsOutsideFloatRange = bounds.isOutsideFloatRange();
712 while (n && (n == e || n->removed))
720 QSGMaterial *m = e->node->activeMaterial();
721 QSGMaterial *nm = n->node->activeMaterial();
722 return (nm->type() == m->type() && nm->viewCount() == m->viewCount() && nm->compare(m) == 0)
728
729
730
731
735 Q_ASSERT_X(e,
"Batch::geometryWasChanged",
"Batch is expected to 'valid' at this time");
737 while (e && (e->node == gn || e->removed))
739 if (!e || e->node->geometry()->attributes() == gn->geometry()->attributes()) {
773
774
775
794 only &= e->translateOnlyToRoot;
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
820 if (e->boundsOutsideFloatRange)
822 if (!is2DSafe(*e->node->matrix()))
843 for (
int i=0; i<batches.size(); ++i) {
844 sum += qsg_countNodesInBatch(batches.at(i));
871#if defined(QSGBATCHRENDERER_INVALIDATE_WEDGED_NODES)
916 qDebug(
"Batch thresholds: nodes: %d vertices: %d srb pool: %d buffer pool: %d",
935 qsg_wipeBuffer(&batch->vbo);
936 qsg_wipeBuffer(&batch->ibo);
938 batch->stencilClipState.reset();
1364#ifndef QT_NO_DEBUG_OUTPUT
1369 debug <<
"Geometry";
1371 debug <<
"Material";
1381 debug <<
"SubtreeBlocked";
1383 debug <<
"ForceUpdate";
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1589 for (
int i=0; i<renderList.size(); ++i) {
1590 Element *e = renderList.at(i);
1591 if (e && !e->removed) {
1600 for (
int i=0; i<orphans.size(); ++i) {
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1708#if defined(QSGBATCHRENDERER_INVALIDATE_WEDGED_NODES)
1737
1738
1775 for (
int j =
i - 1;
j >= 0; --
j) {
1816#if defined(QSGBATCHRENDERER_INVALIDATE_WEDGED_NODES)
1830
1831
1832
1833
1834
1835
1836
1837
1838
1892#if !defined(QSGBATCHRENDERER_INVALIDATE_WEDGED_NODES)
1926
1927
1928
1929
1946 case QSGGeometry::DrawTriangleStrip:
1953 case QSGGeometry::DrawLines:
1955 return iCount - (iCount % 2);
1956 case QSGGeometry::DrawTriangles:
1958 return iCount - (iCount % 3);
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
2087 if (node->type() == QSGNode::TransformNodeType)
2088 return static_cast<QSGTransformNode *>(node->sgNode)->combinedMatrix();
2089 Q_ASSERT(node->type() == QSGNode::ClipNodeType);
2090 QSGClipNode *c =
static_cast<QSGClipNode *>(node->sgNode);
2091 return *c->matrix();
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2257 Q_ASSERT_X(
false,
"uploadBatch (unmerged)",
"uint index with ushort effective index - cannot happen");
2265#ifndef QT_NO_DEBUG_OUTPUT
2271 dump <<
" --- " <<
i <<
": ";
2281 dump << *(
const float *)(
vd +
offset +
t *
sizeof(
float)) <<
" ";
2285 dump << *(
const unsigned char *)(
vd +
offset +
t *
sizeof(
unsigned char)) <<
" ";
2383 qWarning(
"Failed to build stencil clip pipeline");
2502 qWarning(
"Failed to build stencil clip vertex buffer");
2520 qWarning(
"Failed to build stencil clip index buffer");
2538 qWarning(
"Failed to build stencil clip uniform buffer");
2551 qWarning(
"Failed to build stencil clip srb");
2575 qWarning(
"updateClipState: Clip list entries have different primitive topologies, this is not currently supported.");
2577 qWarning(
"updateClipState: Clip list entries have different vertex input layouts, this is must not happen.");
2659 }
else if (
i == 1) {
2688 return f == QRhiGraphicsPipeline::ConstantColor
2689 || f == QRhiGraphicsPipeline::OneMinusConstantColor
2690 || f == QRhiGraphicsPipeline::ConstantAlpha
2691 || f == QRhiGraphicsPipeline::OneMinusConstantAlpha;
2803 qWarning(
"Failed to build graphics pipeline state");
2816static QRhiSampler *
newSampler(QRhi *rhi,
const QSGSamplerDescription &desc)
2818 QRhiSampler::Filter magFilter;
2819 QRhiSampler::Filter minFilter;
2820 QRhiSampler::Filter mipmapMode;
2821 QRhiSampler::AddressMode u;
2822 QRhiSampler::AddressMode v;
2824 switch (desc.filtering) {
2825 case QSGTexture::None:
2827 case QSGTexture::Nearest:
2828 magFilter = minFilter = QRhiSampler::Nearest;
2830 case QSGTexture::Linear:
2831 magFilter = minFilter = QRhiSampler::Linear;
2835 magFilter = minFilter = QRhiSampler::Nearest;
2839 switch (desc.mipmapFiltering) {
2840 case QSGTexture::None:
2841 mipmapMode = QRhiSampler::None;
2843 case QSGTexture::Nearest:
2844 mipmapMode = QRhiSampler::Nearest;
2846 case QSGTexture::Linear:
2847 mipmapMode = QRhiSampler::Linear;
2851 mipmapMode = QRhiSampler::None;
2855 switch (desc.horizontalWrap) {
2856 case QSGTexture::Repeat:
2857 u = QRhiSampler::Repeat;
2859 case QSGTexture::ClampToEdge:
2860 u = QRhiSampler::ClampToEdge;
2862 case QSGTexture::MirroredRepeat:
2863 u = QRhiSampler::Mirror;
2867 u = QRhiSampler::ClampToEdge;
2871 switch (desc.verticalWrap) {
2872 case QSGTexture::Repeat:
2873 v = QRhiSampler::Repeat;
2875 case QSGTexture::ClampToEdge:
2876 v = QRhiSampler::ClampToEdge;
2878 case QSGTexture::MirroredRepeat:
2879 v = QRhiSampler::Mirror;
2883 v = QRhiSampler::ClampToEdge;
2887 return rhi->newSampler(magFilter, minFilter, mipmapMode, u, v);
2911 Q_ASSERT(
int(QSGMaterialShader::GraphicsPipelineState::OneMinusSrc1Alpha) ==
int(QRhiGraphicsPipeline::OneMinusSrc1Alpha));
2912 Q_ASSERT(
int(QSGMaterialShader::GraphicsPipelineState::BlendOp::Max) ==
int(QRhiGraphicsPipeline::Max));
2913 Q_ASSERT(
int(QSGMaterialShader::GraphicsPipelineState::A) ==
int(QRhiGraphicsPipeline::A));
2914 Q_ASSERT(
int(QSGMaterialShader::GraphicsPipelineState::CullBack) ==
int(QRhiGraphicsPipeline::Back));
2915 Q_ASSERT(
int(QSGMaterialShader::GraphicsPipelineState::Line) ==
int(QRhiGraphicsPipeline::Line));
2916 dst->srcColor = QSGMaterialShader::GraphicsPipelineState::BlendFactor(src->srcColor);
2917 dst->dstColor = QSGMaterialShader::GraphicsPipelineState::BlendFactor(src->dstColor);
2925 dst->separateBlendFactors =
false;
2927 dst->srcAlpha = QSGMaterialShader::GraphicsPipelineState::BlendFactor(src->srcAlpha);
2928 dst->dstAlpha = QSGMaterialShader::GraphicsPipelineState::BlendFactor(src->dstAlpha);
2930 dst->opColor = QSGMaterialShader::GraphicsPipelineState::BlendOp(src->opColor);
2931 dst->opAlpha = QSGMaterialShader::GraphicsPipelineState::BlendOp(src->opAlpha);
2933 dst->colorWrite = QSGMaterialShader::GraphicsPipelineState::ColorMask(
int(src->colorWrite));
2935 dst->cullMode = QSGMaterialShader::GraphicsPipelineState::CullMode(src->cullMode);
2936 dst->polygonMode = QSGMaterialShader::GraphicsPipelineState::PolygonMode(src->polygonMode);
2940 QSGMaterialShader::GraphicsPipelineState *src)
2943 dst->srcColor = QRhiGraphicsPipeline::BlendFactor(src->srcColor);
2944 dst->dstColor = QRhiGraphicsPipeline::BlendFactor(src->dstColor);
2945 if (src->separateBlendFactors) {
2946 dst->srcAlpha = QRhiGraphicsPipeline::BlendFactor(src->srcAlpha);
2947 dst->dstAlpha = QRhiGraphicsPipeline::BlendFactor(src->dstAlpha);
2949 dst->srcAlpha = dst->srcColor;
2950 dst->dstAlpha = dst->dstColor;
2952 dst->opColor = QRhiGraphicsPipeline::BlendOp(src->opColor);
2953 dst->opAlpha = QRhiGraphicsPipeline::BlendOp(src->opAlpha);
2954 dst->colorWrite = QRhiGraphicsPipeline::ColorMask(
int(src->colorWrite));
2955 dst->cullMode = QRhiGraphicsPipeline::CullMode(src->cullMode);
2956 dst->polygonMode = QRhiGraphicsPipeline::PolygonMode(src->polygonMode);
3008 qWarning(
"No QSGTexture provided from updateSampledImage(). This is wrong.");
3030 qWarning(
"QSGTexture anisotropy levels are not currently supported");
3042 qWarning(
"Failed to build sampler");
3157 Q_ASSERT_X(
false,
"updateMaterialDynamicData",
"No srb action set, this cannot happen");
3197#ifndef QT_NO_DEBUG_OUTPUT
3334 qWarning(
"Line widths other than 1 are not supported by the graphics API");
3342 qWarning(
"Point size is not controllable by QSGGeometry. "
3343 "Set gl_PointSize from the vertex shader instead.");
3714 qWarning(
"prepareRenderPass() called with an already prepared render pass context");
3738 type +=
" renderlists";
3745 qDebug() <<
"Renderer::render()" <<
this <<
type;
3760 qDebug(
"Opaque render lists %s:", (
complete ?
"(complete)" :
"(partial)"));
3765 qDebug(
"Alpha render list %s:",
complete ?
"(complete)" :
"(partial)");
3790 qDebug(
"Opaque Batches:");
3798 qDebug(
"Alpha Batches:");
3941#if defined(QSGBATCHRENDERER_INVALIDATE_WEDGED_NODES)
3983 qWarning(
"recordRenderPass() called without a prepared render pass context");
4040 qDebug(
" -> times: build: %d, prepare(opaque/alpha): %d/%d, sorting: %d, upload(opaque/alpha): %d/%d, record rendering: %d",
4206 else if (
mode ==
"clip")
4208 else if (
mode ==
"overdraw")
4210 else if (
mode ==
"batches")
4212 else if (
mode ==
"changes")
4225 && a.depthFunc == b.depthFunc
4227 && a.srcColor == b.srcColor
4228 && a.dstColor == b.dstColor
4229 && a.srcAlpha == b.srcAlpha
4230 && a.dstAlpha == b.dstAlpha
4231 && a.opColor == b.opColor
4232 && a.opAlpha == b.opAlpha
4233 && a.colorWrite == b.colorWrite
4234 && a.cullMode == b.cullMode
4238 && a.drawMode == b.drawMode
4240 && a.polygonMode == b.polygonMode
4267 return a.state == b.state
4268 && a
.sms->materialShader == b
.sms->materialShader
4269 && a.renderTargetDescription == b.renderTargetDescription
4270 && a.srbLayoutDescription == b.srbLayoutDescription;
4280 return qHash(k.state, seed)
4281 ^ qHash(k.sms->materialShader)
4282 ^ k.extra.renderTargetDescriptionHash
4283 ^ k.extra.srbLayoutDescriptionHash;
4288 return a.type == b.type
4289 && a.renderMode == b.renderMode
4300 return qHash(k.type, seed) ^
int(k.renderMode) ^ k.multiViewCount;
4313#define QSGNODE_DIRTY_PARENT (QSGNode::DirtyNodeAdded
4314 | QSGNode::DirtyOpacity
4315 | QSGNode::DirtyMatrix
4316 | QSGNode::DirtyNodeRemoved)
4321 uint selfDirty = n->dirtyState | parentChanges;
4322 if (n->type() == QSGNode::GeometryNodeType && selfDirty != 0)
4323 m_visualizeChangeSet.insert(n, selfDirty);
4325 visualizeChangesPrepare(child, childDirty);
4333#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 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