layers: Finish add support to validation for VK_KHR_display extension

Swapchain, object_tracker and unique_objects now intercept and perform
validation checks for this extension.
Change-Id: I2e78d1dc516103de165ef83b99665eaad05b73d9
diff --git a/layers/object_tracker.h b/layers/object_tracker.h
index ac62f03..a20760f 100644
--- a/layers/object_tracker.h
+++ b/layers/object_tracker.h
@@ -289,9 +289,11 @@
 static void create_device(VkDevice dispatchable_object, VkDevice object, VkDebugReportObjectTypeEXT objType);
 static void create_device(VkPhysicalDevice dispatchable_object, VkDevice object, VkDebugReportObjectTypeEXT objType);
 static void create_queue(VkDevice dispatchable_object, VkQueue vkObj, VkDebugReportObjectTypeEXT objType);
+static void create_display_khr(VkPhysicalDevice dispatchable_object, VkDisplayKHR vkObj, VkDebugReportObjectTypeEXT objType);
 static bool validate_image(VkQueue dispatchable_object, VkImage object, VkDebugReportObjectTypeEXT objType, bool null_allowed);
 static bool validate_instance(VkInstance dispatchable_object, VkInstance object, VkDebugReportObjectTypeEXT objType,
                                   bool null_allowed);
+static bool validate_physical_device(VkPhysicalDevice dispatchable_object, VkPhysicalDevice object, VkDebugReportObjectTypeEXT objType, bool null_allowed);
 static bool validate_device(VkDevice dispatchable_object, VkDevice object, VkDebugReportObjectTypeEXT objType,
                                 bool null_allowed);
 static bool validate_descriptor_pool(VkDevice dispatchable_object, VkDescriptorPool object, VkDebugReportObjectTypeEXT objType,
@@ -1025,6 +1027,27 @@
     return result;
 }
 
+VkResult VKAPI_CALL explicit_GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice, uint32_t planeIndex, uint32_t* pDisplayCount, VkDisplayKHR* pDisplays)
+{
+    bool skipCall = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skipCall |= validate_physical_device(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
+    }
+    if (skipCall)
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    VkResult result = get_dispatch_table(object_tracker_instance_table_map, physicalDevice)->GetDisplayPlaneSupportedDisplaysKHR(physicalDevice, planeIndex, pDisplayCount, pDisplays);
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        if (result == VK_SUCCESS) {
+            for (uint32_t idx=0; idx<*pDisplayCount; ++idx) {
+                create_display_khr(physicalDevice, pDisplays[idx], VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT);
+            }
+        }
+    }
+    return result;
+}
+
 // TODO: Add special case to codegen to cover validating all the pipelines instead of just the first
 VkResult explicit_CreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
                                           const VkGraphicsPipelineCreateInfo *pCreateInfos, const VkAllocationCallbacks *pAllocator,
diff --git a/layers/swapchain.cpp b/layers/swapchain.cpp
index 1488feb..f120c7a 100644
--- a/layers/swapchain.cpp
+++ b/layers/swapchain.cpp
@@ -963,8 +963,6 @@
     return VK_ERROR_VALIDATION_FAILED_EXT;
 }
 
-static uint32_t gDisplayPlanePropertyCount = 0;
-static bool gDisplayPlanePropertyCountInit = false;
 VKAPI_ATTR VkResult VKAPI_CALL 
 GetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayPlanePropertiesKHR *pProperties) {
     VkResult result = VK_SUCCESS;
@@ -1028,7 +1026,7 @@
         skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "pDisplayCount");
     }
 
-    if (!gDisplayPlanePropertyCountInit)
+    if (!pPhysicalDevice->gotDisplayPlanePropertyCount)
     {
         LOG_WARNING(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "planeIndex",
                 SWAPCHAIN_GET_SUPPORTED_DISPLAYS_WITHOUT_QUERY,
@@ -1036,14 +1034,14 @@
                 __FUNCTION__);
     }
 
-    if (gDisplayPlanePropertyCountInit && planeIndex >= gDisplayPlanePropertyCount)
+    if (pPhysicalDevice->gotDisplayPlanePropertyCount && planeIndex >= pPhysicalDevice->gotDisplayPlanePropertyCount)
     {
         skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "planeIndex",
                 SWAPCHAIN_PLANE_INDEX_TOO_LARGE,
                 "%s(): %s must be in the range [0, %d] that was returned by vkGetPhysicalDeviceDisplayPlanePropertiesKHR. Do you have the plane index hardcoded?",
                 __FUNCTION__,
                 "planeIndex",
-                gDisplayPlanePropertyCount - 1);
+                pPhysicalDevice->displayPlanePropertyCount - 1);
     }
     lock.unlock();
 
