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. /// When compiling MSL, the result may differ whether or not we're targetting non-Mac Metal platforms.
bool is_apple_mobile = false; 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). /// 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. @param options Optional compilation parameters.
@note Right now, only GLSL is supported as a source shader language. @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; 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; 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(); const char* InputCString = newString.c_str();
glslang::TShader shader(shader_language); 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, glslang::EShClientVulkan,
ClientInputSemanticsVersion); ClientInputSemanticsVersion);
prism::log("compiling {}", newString);
// we are targeting vulkan 1.1, so that uses SPIR-V 1.3 // we are targeting vulkan 1.1, so that uses SPIR-V 1.3
shader.setEnvClient(glslang::EShClientVulkan, glslang::EShTargetVulkan_1_1); shader.setEnvClient(glslang::EShClientVulkan, glslang::EShTargetVulkan_1_1);
shader.setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_3); 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; DirStackFileIncluder file_includer;
for(const auto& path : include_path) for(const auto& path : include_path)
file_includer.pushExternalLocalDirectory(path); file_includer.pushExternalLocalDirectory(path);
if (!shader.parse(&DefaultTBuiltInResource, 100, false, EShMsgDefault, file_includer)) { if (!shader.parse(&DefaultTBuiltInResource, 100, false, EShMsgDefault, file_includer)) {
prism::log("{}", shader.getInfoLog()); prism::log("{}", shader.getInfoLog());
@ -77,7 +87,7 @@ std::vector<uint32_t> compile_glsl_to_spv(const std::string_view source_string,
return SpirV; 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) { if(from_language != ShaderLanguage::GLSL) {
prism::log("Non-supported input language!"); prism::log("Non-supported input language!");
return std::nullopt; return std::nullopt;
@ -96,6 +106,8 @@ std::optional<ShaderSource> ShaderCompiler::compile(const ShaderLanguage from_la
break; break;
} }
options.enable_wgpu_compat = to_language == ShaderLanguage::WGSL;
auto spirv = compile_glsl_to_spv(shader_source.as_string(), lang, options); auto spirv = compile_glsl_to_spv(shader_source.as_string(), lang, options);
if(spirv.empty()) { if(spirv.empty()) {
prism::log("SPIRV generation failed!"); prism::log("SPIRV generation failed!");
@ -103,6 +115,7 @@ std::optional<ShaderSource> ShaderCompiler::compile(const ShaderLanguage from_la
} }
switch(to_language) { switch(to_language) {
case ShaderLanguage::WGSL:
case ShaderLanguage::SPIRV: case ShaderLanguage::SPIRV:
return ShaderSource(spirv); return ShaderSource(spirv);
case ShaderLanguage::MSL: { case ShaderLanguage::MSL: {
@ -123,9 +136,6 @@ std::optional<ShaderSource> ShaderCompiler::compile(const ShaderLanguage from_la
case ShaderLanguage::HLSL: case ShaderLanguage::HLSL:
prism::log("Unimplemented shader language: HLSL"); prism::log("Unimplemented shader language: HLSL");
return ShaderSource(spirv); return ShaderSource(spirv);
case ShaderLanguage::WGSL:
prism::log("Unimplemented shader language: WGSL");
return ShaderSource(spirv);
default: default:
return {}; return {};
} }