17ec681f3Smrg/*
27ec681f3Smrg * Copyright 2019 Google LLC
37ec681f3Smrg * SPDX-License-Identifier: MIT
47ec681f3Smrg *
57ec681f3Smrg * based in part on anv and radv which are:
67ec681f3Smrg * Copyright © 2015 Intel Corporation
77ec681f3Smrg * Copyright © 2016 Red Hat.
87ec681f3Smrg * Copyright © 2016 Bas Nieuwenhuizen
97ec681f3Smrg */
107ec681f3Smrg
117ec681f3Smrg#include "vn_physical_device.h"
127ec681f3Smrg
137ec681f3Smrg#include <stdio.h>
147ec681f3Smrg
157ec681f3Smrg#include "git_sha1.h"
167ec681f3Smrg#include "util/mesa-sha1.h"
177ec681f3Smrg#include "venus-protocol/vn_protocol_driver_device.h"
187ec681f3Smrg#include "venus-protocol/vn_protocol_driver_info.h"
197ec681f3Smrg
207ec681f3Smrg#include "vn_android.h"
217ec681f3Smrg#include "vn_instance.h"
227ec681f3Smrg
237ec681f3Smrg#define VN_EXTENSION_TABLE_INDEX(tbl, ext)                                   \
247ec681f3Smrg   ((const bool *)((const void *)(&(tbl)) +                                  \
257ec681f3Smrg                   offsetof(__typeof__(tbl), ext)) -                         \
267ec681f3Smrg    (tbl).extensions)
277ec681f3Smrg
287ec681f3Smrgstatic void
297ec681f3Smrgvn_physical_device_init_features(struct vn_physical_device *physical_dev)
307ec681f3Smrg{
317ec681f3Smrg   struct vn_instance *instance = physical_dev->instance;
327ec681f3Smrg   struct {
337ec681f3Smrg      /* Vulkan 1.1 */
347ec681f3Smrg      VkPhysicalDevice16BitStorageFeatures sixteen_bit_storage;
357ec681f3Smrg      VkPhysicalDeviceMultiviewFeatures multiview;
367ec681f3Smrg      VkPhysicalDeviceVariablePointersFeatures variable_pointers;
377ec681f3Smrg      VkPhysicalDeviceProtectedMemoryFeatures protected_memory;
387ec681f3Smrg      VkPhysicalDeviceSamplerYcbcrConversionFeatures sampler_ycbcr_conversion;
397ec681f3Smrg      VkPhysicalDeviceShaderDrawParametersFeatures shader_draw_parameters;
407ec681f3Smrg
417ec681f3Smrg      /* Vulkan 1.2 */
427ec681f3Smrg      VkPhysicalDevice8BitStorageFeatures eight_bit_storage;
437ec681f3Smrg      VkPhysicalDeviceShaderAtomicInt64Features shader_atomic_int64;
447ec681f3Smrg      VkPhysicalDeviceShaderFloat16Int8Features shader_float16_int8;
457ec681f3Smrg      VkPhysicalDeviceDescriptorIndexingFeatures descriptor_indexing;
467ec681f3Smrg      VkPhysicalDeviceScalarBlockLayoutFeatures scalar_block_layout;
477ec681f3Smrg      VkPhysicalDeviceImagelessFramebufferFeatures imageless_framebuffer;
487ec681f3Smrg      VkPhysicalDeviceUniformBufferStandardLayoutFeatures
497ec681f3Smrg         uniform_buffer_standard_layout;
507ec681f3Smrg      VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures
517ec681f3Smrg         shader_subgroup_extended_types;
527ec681f3Smrg      VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures
537ec681f3Smrg         separate_depth_stencil_layouts;
547ec681f3Smrg      VkPhysicalDeviceHostQueryResetFeatures host_query_reset;
557ec681f3Smrg      VkPhysicalDeviceTimelineSemaphoreFeatures timeline_semaphore;
567ec681f3Smrg      VkPhysicalDeviceBufferDeviceAddressFeatures buffer_device_address;
577ec681f3Smrg      VkPhysicalDeviceVulkanMemoryModelFeatures vulkan_memory_model;
587ec681f3Smrg   } local_feats;
597ec681f3Smrg
607ec681f3Smrg   physical_dev->features.sType =
617ec681f3Smrg      VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
627ec681f3Smrg   if (physical_dev->renderer_version >= VK_API_VERSION_1_2) {
637ec681f3Smrg      physical_dev->features.pNext = &physical_dev->vulkan_1_1_features;
647ec681f3Smrg
657ec681f3Smrg      physical_dev->vulkan_1_1_features.sType =
667ec681f3Smrg         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
677ec681f3Smrg      physical_dev->vulkan_1_1_features.pNext =
687ec681f3Smrg         &physical_dev->vulkan_1_2_features;
697ec681f3Smrg      physical_dev->vulkan_1_2_features.sType =
707ec681f3Smrg         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
717ec681f3Smrg      physical_dev->vulkan_1_2_features.pNext = NULL;
727ec681f3Smrg   } else {
737ec681f3Smrg      physical_dev->features.pNext = &local_feats.sixteen_bit_storage;
747ec681f3Smrg
757ec681f3Smrg      local_feats.sixteen_bit_storage.sType =
767ec681f3Smrg         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES;
777ec681f3Smrg      local_feats.sixteen_bit_storage.pNext = &local_feats.multiview;
787ec681f3Smrg      local_feats.multiview.sType =
797ec681f3Smrg         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES;
807ec681f3Smrg      local_feats.multiview.pNext = &local_feats.variable_pointers;
817ec681f3Smrg      local_feats.variable_pointers.sType =
827ec681f3Smrg         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES;
837ec681f3Smrg      local_feats.variable_pointers.pNext = &local_feats.protected_memory;
847ec681f3Smrg      local_feats.protected_memory.sType =
857ec681f3Smrg         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES;
867ec681f3Smrg      local_feats.protected_memory.pNext =
877ec681f3Smrg         &local_feats.sampler_ycbcr_conversion;
887ec681f3Smrg      local_feats.sampler_ycbcr_conversion.sType =
897ec681f3Smrg         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES;
907ec681f3Smrg      local_feats.sampler_ycbcr_conversion.pNext =
917ec681f3Smrg         &local_feats.shader_draw_parameters;
927ec681f3Smrg      local_feats.shader_draw_parameters.sType =
937ec681f3Smrg         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES;
947ec681f3Smrg      local_feats.shader_draw_parameters.pNext =
957ec681f3Smrg         &local_feats.eight_bit_storage;
967ec681f3Smrg
977ec681f3Smrg      local_feats.eight_bit_storage.sType =
987ec681f3Smrg         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES;
997ec681f3Smrg      local_feats.eight_bit_storage.pNext = &local_feats.shader_atomic_int64;
1007ec681f3Smrg      local_feats.shader_atomic_int64.sType =
1017ec681f3Smrg         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES;
1027ec681f3Smrg      local_feats.shader_atomic_int64.pNext =
1037ec681f3Smrg         &local_feats.shader_float16_int8;
1047ec681f3Smrg      local_feats.shader_float16_int8.sType =
1057ec681f3Smrg         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES;
1067ec681f3Smrg      local_feats.shader_float16_int8.pNext =
1077ec681f3Smrg         &local_feats.descriptor_indexing;
1087ec681f3Smrg      local_feats.descriptor_indexing.sType =
1097ec681f3Smrg         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES;
1107ec681f3Smrg      local_feats.descriptor_indexing.pNext =
1117ec681f3Smrg         &local_feats.scalar_block_layout;
1127ec681f3Smrg      local_feats.scalar_block_layout.sType =
1137ec681f3Smrg         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES;
1147ec681f3Smrg      local_feats.scalar_block_layout.pNext =
1157ec681f3Smrg         &local_feats.imageless_framebuffer;
1167ec681f3Smrg      local_feats.imageless_framebuffer.sType =
1177ec681f3Smrg         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES;
1187ec681f3Smrg      local_feats.imageless_framebuffer.pNext =
1197ec681f3Smrg         &local_feats.uniform_buffer_standard_layout;
1207ec681f3Smrg      local_feats.uniform_buffer_standard_layout.sType =
1217ec681f3Smrg         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES;
1227ec681f3Smrg      local_feats.uniform_buffer_standard_layout.pNext =
1237ec681f3Smrg         &local_feats.shader_subgroup_extended_types;
1247ec681f3Smrg      local_feats.shader_subgroup_extended_types.sType =
1257ec681f3Smrg         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES;
1267ec681f3Smrg      local_feats.shader_subgroup_extended_types.pNext =
1277ec681f3Smrg         &local_feats.separate_depth_stencil_layouts;
1287ec681f3Smrg      local_feats.separate_depth_stencil_layouts.sType =
1297ec681f3Smrg         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES;
1307ec681f3Smrg      local_feats.separate_depth_stencil_layouts.pNext =
1317ec681f3Smrg         &local_feats.host_query_reset;
1327ec681f3Smrg      local_feats.host_query_reset.sType =
1337ec681f3Smrg         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES;
1347ec681f3Smrg      local_feats.host_query_reset.pNext = &local_feats.timeline_semaphore;
1357ec681f3Smrg      local_feats.timeline_semaphore.sType =
1367ec681f3Smrg         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES;
1377ec681f3Smrg      local_feats.timeline_semaphore.pNext =
1387ec681f3Smrg         &local_feats.buffer_device_address;
1397ec681f3Smrg      local_feats.buffer_device_address.sType =
1407ec681f3Smrg         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES;
1417ec681f3Smrg      local_feats.buffer_device_address.pNext =
1427ec681f3Smrg         &local_feats.vulkan_memory_model;
1437ec681f3Smrg      local_feats.vulkan_memory_model.sType =
1447ec681f3Smrg         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES;
1457ec681f3Smrg      local_feats.vulkan_memory_model.pNext = NULL;
1467ec681f3Smrg   }
1477ec681f3Smrg
1487ec681f3Smrg   if (physical_dev->renderer_extensions.EXT_transform_feedback) {
1497ec681f3Smrg      physical_dev->transform_feedback_features.sType =
1507ec681f3Smrg         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT;
1517ec681f3Smrg      physical_dev->transform_feedback_features.pNext =
1527ec681f3Smrg         physical_dev->features.pNext;
1537ec681f3Smrg      physical_dev->features.pNext =
1547ec681f3Smrg         &physical_dev->transform_feedback_features;
1557ec681f3Smrg   }
1567ec681f3Smrg
1577ec681f3Smrg   vn_call_vkGetPhysicalDeviceFeatures2(
1587ec681f3Smrg      instance, vn_physical_device_to_handle(physical_dev),
1597ec681f3Smrg      &physical_dev->features);
1607ec681f3Smrg
1617ec681f3Smrg   const struct vk_device_extension_table *exts =
1627ec681f3Smrg      &physical_dev->renderer_extensions;
1637ec681f3Smrg   struct VkPhysicalDeviceVulkan11Features *vk11_feats =
1647ec681f3Smrg      &physical_dev->vulkan_1_1_features;
1657ec681f3Smrg   struct VkPhysicalDeviceVulkan12Features *vk12_feats =
1667ec681f3Smrg      &physical_dev->vulkan_1_2_features;
1677ec681f3Smrg
1687ec681f3Smrg   if (physical_dev->renderer_version < VK_API_VERSION_1_2) {
1697ec681f3Smrg      vk11_feats->storageBuffer16BitAccess =
1707ec681f3Smrg         local_feats.sixteen_bit_storage.storageBuffer16BitAccess;
1717ec681f3Smrg      vk11_feats->uniformAndStorageBuffer16BitAccess =
1727ec681f3Smrg         local_feats.sixteen_bit_storage.uniformAndStorageBuffer16BitAccess;
1737ec681f3Smrg      vk11_feats->storagePushConstant16 =
1747ec681f3Smrg         local_feats.sixteen_bit_storage.storagePushConstant16;
1757ec681f3Smrg      vk11_feats->storageInputOutput16 =
1767ec681f3Smrg         local_feats.sixteen_bit_storage.storageInputOutput16;
1777ec681f3Smrg
1787ec681f3Smrg      vk11_feats->multiview = local_feats.multiview.multiview;
1797ec681f3Smrg      vk11_feats->multiviewGeometryShader =
1807ec681f3Smrg         local_feats.multiview.multiviewGeometryShader;
1817ec681f3Smrg      vk11_feats->multiviewTessellationShader =
1827ec681f3Smrg         local_feats.multiview.multiviewTessellationShader;
1837ec681f3Smrg
1847ec681f3Smrg      vk11_feats->variablePointersStorageBuffer =
1857ec681f3Smrg         local_feats.variable_pointers.variablePointersStorageBuffer;
1867ec681f3Smrg      vk11_feats->variablePointers =
1877ec681f3Smrg         local_feats.variable_pointers.variablePointers;
1887ec681f3Smrg
1897ec681f3Smrg      vk11_feats->protectedMemory =
1907ec681f3Smrg         local_feats.protected_memory.protectedMemory;
1917ec681f3Smrg
1927ec681f3Smrg      vk11_feats->samplerYcbcrConversion =
1937ec681f3Smrg         local_feats.sampler_ycbcr_conversion.samplerYcbcrConversion;
1947ec681f3Smrg
1957ec681f3Smrg      vk11_feats->shaderDrawParameters =
1967ec681f3Smrg         local_feats.shader_draw_parameters.shaderDrawParameters;
1977ec681f3Smrg
1987ec681f3Smrg      vk12_feats->samplerMirrorClampToEdge =
1997ec681f3Smrg         exts->KHR_sampler_mirror_clamp_to_edge;
2007ec681f3Smrg      vk12_feats->drawIndirectCount = exts->KHR_draw_indirect_count;
2017ec681f3Smrg
2027ec681f3Smrg      if (exts->KHR_8bit_storage) {
2037ec681f3Smrg         vk12_feats->storageBuffer8BitAccess =
2047ec681f3Smrg            local_feats.eight_bit_storage.storageBuffer8BitAccess;
2057ec681f3Smrg         vk12_feats->uniformAndStorageBuffer8BitAccess =
2067ec681f3Smrg            local_feats.eight_bit_storage.uniformAndStorageBuffer8BitAccess;
2077ec681f3Smrg         vk12_feats->storagePushConstant8 =
2087ec681f3Smrg            local_feats.eight_bit_storage.storagePushConstant8;
2097ec681f3Smrg      }
2107ec681f3Smrg      if (exts->KHR_shader_atomic_int64) {
2117ec681f3Smrg         vk12_feats->shaderBufferInt64Atomics =
2127ec681f3Smrg            local_feats.shader_atomic_int64.shaderBufferInt64Atomics;
2137ec681f3Smrg         vk12_feats->shaderSharedInt64Atomics =
2147ec681f3Smrg            local_feats.shader_atomic_int64.shaderSharedInt64Atomics;
2157ec681f3Smrg      }
2167ec681f3Smrg      if (exts->KHR_shader_float16_int8) {
2177ec681f3Smrg         vk12_feats->shaderFloat16 =
2187ec681f3Smrg            local_feats.shader_float16_int8.shaderFloat16;
2197ec681f3Smrg         vk12_feats->shaderInt8 = local_feats.shader_float16_int8.shaderInt8;
2207ec681f3Smrg      }
2217ec681f3Smrg      if (exts->EXT_descriptor_indexing) {
2227ec681f3Smrg         vk12_feats->descriptorIndexing = true;
2237ec681f3Smrg         vk12_feats->shaderInputAttachmentArrayDynamicIndexing =
2247ec681f3Smrg            local_feats.descriptor_indexing
2257ec681f3Smrg               .shaderInputAttachmentArrayDynamicIndexing;
2267ec681f3Smrg         vk12_feats->shaderUniformTexelBufferArrayDynamicIndexing =
2277ec681f3Smrg            local_feats.descriptor_indexing
2287ec681f3Smrg               .shaderUniformTexelBufferArrayDynamicIndexing;
2297ec681f3Smrg         vk12_feats->shaderStorageTexelBufferArrayDynamicIndexing =
2307ec681f3Smrg            local_feats.descriptor_indexing
2317ec681f3Smrg               .shaderStorageTexelBufferArrayDynamicIndexing;
2327ec681f3Smrg         vk12_feats->shaderUniformBufferArrayNonUniformIndexing =
2337ec681f3Smrg            local_feats.descriptor_indexing
2347ec681f3Smrg               .shaderUniformBufferArrayNonUniformIndexing;
2357ec681f3Smrg         vk12_feats->shaderSampledImageArrayNonUniformIndexing =
2367ec681f3Smrg            local_feats.descriptor_indexing
2377ec681f3Smrg               .shaderSampledImageArrayNonUniformIndexing;
2387ec681f3Smrg         vk12_feats->shaderStorageBufferArrayNonUniformIndexing =
2397ec681f3Smrg            local_feats.descriptor_indexing
2407ec681f3Smrg               .shaderStorageBufferArrayNonUniformIndexing;
2417ec681f3Smrg         vk12_feats->shaderStorageImageArrayNonUniformIndexing =
2427ec681f3Smrg            local_feats.descriptor_indexing
2437ec681f3Smrg               .shaderStorageImageArrayNonUniformIndexing;
2447ec681f3Smrg         vk12_feats->shaderInputAttachmentArrayNonUniformIndexing =
2457ec681f3Smrg            local_feats.descriptor_indexing
2467ec681f3Smrg               .shaderInputAttachmentArrayNonUniformIndexing;
2477ec681f3Smrg         vk12_feats->shaderUniformTexelBufferArrayNonUniformIndexing =
2487ec681f3Smrg            local_feats.descriptor_indexing
2497ec681f3Smrg               .shaderUniformTexelBufferArrayNonUniformIndexing;
2507ec681f3Smrg         vk12_feats->shaderStorageTexelBufferArrayNonUniformIndexing =
2517ec681f3Smrg            local_feats.descriptor_indexing
2527ec681f3Smrg               .shaderStorageTexelBufferArrayNonUniformIndexing;
2537ec681f3Smrg         vk12_feats->descriptorBindingUniformBufferUpdateAfterBind =
2547ec681f3Smrg            local_feats.descriptor_indexing
2557ec681f3Smrg               .descriptorBindingUniformBufferUpdateAfterBind;
2567ec681f3Smrg         vk12_feats->descriptorBindingSampledImageUpdateAfterBind =
2577ec681f3Smrg            local_feats.descriptor_indexing
2587ec681f3Smrg               .descriptorBindingSampledImageUpdateAfterBind;
2597ec681f3Smrg         vk12_feats->descriptorBindingStorageImageUpdateAfterBind =
2607ec681f3Smrg            local_feats.descriptor_indexing
2617ec681f3Smrg               .descriptorBindingStorageImageUpdateAfterBind;
2627ec681f3Smrg         vk12_feats->descriptorBindingStorageBufferUpdateAfterBind =
2637ec681f3Smrg            local_feats.descriptor_indexing
2647ec681f3Smrg               .descriptorBindingStorageBufferUpdateAfterBind;
2657ec681f3Smrg         vk12_feats->descriptorBindingUniformTexelBufferUpdateAfterBind =
2667ec681f3Smrg            local_feats.descriptor_indexing
2677ec681f3Smrg               .descriptorBindingUniformTexelBufferUpdateAfterBind;
2687ec681f3Smrg         vk12_feats->descriptorBindingStorageTexelBufferUpdateAfterBind =
2697ec681f3Smrg            local_feats.descriptor_indexing
2707ec681f3Smrg               .descriptorBindingStorageTexelBufferUpdateAfterBind;
2717ec681f3Smrg         vk12_feats->descriptorBindingUpdateUnusedWhilePending =
2727ec681f3Smrg            local_feats.descriptor_indexing
2737ec681f3Smrg               .descriptorBindingUpdateUnusedWhilePending;
2747ec681f3Smrg         vk12_feats->descriptorBindingPartiallyBound =
2757ec681f3Smrg            local_feats.descriptor_indexing.descriptorBindingPartiallyBound;
2767ec681f3Smrg         vk12_feats->descriptorBindingVariableDescriptorCount =
2777ec681f3Smrg            local_feats.descriptor_indexing
2787ec681f3Smrg               .descriptorBindingVariableDescriptorCount;
2797ec681f3Smrg         vk12_feats->runtimeDescriptorArray =
2807ec681f3Smrg            local_feats.descriptor_indexing.runtimeDescriptorArray;
2817ec681f3Smrg      }
2827ec681f3Smrg
2837ec681f3Smrg      vk12_feats->samplerFilterMinmax = exts->EXT_sampler_filter_minmax;
2847ec681f3Smrg
2857ec681f3Smrg      if (exts->EXT_scalar_block_layout) {
2867ec681f3Smrg         vk12_feats->scalarBlockLayout =
2877ec681f3Smrg            local_feats.scalar_block_layout.scalarBlockLayout;
2887ec681f3Smrg      }
2897ec681f3Smrg      if (exts->KHR_imageless_framebuffer) {
2907ec681f3Smrg         vk12_feats->imagelessFramebuffer =
2917ec681f3Smrg            local_feats.imageless_framebuffer.imagelessFramebuffer;
2927ec681f3Smrg      }
2937ec681f3Smrg      if (exts->KHR_uniform_buffer_standard_layout) {
2947ec681f3Smrg         vk12_feats->uniformBufferStandardLayout =
2957ec681f3Smrg            local_feats.uniform_buffer_standard_layout
2967ec681f3Smrg               .uniformBufferStandardLayout;
2977ec681f3Smrg      }
2987ec681f3Smrg      if (exts->KHR_shader_subgroup_extended_types) {
2997ec681f3Smrg         vk12_feats->shaderSubgroupExtendedTypes =
3007ec681f3Smrg            local_feats.shader_subgroup_extended_types
3017ec681f3Smrg               .shaderSubgroupExtendedTypes;
3027ec681f3Smrg      }
3037ec681f3Smrg      if (exts->KHR_separate_depth_stencil_layouts) {
3047ec681f3Smrg         vk12_feats->separateDepthStencilLayouts =
3057ec681f3Smrg            local_feats.separate_depth_stencil_layouts
3067ec681f3Smrg               .separateDepthStencilLayouts;
3077ec681f3Smrg      }
3087ec681f3Smrg      if (exts->EXT_host_query_reset) {
3097ec681f3Smrg         vk12_feats->hostQueryReset =
3107ec681f3Smrg            local_feats.host_query_reset.hostQueryReset;
3117ec681f3Smrg      }
3127ec681f3Smrg      if (exts->KHR_timeline_semaphore) {
3137ec681f3Smrg         vk12_feats->timelineSemaphore =
3147ec681f3Smrg            local_feats.timeline_semaphore.timelineSemaphore;
3157ec681f3Smrg      }
3167ec681f3Smrg      if (exts->KHR_buffer_device_address) {
3177ec681f3Smrg         vk12_feats->bufferDeviceAddress =
3187ec681f3Smrg            local_feats.buffer_device_address.bufferDeviceAddress;
3197ec681f3Smrg         vk12_feats->bufferDeviceAddressCaptureReplay =
3207ec681f3Smrg            local_feats.buffer_device_address.bufferDeviceAddressCaptureReplay;
3217ec681f3Smrg         vk12_feats->bufferDeviceAddressMultiDevice =
3227ec681f3Smrg            local_feats.buffer_device_address.bufferDeviceAddressMultiDevice;
3237ec681f3Smrg      }
3247ec681f3Smrg      if (exts->KHR_vulkan_memory_model) {
3257ec681f3Smrg         vk12_feats->vulkanMemoryModel =
3267ec681f3Smrg            local_feats.vulkan_memory_model.vulkanMemoryModel;
3277ec681f3Smrg         vk12_feats->vulkanMemoryModelDeviceScope =
3287ec681f3Smrg            local_feats.vulkan_memory_model.vulkanMemoryModelDeviceScope;
3297ec681f3Smrg         vk12_feats->vulkanMemoryModelAvailabilityVisibilityChains =
3307ec681f3Smrg            local_feats.vulkan_memory_model
3317ec681f3Smrg               .vulkanMemoryModelAvailabilityVisibilityChains;
3327ec681f3Smrg      }
3337ec681f3Smrg
3347ec681f3Smrg      vk12_feats->shaderOutputViewportIndex =
3357ec681f3Smrg         exts->EXT_shader_viewport_index_layer;
3367ec681f3Smrg      vk12_feats->shaderOutputLayer = exts->EXT_shader_viewport_index_layer;
3377ec681f3Smrg      vk12_feats->subgroupBroadcastDynamicId = false;
3387ec681f3Smrg   }
3397ec681f3Smrg}
3407ec681f3Smrg
3417ec681f3Smrgstatic void
3427ec681f3Smrgvn_physical_device_init_uuids(struct vn_physical_device *physical_dev)
3437ec681f3Smrg{
3447ec681f3Smrg   struct VkPhysicalDeviceProperties *props =
3457ec681f3Smrg      &physical_dev->properties.properties;
3467ec681f3Smrg   struct VkPhysicalDeviceVulkan11Properties *vk11_props =
3477ec681f3Smrg      &physical_dev->vulkan_1_1_properties;
3487ec681f3Smrg   struct VkPhysicalDeviceVulkan12Properties *vk12_props =
3497ec681f3Smrg      &physical_dev->vulkan_1_2_properties;
3507ec681f3Smrg   struct mesa_sha1 sha1_ctx;
3517ec681f3Smrg   uint8_t sha1[SHA1_DIGEST_LENGTH];
3527ec681f3Smrg
3537ec681f3Smrg   static_assert(VK_UUID_SIZE <= SHA1_DIGEST_LENGTH, "");
3547ec681f3Smrg
3557ec681f3Smrg   _mesa_sha1_init(&sha1_ctx);
3567ec681f3Smrg   _mesa_sha1_update(&sha1_ctx, &props->pipelineCacheUUID,
3577ec681f3Smrg                     sizeof(props->pipelineCacheUUID));
3587ec681f3Smrg   _mesa_sha1_final(&sha1_ctx, sha1);
3597ec681f3Smrg
3607ec681f3Smrg   memcpy(props->pipelineCacheUUID, sha1, VK_UUID_SIZE);
3617ec681f3Smrg
3627ec681f3Smrg   _mesa_sha1_init(&sha1_ctx);
3637ec681f3Smrg   _mesa_sha1_update(&sha1_ctx, &props->vendorID, sizeof(props->vendorID));
3647ec681f3Smrg   _mesa_sha1_update(&sha1_ctx, &props->deviceID, sizeof(props->deviceID));
3657ec681f3Smrg   _mesa_sha1_final(&sha1_ctx, sha1);
3667ec681f3Smrg
3677ec681f3Smrg   memcpy(vk11_props->deviceUUID, sha1, VK_UUID_SIZE);
3687ec681f3Smrg
3697ec681f3Smrg   _mesa_sha1_init(&sha1_ctx);
3707ec681f3Smrg   _mesa_sha1_update(&sha1_ctx, vk12_props->driverName,
3717ec681f3Smrg                     strlen(vk12_props->driverName));
3727ec681f3Smrg   _mesa_sha1_update(&sha1_ctx, vk12_props->driverInfo,
3737ec681f3Smrg                     strlen(vk12_props->driverInfo));
3747ec681f3Smrg   _mesa_sha1_final(&sha1_ctx, sha1);
3757ec681f3Smrg
3767ec681f3Smrg   memcpy(vk11_props->driverUUID, sha1, VK_UUID_SIZE);
3777ec681f3Smrg
3787ec681f3Smrg   memset(vk11_props->deviceLUID, 0, VK_LUID_SIZE);
3797ec681f3Smrg   vk11_props->deviceNodeMask = 0;
3807ec681f3Smrg   vk11_props->deviceLUIDValid = false;
3817ec681f3Smrg}
3827ec681f3Smrg
3837ec681f3Smrgstatic void
3847ec681f3Smrgvn_physical_device_init_properties(struct vn_physical_device *physical_dev)
3857ec681f3Smrg{
3867ec681f3Smrg   struct vn_instance *instance = physical_dev->instance;
3877ec681f3Smrg   struct {
3887ec681f3Smrg      /* Vulkan 1.1 */
3897ec681f3Smrg      VkPhysicalDeviceIDProperties id;
3907ec681f3Smrg      VkPhysicalDeviceSubgroupProperties subgroup;
3917ec681f3Smrg      VkPhysicalDevicePointClippingProperties point_clipping;
3927ec681f3Smrg      VkPhysicalDeviceMultiviewProperties multiview;
3937ec681f3Smrg      VkPhysicalDeviceProtectedMemoryProperties protected_memory;
3947ec681f3Smrg      VkPhysicalDeviceMaintenance3Properties maintenance_3;
3957ec681f3Smrg
3967ec681f3Smrg      /* Vulkan 1.2 */
3977ec681f3Smrg      VkPhysicalDeviceDriverProperties driver;
3987ec681f3Smrg      VkPhysicalDeviceFloatControlsProperties float_controls;
3997ec681f3Smrg      VkPhysicalDeviceDescriptorIndexingProperties descriptor_indexing;
4007ec681f3Smrg      VkPhysicalDeviceDepthStencilResolveProperties depth_stencil_resolve;
4017ec681f3Smrg      VkPhysicalDeviceSamplerFilterMinmaxProperties sampler_filter_minmax;
4027ec681f3Smrg      VkPhysicalDeviceTimelineSemaphoreProperties timeline_semaphore;
4037ec681f3Smrg   } local_props;
4047ec681f3Smrg
4057ec681f3Smrg   physical_dev->properties.sType =
4067ec681f3Smrg      VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
4077ec681f3Smrg   if (physical_dev->renderer_version >= VK_API_VERSION_1_2) {
4087ec681f3Smrg      physical_dev->properties.pNext = &physical_dev->vulkan_1_1_properties;
4097ec681f3Smrg
4107ec681f3Smrg      physical_dev->vulkan_1_1_properties.sType =
4117ec681f3Smrg         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES;
4127ec681f3Smrg      physical_dev->vulkan_1_1_properties.pNext =
4137ec681f3Smrg         &physical_dev->vulkan_1_2_properties;
4147ec681f3Smrg      physical_dev->vulkan_1_2_properties.sType =
4157ec681f3Smrg         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES;
4167ec681f3Smrg      physical_dev->vulkan_1_2_properties.pNext = NULL;
4177ec681f3Smrg   } else {
4187ec681f3Smrg      physical_dev->properties.pNext = &local_props.id;
4197ec681f3Smrg
4207ec681f3Smrg      local_props.id.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES;
4217ec681f3Smrg      local_props.id.pNext = &local_props.subgroup;
4227ec681f3Smrg      local_props.subgroup.sType =
4237ec681f3Smrg         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES;
4247ec681f3Smrg      local_props.subgroup.pNext = &local_props.point_clipping;
4257ec681f3Smrg      local_props.point_clipping.sType =
4267ec681f3Smrg         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES;
4277ec681f3Smrg      local_props.point_clipping.pNext = &local_props.multiview;
4287ec681f3Smrg      local_props.multiview.sType =
4297ec681f3Smrg         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES;
4307ec681f3Smrg      local_props.multiview.pNext = &local_props.protected_memory;
4317ec681f3Smrg      local_props.protected_memory.sType =
4327ec681f3Smrg         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES;
4337ec681f3Smrg      local_props.protected_memory.pNext = &local_props.maintenance_3;
4347ec681f3Smrg      local_props.maintenance_3.sType =
4357ec681f3Smrg         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES;
4367ec681f3Smrg      local_props.maintenance_3.pNext = &local_props.driver;
4377ec681f3Smrg
4387ec681f3Smrg      local_props.driver.sType =
4397ec681f3Smrg         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES;
4407ec681f3Smrg      local_props.driver.pNext = &local_props.float_controls;
4417ec681f3Smrg      local_props.float_controls.sType =
4427ec681f3Smrg         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES;
4437ec681f3Smrg      local_props.float_controls.pNext = &local_props.descriptor_indexing;
4447ec681f3Smrg      local_props.descriptor_indexing.sType =
4457ec681f3Smrg         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES;
4467ec681f3Smrg      local_props.descriptor_indexing.pNext =
4477ec681f3Smrg         &local_props.depth_stencil_resolve;
4487ec681f3Smrg      local_props.depth_stencil_resolve.sType =
4497ec681f3Smrg         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES;
4507ec681f3Smrg      local_props.depth_stencil_resolve.pNext =
4517ec681f3Smrg         &local_props.sampler_filter_minmax;
4527ec681f3Smrg      local_props.sampler_filter_minmax.sType =
4537ec681f3Smrg         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES;
4547ec681f3Smrg      local_props.sampler_filter_minmax.pNext =
4557ec681f3Smrg         &local_props.timeline_semaphore;
4567ec681f3Smrg      local_props.timeline_semaphore.sType =
4577ec681f3Smrg         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES;
4587ec681f3Smrg      local_props.timeline_semaphore.pNext = NULL;
4597ec681f3Smrg   }
4607ec681f3Smrg
4617ec681f3Smrg   if (physical_dev->renderer_extensions.EXT_transform_feedback) {
4627ec681f3Smrg      physical_dev->transform_feedback_properties.sType =
4637ec681f3Smrg         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT;
4647ec681f3Smrg      physical_dev->transform_feedback_properties.pNext =
4657ec681f3Smrg         physical_dev->properties.pNext;
4667ec681f3Smrg      physical_dev->properties.pNext =
4677ec681f3Smrg         &physical_dev->transform_feedback_properties;
4687ec681f3Smrg   }
4697ec681f3Smrg
4707ec681f3Smrg   vn_call_vkGetPhysicalDeviceProperties2(
4717ec681f3Smrg      instance, vn_physical_device_to_handle(physical_dev),
4727ec681f3Smrg      &physical_dev->properties);
4737ec681f3Smrg
4747ec681f3Smrg   const struct vk_device_extension_table *exts =
4757ec681f3Smrg      &physical_dev->renderer_extensions;
4767ec681f3Smrg   struct VkPhysicalDeviceProperties *props =
4777ec681f3Smrg      &physical_dev->properties.properties;
4787ec681f3Smrg   struct VkPhysicalDeviceVulkan11Properties *vk11_props =
4797ec681f3Smrg      &physical_dev->vulkan_1_1_properties;
4807ec681f3Smrg   struct VkPhysicalDeviceVulkan12Properties *vk12_props =
4817ec681f3Smrg      &physical_dev->vulkan_1_2_properties;
4827ec681f3Smrg
4837ec681f3Smrg   if (physical_dev->renderer_version < VK_API_VERSION_1_2) {
4847ec681f3Smrg      memcpy(vk11_props->deviceUUID, local_props.id.deviceUUID,
4857ec681f3Smrg             sizeof(vk11_props->deviceUUID));
4867ec681f3Smrg      memcpy(vk11_props->driverUUID, local_props.id.driverUUID,
4877ec681f3Smrg             sizeof(vk11_props->driverUUID));
4887ec681f3Smrg      memcpy(vk11_props->deviceLUID, local_props.id.deviceLUID,
4897ec681f3Smrg             sizeof(vk11_props->deviceLUID));
4907ec681f3Smrg      vk11_props->deviceNodeMask = local_props.id.deviceNodeMask;
4917ec681f3Smrg      vk11_props->deviceLUIDValid = local_props.id.deviceLUIDValid;
4927ec681f3Smrg
4937ec681f3Smrg      vk11_props->subgroupSize = local_props.subgroup.subgroupSize;
4947ec681f3Smrg      vk11_props->subgroupSupportedStages =
4957ec681f3Smrg         local_props.subgroup.supportedStages;
4967ec681f3Smrg      vk11_props->subgroupSupportedOperations =
4977ec681f3Smrg         local_props.subgroup.supportedOperations;
4987ec681f3Smrg      vk11_props->subgroupQuadOperationsInAllStages =
4997ec681f3Smrg         local_props.subgroup.quadOperationsInAllStages;
5007ec681f3Smrg
5017ec681f3Smrg      vk11_props->pointClippingBehavior =
5027ec681f3Smrg         local_props.point_clipping.pointClippingBehavior;
5037ec681f3Smrg
5047ec681f3Smrg      vk11_props->maxMultiviewViewCount =
5057ec681f3Smrg         local_props.multiview.maxMultiviewViewCount;
5067ec681f3Smrg      vk11_props->maxMultiviewInstanceIndex =
5077ec681f3Smrg         local_props.multiview.maxMultiviewInstanceIndex;
5087ec681f3Smrg
5097ec681f3Smrg      vk11_props->protectedNoFault =
5107ec681f3Smrg         local_props.protected_memory.protectedNoFault;
5117ec681f3Smrg
5127ec681f3Smrg      vk11_props->maxPerSetDescriptors =
5137ec681f3Smrg         local_props.maintenance_3.maxPerSetDescriptors;
5147ec681f3Smrg      vk11_props->maxMemoryAllocationSize =
5157ec681f3Smrg         local_props.maintenance_3.maxMemoryAllocationSize;
5167ec681f3Smrg
5177ec681f3Smrg      if (exts->KHR_driver_properties) {
5187ec681f3Smrg         vk12_props->driverID = local_props.driver.driverID;
5197ec681f3Smrg         memcpy(vk12_props->driverName, local_props.driver.driverName,
5207ec681f3Smrg                VK_MAX_DRIVER_NAME_SIZE);
5217ec681f3Smrg         memcpy(vk12_props->driverInfo, local_props.driver.driverInfo,
5227ec681f3Smrg                VK_MAX_DRIVER_INFO_SIZE);
5237ec681f3Smrg         vk12_props->conformanceVersion =
5247ec681f3Smrg            local_props.driver.conformanceVersion;
5257ec681f3Smrg      }
5267ec681f3Smrg      if (exts->KHR_shader_float_controls) {
5277ec681f3Smrg         vk12_props->denormBehaviorIndependence =
5287ec681f3Smrg            local_props.float_controls.denormBehaviorIndependence;
5297ec681f3Smrg         vk12_props->roundingModeIndependence =
5307ec681f3Smrg            local_props.float_controls.roundingModeIndependence;
5317ec681f3Smrg         vk12_props->shaderSignedZeroInfNanPreserveFloat16 =
5327ec681f3Smrg            local_props.float_controls.shaderSignedZeroInfNanPreserveFloat16;
5337ec681f3Smrg         vk12_props->shaderSignedZeroInfNanPreserveFloat32 =
5347ec681f3Smrg            local_props.float_controls.shaderSignedZeroInfNanPreserveFloat32;
5357ec681f3Smrg         vk12_props->shaderSignedZeroInfNanPreserveFloat64 =
5367ec681f3Smrg            local_props.float_controls.shaderSignedZeroInfNanPreserveFloat64;
5377ec681f3Smrg         vk12_props->shaderDenormPreserveFloat16 =
5387ec681f3Smrg            local_props.float_controls.shaderDenormPreserveFloat16;
5397ec681f3Smrg         vk12_props->shaderDenormPreserveFloat32 =
5407ec681f3Smrg            local_props.float_controls.shaderDenormPreserveFloat32;
5417ec681f3Smrg         vk12_props->shaderDenormPreserveFloat64 =
5427ec681f3Smrg            local_props.float_controls.shaderDenormPreserveFloat64;
5437ec681f3Smrg         vk12_props->shaderDenormFlushToZeroFloat16 =
5447ec681f3Smrg            local_props.float_controls.shaderDenormFlushToZeroFloat16;
5457ec681f3Smrg         vk12_props->shaderDenormFlushToZeroFloat32 =
5467ec681f3Smrg            local_props.float_controls.shaderDenormFlushToZeroFloat32;
5477ec681f3Smrg         vk12_props->shaderDenormFlushToZeroFloat64 =
5487ec681f3Smrg            local_props.float_controls.shaderDenormFlushToZeroFloat64;
5497ec681f3Smrg         vk12_props->shaderRoundingModeRTEFloat16 =
5507ec681f3Smrg            local_props.float_controls.shaderRoundingModeRTEFloat16;
5517ec681f3Smrg         vk12_props->shaderRoundingModeRTEFloat32 =
5527ec681f3Smrg            local_props.float_controls.shaderRoundingModeRTEFloat32;
5537ec681f3Smrg         vk12_props->shaderRoundingModeRTEFloat64 =
5547ec681f3Smrg            local_props.float_controls.shaderRoundingModeRTEFloat64;
5557ec681f3Smrg         vk12_props->shaderRoundingModeRTZFloat16 =
5567ec681f3Smrg            local_props.float_controls.shaderRoundingModeRTZFloat16;
5577ec681f3Smrg         vk12_props->shaderRoundingModeRTZFloat32 =
5587ec681f3Smrg            local_props.float_controls.shaderRoundingModeRTZFloat32;
5597ec681f3Smrg         vk12_props->shaderRoundingModeRTZFloat64 =
5607ec681f3Smrg            local_props.float_controls.shaderRoundingModeRTZFloat64;
5617ec681f3Smrg      }
5627ec681f3Smrg      if (exts->EXT_descriptor_indexing) {
5637ec681f3Smrg         vk12_props->maxUpdateAfterBindDescriptorsInAllPools =
5647ec681f3Smrg            local_props.descriptor_indexing
5657ec681f3Smrg               .maxUpdateAfterBindDescriptorsInAllPools;
5667ec681f3Smrg         vk12_props->shaderUniformBufferArrayNonUniformIndexingNative =
5677ec681f3Smrg            local_props.descriptor_indexing
5687ec681f3Smrg               .shaderUniformBufferArrayNonUniformIndexingNative;
5697ec681f3Smrg         vk12_props->shaderSampledImageArrayNonUniformIndexingNative =
5707ec681f3Smrg            local_props.descriptor_indexing
5717ec681f3Smrg               .shaderSampledImageArrayNonUniformIndexingNative;
5727ec681f3Smrg         vk12_props->shaderStorageBufferArrayNonUniformIndexingNative =
5737ec681f3Smrg            local_props.descriptor_indexing
5747ec681f3Smrg               .shaderStorageBufferArrayNonUniformIndexingNative;
5757ec681f3Smrg         vk12_props->shaderStorageImageArrayNonUniformIndexingNative =
5767ec681f3Smrg            local_props.descriptor_indexing
5777ec681f3Smrg               .shaderStorageImageArrayNonUniformIndexingNative;
5787ec681f3Smrg         vk12_props->shaderInputAttachmentArrayNonUniformIndexingNative =
5797ec681f3Smrg            local_props.descriptor_indexing
5807ec681f3Smrg               .shaderInputAttachmentArrayNonUniformIndexingNative;
5817ec681f3Smrg         vk12_props->robustBufferAccessUpdateAfterBind =
5827ec681f3Smrg            local_props.descriptor_indexing.robustBufferAccessUpdateAfterBind;
5837ec681f3Smrg         vk12_props->quadDivergentImplicitLod =
5847ec681f3Smrg            local_props.descriptor_indexing.quadDivergentImplicitLod;
5857ec681f3Smrg         vk12_props->maxPerStageDescriptorUpdateAfterBindSamplers =
5867ec681f3Smrg            local_props.descriptor_indexing
5877ec681f3Smrg               .maxPerStageDescriptorUpdateAfterBindSamplers;
5887ec681f3Smrg         vk12_props->maxPerStageDescriptorUpdateAfterBindUniformBuffers =
5897ec681f3Smrg            local_props.descriptor_indexing
5907ec681f3Smrg               .maxPerStageDescriptorUpdateAfterBindUniformBuffers;
5917ec681f3Smrg         vk12_props->maxPerStageDescriptorUpdateAfterBindStorageBuffers =
5927ec681f3Smrg            local_props.descriptor_indexing
5937ec681f3Smrg               .maxPerStageDescriptorUpdateAfterBindStorageBuffers;
5947ec681f3Smrg         vk12_props->maxPerStageDescriptorUpdateAfterBindSampledImages =
5957ec681f3Smrg            local_props.descriptor_indexing
5967ec681f3Smrg               .maxPerStageDescriptorUpdateAfterBindSampledImages;
5977ec681f3Smrg         vk12_props->maxPerStageDescriptorUpdateAfterBindStorageImages =
5987ec681f3Smrg            local_props.descriptor_indexing
5997ec681f3Smrg               .maxPerStageDescriptorUpdateAfterBindStorageImages;
6007ec681f3Smrg         vk12_props->maxPerStageDescriptorUpdateAfterBindInputAttachments =
6017ec681f3Smrg            local_props.descriptor_indexing
6027ec681f3Smrg               .maxPerStageDescriptorUpdateAfterBindInputAttachments;
6037ec681f3Smrg         vk12_props->maxPerStageUpdateAfterBindResources =
6047ec681f3Smrg            local_props.descriptor_indexing
6057ec681f3Smrg               .maxPerStageUpdateAfterBindResources;
6067ec681f3Smrg         vk12_props->maxDescriptorSetUpdateAfterBindSamplers =
6077ec681f3Smrg            local_props.descriptor_indexing
6087ec681f3Smrg               .maxDescriptorSetUpdateAfterBindSamplers;
6097ec681f3Smrg         vk12_props->maxDescriptorSetUpdateAfterBindUniformBuffers =
6107ec681f3Smrg            local_props.descriptor_indexing
6117ec681f3Smrg               .maxDescriptorSetUpdateAfterBindUniformBuffers;
6127ec681f3Smrg         vk12_props->maxDescriptorSetUpdateAfterBindUniformBuffersDynamic =
6137ec681f3Smrg            local_props.descriptor_indexing
6147ec681f3Smrg               .maxDescriptorSetUpdateAfterBindUniformBuffersDynamic;
6157ec681f3Smrg         vk12_props->maxDescriptorSetUpdateAfterBindStorageBuffers =
6167ec681f3Smrg            local_props.descriptor_indexing
6177ec681f3Smrg               .maxDescriptorSetUpdateAfterBindStorageBuffers;
6187ec681f3Smrg         vk12_props->maxDescriptorSetUpdateAfterBindStorageBuffersDynamic =
6197ec681f3Smrg            local_props.descriptor_indexing
6207ec681f3Smrg               .maxDescriptorSetUpdateAfterBindStorageBuffersDynamic;
6217ec681f3Smrg         vk12_props->maxDescriptorSetUpdateAfterBindSampledImages =
6227ec681f3Smrg            local_props.descriptor_indexing
6237ec681f3Smrg               .maxDescriptorSetUpdateAfterBindSampledImages;
6247ec681f3Smrg         vk12_props->maxDescriptorSetUpdateAfterBindStorageImages =
6257ec681f3Smrg            local_props.descriptor_indexing
6267ec681f3Smrg               .maxDescriptorSetUpdateAfterBindStorageImages;
6277ec681f3Smrg         vk12_props->maxDescriptorSetUpdateAfterBindInputAttachments =
6287ec681f3Smrg            local_props.descriptor_indexing
6297ec681f3Smrg               .maxDescriptorSetUpdateAfterBindInputAttachments;
6307ec681f3Smrg      }
6317ec681f3Smrg      if (exts->KHR_depth_stencil_resolve) {
6327ec681f3Smrg         vk12_props->supportedDepthResolveModes =
6337ec681f3Smrg            local_props.depth_stencil_resolve.supportedDepthResolveModes;
6347ec681f3Smrg         vk12_props->supportedStencilResolveModes =
6357ec681f3Smrg            local_props.depth_stencil_resolve.supportedStencilResolveModes;
6367ec681f3Smrg         vk12_props->independentResolveNone =
6377ec681f3Smrg            local_props.depth_stencil_resolve.independentResolveNone;
6387ec681f3Smrg         vk12_props->independentResolve =
6397ec681f3Smrg            local_props.depth_stencil_resolve.independentResolve;
6407ec681f3Smrg      }
6417ec681f3Smrg      if (exts->EXT_sampler_filter_minmax) {
6427ec681f3Smrg         vk12_props->filterMinmaxSingleComponentFormats =
6437ec681f3Smrg            local_props.sampler_filter_minmax
6447ec681f3Smrg               .filterMinmaxSingleComponentFormats;
6457ec681f3Smrg         vk12_props->filterMinmaxImageComponentMapping =
6467ec681f3Smrg            local_props.sampler_filter_minmax
6477ec681f3Smrg               .filterMinmaxImageComponentMapping;
6487ec681f3Smrg      }
6497ec681f3Smrg      if (exts->KHR_timeline_semaphore) {
6507ec681f3Smrg         vk12_props->maxTimelineSemaphoreValueDifference =
6517ec681f3Smrg            local_props.timeline_semaphore.maxTimelineSemaphoreValueDifference;
6527ec681f3Smrg      }
6537ec681f3Smrg
6547ec681f3Smrg      vk12_props->framebufferIntegerColorSampleCounts = VK_SAMPLE_COUNT_1_BIT;
6557ec681f3Smrg   }
6567ec681f3Smrg
6577ec681f3Smrg   const uint32_t version_override = vk_get_version_override();
6587ec681f3Smrg   if (version_override) {
6597ec681f3Smrg      props->apiVersion = version_override;
6607ec681f3Smrg   } else {
6617ec681f3Smrg      /* cap the advertised api version */
6627ec681f3Smrg      uint32_t version = MIN3(props->apiVersion, VN_MAX_API_VERSION,
6637ec681f3Smrg                              instance->renderer_info.vk_xml_version);
6647ec681f3Smrg      if (VK_VERSION_PATCH(version) > VK_VERSION_PATCH(props->apiVersion)) {
6657ec681f3Smrg         version = version - VK_VERSION_PATCH(version) +
6667ec681f3Smrg                   VK_VERSION_PATCH(props->apiVersion);
6677ec681f3Smrg      }
6687ec681f3Smrg      props->apiVersion = version;
6697ec681f3Smrg   }
6707ec681f3Smrg
6717ec681f3Smrg   props->driverVersion = vk_get_driver_version();
6727ec681f3Smrg
6737ec681f3Smrg   char device_name[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE];
6747ec681f3Smrg   int device_name_len = snprintf(device_name, sizeof(device_name),
6757ec681f3Smrg                                  "Virtio-GPU Venus (%s)", props->deviceName);
6767ec681f3Smrg   if (device_name_len >= VK_MAX_PHYSICAL_DEVICE_NAME_SIZE) {
6777ec681f3Smrg      memcpy(device_name + VK_MAX_PHYSICAL_DEVICE_NAME_SIZE - 5, "...)", 4);
6787ec681f3Smrg      device_name_len = VK_MAX_PHYSICAL_DEVICE_NAME_SIZE - 1;
6797ec681f3Smrg   }
6807ec681f3Smrg   memcpy(props->deviceName, device_name, device_name_len + 1);
6817ec681f3Smrg
6827ec681f3Smrg   vk12_props->driverID = 0;
6837ec681f3Smrg   snprintf(vk12_props->driverName, sizeof(vk12_props->driverName), "venus");
6847ec681f3Smrg   snprintf(vk12_props->driverInfo, sizeof(vk12_props->driverInfo),
6857ec681f3Smrg            "Mesa " PACKAGE_VERSION MESA_GIT_SHA1);
6867ec681f3Smrg   vk12_props->conformanceVersion = (VkConformanceVersionKHR){
6877ec681f3Smrg      .major = 0,
6887ec681f3Smrg      .minor = 0,
6897ec681f3Smrg      .subminor = 0,
6907ec681f3Smrg      .patch = 0,
6917ec681f3Smrg   };
6927ec681f3Smrg
6937ec681f3Smrg   vn_physical_device_init_uuids(physical_dev);
6947ec681f3Smrg}
6957ec681f3Smrg
6967ec681f3Smrgstatic VkResult
6977ec681f3Smrgvn_physical_device_init_queue_family_properties(
6987ec681f3Smrg   struct vn_physical_device *physical_dev)
6997ec681f3Smrg{
7007ec681f3Smrg   struct vn_instance *instance = physical_dev->instance;
7017ec681f3Smrg   const VkAllocationCallbacks *alloc = &instance->base.base.alloc;
7027ec681f3Smrg   uint32_t count;
7037ec681f3Smrg
7047ec681f3Smrg   vn_call_vkGetPhysicalDeviceQueueFamilyProperties2(
7057ec681f3Smrg      instance, vn_physical_device_to_handle(physical_dev), &count, NULL);
7067ec681f3Smrg
7077ec681f3Smrg   VkQueueFamilyProperties2 *props =
7087ec681f3Smrg      vk_alloc(alloc, sizeof(*props) * count, VN_DEFAULT_ALIGN,
7097ec681f3Smrg               VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
7107ec681f3Smrg   if (!props)
7117ec681f3Smrg      return VK_ERROR_OUT_OF_HOST_MEMORY;
7127ec681f3Smrg
7137ec681f3Smrg   for (uint32_t i = 0; i < count; i++) {
7147ec681f3Smrg      props[i].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2;
7157ec681f3Smrg      props[i].pNext = NULL;
7167ec681f3Smrg   }
7177ec681f3Smrg   vn_call_vkGetPhysicalDeviceQueueFamilyProperties2(
7187ec681f3Smrg      instance, vn_physical_device_to_handle(physical_dev), &count, props);
7197ec681f3Smrg
7207ec681f3Smrg   physical_dev->queue_family_properties = props;
7217ec681f3Smrg   physical_dev->queue_family_count = count;
7227ec681f3Smrg
7237ec681f3Smrg   return VK_SUCCESS;
7247ec681f3Smrg}
7257ec681f3Smrg
7267ec681f3Smrgstatic void
7277ec681f3Smrgvn_physical_device_init_memory_properties(
7287ec681f3Smrg   struct vn_physical_device *physical_dev)
7297ec681f3Smrg{
7307ec681f3Smrg   struct vn_instance *instance = physical_dev->instance;
7317ec681f3Smrg
7327ec681f3Smrg   physical_dev->memory_properties.sType =
7337ec681f3Smrg      VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2;
7347ec681f3Smrg
7357ec681f3Smrg   vn_call_vkGetPhysicalDeviceMemoryProperties2(
7367ec681f3Smrg      instance, vn_physical_device_to_handle(physical_dev),
7377ec681f3Smrg      &physical_dev->memory_properties);
7387ec681f3Smrg
7397ec681f3Smrg   if (!instance->renderer_info.has_cache_management) {
7407ec681f3Smrg      VkPhysicalDeviceMemoryProperties *props =
7417ec681f3Smrg         &physical_dev->memory_properties.memoryProperties;
7427ec681f3Smrg      const uint32_t host_flags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
7437ec681f3Smrg                                  VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
7447ec681f3Smrg                                  VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
7457ec681f3Smrg
7467ec681f3Smrg      for (uint32_t i = 0; i < props->memoryTypeCount; i++) {
7477ec681f3Smrg         const bool coherent = props->memoryTypes[i].propertyFlags &
7487ec681f3Smrg                               VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
7497ec681f3Smrg         if (!coherent)
7507ec681f3Smrg            props->memoryTypes[i].propertyFlags &= ~host_flags;
7517ec681f3Smrg      }
7527ec681f3Smrg   }
7537ec681f3Smrg}
7547ec681f3Smrg
7557ec681f3Smrgstatic void
7567ec681f3Smrgvn_physical_device_init_external_memory(
7577ec681f3Smrg   struct vn_physical_device *physical_dev)
7587ec681f3Smrg{
7597ec681f3Smrg   /* When a renderer VkDeviceMemory is exportable, we can create a
7607ec681f3Smrg    * vn_renderer_bo from it.  The vn_renderer_bo can be freely exported as an
7617ec681f3Smrg    * opaque fd or a dma-buf.
7627ec681f3Smrg    *
7637ec681f3Smrg    * However, to know if a rendender VkDeviceMemory is exportable, we have to
7647ec681f3Smrg    * start from VkPhysicalDeviceExternalImageFormatInfo (or
7657ec681f3Smrg    * vkGetPhysicalDeviceExternalBufferProperties).  That means we need to
7667ec681f3Smrg    * know the handle type that the renderer will use to make those queries.
7677ec681f3Smrg    *
7687ec681f3Smrg    * XXX We also assume that a vn_renderer_bo can be created as long as the
7697ec681f3Smrg    * renderer VkDeviceMemory has a mappable memory type.  That is plain
7707ec681f3Smrg    * wrong.  It is impossible to fix though until some new extension is
7717ec681f3Smrg    * created and supported by the driver, and that the renderer switches to
7727ec681f3Smrg    * the extension.
7737ec681f3Smrg    */
7747ec681f3Smrg
7757ec681f3Smrg   if (!physical_dev->instance->renderer_info.has_dma_buf_import)
7767ec681f3Smrg      return;
7777ec681f3Smrg
7787ec681f3Smrg   /* TODO We assume the renderer uses dma-bufs here.  This should be
7797ec681f3Smrg    * negotiated by adding a new function to VK_MESA_venus_protocol.
7807ec681f3Smrg    */
7817ec681f3Smrg   if (physical_dev->renderer_extensions.EXT_external_memory_dma_buf) {
7827ec681f3Smrg      physical_dev->external_memory.renderer_handle_type =
7837ec681f3Smrg         VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
7847ec681f3Smrg
7857ec681f3Smrg#ifdef ANDROID
7867ec681f3Smrg      physical_dev->external_memory.supported_handle_types =
7877ec681f3Smrg         VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
7887ec681f3Smrg#else
7897ec681f3Smrg      physical_dev->external_memory.supported_handle_types =
7907ec681f3Smrg         VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT |
7917ec681f3Smrg         VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
7927ec681f3Smrg#endif
7937ec681f3Smrg   }
7947ec681f3Smrg}
7957ec681f3Smrg
7967ec681f3Smrgstatic void
7977ec681f3Smrgvn_physical_device_init_external_fence_handles(
7987ec681f3Smrg   struct vn_physical_device *physical_dev)
7997ec681f3Smrg{
8007ec681f3Smrg   /* The current code manipulates the host-side VkFence directly.
8017ec681f3Smrg    * vkWaitForFences is translated to repeated vkGetFenceStatus.
8027ec681f3Smrg    *
8037ec681f3Smrg    * External fence is not possible currently.  At best, we could cheat by
8047ec681f3Smrg    * translating vkGetFenceFdKHR to vkWaitForFences and returning -1, when
8057ec681f3Smrg    * the handle type is sync file.
8067ec681f3Smrg    *
8077ec681f3Smrg    * We would like to create a vn_renderer_sync from a host-side VkFence,
8087ec681f3Smrg    * similar to how a vn_renderer_bo is created from a host-side
8097ec681f3Smrg    * VkDeviceMemory.  That would require kernel support and tons of works on
8107ec681f3Smrg    * the host side.  If we had that, and we kept both the vn_renderer_sync
8117ec681f3Smrg    * and the host-side VkFence in sync, we would have the freedom to use
8127ec681f3Smrg    * either of them depending on the occasions, and support external fences
8137ec681f3Smrg    * and idle waiting.
8147ec681f3Smrg    */
8157ec681f3Smrg   physical_dev->external_fence_handles = 0;
8167ec681f3Smrg
8177ec681f3Smrg#ifdef ANDROID
8187ec681f3Smrg   if (physical_dev->instance->experimental.globalFencing) {
8197ec681f3Smrg      physical_dev->external_fence_handles =
8207ec681f3Smrg         VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT;
8217ec681f3Smrg   }
8227ec681f3Smrg#endif
8237ec681f3Smrg}
8247ec681f3Smrg
8257ec681f3Smrgstatic void
8267ec681f3Smrgvn_physical_device_init_external_semaphore_handles(
8277ec681f3Smrg   struct vn_physical_device *physical_dev)
8287ec681f3Smrg{
8297ec681f3Smrg   /* The current code manipulates the host-side VkSemaphore directly.  It
8307ec681f3Smrg    * works very well for binary semaphores because there is no CPU operation.
8317ec681f3Smrg    * But for timeline semaphores, the situation is similar to that of fences.
8327ec681f3Smrg    * vkWaitSemaphores is translated to repeated vkGetSemaphoreCounterValue.
8337ec681f3Smrg    *
8347ec681f3Smrg    * External semaphore is not possible currently.  We could cheat when the
8357ec681f3Smrg    * semaphore is binary and the handle type is sync file, but that would
8367ec681f3Smrg    * require associating a fence with the semaphore and doing vkWaitForFences
8377ec681f3Smrg    * in vkGetSemaphoreFdKHR.
8387ec681f3Smrg    *
8397ec681f3Smrg    * We would like to create a vn_renderer_sync from a host-side VkSemaphore,
8407ec681f3Smrg    * similar to how a vn_renderer_bo is created from a host-side
8417ec681f3Smrg    * VkDeviceMemory.  The reasoning is the same as that for fences.
8427ec681f3Smrg    * Additionally, we would like the sync file exported from the
8437ec681f3Smrg    * vn_renderer_sync to carry the necessary information to identify the
8447ec681f3Smrg    * host-side VkSemaphore.  That would allow the consumers to wait on the
8457ec681f3Smrg    * host side rather than the guest side.
8467ec681f3Smrg    */
8477ec681f3Smrg   physical_dev->external_binary_semaphore_handles = 0;
8487ec681f3Smrg   physical_dev->external_timeline_semaphore_handles = 0;
8497ec681f3Smrg
8507ec681f3Smrg#ifdef ANDROID
8517ec681f3Smrg   if (physical_dev->instance->experimental.globalFencing) {
8527ec681f3Smrg      physical_dev->external_binary_semaphore_handles =
8537ec681f3Smrg         VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
8547ec681f3Smrg   }
8557ec681f3Smrg#endif
8567ec681f3Smrg}
8577ec681f3Smrg
8587ec681f3Smrgstatic void
8597ec681f3Smrgvn_physical_device_get_native_extensions(
8607ec681f3Smrg   const struct vn_physical_device *physical_dev,
8617ec681f3Smrg   struct vk_device_extension_table *exts)
8627ec681f3Smrg{
8637ec681f3Smrg   const struct vn_instance *instance = physical_dev->instance;
8647ec681f3Smrg   const struct vn_renderer_info *renderer_info = &instance->renderer_info;
8657ec681f3Smrg   const struct vk_device_extension_table *renderer_exts =
8667ec681f3Smrg      &physical_dev->renderer_extensions;
8677ec681f3Smrg
8687ec681f3Smrg   memset(exts, 0, sizeof(*exts));
8697ec681f3Smrg
8707ec681f3Smrg   /* see vn_physical_device_init_external_memory */
8717ec681f3Smrg   const bool can_external_mem = renderer_exts->EXT_external_memory_dma_buf &&
8727ec681f3Smrg                                 renderer_info->has_dma_buf_import;
8737ec681f3Smrg
8747ec681f3Smrg#ifdef ANDROID
8757ec681f3Smrg   if (can_external_mem && renderer_exts->EXT_image_drm_format_modifier &&
8767ec681f3Smrg       renderer_exts->EXT_queue_family_foreign &&
8777ec681f3Smrg       instance->experimental.memoryResourceAllocationSize == VK_TRUE) {
8787ec681f3Smrg      exts->ANDROID_external_memory_android_hardware_buffer = true;
8797ec681f3Smrg      exts->ANDROID_native_buffer = true;
8807ec681f3Smrg   }
8817ec681f3Smrg
8827ec681f3Smrg   /* we have a very poor implementation */
8837ec681f3Smrg   if (instance->experimental.globalFencing) {
8847ec681f3Smrg      exts->KHR_external_fence_fd = true;
8857ec681f3Smrg      exts->KHR_external_semaphore_fd = true;
8867ec681f3Smrg   }
8877ec681f3Smrg#else /* ANDROID */
8887ec681f3Smrg   if (can_external_mem) {
8897ec681f3Smrg      exts->KHR_external_memory_fd = true;
8907ec681f3Smrg      exts->EXT_external_memory_dma_buf = true;
8917ec681f3Smrg   }
8927ec681f3Smrg
8937ec681f3Smrg#ifdef VN_USE_WSI_PLATFORM
8947ec681f3Smrg   /* XXX we should check for EXT_queue_family_foreign */
8957ec681f3Smrg   exts->KHR_incremental_present = true;
8967ec681f3Smrg   exts->KHR_swapchain = true;
8977ec681f3Smrg   exts->KHR_swapchain_mutable_format = true;
8987ec681f3Smrg#endif
8997ec681f3Smrg#endif /* ANDROID */
9007ec681f3Smrg}
9017ec681f3Smrg
9027ec681f3Smrgstatic void
9037ec681f3Smrgvn_physical_device_get_passthrough_extensions(
9047ec681f3Smrg   const struct vn_physical_device *physical_dev,
9057ec681f3Smrg   struct vk_device_extension_table *exts)
9067ec681f3Smrg{
9077ec681f3Smrg   *exts = (struct vk_device_extension_table){
9087ec681f3Smrg      /* promoted to VK_VERSION_1_1 */
9097ec681f3Smrg      .KHR_16bit_storage = true,
9107ec681f3Smrg      .KHR_bind_memory2 = true,
9117ec681f3Smrg      .KHR_dedicated_allocation = true,
9127ec681f3Smrg      .KHR_descriptor_update_template = true,
9137ec681f3Smrg      .KHR_device_group = true,
9147ec681f3Smrg      .KHR_external_fence = true,
9157ec681f3Smrg      .KHR_external_memory = true,
9167ec681f3Smrg      .KHR_external_semaphore = true,
9177ec681f3Smrg      .KHR_get_memory_requirements2 = true,
9187ec681f3Smrg      .KHR_maintenance1 = true,
9197ec681f3Smrg      .KHR_maintenance2 = true,
9207ec681f3Smrg      .KHR_maintenance3 = true,
9217ec681f3Smrg      .KHR_multiview = true,
9227ec681f3Smrg      .KHR_relaxed_block_layout = true,
9237ec681f3Smrg      .KHR_sampler_ycbcr_conversion = true,
9247ec681f3Smrg      .KHR_shader_draw_parameters = true,
9257ec681f3Smrg      .KHR_storage_buffer_storage_class = true,
9267ec681f3Smrg      .KHR_variable_pointers = true,
9277ec681f3Smrg
9287ec681f3Smrg      /* promoted to VK_VERSION_1_2 */
9297ec681f3Smrg      .KHR_8bit_storage = true,
9307ec681f3Smrg      .KHR_buffer_device_address = true,
9317ec681f3Smrg      .KHR_create_renderpass2 = true,
9327ec681f3Smrg      .KHR_depth_stencil_resolve = true,
9337ec681f3Smrg      .KHR_draw_indirect_count = true,
9347ec681f3Smrg#ifndef ANDROID
9357ec681f3Smrg      /* xxx remove the #ifndef after venus has a driver id */
9367ec681f3Smrg      .KHR_driver_properties = true,
9377ec681f3Smrg#endif
9387ec681f3Smrg      .KHR_image_format_list = true,
9397ec681f3Smrg      .KHR_imageless_framebuffer = true,
9407ec681f3Smrg      .KHR_sampler_mirror_clamp_to_edge = true,
9417ec681f3Smrg      .KHR_separate_depth_stencil_layouts = true,
9427ec681f3Smrg      .KHR_shader_atomic_int64 = true,
9437ec681f3Smrg      .KHR_shader_float16_int8 = true,
9447ec681f3Smrg      .KHR_shader_float_controls = true,
9457ec681f3Smrg      .KHR_shader_subgroup_extended_types = true,
9467ec681f3Smrg      .KHR_spirv_1_4 = true,
9477ec681f3Smrg      .KHR_timeline_semaphore = true,
9487ec681f3Smrg      .KHR_uniform_buffer_standard_layout = true,
9497ec681f3Smrg      .KHR_vulkan_memory_model = true,
9507ec681f3Smrg      .EXT_descriptor_indexing = true,
9517ec681f3Smrg      .EXT_host_query_reset = true,
9527ec681f3Smrg      .EXT_sampler_filter_minmax = true,
9537ec681f3Smrg      .EXT_scalar_block_layout = true,
9547ec681f3Smrg      .EXT_separate_stencil_usage = true,
9557ec681f3Smrg      .EXT_shader_viewport_index_layer = true,
9567ec681f3Smrg
9577ec681f3Smrg      /* EXT */
9587ec681f3Smrg#ifndef ANDROID
9597ec681f3Smrg      .EXT_image_drm_format_modifier = true,
9607ec681f3Smrg#endif
9617ec681f3Smrg      .EXT_queue_family_foreign = true,
9627ec681f3Smrg      .EXT_transform_feedback = true,
9637ec681f3Smrg   };
9647ec681f3Smrg}
9657ec681f3Smrg
9667ec681f3Smrgstatic void
9677ec681f3Smrgvn_physical_device_init_supported_extensions(
9687ec681f3Smrg   struct vn_physical_device *physical_dev)
9697ec681f3Smrg{
9707ec681f3Smrg   struct vk_device_extension_table native;
9717ec681f3Smrg   struct vk_device_extension_table passthrough;
9727ec681f3Smrg   vn_physical_device_get_native_extensions(physical_dev, &native);
9737ec681f3Smrg   vn_physical_device_get_passthrough_extensions(physical_dev, &passthrough);
9747ec681f3Smrg
9757ec681f3Smrg   for (uint32_t i = 0; i < VK_DEVICE_EXTENSION_COUNT; i++) {
9767ec681f3Smrg      const VkExtensionProperties *props = &vk_device_extensions[i];
9777ec681f3Smrg
9787ec681f3Smrg#ifdef ANDROID
9797ec681f3Smrg      if (!vk_android_allowed_device_extensions.extensions[i])
9807ec681f3Smrg         continue;
9817ec681f3Smrg#endif
9827ec681f3Smrg
9837ec681f3Smrg      if (native.extensions[i]) {
9847ec681f3Smrg         physical_dev->base.base.supported_extensions.extensions[i] = true;
9857ec681f3Smrg         physical_dev->extension_spec_versions[i] = props->specVersion;
9867ec681f3Smrg      } else if (passthrough.extensions[i] &&
9877ec681f3Smrg                 physical_dev->renderer_extensions.extensions[i]) {
9887ec681f3Smrg         physical_dev->base.base.supported_extensions.extensions[i] = true;
9897ec681f3Smrg         physical_dev->extension_spec_versions[i] = MIN2(
9907ec681f3Smrg            physical_dev->extension_spec_versions[i], props->specVersion);
9917ec681f3Smrg      }
9927ec681f3Smrg   }
9937ec681f3Smrg
9947ec681f3Smrg   /* override VK_ANDROID_native_buffer spec version */
9957ec681f3Smrg   if (native.ANDROID_native_buffer) {
9967ec681f3Smrg      const uint32_t index =
9977ec681f3Smrg         VN_EXTENSION_TABLE_INDEX(native, ANDROID_native_buffer);
9987ec681f3Smrg      physical_dev->extension_spec_versions[index] =
9997ec681f3Smrg         VN_ANDROID_NATIVE_BUFFER_SPEC_VERSION;
10007ec681f3Smrg   }
10017ec681f3Smrg}
10027ec681f3Smrg
10037ec681f3Smrgstatic VkResult
10047ec681f3Smrgvn_physical_device_init_renderer_extensions(
10057ec681f3Smrg   struct vn_physical_device *physical_dev)
10067ec681f3Smrg{
10077ec681f3Smrg   struct vn_instance *instance = physical_dev->instance;
10087ec681f3Smrg   const VkAllocationCallbacks *alloc = &instance->base.base.alloc;
10097ec681f3Smrg
10107ec681f3Smrg   /* get renderer extensions */
10117ec681f3Smrg   uint32_t count;
10127ec681f3Smrg   VkResult result = vn_call_vkEnumerateDeviceExtensionProperties(
10137ec681f3Smrg      instance, vn_physical_device_to_handle(physical_dev), NULL, &count,
10147ec681f3Smrg      NULL);
10157ec681f3Smrg   if (result != VK_SUCCESS)
10167ec681f3Smrg      return result;
10177ec681f3Smrg
10187ec681f3Smrg   VkExtensionProperties *exts = NULL;
10197ec681f3Smrg   if (count) {
10207ec681f3Smrg      exts = vk_alloc(alloc, sizeof(*exts) * count, VN_DEFAULT_ALIGN,
10217ec681f3Smrg                      VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
10227ec681f3Smrg      if (!exts)
10237ec681f3Smrg         return VK_ERROR_OUT_OF_HOST_MEMORY;
10247ec681f3Smrg
10257ec681f3Smrg      result = vn_call_vkEnumerateDeviceExtensionProperties(
10267ec681f3Smrg         instance, vn_physical_device_to_handle(physical_dev), NULL, &count,
10277ec681f3Smrg         exts);
10287ec681f3Smrg      if (result < VK_SUCCESS) {
10297ec681f3Smrg         vk_free(alloc, exts);
10307ec681f3Smrg         return result;
10317ec681f3Smrg      }
10327ec681f3Smrg   }
10337ec681f3Smrg
10347ec681f3Smrg   physical_dev->extension_spec_versions =
10357ec681f3Smrg      vk_zalloc(alloc,
10367ec681f3Smrg                sizeof(*physical_dev->extension_spec_versions) *
10377ec681f3Smrg                   VK_DEVICE_EXTENSION_COUNT,
10387ec681f3Smrg                VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
10397ec681f3Smrg   if (!physical_dev->extension_spec_versions) {
10407ec681f3Smrg      vk_free(alloc, exts);
10417ec681f3Smrg      return VK_ERROR_OUT_OF_HOST_MEMORY;
10427ec681f3Smrg   }
10437ec681f3Smrg
10447ec681f3Smrg   for (uint32_t i = 0; i < VK_DEVICE_EXTENSION_COUNT; i++) {
10457ec681f3Smrg      const VkExtensionProperties *props = &vk_device_extensions[i];
10467ec681f3Smrg      for (uint32_t j = 0; j < count; j++) {
10477ec681f3Smrg         if (strcmp(props->extensionName, exts[j].extensionName))
10487ec681f3Smrg            continue;
10497ec681f3Smrg
10507ec681f3Smrg         /* check encoder support */
10517ec681f3Smrg         const uint32_t spec_version =
10527ec681f3Smrg            vn_info_extension_spec_version(props->extensionName);
10537ec681f3Smrg         if (!spec_version)
10547ec681f3Smrg            continue;
10557ec681f3Smrg
10567ec681f3Smrg         physical_dev->renderer_extensions.extensions[i] = true;
10577ec681f3Smrg         physical_dev->extension_spec_versions[i] =
10587ec681f3Smrg            MIN2(exts[j].specVersion, spec_version);
10597ec681f3Smrg
10607ec681f3Smrg         break;
10617ec681f3Smrg      }
10627ec681f3Smrg   }
10637ec681f3Smrg
10647ec681f3Smrg   vk_free(alloc, exts);
10657ec681f3Smrg
10667ec681f3Smrg   return VK_SUCCESS;
10677ec681f3Smrg}
10687ec681f3Smrg
10697ec681f3Smrgstatic VkResult
10707ec681f3Smrgvn_physical_device_init_renderer_version(
10717ec681f3Smrg   struct vn_physical_device *physical_dev)
10727ec681f3Smrg{
10737ec681f3Smrg   struct vn_instance *instance = physical_dev->instance;
10747ec681f3Smrg
10757ec681f3Smrg   /*
10767ec681f3Smrg    * We either check and enable VK_KHR_get_physical_device_properties2, or we
10777ec681f3Smrg    * must use vkGetPhysicalDeviceProperties to get the device-level version.
10787ec681f3Smrg    */
10797ec681f3Smrg   VkPhysicalDeviceProperties props;
10807ec681f3Smrg   vn_call_vkGetPhysicalDeviceProperties(
10817ec681f3Smrg      instance, vn_physical_device_to_handle(physical_dev), &props);
10827ec681f3Smrg   if (props.apiVersion < VN_MIN_RENDERER_VERSION) {
10837ec681f3Smrg      if (VN_DEBUG(INIT)) {
10847ec681f3Smrg         vn_log(instance, "%s has unsupported renderer device version %d.%d",
10857ec681f3Smrg                props.deviceName, VK_VERSION_MAJOR(props.apiVersion),
10867ec681f3Smrg                VK_VERSION_MINOR(props.apiVersion));
10877ec681f3Smrg      }
10887ec681f3Smrg      return VK_ERROR_INITIALIZATION_FAILED;
10897ec681f3Smrg   }
10907ec681f3Smrg
10917ec681f3Smrg   /* device version for internal use is capped */
10927ec681f3Smrg   physical_dev->renderer_version =
10937ec681f3Smrg      MIN3(props.apiVersion, instance->renderer_api_version,
10947ec681f3Smrg           instance->renderer_info.vk_xml_version);
10957ec681f3Smrg
10967ec681f3Smrg   return VK_SUCCESS;
10977ec681f3Smrg}
10987ec681f3Smrg
10997ec681f3Smrgstatic VkResult
11007ec681f3Smrgvn_physical_device_init(struct vn_physical_device *physical_dev)
11017ec681f3Smrg{
11027ec681f3Smrg   struct vn_instance *instance = physical_dev->instance;
11037ec681f3Smrg   const VkAllocationCallbacks *alloc = &instance->base.base.alloc;
11047ec681f3Smrg   VkResult result;
11057ec681f3Smrg
11067ec681f3Smrg   result = vn_physical_device_init_renderer_extensions(physical_dev);
11077ec681f3Smrg   if (result != VK_SUCCESS)
11087ec681f3Smrg      return result;
11097ec681f3Smrg
11107ec681f3Smrg   vn_physical_device_init_supported_extensions(physical_dev);
11117ec681f3Smrg
11127ec681f3Smrg   /* TODO query all caps with minimal round trips */
11137ec681f3Smrg   vn_physical_device_init_features(physical_dev);
11147ec681f3Smrg   vn_physical_device_init_properties(physical_dev);
11157ec681f3Smrg
11167ec681f3Smrg   result = vn_physical_device_init_queue_family_properties(physical_dev);
11177ec681f3Smrg   if (result != VK_SUCCESS)
11187ec681f3Smrg      goto fail;
11197ec681f3Smrg
11207ec681f3Smrg   vn_physical_device_init_memory_properties(physical_dev);
11217ec681f3Smrg
11227ec681f3Smrg   vn_physical_device_init_external_memory(physical_dev);
11237ec681f3Smrg   vn_physical_device_init_external_fence_handles(physical_dev);
11247ec681f3Smrg   vn_physical_device_init_external_semaphore_handles(physical_dev);
11257ec681f3Smrg
11267ec681f3Smrg   result = vn_wsi_init(physical_dev);
11277ec681f3Smrg   if (result != VK_SUCCESS)
11287ec681f3Smrg      goto fail;
11297ec681f3Smrg
11307ec681f3Smrg   return VK_SUCCESS;
11317ec681f3Smrg
11327ec681f3Smrgfail:
11337ec681f3Smrg   vk_free(alloc, physical_dev->extension_spec_versions);
11347ec681f3Smrg   vk_free(alloc, physical_dev->queue_family_properties);
11357ec681f3Smrg   return result;
11367ec681f3Smrg}
11377ec681f3Smrg
11387ec681f3Smrgvoid
11397ec681f3Smrgvn_physical_device_fini(struct vn_physical_device *physical_dev)
11407ec681f3Smrg{
11417ec681f3Smrg   struct vn_instance *instance = physical_dev->instance;
11427ec681f3Smrg   const VkAllocationCallbacks *alloc = &instance->base.base.alloc;
11437ec681f3Smrg
11447ec681f3Smrg   vn_wsi_fini(physical_dev);
11457ec681f3Smrg   vk_free(alloc, physical_dev->extension_spec_versions);
11467ec681f3Smrg   vk_free(alloc, physical_dev->queue_family_properties);
11477ec681f3Smrg
11487ec681f3Smrg   vn_physical_device_base_fini(&physical_dev->base);
11497ec681f3Smrg}
11507ec681f3Smrg
11517ec681f3Smrgstatic struct vn_physical_device *
11527ec681f3Smrgfind_physical_device(struct vn_physical_device *physical_devs,
11537ec681f3Smrg                     uint32_t count,
11547ec681f3Smrg                     vn_object_id id)
11557ec681f3Smrg{
11567ec681f3Smrg   for (uint32_t i = 0; i < count; i++) {
11577ec681f3Smrg      if (physical_devs[i].base.id == id)
11587ec681f3Smrg         return &physical_devs[i];
11597ec681f3Smrg   }
11607ec681f3Smrg   return NULL;
11617ec681f3Smrg}
11627ec681f3Smrg
11637ec681f3Smrgstatic VkResult
11647ec681f3Smrgvn_instance_enumerate_physical_device_groups_locked(
11657ec681f3Smrg   struct vn_instance *instance,
11667ec681f3Smrg   struct vn_physical_device *physical_devs,
11677ec681f3Smrg   uint32_t physical_dev_count)
11687ec681f3Smrg{
11697ec681f3Smrg   VkInstance instance_handle = vn_instance_to_handle(instance);
11707ec681f3Smrg   const VkAllocationCallbacks *alloc = &instance->base.base.alloc;
11717ec681f3Smrg   VkResult result;
11727ec681f3Smrg
11737ec681f3Smrg   uint32_t count;
11747ec681f3Smrg   result = vn_call_vkEnumeratePhysicalDeviceGroups(instance, instance_handle,
11757ec681f3Smrg                                                    &count, NULL);
11767ec681f3Smrg   if (result != VK_SUCCESS)
11777ec681f3Smrg      return result;
11787ec681f3Smrg
11797ec681f3Smrg   VkPhysicalDeviceGroupProperties *groups =
11807ec681f3Smrg      vk_alloc(alloc, sizeof(*groups) * count, VN_DEFAULT_ALIGN,
11817ec681f3Smrg               VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
11827ec681f3Smrg   if (!groups)
11837ec681f3Smrg      return VK_ERROR_OUT_OF_HOST_MEMORY;
11847ec681f3Smrg
11857ec681f3Smrg   /* VkPhysicalDeviceGroupProperties::physicalDevices is treated as an input
11867ec681f3Smrg    * by the encoder.  Each VkPhysicalDevice must point to a valid object.
11877ec681f3Smrg    * Each object must have id 0 as well, which is interpreted as a query by
11887ec681f3Smrg    * the renderer.
11897ec681f3Smrg    */
11907ec681f3Smrg   struct vn_physical_device_base *temp_objs =
11917ec681f3Smrg      vk_zalloc(alloc, sizeof(*temp_objs) * VK_MAX_DEVICE_GROUP_SIZE * count,
11927ec681f3Smrg                VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
11937ec681f3Smrg   if (!temp_objs) {
11947ec681f3Smrg      vk_free(alloc, groups);
11957ec681f3Smrg      return VK_ERROR_OUT_OF_HOST_MEMORY;
11967ec681f3Smrg   }
11977ec681f3Smrg
11987ec681f3Smrg   for (uint32_t i = 0; i < count; i++) {
11997ec681f3Smrg      VkPhysicalDeviceGroupProperties *group = &groups[i];
12007ec681f3Smrg      group->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES;
12017ec681f3Smrg      group->pNext = NULL;
12027ec681f3Smrg      for (uint32_t j = 0; j < VK_MAX_DEVICE_GROUP_SIZE; j++) {
12037ec681f3Smrg         struct vn_physical_device_base *temp_obj =
12047ec681f3Smrg            &temp_objs[VK_MAX_DEVICE_GROUP_SIZE * i + j];
12057ec681f3Smrg         temp_obj->base.base.type = VK_OBJECT_TYPE_PHYSICAL_DEVICE;
12067ec681f3Smrg         group->physicalDevices[j] = (VkPhysicalDevice)temp_obj;
12077ec681f3Smrg      }
12087ec681f3Smrg   }
12097ec681f3Smrg
12107ec681f3Smrg   result = vn_call_vkEnumeratePhysicalDeviceGroups(instance, instance_handle,
12117ec681f3Smrg                                                    &count, groups);
12127ec681f3Smrg   if (result != VK_SUCCESS) {
12137ec681f3Smrg      vk_free(alloc, groups);
12147ec681f3Smrg      vk_free(alloc, temp_objs);
12157ec681f3Smrg      return result;
12167ec681f3Smrg   }
12177ec681f3Smrg
12187ec681f3Smrg   /* fix VkPhysicalDeviceGroupProperties::physicalDevices to point to
12197ec681f3Smrg    * physical_devs and discard unsupported ones
12207ec681f3Smrg    */
12217ec681f3Smrg   uint32_t supported_count = 0;
12227ec681f3Smrg   for (uint32_t i = 0; i < count; i++) {
12237ec681f3Smrg      VkPhysicalDeviceGroupProperties *group = &groups[i];
12247ec681f3Smrg
12257ec681f3Smrg      uint32_t group_physical_dev_count = 0;
12267ec681f3Smrg      for (uint32_t j = 0; j < group->physicalDeviceCount; j++) {
12277ec681f3Smrg         struct vn_physical_device_base *temp_obj =
12287ec681f3Smrg            (struct vn_physical_device_base *)group->physicalDevices[j];
12297ec681f3Smrg         struct vn_physical_device *physical_dev = find_physical_device(
12307ec681f3Smrg            physical_devs, physical_dev_count, temp_obj->id);
12317ec681f3Smrg         if (!physical_dev)
12327ec681f3Smrg            continue;
12337ec681f3Smrg
12347ec681f3Smrg         group->physicalDevices[group_physical_dev_count++] =
12357ec681f3Smrg            vn_physical_device_to_handle(physical_dev);
12367ec681f3Smrg      }
12377ec681f3Smrg
12387ec681f3Smrg      group->physicalDeviceCount = group_physical_dev_count;
12397ec681f3Smrg      if (!group->physicalDeviceCount)
12407ec681f3Smrg         continue;
12417ec681f3Smrg
12427ec681f3Smrg      if (supported_count < i)
12437ec681f3Smrg         groups[supported_count] = *group;
12447ec681f3Smrg      supported_count++;
12457ec681f3Smrg   }
12467ec681f3Smrg
12477ec681f3Smrg   count = supported_count;
12487ec681f3Smrg   assert(count);
12497ec681f3Smrg
12507ec681f3Smrg   vk_free(alloc, temp_objs);
12517ec681f3Smrg
12527ec681f3Smrg   instance->physical_device.groups = groups;
12537ec681f3Smrg   instance->physical_device.group_count = count;
12547ec681f3Smrg
12557ec681f3Smrg   return VK_SUCCESS;
12567ec681f3Smrg}
12577ec681f3Smrg
12587ec681f3Smrgstatic VkResult
12597ec681f3Smrgenumerate_physical_devices(struct vn_instance *instance,
12607ec681f3Smrg                           struct vn_physical_device **out_physical_devs,
12617ec681f3Smrg                           uint32_t *out_count)
12627ec681f3Smrg{
12637ec681f3Smrg   const VkAllocationCallbacks *alloc = &instance->base.base.alloc;
12647ec681f3Smrg   struct vn_physical_device *physical_devs = NULL;
12657ec681f3Smrg   VkPhysicalDevice *handles = NULL;
12667ec681f3Smrg   VkResult result;
12677ec681f3Smrg
12687ec681f3Smrg   uint32_t count;
12697ec681f3Smrg   result = vn_call_vkEnumeratePhysicalDevices(
12707ec681f3Smrg      instance, vn_instance_to_handle(instance), &count, NULL);
12717ec681f3Smrg   if (result != VK_SUCCESS || !count)
12727ec681f3Smrg      return result;
12737ec681f3Smrg
12747ec681f3Smrg   physical_devs =
12757ec681f3Smrg      vk_zalloc(alloc, sizeof(*physical_devs) * count, VN_DEFAULT_ALIGN,
12767ec681f3Smrg                VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
12777ec681f3Smrg   if (!physical_devs)
12787ec681f3Smrg      return VK_ERROR_OUT_OF_HOST_MEMORY;
12797ec681f3Smrg
12807ec681f3Smrg   handles = vk_alloc(alloc, sizeof(*handles) * count, VN_DEFAULT_ALIGN,
12817ec681f3Smrg                      VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
12827ec681f3Smrg   if (!handles) {
12837ec681f3Smrg      vk_free(alloc, physical_devs);
12847ec681f3Smrg      return VK_ERROR_OUT_OF_HOST_MEMORY;
12857ec681f3Smrg   }
12867ec681f3Smrg
12877ec681f3Smrg   for (uint32_t i = 0; i < count; i++) {
12887ec681f3Smrg      struct vn_physical_device *physical_dev = &physical_devs[i];
12897ec681f3Smrg
12907ec681f3Smrg      struct vk_physical_device_dispatch_table dispatch_table;
12917ec681f3Smrg      vk_physical_device_dispatch_table_from_entrypoints(
12927ec681f3Smrg         &dispatch_table, &vn_physical_device_entrypoints, true);
12937ec681f3Smrg      vk_physical_device_dispatch_table_from_entrypoints(
12947ec681f3Smrg         &dispatch_table, &wsi_physical_device_entrypoints, false);
12957ec681f3Smrg      result = vn_physical_device_base_init(
12967ec681f3Smrg         &physical_dev->base, &instance->base, NULL, &dispatch_table);
12977ec681f3Smrg      if (result != VK_SUCCESS) {
12987ec681f3Smrg         count = i;
12997ec681f3Smrg         goto fail;
13007ec681f3Smrg      }
13017ec681f3Smrg
13027ec681f3Smrg      physical_dev->instance = instance;
13037ec681f3Smrg
13047ec681f3Smrg      handles[i] = vn_physical_device_to_handle(physical_dev);
13057ec681f3Smrg   }
13067ec681f3Smrg
13077ec681f3Smrg   result = vn_call_vkEnumeratePhysicalDevices(
13087ec681f3Smrg      instance, vn_instance_to_handle(instance), &count, handles);
13097ec681f3Smrg   if (result != VK_SUCCESS)
13107ec681f3Smrg      goto fail;
13117ec681f3Smrg
13127ec681f3Smrg   vk_free(alloc, handles);
13137ec681f3Smrg   *out_physical_devs = physical_devs;
13147ec681f3Smrg   *out_count = count;
13157ec681f3Smrg
13167ec681f3Smrg   return VK_SUCCESS;
13177ec681f3Smrg
13187ec681f3Smrgfail:
13197ec681f3Smrg   for (uint32_t i = 0; i < count; i++)
13207ec681f3Smrg      vn_physical_device_base_fini(&physical_devs[i].base);
13217ec681f3Smrg   vk_free(alloc, physical_devs);
13227ec681f3Smrg   vk_free(alloc, handles);
13237ec681f3Smrg   return result;
13247ec681f3Smrg}
13257ec681f3Smrg
13267ec681f3Smrgstatic uint32_t
13277ec681f3Smrgfilter_physical_devices(struct vn_physical_device *physical_devs,
13287ec681f3Smrg                        uint32_t count)
13297ec681f3Smrg{
13307ec681f3Smrg   uint32_t supported_count = 0;
13317ec681f3Smrg   for (uint32_t i = 0; i < count; i++) {
13327ec681f3Smrg      struct vn_physical_device *physical_dev = &physical_devs[i];
13337ec681f3Smrg
13347ec681f3Smrg      /* init renderer version and discard unsupported devices */
13357ec681f3Smrg      VkResult result =
13367ec681f3Smrg         vn_physical_device_init_renderer_version(physical_dev);
13377ec681f3Smrg      if (result != VK_SUCCESS) {
13387ec681f3Smrg         vn_physical_device_base_fini(&physical_dev->base);
13397ec681f3Smrg         continue;
13407ec681f3Smrg      }
13417ec681f3Smrg
13427ec681f3Smrg      if (supported_count < i)
13437ec681f3Smrg         physical_devs[supported_count] = *physical_dev;
13447ec681f3Smrg      supported_count++;
13457ec681f3Smrg   }
13467ec681f3Smrg
13477ec681f3Smrg   return supported_count;
13487ec681f3Smrg}
13497ec681f3Smrg
13507ec681f3Smrgstatic VkResult
13517ec681f3Smrgvn_instance_enumerate_physical_devices_and_groups(struct vn_instance *instance)
13527ec681f3Smrg{
13537ec681f3Smrg   const VkAllocationCallbacks *alloc = &instance->base.base.alloc;
13547ec681f3Smrg   struct vn_physical_device *physical_devs = NULL;
13557ec681f3Smrg   uint32_t count = 0;
13567ec681f3Smrg   VkResult result = VK_SUCCESS;
13577ec681f3Smrg
13587ec681f3Smrg   mtx_lock(&instance->physical_device.mutex);
13597ec681f3Smrg
13607ec681f3Smrg   if (instance->physical_device.initialized)
13617ec681f3Smrg      goto unlock;
13627ec681f3Smrg   instance->physical_device.initialized = true;
13637ec681f3Smrg
13647ec681f3Smrg   result = enumerate_physical_devices(instance, &physical_devs, &count);
13657ec681f3Smrg   if (result != VK_SUCCESS)
13667ec681f3Smrg      goto unlock;
13677ec681f3Smrg
13687ec681f3Smrg   count = filter_physical_devices(physical_devs, count);
13697ec681f3Smrg   if (!count) {
13707ec681f3Smrg      vk_free(alloc, physical_devs);
13717ec681f3Smrg      goto unlock;
13727ec681f3Smrg   }
13737ec681f3Smrg
13747ec681f3Smrg   /* fully initialize physical devices */
13757ec681f3Smrg   for (uint32_t i = 0; i < count; i++) {
13767ec681f3Smrg      struct vn_physical_device *physical_dev = &physical_devs[i];
13777ec681f3Smrg
13787ec681f3Smrg      result = vn_physical_device_init(physical_dev);
13797ec681f3Smrg      if (result != VK_SUCCESS) {
13807ec681f3Smrg         for (uint32_t j = 0; j < i; j++)
13817ec681f3Smrg            vn_physical_device_fini(&physical_devs[j]);
13827ec681f3Smrg         for (uint32_t j = i; j < count; j++)
13837ec681f3Smrg            vn_physical_device_base_fini(&physical_devs[j].base);
13847ec681f3Smrg         vk_free(alloc, physical_devs);
13857ec681f3Smrg         goto unlock;
13867ec681f3Smrg      }
13877ec681f3Smrg   }
13887ec681f3Smrg
13897ec681f3Smrg   result = vn_instance_enumerate_physical_device_groups_locked(
13907ec681f3Smrg      instance, physical_devs, count);
13917ec681f3Smrg   if (result != VK_SUCCESS) {
13927ec681f3Smrg      for (uint32_t i = 0; i < count; i++)
13937ec681f3Smrg         vn_physical_device_fini(&physical_devs[i]);
13947ec681f3Smrg      vk_free(alloc, physical_devs);
13957ec681f3Smrg      goto unlock;
13967ec681f3Smrg   }
13977ec681f3Smrg
13987ec681f3Smrg   instance->physical_device.devices = physical_devs;
13997ec681f3Smrg   instance->physical_device.device_count = count;
14007ec681f3Smrg
14017ec681f3Smrgunlock:
14027ec681f3Smrg   mtx_unlock(&instance->physical_device.mutex);
14037ec681f3Smrg   return result;
14047ec681f3Smrg}
14057ec681f3Smrg
14067ec681f3Smrg/* physical device commands */
14077ec681f3Smrg
14087ec681f3SmrgVkResult
14097ec681f3Smrgvn_EnumeratePhysicalDevices(VkInstance _instance,
14107ec681f3Smrg                            uint32_t *pPhysicalDeviceCount,
14117ec681f3Smrg                            VkPhysicalDevice *pPhysicalDevices)
14127ec681f3Smrg{
14137ec681f3Smrg   struct vn_instance *instance = vn_instance_from_handle(_instance);
14147ec681f3Smrg
14157ec681f3Smrg   VkResult result =
14167ec681f3Smrg      vn_instance_enumerate_physical_devices_and_groups(instance);
14177ec681f3Smrg   if (result != VK_SUCCESS)
14187ec681f3Smrg      return vn_error(instance, result);
14197ec681f3Smrg
14207ec681f3Smrg   VK_OUTARRAY_MAKE(out, pPhysicalDevices, pPhysicalDeviceCount);
14217ec681f3Smrg   for (uint32_t i = 0; i < instance->physical_device.device_count; i++) {
14227ec681f3Smrg      vk_outarray_append(&out, physical_dev) {
14237ec681f3Smrg         *physical_dev = vn_physical_device_to_handle(
14247ec681f3Smrg            &instance->physical_device.devices[i]);
14257ec681f3Smrg      }
14267ec681f3Smrg   }
14277ec681f3Smrg
14287ec681f3Smrg   return vk_outarray_status(&out);
14297ec681f3Smrg}
14307ec681f3Smrg
14317ec681f3SmrgVkResult
14327ec681f3Smrgvn_EnumeratePhysicalDeviceGroups(
14337ec681f3Smrg   VkInstance _instance,
14347ec681f3Smrg   uint32_t *pPhysicalDeviceGroupCount,
14357ec681f3Smrg   VkPhysicalDeviceGroupProperties *pPhysicalDeviceGroupProperties)
14367ec681f3Smrg{
14377ec681f3Smrg   struct vn_instance *instance = vn_instance_from_handle(_instance);
14387ec681f3Smrg
14397ec681f3Smrg   VkResult result =
14407ec681f3Smrg      vn_instance_enumerate_physical_devices_and_groups(instance);
14417ec681f3Smrg   if (result != VK_SUCCESS)
14427ec681f3Smrg      return vn_error(instance, result);
14437ec681f3Smrg
14447ec681f3Smrg   VK_OUTARRAY_MAKE(out, pPhysicalDeviceGroupProperties,
14457ec681f3Smrg                    pPhysicalDeviceGroupCount);
14467ec681f3Smrg   for (uint32_t i = 0; i < instance->physical_device.group_count; i++) {
14477ec681f3Smrg      vk_outarray_append(&out, props) {
14487ec681f3Smrg         *props = instance->physical_device.groups[i];
14497ec681f3Smrg      }
14507ec681f3Smrg   }
14517ec681f3Smrg
14527ec681f3Smrg   return vk_outarray_status(&out);
14537ec681f3Smrg}
14547ec681f3Smrg
14557ec681f3SmrgVkResult
14567ec681f3Smrgvn_EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
14577ec681f3Smrg                                      const char *pLayerName,
14587ec681f3Smrg                                      uint32_t *pPropertyCount,
14597ec681f3Smrg                                      VkExtensionProperties *pProperties)
14607ec681f3Smrg{
14617ec681f3Smrg   struct vn_physical_device *physical_dev =
14627ec681f3Smrg      vn_physical_device_from_handle(physicalDevice);
14637ec681f3Smrg
14647ec681f3Smrg   if (pLayerName)
14657ec681f3Smrg      return vn_error(physical_dev->instance, VK_ERROR_LAYER_NOT_PRESENT);
14667ec681f3Smrg
14677ec681f3Smrg   VK_OUTARRAY_MAKE(out, pProperties, pPropertyCount);
14687ec681f3Smrg   for (uint32_t i = 0; i < VK_DEVICE_EXTENSION_COUNT; i++) {
14697ec681f3Smrg      if (physical_dev->base.base.supported_extensions.extensions[i]) {
14707ec681f3Smrg         vk_outarray_append(&out, prop) {
14717ec681f3Smrg            *prop = vk_device_extensions[i];
14727ec681f3Smrg            prop->specVersion = physical_dev->extension_spec_versions[i];
14737ec681f3Smrg         }
14747ec681f3Smrg      }
14757ec681f3Smrg   }
14767ec681f3Smrg
14777ec681f3Smrg   return vk_outarray_status(&out);
14787ec681f3Smrg}
14797ec681f3Smrg
14807ec681f3SmrgVkResult
14817ec681f3Smrgvn_EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,
14827ec681f3Smrg                                  uint32_t *pPropertyCount,
14837ec681f3Smrg                                  VkLayerProperties *pProperties)
14847ec681f3Smrg{
14857ec681f3Smrg   *pPropertyCount = 0;
14867ec681f3Smrg   return VK_SUCCESS;
14877ec681f3Smrg}
14887ec681f3Smrg
14897ec681f3Smrgvoid
14907ec681f3Smrgvn_GetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice,
14917ec681f3Smrg                             VkPhysicalDeviceFeatures *pFeatures)
14927ec681f3Smrg{
14937ec681f3Smrg   struct vn_physical_device *physical_dev =
14947ec681f3Smrg      vn_physical_device_from_handle(physicalDevice);
14957ec681f3Smrg
14967ec681f3Smrg   *pFeatures = physical_dev->features.features;
14977ec681f3Smrg}
14987ec681f3Smrg
14997ec681f3Smrgvoid
15007ec681f3Smrgvn_GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
15017ec681f3Smrg                               VkPhysicalDeviceProperties *pProperties)
15027ec681f3Smrg{
15037ec681f3Smrg   struct vn_physical_device *physical_dev =
15047ec681f3Smrg      vn_physical_device_from_handle(physicalDevice);
15057ec681f3Smrg
15067ec681f3Smrg   *pProperties = physical_dev->properties.properties;
15077ec681f3Smrg}
15087ec681f3Smrg
15097ec681f3Smrgvoid
15107ec681f3Smrgvn_GetPhysicalDeviceQueueFamilyProperties(
15117ec681f3Smrg   VkPhysicalDevice physicalDevice,
15127ec681f3Smrg   uint32_t *pQueueFamilyPropertyCount,
15137ec681f3Smrg   VkQueueFamilyProperties *pQueueFamilyProperties)
15147ec681f3Smrg{
15157ec681f3Smrg   struct vn_physical_device *physical_dev =
15167ec681f3Smrg      vn_physical_device_from_handle(physicalDevice);
15177ec681f3Smrg
15187ec681f3Smrg   VK_OUTARRAY_MAKE(out, pQueueFamilyProperties, pQueueFamilyPropertyCount);
15197ec681f3Smrg   for (uint32_t i = 0; i < physical_dev->queue_family_count; i++) {
15207ec681f3Smrg      vk_outarray_append(&out, props) {
15217ec681f3Smrg         *props =
15227ec681f3Smrg            physical_dev->queue_family_properties[i].queueFamilyProperties;
15237ec681f3Smrg      }
15247ec681f3Smrg   }
15257ec681f3Smrg}
15267ec681f3Smrg
15277ec681f3Smrgvoid
15287ec681f3Smrgvn_GetPhysicalDeviceMemoryProperties(
15297ec681f3Smrg   VkPhysicalDevice physicalDevice,
15307ec681f3Smrg   VkPhysicalDeviceMemoryProperties *pMemoryProperties)
15317ec681f3Smrg{
15327ec681f3Smrg   struct vn_physical_device *physical_dev =
15337ec681f3Smrg      vn_physical_device_from_handle(physicalDevice);
15347ec681f3Smrg
15357ec681f3Smrg   *pMemoryProperties = physical_dev->memory_properties.memoryProperties;
15367ec681f3Smrg}
15377ec681f3Smrg
15387ec681f3Smrgvoid
15397ec681f3Smrgvn_GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice,
15407ec681f3Smrg                                     VkFormat format,
15417ec681f3Smrg                                     VkFormatProperties *pFormatProperties)
15427ec681f3Smrg{
15437ec681f3Smrg   struct vn_physical_device *physical_dev =
15447ec681f3Smrg      vn_physical_device_from_handle(physicalDevice);
15457ec681f3Smrg
15467ec681f3Smrg   /* TODO query all formats during init */
15477ec681f3Smrg   vn_call_vkGetPhysicalDeviceFormatProperties(
15487ec681f3Smrg      physical_dev->instance, physicalDevice, format, pFormatProperties);
15497ec681f3Smrg}
15507ec681f3Smrg
15517ec681f3SmrgVkResult
15527ec681f3Smrgvn_GetPhysicalDeviceImageFormatProperties(
15537ec681f3Smrg   VkPhysicalDevice physicalDevice,
15547ec681f3Smrg   VkFormat format,
15557ec681f3Smrg   VkImageType type,
15567ec681f3Smrg   VkImageTiling tiling,
15577ec681f3Smrg   VkImageUsageFlags usage,
15587ec681f3Smrg   VkImageCreateFlags flags,
15597ec681f3Smrg   VkImageFormatProperties *pImageFormatProperties)
15607ec681f3Smrg{
15617ec681f3Smrg   struct vn_physical_device *physical_dev =
15627ec681f3Smrg      vn_physical_device_from_handle(physicalDevice);
15637ec681f3Smrg
15647ec681f3Smrg   /* TODO per-device cache */
15657ec681f3Smrg   VkResult result = vn_call_vkGetPhysicalDeviceImageFormatProperties(
15667ec681f3Smrg      physical_dev->instance, physicalDevice, format, type, tiling, usage,
15677ec681f3Smrg      flags, pImageFormatProperties);
15687ec681f3Smrg
15697ec681f3Smrg   return vn_result(physical_dev->instance, result);
15707ec681f3Smrg}
15717ec681f3Smrg
15727ec681f3Smrgvoid
15737ec681f3Smrgvn_GetPhysicalDeviceSparseImageFormatProperties(
15747ec681f3Smrg   VkPhysicalDevice physicalDevice,
15757ec681f3Smrg   VkFormat format,
15767ec681f3Smrg   VkImageType type,
15777ec681f3Smrg   uint32_t samples,
15787ec681f3Smrg   VkImageUsageFlags usage,
15797ec681f3Smrg   VkImageTiling tiling,
15807ec681f3Smrg   uint32_t *pPropertyCount,
15817ec681f3Smrg   VkSparseImageFormatProperties *pProperties)
15827ec681f3Smrg{
15837ec681f3Smrg   struct vn_physical_device *physical_dev =
15847ec681f3Smrg      vn_physical_device_from_handle(physicalDevice);
15857ec681f3Smrg
15867ec681f3Smrg   /* TODO per-device cache */
15877ec681f3Smrg   vn_call_vkGetPhysicalDeviceSparseImageFormatProperties(
15887ec681f3Smrg      physical_dev->instance, physicalDevice, format, type, samples, usage,
15897ec681f3Smrg      tiling, pPropertyCount, pProperties);
15907ec681f3Smrg}
15917ec681f3Smrg
15927ec681f3Smrgvoid
15937ec681f3Smrgvn_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,
15947ec681f3Smrg                              VkPhysicalDeviceFeatures2 *pFeatures)
15957ec681f3Smrg{
15967ec681f3Smrg   struct vn_physical_device *physical_dev =
15977ec681f3Smrg      vn_physical_device_from_handle(physicalDevice);
15987ec681f3Smrg   const struct VkPhysicalDeviceVulkan11Features *vk11_feats =
15997ec681f3Smrg      &physical_dev->vulkan_1_1_features;
16007ec681f3Smrg   const struct VkPhysicalDeviceVulkan12Features *vk12_feats =
16017ec681f3Smrg      &physical_dev->vulkan_1_2_features;
16027ec681f3Smrg   union {
16037ec681f3Smrg      VkBaseOutStructure *pnext;
16047ec681f3Smrg
16057ec681f3Smrg      /* Vulkan 1.1 */
16067ec681f3Smrg      VkPhysicalDevice16BitStorageFeatures *sixteen_bit_storage;
16077ec681f3Smrg      VkPhysicalDeviceMultiviewFeatures *multiview;
16087ec681f3Smrg      VkPhysicalDeviceVariablePointersFeatures *variable_pointers;
16097ec681f3Smrg      VkPhysicalDeviceProtectedMemoryFeatures *protected_memory;
16107ec681f3Smrg      VkPhysicalDeviceSamplerYcbcrConversionFeatures *sampler_ycbcr_conversion;
16117ec681f3Smrg      VkPhysicalDeviceShaderDrawParametersFeatures *shader_draw_parameters;
16127ec681f3Smrg
16137ec681f3Smrg      /* Vulkan 1.2 */
16147ec681f3Smrg      VkPhysicalDevice8BitStorageFeatures *eight_bit_storage;
16157ec681f3Smrg      VkPhysicalDeviceShaderAtomicInt64Features *shader_atomic_int64;
16167ec681f3Smrg      VkPhysicalDeviceShaderFloat16Int8Features *shader_float16_int8;
16177ec681f3Smrg      VkPhysicalDeviceDescriptorIndexingFeatures *descriptor_indexing;
16187ec681f3Smrg      VkPhysicalDeviceScalarBlockLayoutFeatures *scalar_block_layout;
16197ec681f3Smrg      VkPhysicalDeviceImagelessFramebufferFeatures *imageless_framebuffer;
16207ec681f3Smrg      VkPhysicalDeviceUniformBufferStandardLayoutFeatures
16217ec681f3Smrg         *uniform_buffer_standard_layout;
16227ec681f3Smrg      VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures
16237ec681f3Smrg         *shader_subgroup_extended_types;
16247ec681f3Smrg      VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures
16257ec681f3Smrg         *separate_depth_stencil_layouts;
16267ec681f3Smrg      VkPhysicalDeviceHostQueryResetFeatures *host_query_reset;
16277ec681f3Smrg      VkPhysicalDeviceTimelineSemaphoreFeatures *timeline_semaphore;
16287ec681f3Smrg      VkPhysicalDeviceBufferDeviceAddressFeatures *buffer_device_address;
16297ec681f3Smrg      VkPhysicalDeviceVulkanMemoryModelFeatures *vulkan_memory_model;
16307ec681f3Smrg
16317ec681f3Smrg      VkPhysicalDeviceTransformFeedbackFeaturesEXT *transform_feedback;
16327ec681f3Smrg   } u;
16337ec681f3Smrg
16347ec681f3Smrg   u.pnext = (VkBaseOutStructure *)pFeatures;
16357ec681f3Smrg   while (u.pnext) {
16367ec681f3Smrg      void *saved = u.pnext->pNext;
16377ec681f3Smrg      switch (u.pnext->sType) {
16387ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2:
16397ec681f3Smrg         memcpy(u.pnext, &physical_dev->features,
16407ec681f3Smrg                sizeof(physical_dev->features));
16417ec681f3Smrg         break;
16427ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES:
16437ec681f3Smrg         memcpy(u.pnext, vk11_feats, sizeof(*vk11_feats));
16447ec681f3Smrg         break;
16457ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES:
16467ec681f3Smrg         memcpy(u.pnext, vk12_feats, sizeof(*vk12_feats));
16477ec681f3Smrg         break;
16487ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES:
16497ec681f3Smrg         u.sixteen_bit_storage->storageBuffer16BitAccess =
16507ec681f3Smrg            vk11_feats->storageBuffer16BitAccess;
16517ec681f3Smrg         u.sixteen_bit_storage->uniformAndStorageBuffer16BitAccess =
16527ec681f3Smrg            vk11_feats->uniformAndStorageBuffer16BitAccess;
16537ec681f3Smrg         u.sixteen_bit_storage->storagePushConstant16 =
16547ec681f3Smrg            vk11_feats->storagePushConstant16;
16557ec681f3Smrg         u.sixteen_bit_storage->storageInputOutput16 =
16567ec681f3Smrg            vk11_feats->storageInputOutput16;
16577ec681f3Smrg         break;
16587ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES:
16597ec681f3Smrg         u.multiview->multiview = vk11_feats->multiview;
16607ec681f3Smrg         u.multiview->multiviewGeometryShader =
16617ec681f3Smrg            vk11_feats->multiviewGeometryShader;
16627ec681f3Smrg         u.multiview->multiviewTessellationShader =
16637ec681f3Smrg            vk11_feats->multiviewTessellationShader;
16647ec681f3Smrg         break;
16657ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES:
16667ec681f3Smrg         u.variable_pointers->variablePointersStorageBuffer =
16677ec681f3Smrg            vk11_feats->variablePointersStorageBuffer;
16687ec681f3Smrg         u.variable_pointers->variablePointers = vk11_feats->variablePointers;
16697ec681f3Smrg         break;
16707ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES:
16717ec681f3Smrg         u.protected_memory->protectedMemory = vk11_feats->protectedMemory;
16727ec681f3Smrg         break;
16737ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES:
16747ec681f3Smrg         u.sampler_ycbcr_conversion->samplerYcbcrConversion =
16757ec681f3Smrg            vk11_feats->samplerYcbcrConversion;
16767ec681f3Smrg         break;
16777ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES:
16787ec681f3Smrg         u.shader_draw_parameters->shaderDrawParameters =
16797ec681f3Smrg            vk11_feats->shaderDrawParameters;
16807ec681f3Smrg         break;
16817ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES:
16827ec681f3Smrg         u.eight_bit_storage->storageBuffer8BitAccess =
16837ec681f3Smrg            vk12_feats->storageBuffer8BitAccess;
16847ec681f3Smrg         u.eight_bit_storage->uniformAndStorageBuffer8BitAccess =
16857ec681f3Smrg            vk12_feats->uniformAndStorageBuffer8BitAccess;
16867ec681f3Smrg         u.eight_bit_storage->storagePushConstant8 =
16877ec681f3Smrg            vk12_feats->storagePushConstant8;
16887ec681f3Smrg         break;
16897ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES:
16907ec681f3Smrg         u.shader_atomic_int64->shaderBufferInt64Atomics =
16917ec681f3Smrg            vk12_feats->shaderBufferInt64Atomics;
16927ec681f3Smrg         u.shader_atomic_int64->shaderSharedInt64Atomics =
16937ec681f3Smrg            vk12_feats->shaderSharedInt64Atomics;
16947ec681f3Smrg         break;
16957ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES:
16967ec681f3Smrg         u.shader_float16_int8->shaderFloat16 = vk12_feats->shaderFloat16;
16977ec681f3Smrg         u.shader_float16_int8->shaderInt8 = vk12_feats->shaderInt8;
16987ec681f3Smrg         break;
16997ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES:
17007ec681f3Smrg         u.descriptor_indexing->shaderInputAttachmentArrayDynamicIndexing =
17017ec681f3Smrg            vk12_feats->shaderInputAttachmentArrayDynamicIndexing;
17027ec681f3Smrg         u.descriptor_indexing->shaderUniformTexelBufferArrayDynamicIndexing =
17037ec681f3Smrg            vk12_feats->shaderUniformTexelBufferArrayDynamicIndexing;
17047ec681f3Smrg         u.descriptor_indexing->shaderStorageTexelBufferArrayDynamicIndexing =
17057ec681f3Smrg            vk12_feats->shaderStorageTexelBufferArrayDynamicIndexing;
17067ec681f3Smrg         u.descriptor_indexing->shaderUniformBufferArrayNonUniformIndexing =
17077ec681f3Smrg            vk12_feats->shaderUniformBufferArrayNonUniformIndexing;
17087ec681f3Smrg         u.descriptor_indexing->shaderSampledImageArrayNonUniformIndexing =
17097ec681f3Smrg            vk12_feats->shaderSampledImageArrayNonUniformIndexing;
17107ec681f3Smrg         u.descriptor_indexing->shaderStorageBufferArrayNonUniformIndexing =
17117ec681f3Smrg            vk12_feats->shaderStorageBufferArrayNonUniformIndexing;
17127ec681f3Smrg         u.descriptor_indexing->shaderStorageImageArrayNonUniformIndexing =
17137ec681f3Smrg            vk12_feats->shaderStorageImageArrayNonUniformIndexing;
17147ec681f3Smrg         u.descriptor_indexing->shaderInputAttachmentArrayNonUniformIndexing =
17157ec681f3Smrg            vk12_feats->shaderInputAttachmentArrayNonUniformIndexing;
17167ec681f3Smrg         u.descriptor_indexing
17177ec681f3Smrg            ->shaderUniformTexelBufferArrayNonUniformIndexing =
17187ec681f3Smrg            vk12_feats->shaderUniformTexelBufferArrayNonUniformIndexing;
17197ec681f3Smrg         u.descriptor_indexing
17207ec681f3Smrg            ->shaderStorageTexelBufferArrayNonUniformIndexing =
17217ec681f3Smrg            vk12_feats->shaderStorageTexelBufferArrayNonUniformIndexing;
17227ec681f3Smrg         u.descriptor_indexing->descriptorBindingUniformBufferUpdateAfterBind =
17237ec681f3Smrg            vk12_feats->descriptorBindingUniformBufferUpdateAfterBind;
17247ec681f3Smrg         u.descriptor_indexing->descriptorBindingSampledImageUpdateAfterBind =
17257ec681f3Smrg            vk12_feats->descriptorBindingSampledImageUpdateAfterBind;
17267ec681f3Smrg         u.descriptor_indexing->descriptorBindingStorageImageUpdateAfterBind =
17277ec681f3Smrg            vk12_feats->descriptorBindingStorageImageUpdateAfterBind;
17287ec681f3Smrg         u.descriptor_indexing->descriptorBindingStorageBufferUpdateAfterBind =
17297ec681f3Smrg            vk12_feats->descriptorBindingStorageBufferUpdateAfterBind;
17307ec681f3Smrg         u.descriptor_indexing
17317ec681f3Smrg            ->descriptorBindingUniformTexelBufferUpdateAfterBind =
17327ec681f3Smrg            vk12_feats->descriptorBindingUniformTexelBufferUpdateAfterBind;
17337ec681f3Smrg         u.descriptor_indexing
17347ec681f3Smrg            ->descriptorBindingStorageTexelBufferUpdateAfterBind =
17357ec681f3Smrg            vk12_feats->descriptorBindingStorageTexelBufferUpdateAfterBind;
17367ec681f3Smrg         u.descriptor_indexing->descriptorBindingUpdateUnusedWhilePending =
17377ec681f3Smrg            vk12_feats->descriptorBindingUpdateUnusedWhilePending;
17387ec681f3Smrg         u.descriptor_indexing->descriptorBindingPartiallyBound =
17397ec681f3Smrg            vk12_feats->descriptorBindingPartiallyBound;
17407ec681f3Smrg         u.descriptor_indexing->descriptorBindingVariableDescriptorCount =
17417ec681f3Smrg            vk12_feats->descriptorBindingVariableDescriptorCount;
17427ec681f3Smrg         u.descriptor_indexing->runtimeDescriptorArray =
17437ec681f3Smrg            vk12_feats->runtimeDescriptorArray;
17447ec681f3Smrg         break;
17457ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES:
17467ec681f3Smrg         u.scalar_block_layout->scalarBlockLayout =
17477ec681f3Smrg            vk12_feats->scalarBlockLayout;
17487ec681f3Smrg         break;
17497ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES:
17507ec681f3Smrg         u.imageless_framebuffer->imagelessFramebuffer =
17517ec681f3Smrg            vk12_feats->imagelessFramebuffer;
17527ec681f3Smrg         break;
17537ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES:
17547ec681f3Smrg         u.uniform_buffer_standard_layout->uniformBufferStandardLayout =
17557ec681f3Smrg            vk12_feats->uniformBufferStandardLayout;
17567ec681f3Smrg         break;
17577ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES:
17587ec681f3Smrg         u.shader_subgroup_extended_types->shaderSubgroupExtendedTypes =
17597ec681f3Smrg            vk12_feats->shaderSubgroupExtendedTypes;
17607ec681f3Smrg         break;
17617ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES:
17627ec681f3Smrg         u.separate_depth_stencil_layouts->separateDepthStencilLayouts =
17637ec681f3Smrg            vk12_feats->separateDepthStencilLayouts;
17647ec681f3Smrg         break;
17657ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES:
17667ec681f3Smrg         u.host_query_reset->hostQueryReset = vk12_feats->hostQueryReset;
17677ec681f3Smrg         break;
17687ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES:
17697ec681f3Smrg         u.timeline_semaphore->timelineSemaphore =
17707ec681f3Smrg            vk12_feats->timelineSemaphore;
17717ec681f3Smrg         break;
17727ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES:
17737ec681f3Smrg         u.buffer_device_address->bufferDeviceAddress =
17747ec681f3Smrg            vk12_feats->bufferDeviceAddress;
17757ec681f3Smrg         u.buffer_device_address->bufferDeviceAddressCaptureReplay =
17767ec681f3Smrg            vk12_feats->bufferDeviceAddressCaptureReplay;
17777ec681f3Smrg         u.buffer_device_address->bufferDeviceAddressMultiDevice =
17787ec681f3Smrg            vk12_feats->bufferDeviceAddressMultiDevice;
17797ec681f3Smrg         break;
17807ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES:
17817ec681f3Smrg         u.vulkan_memory_model->vulkanMemoryModel =
17827ec681f3Smrg            vk12_feats->vulkanMemoryModel;
17837ec681f3Smrg         u.vulkan_memory_model->vulkanMemoryModelDeviceScope =
17847ec681f3Smrg            vk12_feats->vulkanMemoryModelDeviceScope;
17857ec681f3Smrg         u.vulkan_memory_model->vulkanMemoryModelAvailabilityVisibilityChains =
17867ec681f3Smrg            vk12_feats->vulkanMemoryModelAvailabilityVisibilityChains;
17877ec681f3Smrg         break;
17887ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT:
17897ec681f3Smrg         memcpy(u.transform_feedback,
17907ec681f3Smrg                &physical_dev->transform_feedback_features,
17917ec681f3Smrg                sizeof(physical_dev->transform_feedback_features));
17927ec681f3Smrg         break;
17937ec681f3Smrg      default:
17947ec681f3Smrg         break;
17957ec681f3Smrg      }
17967ec681f3Smrg      u.pnext->pNext = saved;
17977ec681f3Smrg
17987ec681f3Smrg      u.pnext = u.pnext->pNext;
17997ec681f3Smrg   }
18007ec681f3Smrg}
18017ec681f3Smrg
18027ec681f3Smrgvoid
18037ec681f3Smrgvn_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
18047ec681f3Smrg                                VkPhysicalDeviceProperties2 *pProperties)
18057ec681f3Smrg{
18067ec681f3Smrg   struct vn_physical_device *physical_dev =
18077ec681f3Smrg      vn_physical_device_from_handle(physicalDevice);
18087ec681f3Smrg   const struct VkPhysicalDeviceVulkan11Properties *vk11_props =
18097ec681f3Smrg      &physical_dev->vulkan_1_1_properties;
18107ec681f3Smrg   const struct VkPhysicalDeviceVulkan12Properties *vk12_props =
18117ec681f3Smrg      &physical_dev->vulkan_1_2_properties;
18127ec681f3Smrg   union {
18137ec681f3Smrg      VkBaseOutStructure *pnext;
18147ec681f3Smrg
18157ec681f3Smrg      /* Vulkan 1.1 */
18167ec681f3Smrg      VkPhysicalDeviceIDProperties *id;
18177ec681f3Smrg      VkPhysicalDeviceSubgroupProperties *subgroup;
18187ec681f3Smrg      VkPhysicalDevicePointClippingProperties *point_clipping;
18197ec681f3Smrg      VkPhysicalDeviceMultiviewProperties *multiview;
18207ec681f3Smrg      VkPhysicalDeviceProtectedMemoryProperties *protected_memory;
18217ec681f3Smrg      VkPhysicalDeviceMaintenance3Properties *maintenance_3;
18227ec681f3Smrg
18237ec681f3Smrg      /* Vulkan 1.2 */
18247ec681f3Smrg      VkPhysicalDeviceDriverProperties *driver;
18257ec681f3Smrg      VkPhysicalDeviceFloatControlsProperties *float_controls;
18267ec681f3Smrg      VkPhysicalDeviceDescriptorIndexingProperties *descriptor_indexing;
18277ec681f3Smrg      VkPhysicalDeviceDepthStencilResolveProperties *depth_stencil_resolve;
18287ec681f3Smrg      VkPhysicalDeviceSamplerFilterMinmaxProperties *sampler_filter_minmax;
18297ec681f3Smrg      VkPhysicalDeviceTimelineSemaphoreProperties *timeline_semaphore;
18307ec681f3Smrg
18317ec681f3Smrg      VkPhysicalDevicePCIBusInfoPropertiesEXT *pci_bus_info;
18327ec681f3Smrg      VkPhysicalDeviceTransformFeedbackPropertiesEXT *transform_feedback;
18337ec681f3Smrg      VkPhysicalDevicePresentationPropertiesANDROID *presentation_properties;
18347ec681f3Smrg   } u;
18357ec681f3Smrg
18367ec681f3Smrg   u.pnext = (VkBaseOutStructure *)pProperties;
18377ec681f3Smrg   while (u.pnext) {
18387ec681f3Smrg      void *saved = u.pnext->pNext;
18397ec681f3Smrg      switch ((int32_t)u.pnext->sType) {
18407ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2:
18417ec681f3Smrg         memcpy(u.pnext, &physical_dev->properties,
18427ec681f3Smrg                sizeof(physical_dev->properties));
18437ec681f3Smrg         break;
18447ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES:
18457ec681f3Smrg         memcpy(u.pnext, vk11_props, sizeof(*vk11_props));
18467ec681f3Smrg         break;
18477ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES:
18487ec681f3Smrg         memcpy(u.pnext, vk12_props, sizeof(*vk12_props));
18497ec681f3Smrg         break;
18507ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES:
18517ec681f3Smrg         memcpy(u.id->deviceUUID, vk11_props->deviceUUID,
18527ec681f3Smrg                sizeof(vk11_props->deviceUUID));
18537ec681f3Smrg         memcpy(u.id->driverUUID, vk11_props->driverUUID,
18547ec681f3Smrg                sizeof(vk11_props->driverUUID));
18557ec681f3Smrg         memcpy(u.id->deviceLUID, vk11_props->deviceLUID,
18567ec681f3Smrg                sizeof(vk11_props->deviceLUID));
18577ec681f3Smrg         u.id->deviceNodeMask = vk11_props->deviceNodeMask;
18587ec681f3Smrg         u.id->deviceLUIDValid = vk11_props->deviceLUIDValid;
18597ec681f3Smrg         break;
18607ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES:
18617ec681f3Smrg         u.subgroup->subgroupSize = vk11_props->subgroupSize;
18627ec681f3Smrg         u.subgroup->supportedStages = vk11_props->subgroupSupportedStages;
18637ec681f3Smrg         u.subgroup->supportedOperations =
18647ec681f3Smrg            vk11_props->subgroupSupportedOperations;
18657ec681f3Smrg         u.subgroup->quadOperationsInAllStages =
18667ec681f3Smrg            vk11_props->subgroupQuadOperationsInAllStages;
18677ec681f3Smrg         break;
18687ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES:
18697ec681f3Smrg         u.point_clipping->pointClippingBehavior =
18707ec681f3Smrg            vk11_props->pointClippingBehavior;
18717ec681f3Smrg         break;
18727ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES:
18737ec681f3Smrg         u.multiview->maxMultiviewViewCount =
18747ec681f3Smrg            vk11_props->maxMultiviewViewCount;
18757ec681f3Smrg         u.multiview->maxMultiviewInstanceIndex =
18767ec681f3Smrg            vk11_props->maxMultiviewInstanceIndex;
18777ec681f3Smrg         break;
18787ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES:
18797ec681f3Smrg         u.protected_memory->protectedNoFault = vk11_props->protectedNoFault;
18807ec681f3Smrg         break;
18817ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES:
18827ec681f3Smrg         u.maintenance_3->maxPerSetDescriptors =
18837ec681f3Smrg            vk11_props->maxPerSetDescriptors;
18847ec681f3Smrg         u.maintenance_3->maxMemoryAllocationSize =
18857ec681f3Smrg            vk11_props->maxMemoryAllocationSize;
18867ec681f3Smrg         break;
18877ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES:
18887ec681f3Smrg         u.driver->driverID = vk12_props->driverID;
18897ec681f3Smrg         memcpy(u.driver->driverName, vk12_props->driverName,
18907ec681f3Smrg                sizeof(vk12_props->driverName));
18917ec681f3Smrg         memcpy(u.driver->driverInfo, vk12_props->driverInfo,
18927ec681f3Smrg                sizeof(vk12_props->driverInfo));
18937ec681f3Smrg         u.driver->conformanceVersion = vk12_props->conformanceVersion;
18947ec681f3Smrg         break;
18957ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES:
18967ec681f3Smrg         u.float_controls->denormBehaviorIndependence =
18977ec681f3Smrg            vk12_props->denormBehaviorIndependence;
18987ec681f3Smrg         u.float_controls->roundingModeIndependence =
18997ec681f3Smrg            vk12_props->roundingModeIndependence;
19007ec681f3Smrg         u.float_controls->shaderSignedZeroInfNanPreserveFloat16 =
19017ec681f3Smrg            vk12_props->shaderSignedZeroInfNanPreserveFloat16;
19027ec681f3Smrg         u.float_controls->shaderSignedZeroInfNanPreserveFloat32 =
19037ec681f3Smrg            vk12_props->shaderSignedZeroInfNanPreserveFloat32;
19047ec681f3Smrg         u.float_controls->shaderSignedZeroInfNanPreserveFloat64 =
19057ec681f3Smrg            vk12_props->shaderSignedZeroInfNanPreserveFloat64;
19067ec681f3Smrg         u.float_controls->shaderDenormPreserveFloat16 =
19077ec681f3Smrg            vk12_props->shaderDenormPreserveFloat16;
19087ec681f3Smrg         u.float_controls->shaderDenormPreserveFloat32 =
19097ec681f3Smrg            vk12_props->shaderDenormPreserveFloat32;
19107ec681f3Smrg         u.float_controls->shaderDenormPreserveFloat64 =
19117ec681f3Smrg            vk12_props->shaderDenormPreserveFloat64;
19127ec681f3Smrg         u.float_controls->shaderDenormFlushToZeroFloat16 =
19137ec681f3Smrg            vk12_props->shaderDenormFlushToZeroFloat16;
19147ec681f3Smrg         u.float_controls->shaderDenormFlushToZeroFloat32 =
19157ec681f3Smrg            vk12_props->shaderDenormFlushToZeroFloat32;
19167ec681f3Smrg         u.float_controls->shaderDenormFlushToZeroFloat64 =
19177ec681f3Smrg            vk12_props->shaderDenormFlushToZeroFloat64;
19187ec681f3Smrg         u.float_controls->shaderRoundingModeRTEFloat16 =
19197ec681f3Smrg            vk12_props->shaderRoundingModeRTEFloat16;
19207ec681f3Smrg         u.float_controls->shaderRoundingModeRTEFloat32 =
19217ec681f3Smrg            vk12_props->shaderRoundingModeRTEFloat32;
19227ec681f3Smrg         u.float_controls->shaderRoundingModeRTEFloat64 =
19237ec681f3Smrg            vk12_props->shaderRoundingModeRTEFloat64;
19247ec681f3Smrg         u.float_controls->shaderRoundingModeRTZFloat16 =
19257ec681f3Smrg            vk12_props->shaderRoundingModeRTZFloat16;
19267ec681f3Smrg         u.float_controls->shaderRoundingModeRTZFloat32 =
19277ec681f3Smrg            vk12_props->shaderRoundingModeRTZFloat32;
19287ec681f3Smrg         u.float_controls->shaderRoundingModeRTZFloat64 =
19297ec681f3Smrg            vk12_props->shaderRoundingModeRTZFloat64;
19307ec681f3Smrg         break;
19317ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES:
19327ec681f3Smrg         u.descriptor_indexing->maxUpdateAfterBindDescriptorsInAllPools =
19337ec681f3Smrg            vk12_props->maxUpdateAfterBindDescriptorsInAllPools;
19347ec681f3Smrg         u.descriptor_indexing
19357ec681f3Smrg            ->shaderUniformBufferArrayNonUniformIndexingNative =
19367ec681f3Smrg            vk12_props->shaderUniformBufferArrayNonUniformIndexingNative;
19377ec681f3Smrg         u.descriptor_indexing
19387ec681f3Smrg            ->shaderSampledImageArrayNonUniformIndexingNative =
19397ec681f3Smrg            vk12_props->shaderSampledImageArrayNonUniformIndexingNative;
19407ec681f3Smrg         u.descriptor_indexing
19417ec681f3Smrg            ->shaderStorageBufferArrayNonUniformIndexingNative =
19427ec681f3Smrg            vk12_props->shaderStorageBufferArrayNonUniformIndexingNative;
19437ec681f3Smrg         u.descriptor_indexing
19447ec681f3Smrg            ->shaderStorageImageArrayNonUniformIndexingNative =
19457ec681f3Smrg            vk12_props->shaderStorageImageArrayNonUniformIndexingNative;
19467ec681f3Smrg         u.descriptor_indexing
19477ec681f3Smrg            ->shaderInputAttachmentArrayNonUniformIndexingNative =
19487ec681f3Smrg            vk12_props->shaderInputAttachmentArrayNonUniformIndexingNative;
19497ec681f3Smrg         u.descriptor_indexing->robustBufferAccessUpdateAfterBind =
19507ec681f3Smrg            vk12_props->robustBufferAccessUpdateAfterBind;
19517ec681f3Smrg         u.descriptor_indexing->quadDivergentImplicitLod =
19527ec681f3Smrg            vk12_props->quadDivergentImplicitLod;
19537ec681f3Smrg         u.descriptor_indexing->maxPerStageDescriptorUpdateAfterBindSamplers =
19547ec681f3Smrg            vk12_props->maxPerStageDescriptorUpdateAfterBindSamplers;
19557ec681f3Smrg         u.descriptor_indexing
19567ec681f3Smrg            ->maxPerStageDescriptorUpdateAfterBindUniformBuffers =
19577ec681f3Smrg            vk12_props->maxPerStageDescriptorUpdateAfterBindUniformBuffers;
19587ec681f3Smrg         u.descriptor_indexing
19597ec681f3Smrg            ->maxPerStageDescriptorUpdateAfterBindStorageBuffers =
19607ec681f3Smrg            vk12_props->maxPerStageDescriptorUpdateAfterBindStorageBuffers;
19617ec681f3Smrg         u.descriptor_indexing
19627ec681f3Smrg            ->maxPerStageDescriptorUpdateAfterBindSampledImages =
19637ec681f3Smrg            vk12_props->maxPerStageDescriptorUpdateAfterBindSampledImages;
19647ec681f3Smrg         u.descriptor_indexing
19657ec681f3Smrg            ->maxPerStageDescriptorUpdateAfterBindStorageImages =
19667ec681f3Smrg            vk12_props->maxPerStageDescriptorUpdateAfterBindStorageImages;
19677ec681f3Smrg         u.descriptor_indexing
19687ec681f3Smrg            ->maxPerStageDescriptorUpdateAfterBindInputAttachments =
19697ec681f3Smrg            vk12_props->maxPerStageDescriptorUpdateAfterBindInputAttachments;
19707ec681f3Smrg         u.descriptor_indexing->maxPerStageUpdateAfterBindResources =
19717ec681f3Smrg            vk12_props->maxPerStageUpdateAfterBindResources;
19727ec681f3Smrg         u.descriptor_indexing->maxDescriptorSetUpdateAfterBindSamplers =
19737ec681f3Smrg            vk12_props->maxDescriptorSetUpdateAfterBindSamplers;
19747ec681f3Smrg         u.descriptor_indexing->maxDescriptorSetUpdateAfterBindUniformBuffers =
19757ec681f3Smrg            vk12_props->maxDescriptorSetUpdateAfterBindUniformBuffers;
19767ec681f3Smrg         u.descriptor_indexing
19777ec681f3Smrg            ->maxDescriptorSetUpdateAfterBindUniformBuffersDynamic =
19787ec681f3Smrg            vk12_props->maxDescriptorSetUpdateAfterBindUniformBuffersDynamic;
19797ec681f3Smrg         u.descriptor_indexing->maxDescriptorSetUpdateAfterBindStorageBuffers =
19807ec681f3Smrg            vk12_props->maxDescriptorSetUpdateAfterBindStorageBuffers;
19817ec681f3Smrg         u.descriptor_indexing
19827ec681f3Smrg            ->maxDescriptorSetUpdateAfterBindStorageBuffersDynamic =
19837ec681f3Smrg            vk12_props->maxDescriptorSetUpdateAfterBindStorageBuffersDynamic;
19847ec681f3Smrg         u.descriptor_indexing->maxDescriptorSetUpdateAfterBindSampledImages =
19857ec681f3Smrg            vk12_props->maxDescriptorSetUpdateAfterBindSampledImages;
19867ec681f3Smrg         u.descriptor_indexing->maxDescriptorSetUpdateAfterBindStorageImages =
19877ec681f3Smrg            vk12_props->maxDescriptorSetUpdateAfterBindStorageImages;
19887ec681f3Smrg         u.descriptor_indexing
19897ec681f3Smrg            ->maxDescriptorSetUpdateAfterBindInputAttachments =
19907ec681f3Smrg            vk12_props->maxDescriptorSetUpdateAfterBindInputAttachments;
19917ec681f3Smrg         break;
19927ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES:
19937ec681f3Smrg         u.depth_stencil_resolve->supportedDepthResolveModes =
19947ec681f3Smrg            vk12_props->supportedDepthResolveModes;
19957ec681f3Smrg         u.depth_stencil_resolve->supportedStencilResolveModes =
19967ec681f3Smrg            vk12_props->supportedStencilResolveModes;
19977ec681f3Smrg         u.depth_stencil_resolve->independentResolveNone =
19987ec681f3Smrg            vk12_props->independentResolveNone;
19997ec681f3Smrg         u.depth_stencil_resolve->independentResolve =
20007ec681f3Smrg            vk12_props->independentResolve;
20017ec681f3Smrg         break;
20027ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES:
20037ec681f3Smrg         u.sampler_filter_minmax->filterMinmaxSingleComponentFormats =
20047ec681f3Smrg            vk12_props->filterMinmaxSingleComponentFormats;
20057ec681f3Smrg         u.sampler_filter_minmax->filterMinmaxImageComponentMapping =
20067ec681f3Smrg            vk12_props->filterMinmaxImageComponentMapping;
20077ec681f3Smrg         break;
20087ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES:
20097ec681f3Smrg         u.timeline_semaphore->maxTimelineSemaphoreValueDifference =
20107ec681f3Smrg            vk12_props->maxTimelineSemaphoreValueDifference;
20117ec681f3Smrg         break;
20127ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT:
20137ec681f3Smrg         /* this is used by WSI */
20147ec681f3Smrg         if (physical_dev->instance->renderer_info.pci.has_bus_info) {
20157ec681f3Smrg            u.pci_bus_info->pciDomain =
20167ec681f3Smrg               physical_dev->instance->renderer_info.pci.domain;
20177ec681f3Smrg            u.pci_bus_info->pciBus =
20187ec681f3Smrg               physical_dev->instance->renderer_info.pci.bus;
20197ec681f3Smrg            u.pci_bus_info->pciDevice =
20207ec681f3Smrg               physical_dev->instance->renderer_info.pci.device;
20217ec681f3Smrg            u.pci_bus_info->pciFunction =
20227ec681f3Smrg               physical_dev->instance->renderer_info.pci.function;
20237ec681f3Smrg         }
20247ec681f3Smrg         break;
20257ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT:
20267ec681f3Smrg         memcpy(u.transform_feedback,
20277ec681f3Smrg                &physical_dev->transform_feedback_properties,
20287ec681f3Smrg                sizeof(physical_dev->transform_feedback_properties));
20297ec681f3Smrg         break;
20307ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENTATION_PROPERTIES_ANDROID:
20317ec681f3Smrg         u.presentation_properties->sharedImage = VK_FALSE;
20327ec681f3Smrg         break;
20337ec681f3Smrg      default:
20347ec681f3Smrg         break;
20357ec681f3Smrg      }
20367ec681f3Smrg      u.pnext->pNext = saved;
20377ec681f3Smrg
20387ec681f3Smrg      u.pnext = u.pnext->pNext;
20397ec681f3Smrg   }
20407ec681f3Smrg}
20417ec681f3Smrg
20427ec681f3Smrgvoid
20437ec681f3Smrgvn_GetPhysicalDeviceQueueFamilyProperties2(
20447ec681f3Smrg   VkPhysicalDevice physicalDevice,
20457ec681f3Smrg   uint32_t *pQueueFamilyPropertyCount,
20467ec681f3Smrg   VkQueueFamilyProperties2 *pQueueFamilyProperties)
20477ec681f3Smrg{
20487ec681f3Smrg   struct vn_physical_device *physical_dev =
20497ec681f3Smrg      vn_physical_device_from_handle(physicalDevice);
20507ec681f3Smrg
20517ec681f3Smrg   VK_OUTARRAY_MAKE(out, pQueueFamilyProperties, pQueueFamilyPropertyCount);
20527ec681f3Smrg   for (uint32_t i = 0; i < physical_dev->queue_family_count; i++) {
20537ec681f3Smrg      vk_outarray_append(&out, props) {
20547ec681f3Smrg         *props = physical_dev->queue_family_properties[i];
20557ec681f3Smrg      }
20567ec681f3Smrg   }
20577ec681f3Smrg}
20587ec681f3Smrg
20597ec681f3Smrgvoid
20607ec681f3Smrgvn_GetPhysicalDeviceMemoryProperties2(
20617ec681f3Smrg   VkPhysicalDevice physicalDevice,
20627ec681f3Smrg   VkPhysicalDeviceMemoryProperties2 *pMemoryProperties)
20637ec681f3Smrg{
20647ec681f3Smrg   struct vn_physical_device *physical_dev =
20657ec681f3Smrg      vn_physical_device_from_handle(physicalDevice);
20667ec681f3Smrg
20677ec681f3Smrg   pMemoryProperties->memoryProperties =
20687ec681f3Smrg      physical_dev->memory_properties.memoryProperties;
20697ec681f3Smrg}
20707ec681f3Smrg
20717ec681f3Smrgvoid
20727ec681f3Smrgvn_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,
20737ec681f3Smrg                                      VkFormat format,
20747ec681f3Smrg                                      VkFormatProperties2 *pFormatProperties)
20757ec681f3Smrg{
20767ec681f3Smrg   struct vn_physical_device *physical_dev =
20777ec681f3Smrg      vn_physical_device_from_handle(physicalDevice);
20787ec681f3Smrg
20797ec681f3Smrg   /* TODO query all formats during init */
20807ec681f3Smrg   vn_call_vkGetPhysicalDeviceFormatProperties2(
20817ec681f3Smrg      physical_dev->instance, physicalDevice, format, pFormatProperties);
20827ec681f3Smrg}
20837ec681f3Smrg
20847ec681f3Smrgstruct vn_physical_device_image_format_info {
20857ec681f3Smrg   VkPhysicalDeviceImageFormatInfo2 format;
20867ec681f3Smrg   VkPhysicalDeviceExternalImageFormatInfo external;
20877ec681f3Smrg   VkImageFormatListCreateInfo list;
20887ec681f3Smrg   VkImageStencilUsageCreateInfo stencil_usage;
20897ec681f3Smrg   VkPhysicalDeviceImageDrmFormatModifierInfoEXT modifier;
20907ec681f3Smrg};
20917ec681f3Smrg
20927ec681f3Smrgstatic const VkPhysicalDeviceImageFormatInfo2 *
20937ec681f3Smrgvn_physical_device_fix_image_format_info(
20947ec681f3Smrg   struct vn_physical_device *physical_dev,
20957ec681f3Smrg   const VkPhysicalDeviceImageFormatInfo2 *info,
20967ec681f3Smrg   struct vn_physical_device_image_format_info *local_info)
20977ec681f3Smrg{
20987ec681f3Smrg   local_info->format = *info;
20997ec681f3Smrg   VkBaseOutStructure *dst = (void *)&local_info->format;
21007ec681f3Smrg
21017ec681f3Smrg   bool is_ahb = false;
21027ec681f3Smrg   /* we should generate deep copy functions... */
21037ec681f3Smrg   vk_foreach_struct_const(src, info->pNext) {
21047ec681f3Smrg      void *pnext = NULL;
21057ec681f3Smrg      switch (src->sType) {
21067ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO:
21077ec681f3Smrg         memcpy(&local_info->external, src, sizeof(local_info->external));
21087ec681f3Smrg         is_ahb =
21097ec681f3Smrg            local_info->external.handleType ==
21107ec681f3Smrg            VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
21117ec681f3Smrg         local_info->external.handleType =
21127ec681f3Smrg            physical_dev->external_memory.renderer_handle_type;
21137ec681f3Smrg         pnext = &local_info->external;
21147ec681f3Smrg         break;
21157ec681f3Smrg      case VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO:
21167ec681f3Smrg         memcpy(&local_info->list, src, sizeof(local_info->list));
21177ec681f3Smrg         pnext = &local_info->list;
21187ec681f3Smrg         break;
21197ec681f3Smrg      case VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT:
21207ec681f3Smrg         memcpy(&local_info->stencil_usage, src,
21217ec681f3Smrg                sizeof(local_info->stencil_usage));
21227ec681f3Smrg         pnext = &local_info->stencil_usage;
21237ec681f3Smrg         break;
21247ec681f3Smrg      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT:
21257ec681f3Smrg         memcpy(&local_info->modifier, src, sizeof(local_info->modifier));
21267ec681f3Smrg         pnext = &local_info->modifier;
21277ec681f3Smrg         break;
21287ec681f3Smrg      default:
21297ec681f3Smrg         break;
21307ec681f3Smrg      }
21317ec681f3Smrg
21327ec681f3Smrg      if (pnext) {
21337ec681f3Smrg         dst->pNext = pnext;
21347ec681f3Smrg         dst = pnext;
21357ec681f3Smrg      }
21367ec681f3Smrg   }
21377ec681f3Smrg
21387ec681f3Smrg   if (is_ahb) {
21397ec681f3Smrg      assert(local_info->format.tiling !=
21407ec681f3Smrg             VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT);
21417ec681f3Smrg      local_info->format.tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
21427ec681f3Smrg      if (!vn_android_get_drm_format_modifier_info(&local_info->format,
21437ec681f3Smrg                                                   &local_info->modifier))
21447ec681f3Smrg         return NULL;
21457ec681f3Smrg
21467ec681f3Smrg      dst->pNext = (void *)&local_info->modifier;
21477ec681f3Smrg      dst = dst->pNext;
21487ec681f3Smrg   }
21497ec681f3Smrg
21507ec681f3Smrg   dst->pNext = NULL;
21517ec681f3Smrg
21527ec681f3Smrg   return &local_info->format;
21537ec681f3Smrg}
21547ec681f3Smrg
21557ec681f3SmrgVkResult
21567ec681f3Smrgvn_GetPhysicalDeviceImageFormatProperties2(
21577ec681f3Smrg   VkPhysicalDevice physicalDevice,
21587ec681f3Smrg   const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo,
21597ec681f3Smrg   VkImageFormatProperties2 *pImageFormatProperties)
21607ec681f3Smrg{
21617ec681f3Smrg   struct vn_physical_device *physical_dev =
21627ec681f3Smrg      vn_physical_device_from_handle(physicalDevice);
21637ec681f3Smrg   const VkExternalMemoryHandleTypeFlagBits renderer_handle_type =
21647ec681f3Smrg      physical_dev->external_memory.renderer_handle_type;
21657ec681f3Smrg   const VkExternalMemoryHandleTypeFlags supported_handle_types =
21667ec681f3Smrg      physical_dev->external_memory.supported_handle_types;
21677ec681f3Smrg
21687ec681f3Smrg   const VkPhysicalDeviceExternalImageFormatInfo *external_info =
21697ec681f3Smrg      vk_find_struct_const(pImageFormatInfo->pNext,
21707ec681f3Smrg                           PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO);
21717ec681f3Smrg   if (external_info && !external_info->handleType)
21727ec681f3Smrg      external_info = NULL;
21737ec681f3Smrg
21747ec681f3Smrg   struct vn_physical_device_image_format_info local_info;
21757ec681f3Smrg   if (external_info) {
21767ec681f3Smrg      if (!(external_info->handleType & supported_handle_types)) {
21777ec681f3Smrg         return vn_error(physical_dev->instance,
21787ec681f3Smrg                         VK_ERROR_FORMAT_NOT_SUPPORTED);
21797ec681f3Smrg      }
21807ec681f3Smrg
21817ec681f3Smrg      if (external_info->handleType != renderer_handle_type) {
21827ec681f3Smrg         pImageFormatInfo = vn_physical_device_fix_image_format_info(
21837ec681f3Smrg            physical_dev, pImageFormatInfo, &local_info);
21847ec681f3Smrg         if (!pImageFormatInfo) {
21857ec681f3Smrg            return vn_error(physical_dev->instance,
21867ec681f3Smrg                            VK_ERROR_FORMAT_NOT_SUPPORTED);
21877ec681f3Smrg         }
21887ec681f3Smrg      }
21897ec681f3Smrg   }
21907ec681f3Smrg
21917ec681f3Smrg   VkResult result;
21927ec681f3Smrg   /* TODO per-device cache */
21937ec681f3Smrg   result = vn_call_vkGetPhysicalDeviceImageFormatProperties2(
21947ec681f3Smrg      physical_dev->instance, physicalDevice, pImageFormatInfo,
21957ec681f3Smrg      pImageFormatProperties);
21967ec681f3Smrg   if (result != VK_SUCCESS || !external_info)
21977ec681f3Smrg      return vn_result(physical_dev->instance, result);
21987ec681f3Smrg
21997ec681f3Smrg   if (external_info->handleType ==
22007ec681f3Smrg       VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID) {
22017ec681f3Smrg      VkAndroidHardwareBufferUsageANDROID *ahb_usage =
22027ec681f3Smrg         vk_find_struct(pImageFormatProperties->pNext,
22037ec681f3Smrg                        ANDROID_HARDWARE_BUFFER_USAGE_ANDROID);
22047ec681f3Smrg      if (ahb_usage) {
22057ec681f3Smrg         ahb_usage->androidHardwareBufferUsage = vn_android_get_ahb_usage(
22067ec681f3Smrg            pImageFormatInfo->usage, pImageFormatInfo->flags);
22077ec681f3Smrg      }
22087ec681f3Smrg
22097ec681f3Smrg      /* AHBs with mipmap usage will ignore this property */
22107ec681f3Smrg      pImageFormatProperties->imageFormatProperties.maxMipLevels = 1;
22117ec681f3Smrg   }
22127ec681f3Smrg
22137ec681f3Smrg   VkExternalImageFormatProperties *img_props = vk_find_struct(
22147ec681f3Smrg      pImageFormatProperties->pNext, EXTERNAL_IMAGE_FORMAT_PROPERTIES);
22157ec681f3Smrg   if (!img_props)
22167ec681f3Smrg      return VK_SUCCESS;
22177ec681f3Smrg
22187ec681f3Smrg   VkExternalMemoryProperties *mem_props =
22197ec681f3Smrg      &img_props->externalMemoryProperties;
22207ec681f3Smrg
22217ec681f3Smrg   if (external_info->handleType ==
22227ec681f3Smrg       VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID) {
22237ec681f3Smrg      /* AHB backed image requires renderer to support import bit */
22247ec681f3Smrg      if (!(mem_props->externalMemoryFeatures &
22257ec681f3Smrg            VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT))
22267ec681f3Smrg         return vn_error(physical_dev->instance,
22277ec681f3Smrg                         VK_ERROR_FORMAT_NOT_SUPPORTED);
22287ec681f3Smrg
22297ec681f3Smrg      mem_props->externalMemoryFeatures =
22307ec681f3Smrg         VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT |
22317ec681f3Smrg         VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT |
22327ec681f3Smrg         VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
22337ec681f3Smrg      mem_props->exportFromImportedHandleTypes =
22347ec681f3Smrg         VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
22357ec681f3Smrg      mem_props->compatibleHandleTypes =
22367ec681f3Smrg         VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
22377ec681f3Smrg   } else {
22387ec681f3Smrg      mem_props->compatibleHandleTypes = supported_handle_types;
22397ec681f3Smrg      mem_props->exportFromImportedHandleTypes =
22407ec681f3Smrg         (mem_props->exportFromImportedHandleTypes & renderer_handle_type)
22417ec681f3Smrg            ? supported_handle_types
22427ec681f3Smrg            : 0;
22437ec681f3Smrg   }
22447ec681f3Smrg
22457ec681f3Smrg   return VK_SUCCESS;
22467ec681f3Smrg}
22477ec681f3Smrg
22487ec681f3Smrgvoid
22497ec681f3Smrgvn_GetPhysicalDeviceSparseImageFormatProperties2(
22507ec681f3Smrg   VkPhysicalDevice physicalDevice,
22517ec681f3Smrg   const VkPhysicalDeviceSparseImageFormatInfo2 *pFormatInfo,
22527ec681f3Smrg   uint32_t *pPropertyCount,
22537ec681f3Smrg   VkSparseImageFormatProperties2 *pProperties)
22547ec681f3Smrg{
22557ec681f3Smrg   struct vn_physical_device *physical_dev =
22567ec681f3Smrg      vn_physical_device_from_handle(physicalDevice);
22577ec681f3Smrg
22587ec681f3Smrg   /* TODO per-device cache */
22597ec681f3Smrg   vn_call_vkGetPhysicalDeviceSparseImageFormatProperties2(
22607ec681f3Smrg      physical_dev->instance, physicalDevice, pFormatInfo, pPropertyCount,
22617ec681f3Smrg      pProperties);
22627ec681f3Smrg}
22637ec681f3Smrg
22647ec681f3Smrgvoid
22657ec681f3Smrgvn_GetPhysicalDeviceExternalBufferProperties(
22667ec681f3Smrg   VkPhysicalDevice physicalDevice,
22677ec681f3Smrg   const VkPhysicalDeviceExternalBufferInfo *pExternalBufferInfo,
22687ec681f3Smrg   VkExternalBufferProperties *pExternalBufferProperties)
22697ec681f3Smrg{
22707ec681f3Smrg   struct vn_physical_device *physical_dev =
22717ec681f3Smrg      vn_physical_device_from_handle(physicalDevice);
22727ec681f3Smrg   const VkExternalMemoryHandleTypeFlagBits renderer_handle_type =
22737ec681f3Smrg      physical_dev->external_memory.renderer_handle_type;
22747ec681f3Smrg   const VkExternalMemoryHandleTypeFlags supported_handle_types =
22757ec681f3Smrg      physical_dev->external_memory.supported_handle_types;
22767ec681f3Smrg   const bool is_ahb =
22777ec681f3Smrg      pExternalBufferInfo->handleType ==
22787ec681f3Smrg      VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
22797ec681f3Smrg
22807ec681f3Smrg   VkExternalMemoryProperties *props =
22817ec681f3Smrg      &pExternalBufferProperties->externalMemoryProperties;
22827ec681f3Smrg   if (!(pExternalBufferInfo->handleType & supported_handle_types)) {
22837ec681f3Smrg      props->compatibleHandleTypes = pExternalBufferInfo->handleType;
22847ec681f3Smrg      props->exportFromImportedHandleTypes = 0;
22857ec681f3Smrg      props->externalMemoryFeatures = 0;
22867ec681f3Smrg      return;
22877ec681f3Smrg   }
22887ec681f3Smrg
22897ec681f3Smrg   VkPhysicalDeviceExternalBufferInfo local_info;
22907ec681f3Smrg   if (pExternalBufferInfo->handleType != renderer_handle_type) {
22917ec681f3Smrg      local_info = *pExternalBufferInfo;
22927ec681f3Smrg      local_info.handleType = renderer_handle_type;
22937ec681f3Smrg      pExternalBufferInfo = &local_info;
22947ec681f3Smrg   }
22957ec681f3Smrg
22967ec681f3Smrg   /* TODO per-device cache */
22977ec681f3Smrg   vn_call_vkGetPhysicalDeviceExternalBufferProperties(
22987ec681f3Smrg      physical_dev->instance, physicalDevice, pExternalBufferInfo,
22997ec681f3Smrg      pExternalBufferProperties);
23007ec681f3Smrg
23017ec681f3Smrg   if (is_ahb) {
23027ec681f3Smrg      props->compatibleHandleTypes =
23037ec681f3Smrg         VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
23047ec681f3Smrg      /* AHB backed buffer requires renderer to support import bit while it
23057ec681f3Smrg       * also requires the renderer to must not advertise dedicated only bit
23067ec681f3Smrg       */
23077ec681f3Smrg      if (!(props->externalMemoryFeatures &
23087ec681f3Smrg            VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT) ||
23097ec681f3Smrg          (props->externalMemoryFeatures &
23107ec681f3Smrg           VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT)) {
23117ec681f3Smrg         props->externalMemoryFeatures = 0;
23127ec681f3Smrg         props->exportFromImportedHandleTypes = 0;
23137ec681f3Smrg         return;
23147ec681f3Smrg      }
23157ec681f3Smrg      props->externalMemoryFeatures =
23167ec681f3Smrg         VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT |
23177ec681f3Smrg         VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
23187ec681f3Smrg      props->exportFromImportedHandleTypes =
23197ec681f3Smrg         VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
23207ec681f3Smrg   } else {
23217ec681f3Smrg      props->compatibleHandleTypes = supported_handle_types;
23227ec681f3Smrg      props->exportFromImportedHandleTypes =
23237ec681f3Smrg         (props->exportFromImportedHandleTypes & renderer_handle_type)
23247ec681f3Smrg            ? supported_handle_types
23257ec681f3Smrg            : 0;
23267ec681f3Smrg   }
23277ec681f3Smrg}
23287ec681f3Smrg
23297ec681f3Smrgvoid
23307ec681f3Smrgvn_GetPhysicalDeviceExternalFenceProperties(
23317ec681f3Smrg   VkPhysicalDevice physicalDevice,
23327ec681f3Smrg   const VkPhysicalDeviceExternalFenceInfo *pExternalFenceInfo,
23337ec681f3Smrg   VkExternalFenceProperties *pExternalFenceProperties)
23347ec681f3Smrg{
23357ec681f3Smrg   struct vn_physical_device *physical_dev =
23367ec681f3Smrg      vn_physical_device_from_handle(physicalDevice);
23377ec681f3Smrg
23387ec681f3Smrg   if (pExternalFenceInfo->handleType &
23397ec681f3Smrg       physical_dev->external_fence_handles) {
23407ec681f3Smrg      pExternalFenceProperties->compatibleHandleTypes =
23417ec681f3Smrg         physical_dev->external_fence_handles;
23427ec681f3Smrg      pExternalFenceProperties->exportFromImportedHandleTypes =
23437ec681f3Smrg         physical_dev->external_fence_handles;
23447ec681f3Smrg      pExternalFenceProperties->externalFenceFeatures =
23457ec681f3Smrg         VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT |
23467ec681f3Smrg         VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT;
23477ec681f3Smrg   } else {
23487ec681f3Smrg      pExternalFenceProperties->compatibleHandleTypes =
23497ec681f3Smrg         pExternalFenceInfo->handleType;
23507ec681f3Smrg      pExternalFenceProperties->exportFromImportedHandleTypes = 0;
23517ec681f3Smrg      pExternalFenceProperties->externalFenceFeatures = 0;
23527ec681f3Smrg   }
23537ec681f3Smrg}
23547ec681f3Smrg
23557ec681f3Smrgvoid
23567ec681f3Smrgvn_GetPhysicalDeviceExternalSemaphoreProperties(
23577ec681f3Smrg   VkPhysicalDevice physicalDevice,
23587ec681f3Smrg   const VkPhysicalDeviceExternalSemaphoreInfo *pExternalSemaphoreInfo,
23597ec681f3Smrg   VkExternalSemaphoreProperties *pExternalSemaphoreProperties)
23607ec681f3Smrg{
23617ec681f3Smrg   struct vn_physical_device *physical_dev =
23627ec681f3Smrg      vn_physical_device_from_handle(physicalDevice);
23637ec681f3Smrg
23647ec681f3Smrg   const VkSemaphoreTypeCreateInfoKHR *type_info = vk_find_struct_const(
23657ec681f3Smrg      pExternalSemaphoreInfo->pNext, SEMAPHORE_TYPE_CREATE_INFO_KHR);
23667ec681f3Smrg   const VkSemaphoreType sem_type =
23677ec681f3Smrg      type_info ? type_info->semaphoreType : VK_SEMAPHORE_TYPE_BINARY;
23687ec681f3Smrg   const VkExternalSemaphoreHandleTypeFlags valid_handles =
23697ec681f3Smrg      sem_type == VK_SEMAPHORE_TYPE_BINARY
23707ec681f3Smrg         ? physical_dev->external_binary_semaphore_handles
23717ec681f3Smrg         : physical_dev->external_timeline_semaphore_handles;
23727ec681f3Smrg   if (pExternalSemaphoreInfo->handleType & valid_handles) {
23737ec681f3Smrg      pExternalSemaphoreProperties->compatibleHandleTypes = valid_handles;
23747ec681f3Smrg      pExternalSemaphoreProperties->exportFromImportedHandleTypes =
23757ec681f3Smrg         valid_handles;
23767ec681f3Smrg      pExternalSemaphoreProperties->externalSemaphoreFeatures =
23777ec681f3Smrg         VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT |
23787ec681f3Smrg         VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT;
23797ec681f3Smrg   } else {
23807ec681f3Smrg      pExternalSemaphoreProperties->compatibleHandleTypes =
23817ec681f3Smrg         pExternalSemaphoreInfo->handleType;
23827ec681f3Smrg      pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0;
23837ec681f3Smrg      pExternalSemaphoreProperties->externalSemaphoreFeatures = 0;
23847ec681f3Smrg   }
23857ec681f3Smrg}
2386