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