From 8c23ec41e08219c9415bdfa5e1f58f07cbfc95b4 Mon Sep 17 00:00:00 2001 From: Mike Schuchardt Date: Fri, 20 Mar 2026 12:31:55 -0700 Subject: [PATCH] scripts: Fix unused struct members The previous change to completely remove unused struct members from safe_struct doesn't work because the validation layer aliases between raw structs and safe structs, so the layouts have to match. This change keeps the unused members in safe struct but only does shallow copies of unused pointers --- include/vulkan/utility/vk_safe_struct.hpp | 2 ++ scripts/generators/safe_struct_generator.py | 11 +++++------ src/vulkan/vk_safe_struct_core.cpp | 12 ++++++++++++ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/include/vulkan/utility/vk_safe_struct.hpp b/include/vulkan/utility/vk_safe_struct.hpp index 8402a56..af5a1f4 100644 --- a/include/vulkan/utility/vk_safe_struct.hpp +++ b/include/vulkan/utility/vk_safe_struct.hpp @@ -107,6 +107,8 @@ struct safe_VkDeviceCreateInfo { VkDeviceCreateFlags flags; uint32_t queueCreateInfoCount; safe_VkDeviceQueueCreateInfo* pQueueCreateInfos{}; + uint32_t enabledLayerCount; + const char* const* ppEnabledLayerNames{}; uint32_t enabledExtensionCount; const char* const* ppEnabledExtensionNames{}; const VkPhysicalDeviceFeatures* pEnabledFeatures{}; diff --git a/scripts/generators/safe_struct_generator.py b/scripts/generators/safe_struct_generator.py index 69c28b7..10ec800 100644 --- a/scripts/generators/safe_struct_generator.py +++ b/scripts/generators/safe_struct_generator.py @@ -202,8 +202,6 @@ def generateHeader(self): canInitialize = True copy_pnext = ', bool copy_pnext = true' if struct.sType is not None else '' for member in struct.members: - if member.name in self.unused_params.get(struct.name, []): - continue if member.type in self.vk.structs: if self.needSafeStruct(self.vk.structs[member.type]): safe_member_type = self.convertName(member.type) @@ -582,9 +580,10 @@ def qfi_construct(item, member): for member in struct.members: m_type = member.type m_type_safe = False + m_shallow_copy = False - if member.name in self.unused_params.get(struct.name, []): - continue + if member.pointer and ('PFN_' in member.type or member.name in self.unused_params.get(struct.name, [])): + m_shallow_copy = True if member.name == 'pNext': copy_pnext = 'pNext = SafePnextCopy(in_struct->pNext, copy_state);\n' @@ -596,7 +595,7 @@ def qfi_construct(item, member): m_type = self.convertName(member.type) m_type_safe = True; - if member.pointer and not m_type_safe and 'PFN_' not in member.type and not self.typeContainsObjectHandle(member.type, False): + if member.pointer and not m_type_safe and not m_shallow_copy and not self.typeContainsObjectHandle(member.type, False): # Ptr types w/o a safe_struct, for non-null case need to allocate new ptr and copy data in if m_type in ['void', 'char']: if member.name != 'pNext': @@ -703,7 +702,7 @@ def qfi_construct(item, member): construct_txt += f'{member.name}[i] = {array_element};\n' construct_txt += '}\n' construct_txt += '}\n' - elif member.pointer and 'PFN_' not in member.type: + elif member.pointer and not m_shallow_copy: default_init_list += f'\n{member.name}(nullptr),' init_list += f'\n{member.name}(nullptr),' init_func_txt += f'{member.name} = nullptr;\n' diff --git a/src/vulkan/vk_safe_struct_core.cpp b/src/vulkan/vk_safe_struct_core.cpp index 3024378..919deef 100644 --- a/src/vulkan/vk_safe_struct_core.cpp +++ b/src/vulkan/vk_safe_struct_core.cpp @@ -428,6 +428,8 @@ safe_VkDeviceCreateInfo::safe_VkDeviceCreateInfo(const VkDeviceCreateInfo* in_st flags(in_struct->flags), queueCreateInfoCount(in_struct->queueCreateInfoCount), pQueueCreateInfos(nullptr), + enabledLayerCount(in_struct->enabledLayerCount), + ppEnabledLayerNames(in_struct->ppEnabledLayerNames), enabledExtensionCount(in_struct->enabledExtensionCount), pEnabledFeatures(nullptr) { if (copy_pnext) { @@ -456,6 +458,8 @@ safe_VkDeviceCreateInfo::safe_VkDeviceCreateInfo() flags(), queueCreateInfoCount(), pQueueCreateInfos(nullptr), + enabledLayerCount(), + ppEnabledLayerNames(), enabledExtensionCount(), ppEnabledExtensionNames(nullptr), pEnabledFeatures(nullptr) {} @@ -465,6 +469,8 @@ safe_VkDeviceCreateInfo::safe_VkDeviceCreateInfo(const safe_VkDeviceCreateInfo& flags = copy_src.flags; queueCreateInfoCount = copy_src.queueCreateInfoCount; pQueueCreateInfos = nullptr; + enabledLayerCount = copy_src.enabledLayerCount; + ppEnabledLayerNames = copy_src.ppEnabledLayerNames; enabledExtensionCount = copy_src.enabledExtensionCount; pEnabledFeatures = nullptr; pNext = SafePnextCopy(copy_src.pNext); @@ -504,6 +510,8 @@ safe_VkDeviceCreateInfo& safe_VkDeviceCreateInfo::operator=(const safe_VkDeviceC flags = copy_src.flags; queueCreateInfoCount = copy_src.queueCreateInfoCount; pQueueCreateInfos = nullptr; + enabledLayerCount = copy_src.enabledLayerCount; + ppEnabledLayerNames = copy_src.ppEnabledLayerNames; enabledExtensionCount = copy_src.enabledExtensionCount; pEnabledFeatures = nullptr; pNext = SafePnextCopy(copy_src.pNext); @@ -555,6 +563,8 @@ void safe_VkDeviceCreateInfo::initialize(const VkDeviceCreateInfo* in_struct, [[ flags = in_struct->flags; queueCreateInfoCount = in_struct->queueCreateInfoCount; pQueueCreateInfos = nullptr; + enabledLayerCount = in_struct->enabledLayerCount; + ppEnabledLayerNames = in_struct->ppEnabledLayerNames; enabledExtensionCount = in_struct->enabledExtensionCount; pEnabledFeatures = nullptr; pNext = SafePnextCopy(in_struct->pNext, copy_state); @@ -581,6 +591,8 @@ void safe_VkDeviceCreateInfo::initialize(const safe_VkDeviceCreateInfo* copy_src flags = copy_src->flags; queueCreateInfoCount = copy_src->queueCreateInfoCount; pQueueCreateInfos = nullptr; + enabledLayerCount = copy_src->enabledLayerCount; + ppEnabledLayerNames = copy_src->ppEnabledLayerNames; enabledExtensionCount = copy_src->enabledExtensionCount; pEnabledFeatures = nullptr; pNext = SafePnextCopy(copy_src->pNext);