def main(argv):
    parser = argparse.ArgumentParser(
        description='Generate source code for this repository')
    parser.add_argument('registry',
                        metavar='REGISTRY_PATH',
                        help='path to the Vulkan-Headers registry directory')
    parser.add_argument('grammar',
                        metavar='GRAMMAR_PATH',
                        help='path to the SPIRV-Headers grammar directory')
    group = parser.add_mutually_exclusive_group()
    group.add_argument('-i',
                       '--incremental',
                       action='store_true',
                       help='only update repo files that change')
    group.add_argument('-v',
                       '--verify',
                       action='store_true',
                       help='verify repo files match generator output')
    args = parser.parse_args(argv)

    gen_cmds = [
        *[[
            common_codegen.repo_relative('scripts/lvl_genvk.py'), '-registry',
            os.path.abspath(os.path.join(args.registry, 'vk.xml')), '-grammar',
            os.path.abspath(
                os.path.join(args.grammar, 'spirv.core.grammar.json')),
            '-warnExtensions', 'VK_KHR_dynamic_rendering', '-quiet', filename
        ] for filename in [
            "chassis.cpp", "chassis.h", "chassis_dispatch_helper.h",
            "layer_chassis_dispatch.cpp", "layer_chassis_dispatch.h",
            "object_tracker.cpp", "object_tracker.h",
            "parameter_validation.cpp", "parameter_validation.h",
            "synchronization_validation_types.cpp",
            "synchronization_validation_types.h", "thread_safety.cpp",
            "thread_safety.h", "vk_dispatch_table_helper.h",
            "vk_enum_string_helper.h", "vk_extension_helper.h",
            "vk_layer_dispatch_table.h", "vk_object_types.h",
            "vk_safe_struct.cpp", "vk_safe_struct.h",
            "lvt_function_pointers.cpp", "lvt_function_pointers.h",
            "vk_typemap_helper.h", "best_practices.h", "best_practices.cpp",
            "spirv_validation_helper.cpp", "spirv_grammar_helper.cpp",
            "spirv_grammar_helper.h", "command_validation.cpp",
            "command_validation.h", "corechecks_optick_instrumentation.cpp",
            "corechecks_optick_instrumentation.h"
        ]],
        [
            common_codegen.repo_relative('scripts/vk_validation_stats.py'),
            os.path.abspath(os.path.join(args.registry, 'validusage.json')),
            '-export_header'
        ],
        [
            common_codegen.repo_relative(
                'scripts/external_revision_generator.py'), '--json_file',
            common_codegen.repo_relative('scripts/known_good.json'),
            '--json_keys', 'repos,3,commit', '-s', 'SPIRV_TOOLS_COMMIT_ID',
            '-o', 'spirv_tools_commit_id.h'
        ]
    ]

    repo_dir = common_codegen.repo_relative('layers/generated')

    # get directory where generators will run
    if args.verify or args.incremental:
        # generate in temp directory so we can compare or copy later
        temp_obj = tempfile.TemporaryDirectory(
            prefix='VulkanVL_generated_source_')
        temp_dir = temp_obj.name
        gen_dir = temp_dir
    else:
        # generate directly in the repo
        gen_dir = repo_dir

    # run each code generator
    for cmd in gen_cmds:
        print(' '.join(cmd))
        try:
            subprocess.check_call([sys.executable] + cmd, cwd=gen_dir)
        except Exception as e:
            print('ERROR:', str(e))
            return 1

    # optional post-generation steps
    if args.verify:
        # compare contents of temp dir and repo
        temp_files = set(os.listdir(temp_dir))
        repo_files = set(os.listdir(repo_dir))
        files_match = True
        for filename in sorted((temp_files | repo_files) -
                               set(verify_exclude)):
            temp_filename = os.path.join(temp_dir, filename)
            repo_filename = os.path.join(repo_dir, filename)
            if filename not in repo_files:
                print('ERROR: Missing repo file', filename)
                files_match = False
            elif filename not in temp_files:
                print('ERROR: Missing generator for', filename)
                files_match = False
            elif not filecmp.cmp(temp_filename, repo_filename, shallow=False):
                print('ERROR: Repo files do not match generator output for',
                      filename)
                files_match = False
                # print line diff on file mismatch
                with open(temp_filename) as temp_file, open(
                        repo_filename) as repo_file:
                    print(''.join(
                        difflib.unified_diff(temp_file.readlines(),
                                             repo_file.readlines(),
                                             fromfile='temp/' + filename,
                                             tofile='repo/' + filename)))

        # return code for test scripts
        if files_match:
            print('SUCCESS: Repo files match generator output')
            return 0
        return 1

    elif args.incremental:
        # copy missing or differing files from temp directory to repo
        for filename in os.listdir(temp_dir):
            temp_filename = os.path.join(temp_dir, filename)
            repo_filename = os.path.join(repo_dir, filename)
            if not os.path.exists(repo_filename) or \
               not filecmp.cmp(temp_filename, repo_filename, shallow=False):
                print('update', repo_filename)
                shutil.copyfile(temp_filename, repo_filename)

    return 0
