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