Adding SPVC fuzzers

Change-Id: I9dc598f7d929595d674b5a5916e5b00e46e85559
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/14502
Reviewed-by: Ryan Harrison <rharrison@chromium.org>
Commit-Queue: Sarah Mashayekhi <sarahmashay@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index e712d66..368a8b9 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -1224,6 +1224,9 @@
     "src/fuzzers:dawn_spirv_cross_glsl_fast_fuzzer",
     "src/fuzzers:dawn_spirv_cross_hlsl_fast_fuzzer",
     "src/fuzzers:dawn_spirv_cross_msl_fast_fuzzer",
+    "src/fuzzers:dawn_spvc_glsl_fast_fuzzer",
+    "src/fuzzers:dawn_spvc_hlsl_fast_fuzzer",
+    "src/fuzzers:dawn_spvc_msl_fast_fuzzer",
     "src/fuzzers:dawn_wire_server_and_frontend_fuzzer",
   ]
 }
diff --git a/src/fuzzers/BUILD.gn b/src/fuzzers/BUILD.gn
index 57bdcf3..aea8fe6 100644
--- a/src/fuzzers/BUILD.gn
+++ b/src/fuzzers/BUILD.gn
@@ -118,6 +118,33 @@
   asan_options = [ "allow_user_segv_handler=1" ]
 }
 