Ejemplo n.º 2
0
verbose_mode = False
txt_db = False
csv_db = False
html_db = False
txt_filename = "validation_error_database.txt"
csv_filename = "validation_error_database.csv"
html_filename = "validation_error_database.html"
header_filename = "vk_validation_error_messages.h"
vuid_prefixes = ['VUID-', 'UNASSIGNED-', 'kVUID_']

# Hard-coded flags that could be command line args, if we decide that's useful
ignore_unassigned = True  # These are not found in layer code unless they appear explicitly (most don't), so produce false positives

layer_source_files = [
    common_codegen.repo_relative(path) for path in [
        'layers/buffer_validation.cpp',
        'layers/core_validation.cpp',
        'layers/descriptor_sets.cpp',
        'layers/drawdispatch.cpp',
        'layers/parameter_validation_utils.cpp',
        'layers/object_tracker_utils.cpp',
        'layers/shader_validation.cpp',
        'layers/stateless_validation.h',
        'layers/generated/parameter_validation.cpp',
        'layers/generated/object_tracker.cpp',
    ]
]

test_source_files = glob.glob(
    os.path.join(common_codegen.repo_relative('tests'), '*.cpp'))
verbose_mode = False
txt_db = False
csv_db = False
html_db = False
txt_filename = "validation_error_database.txt"
csv_filename = "validation_error_database.csv"
html_filename = "validation_error_database.html"
header_filename = "vk_validation_error_messages.h"
vuid_prefixes = ['VUID-', 'UNASSIGNED-', 'kVUID_']
spirvtools_path = None # default is to not search for repo

# Hard-coded flags that could be command line args, if we decide that's useful
ignore_unassigned = True # These are not found in layer code unless they appear explicitly (most don't), so produce false positives

layer_source_files = [common_codegen.repo_relative(path) for path in [
    'layers/buffer_validation.cpp',
    'layers/core_validation.cpp',
    'layers/descriptor_sets.cpp',
    'layers/drawdispatch.cpp',
    'layers/parameter_validation_utils.cpp',
    'layers/object_tracker_utils.cpp',
    'layers/shader_validation.cpp',
    'layers/stateless_validation.h',
    'layers/generated/parameter_validation.cpp',
    'layers/generated/object_tracker.cpp',
    'layers/generated/spirv_validation_helper.cpp',
]]

