aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Neto <dneto@google.com>2016-10-29 09:21:51 -0400
committerDavid Neto <dneto@google.com>2016-11-08 16:14:01 -0500
commitf0363818a74d60e768ef6ed01d303062b2bf7037 (patch)
tree3ec8dd8824db727b0632b7f751ede42989b912ea
parentaaa8b0cf8696174e411fc280b46f3bfeb4f7ec9c (diff)
downloadshaderc-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.txt4
-rw-r--r--libshaderc/include/shaderc/shaderc.hpp73
-rw-r--r--libshaderc/src/shaderc.cc4
-rw-r--r--libshaderc/src/shaderc_cpp_test.cc73
-rw-r--r--libshaderc/src/shaderc_test.cc114
-rw-r--r--libshaderc_util/include/libshaderc_util/compiler.h9
-rw-r--r--libshaderc_util/src/compiler.cc23
-rw-r--r--libshaderc_util/src/compiler_test.cc34
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