1/*
2 * Copyright 2019 Google LLC
3 * SPDX-License-Identifier: MIT
4 *
5 * based in part on anv and radv which are:
6 * Copyright © 2015 Intel Corporation
7 * Copyright © 2016 Red Hat.
8 * Copyright © 2016 Bas Nieuwenhuizen
9 */
10
11#include "vn_physical_device.h"
12
13#include <stdio.h>
14
15#include "git_sha1.h"
16#include "util/mesa-sha1.h"
17#include "venus-protocol/vn_protocol_driver_device.h"
18
19#include "vn_android.h"
20#include "vn_instance.h"
21
22#define VN_EXTENSION_TABLE_INDEX(tbl, ext)                                   \
23   ((const bool *)((const void *)(&(tbl)) +                                  \
24                   offsetof(__typeof__(tbl), ext)) -                         \
25    (tbl).extensions)
26
27#define VN_PREFIX_STYPE(stype) (VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_##stype)
28#define VN_ADD_TO_PNEXT(elem, s_type, head)                                  \
29   do {                                                                      \
30      (elem).sType = VN_PREFIX_STYPE(s_type);                                \
31      (elem).pNext = (head).pNext;                                           \
32      (head).pNext = &(elem);                                                \
33   } while (0)
34#define VN_ADD_EXT_TO_PNEXT(ext, elem, s_type, head)                         \
35   if (ext) VN_ADD_TO_PNEXT(elem, s_type, head)
36
37static void
38vn_physical_device_init_features(struct vn_physical_device *physical_dev)
39{
40   struct vn_physical_device_features *feats = &physical_dev->features;
41   struct vn_instance *instance = physical_dev->instance;
42   const struct vk_device_extension_table *exts =
43      &physical_dev->renderer_extensions;
44   VkPhysicalDeviceFeatures2 features2 = {
45      .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
46   };
47   struct {
48      /* Vulkan 1.1 */
49      VkPhysicalDevice16BitStorageFeatures sixteen_bit_storage;
50      VkPhysicalDeviceMultiviewFeatures multiview;
51      VkPhysicalDeviceVariablePointersFeatures variable_pointers;
52      VkPhysicalDeviceProtectedMemoryFeatures protected_memory;
53      VkPhysicalDeviceSamplerYcbcrConversionFeatures sampler_ycbcr_conversion;
54      VkPhysicalDeviceShaderDrawParametersFeatures shader_draw_parameters;
55
56      /* Vulkan 1.2 */
57      VkPhysicalDevice8BitStorageFeatures eight_bit_storage;
58      VkPhysicalDeviceShaderAtomicInt64Features shader_atomic_int64;
59      VkPhysicalDeviceShaderFloat16Int8Features shader_float16_int8;
60      VkPhysicalDeviceDescriptorIndexingFeatures descriptor_indexing;
61      VkPhysicalDeviceScalarBlockLayoutFeatures scalar_block_layout;
62      VkPhysicalDeviceImagelessFramebufferFeatures imageless_framebuffer;
63      VkPhysicalDeviceUniformBufferStandardLayoutFeatures
64         uniform_buffer_standard_layout;
65      VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures
66         shader_subgroup_extended_types;
67      VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures
68         separate_depth_stencil_layouts;
69      VkPhysicalDeviceHostQueryResetFeatures host_query_reset;
70      VkPhysicalDeviceTimelineSemaphoreFeatures timeline_semaphore;
71      VkPhysicalDeviceBufferDeviceAddressFeatures buffer_device_address;
72      VkPhysicalDeviceVulkanMemoryModelFeatures vulkan_memory_model;
73   } local_feats;
74
75   if (physical_dev->renderer_version >= VK_API_VERSION_1_2) {
76      VN_ADD_TO_PNEXT(feats->vulkan_1_1, VULKAN_1_1_FEATURES, features2);
77      VN_ADD_TO_PNEXT(feats->vulkan_1_2, VULKAN_1_2_FEATURES, features2);
78   } else {
79      /* Vulkan 1.1 */
80      VN_ADD_TO_PNEXT(local_feats.sixteen_bit_storage, 16BIT_STORAGE_FEATURES,
81                      features2);
82      VN_ADD_TO_PNEXT(local_feats.multiview, MULTIVIEW_FEATURES, features2);
83      VN_ADD_TO_PNEXT(local_feats.variable_pointers,
84                      VARIABLE_POINTERS_FEATURES, features2);
85      VN_ADD_TO_PNEXT(local_feats.protected_memory, PROTECTED_MEMORY_FEATURES,
86                      features2);
87      VN_ADD_TO_PNEXT(local_feats.sampler_ycbcr_conversion,
88                      SAMPLER_YCBCR_CONVERSION_FEATURES, features2);
89      VN_ADD_TO_PNEXT(local_feats.shader_draw_parameters,
90                      SHADER_DRAW_PARAMETERS_FEATURES, features2);
91
92      /* Vulkan 1.2 */
93      VN_ADD_TO_PNEXT(local_feats.eight_bit_storage, 8BIT_STORAGE_FEATURES,
94                      features2);
95      VN_ADD_TO_PNEXT(local_feats.shader_atomic_int64,
96                      SHADER_ATOMIC_INT64_FEATURES, features2);
97      VN_ADD_TO_PNEXT(local_feats.shader_float16_int8,
98                      SHADER_FLOAT16_INT8_FEATURES, features2);
99      VN_ADD_TO_PNEXT(local_feats.descriptor_indexing,
100                      DESCRIPTOR_INDEXING_FEATURES, features2);
101      VN_ADD_TO_PNEXT(local_feats.scalar_block_layout,
102                      SCALAR_BLOCK_LAYOUT_FEATURES, features2);
103      VN_ADD_TO_PNEXT(local_feats.imageless_framebuffer,
104                      IMAGELESS_FRAMEBUFFER_FEATURES, features2);
105      VN_ADD_TO_PNEXT(local_feats.uniform_buffer_standard_layout,
106                      UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES, features2);
107      VN_ADD_TO_PNEXT(local_feats.shader_subgroup_extended_types,
108                      SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES, features2);
109      VN_ADD_TO_PNEXT(local_feats.separate_depth_stencil_layouts,
110                      SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES, features2);
111      VN_ADD_TO_PNEXT(local_feats.host_query_reset, HOST_QUERY_RESET_FEATURES,
112                      features2);
113      VN_ADD_TO_PNEXT(local_feats.timeline_semaphore,
114                      TIMELINE_SEMAPHORE_FEATURES, features2);
115      VN_ADD_TO_PNEXT(local_feats.buffer_device_address,
116                      BUFFER_DEVICE_ADDRESS_FEATURES, features2);
117      VN_ADD_TO_PNEXT(local_feats.vulkan_memory_model,
118                      VULKAN_MEMORY_MODEL_FEATURES, features2);
119   }
120
121   /* Vulkan 1.3 */
122   VN_ADD_EXT_TO_PNEXT(exts->EXT_4444_formats, feats->argb_4444_formats,
123                       4444_FORMATS_FEATURES_EXT, features2);
124   VN_ADD_EXT_TO_PNEXT(exts->EXT_extended_dynamic_state,
125                       feats->extended_dynamic_state,
126                       EXTENDED_DYNAMIC_STATE_FEATURES_EXT, features2);
127   VN_ADD_EXT_TO_PNEXT(exts->EXT_extended_dynamic_state2,
128                       feats->extended_dynamic_state_2,
129                       EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT, features2);
130   VN_ADD_EXT_TO_PNEXT(exts->EXT_image_robustness, feats->image_robustness,
131                       IMAGE_ROBUSTNESS_FEATURES_EXT, features2);
132   VN_ADD_EXT_TO_PNEXT(exts->EXT_inline_uniform_block,
133                       feats->inline_uniform_block,
134                       INLINE_UNIFORM_BLOCK_FEATURES, features2);
135   VN_ADD_EXT_TO_PNEXT(exts->KHR_dynamic_rendering, feats->dynamic_rendering,
136                       DYNAMIC_RENDERING_FEATURES, features2);
137   VN_ADD_EXT_TO_PNEXT(exts->KHR_maintenance4, feats->maintenance4,
138                       MAINTENANCE_4_FEATURES, features2);
139   VN_ADD_EXT_TO_PNEXT(exts->EXT_shader_demote_to_helper_invocation,
140                       feats->shader_demote_to_helper_invocation,
141                       SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES,
142                       features2);
143
144   /* EXT */
145   VN_ADD_EXT_TO_PNEXT(exts->EXT_conditional_rendering,
146                       feats->conditional_rendering,
147                       CONDITIONAL_RENDERING_FEATURES_EXT, features2);
148   VN_ADD_EXT_TO_PNEXT(exts->EXT_custom_border_color,
149                       feats->custom_border_color,
150                       CUSTOM_BORDER_COLOR_FEATURES_EXT, features2);
151   VN_ADD_EXT_TO_PNEXT(exts->EXT_depth_clip_enable, feats->depth_clip_enable,
152                       DEPTH_CLIP_ENABLE_FEATURES_EXT, features2);
153   VN_ADD_EXT_TO_PNEXT(exts->EXT_image_view_min_lod, feats->image_view_min_lod,
154                       IMAGE_VIEW_MIN_LOD_FEATURES_EXT, features2);
155   VN_ADD_EXT_TO_PNEXT(exts->EXT_index_type_uint8, feats->index_type_uint8,
156                       INDEX_TYPE_UINT8_FEATURES_EXT, features2);
157   VN_ADD_EXT_TO_PNEXT(exts->EXT_line_rasterization,
158                       feats->line_rasterization,
159                       LINE_RASTERIZATION_FEATURES_EXT, features2);
160   VN_ADD_EXT_TO_PNEXT(exts->EXT_provoking_vertex, feats->provoking_vertex,
161                       PROVOKING_VERTEX_FEATURES_EXT, features2);
162   VN_ADD_EXT_TO_PNEXT(exts->EXT_robustness2, feats->robustness_2,
163                       ROBUSTNESS_2_FEATURES_EXT, features2);
164   VN_ADD_EXT_TO_PNEXT(exts->EXT_transform_feedback,
165                       feats->transform_feedback,
166                       TRANSFORM_FEEDBACK_FEATURES_EXT, features2);
167   VN_ADD_EXT_TO_PNEXT(exts->EXT_vertex_attribute_divisor,
168                       feats->vertex_attribute_divisor,
169                       VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT, features2);
170
171   vn_call_vkGetPhysicalDeviceFeatures2(
172      instance, vn_physical_device_to_handle(physical_dev), &features2);
173
174   feats->vulkan_1_0 = features2.features;
175
176   /* TODO allow sparse resource along with sync feedback
177    *
178    * vkQueueBindSparse relies on explicit sync primitives. To intercept the
179    * timeline semaphores within each bind info to write the feedback buffer,
180    * we have to split the call into bindInfoCount number of calls while
181    * inserting vkQueueSubmit to wait on the signal timeline semaphores before
182    * filling the feedback buffer. To intercept the fence to be signaled, we
183    * have to relocate the fence to another vkQueueSubmit call and potentially
184    * have to use an internal timeline semaphore to synchronize between them.
185    * Those would make the code overly complex, so we disable sparse binding
186    * for simplicity.
187    */
188   if (!VN_PERF(NO_FENCE_FEEDBACK)) {
189      feats->vulkan_1_0.sparseBinding = false;
190      feats->vulkan_1_0.sparseResidencyBuffer = false;
191      feats->vulkan_1_0.sparseResidencyImage2D = false;
192      feats->vulkan_1_0.sparseResidencyImage3D = false;
193      feats->vulkan_1_0.sparseResidency2Samples = false;
194      feats->vulkan_1_0.sparseResidency4Samples = false;
195      feats->vulkan_1_0.sparseResidency8Samples = false;
196      feats->vulkan_1_0.sparseResidency16Samples = false;
197      feats->vulkan_1_0.sparseResidencyAliased = false;
198   }
199
200   struct VkPhysicalDeviceVulkan11Features *vk11_feats = &feats->vulkan_1_1;
201   struct VkPhysicalDeviceVulkan12Features *vk12_feats = &feats->vulkan_1_2;
202
203   if (physical_dev->renderer_version < VK_API_VERSION_1_2) {
204      vk11_feats->storageBuffer16BitAccess =
205         local_feats.sixteen_bit_storage.storageBuffer16BitAccess;
206      vk11_feats->uniformAndStorageBuffer16BitAccess =
207         local_feats.sixteen_bit_storage.uniformAndStorageBuffer16BitAccess;
208      vk11_feats->storagePushConstant16 =
209         local_feats.sixteen_bit_storage.storagePushConstant16;
210      vk11_feats->storageInputOutput16 =
211         local_feats.sixteen_bit_storage.storageInputOutput16;
212
213      vk11_feats->multiview = local_feats.multiview.multiview;
214      vk11_feats->multiviewGeometryShader =
215         local_feats.multiview.multiviewGeometryShader;
216      vk11_feats->multiviewTessellationShader =
217         local_feats.multiview.multiviewTessellationShader;
218
219      vk11_feats->variablePointersStorageBuffer =
220         local_feats.variable_pointers.variablePointersStorageBuffer;
221      vk11_feats->variablePointers =
222         local_feats.variable_pointers.variablePointers;
223
224      vk11_feats->protectedMemory =
225         local_feats.protected_memory.protectedMemory;
226
227      vk11_feats->samplerYcbcrConversion =
228         local_feats.sampler_ycbcr_conversion.samplerYcbcrConversion;
229
230      vk11_feats->shaderDrawParameters =
231         local_feats.shader_draw_parameters.shaderDrawParameters;
232
233      vk12_feats->samplerMirrorClampToEdge =
234         exts->KHR_sampler_mirror_clamp_to_edge;
235      vk12_feats->drawIndirectCount = exts->KHR_draw_indirect_count;
236
237      if (exts->KHR_8bit_storage) {
238         vk12_feats->storageBuffer8BitAccess =
239            local_feats.eight_bit_storage.storageBuffer8BitAccess;
240         vk12_feats->uniformAndStorageBuffer8BitAccess =
241            local_feats.eight_bit_storage.uniformAndStorageBuffer8BitAccess;
242         vk12_feats->storagePushConstant8 =
243            local_feats.eight_bit_storage.storagePushConstant8;
244      }
245      if (exts->KHR_shader_atomic_int64) {
246         vk12_feats->shaderBufferInt64Atomics =
247            local_feats.shader_atomic_int64.shaderBufferInt64Atomics;
248         vk12_feats->shaderSharedInt64Atomics =
249            local_feats.shader_atomic_int64.shaderSharedInt64Atomics;
250      }
251      if (exts->KHR_shader_float16_int8) {
252         vk12_feats->shaderFloat16 =
253            local_feats.shader_float16_int8.shaderFloat16;
254         vk12_feats->shaderInt8 = local_feats.shader_float16_int8.shaderInt8;
255      }
256      if (exts->EXT_descriptor_indexing) {
257         vk12_feats->descriptorIndexing = true;
258         vk12_feats->shaderInputAttachmentArrayDynamicIndexing =
259            local_feats.descriptor_indexing
260               .shaderInputAttachmentArrayDynamicIndexing;
261         vk12_feats->shaderUniformTexelBufferArrayDynamicIndexing =
262            local_feats.descriptor_indexing
263               .shaderUniformTexelBufferArrayDynamicIndexing;
264         vk12_feats->shaderStorageTexelBufferArrayDynamicIndexing =
265            local_feats.descriptor_indexing
266               .shaderStorageTexelBufferArrayDynamicIndexing;
267         vk12_feats->shaderUniformBufferArrayNonUniformIndexing =
268            local_feats.descriptor_indexing
269               .shaderUniformBufferArrayNonUniformIndexing;
270         vk12_feats->shaderSampledImageArrayNonUniformIndexing =
271            local_feats.descriptor_indexing
272               .shaderSampledImageArrayNonUniformIndexing;
273         vk12_feats->shaderStorageBufferArrayNonUniformIndexing =
274            local_feats.descriptor_indexing
275               .shaderStorageBufferArrayNonUniformIndexing;
276         vk12_feats->shaderStorageImageArrayNonUniformIndexing =
277            local_feats.descriptor_indexing
278               .shaderStorageImageArrayNonUniformIndexing;
279         vk12_feats->shaderInputAttachmentArrayNonUniformIndexing =
280            local_feats.descriptor_indexing
281               .shaderInputAttachmentArrayNonUniformIndexing;
282         vk12_feats->shaderUniformTexelBufferArrayNonUniformIndexing =
283            local_feats.descriptor_indexing
284               .shaderUniformTexelBufferArrayNonUniformIndexing;
285         vk12_feats->shaderStorageTexelBufferArrayNonUniformIndexing =
286            local_feats.descriptor_indexing
287               .shaderStorageTexelBufferArrayNonUniformIndexing;
288         vk12_feats->descriptorBindingUniformBufferUpdateAfterBind =
289            local_feats.descriptor_indexing
290               .descriptorBindingUniformBufferUpdateAfterBind;
291         vk12_feats->descriptorBindingSampledImageUpdateAfterBind =
292            local_feats.descriptor_indexing
293               .descriptorBindingSampledImageUpdateAfterBind;
294         vk12_feats->descriptorBindingStorageImageUpdateAfterBind =
295            local_feats.descriptor_indexing
296               .descriptorBindingStorageImageUpdateAfterBind;
297         vk12_feats->descriptorBindingStorageBufferUpdateAfterBind =
298            local_feats.descriptor_indexing
299               .descriptorBindingStorageBufferUpdateAfterBind;
300         vk12_feats->descriptorBindingUniformTexelBufferUpdateAfterBind =
301            local_feats.descriptor_indexing
302               .descriptorBindingUniformTexelBufferUpdateAfterBind;
303         vk12_feats->descriptorBindingStorageTexelBufferUpdateAfterBind =
304            local_feats.descriptor_indexing
305               .descriptorBindingStorageTexelBufferUpdateAfterBind;
306         vk12_feats->descriptorBindingUpdateUnusedWhilePending =
307            local_feats.descriptor_indexing
308               .descriptorBindingUpdateUnusedWhilePending;
309         vk12_feats->descriptorBindingPartiallyBound =
310            local_feats.descriptor_indexing.descriptorBindingPartiallyBound;
311         vk12_feats->descriptorBindingVariableDescriptorCount =
312            local_feats.descriptor_indexing
313               .descriptorBindingVariableDescriptorCount;
314         vk12_feats->runtimeDescriptorArray =
315            local_feats.descriptor_indexing.runtimeDescriptorArray;
316      }
317
318      vk12_feats->samplerFilterMinmax = exts->EXT_sampler_filter_minmax;
319
320      if (exts->EXT_scalar_block_layout) {
321         vk12_feats->scalarBlockLayout =
322            local_feats.scalar_block_layout.scalarBlockLayout;
323      }
324      if (exts->KHR_imageless_framebuffer) {
325         vk12_feats->imagelessFramebuffer =
326            local_feats.imageless_framebuffer.imagelessFramebuffer;
327      }
328      if (exts->KHR_uniform_buffer_standard_layout) {
329         vk12_feats->uniformBufferStandardLayout =
330            local_feats.uniform_buffer_standard_layout
331               .uniformBufferStandardLayout;
332      }
333      if (exts->KHR_shader_subgroup_extended_types) {
334         vk12_feats->shaderSubgroupExtendedTypes =
335            local_feats.shader_subgroup_extended_types
336               .shaderSubgroupExtendedTypes;
337      }
338      if (exts->KHR_separate_depth_stencil_layouts) {
339         vk12_feats->separateDepthStencilLayouts =
340            local_feats.separate_depth_stencil_layouts
341               .separateDepthStencilLayouts;
342      }
343      if (exts->EXT_host_query_reset) {
344         vk12_feats->hostQueryReset =
345            local_feats.host_query_reset.hostQueryReset;
346      }
347      if (exts->KHR_timeline_semaphore) {
348         vk12_feats->timelineSemaphore =
349            local_feats.timeline_semaphore.timelineSemaphore;
350      }
351      if (exts->KHR_buffer_device_address) {
352         vk12_feats->bufferDeviceAddress =
353            local_feats.buffer_device_address.bufferDeviceAddress;
354         vk12_feats->bufferDeviceAddressCaptureReplay =
355            local_feats.buffer_device_address.bufferDeviceAddressCaptureReplay;
356         vk12_feats->bufferDeviceAddressMultiDevice =
357            local_feats.buffer_device_address.bufferDeviceAddressMultiDevice;
358      }
359      if (exts->KHR_vulkan_memory_model) {
360         vk12_feats->vulkanMemoryModel =
361            local_feats.vulkan_memory_model.vulkanMemoryModel;
362         vk12_feats->vulkanMemoryModelDeviceScope =
363            local_feats.vulkan_memory_model.vulkanMemoryModelDeviceScope;
364         vk12_feats->vulkanMemoryModelAvailabilityVisibilityChains =
365            local_feats.vulkan_memory_model
366               .vulkanMemoryModelAvailabilityVisibilityChains;
367      }
368
369      vk12_feats->shaderOutputViewportIndex =
370         exts->EXT_shader_viewport_index_layer;
371      vk12_feats->shaderOutputLayer = exts->EXT_shader_viewport_index_layer;
372      vk12_feats->subgroupBroadcastDynamicId = false;
373   }
374}
375
376static void
377vn_physical_device_init_uuids(struct vn_physical_device *physical_dev)
378{
379   struct vn_physical_device_properties *props = &physical_dev->properties;
380   struct VkPhysicalDeviceProperties *vk10_props = &props->vulkan_1_0;
381   struct VkPhysicalDeviceVulkan11Properties *vk11_props = &props->vulkan_1_1;
382   struct VkPhysicalDeviceVulkan12Properties *vk12_props = &props->vulkan_1_2;
383   struct mesa_sha1 sha1_ctx;
384   uint8_t sha1[SHA1_DIGEST_LENGTH];
385
386   static_assert(VK_UUID_SIZE <= SHA1_DIGEST_LENGTH, "");
387
388   _mesa_sha1_init(&sha1_ctx);
389   _mesa_sha1_update(&sha1_ctx, &vk10_props->pipelineCacheUUID,
390                     sizeof(vk10_props->pipelineCacheUUID));
391   _mesa_sha1_final(&sha1_ctx, sha1);
392
393   memcpy(vk10_props->pipelineCacheUUID, sha1, VK_UUID_SIZE);
394
395   _mesa_sha1_init(&sha1_ctx);
396   _mesa_sha1_update(&sha1_ctx, &vk10_props->vendorID,
397                     sizeof(vk10_props->vendorID));
398   _mesa_sha1_update(&sha1_ctx, &vk10_props->deviceID,
399                     sizeof(vk10_props->deviceID));
400   _mesa_sha1_final(&sha1_ctx, sha1);
401
402   memcpy(vk11_props->deviceUUID, sha1, VK_UUID_SIZE);
403
404   _mesa_sha1_init(&sha1_ctx);
405   _mesa_sha1_update(&sha1_ctx, vk12_props->driverName,
406                     strlen(vk12_props->driverName));
407   _mesa_sha1_update(&sha1_ctx, vk12_props->driverInfo,
408                     strlen(vk12_props->driverInfo));
409   _mesa_sha1_final(&sha1_ctx, sha1);
410
411   memcpy(vk11_props->driverUUID, sha1, VK_UUID_SIZE);
412
413   memset(vk11_props->deviceLUID, 0, VK_LUID_SIZE);
414   vk11_props->deviceNodeMask = 0;
415   vk11_props->deviceLUIDValid = false;
416}
417
418static void
419vn_physical_device_init_properties(struct vn_physical_device *physical_dev)
420{
421   struct vn_physical_device_properties *props = &physical_dev->properties;
422   struct vn_instance *instance = physical_dev->instance;
423   const struct vk_device_extension_table *exts =
424      &physical_dev->renderer_extensions;
425   VkPhysicalDeviceProperties2 properties2 = {
426      .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
427   };
428   struct {
429      /* Vulkan 1.1 */
430      VkPhysicalDeviceIDProperties id;
431      VkPhysicalDeviceSubgroupProperties subgroup;
432      VkPhysicalDevicePointClippingProperties point_clipping;
433      VkPhysicalDeviceMultiviewProperties multiview;
434      VkPhysicalDeviceProtectedMemoryProperties protected_memory;
435      VkPhysicalDeviceMaintenance3Properties maintenance_3;
436
437      /* Vulkan 1.2 */
438      VkPhysicalDeviceDriverProperties driver;
439      VkPhysicalDeviceFloatControlsProperties float_controls;
440      VkPhysicalDeviceDescriptorIndexingProperties descriptor_indexing;
441      VkPhysicalDeviceDepthStencilResolveProperties depth_stencil_resolve;
442      VkPhysicalDeviceSamplerFilterMinmaxProperties sampler_filter_minmax;
443      VkPhysicalDeviceTimelineSemaphoreProperties timeline_semaphore;
444   } local_props;
445
446   if (physical_dev->renderer_version >= VK_API_VERSION_1_2) {
447      VN_ADD_TO_PNEXT(props->vulkan_1_1, VULKAN_1_1_PROPERTIES, properties2);
448      VN_ADD_TO_PNEXT(props->vulkan_1_2, VULKAN_1_2_PROPERTIES, properties2);
449   } else {
450      /* Vulkan 1.1 */
451      VN_ADD_TO_PNEXT(local_props.id, ID_PROPERTIES, properties2);
452      VN_ADD_TO_PNEXT(local_props.subgroup, SUBGROUP_PROPERTIES, properties2);
453      VN_ADD_TO_PNEXT(local_props.point_clipping, POINT_CLIPPING_PROPERTIES,
454                      properties2);
455      VN_ADD_TO_PNEXT(local_props.multiview, MULTIVIEW_PROPERTIES,
456                      properties2);
457      VN_ADD_TO_PNEXT(local_props.protected_memory,
458                      PROTECTED_MEMORY_PROPERTIES, properties2);
459      VN_ADD_TO_PNEXT(local_props.maintenance_3, MAINTENANCE_3_PROPERTIES,
460                      properties2);
461
462      /* Vulkan 1.2 */
463      VN_ADD_TO_PNEXT(local_props.driver, DRIVER_PROPERTIES, properties2);
464      VN_ADD_TO_PNEXT(local_props.float_controls, FLOAT_CONTROLS_PROPERTIES,
465                      properties2);
466      VN_ADD_TO_PNEXT(local_props.descriptor_indexing,
467                      DESCRIPTOR_INDEXING_PROPERTIES, properties2);
468      VN_ADD_TO_PNEXT(local_props.depth_stencil_resolve,
469                      DEPTH_STENCIL_RESOLVE_PROPERTIES, properties2);
470      VN_ADD_TO_PNEXT(local_props.sampler_filter_minmax,
471                      SAMPLER_FILTER_MINMAX_PROPERTIES, properties2);
472      VN_ADD_TO_PNEXT(local_props.timeline_semaphore,
473                      TIMELINE_SEMAPHORE_PROPERTIES, properties2);
474   }
475
476   /* Vulkan 1.3 */
477   VN_ADD_EXT_TO_PNEXT(exts->EXT_inline_uniform_block,
478                       props->inline_uniform_block,
479                       INLINE_UNIFORM_BLOCK_PROPERTIES, properties2);
480
481   /* EXT */
482   VN_ADD_EXT_TO_PNEXT(
483      exts->EXT_conservative_rasterization, props->conservative_rasterization,
484      CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT, properties2);
485   VN_ADD_EXT_TO_PNEXT(exts->EXT_custom_border_color,
486                       props->custom_border_color,
487                       CUSTOM_BORDER_COLOR_PROPERTIES_EXT, properties2);
488   VN_ADD_EXT_TO_PNEXT(exts->EXT_line_rasterization,
489                       props->line_rasterization,
490                       LINE_RASTERIZATION_PROPERTIES_EXT, properties2);
491   VN_ADD_EXT_TO_PNEXT(exts->EXT_provoking_vertex, props->provoking_vertex,
492                       PROVOKING_VERTEX_PROPERTIES_EXT, properties2);
493   VN_ADD_EXT_TO_PNEXT(exts->EXT_robustness2, props->robustness_2,
494                       ROBUSTNESS_2_PROPERTIES_EXT, properties2);
495   VN_ADD_EXT_TO_PNEXT(exts->EXT_transform_feedback,
496                       props->transform_feedback,
497                       TRANSFORM_FEEDBACK_PROPERTIES_EXT, properties2);
498   VN_ADD_EXT_TO_PNEXT(exts->KHR_maintenance4, props->maintenance4,
499                       MAINTENANCE_4_PROPERTIES, properties2);
500   VN_ADD_EXT_TO_PNEXT(exts->EXT_vertex_attribute_divisor,
501                       props->vertex_attribute_divisor,
502                       VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT, properties2);
503
504   vn_call_vkGetPhysicalDeviceProperties2(
505      instance, vn_physical_device_to_handle(physical_dev), &properties2);
506
507   props->vulkan_1_0 = properties2.properties;
508
509   /* TODO allow sparse resource along with sync feedback */
510   if (!VN_PERF(NO_FENCE_FEEDBACK)) {
511      props->vulkan_1_0.limits.sparseAddressSpaceSize = 0;
512      props->vulkan_1_0.sparseProperties =
513         (VkPhysicalDeviceSparseProperties){ 0 };
514   }
515
516   struct VkPhysicalDeviceProperties *vk10_props = &props->vulkan_1_0;
517   struct VkPhysicalDeviceVulkan11Properties *vk11_props = &props->vulkan_1_1;
518   struct VkPhysicalDeviceVulkan12Properties *vk12_props = &props->vulkan_1_2;
519
520   if (physical_dev->renderer_version < VK_API_VERSION_1_2) {
521      memcpy(vk11_props->deviceUUID, local_props.id.deviceUUID,
522             sizeof(vk11_props->deviceUUID));
523      memcpy(vk11_props->driverUUID, local_props.id.driverUUID,
524             sizeof(vk11_props->driverUUID));
525      memcpy(vk11_props->deviceLUID, local_props.id.deviceLUID,
526             sizeof(vk11_props->deviceLUID));
527      vk11_props->deviceNodeMask = local_props.id.deviceNodeMask;
528      vk11_props->deviceLUIDValid = local_props.id.deviceLUIDValid;
529
530      vk11_props->subgroupSize = local_props.subgroup.subgroupSize;
531      vk11_props->subgroupSupportedStages =
532         local_props.subgroup.supportedStages;
533      vk11_props->subgroupSupportedOperations =
534         local_props.subgroup.supportedOperations;
535      vk11_props->subgroupQuadOperationsInAllStages =
536         local_props.subgroup.quadOperationsInAllStages;
537
538      vk11_props->pointClippingBehavior =
539         local_props.point_clipping.pointClippingBehavior;
540
541      vk11_props->maxMultiviewViewCount =
542         local_props.multiview.maxMultiviewViewCount;
543      vk11_props->maxMultiviewInstanceIndex =
544         local_props.multiview.maxMultiviewInstanceIndex;
545
546      vk11_props->protectedNoFault =
547         local_props.protected_memory.protectedNoFault;
548
549      vk11_props->maxPerSetDescriptors =
550         local_props.maintenance_3.maxPerSetDescriptors;
551      vk11_props->maxMemoryAllocationSize =
552         local_props.maintenance_3.maxMemoryAllocationSize;
553
554      if (exts->KHR_driver_properties) {
555         vk12_props->driverID = local_props.driver.driverID;
556         memcpy(vk12_props->driverName, local_props.driver.driverName,
557                VK_MAX_DRIVER_NAME_SIZE);
558         memcpy(vk12_props->driverInfo, local_props.driver.driverInfo,
559                VK_MAX_DRIVER_INFO_SIZE);
560         vk12_props->conformanceVersion =
561            local_props.driver.conformanceVersion;
562      }
563      if (exts->KHR_shader_float_controls) {
564         vk12_props->denormBehaviorIndependence =
565            local_props.float_controls.denormBehaviorIndependence;
566         vk12_props->roundingModeIndependence =
567            local_props.float_controls.roundingModeIndependence;
568         vk12_props->shaderSignedZeroInfNanPreserveFloat16 =
569            local_props.float_controls.shaderSignedZeroInfNanPreserveFloat16;
570         vk12_props->shaderSignedZeroInfNanPreserveFloat32 =
571            local_props.float_controls.shaderSignedZeroInfNanPreserveFloat32;
572         vk12_props->shaderSignedZeroInfNanPreserveFloat64 =
573            local_props.float_controls.shaderSignedZeroInfNanPreserveFloat64;
574         vk12_props->shaderDenormPreserveFloat16 =
575            local_props.float_controls.shaderDenormPreserveFloat16;
576         vk12_props->shaderDenormPreserveFloat32 =
577            local_props.float_controls.shaderDenormPreserveFloat32;
578         vk12_props->shaderDenormPreserveFloat64 =
579            local_props.float_controls.shaderDenormPreserveFloat64;
580         vk12_props->shaderDenormFlushToZeroFloat16 =
581            local_props.float_controls.shaderDenormFlushToZeroFloat16;
582         vk12_props->shaderDenormFlushToZeroFloat32 =
583            local_props.float_controls.shaderDenormFlushToZeroFloat32;
584         vk12_props->shaderDenormFlushToZeroFloat64 =
585            local_props.float_controls.shaderDenormFlushToZeroFloat64;
586         vk12_props->shaderRoundingModeRTEFloat16 =
587            local_props.float_controls.shaderRoundingModeRTEFloat16;
588         vk12_props->shaderRoundingModeRTEFloat32 =
589            local_props.float_controls.shaderRoundingModeRTEFloat32;
590         vk12_props->shaderRoundingModeRTEFloat64 =
591            local_props.float_controls.shaderRoundingModeRTEFloat64;
592         vk12_props->shaderRoundingModeRTZFloat16 =
593            local_props.float_controls.shaderRoundingModeRTZFloat16;
594         vk12_props->shaderRoundingModeRTZFloat32 =
595            local_props.float_controls.shaderRoundingModeRTZFloat32;
596         vk12_props->shaderRoundingModeRTZFloat64 =
597            local_props.float_controls.shaderRoundingModeRTZFloat64;
598      }
599      if (exts->EXT_descriptor_indexing) {
600         vk12_props->maxUpdateAfterBindDescriptorsInAllPools =
601            local_props.descriptor_indexing
602               .maxUpdateAfterBindDescriptorsInAllPools;
603         vk12_props->shaderUniformBufferArrayNonUniformIndexingNative =
604            local_props.descriptor_indexing
605               .shaderUniformBufferArrayNonUniformIndexingNative;
606         vk12_props->shaderSampledImageArrayNonUniformIndexingNative =
607            local_props.descriptor_indexing
608               .shaderSampledImageArrayNonUniformIndexingNative;
609         vk12_props->shaderStorageBufferArrayNonUniformIndexingNative =
610            local_props.descriptor_indexing
611               .shaderStorageBufferArrayNonUniformIndexingNative;
612         vk12_props->shaderStorageImageArrayNonUniformIndexingNative =
613            local_props.descriptor_indexing
614               .shaderStorageImageArrayNonUniformIndexingNative;
615         vk12_props->shaderInputAttachmentArrayNonUniformIndexingNative =
616            local_props.descriptor_indexing
617               .shaderInputAttachmentArrayNonUniformIndexingNative;
618         vk12_props->robustBufferAccessUpdateAfterBind =
619            local_props.descriptor_indexing.robustBufferAccessUpdateAfterBind;
620         vk12_props->quadDivergentImplicitLod =
621            local_props.descriptor_indexing.quadDivergentImplicitLod;
622         vk12_props->maxPerStageDescriptorUpdateAfterBindSamplers =
623            local_props.descriptor_indexing
624               .maxPerStageDescriptorUpdateAfterBindSamplers;
625         vk12_props->maxPerStageDescriptorUpdateAfterBindUniformBuffers =
626            local_props.descriptor_indexing
627               .maxPerStageDescriptorUpdateAfterBindUniformBuffers;
628         vk12_props->maxPerStageDescriptorUpdateAfterBindStorageBuffers =
629            local_props.descriptor_indexing
630               .maxPerStageDescriptorUpdateAfterBindStorageBuffers;
631         vk12_props->maxPerStageDescriptorUpdateAfterBindSampledImages =
632            local_props.descriptor_indexing
633               .maxPerStageDescriptorUpdateAfterBindSampledImages;
634         vk12_props->maxPerStageDescriptorUpdateAfterBindStorageImages =
635            local_props.descriptor_indexing
636               .maxPerStageDescriptorUpdateAfterBindStorageImages;
637         vk12_props->maxPerStageDescriptorUpdateAfterBindInputAttachments =
638            local_props.descriptor_indexing
639               .maxPerStageDescriptorUpdateAfterBindInputAttachments;
640         vk12_props->maxPerStageUpdateAfterBindResources =
641            local_props.descriptor_indexing
642               .maxPerStageUpdateAfterBindResources;
643         vk12_props->maxDescriptorSetUpdateAfterBindSamplers =
644            local_props.descriptor_indexing
645               .maxDescriptorSetUpdateAfterBindSamplers;
646         vk12_props->maxDescriptorSetUpdateAfterBindUniformBuffers =
647            local_props.descriptor_indexing
648               .maxDescriptorSetUpdateAfterBindUniformBuffers;
649         vk12_props->maxDescriptorSetUpdateAfterBindUniformBuffersDynamic =
650            local_props.descriptor_indexing
651               .maxDescriptorSetUpdateAfterBindUniformBuffersDynamic;
652         vk12_props->maxDescriptorSetUpdateAfterBindStorageBuffers =
653            local_props.descriptor_indexing
654               .maxDescriptorSetUpdateAfterBindStorageBuffers;
655         vk12_props->maxDescriptorSetUpdateAfterBindStorageBuffersDynamic =
656            local_props.descriptor_indexing
657               .maxDescriptorSetUpdateAfterBindStorageBuffersDynamic;
658         vk12_props->maxDescriptorSetUpdateAfterBindSampledImages =
659            local_props.descriptor_indexing
660               .maxDescriptorSetUpdateAfterBindSampledImages;
661         vk12_props->maxDescriptorSetUpdateAfterBindStorageImages =
662            local_props.descriptor_indexing
663               .maxDescriptorSetUpdateAfterBindStorageImages;
664         vk12_props->maxDescriptorSetUpdateAfterBindInputAttachments =
665            local_props.descriptor_indexing
666               .maxDescriptorSetUpdateAfterBindInputAttachments;
667      }
668      if (exts->KHR_depth_stencil_resolve) {
669         vk12_props->supportedDepthResolveModes =
670            local_props.depth_stencil_resolve.supportedDepthResolveModes;
671         vk12_props->supportedStencilResolveModes =
672            local_props.depth_stencil_resolve.supportedStencilResolveModes;
673         vk12_props->independentResolveNone =
674            local_props.depth_stencil_resolve.independentResolveNone;
675         vk12_props->independentResolve =
676            local_props.depth_stencil_resolve.independentResolve;
677      }
678      if (exts->EXT_sampler_filter_minmax) {
679         vk12_props->filterMinmaxSingleComponentFormats =
680            local_props.sampler_filter_minmax
681               .filterMinmaxSingleComponentFormats;
682         vk12_props->filterMinmaxImageComponentMapping =
683            local_props.sampler_filter_minmax
684               .filterMinmaxImageComponentMapping;
685      }
686      if (exts->KHR_timeline_semaphore) {
687         vk12_props->maxTimelineSemaphoreValueDifference =
688            local_props.timeline_semaphore.maxTimelineSemaphoreValueDifference;
689      }
690
691      vk12_props->framebufferIntegerColorSampleCounts = VK_SAMPLE_COUNT_1_BIT;
692   }
693
694   const uint32_t version_override = vk_get_version_override();
695   if (version_override) {
696      vk10_props->apiVersion = version_override;
697   } else {
698      /* cap the advertised api version */
699      uint32_t ver = MIN3(vk10_props->apiVersion, VN_MAX_API_VERSION,
700                          instance->renderer->info.vk_xml_version);
701      if (VK_VERSION_PATCH(ver) > VK_VERSION_PATCH(vk10_props->apiVersion)) {
702         ver = ver - VK_VERSION_PATCH(ver) +
703               VK_VERSION_PATCH(vk10_props->apiVersion);
704      }
705      vk10_props->apiVersion = ver;
706   }
707
708   vk10_props->driverVersion = vk_get_driver_version();
709
710   char device_name[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE];
711   int device_name_len =
712      snprintf(device_name, sizeof(device_name), "Virtio-GPU Venus (%s)",
713               vk10_props->deviceName);
714   if (device_name_len >= VK_MAX_PHYSICAL_DEVICE_NAME_SIZE) {
715      memcpy(device_name + VK_MAX_PHYSICAL_DEVICE_NAME_SIZE - 5, "...)", 4);
716      device_name_len = VK_MAX_PHYSICAL_DEVICE_NAME_SIZE - 1;
717   }
718   memcpy(vk10_props->deviceName, device_name, device_name_len + 1);
719
720   vk12_props->driverID = VK_DRIVER_ID_MESA_VENUS;
721   snprintf(vk12_props->driverName, sizeof(vk12_props->driverName), "venus");
722   snprintf(vk12_props->driverInfo, sizeof(vk12_props->driverInfo),
723            "Mesa " PACKAGE_VERSION MESA_GIT_SHA1);
724   vk12_props->conformanceVersion = (VkConformanceVersion){
725      .major = 1,
726      .minor = 2,
727      .subminor = 7,
728      .patch = 1,
729   };
730
731   vn_physical_device_init_uuids(physical_dev);
732}
733
734static VkResult
735vn_physical_device_init_queue_family_properties(
736   struct vn_physical_device *physical_dev)
737{
738   struct vn_instance *instance = physical_dev->instance;
739   const VkAllocationCallbacks *alloc = &instance->base.base.alloc;
740   uint32_t count;
741
742   vn_call_vkGetPhysicalDeviceQueueFamilyProperties2(
743      instance, vn_physical_device_to_handle(physical_dev), &count, NULL);
744
745   VkQueueFamilyProperties2 *props =
746      vk_alloc(alloc, sizeof(*props) * count, VN_DEFAULT_ALIGN,
747               VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
748   if (!props)
749      return VK_ERROR_OUT_OF_HOST_MEMORY;
750
751   for (uint32_t i = 0; i < count; i++) {
752      props[i].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2;
753      props[i].pNext = NULL;
754   }
755   vn_call_vkGetPhysicalDeviceQueueFamilyProperties2(
756      instance, vn_physical_device_to_handle(physical_dev), &count, props);
757
758   physical_dev->queue_family_properties = props;
759   physical_dev->queue_family_count = count;
760
761   return VK_SUCCESS;
762}
763
764static void
765vn_physical_device_init_memory_properties(
766   struct vn_physical_device *physical_dev)
767{
768   struct vn_instance *instance = physical_dev->instance;
769
770   physical_dev->memory_properties.sType =
771      VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2;
772
773   vn_call_vkGetPhysicalDeviceMemoryProperties2(
774      instance, vn_physical_device_to_handle(physical_dev),
775      &physical_dev->memory_properties);
776
777   if (!instance->renderer->info.has_cache_management) {
778      VkPhysicalDeviceMemoryProperties *props =
779         &physical_dev->memory_properties.memoryProperties;
780      const uint32_t host_flags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
781                                  VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
782                                  VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
783
784      for (uint32_t i = 0; i < props->memoryTypeCount; i++) {
785         const bool coherent = props->memoryTypes[i].propertyFlags &
786                               VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
787         if (!coherent)
788            props->memoryTypes[i].propertyFlags &= ~host_flags;
789      }
790   }
791}
792
793static void
794vn_physical_device_init_external_memory(
795   struct vn_physical_device *physical_dev)
796{
797   /* When a renderer VkDeviceMemory is exportable, we can create a
798    * vn_renderer_bo from it.  The vn_renderer_bo can be freely exported as an
799    * opaque fd or a dma-buf.
800    *
801    * However, to know if a rendender VkDeviceMemory is exportable, we have to
802    * start from VkPhysicalDeviceExternalImageFormatInfo (or
803    * vkGetPhysicalDeviceExternalBufferProperties).  That means we need to
804    * know the handle type that the renderer will use to make those queries.
805    *
806    * XXX We also assume that a vn_renderer_bo can be created as long as the
807    * renderer VkDeviceMemory has a mappable memory type.  That is plain
808    * wrong.  It is impossible to fix though until some new extension is
809    * created and supported by the driver, and that the renderer switches to
810    * the extension.
811    */
812
813   if (!physical_dev->instance->renderer->info.has_dma_buf_import)
814      return;
815
816   /* TODO We assume the renderer uses dma-bufs here.  This should be
817    * negotiated by adding a new function to VK_MESA_venus_protocol.
818    */
819   if (physical_dev->renderer_extensions.EXT_external_memory_dma_buf) {
820      physical_dev->external_memory.renderer_handle_type =
821         VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
822
823#ifdef ANDROID
824      physical_dev->external_memory.supported_handle_types =
825         VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
826#else
827      physical_dev->external_memory.supported_handle_types =
828         VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT |
829         VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
830#endif
831   }
832}
833
834static void
835vn_physical_device_init_external_fence_handles(
836   struct vn_physical_device *physical_dev)
837{
838   /* The current code manipulates the host-side VkFence directly.
839    * vkWaitForFences is translated to repeated vkGetFenceStatus.
840    *
841    * External fence is not possible currently.  At best, we could cheat by
842    * translating vkGetFenceFdKHR to vkWaitForFences and returning -1, when
843    * the handle type is sync file.
844    *
845    * We would like to create a vn_renderer_sync from a host-side VkFence,
846    * similar to how a vn_renderer_bo is created from a host-side
847    * VkDeviceMemory.  That would require kernel support and tons of works on
848    * the host side.  If we had that, and we kept both the vn_renderer_sync
849    * and the host-side VkFence in sync, we would have the freedom to use
850    * either of them depending on the occasions, and support external fences
851    * and idle waiting.
852    */
853   physical_dev->external_fence_handles = 0;
854
855#ifdef ANDROID
856   if (physical_dev->instance->experimental.globalFencing) {
857      physical_dev->external_fence_handles =
858         VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT;
859   }
860#endif
861}
862
863static void
864vn_physical_device_init_external_semaphore_handles(
865   struct vn_physical_device *physical_dev)
866{
867   /* The current code manipulates the host-side VkSemaphore directly.  It
868    * works very well for binary semaphores because there is no CPU operation.
869    * But for timeline semaphores, the situation is similar to that of fences.
870    * vkWaitSemaphores is translated to repeated vkGetSemaphoreCounterValue.
871    *
872    * External semaphore is not possible currently.  We could cheat when the
873    * semaphore is binary and the handle type is sync file, but that would
874    * require associating a fence with the semaphore and doing vkWaitForFences
875    * in vkGetSemaphoreFdKHR.
876    *
877    * We would like to create a vn_renderer_sync from a host-side VkSemaphore,
878    * similar to how a vn_renderer_bo is created from a host-side
879    * VkDeviceMemory.  The reasoning is the same as that for fences.
880    * Additionally, we would like the sync file exported from the
881    * vn_renderer_sync to carry the necessary information to identify the
882    * host-side VkSemaphore.  That would allow the consumers to wait on the
883    * host side rather than the guest side.
884    */
885   physical_dev->external_binary_semaphore_handles = 0;
886   physical_dev->external_timeline_semaphore_handles = 0;
887
888#ifdef ANDROID
889   if (physical_dev->instance->experimental.globalFencing) {
890      physical_dev->external_binary_semaphore_handles =
891         VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
892   }
893#endif
894}
895
896static void
897vn_physical_device_get_native_extensions(
898   const struct vn_physical_device *physical_dev,
899   struct vk_device_extension_table *exts)
900{
901   const struct vn_instance *instance = physical_dev->instance;
902   const struct vk_device_extension_table *renderer_exts =
903      &physical_dev->renderer_extensions;
904
905   memset(exts, 0, sizeof(*exts));
906
907   /* see vn_physical_device_init_external_memory */
908   const bool can_external_mem = renderer_exts->EXT_external_memory_dma_buf &&
909                                 instance->renderer->info.has_dma_buf_import;
910
911#ifdef ANDROID
912   if (can_external_mem && renderer_exts->EXT_image_drm_format_modifier &&
913       renderer_exts->EXT_queue_family_foreign &&
914       instance->experimental.memoryResourceAllocationSize == VK_TRUE) {
915      exts->ANDROID_external_memory_android_hardware_buffer = true;
916      exts->ANDROID_native_buffer = true;
917   }
918
919   /* we have a very poor implementation */
920   if (instance->experimental.globalFencing) {
921      exts->KHR_external_fence_fd = true;
922      exts->KHR_external_semaphore_fd = true;
923   }
924#else /* ANDROID */
925   if (can_external_mem) {
926      exts->KHR_external_memory_fd = true;
927      exts->EXT_external_memory_dma_buf = true;
928   }
929
930#ifdef VN_USE_WSI_PLATFORM
931   /* XXX we should check for EXT_queue_family_foreign */
932   exts->KHR_incremental_present = true;
933   exts->KHR_swapchain = true;
934   exts->KHR_swapchain_mutable_format = true;
935#endif
936#endif /* ANDROID */
937
938   exts->EXT_physical_device_drm = true;
939}
940
941static void
942vn_physical_device_get_passthrough_extensions(
943   const struct vn_physical_device *physical_dev,
944   struct vk_device_extension_table *exts)
945{
946   *exts = (struct vk_device_extension_table){
947      /* promoted to VK_VERSION_1_1 */
948      .KHR_16bit_storage = true,
949      .KHR_bind_memory2 = true,
950      .KHR_dedicated_allocation = true,
951      .KHR_descriptor_update_template = true,
952      .KHR_device_group = true,
953      .KHR_external_fence = true,
954      .KHR_external_memory = true,
955      .KHR_external_semaphore = true,
956      .KHR_get_memory_requirements2 = true,
957      .KHR_maintenance1 = true,
958      .KHR_maintenance2 = true,
959      .KHR_maintenance3 = true,
960      .KHR_multiview = true,
961      .KHR_relaxed_block_layout = true,
962      .KHR_sampler_ycbcr_conversion = true,
963      .KHR_shader_draw_parameters = true,
964      .KHR_storage_buffer_storage_class = true,
965      .KHR_variable_pointers = true,
966
967      /* promoted to VK_VERSION_1_2 */
968      .KHR_8bit_storage = true,
969      .KHR_buffer_device_address = true,
970      .KHR_create_renderpass2 = true,
971      .KHR_depth_stencil_resolve = true,
972      .KHR_draw_indirect_count = true,
973#ifndef ANDROID
974      /* xxx remove the #ifndef after venus has a driver id */
975      .KHR_driver_properties = true,
976#endif
977      .KHR_image_format_list = true,
978      .KHR_imageless_framebuffer = true,
979      .KHR_sampler_mirror_clamp_to_edge = true,
980      .KHR_separate_depth_stencil_layouts = true,
981      .KHR_shader_atomic_int64 = true,
982      .KHR_shader_float16_int8 = true,
983      .KHR_shader_float_controls = true,
984      .KHR_shader_subgroup_extended_types = true,
985      .KHR_spirv_1_4 = true,
986      .KHR_timeline_semaphore = true,
987      .KHR_uniform_buffer_standard_layout = true,
988      .KHR_vulkan_memory_model = true,
989      .EXT_descriptor_indexing = true,
990      .EXT_host_query_reset = true,
991      .EXT_sampler_filter_minmax = true,
992      .EXT_scalar_block_layout = true,
993      .EXT_separate_stencil_usage = true,
994      .EXT_shader_viewport_index_layer = true,
995
996      /* promoted to VK_VERSION_1_3 */
997      .EXT_4444_formats = true,
998      .EXT_extended_dynamic_state = true,
999      .EXT_extended_dynamic_state2 = true,
1000      .EXT_image_robustness = true,
1001      .EXT_inline_uniform_block = true,
1002      .EXT_shader_demote_to_helper_invocation = true,
1003      .KHR_copy_commands2 = true,
1004      .KHR_dynamic_rendering = true,
1005      .KHR_maintenance4 = true,
1006
1007      /* EXT */
1008      .EXT_calibrated_timestamps = true,
1009      .EXT_conditional_rendering = true,
1010      .EXT_conservative_rasterization = true,
1011      .EXT_custom_border_color = true,
1012      .EXT_depth_clip_enable = true,
1013#ifndef ANDROID
1014      .EXT_image_drm_format_modifier = true,
1015#endif
1016      .EXT_image_view_min_lod = true,
1017      .EXT_index_type_uint8 = true,
1018      .EXT_line_rasterization = true,
1019      .EXT_provoking_vertex = true,
1020      .EXT_queue_family_foreign = true,
1021      .EXT_robustness2 = true,
1022      .EXT_shader_stencil_export = true,
1023      .EXT_transform_feedback = true,
1024      .EXT_vertex_attribute_divisor = true,
1025   };
1026}
1027
1028static void
1029vn_physical_device_init_supported_extensions(
1030   struct vn_physical_device *physical_dev)
1031{
1032   struct vk_device_extension_table native;
1033   struct vk_device_extension_table passthrough;
1034   vn_physical_device_get_native_extensions(physical_dev, &native);
1035   vn_physical_device_get_passthrough_extensions(physical_dev, &passthrough);
1036
1037   for (uint32_t i = 0; i < VK_DEVICE_EXTENSION_COUNT; i++) {
1038      const VkExtensionProperties *props = &vk_device_extensions[i];
1039
1040#ifdef ANDROID
1041      if (!vk_android_allowed_device_extensions.extensions[i])
1042         continue;
1043#endif
1044
1045      if (native.extensions[i]) {
1046         physical_dev->base.base.supported_extensions.extensions[i] = true;
1047         physical_dev->extension_spec_versions[i] = props->specVersion;
1048      } else if (passthrough.extensions[i] &&
1049                 physical_dev->renderer_extensions.extensions[i]) {
1050         physical_dev->base.base.supported_extensions.extensions[i] = true;
1051         physical_dev->extension_spec_versions[i] = MIN2(
1052            physical_dev->extension_spec_versions[i], props->specVersion);
1053      }
1054   }
1055
1056   /* override VK_ANDROID_native_buffer spec version */
1057   if (native.ANDROID_native_buffer) {
1058      const uint32_t index =
1059         VN_EXTENSION_TABLE_INDEX(native, ANDROID_native_buffer);
1060      physical_dev->extension_spec_versions[index] =
1061         VN_ANDROID_NATIVE_BUFFER_SPEC_VERSION;
1062   }
1063}
1064
1065static VkResult
1066vn_physical_device_init_renderer_extensions(
1067   struct vn_physical_device *physical_dev)
1068{
1069   struct vn_instance *instance = physical_dev->instance;
1070   const VkAllocationCallbacks *alloc = &instance->base.base.alloc;
1071
1072   /* get renderer extensions */
1073   uint32_t count;
1074   VkResult result = vn_call_vkEnumerateDeviceExtensionProperties(
1075      instance, vn_physical_device_to_handle(physical_dev), NULL, &count,
1076      NULL);
1077   if (result != VK_SUCCESS)
1078      return result;
1079
1080   VkExtensionProperties *exts = NULL;
1081   if (count) {
1082      exts = vk_alloc(alloc, sizeof(*exts) * count, VN_DEFAULT_ALIGN,
1083                      VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
1084      if (!exts)
1085         return VK_ERROR_OUT_OF_HOST_MEMORY;
1086
1087      result = vn_call_vkEnumerateDeviceExtensionProperties(
1088         instance, vn_physical_device_to_handle(physical_dev), NULL, &count,
1089         exts);
1090      if (result < VK_SUCCESS) {
1091         vk_free(alloc, exts);
1092         return result;
1093      }
1094   }
1095
1096   physical_dev->extension_spec_versions =
1097      vk_zalloc(alloc,
1098                sizeof(*physical_dev->extension_spec_versions) *
1099                   VK_DEVICE_EXTENSION_COUNT,
1100                VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
1101   if (!physical_dev->extension_spec_versions) {
1102      vk_free(alloc, exts);
1103      return VK_ERROR_OUT_OF_HOST_MEMORY;
1104   }
1105
1106   for (uint32_t i = 0; i < VK_DEVICE_EXTENSION_COUNT; i++) {
1107      const VkExtensionProperties *props = &vk_device_extensions[i];
1108      for (uint32_t j = 0; j < count; j++) {
1109         if (strcmp(props->extensionName, exts[j].extensionName))
1110            continue;
1111
1112         /* check encoder support */
1113         const uint32_t enc_ext_spec_version =
1114            vn_extension_get_spec_version(props->extensionName);
1115         if (!enc_ext_spec_version)
1116            continue;
1117
1118         physical_dev->renderer_extensions.extensions[i] = true;
1119         physical_dev->extension_spec_versions[i] =
1120            MIN2(exts[j].specVersion, enc_ext_spec_version);
1121
1122         break;
1123      }
1124   }
1125
1126   vk_free(alloc, exts);
1127
1128   return VK_SUCCESS;
1129}
1130
1131static VkResult
1132vn_physical_device_init_renderer_version(
1133   struct vn_physical_device *physical_dev)
1134{
1135   struct vn_instance *instance = physical_dev->instance;
1136
1137   /*
1138    * We either check and enable VK_KHR_get_physical_device_properties2, or we
1139    * must use vkGetPhysicalDeviceProperties to get the device-level version.
1140    */
1141   VkPhysicalDeviceProperties props;
1142   vn_call_vkGetPhysicalDeviceProperties(
1143      instance, vn_physical_device_to_handle(physical_dev), &props);
1144   if (props.apiVersion < VN_MIN_RENDERER_VERSION) {
1145      if (VN_DEBUG(INIT)) {
1146         vn_log(instance, "%s has unsupported renderer device version %d.%d",
1147                props.deviceName, VK_VERSION_MAJOR(props.apiVersion),
1148                VK_VERSION_MINOR(props.apiVersion));
1149      }
1150      return VK_ERROR_INITIALIZATION_FAILED;
1151   }
1152
1153   /* device version for internal use is capped */
1154   physical_dev->renderer_version =
1155      MIN3(props.apiVersion, instance->renderer_api_version,
1156           instance->renderer->info.vk_xml_version);
1157
1158   return VK_SUCCESS;
1159}
1160
1161static VkResult
1162vn_physical_device_init(struct vn_physical_device *physical_dev)
1163{
1164   struct vn_instance *instance = physical_dev->instance;
1165   const VkAllocationCallbacks *alloc = &instance->base.base.alloc;
1166   VkResult result;
1167
1168   result = vn_physical_device_init_renderer_extensions(physical_dev);
1169   if (result != VK_SUCCESS)
1170      return result;
1171
1172   vn_physical_device_init_supported_extensions(physical_dev);
1173
1174   /* TODO query all caps with minimal round trips */
1175   vn_physical_device_init_features(physical_dev);
1176   vn_physical_device_init_properties(physical_dev);
1177
1178   result = vn_physical_device_init_queue_family_properties(physical_dev);
1179   if (result != VK_SUCCESS)
1180      goto fail;
1181
1182   vn_physical_device_init_memory_properties(physical_dev);
1183
1184   vn_physical_device_init_external_memory(physical_dev);
1185   vn_physical_device_init_external_fence_handles(physical_dev);
1186   vn_physical_device_init_external_semaphore_handles(physical_dev);
1187
1188   result = vn_wsi_init(physical_dev);
1189   if (result != VK_SUCCESS)
1190      goto fail;
1191
1192   simple_mtx_init(&physical_dev->format_update_mutex, mtx_plain);
1193   util_sparse_array_init(&physical_dev->format_properties,
1194                          sizeof(struct vn_format_properties_entry), 64);
1195
1196   return VK_SUCCESS;
1197
1198fail:
1199   vk_free(alloc, physical_dev->extension_spec_versions);
1200   vk_free(alloc, physical_dev->queue_family_properties);
1201   return result;
1202}
1203
1204void
1205vn_physical_device_fini(struct vn_physical_device *physical_dev)
1206{
1207   struct vn_instance *instance = physical_dev->instance;
1208   const VkAllocationCallbacks *alloc = &instance->base.base.alloc;
1209
1210   simple_mtx_destroy(&physical_dev->format_update_mutex);
1211   util_sparse_array_finish(&physical_dev->format_properties);
1212
1213   vn_wsi_fini(physical_dev);
1214   vk_free(alloc, physical_dev->extension_spec_versions);
1215   vk_free(alloc, physical_dev->queue_family_properties);
1216
1217   vn_physical_device_base_fini(&physical_dev->base);
1218}
1219
1220static struct vn_physical_device *
1221find_physical_device(struct vn_physical_device *physical_devs,
1222                     uint32_t count,
1223                     vn_object_id id)
1224{
1225   for (uint32_t i = 0; i < count; i++) {
1226      if (physical_devs[i].base.id == id)
1227         return &physical_devs[i];
1228   }
1229   return NULL;
1230}
1231
1232static VkResult
1233vn_instance_enumerate_physical_device_groups_locked(
1234   struct vn_instance *instance,
1235   struct vn_physical_device *physical_devs,
1236   uint32_t physical_dev_count)
1237{
1238   VkInstance instance_handle = vn_instance_to_handle(instance);
1239   const VkAllocationCallbacks *alloc = &instance->base.base.alloc;
1240   VkResult result;
1241
1242   uint32_t count;
1243   result = vn_call_vkEnumeratePhysicalDeviceGroups(instance, instance_handle,
1244                                                    &count, NULL);
1245   if (result != VK_SUCCESS)
1246      return result;
1247
1248   VkPhysicalDeviceGroupProperties *groups =
1249      vk_alloc(alloc, sizeof(*groups) * count, VN_DEFAULT_ALIGN,
1250               VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
1251   if (!groups)
1252      return VK_ERROR_OUT_OF_HOST_MEMORY;
1253
1254   /* VkPhysicalDeviceGroupProperties::physicalDevices is treated as an input
1255    * by the encoder.  Each VkPhysicalDevice must point to a valid object.
1256    * Each object must have id 0 as well, which is interpreted as a query by
1257    * the renderer.
1258    */
1259   struct vn_physical_device_base *temp_objs =
1260      vk_zalloc(alloc, sizeof(*temp_objs) * VK_MAX_DEVICE_GROUP_SIZE * count,
1261                VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
1262   if (!temp_objs) {
1263      vk_free(alloc, groups);
1264      return VK_ERROR_OUT_OF_HOST_MEMORY;
1265   }
1266
1267   for (uint32_t i = 0; i < count; i++) {
1268      VkPhysicalDeviceGroupProperties *group = &groups[i];
1269      group->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES;
1270      group->pNext = NULL;
1271      for (uint32_t j = 0; j < VK_MAX_DEVICE_GROUP_SIZE; j++) {
1272         struct vn_physical_device_base *temp_obj =
1273            &temp_objs[VK_MAX_DEVICE_GROUP_SIZE * i + j];
1274         temp_obj->base.base.type = VK_OBJECT_TYPE_PHYSICAL_DEVICE;
1275         group->physicalDevices[j] = (VkPhysicalDevice)temp_obj;
1276      }
1277   }
1278
1279   result = vn_call_vkEnumeratePhysicalDeviceGroups(instance, instance_handle,
1280                                                    &count, groups);
1281   if (result != VK_SUCCESS) {
1282      vk_free(alloc, groups);
1283      vk_free(alloc, temp_objs);
1284      return result;
1285   }
1286
1287   /* fix VkPhysicalDeviceGroupProperties::physicalDevices to point to
1288    * physical_devs and discard unsupported ones
1289    */
1290   uint32_t supported_count = 0;
1291   for (uint32_t i = 0; i < count; i++) {
1292      VkPhysicalDeviceGroupProperties *group = &groups[i];
1293
1294      uint32_t group_physical_dev_count = 0;
1295      for (uint32_t j = 0; j < group->physicalDeviceCount; j++) {
1296         struct vn_physical_device_base *temp_obj =
1297            (struct vn_physical_device_base *)group->physicalDevices[j];
1298         struct vn_physical_device *physical_dev = find_physical_device(
1299            physical_devs, physical_dev_count, temp_obj->id);
1300         if (!physical_dev)
1301            continue;
1302
1303         group->physicalDevices[group_physical_dev_count++] =
1304            vn_physical_device_to_handle(physical_dev);
1305      }
1306
1307      group->physicalDeviceCount = group_physical_dev_count;
1308      if (!group->physicalDeviceCount)
1309         continue;
1310
1311      if (supported_count < i)
1312         groups[supported_count] = *group;
1313      supported_count++;
1314   }
1315
1316   count = supported_count;
1317   assert(count);
1318
1319   vk_free(alloc, temp_objs);
1320
1321   instance->physical_device.groups = groups;
1322   instance->physical_device.group_count = count;
1323
1324   return VK_SUCCESS;
1325}
1326
1327static VkResult
1328enumerate_physical_devices(struct vn_instance *instance,
1329                           struct vn_physical_device **out_physical_devs,
1330                           uint32_t *out_count)
1331{
1332   const VkAllocationCallbacks *alloc = &instance->base.base.alloc;
1333   struct vn_physical_device *physical_devs = NULL;
1334   VkPhysicalDevice *handles = NULL;
1335   VkResult result;
1336
1337   uint32_t count;
1338   result = vn_call_vkEnumeratePhysicalDevices(
1339      instance, vn_instance_to_handle(instance), &count, NULL);
1340   if (result != VK_SUCCESS || !count)
1341      return result;
1342
1343   physical_devs =
1344      vk_zalloc(alloc, sizeof(*physical_devs) * count, VN_DEFAULT_ALIGN,
1345                VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
1346   if (!physical_devs)
1347      return VK_ERROR_OUT_OF_HOST_MEMORY;
1348
1349   handles = vk_alloc(alloc, sizeof(*handles) * count, VN_DEFAULT_ALIGN,
1350                      VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
1351   if (!handles) {
1352      vk_free(alloc, physical_devs);
1353      return VK_ERROR_OUT_OF_HOST_MEMORY;
1354   }
1355
1356   for (uint32_t i = 0; i < count; i++) {
1357      struct vn_physical_device *physical_dev = &physical_devs[i];
1358
1359      struct vk_physical_device_dispatch_table dispatch_table;
1360      vk_physical_device_dispatch_table_from_entrypoints(
1361         &dispatch_table, &vn_physical_device_entrypoints, true);
1362      vk_physical_device_dispatch_table_from_entrypoints(
1363         &dispatch_table, &wsi_physical_device_entrypoints, false);
1364      result = vn_physical_device_base_init(
1365         &physical_dev->base, &instance->base, NULL, &dispatch_table);
1366      if (result != VK_SUCCESS) {
1367         count = i;
1368         goto fail;
1369      }
1370
1371      physical_dev->instance = instance;
1372
1373      handles[i] = vn_physical_device_to_handle(physical_dev);
1374   }
1375
1376   result = vn_call_vkEnumeratePhysicalDevices(
1377      instance, vn_instance_to_handle(instance), &count, handles);
1378   if (result != VK_SUCCESS)
1379      goto fail;
1380
1381   vk_free(alloc, handles);
1382   *out_physical_devs = physical_devs;
1383   *out_count = count;
1384
1385   return VK_SUCCESS;
1386
1387fail:
1388   for (uint32_t i = 0; i < count; i++)
1389      vn_physical_device_base_fini(&physical_devs[i].base);
1390   vk_free(alloc, physical_devs);
1391   vk_free(alloc, handles);
1392   return result;
1393}
1394
1395static uint32_t
1396filter_physical_devices(struct vn_physical_device *physical_devs,
1397                        uint32_t count)
1398{
1399   uint32_t supported_count = 0;
1400   for (uint32_t i = 0; i < count; i++) {
1401      struct vn_physical_device *physical_dev = &physical_devs[i];
1402
1403      /* init renderer version and discard unsupported devices */
1404      VkResult result =
1405         vn_physical_device_init_renderer_version(physical_dev);
1406      if (result != VK_SUCCESS) {
1407         vn_physical_device_base_fini(&physical_dev->base);
1408         continue;
1409      }
1410
1411      if (supported_count < i)
1412         physical_devs[supported_count] = *physical_dev;
1413      supported_count++;
1414   }
1415
1416   return supported_count;
1417}
1418
1419static VkResult
1420vn_instance_enumerate_physical_devices_and_groups(struct vn_instance *instance)
1421{
1422   const VkAllocationCallbacks *alloc = &instance->base.base.alloc;
1423   struct vn_physical_device *physical_devs = NULL;
1424   uint32_t count = 0;
1425   VkResult result = VK_SUCCESS;
1426
1427   mtx_lock(&instance->physical_device.mutex);
1428
1429   if (instance->physical_device.initialized)
1430      goto unlock;
1431   instance->physical_device.initialized = true;
1432
1433   result = enumerate_physical_devices(instance, &physical_devs, &count);
1434   if (result != VK_SUCCESS)
1435      goto unlock;
1436
1437   count = filter_physical_devices(physical_devs, count);
1438   if (!count) {
1439      vk_free(alloc, physical_devs);
1440      goto unlock;
1441   }
1442
1443   /* fully initialize physical devices */
1444   for (uint32_t i = 0; i < count; i++) {
1445      struct vn_physical_device *physical_dev = &physical_devs[i];
1446
1447      result = vn_physical_device_init(physical_dev);
1448      if (result != VK_SUCCESS) {
1449         for (uint32_t j = 0; j < i; j++)
1450            vn_physical_device_fini(&physical_devs[j]);
1451         for (uint32_t j = i; j < count; j++)
1452            vn_physical_device_base_fini(&physical_devs[j].base);
1453         vk_free(alloc, physical_devs);
1454         goto unlock;
1455      }
1456   }
1457
1458   result = vn_instance_enumerate_physical_device_groups_locked(
1459      instance, physical_devs, count);
1460   if (result != VK_SUCCESS) {
1461      for (uint32_t i = 0; i < count; i++)
1462         vn_physical_device_fini(&physical_devs[i]);
1463      vk_free(alloc, physical_devs);
1464      goto unlock;
1465   }
1466
1467   instance->physical_device.devices = physical_devs;
1468   instance->physical_device.device_count = count;
1469
1470unlock:
1471   mtx_unlock(&instance->physical_device.mutex);
1472   return result;
1473}
1474
1475/* physical device commands */
1476
1477VkResult
1478vn_EnumeratePhysicalDevices(VkInstance _instance,
1479                            uint32_t *pPhysicalDeviceCount,
1480                            VkPhysicalDevice *pPhysicalDevices)
1481{
1482   struct vn_instance *instance = vn_instance_from_handle(_instance);
1483
1484   VkResult result =
1485      vn_instance_enumerate_physical_devices_and_groups(instance);
1486   if (result != VK_SUCCESS)
1487      return vn_error(instance, result);
1488
1489   VK_OUTARRAY_MAKE_TYPED(VkPhysicalDevice, out, pPhysicalDevices, pPhysicalDeviceCount);
1490   for (uint32_t i = 0; i < instance->physical_device.device_count; i++) {
1491      vk_outarray_append_typed(VkPhysicalDevice, &out, physical_dev) {
1492         *physical_dev = vn_physical_device_to_handle(
1493            &instance->physical_device.devices[i]);
1494      }
1495   }
1496
1497   return vk_outarray_status(&out);
1498}
1499
1500VkResult
1501vn_EnumeratePhysicalDeviceGroups(
1502   VkInstance _instance,
1503   uint32_t *pPhysicalDeviceGroupCount,
1504   VkPhysicalDeviceGroupProperties *pPhysicalDeviceGroupProperties)
1505{
1506   struct vn_instance *instance = vn_instance_from_handle(_instance);
1507
1508   VkResult result =
1509      vn_instance_enumerate_physical_devices_and_groups(instance);
1510   if (result != VK_SUCCESS)
1511      return vn_error(instance, result);
1512
1513   VK_OUTARRAY_MAKE_TYPED(VkPhysicalDeviceGroupProperties, out,
1514                          pPhysicalDeviceGroupProperties,
1515                          pPhysicalDeviceGroupCount);
1516   for (uint32_t i = 0; i < instance->physical_device.group_count; i++) {
1517      vk_outarray_append_typed(VkPhysicalDeviceGroupProperties, &out, props) {
1518         *props = instance->physical_device.groups[i];
1519      }
1520   }
1521
1522   return vk_outarray_status(&out);
1523}
1524
1525VkResult
1526vn_EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
1527                                      const char *pLayerName,
1528                                      uint32_t *pPropertyCount,
1529                                      VkExtensionProperties *pProperties)
1530{
1531   struct vn_physical_device *physical_dev =
1532      vn_physical_device_from_handle(physicalDevice);
1533
1534   if (pLayerName)
1535      return vn_error(physical_dev->instance, VK_ERROR_LAYER_NOT_PRESENT);
1536
1537   VK_OUTARRAY_MAKE_TYPED(VkExtensionProperties, out, pProperties, pPropertyCount);
1538   for (uint32_t i = 0; i < VK_DEVICE_EXTENSION_COUNT; i++) {
1539      if (physical_dev->base.base.supported_extensions.extensions[i]) {
1540         vk_outarray_append_typed(VkExtensionProperties, &out, prop) {
1541            *prop = vk_device_extensions[i];
1542            prop->specVersion = physical_dev->extension_spec_versions[i];
1543         }
1544      }
1545   }
1546
1547   return vk_outarray_status(&out);
1548}
1549
1550VkResult
1551vn_EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,
1552                                  uint32_t *pPropertyCount,
1553                                  VkLayerProperties *pProperties)
1554{
1555   *pPropertyCount = 0;
1556   return VK_SUCCESS;
1557}
1558
1559static struct vn_format_properties_entry *
1560vn_physical_device_get_format_properties(
1561   struct vn_physical_device *physical_dev, VkFormat format)
1562{
1563   return util_sparse_array_get(&physical_dev->format_properties, format);
1564}
1565
1566static void
1567vn_physical_device_add_format_properties(
1568   struct vn_physical_device *physical_dev,
1569   struct vn_format_properties_entry *entry,
1570   const VkFormatProperties *props)
1571{
1572   simple_mtx_lock(&physical_dev->format_update_mutex);
1573   if (!entry->valid) {
1574      entry->properties = *props;
1575      entry->valid = true;
1576   }
1577   simple_mtx_unlock(&physical_dev->format_update_mutex);
1578}
1579
1580void
1581vn_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,
1582                              VkPhysicalDeviceFeatures2 *pFeatures)
1583{
1584   struct vn_physical_device *physical_dev =
1585      vn_physical_device_from_handle(physicalDevice);
1586   const struct vn_physical_device_features *feats = &physical_dev->features;
1587   const struct VkPhysicalDeviceVulkan11Features *vk11_feats =
1588      &feats->vulkan_1_1;
1589   const struct VkPhysicalDeviceVulkan12Features *vk12_feats =
1590      &feats->vulkan_1_2;
1591   union {
1592      VkBaseOutStructure *pnext;
1593
1594      VkPhysicalDeviceFeatures2 *features2;
1595      VkPhysicalDeviceVulkan11Features *vulkan_1_1;
1596      VkPhysicalDeviceVulkan12Features *vulkan_1_2;
1597
1598      /* Vulkan 1.1 */
1599      VkPhysicalDevice16BitStorageFeatures *sixteen_bit_storage;
1600      VkPhysicalDeviceMultiviewFeatures *multiview;
1601      VkPhysicalDeviceVariablePointersFeatures *variable_pointers;
1602      VkPhysicalDeviceProtectedMemoryFeatures *protected_memory;
1603      VkPhysicalDeviceSamplerYcbcrConversionFeatures *sampler_ycbcr_conversion;
1604      VkPhysicalDeviceShaderDrawParametersFeatures *shader_draw_parameters;
1605
1606      /* Vulkan 1.2 */
1607      VkPhysicalDevice8BitStorageFeatures *eight_bit_storage;
1608      VkPhysicalDeviceShaderAtomicInt64Features *shader_atomic_int64;
1609      VkPhysicalDeviceShaderFloat16Int8Features *shader_float16_int8;
1610      VkPhysicalDeviceDescriptorIndexingFeatures *descriptor_indexing;
1611      VkPhysicalDeviceScalarBlockLayoutFeatures *scalar_block_layout;
1612      VkPhysicalDeviceImagelessFramebufferFeatures *imageless_framebuffer;
1613      VkPhysicalDeviceUniformBufferStandardLayoutFeatures
1614         *uniform_buffer_standard_layout;
1615      VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures
1616         *shader_subgroup_extended_types;
1617      VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures
1618         *separate_depth_stencil_layouts;
1619      VkPhysicalDeviceHostQueryResetFeatures *host_query_reset;
1620      VkPhysicalDeviceTimelineSemaphoreFeatures *timeline_semaphore;
1621      VkPhysicalDeviceBufferDeviceAddressFeatures *buffer_device_address;
1622      VkPhysicalDeviceVulkanMemoryModelFeatures *vulkan_memory_model;
1623
1624      /* Vulkan 1.3 */
1625      VkPhysicalDevice4444FormatsFeaturesEXT *argb_4444_formats;
1626      VkPhysicalDeviceDynamicRenderingFeatures *dynamic_rendering;
1627      VkPhysicalDeviceExtendedDynamicStateFeaturesEXT *extended_dynamic_state;
1628      VkPhysicalDeviceExtendedDynamicState2FeaturesEXT
1629         *extended_dynamic_state2;
1630      VkPhysicalDeviceImageRobustnessFeatures *image_robustness;
1631      VkPhysicalDeviceInlineUniformBlockFeatures *inline_uniform_block;
1632      VkPhysicalDeviceMaintenance4Features *maintenance4;
1633      VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures
1634         *shader_demote_to_helper_invocation;
1635
1636      /* EXT */
1637      VkPhysicalDeviceConditionalRenderingFeaturesEXT *conditional_rendering;
1638      VkPhysicalDeviceCustomBorderColorFeaturesEXT *custom_border_color;
1639      VkPhysicalDeviceDepthClipEnableFeaturesEXT *depth_clip_enable;
1640      VkPhysicalDeviceIndexTypeUint8FeaturesEXT *index_type_uint8;
1641      VkPhysicalDeviceLineRasterizationFeaturesEXT *line_rasterization;
1642      VkPhysicalDeviceProvokingVertexFeaturesEXT *provoking_vertex;
1643      VkPhysicalDeviceRobustness2FeaturesEXT *robustness_2;
1644      VkPhysicalDeviceTransformFeedbackFeaturesEXT *transform_feedback;
1645      VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT
1646         *vertex_attribute_divisor;
1647   } u;
1648
1649   u.pnext = (VkBaseOutStructure *)pFeatures;
1650   while (u.pnext) {
1651      void *saved = u.pnext->pNext;
1652      switch (u.pnext->sType) {
1653      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2:
1654         u.features2->features = feats->vulkan_1_0;
1655         break;
1656      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES:
1657         *u.vulkan_1_1 = *vk11_feats;
1658         break;
1659      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES:
1660         *u.vulkan_1_2 = *vk12_feats;
1661         break;
1662
1663      /* Vulkan 1.1 */
1664      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES:
1665         u.sixteen_bit_storage->storageBuffer16BitAccess =
1666            vk11_feats->storageBuffer16BitAccess;
1667         u.sixteen_bit_storage->uniformAndStorageBuffer16BitAccess =
1668            vk11_feats->uniformAndStorageBuffer16BitAccess;
1669         u.sixteen_bit_storage->storagePushConstant16 =
1670            vk11_feats->storagePushConstant16;
1671         u.sixteen_bit_storage->storageInputOutput16 =
1672            vk11_feats->storageInputOutput16;
1673         break;
1674      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES:
1675         u.multiview->multiview = vk11_feats->multiview;
1676         u.multiview->multiviewGeometryShader =
1677            vk11_feats->multiviewGeometryShader;
1678         u.multiview->multiviewTessellationShader =
1679            vk11_feats->multiviewTessellationShader;
1680         break;
1681      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES:
1682         u.variable_pointers->variablePointersStorageBuffer =
1683            vk11_feats->variablePointersStorageBuffer;
1684         u.variable_pointers->variablePointers = vk11_feats->variablePointers;
1685         break;
1686      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES:
1687         u.protected_memory->protectedMemory = vk11_feats->protectedMemory;
1688         break;
1689      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES:
1690         u.sampler_ycbcr_conversion->samplerYcbcrConversion =
1691            vk11_feats->samplerYcbcrConversion;
1692         break;
1693      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES:
1694         u.shader_draw_parameters->shaderDrawParameters =
1695            vk11_feats->shaderDrawParameters;
1696         break;
1697
1698      /* Vulkan 1.2 */
1699      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES:
1700         u.eight_bit_storage->storageBuffer8BitAccess =
1701            vk12_feats->storageBuffer8BitAccess;
1702         u.eight_bit_storage->uniformAndStorageBuffer8BitAccess =
1703            vk12_feats->uniformAndStorageBuffer8BitAccess;
1704         u.eight_bit_storage->storagePushConstant8 =
1705            vk12_feats->storagePushConstant8;
1706         break;
1707      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES:
1708         u.shader_atomic_int64->shaderBufferInt64Atomics =
1709            vk12_feats->shaderBufferInt64Atomics;
1710         u.shader_atomic_int64->shaderSharedInt64Atomics =
1711            vk12_feats->shaderSharedInt64Atomics;
1712         break;
1713      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES:
1714         u.shader_float16_int8->shaderFloat16 = vk12_feats->shaderFloat16;
1715         u.shader_float16_int8->shaderInt8 = vk12_feats->shaderInt8;
1716         break;
1717      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES:
1718         u.descriptor_indexing->shaderInputAttachmentArrayDynamicIndexing =
1719            vk12_feats->shaderInputAttachmentArrayDynamicIndexing;
1720         u.descriptor_indexing->shaderUniformTexelBufferArrayDynamicIndexing =
1721            vk12_feats->shaderUniformTexelBufferArrayDynamicIndexing;
1722         u.descriptor_indexing->shaderStorageTexelBufferArrayDynamicIndexing =
1723            vk12_feats->shaderStorageTexelBufferArrayDynamicIndexing;
1724         u.descriptor_indexing->shaderUniformBufferArrayNonUniformIndexing =
1725            vk12_feats->shaderUniformBufferArrayNonUniformIndexing;
1726         u.descriptor_indexing->shaderSampledImageArrayNonUniformIndexing =
1727            vk12_feats->shaderSampledImageArrayNonUniformIndexing;
1728         u.descriptor_indexing->shaderStorageBufferArrayNonUniformIndexing =
1729            vk12_feats->shaderStorageBufferArrayNonUniformIndexing;
1730         u.descriptor_indexing->shaderStorageImageArrayNonUniformIndexing =
1731            vk12_feats->shaderStorageImageArrayNonUniformIndexing;
1732         u.descriptor_indexing->shaderInputAttachmentArrayNonUniformIndexing =
1733            vk12_feats->shaderInputAttachmentArrayNonUniformIndexing;
1734         u.descriptor_indexing
1735            ->shaderUniformTexelBufferArrayNonUniformIndexing =
1736            vk12_feats->shaderUniformTexelBufferArrayNonUniformIndexing;
1737         u.descriptor_indexing
1738            ->shaderStorageTexelBufferArrayNonUniformIndexing =
1739            vk12_feats->shaderStorageTexelBufferArrayNonUniformIndexing;
1740         u.descriptor_indexing->descriptorBindingUniformBufferUpdateAfterBind =
1741            vk12_feats->descriptorBindingUniformBufferUpdateAfterBind;
1742         u.descriptor_indexing->descriptorBindingSampledImageUpdateAfterBind =
1743            vk12_feats->descriptorBindingSampledImageUpdateAfterBind;
1744         u.descriptor_indexing->descriptorBindingStorageImageUpdateAfterBind =
1745            vk12_feats->descriptorBindingStorageImageUpdateAfterBind;
1746         u.descriptor_indexing->descriptorBindingStorageBufferUpdateAfterBind =
1747            vk12_feats->descriptorBindingStorageBufferUpdateAfterBind;
1748         u.descriptor_indexing
1749            ->descriptorBindingUniformTexelBufferUpdateAfterBind =
1750            vk12_feats->descriptorBindingUniformTexelBufferUpdateAfterBind;
1751         u.descriptor_indexing
1752            ->descriptorBindingStorageTexelBufferUpdateAfterBind =
1753            vk12_feats->descriptorBindingStorageTexelBufferUpdateAfterBind;
1754         u.descriptor_indexing->descriptorBindingUpdateUnusedWhilePending =
1755            vk12_feats->descriptorBindingUpdateUnusedWhilePending;
1756         u.descriptor_indexing->descriptorBindingPartiallyBound =
1757            vk12_feats->descriptorBindingPartiallyBound;
1758         u.descriptor_indexing->descriptorBindingVariableDescriptorCount =
1759            vk12_feats->descriptorBindingVariableDescriptorCount;
1760         u.descriptor_indexing->runtimeDescriptorArray =
1761            vk12_feats->runtimeDescriptorArray;
1762         break;
1763      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES:
1764         u.scalar_block_layout->scalarBlockLayout =
1765            vk12_feats->scalarBlockLayout;
1766         break;
1767      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES:
1768         u.imageless_framebuffer->imagelessFramebuffer =
1769            vk12_feats->imagelessFramebuffer;
1770         break;
1771      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES:
1772         u.uniform_buffer_standard_layout->uniformBufferStandardLayout =
1773            vk12_feats->uniformBufferStandardLayout;
1774         break;
1775      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES:
1776         u.shader_subgroup_extended_types->shaderSubgroupExtendedTypes =
1777            vk12_feats->shaderSubgroupExtendedTypes;
1778         break;
1779      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES:
1780         u.separate_depth_stencil_layouts->separateDepthStencilLayouts =
1781            vk12_feats->separateDepthStencilLayouts;
1782         break;
1783      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES:
1784         u.host_query_reset->hostQueryReset = vk12_feats->hostQueryReset;
1785         break;
1786      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES:
1787         u.timeline_semaphore->timelineSemaphore =
1788            vk12_feats->timelineSemaphore;
1789         break;
1790      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES:
1791         u.buffer_device_address->bufferDeviceAddress =
1792            vk12_feats->bufferDeviceAddress;
1793         u.buffer_device_address->bufferDeviceAddressCaptureReplay =
1794            vk12_feats->bufferDeviceAddressCaptureReplay;
1795         u.buffer_device_address->bufferDeviceAddressMultiDevice =
1796            vk12_feats->bufferDeviceAddressMultiDevice;
1797         break;
1798      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES:
1799         u.vulkan_memory_model->vulkanMemoryModel =
1800            vk12_feats->vulkanMemoryModel;
1801         u.vulkan_memory_model->vulkanMemoryModelDeviceScope =
1802            vk12_feats->vulkanMemoryModelDeviceScope;
1803         u.vulkan_memory_model->vulkanMemoryModelAvailabilityVisibilityChains =
1804            vk12_feats->vulkanMemoryModelAvailabilityVisibilityChains;
1805         break;
1806
1807      /* Vulkan 1.3 */
1808      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT:
1809         *u.argb_4444_formats = feats->argb_4444_formats;
1810         break;
1811      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES:
1812         *u.dynamic_rendering = feats->dynamic_rendering;
1813         break;
1814      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT:
1815         *u.extended_dynamic_state = feats->extended_dynamic_state;
1816         break;
1817      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT:
1818         *u.extended_dynamic_state2 = feats->extended_dynamic_state_2;
1819         break;
1820      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES:
1821         *u.image_robustness = feats->image_robustness;
1822         break;
1823      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES:
1824         *u.inline_uniform_block = feats->inline_uniform_block;
1825         break;
1826      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES:
1827         *u.shader_demote_to_helper_invocation =
1828            feats->shader_demote_to_helper_invocation;
1829         break;
1830
1831      /* EXT */
1832      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT:
1833         *u.conditional_rendering = feats->conditional_rendering;
1834         break;
1835      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT:
1836         *u.custom_border_color = feats->custom_border_color;
1837         break;
1838      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT:
1839         *u.depth_clip_enable = feats->depth_clip_enable;
1840         break;
1841      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT:
1842         *u.index_type_uint8 = feats->index_type_uint8;
1843         break;
1844      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT:
1845         *u.line_rasterization = feats->line_rasterization;
1846         break;
1847      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT:
1848         *u.provoking_vertex = feats->provoking_vertex;
1849         break;
1850      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT:
1851         *u.robustness_2 = feats->robustness_2;
1852         break;
1853      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT:
1854         *u.transform_feedback = feats->transform_feedback;
1855         break;
1856      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT:
1857         *u.vertex_attribute_divisor = feats->vertex_attribute_divisor;
1858         break;
1859      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES:
1860         *u.maintenance4 = feats->maintenance4;
1861         break;
1862      default:
1863         break;
1864      }
1865
1866      u.pnext->pNext = saved;
1867      u.pnext = u.pnext->pNext;
1868   }
1869}
1870
1871void
1872vn_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
1873                                VkPhysicalDeviceProperties2 *pProperties)
1874{
1875   struct vn_physical_device *physical_dev =
1876      vn_physical_device_from_handle(physicalDevice);
1877   const struct vn_physical_device_properties *props =
1878      &physical_dev->properties;
1879   const struct VkPhysicalDeviceVulkan11Properties *vk11_props =
1880      &props->vulkan_1_1;
1881   const struct VkPhysicalDeviceVulkan12Properties *vk12_props =
1882      &props->vulkan_1_2;
1883   union {
1884      VkBaseOutStructure *pnext;
1885
1886      VkPhysicalDeviceProperties2 *properties2;
1887      VkPhysicalDeviceVulkan11Properties *vulkan_1_1;
1888      VkPhysicalDeviceVulkan12Properties *vulkan_1_2;
1889
1890      /* Vulkan 1.1 */
1891      VkPhysicalDeviceIDProperties *id;
1892      VkPhysicalDeviceSubgroupProperties *subgroup;
1893      VkPhysicalDevicePointClippingProperties *point_clipping;
1894      VkPhysicalDeviceMultiviewProperties *multiview;
1895      VkPhysicalDeviceProtectedMemoryProperties *protected_memory;
1896      VkPhysicalDeviceMaintenance3Properties *maintenance_3;
1897
1898      /* Vulkan 1.2 */
1899      VkPhysicalDeviceDriverProperties *driver;
1900      VkPhysicalDeviceFloatControlsProperties *float_controls;
1901      VkPhysicalDeviceDescriptorIndexingProperties *descriptor_indexing;
1902      VkPhysicalDeviceDepthStencilResolveProperties *depth_stencil_resolve;
1903      VkPhysicalDeviceSamplerFilterMinmaxProperties *sampler_filter_minmax;
1904      VkPhysicalDeviceTimelineSemaphoreProperties *timeline_semaphore;
1905
1906      /* Vulkan 1.3 */
1907      VkPhysicalDeviceInlineUniformBlockProperties *inline_uniform_block;
1908
1909      /* EXT */
1910      VkPhysicalDeviceConservativeRasterizationPropertiesEXT
1911         *conservative_rasterization;
1912      VkPhysicalDeviceCustomBorderColorPropertiesEXT *custom_border_color;
1913      VkPhysicalDeviceDrmPropertiesEXT *drm;
1914      VkPhysicalDeviceLineRasterizationPropertiesEXT *line_rasterization;
1915      VkPhysicalDevicePCIBusInfoPropertiesEXT *pci_bus_info;
1916      VkPhysicalDevicePresentationPropertiesANDROID *presentation_properties;
1917      VkPhysicalDeviceProvokingVertexPropertiesEXT *provoking_vertex;
1918      VkPhysicalDeviceRobustness2PropertiesEXT *robustness_2;
1919      VkPhysicalDeviceMaintenance4Properties *maintenance4;
1920      VkPhysicalDeviceTransformFeedbackPropertiesEXT *transform_feedback;
1921      VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT
1922         *vertex_attribute_divisor;
1923   } u;
1924
1925   u.pnext = (VkBaseOutStructure *)pProperties;
1926   while (u.pnext) {
1927      void *saved = u.pnext->pNext;
1928      switch ((int32_t)u.pnext->sType) {
1929      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2:
1930         u.properties2->properties = props->vulkan_1_0;
1931         break;
1932      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES:
1933         *u.vulkan_1_1 = *vk11_props;
1934         break;
1935      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES:
1936         *u.vulkan_1_2 = *vk12_props;
1937         break;
1938
1939      /* Vulkan 1.1 */
1940      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES:
1941         memcpy(u.id->deviceUUID, vk11_props->deviceUUID,
1942                sizeof(vk11_props->deviceUUID));
1943         memcpy(u.id->driverUUID, vk11_props->driverUUID,
1944                sizeof(vk11_props->driverUUID));
1945         memcpy(u.id->deviceLUID, vk11_props->deviceLUID,
1946                sizeof(vk11_props->deviceLUID));
1947         u.id->deviceNodeMask = vk11_props->deviceNodeMask;
1948         u.id->deviceLUIDValid = vk11_props->deviceLUIDValid;
1949         break;
1950      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES:
1951         u.subgroup->subgroupSize = vk11_props->subgroupSize;
1952         u.subgroup->supportedStages = vk11_props->subgroupSupportedStages;
1953         u.subgroup->supportedOperations =
1954            vk11_props->subgroupSupportedOperations;
1955         u.subgroup->quadOperationsInAllStages =
1956            vk11_props->subgroupQuadOperationsInAllStages;
1957         break;
1958      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES:
1959         u.point_clipping->pointClippingBehavior =
1960            vk11_props->pointClippingBehavior;
1961         break;
1962      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES:
1963         u.multiview->maxMultiviewViewCount =
1964            vk11_props->maxMultiviewViewCount;
1965         u.multiview->maxMultiviewInstanceIndex =
1966            vk11_props->maxMultiviewInstanceIndex;
1967         break;
1968      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES:
1969         u.protected_memory->protectedNoFault = vk11_props->protectedNoFault;
1970         break;
1971      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES:
1972         u.maintenance_3->maxPerSetDescriptors =
1973            vk11_props->maxPerSetDescriptors;
1974         u.maintenance_3->maxMemoryAllocationSize =
1975            vk11_props->maxMemoryAllocationSize;
1976         break;
1977
1978      /* Vulkan 1.2 */
1979      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES:
1980         u.driver->driverID = vk12_props->driverID;
1981         memcpy(u.driver->driverName, vk12_props->driverName,
1982                sizeof(vk12_props->driverName));
1983         memcpy(u.driver->driverInfo, vk12_props->driverInfo,
1984                sizeof(vk12_props->driverInfo));
1985         u.driver->conformanceVersion = vk12_props->conformanceVersion;
1986         break;
1987      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES:
1988         u.float_controls->denormBehaviorIndependence =
1989            vk12_props->denormBehaviorIndependence;
1990         u.float_controls->roundingModeIndependence =
1991            vk12_props->roundingModeIndependence;
1992         u.float_controls->shaderSignedZeroInfNanPreserveFloat16 =
1993            vk12_props->shaderSignedZeroInfNanPreserveFloat16;
1994         u.float_controls->shaderSignedZeroInfNanPreserveFloat32 =
1995            vk12_props->shaderSignedZeroInfNanPreserveFloat32;
1996         u.float_controls->shaderSignedZeroInfNanPreserveFloat64 =
1997            vk12_props->shaderSignedZeroInfNanPreserveFloat64;
1998         u.float_controls->shaderDenormPreserveFloat16 =
1999            vk12_props->shaderDenormPreserveFloat16;
2000         u.float_controls->shaderDenormPreserveFloat32 =
2001            vk12_props->shaderDenormPreserveFloat32;
2002         u.float_controls->shaderDenormPreserveFloat64 =
2003            vk12_props->shaderDenormPreserveFloat64;
2004         u.float_controls->shaderDenormFlushToZeroFloat16 =
2005            vk12_props->shaderDenormFlushToZeroFloat16;
2006         u.float_controls->shaderDenormFlushToZeroFloat32 =
2007            vk12_props->shaderDenormFlushToZeroFloat32;
2008         u.float_controls->shaderDenormFlushToZeroFloat64 =
2009            vk12_props->shaderDenormFlushToZeroFloat64;
2010         u.float_controls->shaderRoundingModeRTEFloat16 =
2011            vk12_props->shaderRoundingModeRTEFloat16;
2012         u.float_controls->shaderRoundingModeRTEFloat32 =
2013            vk12_props->shaderRoundingModeRTEFloat32;
2014         u.float_controls->shaderRoundingModeRTEFloat64 =
2015            vk12_props->shaderRoundingModeRTEFloat64;
2016         u.float_controls->shaderRoundingModeRTZFloat16 =
2017            vk12_props->shaderRoundingModeRTZFloat16;
2018         u.float_controls->shaderRoundingModeRTZFloat32 =
2019            vk12_props->shaderRoundingModeRTZFloat32;
2020         u.float_controls->shaderRoundingModeRTZFloat64 =
2021            vk12_props->shaderRoundingModeRTZFloat64;
2022         break;
2023      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES:
2024         u.descriptor_indexing->maxUpdateAfterBindDescriptorsInAllPools =
2025            vk12_props->maxUpdateAfterBindDescriptorsInAllPools;
2026         u.descriptor_indexing
2027            ->shaderUniformBufferArrayNonUniformIndexingNative =
2028            vk12_props->shaderUniformBufferArrayNonUniformIndexingNative;
2029         u.descriptor_indexing
2030            ->shaderSampledImageArrayNonUniformIndexingNative =
2031            vk12_props->shaderSampledImageArrayNonUniformIndexingNative;
2032         u.descriptor_indexing
2033            ->shaderStorageBufferArrayNonUniformIndexingNative =
2034            vk12_props->shaderStorageBufferArrayNonUniformIndexingNative;
2035         u.descriptor_indexing
2036            ->shaderStorageImageArrayNonUniformIndexingNative =
2037            vk12_props->shaderStorageImageArrayNonUniformIndexingNative;
2038         u.descriptor_indexing
2039            ->shaderInputAttachmentArrayNonUniformIndexingNative =
2040            vk12_props->shaderInputAttachmentArrayNonUniformIndexingNative;
2041         u.descriptor_indexing->robustBufferAccessUpdateAfterBind =
2042            vk12_props->robustBufferAccessUpdateAfterBind;
2043         u.descriptor_indexing->quadDivergentImplicitLod =
2044            vk12_props->quadDivergentImplicitLod;
2045         u.descriptor_indexing->maxPerStageDescriptorUpdateAfterBindSamplers =
2046            vk12_props->maxPerStageDescriptorUpdateAfterBindSamplers;
2047         u.descriptor_indexing
2048            ->maxPerStageDescriptorUpdateAfterBindUniformBuffers =
2049            vk12_props->maxPerStageDescriptorUpdateAfterBindUniformBuffers;
2050         u.descriptor_indexing
2051            ->maxPerStageDescriptorUpdateAfterBindStorageBuffers =
2052            vk12_props->maxPerStageDescriptorUpdateAfterBindStorageBuffers;
2053         u.descriptor_indexing
2054            ->maxPerStageDescriptorUpdateAfterBindSampledImages =
2055            vk12_props->maxPerStageDescriptorUpdateAfterBindSampledImages;
2056         u.descriptor_indexing
2057            ->maxPerStageDescriptorUpdateAfterBindStorageImages =
2058            vk12_props->maxPerStageDescriptorUpdateAfterBindStorageImages;
2059         u.descriptor_indexing
2060            ->maxPerStageDescriptorUpdateAfterBindInputAttachments =
2061            vk12_props->maxPerStageDescriptorUpdateAfterBindInputAttachments;
2062         u.descriptor_indexing->maxPerStageUpdateAfterBindResources =
2063            vk12_props->maxPerStageUpdateAfterBindResources;
2064         u.descriptor_indexing->maxDescriptorSetUpdateAfterBindSamplers =
2065            vk12_props->maxDescriptorSetUpdateAfterBindSamplers;
2066         u.descriptor_indexing->maxDescriptorSetUpdateAfterBindUniformBuffers =
2067            vk12_props->maxDescriptorSetUpdateAfterBindUniformBuffers;
2068         u.descriptor_indexing
2069            ->maxDescriptorSetUpdateAfterBindUniformBuffersDynamic =
2070            vk12_props->maxDescriptorSetUpdateAfterBindUniformBuffersDynamic;
2071         u.descriptor_indexing->maxDescriptorSetUpdateAfterBindStorageBuffers =
2072            vk12_props->maxDescriptorSetUpdateAfterBindStorageBuffers;
2073         u.descriptor_indexing
2074            ->maxDescriptorSetUpdateAfterBindStorageBuffersDynamic =
2075            vk12_props->maxDescriptorSetUpdateAfterBindStorageBuffersDynamic;
2076         u.descriptor_indexing->maxDescriptorSetUpdateAfterBindSampledImages =
2077            vk12_props->maxDescriptorSetUpdateAfterBindSampledImages;
2078         u.descriptor_indexing->maxDescriptorSetUpdateAfterBindStorageImages =
2079            vk12_props->maxDescriptorSetUpdateAfterBindStorageImages;
2080         u.descriptor_indexing
2081            ->maxDescriptorSetUpdateAfterBindInputAttachments =
2082            vk12_props->maxDescriptorSetUpdateAfterBindInputAttachments;
2083         break;
2084      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES:
2085         u.depth_stencil_resolve->supportedDepthResolveModes =
2086            vk12_props->supportedDepthResolveModes;
2087         u.depth_stencil_resolve->supportedStencilResolveModes =
2088            vk12_props->supportedStencilResolveModes;
2089         u.depth_stencil_resolve->independentResolveNone =
2090            vk12_props->independentResolveNone;
2091         u.depth_stencil_resolve->independentResolve =
2092            vk12_props->independentResolve;
2093         break;
2094      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES:
2095         u.sampler_filter_minmax->filterMinmaxSingleComponentFormats =
2096            vk12_props->filterMinmaxSingleComponentFormats;
2097         u.sampler_filter_minmax->filterMinmaxImageComponentMapping =
2098            vk12_props->filterMinmaxImageComponentMapping;
2099         break;
2100      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES:
2101         u.timeline_semaphore->maxTimelineSemaphoreValueDifference =
2102            vk12_props->maxTimelineSemaphoreValueDifference;
2103         break;
2104
2105      /* Vulkan 1.3 */
2106      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES:
2107         *u.inline_uniform_block = props->inline_uniform_block;
2108         break;
2109
2110      /* EXT */
2111      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT:
2112         *u.conservative_rasterization = props->conservative_rasterization;
2113         break;
2114      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_PROPERTIES_EXT:
2115         *u.custom_border_color = props->custom_border_color;
2116         break;
2117      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT:
2118         u.drm->hasPrimary =
2119            physical_dev->instance->renderer->info.drm.has_primary;
2120         u.drm->primaryMajor =
2121            physical_dev->instance->renderer->info.drm.primary_major;
2122         u.drm->primaryMinor =
2123            physical_dev->instance->renderer->info.drm.primary_minor;
2124         u.drm->hasRender =
2125            physical_dev->instance->renderer->info.drm.has_render;
2126         u.drm->renderMajor =
2127            physical_dev->instance->renderer->info.drm.render_major;
2128         u.drm->renderMinor =
2129            physical_dev->instance->renderer->info.drm.render_minor;
2130         break;
2131      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT:
2132         *u.line_rasterization = props->line_rasterization;
2133         break;
2134      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT:
2135         /* this is used by WSI */
2136         if (physical_dev->instance->renderer->info.pci.has_bus_info) {
2137            u.pci_bus_info->pciDomain =
2138               physical_dev->instance->renderer->info.pci.domain;
2139            u.pci_bus_info->pciBus =
2140               physical_dev->instance->renderer->info.pci.bus;
2141            u.pci_bus_info->pciDevice =
2142               physical_dev->instance->renderer->info.pci.device;
2143            u.pci_bus_info->pciFunction =
2144               physical_dev->instance->renderer->info.pci.function;
2145         }
2146         break;
2147      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENTATION_PROPERTIES_ANDROID:
2148         u.presentation_properties->sharedImage =
2149            vn_android_gralloc_get_shared_present_usage() ? VK_TRUE
2150                                                          : VK_FALSE;
2151         break;
2152      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_PROPERTIES_EXT:
2153         *u.provoking_vertex = props->provoking_vertex;
2154         break;
2155      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_PROPERTIES_EXT:
2156         *u.robustness_2 = props->robustness_2;
2157         break;
2158      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT:
2159         *u.transform_feedback = props->transform_feedback;
2160         break;
2161      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT:
2162         *u.vertex_attribute_divisor = props->vertex_attribute_divisor;
2163         break;
2164      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES:
2165         *u.maintenance4 = props->maintenance4;
2166         break;
2167      default:
2168         break;
2169      }
2170
2171      u.pnext->pNext = saved;
2172      u.pnext = u.pnext->pNext;
2173   }
2174}
2175
2176void
2177vn_GetPhysicalDeviceQueueFamilyProperties2(
2178   VkPhysicalDevice physicalDevice,
2179   uint32_t *pQueueFamilyPropertyCount,
2180   VkQueueFamilyProperties2 *pQueueFamilyProperties)
2181{
2182   struct vn_physical_device *physical_dev =
2183      vn_physical_device_from_handle(physicalDevice);
2184
2185   VK_OUTARRAY_MAKE_TYPED(VkQueueFamilyProperties2, out,
2186                          pQueueFamilyProperties, pQueueFamilyPropertyCount);
2187   for (uint32_t i = 0; i < physical_dev->queue_family_count; i++) {
2188      vk_outarray_append_typed(VkQueueFamilyProperties2, &out, props) {
2189         *props = physical_dev->queue_family_properties[i];
2190      }
2191   }
2192}
2193
2194void
2195vn_GetPhysicalDeviceMemoryProperties2(
2196   VkPhysicalDevice physicalDevice,
2197   VkPhysicalDeviceMemoryProperties2 *pMemoryProperties)
2198{
2199   struct vn_physical_device *physical_dev =
2200      vn_physical_device_from_handle(physicalDevice);
2201
2202   pMemoryProperties->memoryProperties =
2203      physical_dev->memory_properties.memoryProperties;
2204}
2205
2206void
2207vn_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,
2208                                      VkFormat format,
2209                                      VkFormatProperties2 *pFormatProperties)
2210{
2211   struct vn_physical_device *physical_dev =
2212      vn_physical_device_from_handle(physicalDevice);
2213
2214   struct vn_format_properties_entry *entry = NULL;
2215   if (!pFormatProperties->pNext) {
2216      entry = vn_physical_device_get_format_properties(physical_dev, format);
2217      if (entry->valid) {
2218         pFormatProperties->formatProperties = entry->properties;
2219         return;
2220      }
2221   }
2222
2223   vn_call_vkGetPhysicalDeviceFormatProperties2(
2224      physical_dev->instance, physicalDevice, format, pFormatProperties);
2225
2226   if (entry) {
2227      vn_physical_device_add_format_properties(
2228         physical_dev, entry, &pFormatProperties->formatProperties);
2229   }
2230}
2231
2232struct vn_physical_device_image_format_info {
2233   VkPhysicalDeviceImageFormatInfo2 format;
2234   VkPhysicalDeviceExternalImageFormatInfo external;
2235   VkImageFormatListCreateInfo list;
2236   VkImageStencilUsageCreateInfo stencil_usage;
2237   VkPhysicalDeviceImageDrmFormatModifierInfoEXT modifier;
2238};
2239
2240static const VkPhysicalDeviceImageFormatInfo2 *
2241vn_physical_device_fix_image_format_info(
2242   struct vn_physical_device *physical_dev,
2243   const VkPhysicalDeviceImageFormatInfo2 *info,
2244   struct vn_physical_device_image_format_info *local_info)
2245{
2246   local_info->format = *info;
2247   VkBaseOutStructure *dst = (void *)&local_info->format;
2248
2249   bool is_ahb = false;
2250   bool has_format_list = false;
2251   /* we should generate deep copy functions... */
2252   vk_foreach_struct_const(src, info->pNext) {
2253      void *pnext = NULL;
2254      switch (src->sType) {
2255      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO:
2256         memcpy(&local_info->external, src, sizeof(local_info->external));
2257         is_ahb =
2258            local_info->external.handleType ==
2259            VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
2260         local_info->external.handleType =
2261            physical_dev->external_memory.renderer_handle_type;
2262         pnext = &local_info->external;
2263         break;
2264      case VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO:
2265         has_format_list = true;
2266         memcpy(&local_info->list, src, sizeof(local_info->list));
2267         pnext = &local_info->list;
2268         break;
2269      case VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO:
2270         memcpy(&local_info->stencil_usage, src,
2271                sizeof(local_info->stencil_usage));
2272         pnext = &local_info->stencil_usage;
2273         break;
2274      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT:
2275         memcpy(&local_info->modifier, src, sizeof(local_info->modifier));
2276         pnext = &local_info->modifier;
2277         break;
2278      default:
2279         break;
2280      }
2281
2282      if (pnext) {
2283         dst->pNext = pnext;
2284         dst = pnext;
2285      }
2286   }
2287
2288   if (is_ahb) {
2289      assert(local_info->format.tiling !=
2290             VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT);
2291      local_info->format.tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
2292      if (!vn_android_get_drm_format_modifier_info(&local_info->format,
2293                                                   &local_info->modifier))
2294         return NULL;
2295
2296      dst->pNext = (void *)&local_info->modifier;
2297      dst = dst->pNext;
2298
2299      if ((info->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) &&
2300          !local_info->list.viewFormatCount) {
2301         /* 12.3. Images
2302          *
2303          * If tiling is VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT and flags
2304          * contains VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT, then the pNext chain
2305          * must include a VkImageFormatListCreateInfo structure with non-zero
2306          * viewFormatCount.
2307          */
2308         VkImageFormatListCreateInfo *list = &local_info->list;
2309         uint32_t vcount = 0;
2310         const VkFormat *vformats =
2311            vn_android_format_to_view_formats(info->format, &vcount);
2312         if (!vformats) {
2313            /* local_info persists through the image format query call */
2314            vformats = &local_info->format.format;
2315            vcount = 1;
2316         }
2317
2318         list->sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO;
2319         list->viewFormatCount = vcount;
2320         list->pViewFormats = vformats;
2321
2322         if (!has_format_list) {
2323            dst->pNext = (void *)list;
2324            dst = dst->pNext;
2325         }
2326      }
2327   }
2328
2329   dst->pNext = NULL;
2330
2331   return &local_info->format;
2332}
2333
2334VkResult
2335vn_GetPhysicalDeviceImageFormatProperties2(
2336   VkPhysicalDevice physicalDevice,
2337   const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo,
2338   VkImageFormatProperties2 *pImageFormatProperties)
2339{
2340   struct vn_physical_device *physical_dev =
2341      vn_physical_device_from_handle(physicalDevice);
2342   const VkExternalMemoryHandleTypeFlagBits renderer_handle_type =
2343      physical_dev->external_memory.renderer_handle_type;
2344   const VkExternalMemoryHandleTypeFlags supported_handle_types =
2345      physical_dev->external_memory.supported_handle_types;
2346
2347   const VkPhysicalDeviceExternalImageFormatInfo *external_info =
2348      vk_find_struct_const(pImageFormatInfo->pNext,
2349                           PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO);
2350   if (external_info && !external_info->handleType)
2351      external_info = NULL;
2352
2353   struct vn_physical_device_image_format_info local_info;
2354   if (external_info) {
2355      if (!(external_info->handleType & supported_handle_types)) {
2356         return vn_error(physical_dev->instance,
2357                         VK_ERROR_FORMAT_NOT_SUPPORTED);
2358      }
2359
2360      if (external_info->handleType != renderer_handle_type) {
2361         pImageFormatInfo = vn_physical_device_fix_image_format_info(
2362            physical_dev, pImageFormatInfo, &local_info);
2363         if (!pImageFormatInfo) {
2364            return vn_error(physical_dev->instance,
2365                            VK_ERROR_FORMAT_NOT_SUPPORTED);
2366         }
2367      }
2368   }
2369
2370   VkResult result;
2371   /* TODO per-device cache */
2372   result = vn_call_vkGetPhysicalDeviceImageFormatProperties2(
2373      physical_dev->instance, physicalDevice, pImageFormatInfo,
2374      pImageFormatProperties);
2375   if (result != VK_SUCCESS || !external_info)
2376      return vn_result(physical_dev->instance, result);
2377
2378   if (external_info->handleType ==
2379       VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID) {
2380      VkAndroidHardwareBufferUsageANDROID *ahb_usage =
2381         vk_find_struct(pImageFormatProperties->pNext,
2382                        ANDROID_HARDWARE_BUFFER_USAGE_ANDROID);
2383      if (ahb_usage) {
2384         ahb_usage->androidHardwareBufferUsage = vn_android_get_ahb_usage(
2385            pImageFormatInfo->usage, pImageFormatInfo->flags);
2386      }
2387
2388      /* AHBs with mipmap usage will ignore this property */
2389      pImageFormatProperties->imageFormatProperties.maxMipLevels = 1;
2390   }
2391
2392   VkExternalImageFormatProperties *img_props = vk_find_struct(
2393      pImageFormatProperties->pNext, EXTERNAL_IMAGE_FORMAT_PROPERTIES);
2394   if (!img_props)
2395      return VK_SUCCESS;
2396
2397   VkExternalMemoryProperties *mem_props =
2398      &img_props->externalMemoryProperties;
2399
2400   if (external_info->handleType ==
2401       VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID) {
2402      /* AHB backed image requires renderer to support import bit */
2403      if (!(mem_props->externalMemoryFeatures &
2404            VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT))
2405         return vn_error(physical_dev->instance,
2406                         VK_ERROR_FORMAT_NOT_SUPPORTED);
2407
2408      mem_props->externalMemoryFeatures =
2409         VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT |
2410         VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT |
2411         VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
2412      mem_props->exportFromImportedHandleTypes =
2413         VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
2414      mem_props->compatibleHandleTypes =
2415         VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
2416   } else {
2417      mem_props->compatibleHandleTypes = supported_handle_types;
2418      mem_props->exportFromImportedHandleTypes =
2419         (mem_props->exportFromImportedHandleTypes & renderer_handle_type)
2420            ? supported_handle_types
2421            : 0;
2422   }
2423
2424   return VK_SUCCESS;
2425}
2426
2427void
2428vn_GetPhysicalDeviceSparseImageFormatProperties2(
2429   VkPhysicalDevice physicalDevice,
2430   const VkPhysicalDeviceSparseImageFormatInfo2 *pFormatInfo,
2431   uint32_t *pPropertyCount,
2432   VkSparseImageFormatProperties2 *pProperties)
2433{
2434   struct vn_physical_device *physical_dev =
2435      vn_physical_device_from_handle(physicalDevice);
2436
2437   /* TODO allow sparse resource along with sync feedback
2438    *
2439    * If VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT is not supported for the given
2440    * arguments, pPropertyCount will be set to zero upon return, and no data
2441    * will be written to pProperties.
2442    */
2443   if (!VN_PERF(NO_FENCE_FEEDBACK)) {
2444      *pPropertyCount = 0;
2445      return;
2446   }
2447
2448   /* TODO per-device cache */
2449   vn_call_vkGetPhysicalDeviceSparseImageFormatProperties2(
2450      physical_dev->instance, physicalDevice, pFormatInfo, pPropertyCount,
2451      pProperties);
2452}
2453
2454void
2455vn_GetPhysicalDeviceExternalBufferProperties(
2456   VkPhysicalDevice physicalDevice,
2457   const VkPhysicalDeviceExternalBufferInfo *pExternalBufferInfo,
2458   VkExternalBufferProperties *pExternalBufferProperties)
2459{
2460   struct vn_physical_device *physical_dev =
2461      vn_physical_device_from_handle(physicalDevice);
2462   const VkExternalMemoryHandleTypeFlagBits renderer_handle_type =
2463      physical_dev->external_memory.renderer_handle_type;
2464   const VkExternalMemoryHandleTypeFlags supported_handle_types =
2465      physical_dev->external_memory.supported_handle_types;
2466   const bool is_ahb =
2467      pExternalBufferInfo->handleType ==
2468      VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
2469
2470   VkExternalMemoryProperties *props =
2471      &pExternalBufferProperties->externalMemoryProperties;
2472   if (!(pExternalBufferInfo->handleType & supported_handle_types)) {
2473      props->compatibleHandleTypes = pExternalBufferInfo->handleType;
2474      props->exportFromImportedHandleTypes = 0;
2475      props->externalMemoryFeatures = 0;
2476      return;
2477   }
2478
2479   VkPhysicalDeviceExternalBufferInfo local_info;
2480   if (pExternalBufferInfo->handleType != renderer_handle_type) {
2481      local_info = *pExternalBufferInfo;
2482      local_info.handleType = renderer_handle_type;
2483      pExternalBufferInfo = &local_info;
2484   }
2485
2486   /* TODO per-device cache */
2487   vn_call_vkGetPhysicalDeviceExternalBufferProperties(
2488      physical_dev->instance, physicalDevice, pExternalBufferInfo,
2489      pExternalBufferProperties);
2490
2491   if (is_ahb) {
2492      props->compatibleHandleTypes =
2493         VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
2494      /* AHB backed buffer requires renderer to support import bit while it
2495       * also requires the renderer to must not advertise dedicated only bit
2496       */
2497      if (!(props->externalMemoryFeatures &
2498            VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT) ||
2499          (props->externalMemoryFeatures &
2500           VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT)) {
2501         props->externalMemoryFeatures = 0;
2502         props->exportFromImportedHandleTypes = 0;
2503         return;
2504      }
2505      props->externalMemoryFeatures =
2506         VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT |
2507         VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
2508      props->exportFromImportedHandleTypes =
2509         VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
2510   } else {
2511      props->compatibleHandleTypes = supported_handle_types;
2512      props->exportFromImportedHandleTypes =
2513         (props->exportFromImportedHandleTypes & renderer_handle_type)
2514            ? supported_handle_types
2515            : 0;
2516   }
2517}
2518
2519void
2520vn_GetPhysicalDeviceExternalFenceProperties(
2521   VkPhysicalDevice physicalDevice,
2522   const VkPhysicalDeviceExternalFenceInfo *pExternalFenceInfo,
2523   VkExternalFenceProperties *pExternalFenceProperties)
2524{
2525   struct vn_physical_device *physical_dev =
2526      vn_physical_device_from_handle(physicalDevice);
2527
2528   if (pExternalFenceInfo->handleType &
2529       physical_dev->external_fence_handles) {
2530      pExternalFenceProperties->compatibleHandleTypes =
2531         physical_dev->external_fence_handles;
2532      pExternalFenceProperties->exportFromImportedHandleTypes =
2533         physical_dev->external_fence_handles;
2534      pExternalFenceProperties->externalFenceFeatures =
2535         VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT |
2536         VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT;
2537   } else {
2538      pExternalFenceProperties->compatibleHandleTypes = 0;
2539      pExternalFenceProperties->exportFromImportedHandleTypes = 0;
2540      pExternalFenceProperties->externalFenceFeatures = 0;
2541   }
2542}
2543
2544void
2545vn_GetPhysicalDeviceExternalSemaphoreProperties(
2546   VkPhysicalDevice physicalDevice,
2547   const VkPhysicalDeviceExternalSemaphoreInfo *pExternalSemaphoreInfo,
2548   VkExternalSemaphoreProperties *pExternalSemaphoreProperties)
2549{
2550   struct vn_physical_device *physical_dev =
2551      vn_physical_device_from_handle(physicalDevice);
2552
2553   const VkSemaphoreTypeCreateInfo *type_info = vk_find_struct_const(
2554      pExternalSemaphoreInfo->pNext, SEMAPHORE_TYPE_CREATE_INFO);
2555   const VkSemaphoreType sem_type =
2556      type_info ? type_info->semaphoreType : VK_SEMAPHORE_TYPE_BINARY;
2557   const VkExternalSemaphoreHandleTypeFlags valid_handles =
2558      sem_type == VK_SEMAPHORE_TYPE_BINARY
2559         ? physical_dev->external_binary_semaphore_handles
2560         : physical_dev->external_timeline_semaphore_handles;
2561   if (pExternalSemaphoreInfo->handleType & valid_handles) {
2562      pExternalSemaphoreProperties->compatibleHandleTypes = valid_handles;
2563      pExternalSemaphoreProperties->exportFromImportedHandleTypes =
2564         valid_handles;
2565      pExternalSemaphoreProperties->externalSemaphoreFeatures =
2566         VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT |
2567         VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT;
2568   } else {
2569      pExternalSemaphoreProperties->compatibleHandleTypes = 0;
2570      pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0;
2571      pExternalSemaphoreProperties->externalSemaphoreFeatures = 0;
2572   }
2573}
2574
2575VkResult
2576vn_GetPhysicalDeviceCalibrateableTimeDomainsEXT(
2577   VkPhysicalDevice physicalDevice,
2578   uint32_t *pTimeDomainCount,
2579   VkTimeDomainEXT *pTimeDomains)
2580{
2581   struct vn_physical_device *physical_dev =
2582      vn_physical_device_from_handle(physicalDevice);
2583
2584   return vn_call_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT(
2585      physical_dev->instance, physicalDevice, pTimeDomainCount, pTimeDomains);
2586}
2587