test_source_files = glob.glob(os.path.join(common_codegen.repo_relative('tests'), '*.cpp'))
Ejemplo n.º 4
0
def main(argv):
    parser = argparse.ArgumentParser(
        description='Generate source code for this repository')
    parser.add_argument('registry',
                        metavar='REGISTRY_PATH',
                        help='path to the Vulkan-Headers registry directory')
    group = parser.add_mutually_exclusive_group()
    group.add_argument('-i',
                       '--incremental',
                       action='store_true',
                       help='only update repo files that change')
    group.add_argument('-v',
                       '--verify',
                       action='store_true',
                       help='verify repo files match generator output')
    args = parser.parse_args(argv)

    gen_cmds = [[
        common_codegen.repo_relative('scripts/loader_genvk.py'), '-registry',
        os.path.abspath(os.path.join(args.registry, 'vk.xml')), '-quiet',
        filename
    ] for filename in [
        'vk_dispatch_table_helper.h', 'vk_layer_dispatch_table.h',
        'vk_loader_extensions.h', 'vk_loader_extensions.c',
        'vk_object_types.h', 'loader_generated_header_version.cmake'
    ]]

    repo_dir = common_codegen.repo_relative('loader/generated')

    # get directory where generators will run
    if args.verify or args.incremental:
        # generate in temp directory so we can compare or copy later
        temp_obj = tempfile.TemporaryDirectory(
            prefix='VulkanLoader_generated_source_')
        temp_dir = temp_obj.name
        gen_dir = temp_dir
    else:
        # generate directly in the repo
        gen_dir = repo_dir

    # run each code generator
    for cmd in gen_cmds:
        print(' '.join(cmd))
        try:
            subprocess.check_call(
                [sys.executable] + cmd,
                # ignore generator output, vk_validation_stats.py is especially noisy
                stdout=subprocess.DEVNULL,
                cwd=gen_dir)
        except Exception as e:
            print('ERROR:', str(e))
            return 1

    # optional post-generation steps
    if args.verify:
        # compare contents of temp dir and repo
        temp_files = set(os.listdir(temp_dir))
        repo_files = set(os.listdir(repo_dir))
        files_match = True
        for filename in sorted((temp_files | repo_files) -
                               set(verify_exclude)):
            if filename not in repo_files:
                print('ERROR: Missing repo file', filename)
                files_match = False
            elif filename not in temp_files:
                print('ERROR: Missing generator for', filename)
                files_match = False
            elif not filecmp.cmp(os.path.join(temp_dir, filename),
                                 os.path.join(repo_dir, filename),
                                 shallow=False):
                print('ERROR: Repo files do not match generator output for',
                      filename)
                files_match = False

        # return code for test scripts
        if files_match:
            print('SUCCESS: Repo files match generator output')
            return 0
        return 1

    elif args.incremental:
        # copy missing or differing files from temp directory to repo
        for filename in os.listdir(temp_dir):
            temp_filename = os.path.join(temp_dir, filename)
            repo_filename = os.path.join(repo_dir, filename)
            if not os.path.exists(repo_filename) or \
               not filecmp.cmp(temp_filename, repo_filename, shallow=False):
                print('update', repo_filename)
                shutil.copyfile(temp_filename, repo_filename)

    return 0
Ejemplo n.º 5
0
def main(argv):
    parser = argparse.ArgumentParser(
        description='Generate source code for this repository')
    parser.add_argument('registry',
                        metavar='REGISTRY_PATH',
                        help='path to the Vulkan-Headers registry directory')
    group = parser.add_mutually_exclusive_group()
    group.add_argument('-i',
                       '--incremental',
                       action='store_true',
                       help='only update repo files that change')
    group.add_argument('-v',
                       '--verify',
                       action='store_true',
                       help='verify repo files match generator output')
    args = parser.parse_args(argv)

    gen_cmds = [
        *[[
            common_codegen.repo_relative('scripts/lvl_genvk.py'), '-registry',
            os.path.abspath(os.path.join(args.registry, 'vk.xml')), '-quiet',
            '-removeExtensions', 'VK_HUAWEI_subpass_shading', filename
        ] for filename in [
            "vk_safe_struct.cpp", "vk_safe_struct.h",
            "lvt_function_pointers.cpp", "lvt_function_pointers.h",
            "vk_typemap_helper.h"
        ]]
    ]

    repo_dir = common_codegen.repo_relative('utils/generated')

    # get directory where generators will run
    if args.verify or args.incremental:
        # generate in temp directory so we can compare or copy later
        temp_obj = tempfile.TemporaryDirectory(
            prefix='VulkanVL_generated_source_')
        temp_dir = temp_obj.name
        gen_dir = temp_dir
    else:
        # generate directly in the repo
        gen_dir = repo_dir

    # run each code generator
    for cmd in gen_cmds:
        print(' '.join(cmd))
        try:
            subprocess.check_call([sys.executable] + cmd, cwd=gen_dir)
        except Exception as e:
            print('ERROR:', str(e))
            return 1

    # optional post-generation steps
    if args.verify:
        # compare contents of temp dir and repo
        temp_files = set(os.listdir(temp_dir))
        repo_files = set(os.listdir(repo_dir))
        files_match = True
        for filename in sorted((temp_files | repo_files) -
                               set(verify_exclude)):
            temp_filename = os.path.join(temp_dir, filename)
            repo_filename = os.path.join(repo_dir, filename)
            if filename not in repo_files:
                print('ERROR: Missing repo file', filename)
                files_match = False
            elif filename not in temp_files:
                print('ERROR: Missing generator for', filename)
                files_match = False
            elif not filecmp.cmp(temp_filename, repo_filename, shallow=False):
                print('ERROR: Repo files do not match generator output for',
                      filename)
                files_match = False
                # print line diff on file mismatch
                with open(temp_filename) as temp_file, open(
                        repo_filename) as repo_file:
                    print(''.join(
                        difflib.unified_diff(temp_file.readlines(),
                                             repo_file.readlines(),
                                             fromfile='temp/' + filename,
                                             tofile='repo/' + filename)))

        # return code for test scripts
        if files_match:
            print('SUCCESS: Repo files match generator output')
            return 0
        return 1

    elif args.incremental:
        # copy missing or differing files from temp directory to repo
        for filename in os.listdir(temp_dir):
            temp_filename = os.path.join(temp_dir, filename)
            repo_filename = os.path.join(repo_dir, filename)
            if not os.path.exists(repo_filename) or \
               not filecmp.cmp(temp_filename, repo_filename, shallow=False):
                print('update', repo_filename)
                shutil.copyfile(temp_filename, repo_filename)

    return 0
