vulkaninfo: Support VK_EXT_surface_maintenance1 properly
authorCharles Giessen <charles@lunarg.com>
Tue, 12 Sep 2023 22:18:02 +0000 (16:18 -0600)
committerCharles Giessen <46324611+charles-lunarg@users.noreply.github.com>
Tue, 12 Sep 2023 23:06:33 +0000 (17:06 -0600)
The struct VkSurfacePresentModeCompatibilityEXT and
VkSurfacePresentScalingCapabilitiesEXT can only be included in the
VkSurfaceCapabilities2KHR pNext chain if a VkSurfacePresentModeEXT struct is
in the pNext chain for VkPhysicalDeviceSurfaceInfo2KHR. In other words, the
autogen for this extension is not adequate and needs to be special cased.

This is doubly true because the aformentioned structs are 'per-present-mode'
so the output needs to handle printing each struct once per present mode
available, which is not possible with autogenerated code currently.

The easiest solution is to just remove the surface_maintenance1 structs from
autogen in the pNext chain (but keep the autogenerated printing functions).
Then setup the pNext chains appropriate and make the necessary calls, before
printing the data directly.

scripts/vulkaninfo_generator.py
vulkaninfo/generated/vulkaninfo.hpp
vulkaninfo/vulkaninfo.cpp
vulkaninfo/vulkaninfo.h