@@ -1137,7 +1135,7 @@
                               VK_KHR_DISPLAY_EXTENSION_NAME);
     }
 
-    if (!gDisplayPlanePropertyCountInit)
+    if (!pPhysicalDevice->gotDisplayPlanePropertyCount)
     {
         LOG_WARNING(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "planeIndex",
                 SWAPCHAIN_GET_SUPPORTED_DISPLAYS_WITHOUT_QUERY,
@@ -1145,14 +1143,14 @@
                 __FUNCTION__);
     }
 
-    if (gDisplayPlanePropertyCountInit && planeIndex >= gDisplayPlanePropertyCount)
+    if (pPhysicalDevice->gotDisplayPlanePropertyCount && planeIndex >= pPhysicalDevice->displayPlanePropertyCount)
     {
         skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "planeIndex",
                 SWAPCHAIN_PLANE_INDEX_TOO_LARGE,
                 "%s(): %s must be in the range [0, %d] that was returned by vkGetPhysicalDeviceDisplayPlanePropertiesKHR. Do you have the plane index hardcoded?",
                 __FUNCTION__,
                 "planeIndex",
-                gDisplayPlanePropertyCount - 1);
+                pPhysicalDevice->displayPlanePropertyCount - 1);
     }
 
     if (!pCapabilities) {
diff --git a/layers/unique_objects.h b/layers/unique_objects.h
index 5cadf2e..5323006 100644
--- a/layers/unique_objects.h
+++ b/layers/unique_objects.h
@@ -62,6 +62,7 @@
     bool mir_enabled;
     bool android_enabled;
     bool win32_enabled;
+    bool display_enabled;
 };
 
 static std::unordered_map<void *, struct instance_extension_enables> instanceExtMap;
@@ -76,6 +77,7 @@
     VkLayerInstanceDispatchTable *pDisp = get_dispatch_table(unique_objects_instance_table_map, instance);
     PFN_vkGetInstanceProcAddr gpa = pDisp->GetInstanceProcAddr;
 
+    //KHR_surface
     pDisp->DestroySurfaceKHR = (PFN_vkDestroySurfaceKHR)gpa(instance, "vkDestroySurfaceKHR");
     pDisp->GetPhysicalDeviceSurfaceSupportKHR =
         (PFN_vkGetPhysicalDeviceSurfaceSupportKHR)gpa(instance, "vkGetPhysicalDeviceSurfaceSupportKHR");
@@ -85,7 +87,16 @@
         (PFN_vkGetPhysicalDeviceSurfaceFormatsKHR)gpa(instance, "vkGetPhysicalDeviceSurfaceFormatsKHR");
     pDisp->GetPhysicalDeviceSurfacePresentModesKHR =
         (PFN_vkGetPhysicalDeviceSurfacePresentModesKHR)gpa(instance, "vkGetPhysicalDeviceSurfacePresentModesKHR");
+
+    // KHR_display
+    pDisp->GetPhysicalDeviceDisplayPropertiesKHR = (PFN_vkGetPhysicalDeviceDisplayPropertiesKHR)gpa(instance, "vkGetPhysicalDeviceDisplayPropertiesKHR");
+    pDisp->GetPhysicalDeviceDisplayPlanePropertiesKHR = (PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR)gpa(instance, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR");
+    pDisp->GetDisplayPlaneSupportedDisplaysKHR = (PFN_vkGetDisplayPlaneSupportedDisplaysKHR)gpa(instance, "vkGetDisplayPlaneSupportedDisplaysKHR");
+    pDisp->GetDisplayModePropertiesKHR = (PFN_vkGetDisplayModePropertiesKHR)gpa(instance, "vkGetDisplayModePropertiesKHR");
+    pDisp->CreateDisplayModeKHR = (PFN_vkCreateDisplayModeKHR)gpa(instance, "vkCreateDisplayModeKHR");
+    pDisp->GetDisplayPlaneCapabilitiesKHR = (PFN_vkGetDisplayPlaneCapabilitiesKHR)gpa(instance, "vkGetDisplayPlaneCapabilitiesKHR");
     pDisp->CreateDisplayPlaneSurfaceKHR = (PFN_vkCreateDisplayPlaneSurfaceKHR)gpa(instance, "vkCreateDisplayPlaneSurfaceKHR");
+
 #ifdef VK_USE_PLATFORM_WIN32_KHR
     pDisp->CreateWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR)gpa(instance, "vkCreateWin32SurfaceKHR");
     pDisp->GetPhysicalDeviceWin32PresentationSupportKHR =
