[ir][spirv-writer] Rework unit testing
Add a `Generate()` method to the base test helper that runs the SPIR-V
generator and validates the result with spirv-val. The full
disassembled module is then stored to `output_`.
Rewrite the `access` tests to use this method, instead of manually
invoking the PIMPL methods. Attach friendly names to variables and
results to allow the test to only check for a specific instruction.
Bug: tint:1906
Change-Id: I679ecbff46598d50777f5663d36c6c1235a3f5ff
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/139480
Reviewed-by: dan sinclair <dsinclair@google.com>
Commit-Queue: James Price <jrprice@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/tint/writer/spirv/ir/test_helper_ir.h b/src/tint/writer/spirv/ir/test_helper_ir.h
index 08f8246..debe5d8 100644
--- a/src/tint/writer/spirv/ir/test_helper_ir.h
+++ b/src/tint/writer/spirv/ir/test_helper_ir.h
@@ -16,8 +16,10 @@
#define SRC_TINT_WRITER_SPIRV_IR_TEST_HELPER_IR_H_
#include <string>
+#include <utility>
#include "gtest/gtest.h"
+#include "spirv-tools/libspirv.hpp"
#include "src/tint/ir/builder.h"
#include "src/tint/ir/validate.h"
#include "src/tint/writer/spirv/ir/generator_impl_ir.h"
@@ -54,6 +56,9 @@
/// Validation errors
std::string err_;
+ /// SPIR-V output.
+ std::string output_;
+
/// @returns the error string from the validation
std::string Error() const { return err_; }
@@ -67,6 +72,57 @@
return true;
}
+ /// Run the generator on the IR module and validate the result.
+ /// @returns true if generation and validation succeeded
+ bool Generate() {
+ if (!generator_.Generate()) {
+ err_ = generator_.Diagnostics().str();
+ return false;
+ }
+ if (!Validate()) {
+ return false;
+ }
+
+ output_ = Disassemble(generator_.Result(), SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
+ return true;
+ }
+
+ /// Validate the generated SPIR-V using the SPIR-V Tools Validator.
+ /// @returns true if validation succeeded, false otherwise
+ bool Validate() {
+ auto binary = generator_.Result();
+
+ std::string spv_errors;
+ auto msg_consumer = [&spv_errors](spv_message_level_t level, const char*,
+ const spv_position_t& position, const char* message) {
+ switch (level) {
+ case SPV_MSG_FATAL:
+ case SPV_MSG_INTERNAL_ERROR:
+ case SPV_MSG_ERROR:
+ spv_errors +=
+ "error: line " + std::to_string(position.index) + ": " + message + "\n";
+ break;
+ case SPV_MSG_WARNING:
+ spv_errors +=
+ "warning: line " + std::to_string(position.index) + ": " + message + "\n";
+ break;
+ case SPV_MSG_INFO:
+ spv_errors +=
+ "info: line " + std::to_string(position.index) + ": " + message + "\n";
+ break;
+ case SPV_MSG_DEBUG:
+ break;
+ }
+ };
+
+ spvtools::SpirvTools tools(SPV_ENV_VULKAN_1_2);
+ tools.SetMessageConsumer(msg_consumer);
+
+ auto result = tools.Validate(binary);
+ err_ = std::move(spv_errors);
+ return result;
+ }
+
/// @returns the disassembled types from the generated module.
std::string DumpTypes() { return DumpInstructions(generator_.Module().Types()); }