From 72b04e391391d3999e716034925edf6d7fcfcc5b Mon Sep 17 00:00:00 2001 From: pheonix Date: Sat, 17 Oct 2020 20:02:51 -0700 Subject: [PATCH] Shaderc SPIR-V profile additions (#2284) * [shaderc] Add SPIR-V profiles to support Vulkan 1.1 and Vulkan 1.2. * * Add support for Vulkan 1.1 with SPIR-V 1.4. * Update "spirv" values to correlate with shaderc spirv profile name mappings. * Expand on spirv profile naming and encoding documentation. * Address PR notes --- tools/shaderc/shaderc.cpp | 36 ++++++++++++++++--- tools/shaderc/shaderc_spirv.cpp | 64 ++++++++++++++++++++++++++++++++- 2 files changed, 94 insertions(+), 6 deletions(-) diff --git a/tools/shaderc/shaderc.cpp b/tools/shaderc/shaderc.cpp index bbb796e98..39341262f 100644 --- a/tools/shaderc/shaderc.cpp +++ b/tools/shaderc/shaderc.cpp @@ -850,6 +850,15 @@ namespace bgfx // 4.2 420 11.0 vhdgf+c 5.0 // 4.3 430 vhdgf+c // 4.4 440 + // + // SPIR-V profile naming convention: + // spirv- + // + // SPIR-V version | Vulkan version | shaderc encoding + // 1.0 | 1.0 | 1010 + // 1.3 | 1.1 | 1311 + // 1.4 | 1.1 | 1411 + // 1.5 | 1.2 | 1512 void help(const char* _error = NULL) { @@ -894,7 +903,11 @@ namespace bgfx " s_5\n" " metal\n" " pssl\n" - " spirv\n" + " spirv Alias for spirv10-10. \n" + " spirv10-10\n" + " spirv13-11\n" + " spirv14-11\n" + " spirv15-12\n" " --preprocess Preprocess only.\n" " --define Add defines to preprocessor (semicolon separated).\n" " --raw Do not process shader. No preprocessor, and no glsl-optimizer (GLSL only).\n" @@ -960,9 +973,22 @@ namespace bgfx { pssl = 1; } - else if (0 == bx::strCmp(profile, "spirv") ) + else if (0 == bx::strCmp(profile, "spirv13-11") ) { - spirv = 1; + spirv = 1311; + } + else if (0 == bx::strCmp(profile, "spirv14-11") ) + { + spirv = 1411; + } + else if (0 == bx::strCmp(profile, "spirv15-12") ) + { + spirv = 1512; + } + else if (0 == bx::strCmp(profile, "spirv10-10") + || 0 == bx::strCmp(profile, "spirv") ) + { + spirv = 1010; } else { @@ -1512,7 +1538,7 @@ namespace bgfx } else if (0 != spirv) { - compiled = compileSPIRVShader(_options, 0, code, _writer); + compiled = compileSPIRVShader(_options, spirv, code, _writer); } else if (0 != pssl) { @@ -2310,7 +2336,7 @@ namespace bgfx } else if (0 != spirv) { - compiled = compileSPIRVShader(_options, 0, code, _writer); + compiled = compileSPIRVShader(_options, spirv, code, _writer); } else if (0 != pssl) { diff --git a/tools/shaderc/shaderc_spirv.cpp b/tools/shaderc/shaderc_spirv.cpp index 6c950d394..dd321a55d 100644 --- a/tools/shaderc/shaderc_spirv.cpp +++ b/tools/shaderc/shaderc_spirv.cpp @@ -676,6 +676,65 @@ namespace bgfx { namespace spirv return size; } + static spv_target_env getSpirvTargetVersion(uint32_t version) + { + switch (version) + { + case 1010: + return SPV_ENV_VULKAN_1_0; + case 1311: + return SPV_ENV_VULKAN_1_1; + case 1411: + return SPV_ENV_VULKAN_1_1_SPIRV_1_4; + case 1512: + return SPV_ENV_VULKAN_1_2; + default: + BX_ASSERT(0, "Unknown SPIR-V version requested. Returning SPV_ENV_VULKAN_1_0 as default."); + return SPV_ENV_VULKAN_1_0; + } + } + + static glslang::EShTargetClientVersion getGlslangTargetVulkanVersion(uint32_t version) + { + switch (version) + { + case 1010: + return glslang::EShTargetVulkan_1_0; + case 1311: + case 1411: + return glslang::EShTargetVulkan_1_1; + case 1512: + return glslang::EShTargetVulkan_1_2; + default: + BX_ASSERT(0, "Unknown SPIR-V version requested. Returning EShTargetVulkan_1_0 as default."); + return glslang::EShTargetVulkan_1_0; + } + } + + static glslang::EShTargetLanguageVersion getGlslangTargetSpirvVersion(uint32_t version) + { + switch (version) + { + case 1010: + return glslang::EShTargetSpv_1_0; + case 1311: + return glslang::EShTargetSpv_1_3; + case 1411: + return glslang::EShTargetSpv_1_4; + case 1512: + return glslang::EShTargetSpv_1_5; + default: + BX_ASSERT(0, "Unknown SPIR-V version requested. Returning EShTargetSpv_1_0 as default."); + return glslang::EShTargetSpv_1_0; + } + } + + /// This is the value used to fill out GLSLANG's SpvVersion object. + /// The required value is that which is defined by GL_KHR_vulkan_glsl, which is defined here: + /// https://github.com/KhronosGroup/GLSL/blob/master/extensions/khr/GL_KHR_vulkan_glsl.txt + /// The value is 100. + constexpr int s_GLSL_VULKAN_CLIENT_VERSION = 100; + static bool compile(const Options& _options, uint32_t _version, const std::string& _code, bx::WriterI* _writer, bool _firstPass) { BX_UNUSED(_version); @@ -701,6 +760,9 @@ namespace bgfx { namespace spirv shader->setEntryPoint("main"); shader->setAutoMapBindings(true); + shader->setEnvInput(glslang::EShSourceHlsl, stage, glslang::EShClientVulkan, s_GLSL_VULKAN_CLIENT_VERSION); + shader->setEnvClient(glslang::EShClientVulkan, getGlslangTargetVulkanVersion(_version)); + shader->setEnvTarget(glslang::EShTargetSpv, getGlslangTargetSpirvVersion(_version)); uint32_t bindingOffset = (stage == EShLanguage::EShLangFragment ? 48 : 0); shader->setShiftBinding(glslang::EResUbo, bindingOffset); shader->setShiftBinding(glslang::EResTexture, bindingOffset + 16); @@ -938,7 +1000,7 @@ namespace bgfx { namespace spirv glslang::GlslangToSpv(*intermediate, spirv, &options); - spvtools::Optimizer opt(SPV_ENV_VULKAN_1_0); + spvtools::Optimizer opt(getSpirvTargetVersion(_version)); auto print_msg_to_stderr = []( spv_message_level_t