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 
28 static void
vn_physical_device_init_features(struct vn_physical_device * physical_dev)29 vn_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 
341 static void
vn_physical_device_init_uuids(struct vn_physical_device * physical_dev)342 vn_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 
383 static void
vn_physical_device_init_properties(struct vn_physical_device * physical_dev)384 vn_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 
696 static VkResult
vn_physical_device_init_queue_family_properties(struct vn_physical_device * physical_dev)697 vn_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 
726 static void
vn_physical_device_init_memory_properties(struct vn_physical_device * physical_dev)727 vn_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 
755 static void
vn_physical_device_init_external_memory(struct vn_physical_device * physical_dev)756 vn_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 
796 static void
vn_physical_device_init_external_fence_handles(struct vn_physical_device * physical_dev)797 vn_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 
825 static void
vn_physical_device_init_external_semaphore_handles(struct vn_physical_device * physical_dev)826 vn_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 
858 static void
vn_physical_device_get_native_extensions(const struct vn_physical_device * physical_dev,struct vk_device_extension_table * exts)859 vn_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 
902 static void
vn_physical_device_get_passthrough_extensions(const struct vn_physical_device * physical_dev,struct vk_device_extension_table * exts)903 vn_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 
966 static void
vn_physical_device_init_supported_extensions(struct vn_physical_device * physical_dev)967 vn_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 
1003 static VkResult
vn_physical_device_init_renderer_extensions(struct vn_physical_device * physical_dev)1004 vn_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 
1069 static VkResult
vn_physical_device_init_renderer_version(struct vn_physical_device * physical_dev)1070 vn_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 
1099 static VkResult
vn_physical_device_init(struct vn_physical_device * physical_dev)1100 vn_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 
1132 fail:
1133    vk_free(alloc, physical_dev->extension_spec_versions);
1134    vk_free(alloc, physical_dev->queue_family_properties);
1135    return result;
1136 }
1137 
1138 void
vn_physical_device_fini(struct vn_physical_device * physical_dev)1139 vn_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 
1151 static struct vn_physical_device *
find_physical_device(struct vn_physical_device * physical_devs,uint32_t count,vn_object_id id)1152 find_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 
1163 static VkResult
vn_instance_enumerate_physical_device_groups_locked(struct vn_instance * instance,struct vn_physical_device * physical_devs,uint32_t physical_dev_count)1164 vn_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 
1258 static VkResult
enumerate_physical_devices(struct vn_instance * instance,struct vn_physical_device ** out_physical_devs,uint32_t * out_count)1259 enumerate_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 
1318 fail:
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 
1326 static uint32_t
filter_physical_devices(struct vn_physical_device * physical_devs,uint32_t count)1327 filter_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 
1350 static VkResult
vn_instance_enumerate_physical_devices_and_groups(struct vn_instance * instance)1351 vn_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 
1401 unlock:
1402    mtx_unlock(&instance->physical_device.mutex);
1403    return result;
1404 }
1405 
1406 /* physical device commands */
1407 
1408 VkResult
vn_EnumeratePhysicalDevices(VkInstance _instance,uint32_t * pPhysicalDeviceCount,VkPhysicalDevice * pPhysicalDevices)1409 vn_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 
1431 VkResult
vn_EnumeratePhysicalDeviceGroups(VkInstance _instance,uint32_t * pPhysicalDeviceGroupCount,VkPhysicalDeviceGroupProperties * pPhysicalDeviceGroupProperties)1432 vn_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 
1455 VkResult
vn_EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,const char * pLayerName,uint32_t * pPropertyCount,VkExtensionProperties * pProperties)1456 vn_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 
1480 VkResult
vn_EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,uint32_t * pPropertyCount,VkLayerProperties * pProperties)1481 vn_EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,
1482                                   uint32_t *pPropertyCount,
1483                                   VkLayerProperties *pProperties)
1484 {
1485    *pPropertyCount = 0;
1486    return VK_SUCCESS;
1487 }
1488 
1489 void
vn_GetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice,VkPhysicalDeviceFeatures * pFeatures)1490 vn_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 
1499 void
vn_GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,VkPhysicalDeviceProperties * pProperties)1500 vn_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 
1509 void
vn_GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,uint32_t * pQueueFamilyPropertyCount,VkQueueFamilyProperties * pQueueFamilyProperties)1510 vn_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 
1527 void
vn_GetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice,VkPhysicalDeviceMemoryProperties * pMemoryProperties)1528 vn_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 
1538 void
vn_GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice,VkFormat format,VkFormatProperties * pFormatProperties)1539 vn_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 
1551 VkResult
vn_GetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice,VkFormat format,VkImageType type,VkImageTiling tiling,VkImageUsageFlags usage,VkImageCreateFlags flags,VkImageFormatProperties * pImageFormatProperties)1552 vn_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 
1572 void
vn_GetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice,VkFormat format,VkImageType type,uint32_t samples,VkImageUsageFlags usage,VkImageTiling tiling,uint32_t * pPropertyCount,VkSparseImageFormatProperties * pProperties)1573 vn_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 
1592 void
vn_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,VkPhysicalDeviceFeatures2 * pFeatures)1593 vn_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 
1802 void
vn_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,VkPhysicalDeviceProperties2 * pProperties)1803 vn_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 
2042 void
vn_GetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice,uint32_t * pQueueFamilyPropertyCount,VkQueueFamilyProperties2 * pQueueFamilyProperties)2043 vn_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 
2059 void
vn_GetPhysicalDeviceMemoryProperties2(VkPhysicalDevice physicalDevice,VkPhysicalDeviceMemoryProperties2 * pMemoryProperties)2060 vn_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 
2071 void
vn_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,VkFormat format,VkFormatProperties2 * pFormatProperties)2072 vn_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 
2084 struct vn_physical_device_image_format_info {
2085    VkPhysicalDeviceImageFormatInfo2 format;
2086    VkPhysicalDeviceExternalImageFormatInfo external;
2087    VkImageFormatListCreateInfo list;
2088    VkImageStencilUsageCreateInfo stencil_usage;
2089    VkPhysicalDeviceImageDrmFormatModifierInfoEXT modifier;
2090 };
2091 
2092 static const VkPhysicalDeviceImageFormatInfo2 *
vn_physical_device_fix_image_format_info(struct vn_physical_device * physical_dev,const VkPhysicalDeviceImageFormatInfo2 * info,struct vn_physical_device_image_format_info * local_info)2093 vn_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 
2155 VkResult
vn_GetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceImageFormatInfo2 * pImageFormatInfo,VkImageFormatProperties2 * pImageFormatProperties)2156 vn_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 
2248 void
vn_GetPhysicalDeviceSparseImageFormatProperties2(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceSparseImageFormatInfo2 * pFormatInfo,uint32_t * pPropertyCount,VkSparseImageFormatProperties2 * pProperties)2249 vn_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 
2264 void
vn_GetPhysicalDeviceExternalBufferProperties(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceExternalBufferInfo * pExternalBufferInfo,VkExternalBufferProperties * pExternalBufferProperties)2265 vn_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 
2329 void
vn_GetPhysicalDeviceExternalFenceProperties(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceExternalFenceInfo * pExternalFenceInfo,VkExternalFenceProperties * pExternalFenceProperties)2330 vn_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 
2355 void
vn_GetPhysicalDeviceExternalSemaphoreProperties(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceExternalSemaphoreInfo * pExternalSemaphoreInfo,VkExternalSemaphoreProperties * pExternalSemaphoreProperties)2356 vn_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