Commit ce0a8f3c by Nico Weber Committed by Commit Bot

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/1358631Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Nico Weber <thakis@chromium.org>
parent 5c317537
#!/usr/bin/python2
#!/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_vulkan_layers_json.py:
# Generate copies of the Vulkan layers JSON files, with no paths, forcing
# Vulkan to use the default search path to look for layers.
import os, sys, json, glob, platform
"""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)]
if len(sys.argv) != 3:
print("Usage: " + sys.argv[0] + " <source_dir> <target_dir>")
sys.exit(1)
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 = sys.argv[1]
target_dir = sys.argv[2]
angle_root_dir = os.path.dirname(sys.path[0])
source_dir = args.source_dir
target_dir = args.target_dir
data_key = 'layer'
if 'icd' in source_dir:
data_key = 'ICD'
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')]
if not os.path.isdir(source_dir):
print(source_dir + " is not a directory.")
sys.exit(1)
data_key = 'ICD' if args.icd else 'layer'
if not os.path.exists(target_dir):
os.makedirs(target_dir)
if not os.path.isdir(source_dir):
print(source_dir + ' is not a directory.', file=sys.stderr)
return 1
# Copy the *.json files from source dir to target dir
for json_fname in glob.glob(os.path.join(source_dir, "*.json")):
with open(json_fname) as infile:
data = json.load(infile)
if not os.path.exists(target_dir):
os.makedirs(target_dir)
# update the path
# 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 '" + data_key + "' key in " + json_fname)
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]:
......@@ -44,34 +69,48 @@ for json_fname in glob.glob(os.path.join(source_dir, "*.json")):
data[data_key]['library_path'] = prev_name
target_fname = os.path.join(target_dir, os.path.basename(json_fname))
with open(target_fname, "w") as outfile:
with open(target_fname, 'wb') as outfile:
json.dump(data, outfile)
# Get the Vulkan version from the vulkan_core.h file
vk_header_filename = os.path.join(angle_root_dir, "third_party", "vulkan-headers", "src", "include", "vulkan", "vulkan_core.h")
vk_version = '83'
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
# Set json file prefix and suffix for generating files below, default to Linux
relative_path_prefix = "../lib"
file_type_suffix = ".so"
if 'Windows' == platform.system():
relative_path_prefix = "..\\\\"
file_type_suffix = ".dll"
# For each *.json.in template files in source dir generate actual json file in target dir
for json_in_name in glob.glob(os.path.join(source_dir, "*.json.in")):
json_in_fname = os.path.basename(json_in_name)
layer_name = json_in_fname[:-8] # Kill ".json.in" from end of filename
layer_lib_name = '%s%s' % (layer_name, file_type_suffix)
json_out_fname = os.path.join(target_dir, json_in_fname[:-3])
with open(json_out_fname,'w') as json_out_file:
with open(json_in_name) as infile:
# 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@', ('%s%s' % (relative_path_prefix, layer_lib_name)))
line = line.replace('@VK_VERSION@', ('1.1.%s' % (vk_version)))
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())
......@@ -7,6 +7,7 @@
# https://github.com/KhronosGroup/Vulkan-Tools
import("../../gni/angle.gni")
import("$angle_root/third_party/vulkan-headers/vulkan_headers_script_deps.gni")
vulkan_undefine_configs = []
......@@ -185,26 +186,25 @@ if (!is_android) {
action("vulkan_gen_icd_json_file") {
script = "$angle_root/scripts/generate_vulkan_layers_json.py"
sources = [
"../vulkan-headers/src/include/vulkan/vulkan_core.h",
]
args = [ "--icd" ]
if (is_win) {
sources = [
"src/icd/windows/VkICD_mock_icd.json",
]
args = [ "$raw_vulkan_icd_dir/icd/windows" ]
sources += [ "src/icd/windows/VkICD_mock_icd.json" ]
args += [ "$raw_vulkan_icd_dir/icd/windows" ]
}
if (is_linux) {
sources = [
"src/icd/linux/VkICD_mock_icd.json",
]
args = [ "$raw_vulkan_icd_dir/icd/linux" ]
sources += [ "src/icd/linux/VkICD_mock_icd.json" ]
args += [ "$raw_vulkan_icd_dir/icd/linux" ]
}
# The layer JSON files are part of the necessary data deps.
outputs = [
"$root_out_dir/$data_dir/VkICD_mock_icd.json",
]
data = [
"$root_out_dir/$data_dir/VkICD_mock_icd.json",
]
args += [ rebase_path("$root_out_dir/$data_dir", root_build_dir) ]
data = outputs
args += [ rebase_path("$root_out_dir/$data_dir", root_build_dir) ] +
rebase_path(sources, root_build_dir)
}
}
......@@ -7,6 +7,7 @@
# https://github.com/KhronosGroup/Vulkan-ValidationLayers
import("../../gni/angle.gni")
import("$angle_root/third_party/vulkan-headers/vulkan_headers_script_deps.gni")
vulkan_undefine_configs = []
......@@ -315,31 +316,32 @@ layers = [
if (!is_android) {
raw_vulkan_layers_dir = rebase_path("src", root_build_dir)
vulkan_gen_json_files_outputs = [
"$root_out_dir/$data_dir/VkLayer_core_validation.json",
"$root_out_dir/$data_dir/VkLayer_object_tracker.json",
"$root_out_dir/$data_dir/VkLayer_parameter_validation.json",
"$root_out_dir/$data_dir/VkLayer_standard_validation.json",
"$root_out_dir/$data_dir/VkLayer_threading.json",
"$root_out_dir/$data_dir/VkLayer_unique_objects.json",
]
action("vulkan_gen_json_files") {
script = "$angle_root/scripts/generate_vulkan_layers_json.py"
json_names = [
"VkLayer_core_validation.json",
"VkLayer_object_tracker.json",
"VkLayer_parameter_validation.json",
"VkLayer_standard_validation.json",
"VkLayer_threading.json",
"VkLayer_unique_objects.json",
]
sources = [
"src/layers/json/VkLayer_core_validation.json.in",
"src/layers/json/VkLayer_object_tracker.json.in",
"src/layers/json/VkLayer_parameter_validation.json.in",
"src/layers/json/VkLayer_standard_validation.json.in",
"src/layers/json/VkLayer_threading.json.in",
"src/layers/json/VkLayer_unique_objects.json.in",
"../vulkan-headers/src/include/vulkan/vulkan_core.h",
]
args = [ "$raw_vulkan_layers_dir/layers/json" ]
outputs = []
foreach(json_name, json_names) {
sources += [ "src/layers/json/$json_name.in" ]
outputs += [ "$root_out_dir/$data_dir/$json_name" ]
}
args = [
"$raw_vulkan_layers_dir/layers/json",
rebase_path("$root_out_dir/$data_dir", root_build_dir),
] + rebase_path(sources, root_build_dir)
# The layer JSON files are part of the necessary data deps.
outputs = vulkan_gen_json_files_outputs
data = vulkan_gen_json_files_outputs
args += [ rebase_path("$root_out_dir/$data_dir", root_build_dir) ]
data = outputs
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment