CMake: Add TINT_EXTERNAL_BENCHMARK_CORPUS_DIR

If specified, CMake will glob all the .wgsl files in this directory, and add these to the list of benchmarks to run.

Change-Id: I75b2754a6561dcd931c42bd47649c4f625e1c581
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/127980
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
diff --git a/src/tint/CMakeLists.txt b/src/tint/CMakeLists.txt
index 8ac5b15..7b595fd 100644
--- a/src/tint/CMakeLists.txt
+++ b/src/tint/CMakeLists.txt
@@ -1494,4 +1494,27 @@
   tint_core_compile_options(tint-benchmark)
 
   target_link_libraries(tint-benchmark PRIVATE benchmark::benchmark libtint)
+
+  if (TINT_EXTERNAL_BENCHMARK_CORPUS_DIR)
+    # Glob all the files at TINT_EXTERNAL_BENCHMARK_CORPUS_DIR, and create a header
+    # that lists these with the TINT_BENCHMARK_EXTERNAL_WGSL_PROGRAMS() macro
+    set(TINT_BENCHMARK_GEN_DIR "${DAWN_BUILD_GEN_DIR}/src/tint/benchmark/")
+    set(TINT_BENCHMARK_EXTERNAL_WGSL_PROGRAM_HEADER "${TINT_BENCHMARK_GEN_DIR}/external_wgsl_programs.h")
+    message("Globbing ${TINT_EXTERNAL_BENCHMARK_CORPUS_DIR}...")
+    file(GLOB_RECURSE
+      TINT_EXTERNAL_BENCHMARK_FILES
+      RELATIVE "${TINT_EXTERNAL_BENCHMARK_CORPUS_DIR}"
+      "${TINT_EXTERNAL_BENCHMARK_CORPUS_DIR}/**.wgsl")
+    list(TRANSFORM TINT_EXTERNAL_BENCHMARK_FILES REPLACE
+      "(.+)"
+      "    BENCHMARK_CAPTURE\(FUNC, \"\\1\", \"${TINT_EXTERNAL_BENCHMARK_CORPUS_DIR}/\\1\")")
+    list(JOIN TINT_EXTERNAL_BENCHMARK_FILES "; \\\n" TINT_EXTERNAL_BENCHMARK_FILES)
+    file(CONFIGURE
+      OUTPUT "${TINT_BENCHMARK_EXTERNAL_WGSL_PROGRAM_HEADER}"
+      CONTENT "#define TINT_BENCHMARK_EXTERNAL_WGSL_PROGRAMS(FUNC) \\
+${TINT_EXTERNAL_BENCHMARK_FILES};")
+    # Define TINT_BENCHMARK_EXTERNAL_WGSL_PROGRAM_HEADER to the generated header path
+    target_compile_definitions(tint-benchmark PRIVATE
+      "TINT_BENCHMARK_EXTERNAL_WGSL_PROGRAM_HEADER=\"${TINT_BENCHMARK_EXTERNAL_WGSL_PROGRAM_HEADER}\"")
+  endif()
 endif(TINT_BUILD_BENCHMARKS)
diff --git a/src/tint/bench/benchmark.h b/src/tint/bench/benchmark.h
index 6801585..adb28b8 100644
--- a/src/tint/bench/benchmark.h
+++ b/src/tint/bench/benchmark.h
@@ -51,6 +51,15 @@
 /// @returns either the loaded Program or an Error
 std::variant<ProgramAndFile, Error> LoadProgram(std::string name);
 
+// If TINT_BENCHMARK_EXTERNAL_WGSL_PROGRAM_HEADER is defined, include that to
+// declare the TINT_BENCHMARK_EXTERNAL_WGSL_PROGRAMS() macro, which appends
+// external programs to the TINT_BENCHMARK_WGSL_PROGRAMS() list.
+#ifdef TINT_BENCHMARK_EXTERNAL_WGSL_PROGRAM_HEADER
+#include TINT_BENCHMARK_EXTERNAL_WGSL_PROGRAM_HEADER
+#else
+#define TINT_BENCHMARK_EXTERNAL_WGSL_PROGRAMS(x)
+#endif
+
 /// Declares a benchmark with the given function and WGSL file name
 #define TINT_BENCHMARK_WGSL_PROGRAM(FUNC, WGSL_NAME) BENCHMARK_CAPTURE(FUNC, WGSL_NAME, WGSL_NAME);
 
@@ -69,7 +78,8 @@
     TINT_BENCHMARK_WGSL_PROGRAM(FUNC, "simple-fragment.wgsl");               \
     TINT_BENCHMARK_WGSL_PROGRAM(FUNC, "simple-vertex.wgsl");                 \
     TINT_BENCHMARK_WGSL_PROGRAM(FUNC, "skinned-shadowed-pbr-fragment.wgsl"); \
-    TINT_BENCHMARK_WGSL_PROGRAM(FUNC, "skinned-shadowed-pbr-vertex.wgsl");
+    TINT_BENCHMARK_WGSL_PROGRAM(FUNC, "skinned-shadowed-pbr-vertex.wgsl");   \
+    TINT_BENCHMARK_EXTERNAL_WGSL_PROGRAMS(FUNC)
 
 }  // namespace tint::bench