Edit

kc3-lang/angle/scripts/generate_vulkan_layers_json.py

Branch :

  • Show log

    Commit

  • Author : Nico Weber
    Date : 2018-12-03 09:06:02
    Hash : ce0a8f3c
    Message : List vulkan_core.h as input of generate_vulkan_layers_json.py. Since this was missing, the layer json files didn't get regenerated on vulkan rolls, leading to stale generated json files, which in turn led to incremental builds having different files in the swarming isolate than full builds. To make this type of bug harder to introduce, rewrite generate_vulkan_layers_json.py a bit: - pass in path to vulkan_core.h as an argument - also pass in the input .json / .json.in files as arguments, so that the script re-runs if a .json or .json.in input is added or removed, and in the script verify that the passed-in list matches the glob() the script did previously (this verifies that the sources list in the .gn file is up-to-date with the state on disk) - generate outputs list in gn from sources list, to make sure they're in sync - use an expicit --icd flag instead of doing `'icd' in path` - fail when failing to extract vk_version instead of silently using a default - some minor python style fixes Bug: chromium:910699,chromium:869348 Change-Id: I1e598f4566697a7f1ef56b040e52d0717f7ad075 Reviewed-on: https://chromium-review.googlesource.com/c/1358631 Reviewed-by: Jamie Madill <jmadill@chromium.org> Commit-Queue: Nico Weber <thakis@chromium.org>

  • scripts/generate_vulkan_layers_json.py
  • #!/usr/bin/env python
    #
    # Copyright 2016 The ANGLE Project Authors. All rights reserved.
    # Use of this source code is governed by a BSD-style license that can be
    # found in the LICENSE file.
    
    """Generate copies of the Vulkan layers JSON files, with no paths, forcing
    Vulkan to use the default search path to look for layers."""
    
    from __future__ import print_function
    
    import argparse
    import glob
    import json
    import os
    import platform
    import sys
    
    
    def glob_slash(dirname):
        """Like regular glob but replaces \ with / in returned paths."""
        return [s.replace('\\', '/') for s in glob.glob(dirname)]
    
    
    def main():
        parser = argparse.ArgumentParser(description=__doc__)
        parser.add_argument('--icd', action='store_true')
        parser.add_argument('source_dir')
        parser.add_argument('target_dir')
        parser.add_argument('version_header', help='path to vulkan_core.h')
        parser.add_argument('json_files', nargs='*')
        args = parser.parse_args()
    
        source_dir = args.source_dir
        target_dir = args.target_dir
    
        json_files = [j for j in args.json_files if j.endswith('.json')]
        json_in_files = [j for j in args.json_files if j.endswith('.json.in')]
    
        data_key = 'ICD' if args.icd else 'layer'
    
        if not os.path.isdir(source_dir):
            print(source_dir + ' is not a directory.', file=sys.stderr)
            return 1
    
        if not os.path.exists(target_dir):
            os.makedirs(target_dir)
    
        # Copy the *.json files from source dir to target dir
        if (set(glob_slash(os.path.join(source_dir, '*.json'))) != set(json_files)):
            print(glob.glob(os.path.join(source_dir, '*.json')))
            print('.json list in gn file is out-of-date', file=sys.stderr)
            return 1
    
        for json_fname in json_files:
            if not json_fname.endswith('.json'):
                continue
            with open(json_fname) as infile:
                data = json.load(infile)
    
            # Update the path.
            if not data_key in data:
                raise Exception(
                    "Could not find '%s' key in %s" % (data_key, json_fname))
    
            # The standard validation layer has no library path.
            if 'library_path' in data[data_key]:
                prev_name = os.path.basename(data[data_key]['library_path'])
                data[data_key]['library_path'] = prev_name
    
            target_fname = os.path.join(target_dir, os.path.basename(json_fname))
            with open(target_fname, 'wb') as outfile:
                json.dump(data, outfile)
    
        # Get the Vulkan version from the vulkan_core.h file
        vk_header_filename = args.version_header
        vk_version = None
        with open(vk_header_filename) as vk_header_file:
            for line in vk_header_file:
                if line.startswith('#define VK_HEADER_VERSION'):
                    vk_version = line.split()[-1]
                    break
        if not vk_version:
            print('failed to extract vk_version', file=sys.stderr)
            return 1
    
        # Set json file prefix and suffix for generating files, default to Linux.
        relative_path_prefix = '../lib'
        file_type_suffix = '.so'
        if platform.system() == 'Windows':
            relative_path_prefix = r'..\\'  # json-escaped, hence two backslashes.
            file_type_suffix = '.dll'
    
        # For each *.json.in template files in source dir generate actual json file
        # in target dir
        if (set(glob_slash(os.path.join(source_dir, '*.json.in'))) !=
                set(json_in_files)):
            print('.json.in list in gn file is out-of-date', file=sys.stderr)
            return 1
        for json_in_name in json_in_files:
            if not json_in_name.endswith('.json.in'):
                continue
            json_in_fname = os.path.basename(json_in_name)
            layer_name = json_in_fname[:-len('.json.in')]
            layer_lib_name = layer_name + file_type_suffix
            json_out_fname = os.path.join(target_dir, json_in_fname[:-len('.in')])
            with open(json_out_fname,'w') as json_out_file, \
                 open(json_in_name) as infile:
                for line in infile:
                    line = line.replace('@RELATIVE_LAYER_BINARY@',
                                        relative_path_prefix + layer_lib_name)
                    line = line.replace('@VK_VERSION@', '1.1.' + vk_version)
                    json_out_file.write(line)
    
    if __name__ == '__main__':
        sys.exit(main())