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