writer/spriv: Promote the SPIR-V validation to the test helper

This is useful for checking that generated SPIR-V is actually valid.

Change-Id: I851748f96b00e57d5915b32e4afec2b1c933b691
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/40283
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Commit-Queue: dan sinclair <dsinclair@chromium.org>
diff --git a/src/writer/spirv/builder_intrinsic_texture_test.cc b/src/writer/spirv/builder_intrinsic_texture_test.cc
index 4f749ba..d3c7a9e 100644
--- a/src/writer/spirv/builder_intrinsic_texture_test.cc
+++ b/src/writer/spirv/builder_intrinsic_texture_test.cc
@@ -15,7 +15,6 @@
 #include <memory>
 
 #include "gmock/gmock.h"
-#include "spirv-tools/libspirv.hpp"
 #include "src/ast/call_statement.h"
 #include "src/ast/intrinsic_texture_helper_test.h"
 #include "src/ast/stage_decoration.h"
@@ -24,7 +23,6 @@
 #include "src/type/sampled_texture_type.h"
 #include "src/type/storage_texture_type.h"
 #include "src/type_determiner.h"
-#include "src/writer/spirv/binary_writer.h"
 #include "src/writer/spirv/builder.h"
 #include "src/writer/spirv/spv_dump.h"
 #include "src/writer/spirv/test_helper.h"
@@ -4165,38 +4163,7 @@
 
   ASSERT_TRUE(b.Build()) << b.error();
 
-  BinaryWriter writer;
-  writer.WriteHeader(b.id_bound());
-  writer.WriteBuilder(&b);
-  auto binary = writer.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);
-  ASSERT_TRUE(tools.Validate(binary)) << spv_errors;
+  Validate(b);
 }
 
 TEST_P(IntrinsicTextureTest, OutsideFunction_IsError) {
diff --git a/src/writer/spirv/test_helper.h b/src/writer/spirv/test_helper.h
index f0ead89..ec017ca 100644
--- a/src/writer/spirv/test_helper.h
+++ b/src/writer/spirv/test_helper.h
@@ -19,10 +19,12 @@
 #include <utility>
 
 #include "gtest/gtest.h"
+#include "spirv-tools/libspirv.hpp"
 #include "src/ast/module.h"
 #include "src/diagnostic/formatter.h"
 #include "src/program_builder.h"
 #include "src/type_determiner.h"
+#include "src/writer/spirv/binary_writer.h"
 #include "src/writer/spirv/builder.h"
 
 namespace tint {
@@ -57,6 +59,44 @@
     return *spirv_builder;
   }
 
+  /// Validate passes the generated SPIR-V of the builder `b` to the SPIR-V
+  /// Tools Validator. If the validator finds problems the test will fail.
+  /// @param b the spirv::Builder containing the built SPIR-V module
+  void Validate(spirv::Builder& b) {
+    BinaryWriter writer;
+    writer.WriteHeader(b.id_bound());
+    writer.WriteBuilder(&b);
+    auto binary = writer.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);
+    ASSERT_TRUE(tools.Validate(binary)) << spv_errors;
+  }
+
   /// The program built with a call to Build()
   std::unique_ptr<Program> program;