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