@@ -120,6 +131,8 @@
     for (i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SURFACE_EXTENSION_NAME) == 0)
             instanceExtMap[pDisp].wsi_enabled = true;
+        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_DISPLAY_EXTENSION_NAME) == 0)
+            instanceExtMap[pDisp].display_enabled = true;
 #ifdef VK_USE_PLATFORM_XLIB_KHR
         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XLIB_SURFACE_EXTENSION_NAME) == 0)
             instanceExtMap[pDisp].xlib_enabled = true;
@@ -179,6 +192,8 @@
     dispatch_key key = get_dispatch_key(instance);
     get_dispatch_table(unique_objects_instance_table_map, instance)->DestroyInstance(instance, pAllocator);
     layer_data_map.erase(key);
+    VkLayerInstanceDispatchTable *pDisp = get_dispatch_table(unique_objects_instance_table_map, instance);
+    instanceExtMap.erase(pDisp);
 }
 
 // Handle CreateDevice
@@ -403,4 +418,21 @@
     return result;
 }
 
+VkResult explicit_GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice, uint32_t planeIndex, uint32_t* pDisplayCount, VkDisplayKHR* pDisplays)
+{
+    layer_data *my_map_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
+    VkResult result = get_dispatch_table(unique_objects_instance_table_map, physicalDevice)->GetDisplayPlaneSupportedDisplaysKHR(physicalDevice, planeIndex, pDisplayCount, pDisplays);
+    if (VK_SUCCESS == result) {
+        if ((*pDisplayCount > 0) && pDisplays) {
+            std::lock_guard<std::mutex> lock(global_lock);
+            uint64_t unique_id;
+            for (uint32_t i = 0; i < *pDisplayCount; i++) {
+                unique_id = global_unique_id++;
+                my_map_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(*pDisplays);
+                pDisplays[i] = reinterpret_cast<VkDisplayKHR&>(unique_id);
+            }
+        }
+    }
+    return result;
+}
 } // namespace unique_objects
diff --git a/vk-layer-generate.py b/vk-layer-generate.py
index 14354df..13a0d1a 100755
--- a/vk-layer-generate.py
+++ b/vk-layer-generate.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3
+#!/usr/bin/env python3
 #
 # VK
 #
@@ -44,7 +44,6 @@
         "EnumerateInstanceExtensionProperties",
         "EnumerateDeviceLayerProperties",
         "EnumerateDeviceExtensionProperties",
-        "CreateDisplayPlaneSurfaceKHR",
         "CreateXcbSurfaceKHR",
         "GetPhysicalDeviceXcbPresentationSupportKHR",
         "CreateXlibSurfaceKHR",
@@ -55,7 +54,14 @@
         "GetPhysicalDeviceMirPresentationSupportKHR",
         "CreateAndroidSurfaceKHR",
         "CreateWin32SurfaceKHR",
-        "GetPhysicalDeviceWin32PresentationSupportKHR"
+        "GetPhysicalDeviceWin32PresentationSupportKHR",
+        "GetPhysicalDeviceDisplayPropertiesKHR",
+        "GetPhysicalDeviceDisplayPlanePropertiesKHR",
+        "GetDisplayPlaneSupportedDisplaysKHR",
+        "GetDisplayModePropertiesKHR",
+        "CreateDisplayModeKHR",
+        "GetDisplayPlaneCapabilitiesKHR",
+        "CreateDisplayPlaneSurfaceKHR"
     ]
     if proto.params[0].ty == "VkInstance" or proto.params[0].ty == "VkPhysicalDevice" or proto.name in global_function_names:
        return True
@@ -806,7 +812,10 @@
         procs_txt = []
         # First parse through funcs and gather dict of all objects seen by each call
         obj_use_dict = {}
-        proto_list = vulkan.core.protos + vulkan.ext_khr_surface.protos + vulkan.ext_khr_surface.protos + vulkan.ext_khr_win32_surface.protos + vulkan.ext_khr_device_swapchain.protos
+        proto_list = []
+        for grp in vulkan.extensions:
+            proto_list += grp.protos
+        #vulkan.core.protos + vulkan.ext_khr_surface.protos + vulkan.ext_khr_surface.protos + vulkan.ext_khr_win32_surface.protos + vulkan.ext_khr_device_swapchain.protos
         for proto in proto_list:
             disp_obj = proto.params[0].ty.strip('*').replace('const ', '')
             if disp_obj in vulkan.object_dispatch_list:
