blob: c09171c9fae9fc38d83405ce3b7f0843381939b8 [file] [log] [blame]
#!/usr/bin/env python3
#
# Copyright (c) 2025 Valve Corporation
# Copyright (c) 2025 LunarG, Inc.
#
# 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.
#
# Take the JSON with our settings and generates the other setting related files
# See docs/settings.md
import common_ci
import json
import os
def IsDebugSetting(setting):
if setting['key'] == 'debug_action':
return False
return 'debug' in setting['key']
def GenerateTextFile(all_settings):
out = []
out.append(f'''# The settings in this file can be used to configure the behavior of layers in this repository.
# This file doesn't display the dependencies on the various settings
#
# This file is generated by {os.path.basename(__file__)}
# VK_LAYER_KHRONOS_validation
''')
for setting in all_settings:
if IsDebugSetting(setting):
continue
if 'view' in setting and setting['view'] == 'HIDDEN':
continue
default = setting['default']
type = setting['type']
if type == 'BOOL':
default = 'true' if setting['default'] is True else 'false'
if type == 'FLAGS' or type == 'LIST':
default = ','.join(default)
default = str(default)
if default:
default = " " + default
out.append(f'# {setting["label"]}')
out.append('# =====================')
out.append(f'# {setting["description"]}')
out.append(f'khronos_validation.{setting["key"]} ={default}\n')
text_output = common_ci.RepoRelative('layers/vk_layer_settings.txt')
with open(text_output, 'w') as file:
file.write('\n'.join(out))
def GenerateValidation(all_settings):
out = []
out.append(f'''// *** THIS FILE IS GENERATED - DO NOT EDIT ***
// See {os.path.basename(__file__)} for modifications
/***************************************************************************
*
* Copyright (c) 2025 Valve Corporation
* Copyright (c) 2025 LunarG, Inc.
*
* 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.
*/''')
out.append('''
#pragma once
// clang-format off
// This function is generated from scripts/generate_settings.py
static void ValidateLayerSettingsProvided(const VkLayerSettingsCreateInfoEXT &layer_setting_create_info,
std::vector<std::string> &setting_warnings) {
// Found that a set of <const char*> doesn't detect duplicates on all compilers
vvl::unordered_set<std::string> used_settings;
for (uint32_t i = 0; i < layer_setting_create_info.settingCount; i++) {
const VkLayerSettingEXT &setting = layer_setting_create_info.pSettings[i];
if (strcmp(OBJECT_LAYER_NAME, setting.pLayerName) != 0) {
continue;
}
// used as a backup for settings not listed below
VkLayerSettingTypeEXT required_type = VK_LAYER_SETTING_TYPE_MAX_ENUM_EXT;
// Debugging settings are not added here as those are for internal development
// and not designed for an app to use via VkLayerSettings API
const char* name = setting.pSettingName;
if (strcmp(VK_LAYER_ENABLES, name) == 0) { required_type = VK_LAYER_SETTING_TYPE_STRING_EXT; }
else if (strcmp(VK_LAYER_DISABLES, name) == 0) { required_type = VK_LAYER_SETTING_TYPE_STRING_EXT; }''')
for setting in all_settings:
if IsDebugSetting(setting):
continue
if 'view' in setting and setting['view'] == 'HIDDEN':
continue
type = setting['type']
layer_type = None
if type == 'BOOL':
layer_type = 'VK_LAYER_SETTING_TYPE_BOOL32_EXT'
elif type == 'INT':
layer_type = 'VK_LAYER_SETTING_TYPE_UINT32_EXT'
elif type in ['SAVE_FILE', 'LIST', 'FLAGS']:
layer_type = 'VK_LAYER_SETTING_TYPE_STRING_EXT'
else:
print(f'Warning, not type handled for {type} ({setting["key"]})')
continue
out.append(f' else if (strcmp(VK_LAYER_{setting["key"].upper()}, name) == 0) {{ required_type = {layer_type}; }}')
out.append(''' else {
setting_warnings.emplace_back("The setting \\"" + std::string(name) +
"\\" in VkLayerSettingsCreateInfoEXT was not recognized by the Validation Layers. Please "
"view the VkLayer_khronos_validation.json for a list of all settings.");
}
if (required_type != VK_LAYER_SETTING_TYPE_MAX_ENUM_EXT && setting.type != required_type) {
setting_warnings.emplace_back(
"The setting \\"" + std::string(name) + "\\" in VkLayerSettingsCreateInfoEXT was set to type " +
std::string(string_VkLayerSettingTypeEXT(setting.type)) + " but requires type " +
std::string(string_VkLayerSettingTypeEXT(required_type)) + " and the value may be parsed incorrectly.");
}
if (used_settings.count(name)) {
setting_warnings.emplace_back(
"The setting \\"" + std::string(name) +
"\\" in VkLayerSettingsCreateInfoEXT was listed twice and only the first one listed will be recognized.");
}
used_settings.insert(name);
}
}
// clang-format on
''')
text_output = common_ci.RepoRelative('layers/layer_options_validation.h')
with open(text_output, 'w') as file:
file.write('\n'.join(out))
if __name__ == '__main__':
json_input = common_ci.RepoRelative('layers/VkLayer_khronos_validation.json.in')
with open(json_input, 'r') as file:
json_settings = json.load(file)['layer']['features']['settings']
# Build up the list all at once into a flat list
all_settings = []
def Parse(setting):
type = setting['type']
if type == 'GROUP':
for s in setting['settings']:
Parse(s)
return
if type == 'FLAGS':
for flags in setting['flags']:
if 'settings' in flags:
for s in flags['settings']:
Parse(s)
if 'settings' in setting:
for s in setting['settings']:
Parse(s)
all_settings.append(setting)
for setting in json_settings:
Parse(setting)
# Same on all OS (and easy to find setting in large generated list)
all_settings = sorted(all_settings, key=lambda obj: obj['key'])
GenerateTextFile(all_settings)
GenerateValidation(all_settings)