Archived
1
Fork 0

Add a WebGPU compat option in the shader compiler

Come on...
This commit is contained in:
Joshua Goins 2022-02-20 22:28:35 -05:00
parent bd485c2eb8
commit d6fb539583
2 changed files with 20 additions and 8 deletions

View file

@ -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<ShaderSource> compile(ShaderLanguage from_language, ShaderStage shader_stage, const ShaderSource& shader_source, ShaderLanguage to_language, const CompileOptions& options = CompileOptions());
std::optional<ShaderSource> compile(ShaderLanguage from_language, ShaderStage shader_stage, const ShaderSource& shader_source, ShaderLanguage to_language, CompileOptions options = CompileOptions());
};
static inline ShaderCompiler shader_compiler;

View file

@ -31,6 +31,14 @@ std::vector<uint32_t> compile_glsl_to_spv(const std::string_view source_string,
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);
@ -43,6 +51,9 @@ std::vector<uint32_t> 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<uint32_t> 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<uint32_t> compile_glsl_to_spv(const std::string_view source_string,
return SpirV;
}
std::optional<ShaderSource> ShaderCompiler::compile(const ShaderLanguage from_language, const ShaderStage shader_stage, const ShaderSource& shader_source, const ShaderLanguage to_language, const CompileOptions& options) {
std::optional<ShaderSource> 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<ShaderSource> 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<ShaderSource> 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<ShaderSource> 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 {};
}