Layers: Implement PV per-API ext dependency checks
authorMark Lobodzinski <mark@lunarg.com>
Wed, 31 May 2017 15:14:22 +0000 (09:14 -0600)
committerMark Lobodzinski <mark@lunarg.com>
Wed, 31 May 2017 20:30:45 +0000 (14:30 -0600)
As each API is used, PV will now us a code-generated check to verify
that all of the required extensions for this particular API call have
been enabled via CreateInstance or CreateDevice.

Change-Id: I1c11d0b8322edf005b2b197a415c92a82e0cb810

layers/parameter_validation.cpp
layers/parameter_validation_utils.h
scripts/parameter_validation_generator.py

index 949d510..b4d23b8 100644 (file)
@@ -117,13 +117,20 @@ 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<std::string> required_extensions) {
+template <typename T>
+bool ValidateRequiredExtensions(const T *layer_data, const std::string &api_name, const std::vector<std::string> &required_extensions) {
     bool skip = false;
+    std::stringstream error_results;
+    auto const &enabled_extensions = layer_data->enabled_extensions;
 
-    for (auto reqd_ext = required_extensions.begin(); reqd_ext != required_extensions.end(); reqd_ext++) {
-        // Insert depency checks here
+    for (const auto &reqd_ext : required_extensions) {
+        if (enabled_extensions.find(reqd_ext) == enabled_extensions.end()) {
+            skip = log_msg(layer_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
+                           __LINE__, EXTENSION_NOT_ENABLED, LayerName,
+                           "Attemped to call %s() but its required extension %s has not been enabled\n", api_name.c_str(),
+                           reqd_ext.c_str());
+        }
     }
-
     return skip;
 }
 
@@ -595,9 +602,12 @@ 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
+            // Save enabled device AND 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->enabled_extensions.emplace(pCreateInfo->ppEnabledExtensionNames[i]);
+            }
+            for (const auto &inst_ext : my_instance_data->enabled_extensions) {
+                my_device_data->enabled_extensions.emplace(inst_ext);
             }
 
             my_device_data->enables.InitFromDeviceCreateInfo(pCreateInfo);
index a0f268b..0d6ec26 100644 (file)
@@ -119,7 +119,9 @@ const uint32_t ExtEnumBaseValue = 1000000000;
 const uint32_t MaxEnumValue = 0x7FFFFFFF;
 
 // Forward declaration
-bool ValidateRequiredExtensions(std::string api_name, const std::vector<std::string> required_extensions);
+template <typename T>
+bool ValidateRequiredExtensions(const T *layer_data, const std::string &api_name,
+                                const std::vector<std::string> &required_extensions);
 
 template <typename T>
 bool is_extension_added_token(T value) {
index 52cedd0..0e276bf 100644 (file)
@@ -1029,7 +1029,7 @@ class ParamCheckerOutputGenerator(OutputGenerator):
                 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
+                ext_call = 'skipCall |= ValidateRequiredExtensions(layer_data, "%s", required_extensions);\n' % command.name
                 lines.insert(0, ext_call)
                 lines.insert(0, def_line)
             if lines: