yum-mirror/glslang
git clone https://git.yummers.dev/yum-mirror/glslang
0f2400cd
main
1// Copyright (C) 2025 NVIDIA Corporation 2// 3// Permission is hereby granted, free of charge, to any person obtaining a copy 4// of this software and associated documentation files (the "Software"), to deal 5// in the Software without restriction, including without limitation the rights 6// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7// copies of the Software, and to permit persons to whom the Software is 8// furnished to do so, subject to the following conditions: 9// 10// The above copyright notice and this permission notice shall be included in all 11// copies or substantial portions of the Software. 12// 13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19// SOFTWARE. 20 21#include "TestFixture.h" 22#include "glslang/Public/ResourceLimits.h" 23#include <gtest/gtest.h> 24#include <regex> 25#include <sstream> 26#include <string> 27 28namespace glslangtest { 29 30class SpvPatternTest :public ::testing::Test { 31protected : 32void SetUp ()override 33 { 34// Set up any common test state. 35 } 36 37void TearDown ()override 38 { 39// Clean up any common test state. 40 } 41 42// Helper function to compile shader and get SPIR-V disassembly. 43 std::string compileShaderToSpirv (const std::string & shaderSource ,EShLanguage stage ) 44 { 45 glslang::TShader shader (stage ); 46 glslang::TProgram program ; 47 48// Compile the shader 49const char * shaderStrings = shaderSource .c_str (); 50shader .setStrings (& shaderStrings ,1 ); 51 52if (!shader .parse (GetDefaultResources (),450 , false,EShMsgDefault )) { 53return "COMPILATION_FAILED: " + std::string (shader .getInfoLog ()); 54 } 55 56program .addShader (& shader ); 57if (!program .link (EShMsgDefault )) { 58return "LINKING_FAILED: " + std::string (program .getInfoLog ()); 59 } 60 61// Generate SPIR-V. 62 std::vector < uint32_t > spirv ; 63 glslang::GlslangToSpv (* program .getIntermediate (stage ),spirv ); 64 65// Disassemble SPIR-V to text. 66 std::ostringstream disassembly_stream ; 67 spv::Disassemble (disassembly_stream ,spirv ); 68 69return disassembly_stream .str (); 70 } 71 72// Helper function to check if the given SPIR-V string contains a specific pattern. 73bool containsPattern (const std::string & spirvText ,const std::string & pattern ) 74 { 75return spirvText .find (pattern )!= std::string::npos ; 76 } 77 78// Helper function to check if the given SPIR-V string contains a UConvert instruction. 79bool containsUConvert (const std::string & spirvText ) {return containsPattern (spirvText ,"UConvert" ); } 80}; 81 82// Test 1: Indexing an array with a regular int or uint should not generate a zero extension. 83TEST_F (SpvPatternTest ,RegularIntUintArrayIndexNoConversion ) 84{ 85const std::string shaderSource = R"( 86#version 450 core 87 88layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; 89 90void main() { 91uint u = 150u; 92int i = 100; 93float arr[200]; 94float x = arr[u]; // Regular uint index 95float y = arr[i]; // Regular int index 96} 97)" ; 98 99 std::string spirv = compileShaderToSpirv (shaderSource ,EShLangCompute ); 100 101// Check that the SPIR-V does NOT contain conversion instructions for regular int/uint indices. 102EXPECT_FALSE (containsUConvert (spirv )) 103 <<"SPIR-V should not contain OpUConvert instruction for regular int/uint array indexing.\n" 104 <<"Generated SPIR-V:\n" 105 <<spirv ; 106} 107 108// Test 2: Indexing an array with a variable index of type uint8_t should generate a zero extension. 109TEST_F (SpvPatternTest ,Uint8VariableIndexGeneratesUConvert ) 110{ 111const std::string shaderSource = R"( 112#version 450 core 113#extension GL_EXT_shader_explicit_arithmetic_types : enable 114 115layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; 116 117void main() { 118uint8_t u8 = uint8_t(150); 119float arr[200]; 120float x = arr[u8]; // Variable uint8_t index 121} 122)" ; 123 124 std::string spirv = compileShaderToSpirv (shaderSource ,EShLangCompute ); 125 126// Check that the SPIR-V contains OpUConvert instruction for variable uint8_t index. 127EXPECT_TRUE (containsUConvert (spirv )) 128 <<"SPIR-V should contain OpUConvert instruction for variable uint8_t array indexing.\n" 129 <<"Generated SPIR-V:\n" 130 <<spirv ; 131} 132 133// Test 2: Indexing an array with a variable index of type uint16_t should generate a zero extension. 134TEST_F (SpvPatternTest ,Uint16VariableIndexGeneratesUConvert ) 135{ 136const std::string shaderSource = R"( 137#version 450 core 138#extension GL_EXT_shader_explicit_arithmetic_types : enable 139 140layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; 141 142void main() { 143uint16_t u16 = uint16_t(150); 144float arr[200]; 145float x = arr[u16]; // Variable uint16_t index 146} 147)" ; 148 149 std::string spirv = compileShaderToSpirv (shaderSource ,EShLangCompute ); 150 151// Check that the SPIR-V contains OpUConvert instruction for variable uint16_t index. 152EXPECT_TRUE (containsUConvert (spirv )) 153 <<"SPIR-V should contain OpUConvert instruction for variable uint16_t array indexing.\n" 154 <<"Generated SPIR-V:\n" 155 <<spirv ; 156} 157 158// Test 3: Indexing an array with a constant index of type uint8_t should NOT generate a zero extension. 159// Glslang generates small constants as regular 32-bit integers. 160TEST_F (SpvPatternTest ,Uint8ConstantIndexNoConversion ) 161{ 162const std::string shaderSource = R"( 163#version 450 core 164#extension GL_EXT_shader_explicit_arithmetic_types : enable 165 166layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; 167 168void main() { 169float arr[200]; 170float x = arr[uint8_t(150)]; // Constant uint8_t index 171} 172)" ; 173 174 std::string spirv = compileShaderToSpirv (shaderSource ,EShLangCompute ); 175 176// Check that the SPIR-V does NOT contain OpUConvert instruction for constant uint8_t index. 177// Glslang generates small constants as regular 32-bit integers, so no conversion is needed. 178EXPECT_FALSE (containsUConvert (spirv )) 179 <<"SPIR-V should not contain OpUConvert instruction for constant uint8_t array indexing.\n" 180 <<"Generated SPIR-V:\n" 181 <<spirv ; 182} 183 184// Test 3: Indexing an array with a constant index of type uint16_t should NOT generate a zero extension. 185// (Glslang generates small constants as regular 32-bit integers.) 186TEST_F (SpvPatternTest ,Uint16ConstantIndexNoConversion ) 187{ 188const std::string shaderSource = R"( 189#version 450 core 190#extension GL_EXT_shader_explicit_arithmetic_types : enable 191 192layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; 193 194void main() { 195float arr[200]; 196float x = arr[uint16_t(150)]; // Constant uint16_t index 197} 198)" ; 199 200 std::string spirv = compileShaderToSpirv (shaderSource ,EShLangCompute ); 201 202// Check that the SPIR-V does NOT contain OpUConvert instruction for constant uint16_t index. 203// Glslang generates small constants as regular 32-bit integers, so no conversion is needed. 204EXPECT_FALSE (containsUConvert (spirv )) 205 <<"SPIR-V should not contain OpUConvert instruction for constant uint16_t array indexing.\n" 206 <<"Generated SPIR-V:\n" 207 <<spirv ; 208} 209 210}// namespace glslangtest