From a73b9214a5dff21bf4101f36196b7f2ed0e1f491 Mon Sep 17 00:00:00 2001 From: baldurk Date: Tue, 10 Nov 2026 11:16:21 +0000 Subject: [PATCH] Prefer using spirv-as for assembly SPIR-V assembly if possible * Since we no longer can link shaderc we have external dependencies anyway, most likely from the vulkan SDK. shaderc has never fixed the inability to apply target env to shader assembly so this means we can specifically target some SPIR-V versions. --- util/test/demos/test_common.cpp | 59 ++++++++++++++++------ util/test/demos/vk/vk_multi_entry.cpp | 6 +-- util/test/demos/vk/vk_shader_debug_zoo.cpp | 11 ++-- 3 files changed, 50 insertions(+), 26 deletions(-) diff --git a/util/test/demos/test_common.cpp b/util/test/demos/test_common.cpp index 7fe96e36a..180c14391 100644 --- a/util/test/demos/test_common.cpp +++ b/util/test/demos/test_common.cpp @@ -253,27 +253,38 @@ void LoadXPM(const char **XPM, Texture &tex) } static std::string externalCompiler; +static std::string externalASMCompiler; + +bool CheckCompiler(std::string compiler) +{ + FILE *pipe = popen((compiler + EXECUTABLE_SUFFIX " --version 2>&1").c_str(), "r"); + + if(!pipe) + return false; + + char dummy[512]; + while(!feof(pipe)) + { + fread(dummy, 1, 512, pipe); + } + + int code = pclose(pipe); + + return (WEXITSTATUS(code) == 0); +} bool SpvCompilationSupported() { + if(CheckCompiler("spirv-as")) + externalASMCompiler = "spirv-as"; + for(std::string compiler : {"glslc", "glslangValidator"}) { - FILE *pipe = popen((compiler + EXECUTABLE_SUFFIX " --version 2>&1").c_str(), "r"); - - if(!pipe) - continue; - - char dummy[512]; - while(!feof(pipe)) - { - fread(dummy, 1, 512, pipe); - } - - int code = pclose(pipe); - - if(WEXITSTATUS(code) == 0) + if(CheckCompiler(compiler)) { externalCompiler = compiler; + if(externalASMCompiler.empty()) + externalASMCompiler = compiler; return true; } } @@ -302,7 +313,25 @@ std::vector CompileShaderToSpv(const char *demo_name, const std::strin std::string infile = path + "/input"; std::string outfile = path + "/output"; - if(externalCompiler == "glslc") + if(lang == ShaderLang::spvasm && externalASMCompiler == "spirv-as") + { + command_line = "spirv-as" EXECUTABLE_SUFFIX; + + if(target == SPIRVTarget::opengl) + command_line += " --target-env=opengl"; + else if(target == SPIRVTarget::vulkan) + command_line += " --target-env=vulkan1.0"; + else if(target == SPIRVTarget::vulkan11) + command_line += " --target-env=vulkan1.1"; + else if(target == SPIRVTarget::vulkan12) + command_line += " --target-env=vulkan1.2"; + + command_line += " -o "; + command_line += outfile; + command_line += " "; + command_line += infile; + } + else if(externalCompiler == "glslc") { command_line = "glslc" EXECUTABLE_SUFFIX; if(debug_info) diff --git a/util/test/demos/vk/vk_multi_entry.cpp b/util/test/demos/vk/vk_multi_entry.cpp index bc7dc685d..efb8d3016 100644 --- a/util/test/demos/vk/vk_multi_entry.cpp +++ b/util/test/demos/vk/vk_multi_entry.cpp @@ -35,10 +35,10 @@ RD_TEST(VK_Multi_Entry, VulkanGraphicsTest) OpMemoryModel Logical GLSL450 OpEntryPoint Vertex %fakev "fake" %posout - OpEntryPoint Fragment %fakef "fake" %ColorF + OpEntryPoint Fragment %fakef "fake" %ColorF %push %tex1 OpEntryPoint Vertex %mainv "main" %vertOut %Position %_ %Color %UV - OpEntryPoint Fragment %mainf "main" %ColorF %vertIn + OpEntryPoint Fragment %mainf "main" %ColorF %vertIn %push %tex OpExecutionMode %fakef OriginUpperLeft OpExecutionMode %mainf OriginUpperLeft @@ -241,7 +241,7 @@ RD_TEST(VK_Multi_Entry, VulkanGraphicsTest) }; VkPipelineShaderStageCreateInfo shad = CompileShaderModule( - combined_asm, ShaderLang::spvasm, ShaderStage::vert, "main", {}, SPIRVTarget::vulkan); + combined_asm, ShaderLang::spvasm, ShaderStage::vert, "main", {}, SPIRVTarget::vulkan12); pipeCreateInfo.stages = { shad, diff --git a/util/test/demos/vk/vk_shader_debug_zoo.cpp b/util/test/demos/vk/vk_shader_debug_zoo.cpp index a6594885f..69e0d29bf 100644 --- a/util/test/demos/vk/vk_shader_debug_zoo.cpp +++ b/util/test/demos/vk/vk_shader_debug_zoo.cpp @@ -3339,7 +3339,7 @@ OpBranch %_bottomlabel %_addr_bda_data_struct = OpLoad %uint2 %_ptr_addr_bda_data_struct %_ptr_bda_data_struct = OpBitcast %ptr_PhysicalStorageBuffer_bda_data_struct_f32_4 %_addr_bda_data_struct %_ptr_f32 = OpPtrAccessChain %ptr_PhysicalStorageBuffer_f32 %_ptr_bda_data_struct %int_dyn_1 -%_out_float = OpLoad %float %_ptr_f32 Aligned 16 +%_out_float = OpLoad %float %_ptr_f32 Aligned 4 )EOTEST", // OpPtrAccessChain : float[] : ArrayStride 8 R"EOTEST( @@ -3347,7 +3347,7 @@ OpBranch %_bottomlabel %_addr_bda_data_struct = OpLoad %uint2 %_ptr_addr_bda_data_struct %_ptr_bda_data_struct = OpBitcast %ptr_PhysicalStorageBuffer_bda_data_struct_f32_8 %_addr_bda_data_struct %_ptr_f32 = OpPtrAccessChain %ptr_PhysicalStorageBuffer_f32 %_ptr_bda_data_struct %int_dyn_1 -%_out_float = OpLoad %float %_ptr_f32 Aligned 16 +%_out_float = OpLoad %float %_ptr_f32 Aligned 4 )EOTEST", // OpPtrAccessChain : float[] : ArrayStride 12 R"EOTEST( @@ -3355,7 +3355,7 @@ OpBranch %_bottomlabel %_addr_bda_data_struct = OpLoad %uint2 %_ptr_addr_bda_data_struct %_ptr_bda_data_struct = OpBitcast %ptr_PhysicalStorageBuffer_bda_data_struct_f32_12 %_addr_bda_data_struct %_ptr_f32 = OpPtrAccessChain %ptr_PhysicalStorageBuffer_f32 %_ptr_bda_data_struct %int_dyn_1 -%_out_float = OpLoad %float %_ptr_f32 Aligned 16 +%_out_float = OpLoad %float %_ptr_f32 Aligned 4 )EOTEST", // Load through a bda ptr array which is a member of a structure pointed to by a uint2 address R"EOTEST( @@ -5021,11 +5021,6 @@ OpMemberDecorate %cbuffer_struct 17 Offset 216 ; double doublePackSource SPIRVTarget target = SPIRVTarget::vulkan; - if(vk_version >= 0x11) - target = SPIRVTarget::vulkan11; - if(vk_version >= 0x12) - target = SPIRVTarget::vulkan12; - pipeCreateInfo.stages = { CompileShaderModule(vertex, ShaderLang::glsl, ShaderStage::vert, "main"), CompileShaderModule(make_pixel_asm(), ShaderLang::spvasm, ShaderStage::frag, "main", {},