QShaderGenerator: Allow more expressions in input nodes
Currently QShaderGenerator will crash when encountering some expressions in input nodes. For example, this node prototype would make it crash: "VERTEX_COLOR": { "outputs": ["color", "alpha"], "rules": [ "headerSnippets": ["in vec4 vertexColor;"], "substitution": "vec3 $color = vertexColor.rgb; float $alpha = vertexColor.a;" ] } Change-Id: I37abb8099d376843a4cb13228140467dc1b8f60c Reviewed-by: Paul Lemire <paul.lemire@kdab.com> (cherry picked from commit f9086ebd0198c53e8a811af47e0ff0c84d78eb30)
This commit is contained in:
parent
157be588f7
commit
8c8f4c8c48
@ -346,10 +346,9 @@ QByteArray QShaderGenerator::createShaderCode(const QStringList &enabledLayers)
|
|||||||
code << QByteArrayLiteral("void main()");
|
code << QByteArrayLiteral("void main()");
|
||||||
code << QByteArrayLiteral("{");
|
code << QByteArrayLiteral("{");
|
||||||
|
|
||||||
const QRegularExpression localToGlobalRegExp(QStringLiteral("[^;]*\\s+(\\w+)\\s*=\\s*((?:\\w+\\(.*\\))|(?:\\w+))[^;]*;"));
|
|
||||||
const QRegularExpression temporaryVariableToAssignmentRegExp(QStringLiteral("([^;]*\\s+(v\\d+))\\s*=\\s*([^;]*);"));
|
const QRegularExpression temporaryVariableToAssignmentRegExp(QStringLiteral("([^;]*\\s+(v\\d+))\\s*=\\s*([^;]*);"));
|
||||||
const QRegularExpression temporaryVariableInAssignmentRegExp(QStringLiteral("\\W*(v\\d+)\\W*"));
|
const QRegularExpression temporaryVariableInAssignmentRegExp(QStringLiteral("\\W*(v\\d+)\\W*"));
|
||||||
const QRegularExpression outputToTemporaryAssignmentRegExp(QStringLiteral("\\s*(\\w+)\\s*=\\s*([^;]*);"));
|
const QRegularExpression statementRegExp(QStringLiteral("\\s*(\\w+)\\s*=\\s*([^;]*);"));
|
||||||
|
|
||||||
struct Variable;
|
struct Variable;
|
||||||
|
|
||||||
@ -521,14 +520,12 @@ QByteArray QShaderGenerator::createShaderCode(const QStringList &enabledLayers)
|
|||||||
|
|
||||||
switch (node.type()) {
|
switch (node.type()) {
|
||||||
case QShaderNode::Input:
|
case QShaderNode::Input:
|
||||||
matches = localToGlobalRegExp.globalMatch(QString::fromUtf8(substitutionedLine));
|
case QShaderNode::Output:
|
||||||
|
matches = statementRegExp.globalMatch(QString::fromUtf8(substitutionedLine));
|
||||||
break;
|
break;
|
||||||
case QShaderNode::Function:
|
case QShaderNode::Function:
|
||||||
matches = temporaryVariableToAssignmentRegExp.globalMatch(QString::fromUtf8(substitutionedLine));
|
matches = temporaryVariableToAssignmentRegExp.globalMatch(QString::fromUtf8(substitutionedLine));
|
||||||
break;
|
break;
|
||||||
case QShaderNode::Output:
|
|
||||||
matches = outputToTemporaryAssignmentRegExp.globalMatch(QString::fromUtf8(substitutionedLine));
|
|
||||||
break;
|
|
||||||
case QShaderNode::Invalid:
|
case QShaderNode::Invalid:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -200,6 +200,7 @@ private slots:
|
|||||||
void shouldGenerateTemporariesWisely();
|
void shouldGenerateTemporariesWisely();
|
||||||
void shouldHandlePortNamesPrefixingOneAnother();
|
void shouldHandlePortNamesPrefixingOneAnother();
|
||||||
void shouldHandleNodesWithMultipleOutputPorts();
|
void shouldHandleNodesWithMultipleOutputPorts();
|
||||||
|
void shouldHandleExpressionsInInputNodes();
|
||||||
};
|
};
|
||||||
|
|
||||||
void tst_QShaderGenerator::shouldHaveDefaultState()
|
void tst_QShaderGenerator::shouldHaveDefaultState()
|
||||||
@ -1372,6 +1373,55 @@ void tst_QShaderGenerator::shouldHandleNodesWithMultipleOutputPorts()
|
|||||||
QCOMPARE(code, expected.join("\n"));
|
QCOMPARE(code, expected.join("\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QShaderGenerator::shouldHandleExpressionsInInputNodes()
|
||||||
|
{
|
||||||
|
// GIVEN
|
||||||
|
const auto gl4 = createFormat(QShaderFormat::OpenGLCoreProfile, 4, 0);
|
||||||
|
|
||||||
|
auto input = createNode({
|
||||||
|
createPort(QShaderNodePort::Output, "output")
|
||||||
|
});
|
||||||
|
input.addRule(gl4, QShaderNode::Rule("float $output = 3 + 4;"));
|
||||||
|
|
||||||
|
auto output = createNode({
|
||||||
|
createPort(QShaderNodePort::Input, "input")
|
||||||
|
});
|
||||||
|
|
||||||
|
output.addRule(gl4, QShaderNode::Rule("globalOut = $input;",
|
||||||
|
QByteArrayList() << "out float globalOut;"));
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
const auto graph = [=] {
|
||||||
|
auto res = QShaderGraph();
|
||||||
|
|
||||||
|
res.addNode(input);
|
||||||
|
res.addNode(output);
|
||||||
|
|
||||||
|
res.addEdge(createEdge(input.uuid(), "output", output.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"
|
||||||
|
<< ""
|
||||||
|
<< "out float globalOut;"
|
||||||
|
<< ""
|
||||||
|
<< "void main()"
|
||||||
|
<< "{"
|
||||||
|
<< " globalOut = 3 + 4;"
|
||||||
|
<< "}"
|
||||||
|
<< "";
|
||||||
|
QCOMPARE(code, expected.join("\n"));
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_MAIN(tst_QShaderGenerator)
|
QTEST_MAIN(tst_QShaderGenerator)
|
||||||
|
|
||||||
#include "tst_qshadergenerator.moc"
|
#include "tst_qshadergenerator.moc"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user