1// 2// Copyright (C) 2016-2017 Google, Inc. 3// 4// All rights reserved. 5// 6// Redistribution and use in source and binary forms, with or without 7// modification, are permitted provided that the following conditions 8// are met: 9// 10// Redistributions of source code must retain the above copyright 11// notice, this list of conditions and the following disclaimer. 12// 13// Redistributions in binary form must reproduce the above 14// copyright notice, this list of conditions and the following 15// disclaimer in the documentation and/or other materials provided 16// with the distribution. 17// 18// Neither the name of Google Inc. nor the names of its 19// contributors may be used to endorse or promote products derived 20// from this software without specific prior written permission. 21// 22// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 25// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 26// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 27// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 32// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33// POSSIBILITY OF SUCH DAMAGE. 34 35#include <memory> 36 37#include <gtest/gtest.h> 38 39#include "TestFixture.h" 40 41namespace glslangtest { 42namespace { 43 44using LinkTestVulkan = GlslangTest< 45 ::testing::TestWithParam<std::vector<std::string>>>; 46 47TEST_P(LinkTestVulkan, FromFile) 48{ 49 const auto& fileNames = GetParam(); 50 const size_t fileCount = fileNames.size(); 51 const EShMessages controls = DeriveOptions(Source::GLSL, Semantics::Vulkan, Target::AST); 52 GlslangResult result; 53 result.validationResult = false; 54 55 // Compile each input shader file. 56 bool success = true; 57 std::vector<std::unique_ptr<glslang::TShader>> shaders; 58 for (size_t i = 0; i < fileCount; ++i) { 59 std::string contents; 60 tryLoadFile(GlobalTestSettings.testRoot + "/" + fileNames[i], 61 "input", &contents); 62 shaders.emplace_back( 63 new glslang::TShader(GetShaderStage(GetSuffix(fileNames[i])))); 64 auto* shader = shaders.back().get(); 65 shader->setAutoMapLocations(true); 66 success &= compile(shader, contents, "", controls); 67 result.shaderResults.push_back( 68 {fileNames[i], shader->getInfoLog(), shader->getInfoDebugLog()}); 69 } 70 71 // Link all of them. 72 glslang::TProgram program; 73 for (const auto& shader : shaders) program.addShader(shader.get()); 74 success &= program.link(controls); 75 result.linkingOutput = program.getInfoLog(); 76 result.linkingError = program.getInfoDebugLog(); 77 78 if (success) 79 program.mapIO(); 80 81 if (success && (controls & EShMsgSpvRules)) { 82 spv::SpvBuildLogger logger; 83 std::vector<uint32_t> spirv_binary; 84 options().disableOptimizer = true; 85 glslang::GlslangToSpv(*program.getIntermediate(shaders.front()->getStage()), 86 spirv_binary, &logger, &options()); 87 88 std::ostringstream disassembly_stream; 89 spv::Parameterize(); 90 spv::Disassemble(disassembly_stream, spirv_binary); 91 result.spirvWarningsErrors = logger.getAllMessages(); 92 result.spirv = disassembly_stream.str(); 93 result.validationResult = !options().validate || logger.getAllMessages().empty(); 94 } 95 96 std::ostringstream stream; 97 outputResultToStream(&stream, result, controls); 98 99 // Check with expected results. 100 const std::string expectedOutputFname = 101 GlobalTestSettings.testRoot + "/baseResults/" + fileNames.front() + ".out"; 102 std::string expectedOutput; 103 tryLoadFile(expectedOutputFname, "expected output", &expectedOutput); 104 105 checkEqAndUpdateIfRequested(expectedOutput, stream.str(), expectedOutputFname, 106 result.spirvWarningsErrors); 107} 108 109// clang-format off 110INSTANTIATE_TEST_SUITE_P( 111 Glsl, LinkTestVulkan, 112 ::testing::ValuesIn(std::vector<std::vector<std::string>>({ 113 {"link1.vk.frag", "link2.vk.frag"}, 114 {"spv.unit1.frag", "spv.unit2.frag", "spv.unit3.frag"}, 115 {"link.vk.matchingPC.0.0.frag", "link.vk.matchingPC.0.1.frag", 116 "link.vk.matchingPC.0.2.frag"}, 117 {"link.vk.differentPC.0.0.frag", "link.vk.differentPC.0.1.frag", 118 "link.vk.differentPC.0.2.frag"}, 119 {"link.vk.differentPC.1.0.frag", "link.vk.differentPC.1.1.frag", 120 "link.vk.differentPC.1.2.frag"}, 121 {"link.vk.pcNamingValid.0.0.vert", "link.vk.pcNamingValid.0.1.vert"}, 122 {"link.vk.pcNamingInvalid.0.0.vert", "link.vk.pcNamingInvalid.0.1.vert"}, 123 {"link.vk.multiBlocksValid.0.0.vert", "link.vk.multiBlocksValid.0.1.vert"}, 124 {"link.vk.multiBlocksValid.1.0.geom", "link.vk.multiBlocksValid.1.1.geom"}, 125 {"link.vk.inconsistentGLPerVertex.0.vert", "link.vk.inconsistentGLPerVertex.0.geom"}, 126 })) 127); 128// clang-format on 129 130} // anonymous namespace 131} // namespace glslangtest 132