mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-05-13 19:01:24 +00:00
When preparing a corpus of SPIR-V shaders for fuzzing, spirv-as is invoked repeatedly. It could be that a bug in spirv-as leads to conversion failing for some of the shaders. This should not prevent the overall corpus from being generated, as long as the number of overall failures is reasonably small. This change adds some tolerance for such failures. Change-Id: I77750fdeab15a252201bff33e952e1bd44c42331 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/64543 Auto-Submit: Alastair Donaldson <afdx@google.com> Reviewed-by: Ben Clayton <bclayton@google.com> Commit-Queue: Alastair Donaldson <afdx@google.com> Kokoro: Kokoro <noreply+kokoro@google.com>
93 lines
3.3 KiB
Python
93 lines
3.3 KiB
Python
#!/usr/bin/env python3
|
|
|
|
# Copyright 2021 The Tint 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.
|
|
|
|
# Collect all .spvasm files under a given directory, assemble them using
|
|
# spirv-as, and emit the assembled binaries to a given corpus directory,
|
|
# flattening their file names by replacing path separators with underscores.
|
|
# If the output directory already exists, it will be deleted and re-created.
|
|
# Files ending with ".expected.spvasm" are skipped.
|
|
#
|
|
# The intended use of this script is to generate a corpus of SPIR-V
|
|
# binaries for fuzzing.
|
|
#
|
|
# Usage:
|
|
# generate_spirv_corpus.py <input_dir> <corpus_dir> <path to spirv-as>
|
|
|
|
|
|
import os
|
|
import pathlib
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
|
|
|
|
def list_spvasm_files(root_search_dir):
|
|
for root, folders, files in os.walk(root_search_dir):
|
|
for filename in folders + files:
|
|
if pathlib.Path(filename).suffix == ".spvasm":
|
|
yield os.path.join(root, filename)
|
|
|
|
|
|
def main():
|
|
if len(sys.argv) != 4:
|
|
print("Usage: " + sys.argv[0] +
|
|
" <input dir> <output dir> <spirv-as path>")
|
|
return 1
|
|
input_dir: str = os.path.abspath(sys.argv[1].rstrip(os.sep))
|
|
corpus_dir: str = os.path.abspath(sys.argv[2])
|
|
spirv_as_path: str = os.path.abspath(sys.argv[3])
|
|
if os.path.exists(corpus_dir):
|
|
shutil.rmtree(corpus_dir)
|
|
os.makedirs(corpus_dir)
|
|
|
|
# It might be that some of the attempts to convert SPIR-V assembly shaders
|
|
# into SPIR-V binaries go wrong. It is sensible to tolerate a small number
|
|
# of such errors, to avoid fuzzer preparation failing due to bugs in
|
|
# spirv-as. But it is important to know when a large number of failures
|
|
# occur, in case something is more deeply wrong.
|
|
num_errors = 0
|
|
max_tolerated_errors = 10
|
|
logged_errors = ""
|
|
|
|
for in_file in list_spvasm_files(input_dir):
|
|
if in_file.endswith(".expected.spvasm"):
|
|
continue
|
|
out_file = os.path.splitext(corpus_dir + os.sep +
|
|
in_file[len(input_dir) + 1:]
|
|
.replace(os.sep, '_'))[0] + ".spv"
|
|
cmd = [spirv_as_path,
|
|
"--target-env",
|
|
"spv1.3",
|
|
in_file,
|
|
"-o",
|
|
out_file]
|
|
proc = subprocess.Popen(cmd,
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.PIPE)
|
|
stdout, stderr = proc.communicate()
|
|
if proc.returncode != 0:
|
|
num_errors += 1
|
|
logged_errors += "Error running " + " ".join(cmd) + ": " + stdout.decode('utf-8') + stderr.decode('utf-8')
|
|
|
|
if num_errors > max_tolerated_errors:
|
|
print("Too many (" + str(num_errors) + ") errors occured while generating the SPIR-V corpus.")
|
|
print(logged_errors)
|
|
return 1
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|