From dd9d8fe791e3d33e4a791467b9e5bdca2e1a80c3 Mon Sep 17 00:00:00 2001 From: Abdelrahman Date: Mon, 25 May 2026 22:51:00 +0100 Subject: [PATCH] Add Vulkan profiles --- profiles/how_to_vulkan.json | 185 ++ vulkan_profiles/vulkan_profiles.cpp | 4393 ++++++++++++++++++++++++ vulkan_profiles/vulkan_profiles.h | 433 +++ vulkan_profiles/vulkan_profiles.hpp | 4794 +++++++++++++++++++++++++++ 4 files changed, 9805 insertions(+) create mode 100644 profiles/how_to_vulkan.json create mode 100644 vulkan_profiles/vulkan_profiles.cpp create mode 100644 vulkan_profiles/vulkan_profiles.h create mode 100644 vulkan_profiles/vulkan_profiles.hpp diff --git a/profiles/how_to_vulkan.json b/profiles/how_to_vulkan.json new file mode 100644 index 0000000..7e92b2e --- /dev/null +++ b/profiles/how_to_vulkan.json @@ -0,0 +1,185 @@ +{ + "$schema": "https://schema.khronos.org/vulkan/profiles-0.8-latest.json#", + "capabilities": { + "VP_LEARN_how_to_vulkan_2026_block": { + "extensions": { + "VK_KHR_global_priority": 1, + "VK_KHR_get_surface_capabilities2": 1, + "VK_KHR_swapchain": 70 + }, + "features": { + "VkPhysicalDeviceFeatures": { + "robustBufferAccess": true, + "fullDrawIndexUint32": true, + "imageCubeArray": true, + "independentBlend": true, + "sampleRateShading": true, + "drawIndirectFirstInstance": true, + "depthClamp": true, + "depthBiasClamp": true, + "samplerAnisotropy": true, + "occlusionQueryPrecise": true, + "fragmentStoresAndAtomics": true, + "shaderStorageImageExtendedFormats": true, + "shaderUniformBufferArrayDynamicIndexing": true, + "shaderSampledImageArrayDynamicIndexing": true, + "shaderStorageBufferArrayDynamicIndexing": true, + "shaderStorageImageArrayDynamicIndexing": true + }, + "VkPhysicalDeviceVulkan11Features": { + "multiview": true, + "samplerYcbcrConversion": true + }, + "VkPhysicalDeviceVulkan12Features": { + "uniformBufferStandardLayout": true, + "subgroupBroadcastDynamicId": true, + "imagelessFramebuffer": true, + "separateDepthStencilLayouts": true, + "hostQueryReset": true, + "timelineSemaphore": true, + "shaderSubgroupExtendedTypes": true, + "samplerMirrorClampToEdge": true, + "descriptorIndexing": true, + "shaderUniformTexelBufferArrayDynamicIndexing": true, + "shaderStorageTexelBufferArrayDynamicIndexing": true, + "shaderUniformBufferArrayNonUniformIndexing": true, + "shaderSampledImageArrayNonUniformIndexing": true, + "shaderStorageBufferArrayNonUniformIndexing": true, + "shaderStorageImageArrayNonUniformIndexing": true, + "shaderUniformTexelBufferArrayNonUniformIndexing": true, + "shaderStorageTexelBufferArrayNonUniformIndexing": true, + "descriptorBindingSampledImageUpdateAfterBind": true, + "descriptorBindingStorageImageUpdateAfterBind": true, + "descriptorBindingStorageBufferUpdateAfterBind": true, + "descriptorBindingUniformTexelBufferUpdateAfterBind": true, + "descriptorBindingStorageTexelBufferUpdateAfterBind": true, + "descriptorBindingUpdateUnusedWhilePending": true, + "descriptorBindingPartiallyBound": true, + "descriptorBindingVariableDescriptorCount": true, + "runtimeDescriptorArray": true, + "scalarBlockLayout": true, + "vulkanMemoryModel": true, + "vulkanMemoryModelDeviceScope": true, + "bufferDeviceAddress": true + }, + "VkPhysicalDeviceVulkan13Features": { + "robustImageAccess": true, + "shaderTerminateInvocation": true, + "shaderZeroInitializeWorkgroupMemory": true, + "synchronization2": true, + "shaderIntegerDotProduct": true, + "maintenance4": true, + "pipelineCreationCacheControl": true, + "subgroupSizeControl": true, + "computeFullSubgroups": true, + "shaderDemoteToHelperInvocation": true, + "inlineUniformBlock": true, + "dynamicRendering": true, + "descriptorBindingInlineUniformBlockUpdateAfterBind": true + } + }, + "properties": { + "VkPhysicalDeviceProperties": { + "limits": { + "maxImageDimension1D": 8192, + "maxImageDimension2D": 8192, + "maxImageDimensionCube": 8192, + "maxImageArrayLayers": 2048, + "maxUniformBufferRange": 65536, + "bufferImageGranularity": 4096, + "maxPerStageDescriptorSamplers": 64, + "maxPerStageDescriptorUniformBuffers": 15, + "maxPerStageDescriptorStorageBuffers": 30, + "maxPerStageDescriptorSampledImages": 200, + "maxPerStageDescriptorStorageImages": 16, + "maxPerStageResources": 200, + "maxDescriptorSetSamplers": 576, + "maxDescriptorSetUniformBuffers": 90, + "maxDescriptorSetStorageBuffers": 96, + "maxDescriptorSetSampledImages": 1800, + "maxDescriptorSetStorageImages": 144, + "maxFragmentCombinedOutputResources": 16, + "maxComputeWorkGroupInvocations": 256, + "maxComputeWorkGroupSize": [ + 256, + 256, + 64 + ], + "subTexelPrecisionBits": 8, + "mipmapPrecisionBits": 6, + "maxSamplerLodBias": 14, + "standardSampleLocations": true, + "maxColorAttachments": 7 + } + }, + "VkPhysicalDeviceVulkan11Properties": { + "maxMultiviewViewCount": 6, + "maxMultiviewInstanceIndex": 134217727, + "subgroupSize": 4, + "subgroupSupportedStages": [ + "VK_SHADER_STAGE_COMPUTE_BIT", + "VK_SHADER_STAGE_FRAGMENT_BIT" + ], + "subgroupSupportedOperations": [ + "VK_SUBGROUP_FEATURE_BASIC_BIT", + "VK_SUBGROUP_FEATURE_VOTE_BIT", + "VK_SUBGROUP_FEATURE_ARITHMETIC_BIT", + "VK_SUBGROUP_FEATURE_BALLOT_BIT", + "VK_SUBGROUP_FEATURE_SHUFFLE_BIT", + "VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT", + "VK_SUBGROUP_FEATURE_QUAD_BIT" + ] + }, + "VkPhysicalDeviceVulkan12Properties": { + "maxTimelineSemaphoreValueDifference": 2147483647, + "shaderSignedZeroInfNanPreserveFloat16": true, + "shaderSignedZeroInfNanPreserveFloat32": true, + "maxPerStageDescriptorUpdateAfterBindSamplers": 500000, + "maxPerStageDescriptorUpdateAfterBindUniformBuffers": 12, + "maxPerStageDescriptorUpdateAfterBindStorageBuffers": 500000, + "maxPerStageDescriptorUpdateAfterBindSampledImages": 500000, + "maxPerStageDescriptorUpdateAfterBindStorageImages": 500000, + "maxPerStageDescriptorUpdateAfterBindInputAttachments": 7, + "maxPerStageUpdateAfterBindResources": 500000, + "maxDescriptorSetUpdateAfterBindSamplers": 500000, + "maxDescriptorSetUpdateAfterBindUniformBuffers": 72, + "maxDescriptorSetUpdateAfterBindUniformBuffersDynamic": 8, + "maxDescriptorSetUpdateAfterBindStorageBuffers": 500000, + "maxDescriptorSetUpdateAfterBindStorageBuffersDynamic": 4, + "maxDescriptorSetUpdateAfterBindSampledImages": 500000, + "maxDescriptorSetUpdateAfterBindStorageImages": 500000, + "maxDescriptorSetUpdateAfterBindInputAttachments": 7 + }, + "VkPhysicalDeviceVulkan13Properties": { + "maxBufferSize": 1073741824, + "maxInlineUniformBlockSize": 256, + "maxPerStageDescriptorInlineUniformBlocks": 4, + "maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks": 4, + "maxDescriptorSetInlineUniformBlocks": 4, + "maxDescriptorSetUpdateAfterBindInlineUniformBlocks": 4, + "maxInlineUniformTotalSize": 256 + } + } + } + }, + "profiles": { + "VP_LEARN_how_to_vulkan_2026": { + "version": 1, + "api-version": "1.3.204", + "label": "How To Vulkan 2026", + "description": "Generated profile doing an union between profiles: VP_KHR_roadmap_2022", + "capabilities": [ + "VP_LEARN_how_to_vulkan_2026_block" + ] + } + }, + "contributors": {}, + "history": [ + { + "revision": 1, + "date": "2026-05-25", + "author": "LunarG Profiles Merge Script", + "comment": "Generated profiles file" + } + ] +} diff --git a/vulkan_profiles/vulkan_profiles.cpp b/vulkan_profiles/vulkan_profiles.cpp new file mode 100644 index 0000000..b85343e --- /dev/null +++ b/vulkan_profiles/vulkan_profiles.cpp @@ -0,0 +1,4393 @@ + +/* + * Copyright (C) 2021-2026 Valve Corporation + * Copyright (C) 2021-2026 LunarG, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License") + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is ***GENERATED***. Do Not Edit. + * See scripts/gen_profiles_solution.py for modifications. + */ + +#include "vulkan_profiles.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace detail { + + +VPAPI_ATTR std::string FormatString(const char* message, ...) { + std::size_t const STRING_BUFFER(4096); + + assert(message != nullptr); + assert(strlen(message) >= 1 && strlen(message) < STRING_BUFFER); + + char buffer[STRING_BUFFER]; + va_list list; + + va_start(list, message); + vsnprintf(buffer, STRING_BUFFER, message, list); + va_end(list); + + return buffer; +} + +VPAPI_ATTR const void* vpGetStructure(const void* pNext, VkStructureType type) { + const VkBaseOutStructure* p = static_cast(pNext); + while (p != nullptr) { + if (p->sType == type) return p; + p = p->pNext; + } + return nullptr; +} + +VPAPI_ATTR void* vpGetStructure(void* pNext, VkStructureType type) { + VkBaseOutStructure* p = static_cast(pNext); + while (p != nullptr) { + if (p->sType == type) return p; + p = p->pNext; + } + return nullptr; +} + +VPAPI_ATTR VkBaseOutStructure* vpExtractStructure(VkPhysicalDeviceFeatures2KHR* pFeatures, VkStructureType structureType) { + if (structureType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR) { + return nullptr; + } + + VkBaseOutStructure* current = reinterpret_cast(pFeatures); + VkBaseOutStructure* previous = nullptr; + VkBaseOutStructure* found = nullptr; + + while (current != nullptr) { + if (structureType == current->sType) { + found = current; + if (previous != nullptr) { + previous->pNext = current->pNext; + } + current = nullptr; + } else { + previous = current; + current = current->pNext; + } + } + + if (found != nullptr) { + found->pNext = nullptr; + return found; + } else { + return nullptr; + } +} + +VPAPI_ATTR void GatherStructureTypes(std::vector& structureTypes, VkBaseOutStructure* pNext) { + while (pNext) { + if (std::find(structureTypes.begin(), structureTypes.end(), pNext->sType) == structureTypes.end()) { + structureTypes.push_back(pNext->sType); + } + + pNext = pNext->pNext; + } +} + +VPAPI_ATTR bool isMultiple(double source, double multiple) { + double mod = std::fmod(source, multiple); + return std::abs(mod) < 0.0001; +} + +VPAPI_ATTR bool isPowerOfTwo(double source) { + double mod = std::fmod(source, 1.0); + if (std::abs(mod) >= 0.0001) return false; + + std::uint64_t value = static_cast(std::abs(source)); + return !(value & (value - static_cast(1))); +} + +using PFN_vpStructFiller = void(*)(VkBaseOutStructure* p); +using PFN_vpStructComparator = bool(*)(VkBaseOutStructure* p); +using PFN_vpStructChainerCb = void(*)(VkBaseOutStructure* p, void* pUser); +using PFN_vpStructChainer = void(*)(VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb); +using PFN_vpStructArrayChainerCb = void(*)(uint32_t count, VkBaseOutStructure* p, void* pUser); +using PFN_vpStructArrayChainer = void(*)(uint32_t count, VkBaseOutStructure* p, void* pUser, PFN_vpStructArrayChainerCb pfnCb); + +struct VpFeatureDesc { + PFN_vpStructFiller pfnFiller; + PFN_vpStructComparator pfnComparator; +}; + +struct VpPropertyDesc { + PFN_vpStructFiller pfnFiller; + PFN_vpStructComparator pfnComparator; +}; + +struct VpQueueFamilyDesc { + PFN_vpStructFiller pfnFiller; + PFN_vpStructComparator pfnComparator; +}; + +struct VpFormatDesc { + VkFormat format; + PFN_vpStructFiller pfnFiller; + PFN_vpStructComparator pfnComparator; +}; + +struct VpStructChainerDesc { + PFN_vpStructChainer pfnFeature; + PFN_vpStructChainer pfnProperty; + PFN_vpStructArrayChainer pfnQueueFamily; + PFN_vpStructChainer pfnFormat; +}; + +struct VpVideoProfileInfoDesc { + PFN_vpStructFiller pfnFiller; + PFN_vpStructComparator pfnComparator; +}; + +struct VpVideoCapabilityDesc { + PFN_vpStructFiller pfnFiller; + PFN_vpStructComparator pfnComparator; +}; + +struct VpVideoFormatDesc { + PFN_vpStructFiller pfnFiller; + PFN_vpStructComparator pfnComparator; +}; + +struct VpVideoProfileStructChainerDesc { + PFN_vpStructChainer pfnInfo; + PFN_vpStructChainer pfnCapability; + PFN_vpStructArrayChainer pfnFormat; +}; + +struct VpVideoProfileDesc { + VpVideoProfileProperties properties; + + uint32_t infoStructTypeCount; + const VkStructureType* pInfoStructTypes; + VpVideoProfileInfoDesc info; + + uint32_t capabilityStructTypeCount; + const VkStructureType* pCapabilityStructTypes; + VpVideoCapabilityDesc capability; + + uint32_t formatStructTypeCount; + const VkStructureType* pFormatStructTypes; + uint32_t formatCount; + const VpVideoFormatDesc* pFormats; + + VpVideoProfileStructChainerDesc chainers; +}; + +struct VpVariantDesc { + char blockName[VP_MAX_PROFILE_NAME_SIZE]; + + uint32_t instanceExtensionCount; + const VkExtensionProperties* pInstanceExtensions; + + uint32_t deviceExtensionCount; + const VkExtensionProperties* pDeviceExtensions; + + uint32_t featureStructTypeCount; + const VkStructureType* pFeatureStructTypes; + VpFeatureDesc feature; + + uint32_t propertyStructTypeCount; + const VkStructureType* pPropertyStructTypes; + VpPropertyDesc property; + + uint32_t queueFamilyStructTypeCount; + const VkStructureType* pQueueFamilyStructTypes; + uint32_t queueFamilyCount; + const VpQueueFamilyDesc* pQueueFamilies; + + uint32_t formatStructTypeCount; + const VkStructureType* pFormatStructTypes; + uint32_t formatCount; + const VpFormatDesc* pFormats; + + VpStructChainerDesc chainers; + + uint32_t videoProfileCount; + const VpVideoProfileDesc* pVideoProfiles; +}; + +struct VpCapabilitiesDesc { + uint32_t variantCount; + const VpVariantDesc* pVariants; +}; + +struct VpProfileDesc { + VpProfileProperties props; + uint32_t minApiVersion; + + const detail::VpVariantDesc* pMergedCapabilities; + + uint32_t requiredProfileCount; + const VpProfileProperties* pRequiredProfiles; + + uint32_t requiredCapabilityCount; + const VpCapabilitiesDesc* pRequiredCapabilities; + + uint32_t fallbackCount; + const VpProfileProperties* pFallbacks; +}; + +template +VPAPI_ATTR bool vpCheckFlags(const T& actual, const uint64_t expected) { + return (actual & expected) == expected; +} + + +#ifdef VK_KHR_video_queue +VPAPI_ATTR void vpForEachMatchingVideoProfiles( + VkVideoProfileInfoKHR* pVideoProfileInfo, + void* pUser, + PFN_vpStructChainerCb pfnCb) { + const VkVideoChromaSubsamplingFlagsKHR chroma_subsampling_list[] = { + VK_VIDEO_CHROMA_SUBSAMPLING_420_BIT_KHR, + VK_VIDEO_CHROMA_SUBSAMPLING_422_BIT_KHR, + VK_VIDEO_CHROMA_SUBSAMPLING_444_BIT_KHR, + VK_VIDEO_CHROMA_SUBSAMPLING_MONOCHROME_BIT_KHR + }; + const VkVideoComponentBitDepthFlagsKHR bit_depth_list[] = { + VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR, + VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR, + VK_VIDEO_COMPONENT_BIT_DEPTH_12_BIT_KHR + }; + for (size_t chromaSubsampling_idx = 0; chromaSubsampling_idx < std::size(chroma_subsampling_list); ++chromaSubsampling_idx) { + pVideoProfileInfo->chromaSubsampling = chroma_subsampling_list[chromaSubsampling_idx]; + for (size_t lumaBitDepth_idx = 0; lumaBitDepth_idx < std::size(bit_depth_list); ++lumaBitDepth_idx) { + pVideoProfileInfo->lumaBitDepth = bit_depth_list[lumaBitDepth_idx]; + for (size_t chromaBitDepth_idx = 0; chromaBitDepth_idx < std::size(bit_depth_list); ++chromaBitDepth_idx) { + pVideoProfileInfo->chromaBitDepth = bit_depth_list[chromaBitDepth_idx]; + { + pVideoProfileInfo->pNext = nullptr; + pVideoProfileInfo->videoCodecOperation = VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR; + VkVideoDecodeH264ProfileInfoKHR var_VideoDecodeH264ProfileInfoKHR = { VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_INFO_KHR }; + var_VideoDecodeH264ProfileInfoKHR.pNext = pVideoProfileInfo->pNext; + pVideoProfileInfo->pNext = &var_VideoDecodeH264ProfileInfoKHR; + var_VideoDecodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_BASELINE; + var_VideoDecodeH264ProfileInfoKHR.pictureLayout = VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_PROGRESSIVE_KHR; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_MAIN; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_HIGH; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_HIGH_444_PREDICTIVE; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_BASELINE; + var_VideoDecodeH264ProfileInfoKHR.pictureLayout = VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_INTERLEAVED_LINES_BIT_KHR; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_MAIN; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_HIGH; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_HIGH_444_PREDICTIVE; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_BASELINE; + var_VideoDecodeH264ProfileInfoKHR.pictureLayout = VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_SEPARATE_PLANES_BIT_KHR; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_MAIN; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_HIGH; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_HIGH_444_PREDICTIVE; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + } + { + pVideoProfileInfo->pNext = nullptr; + pVideoProfileInfo->videoCodecOperation = VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR; + VkVideoDecodeH265ProfileInfoKHR var_VideoDecodeH265ProfileInfoKHR = { VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_INFO_KHR }; + var_VideoDecodeH265ProfileInfoKHR.pNext = pVideoProfileInfo->pNext; + pVideoProfileInfo->pNext = &var_VideoDecodeH265ProfileInfoKHR; + var_VideoDecodeH265ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_MAIN; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeH265ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_MAIN_10; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeH265ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_MAIN_STILL_PICTURE; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeH265ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSIONS; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeH265ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_SCC_EXTENSIONS; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + } + { + pVideoProfileInfo->pNext = nullptr; + pVideoProfileInfo->videoCodecOperation = VK_VIDEO_CODEC_OPERATION_DECODE_VP9_BIT_KHR; + VkVideoDecodeVP9ProfileInfoKHR var_VideoDecodeVP9ProfileInfoKHR = { VK_STRUCTURE_TYPE_VIDEO_DECODE_VP9_PROFILE_INFO_KHR }; + var_VideoDecodeVP9ProfileInfoKHR.pNext = pVideoProfileInfo->pNext; + pVideoProfileInfo->pNext = &var_VideoDecodeVP9ProfileInfoKHR; + var_VideoDecodeVP9ProfileInfoKHR.stdProfile = STD_VIDEO_VP9_PROFILE_0; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeVP9ProfileInfoKHR.stdProfile = STD_VIDEO_VP9_PROFILE_1; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeVP9ProfileInfoKHR.stdProfile = STD_VIDEO_VP9_PROFILE_2; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeVP9ProfileInfoKHR.stdProfile = STD_VIDEO_VP9_PROFILE_3; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + } + { + pVideoProfileInfo->pNext = nullptr; + pVideoProfileInfo->videoCodecOperation = VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR; + VkVideoDecodeAV1ProfileInfoKHR var_VideoDecodeAV1ProfileInfoKHR = { VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_PROFILE_INFO_KHR }; + var_VideoDecodeAV1ProfileInfoKHR.pNext = pVideoProfileInfo->pNext; + pVideoProfileInfo->pNext = &var_VideoDecodeAV1ProfileInfoKHR; + var_VideoDecodeAV1ProfileInfoKHR.stdProfile = STD_VIDEO_AV1_PROFILE_MAIN; + var_VideoDecodeAV1ProfileInfoKHR.filmGrainSupport = VK_TRUE; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeAV1ProfileInfoKHR.stdProfile = STD_VIDEO_AV1_PROFILE_HIGH; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeAV1ProfileInfoKHR.stdProfile = STD_VIDEO_AV1_PROFILE_PROFESSIONAL; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeAV1ProfileInfoKHR.stdProfile = STD_VIDEO_AV1_PROFILE_MAIN; + var_VideoDecodeAV1ProfileInfoKHR.filmGrainSupport = VK_FALSE; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeAV1ProfileInfoKHR.stdProfile = STD_VIDEO_AV1_PROFILE_HIGH; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeAV1ProfileInfoKHR.stdProfile = STD_VIDEO_AV1_PROFILE_PROFESSIONAL; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + } + { + pVideoProfileInfo->pNext = nullptr; + pVideoProfileInfo->videoCodecOperation = VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR; + VkVideoEncodeH264ProfileInfoKHR var_VideoEncodeH264ProfileInfoKHR = { VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PROFILE_INFO_KHR }; + var_VideoEncodeH264ProfileInfoKHR.pNext = pVideoProfileInfo->pNext; + pVideoProfileInfo->pNext = &var_VideoEncodeH264ProfileInfoKHR; + var_VideoEncodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_BASELINE; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoEncodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_MAIN; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoEncodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_HIGH; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoEncodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_HIGH_444_PREDICTIVE; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + } + { + pVideoProfileInfo->pNext = nullptr; + pVideoProfileInfo->videoCodecOperation = VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR; + VkVideoEncodeH265ProfileInfoKHR var_VideoEncodeH265ProfileInfoKHR = { VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_PROFILE_INFO_KHR }; + var_VideoEncodeH265ProfileInfoKHR.pNext = pVideoProfileInfo->pNext; + pVideoProfileInfo->pNext = &var_VideoEncodeH265ProfileInfoKHR; + var_VideoEncodeH265ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_MAIN; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoEncodeH265ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_MAIN_10; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoEncodeH265ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_MAIN_STILL_PICTURE; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoEncodeH265ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSIONS; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoEncodeH265ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_SCC_EXTENSIONS; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + } + { + pVideoProfileInfo->pNext = nullptr; + pVideoProfileInfo->videoCodecOperation = VK_VIDEO_CODEC_OPERATION_ENCODE_AV1_BIT_KHR; + VkVideoEncodeAV1ProfileInfoKHR var_VideoEncodeAV1ProfileInfoKHR = { VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_PROFILE_INFO_KHR }; + var_VideoEncodeAV1ProfileInfoKHR.pNext = pVideoProfileInfo->pNext; + pVideoProfileInfo->pNext = &var_VideoEncodeAV1ProfileInfoKHR; + var_VideoEncodeAV1ProfileInfoKHR.stdProfile = STD_VIDEO_AV1_PROFILE_MAIN; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoEncodeAV1ProfileInfoKHR.stdProfile = STD_VIDEO_AV1_PROFILE_HIGH; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoEncodeAV1ProfileInfoKHR.stdProfile = STD_VIDEO_AV1_PROFILE_PROFESSIONAL; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + } + } + } + } +} +#endif // VK_KHR_video_queue +#ifdef VP_LEARN_how_to_vulkan_2026 +namespace VP_LEARN_HOW_TO_VULKAN_2026 { + +static const VkStructureType featureStructTypes[] = { + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES, +}; + +static const VkStructureType propertyStructTypes[] = { + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_PROPERTIES, +}; + +static const VkExtensionProperties instanceExtensions[] = { + VkExtensionProperties{ VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, 1 }, +}; + +static const VkExtensionProperties deviceExtensions[] = { + VkExtensionProperties{ VK_KHR_GLOBAL_PRIORITY_EXTENSION_NAME, 1 }, + VkExtensionProperties{ VK_KHR_SWAPCHAIN_EXTENSION_NAME, 70 }, +}; + +static const VpFeatureDesc featureDesc = { + [](VkBaseOutStructure* p) { (void)p; + switch (p->sType) { + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR: { + VkPhysicalDeviceFeatures2KHR* s = static_cast(static_cast(p)); + s->features.depthBiasClamp = VK_TRUE; + s->features.depthClamp = VK_TRUE; + s->features.drawIndirectFirstInstance = VK_TRUE; + s->features.fragmentStoresAndAtomics = VK_TRUE; + s->features.fullDrawIndexUint32 = VK_TRUE; + s->features.imageCubeArray = VK_TRUE; + s->features.independentBlend = VK_TRUE; + s->features.occlusionQueryPrecise = VK_TRUE; + s->features.robustBufferAccess = VK_TRUE; + s->features.sampleRateShading = VK_TRUE; + s->features.samplerAnisotropy = VK_TRUE; + s->features.shaderSampledImageArrayDynamicIndexing = VK_TRUE; + s->features.shaderStorageBufferArrayDynamicIndexing = VK_TRUE; + s->features.shaderStorageImageArrayDynamicIndexing = VK_TRUE; + s->features.shaderStorageImageExtendedFormats = VK_TRUE; + s->features.shaderUniformBufferArrayDynamicIndexing = VK_TRUE; + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES: { + VkPhysicalDeviceVulkan11Features* s = static_cast(static_cast(p)); + s->multiview = VK_TRUE; + s->samplerYcbcrConversion = VK_TRUE; + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES: { + VkPhysicalDeviceVulkan12Features* s = static_cast(static_cast(p)); + s->bufferDeviceAddress = VK_TRUE; + s->descriptorBindingPartiallyBound = VK_TRUE; + s->descriptorBindingSampledImageUpdateAfterBind = VK_TRUE; + s->descriptorBindingStorageBufferUpdateAfterBind = VK_TRUE; + s->descriptorBindingStorageImageUpdateAfterBind = VK_TRUE; + s->descriptorBindingStorageTexelBufferUpdateAfterBind = VK_TRUE; + s->descriptorBindingUniformTexelBufferUpdateAfterBind = VK_TRUE; + s->descriptorBindingUpdateUnusedWhilePending = VK_TRUE; + s->descriptorBindingVariableDescriptorCount = VK_TRUE; + s->descriptorIndexing = VK_TRUE; + s->hostQueryReset = VK_TRUE; + s->imagelessFramebuffer = VK_TRUE; + s->runtimeDescriptorArray = VK_TRUE; + s->samplerMirrorClampToEdge = VK_TRUE; + s->scalarBlockLayout = VK_TRUE; + s->separateDepthStencilLayouts = VK_TRUE; + s->shaderSampledImageArrayNonUniformIndexing = VK_TRUE; + s->shaderStorageBufferArrayNonUniformIndexing = VK_TRUE; + s->shaderStorageImageArrayNonUniformIndexing = VK_TRUE; + s->shaderStorageTexelBufferArrayDynamicIndexing = VK_TRUE; + s->shaderStorageTexelBufferArrayNonUniformIndexing = VK_TRUE; + s->shaderSubgroupExtendedTypes = VK_TRUE; + s->shaderUniformBufferArrayNonUniformIndexing = VK_TRUE; + s->shaderUniformTexelBufferArrayDynamicIndexing = VK_TRUE; + s->shaderUniformTexelBufferArrayNonUniformIndexing = VK_TRUE; + s->subgroupBroadcastDynamicId = VK_TRUE; + s->timelineSemaphore = VK_TRUE; + s->uniformBufferStandardLayout = VK_TRUE; + s->vulkanMemoryModel = VK_TRUE; + s->vulkanMemoryModelDeviceScope = VK_TRUE; + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES: { + VkPhysicalDeviceVulkan13Features* s = static_cast(static_cast(p)); + s->computeFullSubgroups = VK_TRUE; + s->descriptorBindingInlineUniformBlockUpdateAfterBind = VK_TRUE; + s->dynamicRendering = VK_TRUE; + s->inlineUniformBlock = VK_TRUE; + s->maintenance4 = VK_TRUE; + s->pipelineCreationCacheControl = VK_TRUE; + s->robustImageAccess = VK_TRUE; + s->shaderDemoteToHelperInvocation = VK_TRUE; + s->shaderIntegerDotProduct = VK_TRUE; + s->shaderTerminateInvocation = VK_TRUE; + s->shaderZeroInitializeWorkgroupMemory = VK_TRUE; + s->subgroupSizeControl = VK_TRUE; + s->synchronization2 = VK_TRUE; + } break; + default: break; + } + }, + [](VkBaseOutStructure* p) -> bool { (void)p; + bool ret = true; + switch (p->sType) { + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR: { + VkPhysicalDeviceFeatures2KHR* s = static_cast(static_cast(p)); + ret = ret && (s->features.depthBiasClamp == VK_TRUE); + ret = ret && (s->features.depthClamp == VK_TRUE); + ret = ret && (s->features.drawIndirectFirstInstance == VK_TRUE); + ret = ret && (s->features.fragmentStoresAndAtomics == VK_TRUE); + ret = ret && (s->features.fullDrawIndexUint32 == VK_TRUE); + ret = ret && (s->features.imageCubeArray == VK_TRUE); + ret = ret && (s->features.independentBlend == VK_TRUE); + ret = ret && (s->features.occlusionQueryPrecise == VK_TRUE); + ret = ret && (s->features.robustBufferAccess == VK_TRUE); + ret = ret && (s->features.sampleRateShading == VK_TRUE); + ret = ret && (s->features.samplerAnisotropy == VK_TRUE); + ret = ret && (s->features.shaderSampledImageArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->features.shaderStorageBufferArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->features.shaderStorageImageArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->features.shaderStorageImageExtendedFormats == VK_TRUE); + ret = ret && (s->features.shaderUniformBufferArrayDynamicIndexing == VK_TRUE); + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES: { + VkPhysicalDeviceVulkan11Features* s = static_cast(static_cast(p)); + ret = ret && (s->multiview == VK_TRUE); + ret = ret && (s->samplerYcbcrConversion == VK_TRUE); + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES: { + VkPhysicalDeviceVulkan12Features* s = static_cast(static_cast(p)); + ret = ret && (s->bufferDeviceAddress == VK_TRUE); + ret = ret && (s->descriptorBindingPartiallyBound == VK_TRUE); + ret = ret && (s->descriptorBindingSampledImageUpdateAfterBind == VK_TRUE); + ret = ret && (s->descriptorBindingStorageBufferUpdateAfterBind == VK_TRUE); + ret = ret && (s->descriptorBindingStorageImageUpdateAfterBind == VK_TRUE); + ret = ret && (s->descriptorBindingStorageTexelBufferUpdateAfterBind == VK_TRUE); + ret = ret && (s->descriptorBindingUniformTexelBufferUpdateAfterBind == VK_TRUE); + ret = ret && (s->descriptorBindingUpdateUnusedWhilePending == VK_TRUE); + ret = ret && (s->descriptorBindingVariableDescriptorCount == VK_TRUE); + ret = ret && (s->descriptorIndexing == VK_TRUE); + ret = ret && (s->hostQueryReset == VK_TRUE); + ret = ret && (s->imagelessFramebuffer == VK_TRUE); + ret = ret && (s->runtimeDescriptorArray == VK_TRUE); + ret = ret && (s->samplerMirrorClampToEdge == VK_TRUE); + ret = ret && (s->scalarBlockLayout == VK_TRUE); + ret = ret && (s->separateDepthStencilLayouts == VK_TRUE); + ret = ret && (s->shaderSampledImageArrayNonUniformIndexing == VK_TRUE); + ret = ret && (s->shaderStorageBufferArrayNonUniformIndexing == VK_TRUE); + ret = ret && (s->shaderStorageImageArrayNonUniformIndexing == VK_TRUE); + ret = ret && (s->shaderStorageTexelBufferArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->shaderStorageTexelBufferArrayNonUniformIndexing == VK_TRUE); + ret = ret && (s->shaderSubgroupExtendedTypes == VK_TRUE); + ret = ret && (s->shaderUniformBufferArrayNonUniformIndexing == VK_TRUE); + ret = ret && (s->shaderUniformTexelBufferArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->shaderUniformTexelBufferArrayNonUniformIndexing == VK_TRUE); + ret = ret && (s->subgroupBroadcastDynamicId == VK_TRUE); + ret = ret && (s->timelineSemaphore == VK_TRUE); + ret = ret && (s->uniformBufferStandardLayout == VK_TRUE); + ret = ret && (s->vulkanMemoryModel == VK_TRUE); + ret = ret && (s->vulkanMemoryModelDeviceScope == VK_TRUE); + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES: { + VkPhysicalDeviceVulkan13Features* s = static_cast(static_cast(p)); + ret = ret && (s->computeFullSubgroups == VK_TRUE); + ret = ret && (s->descriptorBindingInlineUniformBlockUpdateAfterBind == VK_TRUE); + ret = ret && (s->dynamicRendering == VK_TRUE); + ret = ret && (s->inlineUniformBlock == VK_TRUE); + ret = ret && (s->maintenance4 == VK_TRUE); + ret = ret && (s->pipelineCreationCacheControl == VK_TRUE); + ret = ret && (s->robustImageAccess == VK_TRUE); + ret = ret && (s->shaderDemoteToHelperInvocation == VK_TRUE); + ret = ret && (s->shaderIntegerDotProduct == VK_TRUE); + ret = ret && (s->shaderTerminateInvocation == VK_TRUE); + ret = ret && (s->shaderZeroInitializeWorkgroupMemory == VK_TRUE); + ret = ret && (s->subgroupSizeControl == VK_TRUE); + ret = ret && (s->synchronization2 == VK_TRUE); + } break; + default: break; + } + return ret; + } +}; + +static const VpPropertyDesc propertyDesc = { + [](VkBaseOutStructure* p) { (void)p; + }, + [](VkBaseOutStructure* p) -> bool { (void)p; + bool ret = true; + return ret; + } +}; + +static const VpStructChainerDesc chainerDesc = { + [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { + VkPhysicalDeviceVulkan11Features physicalDeviceVulkan11Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES, nullptr }; + VkPhysicalDeviceVulkan12Features physicalDeviceVulkan12Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, &physicalDeviceVulkan11Features }; + VkPhysicalDeviceVulkan13Features physicalDeviceVulkan13Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES, &physicalDeviceVulkan12Features }; + p->pNext = static_cast(static_cast(&physicalDeviceVulkan13Features)); + pfnCb(p, pUser); + }, + [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { + VkPhysicalDeviceVulkan11Properties physicalDeviceVulkan11Properties{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES, nullptr }; + VkPhysicalDeviceVulkan12Properties physicalDeviceVulkan12Properties{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES, &physicalDeviceVulkan11Properties }; + VkPhysicalDeviceVulkan13Properties physicalDeviceVulkan13Properties{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_PROPERTIES, &physicalDeviceVulkan12Properties }; + p->pNext = static_cast(static_cast(&physicalDeviceVulkan13Properties)); + pfnCb(p, pUser); + }, + [](uint32_t count, VkBaseOutStructure* p, void* pUser, PFN_vpStructArrayChainerCb pfnCb) { + pfnCb(count, p, pUser); + }, + [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { + pfnCb(p, pUser); + }, +}; + +namespace blocks { +namespace VP_LEARN_how_to_vulkan_2026_block { + +static const VkExtensionProperties instanceExtensions[] = { + VkExtensionProperties{ VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, 1 }, +}; + +static const VkExtensionProperties deviceExtensions[] = { + VkExtensionProperties{ VK_KHR_GLOBAL_PRIORITY_EXTENSION_NAME, 1 }, + VkExtensionProperties{ VK_KHR_SWAPCHAIN_EXTENSION_NAME, 70 }, +}; + +static const VpFeatureDesc featureDesc = { + [](VkBaseOutStructure* p) { (void)p; + switch (p->sType) { + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR: { + VkPhysicalDeviceFeatures2KHR* s = static_cast(static_cast(p)); + s->features.depthBiasClamp = VK_TRUE; + s->features.depthClamp = VK_TRUE; + s->features.drawIndirectFirstInstance = VK_TRUE; + s->features.fragmentStoresAndAtomics = VK_TRUE; + s->features.fullDrawIndexUint32 = VK_TRUE; + s->features.imageCubeArray = VK_TRUE; + s->features.independentBlend = VK_TRUE; + s->features.occlusionQueryPrecise = VK_TRUE; + s->features.robustBufferAccess = VK_TRUE; + s->features.sampleRateShading = VK_TRUE; + s->features.samplerAnisotropy = VK_TRUE; + s->features.shaderSampledImageArrayDynamicIndexing = VK_TRUE; + s->features.shaderStorageBufferArrayDynamicIndexing = VK_TRUE; + s->features.shaderStorageImageArrayDynamicIndexing = VK_TRUE; + s->features.shaderStorageImageExtendedFormats = VK_TRUE; + s->features.shaderUniformBufferArrayDynamicIndexing = VK_TRUE; + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES: { + VkPhysicalDeviceVulkan11Features* s = static_cast(static_cast(p)); + s->multiview = VK_TRUE; + s->samplerYcbcrConversion = VK_TRUE; + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES: { + VkPhysicalDeviceVulkan12Features* s = static_cast(static_cast(p)); + s->bufferDeviceAddress = VK_TRUE; + s->descriptorBindingPartiallyBound = VK_TRUE; + s->descriptorBindingSampledImageUpdateAfterBind = VK_TRUE; + s->descriptorBindingStorageBufferUpdateAfterBind = VK_TRUE; + s->descriptorBindingStorageImageUpdateAfterBind = VK_TRUE; + s->descriptorBindingStorageTexelBufferUpdateAfterBind = VK_TRUE; + s->descriptorBindingUniformTexelBufferUpdateAfterBind = VK_TRUE; + s->descriptorBindingUpdateUnusedWhilePending = VK_TRUE; + s->descriptorBindingVariableDescriptorCount = VK_TRUE; + s->descriptorIndexing = VK_TRUE; + s->hostQueryReset = VK_TRUE; + s->imagelessFramebuffer = VK_TRUE; + s->runtimeDescriptorArray = VK_TRUE; + s->samplerMirrorClampToEdge = VK_TRUE; + s->scalarBlockLayout = VK_TRUE; + s->separateDepthStencilLayouts = VK_TRUE; + s->shaderSampledImageArrayNonUniformIndexing = VK_TRUE; + s->shaderStorageBufferArrayNonUniformIndexing = VK_TRUE; + s->shaderStorageImageArrayNonUniformIndexing = VK_TRUE; + s->shaderStorageTexelBufferArrayDynamicIndexing = VK_TRUE; + s->shaderStorageTexelBufferArrayNonUniformIndexing = VK_TRUE; + s->shaderSubgroupExtendedTypes = VK_TRUE; + s->shaderUniformBufferArrayNonUniformIndexing = VK_TRUE; + s->shaderUniformTexelBufferArrayDynamicIndexing = VK_TRUE; + s->shaderUniformTexelBufferArrayNonUniformIndexing = VK_TRUE; + s->subgroupBroadcastDynamicId = VK_TRUE; + s->timelineSemaphore = VK_TRUE; + s->uniformBufferStandardLayout = VK_TRUE; + s->vulkanMemoryModel = VK_TRUE; + s->vulkanMemoryModelDeviceScope = VK_TRUE; + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES: { + VkPhysicalDeviceVulkan13Features* s = static_cast(static_cast(p)); + s->computeFullSubgroups = VK_TRUE; + s->descriptorBindingInlineUniformBlockUpdateAfterBind = VK_TRUE; + s->dynamicRendering = VK_TRUE; + s->inlineUniformBlock = VK_TRUE; + s->maintenance4 = VK_TRUE; + s->pipelineCreationCacheControl = VK_TRUE; + s->robustImageAccess = VK_TRUE; + s->shaderDemoteToHelperInvocation = VK_TRUE; + s->shaderIntegerDotProduct = VK_TRUE; + s->shaderTerminateInvocation = VK_TRUE; + s->shaderZeroInitializeWorkgroupMemory = VK_TRUE; + s->subgroupSizeControl = VK_TRUE; + s->synchronization2 = VK_TRUE; + } break; + default: break; + } + }, + [](VkBaseOutStructure* p) -> bool { (void)p; + bool ret = true; + switch (p->sType) { + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR: { + VkPhysicalDeviceFeatures2KHR* s = static_cast(static_cast(p)); + ret = ret && (s->features.depthBiasClamp == VK_TRUE); + ret = ret && (s->features.depthClamp == VK_TRUE); + ret = ret && (s->features.drawIndirectFirstInstance == VK_TRUE); + ret = ret && (s->features.fragmentStoresAndAtomics == VK_TRUE); + ret = ret && (s->features.fullDrawIndexUint32 == VK_TRUE); + ret = ret && (s->features.imageCubeArray == VK_TRUE); + ret = ret && (s->features.independentBlend == VK_TRUE); + ret = ret && (s->features.occlusionQueryPrecise == VK_TRUE); + ret = ret && (s->features.robustBufferAccess == VK_TRUE); + ret = ret && (s->features.sampleRateShading == VK_TRUE); + ret = ret && (s->features.samplerAnisotropy == VK_TRUE); + ret = ret && (s->features.shaderSampledImageArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->features.shaderStorageBufferArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->features.shaderStorageImageArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->features.shaderStorageImageExtendedFormats == VK_TRUE); + ret = ret && (s->features.shaderUniformBufferArrayDynamicIndexing == VK_TRUE); + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES: { + VkPhysicalDeviceVulkan11Features* s = static_cast(static_cast(p)); + ret = ret && (s->multiview == VK_TRUE); + ret = ret && (s->samplerYcbcrConversion == VK_TRUE); + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES: { + VkPhysicalDeviceVulkan12Features* s = static_cast(static_cast(p)); + ret = ret && (s->bufferDeviceAddress == VK_TRUE); + ret = ret && (s->descriptorBindingPartiallyBound == VK_TRUE); + ret = ret && (s->descriptorBindingSampledImageUpdateAfterBind == VK_TRUE); + ret = ret && (s->descriptorBindingStorageBufferUpdateAfterBind == VK_TRUE); + ret = ret && (s->descriptorBindingStorageImageUpdateAfterBind == VK_TRUE); + ret = ret && (s->descriptorBindingStorageTexelBufferUpdateAfterBind == VK_TRUE); + ret = ret && (s->descriptorBindingUniformTexelBufferUpdateAfterBind == VK_TRUE); + ret = ret && (s->descriptorBindingUpdateUnusedWhilePending == VK_TRUE); + ret = ret && (s->descriptorBindingVariableDescriptorCount == VK_TRUE); + ret = ret && (s->descriptorIndexing == VK_TRUE); + ret = ret && (s->hostQueryReset == VK_TRUE); + ret = ret && (s->imagelessFramebuffer == VK_TRUE); + ret = ret && (s->runtimeDescriptorArray == VK_TRUE); + ret = ret && (s->samplerMirrorClampToEdge == VK_TRUE); + ret = ret && (s->scalarBlockLayout == VK_TRUE); + ret = ret && (s->separateDepthStencilLayouts == VK_TRUE); + ret = ret && (s->shaderSampledImageArrayNonUniformIndexing == VK_TRUE); + ret = ret && (s->shaderStorageBufferArrayNonUniformIndexing == VK_TRUE); + ret = ret && (s->shaderStorageImageArrayNonUniformIndexing == VK_TRUE); + ret = ret && (s->shaderStorageTexelBufferArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->shaderStorageTexelBufferArrayNonUniformIndexing == VK_TRUE); + ret = ret && (s->shaderSubgroupExtendedTypes == VK_TRUE); + ret = ret && (s->shaderUniformBufferArrayNonUniformIndexing == VK_TRUE); + ret = ret && (s->shaderUniformTexelBufferArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->shaderUniformTexelBufferArrayNonUniformIndexing == VK_TRUE); + ret = ret && (s->subgroupBroadcastDynamicId == VK_TRUE); + ret = ret && (s->timelineSemaphore == VK_TRUE); + ret = ret && (s->uniformBufferStandardLayout == VK_TRUE); + ret = ret && (s->vulkanMemoryModel == VK_TRUE); + ret = ret && (s->vulkanMemoryModelDeviceScope == VK_TRUE); + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES: { + VkPhysicalDeviceVulkan13Features* s = static_cast(static_cast(p)); + ret = ret && (s->computeFullSubgroups == VK_TRUE); + ret = ret && (s->descriptorBindingInlineUniformBlockUpdateAfterBind == VK_TRUE); + ret = ret && (s->dynamicRendering == VK_TRUE); + ret = ret && (s->inlineUniformBlock == VK_TRUE); + ret = ret && (s->maintenance4 == VK_TRUE); + ret = ret && (s->pipelineCreationCacheControl == VK_TRUE); + ret = ret && (s->robustImageAccess == VK_TRUE); + ret = ret && (s->shaderDemoteToHelperInvocation == VK_TRUE); + ret = ret && (s->shaderIntegerDotProduct == VK_TRUE); + ret = ret && (s->shaderTerminateInvocation == VK_TRUE); + ret = ret && (s->shaderZeroInitializeWorkgroupMemory == VK_TRUE); + ret = ret && (s->subgroupSizeControl == VK_TRUE); + ret = ret && (s->synchronization2 == VK_TRUE); + } break; + default: break; + } + return ret; + } +}; + +static const VpPropertyDesc propertyDesc = { + [](VkBaseOutStructure* p) { (void)p; + switch (p->sType) { + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR: { + VkPhysicalDeviceProperties2KHR* s = static_cast(static_cast(p)); + s->properties.limits.bufferImageGranularity = 4096; + s->properties.limits.maxColorAttachments = 7; + s->properties.limits.maxComputeWorkGroupInvocations = 256; + s->properties.limits.maxComputeWorkGroupSize[0] = 256; + s->properties.limits.maxComputeWorkGroupSize[1] = 256; + s->properties.limits.maxComputeWorkGroupSize[2] = 64; + s->properties.limits.maxDescriptorSetSampledImages = 1800; + s->properties.limits.maxDescriptorSetSamplers = 576; + s->properties.limits.maxDescriptorSetStorageBuffers = 96; + s->properties.limits.maxDescriptorSetStorageImages = 144; + s->properties.limits.maxDescriptorSetUniformBuffers = 90; + s->properties.limits.maxFragmentCombinedOutputResources = 16; + s->properties.limits.maxImageArrayLayers = 2048; + s->properties.limits.maxImageDimension1D = 8192; + s->properties.limits.maxImageDimension2D = 8192; + s->properties.limits.maxImageDimensionCube = 8192; + s->properties.limits.maxPerStageDescriptorSampledImages = 200; + s->properties.limits.maxPerStageDescriptorSamplers = 64; + s->properties.limits.maxPerStageDescriptorStorageBuffers = 30; + s->properties.limits.maxPerStageDescriptorStorageImages = 16; + s->properties.limits.maxPerStageDescriptorUniformBuffers = 15; + s->properties.limits.maxPerStageResources = 200; + s->properties.limits.maxSamplerLodBias = 14; + s->properties.limits.maxUniformBufferRange = 65536; + s->properties.limits.mipmapPrecisionBits = 6; + s->properties.limits.standardSampleLocations = VK_TRUE; + s->properties.limits.subTexelPrecisionBits = 8; + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES: { + VkPhysicalDeviceVulkan11Properties* s = static_cast(static_cast(p)); + s->maxMultiviewInstanceIndex = 134217727; + s->maxMultiviewViewCount = 6; + s->subgroupSize = 4; + s->subgroupSupportedOperations |= (VK_SUBGROUP_FEATURE_BASIC_BIT | VK_SUBGROUP_FEATURE_VOTE_BIT | VK_SUBGROUP_FEATURE_ARITHMETIC_BIT | VK_SUBGROUP_FEATURE_BALLOT_BIT | VK_SUBGROUP_FEATURE_SHUFFLE_BIT | VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT | VK_SUBGROUP_FEATURE_QUAD_BIT); + s->subgroupSupportedStages |= (VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_FRAGMENT_BIT); + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES: { + VkPhysicalDeviceVulkan12Properties* s = static_cast(static_cast(p)); + s->maxDescriptorSetUpdateAfterBindInputAttachments = 7; + s->maxDescriptorSetUpdateAfterBindSampledImages = 500000; + s->maxDescriptorSetUpdateAfterBindSamplers = 500000; + s->maxDescriptorSetUpdateAfterBindStorageBuffers = 500000; + s->maxDescriptorSetUpdateAfterBindStorageBuffersDynamic = 4; + s->maxDescriptorSetUpdateAfterBindStorageImages = 500000; + s->maxDescriptorSetUpdateAfterBindUniformBuffers = 72; + s->maxDescriptorSetUpdateAfterBindUniformBuffersDynamic = 8; + s->maxPerStageDescriptorUpdateAfterBindInputAttachments = 7; + s->maxPerStageDescriptorUpdateAfterBindSampledImages = 500000; + s->maxPerStageDescriptorUpdateAfterBindSamplers = 500000; + s->maxPerStageDescriptorUpdateAfterBindStorageBuffers = 500000; + s->maxPerStageDescriptorUpdateAfterBindStorageImages = 500000; + s->maxPerStageDescriptorUpdateAfterBindUniformBuffers = 12; + s->maxPerStageUpdateAfterBindResources = 500000; + s->maxTimelineSemaphoreValueDifference = 2147483647; + s->shaderSignedZeroInfNanPreserveFloat16 = VK_TRUE; + s->shaderSignedZeroInfNanPreserveFloat32 = VK_TRUE; + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_PROPERTIES: { + VkPhysicalDeviceVulkan13Properties* s = static_cast(static_cast(p)); + s->maxBufferSize = 1073741824; + s->maxDescriptorSetInlineUniformBlocks = 4; + s->maxDescriptorSetUpdateAfterBindInlineUniformBlocks = 4; + s->maxInlineUniformBlockSize = 256; + s->maxInlineUniformTotalSize = 256; + s->maxPerStageDescriptorInlineUniformBlocks = 4; + s->maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks = 4; + } break; + default: break; + } + }, + [](VkBaseOutStructure* p) -> bool { (void)p; + bool ret = true; + switch (p->sType) { + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR: { + VkPhysicalDeviceProperties2KHR* s = static_cast(static_cast(p)); + ret = ret && (s->properties.limits.bufferImageGranularity <= 4096); + ret = ret && ((4096 % s->properties.limits.bufferImageGranularity) == 0); + ret = ret && (s->properties.limits.maxColorAttachments >= 7); + ret = ret && (s->properties.limits.maxComputeWorkGroupInvocations >= 256); + ret = ret && (s->properties.limits.maxComputeWorkGroupSize[0] >= 256); + ret = ret && (s->properties.limits.maxComputeWorkGroupSize[1] >= 256); + ret = ret && (s->properties.limits.maxComputeWorkGroupSize[2] >= 64); + ret = ret && (s->properties.limits.maxDescriptorSetSampledImages >= 1800); + ret = ret && (s->properties.limits.maxDescriptorSetSamplers >= 576); + ret = ret && (s->properties.limits.maxDescriptorSetStorageBuffers >= 96); + ret = ret && (s->properties.limits.maxDescriptorSetStorageImages >= 144); + ret = ret && (s->properties.limits.maxDescriptorSetUniformBuffers >= 90); + ret = ret && (s->properties.limits.maxFragmentCombinedOutputResources >= 16); + ret = ret && (s->properties.limits.maxImageArrayLayers >= 2048); + ret = ret && (s->properties.limits.maxImageDimension1D >= 8192); + ret = ret && (s->properties.limits.maxImageDimension2D >= 8192); + ret = ret && (s->properties.limits.maxImageDimensionCube >= 8192); + ret = ret && (s->properties.limits.maxPerStageDescriptorSampledImages >= 200); + ret = ret && (s->properties.limits.maxPerStageDescriptorSamplers >= 64); + ret = ret && (s->properties.limits.maxPerStageDescriptorStorageBuffers >= 30); + ret = ret && (s->properties.limits.maxPerStageDescriptorStorageImages >= 16); + ret = ret && (s->properties.limits.maxPerStageDescriptorUniformBuffers >= 15); + ret = ret && (s->properties.limits.maxPerStageResources >= 200); + ret = ret && (s->properties.limits.maxSamplerLodBias >= 14); + ret = ret && (s->properties.limits.maxUniformBufferRange >= 65536); + ret = ret && (s->properties.limits.mipmapPrecisionBits >= 6); + ret = ret && (s->properties.limits.standardSampleLocations >= VK_TRUE); + ret = ret && (s->properties.limits.subTexelPrecisionBits >= 8); + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES: { + VkPhysicalDeviceVulkan11Properties* s = static_cast(static_cast(p)); + ret = ret && (s->maxMultiviewInstanceIndex >= 134217727); + ret = ret && (s->maxMultiviewViewCount >= 6); + ret = ret && (s->subgroupSize >= 4); + ret = ret && ((s->subgroupSize & (s->subgroupSize - 1)) == 0); + ret = ret && (vpCheckFlags(s->subgroupSupportedOperations, (VK_SUBGROUP_FEATURE_BASIC_BIT | VK_SUBGROUP_FEATURE_VOTE_BIT | VK_SUBGROUP_FEATURE_ARITHMETIC_BIT | VK_SUBGROUP_FEATURE_BALLOT_BIT | VK_SUBGROUP_FEATURE_SHUFFLE_BIT | VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT | VK_SUBGROUP_FEATURE_QUAD_BIT))); + ret = ret && (vpCheckFlags(s->subgroupSupportedStages, (VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_FRAGMENT_BIT))); + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES: { + VkPhysicalDeviceVulkan12Properties* s = static_cast(static_cast(p)); + ret = ret && (s->maxDescriptorSetUpdateAfterBindInputAttachments >= 7); + ret = ret && (s->maxDescriptorSetUpdateAfterBindSampledImages >= 500000); + ret = ret && (s->maxDescriptorSetUpdateAfterBindSamplers >= 500000); + ret = ret && (s->maxDescriptorSetUpdateAfterBindStorageBuffers >= 500000); + ret = ret && (s->maxDescriptorSetUpdateAfterBindStorageBuffersDynamic >= 4); + ret = ret && (s->maxDescriptorSetUpdateAfterBindStorageImages >= 500000); + ret = ret && (s->maxDescriptorSetUpdateAfterBindUniformBuffers >= 72); + ret = ret && (s->maxDescriptorSetUpdateAfterBindUniformBuffersDynamic >= 8); + ret = ret && (s->maxPerStageDescriptorUpdateAfterBindInputAttachments >= 7); + ret = ret && (s->maxPerStageDescriptorUpdateAfterBindSampledImages >= 500000); + ret = ret && (s->maxPerStageDescriptorUpdateAfterBindSamplers >= 500000); + ret = ret && (s->maxPerStageDescriptorUpdateAfterBindStorageBuffers >= 500000); + ret = ret && (s->maxPerStageDescriptorUpdateAfterBindStorageImages >= 500000); + ret = ret && (s->maxPerStageDescriptorUpdateAfterBindUniformBuffers >= 12); + ret = ret && (s->maxPerStageUpdateAfterBindResources >= 500000); + ret = ret && (s->maxTimelineSemaphoreValueDifference >= 2147483647); + ret = ret && (s->shaderSignedZeroInfNanPreserveFloat16 >= VK_TRUE); + ret = ret && (s->shaderSignedZeroInfNanPreserveFloat32 >= VK_TRUE); + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_PROPERTIES: { + VkPhysicalDeviceVulkan13Properties* s = static_cast(static_cast(p)); + ret = ret && (s->maxBufferSize >= 1073741824); + ret = ret && (s->maxDescriptorSetInlineUniformBlocks >= 4); + ret = ret && (s->maxDescriptorSetUpdateAfterBindInlineUniformBlocks >= 4); + ret = ret && (s->maxInlineUniformBlockSize >= 256); + ret = ret && (s->maxInlineUniformTotalSize >= 256); + ret = ret && (s->maxPerStageDescriptorInlineUniformBlocks >= 4); + ret = ret && (s->maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks >= 4); + } break; + default: break; + } + return ret; + } +}; + +static const VpStructChainerDesc chainerDesc = { + [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { + VkPhysicalDeviceVulkan11Features physicalDeviceVulkan11Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES, nullptr }; + VkPhysicalDeviceVulkan12Features physicalDeviceVulkan12Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, &physicalDeviceVulkan11Features }; + VkPhysicalDeviceVulkan13Features physicalDeviceVulkan13Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES, &physicalDeviceVulkan12Features }; + p->pNext = static_cast(static_cast(&physicalDeviceVulkan13Features)); + pfnCb(p, pUser); + }, + [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { + VkPhysicalDeviceVulkan11Properties physicalDeviceVulkan11Properties{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES, nullptr }; + VkPhysicalDeviceVulkan12Properties physicalDeviceVulkan12Properties{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES, &physicalDeviceVulkan11Properties }; + VkPhysicalDeviceVulkan13Properties physicalDeviceVulkan13Properties{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_PROPERTIES, &physicalDeviceVulkan12Properties }; + p->pNext = static_cast(static_cast(&physicalDeviceVulkan13Properties)); + pfnCb(p, pUser); + }, + [](uint32_t count, VkBaseOutStructure* p, void* pUser, PFN_vpStructArrayChainerCb pfnCb) { + pfnCb(count, p, pUser); + }, + [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { + pfnCb(p, pUser); + }, +}; +} // namespace VP_LEARN_how_to_vulkan_2026_block +} // namespace blocks +} // namespace VP_LEARN_HOW_TO_VULKAN_2026 +#endif // VP_LEARN_how_to_vulkan_2026 + + +#ifdef VP_LEARN_how_to_vulkan_2026 +namespace VP_LEARN_HOW_TO_VULKAN_2026 { + static const VpVariantDesc mergedCapabilities[] = { + { + "MERGED", + static_cast(std::size(instanceExtensions)), instanceExtensions, + static_cast(std::size(deviceExtensions)), deviceExtensions, + static_cast(std::size(featureStructTypes)), featureStructTypes, + featureDesc, + 0, nullptr, + propertyDesc, + 0, nullptr, + 0, nullptr, + 0, nullptr, + 0, nullptr, + chainerDesc, + 0, nullptr, + }, + }; + + namespace blocks { + namespace VP_LEARN_how_to_vulkan_2026_block { + static const VpVariantDesc variants[] = { + { + "VP_LEARN_how_to_vulkan_2026_block", + static_cast(std::size(blocks::VP_LEARN_how_to_vulkan_2026_block::instanceExtensions)), blocks::VP_LEARN_how_to_vulkan_2026_block::instanceExtensions, + static_cast(std::size(blocks::VP_LEARN_how_to_vulkan_2026_block::deviceExtensions)), blocks::VP_LEARN_how_to_vulkan_2026_block::deviceExtensions, + static_cast(std::size(featureStructTypes)), featureStructTypes, + blocks::VP_LEARN_how_to_vulkan_2026_block::featureDesc, + static_cast(std::size(propertyStructTypes)), propertyStructTypes, + blocks::VP_LEARN_how_to_vulkan_2026_block::propertyDesc, + 0, nullptr, + 0, nullptr, + 0, nullptr, + 0, nullptr, + blocks::VP_LEARN_how_to_vulkan_2026_block::chainerDesc, + 0, nullptr, + }, + }; + static const uint32_t variantCount = static_cast(std::size(variants)); + } // namespace VP_LEARN_how_to_vulkan_2026_block + } // namespace blocks + + static const VpCapabilitiesDesc capabilities[] = { + { blocks::VP_LEARN_how_to_vulkan_2026_block::variantCount, blocks::VP_LEARN_how_to_vulkan_2026_block::variants }, + }; + static const uint32_t capabilityCount = static_cast(std::size(capabilities)); +} // namespace VP_LEARN_HOW_TO_VULKAN_2026 +#endif //VP_LEARN_how_to_vulkan_2026 + +static const VpProfileDesc profiles[] = { +#ifdef VP_LEARN_how_to_vulkan_2026 + VpProfileDesc{ + VpProfileProperties{ VP_LEARN_HOW_TO_VULKAN_2026_NAME, VP_LEARN_HOW_TO_VULKAN_2026_SPEC_VERSION }, + VP_LEARN_HOW_TO_VULKAN_2026_MIN_API_VERSION, + VP_LEARN_HOW_TO_VULKAN_2026::mergedCapabilities, + 0, nullptr, + VP_LEARN_HOW_TO_VULKAN_2026::capabilityCount, VP_LEARN_HOW_TO_VULKAN_2026::capabilities, + 0, nullptr, + }, +#endif // VP_LEARN_HOW_TO_VULKAN_2026 +}; +static const uint32_t profileCount = static_cast(std::size(profiles)); + + +struct FeaturesChain { + std::map structureSize; + + template + constexpr std::size_t size() const { + return (sizeof(T) - sizeof(VkBaseOutStructure)) / sizeof(VkBool32); + } + + // Chain with all Vulkan Features structures + VkPhysicalDeviceDeviceGeneratedCommandsFeaturesNV physicalDeviceDeviceGeneratedCommandsFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_FEATURES_NV, nullptr }; + VkPhysicalDevicePushConstantBankFeaturesNV physicalDevicePushConstantBankFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_CONSTANT_BANK_FEATURES_NV, nullptr }; + VkPhysicalDeviceDeviceGeneratedCommandsComputeFeaturesNV physicalDeviceDeviceGeneratedCommandsComputeFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_COMPUTE_FEATURES_NV, nullptr }; + VkPhysicalDevicePrivateDataFeatures physicalDevicePrivateDataFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES, nullptr }; + VkPhysicalDeviceClusterAccelerationStructureFeaturesNV physicalDeviceClusterAccelerationStructureFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CLUSTER_ACCELERATION_STRUCTURE_FEATURES_NV, nullptr }; + VkPhysicalDeviceVariablePointersFeatures physicalDeviceVariablePointersFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES, nullptr }; + VkPhysicalDeviceMultiviewFeatures physicalDeviceMultiviewFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES, nullptr }; + VkPhysicalDevicePresentIdFeaturesKHR physicalDevicePresentIdFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_ID_FEATURES_KHR, nullptr }; + VkPhysicalDevicePresentId2FeaturesKHR physicalDevicePresentId2FeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_ID_2_FEATURES_KHR, nullptr }; + VkPhysicalDevicePresentWaitFeaturesKHR physicalDevicePresentWaitFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_WAIT_FEATURES_KHR, nullptr }; + VkPhysicalDevicePresentWait2FeaturesKHR physicalDevicePresentWait2FeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_WAIT_2_FEATURES_KHR, nullptr }; + VkPhysicalDevicePresentTimingFeaturesEXT physicalDevicePresentTimingFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_TIMING_FEATURES_EXT, nullptr }; + VkPhysicalDevice16BitStorageFeatures physicalDevice16BitStorageFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES, nullptr }; + VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures physicalDeviceShaderSubgroupExtendedTypesFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES, nullptr }; + VkPhysicalDeviceSamplerYcbcrConversionFeatures physicalDeviceSamplerYcbcrConversionFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES, nullptr }; + VkPhysicalDeviceProtectedMemoryFeatures physicalDeviceProtectedMemoryFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES, nullptr }; + VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT physicalDeviceBlendOperationAdvancedFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT, nullptr }; + VkPhysicalDeviceMultiDrawFeaturesEXT physicalDeviceMultiDrawFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_FEATURES_EXT, nullptr }; + VkPhysicalDeviceInlineUniformBlockFeatures physicalDeviceInlineUniformBlockFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES, nullptr }; + VkPhysicalDeviceMaintenance4Features physicalDeviceMaintenance4Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES, nullptr }; + VkPhysicalDeviceMaintenance5Features physicalDeviceMaintenance5Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_5_FEATURES, nullptr }; + VkPhysicalDeviceMaintenance6Features physicalDeviceMaintenance6Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_6_FEATURES, nullptr }; + VkPhysicalDeviceMaintenance7FeaturesKHR physicalDeviceMaintenance7FeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_7_FEATURES_KHR, nullptr }; + VkPhysicalDeviceMaintenance8FeaturesKHR physicalDeviceMaintenance8FeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_8_FEATURES_KHR, nullptr }; + VkPhysicalDeviceMaintenance9FeaturesKHR physicalDeviceMaintenance9FeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_9_FEATURES_KHR, nullptr }; + VkPhysicalDeviceMaintenance11FeaturesKHR physicalDeviceMaintenance11FeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_11_FEATURES_KHR, nullptr }; + VkPhysicalDeviceMaintenance10FeaturesKHR physicalDeviceMaintenance10FeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_10_FEATURES_KHR, nullptr }; + VkPhysicalDeviceShaderDrawParametersFeatures physicalDeviceShaderDrawParametersFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES, nullptr }; + VkPhysicalDeviceShaderFloat16Int8Features physicalDeviceShaderFloat16Int8Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES, nullptr }; + VkPhysicalDeviceHostQueryResetFeatures physicalDeviceHostQueryResetFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES, nullptr }; + VkPhysicalDeviceGlobalPriorityQueryFeatures physicalDeviceGlobalPriorityQueryFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES, nullptr }; + VkPhysicalDeviceDeviceMemoryReportFeaturesEXT physicalDeviceDeviceMemoryReportFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_MEMORY_REPORT_FEATURES_EXT, nullptr }; + VkPhysicalDeviceDescriptorIndexingFeatures physicalDeviceDescriptorIndexingFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES, nullptr }; + VkPhysicalDeviceTimelineSemaphoreFeatures physicalDeviceTimelineSemaphoreFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES, nullptr }; + VkPhysicalDevice8BitStorageFeatures physicalDevice8BitStorageFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES, nullptr }; + VkPhysicalDeviceConditionalRenderingFeaturesEXT physicalDeviceConditionalRenderingFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT, nullptr }; + VkPhysicalDeviceVulkanMemoryModelFeatures physicalDeviceVulkanMemoryModelFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES, nullptr }; + VkPhysicalDeviceShaderAtomicInt64Features physicalDeviceShaderAtomicInt64Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES, nullptr }; + VkPhysicalDeviceShaderAtomicFloatFeaturesEXT physicalDeviceShaderAtomicFloatFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT, nullptr }; + VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT physicalDeviceShaderAtomicFloat2FeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT, nullptr }; + VkPhysicalDeviceVertexAttributeDivisorFeatures physicalDeviceVertexAttributeDivisorFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES, nullptr }; + VkPhysicalDeviceASTCDecodeFeaturesEXT physicalDeviceASTCDecodeFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT, nullptr }; + VkPhysicalDeviceTransformFeedbackFeaturesEXT physicalDeviceTransformFeedbackFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT, nullptr }; + VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV physicalDeviceRepresentativeFragmentTestFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_REPRESENTATIVE_FRAGMENT_TEST_FEATURES_NV, nullptr }; + VkPhysicalDeviceExclusiveScissorFeaturesNV physicalDeviceExclusiveScissorFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXCLUSIVE_SCISSOR_FEATURES_NV, nullptr }; + VkPhysicalDeviceCornerSampledImageFeaturesNV physicalDeviceCornerSampledImageFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CORNER_SAMPLED_IMAGE_FEATURES_NV, nullptr }; + VkPhysicalDeviceComputeShaderDerivativesFeaturesKHR physicalDeviceComputeShaderDerivativesFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_KHR, nullptr }; + VkPhysicalDeviceShaderImageFootprintFeaturesNV physicalDeviceShaderImageFootprintFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_FOOTPRINT_FEATURES_NV, nullptr }; + VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV physicalDeviceDedicatedAllocationImageAliasingFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEDICATED_ALLOCATION_IMAGE_ALIASING_FEATURES_NV, nullptr }; + VkPhysicalDeviceCopyMemoryIndirectFeaturesKHR physicalDeviceCopyMemoryIndirectFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COPY_MEMORY_INDIRECT_FEATURES_KHR, nullptr }; + VkPhysicalDeviceCopyMemoryIndirectFeaturesNV physicalDeviceCopyMemoryIndirectFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COPY_MEMORY_INDIRECT_FEATURES_NV, nullptr }; + VkPhysicalDeviceMemoryDecompressionFeaturesEXT physicalDeviceMemoryDecompressionFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_DECOMPRESSION_FEATURES_EXT, nullptr }; + VkPhysicalDeviceShadingRateImageFeaturesNV physicalDeviceShadingRateImageFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_FEATURES_NV, nullptr }; + VkPhysicalDeviceInvocationMaskFeaturesHUAWEI physicalDeviceInvocationMaskFeaturesHUAWEI{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INVOCATION_MASK_FEATURES_HUAWEI, nullptr }; + VkPhysicalDeviceMeshShaderFeaturesNV physicalDeviceMeshShaderFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV, nullptr }; + VkPhysicalDeviceMeshShaderFeaturesEXT physicalDeviceMeshShaderFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_EXT, nullptr }; + VkPhysicalDeviceAccelerationStructureFeaturesKHR physicalDeviceAccelerationStructureFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR, nullptr }; + VkPhysicalDeviceRayTracingPipelineFeaturesKHR physicalDeviceRayTracingPipelineFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR, nullptr }; + VkPhysicalDeviceRayQueryFeaturesKHR physicalDeviceRayQueryFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_QUERY_FEATURES_KHR, nullptr }; + VkPhysicalDeviceRayTracingMaintenance1FeaturesKHR physicalDeviceRayTracingMaintenance1FeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_MAINTENANCE_1_FEATURES_KHR, nullptr }; + VkPhysicalDeviceFragmentDensityMapFeaturesEXT physicalDeviceFragmentDensityMapFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT, nullptr }; + VkPhysicalDeviceFragmentDensityMap2FeaturesEXT physicalDeviceFragmentDensityMap2FeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_FEATURES_EXT, nullptr }; + VkPhysicalDeviceFragmentDensityMapOffsetFeaturesEXT physicalDeviceFragmentDensityMapOffsetFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_FEATURES_EXT, nullptr }; + VkPhysicalDeviceScalarBlockLayoutFeatures physicalDeviceScalarBlockLayoutFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES, nullptr }; + VkPhysicalDeviceUniformBufferStandardLayoutFeatures physicalDeviceUniformBufferStandardLayoutFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES, nullptr }; + VkPhysicalDeviceDepthClipEnableFeaturesEXT physicalDeviceDepthClipEnableFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT, nullptr }; + VkPhysicalDeviceMemoryPriorityFeaturesEXT physicalDeviceMemoryPriorityFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT, nullptr }; + VkPhysicalDevicePageableDeviceLocalMemoryFeaturesEXT physicalDevicePageableDeviceLocalMemoryFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PAGEABLE_DEVICE_LOCAL_MEMORY_FEATURES_EXT, nullptr }; + VkPhysicalDeviceBufferDeviceAddressFeatures physicalDeviceBufferDeviceAddressFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES, nullptr }; + VkPhysicalDeviceBufferDeviceAddressFeaturesEXT physicalDeviceBufferDeviceAddressFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT, nullptr }; + VkPhysicalDeviceImagelessFramebufferFeatures physicalDeviceImagelessFramebufferFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES, nullptr }; + VkPhysicalDeviceTextureCompressionASTCHDRFeatures physicalDeviceTextureCompressionASTCHDRFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES, nullptr }; + VkPhysicalDeviceCooperativeMatrixFeaturesNV physicalDeviceCooperativeMatrixFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_NV, nullptr }; + VkPhysicalDeviceYcbcrImageArraysFeaturesEXT physicalDeviceYcbcrImageArraysFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_IMAGE_ARRAYS_FEATURES_EXT, nullptr }; + VkPhysicalDevicePresentBarrierFeaturesNV physicalDevicePresentBarrierFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_BARRIER_FEATURES_NV, nullptr }; + VkPhysicalDevicePerformanceQueryFeaturesKHR physicalDevicePerformanceQueryFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_FEATURES_KHR, nullptr }; + VkPhysicalDeviceCoverageReductionModeFeaturesNV physicalDeviceCoverageReductionModeFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COVERAGE_REDUCTION_MODE_FEATURES_NV, nullptr }; + VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL physicalDeviceShaderIntegerFunctions2FeaturesINTEL{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL, nullptr }; + VkPhysicalDeviceShaderClockFeaturesKHR physicalDeviceShaderClockFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR, nullptr }; + VkPhysicalDeviceIndexTypeUint8Features physicalDeviceIndexTypeUint8Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES, nullptr }; + VkPhysicalDeviceShaderSMBuiltinsFeaturesNV physicalDeviceShaderSMBuiltinsFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SM_BUILTINS_FEATURES_NV, nullptr }; + VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT physicalDeviceFragmentShaderInterlockFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT, nullptr }; + VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures physicalDeviceSeparateDepthStencilLayoutsFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES, nullptr }; + VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT physicalDevicePrimitiveTopologyListRestartFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT, nullptr }; + VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR physicalDevicePipelineExecutablePropertiesFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR, nullptr }; + VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures physicalDeviceShaderDemoteToHelperInvocationFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES, nullptr }; + VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT physicalDeviceTexelBufferAlignmentFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT, nullptr }; + VkPhysicalDeviceSubgroupSizeControlFeatures physicalDeviceSubgroupSizeControlFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES, nullptr }; + VkPhysicalDeviceLineRasterizationFeatures physicalDeviceLineRasterizationFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES, nullptr }; + VkPhysicalDevicePipelineCreationCacheControlFeatures physicalDevicePipelineCreationCacheControlFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES, nullptr }; + VkPhysicalDeviceVulkan11Features physicalDeviceVulkan11Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES, nullptr }; + VkPhysicalDeviceVulkan12Features physicalDeviceVulkan12Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, nullptr }; + VkPhysicalDeviceVulkan13Features physicalDeviceVulkan13Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES, nullptr }; + VkPhysicalDeviceVulkan14Features physicalDeviceVulkan14Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_4_FEATURES, nullptr }; + VkPhysicalDeviceCoherentMemoryFeaturesAMD physicalDeviceCoherentMemoryFeaturesAMD{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COHERENT_MEMORY_FEATURES_AMD, nullptr }; + VkPhysicalDeviceCustomBorderColorFeaturesEXT physicalDeviceCustomBorderColorFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT, nullptr }; + VkPhysicalDeviceBorderColorSwizzleFeaturesEXT physicalDeviceBorderColorSwizzleFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BORDER_COLOR_SWIZZLE_FEATURES_EXT, nullptr }; + VkPhysicalDeviceExtendedDynamicStateFeaturesEXT physicalDeviceExtendedDynamicStateFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT, nullptr }; + VkPhysicalDeviceExtendedDynamicState2FeaturesEXT physicalDeviceExtendedDynamicState2FeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT, nullptr }; + VkPhysicalDeviceExtendedDynamicState3FeaturesEXT physicalDeviceExtendedDynamicState3FeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_3_FEATURES_EXT, nullptr }; + VkPhysicalDevicePartitionedAccelerationStructureFeaturesNV physicalDevicePartitionedAccelerationStructureFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PARTITIONED_ACCELERATION_STRUCTURE_FEATURES_NV, nullptr }; + VkPhysicalDeviceDiagnosticsConfigFeaturesNV physicalDeviceDiagnosticsConfigFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DIAGNOSTICS_CONFIG_FEATURES_NV, nullptr }; + VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures physicalDeviceZeroInitializeWorkgroupMemoryFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES, nullptr }; + VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR physicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_FEATURES_KHR, nullptr }; + VkPhysicalDeviceRobustness2FeaturesKHR physicalDeviceRobustness2FeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_KHR, nullptr }; + VkPhysicalDeviceImageRobustnessFeatures physicalDeviceImageRobustnessFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES, nullptr }; + VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR physicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_FEATURES_KHR, nullptr }; +#ifdef VK_ENABLE_BETA_EXTENSIONS + VkPhysicalDevicePortabilitySubsetFeaturesKHR physicalDevicePortabilitySubsetFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR, nullptr }; +#endif + VkPhysicalDevice4444FormatsFeaturesEXT physicalDevice4444FormatsFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT, nullptr }; + VkPhysicalDeviceSubpassShadingFeaturesHUAWEI physicalDeviceSubpassShadingFeaturesHUAWEI{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_SHADING_FEATURES_HUAWEI, nullptr }; + VkPhysicalDeviceClusterCullingShaderFeaturesHUAWEI physicalDeviceClusterCullingShaderFeaturesHUAWEI{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CLUSTER_CULLING_SHADER_FEATURES_HUAWEI, nullptr }; + VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT physicalDeviceShaderImageAtomicInt64FeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_ATOMIC_INT64_FEATURES_EXT, nullptr }; + VkPhysicalDeviceFragmentShadingRateFeaturesKHR physicalDeviceFragmentShadingRateFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR, nullptr }; + VkPhysicalDeviceShaderTerminateInvocationFeatures physicalDeviceShaderTerminateInvocationFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES, nullptr }; + VkPhysicalDeviceFragmentShadingRateEnumsFeaturesNV physicalDeviceFragmentShadingRateEnumsFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_ENUMS_FEATURES_NV, nullptr }; + VkPhysicalDeviceImage2DViewOf3DFeaturesEXT physicalDeviceImage2DViewOf3DFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_2D_VIEW_OF_3D_FEATURES_EXT, nullptr }; + VkPhysicalDeviceImageSlicedViewOf3DFeaturesEXT physicalDeviceImageSlicedViewOf3DFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_SLICED_VIEW_OF_3D_FEATURES_EXT, nullptr }; + VkPhysicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT physicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_DYNAMIC_STATE_FEATURES_EXT, nullptr }; + VkPhysicalDeviceLegacyVertexAttributesFeaturesEXT physicalDeviceLegacyVertexAttributesFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LEGACY_VERTEX_ATTRIBUTES_FEATURES_EXT, nullptr }; + VkPhysicalDeviceMutableDescriptorTypeFeaturesEXT physicalDeviceMutableDescriptorTypeFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_EXT, nullptr }; + VkPhysicalDeviceDepthClipControlFeaturesEXT physicalDeviceDepthClipControlFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_CONTROL_FEATURES_EXT, nullptr }; + VkPhysicalDeviceZeroInitializeDeviceMemoryFeaturesEXT physicalDeviceZeroInitializeDeviceMemoryFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_DEVICE_MEMORY_FEATURES_EXT, nullptr }; + VkPhysicalDeviceCustomResolveFeaturesEXT physicalDeviceCustomResolveFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_RESOLVE_FEATURES_EXT, nullptr }; + VkPhysicalDeviceDeviceGeneratedCommandsFeaturesEXT physicalDeviceDeviceGeneratedCommandsFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_FEATURES_EXT, nullptr }; + VkPhysicalDeviceDepthClampControlFeaturesEXT physicalDeviceDepthClampControlFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLAMP_CONTROL_FEATURES_EXT, nullptr }; + VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT physicalDeviceVertexInputDynamicStateFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_INPUT_DYNAMIC_STATE_FEATURES_EXT, nullptr }; + VkPhysicalDeviceExternalMemoryRDMAFeaturesNV physicalDeviceExternalMemoryRDMAFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_RDMA_FEATURES_NV, nullptr }; + VkPhysicalDeviceShaderRelaxedExtendedInstructionFeaturesKHR physicalDeviceShaderRelaxedExtendedInstructionFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_RELAXED_EXTENDED_INSTRUCTION_FEATURES_KHR, nullptr }; + VkPhysicalDeviceColorWriteEnableFeaturesEXT physicalDeviceColorWriteEnableFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT, nullptr }; + VkPhysicalDeviceSynchronization2Features physicalDeviceSynchronization2Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES, nullptr }; + VkPhysicalDeviceUnifiedImageLayoutsFeaturesKHR physicalDeviceUnifiedImageLayoutsFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFIED_IMAGE_LAYOUTS_FEATURES_KHR, nullptr }; + VkPhysicalDeviceHostImageCopyFeatures physicalDeviceHostImageCopyFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_FEATURES, nullptr }; + VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT physicalDevicePrimitivesGeneratedQueryFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVES_GENERATED_QUERY_FEATURES_EXT, nullptr }; + VkPhysicalDeviceLegacyDitheringFeaturesEXT physicalDeviceLegacyDitheringFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LEGACY_DITHERING_FEATURES_EXT, nullptr }; + VkPhysicalDeviceMultisampledRenderToSingleSampledFeaturesEXT physicalDeviceMultisampledRenderToSingleSampledFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_FEATURES_EXT, nullptr }; + VkPhysicalDevicePipelineProtectedAccessFeatures physicalDevicePipelineProtectedAccessFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_PROTECTED_ACCESS_FEATURES, nullptr }; + VkPhysicalDeviceVideoMaintenance1FeaturesKHR physicalDeviceVideoMaintenance1FeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_MAINTENANCE_1_FEATURES_KHR, nullptr }; + VkPhysicalDeviceVideoMaintenance2FeaturesKHR physicalDeviceVideoMaintenance2FeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_MAINTENANCE_2_FEATURES_KHR, nullptr }; + VkPhysicalDeviceVideoDecodeVP9FeaturesKHR physicalDeviceVideoDecodeVP9FeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_DECODE_VP9_FEATURES_KHR, nullptr }; + VkPhysicalDeviceVideoEncodeQuantizationMapFeaturesKHR physicalDeviceVideoEncodeQuantizationMapFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_QUANTIZATION_MAP_FEATURES_KHR, nullptr }; + VkPhysicalDeviceVideoEncodeAV1FeaturesKHR physicalDeviceVideoEncodeAV1FeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_AV1_FEATURES_KHR, nullptr }; + VkPhysicalDeviceInheritedViewportScissorFeaturesNV physicalDeviceInheritedViewportScissorFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INHERITED_VIEWPORT_SCISSOR_FEATURES_NV, nullptr }; + VkPhysicalDeviceYcbcr2Plane444FormatsFeaturesEXT physicalDeviceYcbcr2Plane444FormatsFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_2_PLANE_444_FORMATS_FEATURES_EXT, nullptr }; + VkPhysicalDeviceProvokingVertexFeaturesEXT physicalDeviceProvokingVertexFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT, nullptr }; + VkPhysicalDeviceVideoEncodeIntraRefreshFeaturesKHR physicalDeviceVideoEncodeIntraRefreshFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_INTRA_REFRESH_FEATURES_KHR, nullptr }; + VkPhysicalDeviceDescriptorBufferFeaturesEXT physicalDeviceDescriptorBufferFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_BUFFER_FEATURES_EXT, nullptr }; + VkPhysicalDeviceShaderIntegerDotProductFeatures physicalDeviceShaderIntegerDotProductFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES, nullptr }; + VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR physicalDeviceFragmentShaderBarycentricFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_KHR, nullptr }; + VkPhysicalDeviceShaderFmaFeaturesKHR physicalDeviceShaderFmaFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FMA_FEATURES_KHR, nullptr }; + VkPhysicalDeviceRayTracingMotionBlurFeaturesNV physicalDeviceRayTracingMotionBlurFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_MOTION_BLUR_FEATURES_NV, nullptr }; + VkPhysicalDeviceRayTracingValidationFeaturesNV physicalDeviceRayTracingValidationFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_VALIDATION_FEATURES_NV, nullptr }; + VkPhysicalDeviceRayTracingLinearSweptSpheresFeaturesNV physicalDeviceRayTracingLinearSweptSpheresFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_LINEAR_SWEPT_SPHERES_FEATURES_NV, nullptr }; + VkPhysicalDeviceRGBA10X6FormatsFeaturesEXT physicalDeviceRGBA10X6FormatsFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RGBA10X6_FORMATS_FEATURES_EXT, nullptr }; + VkPhysicalDeviceDynamicRenderingFeatures physicalDeviceDynamicRenderingFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES, nullptr }; + VkPhysicalDeviceImageViewMinLodFeaturesEXT physicalDeviceImageViewMinLodFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_MIN_LOD_FEATURES_EXT, nullptr }; + VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT physicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_EXT, nullptr }; + VkPhysicalDeviceLinearColorAttachmentFeaturesNV physicalDeviceLinearColorAttachmentFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINEAR_COLOR_ATTACHMENT_FEATURES_NV, nullptr }; + VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT physicalDeviceGraphicsPipelineLibraryFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_FEATURES_EXT, nullptr }; + VkPhysicalDevicePipelineBinaryFeaturesKHR physicalDevicePipelineBinaryFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_BINARY_FEATURES_KHR, nullptr }; + VkPhysicalDeviceDataGraphNeuralAcceleratorStatisticsFeaturesARM physicalDeviceDataGraphNeuralAcceleratorStatisticsFeaturesARM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DATA_GRAPH_NEURAL_ACCELERATOR_STATISTICS_FEATURES_ARM, nullptr }; + VkPhysicalDeviceDescriptorSetHostMappingFeaturesVALVE physicalDeviceDescriptorSetHostMappingFeaturesVALVE{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_SET_HOST_MAPPING_FEATURES_VALVE, nullptr }; + VkPhysicalDeviceNestedCommandBufferFeaturesEXT physicalDeviceNestedCommandBufferFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_NESTED_COMMAND_BUFFER_FEATURES_EXT, nullptr }; + VkPhysicalDeviceShaderModuleIdentifierFeaturesEXT physicalDeviceShaderModuleIdentifierFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MODULE_IDENTIFIER_FEATURES_EXT, nullptr }; + VkPhysicalDeviceImageCompressionControlFeaturesEXT physicalDeviceImageCompressionControlFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_FEATURES_EXT, nullptr }; + VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT physicalDeviceImageCompressionControlSwapchainFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_FEATURES_EXT, nullptr }; + VkPhysicalDeviceSubpassMergeFeedbackFeaturesEXT physicalDeviceSubpassMergeFeedbackFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_MERGE_FEEDBACK_FEATURES_EXT, nullptr }; + VkPhysicalDeviceOpacityMicromapFeaturesEXT physicalDeviceOpacityMicromapFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_OPACITY_MICROMAP_FEATURES_EXT, nullptr }; +#ifdef VK_ENABLE_BETA_EXTENSIONS + VkPhysicalDeviceDisplacementMicromapFeaturesNV physicalDeviceDisplacementMicromapFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISPLACEMENT_MICROMAP_FEATURES_NV, nullptr }; +#endif + VkPhysicalDevicePipelinePropertiesFeaturesEXT physicalDevicePipelinePropertiesFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_PROPERTIES_FEATURES_EXT, nullptr }; + VkPhysicalDeviceShaderEarlyAndLateFragmentTestsFeaturesAMD physicalDeviceShaderEarlyAndLateFragmentTestsFeaturesAMD{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_EARLY_AND_LATE_FRAGMENT_TESTS_FEATURES_AMD, nullptr }; + VkPhysicalDeviceNonSeamlessCubeMapFeaturesEXT physicalDeviceNonSeamlessCubeMapFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_NON_SEAMLESS_CUBE_MAP_FEATURES_EXT, nullptr }; + VkPhysicalDevicePipelineRobustnessFeatures physicalDevicePipelineRobustnessFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_ROBUSTNESS_FEATURES, nullptr }; + VkPhysicalDeviceImageProcessingFeaturesQCOM physicalDeviceImageProcessingFeaturesQCOM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_PROCESSING_FEATURES_QCOM, nullptr }; + VkPhysicalDeviceTilePropertiesFeaturesQCOM physicalDeviceTilePropertiesFeaturesQCOM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TILE_PROPERTIES_FEATURES_QCOM, nullptr }; + VkPhysicalDeviceAmigoProfilingFeaturesSEC physicalDeviceAmigoProfilingFeaturesSEC{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_AMIGO_PROFILING_FEATURES_SEC, nullptr }; + VkPhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT physicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_FEATURES_EXT, nullptr }; + VkPhysicalDeviceAddressBindingReportFeaturesEXT physicalDeviceAddressBindingReportFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ADDRESS_BINDING_REPORT_FEATURES_EXT, nullptr }; + VkPhysicalDeviceOpticalFlowFeaturesNV physicalDeviceOpticalFlowFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_OPTICAL_FLOW_FEATURES_NV, nullptr }; + VkPhysicalDeviceFaultFeaturesEXT physicalDeviceFaultFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FAULT_FEATURES_EXT, nullptr }; + VkPhysicalDeviceFaultFeaturesKHR physicalDeviceFaultFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FAULT_FEATURES_KHR, nullptr }; + VkPhysicalDevicePipelineLibraryGroupHandlesFeaturesEXT physicalDevicePipelineLibraryGroupHandlesFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_LIBRARY_GROUP_HANDLES_FEATURES_EXT, nullptr }; + VkPhysicalDeviceShaderCoreBuiltinsFeaturesARM physicalDeviceShaderCoreBuiltinsFeaturesARM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_BUILTINS_FEATURES_ARM, nullptr }; + VkPhysicalDeviceFrameBoundaryFeaturesEXT physicalDeviceFrameBoundaryFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAME_BOUNDARY_FEATURES_EXT, nullptr }; + VkPhysicalDeviceDynamicRenderingUnusedAttachmentsFeaturesEXT physicalDeviceDynamicRenderingUnusedAttachmentsFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_UNUSED_ATTACHMENTS_FEATURES_EXT, nullptr }; + VkPhysicalDeviceInternallySynchronizedQueuesFeaturesKHR physicalDeviceInternallySynchronizedQueuesFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INTERNALLY_SYNCHRONIZED_QUEUES_FEATURES_KHR, nullptr }; + VkPhysicalDeviceSwapchainMaintenance1FeaturesKHR physicalDeviceSwapchainMaintenance1FeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_KHR, nullptr }; + VkPhysicalDeviceDepthBiasControlFeaturesEXT physicalDeviceDepthBiasControlFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_BIAS_CONTROL_FEATURES_EXT, nullptr }; + VkPhysicalDeviceRayTracingInvocationReorderFeaturesEXT physicalDeviceRayTracingInvocationReorderFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_INVOCATION_REORDER_FEATURES_EXT, nullptr }; + VkPhysicalDeviceRayTracingInvocationReorderFeaturesNV physicalDeviceRayTracingInvocationReorderFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_INVOCATION_REORDER_FEATURES_NV, nullptr }; + VkPhysicalDeviceExtendedSparseAddressSpaceFeaturesNV physicalDeviceExtendedSparseAddressSpaceFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_SPARSE_ADDRESS_SPACE_FEATURES_NV, nullptr }; + VkPhysicalDeviceMultiviewPerViewViewportsFeaturesQCOM physicalDeviceMultiviewPerViewViewportsFeaturesQCOM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_VIEWPORTS_FEATURES_QCOM, nullptr }; + VkPhysicalDeviceRayTracingPositionFetchFeaturesKHR physicalDeviceRayTracingPositionFetchFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_POSITION_FETCH_FEATURES_KHR, nullptr }; + VkPhysicalDeviceMultiviewPerViewRenderAreasFeaturesQCOM physicalDeviceMultiviewPerViewRenderAreasFeaturesQCOM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_RENDER_AREAS_FEATURES_QCOM, nullptr }; + VkPhysicalDeviceShaderObjectFeaturesEXT physicalDeviceShaderObjectFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_FEATURES_EXT, nullptr }; + VkPhysicalDeviceShaderTileImageFeaturesEXT physicalDeviceShaderTileImageFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TILE_IMAGE_FEATURES_EXT, nullptr }; +#ifdef VK_USE_PLATFORM_SCREEN_QNX + VkPhysicalDeviceExternalMemoryScreenBufferFeaturesQNX physicalDeviceExternalMemoryScreenBufferFeaturesQNX{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_SCREEN_BUFFER_FEATURES_QNX, nullptr }; +#endif + VkPhysicalDeviceCooperativeMatrixFeaturesKHR physicalDeviceCooperativeMatrixFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_KHR, nullptr }; + VkPhysicalDeviceCooperativeMatrixConversionFeaturesQCOM physicalDeviceCooperativeMatrixConversionFeaturesQCOM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_CONVERSION_FEATURES_QCOM, nullptr }; +#ifdef VK_ENABLE_BETA_EXTENSIONS + VkPhysicalDeviceShaderEnqueueFeaturesAMDX physicalDeviceShaderEnqueueFeaturesAMDX{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ENQUEUE_FEATURES_AMDX, nullptr }; +#endif + VkPhysicalDeviceAntiLagFeaturesAMD physicalDeviceAntiLagFeaturesAMD{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ANTI_LAG_FEATURES_AMD, nullptr }; + VkPhysicalDeviceTileMemoryHeapFeaturesQCOM physicalDeviceTileMemoryHeapFeaturesQCOM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TILE_MEMORY_HEAP_FEATURES_QCOM, nullptr }; + VkPhysicalDeviceCubicClampFeaturesQCOM physicalDeviceCubicClampFeaturesQCOM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUBIC_CLAMP_FEATURES_QCOM, nullptr }; + VkPhysicalDeviceYcbcrDegammaFeaturesQCOM physicalDeviceYcbcrDegammaFeaturesQCOM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_DEGAMMA_FEATURES_QCOM, nullptr }; + VkPhysicalDeviceCubicWeightsFeaturesQCOM physicalDeviceCubicWeightsFeaturesQCOM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUBIC_WEIGHTS_FEATURES_QCOM, nullptr }; + VkPhysicalDeviceImageProcessing2FeaturesQCOM physicalDeviceImageProcessing2FeaturesQCOM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_PROCESSING_2_FEATURES_QCOM, nullptr }; + VkPhysicalDeviceDescriptorPoolOverallocationFeaturesNV physicalDeviceDescriptorPoolOverallocationFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_POOL_OVERALLOCATION_FEATURES_NV, nullptr }; + VkPhysicalDevicePerStageDescriptorSetFeaturesNV physicalDevicePerStageDescriptorSetFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PER_STAGE_DESCRIPTOR_SET_FEATURES_NV, nullptr }; +#ifdef VK_USE_PLATFORM_ANDROID_KHR + VkPhysicalDeviceExternalFormatResolveFeaturesANDROID physicalDeviceExternalFormatResolveFeaturesANDROID{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FORMAT_RESOLVE_FEATURES_ANDROID, nullptr }; +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VkPhysicalDeviceCudaKernelLaunchFeaturesNV physicalDeviceCudaKernelLaunchFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUDA_KERNEL_LAUNCH_FEATURES_NV, nullptr }; +#endif + VkPhysicalDeviceSchedulingControlsFeaturesARM physicalDeviceSchedulingControlsFeaturesARM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCHEDULING_CONTROLS_FEATURES_ARM, nullptr }; + VkPhysicalDeviceRelaxedLineRasterizationFeaturesIMG physicalDeviceRelaxedLineRasterizationFeaturesIMG{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RELAXED_LINE_RASTERIZATION_FEATURES_IMG, nullptr }; + VkPhysicalDeviceRenderPassStripedFeaturesARM physicalDeviceRenderPassStripedFeaturesARM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RENDER_PASS_STRIPED_FEATURES_ARM, nullptr }; + VkPhysicalDevicePipelineOpacityMicromapFeaturesARM physicalDevicePipelineOpacityMicromapFeaturesARM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_OPACITY_MICROMAP_FEATURES_ARM, nullptr }; + VkPhysicalDeviceShaderMaximalReconvergenceFeaturesKHR physicalDeviceShaderMaximalReconvergenceFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MAXIMAL_RECONVERGENCE_FEATURES_KHR, nullptr }; + VkPhysicalDeviceShaderSubgroupRotateFeatures physicalDeviceShaderSubgroupRotateFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_ROTATE_FEATURES, nullptr }; + VkPhysicalDeviceShaderExpectAssumeFeatures physicalDeviceShaderExpectAssumeFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_EXPECT_ASSUME_FEATURES, nullptr }; + VkPhysicalDeviceShaderFloatControls2Features physicalDeviceShaderFloatControls2Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT_CONTROLS_2_FEATURES, nullptr }; + VkPhysicalDeviceDynamicRenderingLocalReadFeatures physicalDeviceDynamicRenderingLocalReadFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_LOCAL_READ_FEATURES, nullptr }; + VkPhysicalDeviceShaderQuadControlFeaturesKHR physicalDeviceShaderQuadControlFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_QUAD_CONTROL_FEATURES_KHR, nullptr }; + VkPhysicalDeviceShaderAtomicFloat16VectorFeaturesNV physicalDeviceShaderAtomicFloat16VectorFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT16_VECTOR_FEATURES_NV, nullptr }; + VkPhysicalDeviceMapMemoryPlacedFeaturesEXT physicalDeviceMapMemoryPlacedFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_FEATURES_EXT, nullptr }; + VkPhysicalDeviceShaderBfloat16FeaturesKHR physicalDeviceShaderBfloat16FeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_BFLOAT16_FEATURES_KHR, nullptr }; + VkPhysicalDeviceRawAccessChainsFeaturesNV physicalDeviceRawAccessChainsFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAW_ACCESS_CHAINS_FEATURES_NV, nullptr }; + VkPhysicalDeviceCommandBufferInheritanceFeaturesNV physicalDeviceCommandBufferInheritanceFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMMAND_BUFFER_INHERITANCE_FEATURES_NV, nullptr }; + VkPhysicalDeviceImageAlignmentControlFeaturesMESA physicalDeviceImageAlignmentControlFeaturesMESA{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ALIGNMENT_CONTROL_FEATURES_MESA, nullptr }; + VkPhysicalDeviceShaderReplicatedCompositesFeaturesEXT physicalDeviceShaderReplicatedCompositesFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_REPLICATED_COMPOSITES_FEATURES_EXT, nullptr }; + VkPhysicalDevicePresentModeFifoLatestReadyFeaturesKHR physicalDevicePresentModeFifoLatestReadyFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_MODE_FIFO_LATEST_READY_FEATURES_KHR, nullptr }; + VkPhysicalDeviceCooperativeMatrix2FeaturesNV physicalDeviceCooperativeMatrix2FeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_2_FEATURES_NV, nullptr }; + VkPhysicalDeviceHdrVividFeaturesHUAWEI physicalDeviceHdrVividFeaturesHUAWEI{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HDR_VIVID_FEATURES_HUAWEI, nullptr }; + VkPhysicalDeviceVertexAttributeRobustnessFeaturesEXT physicalDeviceVertexAttributeRobustnessFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_ROBUSTNESS_FEATURES_EXT, nullptr }; +#ifdef VK_ENABLE_BETA_EXTENSIONS + VkPhysicalDeviceDenseGeometryFormatFeaturesAMDX physicalDeviceDenseGeometryFormatFeaturesAMDX{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DENSE_GEOMETRY_FORMAT_FEATURES_AMDX, nullptr }; +#endif + VkPhysicalDeviceDepthClampZeroOneFeaturesKHR physicalDeviceDepthClampZeroOneFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLAMP_ZERO_ONE_FEATURES_KHR, nullptr }; + VkPhysicalDeviceCooperativeVectorFeaturesNV physicalDeviceCooperativeVectorFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_VECTOR_FEATURES_NV, nullptr }; + VkPhysicalDeviceTileShadingFeaturesQCOM physicalDeviceTileShadingFeaturesQCOM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TILE_SHADING_FEATURES_QCOM, nullptr }; + VkPhysicalDeviceFragmentDensityMapLayeredFeaturesVALVE physicalDeviceFragmentDensityMapLayeredFeaturesVALVE{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_LAYERED_FEATURES_VALVE, nullptr }; + VkPhysicalDevicePresentMeteringFeaturesNV physicalDevicePresentMeteringFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_METERING_FEATURES_NV, nullptr }; + VkPhysicalDeviceShaderUniformBufferUnsizedArrayFeaturesEXT physicalDeviceShaderUniformBufferUnsizedArrayFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_UNIFORM_BUFFER_UNSIZED_ARRAY_FEATURES_EXT, nullptr }; + VkPhysicalDeviceShaderMixedFloatDotProductFeaturesVALVE physicalDeviceShaderMixedFloatDotProductFeaturesVALVE{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MIXED_FLOAT_DOT_PRODUCT_FEATURES_VALVE, nullptr }; + VkPhysicalDevicePrimitiveRestartIndexFeaturesEXT physicalDevicePrimitiveRestartIndexFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_RESTART_INDEX_FEATURES_EXT, nullptr }; + VkPhysicalDeviceFormatPackFeaturesARM physicalDeviceFormatPackFeaturesARM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FORMAT_PACK_FEATURES_ARM, nullptr }; + VkPhysicalDeviceThrottleHintFeaturesSEC physicalDeviceThrottleHintFeaturesSEC{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_THROTTLE_HINT_FEATURES_SEC, nullptr }; + VkPhysicalDeviceTensorFeaturesARM physicalDeviceTensorFeaturesARM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TENSOR_FEATURES_ARM, nullptr }; + VkPhysicalDeviceDescriptorBufferTensorFeaturesARM physicalDeviceDescriptorBufferTensorFeaturesARM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_BUFFER_TENSOR_FEATURES_ARM, nullptr }; + VkPhysicalDeviceShaderFloat8FeaturesEXT physicalDeviceShaderFloat8FeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT8_FEATURES_EXT, nullptr }; + VkPhysicalDeviceDataGraphFeaturesARM physicalDeviceDataGraphFeaturesARM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DATA_GRAPH_FEATURES_ARM, nullptr }; + VkPhysicalDevicePipelineCacheIncrementalModeFeaturesSEC physicalDevicePipelineCacheIncrementalModeFeaturesSEC{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CACHE_INCREMENTAL_MODE_FEATURES_SEC, nullptr }; + VkPhysicalDeviceDataGraphModelFeaturesQCOM physicalDeviceDataGraphModelFeaturesQCOM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DATA_GRAPH_MODEL_FEATURES_QCOM, nullptr }; + VkPhysicalDeviceShaderUntypedPointersFeaturesKHR physicalDeviceShaderUntypedPointersFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_UNTYPED_POINTERS_FEATURES_KHR, nullptr }; + VkPhysicalDeviceVideoEncodeRgbConversionFeaturesVALVE physicalDeviceVideoEncodeRgbConversionFeaturesVALVE{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_RGB_CONVERSION_FEATURES_VALVE, nullptr }; + VkPhysicalDeviceShader64BitIndexingFeaturesEXT physicalDeviceShader64BitIndexingFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_64_BIT_INDEXING_FEATURES_EXT, nullptr }; + VkPhysicalDeviceQueuePerfHintFeaturesQCOM physicalDeviceQueuePerfHintFeaturesQCOM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_QUEUE_PERF_HINT_FEATURES_QCOM, nullptr }; + VkPhysicalDevicePerformanceCountersByRegionFeaturesARM physicalDevicePerformanceCountersByRegionFeaturesARM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_COUNTERS_BY_REGION_FEATURES_ARM, nullptr }; + VkPhysicalDeviceComputeOccupancyPriorityFeaturesNV physicalDeviceComputeOccupancyPriorityFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_OCCUPANCY_PRIORITY_FEATURES_NV, nullptr }; + VkPhysicalDeviceShaderLongVectorFeaturesEXT physicalDeviceShaderLongVectorFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_LONG_VECTOR_FEATURES_EXT, nullptr }; + VkPhysicalDeviceTextureCompressionASTC3DFeaturesEXT physicalDeviceTextureCompressionASTC3DFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_3D_FEATURES_EXT, nullptr }; + VkPhysicalDeviceShaderSubgroupPartitionedFeaturesEXT physicalDeviceShaderSubgroupPartitionedFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_PARTITIONED_FEATURES_EXT, nullptr }; + VkPhysicalDeviceDescriptorHeapFeaturesEXT physicalDeviceDescriptorHeapFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_HEAP_FEATURES_EXT, nullptr }; + VkPhysicalDeviceShaderInstrumentationFeaturesARM physicalDeviceShaderInstrumentationFeaturesARM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INSTRUMENTATION_FEATURES_ARM, nullptr }; + VkPhysicalDeviceDeviceAddressCommandsFeaturesKHR physicalDeviceDeviceAddressCommandsFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_ADDRESS_COMMANDS_FEATURES_KHR, nullptr }; + VkPhysicalDeviceShaderConstantDataFeaturesKHR physicalDeviceShaderConstantDataFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CONSTANT_DATA_FEATURES_KHR, nullptr }; + VkPhysicalDeviceShaderAbortFeaturesKHR physicalDeviceShaderAbortFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ABORT_FEATURES_KHR, nullptr }; + VkPhysicalDeviceDataGraphOpticalFlowFeaturesARM physicalDeviceDataGraphOpticalFlowFeaturesARM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DATA_GRAPH_OPTICAL_FLOW_FEATURES_ARM, nullptr }; + VkPhysicalDeviceFeatures2KHR physicalDeviceFeatures2KHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR, nullptr }; + + FeaturesChain() { + // Initializing all feature structures, number of Features (VkBool32) per structure. + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_CONSTANT_BANK_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_COMPUTE_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CLUSTER_ACCELERATION_STRUCTURE_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_ID_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_ID_2_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_WAIT_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_WAIT_2_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_TIMING_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_5_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_6_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_7_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_8_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_9_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_11_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_10_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_MEMORY_REPORT_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_REPRESENTATIVE_FRAGMENT_TEST_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXCLUSIVE_SCISSOR_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CORNER_SAMPLED_IMAGE_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_FOOTPRINT_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEDICATED_ALLOCATION_IMAGE_ALIASING_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COPY_MEMORY_INDIRECT_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COPY_MEMORY_INDIRECT_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_DECOMPRESSION_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INVOCATION_MASK_FEATURES_HUAWEI, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_QUERY_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_MAINTENANCE_1_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PAGEABLE_DEVICE_LOCAL_MEMORY_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_IMAGE_ARRAYS_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_BARRIER_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COVERAGE_REDUCTION_MODE_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SM_BUILTINS_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_4_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COHERENT_MEMORY_FEATURES_AMD, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BORDER_COLOR_SWIZZLE_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_3_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PARTITIONED_ACCELERATION_STRUCTURE_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DIAGNOSTICS_CONFIG_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_FEATURES_KHR, size() }); +#ifdef VK_ENABLE_BETA_EXTENSIONS + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR, size() }); +#endif + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_SHADING_FEATURES_HUAWEI, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CLUSTER_CULLING_SHADER_FEATURES_HUAWEI, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_ATOMIC_INT64_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_ENUMS_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_2D_VIEW_OF_3D_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_SLICED_VIEW_OF_3D_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_DYNAMIC_STATE_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LEGACY_VERTEX_ATTRIBUTES_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_CONTROL_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_DEVICE_MEMORY_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_RESOLVE_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLAMP_CONTROL_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_INPUT_DYNAMIC_STATE_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_RDMA_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_RELAXED_EXTENDED_INSTRUCTION_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFIED_IMAGE_LAYOUTS_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVES_GENERATED_QUERY_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LEGACY_DITHERING_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_PROTECTED_ACCESS_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_MAINTENANCE_1_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_MAINTENANCE_2_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_DECODE_VP9_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_QUANTIZATION_MAP_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_AV1_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INHERITED_VIEWPORT_SCISSOR_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_2_PLANE_444_FORMATS_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_INTRA_REFRESH_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_BUFFER_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FMA_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_MOTION_BLUR_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_VALIDATION_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_LINEAR_SWEPT_SPHERES_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RGBA10X6_FORMATS_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_MIN_LOD_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINEAR_COLOR_ATTACHMENT_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_BINARY_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DATA_GRAPH_NEURAL_ACCELERATOR_STATISTICS_FEATURES_ARM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_SET_HOST_MAPPING_FEATURES_VALVE, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_NESTED_COMMAND_BUFFER_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MODULE_IDENTIFIER_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_MERGE_FEEDBACK_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_OPACITY_MICROMAP_FEATURES_EXT, size() }); +#ifdef VK_ENABLE_BETA_EXTENSIONS + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISPLACEMENT_MICROMAP_FEATURES_NV, size() }); +#endif + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_PROPERTIES_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_EARLY_AND_LATE_FRAGMENT_TESTS_FEATURES_AMD, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_NON_SEAMLESS_CUBE_MAP_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_ROBUSTNESS_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_PROCESSING_FEATURES_QCOM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TILE_PROPERTIES_FEATURES_QCOM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_AMIGO_PROFILING_FEATURES_SEC, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ADDRESS_BINDING_REPORT_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_OPTICAL_FLOW_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FAULT_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FAULT_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_LIBRARY_GROUP_HANDLES_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_BUILTINS_FEATURES_ARM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAME_BOUNDARY_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_UNUSED_ATTACHMENTS_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INTERNALLY_SYNCHRONIZED_QUEUES_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_BIAS_CONTROL_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_INVOCATION_REORDER_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_INVOCATION_REORDER_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_SPARSE_ADDRESS_SPACE_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_VIEWPORTS_FEATURES_QCOM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_POSITION_FETCH_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_RENDER_AREAS_FEATURES_QCOM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TILE_IMAGE_FEATURES_EXT, size() }); +#ifdef VK_USE_PLATFORM_SCREEN_QNX + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_SCREEN_BUFFER_FEATURES_QNX, size() }); +#endif + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_CONVERSION_FEATURES_QCOM, size() }); +#ifdef VK_ENABLE_BETA_EXTENSIONS + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ENQUEUE_FEATURES_AMDX, size() }); +#endif + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ANTI_LAG_FEATURES_AMD, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TILE_MEMORY_HEAP_FEATURES_QCOM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUBIC_CLAMP_FEATURES_QCOM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_DEGAMMA_FEATURES_QCOM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUBIC_WEIGHTS_FEATURES_QCOM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_PROCESSING_2_FEATURES_QCOM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_POOL_OVERALLOCATION_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PER_STAGE_DESCRIPTOR_SET_FEATURES_NV, size() }); +#ifdef VK_USE_PLATFORM_ANDROID_KHR + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FORMAT_RESOLVE_FEATURES_ANDROID, size() }); +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUDA_KERNEL_LAUNCH_FEATURES_NV, size() }); +#endif + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCHEDULING_CONTROLS_FEATURES_ARM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RELAXED_LINE_RASTERIZATION_FEATURES_IMG, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RENDER_PASS_STRIPED_FEATURES_ARM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_OPACITY_MICROMAP_FEATURES_ARM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MAXIMAL_RECONVERGENCE_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_ROTATE_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_EXPECT_ASSUME_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT_CONTROLS_2_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_LOCAL_READ_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_QUAD_CONTROL_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT16_VECTOR_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_BFLOAT16_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAW_ACCESS_CHAINS_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMMAND_BUFFER_INHERITANCE_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ALIGNMENT_CONTROL_FEATURES_MESA, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_REPLICATED_COMPOSITES_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_MODE_FIFO_LATEST_READY_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_2_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HDR_VIVID_FEATURES_HUAWEI, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_ROBUSTNESS_FEATURES_EXT, size() }); +#ifdef VK_ENABLE_BETA_EXTENSIONS + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DENSE_GEOMETRY_FORMAT_FEATURES_AMDX, size() }); +#endif + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLAMP_ZERO_ONE_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_VECTOR_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TILE_SHADING_FEATURES_QCOM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_LAYERED_FEATURES_VALVE, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_METERING_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_UNIFORM_BUFFER_UNSIZED_ARRAY_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MIXED_FLOAT_DOT_PRODUCT_FEATURES_VALVE, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_RESTART_INDEX_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FORMAT_PACK_FEATURES_ARM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_THROTTLE_HINT_FEATURES_SEC, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TENSOR_FEATURES_ARM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_BUFFER_TENSOR_FEATURES_ARM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT8_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DATA_GRAPH_FEATURES_ARM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CACHE_INCREMENTAL_MODE_FEATURES_SEC, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DATA_GRAPH_MODEL_FEATURES_QCOM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_UNTYPED_POINTERS_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_RGB_CONVERSION_FEATURES_VALVE, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_64_BIT_INDEXING_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_QUEUE_PERF_HINT_FEATURES_QCOM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_COUNTERS_BY_REGION_FEATURES_ARM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_OCCUPANCY_PRIORITY_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_LONG_VECTOR_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_3D_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_PARTITIONED_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_HEAP_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INSTRUMENTATION_FEATURES_ARM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_ADDRESS_COMMANDS_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CONSTANT_DATA_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ABORT_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DATA_GRAPH_OPTICAL_FLOW_FEATURES_ARM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR, size() }); + + //Initializing the full list of available structure features + void* pNext = nullptr; + physicalDeviceDeviceGeneratedCommandsFeaturesNV.pNext = pNext; + pNext = &physicalDeviceDeviceGeneratedCommandsFeaturesNV; + physicalDevicePushConstantBankFeaturesNV.pNext = pNext; + pNext = &physicalDevicePushConstantBankFeaturesNV; + physicalDeviceDeviceGeneratedCommandsComputeFeaturesNV.pNext = pNext; + pNext = &physicalDeviceDeviceGeneratedCommandsComputeFeaturesNV; + physicalDevicePrivateDataFeatures.pNext = pNext; + pNext = &physicalDevicePrivateDataFeatures; + physicalDeviceClusterAccelerationStructureFeaturesNV.pNext = pNext; + pNext = &physicalDeviceClusterAccelerationStructureFeaturesNV; + physicalDeviceVariablePointersFeatures.pNext = pNext; + pNext = &physicalDeviceVariablePointersFeatures; + physicalDeviceMultiviewFeatures.pNext = pNext; + pNext = &physicalDeviceMultiviewFeatures; + physicalDevicePresentIdFeaturesKHR.pNext = pNext; + pNext = &physicalDevicePresentIdFeaturesKHR; + physicalDevicePresentId2FeaturesKHR.pNext = pNext; + pNext = &physicalDevicePresentId2FeaturesKHR; + physicalDevicePresentWaitFeaturesKHR.pNext = pNext; + pNext = &physicalDevicePresentWaitFeaturesKHR; + physicalDevicePresentWait2FeaturesKHR.pNext = pNext; + pNext = &physicalDevicePresentWait2FeaturesKHR; + physicalDevicePresentTimingFeaturesEXT.pNext = pNext; + pNext = &physicalDevicePresentTimingFeaturesEXT; + physicalDevice16BitStorageFeatures.pNext = pNext; + pNext = &physicalDevice16BitStorageFeatures; + physicalDeviceShaderSubgroupExtendedTypesFeatures.pNext = pNext; + pNext = &physicalDeviceShaderSubgroupExtendedTypesFeatures; + physicalDeviceSamplerYcbcrConversionFeatures.pNext = pNext; + pNext = &physicalDeviceSamplerYcbcrConversionFeatures; + physicalDeviceProtectedMemoryFeatures.pNext = pNext; + pNext = &physicalDeviceProtectedMemoryFeatures; + physicalDeviceBlendOperationAdvancedFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceBlendOperationAdvancedFeaturesEXT; + physicalDeviceMultiDrawFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceMultiDrawFeaturesEXT; + physicalDeviceInlineUniformBlockFeatures.pNext = pNext; + pNext = &physicalDeviceInlineUniformBlockFeatures; + physicalDeviceMaintenance4Features.pNext = pNext; + pNext = &physicalDeviceMaintenance4Features; + physicalDeviceMaintenance5Features.pNext = pNext; + pNext = &physicalDeviceMaintenance5Features; + physicalDeviceMaintenance6Features.pNext = pNext; + pNext = &physicalDeviceMaintenance6Features; + physicalDeviceMaintenance7FeaturesKHR.pNext = pNext; + pNext = &physicalDeviceMaintenance7FeaturesKHR; + physicalDeviceMaintenance8FeaturesKHR.pNext = pNext; + pNext = &physicalDeviceMaintenance8FeaturesKHR; + physicalDeviceMaintenance9FeaturesKHR.pNext = pNext; + pNext = &physicalDeviceMaintenance9FeaturesKHR; + physicalDeviceMaintenance11FeaturesKHR.pNext = pNext; + pNext = &physicalDeviceMaintenance11FeaturesKHR; + physicalDeviceMaintenance10FeaturesKHR.pNext = pNext; + pNext = &physicalDeviceMaintenance10FeaturesKHR; + physicalDeviceShaderDrawParametersFeatures.pNext = pNext; + pNext = &physicalDeviceShaderDrawParametersFeatures; + physicalDeviceShaderFloat16Int8Features.pNext = pNext; + pNext = &physicalDeviceShaderFloat16Int8Features; + physicalDeviceHostQueryResetFeatures.pNext = pNext; + pNext = &physicalDeviceHostQueryResetFeatures; + physicalDeviceGlobalPriorityQueryFeatures.pNext = pNext; + pNext = &physicalDeviceGlobalPriorityQueryFeatures; + physicalDeviceDeviceMemoryReportFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceDeviceMemoryReportFeaturesEXT; + physicalDeviceDescriptorIndexingFeatures.pNext = pNext; + pNext = &physicalDeviceDescriptorIndexingFeatures; + physicalDeviceTimelineSemaphoreFeatures.pNext = pNext; + pNext = &physicalDeviceTimelineSemaphoreFeatures; + physicalDevice8BitStorageFeatures.pNext = pNext; + pNext = &physicalDevice8BitStorageFeatures; + physicalDeviceConditionalRenderingFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceConditionalRenderingFeaturesEXT; + physicalDeviceVulkanMemoryModelFeatures.pNext = pNext; + pNext = &physicalDeviceVulkanMemoryModelFeatures; + physicalDeviceShaderAtomicInt64Features.pNext = pNext; + pNext = &physicalDeviceShaderAtomicInt64Features; + physicalDeviceShaderAtomicFloatFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceShaderAtomicFloatFeaturesEXT; + physicalDeviceShaderAtomicFloat2FeaturesEXT.pNext = pNext; + pNext = &physicalDeviceShaderAtomicFloat2FeaturesEXT; + physicalDeviceVertexAttributeDivisorFeatures.pNext = pNext; + pNext = &physicalDeviceVertexAttributeDivisorFeatures; + physicalDeviceASTCDecodeFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceASTCDecodeFeaturesEXT; + physicalDeviceTransformFeedbackFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceTransformFeedbackFeaturesEXT; + physicalDeviceRepresentativeFragmentTestFeaturesNV.pNext = pNext; + pNext = &physicalDeviceRepresentativeFragmentTestFeaturesNV; + physicalDeviceExclusiveScissorFeaturesNV.pNext = pNext; + pNext = &physicalDeviceExclusiveScissorFeaturesNV; + physicalDeviceCornerSampledImageFeaturesNV.pNext = pNext; + pNext = &physicalDeviceCornerSampledImageFeaturesNV; + physicalDeviceComputeShaderDerivativesFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceComputeShaderDerivativesFeaturesKHR; + physicalDeviceShaderImageFootprintFeaturesNV.pNext = pNext; + pNext = &physicalDeviceShaderImageFootprintFeaturesNV; + physicalDeviceDedicatedAllocationImageAliasingFeaturesNV.pNext = pNext; + pNext = &physicalDeviceDedicatedAllocationImageAliasingFeaturesNV; + physicalDeviceCopyMemoryIndirectFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceCopyMemoryIndirectFeaturesKHR; + physicalDeviceCopyMemoryIndirectFeaturesNV.pNext = pNext; + pNext = &physicalDeviceCopyMemoryIndirectFeaturesNV; + physicalDeviceMemoryDecompressionFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceMemoryDecompressionFeaturesEXT; + physicalDeviceShadingRateImageFeaturesNV.pNext = pNext; + pNext = &physicalDeviceShadingRateImageFeaturesNV; + physicalDeviceInvocationMaskFeaturesHUAWEI.pNext = pNext; + pNext = &physicalDeviceInvocationMaskFeaturesHUAWEI; + physicalDeviceMeshShaderFeaturesNV.pNext = pNext; + pNext = &physicalDeviceMeshShaderFeaturesNV; + physicalDeviceMeshShaderFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceMeshShaderFeaturesEXT; + physicalDeviceAccelerationStructureFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceAccelerationStructureFeaturesKHR; + physicalDeviceRayTracingPipelineFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceRayTracingPipelineFeaturesKHR; + physicalDeviceRayQueryFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceRayQueryFeaturesKHR; + physicalDeviceRayTracingMaintenance1FeaturesKHR.pNext = pNext; + pNext = &physicalDeviceRayTracingMaintenance1FeaturesKHR; + physicalDeviceFragmentDensityMapFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceFragmentDensityMapFeaturesEXT; + physicalDeviceFragmentDensityMap2FeaturesEXT.pNext = pNext; + pNext = &physicalDeviceFragmentDensityMap2FeaturesEXT; + physicalDeviceFragmentDensityMapOffsetFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceFragmentDensityMapOffsetFeaturesEXT; + physicalDeviceScalarBlockLayoutFeatures.pNext = pNext; + pNext = &physicalDeviceScalarBlockLayoutFeatures; + physicalDeviceUniformBufferStandardLayoutFeatures.pNext = pNext; + pNext = &physicalDeviceUniformBufferStandardLayoutFeatures; + physicalDeviceDepthClipEnableFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceDepthClipEnableFeaturesEXT; + physicalDeviceMemoryPriorityFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceMemoryPriorityFeaturesEXT; + physicalDevicePageableDeviceLocalMemoryFeaturesEXT.pNext = pNext; + pNext = &physicalDevicePageableDeviceLocalMemoryFeaturesEXT; + physicalDeviceBufferDeviceAddressFeatures.pNext = pNext; + pNext = &physicalDeviceBufferDeviceAddressFeatures; + physicalDeviceBufferDeviceAddressFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceBufferDeviceAddressFeaturesEXT; + physicalDeviceImagelessFramebufferFeatures.pNext = pNext; + pNext = &physicalDeviceImagelessFramebufferFeatures; + physicalDeviceTextureCompressionASTCHDRFeatures.pNext = pNext; + pNext = &physicalDeviceTextureCompressionASTCHDRFeatures; + physicalDeviceCooperativeMatrixFeaturesNV.pNext = pNext; + pNext = &physicalDeviceCooperativeMatrixFeaturesNV; + physicalDeviceYcbcrImageArraysFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceYcbcrImageArraysFeaturesEXT; + physicalDevicePresentBarrierFeaturesNV.pNext = pNext; + pNext = &physicalDevicePresentBarrierFeaturesNV; + physicalDevicePerformanceQueryFeaturesKHR.pNext = pNext; + pNext = &physicalDevicePerformanceQueryFeaturesKHR; + physicalDeviceCoverageReductionModeFeaturesNV.pNext = pNext; + pNext = &physicalDeviceCoverageReductionModeFeaturesNV; + physicalDeviceShaderIntegerFunctions2FeaturesINTEL.pNext = pNext; + pNext = &physicalDeviceShaderIntegerFunctions2FeaturesINTEL; + physicalDeviceShaderClockFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceShaderClockFeaturesKHR; + physicalDeviceIndexTypeUint8Features.pNext = pNext; + pNext = &physicalDeviceIndexTypeUint8Features; + physicalDeviceShaderSMBuiltinsFeaturesNV.pNext = pNext; + pNext = &physicalDeviceShaderSMBuiltinsFeaturesNV; + physicalDeviceFragmentShaderInterlockFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceFragmentShaderInterlockFeaturesEXT; + physicalDeviceSeparateDepthStencilLayoutsFeatures.pNext = pNext; + pNext = &physicalDeviceSeparateDepthStencilLayoutsFeatures; + physicalDevicePrimitiveTopologyListRestartFeaturesEXT.pNext = pNext; + pNext = &physicalDevicePrimitiveTopologyListRestartFeaturesEXT; + physicalDevicePipelineExecutablePropertiesFeaturesKHR.pNext = pNext; + pNext = &physicalDevicePipelineExecutablePropertiesFeaturesKHR; + physicalDeviceShaderDemoteToHelperInvocationFeatures.pNext = pNext; + pNext = &physicalDeviceShaderDemoteToHelperInvocationFeatures; + physicalDeviceTexelBufferAlignmentFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceTexelBufferAlignmentFeaturesEXT; + physicalDeviceSubgroupSizeControlFeatures.pNext = pNext; + pNext = &physicalDeviceSubgroupSizeControlFeatures; + physicalDeviceLineRasterizationFeatures.pNext = pNext; + pNext = &physicalDeviceLineRasterizationFeatures; + physicalDevicePipelineCreationCacheControlFeatures.pNext = pNext; + pNext = &physicalDevicePipelineCreationCacheControlFeatures; + physicalDeviceVulkan11Features.pNext = pNext; + pNext = &physicalDeviceVulkan11Features; + physicalDeviceVulkan12Features.pNext = pNext; + pNext = &physicalDeviceVulkan12Features; + physicalDeviceVulkan13Features.pNext = pNext; + pNext = &physicalDeviceVulkan13Features; + physicalDeviceVulkan14Features.pNext = pNext; + pNext = &physicalDeviceVulkan14Features; + physicalDeviceCoherentMemoryFeaturesAMD.pNext = pNext; + pNext = &physicalDeviceCoherentMemoryFeaturesAMD; + physicalDeviceCustomBorderColorFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceCustomBorderColorFeaturesEXT; + physicalDeviceBorderColorSwizzleFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceBorderColorSwizzleFeaturesEXT; + physicalDeviceExtendedDynamicStateFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceExtendedDynamicStateFeaturesEXT; + physicalDeviceExtendedDynamicState2FeaturesEXT.pNext = pNext; + pNext = &physicalDeviceExtendedDynamicState2FeaturesEXT; + physicalDeviceExtendedDynamicState3FeaturesEXT.pNext = pNext; + pNext = &physicalDeviceExtendedDynamicState3FeaturesEXT; + physicalDevicePartitionedAccelerationStructureFeaturesNV.pNext = pNext; + pNext = &physicalDevicePartitionedAccelerationStructureFeaturesNV; + physicalDeviceDiagnosticsConfigFeaturesNV.pNext = pNext; + pNext = &physicalDeviceDiagnosticsConfigFeaturesNV; + physicalDeviceZeroInitializeWorkgroupMemoryFeatures.pNext = pNext; + pNext = &physicalDeviceZeroInitializeWorkgroupMemoryFeatures; + physicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR; + physicalDeviceRobustness2FeaturesKHR.pNext = pNext; + pNext = &physicalDeviceRobustness2FeaturesKHR; + physicalDeviceImageRobustnessFeatures.pNext = pNext; + pNext = &physicalDeviceImageRobustnessFeatures; + physicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR; +#ifdef VK_ENABLE_BETA_EXTENSIONS + physicalDevicePortabilitySubsetFeaturesKHR.pNext = pNext; + pNext = &physicalDevicePortabilitySubsetFeaturesKHR; +#endif + physicalDevice4444FormatsFeaturesEXT.pNext = pNext; + pNext = &physicalDevice4444FormatsFeaturesEXT; + physicalDeviceSubpassShadingFeaturesHUAWEI.pNext = pNext; + pNext = &physicalDeviceSubpassShadingFeaturesHUAWEI; + physicalDeviceClusterCullingShaderFeaturesHUAWEI.pNext = pNext; + pNext = &physicalDeviceClusterCullingShaderFeaturesHUAWEI; + physicalDeviceShaderImageAtomicInt64FeaturesEXT.pNext = pNext; + pNext = &physicalDeviceShaderImageAtomicInt64FeaturesEXT; + physicalDeviceFragmentShadingRateFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceFragmentShadingRateFeaturesKHR; + physicalDeviceShaderTerminateInvocationFeatures.pNext = pNext; + pNext = &physicalDeviceShaderTerminateInvocationFeatures; + physicalDeviceFragmentShadingRateEnumsFeaturesNV.pNext = pNext; + pNext = &physicalDeviceFragmentShadingRateEnumsFeaturesNV; + physicalDeviceImage2DViewOf3DFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceImage2DViewOf3DFeaturesEXT; + physicalDeviceImageSlicedViewOf3DFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceImageSlicedViewOf3DFeaturesEXT; + physicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT; + physicalDeviceLegacyVertexAttributesFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceLegacyVertexAttributesFeaturesEXT; + physicalDeviceMutableDescriptorTypeFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceMutableDescriptorTypeFeaturesEXT; + physicalDeviceDepthClipControlFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceDepthClipControlFeaturesEXT; + physicalDeviceZeroInitializeDeviceMemoryFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceZeroInitializeDeviceMemoryFeaturesEXT; + physicalDeviceCustomResolveFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceCustomResolveFeaturesEXT; + physicalDeviceDeviceGeneratedCommandsFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceDeviceGeneratedCommandsFeaturesEXT; + physicalDeviceDepthClampControlFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceDepthClampControlFeaturesEXT; + physicalDeviceVertexInputDynamicStateFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceVertexInputDynamicStateFeaturesEXT; + physicalDeviceExternalMemoryRDMAFeaturesNV.pNext = pNext; + pNext = &physicalDeviceExternalMemoryRDMAFeaturesNV; + physicalDeviceShaderRelaxedExtendedInstructionFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceShaderRelaxedExtendedInstructionFeaturesKHR; + physicalDeviceColorWriteEnableFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceColorWriteEnableFeaturesEXT; + physicalDeviceSynchronization2Features.pNext = pNext; + pNext = &physicalDeviceSynchronization2Features; + physicalDeviceUnifiedImageLayoutsFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceUnifiedImageLayoutsFeaturesKHR; + physicalDeviceHostImageCopyFeatures.pNext = pNext; + pNext = &physicalDeviceHostImageCopyFeatures; + physicalDevicePrimitivesGeneratedQueryFeaturesEXT.pNext = pNext; + pNext = &physicalDevicePrimitivesGeneratedQueryFeaturesEXT; + physicalDeviceLegacyDitheringFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceLegacyDitheringFeaturesEXT; + physicalDeviceMultisampledRenderToSingleSampledFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceMultisampledRenderToSingleSampledFeaturesEXT; + physicalDevicePipelineProtectedAccessFeatures.pNext = pNext; + pNext = &physicalDevicePipelineProtectedAccessFeatures; + physicalDeviceVideoMaintenance1FeaturesKHR.pNext = pNext; + pNext = &physicalDeviceVideoMaintenance1FeaturesKHR; + physicalDeviceVideoMaintenance2FeaturesKHR.pNext = pNext; + pNext = &physicalDeviceVideoMaintenance2FeaturesKHR; + physicalDeviceVideoDecodeVP9FeaturesKHR.pNext = pNext; + pNext = &physicalDeviceVideoDecodeVP9FeaturesKHR; + physicalDeviceVideoEncodeQuantizationMapFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceVideoEncodeQuantizationMapFeaturesKHR; + physicalDeviceVideoEncodeAV1FeaturesKHR.pNext = pNext; + pNext = &physicalDeviceVideoEncodeAV1FeaturesKHR; + physicalDeviceInheritedViewportScissorFeaturesNV.pNext = pNext; + pNext = &physicalDeviceInheritedViewportScissorFeaturesNV; + physicalDeviceYcbcr2Plane444FormatsFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceYcbcr2Plane444FormatsFeaturesEXT; + physicalDeviceProvokingVertexFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceProvokingVertexFeaturesEXT; + physicalDeviceVideoEncodeIntraRefreshFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceVideoEncodeIntraRefreshFeaturesKHR; + physicalDeviceDescriptorBufferFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceDescriptorBufferFeaturesEXT; + physicalDeviceShaderIntegerDotProductFeatures.pNext = pNext; + pNext = &physicalDeviceShaderIntegerDotProductFeatures; + physicalDeviceFragmentShaderBarycentricFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceFragmentShaderBarycentricFeaturesKHR; + physicalDeviceShaderFmaFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceShaderFmaFeaturesKHR; + physicalDeviceRayTracingMotionBlurFeaturesNV.pNext = pNext; + pNext = &physicalDeviceRayTracingMotionBlurFeaturesNV; + physicalDeviceRayTracingValidationFeaturesNV.pNext = pNext; + pNext = &physicalDeviceRayTracingValidationFeaturesNV; + physicalDeviceRayTracingLinearSweptSpheresFeaturesNV.pNext = pNext; + pNext = &physicalDeviceRayTracingLinearSweptSpheresFeaturesNV; + physicalDeviceRGBA10X6FormatsFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceRGBA10X6FormatsFeaturesEXT; + physicalDeviceDynamicRenderingFeatures.pNext = pNext; + pNext = &physicalDeviceDynamicRenderingFeatures; + physicalDeviceImageViewMinLodFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceImageViewMinLodFeaturesEXT; + physicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT; + physicalDeviceLinearColorAttachmentFeaturesNV.pNext = pNext; + pNext = &physicalDeviceLinearColorAttachmentFeaturesNV; + physicalDeviceGraphicsPipelineLibraryFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceGraphicsPipelineLibraryFeaturesEXT; + physicalDevicePipelineBinaryFeaturesKHR.pNext = pNext; + pNext = &physicalDevicePipelineBinaryFeaturesKHR; + physicalDeviceDataGraphNeuralAcceleratorStatisticsFeaturesARM.pNext = pNext; + pNext = &physicalDeviceDataGraphNeuralAcceleratorStatisticsFeaturesARM; + physicalDeviceDescriptorSetHostMappingFeaturesVALVE.pNext = pNext; + pNext = &physicalDeviceDescriptorSetHostMappingFeaturesVALVE; + physicalDeviceNestedCommandBufferFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceNestedCommandBufferFeaturesEXT; + physicalDeviceShaderModuleIdentifierFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceShaderModuleIdentifierFeaturesEXT; + physicalDeviceImageCompressionControlFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceImageCompressionControlFeaturesEXT; + physicalDeviceImageCompressionControlSwapchainFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceImageCompressionControlSwapchainFeaturesEXT; + physicalDeviceSubpassMergeFeedbackFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceSubpassMergeFeedbackFeaturesEXT; + physicalDeviceOpacityMicromapFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceOpacityMicromapFeaturesEXT; +#ifdef VK_ENABLE_BETA_EXTENSIONS + physicalDeviceDisplacementMicromapFeaturesNV.pNext = pNext; + pNext = &physicalDeviceDisplacementMicromapFeaturesNV; +#endif + physicalDevicePipelinePropertiesFeaturesEXT.pNext = pNext; + pNext = &physicalDevicePipelinePropertiesFeaturesEXT; + physicalDeviceShaderEarlyAndLateFragmentTestsFeaturesAMD.pNext = pNext; + pNext = &physicalDeviceShaderEarlyAndLateFragmentTestsFeaturesAMD; + physicalDeviceNonSeamlessCubeMapFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceNonSeamlessCubeMapFeaturesEXT; + physicalDevicePipelineRobustnessFeatures.pNext = pNext; + pNext = &physicalDevicePipelineRobustnessFeatures; + physicalDeviceImageProcessingFeaturesQCOM.pNext = pNext; + pNext = &physicalDeviceImageProcessingFeaturesQCOM; + physicalDeviceTilePropertiesFeaturesQCOM.pNext = pNext; + pNext = &physicalDeviceTilePropertiesFeaturesQCOM; + physicalDeviceAmigoProfilingFeaturesSEC.pNext = pNext; + pNext = &physicalDeviceAmigoProfilingFeaturesSEC; + physicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT; + physicalDeviceAddressBindingReportFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceAddressBindingReportFeaturesEXT; + physicalDeviceOpticalFlowFeaturesNV.pNext = pNext; + pNext = &physicalDeviceOpticalFlowFeaturesNV; + physicalDeviceFaultFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceFaultFeaturesEXT; + physicalDeviceFaultFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceFaultFeaturesKHR; + physicalDevicePipelineLibraryGroupHandlesFeaturesEXT.pNext = pNext; + pNext = &physicalDevicePipelineLibraryGroupHandlesFeaturesEXT; + physicalDeviceShaderCoreBuiltinsFeaturesARM.pNext = pNext; + pNext = &physicalDeviceShaderCoreBuiltinsFeaturesARM; + physicalDeviceFrameBoundaryFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceFrameBoundaryFeaturesEXT; + physicalDeviceDynamicRenderingUnusedAttachmentsFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceDynamicRenderingUnusedAttachmentsFeaturesEXT; + physicalDeviceInternallySynchronizedQueuesFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceInternallySynchronizedQueuesFeaturesKHR; + physicalDeviceSwapchainMaintenance1FeaturesKHR.pNext = pNext; + pNext = &physicalDeviceSwapchainMaintenance1FeaturesKHR; + physicalDeviceDepthBiasControlFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceDepthBiasControlFeaturesEXT; + physicalDeviceRayTracingInvocationReorderFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceRayTracingInvocationReorderFeaturesEXT; + physicalDeviceRayTracingInvocationReorderFeaturesNV.pNext = pNext; + pNext = &physicalDeviceRayTracingInvocationReorderFeaturesNV; + physicalDeviceExtendedSparseAddressSpaceFeaturesNV.pNext = pNext; + pNext = &physicalDeviceExtendedSparseAddressSpaceFeaturesNV; + physicalDeviceMultiviewPerViewViewportsFeaturesQCOM.pNext = pNext; + pNext = &physicalDeviceMultiviewPerViewViewportsFeaturesQCOM; + physicalDeviceRayTracingPositionFetchFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceRayTracingPositionFetchFeaturesKHR; + physicalDeviceMultiviewPerViewRenderAreasFeaturesQCOM.pNext = pNext; + pNext = &physicalDeviceMultiviewPerViewRenderAreasFeaturesQCOM; + physicalDeviceShaderObjectFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceShaderObjectFeaturesEXT; + physicalDeviceShaderTileImageFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceShaderTileImageFeaturesEXT; +#ifdef VK_USE_PLATFORM_SCREEN_QNX + physicalDeviceExternalMemoryScreenBufferFeaturesQNX.pNext = pNext; + pNext = &physicalDeviceExternalMemoryScreenBufferFeaturesQNX; +#endif + physicalDeviceCooperativeMatrixFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceCooperativeMatrixFeaturesKHR; + physicalDeviceCooperativeMatrixConversionFeaturesQCOM.pNext = pNext; + pNext = &physicalDeviceCooperativeMatrixConversionFeaturesQCOM; +#ifdef VK_ENABLE_BETA_EXTENSIONS + physicalDeviceShaderEnqueueFeaturesAMDX.pNext = pNext; + pNext = &physicalDeviceShaderEnqueueFeaturesAMDX; +#endif + physicalDeviceAntiLagFeaturesAMD.pNext = pNext; + pNext = &physicalDeviceAntiLagFeaturesAMD; + physicalDeviceTileMemoryHeapFeaturesQCOM.pNext = pNext; + pNext = &physicalDeviceTileMemoryHeapFeaturesQCOM; + physicalDeviceCubicClampFeaturesQCOM.pNext = pNext; + pNext = &physicalDeviceCubicClampFeaturesQCOM; + physicalDeviceYcbcrDegammaFeaturesQCOM.pNext = pNext; + pNext = &physicalDeviceYcbcrDegammaFeaturesQCOM; + physicalDeviceCubicWeightsFeaturesQCOM.pNext = pNext; + pNext = &physicalDeviceCubicWeightsFeaturesQCOM; + physicalDeviceImageProcessing2FeaturesQCOM.pNext = pNext; + pNext = &physicalDeviceImageProcessing2FeaturesQCOM; + physicalDeviceDescriptorPoolOverallocationFeaturesNV.pNext = pNext; + pNext = &physicalDeviceDescriptorPoolOverallocationFeaturesNV; + physicalDevicePerStageDescriptorSetFeaturesNV.pNext = pNext; + pNext = &physicalDevicePerStageDescriptorSetFeaturesNV; +#ifdef VK_USE_PLATFORM_ANDROID_KHR + physicalDeviceExternalFormatResolveFeaturesANDROID.pNext = pNext; + pNext = &physicalDeviceExternalFormatResolveFeaturesANDROID; +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + physicalDeviceCudaKernelLaunchFeaturesNV.pNext = pNext; + pNext = &physicalDeviceCudaKernelLaunchFeaturesNV; +#endif + physicalDeviceSchedulingControlsFeaturesARM.pNext = pNext; + pNext = &physicalDeviceSchedulingControlsFeaturesARM; + physicalDeviceRelaxedLineRasterizationFeaturesIMG.pNext = pNext; + pNext = &physicalDeviceRelaxedLineRasterizationFeaturesIMG; + physicalDeviceRenderPassStripedFeaturesARM.pNext = pNext; + pNext = &physicalDeviceRenderPassStripedFeaturesARM; + physicalDevicePipelineOpacityMicromapFeaturesARM.pNext = pNext; + pNext = &physicalDevicePipelineOpacityMicromapFeaturesARM; + physicalDeviceShaderMaximalReconvergenceFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceShaderMaximalReconvergenceFeaturesKHR; + physicalDeviceShaderSubgroupRotateFeatures.pNext = pNext; + pNext = &physicalDeviceShaderSubgroupRotateFeatures; + physicalDeviceShaderExpectAssumeFeatures.pNext = pNext; + pNext = &physicalDeviceShaderExpectAssumeFeatures; + physicalDeviceShaderFloatControls2Features.pNext = pNext; + pNext = &physicalDeviceShaderFloatControls2Features; + physicalDeviceDynamicRenderingLocalReadFeatures.pNext = pNext; + pNext = &physicalDeviceDynamicRenderingLocalReadFeatures; + physicalDeviceShaderQuadControlFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceShaderQuadControlFeaturesKHR; + physicalDeviceShaderAtomicFloat16VectorFeaturesNV.pNext = pNext; + pNext = &physicalDeviceShaderAtomicFloat16VectorFeaturesNV; + physicalDeviceMapMemoryPlacedFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceMapMemoryPlacedFeaturesEXT; + physicalDeviceShaderBfloat16FeaturesKHR.pNext = pNext; + pNext = &physicalDeviceShaderBfloat16FeaturesKHR; + physicalDeviceRawAccessChainsFeaturesNV.pNext = pNext; + pNext = &physicalDeviceRawAccessChainsFeaturesNV; + physicalDeviceCommandBufferInheritanceFeaturesNV.pNext = pNext; + pNext = &physicalDeviceCommandBufferInheritanceFeaturesNV; + physicalDeviceImageAlignmentControlFeaturesMESA.pNext = pNext; + pNext = &physicalDeviceImageAlignmentControlFeaturesMESA; + physicalDeviceShaderReplicatedCompositesFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceShaderReplicatedCompositesFeaturesEXT; + physicalDevicePresentModeFifoLatestReadyFeaturesKHR.pNext = pNext; + pNext = &physicalDevicePresentModeFifoLatestReadyFeaturesKHR; + physicalDeviceCooperativeMatrix2FeaturesNV.pNext = pNext; + pNext = &physicalDeviceCooperativeMatrix2FeaturesNV; + physicalDeviceHdrVividFeaturesHUAWEI.pNext = pNext; + pNext = &physicalDeviceHdrVividFeaturesHUAWEI; + physicalDeviceVertexAttributeRobustnessFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceVertexAttributeRobustnessFeaturesEXT; +#ifdef VK_ENABLE_BETA_EXTENSIONS + physicalDeviceDenseGeometryFormatFeaturesAMDX.pNext = pNext; + pNext = &physicalDeviceDenseGeometryFormatFeaturesAMDX; +#endif + physicalDeviceDepthClampZeroOneFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceDepthClampZeroOneFeaturesKHR; + physicalDeviceCooperativeVectorFeaturesNV.pNext = pNext; + pNext = &physicalDeviceCooperativeVectorFeaturesNV; + physicalDeviceTileShadingFeaturesQCOM.pNext = pNext; + pNext = &physicalDeviceTileShadingFeaturesQCOM; + physicalDeviceFragmentDensityMapLayeredFeaturesVALVE.pNext = pNext; + pNext = &physicalDeviceFragmentDensityMapLayeredFeaturesVALVE; + physicalDevicePresentMeteringFeaturesNV.pNext = pNext; + pNext = &physicalDevicePresentMeteringFeaturesNV; + physicalDeviceShaderUniformBufferUnsizedArrayFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceShaderUniformBufferUnsizedArrayFeaturesEXT; + physicalDeviceShaderMixedFloatDotProductFeaturesVALVE.pNext = pNext; + pNext = &physicalDeviceShaderMixedFloatDotProductFeaturesVALVE; + physicalDevicePrimitiveRestartIndexFeaturesEXT.pNext = pNext; + pNext = &physicalDevicePrimitiveRestartIndexFeaturesEXT; + physicalDeviceFormatPackFeaturesARM.pNext = pNext; + pNext = &physicalDeviceFormatPackFeaturesARM; + physicalDeviceThrottleHintFeaturesSEC.pNext = pNext; + pNext = &physicalDeviceThrottleHintFeaturesSEC; + physicalDeviceTensorFeaturesARM.pNext = pNext; + pNext = &physicalDeviceTensorFeaturesARM; + physicalDeviceDescriptorBufferTensorFeaturesARM.pNext = pNext; + pNext = &physicalDeviceDescriptorBufferTensorFeaturesARM; + physicalDeviceShaderFloat8FeaturesEXT.pNext = pNext; + pNext = &physicalDeviceShaderFloat8FeaturesEXT; + physicalDeviceDataGraphFeaturesARM.pNext = pNext; + pNext = &physicalDeviceDataGraphFeaturesARM; + physicalDevicePipelineCacheIncrementalModeFeaturesSEC.pNext = pNext; + pNext = &physicalDevicePipelineCacheIncrementalModeFeaturesSEC; + physicalDeviceDataGraphModelFeaturesQCOM.pNext = pNext; + pNext = &physicalDeviceDataGraphModelFeaturesQCOM; + physicalDeviceShaderUntypedPointersFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceShaderUntypedPointersFeaturesKHR; + physicalDeviceVideoEncodeRgbConversionFeaturesVALVE.pNext = pNext; + pNext = &physicalDeviceVideoEncodeRgbConversionFeaturesVALVE; + physicalDeviceShader64BitIndexingFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceShader64BitIndexingFeaturesEXT; + physicalDeviceQueuePerfHintFeaturesQCOM.pNext = pNext; + pNext = &physicalDeviceQueuePerfHintFeaturesQCOM; + physicalDevicePerformanceCountersByRegionFeaturesARM.pNext = pNext; + pNext = &physicalDevicePerformanceCountersByRegionFeaturesARM; + physicalDeviceComputeOccupancyPriorityFeaturesNV.pNext = pNext; + pNext = &physicalDeviceComputeOccupancyPriorityFeaturesNV; + physicalDeviceShaderLongVectorFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceShaderLongVectorFeaturesEXT; + physicalDeviceTextureCompressionASTC3DFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceTextureCompressionASTC3DFeaturesEXT; + physicalDeviceShaderSubgroupPartitionedFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceShaderSubgroupPartitionedFeaturesEXT; + physicalDeviceDescriptorHeapFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceDescriptorHeapFeaturesEXT; + physicalDeviceShaderInstrumentationFeaturesARM.pNext = pNext; + pNext = &physicalDeviceShaderInstrumentationFeaturesARM; + physicalDeviceDeviceAddressCommandsFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceDeviceAddressCommandsFeaturesKHR; + physicalDeviceShaderConstantDataFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceShaderConstantDataFeaturesKHR; + physicalDeviceShaderAbortFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceShaderAbortFeaturesKHR; + physicalDeviceDataGraphOpticalFlowFeaturesARM.pNext = pNext; + pNext = &physicalDeviceDataGraphOpticalFlowFeaturesARM; + physicalDeviceFeatures2KHR.pNext = pNext; + + } + + + VkPhysicalDeviceFeatures2KHR requiredFeaturesChain{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR, nullptr}; + VkBaseOutStructure* current = nullptr; + + void ApplyRobustness(const VpDeviceCreateInfo* pCreateInfo) { +#ifdef VK_VERSION_1_1 + VkPhysicalDeviceFeatures2KHR* pFeatures2 = static_cast( + vpGetStructure(&this->requiredFeaturesChain, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR)); + if (pFeatures2 != nullptr && (pCreateInfo->flags & VP_DEVICE_CREATE_DISABLE_ROBUST_BUFFER_ACCESS_BIT)) { + pFeatures2->features.robustBufferAccess = VK_FALSE; + } +#endif + +#ifdef VK_EXT_robustness2 + VkPhysicalDeviceRobustness2FeaturesEXT* pRobustness2FeaturesEXT = static_cast( + vpGetStructure(&this->requiredFeaturesChain, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT)); + if (pRobustness2FeaturesEXT != nullptr) { + if (pCreateInfo->flags & VP_DEVICE_CREATE_DISABLE_ROBUST_BUFFER_ACCESS_BIT) { + pRobustness2FeaturesEXT->robustBufferAccess2 = VK_FALSE; + } + if (pCreateInfo->flags & VP_DEVICE_CREATE_DISABLE_ROBUST_IMAGE_ACCESS_BIT) { + pRobustness2FeaturesEXT->robustImageAccess2 = VK_FALSE; + } + } +#endif +#ifdef VK_EXT_image_robustness + VkPhysicalDeviceImageRobustnessFeaturesEXT* pImageRobustnessFeaturesEXT = + static_cast(vpGetStructure( + &this->requiredFeaturesChain, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES_EXT)); + if (pImageRobustnessFeaturesEXT != nullptr && (pCreateInfo->flags & VP_DEVICE_CREATE_DISABLE_ROBUST_IMAGE_ACCESS_BIT)) { + pImageRobustnessFeaturesEXT->robustImageAccess = VK_FALSE; + } +#endif +#ifdef VK_VERSION_1_3 + VkPhysicalDeviceVulkan13Features* pVulkan13Features = static_cast( + vpGetStructure(&this->requiredFeaturesChain, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES)); + if (pVulkan13Features != nullptr && (pCreateInfo->flags & VP_DEVICE_CREATE_DISABLE_ROBUST_IMAGE_ACCESS_BIT)) { + pVulkan13Features->robustImageAccess = VK_FALSE; + } +#endif + } + + void ApplyFeatures(const VpDeviceCreateInfo* pCreateInfo) { + const std::size_t offset = sizeof(VkBaseOutStructure); + const VkBaseOutStructure* q = reinterpret_cast(pCreateInfo->pCreateInfo->pNext); + while (q) { + const std::size_t count = this->structureSize[q->sType]; + for (std::size_t index = 0; index < count; ++index) { + const VkBaseOutStructure* pInputStruct = reinterpret_cast(q); + VkBaseOutStructure* pOutputStruct = reinterpret_cast(detail::vpGetStructure(&this->requiredFeaturesChain, q->sType)); + const uint8_t* pInputData = reinterpret_cast(pInputStruct) + offset; + uint8_t* pOutputData = reinterpret_cast(pOutputStruct) + offset; + const VkBool32* input = reinterpret_cast(pInputData); + VkBool32* output = reinterpret_cast(pOutputData); + + output[index] = (output[index] == VK_TRUE || input[index] == VK_TRUE) ? VK_TRUE : VK_FALSE; + } + q = q->pNext; + } + + this->ApplyRobustness(pCreateInfo); + } + + void PushBack(VkBaseOutStructure* found) { + VkBaseOutStructure* last = reinterpret_cast(&requiredFeaturesChain); + while (last->pNext != nullptr) { + last = last->pNext; + } + last->pNext = found; + } + + void Build(const std::vector& requiredList) { + for (std::size_t i = 0, n = requiredList.size(); i < n; ++i) { + const VkStructureType sType = requiredList[i]; + if (sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR) { + continue; + } + + VkBaseOutStructure* found = vpExtractStructure(&physicalDeviceFeatures2KHR, sType); + if (found == nullptr) { + continue; + } + + PushBack(found); + } + } +}; // struct FeaturesChain + +VPAPI_ATTR const VpProfileDesc* vpGetProfileDesc(const char profileName[VP_MAX_PROFILE_NAME_SIZE]) { + for (uint32_t profileIndex = 0; profileIndex < profileCount; ++profileIndex) { + if (strncmp(profiles[profileIndex].props.profileName, profileName, VP_MAX_PROFILE_NAME_SIZE) == 0) { + return &profiles[profileIndex]; + } + } + return nullptr; +} + +VPAPI_ATTR std::vector GatherProfiles(const VpProfileProperties& profile, const char* pBlockName = nullptr) { + std::vector gatheredProfiles; + + if (pBlockName == nullptr) { + const detail::VpProfileDesc* profileDesc = detail::vpGetProfileDesc(profile.profileName); + if (profileDesc != nullptr) { + for (uint32_t profileIndex = 0; profileIndex < profileDesc->requiredProfileCount; ++profileIndex) { + gatheredProfiles.push_back(profileDesc->pRequiredProfiles[profileIndex]); + } + } + } + + gatheredProfiles.push_back(profile); + + return gatheredProfiles; +} + +VPAPI_ATTR bool vpCheckVersion(uint32_t actual, uint32_t expected) { + uint32_t actualMajor = VK_API_VERSION_MAJOR(actual); + uint32_t actualMinor = VK_API_VERSION_MINOR(actual); + uint32_t expectedMajor = VK_API_VERSION_MAJOR(expected); + uint32_t expectedMinor = VK_API_VERSION_MINOR(expected); + return actualMajor > expectedMajor || (actualMajor == expectedMajor && actualMinor >= expectedMinor); +} + +VPAPI_ATTR bool HasExtension(const std::vector& list, const VkExtensionProperties& element) { + for (std::size_t i = 0, n = list.size(); i < n; ++i) { + if (strcmp(list[i].extensionName, element.extensionName) == 0) { + return true; + } + } + + return false; +} + +VPAPI_ATTR bool CheckExtension(const VkExtensionProperties* supportedProperties, size_t supportedSize, const char *requestedExtension) { + bool found = false; + for (size_t i = 0, n = supportedSize; i < n; ++i) { + if (strcmp(supportedProperties[i].extensionName, requestedExtension) == 0) { + found = true; + break; + // Drivers don't actually update their spec version, so we cannot rely on this + // if (supportedProperties[i].specVersion >= expectedVersion) found = true; + } + } + return found; +} + +VPAPI_ATTR bool CheckExtension(const std::vector& extensions, const char* extension) { + for (const char* c : extensions) { + if (strcmp(c, extension) == 0) { + return true; + } + } + return false; +} + +VPAPI_ATTR void GetExtensions(uint32_t extensionCount, const VkExtensionProperties *pExtensions, std::vector &extensions) { + for (uint32_t ext_index = 0; ext_index < extensionCount; ++ext_index) { + if (CheckExtension(extensions, pExtensions[ext_index].extensionName)) { + continue; + } + extensions.push_back(pExtensions[ext_index].extensionName); + } +} + +VPAPI_ATTR std::vector GatherBlocks( + uint32_t enabledFullProfileCount, const VpProfileProperties* pEnabledFullProfiles, + uint32_t enabledProfileBlockCount, const VpBlockProperties* pEnabledProfileBlocks) { + std::vector results; + + for (std::size_t profile_index = 0; profile_index < enabledFullProfileCount; ++profile_index) { + const std::vector& gathered_profiles = GatherProfiles(pEnabledFullProfiles[profile_index]); + + for (std::size_t gathered_index = 0; gathered_index < gathered_profiles.size(); ++gathered_index) { + VpBlockProperties block{gathered_profiles[gathered_index], 0, ""}; + results.push_back(block); + } + } + + for (std::size_t block_index = 0; block_index < enabledProfileBlockCount; ++block_index) { + results.push_back(pEnabledProfileBlocks[block_index]); + } + + return results; +} + +VPAPI_ATTR VkResult vpGetInstanceProfileSupportSingleProfile( + uint32_t api_version, + const std::vector& supported_extensions, + const VpProfileProperties* pProfile, + VkBool32* pSupported, + std::vector& supportedBlocks, + std::vector& unsupportedBlocks) { + assert(pProfile != nullptr); + + const detail::VpProfileDesc* pProfileDesc = vpGetProfileDesc(pProfile->profileName); + if (pProfileDesc == nullptr) { + *pSupported = VK_FALSE; + return VK_ERROR_UNKNOWN; + } + + VpBlockProperties block{*pProfile, api_version}; + + if (pProfileDesc->props.specVersion < pProfile->specVersion) { + *pSupported = VK_FALSE; + unsupportedBlocks.push_back(block); + } + + // Required API version is built in root profile, not need to check dependent profile API versions + if (api_version != 0) { + if (!vpCheckVersion(api_version, pProfileDesc->minApiVersion)) { + + *pSupported = VK_FALSE; + unsupportedBlocks.push_back(block); + } + } + + for (uint32_t capability_index = 0; capability_index < pProfileDesc->requiredCapabilityCount; ++capability_index) { + const VpCapabilitiesDesc& capabilities_desc = pProfileDesc->pRequiredCapabilities[capability_index]; + + VkBool32 supported_capabilities = VK_FALSE; + for (uint32_t variant_index = 0; variant_index < capabilities_desc.variantCount; ++variant_index) { + const VpVariantDesc& variant_desc = capabilities_desc.pVariants[variant_index]; + + VkBool32 supported_variant = VK_TRUE; + for (uint32_t i = 0; i < variant_desc.instanceExtensionCount; ++i) { + if (!detail::CheckExtension(supported_extensions.data(), supported_extensions.size(), + variant_desc.pInstanceExtensions[i].extensionName)) { + supported_variant = VK_FALSE; + memcpy(block.blockName, variant_desc.blockName, VP_MAX_PROFILE_NAME_SIZE * sizeof(char)); + unsupportedBlocks.push_back(block); + } + } + + if (supported_variant == VK_TRUE) { + supported_capabilities = VK_TRUE; + memcpy(block.blockName, variant_desc.blockName, VP_MAX_PROFILE_NAME_SIZE * sizeof(char)); + supportedBlocks.push_back(block); + } + } + + if (supported_capabilities == VK_FALSE) { + *pSupported = VK_FALSE; + return VK_SUCCESS; + } + } + + return VK_SUCCESS; +} + +enum structure_type { + STRUCTURE_FEATURE = 0, + STRUCTURE_PROPERTY, + STRUCTURE_QUEUE_FAMILY, + STRUCTURE_FORMAT +}; + +VPAPI_ATTR VkResult vpGetProfileStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + structure_type type, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + VkResult result = pBlockName == nullptr ? VK_SUCCESS : VK_INCOMPLETE; + + std::vector results; + + const std::vector& gathered_profiles = detail::GatherProfiles(*pProfile); + + for (std::size_t profile_index = 0, profile_count = gathered_profiles.size(); profile_index < profile_count; ++profile_index) { + const detail::VpProfileDesc* profile_desc = detail::vpGetProfileDesc(gathered_profiles[profile_index].profileName); + if (profile_desc == nullptr) return VK_ERROR_UNKNOWN; + + for (uint32_t capability_index = 0; capability_index < profile_desc->requiredCapabilityCount; ++capability_index) { + const detail::VpCapabilitiesDesc& cap_desc = profile_desc->pRequiredCapabilities[capability_index]; + + for (uint32_t variant_index = 0; variant_index < cap_desc.variantCount; ++variant_index) { + const detail::VpVariantDesc& variant = cap_desc.pVariants[variant_index]; + if (pBlockName != nullptr) { + if (strcmp(variant.blockName, pBlockName) != 0) { + continue; + } + result = VK_SUCCESS; + } + + uint32_t count = 0; + const VkStructureType* data = nullptr; + + switch (type) { + default: + case STRUCTURE_FEATURE: + count = variant.featureStructTypeCount; + data = variant.pFeatureStructTypes; + break; + case STRUCTURE_PROPERTY: + count = variant.propertyStructTypeCount; + data = variant.pPropertyStructTypes; + break; + case STRUCTURE_QUEUE_FAMILY: + count = variant.queueFamilyStructTypeCount; + data = variant.pQueueFamilyStructTypes; + break; + case STRUCTURE_FORMAT: + count = variant.formatStructTypeCount; + data = variant.pFormatStructTypes; + break; + } + + for (uint32_t type_index = 0; type_index < count; ++type_index) { + const VkStructureType dataType = data[type_index]; + if (std::find(results.begin(), results.end(), dataType) == std::end(results)) { + results.push_back(dataType); + } + } + } + } + } + + const uint32_t count = static_cast(results.size()); + std::sort(results.begin(), results.end()); + + if (pStructureTypes == nullptr) { + *pStructureTypeCount = count; + } else { + if (*pStructureTypeCount < count) { + result = VK_INCOMPLETE; + } else { + *pStructureTypeCount = count; + } + + if (*pStructureTypeCount > 0) { + memcpy(pStructureTypes, &results[0], *pStructureTypeCount * sizeof(VkStructureType)); + } + } + + return result; +} + +enum ExtensionType { + EXTENSION_INSTANCE, + EXTENSION_DEVICE, +}; + +VPAPI_ATTR VkResult vpGetProfileExtensionProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + ExtensionType type, + uint32_t* pPropertyCount, + VkExtensionProperties* pProperties) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + VkResult result = pBlockName == nullptr ? VK_SUCCESS : VK_INCOMPLETE; + + std::vector results; + + const std::vector& gathered_profiles = detail::GatherProfiles(*pProfile, pBlockName); + + for (std::size_t profile_index = 0, profile_count = gathered_profiles.size(); profile_index < profile_count; ++profile_index) { + const detail::VpProfileDesc* profile_desc = detail::vpGetProfileDesc(gathered_profiles[profile_index].profileName); + if (profile_desc == nullptr) { + return VK_ERROR_UNKNOWN; + } + + for (uint32_t capability_index = 0; capability_index < profile_desc->requiredCapabilityCount; ++capability_index) { + const detail::VpCapabilitiesDesc& cap_desc = profile_desc->pRequiredCapabilities[capability_index]; + + for (uint32_t variant_index = 0; variant_index < cap_desc.variantCount; ++variant_index) { + const detail::VpVariantDesc& variant = cap_desc.pVariants[variant_index]; + if (pBlockName != nullptr) { + if (strcmp(variant.blockName, pBlockName) != 0) { + continue; + } + result = VK_SUCCESS; + } + + switch (type) { + default: + case EXTENSION_INSTANCE: + for (uint32_t ext_index = 0; ext_index < variant.instanceExtensionCount; ++ext_index) { + if (detail::HasExtension(results, variant.pInstanceExtensions[ext_index])) { + continue; + } + results.push_back(variant.pInstanceExtensions[ext_index]); + } + break; + case EXTENSION_DEVICE: + for (uint32_t ext_index = 0; ext_index < variant.deviceExtensionCount; ++ext_index) { + if (detail::HasExtension(results, variant.pDeviceExtensions[ext_index])) { + continue; + } + results.push_back(variant.pDeviceExtensions[ext_index]); + } + break; + } + } + } + } + + const uint32_t count = static_cast(results.size()); + + if (pProperties == nullptr) { + *pPropertyCount = count; + } else { + if (*pPropertyCount < count) { + result = VK_INCOMPLETE; + } else { + *pPropertyCount = count; + } + if (*pPropertyCount > 0) { + memcpy(pProperties, &results[0], *pPropertyCount * sizeof(VkExtensionProperties)); + } + } + + return result; +} + +VPAPI_ATTR VkResult vpGetProfileVideoProfileDesc( + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + const detail::VpVideoProfileDesc** ppVideoProfileDesc) { + VkResult result = pBlockName == nullptr ? VK_SUCCESS : VK_INCOMPLETE; + + uint32_t curr_base_video_profile_index = 0; + + const std::vector& gathered_profiles = detail::GatherProfiles(*pProfile); + + for (std::size_t profile_index = 0, profile_count = gathered_profiles.size(); profile_index < profile_count; ++profile_index) { + const detail::VpProfileDesc* profile_desc = detail::vpGetProfileDesc(gathered_profiles[profile_index].profileName); + if (profile_desc == nullptr) return VK_ERROR_UNKNOWN; + + for (uint32_t capability_index = 0; capability_index < profile_desc->requiredCapabilityCount; ++capability_index) { + const detail::VpCapabilitiesDesc& cap_desc = profile_desc->pRequiredCapabilities[capability_index]; + + for (uint32_t variant_index = 0; variant_index < cap_desc.variantCount; ++variant_index) { + const detail::VpVariantDesc& variant = cap_desc.pVariants[variant_index]; + if (pBlockName != nullptr) { + if (strcmp(variant.blockName, pBlockName) != 0) { + continue; + } + result = VK_SUCCESS; + } + + if (videoProfileIndex < curr_base_video_profile_index + variant.videoProfileCount) { + *ppVideoProfileDesc = &variant.pVideoProfiles[videoProfileIndex - curr_base_video_profile_index]; + return result; + } else { + curr_base_video_profile_index += variant.videoProfileCount; + } + } + } + } + + *ppVideoProfileDesc = nullptr; + return VK_ERROR_UNKNOWN; +} + +} // namespace detail + +struct VpCapabilities_T : public VpVulkanFunctions { + bool singleton = false; + uint32_t apiVersion = VK_API_VERSION_1_0; + + static VpCapabilities_T& Get() { + static VpCapabilities_T instance; + VpCapabilitiesCreateInfo createInfo{}; + createInfo.flags = VP_PROFILE_CREATE_STATIC_BIT; + instance.init(&createInfo); + instance.singleton = true; + return instance; + } + + VpCapabilities_T() { + this->GetInstanceProcAddr = nullptr; + this->GetDeviceProcAddr = nullptr; + this->EnumerateInstanceVersion = nullptr; + this->EnumerateInstanceExtensionProperties = nullptr; + this->EnumerateDeviceExtensionProperties = nullptr; + this->GetPhysicalDeviceFeatures2 = nullptr; + this->GetPhysicalDeviceProperties2 = nullptr; + this->GetPhysicalDeviceFormatProperties2 = nullptr; + this->GetPhysicalDeviceQueueFamilyProperties2 = nullptr; + this->CreateInstance = nullptr; + this->CreateDevice = nullptr; + } + + VkResult init(const VpCapabilitiesCreateInfo* pCreateInfo) { + assert(pCreateInfo != nullptr); + + return ImportVulkanFunctions(pCreateInfo); + } + + VkResult ImportVulkanFunctions(const VpCapabilitiesCreateInfo* pCreateInfo) { + if (pCreateInfo->flags & VP_PROFILE_CREATE_STATIC_BIT) { + ImportVulkanFunctions_Static(); + } + + if (pCreateInfo->pVulkanFunctions != nullptr) { + ImportVulkanFunctions_Custom((VpVulkanFunctions*)pCreateInfo->pVulkanFunctions); + } +/* + if (pCreateInfo->flags & VP_PROFILE_CREATE_DYNAMIC_BIT) { + ImportVulkanFunctions_Dynamic(); + } +*/ + return ValidateVulkanFunctions(); + } + + void ImportVulkanFunctions_Static() { + // Vulkan 1.1 + this->GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)vkGetInstanceProcAddr; + this->GetDeviceProcAddr = (PFN_vkGetDeviceProcAddr)vkGetDeviceProcAddr; + + this->EnumerateInstanceVersion = (PFN_vkEnumerateInstanceVersion)vkEnumerateInstanceVersion; + this->EnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties)vkEnumerateInstanceExtensionProperties; + this->EnumerateDeviceExtensionProperties = (PFN_vkEnumerateDeviceExtensionProperties)vkEnumerateDeviceExtensionProperties; + + this->GetPhysicalDeviceFeatures2 = (PFN_vkGetPhysicalDeviceFeatures2)vkGetPhysicalDeviceFeatures2; + this->GetPhysicalDeviceProperties2 = (PFN_vkGetPhysicalDeviceProperties2)vkGetPhysicalDeviceProperties2; + this->GetPhysicalDeviceFormatProperties2 = (PFN_vkGetPhysicalDeviceFormatProperties2)vkGetPhysicalDeviceFormatProperties2; + this->GetPhysicalDeviceQueueFamilyProperties2 = (PFN_vkGetPhysicalDeviceQueueFamilyProperties2)vkGetPhysicalDeviceQueueFamilyProperties2; + + this->CreateInstance = (PFN_vkCreateInstance)vkCreateInstance; + this->CreateDevice = (PFN_vkCreateDevice)vkCreateDevice; + } + + void ImportVulkanFunctions_Custom(VpVulkanFunctions* pFunctions) { + #define VP_COPY_IF_NOT_NULL(funcName) if(pFunctions->funcName != nullptr) this->funcName = pFunctions->funcName; + + VP_COPY_IF_NOT_NULL(GetInstanceProcAddr); + VP_COPY_IF_NOT_NULL(GetDeviceProcAddr); + + VP_COPY_IF_NOT_NULL(EnumerateInstanceVersion); + VP_COPY_IF_NOT_NULL(EnumerateInstanceExtensionProperties); + VP_COPY_IF_NOT_NULL(EnumerateDeviceExtensionProperties); + + VP_COPY_IF_NOT_NULL(GetPhysicalDeviceFeatures2); + VP_COPY_IF_NOT_NULL(GetPhysicalDeviceProperties2); + VP_COPY_IF_NOT_NULL(GetPhysicalDeviceFormatProperties2); + VP_COPY_IF_NOT_NULL(GetPhysicalDeviceQueueFamilyProperties2); + + VP_COPY_IF_NOT_NULL(CreateInstance); + VP_COPY_IF_NOT_NULL(CreateDevice); + #undef VP_COPY_IF_NOT_NULL + } +/* + VkResult ImportVulkanFunctions_Dynamic() { + // To use VP_PROFILE_CREATE_DYNAMIC_BIT you have to pass VpVulkanFunctions::vkGetInstanceProcAddr and vkGetDeviceProcAddr as VpCapabilitiesCreateInfo::pVulkanFunctions. Other members can be null. + if (this->GetInstanceProcAddr == nullptr || this->GetDeviceProcAddr == nullptr) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + #define VP_FETCH_INSTANCE_FUNC(memberName, functionNameString) if(this->memberName == nullptr) this->memberName = (PFN_vk##memberName)this->GetInstanceProcAddr(m_hInstance, functionNameString); + #define VP_FETCH_DEVICE_FUNC(memberName, functionNameString) if(this->memberName == nullptr) this->memberName = (PFN_vk##memberName)this->GetDeviceProcAddr(m_hDevice, functionNameString); + + VP_FETCH_INSTANCE_FUNC(GetInstanceProcAddr, "vkGetInstanceProcAddr"); + VP_FETCH_DEVICE_FUNC(GetDeviceProcAddr, "vkGetDeviceProcAddr"); + + VP_FETCH_INSTANCE_FUNC(EnumerateInstanceVersion, "vkEnumerateInstanceVersion"); + VP_FETCH_INSTANCE_FUNC(EnumerateInstanceExtensionProperties, "vkEnumerateInstanceExtensionProperties"); + VP_FETCH_DEVICE_FUNC(EnumerateDeviceExtensionProperties, "vkEnumerateDeviceExtensionProperties"); + + VP_FETCH_DEVICE_FUNC(GetPhysicalDeviceFeatures2, "vkGetPhysicalDeviceFeatures2"); + VP_FETCH_DEVICE_FUNC(GetPhysicalDeviceProperties2, "vkGetPhysicalDeviceProperties2"); + VP_FETCH_DEVICE_FUNC(GetPhysicalDeviceFormatProperties2, "vkGetPhysicalDeviceFormatProperties2"); + VP_FETCH_DEVICE_FUNC(GetPhysicalDeviceQueueFamilyProperties2, "vkGetPhysicalDeviceQueueFamilyProperties2"); + + VP_FETCH_INSTANCE_FUNC(CreateInstance, "vkCreateInstance"); + VP_FETCH_DEVICE_FUNC(CreateDevice, "vkCreateDevice"); + #undef VP_FETCH_DEVICE_FUNC + #undef VP_FETCH_INSTANCE_FUNC + } +*/ + VkResult ValidateVulkanFunctions() { + if (this->GetInstanceProcAddr == nullptr) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + if (this->GetDeviceProcAddr == nullptr) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + if (this->EnumerateInstanceVersion == nullptr && apiVersion >= VK_API_VERSION_1_1) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + if (this->EnumerateInstanceExtensionProperties == nullptr) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + if (this->EnumerateDeviceExtensionProperties == nullptr) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + if (this->GetPhysicalDeviceFeatures2 == nullptr) { + return apiVersion >= VK_API_VERSION_1_1 ? VK_ERROR_INITIALIZATION_FAILED : VK_ERROR_EXTENSION_NOT_PRESENT; + } + + if (this->GetPhysicalDeviceProperties2 == nullptr) { + return apiVersion >= VK_API_VERSION_1_1 ? VK_ERROR_INITIALIZATION_FAILED : VK_ERROR_EXTENSION_NOT_PRESENT; + } + + if (this->GetPhysicalDeviceFormatProperties2 == nullptr) { + return apiVersion >= VK_API_VERSION_1_1 ? VK_ERROR_INITIALIZATION_FAILED : VK_ERROR_EXTENSION_NOT_PRESENT; + } + + if (this->GetPhysicalDeviceQueueFamilyProperties2 == nullptr) { + return apiVersion >= VK_API_VERSION_1_1 ? VK_ERROR_INITIALIZATION_FAILED : VK_ERROR_EXTENSION_NOT_PRESENT; + } + + if (this->CreateInstance == nullptr) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + if (this->CreateDevice == nullptr) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + return VK_SUCCESS; + } +}; + +VPAPI_ATTR VkResult vpCreateCapabilities( + const VpCapabilitiesCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VpCapabilities* pCapabilities) { + (void)pAllocator; + + VpCapabilities_T* capabilities = new VpCapabilities_T(); + VkResult result = capabilities->init(pCreateInfo); + *pCapabilities = capabilities; + + return result; +} + +/// Destroys allocator object. +VPAPI_ATTR void vpDestroyCapabilities( + VpCapabilities capabilities, + const VkAllocationCallbacks* pAllocator) { + (void)pAllocator; + + delete capabilities; +} + +VPAPI_ATTR VkResult vpGetProfiles( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + uint32_t* pPropertyCount, + VpProfileProperties* pProperties) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + VkResult result = VK_SUCCESS; + + if (pProperties == nullptr) { + *pPropertyCount = detail::profileCount; + } else { + if (*pPropertyCount < detail::profileCount) { + result = VK_INCOMPLETE; + } else { + *pPropertyCount = detail::profileCount; + } + for (uint32_t property_index = 0; property_index < *pPropertyCount; ++property_index) { + pProperties[property_index] = detail::profiles[property_index].props; + } + } + return result; +} + +VPAPI_ATTR VkResult vpGetProfileRequiredProfiles( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + uint32_t* pPropertyCount, + VpProfileProperties* pProperties) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + VkResult result = VK_SUCCESS; + + const detail::VpProfileDesc* desc = detail::vpGetProfileDesc(pProfile->profileName); + if (desc == nullptr) { + return VK_ERROR_UNKNOWN; + } + + if (pProperties == nullptr) { + *pPropertyCount = desc->requiredProfileCount; + } else { + if (*pPropertyCount < desc->requiredProfileCount) { + result = VK_INCOMPLETE; + } else { + *pPropertyCount = desc->requiredProfileCount; + } + for (uint32_t property_index = 0; property_index < *pPropertyCount; ++property_index) { + pProperties[property_index] = desc->pRequiredProfiles[property_index]; + } + } + return result; +} + +VPAPI_ATTR uint32_t vpGetProfileAPIVersion( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + const std::vector& gathered_profiles = detail::GatherProfiles(*pProfile, nullptr); + + uint32_t major = 0; + uint32_t minor = 0; + uint32_t patch = 0; + + for (std::size_t profile_index = 0, profile_count = gathered_profiles.size(); profile_index < profile_count; ++profile_index) { + const detail::VpProfileDesc* desc = detail::vpGetProfileDesc(gathered_profiles[profile_index].profileName); + if (desc == nullptr) { + return 0; + } + + major = std::max(major, VK_API_VERSION_MAJOR(desc->minApiVersion)); + minor = std::max(minor, VK_API_VERSION_MINOR(desc->minApiVersion)); + patch = std::max(patch, VK_API_VERSION_PATCH(desc->minApiVersion)); + } + + return VK_MAKE_API_VERSION(0, major, minor, patch); +} + +VPAPI_ATTR VkResult vpGetProfileFallbacks( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + uint32_t* pPropertyCount, + VpProfileProperties* pProperties) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + VkResult result = VK_SUCCESS; + + const detail::VpProfileDesc* desc = detail::vpGetProfileDesc(pProfile->profileName); + if (desc == nullptr) { + return VK_ERROR_UNKNOWN; + } + + if (pProperties == nullptr) { + *pPropertyCount = desc->fallbackCount; + } else { + if (*pPropertyCount < desc->fallbackCount) { + result = VK_INCOMPLETE; + } else { + *pPropertyCount = desc->fallbackCount; + } + for (uint32_t i = 0; i < *pPropertyCount; ++i) { + pProperties[i] = desc->pFallbacks[i]; + } + } + return result; +} + +VPAPI_ATTR VkResult vpHasMultipleVariantsProfile( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + VkBool32* pHasMultipleVariants) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + const std::vector& gathered_profiles = detail::GatherProfiles(*pProfile, nullptr); + + for (std::size_t profile_index = 0, profile_count = gathered_profiles.size(); profile_index < profile_count; ++profile_index) { + const detail::VpProfileDesc* desc = detail::vpGetProfileDesc(gathered_profiles[profile_index].profileName); + if (desc == nullptr) { + return VK_ERROR_UNKNOWN; + } + + for (uint32_t caps_index = 0, caps_count = desc->requiredCapabilityCount; caps_index < caps_count; ++caps_index) { + if (desc->pRequiredCapabilities[caps_index].variantCount > 1) { + *pHasMultipleVariants = VK_TRUE; + return VK_SUCCESS; + } + } + } + + *pHasMultipleVariants = VK_FALSE; + return VK_SUCCESS; +} + +VPAPI_ATTR VkResult vpGetInstanceProfileVariantsSupport( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const char* pLayerName, + const VpProfileProperties* pProfile, + VkBool32* pSupported, + uint32_t* pPropertyCount, + VpBlockProperties* pProperties) { +#ifdef VP_USE_OBJECT + const VpCapabilities_T& vp = capabilities == nullptr ? VpCapabilities_T::Get() : *capabilities; +#else + const VpCapabilities_T& vp = VpCapabilities_T::Get(); +#endif//VP_USE_OBJECT + + VkResult result = VK_SUCCESS; + + uint32_t api_version = VK_API_VERSION_1_0; + PFN_vkEnumerateInstanceVersion pfnEnumerateInstanceVersion = vp.singleton ? + (PFN_vkEnumerateInstanceVersion)vkGetInstanceProcAddr(VK_NULL_HANDLE, "vkEnumerateInstanceVersion") : vp.EnumerateInstanceVersion; + if (pfnEnumerateInstanceVersion != nullptr) { + result = pfnEnumerateInstanceVersion(&api_version); + if (result != VK_SUCCESS) { + *pSupported = VK_FALSE; + return result; + } /* else { + } */ + } + + uint32_t supported_instance_extension_count = 0; + result = vp.EnumerateInstanceExtensionProperties(pLayerName, &supported_instance_extension_count, nullptr); + if (result != VK_SUCCESS) { + *pSupported = VK_FALSE; + return result; + } + std::vector supported_instance_extensions; + if (supported_instance_extension_count > 0) { + supported_instance_extensions.resize(supported_instance_extension_count); + } + result = vp.EnumerateInstanceExtensionProperties(pLayerName, &supported_instance_extension_count, supported_instance_extensions.data()); + if (result != VK_SUCCESS) { + *pSupported = VK_FALSE; + return result; + } + + VkBool32 supported = VK_TRUE; + + // We require VK_KHR_get_physical_device_properties2 if we are on Vulkan 1.0 + if (api_version < VK_API_VERSION_1_1) { + bool foundGPDP2 = false; + for (size_t ext_index = 0, ext_count = supported_instance_extensions.size(); ext_index < ext_count; ++ext_index) { + if (strcmp(supported_instance_extensions[ext_index].extensionName, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME) == 0) { + foundGPDP2 = true; + break; + } + } + if (!foundGPDP2) { + supported = VK_FALSE; + } + } + + const detail::VpProfileDesc* pProfileDesc = detail::vpGetProfileDesc(pProfile->profileName); + if (pProfileDesc == nullptr) return VK_ERROR_UNKNOWN; + + std::vector supported_blocks; + std::vector unsupported_blocks; + + result = detail::vpGetInstanceProfileSupportSingleProfile(api_version, supported_instance_extensions, pProfile, &supported, supported_blocks, unsupported_blocks); + if (result != VK_SUCCESS) { + *pSupported = supported; + return result; + } + + for (std::size_t required_profile_index = 0; required_profile_index < pProfileDesc->requiredProfileCount; ++required_profile_index) { + result = detail::vpGetInstanceProfileSupportSingleProfile(0, supported_instance_extensions, &pProfileDesc->pRequiredProfiles[required_profile_index], &supported, supported_blocks, unsupported_blocks); + if (result != VK_SUCCESS) { + *pSupported = supported; + return result; + } + } + + const std::vector& blocks = supported ? supported_blocks : unsupported_blocks; + + if (pProperties == nullptr) { + *pPropertyCount = static_cast(blocks.size()); + } else { + if (*pPropertyCount < static_cast(blocks.size())) { + result = VK_INCOMPLETE; + } else { + *pPropertyCount = static_cast(blocks.size()); + } + for (uint32_t block_index = 0, block_count = static_cast(blocks.size()); block_index < block_count; ++block_index) { + pProperties[block_index] = blocks[block_index]; + } + } + + *pSupported = supported; + return result; +} + +VPAPI_ATTR VkResult vpGetInstanceProfileSupport( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const char* pLayerName, + const VpProfileProperties* pProfile, + VkBool32* pSupported) { + uint32_t count = 0; + + return vpGetInstanceProfileVariantsSupport( +#ifdef VP_USE_OBJECT + capabilities, +#endif//VP_USE_OBJECT + pLayerName, pProfile, pSupported, &count, nullptr); +} + +VPAPI_ATTR VkResult vpCreateInstance( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpInstanceCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkInstance* pInstance) { +#ifdef VP_USE_OBJECT + const VpCapabilities_T& vp = capabilities == nullptr ? VpCapabilities_T::Get() : *capabilities; +#else + const VpCapabilities_T& vp = VpCapabilities_T::Get(); +#endif//VP_USE_OBJECT + + if (pCreateInfo == nullptr || pInstance == nullptr) { + return vp.CreateInstance(pCreateInfo == nullptr ? nullptr : pCreateInfo->pCreateInfo, pAllocator, pInstance); + } + + const std::vector& blocks = detail::GatherBlocks( + pCreateInfo->enabledFullProfileCount, pCreateInfo->pEnabledFullProfiles, + pCreateInfo->enabledProfileBlockCount, pCreateInfo->pEnabledProfileBlocks); + + std::vector extensions; + for (std::uint32_t ext_index = 0, ext_count = pCreateInfo->pCreateInfo->enabledExtensionCount; ext_index < ext_count; ++ext_index) { + extensions.push_back(pCreateInfo->pCreateInfo->ppEnabledExtensionNames[ext_index]); + } + + for (std::size_t block_index = 0, block_count = blocks.size(); block_index < block_count; ++block_index) { + const detail::VpProfileDesc* profile_desc = detail::vpGetProfileDesc(blocks[block_index].profiles.profileName); + if (profile_desc == nullptr) { + return VK_ERROR_UNKNOWN; + } + + for (std::size_t caps_index = 0, caps_count = profile_desc->requiredCapabilityCount; caps_index < caps_count; ++caps_index) { + const detail::VpCapabilitiesDesc* caps_desc = &profile_desc->pRequiredCapabilities[caps_index]; + + for (std::size_t variant_index = 0, variant_count = caps_desc->variantCount; variant_index < variant_count; ++variant_index) { + const detail::VpVariantDesc* variant = &caps_desc->pVariants[variant_index]; + + if (strcmp(blocks[block_index].blockName, "") != 0) { + if (strcmp(variant->blockName, blocks[block_index].blockName) != 0) { + continue; + } + } + + detail::GetExtensions(variant->instanceExtensionCount, variant->pInstanceExtensions, extensions); + } + } + } + + VkApplicationInfo appInfo{VK_STRUCTURE_TYPE_APPLICATION_INFO}; + if (pCreateInfo->pCreateInfo->pApplicationInfo != nullptr) { + appInfo = *pCreateInfo->pCreateInfo->pApplicationInfo; + } else if (!blocks.empty()) { + appInfo.apiVersion = vpGetProfileAPIVersion( +#ifdef VP_USE_OBJECT + capabilities, +#endif//VP_USE_OBJECT + &blocks[0].profiles); + } + + VkInstanceCreateInfo createInfo = *pCreateInfo->pCreateInfo; + createInfo.pApplicationInfo = &appInfo; + + // Need to include VK_KHR_get_physical_device_properties2 if we are on Vulkan 1.0 + if (createInfo.pApplicationInfo->apiVersion < VK_API_VERSION_1_1) { + bool foundGPDP2 = false; + for (size_t ext_index = 0, ext_count = extensions.size(); ext_index < ext_count; ++ext_index) { + if (strcmp(extensions[ext_index], VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME) == 0) { + foundGPDP2 = true; + break; + } + } + if (!foundGPDP2) { + extensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); + } + } + +#ifdef __APPLE__ + bool has_portability_ext = false; + for (std::size_t ext_index = 0, ext_count = extensions.size(); ext_index < ext_count; ++ext_index) { + if (strcmp(extensions[ext_index], VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME) == 0) { + has_portability_ext = true; + break; + } + } + + if (!has_portability_ext) { + extensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME); + } + + createInfo.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR; +#endif + + if (!extensions.empty()) { + createInfo.enabledExtensionCount = static_cast(extensions.size()); + createInfo.ppEnabledExtensionNames = extensions.data(); + } + + return vp.CreateInstance(&createInfo, pAllocator, pInstance); +} + +VPAPI_ATTR VkResult vpGetPhysicalDeviceProfileVariantsSupport( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + VkInstance instance, + VkPhysicalDevice physicalDevice, + const VpProfileProperties *pProfile, + VkBool32 *pSupported, + uint32_t *pPropertyCount, + VpBlockProperties* pProperties) { +#ifdef VP_USE_OBJECT + const VpCapabilities_T& vp = capabilities == nullptr ? VpCapabilities_T::Get() : *capabilities; +#else + const VpCapabilities_T& vp = VpCapabilities_T::Get(); +#endif//VP_USE_OBJECT + + VkResult result = VK_SUCCESS; + + uint32_t supported_device_extension_count = 0; + result = vp.EnumerateDeviceExtensionProperties(physicalDevice, nullptr, &supported_device_extension_count, nullptr); + if (result != VK_SUCCESS) { + return result; + } + std::vector supported_device_extensions; + if (supported_device_extension_count > 0) { + supported_device_extensions.resize(supported_device_extension_count); + } + result = vp.EnumerateDeviceExtensionProperties(physicalDevice, nullptr, &supported_device_extension_count, supported_device_extensions.data()); + if (result != VK_SUCCESS) { + return result; + } + + // Workaround old loader bug where count could be smaller on the second call to vkEnumerateDeviceExtensionProperties + if (supported_device_extension_count > 0) { + supported_device_extensions.resize(supported_device_extension_count); + } + + { + const detail::VpProfileDesc* pProfileDesc = detail::vpGetProfileDesc(pProfile->profileName); + if (pProfileDesc == nullptr) { + return VK_ERROR_UNKNOWN; + } + } + + struct GPDP2EntryPoints { + PFN_vkGetPhysicalDeviceFeatures2KHR pfnGetPhysicalDeviceFeatures2; + PFN_vkGetPhysicalDeviceProperties2KHR pfnGetPhysicalDeviceProperties2; + PFN_vkGetPhysicalDeviceFormatProperties2KHR pfnGetPhysicalDeviceFormatProperties2; + PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR pfnGetPhysicalDeviceQueueFamilyProperties2; + }; + +#ifdef VK_KHR_video_queue + struct VideoInfo { + PFN_vkGetPhysicalDeviceVideoCapabilitiesKHR pfnGetPhysicalDeviceVideoCapabilitiesKHR; + PFN_vkGetPhysicalDeviceVideoFormatPropertiesKHR pfnGetPhysicalDeviceVideoFormatPropertiesKHR; + const detail::VpVideoProfileDesc* pProfileDesc; + VkVideoProfileInfoKHR profileInfo; + VkPhysicalDeviceVideoFormatInfoKHR formatInfo; + bool supportedProfile; + uint32_t matchingProfiles; + }; +#endif // VK_KHR_video_queue + + std::vector supported_blocks; + std::vector unsupported_blocks; + + struct UserData { + VkPhysicalDevice physicalDevice; + std::vector& supported_blocks; + std::vector& unsupported_blocks; + const detail::VpVariantDesc* variant; + GPDP2EntryPoints gpdp2; +#ifdef VK_KHR_video_queue + VideoInfo video; +#endif // VK_KHR_video_queue + uint32_t index; + detail::PFN_vpStructChainerCb pfnCb; + bool supported; + } userData{physicalDevice, supported_blocks, unsupported_blocks}; + + if (!vp.singleton) { + userData.gpdp2.pfnGetPhysicalDeviceFeatures2 = vp.GetPhysicalDeviceFeatures2; + userData.gpdp2.pfnGetPhysicalDeviceProperties2 = vp.GetPhysicalDeviceProperties2; + userData.gpdp2.pfnGetPhysicalDeviceFormatProperties2 = vp.GetPhysicalDeviceFormatProperties2; + userData.gpdp2.pfnGetPhysicalDeviceQueueFamilyProperties2 = vp.GetPhysicalDeviceQueueFamilyProperties2; + } + + // Attempt to load core versions of the GPDP2 entry points + if (userData.gpdp2.pfnGetPhysicalDeviceFeatures2 == nullptr) { + userData.gpdp2.pfnGetPhysicalDeviceFeatures2 = + (PFN_vkGetPhysicalDeviceFeatures2KHR)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFeatures2"); + userData.gpdp2.pfnGetPhysicalDeviceProperties2 = + (PFN_vkGetPhysicalDeviceProperties2KHR)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceProperties2"); + userData.gpdp2.pfnGetPhysicalDeviceFormatProperties2 = + (PFN_vkGetPhysicalDeviceFormatProperties2KHR)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFormatProperties2"); + userData.gpdp2.pfnGetPhysicalDeviceQueueFamilyProperties2 = + (PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceQueueFamilyProperties2"); + } + + // If not successful, try to load KHR variant + if (userData.gpdp2.pfnGetPhysicalDeviceFeatures2 == nullptr) { + userData.gpdp2.pfnGetPhysicalDeviceFeatures2 = + (PFN_vkGetPhysicalDeviceFeatures2KHR)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFeatures2KHR"); + userData.gpdp2.pfnGetPhysicalDeviceProperties2 = + (PFN_vkGetPhysicalDeviceProperties2KHR)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceProperties2KHR"); + userData.gpdp2.pfnGetPhysicalDeviceFormatProperties2 = + (PFN_vkGetPhysicalDeviceFormatProperties2KHR)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFormatProperties2KHR"); + userData.gpdp2.pfnGetPhysicalDeviceQueueFamilyProperties2 = + (PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceQueueFamilyProperties2KHR"); + } + + if (userData.gpdp2.pfnGetPhysicalDeviceFeatures2 == nullptr || + userData.gpdp2.pfnGetPhysicalDeviceProperties2 == nullptr || + userData.gpdp2.pfnGetPhysicalDeviceFormatProperties2 == nullptr || + userData.gpdp2.pfnGetPhysicalDeviceQueueFamilyProperties2 == nullptr) { + return VK_ERROR_EXTENSION_NOT_PRESENT; + } + +#ifdef VK_KHR_video_queue + PFN_vkGetInstanceProcAddr gipa = vp.singleton ? vkGetInstanceProcAddr : vp.GetInstanceProcAddr; + userData.video.pfnGetPhysicalDeviceVideoCapabilitiesKHR = + (PFN_vkGetPhysicalDeviceVideoCapabilitiesKHR)gipa(instance, "vkGetPhysicalDeviceVideoCapabilitiesKHR"); + userData.video.pfnGetPhysicalDeviceVideoFormatPropertiesKHR = + (PFN_vkGetPhysicalDeviceVideoFormatPropertiesKHR)gipa(instance, "vkGetPhysicalDeviceVideoFormatPropertiesKHR"); +#endif // VK_KHR_video_queue + + bool supported = true; + + const std::vector& gathered_profiles = detail::GatherProfiles(*pProfile); + + for (std::size_t profile_index = 0, profile_count = gathered_profiles.size(); profile_index < profile_count; ++profile_index) { + const char* profile_name = gathered_profiles[profile_index].profileName; + + const detail::VpProfileDesc* profile_desc = detail::vpGetProfileDesc(profile_name); + if (profile_desc == nullptr) { + return VK_ERROR_UNKNOWN; + } + + bool supported_profile = true; + + if (profile_desc->props.specVersion < gathered_profiles[profile_index].specVersion) { + supported_profile = false; + } + + VpBlockProperties block{gathered_profiles[profile_index], profile_desc->minApiVersion}; + + { + VkPhysicalDeviceProperties2KHR properties2{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR }; + userData.gpdp2.pfnGetPhysicalDeviceProperties2(physicalDevice, &properties2); + if (!detail::vpCheckVersion(properties2.properties.apiVersion, profile_desc->minApiVersion)) { + supported_profile = false; + } + } + + for (uint32_t required_capability_index = 0; required_capability_index < profile_desc->requiredCapabilityCount; ++required_capability_index) { + const detail::VpCapabilitiesDesc* required_capabilities = &profile_desc->pRequiredCapabilities[required_capability_index]; + + bool supported_block = false; + + for (uint32_t variant_index = 0; variant_index < required_capabilities->variantCount; ++variant_index) { + const detail::VpVariantDesc& variant_desc = required_capabilities->pVariants[variant_index]; + + bool supported_variant = true; + + for (uint32_t ext_index = 0; ext_index < variant_desc.deviceExtensionCount; ++ext_index) { + const char *requested_extension = variant_desc.pDeviceExtensions[ext_index].extensionName; + if (!detail::CheckExtension(supported_device_extensions.data(), supported_device_extensions.size(), requested_extension)) { + supported_variant = false; + } + } + + userData.variant = &variant_desc; + + if (supported_variant) { + VkPhysicalDeviceFeatures2KHR features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR }; + userData.variant->chainers.pfnFeature( + static_cast(static_cast(&features)), &userData, + [](VkBaseOutStructure* p, void* pUser) { + UserData* pUserData = static_cast(pUser); + pUserData->gpdp2.pfnGetPhysicalDeviceFeatures2( + pUserData->physicalDevice, + static_cast(static_cast(p))); + + pUserData->supported = true; + while (p != nullptr) { + if (!pUserData->variant->feature.pfnComparator(p)) { + pUserData->supported = false; + } + p = p->pNext; + } + } + ); + if (!userData.supported) { + supported_variant = false; + } + } + + if (supported_variant) { + VkPhysicalDeviceProperties2KHR device_properties2{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR }; + userData.variant->chainers.pfnProperty( + static_cast(static_cast(&device_properties2)), &userData, + [](VkBaseOutStructure* p, void* pUser) { + UserData* pUserData = static_cast(pUser); + pUserData->gpdp2.pfnGetPhysicalDeviceProperties2( + pUserData->physicalDevice, + static_cast(static_cast(p))); + + pUserData->supported = true; + while (p != nullptr) { + if (!pUserData->variant->property.pfnComparator(p)) { + pUserData->supported = false; + } + p = p->pNext; + } + } + ); + if (!userData.supported) { + supported_variant = false; + } + } + + if (supported_variant && userData.variant->queueFamilyCount > 0) { + uint32_t queue_family_count = 0; + userData.gpdp2.pfnGetPhysicalDeviceQueueFamilyProperties2(physicalDevice, &queue_family_count, nullptr); + std::vector queueFamilyProps(queue_family_count, { VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2_KHR }); + userData.variant->chainers.pfnQueueFamily( + queue_family_count, static_cast(static_cast(queueFamilyProps.data())), &userData, + [](uint32_t queue_family_count, VkBaseOutStructure* pBaseArray, void* pUser) { + UserData* pUserData = static_cast(pUser); + VkQueueFamilyProperties2KHR* pArray = static_cast(static_cast(pBaseArray)); + pUserData->gpdp2.pfnGetPhysicalDeviceQueueFamilyProperties2(pUserData->physicalDevice, &queue_family_count, pArray); + pUserData->supported = true; + for (uint32_t profile_qf_idx = 0; profile_qf_idx < pUserData->variant->queueFamilyCount; ++profile_qf_idx) { + bool found_matching = false; + for (uint32_t queue_family_index = 0; queue_family_index < queue_family_count; ++queue_family_index) { + bool this_matches = true; + VkBaseOutStructure* p = static_cast(static_cast(&pArray[queue_family_index])); + while (p != nullptr) { + if (!pUserData->variant->pQueueFamilies[profile_qf_idx].pfnComparator(p)) { + this_matches = false; + } + p = p->pNext; + } + if (this_matches) { + found_matching = true; + break; + } + } + if (!found_matching) { + pUserData->supported = false; + break; + } + } + } + ); + if (!userData.supported) { + supported_variant = false; + } + } + + for (uint32_t format_index = 0; supported_variant && (format_index < userData.variant->formatCount); ++format_index) { + userData.index = format_index; + VkFormatProperties2KHR format_properties2{ VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR }; + userData.variant->chainers.pfnFormat( + static_cast(static_cast(&format_properties2)), &userData, + [](VkBaseOutStructure* p, void* pUser) { + UserData* pUserData = static_cast(pUser); + pUserData->gpdp2.pfnGetPhysicalDeviceFormatProperties2( + pUserData->physicalDevice, + pUserData->variant->pFormats[pUserData->index].format, + static_cast(static_cast(p))); + pUserData->supported = true; + while (p != nullptr) { + if (!pUserData->variant->pFormats[pUserData->index].pfnComparator(p)) { + pUserData->supported = false; + } + p = p->pNext; + } + } + ); + if (!userData.supported) { + supported_variant = false; + } + } + +#ifdef VK_KHR_video_queue + if (supported_variant && (userData.variant->videoProfileCount > 0)) { + VkVideoProfileListInfoKHR profile_list{ VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR }; + profile_list.profileCount = 1; + profile_list.pProfiles = &userData.video.profileInfo; + userData.video.formatInfo.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_FORMAT_INFO_KHR; + userData.video.formatInfo.pNext = &profile_list; + + if (userData.video.pfnGetPhysicalDeviceVideoCapabilitiesKHR != nullptr && + userData.video.pfnGetPhysicalDeviceVideoFormatPropertiesKHR != nullptr) { + for (uint32_t video_profile_index = 0; video_profile_index < userData.variant->videoProfileCount; ++video_profile_index) { + userData.video.profileInfo = VkVideoProfileInfoKHR{ VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR }; + userData.video.pProfileDesc = &userData.variant->pVideoProfiles[video_profile_index]; + userData.supported = true; + userData.video.matchingProfiles = 0; + + detail::vpForEachMatchingVideoProfiles(&userData.video.profileInfo, &userData, + [](VkBaseOutStructure* p, void* pUser) { + UserData* pUserData = static_cast(pUser); + while (p != nullptr) { + if (!pUserData->video.pProfileDesc->info.pfnComparator(p)) { + return; + } + p = p->pNext; + } + + pUserData->video.supportedProfile = true; + + VkVideoCapabilitiesKHR capabilities{ VK_STRUCTURE_TYPE_VIDEO_CAPABILITIES_KHR }; + pUserData->video.pProfileDesc->chainers.pfnCapability( + static_cast(static_cast(&capabilities)), pUserData, + [](VkBaseOutStructure* p, void* pUser) { + UserData* pUserData = static_cast(pUser); + VkResult result = pUserData->video.pfnGetPhysicalDeviceVideoCapabilitiesKHR( + pUserData->physicalDevice, + &pUserData->video.profileInfo, + static_cast(static_cast(p))); + if (result != VK_SUCCESS) { + pUserData->video.supportedProfile = false; + return; + } + while (p != nullptr) { + if (!pUserData->video.pProfileDesc->capability.pfnComparator(p)) { + pUserData->supported = false; + } + p = p->pNext; + } + } + ); + + if (pUserData->video.supportedProfile) { + pUserData->video.matchingProfiles++; + } else { + return; + } + + std::vector format_props; + for (uint32_t format_index = 0; format_index < pUserData->video.pProfileDesc->formatCount; ++format_index) { + pUserData->index = format_index; + { + VkVideoFormatPropertiesKHR tmp_props{ VK_STRUCTURE_TYPE_VIDEO_FORMAT_PROPERTIES_KHR }; + pUserData->video.pProfileDesc->pFormats[format_index].pfnFiller(static_cast(static_cast(&tmp_props))); + pUserData->video.formatInfo.imageUsage = tmp_props.imageUsageFlags; + } + + uint32_t format_count = 0; + pUserData->video.pfnGetPhysicalDeviceVideoFormatPropertiesKHR(pUserData->physicalDevice, &pUserData->video.formatInfo, &format_count, nullptr); + format_props.resize(format_count, { VK_STRUCTURE_TYPE_VIDEO_FORMAT_PROPERTIES_KHR }); + pUserData->video.pProfileDesc->chainers.pfnFormat( + format_count, static_cast(static_cast(format_props.data())), pUserData, + [](uint32_t format_count, VkBaseOutStructure* pBaseArray, void* pUser) { + UserData* pUserData = static_cast(pUser); + VkVideoFormatPropertiesKHR* pArray = static_cast(static_cast(pBaseArray)); + pUserData->video.pfnGetPhysicalDeviceVideoFormatPropertiesKHR(pUserData->physicalDevice, &pUserData->video.formatInfo, &format_count, pArray); + bool found_matching = false; + for (uint32_t i = 0; i < format_count; ++i) { + bool this_matches = true; + VkBaseOutStructure* p = static_cast(static_cast(&pArray[i])); + while (p != nullptr) { + if (!pUserData->video.pProfileDesc->pFormats[pUserData->index].pfnComparator(p)) { + this_matches = false; + } + p = p->pNext; + } + if (this_matches) { + found_matching = true; + break; + } + } + if (!found_matching) { + pUserData->supported = false; + } + } + ); + } + } + ); + if (!userData.supported || userData.video.matchingProfiles == 0) { + supported_variant = false; + } + } + } else { + supported_variant = false; + } + } +#endif // VK_KHR_video_queue + + memcpy(block.blockName, variant_desc.blockName, VP_MAX_PROFILE_NAME_SIZE * sizeof(char)); + if (supported_variant) { + supported_blocks.push_back(block); + supported_block = true; + break; + } else { + unsupported_blocks.push_back(block); + } + } + + if (!supported_block) { + supported_profile = false; + } + } + + if (!supported_profile) { + supported = false; + } + } + + const std::vector& blocks = supported ? supported_blocks : unsupported_blocks; + + if (pProperties == nullptr) { + *pPropertyCount = static_cast(blocks.size()); + } else { + if (*pPropertyCount < static_cast(blocks.size())) { + result = VK_INCOMPLETE; + } else { + *pPropertyCount = static_cast(blocks.size()); + } + for (uint32_t i = 0, n = static_cast(blocks.size()); i < n; ++i) { + pProperties[i] = blocks[i]; + } + } + + *pSupported = supported ? VK_TRUE : VK_FALSE; + return VK_SUCCESS; +} + +VPAPI_ATTR VkResult vpGetPhysicalDeviceProfileSupport( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + VkInstance instance, + VkPhysicalDevice physicalDevice, + const VpProfileProperties* pProfile, + VkBool32 *pSupported) { + uint32_t count = 0; + + return vpGetPhysicalDeviceProfileVariantsSupport( +#ifdef VP_USE_OBJECT + capabilities, +#endif//VP_USE_OBJECT + instance, physicalDevice, pProfile, pSupported, &count, nullptr); +} + +VPAPI_ATTR VkResult vpCreateDevice( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + VkPhysicalDevice physicalDevice, + const VpDeviceCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDevice* pDevice) { +#ifdef VP_USE_OBJECT + const VpCapabilities_T& vp = capabilities == nullptr ? VpCapabilities_T::Get() : *capabilities; +#else + const VpCapabilities_T& vp = VpCapabilities_T::Get(); +#endif//VP_USE_OBJECT + + if (physicalDevice == VK_NULL_HANDLE || pCreateInfo == nullptr || pDevice == nullptr) { + return vp.CreateDevice(physicalDevice, pCreateInfo == nullptr ? nullptr : pCreateInfo->pCreateInfo, pAllocator, pDevice); + } + + const std::vector& blocks = detail::GatherBlocks( + pCreateInfo->enabledFullProfileCount, pCreateInfo->pEnabledFullProfiles, + pCreateInfo->enabledProfileBlockCount, pCreateInfo->pEnabledProfileBlocks); + + std::unique_ptr chain = std::make_unique(); + std::vector structureTypes; + + std::vector extensions; + for (std::uint32_t ext_index = 0, ext_count = pCreateInfo->pCreateInfo->enabledExtensionCount; ext_index < ext_count; ++ext_index) { + extensions.push_back(pCreateInfo->pCreateInfo->ppEnabledExtensionNames[ext_index]); + } + + for (std::size_t block_index = 0, block_count = blocks.size(); block_index < block_count; ++block_index) { + const detail::VpProfileDesc* pProfileDesc = detail::vpGetProfileDesc(blocks[block_index].profiles.profileName); + if (pProfileDesc == nullptr) return VK_ERROR_UNKNOWN; + + for (std::size_t caps_index = 0, caps_count = pProfileDesc->requiredCapabilityCount; caps_index < caps_count; ++caps_index) { + const detail::VpCapabilitiesDesc* pCapsDesc = &pProfileDesc->pRequiredCapabilities[caps_index]; + + for (std::size_t variant_index = 0, variant_count = pCapsDesc->variantCount; variant_index < variant_count; ++variant_index) { + const detail::VpVariantDesc* variant = &pCapsDesc->pVariants[variant_index]; + + if (strcmp(blocks[block_index].blockName, "") != 0) { + if (strcmp(variant->blockName, blocks[block_index].blockName) != 0) { + continue; + } + } + + for (uint32_t type_index = 0; type_index < variant->featureStructTypeCount; ++type_index) { + const VkStructureType type = variant->pFeatureStructTypes[type_index]; + if (std::find(structureTypes.begin(), structureTypes.end(), type) == std::end(structureTypes)) { + structureTypes.push_back(type); + } + } + + detail::GetExtensions(variant->deviceExtensionCount, variant->pDeviceExtensions, extensions); + } + } + } + + VkBaseOutStructure* pNext = static_cast(const_cast(pCreateInfo->pCreateInfo->pNext)); + detail::GatherStructureTypes(structureTypes, pNext); + + chain->Build(structureTypes); + + VkPhysicalDeviceFeatures2KHR* pFeatures = &chain->requiredFeaturesChain; + if (pCreateInfo->pCreateInfo->pEnabledFeatures) { + pFeatures->features = *pCreateInfo->pCreateInfo->pEnabledFeatures; + } + + for (std::size_t block_index = 0, block_count = blocks.size(); block_index < block_count; ++block_index) { + const detail::VpProfileDesc* pProfileDesc = detail::vpGetProfileDesc(blocks[block_index].profiles.profileName); + if (pProfileDesc == nullptr) { + return VK_ERROR_UNKNOWN; + } + + for (std::size_t caps_index = 0, caps_count = pProfileDesc->requiredCapabilityCount; caps_index < caps_count; ++caps_index) { + const detail::VpCapabilitiesDesc* pCapsDesc = &pProfileDesc->pRequiredCapabilities[caps_index]; + + if (pCapsDesc->variantCount > 1) { + continue; // Multiple variants are not supported by this version of vpCreateDevice + } + + for (std::size_t variant_index = 0, variant_count = pCapsDesc->variantCount; variant_index < variant_count; ++variant_index) { + const detail::VpVariantDesc* variant = &pCapsDesc->pVariants[variant_index]; + + VkBaseOutStructure* base_ptr = reinterpret_cast(pFeatures); + if (variant->feature.pfnFiller != nullptr) { + while (base_ptr != nullptr) { + variant->feature.pfnFiller(base_ptr); + base_ptr = base_ptr->pNext; + } + } + } + } + } + + chain->ApplyFeatures(pCreateInfo); + + if (pCreateInfo->flags & VP_DEVICE_CREATE_DISABLE_ROBUST_BUFFER_ACCESS_BIT) { + pFeatures->features.robustBufferAccess = VK_FALSE; + } + + VkDeviceCreateInfo createInfo{VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO}; + createInfo.pNext = &chain->requiredFeaturesChain; + createInfo.queueCreateInfoCount = pCreateInfo->pCreateInfo->queueCreateInfoCount; + createInfo.pQueueCreateInfos = pCreateInfo->pCreateInfo->pQueueCreateInfos; + createInfo.enabledExtensionCount = static_cast(extensions.size()); + createInfo.ppEnabledExtensionNames = extensions.data(); + + return vp.CreateDevice(physicalDevice, &createInfo, pAllocator, pDevice); +} + +VPAPI_ATTR VkResult vpGetProfileInstanceExtensionProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pPropertyCount, + VkExtensionProperties* pProperties) { + return detail::vpGetProfileExtensionProperties( +#ifdef VP_USE_OBJECT + capabilities, +#endif//VP_USE_OBJECT + pProfile, pBlockName, detail::EXTENSION_INSTANCE, pPropertyCount, pProperties); +} + +VPAPI_ATTR VkResult vpGetProfileDeviceExtensionProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pPropertyCount, + VkExtensionProperties* pProperties) { + return detail::vpGetProfileExtensionProperties( +#ifdef VP_USE_OBJECT + capabilities, +#endif//VP_USE_OBJECT + pProfile, pBlockName, detail::EXTENSION_DEVICE, pPropertyCount, pProperties); +} + +VPAPI_ATTR VkResult vpGetProfileFeatures( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + void* pNext) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + VkResult result = pBlockName == nullptr ? VK_SUCCESS : VK_INCOMPLETE; + + const std::vector& gathered_profiles = detail::GatherProfiles(*pProfile); + + for (std::size_t profile_index = 0, profile_count = gathered_profiles.size(); profile_index < profile_count; ++profile_index) { + const detail::VpProfileDesc* profile_desc = detail::vpGetProfileDesc(gathered_profiles[profile_index].profileName); + if (profile_desc == nullptr) return VK_ERROR_UNKNOWN; + + for (uint32_t capability_index = 0; capability_index < profile_desc->requiredCapabilityCount; ++capability_index) { + const detail::VpCapabilitiesDesc& cap_desc = profile_desc->pRequiredCapabilities[capability_index]; + + for (uint32_t variant_index = 0; variant_index < cap_desc.variantCount; ++variant_index) { + const detail::VpVariantDesc& variant = cap_desc.pVariants[variant_index]; + if (pBlockName != nullptr) { + if (strcmp(variant.blockName, pBlockName) != 0) { + continue; + } + result = VK_SUCCESS; + } + + if (variant.feature.pfnFiller == nullptr) continue; + + VkBaseOutStructure* p = static_cast(pNext); + while (p != nullptr) { + variant.feature.pfnFiller(p); + p = p->pNext; + } + } + } + } + + return result; +} + +VPAPI_ATTR VkResult vpGetProfileProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + void* pNext) { + VkResult result = pBlockName == nullptr ? VK_SUCCESS : VK_INCOMPLETE; + + VkBool32 multiple_variants = VK_FALSE; + if (vpHasMultipleVariantsProfile( +#ifdef VP_USE_OBJECT + capabilities, +#endif//VP_USE_OBJECT + pProfile, + &multiple_variants) == VK_ERROR_UNKNOWN) { + return VK_ERROR_UNKNOWN; + } + if (multiple_variants == VK_TRUE && pBlockName == nullptr) { + return VK_ERROR_UNKNOWN; + } + + const std::vector& gathered_profiles = detail::GatherProfiles(*pProfile); + + for (std::size_t profile_index = 0, profile_count = gathered_profiles.size(); profile_index < profile_count; ++profile_index) { + const detail::VpProfileDesc* profile_desc = detail::vpGetProfileDesc(gathered_profiles[profile_index].profileName); + if (profile_desc == nullptr) return VK_ERROR_UNKNOWN; + + for (uint32_t capability_index = 0; capability_index < profile_desc->requiredCapabilityCount; ++capability_index) { + const detail::VpCapabilitiesDesc& cap_desc = profile_desc->pRequiredCapabilities[capability_index]; + + for (uint32_t variant_index = 0; variant_index < cap_desc.variantCount; ++variant_index) { + const detail::VpVariantDesc& variant = cap_desc.pVariants[variant_index]; + if (pBlockName != nullptr) { + if (strcmp(variant.blockName, pBlockName) != 0) { + continue; + } + result = VK_SUCCESS; + } + + if (variant.property.pfnFiller == nullptr) continue; + + VkBaseOutStructure* p = static_cast(pNext); + while (p != nullptr) { + variant.property.pfnFiller(p); + p = p->pNext; + } + } + } + } + + return result; +} + +VPAPI_ATTR VkResult vpGetProfileQueueFamilyProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pPropertyCount, + VkQueueFamilyProperties2KHR* pProperties) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + if (pPropertyCount == nullptr) return VK_ERROR_UNKNOWN; + + VkResult result = pBlockName == nullptr ? VK_SUCCESS : VK_INCOMPLETE; + + const std::vector& gathered_profiles = detail::GatherProfiles(*pProfile); + + uint32_t total_queue_family_count = 0; + + for (std::size_t profile_index = 0, profile_count = gathered_profiles.size(); profile_index < profile_count; ++profile_index) { + const detail::VpProfileDesc* profile_desc = detail::vpGetProfileDesc(gathered_profiles[profile_index].profileName); + if (profile_desc == nullptr) return VK_ERROR_UNKNOWN; + + for (uint32_t capability_index = 0; capability_index < profile_desc->requiredCapabilityCount; ++capability_index) { + const detail::VpCapabilitiesDesc& cap_desc = profile_desc->pRequiredCapabilities[capability_index]; + + for (uint32_t variant_index = 0; variant_index < cap_desc.variantCount; ++variant_index) { + const detail::VpVariantDesc& variant = cap_desc.pVariants[variant_index]; + if (pBlockName != nullptr) { + if (strcmp(variant.blockName, pBlockName) != 0) { + continue; + } + result = VK_SUCCESS; + } + + if (pProperties != nullptr) { + for (uint32_t i = 0; i < variant.queueFamilyCount; ++i) { + if (total_queue_family_count < *pPropertyCount) { + if (variant.pQueueFamilies[i].pfnFiller == nullptr) continue; + + VkBaseOutStructure* p = reinterpret_cast(pProperties); + while (p != nullptr) { + variant.pQueueFamilies[i].pfnFiller(p); + p = p->pNext; + } + + total_queue_family_count++; + pProperties++; + } else { + result = VK_INCOMPLETE; + break; + } + } + } else { + total_queue_family_count += variant.queueFamilyCount; + } + } + } + } + + *pPropertyCount = total_queue_family_count; + return result; +} + +VPAPI_ATTR VkResult vpGetProfileFormats( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pFormatCount, + VkFormat* pFormats) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + VkResult result = pBlockName == nullptr ? VK_SUCCESS : VK_INCOMPLETE; + + std::vector results; + + const std::vector& gathered_profiles = detail::GatherProfiles(*pProfile); + + for (std::size_t profile_index = 0, profile_count = gathered_profiles.size(); profile_index < profile_count; ++profile_index) { + const detail::VpProfileDesc* profile_desc = detail::vpGetProfileDesc(gathered_profiles[profile_index].profileName); + if (profile_desc == nullptr) return VK_ERROR_UNKNOWN; + + for (uint32_t capability_index = 0; capability_index < profile_desc->requiredCapabilityCount; ++capability_index) { + const detail::VpCapabilitiesDesc& cap_desc = profile_desc->pRequiredCapabilities[capability_index]; + + for (uint32_t variant_index = 0; variant_index < cap_desc.variantCount; ++variant_index) { + const detail::VpVariantDesc& variant = cap_desc.pVariants[variant_index]; + if (pBlockName != nullptr) { + if (strcmp(variant.blockName, pBlockName) != 0) { + continue; + } + result = VK_SUCCESS; + } + + for (uint32_t format_index = 0; format_index < variant.formatCount; ++format_index) { + if (std::find(results.begin(), results.end(), variant.pFormats[format_index].format) == std::end(results)) { + results.push_back(variant.pFormats[format_index].format); + } + } + } + } + } + + const uint32_t count = static_cast(results.size()); + + if (pFormats == nullptr) { + *pFormatCount = count; + } else { + if (*pFormatCount < count) { + result = VK_INCOMPLETE; + } else { + *pFormatCount = count; + } + + if (*pFormatCount > 0) { + memcpy(pFormats, &results[0], *pFormatCount * sizeof(VkFormat)); + } + } + return result; +} + +VPAPI_ATTR VkResult vpGetProfileFormatProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + VkFormat format, + void* pNext) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + VkResult result = pBlockName == nullptr ? VK_SUCCESS : VK_INCOMPLETE; + + const std::vector& gathered_profiles = detail::GatherProfiles(*pProfile); + + for (std::size_t profile_index = 0, profile_count = gathered_profiles.size(); profile_index < profile_count; ++profile_index) { + const char* profile_name = gathered_profiles[profile_index].profileName; + + const detail::VpProfileDesc* pProfileDesc = detail::vpGetProfileDesc(profile_name); + if (pProfileDesc == nullptr) return VK_ERROR_UNKNOWN; + + for (uint32_t required_capability_index = 0; required_capability_index < pProfileDesc->requiredCapabilityCount; + ++required_capability_index) { + const detail::VpCapabilitiesDesc& required_capabilities = pProfileDesc->pRequiredCapabilities[required_capability_index]; + + for (uint32_t required_variant_index = 0; required_variant_index < required_capabilities.variantCount; ++required_variant_index) { + const detail::VpVariantDesc& variant = required_capabilities.pVariants[required_variant_index]; + if (pBlockName != nullptr) { + if (strcmp(variant.blockName, pBlockName) != 0) { + continue; + } + result = VK_SUCCESS; + } + + for (uint32_t format_index = 0; format_index < variant.formatCount; ++format_index) { + if (variant.pFormats[format_index].format != format) { + continue; + } + + VkBaseOutStructure* base_ptr = static_cast(static_cast(pNext)); + while (base_ptr != nullptr) { + variant.pFormats[format_index].pfnFiller(base_ptr); + base_ptr = base_ptr->pNext; + } +#if defined(VK_VERSION_1_3) || defined(VK_KHR_format_feature_flags2) + VkFormatProperties2KHR* fp2 = static_cast( + detail::vpGetStructure(pNext, VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR)); + VkFormatProperties3KHR* fp3 = static_cast( + detail::vpGetStructure(pNext, VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR)); + if (fp3 != nullptr) { + VkFormatProperties2KHR fp{ VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR }; + variant.pFormats[format_index].pfnFiller(static_cast(static_cast(&fp))); + fp3->linearTilingFeatures |= static_cast(fp3->linearTilingFeatures | fp.formatProperties.linearTilingFeatures); + fp3->optimalTilingFeatures |= static_cast(fp3->optimalTilingFeatures | fp.formatProperties.optimalTilingFeatures); + fp3->bufferFeatures |= static_cast(fp3->bufferFeatures | fp.formatProperties.bufferFeatures); + } + if (fp2 != nullptr) { + VkFormatProperties3KHR fp{ VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR }; + variant.pFormats[format_index].pfnFiller(static_cast(static_cast(&fp))); + fp2->formatProperties.linearTilingFeatures |= static_cast(fp2->formatProperties.linearTilingFeatures | fp.linearTilingFeatures); + fp2->formatProperties.optimalTilingFeatures |= static_cast(fp2->formatProperties.optimalTilingFeatures | fp.optimalTilingFeatures); + fp2->formatProperties.bufferFeatures |= static_cast(fp2->formatProperties.bufferFeatures | fp.bufferFeatures); + } +#endif + } + } + } + } + + return result; +} + +VPAPI_ATTR VkResult vpGetProfileFeatureStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes) { + return detail::vpGetProfileStructureTypes( +#ifdef VP_USE_OBJECT + capabilities, +#endif//VP_USE_OBJECT + pProfile, pBlockName, detail::STRUCTURE_FEATURE, pStructureTypeCount, pStructureTypes); +} + +VPAPI_ATTR VkResult vpGetProfilePropertyStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes) { + return detail::vpGetProfileStructureTypes( +#ifdef VP_USE_OBJECT + capabilities, +#endif//VP_USE_OBJECT + pProfile, pBlockName, detail::STRUCTURE_PROPERTY, pStructureTypeCount, pStructureTypes); +} + +VPAPI_ATTR VkResult vpGetProfileQueueFamilyStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes) { + return detail::vpGetProfileStructureTypes( +#ifdef VP_USE_OBJECT + capabilities, +#endif//VP_USE_OBJECT + pProfile, pBlockName, detail::STRUCTURE_QUEUE_FAMILY, pStructureTypeCount, pStructureTypes); +} + +VPAPI_ATTR VkResult vpGetProfileFormatStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes) { + return detail::vpGetProfileStructureTypes( +#ifdef VP_USE_OBJECT + capabilities, +#endif//VP_USE_OBJECT + pProfile, pBlockName, detail::STRUCTURE_FORMAT, pStructureTypeCount, pStructureTypes); +} + +#ifdef VK_KHR_video_queue +// Query the list of video profiles specified by the profile +VPAPI_ATTR VkResult vpGetProfileVideoProfiles( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pVideoProfileCount, + VpVideoProfileProperties* pVideoProfiles) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + if (pVideoProfileCount == nullptr) return VK_ERROR_UNKNOWN; + + VkResult result = pBlockName == nullptr ? VK_SUCCESS : VK_INCOMPLETE; + + uint32_t total_video_profile_count = 0; + + const std::vector& gathered_profiles = detail::GatherProfiles(*pProfile); + + for (std::size_t profile_index = 0, profile_count = gathered_profiles.size(); profile_index < profile_count; ++profile_index) { + const detail::VpProfileDesc* profile_desc = detail::vpGetProfileDesc(gathered_profiles[profile_index].profileName); + if (profile_desc == nullptr) return VK_ERROR_UNKNOWN; + + for (uint32_t capability_index = 0; capability_index < profile_desc->requiredCapabilityCount; ++capability_index) { + const detail::VpCapabilitiesDesc& cap_desc = profile_desc->pRequiredCapabilities[capability_index]; + + for (uint32_t variant_index = 0; variant_index < cap_desc.variantCount; ++variant_index) { + const detail::VpVariantDesc& variant = cap_desc.pVariants[variant_index]; + if (pBlockName != nullptr) { + if (strcmp(variant.blockName, pBlockName) != 0) { + continue; + } + result = VK_SUCCESS; + } + + if (pVideoProfiles != nullptr) { + for (uint32_t i = 0; i < variant.videoProfileCount; ++i) { + if (total_video_profile_count < *pVideoProfileCount) { + *pVideoProfiles = variant.pVideoProfiles[i].properties; + total_video_profile_count++; + pVideoProfiles++; + } else { + result = VK_INCOMPLETE; + break; + } + } + } else { + total_video_profile_count += variant.videoProfileCount; + } + } + } + } + + *pVideoProfileCount = total_video_profile_count; + return result; +} + +VPAPI_ATTR VkResult vpGetProfileVideoProfileInfo( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + VkVideoProfileInfoKHR* pVideoProfileInfo) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + const detail::VpVideoProfileDesc* pVideoProfileDesc = nullptr; + VkResult result = detail::vpGetProfileVideoProfileDesc(pProfile, pBlockName, videoProfileIndex, &pVideoProfileDesc); + + if (pVideoProfileDesc != nullptr) { + VkBaseOutStructure* p = reinterpret_cast(pVideoProfileInfo); + while (p != nullptr) { + pVideoProfileDesc->info.pfnFiller(p); + p = p->pNext; + } + } + + return result; +} + +VPAPI_ATTR VkResult vpGetProfileVideoCapabilities( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + void* pNext) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + const detail::VpVideoProfileDesc* pVideoProfileDesc = nullptr; + VkResult result = detail::vpGetProfileVideoProfileDesc(pProfile, pBlockName, videoProfileIndex, &pVideoProfileDesc); + + if (pVideoProfileDesc != nullptr) { + VkBaseOutStructure* p = reinterpret_cast(pNext); + while (p != nullptr) { + pVideoProfileDesc->capability.pfnFiller(p); + p = p->pNext; + } + } + + return result; +} + +VPAPI_ATTR VkResult vpGetProfileVideoFormatProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + uint32_t* pPropertyCount, + VkVideoFormatPropertiesKHR* pProperties) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + const detail::VpVideoProfileDesc* pVideoProfileDesc = nullptr; + VkResult result = detail::vpGetProfileVideoProfileDesc(pProfile, pBlockName, videoProfileIndex, &pVideoProfileDesc); + + uint32_t property_count = 0; + if (pVideoProfileDesc != nullptr) { + if (pProperties != nullptr) { + for (; property_count < pVideoProfileDesc->formatCount; ++property_count) { + if (property_count < *pPropertyCount) { + VkBaseOutStructure* p = reinterpret_cast(&pProperties[property_count]); + while (p != nullptr) { + pVideoProfileDesc->pFormats[property_count].pfnFiller(p); + p = p->pNext; + } + } else { + result = VK_INCOMPLETE; + break; + } + } + } else { + property_count = pVideoProfileDesc->formatCount; + } + } + + *pPropertyCount = property_count; + return result; +} + +VPAPI_ATTR VkResult vpGetProfileVideoProfileInfoStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + const detail::VpVideoProfileDesc* pVideoProfileDesc = nullptr; + VkResult result = detail::vpGetProfileVideoProfileDesc(pProfile, pBlockName, videoProfileIndex, &pVideoProfileDesc); + + if (pVideoProfileDesc != nullptr) { + if (pStructureTypes != nullptr) { + if (*pStructureTypeCount < pVideoProfileDesc->infoStructTypeCount) { + result = VK_INCOMPLETE; + } else { + *pStructureTypeCount = pVideoProfileDesc->infoStructTypeCount; + } + if (*pStructureTypeCount > 0) { + memcpy(pStructureTypes, pVideoProfileDesc->pInfoStructTypes, *pStructureTypeCount * sizeof(VkStructureType)); + } + } else { + *pStructureTypeCount = pVideoProfileDesc->infoStructTypeCount; + } + } + + return result; +} + +VPAPI_ATTR VkResult vpGetProfileVideoCapabilityStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + const detail::VpVideoProfileDesc* pVideoProfileDesc = nullptr; + VkResult result = detail::vpGetProfileVideoProfileDesc(pProfile, pBlockName, videoProfileIndex, &pVideoProfileDesc); + + if (pVideoProfileDesc != nullptr) { + if (pStructureTypes != nullptr) { + if (*pStructureTypeCount < pVideoProfileDesc->capabilityStructTypeCount) { + result = VK_INCOMPLETE; + } else { + *pStructureTypeCount = pVideoProfileDesc->capabilityStructTypeCount; + } + if (*pStructureTypeCount > 0) { + memcpy(pStructureTypes, pVideoProfileDesc->pCapabilityStructTypes, *pStructureTypeCount * sizeof(VkStructureType)); + } + } else { + *pStructureTypeCount = pVideoProfileDesc->capabilityStructTypeCount; + } + } + + return result; +} + +VPAPI_ATTR VkResult vpGetProfileVideoFormatStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + const detail::VpVideoProfileDesc* pVideoProfileDesc = nullptr; + VkResult result = detail::vpGetProfileVideoProfileDesc(pProfile, pBlockName, videoProfileIndex, &pVideoProfileDesc); + + if (pVideoProfileDesc != nullptr) { + if (pStructureTypes != nullptr) { + if (*pStructureTypeCount < pVideoProfileDesc->formatStructTypeCount) { + result = VK_INCOMPLETE; + } else { + *pStructureTypeCount = pVideoProfileDesc->formatStructTypeCount; + } + if (*pStructureTypeCount > 0) { + memcpy(pStructureTypes, pVideoProfileDesc->pFormatStructTypes, *pStructureTypeCount * sizeof(VkStructureType)); + } + } else { + *pStructureTypeCount = pVideoProfileDesc->formatStructTypeCount; + } + } + + return result; +} +#endif // VK_KHR_video_queue diff --git a/vulkan_profiles/vulkan_profiles.h b/vulkan_profiles/vulkan_profiles.h new file mode 100644 index 0000000..e1d92f4 --- /dev/null +++ b/vulkan_profiles/vulkan_profiles.h @@ -0,0 +1,433 @@ + +/* + * Copyright (C) 2021-2026 Valve Corporation + * Copyright (C) 2021-2026 LunarG, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License") + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is ***GENERATED***. Do Not Edit. + * See scripts/gen_profiles_solution.py for modifications. + */ + +#ifndef VULKAN_PROFILES_H_ +#define VULKAN_PROFILES_H_ 1 + +#define VPAPI_ATTR + +#ifdef __cplusplus + extern "C" { +#endif + +#include + +#if defined(VK_VERSION_1_3) && \ + defined(VK_KHR_get_surface_capabilities2) && \ + defined(VK_KHR_global_priority) && \ + defined(VK_KHR_swapchain) +#define VP_LEARN_how_to_vulkan_2026 1 +#define VP_LEARN_HOW_TO_VULKAN_2026_NAME "VP_LEARN_how_to_vulkan_2026" +#define VP_LEARN_HOW_TO_VULKAN_2026_SPEC_VERSION 1 +#define VP_LEARN_HOW_TO_VULKAN_2026_MIN_API_VERSION VK_MAKE_VERSION(1, 3, 204) +#endif + +#define VP_HEADER_VERSION_COMPLETE VK_MAKE_API_VERSION(0, 2, 0, VK_HEADER_VERSION) + +#define VP_MAX_PROFILE_NAME_SIZE 256U + +typedef struct VpProfileProperties { + char profileName[VP_MAX_PROFILE_NAME_SIZE]; + uint32_t specVersion; +} VpProfileProperties; + +typedef struct VpBlockProperties { + VpProfileProperties profiles; + uint32_t apiVersion; + char blockName[VP_MAX_PROFILE_NAME_SIZE]; +} VpBlockProperties; + +typedef struct VpVideoProfileProperties { + char name[VP_MAX_PROFILE_NAME_SIZE]; +} VpVideoProfileProperties; + +typedef enum VpInstanceCreateFlagBits { + VP_INSTANCE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VpInstanceCreateFlagBits; +typedef VkFlags VpInstanceCreateFlags; + +typedef struct VpInstanceCreateInfo { + const VkInstanceCreateInfo* pCreateInfo; + VpInstanceCreateFlags flags; + uint32_t enabledFullProfileCount; + const VpProfileProperties* pEnabledFullProfiles; + uint32_t enabledProfileBlockCount; + const VpBlockProperties* pEnabledProfileBlocks; +} VpInstanceCreateInfo; + +typedef enum VpDeviceCreateFlagBits { + VP_DEVICE_CREATE_DISABLE_ROBUST_BUFFER_ACCESS_BIT = 0x0000001, + VP_DEVICE_CREATE_DISABLE_ROBUST_IMAGE_ACCESS_BIT = 0x0000002, + VP_DEVICE_CREATE_DISABLE_ROBUST_ACCESS = + VP_DEVICE_CREATE_DISABLE_ROBUST_BUFFER_ACCESS_BIT | VP_DEVICE_CREATE_DISABLE_ROBUST_IMAGE_ACCESS_BIT, + + VP_DEVICE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VpDeviceCreateFlagBits; +typedef VkFlags VpDeviceCreateFlags; + +typedef struct VpDeviceCreateInfo { + const VkDeviceCreateInfo* pCreateInfo; + VpDeviceCreateFlags flags; + uint32_t enabledFullProfileCount; + const VpProfileProperties* pEnabledFullProfiles; + uint32_t enabledProfileBlockCount; + const VpBlockProperties* pEnabledProfileBlocks; +} VpDeviceCreateInfo; + +VK_DEFINE_HANDLE(VpCapabilities) + +typedef enum VpCapabilitiesCreateFlagBits { + VP_PROFILE_CREATE_STATIC_BIT = (1 << 0), + //VP_PROFILE_CREATE_DYNAMIC_BIT = (1 << 1), + VP_PROFILE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VpCapabilitiesCreateFlagBits; + +typedef VkFlags VpCapabilitiesCreateFlags; + +// Pointers to some Vulkan functions - a subset used by the library. +// Used in VpCapabilitiesCreateInfo::pVulkanFunctions. + +typedef struct VpVulkanFunctions { + /// Required when using VP_DYNAMIC_VULKAN_FUNCTIONS. + PFN_vkGetInstanceProcAddr GetInstanceProcAddr; + /// Required when using VP_DYNAMIC_VULKAN_FUNCTIONS. + PFN_vkGetDeviceProcAddr GetDeviceProcAddr; + PFN_vkEnumerateInstanceVersion EnumerateInstanceVersion; + PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties; + PFN_vkEnumerateDeviceExtensionProperties EnumerateDeviceExtensionProperties; + PFN_vkGetPhysicalDeviceFeatures2 GetPhysicalDeviceFeatures2; + PFN_vkGetPhysicalDeviceProperties2 GetPhysicalDeviceProperties2; + PFN_vkGetPhysicalDeviceFormatProperties2 GetPhysicalDeviceFormatProperties2; + PFN_vkGetPhysicalDeviceQueueFamilyProperties2 GetPhysicalDeviceQueueFamilyProperties2; + PFN_vkCreateInstance CreateInstance; + PFN_vkCreateDevice CreateDevice; +} VpVulkanFunctions; + +/// Description of a Allocator to be created. +typedef struct VpCapabilitiesCreateInfo +{ + /// Flags for created allocator. Use #VpInstanceCreateFlagBits enum. + VpCapabilitiesCreateFlags flags; + uint32_t apiVersion; + const VpVulkanFunctions* pVulkanFunctions; +} VpCapabilitiesCreateInfo; + +VPAPI_ATTR VkResult vpCreateCapabilities( + const VpCapabilitiesCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VpCapabilities* pCapabilities); + +/// Destroys allocator object. +VPAPI_ATTR void vpDestroyCapabilities( + VpCapabilities capabilities, + const VkAllocationCallbacks* pAllocator); + +// Query the list of available profiles in the library +VPAPI_ATTR VkResult vpGetProfiles( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + uint32_t* pPropertyCount, + VpProfileProperties* pProperties); + +// List the required profiles of a profile +VPAPI_ATTR VkResult vpGetProfileRequiredProfiles( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + uint32_t* pPropertyCount, + VpProfileProperties* pProperties); + +// Query the profile required Vulkan API version +VPAPI_ATTR uint32_t vpGetProfileAPIVersion( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile); + +// List the recommended fallback profiles of a profile +VPAPI_ATTR VkResult vpGetProfileFallbacks( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + uint32_t* pPropertyCount, + VpProfileProperties* pProperties); + +// Query whether the profile has multiple variants. Profiles with multiple variants can only use vpGetInstanceProfileSupport and vpGetPhysicalDeviceProfileSupport capabilities of the library. Other function will return a VK_ERROR_UNKNOWN error +VPAPI_ATTR VkResult vpHasMultipleVariantsProfile( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + VkBool32* pHasMultipleVariants); + +// Check whether a profile is supported at the instance level +VPAPI_ATTR VkResult vpGetInstanceProfileSupport( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const char* pLayerName, + const VpProfileProperties* pProfile, + VkBool32* pSupported); + +// Check whether a variant of a profile is supported at the instance level and report this list of blocks used to validate the profiles +VPAPI_ATTR VkResult vpGetInstanceProfileVariantsSupport( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const char* pLayerName, + const VpProfileProperties* pProfile, + VkBool32* pSupported, + uint32_t* pPropertyCount, + VpBlockProperties* pProperties); + +// Create a VkInstance with the profile instance extensions enabled +VPAPI_ATTR VkResult vpCreateInstance( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpInstanceCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkInstance* pInstance); + +// Check whether a profile is supported by the physical device +VPAPI_ATTR VkResult vpGetPhysicalDeviceProfileSupport( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + VkInstance instance, + VkPhysicalDevice physicalDevice, + const VpProfileProperties* pProfile, + VkBool32* pSupported); + +// Check whether a variant of a profile is supported by the physical device and report this list of blocks used to validate the profiles +VPAPI_ATTR VkResult vpGetPhysicalDeviceProfileVariantsSupport( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + VkInstance instance, + VkPhysicalDevice physicalDevice, + const VpProfileProperties* pProfile, + VkBool32* pSupported, + uint32_t* pPropertyCount, + VpBlockProperties* pProperties); + +// Create a VkDevice with the profile features and device extensions enabled +VPAPI_ATTR VkResult vpCreateDevice( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + VkPhysicalDevice physicalDevice, + const VpDeviceCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDevice* pDevice); + +// Query the list of instance extensions of a profile +VPAPI_ATTR VkResult vpGetProfileInstanceExtensionProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pPropertyCount, + VkExtensionProperties* pProperties); + +// Query the list of device extensions of a profile +VPAPI_ATTR VkResult vpGetProfileDeviceExtensionProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pPropertyCount, + VkExtensionProperties* pProperties); + +// Fill the feature structures with the requirements of a profile +VPAPI_ATTR VkResult vpGetProfileFeatures( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + void* pNext); + +// Query the list of feature structure types specified by the profile +VPAPI_ATTR VkResult vpGetProfileFeatureStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes); + +// Fill the property structures with the requirements of a profile +VPAPI_ATTR VkResult vpGetProfileProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + void* pNext); + +// Query the list of property structure types specified by the profile +VPAPI_ATTR VkResult vpGetProfilePropertyStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes); + +// Fill the queue family property structures with the requirements of a profile +VPAPI_ATTR VkResult vpGetProfileQueueFamilyProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pPropertyCount, + VkQueueFamilyProperties2KHR* pProperties); + +// Query the list of queue family property structure types specified by the profile +VPAPI_ATTR VkResult vpGetProfileQueueFamilyStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes); + +// Query the list of formats with specified requirements by a profile +VPAPI_ATTR VkResult vpGetProfileFormats( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pFormatCount, + VkFormat* pFormats); + +// Query the requirements of a format for a profile +VPAPI_ATTR VkResult vpGetProfileFormatProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + VkFormat format, + void* pNext); + +// Query the list of format structure types specified by the profile +VPAPI_ATTR VkResult vpGetProfileFormatStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes); + +#ifdef VK_KHR_video_queue +// Query the list of video profiles specified by the profile +VPAPI_ATTR VkResult vpGetProfileVideoProfiles( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pVideoProfileCount, + VpVideoProfileProperties* pVideoProfiles); + +// Query the video profile info structures for a video profile defined by a profile +VPAPI_ATTR VkResult vpGetProfileVideoProfileInfo( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + VkVideoProfileInfoKHR* pVideoProfileInfo); + +// Query the list of video profile info structure types specified by the profile for a video profile +VPAPI_ATTR VkResult vpGetProfileVideoProfileInfoStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes); + +// Query the video capabilities requirements for a video profile defined by a profile +VPAPI_ATTR VkResult vpGetProfileVideoCapabilities( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + void* pNext); + +// Query the list of video capability structure types specified by the profile for a video profile +VPAPI_ATTR VkResult vpGetProfileVideoCapabilityStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes); + +// Query the video format property requirements for a video profile defined by a profile +VPAPI_ATTR VkResult vpGetProfileVideoFormatProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + uint32_t* pPropertyCount, + VkVideoFormatPropertiesKHR* pProperties); + +// Query the list of video format property structure types specified by the profile for a video profile +VPAPI_ATTR VkResult vpGetProfileVideoFormatStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes); +#endif // VK_KHR_video_queue + +#ifdef __cplusplus +} +#endif + +#endif // VULKAN_PROFILES_H_ diff --git a/vulkan_profiles/vulkan_profiles.hpp b/vulkan_profiles/vulkan_profiles.hpp new file mode 100644 index 0000000..79c149b --- /dev/null +++ b/vulkan_profiles/vulkan_profiles.hpp @@ -0,0 +1,4794 @@ + +/* + * Copyright (C) 2021-2026 Valve Corporation + * Copyright (C) 2021-2026 LunarG, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License") + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is ***GENERATED***. Do Not Edit. + * See scripts/gen_profiles_solution.py for modifications. + */ + +#pragma once + +#define VPAPI_ATTR inline + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(VK_VERSION_1_3) && \ + defined(VK_KHR_get_surface_capabilities2) && \ + defined(VK_KHR_global_priority) && \ + defined(VK_KHR_swapchain) +#define VP_LEARN_how_to_vulkan_2026 1 +#define VP_LEARN_HOW_TO_VULKAN_2026_NAME "VP_LEARN_how_to_vulkan_2026" +#define VP_LEARN_HOW_TO_VULKAN_2026_SPEC_VERSION 1 +#define VP_LEARN_HOW_TO_VULKAN_2026_MIN_API_VERSION VK_MAKE_VERSION(1, 3, 204) +#endif + +#define VP_HEADER_VERSION_COMPLETE VK_MAKE_API_VERSION(0, 2, 0, VK_HEADER_VERSION) + +#define VP_MAX_PROFILE_NAME_SIZE 256U + +typedef struct VpProfileProperties { + char profileName[VP_MAX_PROFILE_NAME_SIZE]; + uint32_t specVersion; +} VpProfileProperties; + +typedef struct VpBlockProperties { + VpProfileProperties profiles; + uint32_t apiVersion; + char blockName[VP_MAX_PROFILE_NAME_SIZE]; +} VpBlockProperties; + +typedef struct VpVideoProfileProperties { + char name[VP_MAX_PROFILE_NAME_SIZE]; +} VpVideoProfileProperties; + +typedef enum VpInstanceCreateFlagBits { + VP_INSTANCE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VpInstanceCreateFlagBits; +typedef VkFlags VpInstanceCreateFlags; + +typedef struct VpInstanceCreateInfo { + const VkInstanceCreateInfo* pCreateInfo; + VpInstanceCreateFlags flags; + uint32_t enabledFullProfileCount; + const VpProfileProperties* pEnabledFullProfiles; + uint32_t enabledProfileBlockCount; + const VpBlockProperties* pEnabledProfileBlocks; +} VpInstanceCreateInfo; + +typedef enum VpDeviceCreateFlagBits { + VP_DEVICE_CREATE_DISABLE_ROBUST_BUFFER_ACCESS_BIT = 0x0000001, + VP_DEVICE_CREATE_DISABLE_ROBUST_IMAGE_ACCESS_BIT = 0x0000002, + VP_DEVICE_CREATE_DISABLE_ROBUST_ACCESS = + VP_DEVICE_CREATE_DISABLE_ROBUST_BUFFER_ACCESS_BIT | VP_DEVICE_CREATE_DISABLE_ROBUST_IMAGE_ACCESS_BIT, + + VP_DEVICE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VpDeviceCreateFlagBits; +typedef VkFlags VpDeviceCreateFlags; + +typedef struct VpDeviceCreateInfo { + const VkDeviceCreateInfo* pCreateInfo; + VpDeviceCreateFlags flags; + uint32_t enabledFullProfileCount; + const VpProfileProperties* pEnabledFullProfiles; + uint32_t enabledProfileBlockCount; + const VpBlockProperties* pEnabledProfileBlocks; +} VpDeviceCreateInfo; + +VK_DEFINE_HANDLE(VpCapabilities) + +typedef enum VpCapabilitiesCreateFlagBits { + VP_PROFILE_CREATE_STATIC_BIT = (1 << 0), + //VP_PROFILE_CREATE_DYNAMIC_BIT = (1 << 1), + VP_PROFILE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VpCapabilitiesCreateFlagBits; + +typedef VkFlags VpCapabilitiesCreateFlags; + +// Pointers to some Vulkan functions - a subset used by the library. +// Used in VpCapabilitiesCreateInfo::pVulkanFunctions. + +typedef struct VpVulkanFunctions { + /// Required when using VP_DYNAMIC_VULKAN_FUNCTIONS. + PFN_vkGetInstanceProcAddr GetInstanceProcAddr; + /// Required when using VP_DYNAMIC_VULKAN_FUNCTIONS. + PFN_vkGetDeviceProcAddr GetDeviceProcAddr; + PFN_vkEnumerateInstanceVersion EnumerateInstanceVersion; + PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties; + PFN_vkEnumerateDeviceExtensionProperties EnumerateDeviceExtensionProperties; + PFN_vkGetPhysicalDeviceFeatures2 GetPhysicalDeviceFeatures2; + PFN_vkGetPhysicalDeviceProperties2 GetPhysicalDeviceProperties2; + PFN_vkGetPhysicalDeviceFormatProperties2 GetPhysicalDeviceFormatProperties2; + PFN_vkGetPhysicalDeviceQueueFamilyProperties2 GetPhysicalDeviceQueueFamilyProperties2; + PFN_vkCreateInstance CreateInstance; + PFN_vkCreateDevice CreateDevice; +} VpVulkanFunctions; + +/// Description of a Allocator to be created. +typedef struct VpCapabilitiesCreateInfo +{ + /// Flags for created allocator. Use #VpInstanceCreateFlagBits enum. + VpCapabilitiesCreateFlags flags; + uint32_t apiVersion; + const VpVulkanFunctions* pVulkanFunctions; +} VpCapabilitiesCreateInfo; + +VPAPI_ATTR VkResult vpCreateCapabilities( + const VpCapabilitiesCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VpCapabilities* pCapabilities); + +/// Destroys allocator object. +VPAPI_ATTR void vpDestroyCapabilities( + VpCapabilities capabilities, + const VkAllocationCallbacks* pAllocator); + +// Query the list of available profiles in the library +VPAPI_ATTR VkResult vpGetProfiles( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + uint32_t* pPropertyCount, + VpProfileProperties* pProperties); + +// List the required profiles of a profile +VPAPI_ATTR VkResult vpGetProfileRequiredProfiles( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + uint32_t* pPropertyCount, + VpProfileProperties* pProperties); + +// Query the profile required Vulkan API version +VPAPI_ATTR uint32_t vpGetProfileAPIVersion( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile); + +// List the recommended fallback profiles of a profile +VPAPI_ATTR VkResult vpGetProfileFallbacks( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + uint32_t* pPropertyCount, + VpProfileProperties* pProperties); + +// Query whether the profile has multiple variants. Profiles with multiple variants can only use vpGetInstanceProfileSupport and vpGetPhysicalDeviceProfileSupport capabilities of the library. Other function will return a VK_ERROR_UNKNOWN error +VPAPI_ATTR VkResult vpHasMultipleVariantsProfile( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + VkBool32* pHasMultipleVariants); + +// Check whether a profile is supported at the instance level +VPAPI_ATTR VkResult vpGetInstanceProfileSupport( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const char* pLayerName, + const VpProfileProperties* pProfile, + VkBool32* pSupported); + +// Check whether a variant of a profile is supported at the instance level and report this list of blocks used to validate the profiles +VPAPI_ATTR VkResult vpGetInstanceProfileVariantsSupport( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const char* pLayerName, + const VpProfileProperties* pProfile, + VkBool32* pSupported, + uint32_t* pPropertyCount, + VpBlockProperties* pProperties); + +// Create a VkInstance with the profile instance extensions enabled +VPAPI_ATTR VkResult vpCreateInstance( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpInstanceCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkInstance* pInstance); + +// Check whether a profile is supported by the physical device +VPAPI_ATTR VkResult vpGetPhysicalDeviceProfileSupport( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + VkInstance instance, + VkPhysicalDevice physicalDevice, + const VpProfileProperties* pProfile, + VkBool32* pSupported); + +// Check whether a variant of a profile is supported by the physical device and report this list of blocks used to validate the profiles +VPAPI_ATTR VkResult vpGetPhysicalDeviceProfileVariantsSupport( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + VkInstance instance, + VkPhysicalDevice physicalDevice, + const VpProfileProperties* pProfile, + VkBool32* pSupported, + uint32_t* pPropertyCount, + VpBlockProperties* pProperties); + +// Create a VkDevice with the profile features and device extensions enabled +VPAPI_ATTR VkResult vpCreateDevice( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + VkPhysicalDevice physicalDevice, + const VpDeviceCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDevice* pDevice); + +// Query the list of instance extensions of a profile +VPAPI_ATTR VkResult vpGetProfileInstanceExtensionProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pPropertyCount, + VkExtensionProperties* pProperties); + +// Query the list of device extensions of a profile +VPAPI_ATTR VkResult vpGetProfileDeviceExtensionProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pPropertyCount, + VkExtensionProperties* pProperties); + +// Fill the feature structures with the requirements of a profile +VPAPI_ATTR VkResult vpGetProfileFeatures( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + void* pNext); + +// Query the list of feature structure types specified by the profile +VPAPI_ATTR VkResult vpGetProfileFeatureStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes); + +// Fill the property structures with the requirements of a profile +VPAPI_ATTR VkResult vpGetProfileProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + void* pNext); + +// Query the list of property structure types specified by the profile +VPAPI_ATTR VkResult vpGetProfilePropertyStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes); + +// Fill the queue family property structures with the requirements of a profile +VPAPI_ATTR VkResult vpGetProfileQueueFamilyProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pPropertyCount, + VkQueueFamilyProperties2KHR* pProperties); + +// Query the list of queue family property structure types specified by the profile +VPAPI_ATTR VkResult vpGetProfileQueueFamilyStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes); + +// Query the list of formats with specified requirements by a profile +VPAPI_ATTR VkResult vpGetProfileFormats( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pFormatCount, + VkFormat* pFormats); + +// Query the requirements of a format for a profile +VPAPI_ATTR VkResult vpGetProfileFormatProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + VkFormat format, + void* pNext); + +// Query the list of format structure types specified by the profile +VPAPI_ATTR VkResult vpGetProfileFormatStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes); + +#ifdef VK_KHR_video_queue +// Query the list of video profiles specified by the profile +VPAPI_ATTR VkResult vpGetProfileVideoProfiles( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pVideoProfileCount, + VpVideoProfileProperties* pVideoProfiles); + +// Query the video profile info structures for a video profile defined by a profile +VPAPI_ATTR VkResult vpGetProfileVideoProfileInfo( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + VkVideoProfileInfoKHR* pVideoProfileInfo); + +// Query the list of video profile info structure types specified by the profile for a video profile +VPAPI_ATTR VkResult vpGetProfileVideoProfileInfoStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes); + +// Query the video capabilities requirements for a video profile defined by a profile +VPAPI_ATTR VkResult vpGetProfileVideoCapabilities( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + void* pNext); + +// Query the list of video capability structure types specified by the profile for a video profile +VPAPI_ATTR VkResult vpGetProfileVideoCapabilityStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes); + +// Query the video format property requirements for a video profile defined by a profile +VPAPI_ATTR VkResult vpGetProfileVideoFormatProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + uint32_t* pPropertyCount, + VkVideoFormatPropertiesKHR* pProperties); + +// Query the list of video format property structure types specified by the profile for a video profile +VPAPI_ATTR VkResult vpGetProfileVideoFormatStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes); +#endif // VK_KHR_video_queue + +namespace detail { + + +VPAPI_ATTR std::string FormatString(const char* message, ...) { + std::size_t const STRING_BUFFER(4096); + + assert(message != nullptr); + assert(strlen(message) >= 1 && strlen(message) < STRING_BUFFER); + + char buffer[STRING_BUFFER]; + va_list list; + + va_start(list, message); + vsnprintf(buffer, STRING_BUFFER, message, list); + va_end(list); + + return buffer; +} + +VPAPI_ATTR const void* vpGetStructure(const void* pNext, VkStructureType type) { + const VkBaseOutStructure* p = static_cast(pNext); + while (p != nullptr) { + if (p->sType == type) return p; + p = p->pNext; + } + return nullptr; +} + +VPAPI_ATTR void* vpGetStructure(void* pNext, VkStructureType type) { + VkBaseOutStructure* p = static_cast(pNext); + while (p != nullptr) { + if (p->sType == type) return p; + p = p->pNext; + } + return nullptr; +} + +VPAPI_ATTR VkBaseOutStructure* vpExtractStructure(VkPhysicalDeviceFeatures2KHR* pFeatures, VkStructureType structureType) { + if (structureType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR) { + return nullptr; + } + + VkBaseOutStructure* current = reinterpret_cast(pFeatures); + VkBaseOutStructure* previous = nullptr; + VkBaseOutStructure* found = nullptr; + + while (current != nullptr) { + if (structureType == current->sType) { + found = current; + if (previous != nullptr) { + previous->pNext = current->pNext; + } + current = nullptr; + } else { + previous = current; + current = current->pNext; + } + } + + if (found != nullptr) { + found->pNext = nullptr; + return found; + } else { + return nullptr; + } +} + +VPAPI_ATTR void GatherStructureTypes(std::vector& structureTypes, VkBaseOutStructure* pNext) { + while (pNext) { + if (std::find(structureTypes.begin(), structureTypes.end(), pNext->sType) == structureTypes.end()) { + structureTypes.push_back(pNext->sType); + } + + pNext = pNext->pNext; + } +} + +VPAPI_ATTR bool isMultiple(double source, double multiple) { + double mod = std::fmod(source, multiple); + return std::abs(mod) < 0.0001; +} + +VPAPI_ATTR bool isPowerOfTwo(double source) { + double mod = std::fmod(source, 1.0); + if (std::abs(mod) >= 0.0001) return false; + + std::uint64_t value = static_cast(std::abs(source)); + return !(value & (value - static_cast(1))); +} + +using PFN_vpStructFiller = void(*)(VkBaseOutStructure* p); +using PFN_vpStructComparator = bool(*)(VkBaseOutStructure* p); +using PFN_vpStructChainerCb = void(*)(VkBaseOutStructure* p, void* pUser); +using PFN_vpStructChainer = void(*)(VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb); +using PFN_vpStructArrayChainerCb = void(*)(uint32_t count, VkBaseOutStructure* p, void* pUser); +using PFN_vpStructArrayChainer = void(*)(uint32_t count, VkBaseOutStructure* p, void* pUser, PFN_vpStructArrayChainerCb pfnCb); + +struct VpFeatureDesc { + PFN_vpStructFiller pfnFiller; + PFN_vpStructComparator pfnComparator; +}; + +struct VpPropertyDesc { + PFN_vpStructFiller pfnFiller; + PFN_vpStructComparator pfnComparator; +}; + +struct VpQueueFamilyDesc { + PFN_vpStructFiller pfnFiller; + PFN_vpStructComparator pfnComparator; +}; + +struct VpFormatDesc { + VkFormat format; + PFN_vpStructFiller pfnFiller; + PFN_vpStructComparator pfnComparator; +}; + +struct VpStructChainerDesc { + PFN_vpStructChainer pfnFeature; + PFN_vpStructChainer pfnProperty; + PFN_vpStructArrayChainer pfnQueueFamily; + PFN_vpStructChainer pfnFormat; +}; + +struct VpVideoProfileInfoDesc { + PFN_vpStructFiller pfnFiller; + PFN_vpStructComparator pfnComparator; +}; + +struct VpVideoCapabilityDesc { + PFN_vpStructFiller pfnFiller; + PFN_vpStructComparator pfnComparator; +}; + +struct VpVideoFormatDesc { + PFN_vpStructFiller pfnFiller; + PFN_vpStructComparator pfnComparator; +}; + +struct VpVideoProfileStructChainerDesc { + PFN_vpStructChainer pfnInfo; + PFN_vpStructChainer pfnCapability; + PFN_vpStructArrayChainer pfnFormat; +}; + +struct VpVideoProfileDesc { + VpVideoProfileProperties properties; + + uint32_t infoStructTypeCount; + const VkStructureType* pInfoStructTypes; + VpVideoProfileInfoDesc info; + + uint32_t capabilityStructTypeCount; + const VkStructureType* pCapabilityStructTypes; + VpVideoCapabilityDesc capability; + + uint32_t formatStructTypeCount; + const VkStructureType* pFormatStructTypes; + uint32_t formatCount; + const VpVideoFormatDesc* pFormats; + + VpVideoProfileStructChainerDesc chainers; +}; + +struct VpVariantDesc { + char blockName[VP_MAX_PROFILE_NAME_SIZE]; + + uint32_t instanceExtensionCount; + const VkExtensionProperties* pInstanceExtensions; + + uint32_t deviceExtensionCount; + const VkExtensionProperties* pDeviceExtensions; + + uint32_t featureStructTypeCount; + const VkStructureType* pFeatureStructTypes; + VpFeatureDesc feature; + + uint32_t propertyStructTypeCount; + const VkStructureType* pPropertyStructTypes; + VpPropertyDesc property; + + uint32_t queueFamilyStructTypeCount; + const VkStructureType* pQueueFamilyStructTypes; + uint32_t queueFamilyCount; + const VpQueueFamilyDesc* pQueueFamilies; + + uint32_t formatStructTypeCount; + const VkStructureType* pFormatStructTypes; + uint32_t formatCount; + const VpFormatDesc* pFormats; + + VpStructChainerDesc chainers; + + uint32_t videoProfileCount; + const VpVideoProfileDesc* pVideoProfiles; +}; + +struct VpCapabilitiesDesc { + uint32_t variantCount; + const VpVariantDesc* pVariants; +}; + +struct VpProfileDesc { + VpProfileProperties props; + uint32_t minApiVersion; + + const detail::VpVariantDesc* pMergedCapabilities; + + uint32_t requiredProfileCount; + const VpProfileProperties* pRequiredProfiles; + + uint32_t requiredCapabilityCount; + const VpCapabilitiesDesc* pRequiredCapabilities; + + uint32_t fallbackCount; + const VpProfileProperties* pFallbacks; +}; + +template +VPAPI_ATTR bool vpCheckFlags(const T& actual, const uint64_t expected) { + return (actual & expected) == expected; +} + + +#ifdef VK_KHR_video_queue +VPAPI_ATTR void vpForEachMatchingVideoProfiles( + VkVideoProfileInfoKHR* pVideoProfileInfo, + void* pUser, + PFN_vpStructChainerCb pfnCb) { + const VkVideoChromaSubsamplingFlagsKHR chroma_subsampling_list[] = { + VK_VIDEO_CHROMA_SUBSAMPLING_420_BIT_KHR, + VK_VIDEO_CHROMA_SUBSAMPLING_422_BIT_KHR, + VK_VIDEO_CHROMA_SUBSAMPLING_444_BIT_KHR, + VK_VIDEO_CHROMA_SUBSAMPLING_MONOCHROME_BIT_KHR + }; + const VkVideoComponentBitDepthFlagsKHR bit_depth_list[] = { + VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR, + VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR, + VK_VIDEO_COMPONENT_BIT_DEPTH_12_BIT_KHR + }; + for (size_t chromaSubsampling_idx = 0; chromaSubsampling_idx < std::size(chroma_subsampling_list); ++chromaSubsampling_idx) { + pVideoProfileInfo->chromaSubsampling = chroma_subsampling_list[chromaSubsampling_idx]; + for (size_t lumaBitDepth_idx = 0; lumaBitDepth_idx < std::size(bit_depth_list); ++lumaBitDepth_idx) { + pVideoProfileInfo->lumaBitDepth = bit_depth_list[lumaBitDepth_idx]; + for (size_t chromaBitDepth_idx = 0; chromaBitDepth_idx < std::size(bit_depth_list); ++chromaBitDepth_idx) { + pVideoProfileInfo->chromaBitDepth = bit_depth_list[chromaBitDepth_idx]; + { + pVideoProfileInfo->pNext = nullptr; + pVideoProfileInfo->videoCodecOperation = VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR; + VkVideoDecodeH264ProfileInfoKHR var_VideoDecodeH264ProfileInfoKHR = { VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_INFO_KHR }; + var_VideoDecodeH264ProfileInfoKHR.pNext = pVideoProfileInfo->pNext; + pVideoProfileInfo->pNext = &var_VideoDecodeH264ProfileInfoKHR; + var_VideoDecodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_BASELINE; + var_VideoDecodeH264ProfileInfoKHR.pictureLayout = VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_PROGRESSIVE_KHR; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_MAIN; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_HIGH; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_HIGH_444_PREDICTIVE; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_BASELINE; + var_VideoDecodeH264ProfileInfoKHR.pictureLayout = VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_INTERLEAVED_LINES_BIT_KHR; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_MAIN; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_HIGH; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_HIGH_444_PREDICTIVE; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_BASELINE; + var_VideoDecodeH264ProfileInfoKHR.pictureLayout = VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_SEPARATE_PLANES_BIT_KHR; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_MAIN; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_HIGH; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_HIGH_444_PREDICTIVE; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + } + { + pVideoProfileInfo->pNext = nullptr; + pVideoProfileInfo->videoCodecOperation = VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR; + VkVideoDecodeH265ProfileInfoKHR var_VideoDecodeH265ProfileInfoKHR = { VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_INFO_KHR }; + var_VideoDecodeH265ProfileInfoKHR.pNext = pVideoProfileInfo->pNext; + pVideoProfileInfo->pNext = &var_VideoDecodeH265ProfileInfoKHR; + var_VideoDecodeH265ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_MAIN; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeH265ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_MAIN_10; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeH265ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_MAIN_STILL_PICTURE; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeH265ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSIONS; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeH265ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_SCC_EXTENSIONS; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + } + { + pVideoProfileInfo->pNext = nullptr; + pVideoProfileInfo->videoCodecOperation = VK_VIDEO_CODEC_OPERATION_DECODE_VP9_BIT_KHR; + VkVideoDecodeVP9ProfileInfoKHR var_VideoDecodeVP9ProfileInfoKHR = { VK_STRUCTURE_TYPE_VIDEO_DECODE_VP9_PROFILE_INFO_KHR }; + var_VideoDecodeVP9ProfileInfoKHR.pNext = pVideoProfileInfo->pNext; + pVideoProfileInfo->pNext = &var_VideoDecodeVP9ProfileInfoKHR; + var_VideoDecodeVP9ProfileInfoKHR.stdProfile = STD_VIDEO_VP9_PROFILE_0; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeVP9ProfileInfoKHR.stdProfile = STD_VIDEO_VP9_PROFILE_1; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeVP9ProfileInfoKHR.stdProfile = STD_VIDEO_VP9_PROFILE_2; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeVP9ProfileInfoKHR.stdProfile = STD_VIDEO_VP9_PROFILE_3; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + } + { + pVideoProfileInfo->pNext = nullptr; + pVideoProfileInfo->videoCodecOperation = VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR; + VkVideoDecodeAV1ProfileInfoKHR var_VideoDecodeAV1ProfileInfoKHR = { VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_PROFILE_INFO_KHR }; + var_VideoDecodeAV1ProfileInfoKHR.pNext = pVideoProfileInfo->pNext; + pVideoProfileInfo->pNext = &var_VideoDecodeAV1ProfileInfoKHR; + var_VideoDecodeAV1ProfileInfoKHR.stdProfile = STD_VIDEO_AV1_PROFILE_MAIN; + var_VideoDecodeAV1ProfileInfoKHR.filmGrainSupport = VK_TRUE; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeAV1ProfileInfoKHR.stdProfile = STD_VIDEO_AV1_PROFILE_HIGH; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeAV1ProfileInfoKHR.stdProfile = STD_VIDEO_AV1_PROFILE_PROFESSIONAL; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeAV1ProfileInfoKHR.stdProfile = STD_VIDEO_AV1_PROFILE_MAIN; + var_VideoDecodeAV1ProfileInfoKHR.filmGrainSupport = VK_FALSE; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeAV1ProfileInfoKHR.stdProfile = STD_VIDEO_AV1_PROFILE_HIGH; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoDecodeAV1ProfileInfoKHR.stdProfile = STD_VIDEO_AV1_PROFILE_PROFESSIONAL; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + } + { + pVideoProfileInfo->pNext = nullptr; + pVideoProfileInfo->videoCodecOperation = VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR; + VkVideoEncodeH264ProfileInfoKHR var_VideoEncodeH264ProfileInfoKHR = { VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PROFILE_INFO_KHR }; + var_VideoEncodeH264ProfileInfoKHR.pNext = pVideoProfileInfo->pNext; + pVideoProfileInfo->pNext = &var_VideoEncodeH264ProfileInfoKHR; + var_VideoEncodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_BASELINE; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoEncodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_MAIN; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoEncodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_HIGH; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoEncodeH264ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_HIGH_444_PREDICTIVE; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + } + { + pVideoProfileInfo->pNext = nullptr; + pVideoProfileInfo->videoCodecOperation = VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR; + VkVideoEncodeH265ProfileInfoKHR var_VideoEncodeH265ProfileInfoKHR = { VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_PROFILE_INFO_KHR }; + var_VideoEncodeH265ProfileInfoKHR.pNext = pVideoProfileInfo->pNext; + pVideoProfileInfo->pNext = &var_VideoEncodeH265ProfileInfoKHR; + var_VideoEncodeH265ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_MAIN; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoEncodeH265ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_MAIN_10; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoEncodeH265ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_MAIN_STILL_PICTURE; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoEncodeH265ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSIONS; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoEncodeH265ProfileInfoKHR.stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_SCC_EXTENSIONS; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + } + { + pVideoProfileInfo->pNext = nullptr; + pVideoProfileInfo->videoCodecOperation = VK_VIDEO_CODEC_OPERATION_ENCODE_AV1_BIT_KHR; + VkVideoEncodeAV1ProfileInfoKHR var_VideoEncodeAV1ProfileInfoKHR = { VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_PROFILE_INFO_KHR }; + var_VideoEncodeAV1ProfileInfoKHR.pNext = pVideoProfileInfo->pNext; + pVideoProfileInfo->pNext = &var_VideoEncodeAV1ProfileInfoKHR; + var_VideoEncodeAV1ProfileInfoKHR.stdProfile = STD_VIDEO_AV1_PROFILE_MAIN; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoEncodeAV1ProfileInfoKHR.stdProfile = STD_VIDEO_AV1_PROFILE_HIGH; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + var_VideoEncodeAV1ProfileInfoKHR.stdProfile = STD_VIDEO_AV1_PROFILE_PROFESSIONAL; + pfnCb(reinterpret_cast(pVideoProfileInfo), pUser); + } + } + } + } +} +#endif // VK_KHR_video_queue +#ifdef VP_LEARN_how_to_vulkan_2026 +namespace VP_LEARN_HOW_TO_VULKAN_2026 { + +static const VkStructureType featureStructTypes[] = { + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES, +}; + +static const VkStructureType propertyStructTypes[] = { + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_PROPERTIES, +}; + +static const VkExtensionProperties instanceExtensions[] = { + VkExtensionProperties{ VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, 1 }, +}; + +static const VkExtensionProperties deviceExtensions[] = { + VkExtensionProperties{ VK_KHR_GLOBAL_PRIORITY_EXTENSION_NAME, 1 }, + VkExtensionProperties{ VK_KHR_SWAPCHAIN_EXTENSION_NAME, 70 }, +}; + +static const VpFeatureDesc featureDesc = { + [](VkBaseOutStructure* p) { (void)p; + switch (p->sType) { + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR: { + VkPhysicalDeviceFeatures2KHR* s = static_cast(static_cast(p)); + s->features.depthBiasClamp = VK_TRUE; + s->features.depthClamp = VK_TRUE; + s->features.drawIndirectFirstInstance = VK_TRUE; + s->features.fragmentStoresAndAtomics = VK_TRUE; + s->features.fullDrawIndexUint32 = VK_TRUE; + s->features.imageCubeArray = VK_TRUE; + s->features.independentBlend = VK_TRUE; + s->features.occlusionQueryPrecise = VK_TRUE; + s->features.robustBufferAccess = VK_TRUE; + s->features.sampleRateShading = VK_TRUE; + s->features.samplerAnisotropy = VK_TRUE; + s->features.shaderSampledImageArrayDynamicIndexing = VK_TRUE; + s->features.shaderStorageBufferArrayDynamicIndexing = VK_TRUE; + s->features.shaderStorageImageArrayDynamicIndexing = VK_TRUE; + s->features.shaderStorageImageExtendedFormats = VK_TRUE; + s->features.shaderUniformBufferArrayDynamicIndexing = VK_TRUE; + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES: { + VkPhysicalDeviceVulkan11Features* s = static_cast(static_cast(p)); + s->multiview = VK_TRUE; + s->samplerYcbcrConversion = VK_TRUE; + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES: { + VkPhysicalDeviceVulkan12Features* s = static_cast(static_cast(p)); + s->bufferDeviceAddress = VK_TRUE; + s->descriptorBindingPartiallyBound = VK_TRUE; + s->descriptorBindingSampledImageUpdateAfterBind = VK_TRUE; + s->descriptorBindingStorageBufferUpdateAfterBind = VK_TRUE; + s->descriptorBindingStorageImageUpdateAfterBind = VK_TRUE; + s->descriptorBindingStorageTexelBufferUpdateAfterBind = VK_TRUE; + s->descriptorBindingUniformTexelBufferUpdateAfterBind = VK_TRUE; + s->descriptorBindingUpdateUnusedWhilePending = VK_TRUE; + s->descriptorBindingVariableDescriptorCount = VK_TRUE; + s->descriptorIndexing = VK_TRUE; + s->hostQueryReset = VK_TRUE; + s->imagelessFramebuffer = VK_TRUE; + s->runtimeDescriptorArray = VK_TRUE; + s->samplerMirrorClampToEdge = VK_TRUE; + s->scalarBlockLayout = VK_TRUE; + s->separateDepthStencilLayouts = VK_TRUE; + s->shaderSampledImageArrayNonUniformIndexing = VK_TRUE; + s->shaderStorageBufferArrayNonUniformIndexing = VK_TRUE; + s->shaderStorageImageArrayNonUniformIndexing = VK_TRUE; + s->shaderStorageTexelBufferArrayDynamicIndexing = VK_TRUE; + s->shaderStorageTexelBufferArrayNonUniformIndexing = VK_TRUE; + s->shaderSubgroupExtendedTypes = VK_TRUE; + s->shaderUniformBufferArrayNonUniformIndexing = VK_TRUE; + s->shaderUniformTexelBufferArrayDynamicIndexing = VK_TRUE; + s->shaderUniformTexelBufferArrayNonUniformIndexing = VK_TRUE; + s->subgroupBroadcastDynamicId = VK_TRUE; + s->timelineSemaphore = VK_TRUE; + s->uniformBufferStandardLayout = VK_TRUE; + s->vulkanMemoryModel = VK_TRUE; + s->vulkanMemoryModelDeviceScope = VK_TRUE; + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES: { + VkPhysicalDeviceVulkan13Features* s = static_cast(static_cast(p)); + s->computeFullSubgroups = VK_TRUE; + s->descriptorBindingInlineUniformBlockUpdateAfterBind = VK_TRUE; + s->dynamicRendering = VK_TRUE; + s->inlineUniformBlock = VK_TRUE; + s->maintenance4 = VK_TRUE; + s->pipelineCreationCacheControl = VK_TRUE; + s->robustImageAccess = VK_TRUE; + s->shaderDemoteToHelperInvocation = VK_TRUE; + s->shaderIntegerDotProduct = VK_TRUE; + s->shaderTerminateInvocation = VK_TRUE; + s->shaderZeroInitializeWorkgroupMemory = VK_TRUE; + s->subgroupSizeControl = VK_TRUE; + s->synchronization2 = VK_TRUE; + } break; + default: break; + } + }, + [](VkBaseOutStructure* p) -> bool { (void)p; + bool ret = true; + switch (p->sType) { + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR: { + VkPhysicalDeviceFeatures2KHR* s = static_cast(static_cast(p)); + ret = ret && (s->features.depthBiasClamp == VK_TRUE); + ret = ret && (s->features.depthClamp == VK_TRUE); + ret = ret && (s->features.drawIndirectFirstInstance == VK_TRUE); + ret = ret && (s->features.fragmentStoresAndAtomics == VK_TRUE); + ret = ret && (s->features.fullDrawIndexUint32 == VK_TRUE); + ret = ret && (s->features.imageCubeArray == VK_TRUE); + ret = ret && (s->features.independentBlend == VK_TRUE); + ret = ret && (s->features.occlusionQueryPrecise == VK_TRUE); + ret = ret && (s->features.robustBufferAccess == VK_TRUE); + ret = ret && (s->features.sampleRateShading == VK_TRUE); + ret = ret && (s->features.samplerAnisotropy == VK_TRUE); + ret = ret && (s->features.shaderSampledImageArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->features.shaderStorageBufferArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->features.shaderStorageImageArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->features.shaderStorageImageExtendedFormats == VK_TRUE); + ret = ret && (s->features.shaderUniformBufferArrayDynamicIndexing == VK_TRUE); + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES: { + VkPhysicalDeviceVulkan11Features* s = static_cast(static_cast(p)); + ret = ret && (s->multiview == VK_TRUE); + ret = ret && (s->samplerYcbcrConversion == VK_TRUE); + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES: { + VkPhysicalDeviceVulkan12Features* s = static_cast(static_cast(p)); + ret = ret && (s->bufferDeviceAddress == VK_TRUE); + ret = ret && (s->descriptorBindingPartiallyBound == VK_TRUE); + ret = ret && (s->descriptorBindingSampledImageUpdateAfterBind == VK_TRUE); + ret = ret && (s->descriptorBindingStorageBufferUpdateAfterBind == VK_TRUE); + ret = ret && (s->descriptorBindingStorageImageUpdateAfterBind == VK_TRUE); + ret = ret && (s->descriptorBindingStorageTexelBufferUpdateAfterBind == VK_TRUE); + ret = ret && (s->descriptorBindingUniformTexelBufferUpdateAfterBind == VK_TRUE); + ret = ret && (s->descriptorBindingUpdateUnusedWhilePending == VK_TRUE); + ret = ret && (s->descriptorBindingVariableDescriptorCount == VK_TRUE); + ret = ret && (s->descriptorIndexing == VK_TRUE); + ret = ret && (s->hostQueryReset == VK_TRUE); + ret = ret && (s->imagelessFramebuffer == VK_TRUE); + ret = ret && (s->runtimeDescriptorArray == VK_TRUE); + ret = ret && (s->samplerMirrorClampToEdge == VK_TRUE); + ret = ret && (s->scalarBlockLayout == VK_TRUE); + ret = ret && (s->separateDepthStencilLayouts == VK_TRUE); + ret = ret && (s->shaderSampledImageArrayNonUniformIndexing == VK_TRUE); + ret = ret && (s->shaderStorageBufferArrayNonUniformIndexing == VK_TRUE); + ret = ret && (s->shaderStorageImageArrayNonUniformIndexing == VK_TRUE); + ret = ret && (s->shaderStorageTexelBufferArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->shaderStorageTexelBufferArrayNonUniformIndexing == VK_TRUE); + ret = ret && (s->shaderSubgroupExtendedTypes == VK_TRUE); + ret = ret && (s->shaderUniformBufferArrayNonUniformIndexing == VK_TRUE); + ret = ret && (s->shaderUniformTexelBufferArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->shaderUniformTexelBufferArrayNonUniformIndexing == VK_TRUE); + ret = ret && (s->subgroupBroadcastDynamicId == VK_TRUE); + ret = ret && (s->timelineSemaphore == VK_TRUE); + ret = ret && (s->uniformBufferStandardLayout == VK_TRUE); + ret = ret && (s->vulkanMemoryModel == VK_TRUE); + ret = ret && (s->vulkanMemoryModelDeviceScope == VK_TRUE); + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES: { + VkPhysicalDeviceVulkan13Features* s = static_cast(static_cast(p)); + ret = ret && (s->computeFullSubgroups == VK_TRUE); + ret = ret && (s->descriptorBindingInlineUniformBlockUpdateAfterBind == VK_TRUE); + ret = ret && (s->dynamicRendering == VK_TRUE); + ret = ret && (s->inlineUniformBlock == VK_TRUE); + ret = ret && (s->maintenance4 == VK_TRUE); + ret = ret && (s->pipelineCreationCacheControl == VK_TRUE); + ret = ret && (s->robustImageAccess == VK_TRUE); + ret = ret && (s->shaderDemoteToHelperInvocation == VK_TRUE); + ret = ret && (s->shaderIntegerDotProduct == VK_TRUE); + ret = ret && (s->shaderTerminateInvocation == VK_TRUE); + ret = ret && (s->shaderZeroInitializeWorkgroupMemory == VK_TRUE); + ret = ret && (s->subgroupSizeControl == VK_TRUE); + ret = ret && (s->synchronization2 == VK_TRUE); + } break; + default: break; + } + return ret; + } +}; + +static const VpPropertyDesc propertyDesc = { + [](VkBaseOutStructure* p) { (void)p; + }, + [](VkBaseOutStructure* p) -> bool { (void)p; + bool ret = true; + return ret; + } +}; + +static const VpStructChainerDesc chainerDesc = { + [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { + VkPhysicalDeviceVulkan11Features physicalDeviceVulkan11Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES, nullptr }; + VkPhysicalDeviceVulkan12Features physicalDeviceVulkan12Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, &physicalDeviceVulkan11Features }; + VkPhysicalDeviceVulkan13Features physicalDeviceVulkan13Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES, &physicalDeviceVulkan12Features }; + p->pNext = static_cast(static_cast(&physicalDeviceVulkan13Features)); + pfnCb(p, pUser); + }, + [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { + VkPhysicalDeviceVulkan11Properties physicalDeviceVulkan11Properties{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES, nullptr }; + VkPhysicalDeviceVulkan12Properties physicalDeviceVulkan12Properties{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES, &physicalDeviceVulkan11Properties }; + VkPhysicalDeviceVulkan13Properties physicalDeviceVulkan13Properties{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_PROPERTIES, &physicalDeviceVulkan12Properties }; + p->pNext = static_cast(static_cast(&physicalDeviceVulkan13Properties)); + pfnCb(p, pUser); + }, + [](uint32_t count, VkBaseOutStructure* p, void* pUser, PFN_vpStructArrayChainerCb pfnCb) { + pfnCb(count, p, pUser); + }, + [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { + pfnCb(p, pUser); + }, +}; + +namespace blocks { +namespace VP_LEARN_how_to_vulkan_2026_block { + +static const VkExtensionProperties instanceExtensions[] = { + VkExtensionProperties{ VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, 1 }, +}; + +static const VkExtensionProperties deviceExtensions[] = { + VkExtensionProperties{ VK_KHR_GLOBAL_PRIORITY_EXTENSION_NAME, 1 }, + VkExtensionProperties{ VK_KHR_SWAPCHAIN_EXTENSION_NAME, 70 }, +}; + +static const VpFeatureDesc featureDesc = { + [](VkBaseOutStructure* p) { (void)p; + switch (p->sType) { + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR: { + VkPhysicalDeviceFeatures2KHR* s = static_cast(static_cast(p)); + s->features.depthBiasClamp = VK_TRUE; + s->features.depthClamp = VK_TRUE; + s->features.drawIndirectFirstInstance = VK_TRUE; + s->features.fragmentStoresAndAtomics = VK_TRUE; + s->features.fullDrawIndexUint32 = VK_TRUE; + s->features.imageCubeArray = VK_TRUE; + s->features.independentBlend = VK_TRUE; + s->features.occlusionQueryPrecise = VK_TRUE; + s->features.robustBufferAccess = VK_TRUE; + s->features.sampleRateShading = VK_TRUE; + s->features.samplerAnisotropy = VK_TRUE; + s->features.shaderSampledImageArrayDynamicIndexing = VK_TRUE; + s->features.shaderStorageBufferArrayDynamicIndexing = VK_TRUE; + s->features.shaderStorageImageArrayDynamicIndexing = VK_TRUE; + s->features.shaderStorageImageExtendedFormats = VK_TRUE; + s->features.shaderUniformBufferArrayDynamicIndexing = VK_TRUE; + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES: { + VkPhysicalDeviceVulkan11Features* s = static_cast(static_cast(p)); + s->multiview = VK_TRUE; + s->samplerYcbcrConversion = VK_TRUE; + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES: { + VkPhysicalDeviceVulkan12Features* s = static_cast(static_cast(p)); + s->bufferDeviceAddress = VK_TRUE; + s->descriptorBindingPartiallyBound = VK_TRUE; + s->descriptorBindingSampledImageUpdateAfterBind = VK_TRUE; + s->descriptorBindingStorageBufferUpdateAfterBind = VK_TRUE; + s->descriptorBindingStorageImageUpdateAfterBind = VK_TRUE; + s->descriptorBindingStorageTexelBufferUpdateAfterBind = VK_TRUE; + s->descriptorBindingUniformTexelBufferUpdateAfterBind = VK_TRUE; + s->descriptorBindingUpdateUnusedWhilePending = VK_TRUE; + s->descriptorBindingVariableDescriptorCount = VK_TRUE; + s->descriptorIndexing = VK_TRUE; + s->hostQueryReset = VK_TRUE; + s->imagelessFramebuffer = VK_TRUE; + s->runtimeDescriptorArray = VK_TRUE; + s->samplerMirrorClampToEdge = VK_TRUE; + s->scalarBlockLayout = VK_TRUE; + s->separateDepthStencilLayouts = VK_TRUE; + s->shaderSampledImageArrayNonUniformIndexing = VK_TRUE; + s->shaderStorageBufferArrayNonUniformIndexing = VK_TRUE; + s->shaderStorageImageArrayNonUniformIndexing = VK_TRUE; + s->shaderStorageTexelBufferArrayDynamicIndexing = VK_TRUE; + s->shaderStorageTexelBufferArrayNonUniformIndexing = VK_TRUE; + s->shaderSubgroupExtendedTypes = VK_TRUE; + s->shaderUniformBufferArrayNonUniformIndexing = VK_TRUE; + s->shaderUniformTexelBufferArrayDynamicIndexing = VK_TRUE; + s->shaderUniformTexelBufferArrayNonUniformIndexing = VK_TRUE; + s->subgroupBroadcastDynamicId = VK_TRUE; + s->timelineSemaphore = VK_TRUE; + s->uniformBufferStandardLayout = VK_TRUE; + s->vulkanMemoryModel = VK_TRUE; + s->vulkanMemoryModelDeviceScope = VK_TRUE; + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES: { + VkPhysicalDeviceVulkan13Features* s = static_cast(static_cast(p)); + s->computeFullSubgroups = VK_TRUE; + s->descriptorBindingInlineUniformBlockUpdateAfterBind = VK_TRUE; + s->dynamicRendering = VK_TRUE; + s->inlineUniformBlock = VK_TRUE; + s->maintenance4 = VK_TRUE; + s->pipelineCreationCacheControl = VK_TRUE; + s->robustImageAccess = VK_TRUE; + s->shaderDemoteToHelperInvocation = VK_TRUE; + s->shaderIntegerDotProduct = VK_TRUE; + s->shaderTerminateInvocation = VK_TRUE; + s->shaderZeroInitializeWorkgroupMemory = VK_TRUE; + s->subgroupSizeControl = VK_TRUE; + s->synchronization2 = VK_TRUE; + } break; + default: break; + } + }, + [](VkBaseOutStructure* p) -> bool { (void)p; + bool ret = true; + switch (p->sType) { + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR: { + VkPhysicalDeviceFeatures2KHR* s = static_cast(static_cast(p)); + ret = ret && (s->features.depthBiasClamp == VK_TRUE); + ret = ret && (s->features.depthClamp == VK_TRUE); + ret = ret && (s->features.drawIndirectFirstInstance == VK_TRUE); + ret = ret && (s->features.fragmentStoresAndAtomics == VK_TRUE); + ret = ret && (s->features.fullDrawIndexUint32 == VK_TRUE); + ret = ret && (s->features.imageCubeArray == VK_TRUE); + ret = ret && (s->features.independentBlend == VK_TRUE); + ret = ret && (s->features.occlusionQueryPrecise == VK_TRUE); + ret = ret && (s->features.robustBufferAccess == VK_TRUE); + ret = ret && (s->features.sampleRateShading == VK_TRUE); + ret = ret && (s->features.samplerAnisotropy == VK_TRUE); + ret = ret && (s->features.shaderSampledImageArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->features.shaderStorageBufferArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->features.shaderStorageImageArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->features.shaderStorageImageExtendedFormats == VK_TRUE); + ret = ret && (s->features.shaderUniformBufferArrayDynamicIndexing == VK_TRUE); + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES: { + VkPhysicalDeviceVulkan11Features* s = static_cast(static_cast(p)); + ret = ret && (s->multiview == VK_TRUE); + ret = ret && (s->samplerYcbcrConversion == VK_TRUE); + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES: { + VkPhysicalDeviceVulkan12Features* s = static_cast(static_cast(p)); + ret = ret && (s->bufferDeviceAddress == VK_TRUE); + ret = ret && (s->descriptorBindingPartiallyBound == VK_TRUE); + ret = ret && (s->descriptorBindingSampledImageUpdateAfterBind == VK_TRUE); + ret = ret && (s->descriptorBindingStorageBufferUpdateAfterBind == VK_TRUE); + ret = ret && (s->descriptorBindingStorageImageUpdateAfterBind == VK_TRUE); + ret = ret && (s->descriptorBindingStorageTexelBufferUpdateAfterBind == VK_TRUE); + ret = ret && (s->descriptorBindingUniformTexelBufferUpdateAfterBind == VK_TRUE); + ret = ret && (s->descriptorBindingUpdateUnusedWhilePending == VK_TRUE); + ret = ret && (s->descriptorBindingVariableDescriptorCount == VK_TRUE); + ret = ret && (s->descriptorIndexing == VK_TRUE); + ret = ret && (s->hostQueryReset == VK_TRUE); + ret = ret && (s->imagelessFramebuffer == VK_TRUE); + ret = ret && (s->runtimeDescriptorArray == VK_TRUE); + ret = ret && (s->samplerMirrorClampToEdge == VK_TRUE); + ret = ret && (s->scalarBlockLayout == VK_TRUE); + ret = ret && (s->separateDepthStencilLayouts == VK_TRUE); + ret = ret && (s->shaderSampledImageArrayNonUniformIndexing == VK_TRUE); + ret = ret && (s->shaderStorageBufferArrayNonUniformIndexing == VK_TRUE); + ret = ret && (s->shaderStorageImageArrayNonUniformIndexing == VK_TRUE); + ret = ret && (s->shaderStorageTexelBufferArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->shaderStorageTexelBufferArrayNonUniformIndexing == VK_TRUE); + ret = ret && (s->shaderSubgroupExtendedTypes == VK_TRUE); + ret = ret && (s->shaderUniformBufferArrayNonUniformIndexing == VK_TRUE); + ret = ret && (s->shaderUniformTexelBufferArrayDynamicIndexing == VK_TRUE); + ret = ret && (s->shaderUniformTexelBufferArrayNonUniformIndexing == VK_TRUE); + ret = ret && (s->subgroupBroadcastDynamicId == VK_TRUE); + ret = ret && (s->timelineSemaphore == VK_TRUE); + ret = ret && (s->uniformBufferStandardLayout == VK_TRUE); + ret = ret && (s->vulkanMemoryModel == VK_TRUE); + ret = ret && (s->vulkanMemoryModelDeviceScope == VK_TRUE); + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES: { + VkPhysicalDeviceVulkan13Features* s = static_cast(static_cast(p)); + ret = ret && (s->computeFullSubgroups == VK_TRUE); + ret = ret && (s->descriptorBindingInlineUniformBlockUpdateAfterBind == VK_TRUE); + ret = ret && (s->dynamicRendering == VK_TRUE); + ret = ret && (s->inlineUniformBlock == VK_TRUE); + ret = ret && (s->maintenance4 == VK_TRUE); + ret = ret && (s->pipelineCreationCacheControl == VK_TRUE); + ret = ret && (s->robustImageAccess == VK_TRUE); + ret = ret && (s->shaderDemoteToHelperInvocation == VK_TRUE); + ret = ret && (s->shaderIntegerDotProduct == VK_TRUE); + ret = ret && (s->shaderTerminateInvocation == VK_TRUE); + ret = ret && (s->shaderZeroInitializeWorkgroupMemory == VK_TRUE); + ret = ret && (s->subgroupSizeControl == VK_TRUE); + ret = ret && (s->synchronization2 == VK_TRUE); + } break; + default: break; + } + return ret; + } +}; + +static const VpPropertyDesc propertyDesc = { + [](VkBaseOutStructure* p) { (void)p; + switch (p->sType) { + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR: { + VkPhysicalDeviceProperties2KHR* s = static_cast(static_cast(p)); + s->properties.limits.bufferImageGranularity = 4096; + s->properties.limits.maxColorAttachments = 7; + s->properties.limits.maxComputeWorkGroupInvocations = 256; + s->properties.limits.maxComputeWorkGroupSize[0] = 256; + s->properties.limits.maxComputeWorkGroupSize[1] = 256; + s->properties.limits.maxComputeWorkGroupSize[2] = 64; + s->properties.limits.maxDescriptorSetSampledImages = 1800; + s->properties.limits.maxDescriptorSetSamplers = 576; + s->properties.limits.maxDescriptorSetStorageBuffers = 96; + s->properties.limits.maxDescriptorSetStorageImages = 144; + s->properties.limits.maxDescriptorSetUniformBuffers = 90; + s->properties.limits.maxFragmentCombinedOutputResources = 16; + s->properties.limits.maxImageArrayLayers = 2048; + s->properties.limits.maxImageDimension1D = 8192; + s->properties.limits.maxImageDimension2D = 8192; + s->properties.limits.maxImageDimensionCube = 8192; + s->properties.limits.maxPerStageDescriptorSampledImages = 200; + s->properties.limits.maxPerStageDescriptorSamplers = 64; + s->properties.limits.maxPerStageDescriptorStorageBuffers = 30; + s->properties.limits.maxPerStageDescriptorStorageImages = 16; + s->properties.limits.maxPerStageDescriptorUniformBuffers = 15; + s->properties.limits.maxPerStageResources = 200; + s->properties.limits.maxSamplerLodBias = 14; + s->properties.limits.maxUniformBufferRange = 65536; + s->properties.limits.mipmapPrecisionBits = 6; + s->properties.limits.standardSampleLocations = VK_TRUE; + s->properties.limits.subTexelPrecisionBits = 8; + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES: { + VkPhysicalDeviceVulkan11Properties* s = static_cast(static_cast(p)); + s->maxMultiviewInstanceIndex = 134217727; + s->maxMultiviewViewCount = 6; + s->subgroupSize = 4; + s->subgroupSupportedOperations |= (VK_SUBGROUP_FEATURE_BASIC_BIT | VK_SUBGROUP_FEATURE_VOTE_BIT | VK_SUBGROUP_FEATURE_ARITHMETIC_BIT | VK_SUBGROUP_FEATURE_BALLOT_BIT | VK_SUBGROUP_FEATURE_SHUFFLE_BIT | VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT | VK_SUBGROUP_FEATURE_QUAD_BIT); + s->subgroupSupportedStages |= (VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_FRAGMENT_BIT); + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES: { + VkPhysicalDeviceVulkan12Properties* s = static_cast(static_cast(p)); + s->maxDescriptorSetUpdateAfterBindInputAttachments = 7; + s->maxDescriptorSetUpdateAfterBindSampledImages = 500000; + s->maxDescriptorSetUpdateAfterBindSamplers = 500000; + s->maxDescriptorSetUpdateAfterBindStorageBuffers = 500000; + s->maxDescriptorSetUpdateAfterBindStorageBuffersDynamic = 4; + s->maxDescriptorSetUpdateAfterBindStorageImages = 500000; + s->maxDescriptorSetUpdateAfterBindUniformBuffers = 72; + s->maxDescriptorSetUpdateAfterBindUniformBuffersDynamic = 8; + s->maxPerStageDescriptorUpdateAfterBindInputAttachments = 7; + s->maxPerStageDescriptorUpdateAfterBindSampledImages = 500000; + s->maxPerStageDescriptorUpdateAfterBindSamplers = 500000; + s->maxPerStageDescriptorUpdateAfterBindStorageBuffers = 500000; + s->maxPerStageDescriptorUpdateAfterBindStorageImages = 500000; + s->maxPerStageDescriptorUpdateAfterBindUniformBuffers = 12; + s->maxPerStageUpdateAfterBindResources = 500000; + s->maxTimelineSemaphoreValueDifference = 2147483647; + s->shaderSignedZeroInfNanPreserveFloat16 = VK_TRUE; + s->shaderSignedZeroInfNanPreserveFloat32 = VK_TRUE; + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_PROPERTIES: { + VkPhysicalDeviceVulkan13Properties* s = static_cast(static_cast(p)); + s->maxBufferSize = 1073741824; + s->maxDescriptorSetInlineUniformBlocks = 4; + s->maxDescriptorSetUpdateAfterBindInlineUniformBlocks = 4; + s->maxInlineUniformBlockSize = 256; + s->maxInlineUniformTotalSize = 256; + s->maxPerStageDescriptorInlineUniformBlocks = 4; + s->maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks = 4; + } break; + default: break; + } + }, + [](VkBaseOutStructure* p) -> bool { (void)p; + bool ret = true; + switch (p->sType) { + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR: { + VkPhysicalDeviceProperties2KHR* s = static_cast(static_cast(p)); + ret = ret && (s->properties.limits.bufferImageGranularity <= 4096); + ret = ret && ((4096 % s->properties.limits.bufferImageGranularity) == 0); + ret = ret && (s->properties.limits.maxColorAttachments >= 7); + ret = ret && (s->properties.limits.maxComputeWorkGroupInvocations >= 256); + ret = ret && (s->properties.limits.maxComputeWorkGroupSize[0] >= 256); + ret = ret && (s->properties.limits.maxComputeWorkGroupSize[1] >= 256); + ret = ret && (s->properties.limits.maxComputeWorkGroupSize[2] >= 64); + ret = ret && (s->properties.limits.maxDescriptorSetSampledImages >= 1800); + ret = ret && (s->properties.limits.maxDescriptorSetSamplers >= 576); + ret = ret && (s->properties.limits.maxDescriptorSetStorageBuffers >= 96); + ret = ret && (s->properties.limits.maxDescriptorSetStorageImages >= 144); + ret = ret && (s->properties.limits.maxDescriptorSetUniformBuffers >= 90); + ret = ret && (s->properties.limits.maxFragmentCombinedOutputResources >= 16); + ret = ret && (s->properties.limits.maxImageArrayLayers >= 2048); + ret = ret && (s->properties.limits.maxImageDimension1D >= 8192); + ret = ret && (s->properties.limits.maxImageDimension2D >= 8192); + ret = ret && (s->properties.limits.maxImageDimensionCube >= 8192); + ret = ret && (s->properties.limits.maxPerStageDescriptorSampledImages >= 200); + ret = ret && (s->properties.limits.maxPerStageDescriptorSamplers >= 64); + ret = ret && (s->properties.limits.maxPerStageDescriptorStorageBuffers >= 30); + ret = ret && (s->properties.limits.maxPerStageDescriptorStorageImages >= 16); + ret = ret && (s->properties.limits.maxPerStageDescriptorUniformBuffers >= 15); + ret = ret && (s->properties.limits.maxPerStageResources >= 200); + ret = ret && (s->properties.limits.maxSamplerLodBias >= 14); + ret = ret && (s->properties.limits.maxUniformBufferRange >= 65536); + ret = ret && (s->properties.limits.mipmapPrecisionBits >= 6); + ret = ret && (s->properties.limits.standardSampleLocations >= VK_TRUE); + ret = ret && (s->properties.limits.subTexelPrecisionBits >= 8); + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES: { + VkPhysicalDeviceVulkan11Properties* s = static_cast(static_cast(p)); + ret = ret && (s->maxMultiviewInstanceIndex >= 134217727); + ret = ret && (s->maxMultiviewViewCount >= 6); + ret = ret && (s->subgroupSize >= 4); + ret = ret && ((s->subgroupSize & (s->subgroupSize - 1)) == 0); + ret = ret && (vpCheckFlags(s->subgroupSupportedOperations, (VK_SUBGROUP_FEATURE_BASIC_BIT | VK_SUBGROUP_FEATURE_VOTE_BIT | VK_SUBGROUP_FEATURE_ARITHMETIC_BIT | VK_SUBGROUP_FEATURE_BALLOT_BIT | VK_SUBGROUP_FEATURE_SHUFFLE_BIT | VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT | VK_SUBGROUP_FEATURE_QUAD_BIT))); + ret = ret && (vpCheckFlags(s->subgroupSupportedStages, (VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_FRAGMENT_BIT))); + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES: { + VkPhysicalDeviceVulkan12Properties* s = static_cast(static_cast(p)); + ret = ret && (s->maxDescriptorSetUpdateAfterBindInputAttachments >= 7); + ret = ret && (s->maxDescriptorSetUpdateAfterBindSampledImages >= 500000); + ret = ret && (s->maxDescriptorSetUpdateAfterBindSamplers >= 500000); + ret = ret && (s->maxDescriptorSetUpdateAfterBindStorageBuffers >= 500000); + ret = ret && (s->maxDescriptorSetUpdateAfterBindStorageBuffersDynamic >= 4); + ret = ret && (s->maxDescriptorSetUpdateAfterBindStorageImages >= 500000); + ret = ret && (s->maxDescriptorSetUpdateAfterBindUniformBuffers >= 72); + ret = ret && (s->maxDescriptorSetUpdateAfterBindUniformBuffersDynamic >= 8); + ret = ret && (s->maxPerStageDescriptorUpdateAfterBindInputAttachments >= 7); + ret = ret && (s->maxPerStageDescriptorUpdateAfterBindSampledImages >= 500000); + ret = ret && (s->maxPerStageDescriptorUpdateAfterBindSamplers >= 500000); + ret = ret && (s->maxPerStageDescriptorUpdateAfterBindStorageBuffers >= 500000); + ret = ret && (s->maxPerStageDescriptorUpdateAfterBindStorageImages >= 500000); + ret = ret && (s->maxPerStageDescriptorUpdateAfterBindUniformBuffers >= 12); + ret = ret && (s->maxPerStageUpdateAfterBindResources >= 500000); + ret = ret && (s->maxTimelineSemaphoreValueDifference >= 2147483647); + ret = ret && (s->shaderSignedZeroInfNanPreserveFloat16 >= VK_TRUE); + ret = ret && (s->shaderSignedZeroInfNanPreserveFloat32 >= VK_TRUE); + } break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_PROPERTIES: { + VkPhysicalDeviceVulkan13Properties* s = static_cast(static_cast(p)); + ret = ret && (s->maxBufferSize >= 1073741824); + ret = ret && (s->maxDescriptorSetInlineUniformBlocks >= 4); + ret = ret && (s->maxDescriptorSetUpdateAfterBindInlineUniformBlocks >= 4); + ret = ret && (s->maxInlineUniformBlockSize >= 256); + ret = ret && (s->maxInlineUniformTotalSize >= 256); + ret = ret && (s->maxPerStageDescriptorInlineUniformBlocks >= 4); + ret = ret && (s->maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks >= 4); + } break; + default: break; + } + return ret; + } +}; + +static const VpStructChainerDesc chainerDesc = { + [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { + VkPhysicalDeviceVulkan11Features physicalDeviceVulkan11Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES, nullptr }; + VkPhysicalDeviceVulkan12Features physicalDeviceVulkan12Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, &physicalDeviceVulkan11Features }; + VkPhysicalDeviceVulkan13Features physicalDeviceVulkan13Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES, &physicalDeviceVulkan12Features }; + p->pNext = static_cast(static_cast(&physicalDeviceVulkan13Features)); + pfnCb(p, pUser); + }, + [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { + VkPhysicalDeviceVulkan11Properties physicalDeviceVulkan11Properties{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES, nullptr }; + VkPhysicalDeviceVulkan12Properties physicalDeviceVulkan12Properties{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES, &physicalDeviceVulkan11Properties }; + VkPhysicalDeviceVulkan13Properties physicalDeviceVulkan13Properties{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_PROPERTIES, &physicalDeviceVulkan12Properties }; + p->pNext = static_cast(static_cast(&physicalDeviceVulkan13Properties)); + pfnCb(p, pUser); + }, + [](uint32_t count, VkBaseOutStructure* p, void* pUser, PFN_vpStructArrayChainerCb pfnCb) { + pfnCb(count, p, pUser); + }, + [](VkBaseOutStructure* p, void* pUser, PFN_vpStructChainerCb pfnCb) { + pfnCb(p, pUser); + }, +}; +} // namespace VP_LEARN_how_to_vulkan_2026_block +} // namespace blocks +} // namespace VP_LEARN_HOW_TO_VULKAN_2026 +#endif // VP_LEARN_how_to_vulkan_2026 + + +#ifdef VP_LEARN_how_to_vulkan_2026 +namespace VP_LEARN_HOW_TO_VULKAN_2026 { + static const VpVariantDesc mergedCapabilities[] = { + { + "MERGED", + static_cast(std::size(instanceExtensions)), instanceExtensions, + static_cast(std::size(deviceExtensions)), deviceExtensions, + static_cast(std::size(featureStructTypes)), featureStructTypes, + featureDesc, + 0, nullptr, + propertyDesc, + 0, nullptr, + 0, nullptr, + 0, nullptr, + 0, nullptr, + chainerDesc, + 0, nullptr, + }, + }; + + namespace blocks { + namespace VP_LEARN_how_to_vulkan_2026_block { + static const VpVariantDesc variants[] = { + { + "VP_LEARN_how_to_vulkan_2026_block", + static_cast(std::size(blocks::VP_LEARN_how_to_vulkan_2026_block::instanceExtensions)), blocks::VP_LEARN_how_to_vulkan_2026_block::instanceExtensions, + static_cast(std::size(blocks::VP_LEARN_how_to_vulkan_2026_block::deviceExtensions)), blocks::VP_LEARN_how_to_vulkan_2026_block::deviceExtensions, + static_cast(std::size(featureStructTypes)), featureStructTypes, + blocks::VP_LEARN_how_to_vulkan_2026_block::featureDesc, + static_cast(std::size(propertyStructTypes)), propertyStructTypes, + blocks::VP_LEARN_how_to_vulkan_2026_block::propertyDesc, + 0, nullptr, + 0, nullptr, + 0, nullptr, + 0, nullptr, + blocks::VP_LEARN_how_to_vulkan_2026_block::chainerDesc, + 0, nullptr, + }, + }; + static const uint32_t variantCount = static_cast(std::size(variants)); + } // namespace VP_LEARN_how_to_vulkan_2026_block + } // namespace blocks + + static const VpCapabilitiesDesc capabilities[] = { + { blocks::VP_LEARN_how_to_vulkan_2026_block::variantCount, blocks::VP_LEARN_how_to_vulkan_2026_block::variants }, + }; + static const uint32_t capabilityCount = static_cast(std::size(capabilities)); +} // namespace VP_LEARN_HOW_TO_VULKAN_2026 +#endif //VP_LEARN_how_to_vulkan_2026 + +static const VpProfileDesc profiles[] = { +#ifdef VP_LEARN_how_to_vulkan_2026 + VpProfileDesc{ + VpProfileProperties{ VP_LEARN_HOW_TO_VULKAN_2026_NAME, VP_LEARN_HOW_TO_VULKAN_2026_SPEC_VERSION }, + VP_LEARN_HOW_TO_VULKAN_2026_MIN_API_VERSION, + VP_LEARN_HOW_TO_VULKAN_2026::mergedCapabilities, + 0, nullptr, + VP_LEARN_HOW_TO_VULKAN_2026::capabilityCount, VP_LEARN_HOW_TO_VULKAN_2026::capabilities, + 0, nullptr, + }, +#endif // VP_LEARN_HOW_TO_VULKAN_2026 +}; +static const uint32_t profileCount = static_cast(std::size(profiles)); + + +struct FeaturesChain { + std::map structureSize; + + template + constexpr std::size_t size() const { + return (sizeof(T) - sizeof(VkBaseOutStructure)) / sizeof(VkBool32); + } + + // Chain with all Vulkan Features structures + VkPhysicalDeviceDeviceGeneratedCommandsFeaturesNV physicalDeviceDeviceGeneratedCommandsFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_FEATURES_NV, nullptr }; + VkPhysicalDevicePushConstantBankFeaturesNV physicalDevicePushConstantBankFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_CONSTANT_BANK_FEATURES_NV, nullptr }; + VkPhysicalDeviceDeviceGeneratedCommandsComputeFeaturesNV physicalDeviceDeviceGeneratedCommandsComputeFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_COMPUTE_FEATURES_NV, nullptr }; + VkPhysicalDevicePrivateDataFeatures physicalDevicePrivateDataFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES, nullptr }; + VkPhysicalDeviceClusterAccelerationStructureFeaturesNV physicalDeviceClusterAccelerationStructureFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CLUSTER_ACCELERATION_STRUCTURE_FEATURES_NV, nullptr }; + VkPhysicalDeviceVariablePointersFeatures physicalDeviceVariablePointersFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES, nullptr }; + VkPhysicalDeviceMultiviewFeatures physicalDeviceMultiviewFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES, nullptr }; + VkPhysicalDevicePresentIdFeaturesKHR physicalDevicePresentIdFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_ID_FEATURES_KHR, nullptr }; + VkPhysicalDevicePresentId2FeaturesKHR physicalDevicePresentId2FeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_ID_2_FEATURES_KHR, nullptr }; + VkPhysicalDevicePresentWaitFeaturesKHR physicalDevicePresentWaitFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_WAIT_FEATURES_KHR, nullptr }; + VkPhysicalDevicePresentWait2FeaturesKHR physicalDevicePresentWait2FeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_WAIT_2_FEATURES_KHR, nullptr }; + VkPhysicalDevicePresentTimingFeaturesEXT physicalDevicePresentTimingFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_TIMING_FEATURES_EXT, nullptr }; + VkPhysicalDevice16BitStorageFeatures physicalDevice16BitStorageFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES, nullptr }; + VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures physicalDeviceShaderSubgroupExtendedTypesFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES, nullptr }; + VkPhysicalDeviceSamplerYcbcrConversionFeatures physicalDeviceSamplerYcbcrConversionFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES, nullptr }; + VkPhysicalDeviceProtectedMemoryFeatures physicalDeviceProtectedMemoryFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES, nullptr }; + VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT physicalDeviceBlendOperationAdvancedFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT, nullptr }; + VkPhysicalDeviceMultiDrawFeaturesEXT physicalDeviceMultiDrawFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_FEATURES_EXT, nullptr }; + VkPhysicalDeviceInlineUniformBlockFeatures physicalDeviceInlineUniformBlockFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES, nullptr }; + VkPhysicalDeviceMaintenance4Features physicalDeviceMaintenance4Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES, nullptr }; + VkPhysicalDeviceMaintenance5Features physicalDeviceMaintenance5Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_5_FEATURES, nullptr }; + VkPhysicalDeviceMaintenance6Features physicalDeviceMaintenance6Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_6_FEATURES, nullptr }; + VkPhysicalDeviceMaintenance7FeaturesKHR physicalDeviceMaintenance7FeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_7_FEATURES_KHR, nullptr }; + VkPhysicalDeviceMaintenance8FeaturesKHR physicalDeviceMaintenance8FeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_8_FEATURES_KHR, nullptr }; + VkPhysicalDeviceMaintenance9FeaturesKHR physicalDeviceMaintenance9FeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_9_FEATURES_KHR, nullptr }; + VkPhysicalDeviceMaintenance11FeaturesKHR physicalDeviceMaintenance11FeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_11_FEATURES_KHR, nullptr }; + VkPhysicalDeviceMaintenance10FeaturesKHR physicalDeviceMaintenance10FeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_10_FEATURES_KHR, nullptr }; + VkPhysicalDeviceShaderDrawParametersFeatures physicalDeviceShaderDrawParametersFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES, nullptr }; + VkPhysicalDeviceShaderFloat16Int8Features physicalDeviceShaderFloat16Int8Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES, nullptr }; + VkPhysicalDeviceHostQueryResetFeatures physicalDeviceHostQueryResetFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES, nullptr }; + VkPhysicalDeviceGlobalPriorityQueryFeatures physicalDeviceGlobalPriorityQueryFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES, nullptr }; + VkPhysicalDeviceDeviceMemoryReportFeaturesEXT physicalDeviceDeviceMemoryReportFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_MEMORY_REPORT_FEATURES_EXT, nullptr }; + VkPhysicalDeviceDescriptorIndexingFeatures physicalDeviceDescriptorIndexingFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES, nullptr }; + VkPhysicalDeviceTimelineSemaphoreFeatures physicalDeviceTimelineSemaphoreFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES, nullptr }; + VkPhysicalDevice8BitStorageFeatures physicalDevice8BitStorageFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES, nullptr }; + VkPhysicalDeviceConditionalRenderingFeaturesEXT physicalDeviceConditionalRenderingFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT, nullptr }; + VkPhysicalDeviceVulkanMemoryModelFeatures physicalDeviceVulkanMemoryModelFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES, nullptr }; + VkPhysicalDeviceShaderAtomicInt64Features physicalDeviceShaderAtomicInt64Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES, nullptr }; + VkPhysicalDeviceShaderAtomicFloatFeaturesEXT physicalDeviceShaderAtomicFloatFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT, nullptr }; + VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT physicalDeviceShaderAtomicFloat2FeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT, nullptr }; + VkPhysicalDeviceVertexAttributeDivisorFeatures physicalDeviceVertexAttributeDivisorFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES, nullptr }; + VkPhysicalDeviceASTCDecodeFeaturesEXT physicalDeviceASTCDecodeFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT, nullptr }; + VkPhysicalDeviceTransformFeedbackFeaturesEXT physicalDeviceTransformFeedbackFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT, nullptr }; + VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV physicalDeviceRepresentativeFragmentTestFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_REPRESENTATIVE_FRAGMENT_TEST_FEATURES_NV, nullptr }; + VkPhysicalDeviceExclusiveScissorFeaturesNV physicalDeviceExclusiveScissorFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXCLUSIVE_SCISSOR_FEATURES_NV, nullptr }; + VkPhysicalDeviceCornerSampledImageFeaturesNV physicalDeviceCornerSampledImageFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CORNER_SAMPLED_IMAGE_FEATURES_NV, nullptr }; + VkPhysicalDeviceComputeShaderDerivativesFeaturesKHR physicalDeviceComputeShaderDerivativesFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_KHR, nullptr }; + VkPhysicalDeviceShaderImageFootprintFeaturesNV physicalDeviceShaderImageFootprintFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_FOOTPRINT_FEATURES_NV, nullptr }; + VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV physicalDeviceDedicatedAllocationImageAliasingFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEDICATED_ALLOCATION_IMAGE_ALIASING_FEATURES_NV, nullptr }; + VkPhysicalDeviceCopyMemoryIndirectFeaturesKHR physicalDeviceCopyMemoryIndirectFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COPY_MEMORY_INDIRECT_FEATURES_KHR, nullptr }; + VkPhysicalDeviceCopyMemoryIndirectFeaturesNV physicalDeviceCopyMemoryIndirectFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COPY_MEMORY_INDIRECT_FEATURES_NV, nullptr }; + VkPhysicalDeviceMemoryDecompressionFeaturesEXT physicalDeviceMemoryDecompressionFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_DECOMPRESSION_FEATURES_EXT, nullptr }; + VkPhysicalDeviceShadingRateImageFeaturesNV physicalDeviceShadingRateImageFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_FEATURES_NV, nullptr }; + VkPhysicalDeviceInvocationMaskFeaturesHUAWEI physicalDeviceInvocationMaskFeaturesHUAWEI{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INVOCATION_MASK_FEATURES_HUAWEI, nullptr }; + VkPhysicalDeviceMeshShaderFeaturesNV physicalDeviceMeshShaderFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV, nullptr }; + VkPhysicalDeviceMeshShaderFeaturesEXT physicalDeviceMeshShaderFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_EXT, nullptr }; + VkPhysicalDeviceAccelerationStructureFeaturesKHR physicalDeviceAccelerationStructureFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR, nullptr }; + VkPhysicalDeviceRayTracingPipelineFeaturesKHR physicalDeviceRayTracingPipelineFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR, nullptr }; + VkPhysicalDeviceRayQueryFeaturesKHR physicalDeviceRayQueryFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_QUERY_FEATURES_KHR, nullptr }; + VkPhysicalDeviceRayTracingMaintenance1FeaturesKHR physicalDeviceRayTracingMaintenance1FeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_MAINTENANCE_1_FEATURES_KHR, nullptr }; + VkPhysicalDeviceFragmentDensityMapFeaturesEXT physicalDeviceFragmentDensityMapFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT, nullptr }; + VkPhysicalDeviceFragmentDensityMap2FeaturesEXT physicalDeviceFragmentDensityMap2FeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_FEATURES_EXT, nullptr }; + VkPhysicalDeviceFragmentDensityMapOffsetFeaturesEXT physicalDeviceFragmentDensityMapOffsetFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_FEATURES_EXT, nullptr }; + VkPhysicalDeviceScalarBlockLayoutFeatures physicalDeviceScalarBlockLayoutFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES, nullptr }; + VkPhysicalDeviceUniformBufferStandardLayoutFeatures physicalDeviceUniformBufferStandardLayoutFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES, nullptr }; + VkPhysicalDeviceDepthClipEnableFeaturesEXT physicalDeviceDepthClipEnableFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT, nullptr }; + VkPhysicalDeviceMemoryPriorityFeaturesEXT physicalDeviceMemoryPriorityFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT, nullptr }; + VkPhysicalDevicePageableDeviceLocalMemoryFeaturesEXT physicalDevicePageableDeviceLocalMemoryFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PAGEABLE_DEVICE_LOCAL_MEMORY_FEATURES_EXT, nullptr }; + VkPhysicalDeviceBufferDeviceAddressFeatures physicalDeviceBufferDeviceAddressFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES, nullptr }; + VkPhysicalDeviceBufferDeviceAddressFeaturesEXT physicalDeviceBufferDeviceAddressFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT, nullptr }; + VkPhysicalDeviceImagelessFramebufferFeatures physicalDeviceImagelessFramebufferFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES, nullptr }; + VkPhysicalDeviceTextureCompressionASTCHDRFeatures physicalDeviceTextureCompressionASTCHDRFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES, nullptr }; + VkPhysicalDeviceCooperativeMatrixFeaturesNV physicalDeviceCooperativeMatrixFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_NV, nullptr }; + VkPhysicalDeviceYcbcrImageArraysFeaturesEXT physicalDeviceYcbcrImageArraysFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_IMAGE_ARRAYS_FEATURES_EXT, nullptr }; + VkPhysicalDevicePresentBarrierFeaturesNV physicalDevicePresentBarrierFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_BARRIER_FEATURES_NV, nullptr }; + VkPhysicalDevicePerformanceQueryFeaturesKHR physicalDevicePerformanceQueryFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_FEATURES_KHR, nullptr }; + VkPhysicalDeviceCoverageReductionModeFeaturesNV physicalDeviceCoverageReductionModeFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COVERAGE_REDUCTION_MODE_FEATURES_NV, nullptr }; + VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL physicalDeviceShaderIntegerFunctions2FeaturesINTEL{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL, nullptr }; + VkPhysicalDeviceShaderClockFeaturesKHR physicalDeviceShaderClockFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR, nullptr }; + VkPhysicalDeviceIndexTypeUint8Features physicalDeviceIndexTypeUint8Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES, nullptr }; + VkPhysicalDeviceShaderSMBuiltinsFeaturesNV physicalDeviceShaderSMBuiltinsFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SM_BUILTINS_FEATURES_NV, nullptr }; + VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT physicalDeviceFragmentShaderInterlockFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT, nullptr }; + VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures physicalDeviceSeparateDepthStencilLayoutsFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES, nullptr }; + VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT physicalDevicePrimitiveTopologyListRestartFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT, nullptr }; + VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR physicalDevicePipelineExecutablePropertiesFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR, nullptr }; + VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures physicalDeviceShaderDemoteToHelperInvocationFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES, nullptr }; + VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT physicalDeviceTexelBufferAlignmentFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT, nullptr }; + VkPhysicalDeviceSubgroupSizeControlFeatures physicalDeviceSubgroupSizeControlFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES, nullptr }; + VkPhysicalDeviceLineRasterizationFeatures physicalDeviceLineRasterizationFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES, nullptr }; + VkPhysicalDevicePipelineCreationCacheControlFeatures physicalDevicePipelineCreationCacheControlFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES, nullptr }; + VkPhysicalDeviceVulkan11Features physicalDeviceVulkan11Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES, nullptr }; + VkPhysicalDeviceVulkan12Features physicalDeviceVulkan12Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, nullptr }; + VkPhysicalDeviceVulkan13Features physicalDeviceVulkan13Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES, nullptr }; + VkPhysicalDeviceVulkan14Features physicalDeviceVulkan14Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_4_FEATURES, nullptr }; + VkPhysicalDeviceCoherentMemoryFeaturesAMD physicalDeviceCoherentMemoryFeaturesAMD{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COHERENT_MEMORY_FEATURES_AMD, nullptr }; + VkPhysicalDeviceCustomBorderColorFeaturesEXT physicalDeviceCustomBorderColorFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT, nullptr }; + VkPhysicalDeviceBorderColorSwizzleFeaturesEXT physicalDeviceBorderColorSwizzleFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BORDER_COLOR_SWIZZLE_FEATURES_EXT, nullptr }; + VkPhysicalDeviceExtendedDynamicStateFeaturesEXT physicalDeviceExtendedDynamicStateFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT, nullptr }; + VkPhysicalDeviceExtendedDynamicState2FeaturesEXT physicalDeviceExtendedDynamicState2FeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT, nullptr }; + VkPhysicalDeviceExtendedDynamicState3FeaturesEXT physicalDeviceExtendedDynamicState3FeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_3_FEATURES_EXT, nullptr }; + VkPhysicalDevicePartitionedAccelerationStructureFeaturesNV physicalDevicePartitionedAccelerationStructureFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PARTITIONED_ACCELERATION_STRUCTURE_FEATURES_NV, nullptr }; + VkPhysicalDeviceDiagnosticsConfigFeaturesNV physicalDeviceDiagnosticsConfigFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DIAGNOSTICS_CONFIG_FEATURES_NV, nullptr }; + VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures physicalDeviceZeroInitializeWorkgroupMemoryFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES, nullptr }; + VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR physicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_FEATURES_KHR, nullptr }; + VkPhysicalDeviceRobustness2FeaturesKHR physicalDeviceRobustness2FeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_KHR, nullptr }; + VkPhysicalDeviceImageRobustnessFeatures physicalDeviceImageRobustnessFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES, nullptr }; + VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR physicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_FEATURES_KHR, nullptr }; +#ifdef VK_ENABLE_BETA_EXTENSIONS + VkPhysicalDevicePortabilitySubsetFeaturesKHR physicalDevicePortabilitySubsetFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR, nullptr }; +#endif + VkPhysicalDevice4444FormatsFeaturesEXT physicalDevice4444FormatsFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT, nullptr }; + VkPhysicalDeviceSubpassShadingFeaturesHUAWEI physicalDeviceSubpassShadingFeaturesHUAWEI{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_SHADING_FEATURES_HUAWEI, nullptr }; + VkPhysicalDeviceClusterCullingShaderFeaturesHUAWEI physicalDeviceClusterCullingShaderFeaturesHUAWEI{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CLUSTER_CULLING_SHADER_FEATURES_HUAWEI, nullptr }; + VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT physicalDeviceShaderImageAtomicInt64FeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_ATOMIC_INT64_FEATURES_EXT, nullptr }; + VkPhysicalDeviceFragmentShadingRateFeaturesKHR physicalDeviceFragmentShadingRateFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR, nullptr }; + VkPhysicalDeviceShaderTerminateInvocationFeatures physicalDeviceShaderTerminateInvocationFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES, nullptr }; + VkPhysicalDeviceFragmentShadingRateEnumsFeaturesNV physicalDeviceFragmentShadingRateEnumsFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_ENUMS_FEATURES_NV, nullptr }; + VkPhysicalDeviceImage2DViewOf3DFeaturesEXT physicalDeviceImage2DViewOf3DFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_2D_VIEW_OF_3D_FEATURES_EXT, nullptr }; + VkPhysicalDeviceImageSlicedViewOf3DFeaturesEXT physicalDeviceImageSlicedViewOf3DFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_SLICED_VIEW_OF_3D_FEATURES_EXT, nullptr }; + VkPhysicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT physicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_DYNAMIC_STATE_FEATURES_EXT, nullptr }; + VkPhysicalDeviceLegacyVertexAttributesFeaturesEXT physicalDeviceLegacyVertexAttributesFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LEGACY_VERTEX_ATTRIBUTES_FEATURES_EXT, nullptr }; + VkPhysicalDeviceMutableDescriptorTypeFeaturesEXT physicalDeviceMutableDescriptorTypeFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_EXT, nullptr }; + VkPhysicalDeviceDepthClipControlFeaturesEXT physicalDeviceDepthClipControlFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_CONTROL_FEATURES_EXT, nullptr }; + VkPhysicalDeviceZeroInitializeDeviceMemoryFeaturesEXT physicalDeviceZeroInitializeDeviceMemoryFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_DEVICE_MEMORY_FEATURES_EXT, nullptr }; + VkPhysicalDeviceCustomResolveFeaturesEXT physicalDeviceCustomResolveFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_RESOLVE_FEATURES_EXT, nullptr }; + VkPhysicalDeviceDeviceGeneratedCommandsFeaturesEXT physicalDeviceDeviceGeneratedCommandsFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_FEATURES_EXT, nullptr }; + VkPhysicalDeviceDepthClampControlFeaturesEXT physicalDeviceDepthClampControlFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLAMP_CONTROL_FEATURES_EXT, nullptr }; + VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT physicalDeviceVertexInputDynamicStateFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_INPUT_DYNAMIC_STATE_FEATURES_EXT, nullptr }; + VkPhysicalDeviceExternalMemoryRDMAFeaturesNV physicalDeviceExternalMemoryRDMAFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_RDMA_FEATURES_NV, nullptr }; + VkPhysicalDeviceShaderRelaxedExtendedInstructionFeaturesKHR physicalDeviceShaderRelaxedExtendedInstructionFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_RELAXED_EXTENDED_INSTRUCTION_FEATURES_KHR, nullptr }; + VkPhysicalDeviceColorWriteEnableFeaturesEXT physicalDeviceColorWriteEnableFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT, nullptr }; + VkPhysicalDeviceSynchronization2Features physicalDeviceSynchronization2Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES, nullptr }; + VkPhysicalDeviceUnifiedImageLayoutsFeaturesKHR physicalDeviceUnifiedImageLayoutsFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFIED_IMAGE_LAYOUTS_FEATURES_KHR, nullptr }; + VkPhysicalDeviceHostImageCopyFeatures physicalDeviceHostImageCopyFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_FEATURES, nullptr }; + VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT physicalDevicePrimitivesGeneratedQueryFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVES_GENERATED_QUERY_FEATURES_EXT, nullptr }; + VkPhysicalDeviceLegacyDitheringFeaturesEXT physicalDeviceLegacyDitheringFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LEGACY_DITHERING_FEATURES_EXT, nullptr }; + VkPhysicalDeviceMultisampledRenderToSingleSampledFeaturesEXT physicalDeviceMultisampledRenderToSingleSampledFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_FEATURES_EXT, nullptr }; + VkPhysicalDevicePipelineProtectedAccessFeatures physicalDevicePipelineProtectedAccessFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_PROTECTED_ACCESS_FEATURES, nullptr }; + VkPhysicalDeviceVideoMaintenance1FeaturesKHR physicalDeviceVideoMaintenance1FeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_MAINTENANCE_1_FEATURES_KHR, nullptr }; + VkPhysicalDeviceVideoMaintenance2FeaturesKHR physicalDeviceVideoMaintenance2FeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_MAINTENANCE_2_FEATURES_KHR, nullptr }; + VkPhysicalDeviceVideoDecodeVP9FeaturesKHR physicalDeviceVideoDecodeVP9FeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_DECODE_VP9_FEATURES_KHR, nullptr }; + VkPhysicalDeviceVideoEncodeQuantizationMapFeaturesKHR physicalDeviceVideoEncodeQuantizationMapFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_QUANTIZATION_MAP_FEATURES_KHR, nullptr }; + VkPhysicalDeviceVideoEncodeAV1FeaturesKHR physicalDeviceVideoEncodeAV1FeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_AV1_FEATURES_KHR, nullptr }; + VkPhysicalDeviceInheritedViewportScissorFeaturesNV physicalDeviceInheritedViewportScissorFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INHERITED_VIEWPORT_SCISSOR_FEATURES_NV, nullptr }; + VkPhysicalDeviceYcbcr2Plane444FormatsFeaturesEXT physicalDeviceYcbcr2Plane444FormatsFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_2_PLANE_444_FORMATS_FEATURES_EXT, nullptr }; + VkPhysicalDeviceProvokingVertexFeaturesEXT physicalDeviceProvokingVertexFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT, nullptr }; + VkPhysicalDeviceVideoEncodeIntraRefreshFeaturesKHR physicalDeviceVideoEncodeIntraRefreshFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_INTRA_REFRESH_FEATURES_KHR, nullptr }; + VkPhysicalDeviceDescriptorBufferFeaturesEXT physicalDeviceDescriptorBufferFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_BUFFER_FEATURES_EXT, nullptr }; + VkPhysicalDeviceShaderIntegerDotProductFeatures physicalDeviceShaderIntegerDotProductFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES, nullptr }; + VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR physicalDeviceFragmentShaderBarycentricFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_KHR, nullptr }; + VkPhysicalDeviceShaderFmaFeaturesKHR physicalDeviceShaderFmaFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FMA_FEATURES_KHR, nullptr }; + VkPhysicalDeviceRayTracingMotionBlurFeaturesNV physicalDeviceRayTracingMotionBlurFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_MOTION_BLUR_FEATURES_NV, nullptr }; + VkPhysicalDeviceRayTracingValidationFeaturesNV physicalDeviceRayTracingValidationFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_VALIDATION_FEATURES_NV, nullptr }; + VkPhysicalDeviceRayTracingLinearSweptSpheresFeaturesNV physicalDeviceRayTracingLinearSweptSpheresFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_LINEAR_SWEPT_SPHERES_FEATURES_NV, nullptr }; + VkPhysicalDeviceRGBA10X6FormatsFeaturesEXT physicalDeviceRGBA10X6FormatsFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RGBA10X6_FORMATS_FEATURES_EXT, nullptr }; + VkPhysicalDeviceDynamicRenderingFeatures physicalDeviceDynamicRenderingFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES, nullptr }; + VkPhysicalDeviceImageViewMinLodFeaturesEXT physicalDeviceImageViewMinLodFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_MIN_LOD_FEATURES_EXT, nullptr }; + VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT physicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_EXT, nullptr }; + VkPhysicalDeviceLinearColorAttachmentFeaturesNV physicalDeviceLinearColorAttachmentFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINEAR_COLOR_ATTACHMENT_FEATURES_NV, nullptr }; + VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT physicalDeviceGraphicsPipelineLibraryFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_FEATURES_EXT, nullptr }; + VkPhysicalDevicePipelineBinaryFeaturesKHR physicalDevicePipelineBinaryFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_BINARY_FEATURES_KHR, nullptr }; + VkPhysicalDeviceDataGraphNeuralAcceleratorStatisticsFeaturesARM physicalDeviceDataGraphNeuralAcceleratorStatisticsFeaturesARM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DATA_GRAPH_NEURAL_ACCELERATOR_STATISTICS_FEATURES_ARM, nullptr }; + VkPhysicalDeviceDescriptorSetHostMappingFeaturesVALVE physicalDeviceDescriptorSetHostMappingFeaturesVALVE{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_SET_HOST_MAPPING_FEATURES_VALVE, nullptr }; + VkPhysicalDeviceNestedCommandBufferFeaturesEXT physicalDeviceNestedCommandBufferFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_NESTED_COMMAND_BUFFER_FEATURES_EXT, nullptr }; + VkPhysicalDeviceShaderModuleIdentifierFeaturesEXT physicalDeviceShaderModuleIdentifierFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MODULE_IDENTIFIER_FEATURES_EXT, nullptr }; + VkPhysicalDeviceImageCompressionControlFeaturesEXT physicalDeviceImageCompressionControlFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_FEATURES_EXT, nullptr }; + VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT physicalDeviceImageCompressionControlSwapchainFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_FEATURES_EXT, nullptr }; + VkPhysicalDeviceSubpassMergeFeedbackFeaturesEXT physicalDeviceSubpassMergeFeedbackFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_MERGE_FEEDBACK_FEATURES_EXT, nullptr }; + VkPhysicalDeviceOpacityMicromapFeaturesEXT physicalDeviceOpacityMicromapFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_OPACITY_MICROMAP_FEATURES_EXT, nullptr }; +#ifdef VK_ENABLE_BETA_EXTENSIONS + VkPhysicalDeviceDisplacementMicromapFeaturesNV physicalDeviceDisplacementMicromapFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISPLACEMENT_MICROMAP_FEATURES_NV, nullptr }; +#endif + VkPhysicalDevicePipelinePropertiesFeaturesEXT physicalDevicePipelinePropertiesFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_PROPERTIES_FEATURES_EXT, nullptr }; + VkPhysicalDeviceShaderEarlyAndLateFragmentTestsFeaturesAMD physicalDeviceShaderEarlyAndLateFragmentTestsFeaturesAMD{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_EARLY_AND_LATE_FRAGMENT_TESTS_FEATURES_AMD, nullptr }; + VkPhysicalDeviceNonSeamlessCubeMapFeaturesEXT physicalDeviceNonSeamlessCubeMapFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_NON_SEAMLESS_CUBE_MAP_FEATURES_EXT, nullptr }; + VkPhysicalDevicePipelineRobustnessFeatures physicalDevicePipelineRobustnessFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_ROBUSTNESS_FEATURES, nullptr }; + VkPhysicalDeviceImageProcessingFeaturesQCOM physicalDeviceImageProcessingFeaturesQCOM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_PROCESSING_FEATURES_QCOM, nullptr }; + VkPhysicalDeviceTilePropertiesFeaturesQCOM physicalDeviceTilePropertiesFeaturesQCOM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TILE_PROPERTIES_FEATURES_QCOM, nullptr }; + VkPhysicalDeviceAmigoProfilingFeaturesSEC physicalDeviceAmigoProfilingFeaturesSEC{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_AMIGO_PROFILING_FEATURES_SEC, nullptr }; + VkPhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT physicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_FEATURES_EXT, nullptr }; + VkPhysicalDeviceAddressBindingReportFeaturesEXT physicalDeviceAddressBindingReportFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ADDRESS_BINDING_REPORT_FEATURES_EXT, nullptr }; + VkPhysicalDeviceOpticalFlowFeaturesNV physicalDeviceOpticalFlowFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_OPTICAL_FLOW_FEATURES_NV, nullptr }; + VkPhysicalDeviceFaultFeaturesEXT physicalDeviceFaultFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FAULT_FEATURES_EXT, nullptr }; + VkPhysicalDeviceFaultFeaturesKHR physicalDeviceFaultFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FAULT_FEATURES_KHR, nullptr }; + VkPhysicalDevicePipelineLibraryGroupHandlesFeaturesEXT physicalDevicePipelineLibraryGroupHandlesFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_LIBRARY_GROUP_HANDLES_FEATURES_EXT, nullptr }; + VkPhysicalDeviceShaderCoreBuiltinsFeaturesARM physicalDeviceShaderCoreBuiltinsFeaturesARM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_BUILTINS_FEATURES_ARM, nullptr }; + VkPhysicalDeviceFrameBoundaryFeaturesEXT physicalDeviceFrameBoundaryFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAME_BOUNDARY_FEATURES_EXT, nullptr }; + VkPhysicalDeviceDynamicRenderingUnusedAttachmentsFeaturesEXT physicalDeviceDynamicRenderingUnusedAttachmentsFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_UNUSED_ATTACHMENTS_FEATURES_EXT, nullptr }; + VkPhysicalDeviceInternallySynchronizedQueuesFeaturesKHR physicalDeviceInternallySynchronizedQueuesFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INTERNALLY_SYNCHRONIZED_QUEUES_FEATURES_KHR, nullptr }; + VkPhysicalDeviceSwapchainMaintenance1FeaturesKHR physicalDeviceSwapchainMaintenance1FeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_KHR, nullptr }; + VkPhysicalDeviceDepthBiasControlFeaturesEXT physicalDeviceDepthBiasControlFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_BIAS_CONTROL_FEATURES_EXT, nullptr }; + VkPhysicalDeviceRayTracingInvocationReorderFeaturesEXT physicalDeviceRayTracingInvocationReorderFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_INVOCATION_REORDER_FEATURES_EXT, nullptr }; + VkPhysicalDeviceRayTracingInvocationReorderFeaturesNV physicalDeviceRayTracingInvocationReorderFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_INVOCATION_REORDER_FEATURES_NV, nullptr }; + VkPhysicalDeviceExtendedSparseAddressSpaceFeaturesNV physicalDeviceExtendedSparseAddressSpaceFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_SPARSE_ADDRESS_SPACE_FEATURES_NV, nullptr }; + VkPhysicalDeviceMultiviewPerViewViewportsFeaturesQCOM physicalDeviceMultiviewPerViewViewportsFeaturesQCOM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_VIEWPORTS_FEATURES_QCOM, nullptr }; + VkPhysicalDeviceRayTracingPositionFetchFeaturesKHR physicalDeviceRayTracingPositionFetchFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_POSITION_FETCH_FEATURES_KHR, nullptr }; + VkPhysicalDeviceMultiviewPerViewRenderAreasFeaturesQCOM physicalDeviceMultiviewPerViewRenderAreasFeaturesQCOM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_RENDER_AREAS_FEATURES_QCOM, nullptr }; + VkPhysicalDeviceShaderObjectFeaturesEXT physicalDeviceShaderObjectFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_FEATURES_EXT, nullptr }; + VkPhysicalDeviceShaderTileImageFeaturesEXT physicalDeviceShaderTileImageFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TILE_IMAGE_FEATURES_EXT, nullptr }; +#ifdef VK_USE_PLATFORM_SCREEN_QNX + VkPhysicalDeviceExternalMemoryScreenBufferFeaturesQNX physicalDeviceExternalMemoryScreenBufferFeaturesQNX{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_SCREEN_BUFFER_FEATURES_QNX, nullptr }; +#endif + VkPhysicalDeviceCooperativeMatrixFeaturesKHR physicalDeviceCooperativeMatrixFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_KHR, nullptr }; + VkPhysicalDeviceCooperativeMatrixConversionFeaturesQCOM physicalDeviceCooperativeMatrixConversionFeaturesQCOM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_CONVERSION_FEATURES_QCOM, nullptr }; +#ifdef VK_ENABLE_BETA_EXTENSIONS + VkPhysicalDeviceShaderEnqueueFeaturesAMDX physicalDeviceShaderEnqueueFeaturesAMDX{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ENQUEUE_FEATURES_AMDX, nullptr }; +#endif + VkPhysicalDeviceAntiLagFeaturesAMD physicalDeviceAntiLagFeaturesAMD{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ANTI_LAG_FEATURES_AMD, nullptr }; + VkPhysicalDeviceTileMemoryHeapFeaturesQCOM physicalDeviceTileMemoryHeapFeaturesQCOM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TILE_MEMORY_HEAP_FEATURES_QCOM, nullptr }; + VkPhysicalDeviceCubicClampFeaturesQCOM physicalDeviceCubicClampFeaturesQCOM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUBIC_CLAMP_FEATURES_QCOM, nullptr }; + VkPhysicalDeviceYcbcrDegammaFeaturesQCOM physicalDeviceYcbcrDegammaFeaturesQCOM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_DEGAMMA_FEATURES_QCOM, nullptr }; + VkPhysicalDeviceCubicWeightsFeaturesQCOM physicalDeviceCubicWeightsFeaturesQCOM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUBIC_WEIGHTS_FEATURES_QCOM, nullptr }; + VkPhysicalDeviceImageProcessing2FeaturesQCOM physicalDeviceImageProcessing2FeaturesQCOM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_PROCESSING_2_FEATURES_QCOM, nullptr }; + VkPhysicalDeviceDescriptorPoolOverallocationFeaturesNV physicalDeviceDescriptorPoolOverallocationFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_POOL_OVERALLOCATION_FEATURES_NV, nullptr }; + VkPhysicalDevicePerStageDescriptorSetFeaturesNV physicalDevicePerStageDescriptorSetFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PER_STAGE_DESCRIPTOR_SET_FEATURES_NV, nullptr }; +#ifdef VK_USE_PLATFORM_ANDROID_KHR + VkPhysicalDeviceExternalFormatResolveFeaturesANDROID physicalDeviceExternalFormatResolveFeaturesANDROID{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FORMAT_RESOLVE_FEATURES_ANDROID, nullptr }; +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VkPhysicalDeviceCudaKernelLaunchFeaturesNV physicalDeviceCudaKernelLaunchFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUDA_KERNEL_LAUNCH_FEATURES_NV, nullptr }; +#endif + VkPhysicalDeviceSchedulingControlsFeaturesARM physicalDeviceSchedulingControlsFeaturesARM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCHEDULING_CONTROLS_FEATURES_ARM, nullptr }; + VkPhysicalDeviceRelaxedLineRasterizationFeaturesIMG physicalDeviceRelaxedLineRasterizationFeaturesIMG{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RELAXED_LINE_RASTERIZATION_FEATURES_IMG, nullptr }; + VkPhysicalDeviceRenderPassStripedFeaturesARM physicalDeviceRenderPassStripedFeaturesARM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RENDER_PASS_STRIPED_FEATURES_ARM, nullptr }; + VkPhysicalDevicePipelineOpacityMicromapFeaturesARM physicalDevicePipelineOpacityMicromapFeaturesARM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_OPACITY_MICROMAP_FEATURES_ARM, nullptr }; + VkPhysicalDeviceShaderMaximalReconvergenceFeaturesKHR physicalDeviceShaderMaximalReconvergenceFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MAXIMAL_RECONVERGENCE_FEATURES_KHR, nullptr }; + VkPhysicalDeviceShaderSubgroupRotateFeatures physicalDeviceShaderSubgroupRotateFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_ROTATE_FEATURES, nullptr }; + VkPhysicalDeviceShaderExpectAssumeFeatures physicalDeviceShaderExpectAssumeFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_EXPECT_ASSUME_FEATURES, nullptr }; + VkPhysicalDeviceShaderFloatControls2Features physicalDeviceShaderFloatControls2Features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT_CONTROLS_2_FEATURES, nullptr }; + VkPhysicalDeviceDynamicRenderingLocalReadFeatures physicalDeviceDynamicRenderingLocalReadFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_LOCAL_READ_FEATURES, nullptr }; + VkPhysicalDeviceShaderQuadControlFeaturesKHR physicalDeviceShaderQuadControlFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_QUAD_CONTROL_FEATURES_KHR, nullptr }; + VkPhysicalDeviceShaderAtomicFloat16VectorFeaturesNV physicalDeviceShaderAtomicFloat16VectorFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT16_VECTOR_FEATURES_NV, nullptr }; + VkPhysicalDeviceMapMemoryPlacedFeaturesEXT physicalDeviceMapMemoryPlacedFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_FEATURES_EXT, nullptr }; + VkPhysicalDeviceShaderBfloat16FeaturesKHR physicalDeviceShaderBfloat16FeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_BFLOAT16_FEATURES_KHR, nullptr }; + VkPhysicalDeviceRawAccessChainsFeaturesNV physicalDeviceRawAccessChainsFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAW_ACCESS_CHAINS_FEATURES_NV, nullptr }; + VkPhysicalDeviceCommandBufferInheritanceFeaturesNV physicalDeviceCommandBufferInheritanceFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMMAND_BUFFER_INHERITANCE_FEATURES_NV, nullptr }; + VkPhysicalDeviceImageAlignmentControlFeaturesMESA physicalDeviceImageAlignmentControlFeaturesMESA{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ALIGNMENT_CONTROL_FEATURES_MESA, nullptr }; + VkPhysicalDeviceShaderReplicatedCompositesFeaturesEXT physicalDeviceShaderReplicatedCompositesFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_REPLICATED_COMPOSITES_FEATURES_EXT, nullptr }; + VkPhysicalDevicePresentModeFifoLatestReadyFeaturesKHR physicalDevicePresentModeFifoLatestReadyFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_MODE_FIFO_LATEST_READY_FEATURES_KHR, nullptr }; + VkPhysicalDeviceCooperativeMatrix2FeaturesNV physicalDeviceCooperativeMatrix2FeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_2_FEATURES_NV, nullptr }; + VkPhysicalDeviceHdrVividFeaturesHUAWEI physicalDeviceHdrVividFeaturesHUAWEI{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HDR_VIVID_FEATURES_HUAWEI, nullptr }; + VkPhysicalDeviceVertexAttributeRobustnessFeaturesEXT physicalDeviceVertexAttributeRobustnessFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_ROBUSTNESS_FEATURES_EXT, nullptr }; +#ifdef VK_ENABLE_BETA_EXTENSIONS + VkPhysicalDeviceDenseGeometryFormatFeaturesAMDX physicalDeviceDenseGeometryFormatFeaturesAMDX{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DENSE_GEOMETRY_FORMAT_FEATURES_AMDX, nullptr }; +#endif + VkPhysicalDeviceDepthClampZeroOneFeaturesKHR physicalDeviceDepthClampZeroOneFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLAMP_ZERO_ONE_FEATURES_KHR, nullptr }; + VkPhysicalDeviceCooperativeVectorFeaturesNV physicalDeviceCooperativeVectorFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_VECTOR_FEATURES_NV, nullptr }; + VkPhysicalDeviceTileShadingFeaturesQCOM physicalDeviceTileShadingFeaturesQCOM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TILE_SHADING_FEATURES_QCOM, nullptr }; + VkPhysicalDeviceFragmentDensityMapLayeredFeaturesVALVE physicalDeviceFragmentDensityMapLayeredFeaturesVALVE{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_LAYERED_FEATURES_VALVE, nullptr }; + VkPhysicalDevicePresentMeteringFeaturesNV physicalDevicePresentMeteringFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_METERING_FEATURES_NV, nullptr }; + VkPhysicalDeviceShaderUniformBufferUnsizedArrayFeaturesEXT physicalDeviceShaderUniformBufferUnsizedArrayFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_UNIFORM_BUFFER_UNSIZED_ARRAY_FEATURES_EXT, nullptr }; + VkPhysicalDeviceShaderMixedFloatDotProductFeaturesVALVE physicalDeviceShaderMixedFloatDotProductFeaturesVALVE{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MIXED_FLOAT_DOT_PRODUCT_FEATURES_VALVE, nullptr }; + VkPhysicalDevicePrimitiveRestartIndexFeaturesEXT physicalDevicePrimitiveRestartIndexFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_RESTART_INDEX_FEATURES_EXT, nullptr }; + VkPhysicalDeviceFormatPackFeaturesARM physicalDeviceFormatPackFeaturesARM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FORMAT_PACK_FEATURES_ARM, nullptr }; + VkPhysicalDeviceThrottleHintFeaturesSEC physicalDeviceThrottleHintFeaturesSEC{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_THROTTLE_HINT_FEATURES_SEC, nullptr }; + VkPhysicalDeviceTensorFeaturesARM physicalDeviceTensorFeaturesARM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TENSOR_FEATURES_ARM, nullptr }; + VkPhysicalDeviceDescriptorBufferTensorFeaturesARM physicalDeviceDescriptorBufferTensorFeaturesARM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_BUFFER_TENSOR_FEATURES_ARM, nullptr }; + VkPhysicalDeviceShaderFloat8FeaturesEXT physicalDeviceShaderFloat8FeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT8_FEATURES_EXT, nullptr }; + VkPhysicalDeviceDataGraphFeaturesARM physicalDeviceDataGraphFeaturesARM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DATA_GRAPH_FEATURES_ARM, nullptr }; + VkPhysicalDevicePipelineCacheIncrementalModeFeaturesSEC physicalDevicePipelineCacheIncrementalModeFeaturesSEC{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CACHE_INCREMENTAL_MODE_FEATURES_SEC, nullptr }; + VkPhysicalDeviceDataGraphModelFeaturesQCOM physicalDeviceDataGraphModelFeaturesQCOM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DATA_GRAPH_MODEL_FEATURES_QCOM, nullptr }; + VkPhysicalDeviceShaderUntypedPointersFeaturesKHR physicalDeviceShaderUntypedPointersFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_UNTYPED_POINTERS_FEATURES_KHR, nullptr }; + VkPhysicalDeviceVideoEncodeRgbConversionFeaturesVALVE physicalDeviceVideoEncodeRgbConversionFeaturesVALVE{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_RGB_CONVERSION_FEATURES_VALVE, nullptr }; + VkPhysicalDeviceShader64BitIndexingFeaturesEXT physicalDeviceShader64BitIndexingFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_64_BIT_INDEXING_FEATURES_EXT, nullptr }; + VkPhysicalDeviceQueuePerfHintFeaturesQCOM physicalDeviceQueuePerfHintFeaturesQCOM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_QUEUE_PERF_HINT_FEATURES_QCOM, nullptr }; + VkPhysicalDevicePerformanceCountersByRegionFeaturesARM physicalDevicePerformanceCountersByRegionFeaturesARM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_COUNTERS_BY_REGION_FEATURES_ARM, nullptr }; + VkPhysicalDeviceComputeOccupancyPriorityFeaturesNV physicalDeviceComputeOccupancyPriorityFeaturesNV{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_OCCUPANCY_PRIORITY_FEATURES_NV, nullptr }; + VkPhysicalDeviceShaderLongVectorFeaturesEXT physicalDeviceShaderLongVectorFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_LONG_VECTOR_FEATURES_EXT, nullptr }; + VkPhysicalDeviceTextureCompressionASTC3DFeaturesEXT physicalDeviceTextureCompressionASTC3DFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_3D_FEATURES_EXT, nullptr }; + VkPhysicalDeviceShaderSubgroupPartitionedFeaturesEXT physicalDeviceShaderSubgroupPartitionedFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_PARTITIONED_FEATURES_EXT, nullptr }; + VkPhysicalDeviceDescriptorHeapFeaturesEXT physicalDeviceDescriptorHeapFeaturesEXT{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_HEAP_FEATURES_EXT, nullptr }; + VkPhysicalDeviceShaderInstrumentationFeaturesARM physicalDeviceShaderInstrumentationFeaturesARM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INSTRUMENTATION_FEATURES_ARM, nullptr }; + VkPhysicalDeviceDeviceAddressCommandsFeaturesKHR physicalDeviceDeviceAddressCommandsFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_ADDRESS_COMMANDS_FEATURES_KHR, nullptr }; + VkPhysicalDeviceShaderConstantDataFeaturesKHR physicalDeviceShaderConstantDataFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CONSTANT_DATA_FEATURES_KHR, nullptr }; + VkPhysicalDeviceShaderAbortFeaturesKHR physicalDeviceShaderAbortFeaturesKHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ABORT_FEATURES_KHR, nullptr }; + VkPhysicalDeviceDataGraphOpticalFlowFeaturesARM physicalDeviceDataGraphOpticalFlowFeaturesARM{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DATA_GRAPH_OPTICAL_FLOW_FEATURES_ARM, nullptr }; + VkPhysicalDeviceFeatures2KHR physicalDeviceFeatures2KHR{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR, nullptr }; + + FeaturesChain() { + // Initializing all feature structures, number of Features (VkBool32) per structure. + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_CONSTANT_BANK_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_COMPUTE_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CLUSTER_ACCELERATION_STRUCTURE_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_ID_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_ID_2_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_WAIT_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_WAIT_2_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_TIMING_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_5_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_6_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_7_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_8_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_9_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_11_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_10_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_MEMORY_REPORT_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_REPRESENTATIVE_FRAGMENT_TEST_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXCLUSIVE_SCISSOR_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CORNER_SAMPLED_IMAGE_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_FOOTPRINT_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEDICATED_ALLOCATION_IMAGE_ALIASING_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COPY_MEMORY_INDIRECT_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COPY_MEMORY_INDIRECT_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_DECOMPRESSION_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INVOCATION_MASK_FEATURES_HUAWEI, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_QUERY_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_MAINTENANCE_1_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PAGEABLE_DEVICE_LOCAL_MEMORY_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_IMAGE_ARRAYS_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_BARRIER_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COVERAGE_REDUCTION_MODE_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SM_BUILTINS_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_4_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COHERENT_MEMORY_FEATURES_AMD, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BORDER_COLOR_SWIZZLE_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_3_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PARTITIONED_ACCELERATION_STRUCTURE_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DIAGNOSTICS_CONFIG_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_FEATURES_KHR, size() }); +#ifdef VK_ENABLE_BETA_EXTENSIONS + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR, size() }); +#endif + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_SHADING_FEATURES_HUAWEI, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CLUSTER_CULLING_SHADER_FEATURES_HUAWEI, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_ATOMIC_INT64_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_ENUMS_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_2D_VIEW_OF_3D_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_SLICED_VIEW_OF_3D_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_DYNAMIC_STATE_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LEGACY_VERTEX_ATTRIBUTES_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_CONTROL_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_DEVICE_MEMORY_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_RESOLVE_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLAMP_CONTROL_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_INPUT_DYNAMIC_STATE_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_RDMA_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_RELAXED_EXTENDED_INSTRUCTION_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFIED_IMAGE_LAYOUTS_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVES_GENERATED_QUERY_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LEGACY_DITHERING_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_PROTECTED_ACCESS_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_MAINTENANCE_1_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_MAINTENANCE_2_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_DECODE_VP9_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_QUANTIZATION_MAP_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_AV1_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INHERITED_VIEWPORT_SCISSOR_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_2_PLANE_444_FORMATS_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_INTRA_REFRESH_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_BUFFER_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FMA_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_MOTION_BLUR_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_VALIDATION_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_LINEAR_SWEPT_SPHERES_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RGBA10X6_FORMATS_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_MIN_LOD_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINEAR_COLOR_ATTACHMENT_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_BINARY_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DATA_GRAPH_NEURAL_ACCELERATOR_STATISTICS_FEATURES_ARM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_SET_HOST_MAPPING_FEATURES_VALVE, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_NESTED_COMMAND_BUFFER_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MODULE_IDENTIFIER_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_MERGE_FEEDBACK_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_OPACITY_MICROMAP_FEATURES_EXT, size() }); +#ifdef VK_ENABLE_BETA_EXTENSIONS + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISPLACEMENT_MICROMAP_FEATURES_NV, size() }); +#endif + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_PROPERTIES_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_EARLY_AND_LATE_FRAGMENT_TESTS_FEATURES_AMD, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_NON_SEAMLESS_CUBE_MAP_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_ROBUSTNESS_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_PROCESSING_FEATURES_QCOM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TILE_PROPERTIES_FEATURES_QCOM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_AMIGO_PROFILING_FEATURES_SEC, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ADDRESS_BINDING_REPORT_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_OPTICAL_FLOW_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FAULT_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FAULT_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_LIBRARY_GROUP_HANDLES_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_BUILTINS_FEATURES_ARM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAME_BOUNDARY_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_UNUSED_ATTACHMENTS_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INTERNALLY_SYNCHRONIZED_QUEUES_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_BIAS_CONTROL_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_INVOCATION_REORDER_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_INVOCATION_REORDER_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_SPARSE_ADDRESS_SPACE_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_VIEWPORTS_FEATURES_QCOM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_POSITION_FETCH_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_RENDER_AREAS_FEATURES_QCOM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TILE_IMAGE_FEATURES_EXT, size() }); +#ifdef VK_USE_PLATFORM_SCREEN_QNX + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_SCREEN_BUFFER_FEATURES_QNX, size() }); +#endif + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_CONVERSION_FEATURES_QCOM, size() }); +#ifdef VK_ENABLE_BETA_EXTENSIONS + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ENQUEUE_FEATURES_AMDX, size() }); +#endif + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ANTI_LAG_FEATURES_AMD, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TILE_MEMORY_HEAP_FEATURES_QCOM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUBIC_CLAMP_FEATURES_QCOM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_DEGAMMA_FEATURES_QCOM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUBIC_WEIGHTS_FEATURES_QCOM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_PROCESSING_2_FEATURES_QCOM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_POOL_OVERALLOCATION_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PER_STAGE_DESCRIPTOR_SET_FEATURES_NV, size() }); +#ifdef VK_USE_PLATFORM_ANDROID_KHR + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FORMAT_RESOLVE_FEATURES_ANDROID, size() }); +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUDA_KERNEL_LAUNCH_FEATURES_NV, size() }); +#endif + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCHEDULING_CONTROLS_FEATURES_ARM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RELAXED_LINE_RASTERIZATION_FEATURES_IMG, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RENDER_PASS_STRIPED_FEATURES_ARM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_OPACITY_MICROMAP_FEATURES_ARM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MAXIMAL_RECONVERGENCE_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_ROTATE_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_EXPECT_ASSUME_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT_CONTROLS_2_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_LOCAL_READ_FEATURES, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_QUAD_CONTROL_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT16_VECTOR_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_BFLOAT16_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAW_ACCESS_CHAINS_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMMAND_BUFFER_INHERITANCE_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ALIGNMENT_CONTROL_FEATURES_MESA, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_REPLICATED_COMPOSITES_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_MODE_FIFO_LATEST_READY_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_2_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HDR_VIVID_FEATURES_HUAWEI, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_ROBUSTNESS_FEATURES_EXT, size() }); +#ifdef VK_ENABLE_BETA_EXTENSIONS + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DENSE_GEOMETRY_FORMAT_FEATURES_AMDX, size() }); +#endif + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLAMP_ZERO_ONE_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_VECTOR_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TILE_SHADING_FEATURES_QCOM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_LAYERED_FEATURES_VALVE, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_METERING_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_UNIFORM_BUFFER_UNSIZED_ARRAY_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MIXED_FLOAT_DOT_PRODUCT_FEATURES_VALVE, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_RESTART_INDEX_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FORMAT_PACK_FEATURES_ARM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_THROTTLE_HINT_FEATURES_SEC, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TENSOR_FEATURES_ARM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_BUFFER_TENSOR_FEATURES_ARM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT8_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DATA_GRAPH_FEATURES_ARM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CACHE_INCREMENTAL_MODE_FEATURES_SEC, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DATA_GRAPH_MODEL_FEATURES_QCOM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_UNTYPED_POINTERS_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_RGB_CONVERSION_FEATURES_VALVE, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_64_BIT_INDEXING_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_QUEUE_PERF_HINT_FEATURES_QCOM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_COUNTERS_BY_REGION_FEATURES_ARM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_OCCUPANCY_PRIORITY_FEATURES_NV, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_LONG_VECTOR_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_3D_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_PARTITIONED_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_HEAP_FEATURES_EXT, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INSTRUMENTATION_FEATURES_ARM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_ADDRESS_COMMANDS_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CONSTANT_DATA_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ABORT_FEATURES_KHR, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DATA_GRAPH_OPTICAL_FLOW_FEATURES_ARM, size() }); + this->structureSize.insert({ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR, size() }); + + //Initializing the full list of available structure features + void* pNext = nullptr; + physicalDeviceDeviceGeneratedCommandsFeaturesNV.pNext = pNext; + pNext = &physicalDeviceDeviceGeneratedCommandsFeaturesNV; + physicalDevicePushConstantBankFeaturesNV.pNext = pNext; + pNext = &physicalDevicePushConstantBankFeaturesNV; + physicalDeviceDeviceGeneratedCommandsComputeFeaturesNV.pNext = pNext; + pNext = &physicalDeviceDeviceGeneratedCommandsComputeFeaturesNV; + physicalDevicePrivateDataFeatures.pNext = pNext; + pNext = &physicalDevicePrivateDataFeatures; + physicalDeviceClusterAccelerationStructureFeaturesNV.pNext = pNext; + pNext = &physicalDeviceClusterAccelerationStructureFeaturesNV; + physicalDeviceVariablePointersFeatures.pNext = pNext; + pNext = &physicalDeviceVariablePointersFeatures; + physicalDeviceMultiviewFeatures.pNext = pNext; + pNext = &physicalDeviceMultiviewFeatures; + physicalDevicePresentIdFeaturesKHR.pNext = pNext; + pNext = &physicalDevicePresentIdFeaturesKHR; + physicalDevicePresentId2FeaturesKHR.pNext = pNext; + pNext = &physicalDevicePresentId2FeaturesKHR; + physicalDevicePresentWaitFeaturesKHR.pNext = pNext; + pNext = &physicalDevicePresentWaitFeaturesKHR; + physicalDevicePresentWait2FeaturesKHR.pNext = pNext; + pNext = &physicalDevicePresentWait2FeaturesKHR; + physicalDevicePresentTimingFeaturesEXT.pNext = pNext; + pNext = &physicalDevicePresentTimingFeaturesEXT; + physicalDevice16BitStorageFeatures.pNext = pNext; + pNext = &physicalDevice16BitStorageFeatures; + physicalDeviceShaderSubgroupExtendedTypesFeatures.pNext = pNext; + pNext = &physicalDeviceShaderSubgroupExtendedTypesFeatures; + physicalDeviceSamplerYcbcrConversionFeatures.pNext = pNext; + pNext = &physicalDeviceSamplerYcbcrConversionFeatures; + physicalDeviceProtectedMemoryFeatures.pNext = pNext; + pNext = &physicalDeviceProtectedMemoryFeatures; + physicalDeviceBlendOperationAdvancedFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceBlendOperationAdvancedFeaturesEXT; + physicalDeviceMultiDrawFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceMultiDrawFeaturesEXT; + physicalDeviceInlineUniformBlockFeatures.pNext = pNext; + pNext = &physicalDeviceInlineUniformBlockFeatures; + physicalDeviceMaintenance4Features.pNext = pNext; + pNext = &physicalDeviceMaintenance4Features; + physicalDeviceMaintenance5Features.pNext = pNext; + pNext = &physicalDeviceMaintenance5Features; + physicalDeviceMaintenance6Features.pNext = pNext; + pNext = &physicalDeviceMaintenance6Features; + physicalDeviceMaintenance7FeaturesKHR.pNext = pNext; + pNext = &physicalDeviceMaintenance7FeaturesKHR; + physicalDeviceMaintenance8FeaturesKHR.pNext = pNext; + pNext = &physicalDeviceMaintenance8FeaturesKHR; + physicalDeviceMaintenance9FeaturesKHR.pNext = pNext; + pNext = &physicalDeviceMaintenance9FeaturesKHR; + physicalDeviceMaintenance11FeaturesKHR.pNext = pNext; + pNext = &physicalDeviceMaintenance11FeaturesKHR; + physicalDeviceMaintenance10FeaturesKHR.pNext = pNext; + pNext = &physicalDeviceMaintenance10FeaturesKHR; + physicalDeviceShaderDrawParametersFeatures.pNext = pNext; + pNext = &physicalDeviceShaderDrawParametersFeatures; + physicalDeviceShaderFloat16Int8Features.pNext = pNext; + pNext = &physicalDeviceShaderFloat16Int8Features; + physicalDeviceHostQueryResetFeatures.pNext = pNext; + pNext = &physicalDeviceHostQueryResetFeatures; + physicalDeviceGlobalPriorityQueryFeatures.pNext = pNext; + pNext = &physicalDeviceGlobalPriorityQueryFeatures; + physicalDeviceDeviceMemoryReportFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceDeviceMemoryReportFeaturesEXT; + physicalDeviceDescriptorIndexingFeatures.pNext = pNext; + pNext = &physicalDeviceDescriptorIndexingFeatures; + physicalDeviceTimelineSemaphoreFeatures.pNext = pNext; + pNext = &physicalDeviceTimelineSemaphoreFeatures; + physicalDevice8BitStorageFeatures.pNext = pNext; + pNext = &physicalDevice8BitStorageFeatures; + physicalDeviceConditionalRenderingFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceConditionalRenderingFeaturesEXT; + physicalDeviceVulkanMemoryModelFeatures.pNext = pNext; + pNext = &physicalDeviceVulkanMemoryModelFeatures; + physicalDeviceShaderAtomicInt64Features.pNext = pNext; + pNext = &physicalDeviceShaderAtomicInt64Features; + physicalDeviceShaderAtomicFloatFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceShaderAtomicFloatFeaturesEXT; + physicalDeviceShaderAtomicFloat2FeaturesEXT.pNext = pNext; + pNext = &physicalDeviceShaderAtomicFloat2FeaturesEXT; + physicalDeviceVertexAttributeDivisorFeatures.pNext = pNext; + pNext = &physicalDeviceVertexAttributeDivisorFeatures; + physicalDeviceASTCDecodeFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceASTCDecodeFeaturesEXT; + physicalDeviceTransformFeedbackFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceTransformFeedbackFeaturesEXT; + physicalDeviceRepresentativeFragmentTestFeaturesNV.pNext = pNext; + pNext = &physicalDeviceRepresentativeFragmentTestFeaturesNV; + physicalDeviceExclusiveScissorFeaturesNV.pNext = pNext; + pNext = &physicalDeviceExclusiveScissorFeaturesNV; + physicalDeviceCornerSampledImageFeaturesNV.pNext = pNext; + pNext = &physicalDeviceCornerSampledImageFeaturesNV; + physicalDeviceComputeShaderDerivativesFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceComputeShaderDerivativesFeaturesKHR; + physicalDeviceShaderImageFootprintFeaturesNV.pNext = pNext; + pNext = &physicalDeviceShaderImageFootprintFeaturesNV; + physicalDeviceDedicatedAllocationImageAliasingFeaturesNV.pNext = pNext; + pNext = &physicalDeviceDedicatedAllocationImageAliasingFeaturesNV; + physicalDeviceCopyMemoryIndirectFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceCopyMemoryIndirectFeaturesKHR; + physicalDeviceCopyMemoryIndirectFeaturesNV.pNext = pNext; + pNext = &physicalDeviceCopyMemoryIndirectFeaturesNV; + physicalDeviceMemoryDecompressionFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceMemoryDecompressionFeaturesEXT; + physicalDeviceShadingRateImageFeaturesNV.pNext = pNext; + pNext = &physicalDeviceShadingRateImageFeaturesNV; + physicalDeviceInvocationMaskFeaturesHUAWEI.pNext = pNext; + pNext = &physicalDeviceInvocationMaskFeaturesHUAWEI; + physicalDeviceMeshShaderFeaturesNV.pNext = pNext; + pNext = &physicalDeviceMeshShaderFeaturesNV; + physicalDeviceMeshShaderFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceMeshShaderFeaturesEXT; + physicalDeviceAccelerationStructureFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceAccelerationStructureFeaturesKHR; + physicalDeviceRayTracingPipelineFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceRayTracingPipelineFeaturesKHR; + physicalDeviceRayQueryFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceRayQueryFeaturesKHR; + physicalDeviceRayTracingMaintenance1FeaturesKHR.pNext = pNext; + pNext = &physicalDeviceRayTracingMaintenance1FeaturesKHR; + physicalDeviceFragmentDensityMapFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceFragmentDensityMapFeaturesEXT; + physicalDeviceFragmentDensityMap2FeaturesEXT.pNext = pNext; + pNext = &physicalDeviceFragmentDensityMap2FeaturesEXT; + physicalDeviceFragmentDensityMapOffsetFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceFragmentDensityMapOffsetFeaturesEXT; + physicalDeviceScalarBlockLayoutFeatures.pNext = pNext; + pNext = &physicalDeviceScalarBlockLayoutFeatures; + physicalDeviceUniformBufferStandardLayoutFeatures.pNext = pNext; + pNext = &physicalDeviceUniformBufferStandardLayoutFeatures; + physicalDeviceDepthClipEnableFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceDepthClipEnableFeaturesEXT; + physicalDeviceMemoryPriorityFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceMemoryPriorityFeaturesEXT; + physicalDevicePageableDeviceLocalMemoryFeaturesEXT.pNext = pNext; + pNext = &physicalDevicePageableDeviceLocalMemoryFeaturesEXT; + physicalDeviceBufferDeviceAddressFeatures.pNext = pNext; + pNext = &physicalDeviceBufferDeviceAddressFeatures; + physicalDeviceBufferDeviceAddressFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceBufferDeviceAddressFeaturesEXT; + physicalDeviceImagelessFramebufferFeatures.pNext = pNext; + pNext = &physicalDeviceImagelessFramebufferFeatures; + physicalDeviceTextureCompressionASTCHDRFeatures.pNext = pNext; + pNext = &physicalDeviceTextureCompressionASTCHDRFeatures; + physicalDeviceCooperativeMatrixFeaturesNV.pNext = pNext; + pNext = &physicalDeviceCooperativeMatrixFeaturesNV; + physicalDeviceYcbcrImageArraysFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceYcbcrImageArraysFeaturesEXT; + physicalDevicePresentBarrierFeaturesNV.pNext = pNext; + pNext = &physicalDevicePresentBarrierFeaturesNV; + physicalDevicePerformanceQueryFeaturesKHR.pNext = pNext; + pNext = &physicalDevicePerformanceQueryFeaturesKHR; + physicalDeviceCoverageReductionModeFeaturesNV.pNext = pNext; + pNext = &physicalDeviceCoverageReductionModeFeaturesNV; + physicalDeviceShaderIntegerFunctions2FeaturesINTEL.pNext = pNext; + pNext = &physicalDeviceShaderIntegerFunctions2FeaturesINTEL; + physicalDeviceShaderClockFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceShaderClockFeaturesKHR; + physicalDeviceIndexTypeUint8Features.pNext = pNext; + pNext = &physicalDeviceIndexTypeUint8Features; + physicalDeviceShaderSMBuiltinsFeaturesNV.pNext = pNext; + pNext = &physicalDeviceShaderSMBuiltinsFeaturesNV; + physicalDeviceFragmentShaderInterlockFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceFragmentShaderInterlockFeaturesEXT; + physicalDeviceSeparateDepthStencilLayoutsFeatures.pNext = pNext; + pNext = &physicalDeviceSeparateDepthStencilLayoutsFeatures; + physicalDevicePrimitiveTopologyListRestartFeaturesEXT.pNext = pNext; + pNext = &physicalDevicePrimitiveTopologyListRestartFeaturesEXT; + physicalDevicePipelineExecutablePropertiesFeaturesKHR.pNext = pNext; + pNext = &physicalDevicePipelineExecutablePropertiesFeaturesKHR; + physicalDeviceShaderDemoteToHelperInvocationFeatures.pNext = pNext; + pNext = &physicalDeviceShaderDemoteToHelperInvocationFeatures; + physicalDeviceTexelBufferAlignmentFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceTexelBufferAlignmentFeaturesEXT; + physicalDeviceSubgroupSizeControlFeatures.pNext = pNext; + pNext = &physicalDeviceSubgroupSizeControlFeatures; + physicalDeviceLineRasterizationFeatures.pNext = pNext; + pNext = &physicalDeviceLineRasterizationFeatures; + physicalDevicePipelineCreationCacheControlFeatures.pNext = pNext; + pNext = &physicalDevicePipelineCreationCacheControlFeatures; + physicalDeviceVulkan11Features.pNext = pNext; + pNext = &physicalDeviceVulkan11Features; + physicalDeviceVulkan12Features.pNext = pNext; + pNext = &physicalDeviceVulkan12Features; + physicalDeviceVulkan13Features.pNext = pNext; + pNext = &physicalDeviceVulkan13Features; + physicalDeviceVulkan14Features.pNext = pNext; + pNext = &physicalDeviceVulkan14Features; + physicalDeviceCoherentMemoryFeaturesAMD.pNext = pNext; + pNext = &physicalDeviceCoherentMemoryFeaturesAMD; + physicalDeviceCustomBorderColorFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceCustomBorderColorFeaturesEXT; + physicalDeviceBorderColorSwizzleFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceBorderColorSwizzleFeaturesEXT; + physicalDeviceExtendedDynamicStateFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceExtendedDynamicStateFeaturesEXT; + physicalDeviceExtendedDynamicState2FeaturesEXT.pNext = pNext; + pNext = &physicalDeviceExtendedDynamicState2FeaturesEXT; + physicalDeviceExtendedDynamicState3FeaturesEXT.pNext = pNext; + pNext = &physicalDeviceExtendedDynamicState3FeaturesEXT; + physicalDevicePartitionedAccelerationStructureFeaturesNV.pNext = pNext; + pNext = &physicalDevicePartitionedAccelerationStructureFeaturesNV; + physicalDeviceDiagnosticsConfigFeaturesNV.pNext = pNext; + pNext = &physicalDeviceDiagnosticsConfigFeaturesNV; + physicalDeviceZeroInitializeWorkgroupMemoryFeatures.pNext = pNext; + pNext = &physicalDeviceZeroInitializeWorkgroupMemoryFeatures; + physicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR; + physicalDeviceRobustness2FeaturesKHR.pNext = pNext; + pNext = &physicalDeviceRobustness2FeaturesKHR; + physicalDeviceImageRobustnessFeatures.pNext = pNext; + pNext = &physicalDeviceImageRobustnessFeatures; + physicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR; +#ifdef VK_ENABLE_BETA_EXTENSIONS + physicalDevicePortabilitySubsetFeaturesKHR.pNext = pNext; + pNext = &physicalDevicePortabilitySubsetFeaturesKHR; +#endif + physicalDevice4444FormatsFeaturesEXT.pNext = pNext; + pNext = &physicalDevice4444FormatsFeaturesEXT; + physicalDeviceSubpassShadingFeaturesHUAWEI.pNext = pNext; + pNext = &physicalDeviceSubpassShadingFeaturesHUAWEI; + physicalDeviceClusterCullingShaderFeaturesHUAWEI.pNext = pNext; + pNext = &physicalDeviceClusterCullingShaderFeaturesHUAWEI; + physicalDeviceShaderImageAtomicInt64FeaturesEXT.pNext = pNext; + pNext = &physicalDeviceShaderImageAtomicInt64FeaturesEXT; + physicalDeviceFragmentShadingRateFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceFragmentShadingRateFeaturesKHR; + physicalDeviceShaderTerminateInvocationFeatures.pNext = pNext; + pNext = &physicalDeviceShaderTerminateInvocationFeatures; + physicalDeviceFragmentShadingRateEnumsFeaturesNV.pNext = pNext; + pNext = &physicalDeviceFragmentShadingRateEnumsFeaturesNV; + physicalDeviceImage2DViewOf3DFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceImage2DViewOf3DFeaturesEXT; + physicalDeviceImageSlicedViewOf3DFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceImageSlicedViewOf3DFeaturesEXT; + physicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT; + physicalDeviceLegacyVertexAttributesFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceLegacyVertexAttributesFeaturesEXT; + physicalDeviceMutableDescriptorTypeFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceMutableDescriptorTypeFeaturesEXT; + physicalDeviceDepthClipControlFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceDepthClipControlFeaturesEXT; + physicalDeviceZeroInitializeDeviceMemoryFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceZeroInitializeDeviceMemoryFeaturesEXT; + physicalDeviceCustomResolveFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceCustomResolveFeaturesEXT; + physicalDeviceDeviceGeneratedCommandsFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceDeviceGeneratedCommandsFeaturesEXT; + physicalDeviceDepthClampControlFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceDepthClampControlFeaturesEXT; + physicalDeviceVertexInputDynamicStateFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceVertexInputDynamicStateFeaturesEXT; + physicalDeviceExternalMemoryRDMAFeaturesNV.pNext = pNext; + pNext = &physicalDeviceExternalMemoryRDMAFeaturesNV; + physicalDeviceShaderRelaxedExtendedInstructionFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceShaderRelaxedExtendedInstructionFeaturesKHR; + physicalDeviceColorWriteEnableFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceColorWriteEnableFeaturesEXT; + physicalDeviceSynchronization2Features.pNext = pNext; + pNext = &physicalDeviceSynchronization2Features; + physicalDeviceUnifiedImageLayoutsFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceUnifiedImageLayoutsFeaturesKHR; + physicalDeviceHostImageCopyFeatures.pNext = pNext; + pNext = &physicalDeviceHostImageCopyFeatures; + physicalDevicePrimitivesGeneratedQueryFeaturesEXT.pNext = pNext; + pNext = &physicalDevicePrimitivesGeneratedQueryFeaturesEXT; + physicalDeviceLegacyDitheringFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceLegacyDitheringFeaturesEXT; + physicalDeviceMultisampledRenderToSingleSampledFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceMultisampledRenderToSingleSampledFeaturesEXT; + physicalDevicePipelineProtectedAccessFeatures.pNext = pNext; + pNext = &physicalDevicePipelineProtectedAccessFeatures; + physicalDeviceVideoMaintenance1FeaturesKHR.pNext = pNext; + pNext = &physicalDeviceVideoMaintenance1FeaturesKHR; + physicalDeviceVideoMaintenance2FeaturesKHR.pNext = pNext; + pNext = &physicalDeviceVideoMaintenance2FeaturesKHR; + physicalDeviceVideoDecodeVP9FeaturesKHR.pNext = pNext; + pNext = &physicalDeviceVideoDecodeVP9FeaturesKHR; + physicalDeviceVideoEncodeQuantizationMapFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceVideoEncodeQuantizationMapFeaturesKHR; + physicalDeviceVideoEncodeAV1FeaturesKHR.pNext = pNext; + pNext = &physicalDeviceVideoEncodeAV1FeaturesKHR; + physicalDeviceInheritedViewportScissorFeaturesNV.pNext = pNext; + pNext = &physicalDeviceInheritedViewportScissorFeaturesNV; + physicalDeviceYcbcr2Plane444FormatsFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceYcbcr2Plane444FormatsFeaturesEXT; + physicalDeviceProvokingVertexFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceProvokingVertexFeaturesEXT; + physicalDeviceVideoEncodeIntraRefreshFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceVideoEncodeIntraRefreshFeaturesKHR; + physicalDeviceDescriptorBufferFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceDescriptorBufferFeaturesEXT; + physicalDeviceShaderIntegerDotProductFeatures.pNext = pNext; + pNext = &physicalDeviceShaderIntegerDotProductFeatures; + physicalDeviceFragmentShaderBarycentricFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceFragmentShaderBarycentricFeaturesKHR; + physicalDeviceShaderFmaFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceShaderFmaFeaturesKHR; + physicalDeviceRayTracingMotionBlurFeaturesNV.pNext = pNext; + pNext = &physicalDeviceRayTracingMotionBlurFeaturesNV; + physicalDeviceRayTracingValidationFeaturesNV.pNext = pNext; + pNext = &physicalDeviceRayTracingValidationFeaturesNV; + physicalDeviceRayTracingLinearSweptSpheresFeaturesNV.pNext = pNext; + pNext = &physicalDeviceRayTracingLinearSweptSpheresFeaturesNV; + physicalDeviceRGBA10X6FormatsFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceRGBA10X6FormatsFeaturesEXT; + physicalDeviceDynamicRenderingFeatures.pNext = pNext; + pNext = &physicalDeviceDynamicRenderingFeatures; + physicalDeviceImageViewMinLodFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceImageViewMinLodFeaturesEXT; + physicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT; + physicalDeviceLinearColorAttachmentFeaturesNV.pNext = pNext; + pNext = &physicalDeviceLinearColorAttachmentFeaturesNV; + physicalDeviceGraphicsPipelineLibraryFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceGraphicsPipelineLibraryFeaturesEXT; + physicalDevicePipelineBinaryFeaturesKHR.pNext = pNext; + pNext = &physicalDevicePipelineBinaryFeaturesKHR; + physicalDeviceDataGraphNeuralAcceleratorStatisticsFeaturesARM.pNext = pNext; + pNext = &physicalDeviceDataGraphNeuralAcceleratorStatisticsFeaturesARM; + physicalDeviceDescriptorSetHostMappingFeaturesVALVE.pNext = pNext; + pNext = &physicalDeviceDescriptorSetHostMappingFeaturesVALVE; + physicalDeviceNestedCommandBufferFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceNestedCommandBufferFeaturesEXT; + physicalDeviceShaderModuleIdentifierFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceShaderModuleIdentifierFeaturesEXT; + physicalDeviceImageCompressionControlFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceImageCompressionControlFeaturesEXT; + physicalDeviceImageCompressionControlSwapchainFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceImageCompressionControlSwapchainFeaturesEXT; + physicalDeviceSubpassMergeFeedbackFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceSubpassMergeFeedbackFeaturesEXT; + physicalDeviceOpacityMicromapFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceOpacityMicromapFeaturesEXT; +#ifdef VK_ENABLE_BETA_EXTENSIONS + physicalDeviceDisplacementMicromapFeaturesNV.pNext = pNext; + pNext = &physicalDeviceDisplacementMicromapFeaturesNV; +#endif + physicalDevicePipelinePropertiesFeaturesEXT.pNext = pNext; + pNext = &physicalDevicePipelinePropertiesFeaturesEXT; + physicalDeviceShaderEarlyAndLateFragmentTestsFeaturesAMD.pNext = pNext; + pNext = &physicalDeviceShaderEarlyAndLateFragmentTestsFeaturesAMD; + physicalDeviceNonSeamlessCubeMapFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceNonSeamlessCubeMapFeaturesEXT; + physicalDevicePipelineRobustnessFeatures.pNext = pNext; + pNext = &physicalDevicePipelineRobustnessFeatures; + physicalDeviceImageProcessingFeaturesQCOM.pNext = pNext; + pNext = &physicalDeviceImageProcessingFeaturesQCOM; + physicalDeviceTilePropertiesFeaturesQCOM.pNext = pNext; + pNext = &physicalDeviceTilePropertiesFeaturesQCOM; + physicalDeviceAmigoProfilingFeaturesSEC.pNext = pNext; + pNext = &physicalDeviceAmigoProfilingFeaturesSEC; + physicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT; + physicalDeviceAddressBindingReportFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceAddressBindingReportFeaturesEXT; + physicalDeviceOpticalFlowFeaturesNV.pNext = pNext; + pNext = &physicalDeviceOpticalFlowFeaturesNV; + physicalDeviceFaultFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceFaultFeaturesEXT; + physicalDeviceFaultFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceFaultFeaturesKHR; + physicalDevicePipelineLibraryGroupHandlesFeaturesEXT.pNext = pNext; + pNext = &physicalDevicePipelineLibraryGroupHandlesFeaturesEXT; + physicalDeviceShaderCoreBuiltinsFeaturesARM.pNext = pNext; + pNext = &physicalDeviceShaderCoreBuiltinsFeaturesARM; + physicalDeviceFrameBoundaryFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceFrameBoundaryFeaturesEXT; + physicalDeviceDynamicRenderingUnusedAttachmentsFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceDynamicRenderingUnusedAttachmentsFeaturesEXT; + physicalDeviceInternallySynchronizedQueuesFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceInternallySynchronizedQueuesFeaturesKHR; + physicalDeviceSwapchainMaintenance1FeaturesKHR.pNext = pNext; + pNext = &physicalDeviceSwapchainMaintenance1FeaturesKHR; + physicalDeviceDepthBiasControlFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceDepthBiasControlFeaturesEXT; + physicalDeviceRayTracingInvocationReorderFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceRayTracingInvocationReorderFeaturesEXT; + physicalDeviceRayTracingInvocationReorderFeaturesNV.pNext = pNext; + pNext = &physicalDeviceRayTracingInvocationReorderFeaturesNV; + physicalDeviceExtendedSparseAddressSpaceFeaturesNV.pNext = pNext; + pNext = &physicalDeviceExtendedSparseAddressSpaceFeaturesNV; + physicalDeviceMultiviewPerViewViewportsFeaturesQCOM.pNext = pNext; + pNext = &physicalDeviceMultiviewPerViewViewportsFeaturesQCOM; + physicalDeviceRayTracingPositionFetchFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceRayTracingPositionFetchFeaturesKHR; + physicalDeviceMultiviewPerViewRenderAreasFeaturesQCOM.pNext = pNext; + pNext = &physicalDeviceMultiviewPerViewRenderAreasFeaturesQCOM; + physicalDeviceShaderObjectFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceShaderObjectFeaturesEXT; + physicalDeviceShaderTileImageFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceShaderTileImageFeaturesEXT; +#ifdef VK_USE_PLATFORM_SCREEN_QNX + physicalDeviceExternalMemoryScreenBufferFeaturesQNX.pNext = pNext; + pNext = &physicalDeviceExternalMemoryScreenBufferFeaturesQNX; +#endif + physicalDeviceCooperativeMatrixFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceCooperativeMatrixFeaturesKHR; + physicalDeviceCooperativeMatrixConversionFeaturesQCOM.pNext = pNext; + pNext = &physicalDeviceCooperativeMatrixConversionFeaturesQCOM; +#ifdef VK_ENABLE_BETA_EXTENSIONS + physicalDeviceShaderEnqueueFeaturesAMDX.pNext = pNext; + pNext = &physicalDeviceShaderEnqueueFeaturesAMDX; +#endif + physicalDeviceAntiLagFeaturesAMD.pNext = pNext; + pNext = &physicalDeviceAntiLagFeaturesAMD; + physicalDeviceTileMemoryHeapFeaturesQCOM.pNext = pNext; + pNext = &physicalDeviceTileMemoryHeapFeaturesQCOM; + physicalDeviceCubicClampFeaturesQCOM.pNext = pNext; + pNext = &physicalDeviceCubicClampFeaturesQCOM; + physicalDeviceYcbcrDegammaFeaturesQCOM.pNext = pNext; + pNext = &physicalDeviceYcbcrDegammaFeaturesQCOM; + physicalDeviceCubicWeightsFeaturesQCOM.pNext = pNext; + pNext = &physicalDeviceCubicWeightsFeaturesQCOM; + physicalDeviceImageProcessing2FeaturesQCOM.pNext = pNext; + pNext = &physicalDeviceImageProcessing2FeaturesQCOM; + physicalDeviceDescriptorPoolOverallocationFeaturesNV.pNext = pNext; + pNext = &physicalDeviceDescriptorPoolOverallocationFeaturesNV; + physicalDevicePerStageDescriptorSetFeaturesNV.pNext = pNext; + pNext = &physicalDevicePerStageDescriptorSetFeaturesNV; +#ifdef VK_USE_PLATFORM_ANDROID_KHR + physicalDeviceExternalFormatResolveFeaturesANDROID.pNext = pNext; + pNext = &physicalDeviceExternalFormatResolveFeaturesANDROID; +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + physicalDeviceCudaKernelLaunchFeaturesNV.pNext = pNext; + pNext = &physicalDeviceCudaKernelLaunchFeaturesNV; +#endif + physicalDeviceSchedulingControlsFeaturesARM.pNext = pNext; + pNext = &physicalDeviceSchedulingControlsFeaturesARM; + physicalDeviceRelaxedLineRasterizationFeaturesIMG.pNext = pNext; + pNext = &physicalDeviceRelaxedLineRasterizationFeaturesIMG; + physicalDeviceRenderPassStripedFeaturesARM.pNext = pNext; + pNext = &physicalDeviceRenderPassStripedFeaturesARM; + physicalDevicePipelineOpacityMicromapFeaturesARM.pNext = pNext; + pNext = &physicalDevicePipelineOpacityMicromapFeaturesARM; + physicalDeviceShaderMaximalReconvergenceFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceShaderMaximalReconvergenceFeaturesKHR; + physicalDeviceShaderSubgroupRotateFeatures.pNext = pNext; + pNext = &physicalDeviceShaderSubgroupRotateFeatures; + physicalDeviceShaderExpectAssumeFeatures.pNext = pNext; + pNext = &physicalDeviceShaderExpectAssumeFeatures; + physicalDeviceShaderFloatControls2Features.pNext = pNext; + pNext = &physicalDeviceShaderFloatControls2Features; + physicalDeviceDynamicRenderingLocalReadFeatures.pNext = pNext; + pNext = &physicalDeviceDynamicRenderingLocalReadFeatures; + physicalDeviceShaderQuadControlFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceShaderQuadControlFeaturesKHR; + physicalDeviceShaderAtomicFloat16VectorFeaturesNV.pNext = pNext; + pNext = &physicalDeviceShaderAtomicFloat16VectorFeaturesNV; + physicalDeviceMapMemoryPlacedFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceMapMemoryPlacedFeaturesEXT; + physicalDeviceShaderBfloat16FeaturesKHR.pNext = pNext; + pNext = &physicalDeviceShaderBfloat16FeaturesKHR; + physicalDeviceRawAccessChainsFeaturesNV.pNext = pNext; + pNext = &physicalDeviceRawAccessChainsFeaturesNV; + physicalDeviceCommandBufferInheritanceFeaturesNV.pNext = pNext; + pNext = &physicalDeviceCommandBufferInheritanceFeaturesNV; + physicalDeviceImageAlignmentControlFeaturesMESA.pNext = pNext; + pNext = &physicalDeviceImageAlignmentControlFeaturesMESA; + physicalDeviceShaderReplicatedCompositesFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceShaderReplicatedCompositesFeaturesEXT; + physicalDevicePresentModeFifoLatestReadyFeaturesKHR.pNext = pNext; + pNext = &physicalDevicePresentModeFifoLatestReadyFeaturesKHR; + physicalDeviceCooperativeMatrix2FeaturesNV.pNext = pNext; + pNext = &physicalDeviceCooperativeMatrix2FeaturesNV; + physicalDeviceHdrVividFeaturesHUAWEI.pNext = pNext; + pNext = &physicalDeviceHdrVividFeaturesHUAWEI; + physicalDeviceVertexAttributeRobustnessFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceVertexAttributeRobustnessFeaturesEXT; +#ifdef VK_ENABLE_BETA_EXTENSIONS + physicalDeviceDenseGeometryFormatFeaturesAMDX.pNext = pNext; + pNext = &physicalDeviceDenseGeometryFormatFeaturesAMDX; +#endif + physicalDeviceDepthClampZeroOneFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceDepthClampZeroOneFeaturesKHR; + physicalDeviceCooperativeVectorFeaturesNV.pNext = pNext; + pNext = &physicalDeviceCooperativeVectorFeaturesNV; + physicalDeviceTileShadingFeaturesQCOM.pNext = pNext; + pNext = &physicalDeviceTileShadingFeaturesQCOM; + physicalDeviceFragmentDensityMapLayeredFeaturesVALVE.pNext = pNext; + pNext = &physicalDeviceFragmentDensityMapLayeredFeaturesVALVE; + physicalDevicePresentMeteringFeaturesNV.pNext = pNext; + pNext = &physicalDevicePresentMeteringFeaturesNV; + physicalDeviceShaderUniformBufferUnsizedArrayFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceShaderUniformBufferUnsizedArrayFeaturesEXT; + physicalDeviceShaderMixedFloatDotProductFeaturesVALVE.pNext = pNext; + pNext = &physicalDeviceShaderMixedFloatDotProductFeaturesVALVE; + physicalDevicePrimitiveRestartIndexFeaturesEXT.pNext = pNext; + pNext = &physicalDevicePrimitiveRestartIndexFeaturesEXT; + physicalDeviceFormatPackFeaturesARM.pNext = pNext; + pNext = &physicalDeviceFormatPackFeaturesARM; + physicalDeviceThrottleHintFeaturesSEC.pNext = pNext; + pNext = &physicalDeviceThrottleHintFeaturesSEC; + physicalDeviceTensorFeaturesARM.pNext = pNext; + pNext = &physicalDeviceTensorFeaturesARM; + physicalDeviceDescriptorBufferTensorFeaturesARM.pNext = pNext; + pNext = &physicalDeviceDescriptorBufferTensorFeaturesARM; + physicalDeviceShaderFloat8FeaturesEXT.pNext = pNext; + pNext = &physicalDeviceShaderFloat8FeaturesEXT; + physicalDeviceDataGraphFeaturesARM.pNext = pNext; + pNext = &physicalDeviceDataGraphFeaturesARM; + physicalDevicePipelineCacheIncrementalModeFeaturesSEC.pNext = pNext; + pNext = &physicalDevicePipelineCacheIncrementalModeFeaturesSEC; + physicalDeviceDataGraphModelFeaturesQCOM.pNext = pNext; + pNext = &physicalDeviceDataGraphModelFeaturesQCOM; + physicalDeviceShaderUntypedPointersFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceShaderUntypedPointersFeaturesKHR; + physicalDeviceVideoEncodeRgbConversionFeaturesVALVE.pNext = pNext; + pNext = &physicalDeviceVideoEncodeRgbConversionFeaturesVALVE; + physicalDeviceShader64BitIndexingFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceShader64BitIndexingFeaturesEXT; + physicalDeviceQueuePerfHintFeaturesQCOM.pNext = pNext; + pNext = &physicalDeviceQueuePerfHintFeaturesQCOM; + physicalDevicePerformanceCountersByRegionFeaturesARM.pNext = pNext; + pNext = &physicalDevicePerformanceCountersByRegionFeaturesARM; + physicalDeviceComputeOccupancyPriorityFeaturesNV.pNext = pNext; + pNext = &physicalDeviceComputeOccupancyPriorityFeaturesNV; + physicalDeviceShaderLongVectorFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceShaderLongVectorFeaturesEXT; + physicalDeviceTextureCompressionASTC3DFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceTextureCompressionASTC3DFeaturesEXT; + physicalDeviceShaderSubgroupPartitionedFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceShaderSubgroupPartitionedFeaturesEXT; + physicalDeviceDescriptorHeapFeaturesEXT.pNext = pNext; + pNext = &physicalDeviceDescriptorHeapFeaturesEXT; + physicalDeviceShaderInstrumentationFeaturesARM.pNext = pNext; + pNext = &physicalDeviceShaderInstrumentationFeaturesARM; + physicalDeviceDeviceAddressCommandsFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceDeviceAddressCommandsFeaturesKHR; + physicalDeviceShaderConstantDataFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceShaderConstantDataFeaturesKHR; + physicalDeviceShaderAbortFeaturesKHR.pNext = pNext; + pNext = &physicalDeviceShaderAbortFeaturesKHR; + physicalDeviceDataGraphOpticalFlowFeaturesARM.pNext = pNext; + pNext = &physicalDeviceDataGraphOpticalFlowFeaturesARM; + physicalDeviceFeatures2KHR.pNext = pNext; + + } + + + VkPhysicalDeviceFeatures2KHR requiredFeaturesChain{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR, nullptr}; + VkBaseOutStructure* current = nullptr; + + void ApplyRobustness(const VpDeviceCreateInfo* pCreateInfo) { +#ifdef VK_VERSION_1_1 + VkPhysicalDeviceFeatures2KHR* pFeatures2 = static_cast( + vpGetStructure(&this->requiredFeaturesChain, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR)); + if (pFeatures2 != nullptr && (pCreateInfo->flags & VP_DEVICE_CREATE_DISABLE_ROBUST_BUFFER_ACCESS_BIT)) { + pFeatures2->features.robustBufferAccess = VK_FALSE; + } +#endif + +#ifdef VK_EXT_robustness2 + VkPhysicalDeviceRobustness2FeaturesEXT* pRobustness2FeaturesEXT = static_cast( + vpGetStructure(&this->requiredFeaturesChain, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT)); + if (pRobustness2FeaturesEXT != nullptr) { + if (pCreateInfo->flags & VP_DEVICE_CREATE_DISABLE_ROBUST_BUFFER_ACCESS_BIT) { + pRobustness2FeaturesEXT->robustBufferAccess2 = VK_FALSE; + } + if (pCreateInfo->flags & VP_DEVICE_CREATE_DISABLE_ROBUST_IMAGE_ACCESS_BIT) { + pRobustness2FeaturesEXT->robustImageAccess2 = VK_FALSE; + } + } +#endif +#ifdef VK_EXT_image_robustness + VkPhysicalDeviceImageRobustnessFeaturesEXT* pImageRobustnessFeaturesEXT = + static_cast(vpGetStructure( + &this->requiredFeaturesChain, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES_EXT)); + if (pImageRobustnessFeaturesEXT != nullptr && (pCreateInfo->flags & VP_DEVICE_CREATE_DISABLE_ROBUST_IMAGE_ACCESS_BIT)) { + pImageRobustnessFeaturesEXT->robustImageAccess = VK_FALSE; + } +#endif +#ifdef VK_VERSION_1_3 + VkPhysicalDeviceVulkan13Features* pVulkan13Features = static_cast( + vpGetStructure(&this->requiredFeaturesChain, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES)); + if (pVulkan13Features != nullptr && (pCreateInfo->flags & VP_DEVICE_CREATE_DISABLE_ROBUST_IMAGE_ACCESS_BIT)) { + pVulkan13Features->robustImageAccess = VK_FALSE; + } +#endif + } + + void ApplyFeatures(const VpDeviceCreateInfo* pCreateInfo) { + const std::size_t offset = sizeof(VkBaseOutStructure); + const VkBaseOutStructure* q = reinterpret_cast(pCreateInfo->pCreateInfo->pNext); + while (q) { + const std::size_t count = this->structureSize[q->sType]; + for (std::size_t index = 0; index < count; ++index) { + const VkBaseOutStructure* pInputStruct = reinterpret_cast(q); + VkBaseOutStructure* pOutputStruct = reinterpret_cast(detail::vpGetStructure(&this->requiredFeaturesChain, q->sType)); + const uint8_t* pInputData = reinterpret_cast(pInputStruct) + offset; + uint8_t* pOutputData = reinterpret_cast(pOutputStruct) + offset; + const VkBool32* input = reinterpret_cast(pInputData); + VkBool32* output = reinterpret_cast(pOutputData); + + output[index] = (output[index] == VK_TRUE || input[index] == VK_TRUE) ? VK_TRUE : VK_FALSE; + } + q = q->pNext; + } + + this->ApplyRobustness(pCreateInfo); + } + + void PushBack(VkBaseOutStructure* found) { + VkBaseOutStructure* last = reinterpret_cast(&requiredFeaturesChain); + while (last->pNext != nullptr) { + last = last->pNext; + } + last->pNext = found; + } + + void Build(const std::vector& requiredList) { + for (std::size_t i = 0, n = requiredList.size(); i < n; ++i) { + const VkStructureType sType = requiredList[i]; + if (sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR) { + continue; + } + + VkBaseOutStructure* found = vpExtractStructure(&physicalDeviceFeatures2KHR, sType); + if (found == nullptr) { + continue; + } + + PushBack(found); + } + } +}; // struct FeaturesChain + +VPAPI_ATTR const VpProfileDesc* vpGetProfileDesc(const char profileName[VP_MAX_PROFILE_NAME_SIZE]) { + for (uint32_t profileIndex = 0; profileIndex < profileCount; ++profileIndex) { + if (strncmp(profiles[profileIndex].props.profileName, profileName, VP_MAX_PROFILE_NAME_SIZE) == 0) { + return &profiles[profileIndex]; + } + } + return nullptr; +} + +VPAPI_ATTR std::vector GatherProfiles(const VpProfileProperties& profile, const char* pBlockName = nullptr) { + std::vector gatheredProfiles; + + if (pBlockName == nullptr) { + const detail::VpProfileDesc* profileDesc = detail::vpGetProfileDesc(profile.profileName); + if (profileDesc != nullptr) { + for (uint32_t profileIndex = 0; profileIndex < profileDesc->requiredProfileCount; ++profileIndex) { + gatheredProfiles.push_back(profileDesc->pRequiredProfiles[profileIndex]); + } + } + } + + gatheredProfiles.push_back(profile); + + return gatheredProfiles; +} + +VPAPI_ATTR bool vpCheckVersion(uint32_t actual, uint32_t expected) { + uint32_t actualMajor = VK_API_VERSION_MAJOR(actual); + uint32_t actualMinor = VK_API_VERSION_MINOR(actual); + uint32_t expectedMajor = VK_API_VERSION_MAJOR(expected); + uint32_t expectedMinor = VK_API_VERSION_MINOR(expected); + return actualMajor > expectedMajor || (actualMajor == expectedMajor && actualMinor >= expectedMinor); +} + +VPAPI_ATTR bool HasExtension(const std::vector& list, const VkExtensionProperties& element) { + for (std::size_t i = 0, n = list.size(); i < n; ++i) { + if (strcmp(list[i].extensionName, element.extensionName) == 0) { + return true; + } + } + + return false; +} + +VPAPI_ATTR bool CheckExtension(const VkExtensionProperties* supportedProperties, size_t supportedSize, const char *requestedExtension) { + bool found = false; + for (size_t i = 0, n = supportedSize; i < n; ++i) { + if (strcmp(supportedProperties[i].extensionName, requestedExtension) == 0) { + found = true; + break; + // Drivers don't actually update their spec version, so we cannot rely on this + // if (supportedProperties[i].specVersion >= expectedVersion) found = true; + } + } + return found; +} + +VPAPI_ATTR bool CheckExtension(const std::vector& extensions, const char* extension) { + for (const char* c : extensions) { + if (strcmp(c, extension) == 0) { + return true; + } + } + return false; +} + +VPAPI_ATTR void GetExtensions(uint32_t extensionCount, const VkExtensionProperties *pExtensions, std::vector &extensions) { + for (uint32_t ext_index = 0; ext_index < extensionCount; ++ext_index) { + if (CheckExtension(extensions, pExtensions[ext_index].extensionName)) { + continue; + } + extensions.push_back(pExtensions[ext_index].extensionName); + } +} + +VPAPI_ATTR std::vector GatherBlocks( + uint32_t enabledFullProfileCount, const VpProfileProperties* pEnabledFullProfiles, + uint32_t enabledProfileBlockCount, const VpBlockProperties* pEnabledProfileBlocks) { + std::vector results; + + for (std::size_t profile_index = 0; profile_index < enabledFullProfileCount; ++profile_index) { + const std::vector& gathered_profiles = GatherProfiles(pEnabledFullProfiles[profile_index]); + + for (std::size_t gathered_index = 0; gathered_index < gathered_profiles.size(); ++gathered_index) { + VpBlockProperties block{gathered_profiles[gathered_index], 0, ""}; + results.push_back(block); + } + } + + for (std::size_t block_index = 0; block_index < enabledProfileBlockCount; ++block_index) { + results.push_back(pEnabledProfileBlocks[block_index]); + } + + return results; +} + +VPAPI_ATTR VkResult vpGetInstanceProfileSupportSingleProfile( + uint32_t api_version, + const std::vector& supported_extensions, + const VpProfileProperties* pProfile, + VkBool32* pSupported, + std::vector& supportedBlocks, + std::vector& unsupportedBlocks) { + assert(pProfile != nullptr); + + const detail::VpProfileDesc* pProfileDesc = vpGetProfileDesc(pProfile->profileName); + if (pProfileDesc == nullptr) { + *pSupported = VK_FALSE; + return VK_ERROR_UNKNOWN; + } + + VpBlockProperties block{*pProfile, api_version}; + + if (pProfileDesc->props.specVersion < pProfile->specVersion) { + *pSupported = VK_FALSE; + unsupportedBlocks.push_back(block); + } + + // Required API version is built in root profile, not need to check dependent profile API versions + if (api_version != 0) { + if (!vpCheckVersion(api_version, pProfileDesc->minApiVersion)) { + + *pSupported = VK_FALSE; + unsupportedBlocks.push_back(block); + } + } + + for (uint32_t capability_index = 0; capability_index < pProfileDesc->requiredCapabilityCount; ++capability_index) { + const VpCapabilitiesDesc& capabilities_desc = pProfileDesc->pRequiredCapabilities[capability_index]; + + VkBool32 supported_capabilities = VK_FALSE; + for (uint32_t variant_index = 0; variant_index < capabilities_desc.variantCount; ++variant_index) { + const VpVariantDesc& variant_desc = capabilities_desc.pVariants[variant_index]; + + VkBool32 supported_variant = VK_TRUE; + for (uint32_t i = 0; i < variant_desc.instanceExtensionCount; ++i) { + if (!detail::CheckExtension(supported_extensions.data(), supported_extensions.size(), + variant_desc.pInstanceExtensions[i].extensionName)) { + supported_variant = VK_FALSE; + memcpy(block.blockName, variant_desc.blockName, VP_MAX_PROFILE_NAME_SIZE * sizeof(char)); + unsupportedBlocks.push_back(block); + } + } + + if (supported_variant == VK_TRUE) { + supported_capabilities = VK_TRUE; + memcpy(block.blockName, variant_desc.blockName, VP_MAX_PROFILE_NAME_SIZE * sizeof(char)); + supportedBlocks.push_back(block); + } + } + + if (supported_capabilities == VK_FALSE) { + *pSupported = VK_FALSE; + return VK_SUCCESS; + } + } + + return VK_SUCCESS; +} + +enum structure_type { + STRUCTURE_FEATURE = 0, + STRUCTURE_PROPERTY, + STRUCTURE_QUEUE_FAMILY, + STRUCTURE_FORMAT +}; + +VPAPI_ATTR VkResult vpGetProfileStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + structure_type type, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + VkResult result = pBlockName == nullptr ? VK_SUCCESS : VK_INCOMPLETE; + + std::vector results; + + const std::vector& gathered_profiles = detail::GatherProfiles(*pProfile); + + for (std::size_t profile_index = 0, profile_count = gathered_profiles.size(); profile_index < profile_count; ++profile_index) { + const detail::VpProfileDesc* profile_desc = detail::vpGetProfileDesc(gathered_profiles[profile_index].profileName); + if (profile_desc == nullptr) return VK_ERROR_UNKNOWN; + + for (uint32_t capability_index = 0; capability_index < profile_desc->requiredCapabilityCount; ++capability_index) { + const detail::VpCapabilitiesDesc& cap_desc = profile_desc->pRequiredCapabilities[capability_index]; + + for (uint32_t variant_index = 0; variant_index < cap_desc.variantCount; ++variant_index) { + const detail::VpVariantDesc& variant = cap_desc.pVariants[variant_index]; + if (pBlockName != nullptr) { + if (strcmp(variant.blockName, pBlockName) != 0) { + continue; + } + result = VK_SUCCESS; + } + + uint32_t count = 0; + const VkStructureType* data = nullptr; + + switch (type) { + default: + case STRUCTURE_FEATURE: + count = variant.featureStructTypeCount; + data = variant.pFeatureStructTypes; + break; + case STRUCTURE_PROPERTY: + count = variant.propertyStructTypeCount; + data = variant.pPropertyStructTypes; + break; + case STRUCTURE_QUEUE_FAMILY: + count = variant.queueFamilyStructTypeCount; + data = variant.pQueueFamilyStructTypes; + break; + case STRUCTURE_FORMAT: + count = variant.formatStructTypeCount; + data = variant.pFormatStructTypes; + break; + } + + for (uint32_t type_index = 0; type_index < count; ++type_index) { + const VkStructureType dataType = data[type_index]; + if (std::find(results.begin(), results.end(), dataType) == std::end(results)) { + results.push_back(dataType); + } + } + } + } + } + + const uint32_t count = static_cast(results.size()); + std::sort(results.begin(), results.end()); + + if (pStructureTypes == nullptr) { + *pStructureTypeCount = count; + } else { + if (*pStructureTypeCount < count) { + result = VK_INCOMPLETE; + } else { + *pStructureTypeCount = count; + } + + if (*pStructureTypeCount > 0) { + memcpy(pStructureTypes, &results[0], *pStructureTypeCount * sizeof(VkStructureType)); + } + } + + return result; +} + +enum ExtensionType { + EXTENSION_INSTANCE, + EXTENSION_DEVICE, +}; + +VPAPI_ATTR VkResult vpGetProfileExtensionProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + ExtensionType type, + uint32_t* pPropertyCount, + VkExtensionProperties* pProperties) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + VkResult result = pBlockName == nullptr ? VK_SUCCESS : VK_INCOMPLETE; + + std::vector results; + + const std::vector& gathered_profiles = detail::GatherProfiles(*pProfile, pBlockName); + + for (std::size_t profile_index = 0, profile_count = gathered_profiles.size(); profile_index < profile_count; ++profile_index) { + const detail::VpProfileDesc* profile_desc = detail::vpGetProfileDesc(gathered_profiles[profile_index].profileName); + if (profile_desc == nullptr) { + return VK_ERROR_UNKNOWN; + } + + for (uint32_t capability_index = 0; capability_index < profile_desc->requiredCapabilityCount; ++capability_index) { + const detail::VpCapabilitiesDesc& cap_desc = profile_desc->pRequiredCapabilities[capability_index]; + + for (uint32_t variant_index = 0; variant_index < cap_desc.variantCount; ++variant_index) { + const detail::VpVariantDesc& variant = cap_desc.pVariants[variant_index]; + if (pBlockName != nullptr) { + if (strcmp(variant.blockName, pBlockName) != 0) { + continue; + } + result = VK_SUCCESS; + } + + switch (type) { + default: + case EXTENSION_INSTANCE: + for (uint32_t ext_index = 0; ext_index < variant.instanceExtensionCount; ++ext_index) { + if (detail::HasExtension(results, variant.pInstanceExtensions[ext_index])) { + continue; + } + results.push_back(variant.pInstanceExtensions[ext_index]); + } + break; + case EXTENSION_DEVICE: + for (uint32_t ext_index = 0; ext_index < variant.deviceExtensionCount; ++ext_index) { + if (detail::HasExtension(results, variant.pDeviceExtensions[ext_index])) { + continue; + } + results.push_back(variant.pDeviceExtensions[ext_index]); + } + break; + } + } + } + } + + const uint32_t count = static_cast(results.size()); + + if (pProperties == nullptr) { + *pPropertyCount = count; + } else { + if (*pPropertyCount < count) { + result = VK_INCOMPLETE; + } else { + *pPropertyCount = count; + } + if (*pPropertyCount > 0) { + memcpy(pProperties, &results[0], *pPropertyCount * sizeof(VkExtensionProperties)); + } + } + + return result; +} + +VPAPI_ATTR VkResult vpGetProfileVideoProfileDesc( + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + const detail::VpVideoProfileDesc** ppVideoProfileDesc) { + VkResult result = pBlockName == nullptr ? VK_SUCCESS : VK_INCOMPLETE; + + uint32_t curr_base_video_profile_index = 0; + + const std::vector& gathered_profiles = detail::GatherProfiles(*pProfile); + + for (std::size_t profile_index = 0, profile_count = gathered_profiles.size(); profile_index < profile_count; ++profile_index) { + const detail::VpProfileDesc* profile_desc = detail::vpGetProfileDesc(gathered_profiles[profile_index].profileName); + if (profile_desc == nullptr) return VK_ERROR_UNKNOWN; + + for (uint32_t capability_index = 0; capability_index < profile_desc->requiredCapabilityCount; ++capability_index) { + const detail::VpCapabilitiesDesc& cap_desc = profile_desc->pRequiredCapabilities[capability_index]; + + for (uint32_t variant_index = 0; variant_index < cap_desc.variantCount; ++variant_index) { + const detail::VpVariantDesc& variant = cap_desc.pVariants[variant_index]; + if (pBlockName != nullptr) { + if (strcmp(variant.blockName, pBlockName) != 0) { + continue; + } + result = VK_SUCCESS; + } + + if (videoProfileIndex < curr_base_video_profile_index + variant.videoProfileCount) { + *ppVideoProfileDesc = &variant.pVideoProfiles[videoProfileIndex - curr_base_video_profile_index]; + return result; + } else { + curr_base_video_profile_index += variant.videoProfileCount; + } + } + } + } + + *ppVideoProfileDesc = nullptr; + return VK_ERROR_UNKNOWN; +} + +} // namespace detail + +struct VpCapabilities_T : public VpVulkanFunctions { + bool singleton = false; + uint32_t apiVersion = VK_API_VERSION_1_0; + + static VpCapabilities_T& Get() { + static VpCapabilities_T instance; + VpCapabilitiesCreateInfo createInfo{}; + createInfo.flags = VP_PROFILE_CREATE_STATIC_BIT; + instance.init(&createInfo); + instance.singleton = true; + return instance; + } + + VpCapabilities_T() { + this->GetInstanceProcAddr = nullptr; + this->GetDeviceProcAddr = nullptr; + this->EnumerateInstanceVersion = nullptr; + this->EnumerateInstanceExtensionProperties = nullptr; + this->EnumerateDeviceExtensionProperties = nullptr; + this->GetPhysicalDeviceFeatures2 = nullptr; + this->GetPhysicalDeviceProperties2 = nullptr; + this->GetPhysicalDeviceFormatProperties2 = nullptr; + this->GetPhysicalDeviceQueueFamilyProperties2 = nullptr; + this->CreateInstance = nullptr; + this->CreateDevice = nullptr; + } + + VkResult init(const VpCapabilitiesCreateInfo* pCreateInfo) { + assert(pCreateInfo != nullptr); + + return ImportVulkanFunctions(pCreateInfo); + } + + VkResult ImportVulkanFunctions(const VpCapabilitiesCreateInfo* pCreateInfo) { + if (pCreateInfo->flags & VP_PROFILE_CREATE_STATIC_BIT) { + ImportVulkanFunctions_Static(); + } + + if (pCreateInfo->pVulkanFunctions != nullptr) { + ImportVulkanFunctions_Custom((VpVulkanFunctions*)pCreateInfo->pVulkanFunctions); + } +/* + if (pCreateInfo->flags & VP_PROFILE_CREATE_DYNAMIC_BIT) { + ImportVulkanFunctions_Dynamic(); + } +*/ + return ValidateVulkanFunctions(); + } + + void ImportVulkanFunctions_Static() { + // Vulkan 1.1 + this->GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)vkGetInstanceProcAddr; + this->GetDeviceProcAddr = (PFN_vkGetDeviceProcAddr)vkGetDeviceProcAddr; + + this->EnumerateInstanceVersion = (PFN_vkEnumerateInstanceVersion)vkEnumerateInstanceVersion; + this->EnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties)vkEnumerateInstanceExtensionProperties; + this->EnumerateDeviceExtensionProperties = (PFN_vkEnumerateDeviceExtensionProperties)vkEnumerateDeviceExtensionProperties; + + this->GetPhysicalDeviceFeatures2 = (PFN_vkGetPhysicalDeviceFeatures2)vkGetPhysicalDeviceFeatures2; + this->GetPhysicalDeviceProperties2 = (PFN_vkGetPhysicalDeviceProperties2)vkGetPhysicalDeviceProperties2; + this->GetPhysicalDeviceFormatProperties2 = (PFN_vkGetPhysicalDeviceFormatProperties2)vkGetPhysicalDeviceFormatProperties2; + this->GetPhysicalDeviceQueueFamilyProperties2 = (PFN_vkGetPhysicalDeviceQueueFamilyProperties2)vkGetPhysicalDeviceQueueFamilyProperties2; + + this->CreateInstance = (PFN_vkCreateInstance)vkCreateInstance; + this->CreateDevice = (PFN_vkCreateDevice)vkCreateDevice; + } + + void ImportVulkanFunctions_Custom(VpVulkanFunctions* pFunctions) { + #define VP_COPY_IF_NOT_NULL(funcName) if(pFunctions->funcName != nullptr) this->funcName = pFunctions->funcName; + + VP_COPY_IF_NOT_NULL(GetInstanceProcAddr); + VP_COPY_IF_NOT_NULL(GetDeviceProcAddr); + + VP_COPY_IF_NOT_NULL(EnumerateInstanceVersion); + VP_COPY_IF_NOT_NULL(EnumerateInstanceExtensionProperties); + VP_COPY_IF_NOT_NULL(EnumerateDeviceExtensionProperties); + + VP_COPY_IF_NOT_NULL(GetPhysicalDeviceFeatures2); + VP_COPY_IF_NOT_NULL(GetPhysicalDeviceProperties2); + VP_COPY_IF_NOT_NULL(GetPhysicalDeviceFormatProperties2); + VP_COPY_IF_NOT_NULL(GetPhysicalDeviceQueueFamilyProperties2); + + VP_COPY_IF_NOT_NULL(CreateInstance); + VP_COPY_IF_NOT_NULL(CreateDevice); + #undef VP_COPY_IF_NOT_NULL + } +/* + VkResult ImportVulkanFunctions_Dynamic() { + // To use VP_PROFILE_CREATE_DYNAMIC_BIT you have to pass VpVulkanFunctions::vkGetInstanceProcAddr and vkGetDeviceProcAddr as VpCapabilitiesCreateInfo::pVulkanFunctions. Other members can be null. + if (this->GetInstanceProcAddr == nullptr || this->GetDeviceProcAddr == nullptr) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + #define VP_FETCH_INSTANCE_FUNC(memberName, functionNameString) if(this->memberName == nullptr) this->memberName = (PFN_vk##memberName)this->GetInstanceProcAddr(m_hInstance, functionNameString); + #define VP_FETCH_DEVICE_FUNC(memberName, functionNameString) if(this->memberName == nullptr) this->memberName = (PFN_vk##memberName)this->GetDeviceProcAddr(m_hDevice, functionNameString); + + VP_FETCH_INSTANCE_FUNC(GetInstanceProcAddr, "vkGetInstanceProcAddr"); + VP_FETCH_DEVICE_FUNC(GetDeviceProcAddr, "vkGetDeviceProcAddr"); + + VP_FETCH_INSTANCE_FUNC(EnumerateInstanceVersion, "vkEnumerateInstanceVersion"); + VP_FETCH_INSTANCE_FUNC(EnumerateInstanceExtensionProperties, "vkEnumerateInstanceExtensionProperties"); + VP_FETCH_DEVICE_FUNC(EnumerateDeviceExtensionProperties, "vkEnumerateDeviceExtensionProperties"); + + VP_FETCH_DEVICE_FUNC(GetPhysicalDeviceFeatures2, "vkGetPhysicalDeviceFeatures2"); + VP_FETCH_DEVICE_FUNC(GetPhysicalDeviceProperties2, "vkGetPhysicalDeviceProperties2"); + VP_FETCH_DEVICE_FUNC(GetPhysicalDeviceFormatProperties2, "vkGetPhysicalDeviceFormatProperties2"); + VP_FETCH_DEVICE_FUNC(GetPhysicalDeviceQueueFamilyProperties2, "vkGetPhysicalDeviceQueueFamilyProperties2"); + + VP_FETCH_INSTANCE_FUNC(CreateInstance, "vkCreateInstance"); + VP_FETCH_DEVICE_FUNC(CreateDevice, "vkCreateDevice"); + #undef VP_FETCH_DEVICE_FUNC + #undef VP_FETCH_INSTANCE_FUNC + } +*/ + VkResult ValidateVulkanFunctions() { + if (this->GetInstanceProcAddr == nullptr) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + if (this->GetDeviceProcAddr == nullptr) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + if (this->EnumerateInstanceVersion == nullptr && apiVersion >= VK_API_VERSION_1_1) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + if (this->EnumerateInstanceExtensionProperties == nullptr) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + if (this->EnumerateDeviceExtensionProperties == nullptr) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + if (this->GetPhysicalDeviceFeatures2 == nullptr) { + return apiVersion >= VK_API_VERSION_1_1 ? VK_ERROR_INITIALIZATION_FAILED : VK_ERROR_EXTENSION_NOT_PRESENT; + } + + if (this->GetPhysicalDeviceProperties2 == nullptr) { + return apiVersion >= VK_API_VERSION_1_1 ? VK_ERROR_INITIALIZATION_FAILED : VK_ERROR_EXTENSION_NOT_PRESENT; + } + + if (this->GetPhysicalDeviceFormatProperties2 == nullptr) { + return apiVersion >= VK_API_VERSION_1_1 ? VK_ERROR_INITIALIZATION_FAILED : VK_ERROR_EXTENSION_NOT_PRESENT; + } + + if (this->GetPhysicalDeviceQueueFamilyProperties2 == nullptr) { + return apiVersion >= VK_API_VERSION_1_1 ? VK_ERROR_INITIALIZATION_FAILED : VK_ERROR_EXTENSION_NOT_PRESENT; + } + + if (this->CreateInstance == nullptr) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + if (this->CreateDevice == nullptr) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + return VK_SUCCESS; + } +}; + +VPAPI_ATTR VkResult vpCreateCapabilities( + const VpCapabilitiesCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VpCapabilities* pCapabilities) { + (void)pAllocator; + + VpCapabilities_T* capabilities = new VpCapabilities_T(); + VkResult result = capabilities->init(pCreateInfo); + *pCapabilities = capabilities; + + return result; +} + +/// Destroys allocator object. +VPAPI_ATTR void vpDestroyCapabilities( + VpCapabilities capabilities, + const VkAllocationCallbacks* pAllocator) { + (void)pAllocator; + + delete capabilities; +} + +VPAPI_ATTR VkResult vpGetProfiles( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + uint32_t* pPropertyCount, + VpProfileProperties* pProperties) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + VkResult result = VK_SUCCESS; + + if (pProperties == nullptr) { + *pPropertyCount = detail::profileCount; + } else { + if (*pPropertyCount < detail::profileCount) { + result = VK_INCOMPLETE; + } else { + *pPropertyCount = detail::profileCount; + } + for (uint32_t property_index = 0; property_index < *pPropertyCount; ++property_index) { + pProperties[property_index] = detail::profiles[property_index].props; + } + } + return result; +} + +VPAPI_ATTR VkResult vpGetProfileRequiredProfiles( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + uint32_t* pPropertyCount, + VpProfileProperties* pProperties) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + VkResult result = VK_SUCCESS; + + const detail::VpProfileDesc* desc = detail::vpGetProfileDesc(pProfile->profileName); + if (desc == nullptr) { + return VK_ERROR_UNKNOWN; + } + + if (pProperties == nullptr) { + *pPropertyCount = desc->requiredProfileCount; + } else { + if (*pPropertyCount < desc->requiredProfileCount) { + result = VK_INCOMPLETE; + } else { + *pPropertyCount = desc->requiredProfileCount; + } + for (uint32_t property_index = 0; property_index < *pPropertyCount; ++property_index) { + pProperties[property_index] = desc->pRequiredProfiles[property_index]; + } + } + return result; +} + +VPAPI_ATTR uint32_t vpGetProfileAPIVersion( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + const std::vector& gathered_profiles = detail::GatherProfiles(*pProfile, nullptr); + + uint32_t major = 0; + uint32_t minor = 0; + uint32_t patch = 0; + + for (std::size_t profile_index = 0, profile_count = gathered_profiles.size(); profile_index < profile_count; ++profile_index) { + const detail::VpProfileDesc* desc = detail::vpGetProfileDesc(gathered_profiles[profile_index].profileName); + if (desc == nullptr) { + return 0; + } + + major = std::max(major, VK_API_VERSION_MAJOR(desc->minApiVersion)); + minor = std::max(minor, VK_API_VERSION_MINOR(desc->minApiVersion)); + patch = std::max(patch, VK_API_VERSION_PATCH(desc->minApiVersion)); + } + + return VK_MAKE_API_VERSION(0, major, minor, patch); +} + +VPAPI_ATTR VkResult vpGetProfileFallbacks( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + uint32_t* pPropertyCount, + VpProfileProperties* pProperties) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + VkResult result = VK_SUCCESS; + + const detail::VpProfileDesc* desc = detail::vpGetProfileDesc(pProfile->profileName); + if (desc == nullptr) { + return VK_ERROR_UNKNOWN; + } + + if (pProperties == nullptr) { + *pPropertyCount = desc->fallbackCount; + } else { + if (*pPropertyCount < desc->fallbackCount) { + result = VK_INCOMPLETE; + } else { + *pPropertyCount = desc->fallbackCount; + } + for (uint32_t i = 0; i < *pPropertyCount; ++i) { + pProperties[i] = desc->pFallbacks[i]; + } + } + return result; +} + +VPAPI_ATTR VkResult vpHasMultipleVariantsProfile( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + VkBool32* pHasMultipleVariants) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + const std::vector& gathered_profiles = detail::GatherProfiles(*pProfile, nullptr); + + for (std::size_t profile_index = 0, profile_count = gathered_profiles.size(); profile_index < profile_count; ++profile_index) { + const detail::VpProfileDesc* desc = detail::vpGetProfileDesc(gathered_profiles[profile_index].profileName); + if (desc == nullptr) { + return VK_ERROR_UNKNOWN; + } + + for (uint32_t caps_index = 0, caps_count = desc->requiredCapabilityCount; caps_index < caps_count; ++caps_index) { + if (desc->pRequiredCapabilities[caps_index].variantCount > 1) { + *pHasMultipleVariants = VK_TRUE; + return VK_SUCCESS; + } + } + } + + *pHasMultipleVariants = VK_FALSE; + return VK_SUCCESS; +} + +VPAPI_ATTR VkResult vpGetInstanceProfileVariantsSupport( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const char* pLayerName, + const VpProfileProperties* pProfile, + VkBool32* pSupported, + uint32_t* pPropertyCount, + VpBlockProperties* pProperties) { +#ifdef VP_USE_OBJECT + const VpCapabilities_T& vp = capabilities == nullptr ? VpCapabilities_T::Get() : *capabilities; +#else + const VpCapabilities_T& vp = VpCapabilities_T::Get(); +#endif//VP_USE_OBJECT + + VkResult result = VK_SUCCESS; + + uint32_t api_version = VK_API_VERSION_1_0; + PFN_vkEnumerateInstanceVersion pfnEnumerateInstanceVersion = vp.singleton ? + (PFN_vkEnumerateInstanceVersion)vkGetInstanceProcAddr(VK_NULL_HANDLE, "vkEnumerateInstanceVersion") : vp.EnumerateInstanceVersion; + if (pfnEnumerateInstanceVersion != nullptr) { + result = pfnEnumerateInstanceVersion(&api_version); + if (result != VK_SUCCESS) { + *pSupported = VK_FALSE; + return result; + } /* else { + } */ + } + + uint32_t supported_instance_extension_count = 0; + result = vp.EnumerateInstanceExtensionProperties(pLayerName, &supported_instance_extension_count, nullptr); + if (result != VK_SUCCESS) { + *pSupported = VK_FALSE; + return result; + } + std::vector supported_instance_extensions; + if (supported_instance_extension_count > 0) { + supported_instance_extensions.resize(supported_instance_extension_count); + } + result = vp.EnumerateInstanceExtensionProperties(pLayerName, &supported_instance_extension_count, supported_instance_extensions.data()); + if (result != VK_SUCCESS) { + *pSupported = VK_FALSE; + return result; + } + + VkBool32 supported = VK_TRUE; + + // We require VK_KHR_get_physical_device_properties2 if we are on Vulkan 1.0 + if (api_version < VK_API_VERSION_1_1) { + bool foundGPDP2 = false; + for (size_t ext_index = 0, ext_count = supported_instance_extensions.size(); ext_index < ext_count; ++ext_index) { + if (strcmp(supported_instance_extensions[ext_index].extensionName, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME) == 0) { + foundGPDP2 = true; + break; + } + } + if (!foundGPDP2) { + supported = VK_FALSE; + } + } + + const detail::VpProfileDesc* pProfileDesc = detail::vpGetProfileDesc(pProfile->profileName); + if (pProfileDesc == nullptr) return VK_ERROR_UNKNOWN; + + std::vector supported_blocks; + std::vector unsupported_blocks; + + result = detail::vpGetInstanceProfileSupportSingleProfile(api_version, supported_instance_extensions, pProfile, &supported, supported_blocks, unsupported_blocks); + if (result != VK_SUCCESS) { + *pSupported = supported; + return result; + } + + for (std::size_t required_profile_index = 0; required_profile_index < pProfileDesc->requiredProfileCount; ++required_profile_index) { + result = detail::vpGetInstanceProfileSupportSingleProfile(0, supported_instance_extensions, &pProfileDesc->pRequiredProfiles[required_profile_index], &supported, supported_blocks, unsupported_blocks); + if (result != VK_SUCCESS) { + *pSupported = supported; + return result; + } + } + + const std::vector& blocks = supported ? supported_blocks : unsupported_blocks; + + if (pProperties == nullptr) { + *pPropertyCount = static_cast(blocks.size()); + } else { + if (*pPropertyCount < static_cast(blocks.size())) { + result = VK_INCOMPLETE; + } else { + *pPropertyCount = static_cast(blocks.size()); + } + for (uint32_t block_index = 0, block_count = static_cast(blocks.size()); block_index < block_count; ++block_index) { + pProperties[block_index] = blocks[block_index]; + } + } + + *pSupported = supported; + return result; +} + +VPAPI_ATTR VkResult vpGetInstanceProfileSupport( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const char* pLayerName, + const VpProfileProperties* pProfile, + VkBool32* pSupported) { + uint32_t count = 0; + + return vpGetInstanceProfileVariantsSupport( +#ifdef VP_USE_OBJECT + capabilities, +#endif//VP_USE_OBJECT + pLayerName, pProfile, pSupported, &count, nullptr); +} + +VPAPI_ATTR VkResult vpCreateInstance( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpInstanceCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkInstance* pInstance) { +#ifdef VP_USE_OBJECT + const VpCapabilities_T& vp = capabilities == nullptr ? VpCapabilities_T::Get() : *capabilities; +#else + const VpCapabilities_T& vp = VpCapabilities_T::Get(); +#endif//VP_USE_OBJECT + + if (pCreateInfo == nullptr || pInstance == nullptr) { + return vp.CreateInstance(pCreateInfo == nullptr ? nullptr : pCreateInfo->pCreateInfo, pAllocator, pInstance); + } + + const std::vector& blocks = detail::GatherBlocks( + pCreateInfo->enabledFullProfileCount, pCreateInfo->pEnabledFullProfiles, + pCreateInfo->enabledProfileBlockCount, pCreateInfo->pEnabledProfileBlocks); + + std::vector extensions; + for (std::uint32_t ext_index = 0, ext_count = pCreateInfo->pCreateInfo->enabledExtensionCount; ext_index < ext_count; ++ext_index) { + extensions.push_back(pCreateInfo->pCreateInfo->ppEnabledExtensionNames[ext_index]); + } + + for (std::size_t block_index = 0, block_count = blocks.size(); block_index < block_count; ++block_index) { + const detail::VpProfileDesc* profile_desc = detail::vpGetProfileDesc(blocks[block_index].profiles.profileName); + if (profile_desc == nullptr) { + return VK_ERROR_UNKNOWN; + } + + for (std::size_t caps_index = 0, caps_count = profile_desc->requiredCapabilityCount; caps_index < caps_count; ++caps_index) { + const detail::VpCapabilitiesDesc* caps_desc = &profile_desc->pRequiredCapabilities[caps_index]; + + for (std::size_t variant_index = 0, variant_count = caps_desc->variantCount; variant_index < variant_count; ++variant_index) { + const detail::VpVariantDesc* variant = &caps_desc->pVariants[variant_index]; + + if (strcmp(blocks[block_index].blockName, "") != 0) { + if (strcmp(variant->blockName, blocks[block_index].blockName) != 0) { + continue; + } + } + + detail::GetExtensions(variant->instanceExtensionCount, variant->pInstanceExtensions, extensions); + } + } + } + + VkApplicationInfo appInfo{VK_STRUCTURE_TYPE_APPLICATION_INFO}; + if (pCreateInfo->pCreateInfo->pApplicationInfo != nullptr) { + appInfo = *pCreateInfo->pCreateInfo->pApplicationInfo; + } else if (!blocks.empty()) { + appInfo.apiVersion = vpGetProfileAPIVersion( +#ifdef VP_USE_OBJECT + capabilities, +#endif//VP_USE_OBJECT + &blocks[0].profiles); + } + + VkInstanceCreateInfo createInfo = *pCreateInfo->pCreateInfo; + createInfo.pApplicationInfo = &appInfo; + + // Need to include VK_KHR_get_physical_device_properties2 if we are on Vulkan 1.0 + if (createInfo.pApplicationInfo->apiVersion < VK_API_VERSION_1_1) { + bool foundGPDP2 = false; + for (size_t ext_index = 0, ext_count = extensions.size(); ext_index < ext_count; ++ext_index) { + if (strcmp(extensions[ext_index], VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME) == 0) { + foundGPDP2 = true; + break; + } + } + if (!foundGPDP2) { + extensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); + } + } + +#ifdef __APPLE__ + bool has_portability_ext = false; + for (std::size_t ext_index = 0, ext_count = extensions.size(); ext_index < ext_count; ++ext_index) { + if (strcmp(extensions[ext_index], VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME) == 0) { + has_portability_ext = true; + break; + } + } + + if (!has_portability_ext) { + extensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME); + } + + createInfo.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR; +#endif + + if (!extensions.empty()) { + createInfo.enabledExtensionCount = static_cast(extensions.size()); + createInfo.ppEnabledExtensionNames = extensions.data(); + } + + return vp.CreateInstance(&createInfo, pAllocator, pInstance); +} + +VPAPI_ATTR VkResult vpGetPhysicalDeviceProfileVariantsSupport( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + VkInstance instance, + VkPhysicalDevice physicalDevice, + const VpProfileProperties *pProfile, + VkBool32 *pSupported, + uint32_t *pPropertyCount, + VpBlockProperties* pProperties) { +#ifdef VP_USE_OBJECT + const VpCapabilities_T& vp = capabilities == nullptr ? VpCapabilities_T::Get() : *capabilities; +#else + const VpCapabilities_T& vp = VpCapabilities_T::Get(); +#endif//VP_USE_OBJECT + + VkResult result = VK_SUCCESS; + + uint32_t supported_device_extension_count = 0; + result = vp.EnumerateDeviceExtensionProperties(physicalDevice, nullptr, &supported_device_extension_count, nullptr); + if (result != VK_SUCCESS) { + return result; + } + std::vector supported_device_extensions; + if (supported_device_extension_count > 0) { + supported_device_extensions.resize(supported_device_extension_count); + } + result = vp.EnumerateDeviceExtensionProperties(physicalDevice, nullptr, &supported_device_extension_count, supported_device_extensions.data()); + if (result != VK_SUCCESS) { + return result; + } + + // Workaround old loader bug where count could be smaller on the second call to vkEnumerateDeviceExtensionProperties + if (supported_device_extension_count > 0) { + supported_device_extensions.resize(supported_device_extension_count); + } + + { + const detail::VpProfileDesc* pProfileDesc = detail::vpGetProfileDesc(pProfile->profileName); + if (pProfileDesc == nullptr) { + return VK_ERROR_UNKNOWN; + } + } + + struct GPDP2EntryPoints { + PFN_vkGetPhysicalDeviceFeatures2KHR pfnGetPhysicalDeviceFeatures2; + PFN_vkGetPhysicalDeviceProperties2KHR pfnGetPhysicalDeviceProperties2; + PFN_vkGetPhysicalDeviceFormatProperties2KHR pfnGetPhysicalDeviceFormatProperties2; + PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR pfnGetPhysicalDeviceQueueFamilyProperties2; + }; + +#ifdef VK_KHR_video_queue + struct VideoInfo { + PFN_vkGetPhysicalDeviceVideoCapabilitiesKHR pfnGetPhysicalDeviceVideoCapabilitiesKHR; + PFN_vkGetPhysicalDeviceVideoFormatPropertiesKHR pfnGetPhysicalDeviceVideoFormatPropertiesKHR; + const detail::VpVideoProfileDesc* pProfileDesc; + VkVideoProfileInfoKHR profileInfo; + VkPhysicalDeviceVideoFormatInfoKHR formatInfo; + bool supportedProfile; + uint32_t matchingProfiles; + }; +#endif // VK_KHR_video_queue + + std::vector supported_blocks; + std::vector unsupported_blocks; + + struct UserData { + VkPhysicalDevice physicalDevice; + std::vector& supported_blocks; + std::vector& unsupported_blocks; + const detail::VpVariantDesc* variant; + GPDP2EntryPoints gpdp2; +#ifdef VK_KHR_video_queue + VideoInfo video; +#endif // VK_KHR_video_queue + uint32_t index; + detail::PFN_vpStructChainerCb pfnCb; + bool supported; + } userData{physicalDevice, supported_blocks, unsupported_blocks}; + + if (!vp.singleton) { + userData.gpdp2.pfnGetPhysicalDeviceFeatures2 = vp.GetPhysicalDeviceFeatures2; + userData.gpdp2.pfnGetPhysicalDeviceProperties2 = vp.GetPhysicalDeviceProperties2; + userData.gpdp2.pfnGetPhysicalDeviceFormatProperties2 = vp.GetPhysicalDeviceFormatProperties2; + userData.gpdp2.pfnGetPhysicalDeviceQueueFamilyProperties2 = vp.GetPhysicalDeviceQueueFamilyProperties2; + } + + // Attempt to load core versions of the GPDP2 entry points + if (userData.gpdp2.pfnGetPhysicalDeviceFeatures2 == nullptr) { + userData.gpdp2.pfnGetPhysicalDeviceFeatures2 = + (PFN_vkGetPhysicalDeviceFeatures2KHR)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFeatures2"); + userData.gpdp2.pfnGetPhysicalDeviceProperties2 = + (PFN_vkGetPhysicalDeviceProperties2KHR)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceProperties2"); + userData.gpdp2.pfnGetPhysicalDeviceFormatProperties2 = + (PFN_vkGetPhysicalDeviceFormatProperties2KHR)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFormatProperties2"); + userData.gpdp2.pfnGetPhysicalDeviceQueueFamilyProperties2 = + (PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceQueueFamilyProperties2"); + } + + // If not successful, try to load KHR variant + if (userData.gpdp2.pfnGetPhysicalDeviceFeatures2 == nullptr) { + userData.gpdp2.pfnGetPhysicalDeviceFeatures2 = + (PFN_vkGetPhysicalDeviceFeatures2KHR)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFeatures2KHR"); + userData.gpdp2.pfnGetPhysicalDeviceProperties2 = + (PFN_vkGetPhysicalDeviceProperties2KHR)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceProperties2KHR"); + userData.gpdp2.pfnGetPhysicalDeviceFormatProperties2 = + (PFN_vkGetPhysicalDeviceFormatProperties2KHR)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFormatProperties2KHR"); + userData.gpdp2.pfnGetPhysicalDeviceQueueFamilyProperties2 = + (PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceQueueFamilyProperties2KHR"); + } + + if (userData.gpdp2.pfnGetPhysicalDeviceFeatures2 == nullptr || + userData.gpdp2.pfnGetPhysicalDeviceProperties2 == nullptr || + userData.gpdp2.pfnGetPhysicalDeviceFormatProperties2 == nullptr || + userData.gpdp2.pfnGetPhysicalDeviceQueueFamilyProperties2 == nullptr) { + return VK_ERROR_EXTENSION_NOT_PRESENT; + } + +#ifdef VK_KHR_video_queue + PFN_vkGetInstanceProcAddr gipa = vp.singleton ? vkGetInstanceProcAddr : vp.GetInstanceProcAddr; + userData.video.pfnGetPhysicalDeviceVideoCapabilitiesKHR = + (PFN_vkGetPhysicalDeviceVideoCapabilitiesKHR)gipa(instance, "vkGetPhysicalDeviceVideoCapabilitiesKHR"); + userData.video.pfnGetPhysicalDeviceVideoFormatPropertiesKHR = + (PFN_vkGetPhysicalDeviceVideoFormatPropertiesKHR)gipa(instance, "vkGetPhysicalDeviceVideoFormatPropertiesKHR"); +#endif // VK_KHR_video_queue + + bool supported = true; + + const std::vector& gathered_profiles = detail::GatherProfiles(*pProfile); + + for (std::size_t profile_index = 0, profile_count = gathered_profiles.size(); profile_index < profile_count; ++profile_index) { + const char* profile_name = gathered_profiles[profile_index].profileName; + + const detail::VpProfileDesc* profile_desc = detail::vpGetProfileDesc(profile_name); + if (profile_desc == nullptr) { + return VK_ERROR_UNKNOWN; + } + + bool supported_profile = true; + + if (profile_desc->props.specVersion < gathered_profiles[profile_index].specVersion) { + supported_profile = false; + } + + VpBlockProperties block{gathered_profiles[profile_index], profile_desc->minApiVersion}; + + { + VkPhysicalDeviceProperties2KHR properties2{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR }; + userData.gpdp2.pfnGetPhysicalDeviceProperties2(physicalDevice, &properties2); + if (!detail::vpCheckVersion(properties2.properties.apiVersion, profile_desc->minApiVersion)) { + supported_profile = false; + } + } + + for (uint32_t required_capability_index = 0; required_capability_index < profile_desc->requiredCapabilityCount; ++required_capability_index) { + const detail::VpCapabilitiesDesc* required_capabilities = &profile_desc->pRequiredCapabilities[required_capability_index]; + + bool supported_block = false; + + for (uint32_t variant_index = 0; variant_index < required_capabilities->variantCount; ++variant_index) { + const detail::VpVariantDesc& variant_desc = required_capabilities->pVariants[variant_index]; + + bool supported_variant = true; + + for (uint32_t ext_index = 0; ext_index < variant_desc.deviceExtensionCount; ++ext_index) { + const char *requested_extension = variant_desc.pDeviceExtensions[ext_index].extensionName; + if (!detail::CheckExtension(supported_device_extensions.data(), supported_device_extensions.size(), requested_extension)) { + supported_variant = false; + } + } + + userData.variant = &variant_desc; + + if (supported_variant) { + VkPhysicalDeviceFeatures2KHR features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR }; + userData.variant->chainers.pfnFeature( + static_cast(static_cast(&features)), &userData, + [](VkBaseOutStructure* p, void* pUser) { + UserData* pUserData = static_cast(pUser); + pUserData->gpdp2.pfnGetPhysicalDeviceFeatures2( + pUserData->physicalDevice, + static_cast(static_cast(p))); + + pUserData->supported = true; + while (p != nullptr) { + if (!pUserData->variant->feature.pfnComparator(p)) { + pUserData->supported = false; + } + p = p->pNext; + } + } + ); + if (!userData.supported) { + supported_variant = false; + } + } + + if (supported_variant) { + VkPhysicalDeviceProperties2KHR device_properties2{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR }; + userData.variant->chainers.pfnProperty( + static_cast(static_cast(&device_properties2)), &userData, + [](VkBaseOutStructure* p, void* pUser) { + UserData* pUserData = static_cast(pUser); + pUserData->gpdp2.pfnGetPhysicalDeviceProperties2( + pUserData->physicalDevice, + static_cast(static_cast(p))); + + pUserData->supported = true; + while (p != nullptr) { + if (!pUserData->variant->property.pfnComparator(p)) { + pUserData->supported = false; + } + p = p->pNext; + } + } + ); + if (!userData.supported) { + supported_variant = false; + } + } + + if (supported_variant && userData.variant->queueFamilyCount > 0) { + uint32_t queue_family_count = 0; + userData.gpdp2.pfnGetPhysicalDeviceQueueFamilyProperties2(physicalDevice, &queue_family_count, nullptr); + std::vector queueFamilyProps(queue_family_count, { VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2_KHR }); + userData.variant->chainers.pfnQueueFamily( + queue_family_count, static_cast(static_cast(queueFamilyProps.data())), &userData, + [](uint32_t queue_family_count, VkBaseOutStructure* pBaseArray, void* pUser) { + UserData* pUserData = static_cast(pUser); + VkQueueFamilyProperties2KHR* pArray = static_cast(static_cast(pBaseArray)); + pUserData->gpdp2.pfnGetPhysicalDeviceQueueFamilyProperties2(pUserData->physicalDevice, &queue_family_count, pArray); + pUserData->supported = true; + for (uint32_t profile_qf_idx = 0; profile_qf_idx < pUserData->variant->queueFamilyCount; ++profile_qf_idx) { + bool found_matching = false; + for (uint32_t queue_family_index = 0; queue_family_index < queue_family_count; ++queue_family_index) { + bool this_matches = true; + VkBaseOutStructure* p = static_cast(static_cast(&pArray[queue_family_index])); + while (p != nullptr) { + if (!pUserData->variant->pQueueFamilies[profile_qf_idx].pfnComparator(p)) { + this_matches = false; + } + p = p->pNext; + } + if (this_matches) { + found_matching = true; + break; + } + } + if (!found_matching) { + pUserData->supported = false; + break; + } + } + } + ); + if (!userData.supported) { + supported_variant = false; + } + } + + for (uint32_t format_index = 0; supported_variant && (format_index < userData.variant->formatCount); ++format_index) { + userData.index = format_index; + VkFormatProperties2KHR format_properties2{ VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR }; + userData.variant->chainers.pfnFormat( + static_cast(static_cast(&format_properties2)), &userData, + [](VkBaseOutStructure* p, void* pUser) { + UserData* pUserData = static_cast(pUser); + pUserData->gpdp2.pfnGetPhysicalDeviceFormatProperties2( + pUserData->physicalDevice, + pUserData->variant->pFormats[pUserData->index].format, + static_cast(static_cast(p))); + pUserData->supported = true; + while (p != nullptr) { + if (!pUserData->variant->pFormats[pUserData->index].pfnComparator(p)) { + pUserData->supported = false; + } + p = p->pNext; + } + } + ); + if (!userData.supported) { + supported_variant = false; + } + } + +#ifdef VK_KHR_video_queue + if (supported_variant && (userData.variant->videoProfileCount > 0)) { + VkVideoProfileListInfoKHR profile_list{ VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR }; + profile_list.profileCount = 1; + profile_list.pProfiles = &userData.video.profileInfo; + userData.video.formatInfo.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_FORMAT_INFO_KHR; + userData.video.formatInfo.pNext = &profile_list; + + if (userData.video.pfnGetPhysicalDeviceVideoCapabilitiesKHR != nullptr && + userData.video.pfnGetPhysicalDeviceVideoFormatPropertiesKHR != nullptr) { + for (uint32_t video_profile_index = 0; video_profile_index < userData.variant->videoProfileCount; ++video_profile_index) { + userData.video.profileInfo = VkVideoProfileInfoKHR{ VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR }; + userData.video.pProfileDesc = &userData.variant->pVideoProfiles[video_profile_index]; + userData.supported = true; + userData.video.matchingProfiles = 0; + + detail::vpForEachMatchingVideoProfiles(&userData.video.profileInfo, &userData, + [](VkBaseOutStructure* p, void* pUser) { + UserData* pUserData = static_cast(pUser); + while (p != nullptr) { + if (!pUserData->video.pProfileDesc->info.pfnComparator(p)) { + return; + } + p = p->pNext; + } + + pUserData->video.supportedProfile = true; + + VkVideoCapabilitiesKHR capabilities{ VK_STRUCTURE_TYPE_VIDEO_CAPABILITIES_KHR }; + pUserData->video.pProfileDesc->chainers.pfnCapability( + static_cast(static_cast(&capabilities)), pUserData, + [](VkBaseOutStructure* p, void* pUser) { + UserData* pUserData = static_cast(pUser); + VkResult result = pUserData->video.pfnGetPhysicalDeviceVideoCapabilitiesKHR( + pUserData->physicalDevice, + &pUserData->video.profileInfo, + static_cast(static_cast(p))); + if (result != VK_SUCCESS) { + pUserData->video.supportedProfile = false; + return; + } + while (p != nullptr) { + if (!pUserData->video.pProfileDesc->capability.pfnComparator(p)) { + pUserData->supported = false; + } + p = p->pNext; + } + } + ); + + if (pUserData->video.supportedProfile) { + pUserData->video.matchingProfiles++; + } else { + return; + } + + std::vector format_props; + for (uint32_t format_index = 0; format_index < pUserData->video.pProfileDesc->formatCount; ++format_index) { + pUserData->index = format_index; + { + VkVideoFormatPropertiesKHR tmp_props{ VK_STRUCTURE_TYPE_VIDEO_FORMAT_PROPERTIES_KHR }; + pUserData->video.pProfileDesc->pFormats[format_index].pfnFiller(static_cast(static_cast(&tmp_props))); + pUserData->video.formatInfo.imageUsage = tmp_props.imageUsageFlags; + } + + uint32_t format_count = 0; + pUserData->video.pfnGetPhysicalDeviceVideoFormatPropertiesKHR(pUserData->physicalDevice, &pUserData->video.formatInfo, &format_count, nullptr); + format_props.resize(format_count, { VK_STRUCTURE_TYPE_VIDEO_FORMAT_PROPERTIES_KHR }); + pUserData->video.pProfileDesc->chainers.pfnFormat( + format_count, static_cast(static_cast(format_props.data())), pUserData, + [](uint32_t format_count, VkBaseOutStructure* pBaseArray, void* pUser) { + UserData* pUserData = static_cast(pUser); + VkVideoFormatPropertiesKHR* pArray = static_cast(static_cast(pBaseArray)); + pUserData->video.pfnGetPhysicalDeviceVideoFormatPropertiesKHR(pUserData->physicalDevice, &pUserData->video.formatInfo, &format_count, pArray); + bool found_matching = false; + for (uint32_t i = 0; i < format_count; ++i) { + bool this_matches = true; + VkBaseOutStructure* p = static_cast(static_cast(&pArray[i])); + while (p != nullptr) { + if (!pUserData->video.pProfileDesc->pFormats[pUserData->index].pfnComparator(p)) { + this_matches = false; + } + p = p->pNext; + } + if (this_matches) { + found_matching = true; + break; + } + } + if (!found_matching) { + pUserData->supported = false; + } + } + ); + } + } + ); + if (!userData.supported || userData.video.matchingProfiles == 0) { + supported_variant = false; + } + } + } else { + supported_variant = false; + } + } +#endif // VK_KHR_video_queue + + memcpy(block.blockName, variant_desc.blockName, VP_MAX_PROFILE_NAME_SIZE * sizeof(char)); + if (supported_variant) { + supported_blocks.push_back(block); + supported_block = true; + break; + } else { + unsupported_blocks.push_back(block); + } + } + + if (!supported_block) { + supported_profile = false; + } + } + + if (!supported_profile) { + supported = false; + } + } + + const std::vector& blocks = supported ? supported_blocks : unsupported_blocks; + + if (pProperties == nullptr) { + *pPropertyCount = static_cast(blocks.size()); + } else { + if (*pPropertyCount < static_cast(blocks.size())) { + result = VK_INCOMPLETE; + } else { + *pPropertyCount = static_cast(blocks.size()); + } + for (uint32_t i = 0, n = static_cast(blocks.size()); i < n; ++i) { + pProperties[i] = blocks[i]; + } + } + + *pSupported = supported ? VK_TRUE : VK_FALSE; + return VK_SUCCESS; +} + +VPAPI_ATTR VkResult vpGetPhysicalDeviceProfileSupport( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + VkInstance instance, + VkPhysicalDevice physicalDevice, + const VpProfileProperties* pProfile, + VkBool32 *pSupported) { + uint32_t count = 0; + + return vpGetPhysicalDeviceProfileVariantsSupport( +#ifdef VP_USE_OBJECT + capabilities, +#endif//VP_USE_OBJECT + instance, physicalDevice, pProfile, pSupported, &count, nullptr); +} + +VPAPI_ATTR VkResult vpCreateDevice( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + VkPhysicalDevice physicalDevice, + const VpDeviceCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDevice* pDevice) { +#ifdef VP_USE_OBJECT + const VpCapabilities_T& vp = capabilities == nullptr ? VpCapabilities_T::Get() : *capabilities; +#else + const VpCapabilities_T& vp = VpCapabilities_T::Get(); +#endif//VP_USE_OBJECT + + if (physicalDevice == VK_NULL_HANDLE || pCreateInfo == nullptr || pDevice == nullptr) { + return vp.CreateDevice(physicalDevice, pCreateInfo == nullptr ? nullptr : pCreateInfo->pCreateInfo, pAllocator, pDevice); + } + + const std::vector& blocks = detail::GatherBlocks( + pCreateInfo->enabledFullProfileCount, pCreateInfo->pEnabledFullProfiles, + pCreateInfo->enabledProfileBlockCount, pCreateInfo->pEnabledProfileBlocks); + + std::unique_ptr chain = std::make_unique(); + std::vector structureTypes; + + std::vector extensions; + for (std::uint32_t ext_index = 0, ext_count = pCreateInfo->pCreateInfo->enabledExtensionCount; ext_index < ext_count; ++ext_index) { + extensions.push_back(pCreateInfo->pCreateInfo->ppEnabledExtensionNames[ext_index]); + } + + for (std::size_t block_index = 0, block_count = blocks.size(); block_index < block_count; ++block_index) { + const detail::VpProfileDesc* pProfileDesc = detail::vpGetProfileDesc(blocks[block_index].profiles.profileName); + if (pProfileDesc == nullptr) return VK_ERROR_UNKNOWN; + + for (std::size_t caps_index = 0, caps_count = pProfileDesc->requiredCapabilityCount; caps_index < caps_count; ++caps_index) { + const detail::VpCapabilitiesDesc* pCapsDesc = &pProfileDesc->pRequiredCapabilities[caps_index]; + + for (std::size_t variant_index = 0, variant_count = pCapsDesc->variantCount; variant_index < variant_count; ++variant_index) { + const detail::VpVariantDesc* variant = &pCapsDesc->pVariants[variant_index]; + + if (strcmp(blocks[block_index].blockName, "") != 0) { + if (strcmp(variant->blockName, blocks[block_index].blockName) != 0) { + continue; + } + } + + for (uint32_t type_index = 0; type_index < variant->featureStructTypeCount; ++type_index) { + const VkStructureType type = variant->pFeatureStructTypes[type_index]; + if (std::find(structureTypes.begin(), structureTypes.end(), type) == std::end(structureTypes)) { + structureTypes.push_back(type); + } + } + + detail::GetExtensions(variant->deviceExtensionCount, variant->pDeviceExtensions, extensions); + } + } + } + + VkBaseOutStructure* pNext = static_cast(const_cast(pCreateInfo->pCreateInfo->pNext)); + detail::GatherStructureTypes(structureTypes, pNext); + + chain->Build(structureTypes); + + VkPhysicalDeviceFeatures2KHR* pFeatures = &chain->requiredFeaturesChain; + if (pCreateInfo->pCreateInfo->pEnabledFeatures) { + pFeatures->features = *pCreateInfo->pCreateInfo->pEnabledFeatures; + } + + for (std::size_t block_index = 0, block_count = blocks.size(); block_index < block_count; ++block_index) { + const detail::VpProfileDesc* pProfileDesc = detail::vpGetProfileDesc(blocks[block_index].profiles.profileName); + if (pProfileDesc == nullptr) { + return VK_ERROR_UNKNOWN; + } + + for (std::size_t caps_index = 0, caps_count = pProfileDesc->requiredCapabilityCount; caps_index < caps_count; ++caps_index) { + const detail::VpCapabilitiesDesc* pCapsDesc = &pProfileDesc->pRequiredCapabilities[caps_index]; + + if (pCapsDesc->variantCount > 1) { + continue; // Multiple variants are not supported by this version of vpCreateDevice + } + + for (std::size_t variant_index = 0, variant_count = pCapsDesc->variantCount; variant_index < variant_count; ++variant_index) { + const detail::VpVariantDesc* variant = &pCapsDesc->pVariants[variant_index]; + + VkBaseOutStructure* base_ptr = reinterpret_cast(pFeatures); + if (variant->feature.pfnFiller != nullptr) { + while (base_ptr != nullptr) { + variant->feature.pfnFiller(base_ptr); + base_ptr = base_ptr->pNext; + } + } + } + } + } + + chain->ApplyFeatures(pCreateInfo); + + if (pCreateInfo->flags & VP_DEVICE_CREATE_DISABLE_ROBUST_BUFFER_ACCESS_BIT) { + pFeatures->features.robustBufferAccess = VK_FALSE; + } + + VkDeviceCreateInfo createInfo{VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO}; + createInfo.pNext = &chain->requiredFeaturesChain; + createInfo.queueCreateInfoCount = pCreateInfo->pCreateInfo->queueCreateInfoCount; + createInfo.pQueueCreateInfos = pCreateInfo->pCreateInfo->pQueueCreateInfos; + createInfo.enabledExtensionCount = static_cast(extensions.size()); + createInfo.ppEnabledExtensionNames = extensions.data(); + + return vp.CreateDevice(physicalDevice, &createInfo, pAllocator, pDevice); +} + +VPAPI_ATTR VkResult vpGetProfileInstanceExtensionProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pPropertyCount, + VkExtensionProperties* pProperties) { + return detail::vpGetProfileExtensionProperties( +#ifdef VP_USE_OBJECT + capabilities, +#endif//VP_USE_OBJECT + pProfile, pBlockName, detail::EXTENSION_INSTANCE, pPropertyCount, pProperties); +} + +VPAPI_ATTR VkResult vpGetProfileDeviceExtensionProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pPropertyCount, + VkExtensionProperties* pProperties) { + return detail::vpGetProfileExtensionProperties( +#ifdef VP_USE_OBJECT + capabilities, +#endif//VP_USE_OBJECT + pProfile, pBlockName, detail::EXTENSION_DEVICE, pPropertyCount, pProperties); +} + +VPAPI_ATTR VkResult vpGetProfileFeatures( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + void* pNext) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + VkResult result = pBlockName == nullptr ? VK_SUCCESS : VK_INCOMPLETE; + + const std::vector& gathered_profiles = detail::GatherProfiles(*pProfile); + + for (std::size_t profile_index = 0, profile_count = gathered_profiles.size(); profile_index < profile_count; ++profile_index) { + const detail::VpProfileDesc* profile_desc = detail::vpGetProfileDesc(gathered_profiles[profile_index].profileName); + if (profile_desc == nullptr) return VK_ERROR_UNKNOWN; + + for (uint32_t capability_index = 0; capability_index < profile_desc->requiredCapabilityCount; ++capability_index) { + const detail::VpCapabilitiesDesc& cap_desc = profile_desc->pRequiredCapabilities[capability_index]; + + for (uint32_t variant_index = 0; variant_index < cap_desc.variantCount; ++variant_index) { + const detail::VpVariantDesc& variant = cap_desc.pVariants[variant_index]; + if (pBlockName != nullptr) { + if (strcmp(variant.blockName, pBlockName) != 0) { + continue; + } + result = VK_SUCCESS; + } + + if (variant.feature.pfnFiller == nullptr) continue; + + VkBaseOutStructure* p = static_cast(pNext); + while (p != nullptr) { + variant.feature.pfnFiller(p); + p = p->pNext; + } + } + } + } + + return result; +} + +VPAPI_ATTR VkResult vpGetProfileProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + void* pNext) { + VkResult result = pBlockName == nullptr ? VK_SUCCESS : VK_INCOMPLETE; + + VkBool32 multiple_variants = VK_FALSE; + if (vpHasMultipleVariantsProfile( +#ifdef VP_USE_OBJECT + capabilities, +#endif//VP_USE_OBJECT + pProfile, + &multiple_variants) == VK_ERROR_UNKNOWN) { + return VK_ERROR_UNKNOWN; + } + if (multiple_variants == VK_TRUE && pBlockName == nullptr) { + return VK_ERROR_UNKNOWN; + } + + const std::vector& gathered_profiles = detail::GatherProfiles(*pProfile); + + for (std::size_t profile_index = 0, profile_count = gathered_profiles.size(); profile_index < profile_count; ++profile_index) { + const detail::VpProfileDesc* profile_desc = detail::vpGetProfileDesc(gathered_profiles[profile_index].profileName); + if (profile_desc == nullptr) return VK_ERROR_UNKNOWN; + + for (uint32_t capability_index = 0; capability_index < profile_desc->requiredCapabilityCount; ++capability_index) { + const detail::VpCapabilitiesDesc& cap_desc = profile_desc->pRequiredCapabilities[capability_index]; + + for (uint32_t variant_index = 0; variant_index < cap_desc.variantCount; ++variant_index) { + const detail::VpVariantDesc& variant = cap_desc.pVariants[variant_index]; + if (pBlockName != nullptr) { + if (strcmp(variant.blockName, pBlockName) != 0) { + continue; + } + result = VK_SUCCESS; + } + + if (variant.property.pfnFiller == nullptr) continue; + + VkBaseOutStructure* p = static_cast(pNext); + while (p != nullptr) { + variant.property.pfnFiller(p); + p = p->pNext; + } + } + } + } + + return result; +} + +VPAPI_ATTR VkResult vpGetProfileQueueFamilyProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pPropertyCount, + VkQueueFamilyProperties2KHR* pProperties) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + if (pPropertyCount == nullptr) return VK_ERROR_UNKNOWN; + + VkResult result = pBlockName == nullptr ? VK_SUCCESS : VK_INCOMPLETE; + + const std::vector& gathered_profiles = detail::GatherProfiles(*pProfile); + + uint32_t total_queue_family_count = 0; + + for (std::size_t profile_index = 0, profile_count = gathered_profiles.size(); profile_index < profile_count; ++profile_index) { + const detail::VpProfileDesc* profile_desc = detail::vpGetProfileDesc(gathered_profiles[profile_index].profileName); + if (profile_desc == nullptr) return VK_ERROR_UNKNOWN; + + for (uint32_t capability_index = 0; capability_index < profile_desc->requiredCapabilityCount; ++capability_index) { + const detail::VpCapabilitiesDesc& cap_desc = profile_desc->pRequiredCapabilities[capability_index]; + + for (uint32_t variant_index = 0; variant_index < cap_desc.variantCount; ++variant_index) { + const detail::VpVariantDesc& variant = cap_desc.pVariants[variant_index]; + if (pBlockName != nullptr) { + if (strcmp(variant.blockName, pBlockName) != 0) { + continue; + } + result = VK_SUCCESS; + } + + if (pProperties != nullptr) { + for (uint32_t i = 0; i < variant.queueFamilyCount; ++i) { + if (total_queue_family_count < *pPropertyCount) { + if (variant.pQueueFamilies[i].pfnFiller == nullptr) continue; + + VkBaseOutStructure* p = reinterpret_cast(pProperties); + while (p != nullptr) { + variant.pQueueFamilies[i].pfnFiller(p); + p = p->pNext; + } + + total_queue_family_count++; + pProperties++; + } else { + result = VK_INCOMPLETE; + break; + } + } + } else { + total_queue_family_count += variant.queueFamilyCount; + } + } + } + } + + *pPropertyCount = total_queue_family_count; + return result; +} + +VPAPI_ATTR VkResult vpGetProfileFormats( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pFormatCount, + VkFormat* pFormats) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + VkResult result = pBlockName == nullptr ? VK_SUCCESS : VK_INCOMPLETE; + + std::vector results; + + const std::vector& gathered_profiles = detail::GatherProfiles(*pProfile); + + for (std::size_t profile_index = 0, profile_count = gathered_profiles.size(); profile_index < profile_count; ++profile_index) { + const detail::VpProfileDesc* profile_desc = detail::vpGetProfileDesc(gathered_profiles[profile_index].profileName); + if (profile_desc == nullptr) return VK_ERROR_UNKNOWN; + + for (uint32_t capability_index = 0; capability_index < profile_desc->requiredCapabilityCount; ++capability_index) { + const detail::VpCapabilitiesDesc& cap_desc = profile_desc->pRequiredCapabilities[capability_index]; + + for (uint32_t variant_index = 0; variant_index < cap_desc.variantCount; ++variant_index) { + const detail::VpVariantDesc& variant = cap_desc.pVariants[variant_index]; + if (pBlockName != nullptr) { + if (strcmp(variant.blockName, pBlockName) != 0) { + continue; + } + result = VK_SUCCESS; + } + + for (uint32_t format_index = 0; format_index < variant.formatCount; ++format_index) { + if (std::find(results.begin(), results.end(), variant.pFormats[format_index].format) == std::end(results)) { + results.push_back(variant.pFormats[format_index].format); + } + } + } + } + } + + const uint32_t count = static_cast(results.size()); + + if (pFormats == nullptr) { + *pFormatCount = count; + } else { + if (*pFormatCount < count) { + result = VK_INCOMPLETE; + } else { + *pFormatCount = count; + } + + if (*pFormatCount > 0) { + memcpy(pFormats, &results[0], *pFormatCount * sizeof(VkFormat)); + } + } + return result; +} + +VPAPI_ATTR VkResult vpGetProfileFormatProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + VkFormat format, + void* pNext) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + VkResult result = pBlockName == nullptr ? VK_SUCCESS : VK_INCOMPLETE; + + const std::vector& gathered_profiles = detail::GatherProfiles(*pProfile); + + for (std::size_t profile_index = 0, profile_count = gathered_profiles.size(); profile_index < profile_count; ++profile_index) { + const char* profile_name = gathered_profiles[profile_index].profileName; + + const detail::VpProfileDesc* pProfileDesc = detail::vpGetProfileDesc(profile_name); + if (pProfileDesc == nullptr) return VK_ERROR_UNKNOWN; + + for (uint32_t required_capability_index = 0; required_capability_index < pProfileDesc->requiredCapabilityCount; + ++required_capability_index) { + const detail::VpCapabilitiesDesc& required_capabilities = pProfileDesc->pRequiredCapabilities[required_capability_index]; + + for (uint32_t required_variant_index = 0; required_variant_index < required_capabilities.variantCount; ++required_variant_index) { + const detail::VpVariantDesc& variant = required_capabilities.pVariants[required_variant_index]; + if (pBlockName != nullptr) { + if (strcmp(variant.blockName, pBlockName) != 0) { + continue; + } + result = VK_SUCCESS; + } + + for (uint32_t format_index = 0; format_index < variant.formatCount; ++format_index) { + if (variant.pFormats[format_index].format != format) { + continue; + } + + VkBaseOutStructure* base_ptr = static_cast(static_cast(pNext)); + while (base_ptr != nullptr) { + variant.pFormats[format_index].pfnFiller(base_ptr); + base_ptr = base_ptr->pNext; + } +#if defined(VK_VERSION_1_3) || defined(VK_KHR_format_feature_flags2) + VkFormatProperties2KHR* fp2 = static_cast( + detail::vpGetStructure(pNext, VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR)); + VkFormatProperties3KHR* fp3 = static_cast( + detail::vpGetStructure(pNext, VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR)); + if (fp3 != nullptr) { + VkFormatProperties2KHR fp{ VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR }; + variant.pFormats[format_index].pfnFiller(static_cast(static_cast(&fp))); + fp3->linearTilingFeatures |= static_cast(fp3->linearTilingFeatures | fp.formatProperties.linearTilingFeatures); + fp3->optimalTilingFeatures |= static_cast(fp3->optimalTilingFeatures | fp.formatProperties.optimalTilingFeatures); + fp3->bufferFeatures |= static_cast(fp3->bufferFeatures | fp.formatProperties.bufferFeatures); + } + if (fp2 != nullptr) { + VkFormatProperties3KHR fp{ VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR }; + variant.pFormats[format_index].pfnFiller(static_cast(static_cast(&fp))); + fp2->formatProperties.linearTilingFeatures |= static_cast(fp2->formatProperties.linearTilingFeatures | fp.linearTilingFeatures); + fp2->formatProperties.optimalTilingFeatures |= static_cast(fp2->formatProperties.optimalTilingFeatures | fp.optimalTilingFeatures); + fp2->formatProperties.bufferFeatures |= static_cast(fp2->formatProperties.bufferFeatures | fp.bufferFeatures); + } +#endif + } + } + } + } + + return result; +} + +VPAPI_ATTR VkResult vpGetProfileFeatureStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes) { + return detail::vpGetProfileStructureTypes( +#ifdef VP_USE_OBJECT + capabilities, +#endif//VP_USE_OBJECT + pProfile, pBlockName, detail::STRUCTURE_FEATURE, pStructureTypeCount, pStructureTypes); +} + +VPAPI_ATTR VkResult vpGetProfilePropertyStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes) { + return detail::vpGetProfileStructureTypes( +#ifdef VP_USE_OBJECT + capabilities, +#endif//VP_USE_OBJECT + pProfile, pBlockName, detail::STRUCTURE_PROPERTY, pStructureTypeCount, pStructureTypes); +} + +VPAPI_ATTR VkResult vpGetProfileQueueFamilyStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes) { + return detail::vpGetProfileStructureTypes( +#ifdef VP_USE_OBJECT + capabilities, +#endif//VP_USE_OBJECT + pProfile, pBlockName, detail::STRUCTURE_QUEUE_FAMILY, pStructureTypeCount, pStructureTypes); +} + +VPAPI_ATTR VkResult vpGetProfileFormatStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes) { + return detail::vpGetProfileStructureTypes( +#ifdef VP_USE_OBJECT + capabilities, +#endif//VP_USE_OBJECT + pProfile, pBlockName, detail::STRUCTURE_FORMAT, pStructureTypeCount, pStructureTypes); +} + +#ifdef VK_KHR_video_queue +// Query the list of video profiles specified by the profile +VPAPI_ATTR VkResult vpGetProfileVideoProfiles( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t* pVideoProfileCount, + VpVideoProfileProperties* pVideoProfiles) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + if (pVideoProfileCount == nullptr) return VK_ERROR_UNKNOWN; + + VkResult result = pBlockName == nullptr ? VK_SUCCESS : VK_INCOMPLETE; + + uint32_t total_video_profile_count = 0; + + const std::vector& gathered_profiles = detail::GatherProfiles(*pProfile); + + for (std::size_t profile_index = 0, profile_count = gathered_profiles.size(); profile_index < profile_count; ++profile_index) { + const detail::VpProfileDesc* profile_desc = detail::vpGetProfileDesc(gathered_profiles[profile_index].profileName); + if (profile_desc == nullptr) return VK_ERROR_UNKNOWN; + + for (uint32_t capability_index = 0; capability_index < profile_desc->requiredCapabilityCount; ++capability_index) { + const detail::VpCapabilitiesDesc& cap_desc = profile_desc->pRequiredCapabilities[capability_index]; + + for (uint32_t variant_index = 0; variant_index < cap_desc.variantCount; ++variant_index) { + const detail::VpVariantDesc& variant = cap_desc.pVariants[variant_index]; + if (pBlockName != nullptr) { + if (strcmp(variant.blockName, pBlockName) != 0) { + continue; + } + result = VK_SUCCESS; + } + + if (pVideoProfiles != nullptr) { + for (uint32_t i = 0; i < variant.videoProfileCount; ++i) { + if (total_video_profile_count < *pVideoProfileCount) { + *pVideoProfiles = variant.pVideoProfiles[i].properties; + total_video_profile_count++; + pVideoProfiles++; + } else { + result = VK_INCOMPLETE; + break; + } + } + } else { + total_video_profile_count += variant.videoProfileCount; + } + } + } + } + + *pVideoProfileCount = total_video_profile_count; + return result; +} + +VPAPI_ATTR VkResult vpGetProfileVideoProfileInfo( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + VkVideoProfileInfoKHR* pVideoProfileInfo) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + const detail::VpVideoProfileDesc* pVideoProfileDesc = nullptr; + VkResult result = detail::vpGetProfileVideoProfileDesc(pProfile, pBlockName, videoProfileIndex, &pVideoProfileDesc); + + if (pVideoProfileDesc != nullptr) { + VkBaseOutStructure* p = reinterpret_cast(pVideoProfileInfo); + while (p != nullptr) { + pVideoProfileDesc->info.pfnFiller(p); + p = p->pNext; + } + } + + return result; +} + +VPAPI_ATTR VkResult vpGetProfileVideoCapabilities( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + void* pNext) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + const detail::VpVideoProfileDesc* pVideoProfileDesc = nullptr; + VkResult result = detail::vpGetProfileVideoProfileDesc(pProfile, pBlockName, videoProfileIndex, &pVideoProfileDesc); + + if (pVideoProfileDesc != nullptr) { + VkBaseOutStructure* p = reinterpret_cast(pNext); + while (p != nullptr) { + pVideoProfileDesc->capability.pfnFiller(p); + p = p->pNext; + } + } + + return result; +} + +VPAPI_ATTR VkResult vpGetProfileVideoFormatProperties( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + uint32_t* pPropertyCount, + VkVideoFormatPropertiesKHR* pProperties) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + const detail::VpVideoProfileDesc* pVideoProfileDesc = nullptr; + VkResult result = detail::vpGetProfileVideoProfileDesc(pProfile, pBlockName, videoProfileIndex, &pVideoProfileDesc); + + uint32_t property_count = 0; + if (pVideoProfileDesc != nullptr) { + if (pProperties != nullptr) { + for (; property_count < pVideoProfileDesc->formatCount; ++property_count) { + if (property_count < *pPropertyCount) { + VkBaseOutStructure* p = reinterpret_cast(&pProperties[property_count]); + while (p != nullptr) { + pVideoProfileDesc->pFormats[property_count].pfnFiller(p); + p = p->pNext; + } + } else { + result = VK_INCOMPLETE; + break; + } + } + } else { + property_count = pVideoProfileDesc->formatCount; + } + } + + *pPropertyCount = property_count; + return result; +} + +VPAPI_ATTR VkResult vpGetProfileVideoProfileInfoStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + const detail::VpVideoProfileDesc* pVideoProfileDesc = nullptr; + VkResult result = detail::vpGetProfileVideoProfileDesc(pProfile, pBlockName, videoProfileIndex, &pVideoProfileDesc); + + if (pVideoProfileDesc != nullptr) { + if (pStructureTypes != nullptr) { + if (*pStructureTypeCount < pVideoProfileDesc->infoStructTypeCount) { + result = VK_INCOMPLETE; + } else { + *pStructureTypeCount = pVideoProfileDesc->infoStructTypeCount; + } + if (*pStructureTypeCount > 0) { + memcpy(pStructureTypes, pVideoProfileDesc->pInfoStructTypes, *pStructureTypeCount * sizeof(VkStructureType)); + } + } else { + *pStructureTypeCount = pVideoProfileDesc->infoStructTypeCount; + } + } + + return result; +} + +VPAPI_ATTR VkResult vpGetProfileVideoCapabilityStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + const detail::VpVideoProfileDesc* pVideoProfileDesc = nullptr; + VkResult result = detail::vpGetProfileVideoProfileDesc(pProfile, pBlockName, videoProfileIndex, &pVideoProfileDesc); + + if (pVideoProfileDesc != nullptr) { + if (pStructureTypes != nullptr) { + if (*pStructureTypeCount < pVideoProfileDesc->capabilityStructTypeCount) { + result = VK_INCOMPLETE; + } else { + *pStructureTypeCount = pVideoProfileDesc->capabilityStructTypeCount; + } + if (*pStructureTypeCount > 0) { + memcpy(pStructureTypes, pVideoProfileDesc->pCapabilityStructTypes, *pStructureTypeCount * sizeof(VkStructureType)); + } + } else { + *pStructureTypeCount = pVideoProfileDesc->capabilityStructTypeCount; + } + } + + return result; +} + +VPAPI_ATTR VkResult vpGetProfileVideoFormatStructureTypes( +#ifdef VP_USE_OBJECT + VpCapabilities capabilities, +#endif//VP_USE_OBJECT + const VpProfileProperties* pProfile, + const char* pBlockName, + uint32_t videoProfileIndex, + uint32_t* pStructureTypeCount, + VkStructureType* pStructureTypes) { +#ifdef VP_USE_OBJECT + (void)capabilities; +#endif//VP_USE_OBJECT + + const detail::VpVideoProfileDesc* pVideoProfileDesc = nullptr; + VkResult result = detail::vpGetProfileVideoProfileDesc(pProfile, pBlockName, videoProfileIndex, &pVideoProfileDesc); + + if (pVideoProfileDesc != nullptr) { + if (pStructureTypes != nullptr) { + if (*pStructureTypeCount < pVideoProfileDesc->formatStructTypeCount) { + result = VK_INCOMPLETE; + } else { + *pStructureTypeCount = pVideoProfileDesc->formatStructTypeCount; + } + if (*pStructureTypeCount > 0) { + memcpy(pStructureTypes, pVideoProfileDesc->pFormatStructTypes, *pStructureTypeCount * sizeof(VkStructureType)); + } + } else { + *pStructureTypeCount = pVideoProfileDesc->formatStructTypeCount; + } + } + + return result; +} +#endif // VK_KHR_video_queue