From 7b89e75213568a5e44e65a30d7a609fb196ebc6d Mon Sep 17 00:00:00 2001 From: Markus Tavenrath Date: Mon, 23 Jan 2017 16:53:16 -0800 Subject: [PATCH] Use correct OriginUpperLeft when linking more than one shader. --- Test/baseResults/link1.vk.frag.out | 60 ++++++++++++++ Test/link1.vk.frag | 10 +++ Test/link2.vk.frag | 8 ++ glslang/MachineIndependent/ShaderLang.cpp | 9 +++ gtests/CMakeLists.txt | 1 + gtests/Link.FromFile.Vk.cpp | 97 +++++++++++++++++++++++ 6 files changed, 185 insertions(+) create mode 100644 Test/baseResults/link1.vk.frag.out create mode 100644 Test/link1.vk.frag create mode 100644 Test/link2.vk.frag create mode 100644 gtests/Link.FromFile.Vk.cpp diff --git a/Test/baseResults/link1.vk.frag.out b/Test/baseResults/link1.vk.frag.out new file mode 100644 index 00000000..2688e634 --- /dev/null +++ b/Test/baseResults/link1.vk.frag.out @@ -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 index 00000000..443a3205 --- /dev/null +++ b/Test/link1.vk.frag @@ -0,0 +1,10 @@ +#version 450 + +vec4 getColor(); + +out vec4 color; + +void main() +{ + color = getColor(); +} diff --git a/Test/link2.vk.frag b/Test/link2.vk.frag new file mode 100644 index 00000000..b1630cb5 --- /dev/null +++ b/Test/link2.vk.frag @@ -0,0 +1,8 @@ +#version 450 + +uniform sampler2D s2D; + +vec4 getColor() +{ + return texture(s2D, vec2(0.5)); +} diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp index dadac56a..fd7707b0 100644 --- a/glslang/MachineIndependent/ShaderLang.cpp +++ b/glslang/MachineIndependent/ShaderLang.cpp @@ -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; } diff --git a/gtests/CMakeLists.txt b/gtests/CMakeLists.txt index a06442df..c383ca07 100644 --- a/gtests/CMakeLists.txt +++ b/gtests/CMakeLists.txt @@ -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 index 00000000..6ce1fe9f --- /dev/null +++ b/gtests/Link.FromFile.Vk.cpp @@ -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 + +#include + +#include "TestFixture.h" + +namespace glslangtest { +namespace { + +using LinkTestVulkan = GlslangTest< + ::testing::TestWithParam>>; + +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> 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>({ + {"link1.vk.frag", "link2.vk.frag"}, + })), +); +// clang-format on + +} // anonymous namespace +} // namespace glslangtest