From 49dbe760e4e0d8a781b5336efdce4748a7d73a33 Mon Sep 17 00:00:00 2001 From: Nicolas Guichard Date: Fri, 14 Feb 2020 12:50:00 +0100 Subject: Fix QShaderGenerator crashing when a node port name prefixed another one QShaderGenerator didn't handle substitutions like `vec4 $color = mix($color1, $color2, $fac);` Note that `$color` is a prefix to `$color1` and `$color2`. For the substitution `QByteArray::replace` was used so if `$color` was handled first and replaced by `v1`, `$color1` and `$color2` were never correctly replaced and instead became `v11` and `v12` which caused a crash later on. Change-Id: Idaf800fdac468f33c323eb722701da5f8eb918d6 Reviewed-by: Paul Lemire --- .../util/qshadergenerator/tst_qshadergenerator.cpp | 70 ++++++++++++++++++++++ 1 file changed, 70 insertions(+) (limited to 'tests/auto') diff --git a/tests/auto/gui/util/qshadergenerator/tst_qshadergenerator.cpp b/tests/auto/gui/util/qshadergenerator/tst_qshadergenerator.cpp index 59e93d127f..2b9b08a18a 100644 --- a/tests/auto/gui/util/qshadergenerator/tst_qshadergenerator.cpp +++ b/tests/auto/gui/util/qshadergenerator/tst_qshadergenerator.cpp @@ -198,6 +198,7 @@ private slots: void shouldGenerateDifferentCodeDependingOnActiveLayers(); void shouldUseGlobalVariableRatherThanTemporaries(); void shouldGenerateTemporariesWisely(); + void shouldHandlePortNamesPrefixingOneAnother(); }; void tst_QShaderGenerator::shouldHaveDefaultState() @@ -1229,6 +1230,75 @@ void tst_QShaderGenerator::shouldGenerateTemporariesWisely() } } +void tst_QShaderGenerator::shouldHandlePortNamesPrefixingOneAnother() +{ + // GIVEN + const auto gl4 = createFormat(QShaderFormat::OpenGLCoreProfile, 4, 0); + + auto color1 = createNode({ + createPort(QShaderNodePort::Output, "output") + }); + color1.addRule(gl4, QShaderNode::Rule("vec4 $output = color1;", + QByteArrayList() << "in vec4 color1;")); + + auto color2 = createNode({ + createPort(QShaderNodePort::Output, "output") + }); + color2.addRule(gl4, QShaderNode::Rule("vec4 $output = color2;", + QByteArrayList() << "in vec4 color2;")); + + auto addColor = createNode({ + createPort(QShaderNodePort::Output, "color"), + createPort(QShaderNodePort::Input, "color1"), + createPort(QShaderNodePort::Input, "color2"), + }); + addColor.addRule(gl4, QShaderNode::Rule("vec4 $color = $color1 + $color2;")); + + auto shaderOutput = createNode({ + createPort(QShaderNodePort::Input, "input") + }); + + shaderOutput.addRule(gl4, QShaderNode::Rule("shaderOutput = $input;", + QByteArrayList() << "out vec4 shaderOutput;")); + + // WHEN + const auto graph = [=] { + auto res = QShaderGraph(); + + res.addNode(color1); + res.addNode(color2); + res.addNode(addColor); + res.addNode(shaderOutput); + + res.addEdge(createEdge(color1.uuid(), "output", addColor.uuid(), "color1")); + res.addEdge(createEdge(color2.uuid(), "output", addColor.uuid(), "color2")); + res.addEdge(createEdge(addColor.uuid(), "color", shaderOutput.uuid(), "input")); + + return res; + }(); + + auto generator = QShaderGenerator(); + generator.graph = graph; + generator.format = gl4; + + const auto code = generator.createShaderCode(); + + // THEN + const auto expected = QByteArrayList() + << "#version 400 core" + << "" + << "in vec4 color1;" + << "in vec4 color2;" + << "out vec4 shaderOutput;" + << "" + << "void main()" + << "{" + << " shaderOutput = ((color1 + color2));" + << "}" + << ""; + QCOMPARE(code, expected.join("\n")); +} + QTEST_MAIN(tst_QShaderGenerator) #include "tst_qshadergenerator.moc" -- cgit v1.2.3 From 7981dbfaf371a368fbd69e935768b310f42a0e5a Mon Sep 17 00:00:00 2001 From: Nicolas Guichard Date: Wed, 19 Feb 2020 12:38:27 +0100 Subject: QShaderGraph: don't generate statements with undefined inputs This fixes the shader generation for graphs like this one: Function0 ------> Output0 (with unbound input) Input ------> Function1 ------> Output1 With those graphs, createStatements will not return any statement for nodes Function0 and Output0. Change-Id: Iec32aa51623e176b03ae23e580f06d14df80a194 Reviewed-by: Paul Lemire --- tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'tests/auto') diff --git a/tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp b/tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp index 50c925a111..014a163f58 100644 --- a/tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp +++ b/tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp @@ -516,12 +516,9 @@ void tst_QShaderGraph::shouldHandleUnboundPortsDuringGraphSerialization() const auto statements = graph.createStatements(); // THEN - // Note that no edge leads to the unbound input + // Note that no statement has any unbound input const auto expected = QVector() - << createStatement(input, {}, {0}) - << createStatement(function, {-1, 0, -1}, {2, 3, 4}) - << createStatement(unboundOutput, {-1}, {}) - << createStatement(output, {3}, {}); + << createStatement(input, {}, {0}); dumpStatementsIfNeeded(statements, expected); QCOMPARE(statements, expected); } @@ -568,9 +565,8 @@ void tst_QShaderGraph::shouldSurviveCyclesDuringGraphSerialization() const auto statements = graph.createStatements(); // THEN - // Obviously will lead to a compile failure later on since it cuts everything beyond the cycle - const auto expected = QVector() - << createStatement(output, {2}, {}); + // The cycle is ignored + const auto expected = QVector(); dumpStatementsIfNeeded(statements, expected); QCOMPARE(statements, expected); } -- cgit v1.2.3