[tint][spir-v] Improve spir-v version robustness
Fix: 428041882
* The SPIR-V version enum is exposed via the options
* Improve the robustness of its usage by removing the specific values
in the enum
* Add checks that only valid values can be used
* Move conversion to the version word into the printer
* Add validation environment settings to IRFuzzer validation
Change-Id: Ibe2f808f32e20128fda76ec566fe55a9dbf8aea3
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/250474
Auto-Submit: Alan Baker <alanbaker@google.com>
Reviewed-by: James Price <jrprice@google.com>
Reviewed-by: Ryan Harrison <rharrison@chromium.org>
Commit-Queue: Alan Baker <alanbaker@google.com>
Commit-Queue: James Price <jrprice@google.com>
diff --git a/src/tint/lang/spirv/writer/common/options.h b/src/tint/lang/spirv/writer/common/options.h
index 23d6dfd..ba8deb9e0 100644
--- a/src/tint/lang/spirv/writer/common/options.h
+++ b/src/tint/lang/spirv/writer/common/options.h
@@ -130,10 +130,16 @@
};
/// Supported SPIR-V binary versions.
+/// If a new version is added here, also add it to:
+/// * Writer::CanGenerate
+/// * Printer::Code
+/// Fully usable version will also need additions to:
+/// * --spir-version on the command line
+/// * Dawn in the Vulkan backend
enum class SpvVersion : uint32_t {
- kSpv13 = 0x10300u, // SPIR-V 1.3
- kSpv14 = 0x10400u, // SPIR-V 1.4
- kSpv15 = 0x10500u, // SPIR-V 1.5, for testing purposes only
+ kSpv13, // SPIR-V 1.3
+ kSpv14, // SPIR-V 1.4
+ kSpv15, // SPIR-V 1.5, for testing purposes only
};
/// Configuration options used for generating SPIR-V.
diff --git a/src/tint/lang/spirv/writer/printer/printer.cc b/src/tint/lang/spirv/writer/printer/printer.cc
index 2cdd29f..a8c5a30 100644
--- a/src/tint/lang/spirv/writer/printer/printer.cc
+++ b/src/tint/lang/spirv/writer/printer/printer.cc
@@ -215,10 +215,24 @@
return res.Failure();
}
+ uint32_t version = 0u;
+ switch (options_.spirv_version) {
+ case SpvVersion::kSpv13:
+ version = 0x10300u;
+ break;
+ case SpvVersion::kSpv14:
+ version = 0x10400u;
+ break;
+ case SpvVersion::kSpv15:
+ version = 0x10500u;
+ break;
+ default:
+ TINT_ICE() << "unsupported SPIR-V version";
+ }
+
// Serialize the module into binary SPIR-V.
BinaryWriter writer;
- writer.WriteHeader(module_.IdBound(), kWriterVersion,
- static_cast<uint32_t>(options_.spirv_version));
+ writer.WriteHeader(module_.IdBound(), kWriterVersion, version);
writer.WriteModule(module_);
output_.spirv = std::move(writer.Result());
diff --git a/src/tint/lang/spirv/writer/writer.cc b/src/tint/lang/spirv/writer/writer.cc
index 50ef741..23e739a 100644
--- a/src/tint/lang/spirv/writer/writer.cc
+++ b/src/tint/lang/spirv/writer/writer.cc
@@ -42,6 +42,16 @@
namespace tint::spirv::writer {
Result<SuccessType> CanGenerate(const core::ir::Module& ir, const Options& options) {
+ // The enum is accessible in the API so ensure we have a valid value.
+ switch (options.spirv_version) {
+ case SpvVersion::kSpv13:
+ case SpvVersion::kSpv14:
+ case SpvVersion::kSpv15:
+ break;
+ default:
+ return Failure("unsupported SPIR-V version");
+ }
+
// Check optionally supported types against their required options.
for (auto* ty : ir.Types()) {
if (ty->Is<core::type::SubgroupMatrix>()) {
diff --git a/src/tint/lang/spirv/writer/writer_fuzz.cc b/src/tint/lang/spirv/writer/writer_fuzz.cc
index d71f328..bce4dc8 100644
--- a/src/tint/lang/spirv/writer/writer_fuzz.cc
+++ b/src/tint/lang/spirv/writer/writer_fuzz.cc
@@ -49,8 +49,23 @@
<< output.Failure().reason;
}
+ spv_target_env target_env = SPV_ENV_VULKAN_1_1;
+ switch (options.spirv_version) {
+ case SpvVersion::kSpv13:
+ target_env = SPV_ENV_VULKAN_1_1;
+ break;
+ case SpvVersion::kSpv14:
+ target_env = SPV_ENV_VULKAN_1_1_SPIRV_1_4;
+ break;
+ case SpvVersion::kSpv15:
+ target_env = SPV_ENV_VULKAN_1_2;
+ break;
+ default:
+ TINT_ICE() << "unsupported SPIR-V version";
+ }
+
auto& spirv = output->spirv;
- if (auto res = validate::Validate(Slice(spirv.data(), spirv.size()), SPV_ENV_VULKAN_1_1);
+ if (auto res = validate::Validate(Slice(spirv.data(), spirv.size()), target_env);
res != Success) {
TINT_ICE() << "output of SPIR-V writer failed to validate with SPIR-V Tools\n"
<< res.Failure() << "\n\n"