Ejemplo n.º 6
0
def main(argv):
    parser = argparse.ArgumentParser(
        description='Generate source code for this repository')
    parser.add_argument('registry',
                        metavar='REGISTRY_PATH',
                        help='path to the Vulkan-Headers registry directory')
    group = parser.add_mutually_exclusive_group()
    group.add_argument('-i',
                       '--incremental',
                       action='store_true',
                       help='only update repo files that change')
    group.add_argument('-v',
                       '--verify',
                       action='store_true',
                       help='verify repo files match generator output')
    args = parser.parse_args(argv)

    # output paths and the list of files in the path
    files_to_gen = {
        str(os.path.join('icd', 'generated')):
        ['vk_typemap_helper.h', 'mock_icd.h', 'mock_icd.cpp'],
        str(os.path.join('vulkaninfo', 'generated')): ['vulkaninfo.hpp']
    }

    #base directory for the source repository
    repo_dir = common_codegen.repo_relative('')

    # get directory where generators will run if needed
    if args.verify or args.incremental:
        # generate in temp directory so we can compare or copy later
        temp_obj = tempfile.TemporaryDirectory(
            prefix='VulkanLoader_generated_source_')
        temp_dir = temp_obj.name
        for path in files_to_gen.keys():
            os.makedirs(os.path.join(temp_dir, path))

    # run each code generator
    for path, filenames in files_to_gen.items():
        for filename in filenames:
            if args.verify or args.incremental:
                output_path = os.path.join(temp_dir, path)
            else:
                output_path = common_codegen.repo_relative(path)

            cmd = [
                common_codegen.repo_relative(
                    os.path.join('scripts', 'kvt_genvk.py')), '-registry',
                os.path.abspath(os.path.join(args.registry, 'vk.xml')),
                '-quiet', '-directory', output_path, filename
            ]
            print(' '.join(cmd))
            try:
                if args.verify or args.incremental:
                    subprocess.check_call([sys.executable] + cmd, cwd=temp_dir)
                else:
                    subprocess.check_call([sys.executable] + cmd, cwd=repo_dir)

            except Exception as e:
                print('ERROR:', str(e))
                return 1

    # optional post-generation steps
    if args.verify:
        # compare contents of temp dir and repo
        temp_files = {}
        for path in files_to_gen.keys():
            temp_files[path] = set()
            temp_files[path].update(
                set(os.listdir(os.path.join(temp_dir, path))))

        repo_files = {}
        for path in files_to_gen.keys():
            repo_files[path] = set()
            repo_files[path].update(
                set(os.listdir(os.path.join(repo_dir, path))) -
                set(verify_exclude))

        files_match = True
        for path in files_to_gen.keys():
            for filename in sorted((temp_files[path] | repo_files[path])):
                if filename not in repo_files[path]:
                    print('ERROR: Missing repo file', filename)
                    files_match = False
                elif filename not in temp_files[path]:
                    print('ERROR: Missing generator for', filename)
                    files_match = False
                elif not filecmp.cmp(os.path.join(temp_dir, path, filename),
                                     os.path.join(repo_dir, path, filename),
                                     shallow=False):
                    print(
                        'ERROR: Repo files do not match generator output for',
                        filename)
                    files_match = False

        # return code for test scripts
        if files_match:
            print('SUCCESS: Repo files match generator output')
            return 0
        return 1

    elif args.incremental:
        # copy missing or differing files from temp directory to repo
        for path in files_to_gen.keys():
            for filename in os.listdir(os.path.join(temp_dir, path)):
                temp_filename = os.path.join(temp_dir, path, filename)
                repo_filename = os.path.join(repo_dir, path, filename)
                if not os.path.exists(repo_filename) or \
                   not filecmp.cmp(temp_filename, repo_filename, shallow=False):
                    print('update', repo_filename)
                    shutil.copyfile(temp_filename, repo_filename)

    return 0