diff options
-rw-r--r-- | src/render/shadergraph/qshadergenerator.cpp | 86 | ||||
-rw-r--r-- | tests/auto/render/shaderbuilder/output.es2 | 4 | ||||
-rw-r--r-- | tests/auto/render/shaderbuilder/output.gl3 | 10 | ||||
-rw-r--r-- | tests/auto/render/shadergraph/qshadergenerator/tst_qshadergenerator.cpp | 153 |
4 files changed, 111 insertions, 142 deletions
diff --git a/src/render/shadergraph/qshadergenerator.cpp b/src/render/shadergraph/qshadergenerator.cpp index 92c69be72..f80502fcc 100644 --- a/src/render/shadergraph/qshadergenerator.cpp +++ b/src/render/shadergraph/qshadergenerator.cpp @@ -295,30 +295,18 @@ namespace return result; } - bool intersectsEnabledLayers(const QStringList &enabledLayers, const QStringList &layers) noexcept - { - return layers.isEmpty() - || std::any_of(layers.cbegin(), layers.cend(), - [enabledLayers](const QString &s) { return enabledLayers.contains(s); }); - } - struct ShaderGenerationState { - ShaderGenerationState(const QShaderGenerator & gen, QStringList layers, QVector<QShaderNode> nodes) - : generator{gen} - , enabledLayers{layers} - , nodes{nodes} + ShaderGenerationState(const QShaderGenerator &gen, + QVector<QShaderGraph::Statement> statements) + : generator { gen }, statements { statements } { } const QShaderGenerator &generator; - QStringList enabledLayers; - QVector<QShaderNode> nodes; + QVector<QShaderGraph::Statement> statements; QByteArrayList code; - - QVector<QString> globalInputVariables; - const QRegularExpression globalInputExtractRegExp { QStringLiteral("^.*\\s+(\\w+).*;$") }; }; class GLSL45HeaderWriter @@ -328,31 +316,22 @@ namespace { const auto &format = state.generator.format; auto &code = state.code; - for (const QShaderNode &node : state.nodes) { - if (intersectsEnabledLayers(state.enabledLayers, node.layers())) { - const QByteArrayList& headerSnippets = node.rule(format).headerSnippets; - for (const QByteArray &snippet : headerSnippets) { - auto replacedSnippet = replaceParameters(snippet, node, format).trimmed(); - - if (replacedSnippet.startsWith(QByteArrayLiteral("add-input"))) { - onInOut(code, replacedSnippet); - } else if (replacedSnippet.startsWith(QByteArrayLiteral("add-uniform"))) { - onNamedUniform(ubo, replacedSnippet); - } else if (replacedSnippet.startsWith(QByteArrayLiteral("add-sampler"))) { - onNamedSampler(code, replacedSnippet); - } else if (replacedSnippet.startsWith(QByteArrayLiteral("#pragma include "))) { - onInclude(code, replacedSnippet); - } else { - code << replacedSnippet; - } - // If node is an input, record the variable name into the globalInputVariables - // vector - if (node.type() == QShaderNode::Input) { - const QRegularExpressionMatch match = state.globalInputExtractRegExp.match( - QString::fromUtf8(code.last())); - if (match.hasMatch()) - state.globalInputVariables.push_back(match.captured(1)); - } + for (const QShaderGraph::Statement &statement : state.statements) { + const QShaderNode &node = statement.node; + const QByteArrayList &headerSnippets = node.rule(format).headerSnippets; + for (const QByteArray &snippet : headerSnippets) { + auto replacedSnippet = replaceParameters(snippet, node, format).trimmed(); + + if (replacedSnippet.startsWith(QByteArrayLiteral("add-input"))) { + onInOut(code, replacedSnippet); + } else if (replacedSnippet.startsWith(QByteArrayLiteral("add-uniform"))) { + onNamedUniform(ubo, replacedSnippet); + } else if (replacedSnippet.startsWith(QByteArrayLiteral("add-sampler"))) { + onNamedSampler(code, replacedSnippet); + } else if (replacedSnippet.startsWith(QByteArrayLiteral("#pragma include "))) { + onInclude(code, replacedSnippet); + } else { + code << replacedSnippet; } } } @@ -483,21 +462,11 @@ namespace { const auto &format = state.generator.format; auto &code = state.code; - for (const QShaderNode &node : state.nodes) { - if (intersectsEnabledLayers(state.enabledLayers, node.layers())) { - const QByteArrayList& headerSnippets = node.rule(format).headerSnippets; - for (const QByteArray &snippet : headerSnippets) { - code << replaceParameters(snippet, node, format); - - // If node is an input, record the variable name into the globalInputVariables - // vector - if (node.type() == QShaderNode::Input) { - const QRegularExpressionMatch match = state.globalInputExtractRegExp.match( - QString::fromUtf8(code.last())); - if (match.hasMatch()) - state.globalInputVariables.push_back(match.captured(1)); - } - } + for (const QShaderGraph::Statement &statement : state.statements) { + const QShaderNode &node = statement.node; + const QByteArrayList &headerSnippets = node.rule(format).headerSnippets; + for (const QByteArray &snippet : headerSnippets) { + code << replaceParameters(snippet, node, format); } } } @@ -543,7 +512,8 @@ namespace QByteArray QShaderGenerator::createShaderCode(const QStringList &enabledLayers) const { const QVector<QShaderNode> nodes = graph.nodes(); - ShaderGenerationState state(*this, enabledLayers, nodes); + const auto statements = graph.createStatements(enabledLayers); + ShaderGenerationState state(*this, statements); QByteArrayList &code = state.code; code << versionString(format); @@ -670,7 +640,7 @@ QByteArray QShaderGenerator::createShaderCode(const QStringList &enabledLayers) } }; - for (const QShaderGraph::Statement &statement : graph.createStatements(enabledLayers)) { + for (const QShaderGraph::Statement &statement : statements) { const QShaderNode node = statement.node; QByteArray line = node.rule(format).substitution; const QVector<QShaderNodePort> ports = node.ports(); diff --git a/tests/auto/render/shaderbuilder/output.es2 b/tests/auto/render/shaderbuilder/output.es2 index 0298e7e51..ce0413614 100644 --- a/tests/auto/render/shaderbuilder/output.es2 +++ b/tests/auto/render/shaderbuilder/output.es2 @@ -1,9 +1,9 @@ #version 100 -varying highp vec3 worldPosition; -uniform sampler2D texture; varying highp vec2 texCoord; +uniform sampler2D texture; uniform highp float lightIntensity; +varying highp vec3 worldPosition; uniform highp float exposure; highp vec4 lightModel(const in highp vec3 baseColor, const in highp vec3 pos, diff --git a/tests/auto/render/shaderbuilder/output.gl3 b/tests/auto/render/shaderbuilder/output.gl3 index 4c9fd1064..e0951deee 100644 --- a/tests/auto/render/shaderbuilder/output.gl3 +++ b/tests/auto/render/shaderbuilder/output.gl3 @@ -1,11 +1,10 @@ #version 150 core -in vec3 worldPosition; -uniform sampler2D texture; in vec2 texCoord; +uniform sampler2D texture; uniform float lightIntensity; +in vec3 worldPosition; uniform float exposure; -out vec4 fragColor; vec4 lightModel(const in vec3 baseColor, const in vec3 pos, const in float intensity) @@ -13,7 +12,7 @@ vec4 lightModel(const in vec3 baseColor, ... } -#line 10 +#line 9 vec4 lightModel(const in vec3 baseColor, const in vec3 pos, const in float intensity) @@ -21,7 +20,8 @@ vec4 lightModel(const in vec3 baseColor, ... } -#line 12 +#line 11 +out vec4 fragColor; void main() { diff --git a/tests/auto/render/shadergraph/qshadergenerator/tst_qshadergenerator.cpp b/tests/auto/render/shadergraph/qshadergenerator/tst_qshadergenerator.cpp index 90906f4e9..e386ae09f 100644 --- a/tests/auto/render/shadergraph/qshadergenerator/tst_qshadergenerator.cpp +++ b/tests/auto/render/shadergraph/qshadergenerator/tst_qshadergenerator.cpp @@ -233,32 +233,36 @@ void tst_QShaderGenerator::shouldGenerateShaderCode_data() const auto versionGL32 = QByteArrayList() << "#version 150 core" << ""; const auto versionGL4 = QByteArrayList() << "#version 400 core" << ""; - const auto es2Code = QByteArrayList() << "varying highp vec3 worldPosition;" - << "uniform sampler2D texture;" - << "varying highp vec2 texCoord;" - << "uniform highp float lightIntensity;" - << "uniform highp float exposure;" - << "#pragma include es2/lightmodel.frag.inc" - << "" - << "void main()" - << "{" - << " gl_fragColor = (((((lightModel(((texture2D(texture, texCoord))), worldPosition, lightIntensity)))) * pow(2.0, exposure)));" - << "}" - << ""; - - const auto gl3Code = QByteArrayList() << "in vec3 worldPosition;" - << "uniform sampler2D texture;" - << "in vec2 texCoord;" - << "uniform float lightIntensity;" - << "uniform float exposure;" - << "out vec4 fragColor;" - << "#pragma include gl3/lightmodel.frag.inc" - << "" - << "void main()" - << "{" - << " fragColor = (((((lightModel(((texture(texture, texCoord))), worldPosition, lightIntensity)))) * pow(2.0, exposure)));" - << "}" - << ""; + const auto es2Code = QByteArrayList() + << "varying highp vec2 texCoord;" + << "uniform sampler2D texture;" + << "uniform highp float lightIntensity;" + << "varying highp vec3 worldPosition;" + << "uniform highp float exposure;" + << "#pragma include es2/lightmodel.frag.inc" + << "" + << "void main()" + << "{" + << " gl_fragColor = (((((lightModel(((texture2D(texture, texCoord))), " + "worldPosition, lightIntensity)))) * pow(2.0, exposure)));" + << "}" + << ""; + + const auto gl3Code = QByteArrayList() + << "in vec2 texCoord;" + << "uniform sampler2D texture;" + << "uniform float lightIntensity;" + << "in vec3 worldPosition;" + << "uniform float exposure;" + << "#pragma include gl3/lightmodel.frag.inc" + << "out vec4 fragColor;" + << "" + << "void main()" + << "{" + << " fragColor = (((((lightModel(((texture(texture, texCoord))), worldPosition, " + "lightIntensity)))) * pow(2.0, exposure)));" + << "}" + << ""; QTest::newRow("EmptyGraphAndFormat") << QShaderGraph() << QShaderFormat() << QByteArrayLiteral("\n\n\nvoid main()\n{\n}\n"); QTest::newRow("LightExposureGraphAndES2") << graph << openGLES2 << (versionGLES2 + es2Code).join('\n'); @@ -712,7 +716,6 @@ void tst_QShaderGenerator::shouldProcessLanguageQualifierAndTypeEnums_data() const auto gl2Code = (QByteArrayList() << "#version 110" << "" - << "attribute vec4 vertexPosition;" << "" << "void main()" << "{" @@ -720,7 +723,6 @@ void tst_QShaderGenerator::shouldProcessLanguageQualifierAndTypeEnums_data() << "").join("\n"); const auto gl3Code = (QByteArrayList() << "#version 130" << "" - << "in vec4 vertexPosition;" << "" << "void main()" << "{" @@ -728,7 +730,6 @@ void tst_QShaderGenerator::shouldProcessLanguageQualifierAndTypeEnums_data() << "").join("\n"); const auto gl4Code = (QByteArrayList() << "#version 400 core" << "" - << "in vec4 vertexPosition;" << "" << "void main()" << "{" @@ -736,7 +737,6 @@ void tst_QShaderGenerator::shouldProcessLanguageQualifierAndTypeEnums_data() << "").join("\n"); const auto es2Code = (QByteArrayList() << "#version 100" << "" - << "attribute highp vec4 vertexPosition;" << "" << "void main()" << "{" @@ -744,7 +744,6 @@ void tst_QShaderGenerator::shouldProcessLanguageQualifierAndTypeEnums_data() << "").join("\n"); const auto es3Code = (QByteArrayList() << "#version 300 es" << "" - << "in highp vec4 vertexPosition;" << "" << "void main()" << "{" @@ -861,8 +860,8 @@ void tst_QShaderGenerator::shouldGenerateDifferentCodeDependingOnActiveLayers() const auto expected = QByteArrayList() << "#version 400 core" << "" - << "uniform vec4 diffuseUniform;" << "uniform vec3 normalUniform;" + << "uniform vec4 diffuseUniform;" << "#pragma include gl4/lightmodel.frag.inc" << "out vec4 fragColor;" << "" @@ -879,20 +878,20 @@ void tst_QShaderGenerator::shouldGenerateDifferentCodeDependingOnActiveLayers() const auto code = generator.createShaderCode({"diffuseUniform", "normalTexture"}); // THEN - const auto expected = QByteArrayList() - << "#version 400 core" - << "" - << "in vec2 texCoord;" - << "uniform vec4 diffuseUniform;" - << "uniform sampler2D normalTexture;" - << "#pragma include gl4/lightmodel.frag.inc" - << "out vec4 fragColor;" - << "" - << "void main()" - << "{" - << " fragColor = ((lightModel(diffuseUniform, texture2D(normalTexture, texCoord).rgb)));" - << "}" - << ""; + const auto expected = QByteArrayList() << "#version 400 core" + << "" + << "in vec2 texCoord;" + << "uniform sampler2D normalTexture;" + << "uniform vec4 diffuseUniform;" + << "#pragma include gl4/lightmodel.frag.inc" + << "out vec4 fragColor;" + << "" + << "void main()" + << "{" + << " fragColor = ((lightModel(diffuseUniform, " + "texture2D(normalTexture, texCoord).rgb)));" + << "}" + << ""; QCOMPARE(code, expected.join("\n")); } @@ -905,14 +904,15 @@ void tst_QShaderGenerator::shouldGenerateDifferentCodeDependingOnActiveLayers() << "#version 400 core" << "" << "in vec2 texCoord;" - << "uniform sampler2D diffuseTexture;" << "uniform vec3 normalUniform;" + << "uniform sampler2D diffuseTexture;" << "#pragma include gl4/lightmodel.frag.inc" << "out vec4 fragColor;" << "" << "void main()" << "{" - << " fragColor = ((lightModel(texture2D(diffuseTexture, texCoord), normalUniform)));" + << " fragColor = ((lightModel(texture2D(diffuseTexture, texCoord), " + "normalUniform)));" << "}" << ""; QCOMPARE(code, expected.join("\n")); @@ -927,14 +927,15 @@ void tst_QShaderGenerator::shouldGenerateDifferentCodeDependingOnActiveLayers() << "#version 400 core" << "" << "in vec2 texCoord;" - << "uniform sampler2D diffuseTexture;" << "uniform sampler2D normalTexture;" + << "uniform sampler2D diffuseTexture;" << "#pragma include gl4/lightmodel.frag.inc" << "out vec4 fragColor;" << "" << "void main()" << "{" - << " fragColor = ((lightModel(texture2D(diffuseTexture, texCoord), texture2D(normalTexture, texCoord).rgb)));" + << " fragColor = ((lightModel(texture2D(diffuseTexture, texCoord), " + "texture2D(normalTexture, texCoord).rgb)));" << "}" << ""; QCOMPARE(code, expected.join("\n")); @@ -1166,20 +1167,19 @@ void tst_QShaderGenerator::shouldGenerateTemporariesWisely() const auto code = generator.createShaderCode(); // THEN - const auto expected = QByteArrayList() - << "#version 400 core" - << "" - << "in vec4 vertexPosition;" - << "out vec4 shaderOutput1;" - << "out vec4 shaderOutput2;" - << "" - << "void main()" - << "{" - << " vec4 v1 = vertexPosition * 2.0;" - << " shaderOutput2 = v1;" - << " shaderOutput1 = v1;" - << "}" - << ""; + const auto expected = QByteArrayList() << "#version 400 core" + << "" + << "in vec4 vertexPosition;" + << "out vec4 shaderOutput2;" + << "out vec4 shaderOutput1;" + << "" + << "void main()" + << "{" + << " vec4 v1 = vertexPosition * 2.0;" + << " shaderOutput2 = v1;" + << " shaderOutput1 = v1;" + << "}" + << ""; QCOMPARE(code, expected.join("\n")); } @@ -1218,8 +1218,8 @@ void tst_QShaderGenerator::shouldGenerateTemporariesWisely() << "#version 400 core" << "" << "in vec4 vertexPosition;" - << "out vec4 shaderOutput1;" << "out vec4 shaderOutput2;" + << "out vec4 shaderOutput1;" << "" << "void main()" << "{" @@ -1287,18 +1287,17 @@ void tst_QShaderGenerator::shouldHandlePortNamesPrefixingOneAnother() 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));" - << "}" - << ""; + const auto expected = QByteArrayList() << "#version 400 core" + << "" + << "in vec4 color2;" + << "in vec4 color1;" + << "out vec4 shaderOutput;" + << "" + << "void main()" + << "{" + << " shaderOutput = ((color1 + color2));" + << "}" + << ""; QCOMPARE(code, expected.join("\n")); } |