diff --git a/src/gpu/gpu.h b/src/gpu/gpu.h new file mode 100644 index 0000000..dbc5c65 --- /dev/null +++ b/src/gpu/gpu.h @@ -0,0 +1,995 @@ +// vim:fileencoding=utf-8:foldmethod=marker + +#ifndef GPU_H +#define GPU_H + +#include "../window/window_inc.h" +#include "../wapp/wapp.h" +#include "../cglm/struct.h" + +#ifdef WP_PLATFORM_CPP +BEGIN_C_LINKAGE +#endif + +typedef struct GpuInstance GpuInstance; + +typedef struct GpuInitRequest { + const char *app_name; + u32 app_version; +} GpuInitRequest; + +typedef enum GpuPhysicalDeviceType { + GPU_PHYSICAL_DEVICE_TYPE_UNKNOWN, + GPU_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, + GPU_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, + GPU_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU, + GPU_PHYSICAL_DEVICE_TYPE_CPU, + + COUNT_GPU_PHYSICAL_DEVICE_TYPES, +} GpuPhysicalDeviceType; +wp_intern const char *device_type_strings[COUNT_GPU_PHYSICAL_DEVICE_TYPES] = { + [GPU_PHYSICAL_DEVICE_TYPE_UNKNOWN] = "Unknown physical device", + [GPU_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU] = "Discrete GPU", + [GPU_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU] = "Integrated GPU", + [GPU_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU] = "Virtual GPU", + [GPU_PHYSICAL_DEVICE_TYPE_CPU] = "CPU", +}; + +typedef enum GpuPhysicalDeviceOps { + GPU_PHYSICAL_DEVICE_OP_GRAPHICS = 1 << 0, + GPU_PHYSICAL_DEVICE_OP_PRESENTATION = 1 << 1, + GPU_PHYSICAL_DEVICE_OP_COMPUTE = 1 << 2, + GPU_PHYSICAL_DEVICE_OP_TRANSFER = 1 << 3, + GPU_PHYSICAL_DEVICE_OP_VIDEO_DECODE = 1 << 4, + GPU_PHYSICAL_DEVICE_OP_VIDEO_ENCODE = 1 << 5, +} GpuPhysicalDeviceOps; + +typedef struct GpuPhysicalDeviceInternal GpuPhysicalDeviceInternal; + +typedef struct GpuPhysicalDevice { + const GpuInstance *instance; + GpuPhysicalDeviceInternal *internal; + GpuPhysicalDeviceType type; +} GpuPhysicalDevice; + +typedef struct GpuPhysicalDeviceFindRequest { + const GpuInstance *instance; + GpuPhysicalDeviceType type; + GpuPhysicalDeviceOps ops; +} GpuPhysicalDeviceFindRequest; + +typedef struct GpuSurface GpuSurface; + +typedef struct GpuSurfaceCreateRequest { + GpuPhysicalDevice physical_device; + const Window *window; +} GpuSurfaceCreateRequest; + +typedef struct GpuDevice GpuDevice; + +typedef enum GpuFormat { + GPU_FORMAT_UNDEFINED, + GPU_FORMAT_R8_UINT, + GPU_FORMAT_R8_SINT, + GPU_FORMAT_R8_SRGB, + GPU_FORMAT_R8G8_UINT, + GPU_FORMAT_R8G8_SINT, + GPU_FORMAT_R8G8_SRGB, + GPU_FORMAT_R8G8B8_UINT, + GPU_FORMAT_R8G8B8_SINT, + GPU_FORMAT_R8G8B8_SRGB, + GPU_FORMAT_B8G8R8_UINT, + GPU_FORMAT_B8G8R8_SINT, + GPU_FORMAT_B8G8R8_SRGB, + GPU_FORMAT_R8G8B8A8_UINT, + GPU_FORMAT_R8G8B8A8_SINT, + GPU_FORMAT_R8G8B8A8_SRGB, + GPU_FORMAT_B8G8R8A8_UINT, + GPU_FORMAT_B8G8R8A8_SINT, + GPU_FORMAT_B8G8R8A8_SRGB, + GPU_FORMAT_R16_UINT, + GPU_FORMAT_R16_SINT, + GPU_FORMAT_R16_SFLOAT, + GPU_FORMAT_R16G16_UINT, + GPU_FORMAT_R16G16_SINT, + GPU_FORMAT_R16G16_SFLOAT, + GPU_FORMAT_R16G16B16_UINT, + GPU_FORMAT_R16G16B16_SINT, + GPU_FORMAT_R16G16B16_SFLOAT, + GPU_FORMAT_R16G16B16A16_UINT, + GPU_FORMAT_R16G16B16A16_SINT, + GPU_FORMAT_R16G16B16A16_SFLOAT, + GPU_FORMAT_R32_UINT, + GPU_FORMAT_R32_SINT, + GPU_FORMAT_R32_SFLOAT, + GPU_FORMAT_R32G32_UINT, + GPU_FORMAT_R32G32_SINT, + GPU_FORMAT_R32G32_SFLOAT, + GPU_FORMAT_R32G32B32_UINT, + GPU_FORMAT_R32G32B32_SINT, + GPU_FORMAT_R32G32B32_SFLOAT, + GPU_FORMAT_R32G32B32A32_UINT, + GPU_FORMAT_R32G32B32A32_SINT, + GPU_FORMAT_R32G32B32A32_SFLOAT, + GPU_FORMAT_R64_UINT, + GPU_FORMAT_R64_SINT, + GPU_FORMAT_R64_SFLOAT, + GPU_FORMAT_R64G64_UINT, + GPU_FORMAT_R64G64_SINT, + GPU_FORMAT_R64G64_SFLOAT, + GPU_FORMAT_R64G64B64_UINT, + GPU_FORMAT_R64G64B64_SINT, + GPU_FORMAT_R64G64B64_SFLOAT, + GPU_FORMAT_R64G64B64A64_UINT, + GPU_FORMAT_R64G64B64A64_SINT, + GPU_FORMAT_R64G64B64A64_SFLOAT, + GPU_FORMAT_D24_UNORM_S8_UINT, + GPU_FORMAT_D32_SFLOAT_S8_UINT, +} GpuFormat; + +typedef enum GpuColorspace { + GPU_COLOR_SPACE_SRGB_NONLINEAR, + GPU_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT, + GPU_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT, + GPU_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT, + GPU_COLOR_SPACE_DCI_P3_NONLINEAR_EXT, + GPU_COLOR_SPACE_BT709_LINEAR_EXT, + GPU_COLOR_SPACE_BT709_NONLINEAR_EXT, + GPU_COLOR_SPACE_BT2020_LINEAR_EXT, + GPU_COLOR_SPACE_HDR10_ST2084_EXT, + GPU_COLOR_SPACE_DOLBYVISION_EXT, + GPU_COLOR_SPACE_HDR10_HLG_EXT, + GPU_COLOR_SPACE_ADOBERGB_LINEAR_EXT, + GPU_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT, + GPU_COLOR_SPACE_PASS_THROUGH_EXT, + GPU_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT, + GPU_COLORSPACE_SRGB_NONLINEAR, +} GpuColorspace; + +typedef enum GpuPresentMode { + GPU_PRESENT_MODE_IMMEDIATE, + GPU_PRESENT_MODE_FIFO, + GPU_PRESENT_MODE_FIFO_RELAXED, + GPU_PRESENT_MODE_FIFO_LATEST_READY, +} GpuPresentMode; + +typedef struct GpuSwapchain GpuSwapchain; + +typedef struct GpuSwapchainCreateRequest { + GpuDevice *device; + GpuSurface *surface; + GpuFormat format; + GpuColorspace colorspace; + GpuPresentMode present_mode; + u32 ideal_image_count; +} GpuSwapchainCreateRequest; + +typedef enum GpuFilter { + GPU_FILTER_NEAREST, + GPU_FILTER_LINEAR, + GPU_FILTER_CUBIC, +} GpuFilter; + +typedef enum GpuSamplerMipmapMode { + GPU_SAMPLER_MIPMAP_MODE_NEAREST, + GPU_SAMPLER_MIPMAP_MODE_LINEAR, +} GpuSamplerMipmapMode; + +typedef enum GpuSamplerAddressMode { + GPU_SAMPLER_ADDRESS_MODE_REPEAT, + GPU_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, + GPU_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + GPU_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, + GPU_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, +} GpuSamplerAddressMode; + +typedef enum GpuCompareOp { + GPU_COMPARE_OP_NEVER, + GPU_COMPARE_OP_LESS, + GPU_COMPARE_OP_EQUAL, + GPU_COMPARE_OP_LESS_OR_EQUAL, + GPU_COMPARE_OP_GREATER, + GPU_COMPARE_OP_NOT_EQUAL, + GPU_COMPARE_OP_GREATER_OR_EQUAL, + GPU_COMPARE_OP_ALWAYS, +} GpuCompareOp; + +typedef struct GpuSampler GpuSampler; + +typedef struct GpuSamplerCreateRequest { + GpuDevice *device; + GpuFilter mag_filter; + GpuFilter min_filter; + GpuSamplerMipmapMode mipmap_mode; + GpuSamplerAddressMode address_mode_u; + GpuSamplerAddressMode address_mode_v; + GpuSamplerAddressMode address_mode_w; + b32 compare_enable; + GpuCompareOp compare_op; +} GpuSamplerCreateRequest; + +typedef enum GpuImageType { + GPU_IMAGE_TYPE_1D, + GPU_IMAGE_TYPE_2D, + GPU_IMAGE_TYPE_3D, +} GpuImageType; + +typedef enum GpuSampleCount { + GPU_SAMPLE_COUNT_1_BIT, + GPU_SAMPLE_COUNT_2_BIT, + GPU_SAMPLE_COUNT_4_BIT, + GPU_SAMPLE_COUNT_8_BIT, + GPU_SAMPLE_COUNT_16_BIT, + GPU_SAMPLE_COUNT_32_BIT, + GPU_SAMPLE_COUNT_64_BIT, +} GpuSampleCount; + +typedef enum GpuImageTiling { + GPU_IMAGE_TILING_OPTIMAL, + GPU_IMAGE_TILING_LINEAR, +} GpuImageTiling; + +typedef enum GpuImageUsage { + GPU_IMAGE_USAGE_TRANSFER_SRC = wpU32Const(1) << 0, + GPU_IMAGE_USAGE_TRANSFER_DST = wpU32Const(1) << 1, + GPU_IMAGE_USAGE_SAMPLED = wpU32Const(1) << 2, + GPU_IMAGE_USAGE_STORAGE = wpU32Const(1) << 3, + GPU_IMAGE_USAGE_COLOR_ATTACHMENT = wpU32Const(1) << 4, + GPU_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT = wpU32Const(1) << 5, + GPU_IMAGE_USAGE_TRANSIENT_ATTACHMENT = wpU32Const(1) << 6, + GPU_IMAGE_USAGE_INPUT_ATTACHMENT = wpU32Const(1) << 7, + GPU_IMAGE_USAGE_HOST_TRANSFER = wpU32Const(1) << 8, + GPU_IMAGE_USAGE_VIDEO_DECODE_DST = wpU32Const(1) << 9, + GPU_IMAGE_USAGE_VIDEO_DECODE_SRC = wpU32Const(1) << 10, + GPU_IMAGE_USAGE_FRAGMENT_DENSITY_MAP = wpU32Const(1) << 11, + GPU_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT = wpU32Const(1) << 12, + GPU_IMAGE_USAGE_VIDEO_ENCODE_DST = wpU32Const(1) << 13, + GPU_IMAGE_USAGE_VIDEO_ENCODE_SRC = wpU32Const(1) << 14, +} GpuImageUsage; + +typedef enum GpuImageLayout { + GPU_IMAGE_LAYOUT_UNDEFINED, + GPU_IMAGE_LAYOUT_GENERAL, + GPU_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + GPU_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + GPU_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, + GPU_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + GPU_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + GPU_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + GPU_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, + GPU_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, + GPU_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, + GPU_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL, + GPU_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL, + GPU_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL, + GPU_IMAGE_LAYOUT_READ_ONLY_OPTIMAL, + GPU_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL, + GPU_IMAGE_LAYOUT_PRESENT_SRC, + GPU_IMAGE_LAYOUT_VIDEO_DECODE_DST, + GPU_IMAGE_LAYOUT_VIDEO_DECODE_SRC, + GPU_IMAGE_LAYOUT_SHARED_PRESENT, + GPU_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL, + GPU_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL, + GPU_IMAGE_LAYOUT_VIDEO_ENCODE_DST, + GPU_IMAGE_LAYOUT_VIDEO_ENCODE_SRC, + GPU_IMAGE_LAYOUT_VIDEO_ENCODE_QUANTIZATION_MAP, +} GpuImageLayout; + +typedef enum GpuImageAspect { + GPU_IMAGE_ASPECT_NONE = 0, + GPU_IMAGE_ASPECT_COLOR_BIT = 1 << 0, + GPU_IMAGE_ASPECT_DEPTH_BIT = 1 << 1, + GPU_IMAGE_ASPECT_STENCIL_BIT = 1 << 2, +} GpuImageAspect; + +typedef struct GpuImageSubresourceRange { + GpuImageAspect aspect; + u32 base_mip_level; + u32 level_count; + u32 base_array_layer; + u32 layer_count; +} GpuImageSubresourceRange; + +typedef struct GpuImage GpuImage; +typedef GpuImage *GpuImageArray; + +typedef struct GpuImageCreateRequest { + GpuDevice *device; + ivec3s size; + GpuImageType type; + GpuFormat format; + GpuSampleCount samples; + GpuImageTiling tiling; + GpuImageUsage usage; + GpuImageLayout layout; + GpuImageSubresourceRange subresource; +} GpuImageCreateRequest; + +typedef enum GpuBufferUsage { + GPU_BUFFER_USAGE_TRANSFER_SRC = wpU32Const(1) << 0, + GPU_BUFFER_USAGE_TRANSFER_DST = wpU32Const(1) << 1, + GPU_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER = wpU32Const(1) << 2, + GPU_BUFFER_USAGE_STORAGE_TEXEL_BUFFER = wpU32Const(1) << 3, + GPU_BUFFER_USAGE_UNIFORM_BUFFER = wpU32Const(1) << 4, + GPU_BUFFER_USAGE_STORAGE_BUFFER = wpU32Const(1) << 5, + GPU_BUFFER_USAGE_INDEX_BUFFER = wpU32Const(1) << 6, + GPU_BUFFER_USAGE_VERTEX_BUFFER = wpU32Const(1) << 7, + GPU_BUFFER_USAGE_INDIRECT_BUFFER = wpU32Const(1) << 8, + GPU_BUFFER_USAGE_SHADER_DEVICE_ADDRESS = wpU32Const(1) << 9, + GPU_BUFFER_USAGE_DESCRIPTOR_HEAP = wpU32Const(1) << 10, + GPU_BUFFER_USAGE_CONDITIONAL_RENDERING = wpU32Const(1) << 11, + GPU_BUFFER_USAGE_SHADER_BINDING_TABLE = wpU32Const(1) << 12, + GPU_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER = wpU32Const(1) << 13, + GPU_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER = wpU32Const(1) << 14, + GPU_BUFFER_USAGE_VIDEO_DECODE_SRC = wpU32Const(1) << 15, + GPU_BUFFER_USAGE_VIDEO_DECODE_DST = wpU32Const(1) << 16, + GPU_BUFFER_USAGE_VIDEO_ENCODE_DST = wpU32Const(1) << 17, + GPU_BUFFER_USAGE_VIDEO_ENCODE_SRC = wpU32Const(1) << 18, + GPU_BUFFER_USAGE_SAMPLER_DESCRIPTOR_BUFFER = wpU32Const(1) << 19, + GPU_BUFFER_USAGE_RESOURCE_DESCRIPTOR_BUFFER = wpU32Const(1) << 20, + GPU_BUFFER_USAGE_PUSH_DESCRIPTORS_DESCRIPTOR_BUFFER = wpU32Const(1) << 21, +} GpuBufferUsage; + +typedef struct GpuBufferInternal GpuBufferInternal; + +typedef struct GpuBuffer { + GpuDevice *device; + GpuBufferInternal *internal; + void *cpu_mapping; + u64 gpu_device_address; + u64 size; +} GpuBuffer; + +typedef struct GpuBufferCreateRequest { + GpuDevice *device; + u64 size; + GpuBufferUsage usage; +} GpuBufferCreateRequest; + +typedef struct GpuFence GpuFence; + +typedef struct GpuSemaphore GpuSemaphore; + +typedef struct GpuCommandPool GpuCommandPool; + +typedef struct GpuCommandBuffer GpuCommandBuffer; +typedef GpuCommandBuffer **GpuCommandBufferPtrArray; + +typedef struct GpuCommandBufferAllocateRequest { + GpuCommandPool *pool; + u32 buffer_count; +} GpuCommandBufferAllocateRequest; + +typedef u64 GpuPipelineStageFlags; +typedef u64 GpuPipelineStageFlagsBits; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_NONE = wpU64Const(0); +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_TOP_OF_PIPE = wpU64Const(1) << 1; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_DRAW_INDIRECT = wpU64Const(1) << 2; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_VERTEX_INPUT = wpU64Const(1) << 3; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_VERTEX_SHADER = wpU64Const(1) << 4; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER = wpU64Const(1) << 5; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER = wpU64Const(1) << 6; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_GEOMETRY_SHADER = wpU64Const(1) << 7; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_FRAGMENT_SHADER = wpU64Const(1) << 8; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS = wpU64Const(1) << 9; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_LATE_FRAGMENT_TESTS = wpU64Const(1) << 10; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT = wpU64Const(1) << 11; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_COMPUTE_SHADER = wpU64Const(1) << 12; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_ALL_TRANSFER = wpU64Const(1) << 13; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_TRANSFER = wpU64Const(1) << 14; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_BOTTOM_OF_PIPE = wpU64Const(1) << 15; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_HOST = wpU64Const(1) << 16; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_ALL_GRAPHICS = wpU64Const(1) << 17; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_ALL_COMMANDS = wpU64Const(1) << 18; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_COPY = wpU64Const(1) << 19; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_RESOLVE = wpU64Const(1) << 20; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_BLIT = wpU64Const(1) << 21; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_CLEAR = wpU64Const(1) << 22; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_INDEX_INPUT = wpU64Const(1) << 23; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_VERTEX_ATTRIBUTE_INPUT = wpU64Const(1) << 24; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_PRE_RASTERIZATION_SHADERS = wpU64Const(1) << 25; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_VIDEO_DECODE = wpU64Const(1) << 26; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_VIDEO_ENCODE = wpU64Const(1) << 27; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_CONDITIONAL_RENDERING = wpU64Const(1) << 28; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_COMMAND_PREPROCESS = wpU64Const(1) << 29; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT = wpU64Const(1) << 30; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD = wpU64Const(1) << 31; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_RAY_TRACING_SHADER = wpU64Const(1) << 32; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS = wpU64Const(1) << 33; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_TASK_SHADER = wpU64Const(1) << 34; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_MESH_SHADER = wpU64Const(1) << 35; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_ACCELERATION_STRUCTURE_COPY = wpU64Const(1) << 36; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_MICROMAP_BUILD = wpU64Const(1) << 37; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_COPY_INDIRECT = wpU64Const(1) << 38; +wp_intern const GpuPipelineStageFlagsBits GPU_PIPELINE_STAGE_MEMORY_DECOMPRESSION = wpU64Const(1) << 39; + +typedef u64 GpuAccessFlags; +typedef u64 GpuAccessFlagsBits; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_NONE = wpU64Const(0); +wp_intern const GpuAccessFlagsBits GPU_ACCESS_INDIRECT_COMMAND_READ = wpU64Const(1) << 1; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_INDEX_READ = wpU64Const(1) << 2; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_VERTEX_ATTRIBUTE_READ = wpU64Const(1) << 3; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_UNIFORM_READ = wpU64Const(1) << 4; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_INPUT_ATTACHMENT_READ = wpU64Const(1) << 5; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_SHADER_READ = wpU64Const(1) << 6; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_SHADER_WRITE = wpU64Const(1) << 7; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_COLOR_ATTACHMENT_READ = wpU64Const(1) << 8; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_COLOR_ATTACHMENT_WRITE = wpU64Const(1) << 9; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ = wpU64Const(1) << 10; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE = wpU64Const(1) << 11; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_TRANSFER_READ = wpU64Const(1) << 12; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_TRANSFER_WRITE = wpU64Const(1) << 13; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_HOST_READ = wpU64Const(1) << 14; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_HOST_WRITE = wpU64Const(1) << 15; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_MEMORY_READ = wpU64Const(1) << 16; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_MEMORY_WRITE = wpU64Const(1) << 17; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_SHADER_SAMPLED_READ = wpU64Const(1) << 18; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_SHADER_STORAGE_READ = wpU64Const(1) << 19; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_SHADER_STORAGE_WRITE = wpU64Const(1) << 20; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_VIDEO_DECODE_READ = wpU64Const(1) << 21; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_VIDEO_DECODE_WRITE = wpU64Const(1) << 22; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_SAMPLER_HEAP_READ = wpU64Const(1) << 23; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_RESOURCE_HEAP_READ = wpU64Const(1) << 24; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_VIDEO_ENCODE_READ = wpU64Const(1) << 25; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_VIDEO_ENCODE_WRITE = wpU64Const(1) << 26; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_TRANSFORM_FEEDBACK_WRITE = wpU64Const(1) << 27; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ = wpU64Const(1) << 28; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE = wpU64Const(1) << 29; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_CONDITIONAL_RENDERING_READ = wpU64Const(1) << 30; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_COMMAND_PREPROCESS_READ = wpU64Const(1) << 31; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_COMMAND_PREPROCESS_WRITE = wpU64Const(1) << 32; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ = wpU64Const(1) << 33; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_ACCELERATION_STRUCTURE_READ = wpU64Const(1) << 34; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_ACCELERATION_STRUCTURE_WRITE = wpU64Const(1) << 35; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_FRAGMENT_DENSITY_MAP_READ = wpU64Const(1) << 36; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT = wpU64Const(1) << 37; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_DESCRIPTOR_BUFFER_READ = wpU64Const(1) << 38; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_SHADER_BINDING_TABLE_READ = wpU64Const(1) << 39; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_MICROMAP_READ = wpU64Const(1) << 40; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_MICROMAP_WRITE = wpU64Const(1) << 41; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_MEMORY_DECOMPRESSION_READ = wpU64Const(1) << 42; +wp_intern const GpuAccessFlagsBits GPU_ACCESS_MEMORY_DECOMPRESSION_WRITE = wpU64Const(1) << 43; + +typedef struct GpuMemoryBarrier { + GpuPipelineStageFlags src_stage_mask; + GpuPipelineStageFlags dst_stage_mask; + GpuAccessFlags src_access_mask; + GpuAccessFlags dst_access_mask; +} GpuMemoryBarrier; + +typedef struct GpuBufferMemoryBarrier { + GpuBuffer *buffer; + GpuPipelineStageFlags src_stage_mask; + GpuPipelineStageFlags dst_stage_mask; + GpuAccessFlags src_access_mask; + GpuAccessFlags dst_access_mask; + u32 src_queue_family_index; + u32 dst_queue_family_index; +} GpuBufferMemoryBarrier; + +typedef struct GpuImageMemoryBarrier { + GpuImageSubresourceRange subresource; + GpuImage *image; + GpuPipelineStageFlags src_stage_mask; + GpuPipelineStageFlags dst_stage_mask; + GpuAccessFlags src_access_mask; + GpuAccessFlags dst_access_mask; + GpuImageLayout old_layout; + GpuImageLayout new_layout; + u32 src_queue_family_index; + u32 dst_queue_family_index; +} GpuImageMemoryBarrier; + +typedef struct GpuCommandBuffersSubmitRequest { + GpuDevice *device; + GpuFence *fence; + GpuCommandBufferPtrArray buffers; +} GpuCommandBuffersSubmitRequest; + +typedef enum GpuDescriptorType { + GPU_DESCRIPTOR_TYPE_SAMPLER, + GPU_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + GPU_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + GPU_DESCRIPTOR_TYPE_STORAGE_IMAGE, + GPU_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, + GPU_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, + GPU_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + GPU_DESCRIPTOR_TYPE_STORAGE_BUFFER, + GPU_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, + GPU_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, + GPU_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, + GPU_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK, + + GPU_DESCRIPTOR_TYPE_COUNT, +} GpuDescriptorType; + +typedef struct GpuDescriptorPoolSize { + GpuDescriptorType type; + u32 count; +} GpuDescriptorPoolSize; +typedef GpuDescriptorPoolSize *GpuDescriptorPoolSizeArray; + +typedef struct GpuDescriptorPool GpuDescriptorPool; + +typedef struct GpuDescriptorPoolCreateRequest { + GpuDescriptorPoolSizeArray descriptor_pool_sizes; + GpuDevice *device; + u32 max_sets; +} GpuDescriptorPoolCreateRequest; + +typedef enum GpuShaderStage { + GPU_SHADER_STAGE_VERTEX = wpU64Const(1) << 0, + GPU_SHADER_STAGE_TESSELLATION_CONTROL = wpU64Const(1) << 1, + GPU_SHADER_STAGE_TESSELLATION_EVALUATION = wpU64Const(1) << 2, + GPU_SHADER_STAGE_GEOMETRY = wpU64Const(1) << 3, + GPU_SHADER_STAGE_FRAGMENT = wpU64Const(1) << 4, + GPU_SHADER_STAGE_COMPUTE = wpU64Const(1) << 5, + GPU_SHADER_STAGE_ALL_GRAPHICS = wpU64Const(1) << 6, + GPU_SHADER_STAGE_ALL = wpU64Const(1) << 7, + GPU_SHADER_STAGE_RAYGEN = wpU64Const(1) << 8, + GPU_SHADER_STAGE_ANY_HIT = wpU64Const(1) << 9, + GPU_SHADER_STAGE_CLOSEST_HIT = wpU64Const(1) << 10, + GPU_SHADER_STAGE_MISS = wpU64Const(1) << 11, + GPU_SHADER_STAGE_INTERSECTION = wpU64Const(1) << 12, + GPU_SHADER_STAGE_CALLABLE = wpU64Const(1) << 13, + GPU_SHADER_STAGE_TASK = wpU64Const(1) << 14, + GPU_SHADER_STAGE_MESH = wpU64Const(1) << 15, +} GpuShaderStage; + +typedef struct GpuDescriptorSetBinding { + u32 binding; + GpuDescriptorType type; + u32 descriptor_count; + GpuShaderStage stages; + b32 variable_count; +} GpuDescriptorSetBinding; +typedef GpuDescriptorSetBinding *GpuDescriptorSetBindingArray; + +typedef struct GpuDescriptorSetLayout GpuDescriptorSetLayout; +typedef GpuDescriptorSetLayout **GpuDescriptorSetLayoutPtrArray; + +typedef struct GpuDescriptorSetLayoutCreateRequest { + GpuDevice *device; + GpuDescriptorSetBindingArray bindings; +} GpuDescriptorSetLayoutCreateRequest; + +typedef struct GpuDescriptorSet GpuDescriptorSet; +typedef GpuDescriptorSet **GpuDescriptorSetPtrArray; + +typedef struct GpuDescriptorSetAllocateRequest { + GpuDescriptorPool *pool; + GpuDescriptorSetLayoutPtrArray layouts; +} GpuDescriptorSetAllocateRequest; + +typedef struct GpuDescriptorBufferInfo { + GpuBuffer *buffer; + i32 offset; + i32 range; +} GpuDescriptorBufferInfo; +typedef GpuDescriptorBufferInfo *GpuDescriptorBufferInfoArray; + +typedef struct GpuDescriptorImageInfo { + GpuSampler *sampler; + GpuImage *image; + GpuImageLayout image_layout; +} GpuDescriptorImageInfo; +typedef GpuDescriptorImageInfo *GpuDescriptorImageInfoArray; + +typedef struct GpuDescriptorSetWriteInfo { + GpuDescriptorSet *set; + u32 dst_binding; + u32 dst_array_element; + GpuDescriptorType descriptor_type; + GpuDescriptorBufferInfoArray buffer_infos; + GpuDescriptorImageInfoArray image_infos; +} GpuDescriptorSetWriteInfo; +typedef GpuDescriptorSetWriteInfo *GpuDescriptorSetWriteInfoArray; + +typedef struct GpuDescriptorSetWriteRequest { + GpuDevice *device; + GpuDescriptorSetWriteInfoArray write_infos; +} GpuDescriptorSetWriteRequest; + +typedef struct GpuShader GpuShader; + +typedef struct GpuShaderCreateRequest { + GpuDevice *device; + void *code; + u64 size; +} GpuShaderCreateRequest; + +typedef struct GpuPushConstantRange { + GpuShaderStage stages; + u32 offset; + u32 size; +} GpuPushConstantRange; +typedef GpuPushConstantRange *GpuPushConstantRangeArray; + +typedef struct GpuPipelineLayout GpuPipelineLayout; + +typedef struct GpuPipelineLayoutCreateRequest { + GpuDevice *device; + GpuDescriptorSetLayoutPtrArray descriptor_set_layouts; + GpuPushConstantRangeArray push_constants; +} GpuPipelineLayoutCreateRequest; + +typedef struct GpuPipelineShaderStageInfo { + GpuShader *shader; + const char *name; + GpuShaderStage stage; +} GpuPipelineShaderStageInfo; +typedef GpuPipelineShaderStageInfo *GpuPipelineShaderStageInfoArray; + +typedef enum GpuVertexInputRate { + GPU_VERTEX_INPUT_RATE_VERTEX, + GPU_VERTEX_INPUT_RATE_INSTANCE, +} GpuVertexInputRate; + +typedef struct GpuVertexInputBinding { + u32 binding; + u32 stride; + GpuVertexInputRate input_rate; +} GpuVertexInputBinding; +typedef GpuVertexInputBinding *GpuVertexInputBindingArray; + +typedef struct GpuVertexInputAttribute { + u32 location; + u32 binding; + u32 offset; + GpuFormat format; +} GpuVertexInputAttribute; +typedef GpuVertexInputAttribute *GpuVertexInputAttributeArray; + +typedef struct GpuPipelineVertexInputStateInfo { + GpuVertexInputBindingArray bindings; + GpuVertexInputAttributeArray attributes; +} GpuPipelineVertexInputStateInfo; + +typedef enum GpuPrimitiveTopology { + GPU_PRIMITIVE_TOPOLOGY_POINT_LIST, + GPU_PRIMITIVE_TOPOLOGY_LINE_LIST, + GPU_PRIMITIVE_TOPOLOGY_LINE_STRIP, + GPU_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, + GPU_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, + GPU_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, + GPU_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY, + GPU_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY, + GPU_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY, + GPU_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY, + GPU_PRIMITIVE_TOPOLOGY_PATCH_LIST, +} GpuPrimitiveTopology; + +typedef struct GpuPipelineInputAssemblyStateInfo { + GpuPrimitiveTopology topology; +} GpuPipelineInputAssemblyStateInfo; + +typedef struct GpuPipelineTessellationStateInfo { + u32 patch_control_points; +} GpuPipelineTessellationStateInfo; + +typedef struct GpuViewport { + f32 x; + f32 y; + f32 width; + f32 height; + f32 min_depth; + f32 max_depth; +} GpuViewport; +typedef GpuViewport *GpuViewportArray; + +typedef struct GpuExtent2d { + u32 width; + u32 height; +} GpuExtent2d; + +typedef struct GpuExtent3d { + u32 width; + u32 height; + u32 depth; +} GpuExtent3d; + +typedef struct GpuOffset2d { + i32 x; + i32 y; +} GpuOffset2d; + +typedef struct GpuOffset3d { + i32 x; + i32 y; + i32 z; +} GpuOffset3d; + +typedef struct GpuRect2d { + GpuOffset2d offset; + GpuExtent2d extent; +} GpuRect2d; +typedef GpuRect2d *GpuRect2dArray; + +typedef struct GpuPipelineViewportStateInfo { + GpuViewportArray viewports; + GpuRect2dArray scissors; +} GpuPipelineViewportStateInfo; + +typedef enum GpuPolygonMode { + GPU_POLYGON_MODE_FILL, + GPU_POLYGON_MODE_LINE, + GPU_POLYGON_MODE_POINT, +} GpuPolygonMode; + +typedef enum GpuCullMode { + GPU_CULL_MODE_NONE, + GPU_CULL_MODE_FRONT, + GPU_CULL_MODE_BACK, + GPU_CULL_MODE_FRONT_AND_BACK, +} GpuCullMode; + +typedef enum GpuFrontFace { + GPU_FRONT_FACE_COUNTER_CLOCKWISE, + GPU_FRONT_FACE_CLOCKWISE, +} GpuFrontFace; + +typedef struct GpuPipelineRasterizationStateInfo { + b32 depth_clamp_enable; + b32 rasterizer_discard_enable; + GpuPolygonMode polygon_mode; + GpuCullMode cull_mode; + GpuFrontFace front_face; + b32 depth_bias_enable; + f32 depth_bias_constant_factor; + f32 depth_bias_clamp; + f32 depth_bias_slope_factor; + f32 line_width; +} GpuPipelineRasterizationStateInfo; + +typedef struct GpuPipelineMultisampleStateInfo { + GpuSampleCount rasterization_samples; + b32 sample_shading_enable; + f32 min_sample_shading; +} GpuPipelineMultisampleStateInfo; + +typedef enum GpuStencilOp { + GPU_STENCIL_OP_KEEP, + GPU_STENCIL_OP_ZERO, + GPU_STENCIL_OP_REPLACE, + GPU_STENCIL_OP_INCREMENT_AND_CLAMP, + GPU_STENCIL_OP_DECREMENT_AND_CLAMP, + GPU_STENCIL_OP_INVERT, + GPU_STENCIL_OP_INCREMENT_AND_WRAP, + GPU_STENCIL_OP_DECREMENT_AND_WRAP, +} GpuStencilOp; + +typedef struct GpuStencilOpState { + GpuStencilOp fail_op; + GpuStencilOp pass_op; + GpuStencilOp depthFail_op; + GpuCompareOp compare_op; + u32 compare_mask; + u32 write_mask; + u32 reference; +} GpuStencilOpState; + +typedef struct GpuPipelineDepthStencilStateInfo { + b32 depth_test_enable; + b32 depth_write_enable; + GpuCompareOp depth_compare_op; + b32 depth_bounds_test_enable; + b32 stencil_test_enable; + GpuStencilOpState front; + GpuStencilOpState back; + f32 min_depth_bounds; + f32 max_depth_bounds; +} GpuPipelineDepthStencilStateInfo; + +typedef enum GpuBlendFactor { + GPU_BLEND_FACTOR_ZERO, + GPU_BLEND_FACTOR_ONE, + GPU_BLEND_FACTOR_SRC_COLOR, + GPU_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, + GPU_BLEND_FACTOR_DST_COLOR, + GPU_BLEND_FACTOR_ONE_MINUS_DST_COLOR, + GPU_BLEND_FACTOR_SRC_ALPHA, + GPU_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, + GPU_BLEND_FACTOR_DST_ALPHA, + GPU_BLEND_FACTOR_ONE_MINUS_DST_ALPHA, + GPU_BLEND_FACTOR_CONSTANT_COLOR, + GPU_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR, + GPU_BLEND_FACTOR_CONSTANT_ALPHA, + GPU_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA, + GPU_BLEND_FACTOR_SRC_ALPHA_SATURATE, + GPU_BLEND_FACTOR_SRC1_COLOR, + GPU_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, + GPU_BLEND_FACTOR_SRC1_ALPHA, + GPU_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, +} GpuBlendFactor; + +typedef enum GpuBlendOp { + GPU_BLEND_OP_ADD, + GPU_BLEND_OP_SUBTRACT, + GPU_BLEND_OP_REVERSE_SUBTRACT, + GPU_BLEND_OP_MIN, + GPU_BLEND_OP_MAX, + GPU_BLEND_OP_ZERO_EXT, + GPU_BLEND_OP_SRC_EXT, + GPU_BLEND_OP_DST_EXT, + GPU_BLEND_OP_SRC_OVER_EXT, + GPU_BLEND_OP_DST_OVER_EXT, + GPU_BLEND_OP_SRC_IN_EXT, + GPU_BLEND_OP_DST_IN_EXT, + GPU_BLEND_OP_SRC_OUT_EXT, + GPU_BLEND_OP_DST_OUT_EXT, + GPU_BLEND_OP_SRC_ATOP_EXT, + GPU_BLEND_OP_DST_ATOP_EXT, + GPU_BLEND_OP_XOR_EXT, + GPU_BLEND_OP_MULTIPLY_EXT, + GPU_BLEND_OP_SCREEN_EXT, + GPU_BLEND_OP_OVERLAY_EXT, + GPU_BLEND_OP_DARKEN_EXT, + GPU_BLEND_OP_LIGHTEN_EXT, + GPU_BLEND_OP_COLORDODGE_EXT, + GPU_BLEND_OP_COLORBURN_EXT, + GPU_BLEND_OP_HARDLIGHT_EXT, + GPU_BLEND_OP_SOFTLIGHT_EXT, + GPU_BLEND_OP_DIFFERENCE_EXT, + GPU_BLEND_OP_EXCLUSION_EXT, + GPU_BLEND_OP_INVERT_EXT, + GPU_BLEND_OP_INVERT_RGB_EXT, + GPU_BLEND_OP_LINEARDODGE_EXT, + GPU_BLEND_OP_LINEARBURN_EXT, + GPU_BLEND_OP_VIVIDLIGHT_EXT, + GPU_BLEND_OP_LINEARLIGHT_EXT, + GPU_BLEND_OP_PINLIGHT_EXT, + GPU_BLEND_OP_HARDMIX_EXT, + GPU_BLEND_OP_HSL_HUE_EXT, + GPU_BLEND_OP_HSL_SATURATION_EXT, + GPU_BLEND_OP_HSL_COLOR_EXT, + GPU_BLEND_OP_HSL_LUMINOSITY_EXT, + GPU_BLEND_OP_PLUS_EXT, + GPU_BLEND_OP_PLUS_CLAMPED_EXT, + GPU_BLEND_OP_PLUS_CLAMPED_ALPHA_EXT, + GPU_BLEND_OP_PLUS_DARKER_EXT, + GPU_BLEND_OP_MINUS_EXT, + GPU_BLEND_OP_MINUS_CLAMPED_EXT, + GPU_BLEND_OP_CONTRAST_EXT, + GPU_BLEND_OP_INVERT_OVG_EXT, + GPU_BLEND_OP_RED_EXT, + GPU_BLEND_OP_GREEN_EXT, + GPU_BLEND_OP_BLUE_EXT, + GPU_BLEND_OP_MAX_ENUM, +} GpuBlendOp; + +typedef enum GpuColorComponentFlags { + GPU_COLOR_COMPONENT_R_BIT = wpU64Const(1) << 0, + GPU_COLOR_COMPONENT_G_BIT = wpU64Const(1) << 1, + GPU_COLOR_COMPONENT_B_BIT = wpU64Const(1) << 2, + GPU_COLOR_COMPONENT_A_BIT = wpU64Const(1) << 3, +} GpuColorComponentFlags; + +typedef enum GpuLogicOp { + GPU_LOGIC_OP_CLEAR, + GPU_LOGIC_OP_AND, + GPU_LOGIC_OP_AND_REVERSE, + GPU_LOGIC_OP_COPY, + GPU_LOGIC_OP_AND_INVERTED, + GPU_LOGIC_OP_NO_OP, + GPU_LOGIC_OP_XOR, + GPU_LOGIC_OP_OR, + GPU_LOGIC_OP_NOR, + GPU_LOGIC_OP_EQUIVALENT, + GPU_LOGIC_OP_INVERT, + GPU_LOGIC_OP_OR_REVERSE, + GPU_LOGIC_OP_COPY_INVERTED, + GPU_LOGIC_OP_OR_INVERTED, + GPU_LOGIC_OP_NAND, + GPU_LOGIC_OP_SET, +} GpuLogicOp; + +typedef struct GpuPipelineColorBlendAttachmentState { + b32 blend_enable; + GpuBlendFactor src_color_blend_factor; + GpuBlendFactor dst_color_blend_factor; + GpuBlendOp color_blend_op; + GpuBlendFactor src_alpha_blend_factor; + GpuBlendFactor dst_alpha_blend_factor; + GpuBlendOp alpha_blend_op; + GpuColorComponentFlags color_write_mask; +} GpuPipelineColorBlendAttachmentState; +typedef GpuPipelineColorBlendAttachmentState *GpuPipelineColorBlendAttachmentStateArray; + +typedef struct GpuPipelineColorBlendStateInfo { + GpuPipelineColorBlendAttachmentStateArray attachments; + b32 logic_op_enable; + GpuLogicOp logic_op; + f32 blend_constants[4]; +} GpuPipelineColorBlendStateInfo; + +typedef struct GpuPipeline GpuPipeline; +typedef GpuPipeline **GpuPipelinePtrArray; + +typedef struct GpuGraphicsPipelineCreateInfo { + GpuPipelineVertexInputStateInfo vertex_input_state; + GpuPipelineInputAssemblyStateInfo input_assembly_state; + GpuPipelineTessellationStateInfo tesselation_state; + GpuPipelineViewportStateInfo viewport_state; + GpuPipelineRasterizationStateInfo rasterization_state; + GpuPipelineMultisampleStateInfo multisample_state; + GpuPipelineDepthStencilStateInfo depth_stencil_state; + GpuPipelineColorBlendStateInfo color_blend_state; + GpuPipelineShaderStageInfoArray shader_stages; + GpuPipelineLayout *layout; +} GpuGraphicsPipelineCreateInfo; +typedef GpuGraphicsPipelineCreateInfo *GpuGraphicsPipelineCreateInfoArray; + +typedef struct GpuGraphicsPipelinesCreateRequest { + GpuDevice *device; + GpuGraphicsPipelineCreateInfoArray infos; +} GpuGraphicsPipelinesCreateRequest; + +typedef struct GpuComputePipelineCreateInfo { + GpuPipelineShaderStageInfo shader_stage; + GpuPipelineLayout *layout; +} GpuComputePipelineCreateInfo; +typedef GpuComputePipelineCreateInfo *GpuComputePipelineCreateInfoArray; + +typedef struct GpuComputePipelinesCreateRequest { + GpuDevice *device; + GpuComputePipelineCreateInfoArray infos; +} GpuComputePipelinesCreateRequest; + +GpuInstance *gpuInit(const WpAllocator *allocator, GpuInitRequest request); +GpuPhysicalDevice gpuFindPhysicalDevice(const WpAllocator *allocator, const WpAllocator *temp, + GpuPhysicalDeviceFindRequest request); +GpuSurface *gpuCreateSurface(const WpAllocator *allocator, GpuSurfaceCreateRequest request); +void gpuDestroySurface(GpuSurface *surface); +GpuDevice *gpuCreateDevice(const WpAllocator *allocator, GpuPhysicalDevice physical_device); +void gpuDestroyDevice(GpuDevice *device); +GpuSwapchain *gpuCreateSwapchain(const WpAllocator *allocator, const WpAllocator *temp, + GpuSwapchainCreateRequest request); +void gpuDestroySwapchain(GpuSwapchain *swapchain); +u64 gpuGetSwapchainImageCount(GpuSwapchain *swapchain); +GpuSampler *gpuCreateSampler(const WpAllocator *allocator, GpuSamplerCreateRequest request); +void gpuDestroySampler(GpuSampler *sampler); +GpuImage *gpuCreateImage(const WpAllocator *allocator, GpuImageCreateRequest request); +void gpuDestroyImage(GpuImage *image); +ivec3s gpuImageGetSize(GpuImage *image); +GpuBuffer gpuCreateBuffer(const WpAllocator *allocator, GpuBufferCreateRequest request); +void gpuDestroyBuffer(GpuBuffer *buffer); +GpuFence *gpuCreateFence(const WpAllocator *allocator, GpuDevice *device); +void gpuDestroyFence(GpuFence *fence); +void gpuResetFence(GpuFence *fence); +GpuSemaphore *gpuCreateSemaphore(const WpAllocator *allocator, GpuDevice *device); +void gpuDestroySemaphore(GpuSemaphore *semaphore); +GpuCommandPool *gpuCreateCommandPool(const WpAllocator *allocator, GpuDevice *device); +void gpuDestroyCommandPool(GpuCommandPool *pool); +void gpuResetCommandPool(GpuCommandPool *pool); +GpuCommandBufferPtrArray gpuAllocateCommandBuffers(const WpAllocator *allocator, const WpAllocator *temp, + GpuCommandBufferAllocateRequest request); +void gpuBeginCommandBuffer(GpuCommandBuffer *buffer); +void gpuEndCommandBuffer(GpuCommandBuffer *buffer); +void gpuSubmitCommandBuffers(const WpAllocator *temp, GpuCommandBuffersSubmitRequest request); +void gpuResetCommandBuffer(GpuCommandBuffer *buffer); +GpuDescriptorPool *gpuCreateDescriptorPool(const WpAllocator *allocator, GpuDescriptorPoolCreateRequest request); +void gpuDestroyDescriptorPool(GpuDescriptorPool *pool); +void gpuResetDescriptorPool(GpuDescriptorPool *pool); +GpuDescriptorSetLayout *gpuCreateDescriptorSetLayout(const WpAllocator *allocator, const WpAllocator *temp, + GpuDescriptorSetLayoutCreateRequest request); +void gpuDestroyDescriptorSetLayout(GpuDescriptorSetLayout *layout); +GpuDescriptorSetPtrArray gpuAllocateDescriptorSets(const WpAllocator *allocator, const WpAllocator *temp, + GpuDescriptorSetAllocateRequest request); +void gpuWriteDescriptorSets(const WpAllocator *temp, GpuDescriptorSetWriteRequest request); +GpuShader *gpuCreateShader(const WpAllocator *allocator, GpuShaderCreateRequest request); +void gpuDestroyShader(GpuShader *shader); +GpuPipelineLayout *gpuCreatePipelineLayout(const WpAllocator *allocator, const WpAllocator *temp, + GpuPipelineLayoutCreateRequest request); +void gpuDestroyPipelineLayout(GpuPipelineLayout *layout); +GpuPipelinePtrArray gpuCreateGraphicsPipelines(const WpAllocator *allocator, const WpAllocator *temp, + GpuGraphicsPipelinesCreateRequest request); +GpuPipelinePtrArray gpuCreateComputePipelines(const WpAllocator *allocator, const WpAllocator *temp, + GpuComputePipelinesCreateRequest request); +void gpuDestroyPipeline(GpuPipeline *pipeline); +void gpuDeviceWaitIdle(GpuDevice *device); + +#ifdef WP_PLATFORM_CPP +END_C_LINKAGE +#endif + +#endif // !GPU_H diff --git a/src/gpu/gpu_c_src.c b/src/gpu/gpu_c_src.c new file mode 100644 index 0000000..79db82b --- /dev/null +++ b/src/gpu/gpu_c_src.c @@ -0,0 +1,7 @@ +// vim:fileencoding=utf-8:foldmethod=marker + +#ifdef USE_VULKAN_RENDER_BACKEND +#include "vulkan/vk_gpu.c" +#else +#error "No render backend selected" +#endif diff --git a/src/gpu/gpu_cc_src.cpp b/src/gpu/gpu_cc_src.cpp new file mode 100644 index 0000000..f322788 --- /dev/null +++ b/src/gpu/gpu_cc_src.cpp @@ -0,0 +1,8 @@ +// vim:fileencoding=utf-8:foldmethod=marker + +#ifdef USE_VULKAN_RENDER_BACKEND +#include "vulkan/vma.cpp" +#include "vulkan/vulkan_profiles/vulkan_profiles.cpp" +#else +#error "No render backend selected" +#endif diff --git a/src/gpu/gpu_inc.h b/src/gpu/gpu_inc.h new file mode 100644 index 0000000..ceb4f03 --- /dev/null +++ b/src/gpu/gpu_inc.h @@ -0,0 +1,8 @@ +// vim:fileencoding=utf-8:foldmethod=marker + +#ifndef GPU_INC_H +#define GPU_INC_H + +#include "gpu.h" + +#endif // !GPU_INC_H diff --git a/src/gpu/vulkan/vk_gpu.c b/src/gpu/vulkan/vk_gpu.c new file mode 100644 index 0000000..3b04ebb --- /dev/null +++ b/src/gpu/vulkan/vk_gpu.c @@ -0,0 +1,2264 @@ +// vim:fileencoding=utf-8:foldmethod=marker + +#include "vulkan_profiles/vulkan_profiles.h" +#include "../gpu.h" +#include "../../config/config_inc.h" +#include "../../utils/utils_inc.h" +#include "../../window/window_inc.h" +#include "../../wapp/wapp.h" +#include "../../cglm/struct.h" +#include + +#ifdef USE_SDL_WINDOW_BACKEND +#include +#else +#error "No window backend selected" +#endif + +#include +#include +#include + +#define max(a, b) ((a) > (b) ? (a) : (b)) +#define min(a, b) ((a) < (b) ? (a) : (b)) +#define clamp(value, minimum, maximum) (max((minimum), (min((value), (maximum))))) + +wp_intern WpLogger logger = wpLogMakeLogger(wpStr8LitRo("Vulkan Wrapper")); + +typedef VkPhysicalDevice *VkPhysicalDeviceArray; +typedef VkQueueFamilyProperties2 *VkQueueFamilyProperties2Array; +typedef VkImage *VkImageArray; +typedef VkImageView *VkImageViewArray; +typedef VkFormat *VkFormatArray; +typedef VkSurfaceFormat2KHR *VkSurfaceFormat2KHRArray; +typedef VkCommandBuffer *VkCommandBufferArray; +typedef VkDescriptorPoolSize *VkDescriptorPoolSizeArray; +typedef VkDescriptorBindingFlags *VkDescriptorBindingFlagsArray; +typedef VkDescriptorSetLayoutBindingFlagsCreateInfo *VkDescriptorSetLayoutBindingFlagsCreateInfoArray; +typedef VkDescriptorSetLayoutBinding *VkDescriptorSetLayoutBindingArray; +typedef VkDescriptorSetLayout *VkDescriptorSetLayoutArray; +typedef VkDescriptorSetVariableDescriptorCountAllocateInfo *VkDescriptorSetVariableDescriptorCountAllocateInfoArray; +typedef VkDescriptorSet *VkDescriptorSetArray; +typedef VkWriteDescriptorSet *VkWriteDescriptorSetArray; +typedef VkDescriptorBufferInfo *VkDescriptorBufferInfoArray; +typedef VkDescriptorImageInfo *VkDescriptorImageInfoArray; +typedef VkPushConstantRange *VkPushConstantRangeArray; +typedef VkComputePipelineCreateInfo *VkComputePipelineCreateInfoArray; +typedef VkPipeline *VkPipelineArray; + +struct GpuInstance { + VkInstance vk_instance; + VpProfileProperties profile; +}; + +struct GpuPhysicalDeviceInternal { + VkPhysicalDevice vk_physical_device; + u32 queue_family_index; +}; + +struct GpuSurface { + VkSurfaceCapabilitiesKHR capabilities; + const GpuInstance *instance; + VkSurfaceKHR vk_surface; + const Window *window; +}; + +struct GpuDevice { + GpuPhysicalDevice physical_device; + VkDevice vk_device; + VkQueue vk_queue; + VmaAllocator allocator; +}; + +struct GpuSampler { + GpuDevice *device; + VkSampler vk_sampler; +}; + +struct GpuImage { + GpuDevice *device; + VmaAllocation allocation; + VkImage vk_image; + VkImageView vk_view; + ivec3s size; + VkFormat format; +}; + +struct GpuSwapchain { + GpuDevice *device; + VkSwapchainKHR vk_swapchain; + VkExtent2D extent; + GpuImageArray images; + GpuImage depth; +}; + +struct GpuBufferInternal { + VmaAllocationInfo allocation_info; + VkBuffer vk_buffer; + VmaAllocation allocation; +}; + +struct GpuFence { + GpuDevice *device; + VkFence vk_fence; +}; + +struct GpuSemaphore { + GpuDevice *device; + VkSemaphore vk_semaphore; +}; + +struct GpuCommandPool { + GpuDevice *device; + VkCommandPool vk_pool; +}; + +struct GpuCommandBuffer { + GpuCommandPool *pool; + VkCommandBuffer vk_buffer; +}; + +struct GpuDescriptorPool { + GpuDevice *device; + VkDescriptorPool vk_pool; +}; + +struct GpuDescriptorSetLayout { + GpuDevice *device; + VkDescriptorSetLayout vk_layout; + u32 variable_descriptor_count; +}; + +struct GpuDescriptorSet { + GpuDescriptorPool *pool; + GpuDescriptorSetLayout *layout; + VkDescriptorSet vk_set; +}; + +struct GpuShader { + GpuDevice *device; + VkShaderModule vk_shader; +}; + +struct GpuPipelineLayout { + GpuDevice *device; + VkPipelineLayout vk_layout; +}; + +struct GpuPipeline { + GpuPipelineLayout *layout; + VkPipeline vk_pipeline; +}; + +typedef struct VkExtensions { + const char *const *extensions; + u32 count; +} VkExtensions; + +typedef enum GpuDescriptorCategory { + GPU_DESCRIPTOR_CATEGORY_IMAGE, + GPU_DESCRIPTOR_CATEGORY_BUFFER, + GPU_DESCRIPTOR_CATEGORY_TEXEL_BUFFER, + GPU_DESCRIPTOR_CATEGORY_UNIFORM_BLOCK, +} GpuDescriptorCategory; + +wp_intern VkExtensions getInstanceExtensions(void); +wp_intern GpuPhysicalDeviceType vkDeviceTypeToGpuDeviceType(VkPhysicalDeviceType type); +wp_intern VkPhysicalDeviceType gpuDeviceTypeToVkDeviceType(GpuPhysicalDeviceType type); +wp_intern i32 findQueueFamily(const WpAllocator *allocator, VkInstance instance, + VkPhysicalDevice physical_device, GpuPhysicalDeviceOps ops); +wp_intern VkQueueFlags queueFlagsFromOps(GpuPhysicalDeviceOps ops); +wp_intern b8 presentationSupported(VkInstance instance, VkPhysicalDevice device, + u32 queue_family_index); +wp_intern b8 windowBackendCreateSurface(const Window *window, VkInstance instance, + VkSurfaceKHR *surface); +wp_intern VkFormat vkFormatFromGpuFormat(GpuFormat format); +wp_intern GpuFormat gpuFormatFromVkFormat(VkFormat format); +wp_intern VkColorSpaceKHR vkColorspaceFromGpuColorspace(GpuColorspace colorspace); +wp_intern GpuColorspace gpuColorspaceFromVkColorspace(VkColorSpaceKHR colorspace); +wp_intern VkPresentModeKHR vkPresentModeFromGpuPresentMode(GpuPresentMode mode); +wp_intern GpuPresentMode gpuPresentModeFromVkPresentMode(VkPresentModeKHR mode); +wp_intern VkImageType vkImageTypeFromGpuImageType(GpuImageType type); +wp_intern GpuImageType gpuImageTypeFromVkImageType(VkImageType type); +wp_intern VkImageViewType vkImageViewTypeFromGpuImageType(GpuImageType type); +wp_intern GpuImageType gpuImageTypeFromVkImageViewType(VkImageViewType type); +wp_intern VkSampleCountFlagBits vkSampleCountFromGpuSampleCount(GpuSampleCount samples); +wp_intern GpuSampleCount gpuSampleCountFromVkSampleCount(VkSampleCountFlagBits samples); +wp_intern VkImageTiling vkImageTilingFromGpuImageTiling(GpuImageTiling tiling); +wp_intern GpuImageTiling gpuImageTilingFromVkImageTiling(VkImageTiling tiling); +wp_intern VkImageUsageFlags vkImageUsageFromGpuImageUsage(GpuImageUsage usage); +wp_intern GpuImageUsage gpuImageUsageFromVkImageUsage(VkImageUsageFlags usage); +wp_intern VkImageLayout vkImageLayoutFromGpuImageLayout(GpuImageLayout layout); +wp_intern GpuImageLayout gpuImageLayoutFromVkImageLayout(VkImageLayout layout); +wp_intern VkImageAspectFlags vkImageAspectFromGpuImageAspect(GpuImageAspect aspect); +wp_intern GpuImageAspect gpuImageAspectFromVkImageAspect(VkImageAspectFlags aspect); +wp_intern VkBufferUsageFlags2 vkBufferUsageFromGpuBufferUsage(GpuBufferUsage usage); +wp_intern GpuBufferUsage gpuBufferUsageFromVkBufferUsage(VkBufferUsageFlags2 usage); +wp_intern VkPipelineStageFlags2 vkPipelineStagesFromGpuPipelineStages(GpuPipelineStageFlags stage); +wp_intern GpuPipelineStageFlags gpuPipelineStagesFromVkPipelineStages(VkPipelineStageFlags2 stage); +wp_intern VkAccessFlags2 vkAccessFlagsFromGpuAccessFlags(GpuAccessFlags access); +wp_intern GpuAccessFlags gpuAccessFlagsFromVkAccessFlags(VkAccessFlags2 access); +wp_intern VkFilter vkFilterFromGpuFilter(GpuFilter filter); +wp_intern GpuFilter gpuFilterFromVkFilter(VkFilter filter); +wp_intern VkSamplerMipmapMode vkSamplerMipmapModeFromGpuSamplerMipmapMode(GpuSamplerMipmapMode mode); +wp_intern GpuSamplerMipmapMode gpuSamplerMipmapModeFromVkSamplerMipmapMode(VkSamplerMipmapMode mode); +wp_intern VkSamplerAddressMode vkSamplerAddressModeFromGpuSamplerAddressMode(GpuSamplerAddressMode mode); +wp_intern GpuSamplerAddressMode gpuSamplerAddressModeFromVkSamplerAddressMode(VkSamplerAddressMode mode); +wp_intern VkCompareOp vkCompareOpFromGpuCompareOp(GpuCompareOp op); +wp_intern GpuCompareOp gpuCompareOpFromVkCompareOp(VkCompareOp op); +wp_intern VkDescriptorType vkDescriptorTypeFromGpuDescriptorType(GpuDescriptorType type); +wp_intern GpuDescriptorType gpuDescriptorTypeFromVkDescriptorType(VkDescriptorType type); +wp_intern VkShaderStageFlags vkShaderStageFromGpuShaderStage(GpuShaderStage stages); +wp_intern GpuShaderStage gpuShaderStageFromVkShaderStage(VkShaderStageFlags stages); +wp_intern GpuDescriptorCategory descriptorCategoryFromDescriptorType(GpuDescriptorType type); +wp_intern u64 retrieveDescriptorImageInfos(const GpuDescriptorSetWriteInfo *info, + VkWriteDescriptorSet *desc_set_write, + VkDescriptorImageInfoArray desc_img_infos, + u64 img_info_offset); +wp_intern u64 retrieveDescriptorBufferInfos(const GpuDescriptorSetWriteInfo *info, + VkWriteDescriptorSet *desc_set_write, + VkDescriptorBufferInfoArray desc_buf_infos, + u64 buf_info_offset); + +GpuInstance *gpuInit(const WpAllocator *allocator, GpuInitRequest request) { + assertWithLogger(volkInitialize() == VK_SUCCESS, &logger, "Failed to initialise volk"); + + VpProfileProperties profile = { + .profileName = VP_TEST_WINDOW_RENDERER_NAME, + .specVersion = VP_TEST_WINDOW_RENDERER_SPEC_VERSION, + }; + + VkExtensions instance_extensions = getInstanceExtensions(); + + VkBool32 supported = VK_FALSE; + + vpGetInstanceProfileSupport(NULL, &profile, &supported); + assertWithLogger(supported, &logger, "Profile not supported"); + + GpuInstance *instance = wpMemAllocatorAlloc(allocator, sizeof(GpuInstance)); + assertWithLogger(instance != NULL, &logger, "Failed to allocate instance"); + + VkApplicationInfo app_info = { + .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, + .apiVersion = VP_TEST_WINDOW_RENDERER_MIN_API_VERSION, + .pApplicationName = request.app_name, + .applicationVersion = request.app_version, + }; + + VkInstanceCreateInfo instance_info = { + .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, + .pApplicationInfo = &app_info, + .enabledExtensionCount = instance_extensions.count, + .ppEnabledExtensionNames = instance_extensions.extensions, + }; + + VpInstanceCreateInfo vp_instance_info = { + .pCreateInfo = &instance_info, + .enabledFullProfileCount = 1, + .pEnabledFullProfiles = &profile, + }; + + assertWithLogger(vpCreateInstance(&vp_instance_info, NULL, &instance->vk_instance) == VK_SUCCESS, &logger, + "Failed to create Vulkan instance"); + + instance->profile = profile; + + volkLoadInstance(instance->vk_instance); + wpLogInfo(&logger, wpStr8Lit("Initialised Vulkan GPU successfully")); + + return instance; +} + +GpuPhysicalDevice gpuFindPhysicalDevice(const WpAllocator *allocator, const WpAllocator *temp, + GpuPhysicalDeviceFindRequest request) { + VkResult vk_result = VK_SUCCESS; + + u32 count = 0; + vk_result = vkEnumeratePhysicalDevices(request.instance->vk_instance, &count, NULL); + assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to get physical device count"); + + VkPhysicalDeviceArray physical_devices = wpArrayAllocCapacity(VkPhysicalDevice, temp, count, + WP_ARRAY_INIT_FILLED); + assertWithLogger(physical_devices != NULL, &logger, "Failed to allocate physical devices"); + + vk_result = vkEnumeratePhysicalDevices(request.instance->vk_instance, &count, physical_devices); + assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to enumerate physical devices"); + + VkBool32 supported = VK_FALSE; + WpStr8 msg = wpStr8Buf(4096); + + VkPhysicalDevice device = VK_NULL_HANDLE; + i32 queue_family_index = -1; + for (u32 i = 0; i < count; ++i) { + VkPhysicalDeviceProperties2 properties = { .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2 }; + vkGetPhysicalDeviceProperties2(physical_devices[i], &properties); + + if (properties.properties.apiVersion < VP_TEST_WINDOW_RENDERER_MIN_API_VERSION) { + continue; + } + + VkResult profile_support = vpGetPhysicalDeviceProfileSupport(request.instance->vk_instance, physical_devices[i], + &request.instance->profile, &supported); + b8 device_type_match = gpuDeviceTypeToVkDeviceType(request.type) == properties.properties.deviceType; + if (profile_support != VK_SUCCESS || !supported || !device_type_match) { + continue; + } + + queue_family_index = findQueueFamily(temp, request.instance->vk_instance, physical_devices[i], + request.ops); + if (queue_family_index == -1) { + continue; + } + + device = physical_devices[i]; + + wpStr8Format(&msg, "Found suitable physical device (Name: %s)", properties.properties.deviceName); + wpLogDebug(&logger, msg); + + break; + } + + GpuPhysicalDevice physical_device = {0}; + assertWithLogger(device != NULL && queue_family_index > -1, &logger, "Failed to find a suitable physical device"); + + physical_device.internal = wpMemAllocatorAlloc(allocator, sizeof(GpuPhysicalDeviceInternal)); + assertWithLogger(physical_device.internal != NULL, &logger, "Failed to allocate physical device internal"); + + physical_device.instance = request.instance; + physical_device.internal->vk_physical_device = device; + physical_device.internal->queue_family_index = (u32)queue_family_index; + physical_device.type = request.type; + + return physical_device; +} + +GpuSurface *gpuCreateSurface(const WpAllocator *allocator, GpuSurfaceCreateRequest request) { + VkResult vk_result = VK_SUCCESS; + GpuSurface *surface = wpMemAllocatorAlloc(allocator, sizeof(GpuSurface)); + assertWithLogger(surface != NULL, &logger, "Failed to allocate surface"); + + b8 surface_created = windowBackendCreateSurface(request.window, request.physical_device.instance->vk_instance, + &surface->vk_surface); + assertWithLogger(surface_created, &logger, "Failed to create Vulkan surface"); + + vk_result = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(request.physical_device.internal->vk_physical_device, + surface->vk_surface, &surface->capabilities); + assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to get surface capabilities"); + + surface->instance = request.physical_device.instance; + surface->window = request.window; + + WpStr8 msg = wpStr8Buf(4096); + wpStr8Format(&msg, "Created Vulkan surface %p", surface->vk_surface); + wpLogDebug(&logger, msg); + + return surface; +} + +void gpuDestroySurface(GpuSurface *surface) { + vkDestroySurfaceKHR(surface->instance->vk_instance, surface->vk_surface, NULL); +} + +GpuDevice *gpuCreateDevice(const WpAllocator *allocator, GpuPhysicalDevice physical_device) { + VkResult vk_result = VK_SUCCESS; + GpuDevice *device = wpMemAllocatorAlloc(allocator, sizeof(GpuDevice)); + assertWithLogger(device != NULL, &logger, "Failed to allocate device internal"); + + device->physical_device = physical_device; + + f32 queue_priority = 1.0f; + VkDeviceQueueCreateInfo device_queue_create_info = { + .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, + .queueCount = 1, + .queueFamilyIndex = physical_device.internal->queue_family_index, + .pQueuePriorities = &queue_priority, + }; + + VkDeviceCreateInfo device_create_info = { + .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, + .queueCreateInfoCount = 1, + .pQueueCreateInfos = &device_queue_create_info, + }; + + VpDeviceCreateInfo vp_device_create_info = { + .pCreateInfo = &device_create_info, + .enabledFullProfileCount = 1, + .pEnabledFullProfiles = &physical_device.instance->profile, + }; + + vk_result = vpCreateDevice(physical_device.internal->vk_physical_device, &vp_device_create_info, + NULL, &device->vk_device); + assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create Vulkan device"); + + vkGetDeviceQueue(device->vk_device, device->physical_device.internal->queue_family_index, + 0, &device->vk_queue); + + VmaVulkanFunctions vk_functions = { + .vkGetInstanceProcAddr = vkGetInstanceProcAddr, + .vkGetDeviceProcAddr = vkGetDeviceProcAddr, + .vkCreateImage = vkCreateImage, + }; + + VmaAllocatorCreateInfo allocator_create_info = { + .flags = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT | + VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT | + VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE5_BIT, + .instance = physical_device.instance->vk_instance, + .physicalDevice = physical_device.internal->vk_physical_device, + .device = device->vk_device, + .pVulkanFunctions = &vk_functions, + }; + + vk_result = vmaCreateAllocator(&allocator_create_info, &device->allocator); + assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create Vulkan memory allocator"); + + WpStr8 msg = wpStr8Buf(4096); + wpStr8Format(&msg, "Created Vulkan device %p", device->vk_device); + wpLogDebug(&logger, msg); + + return device; +} + +void gpuDestroyDevice(GpuDevice *device) { + vmaDestroyAllocator(device->allocator); + vkDestroyDevice(device->vk_device, NULL); +} + +GpuSwapchain *gpuCreateSwapchain(const WpAllocator *allocator, const WpAllocator *temp, + GpuSwapchainCreateRequest request) { + VkResult vk_result = VK_SUCCESS; + + u32 surface_formats_count = 0; + + VkPhysicalDeviceSurfaceInfo2KHR surface_info = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR, + .surface = request.surface->vk_surface, + }; + vk_result = vkGetPhysicalDeviceSurfaceFormats2KHR(request.device->physical_device.internal->vk_physical_device, + &surface_info, &surface_formats_count, NULL); + assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to query surface formats count"); + + VkSurfaceFormat2KHRArray format_pairs = wpArrayAllocCapacity(VkSurfaceFormat2KHR, temp, + surface_formats_count, WP_ARRAY_INIT_FILLED); + assertWithLogger(format_pairs != NULL, &logger, "Failed to allocate temp format array"); + + for (u32 i = 0; i < surface_formats_count; ++i) { + format_pairs[i].sType = VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR; + } + + vk_result = vkGetPhysicalDeviceSurfaceFormats2KHR(request.device->physical_device.internal->vk_physical_device, + &surface_info, &surface_formats_count, format_pairs); + assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to get surface formats"); + + VkFormat requested_format = vkFormatFromGpuFormat(request.format); + VkColorSpaceKHR requested_colorspace = vkColorspaceFromGpuColorspace(request.colorspace); + b8 surface_format_supported = false; + for (u32 i = 0; i < surface_formats_count; ++i) { + if (requested_format == format_pairs[i].surfaceFormat.format && + requested_colorspace == format_pairs[i].surfaceFormat.colorSpace) { + surface_format_supported = true; + break; + } + } + assertWithLogger(surface_format_supported, &logger, "Requested surface format not supported"); + + GpuSwapchain *swapchain = wpMemAllocatorAlloc(allocator, sizeof(GpuSwapchain)); + assertWithLogger(swapchain != NULL, &logger, "Failed to allocate swapchain internal"); + + swapchain->extent = request.surface->capabilities.currentExtent; + // Handle Wayland's special value (0xffffffff), which indicate that the surface size will + // basically be determined by the size of the surface + if (swapchain->extent.width == 0xffffffff) { + swapchain->extent.width = (u32)request.surface->window->size.x; + swapchain->extent.height = (u32)request.surface->window->size.y; + } + + u32 image_count = clamp(request.ideal_image_count, + request.surface->capabilities.minImageCount, + request.surface->capabilities.maxImageCount > 0 ? + request.surface->capabilities.maxImageCount : + request.ideal_image_count); + + VkSwapchainCreateInfoKHR swapchain_create_info = { + .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, + .surface = request.surface->vk_surface, + .minImageCount = image_count, + .imageFormat = requested_format, + .imageColorSpace = requested_colorspace, + .imageExtent = swapchain->extent, + .imageArrayLayers = 1, + .imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + .imageSharingMode = VK_SHARING_MODE_EXCLUSIVE, + .queueFamilyIndexCount = 1, + .pQueueFamilyIndices = &request.device->physical_device.internal->queue_family_index, + .preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR, + .compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, + .presentMode = vkPresentModeFromGpuPresentMode(request.present_mode), + }; + + vk_result = vkCreateSwapchainKHR(request.device->vk_device, &swapchain_create_info, NULL, + &swapchain->vk_swapchain); + assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create Vulkan swapchain"); + + u32 swapchain_image_count = 0; + vk_result = vkGetSwapchainImagesKHR(request.device->vk_device, swapchain->vk_swapchain, + &swapchain_image_count, NULL); + assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to retrieve swapchain image count"); + + VkImageArray images = wpArrayAllocCapacity(VkImage, temp, swapchain_image_count, WP_ARRAY_INIT_FILLED); + swapchain->images = wpArrayAllocCapacity(GpuImage, allocator, swapchain_image_count, WP_ARRAY_INIT_FILLED); + assertWithLogger(images != NULL && swapchain->images != NULL, &logger, "Failed to allocate swapchain images"); + + vk_result = vkGetSwapchainImagesKHR(request.device->vk_device, swapchain->vk_swapchain, + &swapchain_image_count, images); + assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to retrieve swapchain images"); + + for (u32 i = 0; i < swapchain_image_count; ++i) { + swapchain->images[i].vk_image = images[i]; + swapchain->images[i].size = (ivec3s){ .x = swapchain->extent.width, + .y = swapchain->extent.height, + .z = 1 }; + swapchain->images[i].format = vkFormatFromGpuFormat(request.format); + swapchain->images[i].device = request.device; + + VkImageViewCreateInfo view_create_info = { + .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + .image = swapchain->images[i].vk_image, + .viewType = VK_IMAGE_VIEW_TYPE_2D, + .format = requested_format, + .subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .subresourceRange.levelCount = 1, + .subresourceRange.layerCount = 1, + }; + + vk_result = vkCreateImageView(request.device->vk_device, &view_create_info, NULL, + &swapchain->images[i].vk_view); + assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create swapchain image view"); + } + + // NOTE (Abdelrahman): Favour 24-bit format for performance + VkFormat depth_format = VK_FORMAT_UNDEFINED; + VkFormatArray depth_formats = wpArray(VkFormat, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT); + for (u32 i = 0; i < wpArrayCount(depth_formats); ++i) { + VkFormatProperties2 format_properties = { VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2 }; + vkGetPhysicalDeviceFormatProperties2(request.device->physical_device.internal->vk_physical_device, + depth_formats[i], &format_properties); + if (format_properties.formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) { + depth_format = depth_formats[i]; + break; + } + } + assertWithLogger(depth_format != VK_FORMAT_UNDEFINED, &logger, "Failed to retrieve depth image format"); + + VkImageCreateInfo depth_image_create_info = { + .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + .imageType = VK_IMAGE_TYPE_2D, + .format = depth_format, + .extent = (VkExtent3D){ .width = swapchain->extent.width, + .height = swapchain->extent.height, + .depth = 1 }, + .mipLevels = 1, + .arrayLayers = 1, + .samples = VK_SAMPLE_COUNT_1_BIT, + .tiling = VK_IMAGE_TILING_OPTIMAL, + .usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, + .sharingMode = VK_SHARING_MODE_EXCLUSIVE, + .queueFamilyIndexCount = 1, + .pQueueFamilyIndices = &request.device->physical_device.internal->queue_family_index, + .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, + }; + + VmaAllocationCreateInfo depth_alloc_create_info = { + .flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT, + .usage = VMA_MEMORY_USAGE_AUTO, + }; + + vk_result = vmaCreateImage(request.device->allocator, &depth_image_create_info, &depth_alloc_create_info, + &swapchain->depth.vk_image, &swapchain->depth.allocation, NULL); + assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create depth image"); + + VkImageViewCreateInfo depth_view_create_info = { + .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + .image = swapchain->depth.vk_image, + .viewType = VK_IMAGE_VIEW_TYPE_2D, + .format = depth_format, + .subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT, + .subresourceRange.levelCount = 1, + .subresourceRange.layerCount = 1, + }; + + vk_result = vkCreateImageView(request.device->vk_device, &depth_view_create_info, NULL, + &swapchain->depth.vk_view); + assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create depth image view"); + + swapchain->depth.size = (ivec3s){ .x = swapchain->extent.width, .y = swapchain->extent.height, .z = 1 }; + swapchain->depth.format = depth_format; + swapchain->depth.device = request.device; + swapchain->device = request.device; + + WpStr8 msg = wpStr8Buf(4096); + wpStr8Format(&msg, "Created Vulkan swapchain %p", swapchain->vk_swapchain); + wpLogDebug(&logger, msg); + + return swapchain; +} + +void gpuDestroySwapchain(GpuSwapchain *swapchain) { + vkDestroyImageView(swapchain->device->vk_device, swapchain->depth.vk_view, NULL); + vmaDestroyImage(swapchain->device->allocator, swapchain->depth.vk_image, swapchain->depth.allocation); + if (swapchain->images) { + for (u64 i = 0; i < wpArrayCount(swapchain->images); ++i) { + vkDestroyImageView(swapchain->device->vk_device, swapchain->images[i].vk_view, NULL); + } + } + vkDestroySwapchainKHR(swapchain->device->vk_device, swapchain->vk_swapchain, NULL); +} + +u64 gpuGetSwapchainImageCount(GpuSwapchain *swapchain) { + return wpArrayCount(swapchain->images); +} + +GpuSampler *gpuCreateSampler(const WpAllocator *allocator, GpuSamplerCreateRequest request) { + GpuSampler *output = wpMemAllocatorAlloc(allocator, sizeof(GpuSampler)); + assertWithLogger(output != NULL, &logger, "Failed to allocate sampler"); + + VkSamplerCreateInfo info = { + .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, + .magFilter = vkFilterFromGpuFilter(request.mag_filter), + .minFilter = vkFilterFromGpuFilter(request.min_filter), + .mipmapMode = vkSamplerMipmapModeFromGpuSamplerMipmapMode(request.mipmap_mode), + .addressModeU = vkSamplerAddressModeFromGpuSamplerAddressMode(request.address_mode_u), + .addressModeV = vkSamplerAddressModeFromGpuSamplerAddressMode(request.address_mode_v), + .addressModeW = vkSamplerAddressModeFromGpuSamplerAddressMode(request.address_mode_w), + .anisotropyEnable = VK_TRUE, + .maxAnisotropy = 8.0f, + .maxLod = VK_LOD_CLAMP_NONE, + .compareEnable = request.compare_enable, + .compareOp = vkCompareOpFromGpuCompareOp(request.compare_op), + }; + + VkResult vk_result = vkCreateSampler(request.device->vk_device, &info, NULL, &output->vk_sampler); + assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create Vulkan sampler"); + + wpLogDebug(&logger, wpStr8Lit("Created Vulkan sampler")); + + return output; +} + +void gpuDestroySampler(GpuSampler *sampler) { + vkDestroySampler(sampler->device->vk_device, sampler->vk_sampler, NULL); +} + +GpuImage *gpuCreateImage(const WpAllocator *allocator, GpuImageCreateRequest request) { + VkResult vk_result = VK_SUCCESS; + GpuImage *output = wpMemAllocatorAlloc(allocator, sizeof(GpuImage)); + assertWithLogger(output != NULL, &logger, "Failed to allocate image"); + + VkFormat format = vkFormatFromGpuFormat(request.format); + VkImageCreateInfo image_create_info = { + .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + .imageType = vkImageTypeFromGpuImageType(request.type), + .format = format, + .extent = (VkExtent3D){ .width = request.size.x, + .height = request.size.y, + .depth = request.size.z }, + .mipLevels = request.subresource.level_count, + .arrayLayers = request.subresource.layer_count, + .samples = vkSampleCountFromGpuSampleCount(request.samples), + .tiling = vkImageTilingFromGpuImageTiling(request.tiling), + .usage = vkImageUsageFromGpuImageUsage(request.usage), + .sharingMode = VK_SHARING_MODE_EXCLUSIVE, + .queueFamilyIndexCount = 1, + .pQueueFamilyIndices = &request.device->physical_device.internal->queue_family_index, + .initialLayout = vkImageLayoutFromGpuImageLayout(request.layout), + }; + + VmaAllocationCreateInfo alloc_create_info = { + .flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT, + .usage = VMA_MEMORY_USAGE_AUTO, + }; + + vk_result = vmaCreateImage(request.device->allocator, &image_create_info, &alloc_create_info, + &output->vk_image, &output->allocation, NULL); + assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create depth image"); + + VkImageViewCreateInfo view_create_info = { + .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + .image = output->vk_image, + .viewType = vkImageViewTypeFromGpuImageType(request.type), + .format = vkFormatFromGpuFormat(request.format), + .subresourceRange.aspectMask = vkImageAspectFromGpuImageAspect(request.subresource.aspect), + .subresourceRange.levelCount = 1, + .subresourceRange.layerCount = 1, + }; + + vk_result = vkCreateImageView(request.device->vk_device, &view_create_info, NULL, &output->vk_view); + assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create depth image view"); + + output->size = request.size; + output->format = format; + + wpLogDebug(&logger, wpStr8Lit("Created Vulkan image")); + + return output; +} + +void gpuDestroyImage(GpuImage *image) { + vkDestroyImageView(image->device->vk_device, image->vk_view, NULL); + vmaDestroyImage(image->device->allocator, image->vk_image, image->allocation); +} + +ivec3s gpuImageGetSize(GpuImage *image) { + return image->size; +} + +GpuBuffer gpuCreateBuffer(const WpAllocator *allocator, GpuBufferCreateRequest request) { + GpuBuffer buffer = {0}; + VkResult vk_result = VK_SUCCESS; + + buffer.internal = wpMemAllocatorAlloc(allocator, sizeof(GpuBufferInternal)); + assertWithLogger(buffer.internal != NULL, &logger, "Failed to allocate buffer internal"); + + VkBufferUsageFlags2CreateInfo buf_usage_flags = { + .sType = VK_STRUCTURE_TYPE_BUFFER_USAGE_FLAGS_2_CREATE_INFO, + .usage = vkBufferUsageFromGpuBufferUsage(request.usage), + }; + + VkBufferCreateInfo buf_create_info = { + .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + .size = request.size, + .pNext = &buf_usage_flags, + }; + + VmaAllocationCreateInfo buf_alloc_create_info = { + .flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | + VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT | + VMA_ALLOCATION_CREATE_MAPPED_BIT, + .usage = VMA_MEMORY_USAGE_AUTO, + }; + + vk_result = vmaCreateBuffer(request.device->allocator, &buf_create_info, &buf_alloc_create_info, + &buffer.internal->vk_buffer, &buffer.internal->allocation, + &buffer.internal->allocation_info); + assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create buffer"); + + if ((request.usage & GPU_BUFFER_USAGE_SHADER_DEVICE_ADDRESS) == GPU_BUFFER_USAGE_SHADER_DEVICE_ADDRESS) { + VkBufferDeviceAddressInfo buf_dev_addr_info = { + .sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, + .buffer = buffer.internal->vk_buffer, + }; + + buffer.gpu_device_address = vkGetBufferDeviceAddress(request.device->vk_device, &buf_dev_addr_info); + } + + buffer.device = request.device; + buffer.cpu_mapping = buffer.internal->allocation_info.pMappedData; + buffer.size = buffer.internal->allocation_info.size; + + wpLogDebug(&logger, wpStr8Lit("Created Vulkan buffer")); + + return buffer; +} + +void gpuDestroyBuffer(GpuBuffer *buffer) { + vmaDestroyBuffer(buffer->device->allocator, buffer->internal->vk_buffer, buffer->internal->allocation); + buffer->device = NULL; + buffer->cpu_mapping = NULL; + buffer->gpu_device_address = 0; + buffer->size = 0; +} + +GpuFence *gpuCreateFence(const WpAllocator *allocator, GpuDevice *device) { + GpuFence *fence = wpMemAllocatorAlloc(allocator, sizeof(GpuFence)); + assertWithLogger(fence != NULL, &logger, "Failed to allocate fence internal"); + + VkFenceCreateInfo info = { + .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, + .flags = VK_FENCE_CREATE_SIGNALED_BIT, + }; + + VkResult vk_result = vkCreateFence(device->vk_device, &info, NULL, &fence->vk_fence); + assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create fence"); + + fence->device = device; + + wpLogDebug(&logger, wpStr8Lit("Created Vulkan fence")); + + return fence; +} + +void gpuDestroyFence(GpuFence *fence) { + vkDestroyFence(fence->device->vk_device, fence->vk_fence, NULL); +} + +void gpuResetFence(GpuFence *fence) { + VkResult vk_result = vkResetFences(fence->device->vk_device, 1, &fence->vk_fence); + assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to reset fence"); +} + +GpuSemaphore *gpuCreateSemaphore(const WpAllocator *allocator, GpuDevice *device) { + GpuSemaphore *semaphore = wpMemAllocatorAlloc(allocator, sizeof(GpuSemaphore)); + assertWithLogger(semaphore != NULL, &logger, "Failed to allocate semaphore internal"); + + VkSemaphoreCreateInfo info = { + .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, + }; + + VkResult vk_result = vkCreateSemaphore(device->vk_device, &info, NULL, &semaphore->vk_semaphore); + assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create semaphore"); + + semaphore->device = device; + + wpLogDebug(&logger, wpStr8Lit("Created Vulkan semaphore")); + + return semaphore; +} + +void gpuDestroySemaphore(GpuSemaphore *semaphore) { + vkDestroySemaphore(semaphore->device->vk_device, semaphore->vk_semaphore, NULL); +} + +GpuCommandPool *gpuCreateCommandPool(const WpAllocator *allocator, GpuDevice *device) { + GpuCommandPool *pool = wpMemAllocatorAlloc(allocator, sizeof(GpuCommandPool)); + assertWithLogger(pool != NULL, &logger, "Failed to allocate pool internal"); + + VkCommandPoolCreateInfo pool_create_info = { + .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, + .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, + .queueFamilyIndex = device->physical_device.internal->queue_family_index, + }; + + VkResult vk_result = vkCreateCommandPool(device->vk_device, &pool_create_info, NULL, &pool->vk_pool); + assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create command pool"); + + pool->device = device; + + wpLogDebug(&logger, wpStr8Lit("Created Vulkan command pool")); + + return pool; +} + +void gpuDestroyCommandPool(GpuCommandPool *pool) { + vkDestroyCommandPool(pool->device->vk_device, pool->vk_pool, NULL); +} + +void gpuResetCommandPool(GpuCommandPool *pool) { + VkResult vk_result = vkResetCommandPool(pool->device->vk_device, pool->vk_pool, 0); + assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to reset command pool"); +} + +GpuCommandBufferPtrArray gpuAllocateCommandBuffers(const WpAllocator *allocator, const WpAllocator *temp, + GpuCommandBufferAllocateRequest request) { + VkCommandBufferArray vk_buffers = wpArrayAllocCapacity(VkCommandBuffer, temp, request.buffer_count, + WP_ARRAY_INIT_FILLED); + GpuCommandBufferPtrArray buffers = wpArrayAllocCapacity(GpuCommandBuffer *, allocator, request.buffer_count, + WP_ARRAY_INIT_FILLED); + assertWithLogger(vk_buffers != NULL && buffers != NULL, &logger, "Failed to allocate command buffer arrays"); + + VkCommandBufferAllocateInfo info = { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, + .commandPool = request.pool->vk_pool, + .commandBufferCount = request.buffer_count, + }; + + VkResult vk_result = vkAllocateCommandBuffers(request.pool->device->vk_device, &info, vk_buffers); + assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to allocate command buffers"); + + for (u64 i = 0; i < request.buffer_count; ++i) { + buffers[i] = wpMemAllocatorAlloc(allocator, sizeof(GpuCommandBuffer)); + assertWithLogger(buffers[i] != NULL, &logger, "Failed to allocate command buffer internal"); + + buffers[i]->pool = request.pool; + buffers[i]->vk_buffer = vk_buffers[i]; + } + + WpStr8 msg = wpStr8Buf(4096); + wpStr8Format(&msg, "Allocated %" PRIu32 " command buffers from pool %p", request.buffer_count, request.pool->vk_pool); + wpLogDebug(&logger, msg); + + return buffers; +} + +void gpuBeginCommandBuffer(GpuCommandBuffer *buffer) { + VkCommandBufferBeginInfo info = { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, + .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, + }; + + VkResult vk_result = vkBeginCommandBuffer(buffer->vk_buffer, &info); + assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to begin command buffer"); +} + +void gpuEndCommandBuffer(GpuCommandBuffer *buffer) { + VkResult vk_result = vkEndCommandBuffer(buffer->vk_buffer); + assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to end command buffer"); +} + +void gpuSubmitCommandBuffers(const WpAllocator *temp, GpuCommandBuffersSubmitRequest request) { + u64 buffer_count = wpArrayCount(request.buffers); + + VkCommandBufferArray vk_buffers = wpArrayAllocCapacity(VkCommandBuffer, temp, buffer_count, + WP_ARRAY_INIT_FILLED); + assertWithLogger(vk_buffers != NULL, &logger, "Failed to allocate temp buffers"); + + for (u64 i = 0; i < buffer_count; ++i) { + vk_buffers[i] = request.buffers[i]->vk_buffer; + } + + VkSubmitInfo info = { + .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, + .commandBufferCount = buffer_count, + .pCommandBuffers = vk_buffers, + }; + + VkResult vk_result = VK_SUCCESS; + + gpuResetFence(request.fence); + + vk_result = vkQueueSubmit(request.device->vk_queue, 1, &info, request.fence->vk_fence); + assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to submit command buffers"); + + vk_result = vkWaitForFences(request.device->vk_device, 1, &request.fence->vk_fence, VK_TRUE, UINT64_MAX); + assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to wait for fences"); +} + +void gpuResetCommandBuffer(GpuCommandBuffer *buffer) { + VkResult vk_result = vkResetCommandBuffer(buffer->vk_buffer, 0); + assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to reset command buffer"); +} + +GpuDescriptorPool *gpuCreateDescriptorPool(const WpAllocator *allocator, GpuDescriptorPoolCreateRequest request) { + GpuDescriptorPool *output = wpMemAllocatorAlloc(allocator, sizeof(GpuDescriptorPool)); + assertWithLogger(output != NULL, &logger, "Failed to allocator descriptor pool internal"); + + VkDescriptorPoolSizeArray sizes = wpArrayWithCapacity(VkDescriptorPoolSize, GPU_DESCRIPTOR_TYPE_COUNT, + WP_ARRAY_INIT_NONE); + + if (request.descriptor_pool_sizes != NULL) { + for (u64 i = 0; i < wpArrayCount(request.descriptor_pool_sizes); ++i) { + VkDescriptorPoolSize desc_pool_size = { + .type = vkDescriptorTypeFromGpuDescriptorType(request.descriptor_pool_sizes[i].type), + .descriptorCount = request.descriptor_pool_sizes[i].count, + }; + wpArrayAppendCapped(VkDescriptorPoolSize, sizes, &desc_pool_size); + } + } + + VkDescriptorPoolCreateInfo info = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, + .maxSets = request.max_sets, + .poolSizeCount = wpArrayCount(sizes), + .pPoolSizes = sizes, + }; + + VkResult vk_result = vkCreateDescriptorPool(request.device->vk_device, &info, NULL, &output->vk_pool); + assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create descriptor pool"); + + output->device = request.device; + + wpLogDebug(&logger, wpStr8Lit("Created Vulkan descriptor pool successfully")); + + return output; +} + +void gpuDestroyDescriptorPool(GpuDescriptorPool *pool) { + vkDestroyDescriptorPool(pool->device->vk_device, pool->vk_pool, NULL); +} + +void gpuResetDescriptorPool(GpuDescriptorPool *pool) { + VkResult vk_result = vkResetDescriptorPool(pool->device->vk_device, pool->vk_pool, 0); + assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to reset descriptor pool"); +} + +GpuDescriptorSetLayout *gpuCreateDescriptorSetLayout(const WpAllocator *allocator, const WpAllocator *temp, + GpuDescriptorSetLayoutCreateRequest request) { + GpuDescriptorSetLayout *output = wpMemAllocatorAlloc(allocator, sizeof(GpuDescriptorSetLayout)); + assertWithLogger(output != NULL, &logger, "Failed to allocator descriptor set layout internal"); + + output->variable_descriptor_count = 0; + + u64 bindings_count = wpArrayCount(request.bindings); + + VkDescriptorSetLayoutBindingArray vk_bindings = wpArrayAllocCapacity(VkDescriptorSetLayoutBinding, temp, + bindings_count, WP_ARRAY_INIT_NONE); + VkDescriptorBindingFlagsArray vk_binding_flags = wpArrayAllocCapacity(VkDescriptorBindingFlags, temp, + bindings_count, WP_ARRAY_INIT_NONE); + assertWithLogger(vk_bindings != NULL && vk_binding_flags != NULL, &logger, + "Failed to allocate temp descriptor set bindings and flags"); + + VkDescriptorSetLayoutBindingFlagsCreateInfo binding_flags_info = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO, + .bindingCount = bindings_count, + .pBindingFlags = vk_binding_flags, + }; + + for (u64 i = 0; i < bindings_count; ++i) { + GpuDescriptorSetBinding *binding = &request.bindings[i]; + b32 has_variable_count = binding->variable_count; + b32 is_last_binding = (i + 1) == bindings_count; + + VkDescriptorBindingFlags binding_flags = 0; + if (has_variable_count) { + assertWithLogger(is_last_binding, &logger, "Binding has variable count but it's not the last binding"); + + binding_flags |= VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT; + + output->variable_descriptor_count = binding->descriptor_count; + } + wpArrayAppendCapped(VkDescriptorBindingFlags, vk_binding_flags, &binding_flags); + + VkDescriptorSetLayoutBinding vk_binding = { + .binding = binding->binding, + .descriptorType = vkDescriptorTypeFromGpuDescriptorType(binding->type), + .descriptorCount = binding->descriptor_count, + .stageFlags = vkShaderStageFromGpuShaderStage(binding->stages), + }; + + wpArrayAppendCapped(VkDescriptorSetLayoutBinding, vk_bindings, &vk_binding); + } + + VkDescriptorSetLayoutCreateInfo layout_create_info = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, + .pNext = &binding_flags_info, + .bindingCount = wpArrayCount(vk_bindings), + .pBindings = vk_bindings, + }; + + VkResult vk_result = vkCreateDescriptorSetLayout(request.device->vk_device, &layout_create_info, NULL, + &output->vk_layout); + assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create descriptor set layout"); + + output->device = request.device; + + wpLogDebug(&logger, wpStr8Lit("Created descriptor set layout successfully")); + + return output; +} + +void gpuDestroyDescriptorSetLayout(GpuDescriptorSetLayout *layout) { + vkDestroyDescriptorSetLayout(layout->device->vk_device, layout->vk_layout, NULL); +} + +GpuDescriptorSetPtrArray gpuAllocateDescriptorSets(const WpAllocator *allocator, const WpAllocator *temp, + GpuDescriptorSetAllocateRequest request) { + VkResult vk_result = VK_SUCCESS; + u64 set_count = wpArrayCount(request.layouts); + + GpuDescriptorSetPtrArray output = wpArrayAllocCapacity(GpuDescriptorSet *, allocator, set_count, WP_ARRAY_INIT_FILLED); + assertWithLogger(output != NULL, &logger, "Failed to allocator descriptor set array"); + + VkDescriptorSetLayoutArray vk_layouts = wpArrayAllocCapacity(VkDescriptorSetLayout, temp, set_count, + WP_ARRAY_INIT_FILLED); + VkDescriptorSetVariableDescriptorCountAllocateInfoArray vk_var_alloc_infos = + wpArrayAllocCapacity(VkDescriptorSetVariableDescriptorCountAllocateInfo, temp, set_count, WP_ARRAY_INIT_FILLED); + VkDescriptorSetArray vk_sets = wpArrayAllocCapacity(VkDescriptorSet, temp, set_count, WP_ARRAY_INIT_FILLED); + assertWithLogger(vk_layouts != NULL && vk_sets != NULL, &logger, "Failed to allocate temp sets and layouts"); + + for (u64 i = 0; i < set_count; ++i) { + output[i] = wpMemAllocatorAlloc(allocator, sizeof(GpuDescriptorSet)); + assertWithLogger(output[i] != NULL, &logger, "Failed to allocator descriptor set internal"); + + vk_var_alloc_infos[i].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO; + if (request.layouts[i]->variable_descriptor_count > 0) { + vk_var_alloc_infos[i].descriptorSetCount = 1; + vk_var_alloc_infos[i].pDescriptorCounts = &(request.layouts[i]->variable_descriptor_count); + } + + vk_layouts[i] = request.layouts[i]->vk_layout; + } + + VkDescriptorSetAllocateInfo set_alloc_info = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, + .pNext = vk_var_alloc_infos, + .descriptorPool = request.pool->vk_pool, + .descriptorSetCount = set_count, + .pSetLayouts = vk_layouts, + }; + + vk_result = vkAllocateDescriptorSets(request.pool->device->vk_device, &set_alloc_info, vk_sets); + assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to allocate descriptor sets"); + + for (u64 i = 0; i < set_count; ++i) { + output[i]->pool = request.pool; + output[i]->layout = request.layouts[i]; + output[i]->vk_set = vk_sets[i]; + } + + WpStr8 msg = wpStr8Buf(4096); + wpStr8Format(&msg, "Allocated %" PRIu64 " descriptor set(s) successfully", set_count); + wpLogDebug(&logger, msg); + + return output; +} + +void gpuWriteDescriptorSets(const WpAllocator *temp, GpuDescriptorSetWriteRequest request) { + u64 info_count = wpArrayCount(request.write_infos); + u64 image_info_count = 0; + u64 buffer_info_count = 0; + for (u64 i = 0; i < info_count; ++i) { + GpuDescriptorSetWriteInfo *info = &request.write_infos[i]; + image_info_count += info->image_infos != NULL ? wpArrayCount(info->image_infos) : 0; + buffer_info_count += info->buffer_infos != NULL ? wpArrayCount(info->buffer_infos) : 0; + } + + VkWriteDescriptorSetArray vk_desc_set_writes = wpArrayAllocCapacity(VkWriteDescriptorSet, temp, + info_count, WP_ARRAY_INIT_NONE); + assertWithLogger(vk_desc_set_writes != NULL, &logger, "Failed to allocate temp writes array"); + + VkDescriptorImageInfoArray vk_desc_img_infos = NULL; + if (image_info_count > 0) { + vk_desc_img_infos = wpArrayAllocCapacity(VkDescriptorImageInfo, temp, image_info_count, + WP_ARRAY_INIT_NONE); + assertWithLogger(vk_desc_img_infos != NULL, &logger, "Failed to allocate temp image info array"); + } + + VkDescriptorBufferInfoArray vk_desc_buf_infos = NULL; + if (buffer_info_count > 0) { + vk_desc_buf_infos = wpArrayAllocCapacity(VkDescriptorBufferInfo, temp, buffer_info_count, + WP_ARRAY_INIT_NONE); + assertWithLogger(vk_desc_buf_infos != NULL, &logger, "Failed to allocate temp buffer info array"); + } + + u64 image_info_offset = 0; + u64 buffer_info_offset = 0; + for (u64 i = 0; i < info_count; ++i) { + GpuDescriptorSetWriteInfo *info = &request.write_infos[i]; + VkWriteDescriptorSet desc_set_write = { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstSet = info->set->vk_set, + .dstBinding = info->dst_binding, + .dstArrayElement = info->dst_array_element, + .descriptorType = vkDescriptorTypeFromGpuDescriptorType(info->descriptor_type), + }; + + GpuDescriptorCategory category = descriptorCategoryFromDescriptorType(info->descriptor_type); + switch (category) { + case GPU_DESCRIPTOR_CATEGORY_IMAGE: { + assertWithLogger(info->image_infos != NULL, &logger, "No image info provided for an image descriptor"); + image_info_offset += retrieveDescriptorImageInfos(info, &desc_set_write, vk_desc_img_infos, + image_info_offset); + } break; + case GPU_DESCRIPTOR_CATEGORY_BUFFER: { + assertWithLogger(info->buffer_infos != NULL, &logger, "No buffer info provided for a buffer descriptor"); + buffer_info_offset += retrieveDescriptorBufferInfos(info, &desc_set_write, vk_desc_buf_infos, + buffer_info_offset); + } break; + case GPU_DESCRIPTOR_CATEGORY_TEXEL_BUFFER: + case GPU_DESCRIPTOR_CATEGORY_UNIFORM_BLOCK: + // TODO (Abdelrahman): Handle these cases + assertWithLogger(0, &logger, "Texel buffer and uniform block descriptors are not yet supported"); + } + + wpArrayAppendCapped(VkWriteDescriptorSet, vk_desc_set_writes, &desc_set_write); + } + + WpStr8 msg = wpStr8Buf(4096); + wpStr8Format(&msg, "Wrote to %" PRIu64 " descriptor set(s) successfully", info_count); + wpLogDebug(&logger, msg); + + vkUpdateDescriptorSets(request.device->vk_device, wpArrayCount(vk_desc_set_writes), vk_desc_set_writes, + 0, NULL); +} + +GpuShader *gpuCreateShader(const WpAllocator *allocator, GpuShaderCreateRequest request) { + GpuShader *output = wpMemAllocatorAlloc(allocator, sizeof(GpuShader)); + assertWithLogger(output != NULL, &logger, "Failed to allocate shader internal"); + + VkShaderModuleCreateInfo info = { + .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, + .codeSize = request.size, + .pCode = (u32 *)request.code, + }; + + VkResult vk_result = vkCreateShaderModule(request.device->vk_device, &info, NULL, &output->vk_shader); + assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create Vulkan shader module"); + + output->device = request.device; + + wpLogDebug(&logger, wpStr8Lit("Created Vulkan shader module successfully")); + + return output; +} + +void gpuDestroyShader(GpuShader *shader) { + vkDestroyShaderModule(shader->device->vk_device, shader->vk_shader, NULL); +} + +GpuPipelineLayout *gpuCreatePipelineLayout(const WpAllocator *allocator, const WpAllocator *temp, + GpuPipelineLayoutCreateRequest request) { + GpuPipelineLayout *output = wpMemAllocatorAlloc(allocator, sizeof(GpuPipelineLayout)); + assertWithLogger(output != NULL, &logger, "Failed to allocate pipeline layout internal"); + + u64 layout_count = wpArrayCount(request.descriptor_set_layouts); + u64 push_constant_count = wpArrayCount(request.push_constants); + + VkDescriptorSetLayoutArray layouts = wpArrayAllocCapacity(VkDescriptorSetLayout, temp, + layout_count, WP_ARRAY_INIT_FILLED); + VkPushConstantRangeArray push_constants = wpArrayAllocCapacity(VkPushConstantRange, temp, + push_constant_count, WP_ARRAY_INIT_FILLED); + + for (u64 i = 0; i < layout_count; ++i) { + layouts[i] = request.descriptor_set_layouts[i]->vk_layout; + } + + for (u64 i = 0; i < push_constant_count; ++i) { + push_constants[i].stageFlags = vkShaderStageFromGpuShaderStage(request.push_constants[i].stages); + push_constants[i].offset = request.push_constants[i].offset; + push_constants[i].size = request.push_constants[i].size; + } + + VkPipelineLayoutCreateInfo info = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, + .setLayoutCount = wpArrayCount(layouts), + .pSetLayouts = layouts, + .pushConstantRangeCount = wpArrayCount(push_constants), + .pPushConstantRanges = push_constants, + }; + + VkResult vk_result = vkCreatePipelineLayout(request.device->vk_device, &info, NULL, &output->vk_layout); + assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create Vulkan pipeline layout"); + + output->device = request.device; + + wpLogDebug(&logger, wpStr8Lit("Created Vulkan pipeline layout successfully")); + + return output; +} + +void gpuDestroyPipelineLayout(GpuPipelineLayout *layout) { + vkDestroyPipelineLayout(layout->device->vk_device, layout->vk_layout, NULL); +} + +GpuPipelinePtrArray gpuCreateGraphicsPipelines(const WpAllocator *allocator, const WpAllocator *temp, + GpuGraphicsPipelinesCreateRequest request) { + u64 pipeline_count = wpArrayCount(request.infos); + GpuPipelinePtrArray output = wpArrayAllocCapacity(GpuPipeline *, allocator, pipeline_count, WP_ARRAY_INIT_FILLED); + assertWithLogger(output != NULL, &logger, "Failed to allocate pipeline internals"); + + return output; +} + +GpuPipelinePtrArray gpuCreateComputePipelines(const WpAllocator *allocator, const WpAllocator *temp, + GpuComputePipelinesCreateRequest request) { + u64 pipeline_count = wpArrayCount(request.infos); + GpuPipelinePtrArray output = wpArrayAllocCapacity(GpuPipeline *, allocator, pipeline_count, WP_ARRAY_INIT_FILLED); + assertWithLogger(output != NULL, &logger, "Failed to allocate pipeline array"); + + VkComputePipelineCreateInfoArray infos = wpArrayAllocCapacity(VkComputePipelineCreateInfo, temp, + pipeline_count, WP_ARRAY_INIT_NONE); + assertWithLogger(infos != NULL, &logger, "Failed to allocate pipeline create infos"); + + VkPipelineArray pipelines = wpArrayAllocCapacity(VkPipeline, temp, pipeline_count, WP_ARRAY_INIT_FILLED); + assertWithLogger(infos != NULL, &logger, "Failed to allocate temp pipelines"); + + for (u64 i = 0; i < pipeline_count; ++i) { + VkComputePipelineCreateInfo info = { + .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, + .stage = (VkPipelineShaderStageCreateInfo){ + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .stage = vkShaderStageFromGpuShaderStage(request.infos[i].shader_stage.stage), + .module = request.infos[i].shader_stage.shader->vk_shader, + .pName = request.infos[i].shader_stage.name, + }, + .layout = request.infos[i].layout->vk_layout, + }; + wpArrayAppendCapped(VkComputePipelineCreateInfo, infos, &info); + } + + u64 infos_count = wpArrayCount(infos); + + // TODO (Abdelrahman): Create pipeline cache + VkResult vk_result = vkCreateComputePipelines(request.device->vk_device, VK_NULL_HANDLE, + infos_count, infos, NULL, pipelines); + assertWithLogger(vk_result == VK_SUCCESS, &logger, "Failed to create Vulkan compute pipelines"); + + for (u64 i = 0; i < infos_count; ++i) { + output[i] = wpMemAllocatorAlloc(allocator, sizeof(GpuPipeline)); + assertWithLogger(output[i] != NULL, &logger, "Failed to allocate pipeline internal"); + + output[i]->layout = request.infos[i].layout; + output[i]->vk_pipeline = pipelines[i]; + } + + WpStr8 msg = wpStr8Buf(4096); + wpStr8Format(&msg, "Created %" PRIu64 " compute pipeline(s) successfully", infos_count); + wpLogDebug(&logger, msg); + + return output; +} + +void gpuDestroyPipeline(GpuPipeline *pipeline) { + vkDestroyPipeline(pipeline->layout->device->vk_device, pipeline->vk_pipeline, NULL); +} + +void gpuDeviceWaitIdle(GpuDevice *device) { + vkDeviceWaitIdle(device->vk_device); +} + +wp_intern VkExtensions getInstanceExtensions(void) { + Config config = configGet(); + VkExtensions output = {0}; + + switch (config.window_backend) { + case WINDOW_BACKEND_SDL: { + output.extensions = SDL_Vulkan_GetInstanceExtensions(&output.count); + } break; + default: break; + } + + return output; +} + +wp_intern GpuPhysicalDeviceType vkDeviceTypeToGpuDeviceType(VkPhysicalDeviceType type) { + switch (type) { + case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: return GPU_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU; + case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: return GPU_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU; + case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: return GPU_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU; + case VK_PHYSICAL_DEVICE_TYPE_CPU: return GPU_PHYSICAL_DEVICE_TYPE_CPU; + default: return GPU_PHYSICAL_DEVICE_TYPE_UNKNOWN; + } +} + +wp_intern VkPhysicalDeviceType gpuDeviceTypeToVkDeviceType(GpuPhysicalDeviceType type) { + switch (type) { + case GPU_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: return VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU; + case GPU_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: return VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU; + case GPU_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: return VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU; + case GPU_PHYSICAL_DEVICE_TYPE_CPU: return VK_PHYSICAL_DEVICE_TYPE_CPU; + default: return VK_PHYSICAL_DEVICE_TYPE_OTHER; + } +} + +wp_intern i32 findQueueFamily(const WpAllocator *allocator, VkInstance instance, + VkPhysicalDevice physical_device, GpuPhysicalDeviceOps ops) { + i32 queue_family_index = -1; + + u32 queue_family_count = 0; + vkGetPhysicalDeviceQueueFamilyProperties2(physical_device, &queue_family_count, NULL); + if (queue_family_count == 0) { goto FIND_QUEUE_FAMILY_RETURN; } + + VkQueueFamilyProperties2Array queue_family_properties = + wpArrayAllocCapacity(VkQueueFamilyProperties2, allocator, queue_family_count, WP_ARRAY_INIT_FILLED); + if (!queue_family_properties) { goto FIND_QUEUE_FAMILY_RETURN; } + + for (u32 i = 0; i < queue_family_count; ++i) { + queue_family_properties[i].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2; + } + + vkGetPhysicalDeviceQueueFamilyProperties2(physical_device, &queue_family_count, queue_family_properties); + + VkQueueFlags requested_flags = queueFlagsFromOps(ops); + b8 presentation_requested = (ops & GPU_PHYSICAL_DEVICE_OP_PRESENTATION) == GPU_PHYSICAL_DEVICE_OP_PRESENTATION; + for (u32 i = 0; i < queue_family_count; ++i) { + VkQueueFlags queue_flags = queue_family_properties[i].queueFamilyProperties.queueFlags; + b8 presentation_supported = presentationSupported(instance, physical_device, i); + b8 ops_supported = (queue_flags & requested_flags) == requested_flags; + if (ops_supported && (!presentation_requested || presentation_supported)) { + queue_family_index = i; + break; + } + } + +FIND_QUEUE_FAMILY_RETURN: + return queue_family_index; +} + +wp_intern VkQueueFlags queueFlagsFromOps(GpuPhysicalDeviceOps ops) { + VkQueueFlags flags = 0; + + flags |= (ops & GPU_PHYSICAL_DEVICE_OP_GRAPHICS) != 0 ? VK_QUEUE_GRAPHICS_BIT : 0; + flags |= (ops & GPU_PHYSICAL_DEVICE_OP_COMPUTE) != 0 ? VK_QUEUE_COMPUTE_BIT : 0; + flags |= (ops & GPU_PHYSICAL_DEVICE_OP_TRANSFER) != 0 ? VK_QUEUE_TRANSFER_BIT : 0; + flags |= (ops & GPU_PHYSICAL_DEVICE_OP_VIDEO_DECODE) != 0 ? VK_QUEUE_VIDEO_DECODE_BIT_KHR : 0; + flags |= (ops & GPU_PHYSICAL_DEVICE_OP_VIDEO_ENCODE) != 0 ? VK_QUEUE_VIDEO_ENCODE_BIT_KHR : 0; + + return flags; +} + +wp_intern b8 presentationSupported(VkInstance instance, VkPhysicalDevice device, u32 queue_family_index) { + Config config = configGet(); + + switch (config.window_backend) { + case WINDOW_BACKEND_SDL: return SDL_Vulkan_GetPresentationSupport(instance, device, queue_family_index); + default: return false; + } +} + +wp_intern b8 windowBackendCreateSurface(const Window *window, VkInstance instance, VkSurfaceKHR *surface) { + Config config = configGet(); + + switch (config.window_backend) { + case WINDOW_BACKEND_SDL: return SDL_Vulkan_CreateSurface((SDL_Window *)window->internal.window, + instance, NULL, surface); + default: return false; + } +} + +wp_intern VkFormat vkFormatFromGpuFormat(GpuFormat format) { + switch (format) { + case GPU_FORMAT_R8_UINT: return VK_FORMAT_R8_UINT; + case GPU_FORMAT_R8_SINT: return VK_FORMAT_R8_SINT; + case GPU_FORMAT_R8_SRGB: return VK_FORMAT_R8_SRGB; + case GPU_FORMAT_R8G8_UINT: return VK_FORMAT_R8G8_UINT; + case GPU_FORMAT_R8G8_SINT: return VK_FORMAT_R8G8_SINT; + case GPU_FORMAT_R8G8_SRGB: return VK_FORMAT_R8G8_SRGB; + case GPU_FORMAT_R8G8B8_UINT: return VK_FORMAT_R8G8B8_UINT; + case GPU_FORMAT_R8G8B8_SINT: return VK_FORMAT_R8G8B8_SINT; + case GPU_FORMAT_R8G8B8_SRGB: return VK_FORMAT_R8G8B8_SRGB; + case GPU_FORMAT_B8G8R8_UINT: return VK_FORMAT_B8G8R8_UINT; + case GPU_FORMAT_B8G8R8_SINT: return VK_FORMAT_B8G8R8_SINT; + case GPU_FORMAT_B8G8R8_SRGB: return VK_FORMAT_B8G8R8_SRGB; + case GPU_FORMAT_R8G8B8A8_UINT: return VK_FORMAT_R8G8B8A8_UINT; + case GPU_FORMAT_R8G8B8A8_SINT: return VK_FORMAT_R8G8B8A8_SINT; + case GPU_FORMAT_R8G8B8A8_SRGB: return VK_FORMAT_R8G8B8A8_SRGB; + case GPU_FORMAT_B8G8R8A8_UINT: return VK_FORMAT_B8G8R8A8_UINT; + case GPU_FORMAT_B8G8R8A8_SINT: return VK_FORMAT_B8G8R8A8_SINT; + case GPU_FORMAT_B8G8R8A8_SRGB: return VK_FORMAT_B8G8R8A8_SRGB; + case GPU_FORMAT_R16_UINT: return VK_FORMAT_R16_UINT; + case GPU_FORMAT_R16_SINT: return VK_FORMAT_R16_SINT; + case GPU_FORMAT_R16_SFLOAT: return VK_FORMAT_R16_SFLOAT; + case GPU_FORMAT_R16G16_UINT: return VK_FORMAT_R16G16_UINT; + case GPU_FORMAT_R16G16_SINT: return VK_FORMAT_R16G16_SINT; + case GPU_FORMAT_R16G16_SFLOAT: return VK_FORMAT_R16G16_SFLOAT; + case GPU_FORMAT_R16G16B16_UINT: return VK_FORMAT_R16G16B16_UINT; + case GPU_FORMAT_R16G16B16_SINT: return VK_FORMAT_R16G16B16_SINT; + case GPU_FORMAT_R16G16B16_SFLOAT: return VK_FORMAT_R16G16B16_SFLOAT; + case GPU_FORMAT_R16G16B16A16_UINT: return VK_FORMAT_R16G16B16A16_UINT; + case GPU_FORMAT_R16G16B16A16_SINT: return VK_FORMAT_R16G16B16A16_SINT; + case GPU_FORMAT_R16G16B16A16_SFLOAT: return VK_FORMAT_R16G16B16A16_SFLOAT; + case GPU_FORMAT_R32_UINT: return VK_FORMAT_R32_UINT; + case GPU_FORMAT_R32_SINT: return VK_FORMAT_R32_SINT; + case GPU_FORMAT_R32_SFLOAT: return VK_FORMAT_R32_SFLOAT; + case GPU_FORMAT_R32G32_UINT: return VK_FORMAT_R32G32_UINT; + case GPU_FORMAT_R32G32_SINT: return VK_FORMAT_R32G32_SINT; + case GPU_FORMAT_R32G32_SFLOAT: return VK_FORMAT_R32G32_SFLOAT; + case GPU_FORMAT_R32G32B32_UINT: return VK_FORMAT_R32G32B32_UINT; + case GPU_FORMAT_R32G32B32_SINT: return VK_FORMAT_R32G32B32_SINT; + case GPU_FORMAT_R32G32B32_SFLOAT: return VK_FORMAT_R32G32B32_SFLOAT; + case GPU_FORMAT_R32G32B32A32_UINT: return VK_FORMAT_R32G32B32A32_UINT; + case GPU_FORMAT_R32G32B32A32_SINT: return VK_FORMAT_R32G32B32A32_SINT; + case GPU_FORMAT_R32G32B32A32_SFLOAT: return VK_FORMAT_R32G32B32A32_SFLOAT; + case GPU_FORMAT_R64_UINT: return VK_FORMAT_R64_UINT; + case GPU_FORMAT_R64_SINT: return VK_FORMAT_R64_SINT; + case GPU_FORMAT_R64_SFLOAT: return VK_FORMAT_R64_SFLOAT; + case GPU_FORMAT_R64G64_UINT: return VK_FORMAT_R64G64_UINT; + case GPU_FORMAT_R64G64_SINT: return VK_FORMAT_R64G64_SINT; + case GPU_FORMAT_R64G64_SFLOAT: return VK_FORMAT_R64G64_SFLOAT; + case GPU_FORMAT_R64G64B64_UINT: return VK_FORMAT_R64G64B64_UINT; + case GPU_FORMAT_R64G64B64_SINT: return VK_FORMAT_R64G64B64_SINT; + case GPU_FORMAT_R64G64B64_SFLOAT: return VK_FORMAT_R64G64B64_SFLOAT; + case GPU_FORMAT_R64G64B64A64_UINT: return VK_FORMAT_R64G64B64A64_UINT; + case GPU_FORMAT_R64G64B64A64_SINT: return VK_FORMAT_R64G64B64A64_SINT; + case GPU_FORMAT_R64G64B64A64_SFLOAT: return VK_FORMAT_R64G64B64A64_SFLOAT; + case GPU_FORMAT_D24_UNORM_S8_UINT: return VK_FORMAT_D24_UNORM_S8_UINT; + case GPU_FORMAT_D32_SFLOAT_S8_UINT: return VK_FORMAT_D32_SFLOAT_S8_UINT; + default: return VK_FORMAT_UNDEFINED; + } +} + +wp_intern GpuFormat gpuFormatFromVkFormat(VkFormat format) { + switch (format) { + case VK_FORMAT_R8_UINT: return GPU_FORMAT_R8_UINT; + case VK_FORMAT_R8_SINT: return GPU_FORMAT_R8_SINT; + case VK_FORMAT_R8_SRGB: return GPU_FORMAT_R8_SRGB; + case VK_FORMAT_R8G8_UINT: return GPU_FORMAT_R8G8_UINT; + case VK_FORMAT_R8G8_SINT: return GPU_FORMAT_R8G8_SINT; + case VK_FORMAT_R8G8_SRGB: return GPU_FORMAT_R8G8_SRGB; + case VK_FORMAT_R8G8B8_UINT: return GPU_FORMAT_R8G8B8_UINT; + case VK_FORMAT_R8G8B8_SINT: return GPU_FORMAT_R8G8B8_SINT; + case VK_FORMAT_R8G8B8_SRGB: return GPU_FORMAT_R8G8B8_SRGB; + case VK_FORMAT_B8G8R8_UINT: return GPU_FORMAT_B8G8R8_UINT; + case VK_FORMAT_B8G8R8_SINT: return GPU_FORMAT_B8G8R8_SINT; + case VK_FORMAT_B8G8R8_SRGB: return GPU_FORMAT_B8G8R8_SRGB; + case VK_FORMAT_R8G8B8A8_UINT: return GPU_FORMAT_R8G8B8A8_UINT; + case VK_FORMAT_R8G8B8A8_SINT: return GPU_FORMAT_R8G8B8A8_SINT; + case VK_FORMAT_R8G8B8A8_SRGB: return GPU_FORMAT_R8G8B8A8_SRGB; + case VK_FORMAT_B8G8R8A8_UINT: return GPU_FORMAT_B8G8R8A8_UINT; + case VK_FORMAT_B8G8R8A8_SINT: return GPU_FORMAT_B8G8R8A8_SINT; + case VK_FORMAT_B8G8R8A8_SRGB: return GPU_FORMAT_B8G8R8A8_SRGB; + case VK_FORMAT_R16_UINT: return GPU_FORMAT_R16_UINT; + case VK_FORMAT_R16_SINT: return GPU_FORMAT_R16_SINT; + case VK_FORMAT_R16_SFLOAT: return GPU_FORMAT_R16_SFLOAT; + case VK_FORMAT_R16G16_UINT: return GPU_FORMAT_R16G16_UINT; + case VK_FORMAT_R16G16_SINT: return GPU_FORMAT_R16G16_SINT; + case VK_FORMAT_R16G16_SFLOAT: return GPU_FORMAT_R16G16_SFLOAT; + case VK_FORMAT_R16G16B16_UINT: return GPU_FORMAT_R16G16B16_UINT; + case VK_FORMAT_R16G16B16_SINT: return GPU_FORMAT_R16G16B16_SINT; + case VK_FORMAT_R16G16B16_SFLOAT: return GPU_FORMAT_R16G16B16_SFLOAT; + case VK_FORMAT_R16G16B16A16_UINT: return GPU_FORMAT_R16G16B16A16_UINT; + case VK_FORMAT_R16G16B16A16_SINT: return GPU_FORMAT_R16G16B16A16_SINT; + case VK_FORMAT_R16G16B16A16_SFLOAT: return GPU_FORMAT_R16G16B16A16_SFLOAT; + case VK_FORMAT_R32_UINT: return GPU_FORMAT_R32_UINT; + case VK_FORMAT_R32_SINT: return GPU_FORMAT_R32_SINT; + case VK_FORMAT_R32_SFLOAT: return GPU_FORMAT_R32_SFLOAT; + case VK_FORMAT_R32G32_UINT: return GPU_FORMAT_R32G32_UINT; + case VK_FORMAT_R32G32_SINT: return GPU_FORMAT_R32G32_SINT; + case VK_FORMAT_R32G32_SFLOAT: return GPU_FORMAT_R32G32_SFLOAT; + case VK_FORMAT_R32G32B32_UINT: return GPU_FORMAT_R32G32B32_UINT; + case VK_FORMAT_R32G32B32_SINT: return GPU_FORMAT_R32G32B32_SINT; + case VK_FORMAT_R32G32B32_SFLOAT: return GPU_FORMAT_R32G32B32_SFLOAT; + case VK_FORMAT_R32G32B32A32_UINT: return GPU_FORMAT_R32G32B32A32_UINT; + case VK_FORMAT_R32G32B32A32_SINT: return GPU_FORMAT_R32G32B32A32_SINT; + case VK_FORMAT_R32G32B32A32_SFLOAT: return GPU_FORMAT_R32G32B32A32_SFLOAT; + case VK_FORMAT_R64_UINT: return GPU_FORMAT_R64_UINT; + case VK_FORMAT_R64_SINT: return GPU_FORMAT_R64_SINT; + case VK_FORMAT_R64_SFLOAT: return GPU_FORMAT_R64_SFLOAT; + case VK_FORMAT_R64G64_UINT: return GPU_FORMAT_R64G64_UINT; + case VK_FORMAT_R64G64_SINT: return GPU_FORMAT_R64G64_SINT; + case VK_FORMAT_R64G64_SFLOAT: return GPU_FORMAT_R64G64_SFLOAT; + case VK_FORMAT_R64G64B64_UINT: return GPU_FORMAT_R64G64B64_UINT; + case VK_FORMAT_R64G64B64_SINT: return GPU_FORMAT_R64G64B64_SINT; + case VK_FORMAT_R64G64B64_SFLOAT: return GPU_FORMAT_R64G64B64_SFLOAT; + case VK_FORMAT_R64G64B64A64_UINT: return GPU_FORMAT_R64G64B64A64_UINT; + case VK_FORMAT_R64G64B64A64_SINT: return GPU_FORMAT_R64G64B64A64_SINT; + case VK_FORMAT_R64G64B64A64_SFLOAT: return GPU_FORMAT_R64G64B64A64_SFLOAT; + case VK_FORMAT_D24_UNORM_S8_UINT: return GPU_FORMAT_D24_UNORM_S8_UINT; + case VK_FORMAT_D32_SFLOAT_S8_UINT: return GPU_FORMAT_D32_SFLOAT_S8_UINT; + default: return GPU_FORMAT_UNDEFINED; + } +} + +wp_intern VkColorSpaceKHR vkColorspaceFromGpuColorspace(GpuColorspace colorspace) { + switch (colorspace) { + case GPU_COLOR_SPACE_SRGB_NONLINEAR: return VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; + case GPU_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT: return VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT; + case GPU_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT: return VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT; + case GPU_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT: return VK_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT; + case GPU_COLOR_SPACE_DCI_P3_NONLINEAR_EXT: return VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT; + case GPU_COLOR_SPACE_BT709_LINEAR_EXT: return VK_COLOR_SPACE_BT709_LINEAR_EXT; + case GPU_COLOR_SPACE_BT709_NONLINEAR_EXT: return VK_COLOR_SPACE_BT709_NONLINEAR_EXT; + case GPU_COLOR_SPACE_BT2020_LINEAR_EXT: return VK_COLOR_SPACE_BT2020_LINEAR_EXT; + case GPU_COLOR_SPACE_HDR10_ST2084_EXT: return VK_COLOR_SPACE_HDR10_ST2084_EXT; + case GPU_COLOR_SPACE_DOLBYVISION_EXT: return VK_COLOR_SPACE_DOLBYVISION_EXT; + case GPU_COLOR_SPACE_HDR10_HLG_EXT: return VK_COLOR_SPACE_HDR10_HLG_EXT; + case GPU_COLOR_SPACE_ADOBERGB_LINEAR_EXT: return VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT; + case GPU_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT: return VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT; + case GPU_COLOR_SPACE_PASS_THROUGH_EXT: return VK_COLOR_SPACE_PASS_THROUGH_EXT; + case GPU_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT: return VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT; + case GPU_COLORSPACE_SRGB_NONLINEAR: return VK_COLORSPACE_SRGB_NONLINEAR_KHR; + } +} + +wp_intern GpuColorspace gpuColorspaceFromVkColorspace(VkColorSpaceKHR colorspace) { + switch (colorspace) { + case VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT: return GPU_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT; + case VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT: return GPU_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT; + case VK_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT: return GPU_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT; + case VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT: return GPU_COLOR_SPACE_DCI_P3_NONLINEAR_EXT; + case VK_COLOR_SPACE_BT709_LINEAR_EXT: return GPU_COLOR_SPACE_BT709_LINEAR_EXT; + case VK_COLOR_SPACE_BT709_NONLINEAR_EXT: return GPU_COLOR_SPACE_BT709_NONLINEAR_EXT; + case VK_COLOR_SPACE_BT2020_LINEAR_EXT: return GPU_COLOR_SPACE_BT2020_LINEAR_EXT; + case VK_COLOR_SPACE_HDR10_ST2084_EXT: return GPU_COLOR_SPACE_HDR10_ST2084_EXT; + case VK_COLOR_SPACE_DOLBYVISION_EXT: return GPU_COLOR_SPACE_DOLBYVISION_EXT; + case VK_COLOR_SPACE_HDR10_HLG_EXT: return GPU_COLOR_SPACE_HDR10_HLG_EXT; + case VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT: return GPU_COLOR_SPACE_ADOBERGB_LINEAR_EXT; + case VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT: return GPU_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT; + case VK_COLOR_SPACE_PASS_THROUGH_EXT: return GPU_COLOR_SPACE_PASS_THROUGH_EXT; + case VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT: return GPU_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT; + case VK_COLORSPACE_SRGB_NONLINEAR_KHR: return GPU_COLORSPACE_SRGB_NONLINEAR; + default: return GPU_COLOR_SPACE_SRGB_NONLINEAR; + } +} + +wp_intern VkPresentModeKHR vkPresentModeFromGpuPresentMode(GpuPresentMode mode) { + switch (mode) { + case GPU_PRESENT_MODE_IMMEDIATE: return VK_PRESENT_MODE_IMMEDIATE_KHR; + case GPU_PRESENT_MODE_FIFO: return VK_PRESENT_MODE_FIFO_KHR; + case GPU_PRESENT_MODE_FIFO_RELAXED: return VK_PRESENT_MODE_FIFO_RELAXED_KHR; + case GPU_PRESENT_MODE_FIFO_LATEST_READY: return VK_PRESENT_MODE_FIFO_LATEST_READY_KHR; + } +} + +wp_intern GpuPresentMode gpuPresentModeFromVkPresentMode(VkPresentModeKHR mode) { + switch (mode) { + case VK_PRESENT_MODE_FIFO_KHR: return GPU_PRESENT_MODE_FIFO; + case VK_PRESENT_MODE_FIFO_RELAXED_KHR: return GPU_PRESENT_MODE_FIFO_RELAXED; + case VK_PRESENT_MODE_FIFO_LATEST_READY_KHR: return GPU_PRESENT_MODE_FIFO_LATEST_READY; + default: return GPU_PRESENT_MODE_IMMEDIATE; + } +} + +wp_intern VkImageType vkImageTypeFromGpuImageType(GpuImageType type) { + switch (type) { + case GPU_IMAGE_TYPE_1D: return VK_IMAGE_TYPE_1D; + case GPU_IMAGE_TYPE_2D: return VK_IMAGE_TYPE_2D; + case GPU_IMAGE_TYPE_3D: return VK_IMAGE_TYPE_3D; + } +} + +wp_intern GpuImageType gpuImageTypeFromVkImageType(VkImageType type) { + switch (type) { + case VK_IMAGE_TYPE_1D: return GPU_IMAGE_TYPE_1D; + case VK_IMAGE_TYPE_2D: return GPU_IMAGE_TYPE_2D; + case VK_IMAGE_TYPE_3D: return GPU_IMAGE_TYPE_3D; + default: return GPU_IMAGE_TYPE_2D; + } +} + +wp_intern VkImageViewType vkImageViewTypeFromGpuImageType(GpuImageType type) { + switch (type) { + case GPU_IMAGE_TYPE_1D: return VK_IMAGE_VIEW_TYPE_1D; + case GPU_IMAGE_TYPE_2D: return VK_IMAGE_VIEW_TYPE_2D; + case GPU_IMAGE_TYPE_3D: return VK_IMAGE_VIEW_TYPE_3D; + } +} + +wp_intern GpuImageType gpuImageTypeFromVkImageViewType(VkImageViewType type) { + switch (type) { + case VK_IMAGE_VIEW_TYPE_1D: return GPU_IMAGE_TYPE_1D; + case VK_IMAGE_VIEW_TYPE_2D: return GPU_IMAGE_TYPE_2D; + case VK_IMAGE_VIEW_TYPE_3D: return GPU_IMAGE_TYPE_3D; + default: return GPU_IMAGE_TYPE_2D; + } +} + +wp_intern VkSampleCountFlagBits vkSampleCountFromGpuSampleCount(GpuSampleCount samples) { + switch (samples) { + case GPU_SAMPLE_COUNT_1_BIT: return VK_SAMPLE_COUNT_1_BIT; + case GPU_SAMPLE_COUNT_2_BIT: return VK_SAMPLE_COUNT_2_BIT; + case GPU_SAMPLE_COUNT_4_BIT: return VK_SAMPLE_COUNT_4_BIT; + case GPU_SAMPLE_COUNT_8_BIT: return VK_SAMPLE_COUNT_8_BIT; + case GPU_SAMPLE_COUNT_16_BIT: return VK_SAMPLE_COUNT_16_BIT; + case GPU_SAMPLE_COUNT_32_BIT: return VK_SAMPLE_COUNT_32_BIT; + case GPU_SAMPLE_COUNT_64_BIT: return VK_SAMPLE_COUNT_64_BIT; + } +} + +wp_intern GpuSampleCount gpuSampleCountFromVkSampleCount(VkSampleCountFlagBits samples) { + switch (samples) { + case VK_SAMPLE_COUNT_1_BIT: return GPU_SAMPLE_COUNT_1_BIT; + case VK_SAMPLE_COUNT_2_BIT: return GPU_SAMPLE_COUNT_2_BIT; + case VK_SAMPLE_COUNT_4_BIT: return GPU_SAMPLE_COUNT_4_BIT; + case VK_SAMPLE_COUNT_8_BIT: return GPU_SAMPLE_COUNT_8_BIT; + case VK_SAMPLE_COUNT_16_BIT: return GPU_SAMPLE_COUNT_16_BIT; + case VK_SAMPLE_COUNT_32_BIT: return GPU_SAMPLE_COUNT_32_BIT; + case VK_SAMPLE_COUNT_64_BIT: return GPU_SAMPLE_COUNT_64_BIT; + default: return GPU_SAMPLE_COUNT_1_BIT; + } +} + +wp_intern VkImageTiling vkImageTilingFromGpuImageTiling(GpuImageTiling tiling) { + switch (tiling) { + case GPU_IMAGE_TILING_LINEAR: return VK_IMAGE_TILING_LINEAR; + default: return VK_IMAGE_TILING_OPTIMAL; + } +} + +wp_intern GpuImageTiling gpuImageTilingFromVkImageTiling(VkImageTiling tiling) { + switch (tiling) { + case VK_IMAGE_TILING_LINEAR: return GPU_IMAGE_TILING_LINEAR; + default: return GPU_IMAGE_TILING_OPTIMAL; + } +} + +wp_intern VkImageUsageFlags vkImageUsageFromGpuImageUsage(GpuImageUsage usage) { + VkImageUsageFlags output = 0; + + output |= (usage & GPU_IMAGE_USAGE_TRANSFER_SRC) != 0 ? VK_IMAGE_USAGE_TRANSFER_SRC_BIT : 0; + output |= (usage & GPU_IMAGE_USAGE_TRANSFER_DST) != 0 ? VK_IMAGE_USAGE_TRANSFER_DST_BIT : 0; + output |= (usage & GPU_IMAGE_USAGE_SAMPLED) != 0 ? VK_IMAGE_USAGE_SAMPLED_BIT : 0; + output |= (usage & GPU_IMAGE_USAGE_STORAGE) != 0 ? VK_IMAGE_USAGE_STORAGE_BIT : 0; + output |= (usage & GPU_IMAGE_USAGE_COLOR_ATTACHMENT) != 0 ? VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT : 0; + output |= (usage & GPU_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT) != 0 ? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT : 0; + output |= (usage & GPU_IMAGE_USAGE_TRANSIENT_ATTACHMENT) != 0 ? VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT : 0; + output |= (usage & GPU_IMAGE_USAGE_INPUT_ATTACHMENT) != 0 ? VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT : 0; + output |= (usage & GPU_IMAGE_USAGE_HOST_TRANSFER) != 0 ? VK_IMAGE_USAGE_HOST_TRANSFER_BIT : 0; + output |= (usage & GPU_IMAGE_USAGE_VIDEO_DECODE_DST) != 0 ? VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR : 0; + output |= (usage & GPU_IMAGE_USAGE_VIDEO_DECODE_SRC) != 0 ? VK_IMAGE_USAGE_VIDEO_DECODE_SRC_BIT_KHR : 0; + output |= (usage & GPU_IMAGE_USAGE_FRAGMENT_DENSITY_MAP) != 0 ? VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT : 0; + output |= (usage & GPU_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT) != 0 ? VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR : 0; + output |= (usage & GPU_IMAGE_USAGE_VIDEO_ENCODE_DST) != 0 ? VK_IMAGE_USAGE_VIDEO_ENCODE_DST_BIT_KHR : 0; + output |= (usage & GPU_IMAGE_USAGE_VIDEO_ENCODE_SRC) != 0 ? VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR : 0; + + return output; +} + +wp_intern GpuImageUsage gpuImageUsageFromVkImageUsage(VkImageUsageFlags usage) { + GpuImageUsage output = 0; + + output |= (usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) != 0 ? GPU_IMAGE_USAGE_TRANSFER_SRC : 0; + output |= (usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) != 0 ? GPU_IMAGE_USAGE_TRANSFER_DST : 0; + output |= (usage & VK_IMAGE_USAGE_SAMPLED_BIT) != 0 ? GPU_IMAGE_USAGE_SAMPLED : 0; + output |= (usage & VK_IMAGE_USAGE_STORAGE_BIT) != 0 ? GPU_IMAGE_USAGE_STORAGE : 0; + output |= (usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) != 0 ? GPU_IMAGE_USAGE_COLOR_ATTACHMENT : 0; + output |= (usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0 ? GPU_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT : 0; + output |= (usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0 ? GPU_IMAGE_USAGE_TRANSIENT_ATTACHMENT : 0; + output |= (usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) != 0 ? GPU_IMAGE_USAGE_INPUT_ATTACHMENT : 0; + output |= (usage & VK_IMAGE_USAGE_HOST_TRANSFER_BIT) != 0 ? GPU_IMAGE_USAGE_HOST_TRANSFER : 0; + output |= (usage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR) != 0 ? GPU_IMAGE_USAGE_VIDEO_DECODE_DST : 0; + output |= (usage & VK_IMAGE_USAGE_VIDEO_DECODE_SRC_BIT_KHR) != 0 ? GPU_IMAGE_USAGE_VIDEO_DECODE_SRC : 0; + output |= (usage & VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT) != 0 ? GPU_IMAGE_USAGE_FRAGMENT_DENSITY_MAP : 0; + output |= (usage & VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR) != 0 ? GPU_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT : 0; + output |= (usage & VK_IMAGE_USAGE_VIDEO_ENCODE_DST_BIT_KHR) != 0 ? GPU_IMAGE_USAGE_VIDEO_ENCODE_DST : 0; + output |= (usage & VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR) != 0 ? GPU_IMAGE_USAGE_VIDEO_ENCODE_SRC : 0; + + return output; +} + +wp_intern VkImageLayout vkImageLayoutFromGpuImageLayout(GpuImageLayout layout) { + switch (layout) { + case GPU_IMAGE_LAYOUT_GENERAL: return VK_IMAGE_LAYOUT_GENERAL; + case GPU_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: return VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + case GPU_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + case GPU_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: return VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; + case GPU_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + case GPU_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + case GPU_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + case GPU_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: return VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL; + case GPU_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL: return VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL; + case GPU_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL: return VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL; + case GPU_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL: return VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL; + case GPU_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL: return VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL; + case GPU_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL: return VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL; + case GPU_IMAGE_LAYOUT_READ_ONLY_OPTIMAL: return VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL; + case GPU_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL: return VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL; + case GPU_IMAGE_LAYOUT_PRESENT_SRC: return VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + case GPU_IMAGE_LAYOUT_VIDEO_DECODE_DST: return VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR; + case GPU_IMAGE_LAYOUT_VIDEO_DECODE_SRC: return VK_IMAGE_LAYOUT_VIDEO_DECODE_SRC_KHR; + case GPU_IMAGE_LAYOUT_SHARED_PRESENT: return VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR; + case GPU_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL: return VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; + case GPU_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL: return VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR; + case GPU_IMAGE_LAYOUT_VIDEO_ENCODE_DST: return VK_IMAGE_LAYOUT_VIDEO_ENCODE_DST_KHR; + case GPU_IMAGE_LAYOUT_VIDEO_ENCODE_SRC: return VK_IMAGE_LAYOUT_VIDEO_ENCODE_SRC_KHR; + case GPU_IMAGE_LAYOUT_VIDEO_ENCODE_QUANTIZATION_MAP: return VK_IMAGE_LAYOUT_VIDEO_ENCODE_QUANTIZATION_MAP_KHR; + default: return VK_IMAGE_LAYOUT_UNDEFINED; + } +} + +wp_intern GpuImageLayout gpuImageLayoutFromVkImageLayout(VkImageLayout layout) { + switch (layout) { + case VK_IMAGE_LAYOUT_GENERAL: return GPU_IMAGE_LAYOUT_GENERAL; + case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: return GPU_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: return GPU_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: return GPU_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; + case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: return GPU_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: return GPU_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: return GPU_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: return GPU_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL; + case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL: return GPU_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL; + case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL: return GPU_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL; + case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL: return GPU_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL; + case VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL: return GPU_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL; + case VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL: return GPU_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL; + case VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL: return GPU_IMAGE_LAYOUT_READ_ONLY_OPTIMAL; + case VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL: return GPU_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL; + case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR: return GPU_IMAGE_LAYOUT_PRESENT_SRC; + case VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR: return GPU_IMAGE_LAYOUT_VIDEO_DECODE_DST; + case VK_IMAGE_LAYOUT_VIDEO_DECODE_SRC_KHR: return GPU_IMAGE_LAYOUT_VIDEO_DECODE_SRC; + case VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR: return GPU_IMAGE_LAYOUT_SHARED_PRESENT; + case VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT: return GPU_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL; + case VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR: return GPU_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL; + case VK_IMAGE_LAYOUT_VIDEO_ENCODE_DST_KHR: return GPU_IMAGE_LAYOUT_VIDEO_ENCODE_DST; + case VK_IMAGE_LAYOUT_VIDEO_ENCODE_SRC_KHR: return GPU_IMAGE_LAYOUT_VIDEO_ENCODE_SRC; + case VK_IMAGE_LAYOUT_VIDEO_ENCODE_QUANTIZATION_MAP_KHR: return GPU_IMAGE_LAYOUT_VIDEO_ENCODE_QUANTIZATION_MAP; + default: return GPU_IMAGE_LAYOUT_UNDEFINED; + } +} + +wp_intern VkImageAspectFlags vkImageAspectFromGpuImageAspect(GpuImageAspect aspect) { + VkImageAspectFlags output = VK_IMAGE_ASPECT_NONE; + + output |= (aspect & GPU_IMAGE_ASPECT_COLOR_BIT) != 0 ? VK_IMAGE_ASPECT_COLOR_BIT : 0; + output |= (aspect & GPU_IMAGE_ASPECT_DEPTH_BIT) != 0 ? VK_IMAGE_ASPECT_DEPTH_BIT : 0; + output |= (aspect & GPU_IMAGE_ASPECT_STENCIL_BIT) != 0 ? VK_IMAGE_ASPECT_STENCIL_BIT : 0; + + return output; +} + +wp_intern GpuImageAspect gpuImageAspectFromVkImageAspect(VkImageAspectFlags aspect) { + GpuImageAspect output = GPU_IMAGE_ASPECT_NONE; + + output |= (aspect & VK_IMAGE_ASPECT_COLOR_BIT) != 0 ? GPU_IMAGE_ASPECT_COLOR_BIT : 0; + output |= (aspect & VK_IMAGE_ASPECT_DEPTH_BIT) != 0 ? GPU_IMAGE_ASPECT_DEPTH_BIT : 0; + output |= (aspect & VK_IMAGE_ASPECT_STENCIL_BIT) != 0 ? GPU_IMAGE_ASPECT_STENCIL_BIT : 0; + + return output; +} + +wp_intern VkBufferUsageFlags2 vkBufferUsageFromGpuBufferUsage(GpuBufferUsage usage) { + VkBufferUsageFlags2 output = 0; + + output |= (usage & GPU_BUFFER_USAGE_TRANSFER_SRC) != 0 ? VK_BUFFER_USAGE_2_TRANSFER_SRC_BIT : 0; + output |= (usage & GPU_BUFFER_USAGE_TRANSFER_DST) != 0 ? VK_BUFFER_USAGE_2_TRANSFER_DST_BIT : 0; + output |= (usage & GPU_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER) != 0 ? VK_BUFFER_USAGE_2_UNIFORM_TEXEL_BUFFER_BIT : 0; + output |= (usage & GPU_BUFFER_USAGE_STORAGE_TEXEL_BUFFER) != 0 ? VK_BUFFER_USAGE_2_STORAGE_TEXEL_BUFFER_BIT : 0; + output |= (usage & GPU_BUFFER_USAGE_UNIFORM_BUFFER) != 0 ? VK_BUFFER_USAGE_2_UNIFORM_BUFFER_BIT : 0; + output |= (usage & GPU_BUFFER_USAGE_STORAGE_BUFFER) != 0 ? VK_BUFFER_USAGE_2_STORAGE_BUFFER_BIT : 0; + output |= (usage & GPU_BUFFER_USAGE_INDEX_BUFFER) != 0 ? VK_BUFFER_USAGE_2_INDEX_BUFFER_BIT : 0; + output |= (usage & GPU_BUFFER_USAGE_VERTEX_BUFFER) != 0 ? VK_BUFFER_USAGE_2_VERTEX_BUFFER_BIT : 0; + output |= (usage & GPU_BUFFER_USAGE_INDIRECT_BUFFER) != 0 ? VK_BUFFER_USAGE_2_INDIRECT_BUFFER_BIT : 0; + output |= (usage & GPU_BUFFER_USAGE_SHADER_DEVICE_ADDRESS) != 0 ? VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT : 0; + output |= (usage & GPU_BUFFER_USAGE_DESCRIPTOR_HEAP) != 0 ? VK_BUFFER_USAGE_2_DESCRIPTOR_HEAP_BIT_EXT : 0; + output |= (usage & GPU_BUFFER_USAGE_CONDITIONAL_RENDERING) != 0 ? VK_BUFFER_USAGE_2_CONDITIONAL_RENDERING_BIT_EXT : 0; + output |= (usage & GPU_BUFFER_USAGE_SHADER_BINDING_TABLE) != 0 ? VK_BUFFER_USAGE_2_SHADER_BINDING_TABLE_BIT_KHR : 0; + output |= (usage & GPU_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER) != 0 ? VK_BUFFER_USAGE_2_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT : 0; + output |= (usage & GPU_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER) != 0 ? VK_BUFFER_USAGE_2_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT : 0; + output |= (usage & GPU_BUFFER_USAGE_VIDEO_DECODE_SRC) != 0 ? VK_BUFFER_USAGE_2_VIDEO_DECODE_SRC_BIT_KHR : 0; + output |= (usage & GPU_BUFFER_USAGE_VIDEO_DECODE_DST) != 0 ? VK_BUFFER_USAGE_2_VIDEO_DECODE_DST_BIT_KHR : 0; + output |= (usage & GPU_BUFFER_USAGE_VIDEO_ENCODE_DST) != 0 ? VK_BUFFER_USAGE_2_VIDEO_ENCODE_DST_BIT_KHR : 0; + output |= (usage & GPU_BUFFER_USAGE_VIDEO_ENCODE_SRC) != 0 ? VK_BUFFER_USAGE_2_VIDEO_ENCODE_SRC_BIT_KHR : 0; + output |= (usage & GPU_BUFFER_USAGE_SAMPLER_DESCRIPTOR_BUFFER) != 0 ? VK_BUFFER_USAGE_2_SAMPLER_DESCRIPTOR_BUFFER_BIT_EXT : 0; + output |= (usage & GPU_BUFFER_USAGE_RESOURCE_DESCRIPTOR_BUFFER) != 0 ? VK_BUFFER_USAGE_2_RESOURCE_DESCRIPTOR_BUFFER_BIT_EXT : 0; + output |= (usage & GPU_BUFFER_USAGE_PUSH_DESCRIPTORS_DESCRIPTOR_BUFFER) != 0 ? VK_BUFFER_USAGE_2_PUSH_DESCRIPTORS_DESCRIPTOR_BUFFER_BIT_EXT : 0; + + return output; +} + +wp_intern GpuBufferUsage gpuBufferUsageFromVkBufferUsage(VkBufferUsageFlags2 usage) { + GpuBufferUsage output = 0; + + output |= (usage & VK_BUFFER_USAGE_2_TRANSFER_SRC_BIT) != 0 ? GPU_BUFFER_USAGE_TRANSFER_SRC : 0; + output |= (usage & VK_BUFFER_USAGE_2_TRANSFER_DST_BIT) != 0 ? GPU_BUFFER_USAGE_TRANSFER_DST : 0; + output |= (usage & VK_BUFFER_USAGE_2_UNIFORM_TEXEL_BUFFER_BIT) != 0 ? GPU_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER : 0; + output |= (usage & VK_BUFFER_USAGE_2_STORAGE_TEXEL_BUFFER_BIT) != 0 ? GPU_BUFFER_USAGE_STORAGE_TEXEL_BUFFER : 0; + output |= (usage & VK_BUFFER_USAGE_2_UNIFORM_BUFFER_BIT) != 0 ? GPU_BUFFER_USAGE_UNIFORM_BUFFER : 0; + output |= (usage & VK_BUFFER_USAGE_2_STORAGE_BUFFER_BIT) != 0 ? GPU_BUFFER_USAGE_STORAGE_BUFFER : 0; + output |= (usage & VK_BUFFER_USAGE_2_INDEX_BUFFER_BIT) != 0 ? GPU_BUFFER_USAGE_INDEX_BUFFER : 0; + output |= (usage & VK_BUFFER_USAGE_2_VERTEX_BUFFER_BIT) != 0 ? GPU_BUFFER_USAGE_VERTEX_BUFFER : 0; + output |= (usage & VK_BUFFER_USAGE_2_INDIRECT_BUFFER_BIT) != 0 ? GPU_BUFFER_USAGE_INDIRECT_BUFFER : 0; + output |= (usage & VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT) != 0 ? GPU_BUFFER_USAGE_SHADER_DEVICE_ADDRESS : 0; + output |= (usage & VK_BUFFER_USAGE_2_DESCRIPTOR_HEAP_BIT_EXT) != 0 ? GPU_BUFFER_USAGE_DESCRIPTOR_HEAP : 0; + output |= (usage & VK_BUFFER_USAGE_2_CONDITIONAL_RENDERING_BIT_EXT) != 0 ? GPU_BUFFER_USAGE_CONDITIONAL_RENDERING : 0; + output |= (usage & VK_BUFFER_USAGE_2_SHADER_BINDING_TABLE_BIT_KHR) != 0 ? GPU_BUFFER_USAGE_SHADER_BINDING_TABLE : 0; + output |= (usage & VK_BUFFER_USAGE_2_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT) != 0 ? GPU_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER : 0; + output |= (usage & VK_BUFFER_USAGE_2_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT) != 0 ? GPU_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER : 0; + output |= (usage & VK_BUFFER_USAGE_2_VIDEO_DECODE_SRC_BIT_KHR) != 0 ? GPU_BUFFER_USAGE_VIDEO_DECODE_SRC : 0; + output |= (usage & VK_BUFFER_USAGE_2_VIDEO_DECODE_DST_BIT_KHR) != 0 ? GPU_BUFFER_USAGE_VIDEO_DECODE_DST : 0; + output |= (usage & VK_BUFFER_USAGE_2_VIDEO_ENCODE_DST_BIT_KHR) != 0 ? GPU_BUFFER_USAGE_VIDEO_ENCODE_DST : 0; + output |= (usage & VK_BUFFER_USAGE_2_VIDEO_ENCODE_SRC_BIT_KHR) != 0 ? GPU_BUFFER_USAGE_VIDEO_ENCODE_SRC : 0; + output |= (usage & VK_BUFFER_USAGE_2_SAMPLER_DESCRIPTOR_BUFFER_BIT_EXT) != 0 ? GPU_BUFFER_USAGE_SAMPLER_DESCRIPTOR_BUFFER : 0; + output |= (usage & VK_BUFFER_USAGE_2_RESOURCE_DESCRIPTOR_BUFFER_BIT_EXT) != 0 ? GPU_BUFFER_USAGE_RESOURCE_DESCRIPTOR_BUFFER : 0; + output |= (usage & VK_BUFFER_USAGE_2_PUSH_DESCRIPTORS_DESCRIPTOR_BUFFER_BIT_EXT) != 0 ? GPU_BUFFER_USAGE_PUSH_DESCRIPTORS_DESCRIPTOR_BUFFER : 0; + + return output; +} + +wp_intern VkPipelineStageFlags2 vkPipelineStagesFromGpuPipelineStages(GpuPipelineStageFlags stage) { + VkPipelineStageFlags2 output = 0; + + output |= (stage & GPU_PIPELINE_STAGE_TOP_OF_PIPE) != 0 ? VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT : 0; + output |= (stage & GPU_PIPELINE_STAGE_DRAW_INDIRECT) != 0 ? VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT : 0; + output |= (stage & GPU_PIPELINE_STAGE_VERTEX_INPUT) != 0 ? VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT : 0; + output |= (stage & GPU_PIPELINE_STAGE_VERTEX_SHADER) != 0 ? VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT : 0; + output |= (stage & GPU_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER) != 0 ? VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT : 0; + output |= (stage & GPU_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER) != 0 ? VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT : 0; + output |= (stage & GPU_PIPELINE_STAGE_GEOMETRY_SHADER) != 0 ? VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT : 0; + output |= (stage & GPU_PIPELINE_STAGE_FRAGMENT_SHADER) != 0 ? VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT : 0; + output |= (stage & GPU_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS) != 0 ? VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT : 0; + output |= (stage & GPU_PIPELINE_STAGE_LATE_FRAGMENT_TESTS) != 0 ? VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT : 0; + output |= (stage & GPU_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT) != 0 ? VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT : 0; + output |= (stage & GPU_PIPELINE_STAGE_COMPUTE_SHADER) != 0 ? VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT : 0; + output |= (stage & GPU_PIPELINE_STAGE_ALL_TRANSFER) != 0 ? VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT_KHR : 0; + output |= (stage & GPU_PIPELINE_STAGE_TRANSFER) != 0 ? VK_PIPELINE_STAGE_2_TRANSFER_BIT : 0; + output |= (stage & GPU_PIPELINE_STAGE_BOTTOM_OF_PIPE) != 0 ? VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT : 0; + output |= (stage & GPU_PIPELINE_STAGE_HOST) != 0 ? VK_PIPELINE_STAGE_2_HOST_BIT : 0; + output |= (stage & GPU_PIPELINE_STAGE_ALL_GRAPHICS) != 0 ? VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT : 0; + output |= (stage & GPU_PIPELINE_STAGE_ALL_COMMANDS) != 0 ? VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT : 0; + output |= (stage & GPU_PIPELINE_STAGE_COPY) != 0 ? VK_PIPELINE_STAGE_2_COPY_BIT : 0; + output |= (stage & GPU_PIPELINE_STAGE_RESOLVE) != 0 ? VK_PIPELINE_STAGE_2_RESOLVE_BIT : 0; + output |= (stage & GPU_PIPELINE_STAGE_BLIT) != 0 ? VK_PIPELINE_STAGE_2_BLIT_BIT : 0; + output |= (stage & GPU_PIPELINE_STAGE_CLEAR) != 0 ? VK_PIPELINE_STAGE_2_CLEAR_BIT : 0; + output |= (stage & GPU_PIPELINE_STAGE_INDEX_INPUT) != 0 ? VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT : 0; + output |= (stage & GPU_PIPELINE_STAGE_VERTEX_ATTRIBUTE_INPUT) != 0 ? VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT : 0; + output |= (stage & GPU_PIPELINE_STAGE_PRE_RASTERIZATION_SHADERS) != 0 ? VK_PIPELINE_STAGE_2_PRE_RASTERIZATION_SHADERS_BIT : 0; + output |= (stage & GPU_PIPELINE_STAGE_VIDEO_DECODE) != 0 ? VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR : 0; + output |= (stage & GPU_PIPELINE_STAGE_VIDEO_ENCODE) != 0 ? VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR : 0; + output |= (stage & GPU_PIPELINE_STAGE_CONDITIONAL_RENDERING) != 0 ? VK_PIPELINE_STAGE_2_CONDITIONAL_RENDERING_BIT_EXT : 0; + output |= (stage & GPU_PIPELINE_STAGE_COMMAND_PREPROCESS) != 0 ? VK_PIPELINE_STAGE_2_COMMAND_PREPROCESS_BIT_EXT : 0; + output |= (stage & GPU_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT) != 0 ? VK_PIPELINE_STAGE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR : 0; + output |= (stage & GPU_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD) != 0 ? VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_KHR : 0; + output |= (stage & GPU_PIPELINE_STAGE_RAY_TRACING_SHADER) != 0 ? VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_KHR : 0; + output |= (stage & GPU_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS) != 0 ? VK_PIPELINE_STAGE_2_FRAGMENT_DENSITY_PROCESS_BIT_EXT : 0; + output |= (stage & GPU_PIPELINE_STAGE_TASK_SHADER) != 0 ? VK_PIPELINE_STAGE_2_TASK_SHADER_BIT_EXT : 0; + output |= (stage & GPU_PIPELINE_STAGE_MESH_SHADER) != 0 ? VK_PIPELINE_STAGE_2_MESH_SHADER_BIT_EXT : 0; + output |= (stage & GPU_PIPELINE_STAGE_ACCELERATION_STRUCTURE_COPY) != 0 ? VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_COPY_BIT_KHR : 0; + output |= (stage & GPU_PIPELINE_STAGE_MICROMAP_BUILD) != 0 ? VK_PIPELINE_STAGE_2_MICROMAP_BUILD_BIT_EXT : 0; + output |= (stage & GPU_PIPELINE_STAGE_COPY_INDIRECT) != 0 ? VK_PIPELINE_STAGE_2_COPY_INDIRECT_BIT_KHR : 0; + output |= (stage & GPU_PIPELINE_STAGE_MEMORY_DECOMPRESSION) != 0 ? VK_PIPELINE_STAGE_2_MEMORY_DECOMPRESSION_BIT_EXT : 0; + + return output; +} + +wp_intern GpuPipelineStageFlags gpuPipelineStagesFromVkPipelineStages(VkPipelineStageFlags2 stage) { + GpuPipelineStageFlags output = 0; + + output |= (stage & VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT) != 0 ? GPU_PIPELINE_STAGE_TOP_OF_PIPE : 0; + output |= (stage & VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT) != 0 ? GPU_PIPELINE_STAGE_DRAW_INDIRECT : 0; + output |= (stage & VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT) != 0 ? GPU_PIPELINE_STAGE_VERTEX_INPUT : 0; + output |= (stage & VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT) != 0 ? GPU_PIPELINE_STAGE_VERTEX_SHADER : 0; + output |= (stage & VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT) != 0 ? GPU_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER : 0; + output |= (stage & VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT) != 0 ? GPU_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER : 0; + output |= (stage & VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT) != 0 ? GPU_PIPELINE_STAGE_GEOMETRY_SHADER : 0; + output |= (stage & VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT) != 0 ? GPU_PIPELINE_STAGE_FRAGMENT_SHADER : 0; + output |= (stage & VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT) != 0 ? GPU_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS : 0; + output |= (stage & VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT) != 0 ? GPU_PIPELINE_STAGE_LATE_FRAGMENT_TESTS : 0; + output |= (stage & VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT) != 0 ? GPU_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT : 0; + output |= (stage & VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT) != 0 ? GPU_PIPELINE_STAGE_COMPUTE_SHADER : 0; + output |= (stage & VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT_KHR) != 0 ? GPU_PIPELINE_STAGE_ALL_TRANSFER : 0; + output |= (stage & VK_PIPELINE_STAGE_2_TRANSFER_BIT) != 0 ? GPU_PIPELINE_STAGE_TRANSFER : 0; + output |= (stage & VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT) != 0 ? GPU_PIPELINE_STAGE_BOTTOM_OF_PIPE : 0; + output |= (stage & VK_PIPELINE_STAGE_2_HOST_BIT) != 0 ? GPU_PIPELINE_STAGE_HOST : 0; + output |= (stage & VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT) != 0 ? GPU_PIPELINE_STAGE_ALL_GRAPHICS : 0; + output |= (stage & VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT) != 0 ? GPU_PIPELINE_STAGE_ALL_COMMANDS : 0; + output |= (stage & VK_PIPELINE_STAGE_2_COPY_BIT) != 0 ? GPU_PIPELINE_STAGE_COPY : 0; + output |= (stage & VK_PIPELINE_STAGE_2_RESOLVE_BIT) != 0 ? GPU_PIPELINE_STAGE_RESOLVE : 0; + output |= (stage & VK_PIPELINE_STAGE_2_BLIT_BIT) != 0 ? GPU_PIPELINE_STAGE_BLIT : 0; + output |= (stage & VK_PIPELINE_STAGE_2_CLEAR_BIT) != 0 ? GPU_PIPELINE_STAGE_CLEAR : 0; + output |= (stage & VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT) != 0 ? GPU_PIPELINE_STAGE_INDEX_INPUT : 0; + output |= (stage & VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT) != 0 ? GPU_PIPELINE_STAGE_VERTEX_ATTRIBUTE_INPUT : 0; + output |= (stage & VK_PIPELINE_STAGE_2_PRE_RASTERIZATION_SHADERS_BIT) != 0 ? GPU_PIPELINE_STAGE_PRE_RASTERIZATION_SHADERS : 0; + output |= (stage & VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR) != 0 ? GPU_PIPELINE_STAGE_VIDEO_DECODE : 0; + output |= (stage & VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR) != 0 ? GPU_PIPELINE_STAGE_VIDEO_ENCODE : 0; + output |= (stage & VK_PIPELINE_STAGE_2_CONDITIONAL_RENDERING_BIT_EXT) != 0 ? GPU_PIPELINE_STAGE_CONDITIONAL_RENDERING : 0; + output |= (stage & VK_PIPELINE_STAGE_2_COMMAND_PREPROCESS_BIT_EXT) != 0 ? GPU_PIPELINE_STAGE_COMMAND_PREPROCESS : 0; + output |= (stage & VK_PIPELINE_STAGE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR) != 0 ? GPU_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT : 0; + output |= (stage & VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_KHR) != 0 ? GPU_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD : 0; + output |= (stage & VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_KHR) != 0 ? GPU_PIPELINE_STAGE_RAY_TRACING_SHADER : 0; + output |= (stage & VK_PIPELINE_STAGE_2_FRAGMENT_DENSITY_PROCESS_BIT_EXT) != 0 ? GPU_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS : 0; + output |= (stage & VK_PIPELINE_STAGE_2_TASK_SHADER_BIT_EXT) != 0 ? GPU_PIPELINE_STAGE_TASK_SHADER : 0; + output |= (stage & VK_PIPELINE_STAGE_2_MESH_SHADER_BIT_EXT) != 0 ? GPU_PIPELINE_STAGE_MESH_SHADER : 0; + output |= (stage & VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_COPY_BIT_KHR) != 0 ? GPU_PIPELINE_STAGE_ACCELERATION_STRUCTURE_COPY : 0; + output |= (stage & VK_PIPELINE_STAGE_2_MICROMAP_BUILD_BIT_EXT) != 0 ? GPU_PIPELINE_STAGE_MICROMAP_BUILD : 0; + output |= (stage & VK_PIPELINE_STAGE_2_COPY_INDIRECT_BIT_KHR) != 0 ? GPU_PIPELINE_STAGE_COPY_INDIRECT : 0; + output |= (stage & VK_PIPELINE_STAGE_2_MEMORY_DECOMPRESSION_BIT_EXT) != 0 ? GPU_PIPELINE_STAGE_MEMORY_DECOMPRESSION : 0; + + return output; +} + +wp_intern VkAccessFlags2 vkAccessFlagsFromGpuAccessFlags(GpuAccessFlags access) { + VkAccessFlags2 output = 0; + + output |= (access & GPU_ACCESS_NONE) != 0 ? VK_ACCESS_2_NONE : 0; + output |= (access & GPU_ACCESS_INDIRECT_COMMAND_READ) != 0 ? VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT : 0; + output |= (access & GPU_ACCESS_INDEX_READ) != 0 ? VK_ACCESS_2_INDEX_READ_BIT : 0; + output |= (access & GPU_ACCESS_VERTEX_ATTRIBUTE_READ) != 0 ? VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT : 0; + output |= (access & GPU_ACCESS_UNIFORM_READ) != 0 ? VK_ACCESS_2_UNIFORM_READ_BIT : 0; + output |= (access & GPU_ACCESS_INPUT_ATTACHMENT_READ) != 0 ? VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT : 0; + output |= (access & GPU_ACCESS_SHADER_READ) != 0 ? VK_ACCESS_2_SHADER_READ_BIT : 0; + output |= (access & GPU_ACCESS_SHADER_WRITE) != 0 ? VK_ACCESS_2_SHADER_WRITE_BIT : 0; + output |= (access & GPU_ACCESS_COLOR_ATTACHMENT_READ) != 0 ? VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT : 0; + output |= (access & GPU_ACCESS_COLOR_ATTACHMENT_WRITE) != 0 ? VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT : 0; + output |= (access & GPU_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ) != 0 ? VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT : 0; + output |= (access & GPU_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE) != 0 ? VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT : 0; + output |= (access & GPU_ACCESS_TRANSFER_READ) != 0 ? VK_ACCESS_2_TRANSFER_READ_BIT : 0; + output |= (access & GPU_ACCESS_TRANSFER_WRITE) != 0 ? VK_ACCESS_2_TRANSFER_WRITE_BIT : 0; + output |= (access & GPU_ACCESS_HOST_READ) != 0 ? VK_ACCESS_2_HOST_READ_BIT : 0; + output |= (access & GPU_ACCESS_HOST_WRITE) != 0 ? VK_ACCESS_2_HOST_WRITE_BIT : 0; + output |= (access & GPU_ACCESS_MEMORY_READ) != 0 ? VK_ACCESS_2_MEMORY_READ_BIT : 0; + output |= (access & GPU_ACCESS_MEMORY_WRITE) != 0 ? VK_ACCESS_2_MEMORY_WRITE_BIT : 0; + output |= (access & GPU_ACCESS_SHADER_SAMPLED_READ) != 0 ? VK_ACCESS_2_SHADER_SAMPLED_READ_BIT_KHR : 0; + output |= (access & GPU_ACCESS_SHADER_STORAGE_READ) != 0 ? VK_ACCESS_2_SHADER_STORAGE_READ_BIT_KHR : 0; + output |= (access & GPU_ACCESS_SHADER_STORAGE_WRITE) != 0 ? VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT_KHR : 0; + output |= (access & GPU_ACCESS_VIDEO_DECODE_READ) != 0 ? VK_ACCESS_2_VIDEO_DECODE_READ_BIT_KHR : 0; + output |= (access & GPU_ACCESS_VIDEO_DECODE_WRITE) != 0 ? VK_ACCESS_2_VIDEO_DECODE_WRITE_BIT_KHR : 0; + output |= (access & GPU_ACCESS_SAMPLER_HEAP_READ) != 0 ? VK_ACCESS_2_SAMPLER_HEAP_READ_BIT_EXT : 0; + output |= (access & GPU_ACCESS_RESOURCE_HEAP_READ) != 0 ? VK_ACCESS_2_RESOURCE_HEAP_READ_BIT_EXT : 0; + output |= (access & GPU_ACCESS_VIDEO_ENCODE_READ) != 0 ? VK_ACCESS_2_VIDEO_ENCODE_READ_BIT_KHR : 0; + output |= (access & GPU_ACCESS_VIDEO_ENCODE_WRITE) != 0 ? VK_ACCESS_2_VIDEO_ENCODE_WRITE_BIT_KHR : 0; + output |= (access & GPU_ACCESS_TRANSFORM_FEEDBACK_WRITE) != 0 ? VK_ACCESS_2_TRANSFORM_FEEDBACK_WRITE_BIT_EXT : 0; + output |= (access & GPU_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ) != 0 ? VK_ACCESS_2_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT : 0; + output |= (access & GPU_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE) != 0 ? VK_ACCESS_2_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT : 0; + output |= (access & GPU_ACCESS_CONDITIONAL_RENDERING_READ) != 0 ? VK_ACCESS_2_CONDITIONAL_RENDERING_READ_BIT_EXT : 0; + output |= (access & GPU_ACCESS_COMMAND_PREPROCESS_READ) != 0 ? VK_ACCESS_2_COMMAND_PREPROCESS_READ_BIT_EXT : 0; + output |= (access & GPU_ACCESS_COMMAND_PREPROCESS_WRITE) != 0 ? VK_ACCESS_2_COMMAND_PREPROCESS_WRITE_BIT_EXT : 0; + output |= (access & GPU_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ) != 0 ? VK_ACCESS_2_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR : 0; + output |= (access & GPU_ACCESS_ACCELERATION_STRUCTURE_READ) != 0 ? VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_KHR : 0; + output |= (access & GPU_ACCESS_ACCELERATION_STRUCTURE_WRITE) != 0 ? VK_ACCESS_2_ACCELERATION_STRUCTURE_WRITE_BIT_KHR : 0; + output |= (access & GPU_ACCESS_FRAGMENT_DENSITY_MAP_READ) != 0 ? VK_ACCESS_2_FRAGMENT_DENSITY_MAP_READ_BIT_EXT : 0; + output |= (access & GPU_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT) != 0 ? VK_ACCESS_2_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT : 0; + output |= (access & GPU_ACCESS_DESCRIPTOR_BUFFER_READ) != 0 ? VK_ACCESS_2_DESCRIPTOR_BUFFER_READ_BIT_EXT : 0; + output |= (access & GPU_ACCESS_SHADER_BINDING_TABLE_READ) != 0 ? VK_ACCESS_2_SHADER_BINDING_TABLE_READ_BIT_KHR : 0; + output |= (access & GPU_ACCESS_MICROMAP_READ) != 0 ? VK_ACCESS_2_MICROMAP_READ_BIT_EXT : 0; + output |= (access & GPU_ACCESS_MICROMAP_WRITE) != 0 ? VK_ACCESS_2_MICROMAP_WRITE_BIT_EXT : 0; + output |= (access & GPU_ACCESS_MEMORY_DECOMPRESSION_READ) != 0 ? VK_ACCESS_2_MEMORY_DECOMPRESSION_READ_BIT_EXT : 0; + output |= (access & GPU_ACCESS_MEMORY_DECOMPRESSION_WRITE) != 0 ? VK_ACCESS_2_MEMORY_DECOMPRESSION_WRITE_BIT_EXT : 0; + + return output; +} + +wp_intern GpuAccessFlags gpuAccessFlagsFromVkAccessFlags(VkAccessFlags2 access) { + GpuAccessFlags output = 0; + + output |= (access & VK_ACCESS_2_NONE) != 0 ? GPU_ACCESS_NONE : 0; + output |= (access & VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT) != 0 ? GPU_ACCESS_INDIRECT_COMMAND_READ : 0; + output |= (access & VK_ACCESS_2_INDEX_READ_BIT) != 0 ? GPU_ACCESS_INDEX_READ : 0; + output |= (access & VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT) != 0 ? GPU_ACCESS_VERTEX_ATTRIBUTE_READ : 0; + output |= (access & VK_ACCESS_2_UNIFORM_READ_BIT) != 0 ? GPU_ACCESS_UNIFORM_READ : 0; + output |= (access & VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT) != 0 ? GPU_ACCESS_INPUT_ATTACHMENT_READ : 0; + output |= (access & VK_ACCESS_2_SHADER_READ_BIT) != 0 ? GPU_ACCESS_SHADER_READ : 0; + output |= (access & VK_ACCESS_2_SHADER_WRITE_BIT) != 0 ? GPU_ACCESS_SHADER_WRITE : 0; + output |= (access & VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT) != 0 ? GPU_ACCESS_COLOR_ATTACHMENT_READ : 0; + output |= (access & VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT) != 0 ? GPU_ACCESS_COLOR_ATTACHMENT_WRITE : 0; + output |= (access & VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT) != 0 ? GPU_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ : 0; + output |= (access & VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT) != 0 ? GPU_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE : 0; + output |= (access & VK_ACCESS_2_TRANSFER_READ_BIT) != 0 ? GPU_ACCESS_TRANSFER_READ : 0; + output |= (access & VK_ACCESS_2_TRANSFER_WRITE_BIT) != 0 ? GPU_ACCESS_TRANSFER_WRITE : 0; + output |= (access & VK_ACCESS_2_HOST_READ_BIT) != 0 ? GPU_ACCESS_HOST_READ : 0; + output |= (access & VK_ACCESS_2_HOST_WRITE_BIT) != 0 ? GPU_ACCESS_HOST_WRITE : 0; + output |= (access & VK_ACCESS_2_MEMORY_READ_BIT) != 0 ? GPU_ACCESS_MEMORY_READ : 0; + output |= (access & VK_ACCESS_2_MEMORY_WRITE_BIT) != 0 ? GPU_ACCESS_MEMORY_WRITE : 0; + output |= (access & VK_ACCESS_2_SHADER_SAMPLED_READ_BIT_KHR) != 0 ? GPU_ACCESS_SHADER_SAMPLED_READ : 0; + output |= (access & VK_ACCESS_2_SHADER_STORAGE_READ_BIT_KHR) != 0 ? GPU_ACCESS_SHADER_STORAGE_READ : 0; + output |= (access & VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT_KHR) != 0 ? GPU_ACCESS_SHADER_STORAGE_WRITE : 0; + output |= (access & VK_ACCESS_2_VIDEO_DECODE_READ_BIT_KHR) != 0 ? GPU_ACCESS_VIDEO_DECODE_READ : 0; + output |= (access & VK_ACCESS_2_VIDEO_DECODE_WRITE_BIT_KHR) != 0 ? GPU_ACCESS_VIDEO_DECODE_WRITE : 0; + output |= (access & VK_ACCESS_2_SAMPLER_HEAP_READ_BIT_EXT) != 0 ? GPU_ACCESS_SAMPLER_HEAP_READ : 0; + output |= (access & VK_ACCESS_2_RESOURCE_HEAP_READ_BIT_EXT) != 0 ? GPU_ACCESS_RESOURCE_HEAP_READ : 0; + output |= (access & VK_ACCESS_2_VIDEO_ENCODE_READ_BIT_KHR) != 0 ? GPU_ACCESS_VIDEO_ENCODE_READ : 0; + output |= (access & VK_ACCESS_2_VIDEO_ENCODE_WRITE_BIT_KHR) != 0 ? GPU_ACCESS_VIDEO_ENCODE_WRITE : 0; + output |= (access & VK_ACCESS_2_TRANSFORM_FEEDBACK_WRITE_BIT_EXT) != 0 ? GPU_ACCESS_TRANSFORM_FEEDBACK_WRITE : 0; + output |= (access & VK_ACCESS_2_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT) != 0 ? GPU_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ : 0; + output |= (access & VK_ACCESS_2_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT) != 0 ? GPU_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE : 0; + output |= (access & VK_ACCESS_2_CONDITIONAL_RENDERING_READ_BIT_EXT) != 0 ? GPU_ACCESS_CONDITIONAL_RENDERING_READ : 0; + output |= (access & VK_ACCESS_2_COMMAND_PREPROCESS_READ_BIT_EXT) != 0 ? GPU_ACCESS_COMMAND_PREPROCESS_READ : 0; + output |= (access & VK_ACCESS_2_COMMAND_PREPROCESS_WRITE_BIT_EXT) != 0 ? GPU_ACCESS_COMMAND_PREPROCESS_WRITE : 0; + output |= (access & VK_ACCESS_2_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR) != 0 ? GPU_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ : 0; + output |= (access & VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_KHR) != 0 ? GPU_ACCESS_ACCELERATION_STRUCTURE_READ : 0; + output |= (access & VK_ACCESS_2_ACCELERATION_STRUCTURE_WRITE_BIT_KHR) != 0 ? GPU_ACCESS_ACCELERATION_STRUCTURE_WRITE : 0; + output |= (access & VK_ACCESS_2_FRAGMENT_DENSITY_MAP_READ_BIT_EXT) != 0 ? GPU_ACCESS_FRAGMENT_DENSITY_MAP_READ : 0; + output |= (access & VK_ACCESS_2_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT) != 0 ? GPU_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT : 0; + output |= (access & VK_ACCESS_2_DESCRIPTOR_BUFFER_READ_BIT_EXT) != 0 ? GPU_ACCESS_DESCRIPTOR_BUFFER_READ : 0; + output |= (access & VK_ACCESS_2_SHADER_BINDING_TABLE_READ_BIT_KHR) != 0 ? GPU_ACCESS_SHADER_BINDING_TABLE_READ : 0; + output |= (access & VK_ACCESS_2_MICROMAP_READ_BIT_EXT) != 0 ? GPU_ACCESS_MICROMAP_READ : 0; + output |= (access & VK_ACCESS_2_MICROMAP_WRITE_BIT_EXT) != 0 ? GPU_ACCESS_MICROMAP_WRITE : 0; + output |= (access & VK_ACCESS_2_MEMORY_DECOMPRESSION_READ_BIT_EXT) != 0 ? GPU_ACCESS_MEMORY_DECOMPRESSION_READ : 0; + output |= (access & VK_ACCESS_2_MEMORY_DECOMPRESSION_WRITE_BIT_EXT) != 0 ? GPU_ACCESS_MEMORY_DECOMPRESSION_WRITE : 0; + + return output; +} + +wp_intern VkFilter vkFilterFromGpuFilter(GpuFilter filter) { + switch (filter) { + case GPU_FILTER_NEAREST: return VK_FILTER_NEAREST; + case GPU_FILTER_LINEAR: return VK_FILTER_LINEAR; + case GPU_FILTER_CUBIC: return VK_FILTER_CUBIC_EXT; + } +} + +wp_intern GpuFilter gpuFilterFromVkFilter(VkFilter filter) { + switch (filter) { + case VK_FILTER_NEAREST: return GPU_FILTER_NEAREST; + case VK_FILTER_LINEAR: return GPU_FILTER_LINEAR; + case VK_FILTER_CUBIC_EXT: return GPU_FILTER_CUBIC; + default: return GPU_FILTER_LINEAR; + } +} + +wp_intern VkSamplerMipmapMode vkSamplerMipmapModeFromGpuSamplerMipmapMode(GpuSamplerMipmapMode mode) { + switch (mode) { + case GPU_SAMPLER_MIPMAP_MODE_NEAREST: return VK_SAMPLER_MIPMAP_MODE_NEAREST; + case GPU_SAMPLER_MIPMAP_MODE_LINEAR: return VK_SAMPLER_MIPMAP_MODE_LINEAR; + } +} + +wp_intern GpuSamplerMipmapMode gpuSamplerMipmapModeFromVkSamplerMipmapMode(VkSamplerMipmapMode mode) { + switch (mode) { + case VK_SAMPLER_MIPMAP_MODE_NEAREST: return GPU_SAMPLER_MIPMAP_MODE_NEAREST; + case VK_SAMPLER_MIPMAP_MODE_LINEAR: return GPU_SAMPLER_MIPMAP_MODE_LINEAR; + default: return GPU_SAMPLER_MIPMAP_MODE_LINEAR; + } +} + +wp_intern VkSamplerAddressMode vkSamplerAddressModeFromGpuSamplerAddressMode(GpuSamplerAddressMode mode) { + switch (mode) { + case GPU_SAMPLER_ADDRESS_MODE_REPEAT: return VK_SAMPLER_ADDRESS_MODE_REPEAT; + case GPU_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT: return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT; + case GPU_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE: return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + case GPU_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER: return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; + case GPU_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE: return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE; + } +} + +wp_intern GpuSamplerAddressMode gpuSamplerAddressModeFromVkSamplerAddressMode(VkSamplerAddressMode mode) { + switch (mode) { + case VK_SAMPLER_ADDRESS_MODE_REPEAT: return GPU_SAMPLER_ADDRESS_MODE_REPEAT; + case VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT: return GPU_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT; + case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE: return GPU_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER: return GPU_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; + case VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE: return GPU_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE; + default: return GPU_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; + } +} + +wp_intern VkCompareOp vkCompareOpFromGpuCompareOp(GpuCompareOp op) { + switch (op) { + case GPU_COMPARE_OP_NEVER: return VK_COMPARE_OP_NEVER; + case GPU_COMPARE_OP_LESS: return VK_COMPARE_OP_LESS; + case GPU_COMPARE_OP_EQUAL: return VK_COMPARE_OP_EQUAL; + case GPU_COMPARE_OP_LESS_OR_EQUAL: return VK_COMPARE_OP_LESS_OR_EQUAL; + case GPU_COMPARE_OP_GREATER: return VK_COMPARE_OP_GREATER; + case GPU_COMPARE_OP_NOT_EQUAL: return VK_COMPARE_OP_NOT_EQUAL; + case GPU_COMPARE_OP_GREATER_OR_EQUAL: return VK_COMPARE_OP_GREATER_OR_EQUAL; + case GPU_COMPARE_OP_ALWAYS: return VK_COMPARE_OP_ALWAYS; + } +} + +wp_intern GpuCompareOp gpuCompareOpFromVkCompareOp(VkCompareOp op) { + switch (op) { + case VK_COMPARE_OP_NEVER: return GPU_COMPARE_OP_NEVER; + case VK_COMPARE_OP_LESS: return GPU_COMPARE_OP_LESS; + case VK_COMPARE_OP_EQUAL: return GPU_COMPARE_OP_EQUAL; + case VK_COMPARE_OP_LESS_OR_EQUAL: return GPU_COMPARE_OP_LESS_OR_EQUAL; + case VK_COMPARE_OP_GREATER: return GPU_COMPARE_OP_GREATER; + case VK_COMPARE_OP_NOT_EQUAL: return GPU_COMPARE_OP_NOT_EQUAL; + case VK_COMPARE_OP_GREATER_OR_EQUAL: return GPU_COMPARE_OP_GREATER_OR_EQUAL; + case VK_COMPARE_OP_ALWAYS: return GPU_COMPARE_OP_ALWAYS; + default: return GPU_COMPARE_OP_NEVER; + } +} + +wp_intern VkDescriptorType vkDescriptorTypeFromGpuDescriptorType(GpuDescriptorType type) { + switch (type) { + case GPU_DESCRIPTOR_TYPE_SAMPLER: return VK_DESCRIPTOR_TYPE_SAMPLER; + case GPU_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: return VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + case GPU_DESCRIPTOR_TYPE_SAMPLED_IMAGE: return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + case GPU_DESCRIPTOR_TYPE_STORAGE_IMAGE: return VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + case GPU_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: return VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; + case GPU_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: return VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; + case GPU_DESCRIPTOR_TYPE_UNIFORM_BUFFER: return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + case GPU_DESCRIPTOR_TYPE_STORAGE_BUFFER: return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + case GPU_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; + case GPU_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC; + case GPU_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: return VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; + case GPU_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: return VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK; + default: break; + } + + assertWithLogger(false, &logger, "Invalid GPU descriptor type"); +} + +wp_intern GpuDescriptorType gpuDescriptorTypeFromVkDescriptorType(VkDescriptorType type) { + switch (type) { + case VK_DESCRIPTOR_TYPE_SAMPLER: return GPU_DESCRIPTOR_TYPE_SAMPLER; + case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: return GPU_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: return GPU_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: return GPU_DESCRIPTOR_TYPE_STORAGE_IMAGE; + case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: return GPU_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; + case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: return GPU_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: return GPU_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: return GPU_DESCRIPTOR_TYPE_STORAGE_BUFFER; + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: return GPU_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: return GPU_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC; + case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: return GPU_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; + case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: return GPU_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK; + default: break; + } + + assertWithLogger(false, &logger, "Invalid Vulkan descriptor type"); +} + +wp_intern VkShaderStageFlags vkShaderStageFromGpuShaderStage(GpuShaderStage stages) { + VkShaderStageFlags output = 0; + + output |= (stages & GPU_SHADER_STAGE_VERTEX) != 0 ? VK_SHADER_STAGE_VERTEX_BIT : 0; + output |= (stages & GPU_SHADER_STAGE_TESSELLATION_CONTROL) != 0 ? VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT : 0; + output |= (stages & GPU_SHADER_STAGE_TESSELLATION_EVALUATION) != 0 ? VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT : 0; + output |= (stages & GPU_SHADER_STAGE_GEOMETRY) != 0 ? VK_SHADER_STAGE_GEOMETRY_BIT : 0; + output |= (stages & GPU_SHADER_STAGE_FRAGMENT) != 0 ? VK_SHADER_STAGE_FRAGMENT_BIT : 0; + output |= (stages & GPU_SHADER_STAGE_COMPUTE) != 0 ? VK_SHADER_STAGE_COMPUTE_BIT : 0; + output |= (stages & GPU_SHADER_STAGE_ALL_GRAPHICS) != 0 ? VK_SHADER_STAGE_ALL_GRAPHICS : 0; + output |= (stages & GPU_SHADER_STAGE_ALL) != 0 ? VK_SHADER_STAGE_ALL : 0; + output |= (stages & GPU_SHADER_STAGE_RAYGEN) != 0 ? VK_SHADER_STAGE_RAYGEN_BIT_KHR : 0; + output |= (stages & GPU_SHADER_STAGE_ANY_HIT) != 0 ? VK_SHADER_STAGE_ANY_HIT_BIT_KHR : 0; + output |= (stages & GPU_SHADER_STAGE_CLOSEST_HIT) != 0 ? VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR : 0; + output |= (stages & GPU_SHADER_STAGE_MISS) != 0 ? VK_SHADER_STAGE_MISS_BIT_KHR : 0; + output |= (stages & GPU_SHADER_STAGE_INTERSECTION) != 0 ? VK_SHADER_STAGE_INTERSECTION_BIT_KHR : 0; + output |= (stages & GPU_SHADER_STAGE_CALLABLE) != 0 ? VK_SHADER_STAGE_CALLABLE_BIT_KHR : 0; + output |= (stages & GPU_SHADER_STAGE_TASK) != 0 ? VK_SHADER_STAGE_TASK_BIT_EXT : 0; + output |= (stages & GPU_SHADER_STAGE_MESH) != 0 ? VK_SHADER_STAGE_MESH_BIT_EXT : 0; + + return output; +} + +wp_intern GpuShaderStage gpuShaderStageFromVkShaderStage(VkShaderStageFlags stages) { + GpuShaderStage output = 0; + + output |= (stages & VK_SHADER_STAGE_VERTEX_BIT) != 0 ? GPU_SHADER_STAGE_VERTEX : 0; + output |= (stages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0 ? GPU_SHADER_STAGE_TESSELLATION_CONTROL : 0; + output |= (stages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0 ? GPU_SHADER_STAGE_TESSELLATION_EVALUATION : 0; + output |= (stages & VK_SHADER_STAGE_GEOMETRY_BIT) != 0 ? GPU_SHADER_STAGE_GEOMETRY : 0; + output |= (stages & VK_SHADER_STAGE_FRAGMENT_BIT) != 0 ? GPU_SHADER_STAGE_FRAGMENT : 0; + output |= (stages & VK_SHADER_STAGE_COMPUTE_BIT) != 0 ? GPU_SHADER_STAGE_COMPUTE : 0; + output |= (stages & VK_SHADER_STAGE_ALL_GRAPHICS) != 0 ? GPU_SHADER_STAGE_ALL_GRAPHICS : 0; + output |= (stages & VK_SHADER_STAGE_ALL) != 0 ? GPU_SHADER_STAGE_ALL : 0; + output |= (stages & VK_SHADER_STAGE_RAYGEN_BIT_KHR) != 0 ? GPU_SHADER_STAGE_RAYGEN : 0; + output |= (stages & VK_SHADER_STAGE_ANY_HIT_BIT_KHR) != 0 ? GPU_SHADER_STAGE_ANY_HIT : 0; + output |= (stages & VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR) != 0 ? GPU_SHADER_STAGE_CLOSEST_HIT : 0; + output |= (stages & VK_SHADER_STAGE_MISS_BIT_KHR) != 0 ? GPU_SHADER_STAGE_MISS : 0; + output |= (stages & VK_SHADER_STAGE_INTERSECTION_BIT_KHR) != 0 ? GPU_SHADER_STAGE_INTERSECTION : 0; + output |= (stages & VK_SHADER_STAGE_CALLABLE_BIT_KHR) != 0 ? GPU_SHADER_STAGE_CALLABLE : 0; + output |= (stages & VK_SHADER_STAGE_TASK_BIT_EXT) != 0 ? GPU_SHADER_STAGE_TASK : 0; + output |= (stages & VK_SHADER_STAGE_MESH_BIT_EXT) != 0 ? GPU_SHADER_STAGE_MESH : 0; + + return output; +} + +wp_intern GpuDescriptorCategory descriptorCategoryFromDescriptorType(GpuDescriptorType type) { + switch (type) { + case GPU_DESCRIPTOR_TYPE_SAMPLER: + case GPU_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: + case GPU_DESCRIPTOR_TYPE_SAMPLED_IMAGE: + case GPU_DESCRIPTOR_TYPE_STORAGE_IMAGE: + case GPU_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: + return GPU_DESCRIPTOR_CATEGORY_IMAGE; + case GPU_DESCRIPTOR_TYPE_UNIFORM_BUFFER: + case GPU_DESCRIPTOR_TYPE_STORAGE_BUFFER: + case GPU_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: + case GPU_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: + return GPU_DESCRIPTOR_CATEGORY_BUFFER; + case GPU_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: + case GPU_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: + return GPU_DESCRIPTOR_CATEGORY_TEXEL_BUFFER; + case GPU_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: + return GPU_DESCRIPTOR_CATEGORY_UNIFORM_BLOCK; + default: + break; + } + + assertWithLogger(0, &logger, "Unrecognised descriptor type"); +} + +wp_intern u64 retrieveDescriptorImageInfos(const GpuDescriptorSetWriteInfo *src_write_info, + VkWriteDescriptorSet *dst_write_info, + VkDescriptorImageInfoArray dst_img_infos, + u64 dst_img_infos_offset) { + u64 img_desc_count = wpArrayCount(src_write_info->image_infos); + + for (u64 j = 0; j < img_desc_count; ++j) { + GpuDescriptorImageInfo *img_info = &(src_write_info->image_infos[j]); + VkDescriptorImageInfo vk_img_info = { + .sampler = img_info->sampler != NULL ? img_info->sampler->vk_sampler : NULL, + .imageView = img_info->image != NULL ? img_info->image->vk_view : NULL, + .imageLayout = vkImageLayoutFromGpuImageLayout(img_info->image_layout), + }; + wpArrayAppendCapped(VkDescriptorImageInfo, dst_img_infos, &vk_img_info); + } + + dst_write_info->descriptorCount = img_desc_count; + dst_write_info->pImageInfo = &dst_img_infos[dst_img_infos_offset]; + + return img_desc_count; +} + +wp_intern u64 retrieveDescriptorBufferInfos(const GpuDescriptorSetWriteInfo *src_write_info, + VkWriteDescriptorSet *dst_write_info, + VkDescriptorBufferInfoArray dst_buf_infos, + u64 dst_buf_infos_offset) { + + u64 buf_desc_count = wpArrayCount(src_write_info->buffer_infos); + + for (u64 j = 0; j < buf_desc_count; ++j) { + GpuDescriptorBufferInfo *buf_info = &(src_write_info->buffer_infos[j]); + VkDescriptorBufferInfo vk_buf_info = { + .buffer = buf_info->buffer->internal->vk_buffer, + .offset = buf_info->offset, + .range = buf_info->range > 0 ? buf_info->range : VK_WHOLE_SIZE, + }; + wpArrayAppendCapped(VkDescriptorBufferInfo, dst_buf_infos, &vk_buf_info); + } + + dst_write_info->descriptorCount = buf_desc_count; + dst_write_info->pBufferInfo = &dst_buf_infos[dst_buf_infos_offset]; + + return buf_desc_count; +} diff --git a/src/gpu/vulkan/vma.cpp b/src/gpu/vulkan/vma.cpp new file mode 100644 index 0000000..d680a39 --- /dev/null +++ b/src/gpu/vulkan/vma.cpp @@ -0,0 +1,4 @@ +// vim:fileencoding=utf-8:foldmethod=marker + +#define VMA_IMPLEMENTATION +#include diff --git a/src/gpu/vulkan/vulkan_profiles/vulkan_profiles.cpp b/src/gpu/vulkan/vulkan_profiles/vulkan_profiles.cpp new file mode 100644 index 0000000..9113e42 --- /dev/null +++ b/src/gpu/vulkan/vulkan_profiles/vulkan_profiles.cpp @@ -0,0 +1,4399 @@ + +/* + * 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_TEST_window_renderer +namespace VP_TEST_WINDOW_RENDERER { + +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_MAINTENANCE_5_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; + s->shaderDrawParameters = 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); + ret = ret && (s->shaderDrawParameters == 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_TEST_window_renderer_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_MAINTENANCE_5_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; + s->shaderDrawParameters = 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); + ret = ret && (s->shaderDrawParameters == 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_TEST_window_renderer_block +} // namespace blocks +} // namespace VP_TEST_WINDOW_RENDERER +#endif // VP_TEST_window_renderer + + +#ifdef VP_TEST_window_renderer +namespace VP_TEST_WINDOW_RENDERER { + 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_TEST_window_renderer_block { + static const VpVariantDesc variants[] = { + { + "VP_TEST_window_renderer_block", + static_cast(std::size(blocks::VP_TEST_window_renderer_block::instanceExtensions)), blocks::VP_TEST_window_renderer_block::instanceExtensions, + static_cast(std::size(blocks::VP_TEST_window_renderer_block::deviceExtensions)), blocks::VP_TEST_window_renderer_block::deviceExtensions, + static_cast(std::size(featureStructTypes)), featureStructTypes, + blocks::VP_TEST_window_renderer_block::featureDesc, + static_cast(std::size(propertyStructTypes)), propertyStructTypes, + blocks::VP_TEST_window_renderer_block::propertyDesc, + 0, nullptr, + 0, nullptr, + 0, nullptr, + 0, nullptr, + blocks::VP_TEST_window_renderer_block::chainerDesc, + 0, nullptr, + }, + }; + static const uint32_t variantCount = static_cast(std::size(variants)); + } // namespace VP_TEST_window_renderer_block + } // namespace blocks + + static const VpCapabilitiesDesc capabilities[] = { + { blocks::VP_TEST_window_renderer_block::variantCount, blocks::VP_TEST_window_renderer_block::variants }, + }; + static const uint32_t capabilityCount = static_cast(std::size(capabilities)); +} // namespace VP_TEST_WINDOW_RENDERER +#endif //VP_TEST_window_renderer + +static const VpProfileDesc profiles[] = { +#ifdef VP_TEST_window_renderer + VpProfileDesc{ + VpProfileProperties{ VP_TEST_WINDOW_RENDERER_NAME, VP_TEST_WINDOW_RENDERER_SPEC_VERSION }, + VP_TEST_WINDOW_RENDERER_MIN_API_VERSION, + VP_TEST_WINDOW_RENDERER::mergedCapabilities, + 0, nullptr, + VP_TEST_WINDOW_RENDERER::capabilityCount, VP_TEST_WINDOW_RENDERER::capabilities, + 0, nullptr, + }, +#endif // VP_TEST_WINDOW_RENDERER +}; +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/src/gpu/vulkan/vulkan_profiles/vulkan_profiles.h b/src/gpu/vulkan/vulkan_profiles/vulkan_profiles.h new file mode 100644 index 0000000..deb0deb --- /dev/null +++ b/src/gpu/vulkan/vulkan_profiles/vulkan_profiles.h @@ -0,0 +1,434 @@ + +/* + * 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_maintenance5) && \ + defined(VK_KHR_swapchain) +#define VP_TEST_window_renderer 1 +#define VP_TEST_WINDOW_RENDERER_NAME "VP_TEST_window_renderer" +#define VP_TEST_WINDOW_RENDERER_SPEC_VERSION 1 +#define VP_TEST_WINDOW_RENDERER_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/src/gpu/vulkan/vulkan_profiles/vulkan_profiles.hpp b/src/gpu/vulkan/vulkan_profiles/vulkan_profiles.hpp new file mode 100644 index 0000000..5e61915 --- /dev/null +++ b/src/gpu/vulkan/vulkan_profiles/vulkan_profiles.hpp @@ -0,0 +1,4801 @@ + +/* + * 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_maintenance5) && \ + defined(VK_KHR_swapchain) +#define VP_TEST_window_renderer 1 +#define VP_TEST_WINDOW_RENDERER_NAME "VP_TEST_window_renderer" +#define VP_TEST_WINDOW_RENDERER_SPEC_VERSION 1 +#define VP_TEST_WINDOW_RENDERER_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_TEST_window_renderer +namespace VP_TEST_WINDOW_RENDERER { + +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_MAINTENANCE_5_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; + s->shaderDrawParameters = 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); + ret = ret && (s->shaderDrawParameters == 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_TEST_window_renderer_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_MAINTENANCE_5_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; + s->shaderDrawParameters = 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); + ret = ret && (s->shaderDrawParameters == 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_TEST_window_renderer_block +} // namespace blocks +} // namespace VP_TEST_WINDOW_RENDERER +#endif // VP_TEST_window_renderer + + +#ifdef VP_TEST_window_renderer +namespace VP_TEST_WINDOW_RENDERER { + 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_TEST_window_renderer_block { + static const VpVariantDesc variants[] = { + { + "VP_TEST_window_renderer_block", + static_cast(std::size(blocks::VP_TEST_window_renderer_block::instanceExtensions)), blocks::VP_TEST_window_renderer_block::instanceExtensions, + static_cast(std::size(blocks::VP_TEST_window_renderer_block::deviceExtensions)), blocks::VP_TEST_window_renderer_block::deviceExtensions, + static_cast(std::size(featureStructTypes)), featureStructTypes, + blocks::VP_TEST_window_renderer_block::featureDesc, + static_cast(std::size(propertyStructTypes)), propertyStructTypes, + blocks::VP_TEST_window_renderer_block::propertyDesc, + 0, nullptr, + 0, nullptr, + 0, nullptr, + 0, nullptr, + blocks::VP_TEST_window_renderer_block::chainerDesc, + 0, nullptr, + }, + }; + static const uint32_t variantCount = static_cast(std::size(variants)); + } // namespace VP_TEST_window_renderer_block + } // namespace blocks + + static const VpCapabilitiesDesc capabilities[] = { + { blocks::VP_TEST_window_renderer_block::variantCount, blocks::VP_TEST_window_renderer_block::variants }, + }; + static const uint32_t capabilityCount = static_cast(std::size(capabilities)); +} // namespace VP_TEST_WINDOW_RENDERER +#endif //VP_TEST_window_renderer + +static const VpProfileDesc profiles[] = { +#ifdef VP_TEST_window_renderer + VpProfileDesc{ + VpProfileProperties{ VP_TEST_WINDOW_RENDERER_NAME, VP_TEST_WINDOW_RENDERER_SPEC_VERSION }, + VP_TEST_WINDOW_RENDERER_MIN_API_VERSION, + VP_TEST_WINDOW_RENDERER::mergedCapabilities, + 0, nullptr, + VP_TEST_WINDOW_RENDERER::capabilityCount, VP_TEST_WINDOW_RENDERER::capabilities, + 0, nullptr, + }, +#endif // VP_TEST_WINDOW_RENDERER +}; +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