def get_function_signature_from_address( module: Path, address: str, addr2line_mock: Optional[Callable[[Path, str], str]] = None, ) -> Optional[str]: # stdout result can be mocked for testing. stdout: str if addr2line_mock: stdout = addr2line_mock(module, address) else: try: address_tool = util.tool_on_path("addr2line") except util.ToolNotOnPathError: return None result = subprocess_util.run( [str(address_tool), "-e", str(module), address, "-f", "-C"], check_exit_code=False, verbose=True, ) if result.returncode != 0: return None stdout = result.stdout lines = stdout.splitlines() if not lines: return None if lines[0].startswith("??"): return None return lines[0]
def run_glslang_glsl_shader_to_spirv_shader( glsl_shader_path: pathlib.Path, output_dir_path: pathlib.Path, glslang_validator_file_path: Optional[pathlib.Path] = None, time_limit: int = GLSLANG_DEFAULT_TIME_LIMIT, ) -> pathlib.Path: if not glslang_validator_file_path: glslang_validator_file_path = util.tool_on_path( binaries_util.GLSLANG_VALIDATOR_NAME ) output_spirv_file_path = output_dir_path / (glsl_shader_path.name + ".spv") util.file_mkdirs_parent(output_spirv_file_path) subprocess_util.run( util.prepend_catchsegv_if_available( [ str(glslang_validator_file_path), "-V", "-o", str(output_spirv_file_path), str(glsl_shader_path), ] ), timeout=time_limit, ) return output_spirv_file_path
def adb_path() -> Path: if "ANDROID_HOME" in os.environ: platform_tools_path = Path(os.environ["ANDROID_HOME"]) / "platform-tools" adb = shutil.which("adb", path=str(platform_tools_path)) if adb: return Path(adb) return util.tool_on_path("adb")
def run_glslang_glsl_to_spirv_job( glsl_shader_job_json_file_path: pathlib.Path, spirv_shader_job_json_file_path: pathlib.Path, glslang_validator_file_path: Optional[pathlib.Path] = None, ) -> pathlib.Path: if not glslang_validator_file_path: glslang_validator_file_path = util.tool_on_path( binaries_util.GLSLANG_VALIDATOR_NAME ) glsl_shader_files = shader_job_util.get_related_files( glsl_shader_job_json_file_path ) util.copy_file(glsl_shader_job_json_file_path, spirv_shader_job_json_file_path) for glsl_shader_file in glsl_shader_files: run_glslang_glsl_shader_to_spirv_shader( glsl_shader_file, spirv_shader_job_json_file_path.parent, glslang_validator_file_path, ) return spirv_shader_job_json_file_path
def run_spirv_opt_on_spirv_shader_job( input_spirv_shader_job_json_file_path: pathlib.Path, output_spirv_shader_job_json_file_path: pathlib.Path, spirv_opt_args: List[str], spirv_opt_file_path: Optional[pathlib.Path] = None, spirv_opt_no_validate_after_all: bool = False, preprocessor_cache: Optional[util.CommandCache] = None, ) -> pathlib.Path: if not spirv_opt_file_path: spirv_opt_file_path = util.tool_on_path(binaries_util.SPIRV_OPT_NAME) shader_files = shader_job_util.get_related_files( input_spirv_shader_job_json_file_path, language_suffix=[shader_job_util.SUFFIX_SPIRV], ) util.copy_file(input_spirv_shader_job_json_file_path, output_spirv_shader_job_json_file_path) for shader_file in shader_files: run_spirv_opt_on_spirv_shader( shader_file, output_spirv_shader_job_json_file_path.parent, spirv_opt_args, spirv_opt_file_path, spirv_opt_no_validate_after_all, preprocessor_cache=preprocessor_cache, ) return output_spirv_shader_job_json_file_path
def main() -> None: parser = argparse.ArgumentParser( description= "Downloads the latest GraphicsFuzz AmberScript tests from vk-gl-cts, " "including those in pending CLs. " "Requires Git. Requires Khronos membership.") parser.add_argument( "gerrit_cookie", help= "The Gerrit cookie used for authentication. Requires Khronos membership. Obtain this as follows. " + GERRIT_COOKIE_INSTRUCTIONS, ) parser.add_argument( "--settings", help="Path to the settings JSON file for this instance.", default=str(settings_util.DEFAULT_SETTINGS_FILE_PATH), ) parsed_args = parser.parse_args(sys.argv[1:]) cookie: str = parsed_args.gerrit_cookie settings_path: Path = Path(parsed_args.settings) # Need git. git_tool = util.tool_on_path("git") settings = settings_util.read_or_create(settings_path) binaries = binaries_util.get_default_binary_manager(settings=settings) tests_dir = Path() / "graphicsfuzz" download_cts_graphicsfuzz_tests(git_tool, cookie, tests_dir) extract_shaders(tests_dir, binaries)
def main() -> None: parser = argparse.ArgumentParser( description= "Downloads the latest GraphicsFuzz AmberScript tests from vk-gl-cts, " "including those in pending CLs. " "Requires Git.") parser.add_argument("gerrit_cookie", help=GERRIT_COOKIE_ARGUMENT_DESCRIPTION) parser.add_argument( "--settings", help="Path to the settings JSON file for this instance.", default=str(settings_util.DEFAULT_SETTINGS_FILE_PATH), ) parsed_args = parser.parse_args(sys.argv[1:]) cookie: str = parsed_args.gerrit_cookie settings_path: Path = Path(parsed_args.settings) # Need git. git_tool = util.tool_on_path("git") settings = settings_util.read_or_create(settings_path) binaries = binaries_util.get_default_binary_manager(settings=settings) download_cts_graphicsfuzz_tests(git_tool, cookie, binaries)
def run_spirv_opt_on_spirv_shader( input_spirv_file_path: pathlib.Path, output_dir_path: pathlib.Path, spirv_opt_args: List[str], spirv_opt_file_path: Optional[pathlib.Path] = None, spirv_opt_no_validate_after_all: bool = False, time_limit: int = SPIRV_OPT_DEFAULT_TIME_LIMIT, ) -> pathlib.Path: if not spirv_opt_file_path: spirv_opt_file_path = util.tool_on_path(binaries_util.SPIRV_OPT_NAME) output_spirv_file_path = output_dir_path / input_spirv_file_path.name util.file_mkdirs_parent(output_spirv_file_path) cmd = [ str(spirv_opt_file_path), str(input_spirv_file_path), "-o", str(output_spirv_file_path), ] if not spirv_opt_no_validate_after_all: cmd.append("--validate-after-all") cmd += spirv_opt_args cmd = util.prepend_catchsegv_if_available(cmd) subprocess_util.run(cmd, timeout=time_limit) return output_spirv_file_path
def run_glsl_reduce( source_dir: Path, name_of_shader_to_reduce: str, output_dir: Path, binary_manager: binaries_util.BinaryManager, preserve_semantics: bool = False, extra_args: Optional[List[str]] = None, ) -> Path: input_shader_job = source_dir / name_of_shader_to_reduce / test_util.SHADER_JOB glsl_reduce_path = util.tool_on_path( "glsl-reduce", str( binary_manager.get_binary_path_by_name( "graphicsfuzz-tool").path.parent), ) cmd = [ str(glsl_reduce_path), str(input_shader_job), "--output", str(output_dir), ] if preserve_semantics: cmd.append("--preserve-semantics") if extra_args: cmd.extend(extra_args) cmd.extend([ # This ensures the arguments that follow are all positional arguments. "--", "gfauto_interestingness_test", str(source_dir), # --override_shader_job requires two parameters to follow; the second will be added by glsl-reduce (the shader.json file). "--override_shader_job", str(name_of_shader_to_reduce), ]) # Log the reduction. with util.file_open_text(output_dir / "command.log", "w") as f: gflogging.push_stream_for_logging(f) try: # The reducer can fail, but it will typically output an exception file, so we can ignore the exit code. subprocess_util.run(cmd, verbose=True, check_exit_code=False) finally: gflogging.pop_stream_for_logging() return output_dir
def get_function_signature_from_address(module: Path, address: str) -> Optional[str]: try: address_tool = util.tool_on_path("addr2line") result = subprocess_util.run( [str(address_tool), "-e", str(module), address, "-f", "-C"], check_exit_code=False, ) if result.returncode != 0: return None stdout: str = result.stdout lines = stdout.splitlines() if not lines: return None return lines[0] except util.ToolNotOnPathError: return None
def run_spirv_shader_job_to_spirv_asm_shader_job( input_spirv_job_json_file_path: pathlib.Path, output_spirv_job_json_file_path: pathlib.Path, spirv_dis_file_path: Optional[pathlib.Path] = None, ) -> pathlib.Path: if not spirv_dis_file_path: spirv_dis_file_path = util.tool_on_path(binaries_util.SPIRV_DIS_NAME) shader_files = shader_job_util.get_related_files( input_spirv_job_json_file_path, language_suffix=[shader_job_util.SUFFIX_SPIRV]) util.copy_file(input_spirv_job_json_file_path, output_spirv_job_json_file_path) for shader_file in shader_files: run_spirv_dis_on_spirv_shader(shader_file, output_spirv_job_json_file_path.parent, spirv_dis_file_path) return output_spirv_job_json_file_path
def run_spirv_dis_on_spirv_shader( input_spirv_file_path: pathlib.Path, output_dir_path: pathlib.Path, spirv_dis_file_path: Optional[pathlib.Path] = None, ) -> pathlib.Path: if not spirv_dis_file_path: spirv_dis_file_path = util.tool_on_path(binaries_util.SPIRV_DIS_NAME) output_spirv_file_path = output_dir_path / ( util.remove_end(input_spirv_file_path.name, ".spv") + ".asm") util.file_mkdirs_parent(output_spirv_file_path) subprocess_util.run( util.prepend_catchsegv_if_available([ str(spirv_dis_file_path), str(input_spirv_file_path), "-o", str(output_spirv_file_path), "--raw-id", ])) return output_spirv_file_path
def run_spirv_opt_on_spirv_shader( input_spirv_file_path: pathlib.Path, output_dir_path: pathlib.Path, spirv_opt_args: List[str], spirv_opt_file_path: Optional[pathlib.Path] = None, spirv_opt_no_validate_after_all: bool = False, time_limit: int = SPIRV_OPT_DEFAULT_TIME_LIMIT, preprocessor_cache: Optional[util.CommandCache] = None, ) -> pathlib.Path: if not spirv_opt_file_path: spirv_opt_file_path = util.tool_on_path(binaries_util.SPIRV_OPT_NAME) output_spirv_file_path = output_dir_path / input_spirv_file_path.name util.file_mkdirs_parent(output_spirv_file_path) cmd = util.HashedCommand() cmd.append_program_path(spirv_opt_file_path) cmd.append_input_file(input_spirv_file_path) cmd.append_str("-o") cmd.append_output_file(output_spirv_file_path) if not spirv_opt_no_validate_after_all: cmd.append_str("--validate-after-all") cmd.extend_str(spirv_opt_args) if preprocessor_cache and preprocessor_cache.write_cached_output_file( cmd, output_spirv_file_path): return output_spirv_file_path cmd_str = util.prepend_catchsegv_if_available(cmd.cmd) subprocess_util.run(cmd_str, timeout=time_limit) if preprocessor_cache: preprocessor_cache.add_output_to_cache(cmd, output_spirv_file_path) return output_spirv_file_path
def run_glslang_glsl_shader_to_spirv_shader( glsl_shader_path: pathlib.Path, output_dir_path: pathlib.Path, glslang_validator_file_path: Optional[pathlib.Path] = None, time_limit: int = GLSLANG_DEFAULT_TIME_LIMIT, preprocessor_cache: Optional[util.CommandCache] = None, ) -> pathlib.Path: if not glslang_validator_file_path: glslang_validator_file_path = util.tool_on_path( binaries_util.GLSLANG_VALIDATOR_NAME) output_spirv_file_path = output_dir_path / (glsl_shader_path.name + ".spv") util.file_mkdirs_parent(output_spirv_file_path) cmd = util.HashedCommand() cmd.append_program_path(glslang_validator_file_path) cmd.append_str("-V") cmd.append_str("-o") cmd.append_output_file(output_spirv_file_path) cmd.append_input_file(glsl_shader_path) if preprocessor_cache and preprocessor_cache.write_cached_output_file( cmd, output_spirv_file_path): return output_spirv_file_path cmd_str = util.prepend_catchsegv_if_available(cmd.cmd) subprocess_util.run( cmd_str, timeout=time_limit, ) if preprocessor_cache: preprocessor_cache.add_output_to_cache(cmd, output_spirv_file_path) return output_spirv_file_path
def main_helper( # pylint: disable=too-many-locals, too-many-branches, too-many-statements; settings_path: Path, iteration_seed_override: Optional[int] = None, fuzzing_tool_pattern: Optional[List[FuzzingTool]] = None, allow_no_stack_traces: bool = False, override_sigint: bool = True, use_amber_vulkan_loader: bool = False, active_device_names: Optional[List[str]] = None, update_ignored_crash_signatures_gerrit_cookie: Optional[str] = None, ) -> None: if not fuzzing_tool_pattern: fuzzing_tool_pattern = [FuzzingTool.GLSL_FUZZ] util.update_gcov_environment_variable_if_needed() if override_sigint: interrupt_util.override_sigint() try_get_root_file() settings = settings_util.read_or_create(settings_path) binary_manager = binaries_util.get_default_binary_manager( settings=settings) temp_dir = Path() / "temp" # Note: we use "is not None" so that if the user passes an empty Gerrit cookie, we still try to execute this code. if update_ignored_crash_signatures_gerrit_cookie is not None: git_tool = util.tool_on_path("git") downloaded_graphicsfuzz_tests_dir = ( temp_dir / f"graphicsfuzz_cts_tests_{get_random_name()[:8]}") work_dir = temp_dir / f"graphicsfuzz_cts_run_{get_random_name()[:8]}" download_cts_gf_tests.download_cts_graphicsfuzz_tests( git_tool=git_tool, cookie=update_ignored_crash_signatures_gerrit_cookie, output_tests_dir=downloaded_graphicsfuzz_tests_dir, ) download_cts_gf_tests.extract_shaders( tests_dir=downloaded_graphicsfuzz_tests_dir, binaries=binary_manager) with util.file_open_text(work_dir / "results.csv", "w") as results_out_handle: run_cts_gf_tests.main_helper( tests_dir=downloaded_graphicsfuzz_tests_dir, work_dir=work_dir, binaries=binary_manager, settings=settings, active_devices=devices_util.get_active_devices( settings.device_list), results_out_handle=results_out_handle, updated_settings_output_path=settings_path, ) return active_devices = devices_util.get_active_devices( settings.device_list, active_device_names=active_device_names) # Add host_preprocessor device from device list if it is missing. if not active_devices[0].HasField("preprocess"): for device in settings.device_list.devices: if device.HasField("preprocess"): active_devices.insert(0, device) break # Add host_preprocessor device (from scratch) if it is still missing. if not active_devices[0].HasField("preprocess"): active_devices.insert( 0, Device(name="host_preprocessor", preprocess=DevicePreprocess())) reports_dir = Path() / "reports" fuzz_failures_dir = reports_dir / FUZZ_FAILURES_DIR_NAME references_dir = Path() / REFERENCES_DIR donors_dir = Path() / DONORS_DIR spirv_fuzz_shaders_dir = Path() / "spirv_fuzz_shaders" # Log a warning if there is no tool on the PATH for printing stack traces. prepended = util.prepend_catchsegv_if_available([], log_warning=True) if not allow_no_stack_traces and not prepended: raise AssertionError("Stopping because we cannot get stack traces.") spirv_fuzz_shaders: List[Path] = [] references: List[Path] = [] if FuzzingTool.SPIRV_FUZZ in fuzzing_tool_pattern: check_dir_exists(spirv_fuzz_shaders_dir) spirv_fuzz_shaders = sorted(spirv_fuzz_shaders_dir.rglob("*.json")) if FuzzingTool.GLSL_FUZZ in fuzzing_tool_pattern: check_dir_exists(references_dir) check_dir_exists(donors_dir) # TODO: make GraphicsFuzz find donors recursively. references = sorted(references_dir.rglob("*.json")) # Filter to only include .json files that have at least one shader (.frag, .vert, .comp) file. references = [ ref for ref in references if shader_job_util.get_related_files(ref) ] if use_amber_vulkan_loader: library_path = binary_manager.get_binary_path_by_name( binaries_util.AMBER_VULKAN_LOADER_NAME).path.parent util.add_library_paths_to_environ([library_path], os.environ) fuzzing_tool_index = 0 while True: interrupt_util.interrupt_if_needed() # We have to use "is not None" because the seed could be 0. if iteration_seed_override is not None: iteration_seed = iteration_seed_override else: iteration_seed = secrets.randbits(ITERATION_SEED_BITS) log(f"Iteration seed: {iteration_seed}") random.seed(iteration_seed) staging_name = get_random_name()[:8] staging_dir = temp_dir / staging_name try: util.mkdir_p_new(staging_dir) except FileExistsError: if iteration_seed_override is not None: raise log(f"Staging directory already exists: {str(staging_dir)}") log("Starting new iteration.") continue # Pseudocode: # - Create test_dir(s) in staging directory. # - Run test_dir(s) on all active devices (stop early if appropriate). # - For each test failure on each device, copy the test to reports_dir, adding the device and crash signature. # - Reduce each report (on the given device). # - Produce a summary for each report. fuzzing_tool = fuzzing_tool_pattern[fuzzing_tool_index] fuzzing_tool_index = (fuzzing_tool_index + 1) % len(fuzzing_tool_pattern) if fuzzing_tool == FuzzingTool.SPIRV_FUZZ: fuzz_spirv_test.fuzz_spirv( staging_dir, reports_dir, fuzz_failures_dir, active_devices, spirv_fuzz_shaders, settings, binary_manager, ) elif fuzzing_tool == FuzzingTool.GLSL_FUZZ: fuzz_glsl_test.fuzz_glsl( staging_dir, reports_dir, fuzz_failures_dir, active_devices, references, donors_dir, settings, binary_manager, ) else: raise AssertionError(f"Unknown fuzzing tool: {fuzzing_tool}") if iteration_seed_override is not None: log("Stopping due to iteration_seed") break shutil.rmtree(staging_dir)
def fuzz_glsl( # pylint: disable=too-many-locals; staging_dir: Path, reports_dir: Path, fuzz_failures_dir: Path, active_devices: List[Device], references: List[Path], donors_dir: Path, settings: Settings, binary_manager: binaries_util.BinaryManager, ) -> None: staging_name = staging_dir.name template_source_dir = staging_dir / "source_template" # Pick a randomly chosen reference. unprepared_reference_shader_job: Path = random.choice(references) # The "graphicsfuzz-tool" tool is designed to be on your PATH so that e.g. ".bat" will be appended on Windows. # So we use tool_on_path with a custom PATH to get the actual file we want to execute. graphicsfuzz_tool_path = util.tool_on_path( "graphicsfuzz-tool", str( binary_manager.get_binary_path_by_name( "graphicsfuzz-tool").path.parent), ) try: with util.file_open_text(staging_dir / "log.txt", "w") as log_file: try: gflogging.push_stream_for_logging(log_file) # Create the prepared (for Vulkan GLSL) reference. glsl_generate_util.run_prepare_reference( graphicsfuzz_tool_path, unprepared_reference_shader_job, template_source_dir / test_util.REFERENCE_DIR / test_util.SHADER_JOB, legacy_graphics_fuzz_vulkan_arg=settings. legacy_graphics_fuzz_vulkan_arg, ) # Generate the variant (GraphicsFuzz requires the unprepared reference as input). glsl_generate_util.run_generate( graphicsfuzz_tool_path, unprepared_reference_shader_job, donors_dir, template_source_dir / test_util.VARIANT_DIR / test_util.SHADER_JOB, seed=str( random.getrandbits( glsl_generate_util.GENERATE_SEED_BITS)), other_args=list(settings.extra_graphics_fuzz_generate_args) if settings.extra_graphics_fuzz_generate_args else None, legacy_graphics_fuzz_vulkan_arg=settings. legacy_graphics_fuzz_vulkan_arg, ) finally: gflogging.pop_stream_for_logging() except subprocess.CalledProcessError: util.mkdirs_p(fuzz_failures_dir) if len(list( fuzz_failures_dir.iterdir())) < settings.maximum_fuzz_failures: util.copy_dir(staging_dir, fuzz_failures_dir / staging_dir.name) return reference_name = unprepared_reference_shader_job.stem stable_shader = reference_name.startswith("stable_") common_spirv_args = list(settings.common_spirv_args) test_dirs = [ make_test( template_source_dir, staging_dir / f"{staging_name}_no_opt_test", spirv_opt_args=None, binary_manager=binary_manager, derived_from=reference_name, stable_shader=stable_shader, common_spirv_args=common_spirv_args, ), make_test( template_source_dir, staging_dir / f"{staging_name}_opt_O_test", spirv_opt_args=["-O"], binary_manager=binary_manager, derived_from=reference_name, stable_shader=stable_shader, common_spirv_args=common_spirv_args, ), ] if not settings.spirv_opt_just_o: test_dirs += [ make_test( template_source_dir, staging_dir / f"{staging_name}_opt_Os_test", spirv_opt_args=["-Os"], binary_manager=binary_manager, derived_from=reference_name, stable_shader=stable_shader, common_spirv_args=common_spirv_args, ), make_test( template_source_dir, staging_dir / f"{staging_name}_opt_rand1_test", spirv_opt_args=spirv_opt_util.random_spirv_opt_args(), binary_manager=binary_manager, derived_from=reference_name, stable_shader=stable_shader, common_spirv_args=common_spirv_args, ), make_test( template_source_dir, staging_dir / f"{staging_name}_opt_rand2_test", spirv_opt_args=spirv_opt_util.random_spirv_opt_args(), binary_manager=binary_manager, derived_from=reference_name, stable_shader=stable_shader, common_spirv_args=common_spirv_args, ), make_test( template_source_dir, staging_dir / f"{staging_name}_opt_rand3_test", spirv_opt_args=spirv_opt_util.random_spirv_opt_args(), binary_manager=binary_manager, derived_from=reference_name, stable_shader=stable_shader, common_spirv_args=common_spirv_args, ), ] for test_dir in test_dirs: interrupt_util.interrupt_if_needed() if handle_test(test_dir, reports_dir, active_devices, binary_manager, settings): # If we generated a report, don't bother trying other optimization combinations. break
def main() -> None: # pylint: disable=too-many-locals; parser = argparse.ArgumentParser( description="Generates an AmberScript test from a shader job.") parser.add_argument( "shader_job", help="The input .json shader job file.", ) parser.add_argument( "--output", help="Output directory.", default="output", ) parser.add_argument( "--spirv_opt_args", help= "Arguments for spirv-opt as a space-separated string, or an empty string to skip running spirv-opt.", default="", ) parser.add_argument( "--settings", help= "Path to a settings JSON file for this instance. The file will be generated if needed. ", default="settings.json", ) parsed_args = parser.parse_args(sys.argv[1:]) shader_job: Path = Path(parsed_args.shader_job) out_dir: Path = Path(parsed_args.output) spirv_opt_args_str: str = parsed_args.spirv_opt_args settings_path: Path = Path(parsed_args.settings) spirv_opt_args: List[str] = [] if spirv_opt_args_str: spirv_opt_args = spirv_opt_args_str.split(" ") settings = settings_util.read_or_create(settings_path) binary_manager = binaries_util.get_default_binary_manager(settings) staging_dir = out_dir / "staging" template_source_dir = staging_dir / "source_template" test_dir = staging_dir / "test" run_output_dir: Path = out_dir / "run" # Remove stale directories. if staging_dir.is_dir(): shutil.rmtree(staging_dir) if run_output_dir.is_dir(): shutil.rmtree(run_output_dir) # Create source template and call |make_test|. if shader_job_util.get_related_suffixes_that_exist( shader_job, language_suffix=[shader_job_util.SUFFIX_SPIRV]): # This is a SPIR-V shader job. shader_job_util.copy( shader_job, template_source_dir / test_util.VARIANT_DIR / test_util.SHADER_JOB, language_suffix=shader_job_util.SUFFIXES_SPIRV_FUZZ_INPUT, ) fuzz_spirv_amber_test.make_test( template_source_dir, test_dir, spirv_opt_args=spirv_opt_args, binary_manager=binary_manager, derived_from=shader_job.stem, stable_shader=False, common_spirv_args=list(settings.common_spirv_args), ) elif shader_job_util.get_related_suffixes_that_exist( shader_job, language_suffix=[shader_job_util.SUFFIX_GLSL]): # This is a GLSL shader job. # The "graphicsfuzz-tool" tool is designed to be on your PATH so that e.g. ".bat" will be appended on Windows. # So we use tool_on_path with a custom PATH to get the actual file we want to execute. graphicsfuzz_tool_path = util.tool_on_path( "graphicsfuzz-tool", str( binary_manager.get_binary_path_by_name( "graphicsfuzz-tool").path.parent), ) with util.file_open_text(staging_dir / "log.txt", "w") as log_file: try: gflogging.push_stream_for_logging(log_file) # Create the prepared (for Vulkan GLSL) reference. glsl_generate_util.run_prepare_reference( graphicsfuzz_tool_path, shader_job, template_source_dir / test_util.VARIANT_DIR / test_util.SHADER_JOB, legacy_graphics_fuzz_vulkan_arg=settings. legacy_graphics_fuzz_vulkan_arg, ) finally: gflogging.pop_stream_for_logging() fuzz_glsl_amber_test.make_test( template_source_dir, test_dir, spirv_opt_args=spirv_opt_args, binary_manager=binary_manager, derived_from=shader_job.stem, stable_shader=False, common_spirv_args=list(settings.common_spirv_args), ) else: raise AssertionError( "Unexpected shader job type; expected GLSL or SPIR-V shaders.") preprocessor_cache = util.CommandCache() fuzz_test_util.run_shader_job( source_dir=test_util.get_source_dir(test_dir), output_dir=run_output_dir, binary_manager=binary_manager, device=Device(host=DeviceHost()), preprocessor_cache=preprocessor_cache, stop_after_amber=True, )