@@ -819,7 +828,7 @@
                     if vk_helper.is_type(base_type, 'struct'):
                         obj_use_dict[disp_obj] = self._gather_object_uses(vulkan.object_type_list, base_type, obj_use_dict[disp_obj])
         #for do in obj_use_dict:
-        #    print "Disp obj %s has uses for objs: %s" % (do, ', '.join(obj_use_dict[do]))
+        #    print("Disp obj %s has uses for objs: %s" % (do, ', '.join(obj_use_dict[do])))
 
         for o in vulkan.object_type_list:# vulkan.core.objects:
             procs_txt.append('%s' % self.lineinfo.get())
@@ -827,6 +836,8 @@
             name = re.sub('([a-z0-9])([A-Z])', r'\1_\2', name).lower()[3:]
             if o in vulkan.object_dispatch_list:
                 procs_txt.append('static void create_%s(%s dispatchable_object, %s vkObj, VkDebugReportObjectTypeEXT objType)' % (name, o, o))
+            elif o in ['VkSurfaceKHR', 'VkDisplayKHR', 'VkDisplayModeKHR']:
+                procs_txt.append('static void create_%s(VkPhysicalDevice dispatchable_object, %s vkObj, VkDebugReportObjectTypeEXT objType)' % (name, o))
             else:
                 procs_txt.append('static void create_%s(VkDevice dispatchable_object, %s vkObj, VkDebugReportObjectTypeEXT objType)' % (name, o))
             procs_txt.append('{')
@@ -848,6 +859,8 @@
             procs_txt.append('%s' % self.lineinfo.get())
             if o in vulkan.object_dispatch_list:
                 procs_txt.append('static void destroy_%s(%s dispatchable_object, %s object)' % (name, o, o))
+            elif o in ['VkSurfaceKHR', 'VkDisplayKHR', 'VkDisplayModeKHR']:
+                procs_txt.append('static void destroy_%s(VkPhysicalDevice dispatchable_object, %s object)' % (name, o))
             else:
                 procs_txt.append('static void destroy_%s(VkDevice dispatchable_object, %s object)' % (name, o))
             procs_txt.append('{')
@@ -1096,8 +1109,11 @@
                 if array != '':
                     idx = 'idx%s' % str(array_index)
                     array_index += 1
+                    deref = ''
+                    if 'p' == array[0]:
+                        deref = '*'
                     pre_code += '%s\n' % self.lineinfo.get()
-                    pre_code += '%sfor (uint32_t %s=0; %s<%s%s; ++%s) {\n' % (indent, idx, idx, prefix, array, idx)
+                    pre_code += '%sfor (uint32_t %s=0; %s<%s%s%s; ++%s) {\n' % (indent, idx, idx, deref, prefix, array, idx)
                     indent += '    '
                     local_prefix = '%s[%s].' % (name, idx)
                 elif ptr_type:
@@ -1157,6 +1173,8 @@
         # Command Buffer Object doesn't follow the rule.
         obj_type_mapping['VkCommandBuffer'] = "VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT"
         obj_type_mapping['VkShaderModule'] = "VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT"
+        obj_type_mapping['VkDisplayKHR'] = "VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT"
+        obj_type_mapping['VkDisplayModeKHR'] = "VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT"
 
         explicit_object_tracker_functions = [
             "CreateInstance",
@@ -1177,7 +1195,8 @@
             "UnmapMemory",
             "FreeMemory",
             "DestroySwapchainKHR",
-            "GetSwapchainImagesKHR"
+            "GetSwapchainImagesKHR",
+            "GetDisplayPlaneSupportedDisplaysKHR"
         ]
         decl = proto.c_func(attr="VKAPI")
         param0_name = proto.params[0].name
@@ -1199,7 +1218,6 @@
                                    'AcquireNextImageKHR' : ['fence', 'semaphore' ],
                                    'UpdateDescriptorSets' : ['pTexelBufferView'],
                                    'CreateSwapchainKHR' : ['oldSwapchain'],
-                                   'CreateDisplayModeKHR': ['pAllocator'],
                                   }
         param_count = 'NONE' # keep track of arrays passed directly into API functions
         for p in proto.params:
@@ -1266,7 +1284,7 @@
                      '}' % (qual, decl, proto.c_call()))
             return "".join(funcs)
         # Temporarily prevent  DestroySurface call from being generated until WSI layer support is fleshed out
-        elif 'DestroyInstance' in proto.name or 'DestroyDevice' in proto.name or 'CreateDisplayModeKHR' in proto.name:
+        elif 'DestroyInstance' in proto.name or 'DestroyDevice' in proto.name:
             return ""
         else:
             if create_func:
@@ -1363,6 +1381,12 @@
                 'vkGetPhysicalDeviceSurfaceCapabilitiesKHR',
                 'vkGetPhysicalDeviceSurfaceFormatsKHR',
                 'vkGetPhysicalDeviceSurfacePresentModesKHR',
+                'vkGetPhysicalDeviceDisplayPropertiesKHR',
+                'vkGetPhysicalDeviceDisplayPlanePropertiesKHR',
+                'vkGetDisplayPlaneSupportedDisplaysKHR',
+                'vkGetDisplayModePropertiesKHR',
+                'vkCreateDisplayModeKHR',
+                'vkGetDisplayPlaneCapabilitiesKHR',
                 'vkCreateDisplayPlaneSurfaceKHR',
                 ]
         if self.wsi == 'Win32':
@@ -1438,13 +1462,17 @@
                         pre_code += '%sif (local_%s) {\n' % (indent, name)
                     indent += '    '
                 if array != '':
+                    if 'p' == array[0] and array[1] != array[1].lower(): # TODO : Not ideal way to determine ptr
+                        count_prefix = '*'
+                    else:
+                        count_prefix = ''
                     idx = 'idx%s' % str(array_index)
                     array_index += 1
                     if first_level_param and name in param_type:
-                        pre_code += '%slocal_%s = new safe_%s[%s];\n' % (indent, name, param_type[name].strip('*'), array)
+                        pre_code += '%slocal_%s = new safe_%s[%s%s];\n' % (indent, name, param_type[name].strip('*'), count_prefix, array)
                         post_code += '    if (local_%s)\n' % (name)
                         post_code += '        delete[] local_%s;\n' % (name)
-                    pre_code += '%sfor (uint32_t %s=0; %s<%s%s; ++%s) {\n' % (indent, idx, idx, prefix, array, idx)
+                    pre_code += '%sfor (uint32_t %s=0; %s<%s%s%s; ++%s) {\n' % (indent, idx, idx, count_prefix, prefix, array, idx)
                     indent += '    '
                     if first_level_param:
                         pre_code += '%slocal_%s[%s].initialize(&%s[%s]);\n' % (indent, name, idx, name, idx)
@@ -1518,14 +1546,15 @@
         decl = proto.c_func(attr="VKAPI")
         # A few API cases that are manual code
         # TODO : Special case Create*Pipelines funcs to handle creating multiple unique objects
