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