diff options
author | android-build-prod (mdb) <android-build-team-robot@google.com> | 2021-02-27 05:49:55 +0000 |
---|---|---|
committer | android-build-prod (mdb) <android-build-team-robot@google.com> | 2021-02-27 05:49:55 +0000 |
commit | 7746b2f033a5f53378ab0f67b3009df419f5ec69 (patch) | |
tree | 1e16a1726e2686518ccac85e87bacda2d18bbed3 | |
parent | 2e9aa5c5283b859603e8c5755204fd9b0f6bf7ae (diff) | |
parent | 9c602842f9386ec12d53b31fbd70f1d596775f58 (diff) | |
download | shaderc-busytown-mac1010-release.tar.gz |
Snap for 7174163 from 9c602842f9386ec12d53b31fbd70f1d596775f58 to busytown-mac1010-releasebusytown-mac1010-release
Change-Id: I306a57d367afcf25752d1a1af0d0bef2b31a0200
-rw-r--r-- | CHANGES | 15 | ||||
-rw-r--r-- | CMakeLists.txt | 14 | ||||
-rw-r--r-- | DEPS | 10 | ||||
-rw-r--r-- | libshaderc/include/shaderc/env.h | 7 | ||||
-rw-r--r-- | libshaderc/src/shaderc.cc | 3 | ||||
-rw-r--r-- | libshaderc_util/include/libshaderc_util/compiler.h | 1 | ||||
-rw-r--r-- | libshaderc_util/include/libshaderc_util/message.h | 3 | ||||
-rw-r--r-- | libshaderc_util/include/libshaderc_util/spirv_tools_wrapper.h | 1 | ||||
-rw-r--r-- | libshaderc_util/src/compiler.cc | 34 | ||||
-rw-r--r-- | libshaderc_util/src/message.cc | 89 | ||||
-rw-r--r-- | libshaderc_util/src/message_test.cc | 70 | ||||
-rw-r--r-- | libshaderc_util/src/spirv_tools_wrapper.cc | 5 | ||||
-rwxr-xr-x | utils/add_copyright.py | 2 |
13 files changed, 175 insertions, 79 deletions
@@ -1,7 +1,18 @@ Revision history for Shaderc -v2020.4-dev 2020-09-02 - - Start v2020.4-dev +v2020.5 2021-02-19 + - Refresh dependencies (in DEPS): + - SPIRV-Tools v2020.7 + 1 patch + - Glslang 11.1.0 + - Add option to skip building examples + - Fixes: + #1153: Improve file+line parsing from Glslang messages + +v2020.4 2020-12-09 + - Removed svpc + - Fixed issues with embedders getting duplicate symbols + - Converted C-style casts to static_cast + - Rolled ahead to fix/pickup Vulkan Raytracing support v2020.3 2020-09-02 - General: diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c74cd8..0c8d1ae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,6 +40,16 @@ else() message(STATUS "Configuring Shaderc to avoid building tests.") endif() +option(SHADERC_SKIP_EXAMPLES "Skip building examples" ${SHADERC_SKIP_EXAMPLES}) +if(NOT ${SHADERC_SKIP_EXAMPLES}) + set(SHADERC_ENABLE_EXAMPLES ON) +endif() +if(${SHADERC_ENABLE_EXAMPLES}) + message(STATUS "Configuring Shaderc to build examples.") +else() + message(STATUS "Configuring Shaderc to avoid building examples.") +endif() + option(SHADERC_ENABLE_WERROR_COMPILE "Enable passing -Werror to compiler, if available" ON) set (CMAKE_CXX_STANDARD 11) @@ -107,7 +117,9 @@ add_subdirectory(third_party) add_subdirectory(libshaderc_util) add_subdirectory(libshaderc) add_subdirectory(glslc) -add_subdirectory(examples) +if(${SHADERC_ENABLE_EXAMPLES}) + add_subdirectory(examples) +endif() add_custom_target(build-version ${PYTHON_EXECUTABLE} @@ -5,11 +5,11 @@ vars = { 'khronos_git': 'https://github.com/KhronosGroup', 'effcee_revision' : '2ec8f8738118cc483b67c04a759fee53496c5659', - 'glslang_revision': 'ffccefddfd9a02ec0c0b6dd04ef5e1042279c97f', - 'googletest_revision': '36d8eb532022d3b543bf55aa8ffa01b6e9f03490', - 're2_revision': '9e5430536b59ad8a8aff8616a6e6b0f888594fac', - 'spirv_headers_revision': '104ecc356c1bea4476320faca64440cd1df655a3', - 'spirv_tools_revision': 'cd590fa3341284cd6d1ee82366155786cfd44c96', + 'glslang_revision': 'e56beaee736863ce48455955158f1839e6e4c1a1', + 'googletest_revision': '389cb68b87193358358ae87cc56d257fd0d80189', + 're2_revision': '7107ebc4fbf7205151d8d2a57b2fc6e7853125d4', + 'spirv_headers_revision': 'a3fdfe81465d57efc97cfd28ac6c8190fb31a6c8', + 'spirv_tools_revision': 'ef3290bbea35935ba8fd623970511ed9f045bbd7', } deps = { diff --git a/libshaderc/include/shaderc/env.h b/libshaderc/include/shaderc/env.h index a0e7a02..5285b9e 100644 --- a/libshaderc/include/shaderc/env.h +++ b/libshaderc/include/shaderc/env.h @@ -29,7 +29,8 @@ typedef enum { shaderc_target_env_opengl_compat, // SPIR-V under OpenGL semantics, // including compatibility profile // functions - shaderc_target_env_webgpu, // SPIR-V under WebGPU semantics + shaderc_target_env_webgpu, // Deprecated, SPIR-V under WebGPU + // semantics shaderc_target_env_default = shaderc_target_env_vulkan } shaderc_target_env; @@ -44,9 +45,7 @@ typedef enum { // See glslang/Standalone/Standalone.cpp // TODO(dneto): Glslang doesn't accept a OpenGL client version of 460. shaderc_env_version_opengl_4_5 = 450, - // Currently WebGPU doesn't have versioning, since it isn't finalized. This - // will have to be updated once the spec is finished. - shaderc_env_version_webgpu, + shaderc_env_version_webgpu, // Deprecated, WebGPU env never defined versions } shaderc_env_version; // The known versions of SPIR-V. diff --git a/libshaderc/src/shaderc.cc b/libshaderc/src/shaderc.cc index 28985e0..da0f3b2 100644 --- a/libshaderc/src/shaderc.cc +++ b/libshaderc/src/shaderc.cc @@ -279,7 +279,8 @@ shaderc_util::Compiler::TargetEnv GetCompilerTargetEnv(shaderc_target_env env) { case shaderc_target_env_opengl_compat: return shaderc_util::Compiler::TargetEnv::OpenGLCompat; case shaderc_target_env_webgpu: - return shaderc_util::Compiler::TargetEnv::WebGPU; + assert(false); + break; case shaderc_target_env_vulkan: default: break; diff --git a/libshaderc_util/include/libshaderc_util/compiler.h b/libshaderc_util/include/libshaderc_util/compiler.h index 0207fc3..3277a9b 100644 --- a/libshaderc_util/include/libshaderc_util/compiler.h +++ b/libshaderc_util/include/libshaderc_util/compiler.h @@ -76,7 +76,6 @@ class Compiler { Vulkan, // Default to Vulkan 1.0 OpenGL, // Default to OpenGL 4.5 OpenGLCompat, // Deprecated. - WebGPU, }; // Target environment versions. These numbers match those used by Glslang. diff --git a/libshaderc_util/include/libshaderc_util/message.h b/libshaderc_util/include/libshaderc_util/message.h index f07a62c..8a77790 100644 --- a/libshaderc_util/include/libshaderc_util/message.h +++ b/libshaderc_util/include/libshaderc_util/message.h @@ -53,6 +53,9 @@ enum class MessageType { // source_name="", line_number="", rest="Message" // "ERROR: 2 errors found." // source_name="2", line_number="", rest="errors found". +// +// Note that filenames can contain colons: +// "ERROR: foo:bar.comp.hlsl:2: 'a' : unknown variable" MessageType ParseGlslangOutput(const shaderc_util::string_piece& message, bool warnings_as_errors, bool suppress_warnings, shaderc_util::string_piece* source_name, diff --git a/libshaderc_util/include/libshaderc_util/spirv_tools_wrapper.h b/libshaderc_util/include/libshaderc_util/spirv_tools_wrapper.h index d1083a0..09d8462 100644 --- a/libshaderc_util/include/libshaderc_util/spirv_tools_wrapper.h +++ b/libshaderc_util/include/libshaderc_util/spirv_tools_wrapper.h @@ -46,7 +46,6 @@ enum class PassId { kLegalizationPasses, kPerformancePasses, kSizePasses, - kVulkanToWebGPUPasses, // SPIRV-Tools specific passes kNullPass, diff --git a/libshaderc_util/src/compiler.cc b/libshaderc_util/src/compiler.cc index c5ce37e..bf06589 100644 --- a/libshaderc_util/src/compiler.cc +++ b/libshaderc_util/src/compiler.cc @@ -84,7 +84,6 @@ EShMessages GetMessageRules(shaderc_util::Compiler::TargetEnv env, case Compiler::TargetEnv::OpenGL: result = static_cast<EShMessages>(result | EShMsgSpvRules); break; - case Compiler::TargetEnv::WebGPU: case Compiler::TargetEnv::Vulkan: result = static_cast<EShMessages>(result | EShMsgSpvRules | EShMsgVulkanRules); @@ -184,17 +183,9 @@ std::tuple<bool, std::vector<uint32_t>, size_t> Compiler::Compile( std::vector<uint32_t>& compilation_output_data = std::get<1>(result_tuple); size_t& compilation_output_data_size_in_bytes = std::get<2>(result_tuple); - // glslang doesn't currently support WebGPU, so we need to fake it by having - // it generate Vulkan1.1 and then use spirv-opt later to convert to WebGPU. - bool is_webgpu = target_env_ == Compiler::TargetEnv::WebGPU; - TargetEnv internal_target_env = - !is_webgpu ? target_env_ : Compiler::TargetEnv::Vulkan; - TargetEnvVersion internal_target_env_version = - !is_webgpu ? target_env_version_ : Compiler::TargetEnvVersion::Vulkan_1_1; - // Check target environment. const auto target_client_info = GetGlslangClientInfo( - error_tag, internal_target_env, internal_target_env_version, + error_tag, target_env_, target_env_version_, target_spirv_version_, target_spirv_version_is_forced_); if (!target_client_info.error.empty()) { *error_stream << target_client_info.error; @@ -297,7 +288,7 @@ std::tuple<bool, std::vector<uint32_t>, size_t> Compiler::Compile( shader.setNanMinMaxClamp(nan_clamp_); const EShMessages rules = - GetMessageRules(internal_target_env, source_language_, hlsl_offsets_, + GetMessageRules(target_env_, source_language_, hlsl_offsets_, generate_debug_info_); bool success = shader.parse(&limits_, default_version_, default_profile_, @@ -347,14 +338,9 @@ std::tuple<bool, std::vector<uint32_t>, size_t> Compiler::Compile( opt_passes.insert(opt_passes.end(), enabled_opt_passes_.begin(), enabled_opt_passes_.end()); - // WebGPU goes last, since it is converting the env. - if (is_webgpu) { - opt_passes.push_back(PassId::kVulkanToWebGPUPasses); - } - if (!opt_passes.empty()) { std::string opt_errors; - if (!SpirvToolsOptimize(internal_target_env, internal_target_env_version, + if (!SpirvToolsOptimize(target_env_, target_env_version_, opt_passes, &spirv, &opt_errors)) { *error_stream << "shaderc: internal error: compilation succeeded but " "failed to optimize: " @@ -365,8 +351,6 @@ std::tuple<bool, std::vector<uint32_t>, size_t> Compiler::Compile( if (output_type == OutputType::SpirvAssemblyText) { std::string text_or_error; - // spirv-tools does know about WebGPU, so don't need to punt to Vulkan1.1 - // here. if (!SpirvToolsDisassemble(target_env_, target_env_version_, spirv, &text_or_error)) { *error_stream << "shaderc: internal error: compilation succeeded but " @@ -464,14 +448,6 @@ void Compiler::SetSuppressWarnings() { suppress_warnings_ = true; } std::tuple<bool, std::string, std::string> Compiler::PreprocessShader( const std::string& error_tag, const string_piece& shader_source, const string_piece& shader_preamble, CountingIncluder& includer) const { - // glslang doesn't currently support WebGPU, so we need to fake it by having - // it generate Vulkan1.1 and then use spirv-opt later to convert to WebGPU. - bool is_webgpu = target_env_ == Compiler::TargetEnv::WebGPU; - TargetEnv internal_target_env = - !is_webgpu ? target_env_ : Compiler::TargetEnv::Vulkan; - TargetEnvVersion internal_target_env_version = - !is_webgpu ? target_env_version_ : Compiler::TargetEnvVersion::Vulkan_1_1; - // The stage does not matter for preprocessing. glslang::TShader shader(EShLangVertex); const char* shader_strings = shader_source.data(); @@ -481,7 +457,7 @@ std::tuple<bool, std::string, std::string> Compiler::PreprocessShader( &string_names, 1); shader.setPreamble(shader_preamble.data()); auto target_client_info = GetGlslangClientInfo( - error_tag, internal_target_env, internal_target_env_version, + error_tag, target_env_, target_env_version_, target_spirv_version_, target_spirv_version_is_forced_); if (!target_client_info.error.empty()) { return std::make_tuple(false, "", target_client_info.error); @@ -499,7 +475,7 @@ std::tuple<bool, std::string, std::string> Compiler::PreprocessShader( // flag. const auto rules = static_cast<EShMessages>( EShMsgOnlyPreprocessor | - GetMessageRules(internal_target_env, source_language_, hlsl_offsets_, + GetMessageRules(target_env_, source_language_, hlsl_offsets_, false)); std::string preprocessed_shader; diff --git a/libshaderc_util/src/message.cc b/libshaderc_util/src/message.cc index 11fd10a..3604b1e 100644 --- a/libshaderc_util/src/message.cc +++ b/libshaderc_util/src/message.cc @@ -45,41 +45,72 @@ MessageType DeduceMessageType(string_piece* message) { } // Deduces a location specification from the given message. A location -// specification is of the form "<source-name>:<line-number>:". If the deduction -// is successful, returns true and updates source_name and line_number to the -// deduced source name and line numer respectively. The prefix standing for the -// location specification in message is skipped. Otherwise, returns false and -// keeps all parameters untouched. +// specification is of the form "<source-name>:<line-number>:" and a trailing +// space. If the deduction is successful, returns true and updates source_name +// and line_number to the deduced source name and line numer respectively. The +// prefix standing for the location specification in message is skipped. +// Otherwise, returns false and keeps all parameters untouched. bool DeduceLocationSpec(string_piece* message, string_piece* source_name, string_piece* line_number) { - // TODO(antiagainst): we use ':' as a delimiter here. It may be a valid - // character in the filename. Also be aware of other special characters, - // for example, ' '. - string_piece rest(*message); - size_t colon_after_source = rest.find_first_of(':'); - if (colon_after_source == string_piece::npos) return false; + if (!message || message->empty()) { + return false; + } + + // When we find a pattern like this: + // colon + // digits + // colon + // space + // Then deduce that the source_name is the text before the first colon, + // the line number is the digits, and the message is the text after the + // second colon. - string_piece source = rest.substr(0, colon_after_source); - rest = rest.substr(colon_after_source + 1); - size_t colon_after_line = rest.find_first_of(':'); - if (source.size() == 1 && ::isalpha(source.front()) && rest.size() > 0 && - rest.front() == '\\') { - // Handle Windows path. - colon_after_source += colon_after_line + 1; - source = message->substr(0, colon_after_source); - rest = rest.substr(colon_after_line + 1); - colon_after_line = rest.find_first_of(':'); + const size_t size = message->size(); + if (size <= 4) { + // A valid message must have a colon, a digit, a colon, and a space. + return false; } + // The last possible position of the first colon. + const size_t first_colon_cutoff = size - 4; + // The last possible position of the second colon. + const size_t next_colon_cutoff = size - 2; - if (colon_after_line == string_piece::npos) return false; - const string_piece line = rest.substr(0, colon_after_line); + for (size_t first_colon_pos = message->find_first_of(':'), next_colon_pos = 0; - if (!std::all_of(line.begin(), line.end(), ::isdigit)) return false; + // There is a first colon, and it's not too close to the end + (first_colon_pos != string_piece::npos) && + (first_colon_pos <= first_colon_cutoff); - *source_name = source; - *line_number = line; - *message = rest.substr(colon_after_line + 1).strip_whitespace(); - return true; + // Try the next pair of colons. + first_colon_pos = next_colon_pos) { + // We're guaranteed to have at least 3 more characters. + // Guarantee progress toward the end of the string. + next_colon_pos = message->find_first_of(':', first_colon_pos + 1); + if ((next_colon_pos == string_piece::npos) || + (next_colon_pos > next_colon_cutoff)) { + // No valid solution. + return false; + } + if (first_colon_pos + 1 == next_colon_pos) { + // There is no room for digits. + continue; + } + if ((message->data()[next_colon_pos + 1] != ' ')) { + // There is no space character after the second colon. + continue; + } + if (message->find_first_not_of("0123456789", first_colon_pos + 1) == + next_colon_pos) { + // We found the first solution. + *source_name = message->substr(0, first_colon_pos); + *line_number = message->substr(first_colon_pos + 1, + next_colon_pos - 1 - first_colon_pos); + *message = message->substr(next_colon_pos + 2); + return true; + } + } + + return false; } // Returns true if the given message is a summary message. @@ -114,6 +145,8 @@ MessageType ParseGlslangOutput(const string_piece& message, // <location-specification> is of the form: // <filename-or-string-number>:<line-number>: // It doesn't exist if the warning/error message is a global one. + // + // See Glslang's TInfoSink class implementation for details. bool is_error = false; diff --git a/libshaderc_util/src/message_test.cc b/libshaderc_util/src/message_test.cc index 5d65023..26dc26b 100644 --- a/libshaderc_util/src/message_test.cc +++ b/libshaderc_util/src/message_test.cc @@ -135,6 +135,8 @@ TEST(ParseGlslangOutputTest, LocationSpecification) { string_piece line_number; string_piece rest; + // Glslang reading from strings can give string segment numbers as + // the filename part. EXPECT_EQ( MessageType::Error, ParseGlslangOutput("ERROR: 0:2: '#' : invalid directive: foo", false, @@ -154,7 +156,7 @@ TEST(ParseGlslangOutputTest, LocationSpecification) { rest.str()); } -TEST(ParseGlslangOutputTest, FileName) { +TEST(ParseGlslangOutputTest, FileName_BaseAndExtension) { string_piece source_name; string_piece line_number; string_piece rest; @@ -165,6 +167,12 @@ TEST(ParseGlslangOutputTest, FileName) { EXPECT_EQ("shader.vert", source_name.str()); EXPECT_EQ("5", line_number.str()); EXPECT_EQ("something wrong", rest.str()); +} + +TEST(ParseGlslangOutputTest, FileName_BaseOnly) { + string_piece source_name; + string_piece line_number; + string_piece rest; EXPECT_EQ(MessageType::Warning, ParseGlslangOutput("WARNING: file:42: something wrong", false, @@ -172,6 +180,12 @@ TEST(ParseGlslangOutputTest, FileName) { EXPECT_EQ("file", source_name.str()); EXPECT_EQ("42", line_number.str()); EXPECT_EQ("something wrong", rest.str()); +} + +TEST(ParseGlslangOutputTest, FileName_HexNumber) { + string_piece source_name; + string_piece line_number; + string_piece rest; EXPECT_EQ(MessageType::Warning, ParseGlslangOutput("WARNING: 0xdeedbeef:0: wa:ha:ha", false, false, @@ -181,6 +195,60 @@ TEST(ParseGlslangOutputTest, FileName) { EXPECT_EQ("wa:ha:ha", rest.str()); } +TEST(ParseGlslangOutputTest, FileName_ContainsColons) { + string_piece source_name; + string_piece line_number; + string_piece rest; + + EXPECT_EQ(MessageType::Warning, + ParseGlslangOutput("WARNING: foo:bar:0: wa:ha:ha", false, false, + &source_name, &line_number, &rest)); + EXPECT_EQ("foo:bar", source_name.str()); + EXPECT_EQ("0", line_number.str()); + EXPECT_EQ("wa:ha:ha", rest.str()); +} + +TEST(ParseGlslangOutputTest, NoFile) { + string_piece source_name; + string_piece line_number; + string_piece rest; + + EXPECT_EQ(MessageType::Warning, + ParseGlslangOutput("WARNING: :12: abc", false, false, &source_name, + &line_number, &rest)); + EXPECT_EQ("", source_name.str()); + EXPECT_EQ("12", line_number.str()); + EXPECT_EQ("abc", rest.str()); +} + +TEST(ParseGlslangOutputTest, NoLineNumber_InferredAsGlobalNoLocation) { + string_piece source_name; + string_piece line_number; + string_piece rest; + + // No solution since there is no room for digits. + EXPECT_EQ(MessageType::GlobalWarning, + ParseGlslangOutput("WARNING: foo:: abc", false, false, + &source_name, &line_number, &rest)); + EXPECT_EQ("", source_name.str()); + EXPECT_EQ("", line_number.str()); + EXPECT_EQ("foo:: abc", rest.str()); +} + +TEST(ParseGlslangOutputTest, NoSpaceAfterColon_InferredAsGlobalNoLocation) { + string_piece source_name; + string_piece line_number; + string_piece rest; + + // No solution since there is no space after the line-number-and-colon. + EXPECT_EQ(MessageType::GlobalWarning, + ParseGlslangOutput("WARNING: foo:12:abc", false, false, + &source_name, &line_number, &rest)); + EXPECT_EQ("", source_name.str()); + EXPECT_EQ("", line_number.str()); + EXPECT_EQ("foo:12:abc", rest.str()); +} + TEST(ParseGlslangOutputTest, WindowsPath) { string_piece source_name; string_piece line_number; diff --git a/libshaderc_util/src/spirv_tools_wrapper.cc b/libshaderc_util/src/spirv_tools_wrapper.cc index 372f9a2..4ed2bac 100644 --- a/libshaderc_util/src/spirv_tools_wrapper.cc +++ b/libshaderc_util/src/spirv_tools_wrapper.cc @@ -45,8 +45,6 @@ spv_target_env GetSpirvToolsTargetEnv(Compiler::TargetEnv env, return SPV_ENV_OPENGL_4_5; case Compiler::TargetEnv::OpenGLCompat: // Deprecated return SPV_ENV_OPENGL_4_5; - case Compiler::TargetEnv::WebGPU: - return SPV_ENV_WEBGPU_0; } assert(false && "unexpected target environment or version"); return SPV_ENV_VULKAN_1_0; @@ -145,9 +143,6 @@ bool SpirvToolsOptimize(Compiler::TargetEnv env, case PassId::kSizePasses: optimizer.RegisterSizePasses(); break; - case PassId::kVulkanToWebGPUPasses: - optimizer.RegisterVulkanToWebGPUPasses(); - break; case PassId::kNullPass: // We actually don't need to do anything for null pass. break; diff --git a/utils/add_copyright.py b/utils/add_copyright.py index d1ede56..37505bc 100755 --- a/utils/add_copyright.py +++ b/utils/add_copyright.py @@ -62,7 +62,7 @@ def filtered_descendants(glob): """Returns glob-matching filenames under the current directory, but skips some irrelevant paths.""" return find('.', glob, ['third_party', 'external', 'build*', 'out*', - 'CompilerIdCXX']) + 'CompilerIdCXX', '.venv']) def skip(line): |