Sort out target environments used in different components.
SPIRV-Tools has its own target environment definition, and public
shaderc API has its own. A new one is added into Compiler in
shaderc_util, for better isolation.
Now shaderc_util::Compiler's interface accepts target environment,
not glslang messages anymore. All the conversion to glslang messages
are done in the implementation now.
diff --git a/libshaderc/src/shaderc.cc b/libshaderc/src/shaderc.cc
index f301158..4702608 100644
--- a/libshaderc/src/shaderc.cc
+++ b/libshaderc/src/shaderc.cc
@@ -70,20 +70,6 @@
return EShLangCount;
}
-// Converts shaderc_target_env to EShMessages
-EShMessages GetMessageRules(shaderc_target_env target) {
- switch (target) {
- case shaderc_target_env_opengl_compat:
- break;
- case shaderc_target_env_opengl:
- return static_cast<EShMessages>(EShMsgSpvRules | EShMsgCascadingErrors);
- case shaderc_target_env_vulkan:
- return static_cast<EShMessages>(EShMsgSpvRules | EShMsgVulkanRules |
- EShMsgCascadingErrors);
- }
- return EShMsgCascadingErrors;
-}
-
// A wrapper functor class to be used as stage deducer for libshaderc_util
// Compile() interface. When the given shader kind is one of the default shader
// kinds, this functor will be called if #pragma is not found in the source
@@ -237,14 +223,29 @@
void* user_data_;
};
+// Converts the target env to the corresponding one in shaderc_util::Compiler.
+shaderc_util::Compiler::TargetEnv GetCompilerTargetEnv(shaderc_target_env env) {
+ switch (env) {
+ case shaderc_target_env_opengl:
+ return shaderc_util::Compiler::TargetEnv::OpenGL;
+ case shaderc_target_env_opengl_compat:
+ return shaderc_util::Compiler::TargetEnv::OpenGLCompat;
+ case shaderc_target_env_vulkan:
+ default:
+ break;
+ }
+
+ return shaderc_util::Compiler::TargetEnv::Vulkan;
+}
+
} // anonymous namespace
struct shaderc_compile_options {
- shaderc_compile_options() : include_user_data(nullptr) {}
+ shaderc_target_env target_env = shaderc_target_env_default;
shaderc_util::Compiler compiler;
- shaderc_include_resolve_fn include_resolver;
- shaderc_include_result_release_fn include_result_releaser;
- void* include_user_data;
+ shaderc_include_resolve_fn include_resolver = nullptr;
+ shaderc_include_result_release_fn include_result_releaser = nullptr;
+ void* include_user_data = nullptr;
};
shaderc_compile_options_t shaderc_compile_options_initialize() {
@@ -327,7 +328,8 @@
uint32_t version) {
// "version" reserved for future use, intended to distinguish between
// different versions of a target environment
- options->compiler.SetMessageRules(GetMessageRules(target));
+ options->target_env = target;
+ options->compiler.SetTargetEnv(GetCompilerTargetEnv(target));
}
void shaderc_compile_options_set_warnings_as_errors(
@@ -459,7 +461,7 @@
shaderc_compilation_result_t shaderc_assemble_into_spv(
const shaderc_compiler_t compiler, const char* source_assembly,
size_t source_assembly_size,
- const shaderc_compile_options_t /* additional_options */) {
+ const shaderc_compile_options_t additional_options) {
auto* result = new (std::nothrow) shaderc_compilation_result_spv_binary;
if (!result) return nullptr;
result->compilation_status = shaderc_compilation_status_invalid_assembly;
@@ -469,7 +471,10 @@
TRY_IF_EXCEPTIONS_ENABLED {
spv_binary assembling_output_data = nullptr;
std::string errors;
+ const auto target_env = additional_options ? additional_options->target_env
+ : shaderc_target_env_default;
const bool assembling_succeeded = shaderc_util::SpirvToolsAssemble(
+ GetCompilerTargetEnv(target_env),
{source_assembly, source_assembly + source_assembly_size},
&assembling_output_data, &errors);
result->num_errors = !assembling_succeeded;
diff --git a/libshaderc/src/shaderc_cpp_test.cc b/libshaderc/src/shaderc_cpp_test.cc
index 88ed03d..521f109 100644
--- a/libshaderc/src/shaderc_cpp_test.cc
+++ b/libshaderc/src/shaderc_cpp_test.cc
@@ -130,15 +130,17 @@
}
// Assembles the given SPIR-V assembly and returns true on success.
- bool AssemblingSuccess(const std::string& shader) const {
- return compiler_.AssembleToSpv(shader).GetCompilationStatus() ==
+ bool AssemblingSuccess(const std::string& shader,
+ const CompileOptions& options) const {
+ return compiler_.AssembleToSpv(shader, options).GetCompilationStatus() ==
shaderc_compilation_status_success;
}
// Assembles the given SPIR-V assembly and returns true if the result contains
// a valid SPIR-V module.
- bool AssemblingValid(const std::string& shader) const {
- return IsValidSpv(compiler_.AssembleToSpv(shader));
+ bool AssemblingValid(const std::string& shader,
+ const CompileOptions& options) const {
+ return IsValidSpv(compiler_.AssembleToSpv(shader, options));
}
// Compiles a shader, expects compilation success, and returns the output
@@ -218,7 +220,7 @@
}
TEST_F(CppInterface, AssembleEmptyString) {
- EXPECT_TRUE(AssemblingSuccess(""));
+ EXPECT_TRUE(AssemblingSuccess("", options_));
}
TEST_F(CppInterface, ResultObjectMoves) {
@@ -236,12 +238,20 @@
}
TEST_F(CppInterface, AssembleGarbageString) {
- const auto result = compiler_.AssembleToSpv("jfalkds");
+ const auto result = compiler_.AssembleToSpv("jfalkds", options_);
EXPECT_FALSE(CompilationResultIsSuccess(result));
EXPECT_EQ(0u, result.GetNumWarnings());
EXPECT_EQ(1u, result.GetNumErrors());
}
+// TODO(antiagainst): right now there is no assembling difference for all the
+// target environments exposed by shaderc. So the following is just testing the
+// target environment is accepted.
+TEST_F(CppInterface, AssembleTargetEnv) {
+ options_.SetTargetEnvironment(shaderc_target_env_opengl, 0);
+ EXPECT_TRUE(AssemblingValid("OpCapability Shader", options_));
+}
+
TEST_F(CppInterface, MinimalShader) {
EXPECT_TRUE(CompilesToValidSpv(compiler_, kMinimalShader,
shaderc_glsl_vertex_shader));
@@ -250,7 +260,7 @@
}
TEST_F(CppInterface, AssembleMinimalShader) {
- EXPECT_TRUE(AssemblingValid(kMinimalShaderAssembly));
+ EXPECT_TRUE(AssemblingValid(kMinimalShaderAssembly, options_));
}
TEST_F(CppInterface, BasicOptions) {
diff --git a/libshaderc/src/shaderc_test.cc b/libshaderc/src/shaderc_test.cc
index 6de7053..c14b9c3 100644
--- a/libshaderc/src/shaderc_test.cc
+++ b/libshaderc/src/shaderc_test.cc
@@ -266,11 +266,16 @@
// checking methods. Subclass tests can access the compiler object to set their
// properties.
class AssembleStringTest : public testing::Test {
+ public:
+ AssembleStringTest() : options_(shaderc_compile_options_initialize()) {}
+ ~AssembleStringTest() { shaderc_compile_options_release(options_); }
+
protected:
// Assembles the given assembly and returns true on success.
bool AssemblingSuccess(const std::string& assembly) {
return CompilationResultIsSuccess(
- Assembling(compiler_.get_compiler_handle(), assembly).result());
+ Assembling(compiler_.get_compiler_handle(), assembly, options_)
+ .result());
}
bool AssemblingValid(const std::string& assembly) {
@@ -280,6 +285,7 @@
}
Compiler compiler_;
+ shaderc_compile_options_t options_;
};
// Name holders so that we have test cases being grouped with only one real
@@ -312,6 +318,16 @@
EXPECT_EQ(0u, shaderc_result_get_num_warnings(assembling.result()));
}
+// TODO(antiagainst): right now there is no assembling difference for all the
+// target environments exposed by shaderc. So the following is just testing the
+// target environment is accepted.
+TEST_F(AssembleStringTest, AcceptTargetEnv) {
+ ASSERT_NE(nullptr, compiler_.get_compiler_handle());
+ shaderc_compile_options_set_target_env(options_, shaderc_target_env_opengl,
+ /* version = */ 0);
+ EXPECT_TRUE(AssemblingSuccess("OpCapability Shader"));
+}
+
TEST_F(CompileStringTest, ReallyLongShader) {
ASSERT_NE(nullptr, compiler_.get_compiler_handle());
std::string minimal_shader = "";
diff --git a/libshaderc_util/include/libshaderc_util/compiler.h b/libshaderc_util/include/libshaderc_util/compiler.h
index 8647a93..5b06ce1 100644
--- a/libshaderc_util/include/libshaderc_util/compiler.h
+++ b/libshaderc_util/include/libshaderc_util/compiler.h
@@ -22,7 +22,6 @@
#include <utility>
#include "glslang/Public/ShaderLang.h"
-#include "libshaderc_util/spirv_tools_wrapper.h"
#include "counting_includer.h"
#include "file_finder.h"
@@ -31,6 +30,10 @@
namespace shaderc_util {
+// To break recursive including. This header is already included in
+// spirv_tools_wrapper.h, so cannot include spirv_tools_wrapper.h here.
+enum class PassId;
+
// Initializes glslang on creation, and destroys it on completion.
// This object is expected to be a singleton, so that internal
// glslang state can be correctly handled.
@@ -89,6 +92,13 @@
// Holds all of the state required to compile source GLSL into SPIR-V.
class Compiler {
public:
+ // Target environment.
+ enum class TargetEnv {
+ Vulkan,
+ OpenGL,
+ OpenGLCompat,
+ };
+
enum class OutputType {
SpirvBinary, // A binary module, as defined by the SPIR-V specification.
SpirvAssemblyText, // Assembly syntax defined by the SPIRV-Tools project.
@@ -111,7 +121,7 @@
suppress_warnings_(false),
generate_debug_info_(false),
enabled_opt_passes_(),
- message_rules_(GetDefaultRules()) {}
+ target_env_(TargetEnv::Vulkan) {}
// Requests that the compiler place debug information into the object code,
// such as identifier names and line numbers.
@@ -134,11 +144,8 @@
void AddMacroDefinition(const char* macro, size_t macro_length,
const char* definition, size_t definition_length);
- // Sets message rules to be used when generating compiler warnings/errors
- void SetMessageRules(EShMessages rules);
-
- // Gets the message rules when generating compiler warnings/error.
- EShMessages GetMessageRules() const;
+ // Sets the target environment.
+ void SetTargetEnv(TargetEnv env);
// Forces (without any verification) the default version and profile for
// subsequent CompileShader() calls.
@@ -174,11 +181,11 @@
// binary code, the size is the number of bytes of valid data in the vector.
// 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 shaderc_util::string_piece& input_source_string,
- EShLanguage forced_shader_stage, const std::string& error_tag,
- const std::function<EShLanguage(
- std::ostream* error_stream,
- const shaderc_util::string_piece& error_tag)>& stage_callback,
+ const string_piece& input_source_string, EShLanguage forced_shader_stage,
+ const std::string& error_tag,
+ const std::function<EShLanguage(std::ostream* error_stream,
+ const string_piece& error_tag)>&
+ stage_callback,
CountingIncluder& includer, OutputType output_type,
std::ostream* error_stream, size_t* total_warnings, size_t* total_errors,
GlslInitializer* initializer) const;
@@ -206,10 +213,8 @@
// to be default_version_/default_profile_ regardless of the #version
// directive in the source code.
std::tuple<bool, std::string, std::string> PreprocessShader(
- const std::string& error_tag,
- const shaderc_util::string_piece& shader_source,
- const shaderc_util::string_piece& shader_preamble,
- CountingIncluder& includer) const;
+ const std::string& error_tag, const string_piece& shader_source,
+ const string_piece& shader_preamble, CountingIncluder& includer) const;
// Cleans up the preamble in a given preprocessed shader.
//
@@ -225,11 +230,11 @@
// delete the #extension directive we injected via preamble. Otherwise, we
// need to adjust it if there exists a #version directive in the original
// shader source code.
- std::string CleanupPreamble(
- const shaderc_util::string_piece& preprocessed_shader,
- const shaderc_util::string_piece& error_tag,
- const shaderc_util::string_piece& pound_extension,
- int num_include_directives, bool is_for_next_line) const;
+ std::string CleanupPreamble(const string_piece& preprocessed_shader,
+ const string_piece& error_tag,
+ const string_piece& pound_extension,
+ int num_include_directives,
+ bool is_for_next_line) const;
// Determines version and profile from command line, or the source code.
// Returns the decoded version and profile pair on success. Otherwise,
@@ -243,8 +248,7 @@
// EShLangCount. If errors occur, the second element in the pair is the
// error message. Otherwise, it's an empty string.
std::pair<EShLanguage, std::string> GetShaderStageFromSourceCode(
- shaderc_util::string_piece filename,
- const std::string& preprocessed_shader) const;
+ string_piece filename, const std::string& preprocessed_shader) const;
// Determines version and profile from command line, or the source code.
// Returns the decoded version and profile pair on success. Otherwise,
@@ -280,10 +284,12 @@
// Optimization passes to be applied.
std::vector<PassId> enabled_opt_passes_;
- // Sets the glslang EshMessages bitmask for determining which dialect of GLSL
- // and which SPIR-V codegen semantics are used. This impacts the warning &
- // error messages as well as the set of available builtins
- EShMessages message_rules_;
+ // The target environment to compile with. This controls the glslang
+ // EshMessages bitmask, which determines which dialect of GLSL and which
+ // SPIR-V codegen semantics are used. This impacts the warning & error
+ // messages as well as the set of available builtins, as per the
+ // implementation of glslang.
+ TargetEnv target_env_;
};
// Converts a string to a vector of uint32_t by copying the content of a given
diff --git a/libshaderc_util/include/libshaderc_util/spirv_tools_wrapper.h b/libshaderc_util/include/libshaderc_util/spirv_tools_wrapper.h
index 14a597d..b02e15d 100644
--- a/libshaderc_util/include/libshaderc_util/spirv_tools_wrapper.h
+++ b/libshaderc_util/include/libshaderc_util/spirv_tools_wrapper.h
@@ -18,21 +18,23 @@
#include <string>
#include <vector>
-#include "libshaderc_util/string_piece.h"
-
#include "spirv-tools/libspirv.hpp"
+#include "libshaderc_util/compiler.h"
+#include "libshaderc_util/string_piece.h"
+
namespace shaderc_util {
// Assembles the given assembly. On success, returns true, writes the assembled
// binary to *binary, and clears *errors. Otherwise, writes the error message
// into *errors.
-bool SpirvToolsAssemble(const string_piece assembly, spv_binary* binary,
- std::string* errors);
+bool SpirvToolsAssemble(Compiler::TargetEnv env, const string_piece assembly,
+ spv_binary* binary, std::string* errors);
// Disassembles the given binary. Returns true and writes the disassembled text
// to *text_or_error if successful. Otherwise, writes the error message to
// *text_or_error.
-bool SpirvToolsDisassemble(const std::vector<uint32_t>& binary,
+bool SpirvToolsDisassemble(Compiler::TargetEnv env,
+ const std::vector<uint32_t>& binary,
std::string* text_or_error);
// The ids of a list of supported optimization passes.
@@ -46,7 +48,8 @@
// in enabled_passes, without de-duplication. Returns true and writes the
// optimized binary back to *binary if successful. Otherwise, writes errors to
// *errors and the content of binary may be in an invalid state.
-bool SpirvToolsOptimize(const std::vector<PassId>& enabled_passes,
+bool SpirvToolsOptimize(Compiler::TargetEnv env,
+ const std::vector<PassId>& enabled_passes,
std::vector<uint32_t>* binary, std::string* errors);
} // namespace shaderc_util
diff --git a/libshaderc_util/src/compiler.cc b/libshaderc_util/src/compiler.cc
index fd6f65a..686f78f 100644
--- a/libshaderc_util/src/compiler.cc
+++ b/libshaderc_util/src/compiler.cc
@@ -22,6 +22,7 @@
#include "libshaderc_util/message.h"
#include "libshaderc_util/resources.h"
#include "libshaderc_util/shader_stage.h"
+#include "libshaderc_util/spirv_tools_wrapper.h"
#include "libshaderc_util/string_piece.h"
#include "libshaderc_util/version_profile.h"
@@ -63,6 +64,22 @@
directive = directive.strip("\" \n");
return std::make_pair(line, directive);
}
+
+// Gets the corresponding message rules for the given target environment.
+EShMessages GetMessageRules(shaderc_util::Compiler::TargetEnv env) {
+ using shaderc_util::Compiler;
+ switch (env) {
+ case Compiler::TargetEnv::OpenGLCompat:
+ break;
+ case Compiler::TargetEnv::OpenGL:
+ return static_cast<EShMessages>(EShMsgSpvRules | EShMsgCascadingErrors);
+ case Compiler::TargetEnv::Vulkan:
+ return static_cast<EShMessages>(EShMsgSpvRules | EShMsgVulkanRules |
+ EShMsgCascadingErrors);
+ }
+ return EShMsgCascadingErrors;
+}
+
} // anonymous namespace
namespace shaderc_util {
@@ -157,10 +174,10 @@
shader.setPreamble(preamble.c_str());
// TODO(dneto): Generate source-level debug info if requested.
- bool success =
- shader.parse(&shaderc_util::kDefaultTBuiltInResource, default_version_,
- default_profile_, force_version_profile_,
- kNotForwardCompatible, message_rules_, includer);
+ bool success = shader.parse(&shaderc_util::kDefaultTBuiltInResource,
+ default_version_, default_profile_,
+ force_version_profile_, kNotForwardCompatible,
+ GetMessageRules(target_env_), includer);
success &= PrintFilteredErrors(error_tag, error_stream, warnings_as_errors_,
suppress_warnings_, shader.getInfoLog(),
@@ -183,7 +200,8 @@
if (!enabled_opt_passes_.empty()) {
std::string opt_errors;
- if (!SpirvToolsOptimize(enabled_opt_passes_, &spirv, &opt_errors)) {
+ if (!SpirvToolsOptimize(target_env_, enabled_opt_passes_, &spirv,
+ &opt_errors)) {
*error_stream << "shaderc: internal error: compilation succeeded but "
"failed to optimize: "
<< opt_errors << "\n";
@@ -193,7 +211,7 @@
if (output_type == OutputType::SpirvAssemblyText) {
std::string text_or_error;
- if (!SpirvToolsDisassemble(spirv, &text_or_error)) {
+ if (!SpirvToolsDisassemble(target_env_, spirv, &text_or_error)) {
*error_stream << "shaderc: internal error: compilation succeeded but "
"failed to disassemble: "
<< text_or_error << "\n";
@@ -218,9 +236,7 @@
definition ? std::string(definition, definition_length) : "";
}
-void Compiler::SetMessageRules(EShMessages rules) { message_rules_ = rules; }
-
-EShMessages Compiler::GetMessageRules() const { return message_rules_; }
+void Compiler::SetTargetEnv(Compiler::TargetEnv env) { target_env_ = env; }
void Compiler::SetForcedVersionProfile(int version, EProfile profile) {
default_version_ = version;
@@ -272,8 +288,8 @@
// 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 | message_rules_);
+ const auto rules = static_cast<EShMessages>(EShMsgOnlyPreprocessor |
+ GetMessageRules(target_env_));
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 30d00de..b11e04b 100644
--- a/libshaderc_util/src/compiler_test.cc
+++ b/libshaderc_util/src/compiler_test.cc
@@ -25,13 +25,6 @@
using shaderc_util::Compiler;
-// These are the flag combinations Glslang uses to set language
-// rules based on the target environment.
-const EShMessages kOpenGLCompatibilityRules = EShMsgDefault;
-const EShMessages kOpenGLRules = EShMsgSpvRules;
-const EShMessages kVulkanRules =
- static_cast<EShMessages>(EShMsgSpvRules | EShMsgVulkanRules);
-
// A trivial vertex shader
const char kVertexShader[] =
"#version 140\n"
@@ -90,8 +83,7 @@
private:
// Returns a pair of empty strings.
virtual glslang::TShader::Includer::IncludeResult* include_delegate(
- const char*, glslang::TShader::Includer::IncludeType,
- const char*,
+ const char*, glslang::TShader::Includer::IncludeType, const char*,
size_t) override {
return nullptr;
}
@@ -132,6 +124,7 @@
return SimpleCompilationSucceedsForOutputType(
source, stage, Compiler::OutputType::SpirvBinary);
}
+
protected:
Compiler compiler_;
// The error string from the most recent compilation.
@@ -163,12 +156,12 @@
TEST_F(CompilerTest, RespectTargetEnvOnOpenGLCompatibilityShader) {
const EShLanguage stage = EShLangFragment;
- compiler_.SetMessageRules(kOpenGLCompatibilityRules);
+ compiler_.SetTargetEnv(Compiler::TargetEnv::OpenGLCompat);
EXPECT_TRUE(SimpleCompilationSucceeds(kOpenGLCompatibilityFragShader, stage));
- compiler_.SetMessageRules(kOpenGLRules);
+ compiler_.SetTargetEnv(Compiler::TargetEnv::OpenGL);
EXPECT_FALSE(
SimpleCompilationSucceeds(kOpenGLCompatibilityFragShader, stage));
- compiler_.SetMessageRules(kVulkanRules);
+ compiler_.SetTargetEnv(Compiler::TargetEnv::Vulkan);
EXPECT_FALSE(
SimpleCompilationSucceeds(kOpenGLCompatibilityFragShader, stage));
// Default compiler.
@@ -181,15 +174,15 @@
RespectTargetEnvOnOpenGLCompatibilityShaderWhenDeducingStage) {
const EShLanguage stage = EShLangCount;
- compiler_.SetMessageRules(kOpenGLCompatibilityRules);
+ compiler_.SetTargetEnv(Compiler::TargetEnv::OpenGLCompat);
EXPECT_TRUE(SimpleCompilationSucceeds(
kOpenGLCompatibilityFragShaderDeducibleStage, stage))
<< errors_;
- compiler_.SetMessageRules(kOpenGLRules);
+ compiler_.SetTargetEnv(Compiler::TargetEnv::OpenGL);
EXPECT_FALSE(SimpleCompilationSucceeds(
kOpenGLCompatibilityFragShaderDeducibleStage, stage))
<< errors_;
- compiler_.SetMessageRules(kVulkanRules);
+ compiler_.SetTargetEnv(Compiler::TargetEnv::Vulkan);
EXPECT_FALSE(SimpleCompilationSucceeds(
kOpenGLCompatibilityFragShaderDeducibleStage, stage))
<< errors_;
@@ -203,37 +196,37 @@
TEST_F(CompilerTest, RespectTargetEnvOnOpenGLShader) {
const EShLanguage stage = EShLangVertex;
- compiler_.SetMessageRules(kOpenGLCompatibilityRules);
+ compiler_.SetTargetEnv(Compiler::TargetEnv::OpenGLCompat);
EXPECT_TRUE(SimpleCompilationSucceeds(kOpenGLVertexShader, stage));
- compiler_.SetMessageRules(kOpenGLRules);
+ compiler_.SetTargetEnv(Compiler::TargetEnv::OpenGL);
EXPECT_TRUE(SimpleCompilationSucceeds(kOpenGLVertexShader, stage));
}
TEST_F(CompilerTest, RespectTargetEnvOnOpenGLShaderWhenDeducingStage) {
const EShLanguage stage = EShLangCount;
- compiler_.SetMessageRules(kOpenGLCompatibilityRules);
+ compiler_.SetTargetEnv(Compiler::TargetEnv::OpenGLCompat);
EXPECT_TRUE(
SimpleCompilationSucceeds(kOpenGLVertexShaderDeducibleStage, stage));
- compiler_.SetMessageRules(kOpenGLRules);
+ compiler_.SetTargetEnv(Compiler::TargetEnv::OpenGL);
EXPECT_TRUE(
SimpleCompilationSucceeds(kOpenGLVertexShaderDeducibleStage, stage));
}
TEST_F(CompilerTest, RespectTargetEnvOnVulkanShader) {
- compiler_.SetMessageRules(kVulkanRules);
+ compiler_.SetTargetEnv(Compiler::TargetEnv::Vulkan);
EXPECT_TRUE(SimpleCompilationSucceeds(kVulkanVertexShader, EShLangVertex));
}
TEST_F(CompilerTest, VulkanSpecificShaderFailsUnderOpenGLCompatibilityRules) {
- compiler_.SetMessageRules(kOpenGLCompatibilityRules);
+ compiler_.SetTargetEnv(Compiler::TargetEnv::OpenGLCompat);
EXPECT_FALSE(SimpleCompilationSucceeds(kVulkanVertexShader, EShLangVertex));
}
TEST_F(CompilerTest, VulkanSpecificShaderFailsUnderOpenGLRules) {
- compiler_.SetMessageRules(kOpenGLRules);
+ compiler_.SetTargetEnv(Compiler::TargetEnv::OpenGL);
EXPECT_FALSE(SimpleCompilationSucceeds(kVulkanVertexShader, EShLangVertex));
}
@@ -247,13 +240,13 @@
}
TEST_F(CompilerTest, OpenGLCompatibilitySpecificShaderFailsUnderVulkanRules) {
- compiler_.SetMessageRules(kVulkanRules);
+ compiler_.SetTargetEnv(Compiler::TargetEnv::Vulkan);
EXPECT_FALSE(SimpleCompilationSucceeds(kOpenGLCompatibilityFragShader,
EShLangFragment));
}
TEST_F(CompilerTest, OpenGLSpecificShaderFailsUnderVulkanRules) {
- compiler_.SetMessageRules(kVulkanRules);
+ compiler_.SetTargetEnv(Compiler::TargetEnv::Vulkan);
EXPECT_FALSE(SimpleCompilationSucceeds(kOpenGLVertexShader, EShLangVertex));
}
diff --git a/libshaderc_util/src/spirv_tools_wrapper.cc b/libshaderc_util/src/spirv_tools_wrapper.cc
index b6bff02..273d1ba 100644
--- a/libshaderc_util/src/spirv_tools_wrapper.cc
+++ b/libshaderc_util/src/spirv_tools_wrapper.cc
@@ -21,7 +21,25 @@
namespace shaderc_util {
-bool SpirvToolsDisassemble(const std::vector<uint32_t>& binary,
+namespace {
+
+// Gets the corresponding target environment used in SPIRV-Tools.
+spv_target_env GetSpirvToolsTargetEnv(Compiler::TargetEnv env) {
+ switch (env) {
+ case Compiler::TargetEnv::Vulkan:
+ return SPV_ENV_VULKAN_1_0;
+ case Compiler::TargetEnv::OpenGL:
+ return SPV_ENV_OPENGL_4_5;
+ case Compiler::TargetEnv::OpenGLCompat:
+ return SPV_ENV_OPENGL_4_5; // TODO(antiagainst): is this correct?
+ }
+ return SPV_ENV_VULKAN_1_0;
+}
+
+} // anonymous namespace
+
+bool SpirvToolsDisassemble(Compiler::TargetEnv env,
+ const std::vector<uint32_t>& binary,
std::string* text_or_error) {
spvtools::SpirvTools tools(SPV_ENV_VULKAN_1_0);
std::ostringstream oss;
@@ -37,9 +55,9 @@
return success;
}
-bool SpirvToolsAssemble(const string_piece assembly, spv_binary* binary,
- std::string* errors) {
- auto spvtools_context = spvContextCreate(SPV_ENV_VULKAN_1_0);
+bool SpirvToolsAssemble(Compiler::TargetEnv env, const string_piece assembly,
+ spv_binary* binary, std::string* errors) {
+ auto spvtools_context = spvContextCreate(GetSpirvToolsTargetEnv(env));
spv_diagnostic spvtools_diagnostic = nullptr;
*binary = nullptr;
@@ -62,7 +80,8 @@
return success;
}
-bool SpirvToolsOptimize(const std::vector<PassId>& enabled_passes,
+bool SpirvToolsOptimize(Compiler::TargetEnv env,
+ const std::vector<PassId>& enabled_passes,
std::vector<uint32_t>* binary, std::string* errors) {
errors->clear();
if (enabled_passes.empty()) return true;
@@ -72,7 +91,7 @@
return true;
}
- spvtools::Optimizer optimizer(SPV_ENV_VULKAN_1_0);
+ spvtools::Optimizer optimizer(GetSpirvToolsTargetEnv(env));
std::ostringstream oss;
optimizer.SetMessageConsumer(
[&oss](spv_message_level_t, const char*, const spv_position_t&,