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