xref: /aosp_15_r20/external/mesa3d/src/gallium/frontends/lavapipe/lvp_device.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2019 Red Hat.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 #include "lvp_private.h"
25 #include "lvp_conv.h"
26 
27 #include "pipe-loader/pipe_loader.h"
28 #include "git_sha1.h"
29 #include "vk_cmd_enqueue_entrypoints.h"
30 #include "vk_sampler.h"
31 #include "vk_util.h"
32 #include "util/detect.h"
33 #include "pipe/p_defines.h"
34 #include "pipe/p_state.h"
35 #include "pipe/p_context.h"
36 #include "frontend/drisw_api.h"
37 
38 #include "util/u_inlines.h"
39 #include "util/os_memory.h"
40 #include "util/os_time.h"
41 #include "util/u_thread.h"
42 #include "util/u_atomic.h"
43 #include "util/timespec.h"
44 #include "util/ptralloc.h"
45 #include "nir.h"
46 #include "nir_builder.h"
47 
48 #if DETECT_OS_LINUX
49 #include <sys/mman.h>
50 #include <sys/resource.h>
51 #endif
52 
53 #if DETECT_OS_ANDROID
54 #include "vk_android.h"
55 #endif
56 
57 #if defined(VK_USE_PLATFORM_WAYLAND_KHR) || \
58     defined(VK_USE_PLATFORM_WIN32_KHR) || \
59     defined(VK_USE_PLATFORM_XCB_KHR) || \
60     defined(VK_USE_PLATFORM_XLIB_KHR) || \
61     defined(VK_USE_PLATFORM_METAL_EXT)
62 #define LVP_USE_WSI_PLATFORM
63 #endif
64 #define LVP_API_VERSION VK_MAKE_VERSION(1, 3, VK_HEADER_VERSION)
65 
lvp_EnumerateInstanceVersion(uint32_t * pApiVersion)66 VKAPI_ATTR VkResult VKAPI_CALL lvp_EnumerateInstanceVersion(uint32_t* pApiVersion)
67 {
68    *pApiVersion = LVP_API_VERSION;
69    return VK_SUCCESS;
70 }
71 
72 static const struct vk_instance_extension_table lvp_instance_extensions_supported = {
73    .KHR_device_group_creation                = true,
74    .KHR_external_fence_capabilities          = true,
75    .KHR_external_memory_capabilities         = true,
76    .KHR_external_semaphore_capabilities      = true,
77    .KHR_get_physical_device_properties2      = true,
78    .EXT_debug_report                         = true,
79    .EXT_debug_utils                          = true,
80 #ifdef LVP_USE_WSI_PLATFORM
81    .KHR_get_surface_capabilities2            = true,
82    .KHR_surface                              = true,
83    .KHR_surface_protected_capabilities       = true,
84    .EXT_swapchain_colorspace                 = true,
85    .EXT_surface_maintenance1                 = true,
86 #endif
87 #ifdef VK_USE_PLATFORM_WAYLAND_KHR
88    .KHR_wayland_surface                      = true,
89 #endif
90 #ifdef VK_USE_PLATFORM_WIN32_KHR
91    .KHR_win32_surface                        = true,
92 #endif
93 #ifdef VK_USE_PLATFORM_XCB_KHR
94    .KHR_xcb_surface                          = true,
95 #endif
96 #ifdef VK_USE_PLATFORM_XLIB_KHR
97    .KHR_xlib_surface                         = true,
98 #endif
99 #ifdef VK_USE_PLATFORM_METAL_EXT
100    .EXT_metal_surface                        = true,
101 #endif
102 #ifndef VK_USE_PLATFORM_WIN32_KHR
103    .EXT_headless_surface                     = true,
104 #endif
105 };
106 
107 static const struct vk_device_extension_table lvp_device_extensions_supported = {
108    .KHR_8bit_storage                      = true,
109    .KHR_16bit_storage                     = true,
110    .KHR_acceleration_structure            = true,
111    .KHR_bind_memory2                      = true,
112    .KHR_buffer_device_address             = true,
113    .KHR_create_renderpass2                = true,
114    .KHR_copy_commands2                    = true,
115    .KHR_dedicated_allocation              = true,
116    .KHR_deferred_host_operations          = true,
117    .KHR_depth_stencil_resolve             = true,
118    .KHR_descriptor_update_template        = true,
119    .KHR_device_group                      = true,
120    .KHR_draw_indirect_count               = true,
121    .KHR_driver_properties                 = true,
122    .KHR_dynamic_rendering                 = true,
123    .KHR_dynamic_rendering_local_read      = true,
124    .KHR_format_feature_flags2             = true,
125    .KHR_external_fence                    = true,
126    .KHR_external_memory                   = true,
127 #ifdef PIPE_MEMORY_FD
128    .KHR_external_memory_fd                = true,
129 #endif
130    .KHR_external_semaphore                = true,
131    .KHR_shader_float_controls             = true,
132    .KHR_get_memory_requirements2          = true,
133    .KHR_global_priority                   = true,
134 #ifdef LVP_USE_WSI_PLATFORM
135    .KHR_incremental_present               = true,
136 #endif
137    .KHR_image_format_list                 = true,
138    .KHR_imageless_framebuffer             = true,
139    .KHR_index_type_uint8                  = true,
140    .KHR_line_rasterization                = true,
141    .KHR_load_store_op_none                = true,
142    .KHR_maintenance1                      = true,
143    .KHR_maintenance2                      = true,
144    .KHR_maintenance3                      = true,
145    .KHR_maintenance4                      = true,
146    .KHR_maintenance5                      = true,
147    .KHR_maintenance6                      = true,
148    .KHR_maintenance7                      = true,
149    .KHR_map_memory2                       = true,
150    .KHR_multiview                         = true,
151    .KHR_push_descriptor                   = true,
152    .KHR_pipeline_library                  = true,
153    .KHR_ray_query                         = true,
154    .KHR_ray_tracing_maintenance1          = true,
155    .KHR_ray_tracing_pipeline              = true,
156    .KHR_ray_tracing_position_fetch        = true,
157    .KHR_relaxed_block_layout              = true,
158    .KHR_sampler_mirror_clamp_to_edge      = true,
159    .KHR_sampler_ycbcr_conversion          = true,
160    .KHR_separate_depth_stencil_layouts    = true,
161    .KHR_shader_atomic_int64               = true,
162    .KHR_shader_clock                      = true,
163    .KHR_shader_draw_parameters            = true,
164    .KHR_shader_expect_assume              = true,
165    .KHR_shader_float16_int8               = true,
166    .KHR_shader_integer_dot_product        = true,
167    .KHR_shader_maximal_reconvergence      = true,
168    .KHR_shader_non_semantic_info          = true,
169    .KHR_shader_relaxed_extended_instruction = true,
170    .KHR_shader_subgroup_extended_types    = true,
171    .KHR_shader_terminate_invocation       = true,
172    .KHR_spirv_1_4                         = true,
173    .KHR_storage_buffer_storage_class      = true,
174 #ifdef LVP_USE_WSI_PLATFORM
175    .KHR_swapchain                         = true,
176    .KHR_swapchain_mutable_format          = true,
177 #endif
178    .KHR_synchronization2                  = true,
179    .KHR_timeline_semaphore                = true,
180    .KHR_uniform_buffer_standard_layout    = true,
181    .KHR_variable_pointers                 = true,
182    .KHR_vertex_attribute_divisor          = true,
183    .KHR_vulkan_memory_model               = true,
184    .KHR_zero_initialize_workgroup_memory  = true,
185    .ARM_rasterization_order_attachment_access = true,
186    .EXT_4444_formats                      = true,
187    .EXT_attachment_feedback_loop_layout   = true,
188    .EXT_attachment_feedback_loop_dynamic_state = true,
189    .EXT_border_color_swizzle              = true,
190    .EXT_calibrated_timestamps             = true,
191    .EXT_color_write_enable                = true,
192    .EXT_conditional_rendering             = true,
193    .EXT_depth_clip_enable                 = true,
194    .EXT_depth_clip_control                = true,
195    .EXT_depth_range_unrestricted          = true,
196    .EXT_dynamic_rendering_unused_attachments = true,
197    .EXT_descriptor_buffer                 = true,
198    .EXT_descriptor_indexing               = true,
199    .EXT_extended_dynamic_state            = true,
200    .EXT_extended_dynamic_state2           = true,
201    .EXT_extended_dynamic_state3           = true,
202    .EXT_external_memory_host              = true,
203    .EXT_graphics_pipeline_library         = true,
204    .EXT_host_image_copy                   = true,
205    .EXT_host_query_reset                  = true,
206    .EXT_image_2d_view_of_3d               = true,
207    .EXT_image_sliced_view_of_3d           = true,
208    .EXT_image_robustness                  = true,
209    .EXT_index_type_uint8                  = true,
210    .EXT_inline_uniform_block              = true,
211    .EXT_load_store_op_none                = true,
212    .EXT_legacy_vertex_attributes          = true,
213    .EXT_memory_budget                     = true,
214 #if DETECT_OS_LINUX
215    .EXT_memory_priority                   = true,
216 #endif
217    .EXT_mesh_shader                       = true,
218    .EXT_multisampled_render_to_single_sampled = true,
219    .EXT_multi_draw                        = true,
220    .EXT_mutable_descriptor_type           = true,
221    .EXT_nested_command_buffer             = true,
222    .EXT_non_seamless_cube_map             = true,
223 #if DETECT_OS_LINUX
224    .EXT_pageable_device_local_memory      = true,
225 #endif
226    .EXT_pipeline_creation_feedback        = true,
227    .EXT_pipeline_creation_cache_control   = true,
228    .EXT_pipeline_library_group_handles    = true,
229    .EXT_pipeline_protected_access         = true,
230    .EXT_pipeline_robustness               = true,
231    .EXT_post_depth_coverage               = true,
232    .EXT_private_data                      = true,
233    .EXT_primitives_generated_query        = true,
234    .EXT_primitive_topology_list_restart   = true,
235    .EXT_rasterization_order_attachment_access = true,
236    .EXT_queue_family_foreign              = true,
237    .EXT_sampler_filter_minmax             = true,
238    .EXT_scalar_block_layout               = true,
239    .EXT_separate_stencil_usage            = true,
240    .EXT_shader_atomic_float               = true,
241    .EXT_shader_atomic_float2              = true,
242    .EXT_shader_demote_to_helper_invocation= true,
243    .EXT_shader_object                     = true,
244    .EXT_shader_replicated_composites      = true,
245    .EXT_shader_stencil_export             = true,
246    .EXT_shader_subgroup_ballot            = true,
247    .EXT_shader_subgroup_vote              = true,
248    .EXT_shader_viewport_index_layer       = true,
249    .EXT_subgroup_size_control             = true,
250 #ifdef LVP_USE_WSI_PLATFORM
251    .EXT_swapchain_maintenance1            = true,
252 #endif
253    .EXT_texel_buffer_alignment            = true,
254    .EXT_transform_feedback                = true,
255    .EXT_vertex_attribute_divisor          = true,
256    .EXT_vertex_input_dynamic_state        = true,
257    .EXT_ycbcr_image_arrays                = true,
258    .EXT_ycbcr_2plane_444_formats          = true,
259    .EXT_custom_border_color               = true,
260    .EXT_provoking_vertex                  = true,
261    .EXT_line_rasterization                = true,
262    .EXT_robustness2                       = true,
263    .AMDX_shader_enqueue                   = true,
264 #if DETECT_OS_ANDROID
265    .ANDROID_native_buffer                 = true,
266 #endif
267    .GOOGLE_decorate_string                = true,
268    .GOOGLE_hlsl_functionality1            = true,
269    .NV_device_generated_commands          = true,
270 };
271 
272 static bool
assert_memhandle_type(VkExternalMemoryHandleTypeFlags types)273 assert_memhandle_type(VkExternalMemoryHandleTypeFlags types)
274 {
275    unsigned valid[] = {
276       VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
277       VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
278    };
279    for (unsigned i = 0; i < ARRAY_SIZE(valid); i++) {
280       if (types & valid[i])
281          types &= ~valid[i];
282    }
283    u_foreach_bit(type, types)
284       mesa_loge("lavapipe: unimplemented external memory type %u", 1<<type);
285    return types == 0;
286 }
287 
288 static int
min_vertex_pipeline_param(struct pipe_screen * pscreen,enum pipe_shader_cap param)289 min_vertex_pipeline_param(struct pipe_screen *pscreen, enum pipe_shader_cap param)
290 {
291    int val = INT_MAX;
292    for (int i = 0; i < MESA_SHADER_COMPUTE; ++i) {
293       if (i == MESA_SHADER_FRAGMENT ||
294           !pscreen->get_shader_param(pscreen, i,
295                                      PIPE_SHADER_CAP_MAX_INSTRUCTIONS))
296          continue;
297 
298       val = MAX2(val, pscreen->get_shader_param(pscreen, i, param));
299    }
300    return val;
301 }
302 
303 static int
min_shader_param(struct pipe_screen * pscreen,enum pipe_shader_cap param)304 min_shader_param(struct pipe_screen *pscreen, enum pipe_shader_cap param)
305 {
306    return MIN3(min_vertex_pipeline_param(pscreen, param),
307                pscreen->get_shader_param(pscreen, MESA_SHADER_FRAGMENT, param),
308                pscreen->get_shader_param(pscreen, MESA_SHADER_COMPUTE, param));
309 }
310 
311 static void
lvp_get_features(const struct lvp_physical_device * pdevice,struct vk_features * features)312 lvp_get_features(const struct lvp_physical_device *pdevice,
313                  struct vk_features *features)
314 {
315    bool instance_divisor = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR) != 0;
316 
317    *features = (struct vk_features){
318       /* Vulkan 1.0 */
319       .robustBufferAccess                       = true,
320       .fullDrawIndexUint32                      = true,
321       .imageCubeArray                           = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_CUBE_MAP_ARRAY) != 0),
322       .independentBlend                         = true,
323       .geometryShader                           = (pdevice->pscreen->get_shader_param(pdevice->pscreen, MESA_SHADER_GEOMETRY, PIPE_SHADER_CAP_MAX_INSTRUCTIONS) != 0),
324       .tessellationShader                       = (pdevice->pscreen->get_shader_param(pdevice->pscreen, MESA_SHADER_TESS_EVAL, PIPE_SHADER_CAP_MAX_INSTRUCTIONS) != 0),
325       .sampleRateShading                        = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_SAMPLE_SHADING) != 0),
326       .dualSrcBlend                             = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS) != 0),
327       .logicOp                                  = true,
328       .multiDrawIndirect                        = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MULTI_DRAW_INDIRECT) != 0),
329       .drawIndirectFirstInstance                = true,
330       .depthClamp                               = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_DEPTH_CLIP_DISABLE) != 0),
331       .depthBiasClamp                           = true,
332       .fillModeNonSolid                         = true,
333       .depthBounds                              = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_DEPTH_BOUNDS_TEST) != 0),
334       .wideLines                                = true,
335       .largePoints                              = true,
336       .alphaToOne                               = true,
337       .multiViewport                            = true,
338       .samplerAnisotropy                        = true,
339       .textureCompressionETC2                   = false,
340       .textureCompressionASTC_LDR               = false,
341       .textureCompressionBC                     = true,
342       .occlusionQueryPrecise                    = true,
343       .pipelineStatisticsQuery                  = true,
344       .vertexPipelineStoresAndAtomics           = (min_vertex_pipeline_param(pdevice->pscreen, PIPE_SHADER_CAP_MAX_SHADER_BUFFERS) != 0),
345       .fragmentStoresAndAtomics                 = (pdevice->pscreen->get_shader_param(pdevice->pscreen, MESA_SHADER_FRAGMENT, PIPE_SHADER_CAP_MAX_SHADER_BUFFERS) != 0),
346       .shaderTessellationAndGeometryPointSize   = true,
347       .shaderImageGatherExtended                = true,
348       .shaderStorageImageExtendedFormats        = (min_shader_param(pdevice->pscreen, PIPE_SHADER_CAP_MAX_SHADER_IMAGES) != 0),
349       .shaderStorageImageMultisample            = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_TEXTURE_MULTISAMPLE) != 0),
350       .shaderUniformBufferArrayDynamicIndexing  = true,
351       .shaderSampledImageArrayDynamicIndexing   = true,
352       .shaderStorageBufferArrayDynamicIndexing  = true,
353       .shaderStorageImageArrayDynamicIndexing   = true,
354       .shaderStorageImageReadWithoutFormat      = true,
355       .shaderStorageImageWriteWithoutFormat     = true,
356       .shaderClipDistance                       = true,
357       .shaderCullDistance                       = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_CULL_DISTANCE) == 1),
358       .shaderFloat64                            = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_DOUBLES) == 1),
359       .shaderInt64                              = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_INT64) == 1),
360       .shaderInt16                              = (min_shader_param(pdevice->pscreen, PIPE_SHADER_CAP_INT16) == 1),
361       .variableMultisampleRate                  = false,
362       .inheritedQueries                         = false,
363       .sparseBinding                            = DETECT_OS_LINUX,
364       .sparseResidencyBuffer                    = DETECT_OS_LINUX,
365       .sparseResidencyImage2D                   = DETECT_OS_LINUX,
366       .sparseResidencyImage3D                   = DETECT_OS_LINUX,
367       .sparseResidencyAliased                   = DETECT_OS_LINUX,
368       .shaderResourceResidency                  = DETECT_OS_LINUX,
369 
370       /* Vulkan 1.1 */
371       .storageBuffer16BitAccess            = true,
372       .uniformAndStorageBuffer16BitAccess  = true,
373       .storagePushConstant16               = true,
374       .storageInputOutput16                = false,
375       .multiview                           = true,
376       .multiviewGeometryShader             = true,
377       .multiviewTessellationShader         = true,
378       .variablePointersStorageBuffer       = true,
379       .variablePointers                    = true,
380       .protectedMemory                     = false,
381       .samplerYcbcrConversion              = true,
382       .shaderDrawParameters                = true,
383 
384       /* Vulkan 1.2 */
385       .samplerMirrorClampToEdge = true,
386       .drawIndirectCount = true,
387       .storageBuffer8BitAccess = true,
388       .uniformAndStorageBuffer8BitAccess = true,
389       .storagePushConstant8 = true,
390       .shaderBufferInt64Atomics = true,
391       .shaderSharedInt64Atomics = true,
392       .shaderFloat16 = pdevice->pscreen->get_shader_param(pdevice->pscreen, MESA_SHADER_FRAGMENT, PIPE_SHADER_CAP_FP16) != 0,
393       .shaderInt8 = true,
394 
395       .descriptorIndexing = true,
396       .shaderInputAttachmentArrayDynamicIndexing = true,
397       .shaderUniformTexelBufferArrayDynamicIndexing = true,
398       .shaderStorageTexelBufferArrayDynamicIndexing = true,
399       .shaderUniformBufferArrayNonUniformIndexing = true,
400       .shaderSampledImageArrayNonUniformIndexing = true,
401       .shaderStorageBufferArrayNonUniformIndexing = true,
402       .shaderStorageImageArrayNonUniformIndexing = true,
403       .shaderInputAttachmentArrayNonUniformIndexing = true,
404       .shaderUniformTexelBufferArrayNonUniformIndexing = true,
405       .shaderStorageTexelBufferArrayNonUniformIndexing = true,
406       .descriptorBindingUniformBufferUpdateAfterBind = true,
407       .descriptorBindingSampledImageUpdateAfterBind = true,
408       .descriptorBindingStorageImageUpdateAfterBind = true,
409       .descriptorBindingStorageBufferUpdateAfterBind = true,
410       .descriptorBindingUniformTexelBufferUpdateAfterBind = true,
411       .descriptorBindingStorageTexelBufferUpdateAfterBind = true,
412       .descriptorBindingUpdateUnusedWhilePending = true,
413       .descriptorBindingPartiallyBound = true,
414       .descriptorBindingVariableDescriptorCount = true,
415       .runtimeDescriptorArray = true,
416 
417       .samplerFilterMinmax = true,
418       .scalarBlockLayout = true,
419       .imagelessFramebuffer = true,
420       .uniformBufferStandardLayout = true,
421       .shaderSubgroupExtendedTypes = true,
422       .separateDepthStencilLayouts = true,
423       .hostQueryReset = true,
424       .timelineSemaphore = true,
425       .bufferDeviceAddress = true,
426       .bufferDeviceAddressCaptureReplay = false,
427       .bufferDeviceAddressMultiDevice = false,
428       .vulkanMemoryModel = true,
429       .vulkanMemoryModelDeviceScope = true,
430       .vulkanMemoryModelAvailabilityVisibilityChains = true,
431       .shaderOutputViewportIndex = true,
432       .shaderOutputLayer = true,
433       .subgroupBroadcastDynamicId = true,
434 
435       /* Vulkan 1.3 */
436       .robustImageAccess = true,
437       .inlineUniformBlock = true,
438       .descriptorBindingInlineUniformBlockUpdateAfterBind = true,
439       .pipelineCreationCacheControl = true,
440       .privateData = true,
441       .shaderDemoteToHelperInvocation = true,
442       .shaderTerminateInvocation = true,
443       .subgroupSizeControl = true,
444       .computeFullSubgroups = true,
445       .synchronization2 = true,
446       .textureCompressionASTC_HDR = VK_FALSE,
447       .shaderZeroInitializeWorkgroupMemory = true,
448       .dynamicRendering = true,
449       .shaderIntegerDotProduct = true,
450       .maintenance4 = true,
451 
452       /* VK_KHR_acceleration_structure */
453       .accelerationStructure = true,
454       .accelerationStructureCaptureReplay = false,
455       .accelerationStructureIndirectBuild = false,
456       .accelerationStructureHostCommands = false,
457       .descriptorBindingAccelerationStructureUpdateAfterBind = true,
458 
459       /* VK_EXT_descriptor_buffer */
460       .descriptorBuffer = true,
461       .descriptorBufferCaptureReplay = false,
462       .descriptorBufferPushDescriptors = true,
463       .descriptorBufferImageLayoutIgnored = true,
464 
465       /* VK_EXT_primitives_generated_query */
466       .primitivesGeneratedQuery = true,
467       .primitivesGeneratedQueryWithRasterizerDiscard = true,
468       .primitivesGeneratedQueryWithNonZeroStreams = true,
469 
470       /* VK_EXT_border_color_swizzle */
471       .borderColorSwizzle = true,
472       .borderColorSwizzleFromImage = true,
473 
474       /* VK_EXT_non_seamless_cube_map */
475       .nonSeamlessCubeMap = true,
476 
477       /* VK_KHR_global_priority */
478       .globalPriorityQuery = true,
479 
480       /* VK_EXT_attachment_feedback_loop_layout */
481       .attachmentFeedbackLoopLayout = true,
482 
483       /* VK_EXT_pipeline_protected_access */
484       .pipelineProtectedAccess = true,
485 
486       /* VK_EXT_rasterization_order_attachment_access */
487       .rasterizationOrderColorAttachmentAccess = true,
488       .rasterizationOrderDepthAttachmentAccess = true,
489       .rasterizationOrderStencilAttachmentAccess = true,
490 
491       /* VK_EXT_line_rasterization */
492       .rectangularLines = true,
493       .bresenhamLines = true,
494       .smoothLines = true,
495       .stippledRectangularLines = true,
496       .stippledBresenhamLines = true,
497       .stippledSmoothLines = true,
498 
499       /* VK_EXT_vertex_attribute_divisor */
500       .vertexAttributeInstanceRateZeroDivisor = instance_divisor,
501       .vertexAttributeInstanceRateDivisor = instance_divisor,
502 
503       /* VK_EXT_multisampled_render_to_single_sampled */
504       .multisampledRenderToSingleSampled = true,
505 
506       /* VK_EXT_mutable_descriptor_type */
507       .mutableDescriptorType = true,
508 
509       /* VK_EXT_index_type_uint8 */
510       .indexTypeUint8 = true,
511 
512       /* VK_EXT_vertex_input_dynamic_state */
513       .vertexInputDynamicState = true,
514 
515       /* VK_EXT_image_sliced_view_of_3d */
516       .imageSlicedViewOf3D = true,
517 
518       /* VK_EXT_depth_clip_control */
519       .depthClipControl = true,
520 
521       /* VK_EXT_attachment_feedback_loop_layout_dynamic_state */
522       .attachmentFeedbackLoopDynamicState = true,
523 
524       /* VK_KHR_ray_query */
525       .rayQuery = true,
526 
527       /* VK_KHR_ray_tracing_maintenance1 */
528       .rayTracingMaintenance1 = true,
529       .rayTracingPipelineTraceRaysIndirect2 = true,
530 
531       /* VK_KHR_ray_tracing_pipeline */
532       .rayTracingPipeline = true,
533       .rayTracingPipelineShaderGroupHandleCaptureReplay = false,
534       .rayTracingPipelineShaderGroupHandleCaptureReplayMixed = false,
535       .rayTracingPipelineTraceRaysIndirect = true,
536       .rayTraversalPrimitiveCulling = true,
537 
538       /* VK_EXT_pipeline_library_group_handles */
539       .pipelineLibraryGroupHandles = true,
540 
541       /* VK_KHR_ray_tracing_position_fetch */
542       .rayTracingPositionFetch = true,
543 
544       /* VK_EXT_shader_object */
545       .shaderObject = true,
546 
547       /* VK_EXT_shader_replicated_composites */
548       .shaderReplicatedComposites = true,
549 
550       /* VK_KHR_shader_clock */
551       .shaderSubgroupClock = true,
552       .shaderDeviceClock = true,
553 
554       /* VK_EXT_texel_buffer_alignment */
555       .texelBufferAlignment = true,
556 
557       /* VK_EXT_transform_feedback */
558       .transformFeedback = true,
559       .geometryStreams = true,
560 
561       /* VK_EXT_conditional_rendering */
562       .conditionalRendering = true,
563       .inheritedConditionalRendering = false,
564 
565       /* VK_EXT_extended_dynamic_state */
566       .extendedDynamicState = true,
567 
568       /* VK_EXT_4444_formats */
569       .formatA4R4G4B4 = true,
570       .formatA4B4G4R4 = true,
571 
572       /* VK_EXT_custom_border_color */
573       .customBorderColors = true,
574       .customBorderColorWithoutFormat = true,
575 
576       /* VK_EXT_color_write_enable */
577       .colorWriteEnable = true,
578 
579       /* VK_EXT_image_2d_view_of_3d  */
580       .image2DViewOf3D = true,
581       .sampler2DViewOf3D = true,
582 
583       /* VK_EXT_provoking_vertex */
584       .provokingVertexLast = true,
585       .transformFeedbackPreservesProvokingVertex = true,
586 
587       /* VK_EXT_multi_draw */
588       .multiDraw = true,
589 
590       /* VK_EXT_pipeline_robustness */
591       .pipelineRobustness = true,
592 
593       /* VK_EXT_depth_clip_enable */
594       .depthClipEnable = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_DEPTH_CLAMP_ENABLE) != 0),
595 
596       /* VK_EXT_extended_dynamic_state2 */
597       .extendedDynamicState2 = true,
598       .extendedDynamicState2LogicOp = true,
599       .extendedDynamicState2PatchControlPoints = true,
600 
601       /* VK_EXT_extended_dynamic_state3 */
602       .extendedDynamicState3PolygonMode = true,
603       .extendedDynamicState3TessellationDomainOrigin = true,
604       .extendedDynamicState3DepthClampEnable = true,
605       .extendedDynamicState3DepthClipEnable = true,
606       .extendedDynamicState3LogicOpEnable = true,
607       .extendedDynamicState3SampleMask = true,
608       .extendedDynamicState3RasterizationSamples = true,
609       .extendedDynamicState3AlphaToCoverageEnable = true,
610       .extendedDynamicState3AlphaToOneEnable = true,
611       .extendedDynamicState3DepthClipNegativeOneToOne = true,
612       .extendedDynamicState3RasterizationStream = false,
613       .extendedDynamicState3ConservativeRasterizationMode = false,
614       .extendedDynamicState3ExtraPrimitiveOverestimationSize = false,
615       .extendedDynamicState3LineRasterizationMode = true,
616       .extendedDynamicState3LineStippleEnable = true,
617       .extendedDynamicState3ProvokingVertexMode = true,
618       .extendedDynamicState3SampleLocationsEnable = false,
619       .extendedDynamicState3ColorBlendEnable = true,
620       .extendedDynamicState3ColorBlendEquation = true,
621       .extendedDynamicState3ColorWriteMask = true,
622       .extendedDynamicState3ViewportWScalingEnable = false,
623       .extendedDynamicState3ViewportSwizzle = false,
624       .extendedDynamicState3ShadingRateImageEnable = false,
625       .extendedDynamicState3CoverageToColorEnable = false,
626       .extendedDynamicState3CoverageToColorLocation = false,
627       .extendedDynamicState3CoverageModulationMode = false,
628       .extendedDynamicState3CoverageModulationTableEnable = false,
629       .extendedDynamicState3CoverageModulationTable = false,
630       .extendedDynamicState3CoverageReductionMode = false,
631       .extendedDynamicState3RepresentativeFragmentTestEnable = false,
632       .extendedDynamicState3ColorBlendAdvanced = false,
633 
634       /* VK_EXT_dynamic_rendering_unused_attachments */
635       .dynamicRenderingUnusedAttachments = true,
636 
637       /* VK_EXT_robustness2 */
638       .robustBufferAccess2 = true,
639       .robustImageAccess2 = true,
640       .nullDescriptor = true,
641 
642       /* VK_NV_device_generated_commands */
643       .deviceGeneratedCommandsNV = true,
644 
645       /* VK_EXT_primitive_topology_list_restart */
646       .primitiveTopologyListRestart = true,
647       .primitiveTopologyPatchListRestart = true,
648 
649       /* VK_EXT_graphics_pipeline_library */
650       .graphicsPipelineLibrary = true,
651 
652       /* VK_EXT_shader_atomic_float */
653       .shaderBufferFloat32Atomics =    true,
654       .shaderBufferFloat32AtomicAdd =  true,
655       .shaderBufferFloat64Atomics =    false,
656       .shaderBufferFloat64AtomicAdd =  false,
657       .shaderSharedFloat32Atomics =    true,
658       .shaderSharedFloat32AtomicAdd =  true,
659       .shaderSharedFloat64Atomics =    false,
660       .shaderSharedFloat64AtomicAdd =  false,
661       .shaderImageFloat32Atomics =     true,
662       .shaderImageFloat32AtomicAdd =   true,
663       .sparseImageFloat32Atomics =     DETECT_OS_LINUX,
664       .sparseImageFloat32AtomicAdd =   DETECT_OS_LINUX,
665 
666       /* VK_EXT_shader_atomic_float2 */
667       .shaderBufferFloat16Atomics      = false,
668       .shaderBufferFloat16AtomicAdd    = false,
669       .shaderBufferFloat16AtomicMinMax = false,
670       .shaderBufferFloat32AtomicMinMax = LLVM_VERSION_MAJOR >= 15,
671       .shaderBufferFloat64AtomicMinMax = false,
672       .shaderSharedFloat16Atomics      = false,
673       .shaderSharedFloat16AtomicAdd    = false,
674       .shaderSharedFloat16AtomicMinMax = false,
675       .shaderSharedFloat32AtomicMinMax = LLVM_VERSION_MAJOR >= 15,
676       .shaderSharedFloat64AtomicMinMax = false,
677       .shaderImageFloat32AtomicMinMax  = LLVM_VERSION_MAJOR >= 15,
678       .sparseImageFloat32AtomicMinMax  = false,
679 
680       /* VK_EXT_memory_priority */
681       .memoryPriority = true,
682 
683       /* VK_EXT_legacy_vertex_attributes */
684       .legacyVertexAttributes = true,
685 
686       /* VK_EXT_pageable_device_local_memory */
687       .pageableDeviceLocalMemory = true,
688 
689       /* VK_EXT_nested_command_buffer */
690       .nestedCommandBuffer = true,
691       .nestedCommandBufferRendering = true,
692       .nestedCommandBufferSimultaneousUse = true,
693 
694       /* VK_KHR_dynamic_rendering_local_read */
695       .dynamicRenderingLocalRead = true,
696 
697       /* VK_EXT_mesh_shader */
698       .taskShader = true,
699       .meshShader = true,
700       .multiviewMeshShader = false,
701       .primitiveFragmentShadingRateMeshShader = false,
702       .meshShaderQueries = true,
703 
704       /* host_image_copy */
705       .hostImageCopy = true,
706 
707       /* maintenance5 */
708       .maintenance5 = true,
709 
710       /* VK_EXT_ycbcr_2plane_444_formats */
711       .ycbcr2plane444Formats = true,
712 
713       /* VK_EXT_ycbcr_image_arrays */
714       .ycbcrImageArrays = true,
715 
716       /* maintenance6 */
717       .maintenance6 = true,
718       /* maintenance7 */
719       .maintenance7 = true,
720 
721       /* VK_KHR_shader_expect_assume */
722       .shaderExpectAssume = true,
723 
724       /* VK_KHR_shader_maximal_reconvergence */
725       .shaderMaximalReconvergence = true,
726 
727       /* VK_AMDX_shader_enqueue */
728 #ifdef VK_ENABLE_BETA_EXTENSIONS
729       .shaderEnqueue = true,
730 #endif
731 
732 #ifdef LVP_USE_WSI_PLATFORM
733       /* VK_EXT_swapchain_maintenance1 */
734       .swapchainMaintenance1 = true,
735 #endif
736 
737       /* VK_KHR_shader_relaxed_extended_instruction */
738       .shaderRelaxedExtendedInstruction = true,
739    };
740 }
741 
742 extern unsigned lp_native_vector_width;
743 
744 static VkImageLayout lvp_host_copy_image_layouts[] = {
745    VK_IMAGE_LAYOUT_GENERAL,
746    VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
747    VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
748    VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
749    VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
750    VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
751    VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
752    VK_IMAGE_LAYOUT_PREINITIALIZED,
753    VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL,
754    VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL,
755    VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL,
756    VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL,
757    VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL,
758    VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL,
759    VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL,
760    VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL,
761    VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
762    VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR,
763    VK_IMAGE_LAYOUT_VIDEO_DECODE_SRC_KHR,
764    VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR,
765    VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR,
766    VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT,
767    VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR,
768 };
769 
770 static void
lvp_get_properties(const struct lvp_physical_device * device,struct vk_properties * p)771 lvp_get_properties(const struct lvp_physical_device *device, struct vk_properties *p)
772 {
773    VkSampleCountFlags sample_counts = VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT;
774 
775    uint64_t grid_size[3], block_size[3];
776    uint64_t max_threads_per_block, max_local_size;
777 
778    device->pscreen->get_compute_param(device->pscreen, PIPE_SHADER_IR_NIR,
779                                        PIPE_COMPUTE_CAP_MAX_GRID_SIZE, grid_size);
780    device->pscreen->get_compute_param(device->pscreen, PIPE_SHADER_IR_NIR,
781                                        PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE, block_size);
782    device->pscreen->get_compute_param(device->pscreen, PIPE_SHADER_IR_NIR,
783                                        PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK,
784                                        &max_threads_per_block);
785    device->pscreen->get_compute_param(device->pscreen, PIPE_SHADER_IR_NIR,
786                                        PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE,
787                                        &max_local_size);
788 
789    const uint64_t max_render_targets = device->pscreen->get_param(device->pscreen, PIPE_CAP_MAX_RENDER_TARGETS);
790 
791    int texel_buffer_alignment = device->pscreen->get_param(device->pscreen, PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT);
792 
793    STATIC_ASSERT(sizeof(struct lp_descriptor) <= 256);
794    *p = (struct vk_properties) {
795       /* Vulkan 1.0 */
796       .apiVersion = LVP_API_VERSION,
797       .driverVersion = 1,
798       .vendorID = VK_VENDOR_ID_MESA,
799       .deviceID = 0,
800       .deviceType = VK_PHYSICAL_DEVICE_TYPE_CPU,
801       .maxImageDimension1D                      = device->pscreen->get_param(device->pscreen, PIPE_CAP_MAX_TEXTURE_2D_SIZE),
802       .maxImageDimension2D                      = device->pscreen->get_param(device->pscreen, PIPE_CAP_MAX_TEXTURE_2D_SIZE),
803       .maxImageDimension3D                      = (1 << device->pscreen->get_param(device->pscreen, PIPE_CAP_MAX_TEXTURE_3D_LEVELS)),
804       .maxImageDimensionCube                    = (1 << device->pscreen->get_param(device->pscreen, PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS)),
805       .maxImageArrayLayers                      = device->pscreen->get_param(device->pscreen, PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS),
806       .maxTexelBufferElements                   = device->pscreen->get_param(device->pscreen, PIPE_CAP_MAX_TEXEL_BUFFER_ELEMENTS_UINT),
807       .maxUniformBufferRange                    = min_shader_param(device->pscreen, PIPE_SHADER_CAP_MAX_CONST_BUFFER0_SIZE),
808       .maxStorageBufferRange                    = device->pscreen->get_param(device->pscreen, PIPE_CAP_MAX_SHADER_BUFFER_SIZE_UINT),
809       .maxPushConstantsSize                     = MAX_PUSH_CONSTANTS_SIZE,
810       .maxMemoryAllocationCount                 = UINT32_MAX,
811       .maxSamplerAllocationCount                = 32 * 1024,
812       .bufferImageGranularity                   = 64, /* A cache line */
813       .sparseAddressSpaceSize                   = 2UL*1024*1024*1024,
814       .maxBoundDescriptorSets                   = MAX_SETS,
815       .maxPerStageDescriptorSamplers            = MAX_DESCRIPTORS,
816       .maxPerStageDescriptorUniformBuffers      = MAX_DESCRIPTORS,
817       .maxPerStageDescriptorStorageBuffers      = MAX_DESCRIPTORS,
818       .maxPerStageDescriptorSampledImages       = MAX_DESCRIPTORS,
819       .maxPerStageDescriptorStorageImages       = MAX_DESCRIPTORS,
820       .maxPerStageDescriptorInputAttachments    = MAX_DESCRIPTORS,
821       .maxPerStageResources                     = MAX_DESCRIPTORS,
822       .maxDescriptorSetSamplers                 = MAX_DESCRIPTORS,
823       .maxDescriptorSetUniformBuffers           = MAX_DESCRIPTORS,
824       .maxDescriptorSetUniformBuffersDynamic    = MAX_DESCRIPTORS,
825       .maxDescriptorSetStorageBuffers           = MAX_DESCRIPTORS,
826       .maxDescriptorSetStorageBuffersDynamic    = MAX_DESCRIPTORS,
827       .maxDescriptorSetSampledImages            = MAX_DESCRIPTORS,
828       .maxDescriptorSetStorageImages            = MAX_DESCRIPTORS,
829       .maxDescriptorSetInputAttachments         = MAX_DESCRIPTORS,
830       .maxVertexInputAttributes                 = 32,
831       .maxVertexInputBindings                   = 32,
832       .maxVertexInputAttributeOffset            = 2047,
833       .maxVertexInputBindingStride              = 2048,
834       .maxVertexOutputComponents                = 128,
835       .maxTessellationGenerationLevel           = 64,
836       .maxTessellationPatchSize                 = 32,
837       .maxTessellationControlPerVertexInputComponents = 128,
838       .maxTessellationControlPerVertexOutputComponents = 128,
839       .maxTessellationControlPerPatchOutputComponents = 128,
840       .maxTessellationControlTotalOutputComponents = 4096,
841       .maxTessellationEvaluationInputComponents = 128,
842       .maxTessellationEvaluationOutputComponents = 128,
843       .maxGeometryShaderInvocations             = device->pscreen->get_param(device->pscreen, PIPE_CAP_MAX_GS_INVOCATIONS),
844       .maxGeometryInputComponents               = 64,
845       .maxGeometryOutputComponents              = 128,
846       .maxGeometryOutputVertices                = device->pscreen->get_param(device->pscreen, PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES),
847       .maxGeometryTotalOutputComponents         = device->pscreen->get_param(device->pscreen, PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS),
848       .maxFragmentInputComponents               = 128,
849       .maxFragmentOutputAttachments             = 8,
850       .maxFragmentDualSrcAttachments            = 2,
851       .maxFragmentCombinedOutputResources       = max_render_targets +
852                                                   device->pscreen->get_shader_param(device->pscreen, MESA_SHADER_FRAGMENT,
853                                                      PIPE_SHADER_CAP_MAX_SHADER_BUFFERS) +
854                                                   device->pscreen->get_shader_param(device->pscreen, MESA_SHADER_FRAGMENT,
855                                                      PIPE_SHADER_CAP_MAX_SHADER_IMAGES),
856       .maxComputeSharedMemorySize               = max_local_size,
857       .maxComputeWorkGroupCount                 = { grid_size[0], grid_size[1], grid_size[2] },
858       .maxComputeWorkGroupInvocations           = max_threads_per_block,
859       .maxComputeWorkGroupSize                  = { block_size[0], block_size[1], block_size[2] },
860       .subPixelPrecisionBits                    = device->pscreen->get_param(device->pscreen, PIPE_CAP_RASTERIZER_SUBPIXEL_BITS),
861       .subTexelPrecisionBits                    = 8,
862       .mipmapPrecisionBits                      = 6,
863       .maxDrawIndexedIndexValue                 = UINT32_MAX,
864       .maxDrawIndirectCount                     = UINT32_MAX,
865       .maxSamplerLodBias                        = 16,
866       .maxSamplerAnisotropy                     = 16,
867       .maxViewports                             = device->pscreen->get_param(device->pscreen, PIPE_CAP_MAX_VIEWPORTS),
868       .maxViewportDimensions                    = { (1 << 14), (1 << 14) },
869       .viewportBoundsRange                      = { -32768.0, 32768.0 },
870       .viewportSubPixelBits                     = device->pscreen->get_param(device->pscreen, PIPE_CAP_VIEWPORT_SUBPIXEL_BITS),
871       .minMemoryMapAlignment                    = device->pscreen->get_param(device->pscreen, PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT),
872       .minTexelBufferOffsetAlignment            = device->pscreen->get_param(device->pscreen, PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT),
873       .minUniformBufferOffsetAlignment          = device->pscreen->get_param(device->pscreen, PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT),
874       .minStorageBufferOffsetAlignment          = device->pscreen->get_param(device->pscreen, PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT),
875       .minTexelOffset                           = device->pscreen->get_param(device->pscreen, PIPE_CAP_MIN_TEXEL_OFFSET),
876       .maxTexelOffset                           = device->pscreen->get_param(device->pscreen, PIPE_CAP_MAX_TEXEL_OFFSET),
877       .minTexelGatherOffset                     = device->pscreen->get_param(device->pscreen, PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET),
878       .maxTexelGatherOffset                     = device->pscreen->get_param(device->pscreen, PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET),
879       .minInterpolationOffset                   = -2, /* FIXME */
880       .maxInterpolationOffset                   = 2, /* FIXME */
881       .subPixelInterpolationOffsetBits          = 8, /* FIXME */
882       .maxFramebufferWidth                      = device->pscreen->get_param(device->pscreen, PIPE_CAP_MAX_TEXTURE_2D_SIZE),
883       .maxFramebufferHeight                     = device->pscreen->get_param(device->pscreen, PIPE_CAP_MAX_TEXTURE_2D_SIZE),
884       .maxFramebufferLayers                     = device->pscreen->get_param(device->pscreen, PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS),
885       .framebufferColorSampleCounts             = sample_counts,
886       .framebufferDepthSampleCounts             = sample_counts,
887       .framebufferStencilSampleCounts           = sample_counts,
888       .framebufferNoAttachmentsSampleCounts     = sample_counts,
889       .maxColorAttachments                      = max_render_targets,
890       .sampledImageColorSampleCounts            = sample_counts,
891       .sampledImageIntegerSampleCounts          = sample_counts,
892       .sampledImageDepthSampleCounts            = sample_counts,
893       .sampledImageStencilSampleCounts          = sample_counts,
894       .storageImageSampleCounts                 = sample_counts,
895       .maxSampleMaskWords                       = 1,
896       .timestampComputeAndGraphics              = true,
897       .timestampPeriod                          = 1,
898       .maxClipDistances                         = 8,
899       .maxCullDistances                         = 8,
900       .maxCombinedClipAndCullDistances          = 8,
901       .discreteQueuePriorities                  = 2,
902       .pointSizeRange                           = { 0.0, device->pscreen->get_paramf(device->pscreen, PIPE_CAPF_MAX_POINT_SIZE) },
903       .lineWidthRange                           = { 1.0, device->pscreen->get_paramf(device->pscreen, PIPE_CAPF_MAX_LINE_WIDTH) },
904       .pointSizeGranularity                     = (1.0 / 8.0),
905       .lineWidthGranularity                     = 1.0 / 128.0,
906       .strictLines                              = true,
907       .standardSampleLocations                  = true,
908       .optimalBufferCopyOffsetAlignment         = 128,
909       .optimalBufferCopyRowPitchAlignment       = 128,
910       .nonCoherentAtomSize                      = 64,
911       .sparseResidencyStandard2DBlockShape      = true,
912       .sparseResidencyStandard2DMultisampleBlockShape = true,
913       .sparseResidencyStandard3DBlockShape      = true,
914 
915       /* Vulkan 1.1 */
916       /* The LUID is for Windows. */
917       .deviceLUIDValid = false,
918       .deviceNodeMask = 0,
919 
920       .subgroupSize = lp_native_vector_width / 32,
921       .subgroupSupportedStages = VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_TASK_BIT_EXT | VK_SHADER_STAGE_MESH_BIT_EXT,
922       .subgroupSupportedOperations = VK_SUBGROUP_FEATURE_BASIC_BIT | VK_SUBGROUP_FEATURE_VOTE_BIT | VK_SUBGROUP_FEATURE_ARITHMETIC_BIT | VK_SUBGROUP_FEATURE_BALLOT_BIT,
923       .subgroupQuadOperationsInAllStages = false,
924 
925       .pointClippingBehavior = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES,
926       .maxMultiviewViewCount = 6,
927       .maxMultiviewInstanceIndex = INT_MAX,
928       .protectedNoFault = false,
929       .maxPerSetDescriptors = MAX_DESCRIPTORS,
930       .maxMemoryAllocationSize = (1u << 31),
931 
932       /* Vulkan 1.2 */
933       .driverID = VK_DRIVER_ID_MESA_LLVMPIPE,
934 
935       .conformanceVersion = (VkConformanceVersion){
936          .major = 1,
937          .minor = 3,
938          .subminor = 1,
939          .patch = 1,
940       },
941 
942       .denormBehaviorIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL,
943       .roundingModeIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL,
944       .shaderDenormFlushToZeroFloat16 = false,
945       .shaderDenormPreserveFloat16 = false,
946       .shaderRoundingModeRTEFloat16 = true,
947       .shaderRoundingModeRTZFloat16 = false,
948       .shaderSignedZeroInfNanPreserveFloat16 = true,
949 
950       .shaderDenormFlushToZeroFloat32 = false,
951       .shaderDenormPreserveFloat32 = false,
952       .shaderRoundingModeRTEFloat32 = true,
953       .shaderRoundingModeRTZFloat32 = false,
954       .shaderSignedZeroInfNanPreserveFloat32 = true,
955 
956       .shaderDenormFlushToZeroFloat64 = false,
957       .shaderDenormPreserveFloat64 = false,
958       .shaderRoundingModeRTEFloat64 = true,
959       .shaderRoundingModeRTZFloat64 = false,
960       .shaderSignedZeroInfNanPreserveFloat64 = true,
961 
962       .maxUpdateAfterBindDescriptorsInAllPools = UINT32_MAX,
963       .shaderUniformBufferArrayNonUniformIndexingNative = true,
964       .shaderSampledImageArrayNonUniformIndexingNative = true,
965       .shaderStorageBufferArrayNonUniformIndexingNative = true,
966       .shaderStorageImageArrayNonUniformIndexingNative = true,
967       .shaderInputAttachmentArrayNonUniformIndexingNative = true,
968       .robustBufferAccessUpdateAfterBind = true,
969       .quadDivergentImplicitLod = true,
970       .maxPerStageDescriptorUpdateAfterBindSamplers = MAX_DESCRIPTORS,
971       .maxPerStageDescriptorUpdateAfterBindUniformBuffers = MAX_DESCRIPTORS,
972       .maxPerStageDescriptorUpdateAfterBindStorageBuffers = MAX_DESCRIPTORS,
973       .maxPerStageDescriptorUpdateAfterBindSampledImages = MAX_DESCRIPTORS,
974       .maxPerStageDescriptorUpdateAfterBindStorageImages = MAX_DESCRIPTORS,
975       .maxPerStageDescriptorUpdateAfterBindInputAttachments = MAX_DESCRIPTORS,
976       .maxPerStageUpdateAfterBindResources = MAX_DESCRIPTORS,
977       .maxDescriptorSetUpdateAfterBindSamplers = MAX_DESCRIPTORS,
978       .maxDescriptorSetUpdateAfterBindUniformBuffers = MAX_DESCRIPTORS,
979       .maxDescriptorSetUpdateAfterBindUniformBuffersDynamic = MAX_DESCRIPTORS,
980       .maxDescriptorSetUpdateAfterBindStorageBuffers = MAX_DESCRIPTORS,
981       .maxDescriptorSetUpdateAfterBindStorageBuffersDynamic = MAX_DESCRIPTORS,
982       .maxDescriptorSetUpdateAfterBindSampledImages = MAX_DESCRIPTORS,
983       .maxDescriptorSetUpdateAfterBindStorageImages = MAX_DESCRIPTORS,
984       .maxDescriptorSetUpdateAfterBindInputAttachments = MAX_DESCRIPTORS,
985 
986       .supportedDepthResolveModes = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT | VK_RESOLVE_MODE_AVERAGE_BIT,
987       .supportedStencilResolveModes = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT,
988       .independentResolveNone = false,
989       .independentResolve = false,
990 
991       .filterMinmaxImageComponentMapping = true,
992       .filterMinmaxSingleComponentFormats = true,
993 
994       .maxTimelineSemaphoreValueDifference = UINT64_MAX,
995       .framebufferIntegerColorSampleCounts = VK_SAMPLE_COUNT_1_BIT,
996 
997       /* Vulkan 1.3 */
998       .minSubgroupSize = lp_native_vector_width / 32,
999       .maxSubgroupSize = lp_native_vector_width / 32,
1000       .maxComputeWorkgroupSubgroups = 32,
1001       .requiredSubgroupSizeStages = VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT,
1002       .maxInlineUniformTotalSize = MAX_DESCRIPTOR_UNIFORM_BLOCK_SIZE * MAX_PER_STAGE_DESCRIPTOR_UNIFORM_BLOCKS * MAX_SETS,
1003       .maxInlineUniformBlockSize = MAX_DESCRIPTOR_UNIFORM_BLOCK_SIZE,
1004       .maxPerStageDescriptorInlineUniformBlocks = MAX_PER_STAGE_DESCRIPTOR_UNIFORM_BLOCKS,
1005       .maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks = MAX_PER_STAGE_DESCRIPTOR_UNIFORM_BLOCKS,
1006       .maxDescriptorSetInlineUniformBlocks = MAX_PER_STAGE_DESCRIPTOR_UNIFORM_BLOCKS,
1007       .maxDescriptorSetUpdateAfterBindInlineUniformBlocks = MAX_PER_STAGE_DESCRIPTOR_UNIFORM_BLOCKS,
1008       .storageTexelBufferOffsetAlignmentBytes = texel_buffer_alignment,
1009       .storageTexelBufferOffsetSingleTexelAlignment = true,
1010       .uniformTexelBufferOffsetAlignmentBytes = texel_buffer_alignment,
1011       .uniformTexelBufferOffsetSingleTexelAlignment = true,
1012       .maxBufferSize = UINT32_MAX,
1013 
1014       /* VK_KHR_push_descriptor */
1015       .maxPushDescriptors = MAX_PUSH_DESCRIPTORS,
1016 
1017       /* VK_EXT_host_image_copy */
1018       .pCopySrcLayouts = lvp_host_copy_image_layouts,
1019       .copySrcLayoutCount = ARRAY_SIZE(lvp_host_copy_image_layouts),
1020       .pCopyDstLayouts = lvp_host_copy_image_layouts,
1021       .copyDstLayoutCount = ARRAY_SIZE(lvp_host_copy_image_layouts),
1022       .identicalMemoryTypeRequirements = VK_FALSE,
1023 
1024       /* VK_EXT_transform_feedback */
1025       .maxTransformFeedbackStreams = device->pscreen->get_param(device->pscreen, PIPE_CAP_MAX_VERTEX_STREAMS),
1026       .maxTransformFeedbackBuffers = device->pscreen->get_param(device->pscreen, PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS),
1027       .maxTransformFeedbackBufferSize = UINT32_MAX,
1028       .maxTransformFeedbackStreamDataSize = 512,
1029       .maxTransformFeedbackBufferDataSize = 512,
1030       .maxTransformFeedbackBufferDataStride = 512,
1031       .transformFeedbackQueries = true,
1032       .transformFeedbackStreamsLinesTriangles = false,
1033       .transformFeedbackRasterizationStreamSelect = false,
1034       .transformFeedbackDraw = true,
1035 
1036       /* VK_KHR_maintenance5 */
1037       /* FIXME No idea about most of these ones. */
1038       .earlyFragmentMultisampleCoverageAfterSampleCounting = true,
1039       .earlyFragmentSampleMaskTestBeforeSampleCounting = false,
1040       .depthStencilSwizzleOneSupport = false,
1041       .polygonModePointSize = true, /* This one is correct. */
1042       .nonStrictSinglePixelWideLinesUseParallelogram = false,
1043       .nonStrictWideLinesUseParallelogram = false,
1044 
1045       /* maintenance6 */
1046       .maxCombinedImageSamplerDescriptorCount = 3,
1047 
1048       /* VK_EXT_extended_dynamic_state3 */
1049       .dynamicPrimitiveTopologyUnrestricted = VK_TRUE,
1050 
1051       /* VK_EXT_line_rasterization */
1052       .lineSubPixelPrecisionBits = device->pscreen->get_param(device->pscreen, PIPE_CAP_RASTERIZER_SUBPIXEL_BITS),
1053 
1054       /* VK_NV_device_generated_commands */
1055       .maxGraphicsShaderGroupCount = 1<<12,
1056       .maxIndirectSequenceCount = 1<<20,
1057       .maxIndirectCommandsTokenCount = MAX_DGC_TOKENS,
1058       .maxIndirectCommandsStreamCount = MAX_DGC_STREAMS,
1059       .maxIndirectCommandsTokenOffset = 2047,
1060       .maxIndirectCommandsStreamStride = 2048,
1061       .minSequencesCountBufferOffsetAlignment = 4,
1062       .minSequencesIndexBufferOffsetAlignment = 4,
1063       .minIndirectCommandsBufferOffsetAlignment = 4,
1064 
1065       /* VK_EXT_external_memory_host */
1066       .minImportedHostPointerAlignment = 4096,
1067 
1068       /* VK_EXT_custom_border_color */
1069       .maxCustomBorderColorSamplers = 32 * 1024,
1070 
1071       /* VK_EXT_provoking_vertex */
1072       .provokingVertexModePerPipeline = true,
1073       .transformFeedbackPreservesTriangleFanProvokingVertex = true,
1074 
1075       /* VK_EXT_multi_draw */
1076       .maxMultiDrawCount = 2048,
1077 
1078       /* VK_EXT_pipeline_robustness */
1079       .defaultRobustnessStorageBuffers = VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_2_EXT,
1080       .defaultRobustnessUniformBuffers = VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_2_EXT,
1081       .defaultRobustnessVertexInputs = VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_2_EXT,
1082       .defaultRobustnessImages = VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_ROBUST_IMAGE_ACCESS_2_EXT,
1083 
1084       /* VK_EXT_descriptor_buffer */
1085       .combinedImageSamplerDescriptorSingleArray = VK_TRUE,
1086       .bufferlessPushDescriptors = VK_TRUE,
1087       .descriptorBufferOffsetAlignment = 4,
1088       .maxDescriptorBufferBindings = MAX_SETS,
1089       .maxResourceDescriptorBufferBindings = MAX_SETS,
1090       .maxSamplerDescriptorBufferBindings = MAX_SETS,
1091       .maxEmbeddedImmutableSamplerBindings = MAX_SETS,
1092       .maxEmbeddedImmutableSamplers = 2032,
1093       .bufferCaptureReplayDescriptorDataSize = 0,
1094       .imageCaptureReplayDescriptorDataSize = 0,
1095       .imageViewCaptureReplayDescriptorDataSize = 0,
1096       .samplerCaptureReplayDescriptorDataSize = 0,
1097       .accelerationStructureCaptureReplayDescriptorDataSize = 0,
1098       .samplerDescriptorSize = sizeof(struct lp_descriptor),
1099       .combinedImageSamplerDescriptorSize = sizeof(struct lp_descriptor),
1100       .sampledImageDescriptorSize = sizeof(struct lp_descriptor),
1101       .storageImageDescriptorSize = sizeof(struct lp_descriptor),
1102       .uniformTexelBufferDescriptorSize = sizeof(struct lp_descriptor),
1103       .robustUniformTexelBufferDescriptorSize = sizeof(struct lp_descriptor),
1104       .storageTexelBufferDescriptorSize = sizeof(struct lp_descriptor),
1105       .robustStorageTexelBufferDescriptorSize = sizeof(struct lp_descriptor),
1106       .uniformBufferDescriptorSize = sizeof(struct lp_descriptor),
1107       .robustUniformBufferDescriptorSize = sizeof(struct lp_descriptor),
1108       .storageBufferDescriptorSize = sizeof(struct lp_descriptor),
1109       .robustStorageBufferDescriptorSize = sizeof(struct lp_descriptor),
1110       .inputAttachmentDescriptorSize = sizeof(struct lp_descriptor),
1111       .accelerationStructureDescriptorSize = sizeof(struct lp_descriptor),
1112       .maxSamplerDescriptorBufferRange = UINT32_MAX,
1113       .maxResourceDescriptorBufferRange = UINT32_MAX,
1114       .resourceDescriptorBufferAddressSpaceSize = UINT32_MAX,
1115       .samplerDescriptorBufferAddressSpaceSize = UINT32_MAX,
1116       .descriptorBufferAddressSpaceSize = UINT32_MAX,
1117 
1118       /* VK_EXT_graphics_pipeline_library */
1119       .graphicsPipelineLibraryFastLinking = VK_TRUE,
1120       .graphicsPipelineLibraryIndependentInterpolationDecoration = VK_TRUE,
1121 
1122       /* VK_EXT_robustness2 */
1123       .robustStorageBufferAccessSizeAlignment = 1,
1124       .robustUniformBufferAccessSizeAlignment = 1,
1125 
1126       /* VK_EXT_mesh_shader */
1127       .maxTaskWorkGroupTotalCount = 4194304,
1128       .maxTaskWorkGroupCount[0] = 65536,
1129       .maxTaskWorkGroupCount[1] = 65536,
1130       .maxTaskWorkGroupCount[2] = 65536,
1131       .maxTaskWorkGroupInvocations = 1024,
1132       .maxTaskWorkGroupSize[0] = 1024,
1133       .maxTaskWorkGroupSize[1] = 1024,
1134       .maxTaskWorkGroupSize[2] = 1024,
1135       .maxTaskPayloadSize = 16384,
1136       .maxTaskSharedMemorySize = 32768,
1137       .maxTaskPayloadAndSharedMemorySize = 32768,
1138 
1139       .maxMeshWorkGroupTotalCount = 4194304,
1140       .maxMeshWorkGroupCount[0] = 65536,
1141       .maxMeshWorkGroupCount[1] = 65536,
1142       .maxMeshWorkGroupCount[2] = 65536,
1143       .maxMeshWorkGroupInvocations = 1024,
1144       .maxMeshWorkGroupSize[0] = 1024,
1145       .maxMeshWorkGroupSize[1] = 1024,
1146       .maxMeshWorkGroupSize[2] = 1024,
1147       .maxMeshOutputMemorySize = 32768, /* 32K min required */
1148       .maxMeshSharedMemorySize = 28672,     /* 28K min required */
1149       .maxMeshOutputComponents = 128, /* 32x vec4 min required */
1150       .maxMeshOutputVertices = 256,
1151       .maxMeshOutputPrimitives = 256,
1152       .maxMeshOutputLayers = 8,
1153       .meshOutputPerVertexGranularity = 1,
1154       .meshOutputPerPrimitiveGranularity = 1,
1155       .maxPreferredTaskWorkGroupInvocations = 64,
1156       .maxPreferredMeshWorkGroupInvocations = 128,
1157       .prefersLocalInvocationVertexOutput = true,
1158       .prefersLocalInvocationPrimitiveOutput = true,
1159       .prefersCompactVertexOutput = true,
1160       .prefersCompactPrimitiveOutput = false,
1161 
1162       /* VK_AMDX_shader_enqueue */
1163 #ifdef VK_ENABLE_BETA_EXTENSIONS
1164       .maxExecutionGraphDepth = 32,
1165       .maxExecutionGraphShaderOutputNodes = LVP_MAX_EXEC_GRAPH_PAYLOADS,
1166       .maxExecutionGraphShaderPayloadSize = 0xFFFF,
1167       .maxExecutionGraphShaderPayloadCount = LVP_MAX_EXEC_GRAPH_PAYLOADS,
1168       .executionGraphDispatchAddressAlignment = 4,
1169 #endif
1170 
1171       /* VK_KHR_acceleration_structure */
1172       .maxGeometryCount = (1 << 24) - 1,
1173       .maxInstanceCount = (1 << 24) - 1,
1174       .maxPrimitiveCount = (1 << 24) - 1,
1175       .maxPerStageDescriptorAccelerationStructures = MAX_DESCRIPTORS,
1176       .maxPerStageDescriptorUpdateAfterBindAccelerationStructures = MAX_DESCRIPTORS,
1177       .maxDescriptorSetAccelerationStructures = MAX_DESCRIPTORS,
1178       .maxDescriptorSetUpdateAfterBindAccelerationStructures = MAX_DESCRIPTORS,
1179       .minAccelerationStructureScratchOffsetAlignment = 128,
1180 
1181       /* VK_EXT_legacy_vertex_attributes */
1182       .nativeUnalignedPerformance = true,
1183 
1184       /* VK_KHR_ray_tracing_pipeline */
1185       .shaderGroupHandleSize = LVP_RAY_TRACING_GROUP_HANDLE_SIZE,
1186       .maxRayRecursionDepth = 31,    /* Minimum allowed for DXR. */
1187       .maxShaderGroupStride = 16384, /* dummy */
1188       /* This isn't strictly necessary, but Doom Eternal breaks if the
1189        * alignment is any lower. */
1190       .shaderGroupBaseAlignment = 32,
1191       .shaderGroupHandleCaptureReplaySize = 0,
1192       .maxRayDispatchInvocationCount = 1024 * 1024 * 64,
1193       .shaderGroupHandleAlignment = 16,
1194       .maxRayHitAttributeSize = LVP_RAY_HIT_ATTRIBS_SIZE,
1195    };
1196 
1197    /* Vulkan 1.0 */
1198    strcpy(p->deviceName, device->pscreen->get_name(device->pscreen));
1199    lvp_device_get_cache_uuid(p->pipelineCacheUUID);
1200 
1201    /* Vulkan 1.1 */
1202    device->pscreen->get_device_uuid(device->pscreen, (char*)(p->deviceUUID));
1203    device->pscreen->get_driver_uuid(device->pscreen, (char*)(p->driverUUID));
1204    memset(p->deviceLUID, 0, VK_LUID_SIZE);
1205 
1206 #if LLVM_VERSION_MAJOR >= 10
1207    p->subgroupSupportedOperations |= VK_SUBGROUP_FEATURE_SHUFFLE_BIT | VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT | VK_SUBGROUP_FEATURE_QUAD_BIT;
1208 #endif
1209 
1210    /* Vulkan 1.2 */
1211    snprintf(p->driverName, VK_MAX_DRIVER_NAME_SIZE, "llvmpipe");
1212    snprintf(p->driverInfo, VK_MAX_DRIVER_INFO_SIZE, "Mesa " PACKAGE_VERSION MESA_GIT_SHA1
1213 #ifdef MESA_LLVM_VERSION_STRING
1214             " (LLVM " MESA_LLVM_VERSION_STRING ")"
1215 #endif
1216            );
1217 
1218    /* VK_EXT_nested_command_buffer */
1219    p->maxCommandBufferNestingLevel = UINT32_MAX;
1220 
1221    /* VK_EXT_host_image_copy */
1222    lvp_device_get_cache_uuid(p->optimalTilingLayoutUUID);
1223 
1224    /* VK_EXT_vertex_attribute_divisor */
1225    if (device->pscreen->get_param(device->pscreen, PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR) != 0)
1226       p->maxVertexAttribDivisor = UINT32_MAX;
1227    else
1228       p->maxVertexAttribDivisor = 1;
1229 
1230    /* maintenance6 */
1231    p->blockTexelViewCompatibleMultipleLayers = true,
1232 
1233    /* maintenance7 */
1234    p->robustFragmentShadingRateAttachmentAccess = false;
1235    p->separateDepthStencilAttachmentAccess = true;
1236    p->maxDescriptorSetTotalUniformBuffersDynamic = MAX_DESCRIPTORS;
1237    p->maxDescriptorSetTotalStorageBuffersDynamic = MAX_DESCRIPTORS;
1238    p->maxDescriptorSetTotalBuffersDynamic = MAX_DESCRIPTORS;
1239    p->maxDescriptorSetUpdateAfterBindTotalUniformBuffersDynamic = MAX_DESCRIPTORS;
1240    p->maxDescriptorSetUpdateAfterBindTotalStorageBuffersDynamic = MAX_DESCRIPTORS;
1241    p->maxDescriptorSetUpdateAfterBindTotalBuffersDynamic = MAX_DESCRIPTORS;
1242 
1243    /* VK_EXT_shader_object */
1244    /* this is basically unsupported */
1245    lvp_device_get_cache_uuid(p->shaderBinaryUUID);
1246    p->shaderBinaryVersion = 1;
1247 
1248    /* VK_EXT_mesh_shader */
1249    p->maxMeshPayloadAndSharedMemorySize = p->maxTaskPayloadSize + p->maxMeshSharedMemorySize; /* 28K min required */
1250    p->maxMeshPayloadAndOutputMemorySize = p->maxTaskPayloadSize + p->maxMeshOutputMemorySize; /* 47K min required */
1251 }
1252 
1253 static VkResult VKAPI_CALL
lvp_physical_device_init(struct lvp_physical_device * device,struct lvp_instance * instance,struct pipe_loader_device * pld)1254 lvp_physical_device_init(struct lvp_physical_device *device,
1255                          struct lvp_instance *instance,
1256                          struct pipe_loader_device *pld)
1257 {
1258    VkResult result;
1259 
1260    struct vk_physical_device_dispatch_table dispatch_table;
1261    vk_physical_device_dispatch_table_from_entrypoints(
1262       &dispatch_table, &lvp_physical_device_entrypoints, true);
1263    vk_physical_device_dispatch_table_from_entrypoints(
1264       &dispatch_table, &wsi_physical_device_entrypoints, false);
1265    result = vk_physical_device_init(&device->vk, &instance->vk,
1266                                     NULL, NULL, NULL, &dispatch_table);
1267    if (result != VK_SUCCESS) {
1268       vk_error(instance, result);
1269       goto fail;
1270    }
1271    device->pld = pld;
1272 
1273    device->pscreen = pipe_loader_create_screen_vk(device->pld, true, false);
1274    if (!device->pscreen)
1275       return vk_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY);
1276    for (unsigned i = 0; i < ARRAY_SIZE(device->drv_options); i++)
1277       device->drv_options[i] = device->pscreen->get_compiler_options(device->pscreen, PIPE_SHADER_IR_NIR, i);
1278 
1279    device->sync_timeline_type = vk_sync_timeline_get_type(&lvp_pipe_sync_type);
1280    device->sync_types[0] = &lvp_pipe_sync_type;
1281    device->sync_types[1] = &device->sync_timeline_type.sync;
1282    device->sync_types[2] = NULL;
1283    device->vk.supported_sync_types = device->sync_types;
1284 
1285    device->max_images = device->pscreen->get_shader_param(device->pscreen, MESA_SHADER_FRAGMENT, PIPE_SHADER_CAP_MAX_SHADER_IMAGES);
1286    device->vk.supported_extensions = lvp_device_extensions_supported;
1287 #ifdef HAVE_LIBDRM
1288    int dmabuf_bits = DRM_PRIME_CAP_EXPORT | DRM_PRIME_CAP_IMPORT;
1289    int supported_dmabuf_bits = device->pscreen->get_param(device->pscreen, PIPE_CAP_DMABUF);
1290    /* if import or export is supported then EXT_external_memory_dma_buf is supported */
1291    if (supported_dmabuf_bits)
1292       device->vk.supported_extensions.EXT_external_memory_dma_buf = true;
1293    if ((supported_dmabuf_bits & dmabuf_bits) == dmabuf_bits)
1294       device->vk.supported_extensions.EXT_image_drm_format_modifier = true;
1295    if (device->pscreen->get_param(device->pscreen, PIPE_CAP_NATIVE_FENCE_FD)) {
1296       device->vk.supported_extensions.KHR_external_semaphore_fd = true;
1297       device->vk.supported_extensions.KHR_external_fence_fd = true;
1298    }
1299    if (supported_dmabuf_bits & DRM_PRIME_CAP_IMPORT)
1300       device->vk.supported_extensions.ANDROID_external_memory_android_hardware_buffer = true;
1301 #endif
1302 
1303    /* SNORM blending on llvmpipe fails CTS - disable by default */
1304    device->snorm_blend = debug_get_bool_option("LVP_SNORM_BLEND", false);
1305 
1306    lvp_get_features(device, &device->vk.supported_features);
1307    lvp_get_properties(device, &device->vk.properties);
1308 
1309 #ifdef LVP_USE_WSI_PLATFORM
1310    result = lvp_init_wsi(device);
1311    if (result != VK_SUCCESS) {
1312       vk_physical_device_finish(&device->vk);
1313       vk_error(instance, result);
1314       goto fail;
1315    }
1316 #endif
1317 
1318    return VK_SUCCESS;
1319  fail:
1320    return result;
1321 }
1322 
1323 static void VKAPI_CALL
lvp_physical_device_finish(struct lvp_physical_device * device)1324 lvp_physical_device_finish(struct lvp_physical_device *device)
1325 {
1326 #ifdef LVP_USE_WSI_PLATFORM
1327    lvp_finish_wsi(device);
1328 #endif
1329    device->pscreen->destroy(device->pscreen);
1330    vk_physical_device_finish(&device->vk);
1331 }
1332 
1333 static void
lvp_destroy_physical_device(struct vk_physical_device * device)1334 lvp_destroy_physical_device(struct vk_physical_device *device)
1335 {
1336    lvp_physical_device_finish((struct lvp_physical_device *)device);
1337    vk_free(&device->instance->alloc, device);
1338 }
1339 
1340 static VkResult
1341 lvp_enumerate_physical_devices(struct vk_instance *vk_instance);
1342 
lvp_CreateInstance(const VkInstanceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkInstance * pInstance)1343 VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateInstance(
1344    const VkInstanceCreateInfo*                 pCreateInfo,
1345    const VkAllocationCallbacks*                pAllocator,
1346    VkInstance*                                 pInstance)
1347 {
1348    struct lvp_instance *instance;
1349    VkResult result;
1350 
1351    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO);
1352 
1353    if (pAllocator == NULL)
1354       pAllocator = vk_default_allocator();
1355 
1356    instance = vk_zalloc(pAllocator, sizeof(*instance), 8,
1357                         VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
1358    if (!instance)
1359       return vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY);
1360 
1361    struct vk_instance_dispatch_table dispatch_table;
1362    vk_instance_dispatch_table_from_entrypoints(
1363       &dispatch_table, &lvp_instance_entrypoints, true);
1364    vk_instance_dispatch_table_from_entrypoints(
1365       &dispatch_table, &wsi_instance_entrypoints, false);
1366 
1367    result = vk_instance_init(&instance->vk,
1368                              &lvp_instance_extensions_supported,
1369                              &dispatch_table,
1370                              pCreateInfo,
1371                              pAllocator);
1372    if (result != VK_SUCCESS) {
1373       vk_free(pAllocator, instance);
1374       return vk_error(NULL, result);
1375    }
1376 
1377    instance->apiVersion = LVP_API_VERSION;
1378 
1379    instance->vk.physical_devices.enumerate = lvp_enumerate_physical_devices;
1380    instance->vk.physical_devices.destroy = lvp_destroy_physical_device;
1381 
1382    //   VG(VALGRIND_CREATE_MEMPOOL(instance, 0, false));
1383 
1384 #if DETECT_OS_ANDROID
1385    vk_android_init_ugralloc();
1386 #endif
1387 
1388    *pInstance = lvp_instance_to_handle(instance);
1389 
1390    return VK_SUCCESS;
1391 }
1392 
lvp_DestroyInstance(VkInstance _instance,const VkAllocationCallbacks * pAllocator)1393 VKAPI_ATTR void VKAPI_CALL lvp_DestroyInstance(
1394    VkInstance                                  _instance,
1395    const VkAllocationCallbacks*                pAllocator)
1396 {
1397    LVP_FROM_HANDLE(lvp_instance, instance, _instance);
1398 
1399    if (!instance)
1400       return;
1401 
1402 #if DETECT_OS_ANDROID
1403    vk_android_destroy_ugralloc();
1404 #endif
1405 
1406    pipe_loader_release(&instance->devs, instance->num_devices);
1407 
1408    vk_instance_finish(&instance->vk);
1409    vk_free(&instance->vk.alloc, instance);
1410 }
1411 
1412 #if defined(HAVE_DRI)
lvp_get_image(struct dri_drawable * dri_drawable,int x,int y,unsigned width,unsigned height,unsigned stride,void * data)1413 static void lvp_get_image(struct dri_drawable *dri_drawable,
1414                           int x, int y, unsigned width, unsigned height, unsigned stride,
1415                           void *data)
1416 {
1417 
1418 }
1419 
lvp_put_image(struct dri_drawable * dri_drawable,void * data,unsigned width,unsigned height)1420 static void lvp_put_image(struct dri_drawable *dri_drawable,
1421                           void *data, unsigned width, unsigned height)
1422 {
1423    fprintf(stderr, "put image %dx%d\n", width, height);
1424 }
1425 
lvp_put_image2(struct dri_drawable * dri_drawable,void * data,int x,int y,unsigned width,unsigned height,unsigned stride)1426 static void lvp_put_image2(struct dri_drawable *dri_drawable,
1427                            void *data, int x, int y, unsigned width, unsigned height,
1428                            unsigned stride)
1429 {
1430    fprintf(stderr, "put image 2 %d,%d %dx%d\n", x, y, width, height);
1431 }
1432 
1433 static struct drisw_loader_funcs lvp_sw_lf = {
1434    .get_image = lvp_get_image,
1435    .put_image = lvp_put_image,
1436    .put_image2 = lvp_put_image2,
1437 };
1438 #endif
1439 
1440 static VkResult
lvp_enumerate_physical_devices(struct vk_instance * vk_instance)1441 lvp_enumerate_physical_devices(struct vk_instance *vk_instance)
1442 {
1443    struct lvp_instance *instance =
1444       container_of(vk_instance, struct lvp_instance, vk);
1445 
1446    /* sw only for now */
1447    instance->num_devices = pipe_loader_sw_probe(NULL, 0);
1448 
1449    assert(instance->num_devices == 1);
1450 
1451 #if defined(HAVE_DRI)
1452    pipe_loader_sw_probe_dri(&instance->devs, &lvp_sw_lf);
1453 #else
1454    pipe_loader_sw_probe_null(&instance->devs);
1455 #endif
1456 
1457    struct lvp_physical_device *device =
1458       vk_zalloc2(&instance->vk.alloc, NULL, sizeof(*device), 8,
1459                  VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
1460    if (!device)
1461       return vk_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY);
1462 
1463    VkResult result = lvp_physical_device_init(device, instance, &instance->devs[0]);
1464    if (result == VK_SUCCESS)
1465       list_addtail(&device->vk.link, &instance->vk.physical_devices.list);
1466    else
1467       vk_free(&vk_instance->alloc, device);
1468 
1469    return result;
1470 }
1471 
1472 void
lvp_device_get_cache_uuid(void * uuid)1473 lvp_device_get_cache_uuid(void *uuid)
1474 {
1475    memset(uuid, 'a', VK_UUID_SIZE);
1476    if (MESA_GIT_SHA1[0])
1477       /* debug build */
1478       memcpy(uuid, &MESA_GIT_SHA1[4], MIN2(strlen(MESA_GIT_SHA1) - 4, VK_UUID_SIZE));
1479    else
1480       /* release build */
1481       memcpy(uuid, PACKAGE_VERSION, MIN2(strlen(PACKAGE_VERSION), VK_UUID_SIZE));
1482 }
1483 
lvp_GetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice,uint32_t * pCount,VkQueueFamilyProperties2 * pQueueFamilyProperties)1484 VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceQueueFamilyProperties2(
1485    VkPhysicalDevice                            physicalDevice,
1486    uint32_t*                                   pCount,
1487    VkQueueFamilyProperties2                   *pQueueFamilyProperties)
1488 {
1489    VK_OUTARRAY_MAKE_TYPED(VkQueueFamilyProperties2, out, pQueueFamilyProperties, pCount);
1490 
1491    VkQueueFamilyGlobalPriorityPropertiesKHR *prio = vk_find_struct(pQueueFamilyProperties, QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_KHR);
1492    if (prio) {
1493       prio->priorityCount = 4;
1494       prio->priorities[0] = VK_QUEUE_GLOBAL_PRIORITY_LOW_KHR;
1495       prio->priorities[1] = VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_KHR;
1496       prio->priorities[2] = VK_QUEUE_GLOBAL_PRIORITY_HIGH_KHR;
1497       prio->priorities[3] = VK_QUEUE_GLOBAL_PRIORITY_REALTIME_KHR;
1498    }
1499 
1500    vk_outarray_append_typed(VkQueueFamilyProperties2, &out, p) {
1501       p->queueFamilyProperties = (VkQueueFamilyProperties) {
1502          .queueFlags = VK_QUEUE_GRAPHICS_BIT |
1503          VK_QUEUE_COMPUTE_BIT |
1504          VK_QUEUE_TRANSFER_BIT |
1505          (DETECT_OS_LINUX ? VK_QUEUE_SPARSE_BINDING_BIT : 0),
1506          .queueCount = 1,
1507          .timestampValidBits = 64,
1508          .minImageTransferGranularity = (VkExtent3D) { 1, 1, 1 },
1509       };
1510    }
1511 }
1512 
lvp_GetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice,VkPhysicalDeviceMemoryProperties * pMemoryProperties)1513 VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceMemoryProperties(
1514    VkPhysicalDevice                            physicalDevice,
1515    VkPhysicalDeviceMemoryProperties*           pMemoryProperties)
1516 {
1517    pMemoryProperties->memoryTypeCount = 1;
1518    pMemoryProperties->memoryTypes[0] = (VkMemoryType) {
1519       .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
1520       VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
1521       VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
1522       VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
1523       .heapIndex = 0,
1524    };
1525 
1526    VkDeviceSize low_size = 3ULL*1024*1024*1024;
1527    VkDeviceSize total_size;
1528    os_get_total_physical_memory(&total_size);
1529    pMemoryProperties->memoryHeapCount = 1;
1530    pMemoryProperties->memoryHeaps[0] = (VkMemoryHeap) {
1531       .size = low_size,
1532       .flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT,
1533    };
1534    if (sizeof(void*) > sizeof(uint32_t))
1535       pMemoryProperties->memoryHeaps[0].size = total_size;
1536 }
1537 
lvp_GetPhysicalDeviceMemoryProperties2(VkPhysicalDevice physicalDevice,VkPhysicalDeviceMemoryProperties2 * pMemoryProperties)1538 VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceMemoryProperties2(
1539    VkPhysicalDevice                            physicalDevice,
1540    VkPhysicalDeviceMemoryProperties2          *pMemoryProperties)
1541 {
1542    lvp_GetPhysicalDeviceMemoryProperties(physicalDevice,
1543                                          &pMemoryProperties->memoryProperties);
1544    VkPhysicalDeviceMemoryBudgetPropertiesEXT *props = vk_find_struct(pMemoryProperties, PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT);
1545    if (props) {
1546       props->heapBudget[0] = pMemoryProperties->memoryProperties.memoryHeaps[0].size;
1547       if (os_get_available_system_memory(&props->heapUsage[0])) {
1548          props->heapUsage[0] = props->heapBudget[0] - props->heapUsage[0];
1549       } else {
1550          props->heapUsage[0] = 0;
1551       }
1552       memset(&props->heapBudget[1], 0, sizeof(props->heapBudget[0]) * (VK_MAX_MEMORY_HEAPS - 1));
1553       memset(&props->heapUsage[1], 0, sizeof(props->heapUsage[0]) * (VK_MAX_MEMORY_HEAPS - 1));
1554    }
1555 }
1556 
1557 VKAPI_ATTR VkResult VKAPI_CALL
lvp_GetMemoryHostPointerPropertiesEXT(VkDevice _device,VkExternalMemoryHandleTypeFlagBits handleType,const void * pHostPointer,VkMemoryHostPointerPropertiesEXT * pMemoryHostPointerProperties)1558 lvp_GetMemoryHostPointerPropertiesEXT(
1559    VkDevice _device,
1560    VkExternalMemoryHandleTypeFlagBits handleType,
1561    const void *pHostPointer,
1562    VkMemoryHostPointerPropertiesEXT *pMemoryHostPointerProperties)
1563 {
1564    switch (handleType) {
1565    case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT: {
1566       pMemoryHostPointerProperties->memoryTypeBits = 1;
1567       return VK_SUCCESS;
1568    }
1569    default:
1570       return VK_ERROR_INVALID_EXTERNAL_HANDLE;
1571    }
1572 }
1573 
lvp_GetInstanceProcAddr(VkInstance _instance,const char * pName)1574 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL lvp_GetInstanceProcAddr(
1575    VkInstance                                  _instance,
1576    const char*                                 pName)
1577 {
1578    VK_FROM_HANDLE(vk_instance, instance, _instance);
1579    return vk_instance_get_proc_addr(instance,
1580                                     &lvp_instance_entrypoints,
1581                                     pName);
1582 }
1583 
1584 /* Windows will use a dll definition file to avoid build errors. */
1585 #ifdef _WIN32
1586 #undef PUBLIC
1587 #define PUBLIC
1588 #endif
1589 
1590 /* The loader wants us to expose a second GetInstanceProcAddr function
1591  * to work around certain LD_PRELOAD issues seen in apps.
1592  */
1593 PUBLIC
vk_icdGetInstanceProcAddr(VkInstance instance,const char * pName)1594 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(
1595    VkInstance                                  instance,
1596    const char*                                 pName)
1597 {
1598    return lvp_GetInstanceProcAddr(instance, pName);
1599 }
1600 
1601 static void
destroy_pipelines(struct lvp_queue * queue)1602 destroy_pipelines(struct lvp_queue *queue)
1603 {
1604    simple_mtx_lock(&queue->lock);
1605    while (util_dynarray_contains(&queue->pipeline_destroys, struct lvp_pipeline*)) {
1606       lvp_pipeline_destroy(queue->device, util_dynarray_pop(&queue->pipeline_destroys, struct lvp_pipeline*), true);
1607    }
1608    simple_mtx_unlock(&queue->lock);
1609 }
1610 
1611 static VkResult
lvp_queue_submit(struct vk_queue * vk_queue,struct vk_queue_submit * submit)1612 lvp_queue_submit(struct vk_queue *vk_queue,
1613                  struct vk_queue_submit *submit)
1614 {
1615    struct lvp_queue *queue = container_of(vk_queue, struct lvp_queue, vk);
1616 
1617    VkResult result = vk_sync_wait_many(&queue->device->vk,
1618                                        submit->wait_count, submit->waits,
1619                                        VK_SYNC_WAIT_COMPLETE, UINT64_MAX);
1620    if (result != VK_SUCCESS)
1621       return result;
1622 
1623    simple_mtx_lock(&queue->lock);
1624 
1625    for (uint32_t i = 0; i < submit->buffer_bind_count; i++) {
1626       VkSparseBufferMemoryBindInfo *bind = &submit->buffer_binds[i];
1627 
1628       lvp_buffer_bind_sparse(queue->device, queue, bind);
1629    }
1630 
1631    for (uint32_t i = 0; i < submit->image_opaque_bind_count; i++) {
1632       VkSparseImageOpaqueMemoryBindInfo *bind = &submit->image_opaque_binds[i];
1633 
1634       lvp_image_bind_opaque_sparse(queue->device, queue, bind);
1635    }
1636 
1637    for (uint32_t i = 0; i < submit->image_bind_count; i++) {
1638       VkSparseImageMemoryBindInfo *bind = &submit->image_binds[i];
1639 
1640       lvp_image_bind_sparse(queue->device, queue, bind);
1641    }
1642 
1643    for (uint32_t i = 0; i < submit->command_buffer_count; i++) {
1644       struct lvp_cmd_buffer *cmd_buffer =
1645          container_of(submit->command_buffers[i], struct lvp_cmd_buffer, vk);
1646 
1647       lvp_execute_cmds(queue->device, queue, cmd_buffer);
1648    }
1649 
1650    simple_mtx_unlock(&queue->lock);
1651 
1652    if (submit->command_buffer_count > 0)
1653       queue->ctx->flush(queue->ctx, &queue->last_fence, 0);
1654 
1655    for (uint32_t i = 0; i < submit->signal_count; i++) {
1656       struct lvp_pipe_sync *sync =
1657          vk_sync_as_lvp_pipe_sync(submit->signals[i].sync);
1658       lvp_pipe_sync_signal_with_fence(queue->device, sync, queue->last_fence);
1659    }
1660    destroy_pipelines(queue);
1661 
1662    return VK_SUCCESS;
1663 }
1664 
1665 static VkResult
lvp_queue_init(struct lvp_device * device,struct lvp_queue * queue,const VkDeviceQueueCreateInfo * create_info,uint32_t index_in_family)1666 lvp_queue_init(struct lvp_device *device, struct lvp_queue *queue,
1667                const VkDeviceQueueCreateInfo *create_info,
1668                uint32_t index_in_family)
1669 {
1670    VkResult result = vk_queue_init(&queue->vk, &device->vk, create_info,
1671                                    index_in_family);
1672    if (result != VK_SUCCESS)
1673       return result;
1674 
1675    result = vk_queue_enable_submit_thread(&queue->vk);
1676    if (result != VK_SUCCESS) {
1677       vk_queue_finish(&queue->vk);
1678       return result;
1679    }
1680 
1681    queue->device = device;
1682 
1683    queue->ctx = device->pscreen->context_create(device->pscreen, NULL, PIPE_CONTEXT_ROBUST_BUFFER_ACCESS);
1684    queue->cso = cso_create_context(queue->ctx, CSO_NO_VBUF);
1685    queue->uploader = u_upload_create(queue->ctx, 1024 * 1024, PIPE_BIND_CONSTANT_BUFFER, PIPE_USAGE_STREAM, 0);
1686 
1687    queue->vk.driver_submit = lvp_queue_submit;
1688 
1689    simple_mtx_init(&queue->lock, mtx_plain);
1690    util_dynarray_init(&queue->pipeline_destroys, NULL);
1691 
1692    return VK_SUCCESS;
1693 }
1694 
1695 static void
lvp_queue_finish(struct lvp_queue * queue)1696 lvp_queue_finish(struct lvp_queue *queue)
1697 {
1698    vk_queue_finish(&queue->vk);
1699 
1700    destroy_pipelines(queue);
1701    simple_mtx_destroy(&queue->lock);
1702    util_dynarray_fini(&queue->pipeline_destroys);
1703 
1704    u_upload_destroy(queue->uploader);
1705    cso_destroy_context(queue->cso);
1706    queue->ctx->destroy(queue->ctx);
1707 }
1708 
lvp_CreateDevice(VkPhysicalDevice physicalDevice,const VkDeviceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDevice * pDevice)1709 VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateDevice(
1710    VkPhysicalDevice                            physicalDevice,
1711    const VkDeviceCreateInfo*                   pCreateInfo,
1712    const VkAllocationCallbacks*                pAllocator,
1713    VkDevice*                                   pDevice)
1714 {
1715    LVP_FROM_HANDLE(lvp_physical_device, physical_device, physicalDevice);
1716    struct lvp_device *device;
1717    struct lvp_instance *instance = (struct lvp_instance *)physical_device->vk.instance;
1718 
1719    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO);
1720 
1721    size_t state_size = lvp_get_rendering_state_size();
1722    device = vk_zalloc2(&physical_device->vk.instance->alloc, pAllocator,
1723                        sizeof(*device) + state_size, 8,
1724                        VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
1725    if (!device)
1726       return vk_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY);
1727 
1728    device->queue.state = device + 1;
1729    device->poison_mem = debug_get_bool_option("LVP_POISON_MEMORY", false);
1730    device->print_cmds = debug_get_bool_option("LVP_CMD_DEBUG", false);
1731 
1732    struct vk_device_dispatch_table dispatch_table;
1733    vk_device_dispatch_table_from_entrypoints(&dispatch_table,
1734       &lvp_device_entrypoints, true);
1735    lvp_add_enqueue_cmd_entrypoints(&dispatch_table);
1736    vk_device_dispatch_table_from_entrypoints(&dispatch_table,
1737       &wsi_device_entrypoints, false);
1738    VkResult result = vk_device_init(&device->vk,
1739                                     &physical_device->vk,
1740                                     &dispatch_table, pCreateInfo,
1741                                     pAllocator);
1742    if (result != VK_SUCCESS) {
1743       vk_free(&device->vk.alloc, device);
1744       return result;
1745    }
1746 
1747    vk_device_enable_threaded_submit(&device->vk);
1748    device->vk.command_buffer_ops = &lvp_cmd_buffer_ops;
1749 
1750    device->instance = (struct lvp_instance *)physical_device->vk.instance;
1751    device->physical_device = physical_device;
1752 
1753    device->pscreen = physical_device->pscreen;
1754 
1755    assert(pCreateInfo->queueCreateInfoCount == 1);
1756    assert(pCreateInfo->pQueueCreateInfos[0].queueFamilyIndex == 0);
1757    assert(pCreateInfo->pQueueCreateInfos[0].queueCount == 1);
1758    result = lvp_queue_init(device, &device->queue, pCreateInfo->pQueueCreateInfos, 0);
1759    if (result != VK_SUCCESS) {
1760       vk_free(&device->vk.alloc, device);
1761       return result;
1762    }
1763 
1764    nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_FRAGMENT, NULL, "dummy_frag");
1765    struct pipe_shader_state shstate = {0};
1766    shstate.type = PIPE_SHADER_IR_NIR;
1767    shstate.ir.nir = b.shader;
1768    device->noop_fs = device->queue.ctx->create_fs_state(device->queue.ctx, &shstate);
1769    _mesa_hash_table_init(&device->bda, NULL, _mesa_hash_pointer, _mesa_key_pointer_equal);
1770    simple_mtx_init(&device->bda_lock, mtx_plain);
1771 
1772    uint32_t zero = 0;
1773    device->zero_buffer = pipe_buffer_create_with_data(device->queue.ctx, 0, PIPE_USAGE_IMMUTABLE, sizeof(uint32_t), &zero);
1774 
1775    device->null_texture_handle = (void *)(uintptr_t)device->queue.ctx->create_texture_handle(device->queue.ctx,
1776       &(struct pipe_sampler_view){ 0 }, NULL);
1777    device->null_image_handle = (void *)(uintptr_t)device->queue.ctx->create_image_handle(device->queue.ctx,
1778       &(struct pipe_image_view){ 0 });
1779 
1780    util_dynarray_init(&device->bda_texture_handles, NULL);
1781    util_dynarray_init(&device->bda_image_handles, NULL);
1782 
1783    device->group_handle_alloc = 1;
1784 
1785    *pDevice = lvp_device_to_handle(device);
1786 
1787    return VK_SUCCESS;
1788 
1789 }
1790 
lvp_DestroyDevice(VkDevice _device,const VkAllocationCallbacks * pAllocator)1791 VKAPI_ATTR void VKAPI_CALL lvp_DestroyDevice(
1792    VkDevice                                    _device,
1793    const VkAllocationCallbacks*                pAllocator)
1794 {
1795    LVP_FROM_HANDLE(lvp_device, device, _device);
1796 
1797    util_dynarray_foreach(&device->bda_texture_handles, struct lp_texture_handle *, handle)
1798       device->queue.ctx->delete_texture_handle(device->queue.ctx, (uint64_t)(uintptr_t)*handle);
1799 
1800    util_dynarray_fini(&device->bda_texture_handles);
1801 
1802    util_dynarray_foreach(&device->bda_image_handles, struct lp_texture_handle *, handle)
1803       device->queue.ctx->delete_image_handle(device->queue.ctx, (uint64_t)(uintptr_t)*handle);
1804 
1805    util_dynarray_fini(&device->bda_image_handles);
1806 
1807    device->queue.ctx->delete_texture_handle(device->queue.ctx, (uint64_t)(uintptr_t)device->null_texture_handle);
1808    device->queue.ctx->delete_image_handle(device->queue.ctx, (uint64_t)(uintptr_t)device->null_image_handle);
1809 
1810    device->queue.ctx->delete_fs_state(device->queue.ctx, device->noop_fs);
1811 
1812    if (device->queue.last_fence)
1813       device->pscreen->fence_reference(device->pscreen, &device->queue.last_fence, NULL);
1814    ralloc_free(device->bda.table);
1815    simple_mtx_destroy(&device->bda_lock);
1816    pipe_resource_reference(&device->zero_buffer, NULL);
1817 
1818    lvp_queue_finish(&device->queue);
1819    vk_device_finish(&device->vk);
1820    vk_free(&device->vk.alloc, device);
1821 }
1822 
lvp_EnumerateInstanceExtensionProperties(const char * pLayerName,uint32_t * pPropertyCount,VkExtensionProperties * pProperties)1823 VKAPI_ATTR VkResult VKAPI_CALL lvp_EnumerateInstanceExtensionProperties(
1824    const char*                                 pLayerName,
1825    uint32_t*                                   pPropertyCount,
1826    VkExtensionProperties*                      pProperties)
1827 {
1828    if (pLayerName)
1829       return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT);
1830 
1831    return vk_enumerate_instance_extension_properties(
1832       &lvp_instance_extensions_supported, pPropertyCount, pProperties);
1833 }
1834 
lvp_EnumerateInstanceLayerProperties(uint32_t * pPropertyCount,VkLayerProperties * pProperties)1835 VKAPI_ATTR VkResult VKAPI_CALL lvp_EnumerateInstanceLayerProperties(
1836    uint32_t*                                   pPropertyCount,
1837    VkLayerProperties*                          pProperties)
1838 {
1839    if (pProperties == NULL) {
1840       *pPropertyCount = 0;
1841       return VK_SUCCESS;
1842    }
1843 
1844    /* None supported at this time */
1845    return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT);
1846 }
1847 
lvp_EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,uint32_t * pPropertyCount,VkLayerProperties * pProperties)1848 VKAPI_ATTR VkResult VKAPI_CALL lvp_EnumerateDeviceLayerProperties(
1849    VkPhysicalDevice                            physicalDevice,
1850    uint32_t*                                   pPropertyCount,
1851    VkLayerProperties*                          pProperties)
1852 {
1853    if (pProperties == NULL) {
1854       *pPropertyCount = 0;
1855       return VK_SUCCESS;
1856    }
1857 
1858    /* None supported at this time */
1859    return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT);
1860 }
1861 
1862 static void
set_mem_priority(struct lvp_device_memory * mem,int priority)1863 set_mem_priority(struct lvp_device_memory *mem, int priority)
1864 {
1865 #if DETECT_OS_LINUX
1866    if (priority) {
1867       int advice = 0;
1868 #ifdef MADV_COLD
1869       if (priority < 0)
1870          advice |= MADV_COLD;
1871 #endif
1872       if (priority > 0)
1873          advice |= MADV_WILLNEED;
1874       if (advice)
1875          madvise(mem->map, mem->size, advice);
1876    }
1877 #endif
1878 }
1879 
1880 static int
get_mem_priority(float priority)1881 get_mem_priority(float priority)
1882 {
1883    if (priority < 0.3)
1884       return -1;
1885    if (priority < 0.6)
1886       return 0;
1887    return priority = 1;
1888 }
1889 
lvp_AllocateMemory(VkDevice _device,const VkMemoryAllocateInfo * pAllocateInfo,const VkAllocationCallbacks * pAllocator,VkDeviceMemory * pMem)1890 VKAPI_ATTR VkResult VKAPI_CALL lvp_AllocateMemory(
1891    VkDevice                                    _device,
1892    const VkMemoryAllocateInfo*                 pAllocateInfo,
1893    const VkAllocationCallbacks*                pAllocator,
1894    VkDeviceMemory*                             pMem)
1895 {
1896    LVP_FROM_HANDLE(lvp_device, device, _device);
1897    struct lvp_device_memory *mem;
1898    ASSERTED const VkExportMemoryAllocateInfo *export_info = NULL;
1899    ASSERTED const VkImportMemoryFdInfoKHR *import_info = NULL;
1900 #if DETECT_OS_ANDROID
1901    ASSERTED const VkImportAndroidHardwareBufferInfoANDROID *ahb_import_info = NULL;
1902 #endif
1903    const VkImportMemoryHostPointerInfoEXT *host_ptr_info = NULL;
1904    VkResult error = VK_ERROR_OUT_OF_DEVICE_MEMORY;
1905    assert(pAllocateInfo->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);
1906    int priority = 0;
1907 
1908    if (pAllocateInfo->allocationSize == 0) {
1909       /* Apparently, this is allowed */
1910       *pMem = VK_NULL_HANDLE;
1911       return VK_SUCCESS;
1912    }
1913 
1914    vk_foreach_struct_const(ext, pAllocateInfo->pNext) {
1915       switch ((unsigned)ext->sType) {
1916       case VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT:
1917          host_ptr_info = (VkImportMemoryHostPointerInfoEXT*)ext;
1918          assert(host_ptr_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT);
1919          break;
1920       case VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO:
1921          export_info = (VkExportMemoryAllocateInfo*)ext;
1922          assert_memhandle_type(export_info->handleTypes);
1923          break;
1924       case VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR:
1925          import_info = (VkImportMemoryFdInfoKHR*)ext;
1926          assert_memhandle_type(import_info->handleType);
1927          break;
1928       case VK_STRUCTURE_TYPE_MEMORY_PRIORITY_ALLOCATE_INFO_EXT: {
1929          VkMemoryPriorityAllocateInfoEXT *prio = (VkMemoryPriorityAllocateInfoEXT*)ext;
1930          priority = get_mem_priority(prio->priority);
1931          break;
1932       }
1933 #if DETECT_OS_ANDROID
1934       case VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID: {
1935          ahb_import_info = (VkImportAndroidHardwareBufferInfoANDROID*)ext;
1936          break;
1937       }
1938 #endif
1939       default:
1940          break;
1941       }
1942    }
1943 
1944 #ifdef PIPE_MEMORY_FD
1945    if (import_info != NULL && import_info->fd < 0) {
1946       return vk_error(device->instance, VK_ERROR_INVALID_EXTERNAL_HANDLE);
1947    }
1948 #endif
1949 
1950    mem = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*mem), 8,
1951                    VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1952    if (mem == NULL)
1953       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
1954 
1955    vk_object_base_init(&device->vk, &mem->base,
1956                        VK_OBJECT_TYPE_DEVICE_MEMORY);
1957 
1958    mem->memory_type = LVP_DEVICE_MEMORY_TYPE_DEFAULT;
1959    mem->backed_fd = -1;
1960    mem->size = pAllocateInfo->allocationSize;
1961 
1962 #if DETECT_OS_ANDROID
1963    mem->android_hardware_buffer = NULL;
1964 #endif
1965 
1966    if (host_ptr_info) {
1967       mem->mem_alloc = (struct llvmpipe_memory_allocation) {
1968          .cpu_addr = host_ptr_info->pHostPointer,
1969       };
1970       mem->pmem = (void *)&mem->mem_alloc;
1971       mem->map = host_ptr_info->pHostPointer;
1972       mem->memory_type = LVP_DEVICE_MEMORY_TYPE_USER_PTR;
1973    }
1974 #if DETECT_OS_ANDROID
1975    else if(ahb_import_info) {
1976       error = lvp_import_ahb_memory(device, mem, ahb_import_info);
1977       if (error != VK_SUCCESS)
1978          goto fail;
1979    } else if(export_info &&
1980              (export_info->handleTypes & VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)) {
1981       error = lvp_create_ahb_memory(device, mem, pAllocateInfo);
1982       if (error != VK_SUCCESS)
1983          goto fail;
1984    }
1985 #endif
1986 #ifdef PIPE_MEMORY_FD
1987    else if(import_info && import_info->handleType) {
1988       bool dmabuf = import_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
1989       uint64_t size;
1990       if(!device->pscreen->import_memory_fd(device->pscreen, import_info->fd, &mem->pmem, &size, dmabuf)) {
1991          close(import_info->fd);
1992          error = VK_ERROR_INVALID_EXTERNAL_HANDLE;
1993          goto fail;
1994       }
1995       if(size < pAllocateInfo->allocationSize) {
1996          device->pscreen->free_memory_fd(device->pscreen, mem->pmem);
1997          close(import_info->fd);
1998          goto fail;
1999       }
2000       if (export_info && export_info->handleTypes == import_info->handleType) {
2001          mem->backed_fd = import_info->fd;
2002       }
2003       else {
2004          close(import_info->fd);
2005       }
2006 
2007       mem->size = size;
2008       mem->map = device->pscreen->map_memory(device->pscreen, mem->pmem);
2009       mem->memory_type = dmabuf ? LVP_DEVICE_MEMORY_TYPE_DMA_BUF : LVP_DEVICE_MEMORY_TYPE_OPAQUE_FD;
2010    }
2011    else if (export_info && export_info->handleTypes) {
2012       bool dmabuf = export_info->handleTypes == VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
2013       mem->pmem = device->pscreen->allocate_memory_fd(device->pscreen, pAllocateInfo->allocationSize, &mem->backed_fd, dmabuf);
2014       if (!mem->pmem || mem->backed_fd < 0) {
2015           goto fail;
2016       }
2017 
2018       mem->map = device->pscreen->map_memory(device->pscreen, mem->pmem);
2019       mem->memory_type = dmabuf ? LVP_DEVICE_MEMORY_TYPE_DMA_BUF : LVP_DEVICE_MEMORY_TYPE_OPAQUE_FD;
2020    }
2021 #endif
2022    else {
2023       mem->pmem = device->pscreen->allocate_memory(device->pscreen, pAllocateInfo->allocationSize);
2024       if (!mem->pmem) {
2025          goto fail;
2026       }
2027       mem->map = device->pscreen->map_memory(device->pscreen, mem->pmem);
2028       if (device->poison_mem) {
2029          /* this is a value that will definitely break things */
2030          memset(mem->map, UINT8_MAX / 2 + 1, pAllocateInfo->allocationSize);
2031       }
2032       set_mem_priority(mem, priority);
2033    }
2034 
2035    mem->type_index = pAllocateInfo->memoryTypeIndex;
2036 
2037    *pMem = lvp_device_memory_to_handle(mem);
2038 
2039    return VK_SUCCESS;
2040 
2041 fail:
2042    vk_free2(&device->vk.alloc, pAllocator, mem);
2043    return vk_error(device, error);
2044 }
2045 
lvp_FreeMemory(VkDevice _device,VkDeviceMemory _mem,const VkAllocationCallbacks * pAllocator)2046 VKAPI_ATTR void VKAPI_CALL lvp_FreeMemory(
2047    VkDevice                                    _device,
2048    VkDeviceMemory                              _mem,
2049    const VkAllocationCallbacks*                pAllocator)
2050 {
2051    LVP_FROM_HANDLE(lvp_device, device, _device);
2052    LVP_FROM_HANDLE(lvp_device_memory, mem, _mem);
2053 
2054    if (mem == NULL)
2055       return;
2056 
2057    if (mem->memory_type != LVP_DEVICE_MEMORY_TYPE_USER_PTR)
2058       device->pscreen->unmap_memory(device->pscreen, mem->pmem);
2059 
2060    switch(mem->memory_type) {
2061    case LVP_DEVICE_MEMORY_TYPE_DEFAULT:
2062       device->pscreen->free_memory(device->pscreen, mem->pmem);
2063       break;
2064 #ifdef PIPE_MEMORY_FD
2065    case LVP_DEVICE_MEMORY_TYPE_DMA_BUF:
2066    case LVP_DEVICE_MEMORY_TYPE_OPAQUE_FD:
2067       device->pscreen->free_memory_fd(device->pscreen, mem->pmem);
2068       if(mem->backed_fd >= 0)
2069          close(mem->backed_fd);
2070       break;
2071 #endif
2072    case LVP_DEVICE_MEMORY_TYPE_USER_PTR:
2073    default:
2074       break;
2075    }
2076    vk_object_base_finish(&mem->base);
2077    vk_free2(&device->vk.alloc, pAllocator, mem);
2078 
2079 }
2080 
lvp_MapMemory2KHR(VkDevice _device,const VkMemoryMapInfoKHR * pMemoryMapInfo,void ** ppData)2081 VKAPI_ATTR VkResult VKAPI_CALL lvp_MapMemory2KHR(
2082     VkDevice                                    _device,
2083     const VkMemoryMapInfoKHR*                   pMemoryMapInfo,
2084     void**                                      ppData)
2085 {
2086    LVP_FROM_HANDLE(lvp_device_memory, mem, pMemoryMapInfo->memory);
2087 
2088    if (mem == NULL) {
2089       *ppData = NULL;
2090       return VK_SUCCESS;
2091    }
2092 
2093    *ppData = (char *)mem->map + pMemoryMapInfo->offset;
2094    return VK_SUCCESS;
2095 }
2096 
lvp_UnmapMemory2KHR(VkDevice _device,const VkMemoryUnmapInfoKHR * pMemoryUnmapInfo)2097 VKAPI_ATTR VkResult VKAPI_CALL lvp_UnmapMemory2KHR(
2098     VkDevice                                    _device,
2099     const VkMemoryUnmapInfoKHR*                 pMemoryUnmapInfo)
2100 {
2101    return VK_SUCCESS;
2102 }
2103 
lvp_FlushMappedMemoryRanges(VkDevice _device,uint32_t memoryRangeCount,const VkMappedMemoryRange * pMemoryRanges)2104 VKAPI_ATTR VkResult VKAPI_CALL lvp_FlushMappedMemoryRanges(
2105    VkDevice                                    _device,
2106    uint32_t                                    memoryRangeCount,
2107    const VkMappedMemoryRange*                  pMemoryRanges)
2108 {
2109    return VK_SUCCESS;
2110 }
2111 
lvp_InvalidateMappedMemoryRanges(VkDevice _device,uint32_t memoryRangeCount,const VkMappedMemoryRange * pMemoryRanges)2112 VKAPI_ATTR VkResult VKAPI_CALL lvp_InvalidateMappedMemoryRanges(
2113    VkDevice                                    _device,
2114    uint32_t                                    memoryRangeCount,
2115    const VkMappedMemoryRange*                  pMemoryRanges)
2116 {
2117    return VK_SUCCESS;
2118 }
2119 
lvp_GetDeviceBufferMemoryRequirements(VkDevice _device,const VkDeviceBufferMemoryRequirements * pInfo,VkMemoryRequirements2 * pMemoryRequirements)2120 VKAPI_ATTR void VKAPI_CALL lvp_GetDeviceBufferMemoryRequirements(
2121     VkDevice                                    _device,
2122     const VkDeviceBufferMemoryRequirements*     pInfo,
2123     VkMemoryRequirements2*                      pMemoryRequirements)
2124 {
2125    pMemoryRequirements->memoryRequirements.memoryTypeBits = 1;
2126    pMemoryRequirements->memoryRequirements.alignment = 64;
2127 
2128    if (pInfo->pCreateInfo->flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) {
2129       uint64_t alignment;
2130       os_get_page_size(&alignment);
2131       pMemoryRequirements->memoryRequirements.alignment = alignment;
2132    }
2133    pMemoryRequirements->memoryRequirements.size = 0;
2134 
2135    VkBuffer _buffer;
2136    if (lvp_CreateBuffer(_device, pInfo->pCreateInfo, NULL, &_buffer) != VK_SUCCESS)
2137       return;
2138    LVP_FROM_HANDLE(lvp_buffer, buffer, _buffer);
2139    pMemoryRequirements->memoryRequirements.size = buffer->total_size;
2140    lvp_DestroyBuffer(_device, _buffer, NULL);
2141 }
2142 
lvp_GetDeviceImageMemoryRequirements(VkDevice _device,const VkDeviceImageMemoryRequirements * pInfo,VkMemoryRequirements2 * pMemoryRequirements)2143 VKAPI_ATTR void VKAPI_CALL lvp_GetDeviceImageMemoryRequirements(
2144     VkDevice                                    _device,
2145     const VkDeviceImageMemoryRequirements*     pInfo,
2146     VkMemoryRequirements2*                      pMemoryRequirements)
2147 {
2148    pMemoryRequirements->memoryRequirements.memoryTypeBits = 1;
2149    pMemoryRequirements->memoryRequirements.alignment = 0;
2150    pMemoryRequirements->memoryRequirements.size = 0;
2151 
2152    VkImage _image;
2153    if (lvp_CreateImage(_device, pInfo->pCreateInfo, NULL, &_image) != VK_SUCCESS)
2154       return;
2155    LVP_FROM_HANDLE(lvp_image, image, _image);
2156    pMemoryRequirements->memoryRequirements.size = image->size;
2157    pMemoryRequirements->memoryRequirements.alignment = image->alignment;
2158    lvp_DestroyImage(_device, _image, NULL);
2159 }
2160 
lvp_GetBufferMemoryRequirements(VkDevice device,VkBuffer _buffer,VkMemoryRequirements * pMemoryRequirements)2161 VKAPI_ATTR void VKAPI_CALL lvp_GetBufferMemoryRequirements(
2162    VkDevice                                    device,
2163    VkBuffer                                    _buffer,
2164    VkMemoryRequirements*                       pMemoryRequirements)
2165 {
2166    LVP_FROM_HANDLE(lvp_buffer, buffer, _buffer);
2167 
2168    pMemoryRequirements->alignment = 64;
2169    if (buffer->vk.create_flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) {
2170       uint64_t alignment;
2171       os_get_page_size(&alignment);
2172       pMemoryRequirements->alignment = alignment;
2173    }
2174    /* The Vulkan spec (git aaed022) says:
2175     *
2176     *    memoryTypeBits is a bitfield and contains one bit set for every
2177     *    supported memory type for the resource. The bit `1<<i` is set if and
2178     *    only if the memory type `i` in the VkPhysicalDeviceMemoryProperties
2179     *    structure for the physical device is supported.
2180     *
2181     * We support exactly one memory type.
2182     */
2183    pMemoryRequirements->memoryTypeBits = 1;
2184 
2185    pMemoryRequirements->size = buffer->total_size;
2186 }
2187 
lvp_GetBufferMemoryRequirements2(VkDevice device,const VkBufferMemoryRequirementsInfo2 * pInfo,VkMemoryRequirements2 * pMemoryRequirements)2188 VKAPI_ATTR void VKAPI_CALL lvp_GetBufferMemoryRequirements2(
2189    VkDevice                                     device,
2190    const VkBufferMemoryRequirementsInfo2       *pInfo,
2191    VkMemoryRequirements2                       *pMemoryRequirements)
2192 {
2193    lvp_GetBufferMemoryRequirements(device, pInfo->buffer,
2194                                    &pMemoryRequirements->memoryRequirements);
2195    vk_foreach_struct(ext, pMemoryRequirements->pNext) {
2196       switch (ext->sType) {
2197       case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {
2198          VkMemoryDedicatedRequirements *req =
2199             (VkMemoryDedicatedRequirements *) ext;
2200          req->requiresDedicatedAllocation = false;
2201          req->prefersDedicatedAllocation = req->requiresDedicatedAllocation;
2202          break;
2203       }
2204       default:
2205          break;
2206       }
2207    }
2208 }
2209 
lvp_GetImageMemoryRequirements(VkDevice device,VkImage _image,VkMemoryRequirements * pMemoryRequirements)2210 VKAPI_ATTR void VKAPI_CALL lvp_GetImageMemoryRequirements(
2211    VkDevice                                    device,
2212    VkImage                                     _image,
2213    VkMemoryRequirements*                       pMemoryRequirements)
2214 {
2215    LVP_FROM_HANDLE(lvp_image, image, _image);
2216    pMemoryRequirements->memoryTypeBits = 1;
2217 
2218    pMemoryRequirements->size = image->size;
2219    pMemoryRequirements->alignment = image->alignment;
2220 }
2221 
lvp_GetImageMemoryRequirements2(VkDevice device,const VkImageMemoryRequirementsInfo2 * pInfo,VkMemoryRequirements2 * pMemoryRequirements)2222 VKAPI_ATTR void VKAPI_CALL lvp_GetImageMemoryRequirements2(
2223    VkDevice                                    device,
2224    const VkImageMemoryRequirementsInfo2       *pInfo,
2225    VkMemoryRequirements2                      *pMemoryRequirements)
2226 {
2227    lvp_GetImageMemoryRequirements(device, pInfo->image,
2228                                   &pMemoryRequirements->memoryRequirements);
2229 
2230    vk_foreach_struct(ext, pMemoryRequirements->pNext) {
2231       switch (ext->sType) {
2232       case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {
2233          VkMemoryDedicatedRequirements *req =
2234             (VkMemoryDedicatedRequirements *) ext;
2235          req->requiresDedicatedAllocation = false;
2236          req->prefersDedicatedAllocation = req->requiresDedicatedAllocation;
2237          break;
2238       }
2239       default:
2240          break;
2241       }
2242    }
2243 }
2244 
lvp_GetDeviceMemoryCommitment(VkDevice device,VkDeviceMemory memory,VkDeviceSize * pCommittedMemoryInBytes)2245 VKAPI_ATTR void VKAPI_CALL lvp_GetDeviceMemoryCommitment(
2246    VkDevice                                    device,
2247    VkDeviceMemory                              memory,
2248    VkDeviceSize*                               pCommittedMemoryInBytes)
2249 {
2250    *pCommittedMemoryInBytes = 0;
2251 }
2252 
lvp_BindBufferMemory2(VkDevice _device,uint32_t bindInfoCount,const VkBindBufferMemoryInfo * pBindInfos)2253 VKAPI_ATTR VkResult VKAPI_CALL lvp_BindBufferMemory2(VkDevice _device,
2254                                uint32_t bindInfoCount,
2255                                const VkBindBufferMemoryInfo *pBindInfos)
2256 {
2257    LVP_FROM_HANDLE(lvp_device, device, _device);
2258    for (uint32_t i = 0; i < bindInfoCount; ++i) {
2259       LVP_FROM_HANDLE(lvp_device_memory, mem, pBindInfos[i].memory);
2260       LVP_FROM_HANDLE(lvp_buffer, buffer, pBindInfos[i].buffer);
2261       VkBindMemoryStatusKHR *status = (void*)vk_find_struct_const(&pBindInfos[i], BIND_MEMORY_STATUS_KHR);
2262 
2263       buffer->mem = mem;
2264       buffer->map = (char*)mem->map + pBindInfos[i].memoryOffset;
2265       buffer->offset = pBindInfos[i].memoryOffset;
2266       device->pscreen->resource_bind_backing(device->pscreen,
2267                                              buffer->bo,
2268                                              mem->pmem,
2269                                              0, 0,
2270                                              pBindInfos[i].memoryOffset);
2271       if (status)
2272          *status->pResult = VK_SUCCESS;
2273    }
2274    return VK_SUCCESS;
2275 }
2276 
2277 static VkResult
lvp_image_plane_bind(struct lvp_device * device,struct lvp_image_plane * plane,struct lvp_device_memory * mem,VkDeviceSize memory_offset,VkDeviceSize * plane_offset)2278 lvp_image_plane_bind(struct lvp_device *device,
2279                      struct lvp_image_plane *plane,
2280                      struct lvp_device_memory *mem,
2281                      VkDeviceSize memory_offset,
2282                      VkDeviceSize *plane_offset)
2283 {
2284    if (!device->pscreen->resource_bind_backing(device->pscreen,
2285                                                plane->bo,
2286                                                mem->pmem,
2287                                                0, 0,
2288                                                memory_offset + *plane_offset)) {
2289       /* This is probably caused by the texture being too large, so let's
2290        * report this as the *closest* allowed error-code. It's not ideal,
2291        * but it's unlikely that anyone will care too much.
2292        */
2293       return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
2294    }
2295    plane->pmem = mem->pmem;
2296    plane->memory_offset = memory_offset;
2297    plane->plane_offset = *plane_offset;
2298    *plane_offset += plane->size;
2299    return VK_SUCCESS;
2300 }
2301 
2302 
lvp_BindImageMemory2(VkDevice _device,uint32_t bindInfoCount,const VkBindImageMemoryInfo * pBindInfos)2303 VKAPI_ATTR VkResult VKAPI_CALL lvp_BindImageMemory2(VkDevice _device,
2304                               uint32_t bindInfoCount,
2305                               const VkBindImageMemoryInfo *pBindInfos)
2306 {
2307    LVP_FROM_HANDLE(lvp_device, device, _device);
2308    VkResult res = VK_SUCCESS;
2309    for (uint32_t i = 0; i < bindInfoCount; ++i) {
2310       const VkBindImageMemoryInfo *bind_info = &pBindInfos[i];
2311       LVP_FROM_HANDLE(lvp_device_memory, mem, bind_info->memory);
2312       LVP_FROM_HANDLE(lvp_image, image, bind_info->image);
2313       VkBindMemoryStatusKHR *status = (void*)vk_find_struct_const(&pBindInfos[i], BIND_MEMORY_STATUS_KHR);
2314       bool did_bind = false;
2315 
2316       if (!mem) {
2317          continue;
2318       }
2319 
2320 #ifdef LVP_USE_WSI_PLATFORM
2321       vk_foreach_struct_const(s, bind_info->pNext) {
2322          switch (s->sType) {
2323          case VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR: {
2324             const VkBindImageMemorySwapchainInfoKHR *swapchain_info =
2325                (const VkBindImageMemorySwapchainInfoKHR *) s;
2326             struct lvp_image *swapchain_image =
2327                lvp_swapchain_get_image(swapchain_info->swapchain,
2328                                        swapchain_info->imageIndex);
2329 
2330             image->planes[0].pmem = swapchain_image->planes[0].pmem;
2331             image->planes[0].memory_offset = swapchain_image->planes[0].memory_offset;
2332             device->pscreen->resource_bind_backing(device->pscreen,
2333                                                    image->planes[0].bo,
2334                                                    image->planes[0].pmem,
2335                                                    0, 0,
2336                                                    image->planes[0].memory_offset);
2337             did_bind = true;
2338             if (status)
2339                *status->pResult = VK_SUCCESS;
2340             break;
2341          }
2342          default:
2343             break;
2344          }
2345       }
2346 #endif
2347 
2348       if (!did_bind) {
2349          uint64_t offset_B = 0;
2350          VkResult result;
2351          if (image->disjoint) {
2352             const VkBindImagePlaneMemoryInfo *plane_info =
2353                vk_find_struct_const(pBindInfos[i].pNext, BIND_IMAGE_PLANE_MEMORY_INFO);
2354             uint8_t plane = lvp_image_aspects_to_plane(image, plane_info->planeAspect);
2355             result = lvp_image_plane_bind(device, &image->planes[plane],
2356                                           mem, bind_info->memoryOffset, &offset_B);
2357             if (status)
2358                *status->pResult = result;
2359             if (result != VK_SUCCESS)
2360                return result;
2361          } else {
2362             VkResult fail = VK_SUCCESS;
2363             for (unsigned plane = 0; plane < image->plane_count; plane++) {
2364                result = lvp_image_plane_bind(device, &image->planes[plane],
2365                                              mem, bind_info->memoryOffset + image->offset, &offset_B);
2366                if (status)
2367                   *status->pResult = res;
2368                if (result != VK_SUCCESS)
2369                   fail = result;
2370             }
2371             if (fail != VK_SUCCESS)
2372                return fail;
2373          }
2374       }
2375    }
2376    return res;
2377 }
2378 
2379 #ifdef PIPE_MEMORY_FD
2380 
2381 VkResult
lvp_GetMemoryFdKHR(VkDevice _device,const VkMemoryGetFdInfoKHR * pGetFdInfo,int * pFD)2382 lvp_GetMemoryFdKHR(VkDevice _device, const VkMemoryGetFdInfoKHR *pGetFdInfo, int *pFD)
2383 {
2384    LVP_FROM_HANDLE(lvp_device_memory, memory, pGetFdInfo->memory);
2385 
2386    assert(pGetFdInfo->sType == VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR);
2387    assert_memhandle_type(pGetFdInfo->handleType);
2388 
2389    *pFD = dup(memory->backed_fd);
2390    assert(*pFD >= 0);
2391    return VK_SUCCESS;
2392 }
2393 
2394 VkResult
lvp_GetMemoryFdPropertiesKHR(VkDevice _device,VkExternalMemoryHandleTypeFlagBits handleType,int fd,VkMemoryFdPropertiesKHR * pMemoryFdProperties)2395 lvp_GetMemoryFdPropertiesKHR(VkDevice _device,
2396                              VkExternalMemoryHandleTypeFlagBits handleType,
2397                              int fd,
2398                              VkMemoryFdPropertiesKHR *pMemoryFdProperties)
2399 {
2400    LVP_FROM_HANDLE(lvp_device, device, _device);
2401 
2402    assert(pMemoryFdProperties->sType == VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR);
2403 
2404    if (assert_memhandle_type(handleType)) {
2405       // There is only one memoryType so select this one
2406       pMemoryFdProperties->memoryTypeBits = 1;
2407    }
2408    else
2409       return vk_error(device->instance, VK_ERROR_INVALID_EXTERNAL_HANDLE);
2410    return VK_SUCCESS;
2411 }
2412 
2413 #endif
2414 
lvp_CreateEvent(VkDevice _device,const VkEventCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkEvent * pEvent)2415 VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateEvent(
2416    VkDevice                                    _device,
2417    const VkEventCreateInfo*                    pCreateInfo,
2418    const VkAllocationCallbacks*                pAllocator,
2419    VkEvent*                                    pEvent)
2420 {
2421    LVP_FROM_HANDLE(lvp_device, device, _device);
2422    struct lvp_event *event = vk_alloc2(&device->vk.alloc, pAllocator,
2423                                        sizeof(*event), 8,
2424                                        VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
2425 
2426    if (!event)
2427       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
2428 
2429    vk_object_base_init(&device->vk, &event->base, VK_OBJECT_TYPE_EVENT);
2430    *pEvent = lvp_event_to_handle(event);
2431    event->event_storage = 0;
2432 
2433    return VK_SUCCESS;
2434 }
2435 
lvp_DestroyEvent(VkDevice _device,VkEvent _event,const VkAllocationCallbacks * pAllocator)2436 VKAPI_ATTR void VKAPI_CALL lvp_DestroyEvent(
2437    VkDevice                                    _device,
2438    VkEvent                                     _event,
2439    const VkAllocationCallbacks*                pAllocator)
2440 {
2441    LVP_FROM_HANDLE(lvp_device, device, _device);
2442    LVP_FROM_HANDLE(lvp_event, event, _event);
2443 
2444    if (!event)
2445       return;
2446 
2447    vk_object_base_finish(&event->base);
2448    vk_free2(&device->vk.alloc, pAllocator, event);
2449 }
2450 
lvp_GetEventStatus(VkDevice _device,VkEvent _event)2451 VKAPI_ATTR VkResult VKAPI_CALL lvp_GetEventStatus(
2452    VkDevice                                    _device,
2453    VkEvent                                     _event)
2454 {
2455    LVP_FROM_HANDLE(lvp_event, event, _event);
2456    if (event->event_storage == 1)
2457       return VK_EVENT_SET;
2458    return VK_EVENT_RESET;
2459 }
2460 
lvp_SetEvent(VkDevice _device,VkEvent _event)2461 VKAPI_ATTR VkResult VKAPI_CALL lvp_SetEvent(
2462    VkDevice                                    _device,
2463    VkEvent                                     _event)
2464 {
2465    LVP_FROM_HANDLE(lvp_event, event, _event);
2466    event->event_storage = 1;
2467 
2468    return VK_SUCCESS;
2469 }
2470 
lvp_ResetEvent(VkDevice _device,VkEvent _event)2471 VKAPI_ATTR VkResult VKAPI_CALL lvp_ResetEvent(
2472    VkDevice                                    _device,
2473    VkEvent                                     _event)
2474 {
2475    LVP_FROM_HANDLE(lvp_event, event, _event);
2476    event->event_storage = 0;
2477 
2478    return VK_SUCCESS;
2479 }
2480 
lvp_CreateSampler(VkDevice _device,const VkSamplerCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSampler * pSampler)2481 VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateSampler(
2482    VkDevice                                    _device,
2483    const VkSamplerCreateInfo*                  pCreateInfo,
2484    const VkAllocationCallbacks*                pAllocator,
2485    VkSampler*                                  pSampler)
2486 {
2487    LVP_FROM_HANDLE(lvp_device, device, _device);
2488    struct lvp_sampler *sampler;
2489 
2490    sampler = vk_sampler_create(&device->vk, pCreateInfo,
2491                                pAllocator, sizeof(*sampler));
2492    if (!sampler)
2493       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
2494 
2495    struct pipe_sampler_state state = {0};
2496    VkClearColorValue border_color =
2497       vk_sampler_border_color_value(pCreateInfo, NULL);
2498    STATIC_ASSERT(sizeof(state.border_color) == sizeof(border_color));
2499 
2500    state.wrap_s = vk_conv_wrap_mode(pCreateInfo->addressModeU);
2501    state.wrap_t = vk_conv_wrap_mode(pCreateInfo->addressModeV);
2502    state.wrap_r = vk_conv_wrap_mode(pCreateInfo->addressModeW);
2503    state.min_img_filter = pCreateInfo->minFilter == VK_FILTER_LINEAR ? PIPE_TEX_FILTER_LINEAR : PIPE_TEX_FILTER_NEAREST;
2504    state.min_mip_filter = pCreateInfo->mipmapMode == VK_SAMPLER_MIPMAP_MODE_LINEAR ? PIPE_TEX_MIPFILTER_LINEAR : PIPE_TEX_MIPFILTER_NEAREST;
2505    state.mag_img_filter = pCreateInfo->magFilter == VK_FILTER_LINEAR ? PIPE_TEX_FILTER_LINEAR : PIPE_TEX_FILTER_NEAREST;
2506    state.min_lod = pCreateInfo->minLod;
2507    state.max_lod = pCreateInfo->maxLod;
2508    state.lod_bias = pCreateInfo->mipLodBias;
2509    if (pCreateInfo->anisotropyEnable)
2510       state.max_anisotropy = pCreateInfo->maxAnisotropy;
2511    else
2512       state.max_anisotropy = 1;
2513    state.unnormalized_coords = pCreateInfo->unnormalizedCoordinates;
2514    state.compare_mode = pCreateInfo->compareEnable ? PIPE_TEX_COMPARE_R_TO_TEXTURE : PIPE_TEX_COMPARE_NONE;
2515    state.compare_func = pCreateInfo->compareOp;
2516    state.seamless_cube_map = !(pCreateInfo->flags & VK_SAMPLER_CREATE_NON_SEAMLESS_CUBE_MAP_BIT_EXT);
2517    STATIC_ASSERT((unsigned)VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE == (unsigned)PIPE_TEX_REDUCTION_WEIGHTED_AVERAGE);
2518    STATIC_ASSERT((unsigned)VK_SAMPLER_REDUCTION_MODE_MIN == (unsigned)PIPE_TEX_REDUCTION_MIN);
2519    STATIC_ASSERT((unsigned)VK_SAMPLER_REDUCTION_MODE_MAX == (unsigned)PIPE_TEX_REDUCTION_MAX);
2520    state.reduction_mode = (enum pipe_tex_reduction_mode)sampler->vk.reduction_mode;
2521    memcpy(&state.border_color, &border_color, sizeof(border_color));
2522 
2523    simple_mtx_lock(&device->queue.lock);
2524    sampler->texture_handle = (void *)(uintptr_t)device->queue.ctx->create_texture_handle(device->queue.ctx, NULL, &state);
2525    simple_mtx_unlock(&device->queue.lock);
2526 
2527    lp_jit_sampler_from_pipe(&sampler->desc.sampler, &state);
2528    sampler->desc.texture.sampler_index = sampler->texture_handle->sampler_index;
2529 
2530    *pSampler = lvp_sampler_to_handle(sampler);
2531 
2532    return VK_SUCCESS;
2533 }
2534 
lvp_DestroySampler(VkDevice _device,VkSampler _sampler,const VkAllocationCallbacks * pAllocator)2535 VKAPI_ATTR void VKAPI_CALL lvp_DestroySampler(
2536    VkDevice                                    _device,
2537    VkSampler                                   _sampler,
2538    const VkAllocationCallbacks*                pAllocator)
2539 {
2540    LVP_FROM_HANDLE(lvp_device, device, _device);
2541    LVP_FROM_HANDLE(lvp_sampler, sampler, _sampler);
2542 
2543    if (!_sampler)
2544       return;
2545 
2546    simple_mtx_lock(&device->queue.lock);
2547    device->queue.ctx->delete_texture_handle(device->queue.ctx, (uint64_t)(uintptr_t)sampler->texture_handle);
2548    simple_mtx_unlock(&device->queue.lock);
2549 
2550    vk_sampler_destroy(&device->vk, pAllocator, &sampler->vk);
2551 }
2552 
lvp_CreatePrivateDataSlot(VkDevice _device,const VkPrivateDataSlotCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkPrivateDataSlot * pPrivateDataSlot)2553 VKAPI_ATTR VkResult VKAPI_CALL lvp_CreatePrivateDataSlot(
2554    VkDevice                                    _device,
2555    const VkPrivateDataSlotCreateInfo*          pCreateInfo,
2556    const VkAllocationCallbacks*                pAllocator,
2557    VkPrivateDataSlot*                          pPrivateDataSlot)
2558 {
2559    LVP_FROM_HANDLE(lvp_device, device, _device);
2560    return vk_private_data_slot_create(&device->vk, pCreateInfo, pAllocator,
2561                                       pPrivateDataSlot);
2562 }
2563 
lvp_DestroyPrivateDataSlot(VkDevice _device,VkPrivateDataSlot privateDataSlot,const VkAllocationCallbacks * pAllocator)2564 VKAPI_ATTR void VKAPI_CALL lvp_DestroyPrivateDataSlot(
2565    VkDevice                                    _device,
2566    VkPrivateDataSlot                           privateDataSlot,
2567    const VkAllocationCallbacks*                pAllocator)
2568 {
2569    LVP_FROM_HANDLE(lvp_device, device, _device);
2570    vk_private_data_slot_destroy(&device->vk, privateDataSlot, pAllocator);
2571 }
2572 
lvp_SetPrivateData(VkDevice _device,VkObjectType objectType,uint64_t objectHandle,VkPrivateDataSlot privateDataSlot,uint64_t data)2573 VKAPI_ATTR VkResult VKAPI_CALL lvp_SetPrivateData(
2574    VkDevice                                    _device,
2575    VkObjectType                                objectType,
2576    uint64_t                                    objectHandle,
2577    VkPrivateDataSlot                           privateDataSlot,
2578    uint64_t                                    data)
2579 {
2580    LVP_FROM_HANDLE(lvp_device, device, _device);
2581    return vk_object_base_set_private_data(&device->vk, objectType,
2582                                           objectHandle, privateDataSlot,
2583                                           data);
2584 }
2585 
lvp_GetPrivateData(VkDevice _device,VkObjectType objectType,uint64_t objectHandle,VkPrivateDataSlot privateDataSlot,uint64_t * pData)2586 VKAPI_ATTR void VKAPI_CALL lvp_GetPrivateData(
2587    VkDevice                                    _device,
2588    VkObjectType                                objectType,
2589    uint64_t                                    objectHandle,
2590    VkPrivateDataSlot                           privateDataSlot,
2591    uint64_t*                                   pData)
2592 {
2593    LVP_FROM_HANDLE(lvp_device, device, _device);
2594    vk_object_base_get_private_data(&device->vk, objectType, objectHandle,
2595                                    privateDataSlot, pData);
2596 }
2597 
lvp_GetPhysicalDeviceExternalFenceProperties(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceExternalFenceInfo * pExternalFenceInfo,VkExternalFenceProperties * pExternalFenceProperties)2598 VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceExternalFenceProperties(
2599    VkPhysicalDevice                           physicalDevice,
2600    const VkPhysicalDeviceExternalFenceInfo    *pExternalFenceInfo,
2601    VkExternalFenceProperties                  *pExternalFenceProperties)
2602 {
2603    LVP_FROM_HANDLE(lvp_physical_device, physical_device, physicalDevice);
2604    const VkExternalFenceHandleTypeFlagBits handle_type = pExternalFenceInfo->handleType;
2605 
2606    if (handle_type == VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT &&
2607        physical_device->pscreen->get_param(
2608           physical_device->pscreen, PIPE_CAP_NATIVE_FENCE_FD)) {
2609       pExternalFenceProperties->exportFromImportedHandleTypes =
2610          VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT;
2611       pExternalFenceProperties->compatibleHandleTypes =
2612          VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT;
2613        pExternalFenceProperties->externalFenceFeatures =
2614           VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT |
2615           VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT;
2616    } else {
2617       pExternalFenceProperties->exportFromImportedHandleTypes = 0;
2618       pExternalFenceProperties->compatibleHandleTypes = 0;
2619       pExternalFenceProperties->externalFenceFeatures = 0;
2620    }
2621 }
2622 
lvp_GetPhysicalDeviceExternalSemaphoreProperties(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceExternalSemaphoreInfo * pExternalSemaphoreInfo,VkExternalSemaphoreProperties * pExternalSemaphoreProperties)2623 VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceExternalSemaphoreProperties(
2624    VkPhysicalDevice                            physicalDevice,
2625    const VkPhysicalDeviceExternalSemaphoreInfo *pExternalSemaphoreInfo,
2626    VkExternalSemaphoreProperties               *pExternalSemaphoreProperties)
2627 {
2628    LVP_FROM_HANDLE(lvp_physical_device, physical_device, physicalDevice);
2629    const VkSemaphoreTypeCreateInfo *type_info =
2630       vk_find_struct_const(pExternalSemaphoreInfo->pNext, SEMAPHORE_TYPE_CREATE_INFO);
2631    const VkSemaphoreType type = !type_info ? VK_SEMAPHORE_TYPE_BINARY : type_info->semaphoreType;
2632    const VkExternalSemaphoreHandleTypeFlagBits handle_type = pExternalSemaphoreInfo->handleType;
2633 
2634    if (type == VK_SEMAPHORE_TYPE_BINARY &&
2635        handle_type == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT &&
2636        physical_device->pscreen->get_param(
2637           physical_device->pscreen, PIPE_CAP_NATIVE_FENCE_FD)) {
2638       pExternalSemaphoreProperties->exportFromImportedHandleTypes =
2639          VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
2640       pExternalSemaphoreProperties->compatibleHandleTypes =
2641          VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
2642       pExternalSemaphoreProperties->externalSemaphoreFeatures =
2643          VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT |
2644          VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT;
2645    } else {
2646       pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0;
2647       pExternalSemaphoreProperties->compatibleHandleTypes = 0;
2648       pExternalSemaphoreProperties->externalSemaphoreFeatures = 0;
2649    }
2650 }
2651 
2652 static const VkTimeDomainEXT lvp_time_domains[] = {
2653         VK_TIME_DOMAIN_DEVICE_EXT,
2654         VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT,
2655 };
2656 
lvp_GetPhysicalDeviceCalibrateableTimeDomainsEXT(VkPhysicalDevice physicalDevice,uint32_t * pTimeDomainCount,VkTimeDomainEXT * pTimeDomains)2657 VKAPI_ATTR VkResult VKAPI_CALL lvp_GetPhysicalDeviceCalibrateableTimeDomainsEXT(
2658    VkPhysicalDevice physicalDevice,
2659    uint32_t *pTimeDomainCount,
2660    VkTimeDomainEXT *pTimeDomains)
2661 {
2662    int d;
2663    VK_OUTARRAY_MAKE_TYPED(VkTimeDomainEXT, out, pTimeDomains,
2664                           pTimeDomainCount);
2665 
2666    for (d = 0; d < ARRAY_SIZE(lvp_time_domains); d++) {
2667       vk_outarray_append_typed(VkTimeDomainEXT, &out, i) {
2668          *i = lvp_time_domains[d];
2669       }
2670     }
2671 
2672     return vk_outarray_status(&out);
2673 }
2674 
lvp_GetCalibratedTimestampsEXT(VkDevice device,uint32_t timestampCount,const VkCalibratedTimestampInfoEXT * pTimestampInfos,uint64_t * pTimestamps,uint64_t * pMaxDeviation)2675 VKAPI_ATTR VkResult VKAPI_CALL lvp_GetCalibratedTimestampsEXT(
2676    VkDevice device,
2677    uint32_t timestampCount,
2678    const VkCalibratedTimestampInfoEXT *pTimestampInfos,
2679    uint64_t *pTimestamps,
2680    uint64_t *pMaxDeviation)
2681 {
2682    *pMaxDeviation = 1;
2683 
2684    uint64_t now = os_time_get_nano();
2685    for (unsigned i = 0; i < timestampCount; i++) {
2686       pTimestamps[i] = now;
2687    }
2688    return VK_SUCCESS;
2689 }
2690 
lvp_GetDeviceGroupPeerMemoryFeatures(VkDevice device,uint32_t heapIndex,uint32_t localDeviceIndex,uint32_t remoteDeviceIndex,VkPeerMemoryFeatureFlags * pPeerMemoryFeatures)2691 VKAPI_ATTR void VKAPI_CALL lvp_GetDeviceGroupPeerMemoryFeatures(
2692     VkDevice device,
2693     uint32_t heapIndex,
2694     uint32_t localDeviceIndex,
2695     uint32_t remoteDeviceIndex,
2696     VkPeerMemoryFeatureFlags *pPeerMemoryFeatures)
2697 {
2698    *pPeerMemoryFeatures = 0;
2699 }
2700 
lvp_SetDeviceMemoryPriorityEXT(VkDevice _device,VkDeviceMemory _memory,float priority)2701 VKAPI_ATTR void VKAPI_CALL lvp_SetDeviceMemoryPriorityEXT(
2702     VkDevice                                    _device,
2703     VkDeviceMemory                              _memory,
2704     float                                       priority)
2705 {
2706    LVP_FROM_HANDLE(lvp_device_memory, mem, _memory);
2707    set_mem_priority(mem, get_mem_priority(priority));
2708 }
2709 
lvp_GetRenderingAreaGranularityKHR(VkDevice device,const VkRenderingAreaInfoKHR * pRenderingAreaInfo,VkExtent2D * pGranularity)2710 VKAPI_ATTR void VKAPI_CALL lvp_GetRenderingAreaGranularityKHR(
2711     VkDevice                                    device,
2712     const VkRenderingAreaInfoKHR*               pRenderingAreaInfo,
2713     VkExtent2D*                                 pGranularity)
2714 {
2715    VkExtent2D tile_size = {64, 64};
2716    *pGranularity = tile_size;
2717 }
2718