+dawn_fuzzer_test("dawn_spvc_glsl_fast_fuzzer") {
+  sources = [
+    "DawnSPVCglslFastFuzzer.cpp",
+  ]
+  deps = [
+     "${dawn_shaderc_dir}:libshaderc_spvc",
+  ]
+}
+
+dawn_fuzzer_test("dawn_spvc_hlsl_fast_fuzzer") {
+  sources = [
+    "DawnSPVChlslFastFuzzer.cpp",
+  ]
+  deps = [
+     "${dawn_shaderc_dir}:libshaderc_spvc",
+  ]
+}
+
+dawn_fuzzer_test("dawn_spvc_msl_fast_fuzzer") {
+  sources = [
+    "DawnSPVCmslFastFuzzer.cpp",
+  ]
+  deps = [
+     "${dawn_shaderc_dir}:libshaderc_spvc",
+  ]
+}
+
 dawn_fuzzer_test("dawn_wire_server_and_frontend_fuzzer") {
   sources = [
     "DawnWireServerAndFrontendFuzzer.cpp",
diff --git a/src/fuzzers/DawnSPVCglslFastFuzzer.cpp b/src/fuzzers/DawnSPVCglslFastFuzzer.cpp
new file mode 100644
index 0000000..9a67c3c
--- /dev/null
+++ b/src/fuzzers/DawnSPVCglslFastFuzzer.cpp
@@ -0,0 +1,53 @@
+// Copyright 2019 The Dawn Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <cstdint>
+#include <string>
+#include <vector>
+
+#include "spvc/spvc.hpp"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    shaderc_spvc::Context context;
+    if (!context.IsValid()) {
+        return 0;
+    }
+
+    shaderc_spvc::CompilationResult result;
+    shaderc_spvc::CompileOptions options;
+    options.SetSourceEnvironment(shaderc_target_env_webgpu, shaderc_env_version_webgpu);
+    options.SetTargetEnvironment(shaderc_target_env_vulkan, shaderc_env_version_vulkan_1_1);
+    // Using the options that are used by Dawn, they appear in ShaderModuleGL.cpp
+    // TODO(sarahM0): double check these option after completion of spvc integration
+    options.SetFlipVertY(true);
+    options.SetFixupClipspace(true);
+#if defined(DAWN_PLATFORM_APPLE)
+    options.SetGLSLLanguageVersion(410);
+#else
+    options.SetGLSLLanguageVersion(440);
+#endif
+
+    size_t sizeInU32 = size / sizeof(uint32_t);
+    const uint32_t* u32Data = reinterpret_cast<const uint32_t*>(data);
+    std::vector<uint32_t> input(u32Data, u32Data + sizeInU32);
+
+    if (input.size() != 0) {
+        if (context.InitializeForGlsl(input.data(), input.size(), options) ==
+            shaderc_spvc_status_success) {
+            context.SetUseSpvcParser(true);
+            context.CompileShader(&result);
+        }
+    }
+    return 0;
+}
diff --git a/src/fuzzers/DawnSPVChlslFastFuzzer.cpp b/src/fuzzers/DawnSPVChlslFastFuzzer.cpp
new file mode 100644
index 0000000..f59bd2c
--- /dev/null
+++ b/src/fuzzers/DawnSPVChlslFastFuzzer.cpp
@@ -0,0 +1,53 @@
+// Copyright 2019 The Dawn Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <cstdint>
+#include <string>
+#include <vector>
+
+#include "spvc/spvc.hpp"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    shaderc_spvc::Context context;
+    if (!context.IsValid()) {
+        return 0;
+    }
+
+    shaderc_spvc::CompilationResult result;
+    shaderc_spvc::CompileOptions options;
+    options.SetSourceEnvironment(shaderc_target_env_webgpu, shaderc_env_version_webgpu);
+    options.SetTargetEnvironment(shaderc_target_env_vulkan, shaderc_env_version_vulkan_1_1);
+
+    // Using the options that are used by Dawn, they appear in ShaderModuleD3D12.cpp
+    // TODO(sarahM0): double check these option after completion of spvc integration
+    options.SetHLSLShaderModel(51);
+    // TODO (hao.x.li@intel.com): The HLSLPointCoordCompat and HLSLPointSizeCompat are
+    // required temporarily for https://bugs.chromium.org/p/dawn/issues/detail?id=146,
+    // but should be removed once WebGPU requires there is no gl_PointSize builtin.
+    // See https://github.com/gpuweb/gpuweb/issues/332
+    options.SetHLSLPointCoordCompat(true);
+    options.SetHLSLPointSizeCompat(true);
+
+    size_t sizeInU32 = size / sizeof(uint32_t);
+    const uint32_t* u32Data = reinterpret_cast<const uint32_t*>(data);
+    std::vector<uint32_t> input(u32Data, u32Data + sizeInU32);
+
+    if (input.size() != 0) {
+        if (context.InitializeForHlsl(input.data(), input.size(), options) ==
+            shaderc_spvc_status_success) {
+            context.CompileShader(&result);
+        }
+    }
+    return 0;
+}
diff --git a/src/fuzzers/DawnSPVCmslFastFuzzer.cpp b/src/fuzzers/DawnSPVCmslFastFuzzer.cpp
new file mode 100644
index 0000000..331d924
--- /dev/null
+++ b/src/fuzzers/DawnSPVCmslFastFuzzer.cpp
@@ -0,0 +1,45 @@
+// Copyright 2019 The Dawn Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <cstdint>
+#include <string>
+#include <vector>
+
+#include "spvc/spvc.hpp"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    shaderc_spvc::Context context;
+    if (!context.IsValid()) {
+        return 0;
+    }
+
+    shaderc_spvc::CompilationResult result;
+    shaderc_spvc::CompileOptions options;
+    options.SetSourceEnvironment(shaderc_target_env_webgpu, shaderc_env_version_webgpu);
+    options.SetTargetEnvironment(shaderc_target_env_vulkan, shaderc_env_version_vulkan_1_1);
+
+    // Using the options that are used by Dawn, they appear in ShaderModuleMTL.mm
+    // TODO(sarahM0): double check these option after completion of spvc integration
+    size_t sizeInU32 = size / sizeof(uint32_t);
+    const uint32_t* u32Data = reinterpret_cast<const uint32_t*>(data);
+    std::vector<uint32_t> input(u32Data, u32Data + sizeInU32);
+
+    if (input.size() != 0) {
+        if (context.InitializeForMsl(input.data(), input.size(), options) ==
+            shaderc_spvc_status_success) {
+            context.CompileShader(&result);
+        }
+    }
+    return 0;
+}