Use correct OriginUpperLeft when linking more than one shader.
authorMarkus Tavenrath <matavenrath@nvidia.com>
Tue, 24 Jan 2017 00:53:16 +0000 (16:53 -0800)
committerMarkus Tavenrath <matavenrath@nvidia.com>
Wed, 25 Jan 2017 20:11:16 +0000 (12:11 -0800)
Test/baseResults/link1.vk.frag.out [new file with mode: 0644]
Test/link1.vk.frag [new file with mode: 0644]
Test/link2.vk.frag [new file with mode: 0644]
glslang/MachineIndependent/ShaderLang.cpp
gtests/CMakeLists.txt
gtests/Link.FromFile.Vk.cpp [new file with mode: 0644]

diff --git a/Test/baseResults/link1.vk.frag.out b/Test/baseResults/link1.vk.frag.out
new file mode 100644 (file)
index 0000000..2688e63
--- /dev/null
@@ -0,0 +1,60 @@
+link1.vk.frag
+Warning, version 450 is not yet complete; most version-specific features are present, but some are missing.
+
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:7  Function Definition: main( (global void)
+0:7    Function Parameters: 
+0:9    Sequence
+0:9      move second child to first child (temp highp 4-component vector of float)
+0:9        'color' (out highp 4-component vector of float)
+0:9        Function Call: getColor( (global highp 4-component vector of float)
+0:?   Linker Objects
+0:?     'color' (out highp 4-component vector of float)
+
+link2.vk.frag
+Warning, version 450 is not yet complete; most version-specific features are present, but some are missing.
+
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:5  Function Definition: getColor( (global highp 4-component vector of float)
+0:5    Function Parameters: 
+0:7    Sequence
+0:7      Branch: Return with expression
+0:7        texture (global highp 4-component vector of float)
+0:7          's2D' (uniform highp sampler2D)
+0:7          Constant:
+0:7            0.500000
+0:7            0.500000
+0:?   Linker Objects
+0:?     's2D' (uniform highp sampler2D)
+
+
+Linked fragment stage:
+
+
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:7  Function Definition: main( (global void)
+0:7    Function Parameters: 
+0:9    Sequence
+0:9      move second child to first child (temp highp 4-component vector of float)
+0:9        'color' (out highp 4-component vector of float)
+0:9        Function Call: getColor( (global highp 4-component vector of float)
+0:5  Function Definition: getColor( (global highp 4-component vector of float)
+0:5    Function Parameters: 
+0:7    Sequence
+0:7      Branch: Return with expression
+0:7        texture (global highp 4-component vector of float)
+0:7          's2D' (uniform highp sampler2D)
+0:7          Constant:
+0:7            0.500000
+0:7            0.500000
+0:?   Linker Objects
+0:?     'color' (out highp 4-component vector of float)
+0:?     's2D' (uniform highp sampler2D)
+
+SPIR-V is not generated for failed compile or link
diff --git a/Test/link1.vk.frag b/Test/link1.vk.frag
new file mode 100644 (file)
index 0000000..443a320
--- /dev/null
@@ -0,0 +1,10 @@
+#version 450\r
+\r
+vec4 getColor();\r
+\r
+out vec4 color;\r
+\r
+void main()\r
+{\r
+    color = getColor();\r
+}\r
diff --git a/Test/link2.vk.frag b/Test/link2.vk.frag
new file mode 100644 (file)
index 0000000..b1630cb
--- /dev/null
@@ -0,0 +1,8 @@
+#version 450\r
+\r
+uniform sampler2D s2D;\r
+\r
+vec4 getColor()\r
+{\r
+  return texture(s2D, vec2(0.5));\r
+}\r
index dadac56..fd7707b 100644 (file)
@@ -1707,6 +1707,15 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages)
         intermediate[stage] = new TIntermediate(stage,
                                                 firstIntermediate->getVersion(),
                                                 firstIntermediate->getProfile());
+
+
+        // The new TIntermediate must use the same origin as the original TIntermediates.
+        // Otherwise linking will fail due to different coordinate systems.
+        if (firstIntermediate->getOriginUpperLeft()) {
+            intermediate[stage]->setOriginUpperLeft();
+        }
+        intermediate[stage]->setSpv(firstIntermediate->getSpv());
+
         newedIntermediate[stage] = true;
     }
 
index a06442d..c383ca0 100644 (file)
@@ -17,6 +17,7 @@ if (TARGET gmock)
     ${CMAKE_CURRENT_SOURCE_DIR}/HexFloat.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/Hlsl.FromFile.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/Link.FromFile.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/Link.FromFile.Vk.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/Pp.FromFile.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/Spv.FromFile.cpp
     # -- Remapper tests
diff --git a/gtests/Link.FromFile.Vk.cpp b/gtests/Link.FromFile.Vk.cpp
new file mode 100644 (file)
index 0000000..6ce1fe9
--- /dev/null
@@ -0,0 +1,97 @@
+//
+// Copyright (C) 2016-2017 Google, Inc.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//    Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//
+//    Redistributions in binary form must reproduce the above
+//    copyright notice, this list of conditions and the following
+//    disclaimer in the documentation and/or other materials provided
+//    with the distribution.
+//
+//    Neither the name of Google Inc. nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+
+#include <memory>
+
+#include <gtest/gtest.h>
+
+#include "TestFixture.h"
+
+namespace glslangtest {
+namespace {
+
+using LinkTestVulkan = GlslangTest<
+    ::testing::TestWithParam<std::vector<std::string>>>;
+
+TEST_P(LinkTestVulkan, FromFile)
+{
+    const auto& fileNames = GetParam();
+    const size_t fileCount = fileNames.size();
+    const EShMessages controls = DeriveOptions(Source::GLSL, Semantics::Vulkan, Target::AST);
+    GlslangResult result;
+
+    // Compile each input shader file.
+    std::vector<std::unique_ptr<glslang::TShader>> shaders;
+    for (size_t i = 0; i < fileCount; ++i) {
+        std::string contents;
+        tryLoadFile(GlobalTestSettings.testRoot + "/" + fileNames[i],
+                    "input", &contents);
+        shaders.emplace_back(
+                new glslang::TShader(GetShaderStage(GetSuffix(fileNames[i]))));
+        auto* shader = shaders.back().get();
+        compile(shader, contents, "", controls);
+        result.shaderResults.push_back(
+            {fileNames[i], shader->getInfoLog(), shader->getInfoDebugLog()});
+    }
+
+    // Link all of them.
+    glslang::TProgram program;
+    for (const auto& shader : shaders) program.addShader(shader.get());
+    program.link(controls);
+    result.linkingOutput = program.getInfoLog();
+    result.linkingError = program.getInfoDebugLog();
+
+    std::ostringstream stream;
+    outputResultToStream(&stream, result, controls);
+
+    // Check with expected results.
+    const std::string expectedOutputFname =
+        GlobalTestSettings.testRoot + "/baseResults/" + fileNames.front() + ".out";
+    std::string expectedOutput;
+    tryLoadFile(expectedOutputFname, "expected output", &expectedOutput);
+
+    checkEqAndUpdateIfRequested(expectedOutput, stream.str(), expectedOutputFname);
+}
+
+// clang-format off
+INSTANTIATE_TEST_CASE_P(
+    Glsl, LinkTestVulkan,
+    ::testing::ValuesIn(std::vector<std::vector<std::string>>({
+        {"link1.vk.frag", "link2.vk.frag"},
+    })),
+);
+// clang-format on
+
+}  // anonymous namespace
+}  // namespace glslangtest