| #!/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) |