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 <paul.lemire@kdab.com> (cherry picked from commit 7981dbfaf371a368fbd69e935768b310f42a0e5a)
This commit is contained in:
parent
b150901525
commit
34369b5e90
@ -123,6 +123,50 @@ namespace
|
||||
}
|
||||
return targetStatement;
|
||||
}
|
||||
|
||||
void removeNodesWithUnboundInputs(QVector<QShaderGraph::Statement> &statements,
|
||||
const QVector<QShaderGraph::Edge> &allEdges)
|
||||
{
|
||||
// A node is invalid if any of its input ports is disconected
|
||||
// or connected to the output port of another invalid node.
|
||||
|
||||
// Keeps track of the edges from the nodes we know to be valid
|
||||
// to unvisited nodes
|
||||
auto currentEdges = QVector<QShaderGraph::Edge>();
|
||||
|
||||
statements.erase(std::remove_if(statements.begin(),
|
||||
statements.end(),
|
||||
[¤tEdges, &allEdges] (const QShaderGraph::Statement &statement) {
|
||||
const QShaderNode &node = statement.node;
|
||||
const QVector<QShaderGraph::Edge> outgoing = outgoingEdges(currentEdges, node.uuid());
|
||||
const QVector<QShaderNodePort> ports = node.ports();
|
||||
|
||||
bool allInputsConnected = true;
|
||||
for (const QShaderNodePort &port : node.ports()) {
|
||||
if (port.direction == QShaderNodePort::Output)
|
||||
continue;
|
||||
|
||||
const auto edgeIt = std::find_if(outgoing.cbegin(),
|
||||
outgoing.cend(),
|
||||
[&port] (const QShaderGraph::Edge &edge) {
|
||||
return edge.targetPortName == port.name;
|
||||
});
|
||||
|
||||
if (edgeIt != outgoing.cend())
|
||||
currentEdges.removeAll(*edgeIt);
|
||||
else
|
||||
allInputsConnected = false;
|
||||
}
|
||||
|
||||
if (allInputsConnected) {
|
||||
const QVector<QShaderGraph::Edge> incoming = incomingEdges(allEdges, node.uuid());
|
||||
currentEdges.append(incoming);
|
||||
}
|
||||
|
||||
return !allInputsConnected;
|
||||
}),
|
||||
statements.end());
|
||||
}
|
||||
}
|
||||
|
||||
QUuid QShaderGraph::Statement::uuid() const Q_DECL_NOTHROW
|
||||
@ -248,6 +292,9 @@ QVector<QShaderGraph::Statement> QShaderGraph::createStatements(const QStringLis
|
||||
}
|
||||
|
||||
std::reverse(result.begin(), result.end());
|
||||
|
||||
removeNodesWithUnboundInputs(result, enabledEdges);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -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<QShaderGraph::Statement>()
|
||||
<< 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<QShaderGraph::Statement>()
|
||||
<< createStatement(output, {2}, {});
|
||||
// The cycle is ignored
|
||||
const auto expected = QVector<QShaderGraph::Statement>();
|
||||
dumpStatementsIfNeeded(statements, expected);
|
||||
QCOMPARE(statements, expected);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user