diff options
author | David Neto <dneto@google.com> | 2016-10-29 09:21:51 -0400 |
---|---|---|
committer | David Neto <dneto@google.com> | 2016-11-08 16:14:01 -0500 |
commit | f0363818a74d60e768ef6ed01d303062b2bf7037 (patch) | |
tree | 3ec8dd8824db727b0632b7f751ede42989b912ea | |
parent | aaa8b0cf8696174e411fc280b46f3bfeb4f7ec9c (diff) | |
download | shaderc-f0363818a74d60e768ef6ed01d303062b2bf7037.tar.gz |
C, C++ APIs are sensitive to entry_point_name
Before, the C API ignored the entry point name.
Before, the C++ API didn't have entry points that accepted
an entry point name.
-rw-r--r-- | libshaderc/CMakeLists.txt | 4 | ||||
-rw-r--r-- | libshaderc/include/shaderc/shaderc.hpp | 73 | ||||
-rw-r--r-- | libshaderc/src/shaderc.cc | 4 | ||||
-rw-r--r-- | libshaderc/src/shaderc_cpp_test.cc | 73 | ||||
-rw-r--r-- | libshaderc/src/shaderc_test.cc | 114 | ||||
-rw-r--r-- | libshaderc_util/include/libshaderc_util/compiler.h | 9 | ||||
-rw-r--r-- | libshaderc_util/src/compiler.cc | 23 | ||||
-rw-r--r-- | libshaderc_util/src/compiler_test.cc | 34 |
8 files changed, 260 insertions, 74 deletions
diff --git a/libshaderc/CMakeLists.txt b/libshaderc/CMakeLists.txt index 59ff932..888c858 100644 --- a/libshaderc/CMakeLists.txt +++ b/libshaderc/CMakeLists.txt @@ -23,7 +23,7 @@ target_link_libraries(shaderc PRIVATE SPIRV-Tools) shaderc_add_tests( TEST_PREFIX shaderc LINK_LIBS shaderc - INCLUDE_DIRS include ${glslang_SOURCE_DIR} + INCLUDE_DIRS include ${glslang_SOURCE_DIR} ${spirv-tools_SOURCE_DIR}/include TEST_NAMES shaderc shaderc_cpp) @@ -34,7 +34,7 @@ shaderc_combine_static_lib(shaderc_combined shaderc) shaderc_add_tests( TEST_PREFIX shaderc_combined LINK_LIBS shaderc_combined ${CMAKE_THREAD_LIBS_INIT} - INCLUDE_DIRS include ${glslang_SOURCE_DIR} + INCLUDE_DIRS include ${glslang_SOURCE_DIR} ${spirv-tools_SOURCE_DIR}/include TEST_NAMES shaderc shaderc_cpp) diff --git a/libshaderc/include/shaderc/shaderc.hpp b/libshaderc/include/shaderc/shaderc.hpp index 1dc2631..a3facfc 100644 --- a/libshaderc/include/shaderc/shaderc.hpp +++ b/libshaderc/include/shaderc/shaderc.hpp @@ -279,6 +279,9 @@ class Compiler { // The input_file_name is a null-termintated string. It is used as a tag to // identify the source string in cases like emitting error messages. It // doesn't have to be a 'file name'. + // The entry_point_name parameter is a null-terminated string specifying + // the entry point name for HLSL compilation. For GLSL compilation, the + // entry point name is assumed to be "main". // The compilation is passed any options specified in the CompileOptions // parameter. // It is valid for the returned CompilationResult object to outlive this @@ -290,16 +293,30 @@ class Compiler { size_t source_text_size, shaderc_shader_kind shader_kind, const char* input_file_name, + const char* entry_point_name, const CompileOptions& options) const { shaderc_compilation_result_t compilation_result = shaderc_compile_into_spv( compiler_, source_text, source_text_size, shader_kind, input_file_name, - "main", options.options_); + entry_point_name, options.options_); return SpvCompilationResult(compilation_result); } + // Compiles the given source shader and returns a SPIR-V binary module + // compilation result. + // Like the first CompileGlslToSpv method but assumes the entry point name + // is "main". + SpvCompilationResult CompileGlslToSpv(const char* source_text, + size_t source_text_size, + shaderc_shader_kind shader_kind, + const char* input_file_name, + const CompileOptions& options) const { + return CompileGlslToSpv(source_text, source_text_size, shader_kind, + input_file_name, "main", options); + } + // Compiles the given source GLSL and returns a SPIR-V binary module // compilation result. - // Like the first CompileGlslToSpv method but uses default options. + // Like the previous CompileGlslToSpv method but uses default options. SpvCompilationResult CompileGlslToSpv(const char* source_text, size_t source_text_size, shaderc_shader_kind shader_kind, @@ -310,10 +327,10 @@ class Compiler { return SpvCompilationResult(compilation_result); } - // Compiles the given source GLSL and returns a SPIR-V binary module + // Compiles the given source shader and returns a SPIR-V binary module // compilation result. // Like the first CompileGlslToSpv method but the source is provided as - // a std::string. + // a std::string, and we assume the entry point is "main". SpvCompilationResult CompileGlslToSpv(const std::string& source_text, shaderc_shader_kind shader_kind, const char* input_file_name, @@ -322,10 +339,23 @@ class Compiler { input_file_name, options); } - // Compiles the given source GLSL and returns a SPIR-V binary module + // Compiles the given source shader and returns a SPIR-V binary module // compilation result. // Like the first CompileGlslToSpv method but the source is provided as - // a std::string and also uses default compiler options. + // a std::string. + SpvCompilationResult CompileGlslToSpv(const std::string& source_text, + shaderc_shader_kind shader_kind, + const char* input_file_name, + const char* entry_point_name, + const CompileOptions& options) const { + return CompileGlslToSpv(source_text.data(), source_text.size(), shader_kind, + input_file_name, entry_point_name, options); + } + + // Compiles the given source GLSL and returns a SPIR-V binary module + // compilation result. + // Like the previous CompileGlslToSpv method but assumes the entry point + // name is "main". SpvCompilationResult CompileGlslToSpv(const std::string& source_text, shaderc_shader_kind shader_kind, const char* input_file_name) const { @@ -383,23 +413,46 @@ class Compiler { AssemblyCompilationResult CompileGlslToSpvAssembly( const char* source_text, size_t source_text_size, shaderc_shader_kind shader_kind, const char* input_file_name, - const CompileOptions& options) const { + const char* entry_point_name, const CompileOptions& options) const { shaderc_compilation_result_t compilation_result = shaderc_compile_into_spv_assembly( compiler_, source_text, source_text_size, shader_kind, - input_file_name, "main", options.options_); + input_file_name, entry_point_name, options.options_); return AssemblyCompilationResult(compilation_result); } // Compiles the given source GLSL and returns the SPIR-V assembly text + // compilation result. + // Similare to the previous method, but assumes entry point name is "main". + AssemblyCompilationResult CompileGlslToSpvAssembly( + const char* source_text, size_t source_text_size, + shaderc_shader_kind shader_kind, const char* input_file_name, + const CompileOptions& options) const { + return CompileGlslToSpvAssembly(source_text, source_text_size, shader_kind, + input_file_name, "main", options); + } + + // Compiles the given source GLSL and returns the SPIR-V assembly text // result. Like the first CompileGlslToSpvAssembly method but the source // is provided as a std::string. Options are otherwise similar to // the first CompileToSpv method. AssemblyCompilationResult CompileGlslToSpvAssembly( const std::string& source_text, shaderc_shader_kind shader_kind, - const char* input_file_name, const CompileOptions& options) const { + const char* input_file_name, const char* entry_point_name, + const CompileOptions& options) const { return CompileGlslToSpvAssembly(source_text.data(), source_text.size(), - shader_kind, input_file_name, options); + shader_kind, input_file_name, + entry_point_name, options); + } + + // Compiles the given source GLSL and returns the SPIR-V assembly text + // result. Like the previous CompileGlslToSpvAssembly method but assumes + // the entry point name is "main". + AssemblyCompilationResult CompileGlslToSpvAssembly( + const std::string& source_text, shaderc_shader_kind shader_kind, + const char* input_file_name, const CompileOptions& options) const { + return CompileGlslToSpvAssembly(source_text, shader_kind, input_file_name, + "main", options); } // Preprocesses the given source GLSL and returns the preprocessed diff --git a/libshaderc/src/shaderc.cc b/libshaderc/src/shaderc.cc index 845320b..15d16d2 100644 --- a/libshaderc/src/shaderc.cc +++ b/libshaderc/src/shaderc.cc @@ -394,7 +394,7 @@ shaderc_compilation_result_t CompileToSpecifiedOutputType( std::tie(compilation_succeeded, compilation_output_data, compilation_output_data_size_in_bytes) = additional_options->compiler.Compile( - source_string, forced_stage, input_file_name_str, + source_string, forced_stage, input_file_name_str, entry_point_name, // stage_deducer has a flag: error_, which we need to check later. // We need to make this a reference wrapper, so that std::function // won't make a copy for this callable object. @@ -406,7 +406,7 @@ shaderc_compilation_result_t CompileToSpecifiedOutputType( std::tie(compilation_succeeded, compilation_output_data, compilation_output_data_size_in_bytes) = shaderc_util::Compiler().Compile( - source_string, forced_stage, input_file_name_str, + source_string, forced_stage, input_file_name_str, entry_point_name, std::ref(stage_deducer), includer, output_type, &errors, &total_warnings, &total_errors, compiler->initializer); } diff --git a/libshaderc/src/shaderc_cpp_test.cc b/libshaderc/src/shaderc_cpp_test.cc index 2762197..6917e59 100644 --- a/libshaderc/src/shaderc_cpp_test.cc +++ b/libshaderc/src/shaderc_cpp_test.cc @@ -19,6 +19,7 @@ #include <unordered_map> #include "SPIRV/spirv.hpp" +#include "spirv-tools/libspirv.hpp" #include "common_shaders_for_test.h" #include "shaderc/shaderc.hpp" @@ -1017,30 +1018,86 @@ TEST_F(CppInterface, BeginAndEndOnPreprocessedResult) { TEST_F(CppInterface, SourceLangGlslMinimalGlslVertexShaderSucceeds) { options_.SetSourceLanguage(shaderc_source_language_glsl); - EXPECT_TRUE(CompilationSuccess(kVertexOnlyShader, - shaderc_glsl_vertex_shader, + 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_)); + shaderc_glsl_vertex_shader, options_)); } TEST_F(CppInterface, SourceLangHlslMinimalGlslVertexShaderFails) { options_.SetSourceLanguage(shaderc_source_language_hlsl); - EXPECT_FALSE(CompilationSuccess(kVertexOnlyShader, - shaderc_glsl_vertex_shader, + 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, + EXPECT_TRUE(CompilationSuccess(kMinimalHlslShader, shaderc_glsl_vertex_shader, options_)); } +TEST( + EntryPointTest, + SourceLangHlslMinimalHlslVertexShaderAsConstCharPtrSucceedsWithEntryPointName) { + shaderc::Compiler compiler; + CompileOptions options; + options.SetSourceLanguage(shaderc_source_language_hlsl); + auto result = compiler.CompileGlslToSpv( + kMinimalHlslShader, strlen(kMinimalHlslShader), + shaderc_glsl_vertex_shader, "shader", "EntryPoint", options); + std::vector<uint32_t> binary(result.begin(), result.end()); + std::string assembly; + spvtools::SpirvTools(SPV_ENV_UNIVERSAL_1_0).Disassemble(binary, &assembly); + EXPECT_THAT(assembly, + HasSubstr("OpEntryPoint Vertex %EntryPoint \"EntryPoint\"")) + << assembly; +} + +TEST( + EntryPointTest, + SourceLangHlslMinimalHlslVertexShaderAsStdStringSucceedsWithEntryPointName) { + shaderc::Compiler compiler; + CompileOptions options; + options.SetSourceLanguage(shaderc_source_language_hlsl); + std::string shader(kMinimalHlslShader); + auto result = compiler.CompileGlslToSpv(shader, shaderc_glsl_vertex_shader, + "shader", "EntryPoint", options); + std::vector<uint32_t> binary(result.begin(), result.end()); + std::string assembly; + spvtools::SpirvTools(SPV_ENV_UNIVERSAL_1_0).Disassemble(binary, &assembly); + EXPECT_THAT(assembly, + HasSubstr("OpEntryPoint Vertex %EntryPoint \"EntryPoint\"")) + << assembly; +} + +TEST( + EntryPointTest, + SourceLangHlslMinimalHlslVertexShaderAsConstCharPtrSucceedsToAssemblyWithEntryPointName) { + shaderc::Compiler compiler; + CompileOptions options; + options.SetSourceLanguage(shaderc_source_language_hlsl); + auto assembly = compiler.CompileGlslToSpvAssembly( + kMinimalHlslShader, strlen(kMinimalHlslShader), + shaderc_glsl_vertex_shader, "shader", "EntryPoint", options); + EXPECT_THAT(std::string(assembly.begin(), assembly.end()), + HasSubstr("OpEntryPoint Vertex %EntryPoint \"EntryPoint\"")); +} + +TEST( + EntryPointTest, + SourceLangHlslMinimalHlslVertexShaderAsStdStringSucceedsToAssemblyWithEntryPointName) { + shaderc::Compiler compiler; + CompileOptions options; + options.SetSourceLanguage(shaderc_source_language_hlsl); + std::string shader(kMinimalHlslShader); + auto assembly = compiler.CompileGlslToSpvAssembly( + shader, shaderc_glsl_vertex_shader, "shader", "EntryPoint", options); + EXPECT_THAT(std::string(assembly.begin(), assembly.end()), + HasSubstr("OpEntryPoint Vertex %EntryPoint \"EntryPoint\"")); +} + } // anonymous namespace diff --git a/libshaderc/src/shaderc_test.cc b/libshaderc/src/shaderc_test.cc index 280a5d1..bde5cf0 100644 --- a/libshaderc/src/shaderc_test.cc +++ b/libshaderc/src/shaderc_test.cc @@ -72,43 +72,49 @@ enum class OutputType { }; // Generate a compilation result object with the given compile, -// shader source, shader kind, input file name, options, and for the -// specified output type. +// shader source, shader kind, input file name, entry point name, options, +// and for the specified output type. The entry point name is only significant +// for HLSL compilation. shaderc_compilation_result_t MakeCompilationResult( const shaderc_compiler_t compiler, const std::string& shader, shaderc_shader_kind kind, const char* input_file_name, - const shaderc_compile_options_t options, OutputType output_type) { + const char* entry_point_name, const shaderc_compile_options_t options, + OutputType output_type) { switch (output_type) { case OutputType::SpirvBinary: return shaderc_compile_into_spv(compiler, shader.c_str(), shader.size(), - kind, input_file_name, "", options); + kind, input_file_name, entry_point_name, + options); break; case OutputType::SpirvAssemblyText: - return shaderc_compile_into_spv_assembly(compiler, shader.c_str(), - shader.size(), kind, - input_file_name, "", options); + return shaderc_compile_into_spv_assembly( + compiler, shader.c_str(), shader.size(), kind, input_file_name, + entry_point_name, options); break; case OutputType::PreprocessedText: return shaderc_compile_into_preprocessed_text( - compiler, shader.c_str(), shader.size(), kind, input_file_name, "", - options); + compiler, shader.c_str(), shader.size(), kind, input_file_name, + entry_point_name, options); break; } // We shouldn't reach here. But some compilers might not know that. // Be a little defensive and produce something. return shaderc_compile_into_spv(compiler, shader.c_str(), shader.size(), kind, - input_file_name, "", options); + input_file_name, entry_point_name, options); } + // RAII class for shaderc_compilation_result. Used for shader compilation. class Compilation { public: // Compiles shader and keeps the result. Compilation(const shaderc_compiler_t compiler, const std::string& shader, shaderc_shader_kind kind, const char* input_file_name, + const char* entry_point_name, const shaderc_compile_options_t options = nullptr, OutputType output_type = OutputType::SpirvBinary) - : compiled_result_(MakeCompilationResult( - compiler, shader, kind, input_file_name, options, output_type)) {} + : compiled_result_( + MakeCompilationResult(compiler, shader, kind, input_file_name, + entry_point_name, options, output_type)) {} ~Compilation() { shaderc_result_release(compiled_result_); } @@ -155,6 +161,17 @@ class Compiler { shaderc_compiler_t compiler; }; +// RAII class for shader_compiler_options_t +class Options { + public: + Options() : options_(shaderc_compile_options_initialize()) {} + ~Options() { shaderc_compile_options_release(options_); } + shaderc_compile_options_t get() { return options_; } + + private: + shaderc_compile_options_t options_; +}; + // Helper function to check if the compilation result indicates a successful // compilation. bool CompilationResultIsSuccess(const shaderc_compilation_result_t result) { @@ -178,7 +195,7 @@ bool CompilesToValidSpv(Compiler& compiler, const std::string& shader, shaderc_shader_kind kind, const shaderc_compile_options_t options = nullptr) { const Compilation comp(compiler.get_compiler_handle(), shader, kind, "shader", - options, OutputType::SpirvBinary); + "main", options, OutputType::SpirvBinary); return ResultContainsValidSpv(comp.result()); } @@ -195,7 +212,7 @@ class CompileStringTest : public testing::Test { OutputType output_type = OutputType::SpirvBinary) { return CompilationResultIsSuccess( Compilation(compiler_.get_compiler_handle(), shader, kind, "shader", - options, output_type) + "main", options, output_type) .result()); } @@ -206,7 +223,7 @@ class CompileStringTest : public testing::Test { const shaderc_compile_options_t options = nullptr, OutputType output_type = OutputType::SpirvBinary) { const Compilation comp(compiler_.get_compiler_handle(), shader, kind, - "shader", options, output_type); + "shader", "main", options, output_type); EXPECT_TRUE(CompilationResultIsSuccess(comp.result())) << kind << '\n' << shader; return shaderc_result_get_error_message(comp.result()); @@ -219,7 +236,7 @@ class CompileStringTest : public testing::Test { OutputType output_type = OutputType::SpirvBinary, const char* source_name = "shader") { const Compilation comp(compiler_.get_compiler_handle(), shader, kind, - source_name, options, output_type); + source_name, "main", options, output_type); EXPECT_FALSE(CompilationResultIsSuccess(comp.result())) << kind << '\n' << shader; EXPECT_EQ(0u, shaderc_result_get_length(comp.result())); @@ -232,7 +249,7 @@ class CompileStringTest : public testing::Test { const shaderc_compile_options_t options = nullptr, OutputType output_type = OutputType::SpirvBinary) { const Compilation comp(compiler_.get_compiler_handle(), shader, kind, - "shader", options, output_type); + "shader", "main", options, output_type); return shaderc_result_get_error_message(comp.result()); }; @@ -243,7 +260,7 @@ class CompileStringTest : public testing::Test { const shaderc_compile_options_t options = nullptr, OutputType output_type = OutputType::SpirvBinary) { const Compilation comp(compiler_.get_compiler_handle(), shader, kind, - "shader", options, output_type); + "shader", "main", options, output_type); EXPECT_TRUE(CompilationResultIsSuccess(comp.result())) << kind << '\n' << shader; // Use string(const char* s, size_t n) constructor instead of @@ -362,7 +379,7 @@ TEST_F(CompileStringTest, WorksWithCompileOptions) { TEST_F(CompileStringTest, GetNumErrors) { Compilation comp(compiler_.get_compiler_handle(), kTwoErrorsShader, - shaderc_glsl_vertex_shader, "shader"); + shaderc_glsl_vertex_shader, "shader", "main"); // Expects compilation failure and two errors. EXPECT_FALSE(CompilationResultIsSuccess(comp.result())); EXPECT_EQ(2u, shaderc_result_get_num_errors(comp.result())); @@ -372,7 +389,7 @@ TEST_F(CompileStringTest, GetNumErrors) { TEST_F(CompileStringTest, GetNumWarnings) { Compilation comp(compiler_.get_compiler_handle(), kTwoWarningsShader, - shaderc_glsl_vertex_shader, "shader"); + shaderc_glsl_vertex_shader, "shader", "main"); // Expects compilation success with two warnings. EXPECT_TRUE(CompilationResultIsSuccess(comp.result())); EXPECT_EQ(2u, shaderc_result_get_num_warnings(comp.result())); @@ -382,7 +399,7 @@ TEST_F(CompileStringTest, GetNumWarnings) { TEST_F(CompileStringTest, ZeroErrorsZeroWarnings) { Compilation comp(compiler_.get_compiler_handle(), kMinimalShader, - shaderc_glsl_vertex_shader, "shader"); + shaderc_glsl_vertex_shader, "shader", "main"); // Expects compilation success with zero warnings. EXPECT_TRUE(CompilationResultIsSuccess(comp.result())); EXPECT_EQ(0u, shaderc_result_get_num_warnings(comp.result())); @@ -394,7 +411,7 @@ TEST_F(CompileStringTest, ErrorTypeUnknownShaderStage) { // The shader kind/stage can not be determined, the error type field should // indicate the error type is shaderc_shader_kind_error. Compilation comp(compiler_.get_compiler_handle(), kMinimalShader, - shaderc_glsl_infer_from_source, "shader"); + shaderc_glsl_infer_from_source, "shader", "main"); EXPECT_EQ(shaderc_compilation_status_invalid_stage, shaderc_result_get_compilation_status(comp.result())); } @@ -402,7 +419,7 @@ TEST_F(CompileStringTest, ErrorTypeCompilationError) { // The shader kind is valid, the result object's error type field should // indicate this compilaion fails due to compilation errors. Compilation comp(compiler_.get_compiler_handle(), kTwoErrorsShader, - shaderc_glsl_vertex_shader, "shader"); + shaderc_glsl_vertex_shader, "shader", "main"); EXPECT_EQ(shaderc_compilation_status_compilation_error, shaderc_result_get_compilation_status(comp.result())); } @@ -869,8 +886,8 @@ TEST_P(IncluderTests, SetIncluderCallbacks) { TestIncluder::ReleaseIncluderResponseWrapper, &includer); const Compilation comp(compiler.get_compiler_handle(), shader, - shaderc_glsl_vertex_shader, "shader", options.get(), - OutputType::PreprocessedText); + shaderc_glsl_vertex_shader, "shader", "main", + options.get(), OutputType::PreprocessedText); // Checks the existence of the expected string. EXPECT_THAT(shaderc_result_get_bytes(comp.result()), HasSubstr(test_case.expected_substring())); @@ -892,7 +909,7 @@ TEST_P(IncluderTests, SetIncluderCallbacksClonedOptions) { shaderc_compile_options_clone(options.get())); const Compilation comp(compiler.get_compiler_handle(), shader, - shaderc_glsl_vertex_shader, "shader", + shaderc_glsl_vertex_shader, "shader", "main", cloned_options.get(), OutputType::PreprocessedText); // Checks the existence of the expected string. EXPECT_THAT(shaderc_result_get_bytes(comp.result()), @@ -998,13 +1015,13 @@ TEST_F(CompileStringWithOptionsTest, // Warnings on particular lines should be inhibited. Compilation comp_line(compiler_.get_compiler_handle(), kDeprecatedAttributeShader, shaderc_glsl_vertex_shader, - "shader", options_.get()); + "shader", "main", options_.get()); EXPECT_EQ(0u, shaderc_result_get_num_warnings(comp_line.result())); // Global warnings should be inhibited. - Compilation comp_global(compiler_.get_compiler_handle(), - kMinimalUnknownVersionShader, - shaderc_glsl_vertex_shader, "shader", options_.get()); + Compilation comp_global( + compiler_.get_compiler_handle(), kMinimalUnknownVersionShader, + shaderc_glsl_vertex_shader, "shader", "main", options_.get()); EXPECT_EQ(0u, shaderc_result_get_num_warnings(comp_global.result())); } @@ -1019,13 +1036,13 @@ TEST_F(CompileStringWithOptionsTest, // Warnings on particular lines should be inhibited. Compilation comp_line(compiler_.get_compiler_handle(), kDeprecatedAttributeShader, shaderc_glsl_vertex_shader, - "shader", options_.get()); + "shader", "main", options_.get()); EXPECT_EQ(0u, shaderc_result_get_num_warnings(comp_line.result())); // Global warnings should be inhibited. - Compilation comp_global(compiler_.get_compiler_handle(), - kMinimalUnknownVersionShader, - shaderc_glsl_vertex_shader, "shader", options_.get()); + Compilation comp_global( + compiler_.get_compiler_handle(), kMinimalUnknownVersionShader, + shaderc_glsl_vertex_shader, "shader", "main", options_.get()); EXPECT_EQ(0u, shaderc_result_get_num_warnings(comp_global.result())); } @@ -1327,4 +1344,33 @@ TEST_F(CompileStringTest, LangHlslOnHlslVertexSucceeds) { options_.get())); } +TEST(EntryPointTest, + LangGlslOnHlslVertexSucceedsButAssumesEntryPointNameIsMain) { + Compiler compiler; + Options options; + auto compilation = + Compilation(compiler.get_compiler_handle(), kGlslVertexShader, + shaderc_glsl_vertex_shader, "shader", "blah blah blah", + options.get(), OutputType::SpirvAssemblyText); + + EXPECT_THAT(shaderc_result_get_bytes(compilation.result()), + HasSubstr("OpEntryPoint Vertex %main \"main\"")) + << std::string(shaderc_result_get_bytes(compilation.result())); +} + +TEST(EntryPointTest, LangHlslOnHlslVertexSucceedsWithGivenEntryPointName) { + Compiler compiler; + Options options; + shaderc_compile_options_set_source_language(options.get(), + shaderc_source_language_hlsl); + auto compilation = + Compilation(compiler.get_compiler_handle(), kHlslVertexShader, + shaderc_glsl_vertex_shader, "shader", "EntryPoint", + options.get(), OutputType::SpirvAssemblyText); + + EXPECT_THAT(shaderc_result_get_bytes(compilation.result()), + HasSubstr("OpEntryPoint Vertex %EntryPoint \"EntryPoint\"")) + << std::string(shaderc_result_get_bytes(compilation.result())); +} + } // anonymous namespace diff --git a/libshaderc_util/include/libshaderc_util/compiler.h b/libshaderc_util/include/libshaderc_util/compiler.h index d396ca1..fc47766 100644 --- a/libshaderc_util/include/libshaderc_util/compiler.h +++ b/libshaderc_util/include/libshaderc_util/compiler.h @@ -94,7 +94,7 @@ class Compiler { public: // Source language enum class SourceLanguage { - GLSL, // The default + GLSL, // The default HLSL, }; @@ -168,6 +168,11 @@ class Compiler { // If the forced_shader stage parameter is not EShLangCount then // the shader is assumed to be of the given stage. // + // For HLSL compilation, entry_point_name is the null-terminated string for + // the + // entry point. For GLSL compilation, entry_point_name is ignored, and + // compilation assumes the entry point is named "main". + // // The stage_callback function will be called if a shader_stage has // not been forced and the stage can not be determined // from the shader text. Any #include directives are parsed with the given @@ -194,7 +199,7 @@ class Compiler { // If the output is a text string, the size equals the length of that string. std::tuple<bool, std::vector<uint32_t>, size_t> Compile( const string_piece& input_source_string, EShLanguage forced_shader_stage, - const std::string& error_tag, + const std::string& error_tag, const char* entry_point_name, const std::function<EShLanguage(std::ostream* error_stream, const string_piece& error_tag)>& stage_callback, diff --git a/libshaderc_util/src/compiler.cc b/libshaderc_util/src/compiler.cc index 52eb81f..a170a4c 100644 --- a/libshaderc_util/src/compiler.cc +++ b/libshaderc_util/src/compiler.cc @@ -81,7 +81,8 @@ EShMessages GetMessageRules(shaderc_util::Compiler::TargetEnv env, result = static_cast<EShMessages>(result | EShMsgSpvRules); break; case Compiler::TargetEnv::Vulkan: - result = static_cast<EShMessages>(result | EShMsgSpvRules | EShMsgVulkanRules); + result = + static_cast<EShMessages>(result | EShMsgSpvRules | EShMsgVulkanRules); break; } return result; @@ -92,7 +93,7 @@ EShMessages GetMessageRules(shaderc_util::Compiler::TargetEnv env, namespace shaderc_util { std::tuple<bool, std::vector<uint32_t>, size_t> Compiler::Compile( const string_piece& input_source_string, EShLanguage forced_shader_stage, - const std::string& error_tag, + const std::string& error_tag, const char* entry_point_name, const std::function<EShLanguage(std::ostream* error_stream, const string_piece& error_tag)>& stage_callback, @@ -179,13 +180,13 @@ std::tuple<bool, std::vector<uint32_t>, size_t> Compiler::Compile( shader.setStringsWithLengthsAndNames(&shader_strings, &shader_lengths, &string_names, 1); shader.setPreamble(preamble.c_str()); + shader.setEntryPoint(entry_point_name); // TODO(dneto): Generate source-level debug info if requested. - bool success = shader.parse(&shaderc_util::kDefaultTBuiltInResource, - default_version_, default_profile_, - force_version_profile_, kNotForwardCompatible, - GetMessageRules(target_env_, source_language_), - includer); + bool success = shader.parse( + &shaderc_util::kDefaultTBuiltInResource, default_version_, + default_profile_, force_version_profile_, kNotForwardCompatible, + GetMessageRules(target_env_, source_language_), includer); success &= PrintFilteredErrors(error_tag, error_stream, warnings_as_errors_, suppress_warnings_, shader.getInfoLog(), @@ -246,7 +247,9 @@ 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::SetSourceLanguage(Compiler::SourceLanguage lang) { + source_language_ = lang; +} void Compiler::SetForcedVersionProfile(int version, EProfile profile) { default_version_ = version; @@ -298,8 +301,8 @@ std::tuple<bool, std::string, std::string> Compiler::PreprocessShader( // The preprocessor might be sensitive to the target environment. // So combine the existing rules with the just-give-me-preprocessor-output // flag. - const auto rules = static_cast<EShMessages>(EShMsgOnlyPreprocessor | - GetMessageRules(target_env_, source_language_)); + const auto rules = static_cast<EShMessages>( + EShMsgOnlyPreprocessor | 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 36931ff..3af7c22 100644 --- a/libshaderc_util/src/compiler_test.cc +++ b/libshaderc_util/src/compiler_test.cc @@ -16,7 +16,7 @@ #include <sstream> -#include <gtest/gtest.h> +#include <gmock/gmock.h> #include "death_test.h" #include "libshaderc_util/counting_includer.h" @@ -24,6 +24,7 @@ namespace { using shaderc_util::Compiler; +using ::testing::HasSubstr; // A trivial vertex shader const char kVertexShader[] = @@ -105,10 +106,6 @@ class CompilerTest : public testing::Test { // shader stage. bool SimpleCompilationSucceedsForOutputType( std::string source, EShLanguage stage, Compiler::OutputType output_type) { - std::function<EShLanguage(std::ostream*, const shaderc_util::string_piece&)> - stage_callback = [](std::ostream*, const shaderc_util::string_piece&) { - return EShLangCount; - }; std::stringstream errors; size_t total_warnings = 0; size_t total_errors = 0; @@ -116,7 +113,7 @@ class CompilerTest : public testing::Test { bool result = false; DummyCountingIncluder dummy_includer; std::tie(result, std::ignore, std::ignore) = compiler_.Compile( - source, stage, "shader", stage_callback, dummy_includer, + source, stage, "shader", "main", dummy_stage_callback_, dummy_includer, Compiler::OutputType::SpirvBinary, &errors, &total_warnings, &total_errors, &initializer); errors_ = errors.str(); @@ -134,6 +131,11 @@ class CompilerTest : public testing::Test { Compiler compiler_; // The error string from the most recent compilation. std::string errors_; + std::function<EShLanguage(std::ostream*, const shaderc_util::string_piece&)> + dummy_stage_callback_ = + [](std::ostream*, const shaderc_util::string_piece&) { + return EShLangCount; + }; }; TEST_F(CompilerTest, SimpleVertexShaderCompilesSuccessfullyToBinary) { @@ -337,5 +339,25 @@ TEST_F(CompilerTest, SetSourceLanguageToHLSLFailsOnGLSL) { EXPECT_FALSE(SimpleCompilationSucceeds(kVulkanVertexShader, EShLangVertex)); } +TEST_F(CompilerTest, EntryPointParameterTakesEffectForHLSL) { + compiler_.SetSourceLanguage(Compiler::SourceLanguage::HLSL); + std::stringstream errors; + size_t total_warnings = 0; + size_t total_errors = 0; + shaderc_util::GlslangInitializer initializer; + bool result = false; + DummyCountingIncluder dummy_includer; + std::vector<uint32_t> words; + std::tie(result, words, std::ignore) = + compiler_.Compile(kHlslVertexShader, EShLangVertex, "shader", + "EntryPoint", dummy_stage_callback_, dummy_includer, + Compiler::OutputType::SpirvAssemblyText, &errors, + &total_warnings, &total_errors, &initializer); + EXPECT_TRUE(result); + std::string assembly(reinterpret_cast<char*>(words.data())); + EXPECT_THAT(assembly, + HasSubstr("OpEntryPoint Vertex %EntryPoint \"EntryPoint\"")) + << assembly; +} } // anonymous namespace |