fuzzing: Create Instance and discover Adapters only once

This patch moves Instance initialization and adapter discovery so that
it is done once globally, and not for every fuzz input. This is to work
around a bug where destructing the instance at the end of a run breaks
when fuzzing with Swiftshader.

Bug: dawn:295, chromium:1038952
Change-Id: Iabfe178f40b9df85d47a6353f16cd2ef26f39966
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/14822
Commit-Queue: Austin Eng <enga@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
diff --git a/src/fuzzers/DawnWireServerAndFrontendFuzzer.cpp b/src/fuzzers/DawnWireServerAndFrontendFuzzer.cpp
index 66de766..0126028 100644
--- a/src/fuzzers/DawnWireServerAndFrontendFuzzer.cpp
+++ b/src/fuzzers/DawnWireServerAndFrontendFuzzer.cpp
@@ -25,8 +25,6 @@
     return DawnWireServerFuzzer::Run(
         data, size,
         [](dawn_native::Instance* instance) {
-            instance->DiscoverDefaultAdapters();
-
             std::vector<dawn_native::Adapter> adapters = instance->GetAdapters();
 
             wgpu::Device nullDevice;
diff --git a/src/fuzzers/DawnWireServerAndVulkanBackendFuzzer.cpp b/src/fuzzers/DawnWireServerAndVulkanBackendFuzzer.cpp
index 266b756..784a8ce 100644
--- a/src/fuzzers/DawnWireServerAndVulkanBackendFuzzer.cpp
+++ b/src/fuzzers/DawnWireServerAndVulkanBackendFuzzer.cpp
@@ -24,8 +24,6 @@
     return DawnWireServerFuzzer::Run(
         data, size,
         [](dawn_native::Instance* instance) {
-            instance->DiscoverDefaultAdapters();
-
             std::vector<dawn_native::Adapter> adapters = instance->GetAdapters();
 
             wgpu::Device device;
diff --git a/src/fuzzers/DawnWireServerFuzzer.cpp b/src/fuzzers/DawnWireServerFuzzer.cpp
index 522e281..4d2af48 100644
--- a/src/fuzzers/DawnWireServerFuzzer.cpp
+++ b/src/fuzzers/DawnWireServerFuzzer.cpp
@@ -43,6 +43,7 @@
         std::vector<char> buf;
     };
 
+    std::unique_ptr<dawn_native::Instance> sInstance;
     WGPUProcDeviceCreateSwapChain sOriginalDeviceCreateSwapChain = nullptr;
 
     std::string sInjectedErrorTestcaseOutDir;
@@ -86,6 +87,12 @@
     // Write the argument count
     *argc = argcOut;
 
+    // TODO(crbug.com/1038952): The Instance must be static because destructing the vkInstance with
+    // Swiftshader crashes libFuzzer. When this is fixed, move this into Run so that error injection
+    // for adapter discovery can be fuzzed.
+    sInstance = std::make_unique<dawn_native::Instance>();
+    sInstance->DiscoverDefaultAdapters();
+
     return 0;
 }
 
@@ -125,8 +132,7 @@
 
     dawnProcSetProcs(&procs);
 
-    std::unique_ptr<dawn_native::Instance> instance = std::make_unique<dawn_native::Instance>();
-    wgpu::Device device = MakeDevice(instance.get());
+    wgpu::Device device = MakeDevice(sInstance.get());
     if (!device) {
         // We should only ever fail device creation if an error was injected.
         ASSERT(didInjectError);
@@ -149,7 +155,6 @@
     // Destroy the server before the device because it needs to free all objects.
     wireServer = nullptr;
     device = nullptr;
-    instance = nullptr;
 
     // If we support error injection, and an output directory was provided, output copies of the
     // original testcase data, prepended with the injected error index.