yum-mirror/glslang
git clone https://git.yummers.dev/yum-mirror/glslang
c8ec3690
main
1// Copyright (C) 2026 The Khronos Group Inc. 2// 3// All rights reserved. 4// 5// Redistribution and use in source and binary forms, with or without 6// modification, are permitted provided that the following conditions 7// are met: 8// 9// Redistributions of source code must retain the above copyright 10// notice, this list of conditions and the following disclaimer. 11// 12// Redistributions in binary form must reproduce the above 13// copyright notice, this list of conditions and the following 14// disclaimer in the documentation and/or other materials provided 15// with the distribution. 16// 17// Neither the name of The Khronos Group Inc. nor the names of its 18// contributors may be used to endorse or promote products derived 19// from this software without specific prior written permission. 20// 21// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 31// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32// POSSIBILITY OF SUCH DAMAGE. 33 34#include "TestFixture.h" 35#include "glslang/Public/ShaderLang.h" 36#include "SPIRV/GlslangToSpv.h" 37#include "SPIRV/disassemble.h" 38#include <gtest/gtest.h> 39#include <sstream> 40#include <string> 41#include <vector> 42 43namespace glslangtest { 44 45class DiscardTest :public ::testing::Test { 46protected : 47struct CompileResult { 48bool success ; 49 std::string spirvText ; 50 std::string infoLog ; 51 }; 52 53CompileResult compileGlsl (const std::string & source , glslang::EShTargetLanguageVersion spvVersion , 54bool discardIsTerminate ) 55 { 56const char * const src = source .c_str (); 57 58 glslang::TShader shader (EShLangFragment ); 59shader .setStrings (& src ,1 ); 60shader .setEnvInput (glslang::EShSourceGlsl ,EShLangFragment , glslang::EShClientVulkan ,100 ); 61shader .setEnvClient (glslang::EShClientVulkan , glslang::EShTargetVulkan_1_4 ); 62shader .setEnvTarget (glslang::EShTargetSpv ,spvVersion ); 63shader .setAutoMapBindings (true); 64shader .setAutoMapLocations (true); 65shader .setDiscardIsTerminate (discardIsTerminate ); 66 67const EShMessages msgs = static_cast < EShMessages > (EShMsgSpvRules |EShMsgVulkanRules ); 68if (!shader .parse (GetDefaultResources (),450 , false,msgs )) { 69return {false,"" ,shader .getInfoLog ()}; 70 } 71 72 glslang::TProgram program ; 73program .addShader (& shader ); 74if (!program .link (msgs )) { 75return {false,"" ,program .getInfoLog ()}; 76 } 77 78 std::vector < uint32_t > spirv ; 79 glslang::GlslangToSpv (* program .getIntermediate (EShLangFragment ),spirv ); 80 81 std::ostringstream dis ; 82 spv::Disassemble (dis ,spirv ); 83return {true,dis .str (),"" }; 84 } 85 86// Helper function to check if the given SPIR-V string contains a specific pattern. 87static bool containsPattern (const std::string & spirvText ,const std::string & pattern ) 88 { 89return spirvText .find (pattern )!= std::string::npos ; 90 } 91}; 92 93static const char kSimpleFrag []= R"glsl( 94#version 450 95uniform sampler2D tex ; 96in vec2 texCoord ; 97out vec4 outColor ; 98void main () { 99outColor = texture ( tex , texCoord ); 100if ( outColor . a == 0.0 ) 101discard ; 102} 103)glsl" ; 104 105TEST_F (DiscardTest ,DiscardMappedToOpKill ) 106{ 107const bool discardIsTerminate = false; 108auto const r = compileGlsl (kSimpleFrag , glslang::EShTargetSpv_1_4 ,discardIsTerminate ); 109ASSERT_TRUE (r .success ) <<r .infoLog ; 110EXPECT_TRUE (containsPattern (r .spirvText ,"Kill" )) 111 <<"Expected OpKill in SPIR-V when SPIR-V version < 1.6 is used.\n" 112 <<r .spirvText ; 113EXPECT_FALSE (containsPattern (r .spirvText ,"DemoteToHelperInvocation" )) 114 <<"Did not expect OpDemoteToHelperInvocation in SPIR-V when SPIR-V version < 1.6 is used.\n" 115 <<r .spirvText ; 116EXPECT_FALSE (containsPattern (r .spirvText ,"TerminateInvocation" )) 117 <<"Did not expect OpTerminateInvocation in SPIR-V when SPIR-V version < 1.6 is used.\n" 118 <<r .spirvText ; 119} 120 121TEST_F (DiscardTest ,DiscardMappedToOpDemoteToHelperInvocation ) 122{ 123const bool discardIsTerminate = false; 124auto const r = compileGlsl (kSimpleFrag , glslang::EShTargetSpv_1_6 ,discardIsTerminate ); 125ASSERT_TRUE (r .success ) <<r .infoLog ; 126EXPECT_FALSE (containsPattern (r .spirvText ,"Kill" )) 127 <<"Did not expect OpKill in SPIR-V when SPIR-V version >= 1.6 is used.\n" 128 <<r .spirvText ; 129EXPECT_TRUE (containsPattern (r .spirvText ,"DemoteToHelperInvocation" )) 130 <<"Expected OpDemoteToHelperInvocation in SPIR-V when setDiscardIsTerminate(false) is used.\n" 131 <<r .spirvText ; 132EXPECT_FALSE (containsPattern (r .spirvText ,"TerminateInvocation" )) 133 <<"Did not expect OpTerminateInvocation in SPIR-V when setDiscardIsTerminate(false) is used.\n" 134 <<r .spirvText ; 135} 136 137TEST_F (DiscardTest ,DiscardMappedToOpTerminateInvocation ) 138{ 139const bool discardIsTerminate = true; 140auto const r = compileGlsl (kSimpleFrag , glslang::EShTargetSpv_1_6 ,discardIsTerminate ); 141ASSERT_TRUE (r .success ) <<r .infoLog ; 142EXPECT_FALSE (containsPattern (r .spirvText ,"Kill" )) 143 <<"Did not expect OpKill in SPIR-V when SPIR-V version >= 1.6 is used.\n" 144 <<r .spirvText ; 145EXPECT_FALSE (containsPattern (r .spirvText ,"DemoteToHelperInvocation" )) 146 <<"Did not expect OpDemoteToHelperInvocation in SPIR-V when setDiscardIsTerminate(true) is used.\n" 147 <<r .spirvText ; 148EXPECT_TRUE (containsPattern (r .spirvText ,"TerminateInvocation" )) 149 <<"Expected OpTerminateInvocation in SPIR-V when setDiscardIsTerminate(true) is used.\n" 150 <<r .spirvText ; 151} 152 153}// namespace glslangtest