From 1256d00dbd8a7ce0c8b344e355631e415c683028 Mon Sep 17 00:00:00 2001 From: Mark Lobodzinski Date: Tue, 30 May 2017 12:02:17 -0600 Subject: [PATCH] Layers: Add code-gen'd calls to val exts Modified PV code gen to insert and make calls to validate extension dependencies. Change-Id: I90103b16d36fb868b32df796b1dae7741dfcba34 --- layers/parameter_validation.cpp | 25 ++++++++++++++++++++++++- layers/parameter_validation_utils.h | 3 +++ scripts/parameter_validation_generator.py | 25 ++++++++++++++++++++++++- 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/layers/parameter_validation.cpp b/layers/parameter_validation.cpp index 7070535..7e74d1e 100644 --- a/layers/parameter_validation.cpp +++ b/layers/parameter_validation.cpp @@ -81,7 +81,7 @@ struct instance_layer_data { VkDebugReportCallbackCreateInfoEXT *tmp_dbg_create_infos = nullptr; VkDebugReportCallbackEXT *tmp_callbacks = nullptr; InstanceExtensions extensions = {}; - + std::unordered_set enabled_extensions; VkLayerInstanceDispatchTable dispatch_table = {}; }; @@ -94,6 +94,7 @@ struct layer_data { VkPhysicalDevice physical_device = VK_NULL_HANDLE; VkDevice device = VK_NULL_HANDLE; DeviceExtensions enables; + std::unordered_set enabled_extensions; VkLayerDispatchTable dispatch_table = {}; }; @@ -109,6 +110,8 @@ static void init_parameter_validation(instance_layer_data *my_data, const VkAllo layer_debug_actions(my_data->report_data, my_data->logging_callback, pAllocator, "lunarg_parameter_validation"); } + + VKAPI_ATTR VkResult VKAPI_CALL CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, @@ -144,6 +147,16 @@ static const VkLayerProperties global_layer = { "VK_LAYER_LUNARG_parameter_validation", VK_LAYER_API_VERSION, 1, "LunarG Validation Layer", }; +bool ValidateRequiredExtensions(std::string api_name, const std::vector required_extensions) { + bool skip = false; + + for (auto reqd_ext = required_extensions.begin(); reqd_ext != required_extensions.end(); reqd_ext++) { + // Insert depency checks here + } + + return skip; +} + static const int MaxParamCheckerStringLength = 256; static bool validate_string(debug_report_data *report_data, const char *apiName, const ParameterName &stringName, @@ -248,6 +261,11 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateInstance(const VkInstanceCreateInfo *pCreat auto my_instance_data = GetLayerDataPtr(get_dispatch_key(*pInstance), instance_layer_data_map); assert(my_instance_data != nullptr); + // Save enabled instance extension names for validation extension APIs + for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) { + my_instance_data->enabled_extensions.emplace(pCreateInfo->ppEnabledExtensionNames[i]); + } + layer_init_instance_dispatch_table(*pInstance, &my_instance_data->dispatch_table, fpGetInstanceProcAddr); my_instance_data->instance = *pInstance; my_instance_data->report_data = @@ -607,6 +625,11 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice physicalDevice, con my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice); layer_init_device_dispatch_table(*pDevice, &my_device_data->dispatch_table, fpGetDeviceProcAddr); + // Save enabled instance extension names for validation extension APIs + for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) { + my_instance_data->enabled_extensions.emplace(pCreateInfo->ppEnabledExtensionNames[i]); + } + my_device_data->enables.InitFromDeviceCreateInfo(pCreateInfo); storeCreateDeviceData(*pDevice, pCreateInfo); diff --git a/layers/parameter_validation_utils.h b/layers/parameter_validation_utils.h index d5497cb..791a7a1 100644 --- a/layers/parameter_validation_utils.h +++ b/layers/parameter_validation_utils.h @@ -86,6 +86,9 @@ const uint32_t ExtEnumBaseValue = 1000000000; // The value of all VK_xxx_MAX_ENUM tokens const uint32_t MaxEnumValue = 0x7FFFFFFF; +// Forward declaration +bool ValidateRequiredExtensions(std::string api_name, const std::vector required_extensions); + template bool is_extension_added_token(T value) { return (value != MaxEnumValue) && (static_cast(std::abs(static_cast(value))) >= ExtEnumBaseValue); diff --git a/scripts/parameter_validation_generator.py b/scripts/parameter_validation_generator.py index 1c5a4e4..330e532 100644 --- a/scripts/parameter_validation_generator.py +++ b/scripts/parameter_validation_generator.py @@ -18,6 +18,7 @@ # limitations under the License. # # Author: Dustin Graves +# Author: Mark Lobodzinski import os,re,sys import xml.etree.ElementTree as etree @@ -155,6 +156,7 @@ class ParamCheckerOutputGenerator(OutputGenerator): self.flags = set() # Map of flags typenames self.flagBits = dict() # Map of flag bits typename to list of values self.newFlags = set() # Map of flags typenames /defined in the current feature/ + self.required_extensions = [] # List of required extensions for the current extension # Named tuples to store struct and command data self.StructType = namedtuple('StructType', ['name', 'value']) self.CommandParam = namedtuple('CommandParam', ['type', 'name', 'ispointer', 'isstaticarray', 'isbool', 'israngedenum', @@ -241,6 +243,13 @@ class ParamCheckerOutputGenerator(OutputGenerator): self.commands = [] self.structMembers = [] self.newFlags = set() + # Save list of required extensions for this extension + self.required_extensions = [] + if self.featureName != "VK_VERSION_1_0": + self.required_extensions.append(self.featureName) + required_extensions = interface.get('requires') + if required_extensions is not None: + self.required_extensions.extend(required_extensions.split(',')) def endFeature(self): # C-specific # Actually write the interface to the output file. @@ -631,7 +640,10 @@ class ParamCheckerOutputGenerator(OutputGenerator): # argument is a handle (not vkCreateInstance) reportData = ' debug_report_data*'.ljust(self.genOpts.alignFuncParam) + 'report_data,' if cmd.name != 'vkCreateInstance': - lines[1] = reportData + if len(lines) < 3: # Terminate correctly if single parameter + lines[1] = reportData[:-1] + ')' + else: + lines[1] = reportData else: lines.insert(1, reportData) return '\n'.join(lines) @@ -1010,7 +1022,17 @@ class ParamCheckerOutputGenerator(OutputGenerator): for command in self.commands: # Skip first parameter if it is a dispatch handle (everything except vkCreateInstance) startIndex = 0 if command.name == 'vkCreateInstance' else 1 + if command.name == 'vkCmdDebugMarkerEndEXT': + stop = 'here' lines, unused = self.genFuncBody(command.name, command.params[startIndex:], '', '', None) + if self.required_extensions: + def_line = 'std::vector required_extensions = {' + for ext in self.required_extensions: + def_line += '"%s", ' % ext + def_line = def_line[:-2] + '};' + ext_call = 'skipCall |= ValidateRequiredExtensions("%s", required_extensions);\n' % command.name + lines.insert(0, ext_call) + lines.insert(0, def_line) if lines: cmdDef = self.getCmdDef(command) + '\n' cmdDef += '{\n' @@ -1023,6 +1045,7 @@ class ParamCheckerOutputGenerator(OutputGenerator): if len(unused) > 0: cmdDef += '\n' cmdDef += indent + 'bool skipCall = false;\n' + for line in lines: cmdDef += '\n' if type(line) is list: -- 2.7.4