index 6668d04..9d7d683 100644 (file)
@@ -81,7 +81,8 @@ std::string to_hex_str(Printer &p, const T i) {
 
 # used in the .cpp code
 structures_to_gen = ['VkExtent3D', 'VkExtent2D', 'VkPhysicalDeviceLimits', 'VkPhysicalDeviceFeatures', 'VkPhysicalDeviceSparseProperties',
-                     'VkSurfaceCapabilitiesKHR', 'VkSurfaceFormatKHR', 'VkLayerProperties', 'VkPhysicalDeviceToolProperties', 'VkFormatProperties']
+                     'VkSurfaceCapabilitiesKHR', 'VkSurfaceFormatKHR', 'VkLayerProperties', 'VkPhysicalDeviceToolProperties', 'VkFormatProperties',
+                     'VkSurfacePresentScalingCapabilitiesEXT', 'VkSurfacePresentModeCompatibilityEXT']
 enums_to_gen = ['VkResult', 'VkFormat', 'VkPresentModeKHR',
                 'VkPhysicalDeviceType', 'VkImageTiling']
 flags_to_gen = ['VkSurfaceTransformFlagsKHR', 'VkCompositeAlphaFlagsKHR', 'VkSurfaceCounterFlagsEXT', 'VkQueueFlags',
@@ -110,12 +111,37 @@ EXTENSION_TYPE_BOTH = 'both'
 
 # Types that need pNext Chains built. 'extends' is the xml tag used in the structextends member. 'type' can be device, instance, or both
 EXTENSION_CATEGORIES = OrderedDict((
-    ('phys_device_props2', {'extends': 'VkPhysicalDeviceProperties2', 'type': EXTENSION_TYPE_BOTH, 'holder_type': 'VkPhysicalDeviceProperties2', 'print_iterator': True}),
-    ('phys_device_mem_props2', {'extends': 'VkPhysicalDeviceMemoryProperties2', 'type': EXTENSION_TYPE_DEVICE, 'holder_type':'VkPhysicalDeviceMemoryProperties2', 'print_iterator': False}),
-    ('phys_device_features2', {'extends': 'VkPhysicalDeviceFeatures2,VkDeviceCreateInfo', 'type': EXTENSION_TYPE_DEVICE, 'holder_type': 'VkPhysicalDeviceFeatures2', 'print_iterator': True}),
-    ('surface_capabilities2', {'extends': 'VkSurfaceCapabilities2KHR', 'type': EXTENSION_TYPE_BOTH, 'holder_type': 'VkSurfaceCapabilities2KHR', 'print_iterator': True}),
-    ('format_properties2', {'extends': 'VkFormatProperties2', 'type': EXTENSION_TYPE_DEVICE, 'holder_type':'VkFormatProperties2', 'print_iterator': True}),
-    ('queue_properties2', {'extends': 'VkQueueFamilyProperties2', 'type': EXTENSION_TYPE_DEVICE, 'holder_type': 'VkQueueFamilyProperties2', 'print_iterator': True})
+    ('phys_device_props2',
+        {'extends': 'VkPhysicalDeviceProperties2',
+         'type': EXTENSION_TYPE_BOTH,
+         'holder_type': 'VkPhysicalDeviceProperties2',
+         'print_iterator': True}),
+    ('phys_device_mem_props2',
+        {'extends': 'VkPhysicalDeviceMemoryProperties2',
+        'type': EXTENSION_TYPE_DEVICE,
+        'holder_type':'VkPhysicalDeviceMemoryProperties2',
+        'print_iterator': False}),
+    ('phys_device_features2',
+        {'extends': 'VkPhysicalDeviceFeatures2,VkDeviceCreateInfo',
+        'type': EXTENSION_TYPE_DEVICE,
+        'holder_type': 'VkPhysicalDeviceFeatures2',
+        'print_iterator': True}),
+    ('surface_capabilities2',
+        {'extends': 'VkSurfaceCapabilities2KHR',
+        'type': EXTENSION_TYPE_BOTH,
+        'holder_type': 'VkSurfaceCapabilities2KHR',
+        'print_iterator': True,
+        'exclude': ['VkSurfacePresentScalingCapabilitiesEXT', 'VkSurfacePresentModeCompatibilityEXT']}),
+    ('format_properties2',
+        {'extends': 'VkFormatProperties2',
+        'type': EXTENSION_TYPE_DEVICE,
+        'holder_type':'VkFormatProperties2',
+        'print_iterator': True}),
+    ('queue_properties2',
+        {'extends': 'VkQueueFamilyProperties2',
+        'type': EXTENSION_TYPE_DEVICE,
+        'holder_type': 'VkQueueFamilyProperties2',
+        'print_iterator': True})
                                    ))
 class VulkanInfoGeneratorOptions(GeneratorOptions):
     def __init__(self,
@@ -243,9 +269,9 @@ class VulkanInfoGenerator(OutputGenerator):
 
         types_to_gen.update(
             GatherTypesToGen(self.all_structures, structures_to_gen))
-        for key in EXTENSION_CATEGORIES.keys():
+        for key, info in EXTENSION_CATEGORIES.items():
             types_to_gen.update(
-                GatherTypesToGen(self.all_structures, self.extension_sets[key]))
+                GatherTypesToGen(self.all_structures, self.extension_sets[key], info.get('exclude')))
         types_to_gen = sorted(types_to_gen)
 
         names_of_structures_to_gen = set()
@@ -365,10 +391,13 @@ class VulkanInfoGenerator(OutputGenerator):
 
         for key, value in EXTENSION_CATEGORIES.items():
             if str(typeinfo.elem.get('structextends')).find(value.get('extends')) != -1:
-                self.extension_sets[key].add(name)
+                if value.get('exclude') is None or name not in value.get('exclude'):
+                    self.extension_sets[key].add(name)
 
 
-def GatherTypesToGen(structure_list, structures):
+def GatherTypesToGen(structure_list, structures, exclude = []):
+    if exclude == None:
+        exclude = []
     types = set()
     for s in structures:
         types.add(s)
@@ -380,8 +409,9 @@ def GatherTypesToGen(structure_list, structures):
                 for m in s.members:
                     if m.typeID not in predefined_types and m.name not in names_to_ignore:
                         if m.typeID not in types:
-                            types.add(m.typeID)
-                            added_stuff = True
+                            if s.name not in exclude:
+                                types.add(m.typeID)
+                                added_stuff = True
     return types
 
 
index 1e06b76..81c4d74 100644 (file)
@@ -3853,24 +3853,18 @@ struct surface_capabilities2_chain {
 #ifdef VK_USE_PLATFORM_WIN32_KHR
     VkSurfaceCapabilitiesFullScreenExclusiveEXT SurfaceCapabilitiesFullScreenExclusiveEXT{};
 #endif  // VK_USE_PLATFORM_WIN32_KHR
-    VkSurfacePresentModeCompatibilityEXT SurfacePresentModeCompatibilityEXT{};
-    VkSurfacePresentScalingCapabilitiesEXT SurfacePresentScalingCapabilitiesEXT{};
     VkSurfaceProtectedCapabilitiesKHR SurfaceProtectedCapabilitiesKHR{};
     void initialize_chain() noexcept {
         SharedPresentSurfaceCapabilitiesKHR.sType = VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR;
 #ifdef VK_USE_PLATFORM_WIN32_KHR
         SurfaceCapabilitiesFullScreenExclusiveEXT.sType = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_FULL_SCREEN_EXCLUSIVE_EXT;
 #endif  // VK_USE_PLATFORM_WIN32_KHR
-        SurfacePresentModeCompatibilityEXT.sType = VK_STRUCTURE_TYPE_SURFACE_PRESENT_MODE_COMPATIBILITY_EXT;
-        SurfacePresentScalingCapabilitiesEXT.sType = VK_STRUCTURE_TYPE_SURFACE_PRESENT_SCALING_CAPABILITIES_EXT;
         SurfaceProtectedCapabilitiesKHR.sType = VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR;
         std::vector<VkBaseOutStructure*> chain_members;
         chain_members.push_back(reinterpret_cast<VkBaseOutStructure*>(&SharedPresentSurfaceCapabilitiesKHR));
 #ifdef VK_USE_PLATFORM_WIN32_KHR
         chain_members.push_back(reinterpret_cast<VkBaseOutStructure*>(&SurfaceCapabilitiesFullScreenExclusiveEXT));
 #endif  // VK_USE_PLATFORM_WIN32_KHR
-        chain_members.push_back(reinterpret_cast<VkBaseOutStructure*>(&SurfacePresentModeCompatibilityEXT));
-        chain_members.push_back(reinterpret_cast<VkBaseOutStructure*>(&SurfacePresentScalingCapabilitiesEXT));
         chain_members.push_back(reinterpret_cast<VkBaseOutStructure*>(&SurfaceProtectedCapabilitiesKHR));
 
         for(size_t i = 0; i < chain_members.size() - 1; i++){
@@ -5084,18 +5078,6 @@ void chain_iterator_surface_capabilities2(Printer &p, AppInstance &inst, AppGpu
             p.AddNewline();
         }
 #endif  // VK_USE_PLATFORM_WIN32_KHR
-        if (structure->sType == VK_STRUCTURE_TYPE_SURFACE_PRESENT_MODE_COMPATIBILITY_EXT &&
-           (inst.CheckExtensionEnabled(VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME))) {
-            VkSurfacePresentModeCompatibilityEXT* props = (VkSurfacePresentModeCompatibilityEXT*)structure;
-            DumpVkSurfacePresentModeCompatibilityEXT(p, "VkSurfacePresentModeCompatibilityEXT", *props);
-            p.AddNewline();
-        }
-        if (structure->sType == VK_STRUCTURE_TYPE_SURFACE_PRESENT_SCALING_CAPABILITIES_EXT &&
-           (inst.CheckExtensionEnabled(VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME))) {
-            VkSurfacePresentScalingCapabilitiesEXT* props = (VkSurfacePresentScalingCapabilitiesEXT*)structure;
-            DumpVkSurfacePresentScalingCapabilitiesEXT(p, "VkSurfacePresentScalingCapabilitiesEXT", *props);
-            p.AddNewline();
-        }
         if (structure->sType == VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR &&
            (inst.CheckExtensionEnabled(VK_KHR_SURFACE_PROTECTED_CAPABILITIES_EXTENSION_NAME))) {
             VkSurfaceProtectedCapabilitiesKHR* props = (VkSurfaceProtectedCapabilitiesKHR*)structure;
index 0696cff..cad6779 100644 (file)
@@ -155,6 +155,50 @@ void DumpSurfaceCapabilities(Printer &p, AppInstance &inst, AppGpu &gpu, AppSurf
     if (inst.CheckExtensionEnabled(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME)) {
         chain_iterator_surface_capabilities2(p, inst, gpu, surface.surface_capabilities2_khr.pNext);
     }
+    if (inst.CheckExtensionEnabled(VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME)) {
+        p.SetSubHeader();
+        ObjectWrapper obj(p, "VK_EXT_surface_maintenance_1");
+        for (auto &mode : surface.surf_present_modes) {
+            VkSurfacePresentModeEXT present_mode{};
+            present_mode.sType = VK_STRUCTURE_TYPE_SURFACE_PRESENT_MODE_EXT;
+            present_mode.presentMode = mode;
+
+            VkPhysicalDeviceSurfaceInfo2KHR surface_info{};
+            surface_info.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR;
+            surface_info.surface = surface.surface_extension.surface;
+            surface_info.pNext = &present_mode;
+
+            VkSurfacePresentModeCompatibilityEXT SurfacePresentModeCompatibilityEXT{};
+            SurfacePresentModeCompatibilityEXT.sType = VK_STRUCTURE_TYPE_SURFACE_PRESENT_MODE_COMPATIBILITY_EXT;
+
+            VkSurfacePresentScalingCapabilitiesEXT SurfacePresentScalingCapabilitiesEXT{};
+            SurfacePresentScalingCapabilitiesEXT.sType = VK_STRUCTURE_TYPE_SURFACE_PRESENT_SCALING_CAPABILITIES_EXT;
+            SurfacePresentScalingCapabilitiesEXT.pNext = &SurfacePresentModeCompatibilityEXT;
+
+            VkSurfaceCapabilities2KHR surface_caps2{};
+            surface_caps2.sType = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR;
+            surface_caps2.pNext = &SurfacePresentScalingCapabilitiesEXT;
+
+            VkResult err =
+                inst.ext_funcs.vkGetPhysicalDeviceSurfaceCapabilities2KHR(gpu.phys_device, &surface_info, &surface_caps2);
+            if (err != VK_SUCCESS) {
+                continue;
+            }
+
+            std::vector<VkPresentModeKHR> compatible_present_modes{SurfacePresentModeCompatibilityEXT.presentModeCount};
+            SurfacePresentModeCompatibilityEXT.pPresentModes = compatible_present_modes.data();
+
+            err = inst.ext_funcs.vkGetPhysicalDeviceSurfaceCapabilities2KHR(gpu.phys_device, &surface_info, &surface_caps2);
+
+            if (err == VK_SUCCESS) {
+                ObjectWrapper present_mode_obj(p, VkPresentModeKHRString(mode));
+                DumpVkSurfacePresentScalingCapabilitiesEXT(p, "VkSurfacePresentScalingCapabilitiesEXT",
+                                                           SurfacePresentScalingCapabilitiesEXT);
+                DumpVkSurfacePresentModeCompatibilityEXT(p, "VkSurfacePresentModeCompatibilityEXT",
+                                                         SurfacePresentModeCompatibilityEXT);
+            }
+        }
+    }
 }
 
 void DumpSurface(Printer &p, AppInstance &inst, AppGpu &gpu, AppSurface &surface, std::set<std::string> surface_types) {
index 9a2f642..1390863 100644 (file)
@@ -631,8 +631,8 @@ struct AppInstance {
     ANativeWindow *window;
 #endif
 #ifdef VK_USE_PLATFORM_SCREEN_QNX
-    struct _screen_contextcontext;
-    struct _screen_windowwindow;
+    struct _screen_context *context;
+    struct _screen_window *window;
 #endif
     AppInstance() {
         VkResult dllErr = dll.Initialize();
@@ -813,6 +813,9 @@ struct AppInstance {
             if (strcmp(VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME, ext.extensionName) == 0) {
                 inst_extensions.push_back(ext.extensionName);
             }
+            if (strcmp(VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME, ext.extensionName) == 0) {
+                inst_extensions.push_back(ext.extensionName);
+            }
         }
     }
 
@@ -1237,8 +1240,7 @@ static VkSurfaceKHR AppCreateScreenSurface(AppInstance &inst) {
     return surface;
 }
 
-static void AppDestroyScreenWindow(AppInstance &inst)
-{
+static void AppDestroyScreenWindow(AppInstance &inst) {
     screen_destroy_window(inst.window);
     screen_destroy_context(inst.context);
 }