-        explicit_object_tracker_functions = ['GetSwapchainImagesKHR',
+        explicit_unique_objects_functions = ['GetSwapchainImagesKHR',
                                              'CreateSwapchainKHR',
                                              'CreateInstance',
                                              'DestroyInstance',
                                              'CreateDevice',
                                              'DestroyDevice',
                                              'CreateComputePipelines',
-                                             'CreateGraphicsPipelines'
+                                             'CreateGraphicsPipelines',
+                                             'GetDisplayPlaneSupportedDisplaysKHR'
                                              ]
         # TODO : This is hacky, need to make this a more general-purpose solution for all layers
         ifdef_dict = {'CreateXcbSurfaceKHR': 'VK_USE_PLATFORM_XCB_KHR',
@@ -1538,7 +1567,7 @@
         # This dict stores array name and size of array
         custom_create_dict = {'pDescriptorSets' : 'pAllocateInfo->descriptorSetCount'}
         pre_call_txt += '%s\n' % (self.lineinfo.get())
-        if proto.name in explicit_object_tracker_functions:
+        if proto.name in explicit_unique_objects_functions:
             funcs.append('%s%s\n'
                      '{\n'
                      '    return explicit_%s;\n'
@@ -1638,7 +1667,11 @@
         call_sig = proto.c_call()
         # Replace default params with any custom local params
         for ld in local_decls:
-            call_sig = call_sig.replace(ld, '(const %s)local_%s' % (local_decls[ld], ld))
+            const_qualifier = ''
+            for p in proto.params:
+                if ld == p.name and 'const' in p.ty:
+                    const_qualifier = 'const'
+            call_sig = call_sig.replace(ld, '(%s %s)local_%s' % (const_qualifier, local_decls[ld], ld))
         if proto_is_global(proto):
             table_type = "instance"
         else:
@@ -1666,27 +1699,35 @@
                      ['vkCreateSwapchainKHR',
                       'vkDestroySwapchainKHR', 'vkGetSwapchainImagesKHR',
                       'vkAcquireNextImageKHR', 'vkQueuePresentKHR'])]
-        additional_instance_extensions = [
+        surface_wsi_instance_exts = [
                       'vkDestroySurfaceKHR',
                       'vkGetPhysicalDeviceSurfaceSupportKHR',
                       'vkGetPhysicalDeviceSurfaceCapabilitiesKHR',
                       'vkGetPhysicalDeviceSurfaceFormatsKHR',
-                      'vkGetPhysicalDeviceSurfacePresentModesKHR',
+                      'vkGetPhysicalDeviceSurfacePresentModesKHR']
+        display_wsi_instance_exts = [
+                      'vkGetPhysicalDeviceDisplayPropertiesKHR',
+                      'vkGetPhysicalDeviceDisplayPlanePropertiesKHR',
+                      'vkGetDisplayPlaneSupportedDisplaysKHR',
+                      'vkGetDisplayModePropertiesKHR',
+                      'vkCreateDisplayModeKHR',
+                      'vkGetDisplayPlaneCapabilitiesKHR',
                       'vkCreateDisplayPlaneSurfaceKHR']
         if self.wsi == 'Win32':
-            instance_extensions=[('wsi_enabled',
-                                  additional_instance_extensions + ['vkCreateWin32SurfaceKHR'])]
+            instance_extensions=[('wsi_enabled', surface_wsi_instance_exts),
+                                 ('display_enabled', display_wsi_instance_exts),
+                                 ('win32_enabled', ['vkCreateWin32SurfaceKHR'])]
         elif self.wsi == 'Android':
-            instance_extensions=[('wsi_enabled',
-                                  additional_instance_extensions + ['vkCreateAndroidSurfaceKHR'])]
+            instance_extensions=[('wsi_enabled', surface_wsi_instance_exts),
+                                 ('display_enabled', display_wsi_instance_exts),
+                                 ('android_enabled', ['vkCreateAndroidSurfaceKHR'])]
         elif self.wsi == 'Xcb' or self.wsi == 'Xlib' or self.wsi == 'Wayland' or self.wsi == 'Mir':
-            instance_extensions=[('wsi_enabled',
-                                  additional_instance_extensions + 
-                                  ['vkCreateXcbSurfaceKHR',
-                                   'vkCreateXlibSurfaceKHR',
-                                   'vkCreateWaylandSurfaceKHR',
-                                   'vkCreateMirSurfaceKHR'
-                                   ])]
+            instance_extensions=[('wsi_enabled', surface_wsi_instance_exts),
+                                 ('display_enabled', display_wsi_instance_exts),
+                                 ('xcb_enabled', ['vkCreateXcbSurfaceKHR']),
+                                 ('xlib_enabled', ['vkCreateXlibSurfaceKHR']),
+                                 ('wayland_enabled',  ['vkCreateWaylandSurfaceKHR']),
+                                 ('mir_enabled', ['vkCreateMirSurfaceKHR'])]
         else:
             print('Error: Undefined DisplayServer')
             instance_extensions=[]
diff --git a/vk_helper.py b/vk_helper.py
index dc49b0f..c55607d 100755
--- a/vk_helper.py
+++ b/vk_helper.py
@@ -1571,6 +1571,9 @@
         for m in self.struct_dict[s]:
             if self.struct_dict[s][m]['ptr']:
                 return True
+        inclusions = ['VkDisplayPlanePropertiesKHR', 'VkDisplayModePropertiesKHR', 'VkDisplayPropertiesKHR']
+        if s in inclusions:
+            return True
         return False
 
     def _generateSafeStructHeader(self):
diff --git a/vulkan.py b/vulkan.py
index 0048cbd..56c18b6 100644
--- a/vulkan.py
+++ b/vulkan.py
@@ -1326,6 +1326,8 @@
     "VkSwapchainKHR",
     "VkSurfaceKHR",
     "VkDebugReportCallbackEXT",
+    "VkDisplayKHR",
+    "VkDisplayModeKHR",
 ]
 
 object_type_list = object_dispatch_list + object_non_dispatch_list