diff --git a/engine/shadercompiler/include/shadercompiler.hpp b/engine/shadercompiler/include/shadercompiler.hpp index 35c0333..fec5981 100755 --- a/engine/shadercompiler/include/shadercompiler.hpp +++ b/engine/shadercompiler/include/shadercompiler.hpp @@ -36,6 +36,8 @@ public: /// When compiling MSL, the result may differ whether or not we're targetting non-Mac Metal platforms. bool is_apple_mobile = false; + + bool enable_wgpu_compat = false; }; /// Represents the source code of a shader either in plaintext (GLSL, MSL) or bytecode (SPIR-V). @@ -94,7 +96,7 @@ public: @param options Optional compilation parameters. @note Right now, only GLSL is supported as a source shader language. */ - std::optional compile(ShaderLanguage from_language, ShaderStage shader_stage, const ShaderSource& shader_source, ShaderLanguage to_language, const CompileOptions& options = CompileOptions()); + std::optional compile(ShaderLanguage from_language, ShaderStage shader_stage, const ShaderSource& shader_source, ShaderLanguage to_language, CompileOptions options = CompileOptions()); }; static inline ShaderCompiler shader_compiler; diff --git a/engine/shadercompiler/src/shadercompiler.cpp b/engine/shadercompiler/src/shadercompiler.cpp index 8fef51a..ef644dc 100755 --- a/engine/shadercompiler/src/shadercompiler.cpp +++ b/engine/shadercompiler/src/shadercompiler.cpp @@ -30,12 +30,20 @@ std::vector compile_glsl_to_spv(const std::string_view source_string, newString += "#line 1\n"; newString += source_string; - + + if(options.enable_wgpu_compat) { + // in some wacky world the webgpu devs live in, push constants do not exist. + + // alright, so to make webgpu happy we are going to hand-waive all of our push constant blocks + // away into UBOs. let's start by rewriting our GLSL. yay... + newString = replace_substring(newString, "push_constant", "binding = 10"); + } + const char* InputCString = newString.c_str(); glslang::TShader shader(shader_language); shader.setStrings(&InputCString, 1); - + int ClientInputSemanticsVersion = 100; // maps to, say, #define VULKAN 100 shader.setEnvInput(glslang::EShSourceGlsl, @@ -43,6 +51,9 @@ std::vector compile_glsl_to_spv(const std::string_view source_string, glslang::EShClientVulkan, ClientInputSemanticsVersion); + + prism::log("compiling {}", newString); + // we are targeting vulkan 1.1, so that uses SPIR-V 1.3 shader.setEnvClient(glslang::EShClientVulkan, glslang::EShTargetVulkan_1_1); shader.setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_3); @@ -50,7 +61,6 @@ std::vector compile_glsl_to_spv(const std::string_view source_string, DirStackFileIncluder file_includer; for(const auto& path : include_path) file_includer.pushExternalLocalDirectory(path); - if (!shader.parse(&DefaultTBuiltInResource, 100, false, EShMsgDefault, file_includer)) { prism::log("{}", shader.getInfoLog()); @@ -77,7 +87,7 @@ std::vector compile_glsl_to_spv(const std::string_view source_string, return SpirV; } -std::optional ShaderCompiler::compile(const ShaderLanguage from_language, const ShaderStage shader_stage, const ShaderSource& shader_source, const ShaderLanguage to_language, const CompileOptions& options) { +std::optional ShaderCompiler::compile(const ShaderLanguage from_language, const ShaderStage shader_stage, const ShaderSource& shader_source, const ShaderLanguage to_language, CompileOptions options) { if(from_language != ShaderLanguage::GLSL) { prism::log("Non-supported input language!"); return std::nullopt; @@ -96,6 +106,8 @@ std::optional ShaderCompiler::compile(const ShaderLanguage from_la break; } + options.enable_wgpu_compat = to_language == ShaderLanguage::WGSL; + auto spirv = compile_glsl_to_spv(shader_source.as_string(), lang, options); if(spirv.empty()) { prism::log("SPIRV generation failed!"); @@ -103,6 +115,7 @@ std::optional ShaderCompiler::compile(const ShaderLanguage from_la } switch(to_language) { + case ShaderLanguage::WGSL: case ShaderLanguage::SPIRV: return ShaderSource(spirv); case ShaderLanguage::MSL: { @@ -123,9 +136,6 @@ std::optional ShaderCompiler::compile(const ShaderLanguage from_la case ShaderLanguage::HLSL: prism::log("Unimplemented shader language: HLSL"); return ShaderSource(spirv); - case ShaderLanguage::WGSL: - prism::log("Unimplemented shader language: WGSL"); - return ShaderSource(spirv); default: return {}; }