diff options
author | David Neto <dneto@google.com> | 2016-10-20 15:08:31 -0400 |
---|---|---|
committer | David Neto <dneto@google.com> | 2016-10-21 09:57:22 -0400 |
commit | fa933206ff7943ff8f58bfb1748d3a401231377c (patch) | |
tree | 6d933d97d1c843ee16ed949e6a23b8c931dd5b80 | |
parent | e6b4795750f3ceb028fbfd860bd96b6aec859da1 (diff) | |
download | shaderc-fa933206ff7943ff8f58bfb1748d3a401231377c.tar.gz |
Add API support for compiling HLSL
Exposes the HLSL functionality in Glslang.
Done in three layers:
- libshaderc_util::Compiler:
Add libshaderc_util::Compiler::SourceLanguage enum.
Add libshaderc_util::Compiler::SetSourceLanguage method.
The default language remains GLSL.
libshaderc_util::Compiler passes the source language option into Glslang.
- C API
Add function to set source language on compiler options.
- C++ API
Add shaderc::CompileOptions::SetSourceLanguage
-rw-r--r-- | libshaderc/include/shaderc/shaderc.h | 10 | ||||
-rw-r--r-- | libshaderc/include/shaderc/shaderc.hpp | 5 | ||||
-rw-r--r-- | libshaderc/src/common_shaders_for_test.h | 3 | ||||
-rw-r--r-- | libshaderc/src/shaderc.cc | 9 | ||||
-rw-r--r-- | libshaderc/src/shaderc_cpp_test.cc | 28 | ||||
-rw-r--r-- | libshaderc/src/shaderc_test.cc | 40 | ||||
-rw-r--r-- | libshaderc_util/include/libshaderc_util/compiler.h | 17 | ||||
-rw-r--r-- | libshaderc_util/src/compiler.cc | 26 | ||||
-rw-r--r-- | libshaderc_util/src/compiler_test.cc | 27 |
9 files changed, 155 insertions, 10 deletions
diff --git a/libshaderc/include/shaderc/shaderc.h b/libshaderc/include/shaderc/shaderc.h index 46d98b4..64d94ea 100644 --- a/libshaderc/include/shaderc/shaderc.h +++ b/libshaderc/include/shaderc/shaderc.h @@ -23,6 +23,12 @@ extern "C" { #include <stddef.h> #include <stdint.h> +// Source language kind. +typedef enum { + shaderc_source_language_glsl, + shaderc_source_language_hlsl, +} shaderc_source_language; + typedef enum { // Forced shader kinds. These shader kinds force the compiler to compile the // source code as the specified kind of shader. @@ -158,6 +164,10 @@ void shaderc_compile_options_add_macro_definition( shaderc_compile_options_t options, const char* name, size_t name_length, const char* value, size_t value_length); +// Sets the source language. The default is GLSL. +void shaderc_compile_options_set_source_language( + shaderc_compile_options_t options, shaderc_source_language lang); + // Sets the compiler mode to generate debug information in the output. void shaderc_compile_options_set_generate_debug_info( shaderc_compile_options_t options); diff --git a/libshaderc/include/shaderc/shaderc.hpp b/libshaderc/include/shaderc/shaderc.hpp index 4e5dfd7..1dc2631 100644 --- a/libshaderc/include/shaderc/shaderc.hpp +++ b/libshaderc/include/shaderc/shaderc.hpp @@ -221,6 +221,11 @@ class CompileOptions { shaderc_compile_options_set_suppress_warnings(options_); } + // Sets the source language. The default is GLSL. + void SetSourceLanguage(shaderc_source_language lang) { + shaderc_compile_options_set_source_language(options_, lang); + } + // Sets the target shader environment, affecting which warnings or errors will // be issued. // The version will be for distinguishing between different versions of the diff --git a/libshaderc/src/common_shaders_for_test.h b/libshaderc/src/common_shaders_for_test.h index d25c6bf..a0120a2 100644 --- a/libshaderc/src/common_shaders_for_test.h +++ b/libshaderc/src/common_shaders_for_test.h @@ -25,6 +25,9 @@ const char kMinimalShaderWithoutVersion[] = "void main(){}"; const char kMinimalShader[] = "#version 140\n" "void main(){}"; +const char kMinimalHlslShader[] = + "float4 EntryPoint(uint index : SV_VERTEXID) : SV_POSITION\n" + "{ return float4(1.0, 2.0, 3.0, 4.0); }"; const char kMinimalShaderWithMacro[] = "#version 140\n" "#define E main\n" diff --git a/libshaderc/src/shaderc.cc b/libshaderc/src/shaderc.cc index 8a2f46a..845320b 100644 --- a/libshaderc/src/shaderc.cc +++ b/libshaderc/src/shaderc.cc @@ -270,6 +270,15 @@ void shaderc_compile_options_add_macro_definition( options->compiler.AddMacroDefinition(name, name_length, value, value_length); } +void shaderc_compile_options_set_source_language( + shaderc_compile_options_t options, + shaderc_source_language set_lang) { + auto lang = shaderc_util::Compiler::SourceLanguage::GLSL; + if (set_lang == shaderc_source_language_hlsl) + lang = shaderc_util::Compiler::SourceLanguage::HLSL; + options->compiler.SetSourceLanguage(lang); +} + void shaderc_compile_options_set_generate_debug_info( shaderc_compile_options_t options) { options->compiler.SetGenerateDebugInfo(); diff --git a/libshaderc/src/shaderc_cpp_test.cc b/libshaderc/src/shaderc_cpp_test.cc index 521f109..2762197 100644 --- a/libshaderc/src/shaderc_cpp_test.cc +++ b/libshaderc/src/shaderc_cpp_test.cc @@ -1015,4 +1015,32 @@ TEST_F(CppInterface, BeginAndEndOnPreprocessedResult) { EXPECT_THAT(string_via_begin_end, Eq(forced_to_be_a_string)); } +TEST_F(CppInterface, SourceLangGlslMinimalGlslVertexShaderSucceeds) { + options_.SetSourceLanguage(shaderc_source_language_glsl); + EXPECT_TRUE(CompilationSuccess(kVertexOnlyShader, + shaderc_glsl_vertex_shader, + options_)); +} + +TEST_F(CppInterface, SourceLangGlslMinimalHlslVertexShaderFails) { + options_.SetSourceLanguage(shaderc_source_language_glsl); + EXPECT_FALSE(CompilationSuccess(kMinimalHlslShader, + shaderc_glsl_vertex_shader, + options_)); +} + +TEST_F(CppInterface, SourceLangHlslMinimalGlslVertexShaderFails) { + options_.SetSourceLanguage(shaderc_source_language_hlsl); + EXPECT_FALSE(CompilationSuccess(kVertexOnlyShader, + shaderc_glsl_vertex_shader, + options_)); +} + +TEST_F(CppInterface, SourceLangHlslMinimalHlslVertexShaderSucceeds) { + options_.SetSourceLanguage(shaderc_source_language_hlsl); + EXPECT_TRUE(CompilationSuccess(kMinimalHlslShader, + shaderc_glsl_vertex_shader, + options_)); +} + } // anonymous namespace diff --git a/libshaderc/src/shaderc_test.cc b/libshaderc/src/shaderc_test.cc index c14b9c3..df8a5cb 100644 --- a/libshaderc/src/shaderc_test.cc +++ b/libshaderc/src/shaderc_test.cc @@ -1292,4 +1292,44 @@ TEST_F(CompileStringTest, NullSourceNameFailsCompilingToPreprocessedText) { HasSubstr("Input file name string was null.")); } +const char kGlslVertexShader[] = + "#version 140\nvoid main(){ gl_Position = vec4(0);}"; + +const char kHlslVertexShader[] = + "float4 EntryPoint(uint index : SV_VERTEXID) : SV_POSITION\n" + "{ return float4(1.0, 2.0, 3.0, 4.0); }"; + +TEST_F(CompileStringTest, LangGlslOnGlslVertexSucceeds) { + shaderc_compile_options_set_source_language(options_.get(), + shaderc_source_language_glsl); + EXPECT_TRUE(CompilationSuccess(kGlslVertexShader, + shaderc_glsl_vertex_shader, + options_.get())); +} + +TEST_F(CompileStringTest, LangGlslOnHlslVertexFails) { + shaderc_compile_options_set_source_language(options_.get(), + shaderc_source_language_glsl); + EXPECT_FALSE(CompilationSuccess(kHlslVertexShader, + shaderc_glsl_vertex_shader, + options_.get())); +} + +TEST_F(CompileStringTest, LangHlslOnGlslVertexFails) { + shaderc_compile_options_set_source_language(options_.get(), + shaderc_source_language_hlsl); + EXPECT_FALSE(CompilationSuccess(kGlslVertexShader, + shaderc_glsl_vertex_shader, + options_.get())); +} + +TEST_F(CompileStringTest, LangHlslOnHlslVertexSucceeds) { + shaderc_compile_options_set_source_language(options_.get(), + shaderc_source_language_hlsl); + EXPECT_TRUE(CompilationSuccess(kHlslVertexShader, + shaderc_glsl_vertex_shader, + options_.get())); +} + + } // anonymous namespace diff --git a/libshaderc_util/include/libshaderc_util/compiler.h b/libshaderc_util/include/libshaderc_util/compiler.h index f774007..d396ca1 100644 --- a/libshaderc_util/include/libshaderc_util/compiler.h +++ b/libshaderc_util/include/libshaderc_util/compiler.h @@ -92,6 +92,12 @@ using MacroDictionary = std::unordered_map<std::string, std::string>; // Holds all of the state required to compile source GLSL into SPIR-V. class Compiler { public: + // Source language + enum class SourceLanguage { + GLSL, // The default + HLSL, + }; + // Target environment. enum class TargetEnv { Vulkan, @@ -123,7 +129,8 @@ class Compiler { suppress_warnings_(false), generate_debug_info_(false), enabled_opt_passes_(), - target_env_(TargetEnv::Vulkan) {} + target_env_(TargetEnv::Vulkan), + source_language_(SourceLanguage::GLSL) {} // Requests that the compiler place debug information into the object code, // such as identifier names and line numbers. @@ -149,6 +156,9 @@ class Compiler { // Sets the target environment. void SetTargetEnv(TargetEnv env); + // Sets the souce language. + void SetSourceLanguage(SourceLanguage lang); + // Forces (without any verification) the default version and profile for // subsequent CompileShader() calls. void SetForcedVersionProfile(int version, EProfile profile); @@ -165,7 +175,7 @@ class Compiler { // // The initializer parameter must be a valid GlslangInitializer object. // Acquire will be called on the initializer and the result will be - // destoryed before the function ends. + // destroyed before the function ends. // // The output_type parameter determines what kind of output should be // produced. @@ -292,6 +302,9 @@ class Compiler { // messages as well as the set of available builtins, as per the // implementation of glslang. TargetEnv target_env_; + + // The source language. Defaults to GLSL. + SourceLanguage source_language_; }; // Converts a string to a vector of uint32_t by copying the content of a given diff --git a/libshaderc_util/src/compiler.cc b/libshaderc_util/src/compiler.cc index b3c0a4f..52eb81f 100644 --- a/libshaderc_util/src/compiler.cc +++ b/libshaderc_util/src/compiler.cc @@ -65,19 +65,26 @@ std::pair<int, string_piece> DecodeLineDirective(string_piece directive) { return std::make_pair(line, directive); } -// Gets the corresponding message rules for the given target environment. -EShMessages GetMessageRules(shaderc_util::Compiler::TargetEnv env) { +// Returns the Glslang message rules for the given target environment +// and source language. We assume only valid combinations are used. +EShMessages GetMessageRules(shaderc_util::Compiler::TargetEnv env, + shaderc_util::Compiler::SourceLanguage lang) { using shaderc_util::Compiler; + EShMessages result = EShMsgCascadingErrors; + if (lang == Compiler::SourceLanguage::HLSL) { + result = static_cast<EShMessages>(result | EShMsgReadHlsl); + } switch (env) { case Compiler::TargetEnv::OpenGLCompat: break; case Compiler::TargetEnv::OpenGL: - return static_cast<EShMessages>(EShMsgSpvRules | EShMsgCascadingErrors); + result = static_cast<EShMessages>(result | EShMsgSpvRules); + break; case Compiler::TargetEnv::Vulkan: - return static_cast<EShMessages>(EShMsgSpvRules | EShMsgVulkanRules | - EShMsgCascadingErrors); + result = static_cast<EShMessages>(result | EShMsgSpvRules | EShMsgVulkanRules); + break; } - return EShMsgCascadingErrors; + return result; } } // anonymous namespace @@ -177,7 +184,8 @@ std::tuple<bool, std::vector<uint32_t>, size_t> Compiler::Compile( bool success = shader.parse(&shaderc_util::kDefaultTBuiltInResource, default_version_, default_profile_, force_version_profile_, kNotForwardCompatible, - GetMessageRules(target_env_), includer); + GetMessageRules(target_env_, source_language_), + includer); success &= PrintFilteredErrors(error_tag, error_stream, warnings_as_errors_, suppress_warnings_, shader.getInfoLog(), @@ -238,6 +246,8 @@ void Compiler::AddMacroDefinition(const char* macro, size_t macro_length, void Compiler::SetTargetEnv(Compiler::TargetEnv env) { target_env_ = env; } +void Compiler::SetSourceLanguage(Compiler::SourceLanguage lang) { source_language_ = lang; } + void Compiler::SetForcedVersionProfile(int version, EProfile profile) { default_version_ = version; default_profile_ = profile; @@ -289,7 +299,7 @@ std::tuple<bool, std::string, std::string> Compiler::PreprocessShader( // So combine the existing rules with the just-give-me-preprocessor-output // flag. const auto rules = static_cast<EShMessages>(EShMsgOnlyPreprocessor | - GetMessageRules(target_env_)); + GetMessageRules(target_env_, source_language_)); std::string preprocessed_shader; const bool success = shader.preprocess( diff --git a/libshaderc_util/src/compiler_test.cc b/libshaderc_util/src/compiler_test.cc index 957f8f3..36931ff 100644 --- a/libshaderc_util/src/compiler_test.cc +++ b/libshaderc_util/src/compiler_test.cc @@ -77,6 +77,11 @@ const std::string kValuelessPredefinitionShader = "#error\n" "#endif"; +// An HLSL vertex shader. +const char kHlslVertexShader[] = + R"(float4 EntryPoint(uint index : SV_VERTEXID) : SV_POSITION + { return float4(1.0, 2.0, 3.0, 4.0); })"; + // A CountingIncluder that never returns valid content for a requested // file inclusion. class DummyCountingIncluder : public shaderc_util::CountingIncluder { @@ -311,4 +316,26 @@ INSTANTIATE_TEST_CASE_P( {"123456789", {0x34333231, 0x38373635, 0x00000039}}, })); +TEST_F(CompilerTest, SetSourceLanguageToGLSLSucceeds) { + compiler_.SetSourceLanguage(Compiler::SourceLanguage::GLSL); + EXPECT_TRUE(SimpleCompilationSucceeds(kVulkanVertexShader, EShLangVertex)); +} + +TEST_F(CompilerTest, SetSourceLanguageToGLSLFailsOnHLSL) { + compiler_.SetSourceLanguage(Compiler::SourceLanguage::GLSL); + EXPECT_FALSE(SimpleCompilationSucceeds(kHlslVertexShader, EShLangVertex)); +} + +TEST_F(CompilerTest, SetSourceLanguageToHLSLSucceeds) { + compiler_.SetSourceLanguage(Compiler::SourceLanguage::HLSL); + EXPECT_TRUE(SimpleCompilationSucceeds(kHlslVertexShader, EShLangVertex)) + << errors_; +} + +TEST_F(CompilerTest, SetSourceLanguageToHLSLFailsOnGLSL) { + compiler_.SetSourceLanguage(Compiler::SourceLanguage::HLSL); + EXPECT_FALSE(SimpleCompilationSucceeds(kVulkanVertexShader, EShLangVertex)); +} + + } // anonymous namespace |