diff --git a/.gitignore b/.gitignore index 06673ec03..1cd253f53 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,4 @@ third_party/tint android_test/libs android_test/include .DS_Store +.vscode/ diff --git a/libshaderc/include/shaderc/shaderc.h b/libshaderc/include/shaderc/shaderc.h index 235f6074d..3a3e97d6b 100644 --- a/libshaderc/include/shaderc/shaderc.h +++ b/libshaderc/include/shaderc/shaderc.h @@ -489,6 +489,12 @@ SHADERC_EXPORT void shaderc_compile_options_set_hlsl_functionality1( SHADERC_EXPORT void shaderc_compile_options_set_hlsl_16bit_types( shaderc_compile_options_t options, bool enable); +// Enables or disables relaxed Vulkan rules. +// +// This allows most OpenGL shaders to compile under Vulkan semantics. +SHADERC_EXPORT void shaderc_compile_options_set_vulkan_rules_relaxed( + shaderc_compile_options_t options, bool enable); + // Sets whether the compiler should invert position.Y output in vertex shader. SHADERC_EXPORT void shaderc_compile_options_set_invert_y( shaderc_compile_options_t options, bool enable); diff --git a/libshaderc/include/shaderc/shaderc.hpp b/libshaderc/include/shaderc/shaderc.hpp index bc057c13d..3817af806 100644 --- a/libshaderc/include/shaderc/shaderc.hpp +++ b/libshaderc/include/shaderc/shaderc.hpp @@ -353,6 +353,13 @@ class CompileOptions { shaderc_compile_options_set_hlsl_16bit_types(options_, enable); } + // Enables or disables relaxed Vulkan rules. + // + // This allows most OpenGL shaders to compile under Vulkan semantics. + void SetVulkanRulesRelaxed(bool enable) { + shaderc_compile_options_set_vulkan_rules_relaxed(options_, enable); + } + // Sets whether the compiler should invert position.Y output in vertex shader. void SetInvertY(bool enable) { shaderc_compile_options_set_invert_y(options_, enable); diff --git a/libshaderc/src/shaderc.cc b/libshaderc/src/shaderc.cc index 322382092..63f1bbc6c 100644 --- a/libshaderc/src/shaderc.cc +++ b/libshaderc/src/shaderc.cc @@ -564,6 +564,11 @@ void shaderc_compile_options_set_hlsl_16bit_types( options->compiler.EnableHlsl16BitTypes(enable); } +void shaderc_compile_options_set_vulkan_rules_relaxed( + shaderc_compile_options_t options, bool enable) { + options->compiler.SetVulkanRulesRelaxed(enable); +} + void shaderc_compile_options_set_invert_y( shaderc_compile_options_t options, bool enable) { options->compiler.EnableInvertY(enable); diff --git a/libshaderc_util/include/libshaderc_util/compiler.h b/libshaderc_util/include/libshaderc_util/compiler.h index ffd7c248a..d9d02b951 100644 --- a/libshaderc_util/include/libshaderc_util/compiler.h +++ b/libshaderc_util/include/libshaderc_util/compiler.h @@ -233,6 +233,11 @@ class Compiler { // Enables or disables HLSL 16-bit types. void EnableHlsl16BitTypes(bool enable); + // Enables or disables relaxed Vulkan rules. + // + // This allows most OpenGL shaders to compile under Vulkan semantics. + void SetVulkanRulesRelaxed(bool enable); + // Enables or disables invert position.Y output in vertex shader. void EnableInvertY(bool enable); @@ -545,6 +550,10 @@ class Compiler { // True if the compiler should support 16-bit HLSL types. bool hlsl_16bit_types_enabled_; + // True if the compiler should relax Vulkan rules to allow OGL shaders to + // compile. + bool vulkan_rules_relaxed_ = false; + // True if the compiler should invert position.Y output in vertex shader. bool invert_y_enabled_; diff --git a/libshaderc_util/src/compiler.cc b/libshaderc_util/src/compiler.cc index 525cbc573..e5f5d1055 100644 --- a/libshaderc_util/src/compiler.cc +++ b/libshaderc_util/src/compiler.cc @@ -294,6 +294,22 @@ std::tuple, size_t> Compiler::Compile( if (hlsl_functionality1_enabled_) { shader.setEnvTargetHlslFunctionality1(); } + if (vulkan_rules_relaxed_) { + glslang::EShSource language = glslang::EShSourceNone; + switch(source_language_) { + case SourceLanguage::GLSL: + language = glslang::EShSourceGlsl; + break; + case SourceLanguage::HLSL: + language = glslang::EShSourceHlsl; + break; + } + // This option will only be used if the Vulkan client is used. + // If new versions of GL_KHR_vulkan_glsl come out, it would make sense to + // let callers specify which version to use. For now, just use 100. + shader.setEnvInput(language, used_shader_stage, glslang::EShClientVulkan, 100); + shader.setEnvInputVulkanRulesRelaxed(); + } shader.setInvertY(invert_y_enabled_); shader.setNanMinMaxClamp(nan_clamp_); @@ -452,6 +468,10 @@ void Compiler::EnableHlslFunctionality1(bool enable) { hlsl_functionality1_enabled_ = enable; } +void Compiler::SetVulkanRulesRelaxed(bool enable) { + vulkan_rules_relaxed_ = enable; +} + void Compiler::EnableHlsl16BitTypes(bool enable) { hlsl_16bit_types_enabled_ = enable; } diff --git a/libshaderc_util/src/compiler_test.cc b/libshaderc_util/src/compiler_test.cc index a0a964d3f..4ebb91324 100644 --- a/libshaderc_util/src/compiler_test.cc +++ b/libshaderc_util/src/compiler_test.cc @@ -106,6 +106,18 @@ const char kGlslVertShaderExplicitLocation[] = gl_Position = my_mat * my_vec; })"; +// A GLSL fragment shader with the location defined for its non-opaque uniform +// variable. +const char kGlslFragShaderOpaqueUniforms[] = + R"(#version 320 es + precision lowp float; + + layout(location = 0) out vec4 oColor; + layout(location = 0) uniform float a; + void main(void) { + oColor = vec4(1.0, 0.0, 0.0, a); + })"; + // A GLSL vertex shader without the location defined for its non-opaque uniform // variable. const char kGlslVertShaderNoExplicitLocation[] = @@ -813,6 +825,18 @@ TEST_F(CompilerTest, HlslFunctionality1Enabled) { << disassembly; } +TEST_F(CompilerTest, RelaxedVulkanRulesEnabled) { + compiler_.SetSourceLanguage(Compiler::SourceLanguage::GLSL); + compiler_.SetAutoBindUniforms(true); // Uniform variable needs a binding + compiler_.SetVulkanRulesRelaxed(true); + const auto words = + SimpleCompilationBinary(kGlslFragShaderOpaqueUniforms, EShLangFragment); + const auto disassembly = Disassemble(words); + EXPECT_THAT(disassembly, + HasSubstr("OpMemberName %gl_DefaultUniformBlock 0 \"a\"")) + << disassembly; +} + TEST_F(CompilerTest, ClampMapsToFClampByDefault) { const auto words = SimpleCompilationBinary(kGlslShaderWithClamp, EShLangFragment);