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
26 #include "pipe-loader/pipe_loader.h"
27 #include "git_sha1.h"
28 #include "vk_cmd_enqueue_entrypoints.h"
29 #include "vk_sampler.h"
30 #include "vk_util.h"
31 #include "pipe/p_config.h"
32 #include "pipe/p_defines.h"
33 #include "pipe/p_state.h"
34 #include "pipe/p_context.h"
35 #include "frontend/drisw_api.h"
36
37 #include "util/u_inlines.h"
38 #include "util/os_memory.h"
39 #include "util/u_thread.h"
40 #include "util/u_atomic.h"
41 #include "util/timespec.h"
42 #include "util/ptralloc.h"
43 #include "os_time.h"
44
45 #if defined(VK_USE_PLATFORM_WAYLAND_KHR) || \
46 defined(VK_USE_PLATFORM_WIN32_KHR) || \
47 defined(VK_USE_PLATFORM_XCB_KHR) || \
48 defined(VK_USE_PLATFORM_XLIB_KHR)
49 #define LVP_USE_WSI_PLATFORM
50 #endif
51 #define LVP_API_VERSION VK_MAKE_VERSION(1, 3, VK_HEADER_VERSION)
52
lvp_EnumerateInstanceVersion(uint32_t * pApiVersion)53 VKAPI_ATTR VkResult VKAPI_CALL lvp_EnumerateInstanceVersion(uint32_t* pApiVersion)
54 {
55 *pApiVersion = LVP_API_VERSION;
56 return VK_SUCCESS;
57 }
58
59 static const struct vk_instance_extension_table lvp_instance_extensions_supported = {
60 .KHR_device_group_creation = true,
61 .KHR_external_fence_capabilities = true,
62 .KHR_external_memory_capabilities = true,
63 .KHR_external_semaphore_capabilities = true,
64 .KHR_get_physical_device_properties2 = true,
65 .EXT_debug_report = true,
66 .EXT_debug_utils = true,
67 #ifdef LVP_USE_WSI_PLATFORM
68 .KHR_get_surface_capabilities2 = true,
69 .KHR_surface = true,
70 .KHR_surface_protected_capabilities = true,
71 #endif
72 #ifdef VK_USE_PLATFORM_WAYLAND_KHR
73 .KHR_wayland_surface = true,
74 #endif
75 #ifdef VK_USE_PLATFORM_WIN32_KHR
76 .KHR_win32_surface = true,
77 #endif
78 #ifdef VK_USE_PLATFORM_XCB_KHR
79 .KHR_xcb_surface = true,
80 #endif
81 #ifdef VK_USE_PLATFORM_XLIB_KHR
82 .KHR_xlib_surface = true,
83 #endif
84 };
85
86 static const struct vk_device_extension_table lvp_device_extensions_supported = {
87 .KHR_8bit_storage = true,
88 .KHR_16bit_storage = true,
89 .KHR_bind_memory2 = true,
90 .KHR_buffer_device_address = true,
91 .KHR_create_renderpass2 = true,
92 .KHR_copy_commands2 = true,
93 .KHR_dedicated_allocation = true,
94 .KHR_depth_stencil_resolve = true,
95 .KHR_descriptor_update_template = true,
96 .KHR_device_group = true,
97 .KHR_draw_indirect_count = true,
98 .KHR_driver_properties = true,
99 .KHR_dynamic_rendering = true,
100 .KHR_format_feature_flags2 = true,
101 .KHR_external_fence = true,
102 .KHR_external_memory = true,
103 #ifdef PIPE_MEMORY_FD
104 .KHR_external_memory_fd = true,
105 #endif
106 .KHR_external_semaphore = true,
107 .KHR_shader_float_controls = true,
108 .KHR_get_memory_requirements2 = true,
109 #ifdef LVP_USE_WSI_PLATFORM
110 .KHR_incremental_present = true,
111 #endif
112 .KHR_image_format_list = true,
113 .KHR_imageless_framebuffer = true,
114 .KHR_maintenance1 = true,
115 .KHR_maintenance2 = true,
116 .KHR_maintenance3 = true,
117 .KHR_maintenance4 = true,
118 .KHR_multiview = true,
119 .KHR_push_descriptor = true,
120 .KHR_pipeline_library = true,
121 .KHR_relaxed_block_layout = true,
122 .KHR_sampler_mirror_clamp_to_edge = true,
123 .KHR_separate_depth_stencil_layouts = true,
124 .KHR_shader_atomic_int64 = true,
125 .KHR_shader_draw_parameters = true,
126 .KHR_shader_float16_int8 = true,
127 .KHR_shader_integer_dot_product = true,
128 .KHR_shader_subgroup_extended_types = true,
129 .KHR_shader_terminate_invocation = true,
130 .KHR_spirv_1_4 = true,
131 .KHR_storage_buffer_storage_class = true,
132 #ifdef LVP_USE_WSI_PLATFORM
133 .KHR_swapchain = true,
134 .KHR_swapchain_mutable_format = true,
135 #endif
136 .KHR_synchronization2 = true,
137 .KHR_timeline_semaphore = true,
138 .KHR_uniform_buffer_standard_layout = true,
139 .KHR_variable_pointers = true,
140 .KHR_vulkan_memory_model = true,
141 .KHR_zero_initialize_workgroup_memory = true,
142 .EXT_4444_formats = true,
143 .EXT_border_color_swizzle = true,
144 .EXT_calibrated_timestamps = true,
145 .EXT_color_write_enable = true,
146 .EXT_conditional_rendering = true,
147 .EXT_depth_clip_enable = true,
148 .EXT_depth_clip_control = true,
149 .EXT_depth_range_unrestricted = true,
150 .EXT_extended_dynamic_state = true,
151 .EXT_extended_dynamic_state2 = true,
152 .EXT_external_memory_host = true,
153 .EXT_graphics_pipeline_library = true,
154 .EXT_host_query_reset = true,
155 .EXT_image_2d_view_of_3d = true,
156 .EXT_image_robustness = true,
157 .EXT_index_type_uint8 = true,
158 .EXT_inline_uniform_block = true,
159 .EXT_multisampled_render_to_single_sampled = true,
160 .EXT_multi_draw = true,
161 .EXT_non_seamless_cube_map = true,
162 .EXT_pipeline_creation_feedback = true,
163 .EXT_pipeline_creation_cache_control = true,
164 .EXT_post_depth_coverage = true,
165 .EXT_private_data = true,
166 .EXT_primitives_generated_query = true,
167 .EXT_primitive_topology_list_restart = true,
168 .EXT_sampler_filter_minmax = true,
169 .EXT_scalar_block_layout = true,
170 .EXT_separate_stencil_usage = true,
171 .EXT_shader_demote_to_helper_invocation= true,
172 .EXT_shader_stencil_export = true,
173 .EXT_shader_subgroup_ballot = true,
174 .EXT_shader_subgroup_vote = true,
175 .EXT_shader_viewport_index_layer = true,
176 .EXT_subgroup_size_control = true,
177 .EXT_texel_buffer_alignment = true,
178 .EXT_transform_feedback = true,
179 .EXT_vertex_attribute_divisor = true,
180 .EXT_vertex_input_dynamic_state = true,
181 .EXT_custom_border_color = true,
182 .EXT_provoking_vertex = true,
183 .EXT_line_rasterization = true,
184 .EXT_robustness2 = true,
185 .GOOGLE_decorate_string = true,
186 .GOOGLE_hlsl_functionality1 = true,
187 };
188
189 static int
min_vertex_pipeline_param(struct pipe_screen * pscreen,enum pipe_shader_cap param)190 min_vertex_pipeline_param(struct pipe_screen *pscreen, enum pipe_shader_cap param)
191 {
192 int val = INT_MAX;
193 for (int i = 0; i < PIPE_SHADER_COMPUTE; ++i) {
194 if (i == PIPE_SHADER_FRAGMENT ||
195 !pscreen->get_shader_param(pscreen, i,
196 PIPE_SHADER_CAP_MAX_INSTRUCTIONS))
197 continue;
198
199 val = MAX2(val, pscreen->get_shader_param(pscreen, i, param));
200 }
201 return val;
202 }
203
204 static int
min_shader_param(struct pipe_screen * pscreen,enum pipe_shader_cap param)205 min_shader_param(struct pipe_screen *pscreen, enum pipe_shader_cap param)
206 {
207 return MIN3(min_vertex_pipeline_param(pscreen, param),
208 pscreen->get_shader_param(pscreen, PIPE_SHADER_FRAGMENT, param),
209 pscreen->get_shader_param(pscreen, PIPE_SHADER_COMPUTE, param));
210 }
211
212 static VkResult VKAPI_CALL
lvp_physical_device_init(struct lvp_physical_device * device,struct lvp_instance * instance,struct pipe_loader_device * pld)213 lvp_physical_device_init(struct lvp_physical_device *device,
214 struct lvp_instance *instance,
215 struct pipe_loader_device *pld)
216 {
217 VkResult result;
218
219 struct vk_physical_device_dispatch_table dispatch_table;
220 vk_physical_device_dispatch_table_from_entrypoints(
221 &dispatch_table, &lvp_physical_device_entrypoints, true);
222 vk_physical_device_dispatch_table_from_entrypoints(
223 &dispatch_table, &wsi_physical_device_entrypoints, false);
224 result = vk_physical_device_init(&device->vk, &instance->vk,
225 NULL, &dispatch_table);
226 if (result != VK_SUCCESS) {
227 vk_error(instance, result);
228 goto fail;
229 }
230 device->pld = pld;
231
232 device->pscreen = pipe_loader_create_screen_vk(device->pld, true);
233 if (!device->pscreen)
234 return vk_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY);
235
236 device->sync_timeline_type = vk_sync_timeline_get_type(&lvp_pipe_sync_type);
237 device->sync_types[0] = &lvp_pipe_sync_type;
238 device->sync_types[1] = &device->sync_timeline_type.sync;
239 device->sync_types[2] = NULL;
240 device->vk.supported_sync_types = device->sync_types;
241
242 device->max_images = device->pscreen->get_shader_param(device->pscreen, PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_MAX_SHADER_IMAGES);
243 device->vk.supported_extensions = lvp_device_extensions_supported;
244
245 VkSampleCountFlags sample_counts = VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT;
246
247 uint64_t grid_size[3], block_size[3];
248 uint64_t max_threads_per_block, max_local_size;
249
250 device->pscreen->get_compute_param(device->pscreen, PIPE_SHADER_IR_NIR,
251 PIPE_COMPUTE_CAP_MAX_GRID_SIZE, grid_size);
252 device->pscreen->get_compute_param(device->pscreen, PIPE_SHADER_IR_NIR,
253 PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE, block_size);
254 device->pscreen->get_compute_param(device->pscreen, PIPE_SHADER_IR_NIR,
255 PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK,
256 &max_threads_per_block);
257 device->pscreen->get_compute_param(device->pscreen, PIPE_SHADER_IR_NIR,
258 PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE,
259 &max_local_size);
260
261 const uint64_t max_render_targets = device->pscreen->get_param(device->pscreen, PIPE_CAP_MAX_RENDER_TARGETS);
262 device->device_limits = (VkPhysicalDeviceLimits) {
263 .maxImageDimension1D = device->pscreen->get_param(device->pscreen, PIPE_CAP_MAX_TEXTURE_2D_SIZE),
264 .maxImageDimension2D = device->pscreen->get_param(device->pscreen, PIPE_CAP_MAX_TEXTURE_2D_SIZE),
265 .maxImageDimension3D = (1 << device->pscreen->get_param(device->pscreen, PIPE_CAP_MAX_TEXTURE_3D_LEVELS)),
266 .maxImageDimensionCube = (1 << device->pscreen->get_param(device->pscreen, PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS)),
267 .maxImageArrayLayers = device->pscreen->get_param(device->pscreen, PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS),
268 .maxTexelBufferElements = device->pscreen->get_param(device->pscreen, PIPE_CAP_MAX_TEXEL_BUFFER_ELEMENTS_UINT),
269 .maxUniformBufferRange = min_shader_param(device->pscreen, PIPE_SHADER_CAP_MAX_CONST_BUFFER0_SIZE),
270 .maxStorageBufferRange = device->pscreen->get_param(device->pscreen, PIPE_CAP_MAX_SHADER_BUFFER_SIZE_UINT),
271 .maxPushConstantsSize = MAX_PUSH_CONSTANTS_SIZE,
272 .maxMemoryAllocationCount = UINT32_MAX,
273 .maxSamplerAllocationCount = 32 * 1024,
274 .bufferImageGranularity = 64, /* A cache line */
275 .sparseAddressSpaceSize = 0,
276 .maxBoundDescriptorSets = MAX_SETS,
277 .maxPerStageDescriptorSamplers = min_shader_param(device->pscreen, PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS),
278 .maxPerStageDescriptorUniformBuffers = min_shader_param(device->pscreen, PIPE_SHADER_CAP_MAX_CONST_BUFFERS) - 1,
279 .maxPerStageDescriptorStorageBuffers = min_shader_param(device->pscreen, PIPE_SHADER_CAP_MAX_SHADER_BUFFERS),
280 .maxPerStageDescriptorSampledImages = min_shader_param(device->pscreen, PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS),
281 .maxPerStageDescriptorStorageImages = min_shader_param(device->pscreen, PIPE_SHADER_CAP_MAX_SHADER_IMAGES),
282 .maxPerStageDescriptorInputAttachments = 8,
283 .maxPerStageResources = 128,
284 .maxDescriptorSetSamplers = 32 * 1024,
285 .maxDescriptorSetUniformBuffers = 256,
286 .maxDescriptorSetUniformBuffersDynamic = 256,
287 .maxDescriptorSetStorageBuffers = 256,
288 .maxDescriptorSetStorageBuffersDynamic = 256,
289 .maxDescriptorSetSampledImages = 256,
290 .maxDescriptorSetStorageImages = 256,
291 .maxDescriptorSetInputAttachments = 256,
292 .maxVertexInputAttributes = 32,
293 .maxVertexInputBindings = 32,
294 .maxVertexInputAttributeOffset = 2047,
295 .maxVertexInputBindingStride = 2048,
296 .maxVertexOutputComponents = 128,
297 .maxTessellationGenerationLevel = 64,
298 .maxTessellationPatchSize = 32,
299 .maxTessellationControlPerVertexInputComponents = 128,
300 .maxTessellationControlPerVertexOutputComponents = 128,
301 .maxTessellationControlPerPatchOutputComponents = 128,
302 .maxTessellationControlTotalOutputComponents = 4096,
303 .maxTessellationEvaluationInputComponents = 128,
304 .maxTessellationEvaluationOutputComponents = 128,
305 .maxGeometryShaderInvocations = device->pscreen->get_param(device->pscreen, PIPE_CAP_MAX_GS_INVOCATIONS),
306 .maxGeometryInputComponents = 64,
307 .maxGeometryOutputComponents = 128,
308 .maxGeometryOutputVertices = device->pscreen->get_param(device->pscreen, PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES),
309 .maxGeometryTotalOutputComponents = device->pscreen->get_param(device->pscreen, PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS),
310 .maxFragmentInputComponents = 128,
311 .maxFragmentOutputAttachments = 8,
312 .maxFragmentDualSrcAttachments = 2,
313 .maxFragmentCombinedOutputResources = max_render_targets +
314 device->pscreen->get_shader_param(device->pscreen, PIPE_SHADER_FRAGMENT,
315 PIPE_SHADER_CAP_MAX_SHADER_BUFFERS) +
316 device->pscreen->get_shader_param(device->pscreen, PIPE_SHADER_FRAGMENT,
317 PIPE_SHADER_CAP_MAX_SHADER_IMAGES),
318 .maxComputeSharedMemorySize = max_local_size,
319 .maxComputeWorkGroupCount = { grid_size[0], grid_size[1], grid_size[2] },
320 .maxComputeWorkGroupInvocations = max_threads_per_block,
321 .maxComputeWorkGroupSize = { block_size[0], block_size[1], block_size[2] },
322 .subPixelPrecisionBits = device->pscreen->get_param(device->pscreen, PIPE_CAP_RASTERIZER_SUBPIXEL_BITS),
323 .subTexelPrecisionBits = 8,
324 .mipmapPrecisionBits = 4,
325 .maxDrawIndexedIndexValue = UINT32_MAX,
326 .maxDrawIndirectCount = UINT32_MAX,
327 .maxSamplerLodBias = 16,
328 .maxSamplerAnisotropy = 16,
329 .maxViewports = device->pscreen->get_param(device->pscreen, PIPE_CAP_MAX_VIEWPORTS),
330 .maxViewportDimensions = { (1 << 14), (1 << 14) },
331 .viewportBoundsRange = { -32768.0, 32768.0 },
332 .viewportSubPixelBits = device->pscreen->get_param(device->pscreen, PIPE_CAP_VIEWPORT_SUBPIXEL_BITS),
333 .minMemoryMapAlignment = device->pscreen->get_param(device->pscreen, PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT),
334 .minTexelBufferOffsetAlignment = device->pscreen->get_param(device->pscreen, PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT),
335 .minUniformBufferOffsetAlignment = device->pscreen->get_param(device->pscreen, PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT),
336 .minStorageBufferOffsetAlignment = device->pscreen->get_param(device->pscreen, PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT),
337 .minTexelOffset = device->pscreen->get_param(device->pscreen, PIPE_CAP_MIN_TEXEL_OFFSET),
338 .maxTexelOffset = device->pscreen->get_param(device->pscreen, PIPE_CAP_MAX_TEXEL_OFFSET),
339 .minTexelGatherOffset = device->pscreen->get_param(device->pscreen, PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET),
340 .maxTexelGatherOffset = device->pscreen->get_param(device->pscreen, PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET),
341 .minInterpolationOffset = -2, /* FIXME */
342 .maxInterpolationOffset = 2, /* FIXME */
343 .subPixelInterpolationOffsetBits = 8, /* FIXME */
344 .maxFramebufferWidth = device->pscreen->get_param(device->pscreen, PIPE_CAP_MAX_TEXTURE_2D_SIZE),
345 .maxFramebufferHeight = device->pscreen->get_param(device->pscreen, PIPE_CAP_MAX_TEXTURE_2D_SIZE),
346 .maxFramebufferLayers = device->pscreen->get_param(device->pscreen, PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS),
347 .framebufferColorSampleCounts = sample_counts,
348 .framebufferDepthSampleCounts = sample_counts,
349 .framebufferStencilSampleCounts = sample_counts,
350 .framebufferNoAttachmentsSampleCounts = sample_counts,
351 .maxColorAttachments = max_render_targets,
352 .sampledImageColorSampleCounts = sample_counts,
353 .sampledImageIntegerSampleCounts = sample_counts,
354 .sampledImageDepthSampleCounts = sample_counts,
355 .sampledImageStencilSampleCounts = sample_counts,
356 .storageImageSampleCounts = sample_counts,
357 .maxSampleMaskWords = 1,
358 .timestampComputeAndGraphics = true,
359 .timestampPeriod = 1,
360 .maxClipDistances = 8,
361 .maxCullDistances = 8,
362 .maxCombinedClipAndCullDistances = 8,
363 .discreteQueuePriorities = 2,
364 .pointSizeRange = { 0.0, device->pscreen->get_paramf(device->pscreen, PIPE_CAPF_MAX_POINT_SIZE) },
365 .lineWidthRange = { 1.0, device->pscreen->get_paramf(device->pscreen, PIPE_CAPF_MAX_LINE_WIDTH) },
366 .pointSizeGranularity = (1.0 / 8.0),
367 .lineWidthGranularity = 1.0 / 128.0,
368 .strictLines = true,
369 .standardSampleLocations = true,
370 .optimalBufferCopyOffsetAlignment = 128,
371 .optimalBufferCopyRowPitchAlignment = 128,
372 .nonCoherentAtomSize = 64,
373 };
374 result = lvp_init_wsi(device);
375 if (result != VK_SUCCESS) {
376 vk_physical_device_finish(&device->vk);
377 vk_error(instance, result);
378 goto fail;
379 }
380
381 return VK_SUCCESS;
382 fail:
383 return result;
384 }
385
386 static void VKAPI_CALL
lvp_physical_device_finish(struct lvp_physical_device * device)387 lvp_physical_device_finish(struct lvp_physical_device *device)
388 {
389 lvp_finish_wsi(device);
390 device->pscreen->destroy(device->pscreen);
391 vk_physical_device_finish(&device->vk);
392 }
393
lvp_CreateInstance(const VkInstanceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkInstance * pInstance)394 VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateInstance(
395 const VkInstanceCreateInfo* pCreateInfo,
396 const VkAllocationCallbacks* pAllocator,
397 VkInstance* pInstance)
398 {
399 struct lvp_instance *instance;
400 VkResult result;
401
402 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO);
403
404 if (pAllocator == NULL)
405 pAllocator = vk_default_allocator();
406
407 instance = vk_zalloc(pAllocator, sizeof(*instance), 8,
408 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
409 if (!instance)
410 return vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY);
411
412 struct vk_instance_dispatch_table dispatch_table;
413 vk_instance_dispatch_table_from_entrypoints(
414 &dispatch_table, &lvp_instance_entrypoints, true);
415 vk_instance_dispatch_table_from_entrypoints(
416 &dispatch_table, &wsi_instance_entrypoints, false);
417
418 result = vk_instance_init(&instance->vk,
419 &lvp_instance_extensions_supported,
420 &dispatch_table,
421 pCreateInfo,
422 pAllocator);
423 if (result != VK_SUCCESS) {
424 vk_free(pAllocator, instance);
425 return vk_error(instance, result);
426 }
427
428 instance->apiVersion = LVP_API_VERSION;
429 instance->physicalDeviceCount = -1;
430
431 // _mesa_locale_init();
432 // VG(VALGRIND_CREATE_MEMPOOL(instance, 0, false));
433
434 *pInstance = lvp_instance_to_handle(instance);
435
436 return VK_SUCCESS;
437 }
438
lvp_DestroyInstance(VkInstance _instance,const VkAllocationCallbacks * pAllocator)439 VKAPI_ATTR void VKAPI_CALL lvp_DestroyInstance(
440 VkInstance _instance,
441 const VkAllocationCallbacks* pAllocator)
442 {
443 LVP_FROM_HANDLE(lvp_instance, instance, _instance);
444
445 if (!instance)
446 return;
447 if (instance->physicalDeviceCount > 0)
448 lvp_physical_device_finish(&instance->physicalDevice);
449 // _mesa_locale_fini();
450
451 pipe_loader_release(&instance->devs, instance->num_devices);
452
453 vk_instance_finish(&instance->vk);
454 vk_free(&instance->vk.alloc, instance);
455 }
456
457 #if defined(HAVE_DRI)
lvp_get_image(struct dri_drawable * dri_drawable,int x,int y,unsigned width,unsigned height,unsigned stride,void * data)458 static void lvp_get_image(struct dri_drawable *dri_drawable,
459 int x, int y, unsigned width, unsigned height, unsigned stride,
460 void *data)
461 {
462
463 }
464
lvp_put_image(struct dri_drawable * dri_drawable,void * data,unsigned width,unsigned height)465 static void lvp_put_image(struct dri_drawable *dri_drawable,
466 void *data, unsigned width, unsigned height)
467 {
468 fprintf(stderr, "put image %dx%d\n", width, height);
469 }
470
lvp_put_image2(struct dri_drawable * dri_drawable,void * data,int x,int y,unsigned width,unsigned height,unsigned stride)471 static void lvp_put_image2(struct dri_drawable *dri_drawable,
472 void *data, int x, int y, unsigned width, unsigned height,
473 unsigned stride)
474 {
475 fprintf(stderr, "put image 2 %d,%d %dx%d\n", x, y, width, height);
476 }
477
478 static struct drisw_loader_funcs lvp_sw_lf = {
479 .get_image = lvp_get_image,
480 .put_image = lvp_put_image,
481 .put_image2 = lvp_put_image2,
482 };
483 #endif
484
485 static VkResult
lvp_enumerate_physical_devices(struct lvp_instance * instance)486 lvp_enumerate_physical_devices(struct lvp_instance *instance)
487 {
488 VkResult result;
489
490 if (instance->physicalDeviceCount != -1)
491 return VK_SUCCESS;
492
493 /* sw only for now */
494 instance->num_devices = pipe_loader_sw_probe(NULL, 0);
495
496 assert(instance->num_devices == 1);
497
498 #if defined(HAVE_DRI)
499 pipe_loader_sw_probe_dri(&instance->devs, &lvp_sw_lf);
500 #else
501 pipe_loader_sw_probe_null(&instance->devs);
502 #endif
503
504 result = lvp_physical_device_init(&instance->physicalDevice,
505 instance, &instance->devs[0]);
506 if (result == VK_ERROR_INCOMPATIBLE_DRIVER) {
507 instance->physicalDeviceCount = 0;
508 } else if (result == VK_SUCCESS) {
509 instance->physicalDeviceCount = 1;
510 }
511
512 return result;
513 }
514
lvp_EnumeratePhysicalDevices(VkInstance _instance,uint32_t * pPhysicalDeviceCount,VkPhysicalDevice * pPhysicalDevices)515 VKAPI_ATTR VkResult VKAPI_CALL lvp_EnumeratePhysicalDevices(
516 VkInstance _instance,
517 uint32_t* pPhysicalDeviceCount,
518 VkPhysicalDevice* pPhysicalDevices)
519 {
520 LVP_FROM_HANDLE(lvp_instance, instance, _instance);
521 VkResult result;
522
523 result = lvp_enumerate_physical_devices(instance);
524 if (result != VK_SUCCESS)
525 return result;
526
527 if (!pPhysicalDevices) {
528 *pPhysicalDeviceCount = instance->physicalDeviceCount;
529 } else if (*pPhysicalDeviceCount >= 1) {
530 pPhysicalDevices[0] = lvp_physical_device_to_handle(&instance->physicalDevice);
531 *pPhysicalDeviceCount = 1;
532 } else {
533 *pPhysicalDeviceCount = 0;
534 }
535
536 return VK_SUCCESS;
537 }
538
lvp_EnumeratePhysicalDeviceGroups(VkInstance _instance,uint32_t * pPhysicalDeviceGroupCount,VkPhysicalDeviceGroupProperties * pPhysicalDeviceGroupProperties)539 VKAPI_ATTR VkResult VKAPI_CALL lvp_EnumeratePhysicalDeviceGroups(
540 VkInstance _instance,
541 uint32_t* pPhysicalDeviceGroupCount,
542 VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties)
543 {
544 LVP_FROM_HANDLE(lvp_instance, instance, _instance);
545 VK_OUTARRAY_MAKE_TYPED(VkPhysicalDeviceGroupProperties, out,
546 pPhysicalDeviceGroupProperties,
547 pPhysicalDeviceGroupCount);
548
549 VkResult result = lvp_enumerate_physical_devices(instance);
550 if (result != VK_SUCCESS)
551 return result;
552
553 vk_outarray_append_typed(VkPhysicalDeviceGroupProperties, &out, p) {
554 p->physicalDeviceCount = 1;
555 memset(p->physicalDevices, 0, sizeof(p->physicalDevices));
556 p->physicalDevices[0] = lvp_physical_device_to_handle(&instance->physicalDevice);
557 p->subsetAllocation = false;
558 }
559
560 return vk_outarray_status(&out);
561 }
562
lvp_GetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice,VkPhysicalDeviceFeatures * pFeatures)563 VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceFeatures(
564 VkPhysicalDevice physicalDevice,
565 VkPhysicalDeviceFeatures* pFeatures)
566 {
567 LVP_FROM_HANDLE(lvp_physical_device, pdevice, physicalDevice);
568 bool indirect = false;//pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_GLSL_FEATURE_LEVEL) >= 400;
569 memset(pFeatures, 0, sizeof(*pFeatures));
570 *pFeatures = (VkPhysicalDeviceFeatures) {
571 .robustBufferAccess = true,
572 .fullDrawIndexUint32 = true,
573 .imageCubeArray = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_CUBE_MAP_ARRAY) != 0),
574 .independentBlend = true,
575 .geometryShader = (pdevice->pscreen->get_shader_param(pdevice->pscreen, PIPE_SHADER_GEOMETRY, PIPE_SHADER_CAP_MAX_INSTRUCTIONS) != 0),
576 .tessellationShader = (pdevice->pscreen->get_shader_param(pdevice->pscreen, PIPE_SHADER_TESS_EVAL, PIPE_SHADER_CAP_MAX_INSTRUCTIONS) != 0),
577 .sampleRateShading = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_SAMPLE_SHADING) != 0),
578 .dualSrcBlend = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS) != 0),
579 .logicOp = true,
580 .multiDrawIndirect = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MULTI_DRAW_INDIRECT) != 0),
581 .drawIndirectFirstInstance = true,
582 .depthClamp = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_DEPTH_CLIP_DISABLE) != 0),
583 .depthBiasClamp = true,
584 .fillModeNonSolid = true,
585 .depthBounds = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_DEPTH_BOUNDS_TEST) != 0),
586 .wideLines = true,
587 .largePoints = true,
588 .alphaToOne = true,
589 .multiViewport = true,
590 .samplerAnisotropy = true,
591 .textureCompressionETC2 = false,
592 .textureCompressionASTC_LDR = false,
593 .textureCompressionBC = true,
594 .occlusionQueryPrecise = true,
595 .pipelineStatisticsQuery = true,
596 .vertexPipelineStoresAndAtomics = (min_vertex_pipeline_param(pdevice->pscreen, PIPE_SHADER_CAP_MAX_SHADER_BUFFERS) != 0),
597 .fragmentStoresAndAtomics = (pdevice->pscreen->get_shader_param(pdevice->pscreen, PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_MAX_SHADER_BUFFERS) != 0),
598 .shaderTessellationAndGeometryPointSize = true,
599 .shaderImageGatherExtended = true,
600 .shaderStorageImageExtendedFormats = (min_shader_param(pdevice->pscreen, PIPE_SHADER_CAP_MAX_SHADER_IMAGES) != 0),
601 .shaderStorageImageMultisample = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_TEXTURE_MULTISAMPLE) != 0),
602 .shaderUniformBufferArrayDynamicIndexing = true,
603 .shaderSampledImageArrayDynamicIndexing = indirect,
604 .shaderStorageBufferArrayDynamicIndexing = true,
605 .shaderStorageImageArrayDynamicIndexing = indirect,
606 .shaderStorageImageReadWithoutFormat = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_IMAGE_LOAD_FORMATTED) != 0),
607 .shaderStorageImageWriteWithoutFormat = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_IMAGE_STORE_FORMATTED) != 0),
608 .shaderClipDistance = true,
609 .shaderCullDistance = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_CULL_DISTANCE) == 1),
610 .shaderFloat64 = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_DOUBLES) == 1),
611 .shaderInt64 = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_INT64) == 1),
612 .shaderInt16 = (min_shader_param(pdevice->pscreen, PIPE_SHADER_CAP_INT16) == 1),
613 .variableMultisampleRate = false,
614 .inheritedQueries = false,
615 };
616 }
617
618 static void
lvp_get_physical_device_features_1_1(struct lvp_physical_device * pdevice,VkPhysicalDeviceVulkan11Features * f)619 lvp_get_physical_device_features_1_1(struct lvp_physical_device *pdevice,
620 VkPhysicalDeviceVulkan11Features *f)
621 {
622 assert(f->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES);
623
624 f->storageBuffer16BitAccess = true;
625 f->uniformAndStorageBuffer16BitAccess = true;
626 f->storagePushConstant16 = true;
627 f->storageInputOutput16 = false;
628 f->multiview = true;
629 f->multiviewGeometryShader = true;
630 f->multiviewTessellationShader = true;
631 f->variablePointersStorageBuffer = true;
632 f->variablePointers = true;
633 f->protectedMemory = false;
634 f->samplerYcbcrConversion = false;
635 f->shaderDrawParameters = true;
636 }
637
638 static void
lvp_get_physical_device_features_1_2(struct lvp_physical_device * pdevice,VkPhysicalDeviceVulkan12Features * f)639 lvp_get_physical_device_features_1_2(struct lvp_physical_device *pdevice,
640 VkPhysicalDeviceVulkan12Features *f)
641 {
642 assert(f->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES);
643
644 f->samplerMirrorClampToEdge = true;
645 f->drawIndirectCount = true;
646 f->storageBuffer8BitAccess = true;
647 f->uniformAndStorageBuffer8BitAccess = true;
648 f->storagePushConstant8 = true;
649 f->shaderBufferInt64Atomics = true;
650 f->shaderSharedInt64Atomics = true;
651 f->shaderFloat16 = pdevice->pscreen->get_shader_param(pdevice->pscreen, PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_FP16) != 0;
652 f->shaderInt8 = true;
653
654 f->descriptorIndexing = false;
655 f->shaderInputAttachmentArrayDynamicIndexing = false;
656 f->shaderUniformTexelBufferArrayDynamicIndexing = false;
657 f->shaderStorageTexelBufferArrayDynamicIndexing = false;
658 f->shaderUniformBufferArrayNonUniformIndexing = false;
659 f->shaderSampledImageArrayNonUniformIndexing = false;
660 f->shaderStorageBufferArrayNonUniformIndexing = false;
661 f->shaderStorageImageArrayNonUniformIndexing = false;
662 f->shaderInputAttachmentArrayNonUniformIndexing = false;
663 f->shaderUniformTexelBufferArrayNonUniformIndexing = false;
664 f->shaderStorageTexelBufferArrayNonUniformIndexing = false;
665 f->descriptorBindingUniformBufferUpdateAfterBind = false;
666 f->descriptorBindingSampledImageUpdateAfterBind = false;
667 f->descriptorBindingStorageImageUpdateAfterBind = false;
668 f->descriptorBindingStorageBufferUpdateAfterBind = false;
669 f->descriptorBindingUniformTexelBufferUpdateAfterBind = false;
670 f->descriptorBindingStorageTexelBufferUpdateAfterBind = false;
671 f->descriptorBindingUpdateUnusedWhilePending = false;
672 f->descriptorBindingPartiallyBound = false;
673 f->descriptorBindingVariableDescriptorCount = false;
674 f->runtimeDescriptorArray = false;
675
676 f->samplerFilterMinmax = true;
677 f->scalarBlockLayout = true;
678 f->imagelessFramebuffer = true;
679 f->uniformBufferStandardLayout = true;
680 f->shaderSubgroupExtendedTypes = true;
681 f->separateDepthStencilLayouts = true;
682 f->hostQueryReset = true;
683 f->timelineSemaphore = true;
684 f->bufferDeviceAddress = true;
685 f->bufferDeviceAddressCaptureReplay = false;
686 f->bufferDeviceAddressMultiDevice = false;
687 f->vulkanMemoryModel = true;
688 f->vulkanMemoryModelDeviceScope = true;
689 f->vulkanMemoryModelAvailabilityVisibilityChains = true;
690 f->shaderOutputViewportIndex = true;
691 f->shaderOutputLayer = true;
692 f->subgroupBroadcastDynamicId = true;
693 }
694
695 static void
lvp_get_physical_device_features_1_3(struct lvp_physical_device * pdevice,VkPhysicalDeviceVulkan13Features * f)696 lvp_get_physical_device_features_1_3(struct lvp_physical_device *pdevice,
697 VkPhysicalDeviceVulkan13Features *f)
698 {
699 assert(f->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES);
700
701 f->robustImageAccess = VK_TRUE;
702 f->inlineUniformBlock = VK_TRUE;
703 f->descriptorBindingInlineUniformBlockUpdateAfterBind = VK_TRUE;
704 f->pipelineCreationCacheControl = VK_TRUE;
705 f->privateData = VK_TRUE;
706 f->shaderDemoteToHelperInvocation = VK_TRUE;
707 f->shaderTerminateInvocation = VK_TRUE;
708 f->subgroupSizeControl = VK_TRUE;
709 f->computeFullSubgroups = VK_TRUE;
710 f->synchronization2 = VK_TRUE;
711 f->textureCompressionASTC_HDR = VK_FALSE;
712 f->shaderZeroInitializeWorkgroupMemory = VK_TRUE;
713 f->dynamicRendering = VK_TRUE;
714 f->shaderIntegerDotProduct = VK_TRUE;
715 f->maintenance4 = VK_TRUE;
716 }
717
lvp_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,VkPhysicalDeviceFeatures2 * pFeatures)718 VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceFeatures2(
719 VkPhysicalDevice physicalDevice,
720 VkPhysicalDeviceFeatures2 *pFeatures)
721 {
722 LVP_FROM_HANDLE(lvp_physical_device, pdevice, physicalDevice);
723 lvp_GetPhysicalDeviceFeatures(physicalDevice, &pFeatures->features);
724
725 VkPhysicalDeviceVulkan11Features core_1_1 = {
726 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES,
727 };
728 lvp_get_physical_device_features_1_1(pdevice, &core_1_1);
729
730 VkPhysicalDeviceVulkan12Features core_1_2 = {
731 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES,
732 };
733 lvp_get_physical_device_features_1_2(pdevice, &core_1_2);
734
735 VkPhysicalDeviceVulkan13Features core_1_3 = {
736 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES,
737 };
738 lvp_get_physical_device_features_1_3(pdevice, &core_1_3);
739
740 vk_foreach_struct(ext, pFeatures->pNext) {
741
742 if (vk_get_physical_device_core_1_1_feature_ext(ext, &core_1_1))
743 continue;
744 if (vk_get_physical_device_core_1_2_feature_ext(ext, &core_1_2))
745 continue;
746 if (vk_get_physical_device_core_1_3_feature_ext(ext, &core_1_3))
747 continue;
748
749 switch (ext->sType) {
750 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES: {
751 VkPhysicalDevicePrivateDataFeatures *features =
752 (VkPhysicalDevicePrivateDataFeatures *)ext;
753 features->privateData = true;
754 break;
755 }
756 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES: {
757 VkPhysicalDeviceSynchronization2Features *features =
758 (VkPhysicalDeviceSynchronization2Features *)ext;
759 features->synchronization2 = true;
760 break;
761 }
762 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES: {
763 VkPhysicalDevicePipelineCreationCacheControlFeatures *features =
764 (VkPhysicalDevicePipelineCreationCacheControlFeatures *)ext;
765 features->pipelineCreationCacheControl = true;
766 break;
767 }
768 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVES_GENERATED_QUERY_FEATURES_EXT: {
769 VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT *features =
770 (VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT *)ext;
771 features->primitivesGeneratedQuery = true;
772 features->primitivesGeneratedQueryWithRasterizerDiscard = true;
773 features->primitivesGeneratedQueryWithNonZeroStreams = true;
774 break;
775 }
776 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BORDER_COLOR_SWIZZLE_FEATURES_EXT: {
777 VkPhysicalDeviceBorderColorSwizzleFeaturesEXT *features =
778 (VkPhysicalDeviceBorderColorSwizzleFeaturesEXT *)ext;
779 features->borderColorSwizzle = true;
780 features->borderColorSwizzleFromImage = true;
781 break;
782 }
783 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_NON_SEAMLESS_CUBE_MAP_FEATURES_EXT: {
784 VkPhysicalDeviceNonSeamlessCubeMapFeaturesEXT *features =
785 (VkPhysicalDeviceNonSeamlessCubeMapFeaturesEXT *)ext;
786 features->nonSeamlessCubeMap = true;
787 break;
788 }
789 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT: {
790 VkPhysicalDeviceLineRasterizationFeaturesEXT *features =
791 (VkPhysicalDeviceLineRasterizationFeaturesEXT *)ext;
792 features->rectangularLines = true;
793 features->bresenhamLines = true;
794 features->smoothLines = true;
795 features->stippledRectangularLines = true;
796 features->stippledBresenhamLines = true;
797 features->stippledSmoothLines = true;
798 break;
799 }
800 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT: {
801 VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *features =
802 (VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *)ext;
803 if (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR) != 0) {
804 features->vertexAttributeInstanceRateZeroDivisor = true;
805 features->vertexAttributeInstanceRateDivisor = true;
806 } else {
807 features->vertexAttributeInstanceRateDivisor = false;
808 features->vertexAttributeInstanceRateZeroDivisor = false;
809 }
810 break;
811 }
812 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_FEATURES_EXT: {
813 VkPhysicalDeviceMultisampledRenderToSingleSampledFeaturesEXT *features =
814 (VkPhysicalDeviceMultisampledRenderToSingleSampledFeaturesEXT *)ext;
815 features->multisampledRenderToSingleSampled = true;
816 break;
817 }
818 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT: {
819 VkPhysicalDeviceIndexTypeUint8FeaturesEXT *features =
820 (VkPhysicalDeviceIndexTypeUint8FeaturesEXT *)ext;
821 features->indexTypeUint8 = true;
822 break;
823 }
824 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES: {
825 VkPhysicalDeviceShaderIntegerDotProductFeatures *features =
826 (VkPhysicalDeviceShaderIntegerDotProductFeatures *)ext;
827 features->shaderIntegerDotProduct = true;
828 break;
829 }
830
831 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_INPUT_DYNAMIC_STATE_FEATURES_EXT: {
832 VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT *features =
833 (VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT *)ext;
834 features->vertexInputDynamicState = true;
835 break;
836 }
837 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES: {
838 VkPhysicalDeviceMaintenance4Features *features =
839 (VkPhysicalDeviceMaintenance4Features *)ext;
840 features->maintenance4 = true;
841 break;
842 }
843
844 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES: {
845 VkPhysicalDeviceSubgroupSizeControlFeatures *features =
846 (VkPhysicalDeviceSubgroupSizeControlFeatures *)ext;
847 features->subgroupSizeControl = true;
848 features->computeFullSubgroups = true;
849 break;
850 }
851
852 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_CONTROL_FEATURES_EXT: {
853 VkPhysicalDeviceDepthClipControlFeaturesEXT *features =
854 (VkPhysicalDeviceDepthClipControlFeaturesEXT *)ext;
855 features->depthClipControl = true;
856 break;
857 }
858 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES: {
859 VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures *features =
860 (VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures *)ext;
861 features->shaderZeroInitializeWorkgroupMemory = true;
862 break;
863 }
864 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT: {
865 VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT *features =
866 (VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT *)ext;
867 features->texelBufferAlignment = true;
868 break;
869 }
870 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT: {
871 VkPhysicalDeviceTransformFeedbackFeaturesEXT *features =
872 (VkPhysicalDeviceTransformFeedbackFeaturesEXT*)ext;
873
874 features->transformFeedback = true;
875 features->geometryStreams = true;
876 break;
877 }
878 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT: {
879 VkPhysicalDeviceConditionalRenderingFeaturesEXT *features =
880 (VkPhysicalDeviceConditionalRenderingFeaturesEXT*)ext;
881 features->conditionalRendering = true;
882 features->inheritedConditionalRendering = false;
883 break;
884 }
885 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT: {
886 VkPhysicalDeviceExtendedDynamicStateFeaturesEXT *features =
887 (VkPhysicalDeviceExtendedDynamicStateFeaturesEXT*)ext;
888 features->extendedDynamicState = true;
889 break;
890 }
891 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES: {
892 VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures *features =
893 (VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures *)ext;
894 features->shaderDemoteToHelperInvocation = true;
895 break;
896 }
897 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT: {
898 VkPhysicalDevice4444FormatsFeaturesEXT *features =
899 (VkPhysicalDevice4444FormatsFeaturesEXT*)ext;
900 features->formatA4R4G4B4 = true;
901 features->formatA4B4G4R4 = true;
902 break;
903 }
904 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES: {
905 VkPhysicalDeviceInlineUniformBlockFeatures *features =
906 (VkPhysicalDeviceInlineUniformBlockFeatures*)ext;
907 features->inlineUniformBlock = true;
908 features->descriptorBindingInlineUniformBlockUpdateAfterBind = true;
909 break;
910 }
911 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT: {
912 VkPhysicalDeviceCustomBorderColorFeaturesEXT *features =
913 (VkPhysicalDeviceCustomBorderColorFeaturesEXT *)ext;
914 features->customBorderColors = true;
915 features->customBorderColorWithoutFormat = true;
916 break;
917 }
918 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT: {
919 VkPhysicalDeviceColorWriteEnableFeaturesEXT *features =
920 (VkPhysicalDeviceColorWriteEnableFeaturesEXT *)ext;
921 features->colorWriteEnable = true;
922 break;
923 }
924 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_2D_VIEW_OF_3D_FEATURES_EXT: {
925 VkPhysicalDeviceImage2DViewOf3DFeaturesEXT *features =
926 (VkPhysicalDeviceImage2DViewOf3DFeaturesEXT *)ext;
927 features->image2DViewOf3D = true;
928 features->sampler2DViewOf3D = true;
929 break;
930 }
931 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT: {
932 VkPhysicalDeviceProvokingVertexFeaturesEXT *features =
933 (VkPhysicalDeviceProvokingVertexFeaturesEXT*)ext;
934 features->provokingVertexLast = true;
935 features->transformFeedbackPreservesProvokingVertex = true;
936 break;
937 }
938 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_FEATURES_EXT: {
939 VkPhysicalDeviceMultiDrawFeaturesEXT *features = (VkPhysicalDeviceMultiDrawFeaturesEXT *)ext;
940 features->multiDraw = true;
941 break;
942 }
943 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT: {
944 VkPhysicalDeviceDepthClipEnableFeaturesEXT *features =
945 (VkPhysicalDeviceDepthClipEnableFeaturesEXT *)ext;
946 if (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_DEPTH_CLAMP_ENABLE) != 0)
947 features->depthClipEnable = true;
948 else
949 features->depthClipEnable = false;
950 break;
951 }
952 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT: {
953 VkPhysicalDeviceExtendedDynamicState2FeaturesEXT *features = (VkPhysicalDeviceExtendedDynamicState2FeaturesEXT *)ext;
954 features->extendedDynamicState2 = true;
955 features->extendedDynamicState2LogicOp = true;
956 features->extendedDynamicState2PatchControlPoints = true;
957 break;
958 }
959 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES: {
960 VkPhysicalDeviceImageRobustnessFeatures *features = (VkPhysicalDeviceImageRobustnessFeatures *)ext;
961 features->robustImageAccess = true;
962 break;
963 }
964 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT: {
965 VkPhysicalDeviceRobustness2FeaturesEXT *features = (VkPhysicalDeviceRobustness2FeaturesEXT *)ext;
966 features->robustBufferAccess2 = true;
967 features->robustImageAccess2 = true;
968 features->nullDescriptor = true;
969 break;
970 }
971 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT: {
972 VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT *features = (VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT *)ext;
973 features->primitiveTopologyListRestart = true;
974 features->primitiveTopologyPatchListRestart = true;
975 break;
976 }
977 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES: {
978 VkPhysicalDeviceShaderTerminateInvocationFeatures *features = (VkPhysicalDeviceShaderTerminateInvocationFeatures *)ext;
979 features->shaderTerminateInvocation = true;
980 break;
981 }
982 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES: {
983 VkPhysicalDeviceDynamicRenderingFeatures *features = (VkPhysicalDeviceDynamicRenderingFeatures *)ext;
984 features->dynamicRendering = VK_TRUE;
985 break;
986 }
987 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_FEATURES_EXT: {
988 VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT *features = (VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT *)ext;
989 features->graphicsPipelineLibrary = VK_TRUE;
990 break;
991 }
992 default:
993 break;
994 }
995 }
996 }
997
998 void
lvp_device_get_cache_uuid(void * uuid)999 lvp_device_get_cache_uuid(void *uuid)
1000 {
1001 memset(uuid, 0, VK_UUID_SIZE);
1002 snprintf(uuid, VK_UUID_SIZE, "val-%s", &MESA_GIT_SHA1[4]);
1003 }
1004
lvp_GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,VkPhysicalDeviceProperties * pProperties)1005 VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
1006 VkPhysicalDeviceProperties *pProperties)
1007 {
1008 LVP_FROM_HANDLE(lvp_physical_device, pdevice, physicalDevice);
1009
1010 *pProperties = (VkPhysicalDeviceProperties) {
1011 .apiVersion = LVP_API_VERSION,
1012 .driverVersion = 1,
1013 .vendorID = VK_VENDOR_ID_MESA,
1014 .deviceID = 0,
1015 .deviceType = VK_PHYSICAL_DEVICE_TYPE_CPU,
1016 .limits = pdevice->device_limits,
1017 .sparseProperties = {0},
1018 };
1019
1020 strcpy(pProperties->deviceName, pdevice->pscreen->get_name(pdevice->pscreen));
1021 lvp_device_get_cache_uuid(pProperties->pipelineCacheUUID);
1022
1023 }
1024
1025 extern unsigned lp_native_vector_width;
1026 static void
lvp_get_physical_device_properties_1_1(struct lvp_physical_device * pdevice,VkPhysicalDeviceVulkan11Properties * p)1027 lvp_get_physical_device_properties_1_1(struct lvp_physical_device *pdevice,
1028 VkPhysicalDeviceVulkan11Properties *p)
1029 {
1030 assert(p->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES);
1031
1032 pdevice->pscreen->get_device_uuid(pdevice->pscreen, (char*)(p->deviceUUID));
1033 pdevice->pscreen->get_driver_uuid(pdevice->pscreen, (char*)(p->driverUUID));
1034 memset(p->deviceLUID, 0, VK_LUID_SIZE);
1035 /* The LUID is for Windows. */
1036 p->deviceLUIDValid = false;
1037 p->deviceNodeMask = 0;
1038
1039 p->subgroupSize = lp_native_vector_width / 32;
1040 p->subgroupSupportedStages = VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT;
1041 p->subgroupSupportedOperations = VK_SUBGROUP_FEATURE_BASIC_BIT | VK_SUBGROUP_FEATURE_VOTE_BIT | VK_SUBGROUP_FEATURE_ARITHMETIC_BIT | VK_SUBGROUP_FEATURE_BALLOT_BIT;
1042 p->subgroupQuadOperationsInAllStages = false;
1043
1044 #if LLVM_VERSION_MAJOR >= 10
1045 p->subgroupSupportedOperations |= VK_SUBGROUP_FEATURE_SHUFFLE_BIT | VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT | VK_SUBGROUP_FEATURE_QUAD_BIT;
1046 #endif
1047
1048 p->pointClippingBehavior = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES;
1049 p->maxMultiviewViewCount = 6;
1050 p->maxMultiviewInstanceIndex = INT_MAX;
1051 p->protectedNoFault = false;
1052 p->maxPerSetDescriptors = 1024;
1053 p->maxMemoryAllocationSize = (1u << 31);
1054 }
1055
1056 static void
lvp_get_physical_device_properties_1_2(struct lvp_physical_device * pdevice,VkPhysicalDeviceVulkan12Properties * p)1057 lvp_get_physical_device_properties_1_2(struct lvp_physical_device *pdevice,
1058 VkPhysicalDeviceVulkan12Properties *p)
1059 {
1060 p->driverID = VK_DRIVER_ID_MESA_LLVMPIPE;
1061 snprintf(p->driverName, VK_MAX_DRIVER_NAME_SIZE, "llvmpipe");
1062 snprintf(p->driverInfo, VK_MAX_DRIVER_INFO_SIZE, "Mesa " PACKAGE_VERSION MESA_GIT_SHA1
1063 #ifdef MESA_LLVM_VERSION_STRING
1064 " (LLVM " MESA_LLVM_VERSION_STRING ")"
1065 #endif
1066 );
1067
1068 p->conformanceVersion = (VkConformanceVersion){
1069 .major = 1,
1070 .minor = 3,
1071 .subminor = 1,
1072 .patch = 1,
1073 };
1074
1075 p->denormBehaviorIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL;
1076 p->roundingModeIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL;
1077 p->shaderDenormFlushToZeroFloat16 = false;
1078 p->shaderDenormPreserveFloat16 = false;
1079 p->shaderRoundingModeRTEFloat16 = true;
1080 p->shaderRoundingModeRTZFloat16 = false;
1081 p->shaderSignedZeroInfNanPreserveFloat16 = true;
1082
1083 p->shaderDenormFlushToZeroFloat32 = false;
1084 p->shaderDenormPreserveFloat32 = false;
1085 p->shaderRoundingModeRTEFloat32 = true;
1086 p->shaderRoundingModeRTZFloat32 = false;
1087 p->shaderSignedZeroInfNanPreserveFloat32 = true;
1088
1089 p->shaderDenormFlushToZeroFloat64 = false;
1090 p->shaderDenormPreserveFloat64 = false;
1091 p->shaderRoundingModeRTEFloat64 = true;
1092 p->shaderRoundingModeRTZFloat64 = false;
1093 p->shaderSignedZeroInfNanPreserveFloat64 = true;
1094
1095 p->maxUpdateAfterBindDescriptorsInAllPools = UINT32_MAX / 64;
1096 p->shaderUniformBufferArrayNonUniformIndexingNative = false;
1097 p->shaderSampledImageArrayNonUniformIndexingNative = false;
1098 p->shaderStorageBufferArrayNonUniformIndexingNative = false;
1099 p->shaderStorageImageArrayNonUniformIndexingNative = false;
1100 p->shaderInputAttachmentArrayNonUniformIndexingNative = false;
1101 p->robustBufferAccessUpdateAfterBind = true;
1102 p->quadDivergentImplicitLod = false;
1103
1104 size_t max_descriptor_set_size = 65536; //TODO
1105 p->maxPerStageDescriptorUpdateAfterBindSamplers = max_descriptor_set_size;
1106 p->maxPerStageDescriptorUpdateAfterBindUniformBuffers = max_descriptor_set_size;
1107 p->maxPerStageDescriptorUpdateAfterBindStorageBuffers = max_descriptor_set_size;
1108 p->maxPerStageDescriptorUpdateAfterBindSampledImages = max_descriptor_set_size;
1109 p->maxPerStageDescriptorUpdateAfterBindStorageImages = max_descriptor_set_size;
1110 p->maxPerStageDescriptorUpdateAfterBindInputAttachments = max_descriptor_set_size;
1111 p->maxPerStageUpdateAfterBindResources = max_descriptor_set_size;
1112 p->maxDescriptorSetUpdateAfterBindSamplers = max_descriptor_set_size;
1113 p->maxDescriptorSetUpdateAfterBindUniformBuffers = max_descriptor_set_size;
1114 p->maxDescriptorSetUpdateAfterBindUniformBuffersDynamic = 16;
1115 p->maxDescriptorSetUpdateAfterBindStorageBuffers = max_descriptor_set_size;
1116 p->maxDescriptorSetUpdateAfterBindStorageBuffersDynamic = 16;
1117 p->maxDescriptorSetUpdateAfterBindSampledImages = max_descriptor_set_size;
1118 p->maxDescriptorSetUpdateAfterBindStorageImages = max_descriptor_set_size;
1119 p->maxDescriptorSetUpdateAfterBindInputAttachments = max_descriptor_set_size;
1120
1121 p->supportedDepthResolveModes = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT | VK_RESOLVE_MODE_AVERAGE_BIT;
1122 p->supportedStencilResolveModes = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT;
1123 p->independentResolveNone = false;
1124 p->independentResolve = false;
1125
1126 p->filterMinmaxImageComponentMapping = true;
1127 p->filterMinmaxSingleComponentFormats = true;
1128
1129 p->maxTimelineSemaphoreValueDifference = UINT64_MAX;
1130 p->framebufferIntegerColorSampleCounts = VK_SAMPLE_COUNT_1_BIT;
1131 }
1132
1133 static void
lvp_get_physical_device_properties_1_3(struct lvp_physical_device * pdevice,VkPhysicalDeviceVulkan13Properties * p)1134 lvp_get_physical_device_properties_1_3(struct lvp_physical_device *pdevice,
1135 VkPhysicalDeviceVulkan13Properties *p)
1136 {
1137 p->minSubgroupSize = lp_native_vector_width / 32;
1138 p->maxSubgroupSize = lp_native_vector_width / 32;
1139 p->maxComputeWorkgroupSubgroups = 32;
1140 p->requiredSubgroupSizeStages = VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT;
1141 p->maxInlineUniformTotalSize = MAX_DESCRIPTOR_UNIFORM_BLOCK_SIZE * MAX_PER_STAGE_DESCRIPTOR_UNIFORM_BLOCKS * MAX_SETS;
1142 p->maxInlineUniformBlockSize = MAX_DESCRIPTOR_UNIFORM_BLOCK_SIZE;
1143 p->maxPerStageDescriptorInlineUniformBlocks = MAX_PER_STAGE_DESCRIPTOR_UNIFORM_BLOCKS;
1144 p->maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks = MAX_PER_STAGE_DESCRIPTOR_UNIFORM_BLOCKS;
1145 p->maxDescriptorSetInlineUniformBlocks = MAX_PER_STAGE_DESCRIPTOR_UNIFORM_BLOCKS;
1146 p->maxDescriptorSetUpdateAfterBindInlineUniformBlocks = MAX_PER_STAGE_DESCRIPTOR_UNIFORM_BLOCKS;
1147 int alignment = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT);
1148 p->storageTexelBufferOffsetAlignmentBytes = alignment;
1149 p->storageTexelBufferOffsetSingleTexelAlignment = true;
1150 p->uniformTexelBufferOffsetAlignmentBytes = alignment;
1151 p->uniformTexelBufferOffsetSingleTexelAlignment = true;
1152 p->maxBufferSize = UINT32_MAX;
1153 }
1154
lvp_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,VkPhysicalDeviceProperties2 * pProperties)1155 VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceProperties2(
1156 VkPhysicalDevice physicalDevice,
1157 VkPhysicalDeviceProperties2 *pProperties)
1158 {
1159 LVP_FROM_HANDLE(lvp_physical_device, pdevice, physicalDevice);
1160 lvp_GetPhysicalDeviceProperties(physicalDevice, &pProperties->properties);
1161
1162 VkPhysicalDeviceVulkan11Properties core_1_1 = {
1163 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES,
1164 };
1165 lvp_get_physical_device_properties_1_1(pdevice, &core_1_1);
1166
1167 VkPhysicalDeviceVulkan12Properties core_1_2 = {
1168 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES,
1169 };
1170 lvp_get_physical_device_properties_1_2(pdevice, &core_1_2);
1171
1172 VkPhysicalDeviceVulkan13Properties core_1_3 = {
1173 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_PROPERTIES,
1174 };
1175 lvp_get_physical_device_properties_1_3(pdevice, &core_1_3);
1176
1177 vk_foreach_struct(ext, pProperties->pNext) {
1178
1179 if (vk_get_physical_device_core_1_1_property_ext(ext, &core_1_1))
1180 continue;
1181 if (vk_get_physical_device_core_1_2_property_ext(ext, &core_1_2))
1182 continue;
1183 if (vk_get_physical_device_core_1_3_property_ext(ext, &core_1_3))
1184 continue;
1185 switch (ext->sType) {
1186 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR: {
1187 VkPhysicalDevicePushDescriptorPropertiesKHR *properties =
1188 (VkPhysicalDevicePushDescriptorPropertiesKHR *) ext;
1189 properties->maxPushDescriptors = MAX_PUSH_DESCRIPTORS;
1190 break;
1191 }
1192 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES: {
1193 VkPhysicalDeviceShaderIntegerDotProductProperties *properties =
1194 (VkPhysicalDeviceShaderIntegerDotProductProperties *) ext;
1195 void *pnext = properties->pNext;
1196 memset(properties, 0, sizeof(VkPhysicalDeviceShaderIntegerDotProductProperties));
1197 properties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES;
1198 properties->pNext = pnext;
1199 break;
1200 }
1201 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES: {
1202 VkPhysicalDevicePointClippingProperties *properties =
1203 (VkPhysicalDevicePointClippingProperties*)ext;
1204 properties->pointClippingBehavior = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES;
1205 break;
1206 }
1207 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT: {
1208 VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *props =
1209 (VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *)ext;
1210 if (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR) != 0)
1211 props->maxVertexAttribDivisor = UINT32_MAX;
1212 else
1213 props->maxVertexAttribDivisor = 1;
1214 break;
1215 }
1216 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT: {
1217 VkPhysicalDeviceTransformFeedbackPropertiesEXT *properties =
1218 (VkPhysicalDeviceTransformFeedbackPropertiesEXT*)ext;
1219 properties->maxTransformFeedbackStreams = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_VERTEX_STREAMS);
1220 properties->maxTransformFeedbackBuffers = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS);
1221 properties->maxTransformFeedbackBufferSize = UINT32_MAX;
1222 properties->maxTransformFeedbackStreamDataSize = 512;
1223 properties->maxTransformFeedbackBufferDataSize = 512;
1224 properties->maxTransformFeedbackBufferDataStride = 512;
1225 properties->transformFeedbackQueries = true;
1226 properties->transformFeedbackStreamsLinesTriangles = false;
1227 properties->transformFeedbackRasterizationStreamSelect = false;
1228 properties->transformFeedbackDraw = true;
1229 break;
1230 }
1231 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES: {
1232 VkPhysicalDeviceMaintenance4Properties *properties =
1233 (VkPhysicalDeviceMaintenance4Properties *)ext;
1234 properties->maxBufferSize = UINT32_MAX;
1235 break;
1236 }
1237 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT: {
1238 VkPhysicalDeviceLineRasterizationPropertiesEXT *properties =
1239 (VkPhysicalDeviceLineRasterizationPropertiesEXT *)ext;
1240 properties->lineSubPixelPrecisionBits =
1241 pdevice->pscreen->get_param(pdevice->pscreen,
1242 PIPE_CAP_RASTERIZER_SUBPIXEL_BITS);
1243 break;
1244 }
1245 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES: {
1246 VkPhysicalDeviceInlineUniformBlockProperties *properties =
1247 (VkPhysicalDeviceInlineUniformBlockProperties *)ext;
1248 properties->maxInlineUniformBlockSize = MAX_DESCRIPTOR_UNIFORM_BLOCK_SIZE;
1249 properties->maxPerStageDescriptorInlineUniformBlocks = MAX_PER_STAGE_DESCRIPTOR_UNIFORM_BLOCKS;
1250 properties->maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks = MAX_PER_STAGE_DESCRIPTOR_UNIFORM_BLOCKS;
1251 properties->maxDescriptorSetInlineUniformBlocks = MAX_PER_STAGE_DESCRIPTOR_UNIFORM_BLOCKS;
1252 properties->maxDescriptorSetUpdateAfterBindInlineUniformBlocks = MAX_PER_STAGE_DESCRIPTOR_UNIFORM_BLOCKS;
1253 break;
1254 }
1255 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT: {
1256 VkPhysicalDeviceExternalMemoryHostPropertiesEXT *properties =
1257 (VkPhysicalDeviceExternalMemoryHostPropertiesEXT *)ext;
1258 properties->minImportedHostPointerAlignment = 4096;
1259 break;
1260 }
1261 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_PROPERTIES_EXT: {
1262 VkPhysicalDeviceCustomBorderColorPropertiesEXT *properties =
1263 (VkPhysicalDeviceCustomBorderColorPropertiesEXT *)ext;
1264 properties->maxCustomBorderColorSamplers = 32 * 1024;
1265 break;
1266 }
1267 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES: {
1268 VkPhysicalDeviceSubgroupSizeControlProperties *props = (VkPhysicalDeviceSubgroupSizeControlProperties *)ext;
1269 props->minSubgroupSize = lp_native_vector_width / 32;
1270 props->maxSubgroupSize = lp_native_vector_width / 32;
1271 props->maxComputeWorkgroupSubgroups = 32;
1272 props->requiredSubgroupSizeStages = VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT;
1273 break;
1274 }
1275 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_PROPERTIES_EXT: {
1276 VkPhysicalDeviceProvokingVertexPropertiesEXT *properties =
1277 (VkPhysicalDeviceProvokingVertexPropertiesEXT*)ext;
1278 properties->provokingVertexModePerPipeline = true;
1279 properties->transformFeedbackPreservesTriangleFanProvokingVertex = true;
1280 break;
1281 }
1282 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_PROPERTIES_EXT: {
1283 VkPhysicalDeviceMultiDrawPropertiesEXT *props = (VkPhysicalDeviceMultiDrawPropertiesEXT *)ext;
1284 props->maxMultiDrawCount = 2048;
1285 break;
1286 }
1287 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES: {
1288 VkPhysicalDeviceTexelBufferAlignmentProperties *properties =
1289 (VkPhysicalDeviceTexelBufferAlignmentProperties *)ext;
1290 int alignment = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT);
1291 properties->storageTexelBufferOffsetAlignmentBytes = alignment;
1292 properties->storageTexelBufferOffsetSingleTexelAlignment = true;
1293 properties->uniformTexelBufferOffsetAlignmentBytes = alignment;
1294 properties->uniformTexelBufferOffsetSingleTexelAlignment = true;
1295 break;
1296 }
1297 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_PROPERTIES_EXT: {
1298 VkPhysicalDeviceGraphicsPipelineLibraryPropertiesEXT *props = (VkPhysicalDeviceGraphicsPipelineLibraryPropertiesEXT *)ext;
1299 props->graphicsPipelineLibraryFastLinking = VK_TRUE;
1300 props->graphicsPipelineLibraryIndependentInterpolationDecoration = VK_TRUE;
1301 break;
1302 }
1303 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_PROPERTIES_EXT: {
1304 VkPhysicalDeviceRobustness2PropertiesEXT *props =
1305 (VkPhysicalDeviceRobustness2PropertiesEXT *)ext;
1306 props->robustStorageBufferAccessSizeAlignment = 1;
1307 props->robustUniformBufferAccessSizeAlignment = 1;
1308 break;
1309 }
1310 default:
1311 break;
1312 }
1313 }
1314 }
1315
lvp_GetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice,uint32_t * pCount,VkQueueFamilyProperties2 * pQueueFamilyProperties)1316 VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceQueueFamilyProperties2(
1317 VkPhysicalDevice physicalDevice,
1318 uint32_t* pCount,
1319 VkQueueFamilyProperties2 *pQueueFamilyProperties)
1320 {
1321 VK_OUTARRAY_MAKE_TYPED(VkQueueFamilyProperties2, out, pQueueFamilyProperties, pCount);
1322
1323 vk_outarray_append_typed(VkQueueFamilyProperties2, &out, p) {
1324 p->queueFamilyProperties = (VkQueueFamilyProperties) {
1325 .queueFlags = VK_QUEUE_GRAPHICS_BIT |
1326 VK_QUEUE_COMPUTE_BIT |
1327 VK_QUEUE_TRANSFER_BIT,
1328 .queueCount = 1,
1329 .timestampValidBits = 64,
1330 .minImageTransferGranularity = (VkExtent3D) { 1, 1, 1 },
1331 };
1332 }
1333 }
1334
lvp_GetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice,VkPhysicalDeviceMemoryProperties * pMemoryProperties)1335 VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceMemoryProperties(
1336 VkPhysicalDevice physicalDevice,
1337 VkPhysicalDeviceMemoryProperties* pMemoryProperties)
1338 {
1339 pMemoryProperties->memoryTypeCount = 1;
1340 pMemoryProperties->memoryTypes[0] = (VkMemoryType) {
1341 .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
1342 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
1343 VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
1344 VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
1345 .heapIndex = 0,
1346 };
1347
1348 pMemoryProperties->memoryHeapCount = 1;
1349 pMemoryProperties->memoryHeaps[0] = (VkMemoryHeap) {
1350 .size = 2ULL*1024*1024*1024,
1351 .flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT,
1352 };
1353 }
1354
lvp_GetPhysicalDeviceMemoryProperties2(VkPhysicalDevice physicalDevice,VkPhysicalDeviceMemoryProperties2 * pMemoryProperties)1355 VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceMemoryProperties2(
1356 VkPhysicalDevice physicalDevice,
1357 VkPhysicalDeviceMemoryProperties2 *pMemoryProperties)
1358 {
1359 lvp_GetPhysicalDeviceMemoryProperties(physicalDevice,
1360 &pMemoryProperties->memoryProperties);
1361 }
1362
1363 VKAPI_ATTR VkResult VKAPI_CALL
lvp_GetMemoryHostPointerPropertiesEXT(VkDevice _device,VkExternalMemoryHandleTypeFlagBits handleType,const void * pHostPointer,VkMemoryHostPointerPropertiesEXT * pMemoryHostPointerProperties)1364 lvp_GetMemoryHostPointerPropertiesEXT(
1365 VkDevice _device,
1366 VkExternalMemoryHandleTypeFlagBits handleType,
1367 const void *pHostPointer,
1368 VkMemoryHostPointerPropertiesEXT *pMemoryHostPointerProperties)
1369 {
1370 switch (handleType) {
1371 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT: {
1372 pMemoryHostPointerProperties->memoryTypeBits = 1;
1373 return VK_SUCCESS;
1374 }
1375 default:
1376 return VK_ERROR_INVALID_EXTERNAL_HANDLE;
1377 }
1378 }
1379
lvp_GetInstanceProcAddr(VkInstance _instance,const char * pName)1380 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL lvp_GetInstanceProcAddr(
1381 VkInstance _instance,
1382 const char* pName)
1383 {
1384 LVP_FROM_HANDLE(lvp_instance, instance, _instance);
1385 return vk_instance_get_proc_addr(&instance->vk,
1386 &lvp_instance_entrypoints,
1387 pName);
1388 }
1389
1390 /* Windows will use a dll definition file to avoid build errors. */
1391 #ifdef _WIN32
1392 #undef PUBLIC
1393 #define PUBLIC
1394 #endif
1395
1396 /* The loader wants us to expose a second GetInstanceProcAddr function
1397 * to work around certain LD_PRELOAD issues seen in apps.
1398 */
1399 PUBLIC
1400 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(
1401 VkInstance instance,
1402 const char* pName);
1403
1404 PUBLIC
vk_icdGetInstanceProcAddr(VkInstance instance,const char * pName)1405 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(
1406 VkInstance instance,
1407 const char* pName)
1408 {
1409 return lvp_GetInstanceProcAddr(instance, pName);
1410 }
1411
1412 PUBLIC
1413 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetPhysicalDeviceProcAddr(
1414 VkInstance _instance,
1415 const char* pName);
1416
1417 PUBLIC
vk_icdGetPhysicalDeviceProcAddr(VkInstance _instance,const char * pName)1418 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetPhysicalDeviceProcAddr(
1419 VkInstance _instance,
1420 const char* pName)
1421 {
1422 LVP_FROM_HANDLE(lvp_instance, instance, _instance);
1423 return vk_instance_get_physical_device_proc_addr(&instance->vk, pName);
1424 }
1425
1426 static void
destroy_pipelines(struct lvp_queue * queue)1427 destroy_pipelines(struct lvp_queue *queue)
1428 {
1429 simple_mtx_lock(&queue->pipeline_lock);
1430 while (util_dynarray_contains(&queue->pipeline_destroys, struct lvp_pipeline*)) {
1431 lvp_pipeline_destroy(queue->device, util_dynarray_pop(&queue->pipeline_destroys, struct lvp_pipeline*));
1432 }
1433 simple_mtx_unlock(&queue->pipeline_lock);
1434 }
1435
1436 static VkResult
lvp_queue_submit(struct vk_queue * vk_queue,struct vk_queue_submit * submit)1437 lvp_queue_submit(struct vk_queue *vk_queue,
1438 struct vk_queue_submit *submit)
1439 {
1440 struct lvp_queue *queue = container_of(vk_queue, struct lvp_queue, vk);
1441
1442 VkResult result = vk_sync_wait_many(&queue->device->vk,
1443 submit->wait_count, submit->waits,
1444 VK_SYNC_WAIT_COMPLETE, UINT64_MAX);
1445 if (result != VK_SUCCESS)
1446 return result;
1447
1448 for (uint32_t i = 0; i < submit->command_buffer_count; i++) {
1449 struct lvp_cmd_buffer *cmd_buffer =
1450 container_of(submit->command_buffers[i], struct lvp_cmd_buffer, vk);
1451
1452 lvp_execute_cmds(queue->device, queue, cmd_buffer);
1453 }
1454
1455 if (submit->command_buffer_count > 0)
1456 queue->ctx->flush(queue->ctx, &queue->last_fence, 0);
1457
1458 for (uint32_t i = 0; i < submit->signal_count; i++) {
1459 struct lvp_pipe_sync *sync =
1460 vk_sync_as_lvp_pipe_sync(submit->signals[i].sync);
1461 lvp_pipe_sync_signal_with_fence(queue->device, sync, queue->last_fence);
1462 }
1463 destroy_pipelines(queue);
1464
1465 return VK_SUCCESS;
1466 }
1467
1468 static VkResult
lvp_queue_init(struct lvp_device * device,struct lvp_queue * queue,const VkDeviceQueueCreateInfo * create_info,uint32_t index_in_family)1469 lvp_queue_init(struct lvp_device *device, struct lvp_queue *queue,
1470 const VkDeviceQueueCreateInfo *create_info,
1471 uint32_t index_in_family)
1472 {
1473 VkResult result = vk_queue_init(&queue->vk, &device->vk, create_info,
1474 index_in_family);
1475 if (result != VK_SUCCESS)
1476 return result;
1477
1478 result = vk_queue_enable_submit_thread(&queue->vk);
1479 if (result != VK_SUCCESS) {
1480 vk_queue_finish(&queue->vk);
1481 return result;
1482 }
1483
1484 queue->device = device;
1485
1486 queue->ctx = device->pscreen->context_create(device->pscreen, NULL, PIPE_CONTEXT_ROBUST_BUFFER_ACCESS);
1487 queue->cso = cso_create_context(queue->ctx, CSO_NO_VBUF);
1488 queue->uploader = u_upload_create(queue->ctx, 1024 * 1024, PIPE_BIND_CONSTANT_BUFFER, PIPE_USAGE_STREAM, 0);
1489
1490 queue->vk.driver_submit = lvp_queue_submit;
1491
1492 simple_mtx_init(&queue->pipeline_lock, mtx_plain);
1493 util_dynarray_init(&queue->pipeline_destroys, NULL);
1494
1495 return VK_SUCCESS;
1496 }
1497
1498 static void
lvp_queue_finish(struct lvp_queue * queue)1499 lvp_queue_finish(struct lvp_queue *queue)
1500 {
1501 vk_queue_finish(&queue->vk);
1502
1503 destroy_pipelines(queue);
1504 simple_mtx_destroy(&queue->pipeline_lock);
1505 util_dynarray_fini(&queue->pipeline_destroys);
1506
1507 u_upload_destroy(queue->uploader);
1508 cso_destroy_context(queue->cso);
1509 queue->ctx->destroy(queue->ctx);
1510 }
1511
lvp_CreateDevice(VkPhysicalDevice physicalDevice,const VkDeviceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDevice * pDevice)1512 VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateDevice(
1513 VkPhysicalDevice physicalDevice,
1514 const VkDeviceCreateInfo* pCreateInfo,
1515 const VkAllocationCallbacks* pAllocator,
1516 VkDevice* pDevice)
1517 {
1518 LVP_FROM_HANDLE(lvp_physical_device, physical_device, physicalDevice);
1519 struct lvp_device *device;
1520 struct lvp_instance *instance = (struct lvp_instance *)physical_device->vk.instance;
1521
1522 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO);
1523
1524 size_t state_size = lvp_get_rendering_state_size();
1525 device = vk_zalloc2(&physical_device->vk.instance->alloc, pAllocator,
1526 sizeof(*device) + state_size, 8,
1527 VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
1528 if (!device)
1529 return vk_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY);
1530
1531 device->queue.state = device + 1;
1532 device->poison_mem = debug_get_bool_option("LVP_POISON_MEMORY", false);
1533
1534 struct vk_device_dispatch_table dispatch_table;
1535 vk_device_dispatch_table_from_entrypoints(&dispatch_table,
1536 &lvp_device_entrypoints, true);
1537 lvp_add_enqueue_cmd_entrypoints(&dispatch_table);
1538 vk_device_dispatch_table_from_entrypoints(&dispatch_table,
1539 &wsi_device_entrypoints, false);
1540 VkResult result = vk_device_init(&device->vk,
1541 &physical_device->vk,
1542 &dispatch_table, pCreateInfo,
1543 pAllocator);
1544 if (result != VK_SUCCESS) {
1545 vk_free(&device->vk.alloc, device);
1546 return result;
1547 }
1548
1549 vk_device_enable_threaded_submit(&device->vk);
1550
1551 device->instance = (struct lvp_instance *)physical_device->vk.instance;
1552 device->physical_device = physical_device;
1553
1554 device->pscreen = physical_device->pscreen;
1555
1556 assert(pCreateInfo->queueCreateInfoCount == 1);
1557 assert(pCreateInfo->pQueueCreateInfos[0].queueFamilyIndex == 0);
1558 assert(pCreateInfo->pQueueCreateInfos[0].queueCount == 1);
1559 result = lvp_queue_init(device, &device->queue, pCreateInfo->pQueueCreateInfos, 0);
1560 if (result != VK_SUCCESS) {
1561 vk_free(&device->vk.alloc, device);
1562 return result;
1563 }
1564
1565 *pDevice = lvp_device_to_handle(device);
1566
1567 return VK_SUCCESS;
1568
1569 }
1570
lvp_DestroyDevice(VkDevice _device,const VkAllocationCallbacks * pAllocator)1571 VKAPI_ATTR void VKAPI_CALL lvp_DestroyDevice(
1572 VkDevice _device,
1573 const VkAllocationCallbacks* pAllocator)
1574 {
1575 LVP_FROM_HANDLE(lvp_device, device, _device);
1576
1577 if (device->queue.last_fence)
1578 device->pscreen->fence_reference(device->pscreen, &device->queue.last_fence, NULL);
1579 lvp_queue_finish(&device->queue);
1580 vk_device_finish(&device->vk);
1581 vk_free(&device->vk.alloc, device);
1582 }
1583
lvp_EnumerateInstanceExtensionProperties(const char * pLayerName,uint32_t * pPropertyCount,VkExtensionProperties * pProperties)1584 VKAPI_ATTR VkResult VKAPI_CALL lvp_EnumerateInstanceExtensionProperties(
1585 const char* pLayerName,
1586 uint32_t* pPropertyCount,
1587 VkExtensionProperties* pProperties)
1588 {
1589 if (pLayerName)
1590 return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT);
1591
1592 return vk_enumerate_instance_extension_properties(
1593 &lvp_instance_extensions_supported, pPropertyCount, pProperties);
1594 }
1595
lvp_EnumerateInstanceLayerProperties(uint32_t * pPropertyCount,VkLayerProperties * pProperties)1596 VKAPI_ATTR VkResult VKAPI_CALL lvp_EnumerateInstanceLayerProperties(
1597 uint32_t* pPropertyCount,
1598 VkLayerProperties* pProperties)
1599 {
1600 if (pProperties == NULL) {
1601 *pPropertyCount = 0;
1602 return VK_SUCCESS;
1603 }
1604
1605 /* None supported at this time */
1606 return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT);
1607 }
1608
lvp_EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,uint32_t * pPropertyCount,VkLayerProperties * pProperties)1609 VKAPI_ATTR VkResult VKAPI_CALL lvp_EnumerateDeviceLayerProperties(
1610 VkPhysicalDevice physicalDevice,
1611 uint32_t* pPropertyCount,
1612 VkLayerProperties* pProperties)
1613 {
1614 if (pProperties == NULL) {
1615 *pPropertyCount = 0;
1616 return VK_SUCCESS;
1617 }
1618
1619 /* None supported at this time */
1620 return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT);
1621 }
1622
lvp_AllocateMemory(VkDevice _device,const VkMemoryAllocateInfo * pAllocateInfo,const VkAllocationCallbacks * pAllocator,VkDeviceMemory * pMem)1623 VKAPI_ATTR VkResult VKAPI_CALL lvp_AllocateMemory(
1624 VkDevice _device,
1625 const VkMemoryAllocateInfo* pAllocateInfo,
1626 const VkAllocationCallbacks* pAllocator,
1627 VkDeviceMemory* pMem)
1628 {
1629 LVP_FROM_HANDLE(lvp_device, device, _device);
1630 struct lvp_device_memory *mem;
1631 ASSERTED const VkExportMemoryAllocateInfo *export_info = NULL;
1632 ASSERTED const VkImportMemoryFdInfoKHR *import_info = NULL;
1633 const VkImportMemoryHostPointerInfoEXT *host_ptr_info = NULL;
1634 VkResult error = VK_ERROR_OUT_OF_DEVICE_MEMORY;
1635 assert(pAllocateInfo->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);
1636
1637 if (pAllocateInfo->allocationSize == 0) {
1638 /* Apparently, this is allowed */
1639 *pMem = VK_NULL_HANDLE;
1640 return VK_SUCCESS;
1641 }
1642
1643 vk_foreach_struct_const(ext, pAllocateInfo->pNext) {
1644 switch ((unsigned)ext->sType) {
1645 case VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT:
1646 host_ptr_info = (VkImportMemoryHostPointerInfoEXT*)ext;
1647 assert(host_ptr_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT);
1648 break;
1649 case VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO:
1650 export_info = (VkExportMemoryAllocateInfo*)ext;
1651 assert(!export_info->handleTypes || export_info->handleTypes == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT);
1652 break;
1653 case VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR:
1654 import_info = (VkImportMemoryFdInfoKHR*)ext;
1655 assert(import_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT);
1656 break;
1657 default:
1658 break;
1659 }
1660 }
1661
1662 #ifdef PIPE_MEMORY_FD
1663 if (import_info != NULL && import_info->fd < 0) {
1664 return vk_error(device->instance, VK_ERROR_INVALID_EXTERNAL_HANDLE);
1665 }
1666 #endif
1667
1668 mem = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*mem), 8,
1669 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1670 if (mem == NULL)
1671 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
1672
1673 vk_object_base_init(&device->vk, &mem->base,
1674 VK_OBJECT_TYPE_DEVICE_MEMORY);
1675
1676 mem->memory_type = LVP_DEVICE_MEMORY_TYPE_DEFAULT;
1677 mem->backed_fd = -1;
1678
1679 if (host_ptr_info) {
1680 mem->pmem = host_ptr_info->pHostPointer;
1681 mem->memory_type = LVP_DEVICE_MEMORY_TYPE_USER_PTR;
1682 }
1683 #ifdef PIPE_MEMORY_FD
1684 else if(import_info) {
1685 uint64_t size;
1686 if(!device->pscreen->import_memory_fd(device->pscreen, import_info->fd, &mem->pmem, &size)) {
1687 close(import_info->fd);
1688 error = VK_ERROR_INVALID_EXTERNAL_HANDLE;
1689 goto fail;
1690 }
1691 if(size < pAllocateInfo->allocationSize) {
1692 device->pscreen->free_memory_fd(device->pscreen, mem->pmem);
1693 close(import_info->fd);
1694 goto fail;
1695 }
1696 if (export_info && export_info->handleTypes) {
1697 mem->backed_fd = import_info->fd;
1698 }
1699 else {
1700 close(import_info->fd);
1701 }
1702 mem->memory_type = LVP_DEVICE_MEMORY_TYPE_OPAQUE_FD;
1703 }
1704 else if (export_info && export_info->handleTypes) {
1705 mem->pmem = device->pscreen->allocate_memory_fd(device->pscreen, pAllocateInfo->allocationSize, &mem->backed_fd);
1706 if (!mem->pmem || mem->backed_fd < 0) {
1707 goto fail;
1708 }
1709 mem->memory_type = LVP_DEVICE_MEMORY_TYPE_OPAQUE_FD;
1710 }
1711 #endif
1712 else {
1713 mem->pmem = device->pscreen->allocate_memory(device->pscreen, pAllocateInfo->allocationSize);
1714 if (!mem->pmem) {
1715 goto fail;
1716 }
1717 if (device->poison_mem)
1718 /* this is a value that will definitely break things */
1719 memset(mem->pmem, UINT8_MAX / 2 + 1, pAllocateInfo->allocationSize);
1720 }
1721
1722 mem->type_index = pAllocateInfo->memoryTypeIndex;
1723
1724 *pMem = lvp_device_memory_to_handle(mem);
1725
1726 return VK_SUCCESS;
1727
1728 fail:
1729 vk_free2(&device->vk.alloc, pAllocator, mem);
1730 return vk_error(device, error);
1731 }
1732
lvp_FreeMemory(VkDevice _device,VkDeviceMemory _mem,const VkAllocationCallbacks * pAllocator)1733 VKAPI_ATTR void VKAPI_CALL lvp_FreeMemory(
1734 VkDevice _device,
1735 VkDeviceMemory _mem,
1736 const VkAllocationCallbacks* pAllocator)
1737 {
1738 LVP_FROM_HANDLE(lvp_device, device, _device);
1739 LVP_FROM_HANDLE(lvp_device_memory, mem, _mem);
1740
1741 if (mem == NULL)
1742 return;
1743
1744 switch(mem->memory_type) {
1745 case LVP_DEVICE_MEMORY_TYPE_DEFAULT:
1746 device->pscreen->free_memory(device->pscreen, mem->pmem);
1747 break;
1748 #ifdef PIPE_MEMORY_FD
1749 case LVP_DEVICE_MEMORY_TYPE_OPAQUE_FD:
1750 device->pscreen->free_memory_fd(device->pscreen, mem->pmem);
1751 if(mem->backed_fd >= 0)
1752 close(mem->backed_fd);
1753 break;
1754 #endif
1755 case LVP_DEVICE_MEMORY_TYPE_USER_PTR:
1756 default:
1757 break;
1758 }
1759 vk_object_base_finish(&mem->base);
1760 vk_free2(&device->vk.alloc, pAllocator, mem);
1761
1762 }
1763
lvp_MapMemory(VkDevice _device,VkDeviceMemory _memory,VkDeviceSize offset,VkDeviceSize size,VkMemoryMapFlags flags,void ** ppData)1764 VKAPI_ATTR VkResult VKAPI_CALL lvp_MapMemory(
1765 VkDevice _device,
1766 VkDeviceMemory _memory,
1767 VkDeviceSize offset,
1768 VkDeviceSize size,
1769 VkMemoryMapFlags flags,
1770 void** ppData)
1771 {
1772 LVP_FROM_HANDLE(lvp_device, device, _device);
1773 LVP_FROM_HANDLE(lvp_device_memory, mem, _memory);
1774 void *map;
1775 if (mem == NULL) {
1776 *ppData = NULL;
1777 return VK_SUCCESS;
1778 }
1779
1780 map = device->pscreen->map_memory(device->pscreen, mem->pmem);
1781
1782 *ppData = (char *)map + offset;
1783 return VK_SUCCESS;
1784 }
1785
lvp_UnmapMemory(VkDevice _device,VkDeviceMemory _memory)1786 VKAPI_ATTR void VKAPI_CALL lvp_UnmapMemory(
1787 VkDevice _device,
1788 VkDeviceMemory _memory)
1789 {
1790 LVP_FROM_HANDLE(lvp_device, device, _device);
1791 LVP_FROM_HANDLE(lvp_device_memory, mem, _memory);
1792
1793 if (mem == NULL)
1794 return;
1795
1796 device->pscreen->unmap_memory(device->pscreen, mem->pmem);
1797 }
1798
lvp_FlushMappedMemoryRanges(VkDevice _device,uint32_t memoryRangeCount,const VkMappedMemoryRange * pMemoryRanges)1799 VKAPI_ATTR VkResult VKAPI_CALL lvp_FlushMappedMemoryRanges(
1800 VkDevice _device,
1801 uint32_t memoryRangeCount,
1802 const VkMappedMemoryRange* pMemoryRanges)
1803 {
1804 return VK_SUCCESS;
1805 }
1806
lvp_InvalidateMappedMemoryRanges(VkDevice _device,uint32_t memoryRangeCount,const VkMappedMemoryRange * pMemoryRanges)1807 VKAPI_ATTR VkResult VKAPI_CALL lvp_InvalidateMappedMemoryRanges(
1808 VkDevice _device,
1809 uint32_t memoryRangeCount,
1810 const VkMappedMemoryRange* pMemoryRanges)
1811 {
1812 return VK_SUCCESS;
1813 }
1814
lvp_GetDeviceBufferMemoryRequirements(VkDevice _device,const VkDeviceBufferMemoryRequirements * pInfo,VkMemoryRequirements2 * pMemoryRequirements)1815 VKAPI_ATTR void VKAPI_CALL lvp_GetDeviceBufferMemoryRequirements(
1816 VkDevice _device,
1817 const VkDeviceBufferMemoryRequirements* pInfo,
1818 VkMemoryRequirements2* pMemoryRequirements)
1819 {
1820 pMemoryRequirements->memoryRequirements.memoryTypeBits = 1;
1821 pMemoryRequirements->memoryRequirements.alignment = 64;
1822 pMemoryRequirements->memoryRequirements.size = 0;
1823
1824 VkBuffer _buffer;
1825 if (lvp_CreateBuffer(_device, pInfo->pCreateInfo, NULL, &_buffer) != VK_SUCCESS)
1826 return;
1827 LVP_FROM_HANDLE(lvp_buffer, buffer, _buffer);
1828 pMemoryRequirements->memoryRequirements.size = buffer->total_size;
1829 lvp_DestroyBuffer(_device, _buffer, NULL);
1830 }
1831
lvp_GetDeviceImageSparseMemoryRequirements(VkDevice device,const VkDeviceImageMemoryRequirements * pInfo,uint32_t * pSparseMemoryRequirementCount,VkSparseImageMemoryRequirements2 * pSparseMemoryRequirements)1832 VKAPI_ATTR void VKAPI_CALL lvp_GetDeviceImageSparseMemoryRequirements(
1833 VkDevice device,
1834 const VkDeviceImageMemoryRequirements* pInfo,
1835 uint32_t* pSparseMemoryRequirementCount,
1836 VkSparseImageMemoryRequirements2* pSparseMemoryRequirements)
1837 {
1838 stub();
1839 }
1840
lvp_GetDeviceImageMemoryRequirements(VkDevice _device,const VkDeviceImageMemoryRequirements * pInfo,VkMemoryRequirements2 * pMemoryRequirements)1841 VKAPI_ATTR void VKAPI_CALL lvp_GetDeviceImageMemoryRequirements(
1842 VkDevice _device,
1843 const VkDeviceImageMemoryRequirements* pInfo,
1844 VkMemoryRequirements2* pMemoryRequirements)
1845 {
1846 pMemoryRequirements->memoryRequirements.memoryTypeBits = 1;
1847 pMemoryRequirements->memoryRequirements.alignment = 0;
1848 pMemoryRequirements->memoryRequirements.size = 0;
1849
1850 VkImage _image;
1851 if (lvp_CreateImage(_device, pInfo->pCreateInfo, NULL, &_image) != VK_SUCCESS)
1852 return;
1853 LVP_FROM_HANDLE(lvp_image, image, _image);
1854 pMemoryRequirements->memoryRequirements.size = image->size;
1855 pMemoryRequirements->memoryRequirements.alignment = image->alignment;
1856 lvp_DestroyImage(_device, _image, NULL);
1857 }
1858
lvp_GetBufferMemoryRequirements(VkDevice device,VkBuffer _buffer,VkMemoryRequirements * pMemoryRequirements)1859 VKAPI_ATTR void VKAPI_CALL lvp_GetBufferMemoryRequirements(
1860 VkDevice device,
1861 VkBuffer _buffer,
1862 VkMemoryRequirements* pMemoryRequirements)
1863 {
1864 LVP_FROM_HANDLE(lvp_buffer, buffer, _buffer);
1865
1866 /* The Vulkan spec (git aaed022) says:
1867 *
1868 * memoryTypeBits is a bitfield and contains one bit set for every
1869 * supported memory type for the resource. The bit `1<<i` is set if and
1870 * only if the memory type `i` in the VkPhysicalDeviceMemoryProperties
1871 * structure for the physical device is supported.
1872 *
1873 * We support exactly one memory type.
1874 */
1875 pMemoryRequirements->memoryTypeBits = 1;
1876
1877 pMemoryRequirements->size = buffer->total_size;
1878 pMemoryRequirements->alignment = 64;
1879 }
1880
lvp_GetBufferMemoryRequirements2(VkDevice device,const VkBufferMemoryRequirementsInfo2 * pInfo,VkMemoryRequirements2 * pMemoryRequirements)1881 VKAPI_ATTR void VKAPI_CALL lvp_GetBufferMemoryRequirements2(
1882 VkDevice device,
1883 const VkBufferMemoryRequirementsInfo2 *pInfo,
1884 VkMemoryRequirements2 *pMemoryRequirements)
1885 {
1886 lvp_GetBufferMemoryRequirements(device, pInfo->buffer,
1887 &pMemoryRequirements->memoryRequirements);
1888 vk_foreach_struct(ext, pMemoryRequirements->pNext) {
1889 switch (ext->sType) {
1890 case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {
1891 VkMemoryDedicatedRequirements *req =
1892 (VkMemoryDedicatedRequirements *) ext;
1893 req->requiresDedicatedAllocation = false;
1894 req->prefersDedicatedAllocation = req->requiresDedicatedAllocation;
1895 break;
1896 }
1897 default:
1898 break;
1899 }
1900 }
1901 }
1902
lvp_GetImageMemoryRequirements(VkDevice device,VkImage _image,VkMemoryRequirements * pMemoryRequirements)1903 VKAPI_ATTR void VKAPI_CALL lvp_GetImageMemoryRequirements(
1904 VkDevice device,
1905 VkImage _image,
1906 VkMemoryRequirements* pMemoryRequirements)
1907 {
1908 LVP_FROM_HANDLE(lvp_image, image, _image);
1909 pMemoryRequirements->memoryTypeBits = 1;
1910
1911 pMemoryRequirements->size = image->size;
1912 pMemoryRequirements->alignment = image->alignment;
1913 }
1914
lvp_GetImageMemoryRequirements2(VkDevice device,const VkImageMemoryRequirementsInfo2 * pInfo,VkMemoryRequirements2 * pMemoryRequirements)1915 VKAPI_ATTR void VKAPI_CALL lvp_GetImageMemoryRequirements2(
1916 VkDevice device,
1917 const VkImageMemoryRequirementsInfo2 *pInfo,
1918 VkMemoryRequirements2 *pMemoryRequirements)
1919 {
1920 lvp_GetImageMemoryRequirements(device, pInfo->image,
1921 &pMemoryRequirements->memoryRequirements);
1922
1923 vk_foreach_struct(ext, pMemoryRequirements->pNext) {
1924 switch (ext->sType) {
1925 case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {
1926 VkMemoryDedicatedRequirements *req =
1927 (VkMemoryDedicatedRequirements *) ext;
1928 req->requiresDedicatedAllocation = false;
1929 req->prefersDedicatedAllocation = req->requiresDedicatedAllocation;
1930 break;
1931 }
1932 default:
1933 break;
1934 }
1935 }
1936 }
1937
lvp_GetImageSparseMemoryRequirements(VkDevice device,VkImage image,uint32_t * pSparseMemoryRequirementCount,VkSparseImageMemoryRequirements * pSparseMemoryRequirements)1938 VKAPI_ATTR void VKAPI_CALL lvp_GetImageSparseMemoryRequirements(
1939 VkDevice device,
1940 VkImage image,
1941 uint32_t* pSparseMemoryRequirementCount,
1942 VkSparseImageMemoryRequirements* pSparseMemoryRequirements)
1943 {
1944 stub();
1945 }
1946
lvp_GetImageSparseMemoryRequirements2(VkDevice device,const VkImageSparseMemoryRequirementsInfo2 * pInfo,uint32_t * pSparseMemoryRequirementCount,VkSparseImageMemoryRequirements2 * pSparseMemoryRequirements)1947 VKAPI_ATTR void VKAPI_CALL lvp_GetImageSparseMemoryRequirements2(
1948 VkDevice device,
1949 const VkImageSparseMemoryRequirementsInfo2* pInfo,
1950 uint32_t* pSparseMemoryRequirementCount,
1951 VkSparseImageMemoryRequirements2* pSparseMemoryRequirements)
1952 {
1953 stub();
1954 }
1955
lvp_GetDeviceMemoryCommitment(VkDevice device,VkDeviceMemory memory,VkDeviceSize * pCommittedMemoryInBytes)1956 VKAPI_ATTR void VKAPI_CALL lvp_GetDeviceMemoryCommitment(
1957 VkDevice device,
1958 VkDeviceMemory memory,
1959 VkDeviceSize* pCommittedMemoryInBytes)
1960 {
1961 *pCommittedMemoryInBytes = 0;
1962 }
1963
lvp_BindBufferMemory2(VkDevice _device,uint32_t bindInfoCount,const VkBindBufferMemoryInfo * pBindInfos)1964 VKAPI_ATTR VkResult VKAPI_CALL lvp_BindBufferMemory2(VkDevice _device,
1965 uint32_t bindInfoCount,
1966 const VkBindBufferMemoryInfo *pBindInfos)
1967 {
1968 LVP_FROM_HANDLE(lvp_device, device, _device);
1969 for (uint32_t i = 0; i < bindInfoCount; ++i) {
1970 LVP_FROM_HANDLE(lvp_device_memory, mem, pBindInfos[i].memory);
1971 LVP_FROM_HANDLE(lvp_buffer, buffer, pBindInfos[i].buffer);
1972
1973 buffer->pmem = mem->pmem;
1974 device->pscreen->resource_bind_backing(device->pscreen,
1975 buffer->bo,
1976 mem->pmem,
1977 pBindInfos[i].memoryOffset);
1978 }
1979 return VK_SUCCESS;
1980 }
1981
lvp_BindImageMemory2(VkDevice _device,uint32_t bindInfoCount,const VkBindImageMemoryInfo * pBindInfos)1982 VKAPI_ATTR VkResult VKAPI_CALL lvp_BindImageMemory2(VkDevice _device,
1983 uint32_t bindInfoCount,
1984 const VkBindImageMemoryInfo *pBindInfos)
1985 {
1986 LVP_FROM_HANDLE(lvp_device, device, _device);
1987 for (uint32_t i = 0; i < bindInfoCount; ++i) {
1988 const VkBindImageMemoryInfo *bind_info = &pBindInfos[i];
1989 LVP_FROM_HANDLE(lvp_device_memory, mem, bind_info->memory);
1990 LVP_FROM_HANDLE(lvp_image, image, bind_info->image);
1991 bool did_bind = false;
1992
1993 vk_foreach_struct_const(s, bind_info->pNext) {
1994 switch (s->sType) {
1995 case VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR: {
1996 const VkBindImageMemorySwapchainInfoKHR *swapchain_info =
1997 (const VkBindImageMemorySwapchainInfoKHR *) s;
1998 struct lvp_image *swapchain_image =
1999 lvp_swapchain_get_image(swapchain_info->swapchain,
2000 swapchain_info->imageIndex);
2001
2002 image->pmem = swapchain_image->pmem;
2003 image->memory_offset = swapchain_image->memory_offset;
2004 device->pscreen->resource_bind_backing(device->pscreen,
2005 image->bo,
2006 image->pmem,
2007 image->memory_offset);
2008 did_bind = true;
2009 break;
2010 }
2011 default:
2012 break;
2013 }
2014 }
2015
2016 if (!did_bind) {
2017 if (!device->pscreen->resource_bind_backing(device->pscreen,
2018 image->bo,
2019 mem->pmem,
2020 bind_info->memoryOffset)) {
2021 /* This is probably caused by the texture being too large, so let's
2022 * report this as the *closest* allowed error-code. It's not ideal,
2023 * but it's unlikely that anyone will care too much.
2024 */
2025 return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
2026 }
2027 image->pmem = mem->pmem;
2028 image->memory_offset = bind_info->memoryOffset;
2029 }
2030 }
2031 return VK_SUCCESS;
2032 }
2033
2034 #ifdef PIPE_MEMORY_FD
2035
2036 VkResult
lvp_GetMemoryFdKHR(VkDevice _device,const VkMemoryGetFdInfoKHR * pGetFdInfo,int * pFD)2037 lvp_GetMemoryFdKHR(VkDevice _device, const VkMemoryGetFdInfoKHR *pGetFdInfo, int *pFD)
2038 {
2039 LVP_FROM_HANDLE(lvp_device_memory, memory, pGetFdInfo->memory);
2040
2041 assert(pGetFdInfo->sType == VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR);
2042 assert(pGetFdInfo->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT);
2043
2044 *pFD = dup(memory->backed_fd);
2045 assert(*pFD >= 0);
2046 return VK_SUCCESS;
2047 }
2048
2049 VkResult
lvp_GetMemoryFdPropertiesKHR(VkDevice _device,VkExternalMemoryHandleTypeFlagBits handleType,int fd,VkMemoryFdPropertiesKHR * pMemoryFdProperties)2050 lvp_GetMemoryFdPropertiesKHR(VkDevice _device,
2051 VkExternalMemoryHandleTypeFlagBits handleType,
2052 int fd,
2053 VkMemoryFdPropertiesKHR *pMemoryFdProperties)
2054 {
2055 LVP_FROM_HANDLE(lvp_device, device, _device);
2056
2057 assert(pMemoryFdProperties->sType == VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR);
2058
2059 if(handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT) {
2060 // There is only one memoryType so select this one
2061 pMemoryFdProperties->memoryTypeBits = 1;
2062 }
2063 else
2064 return vk_error(device->instance, VK_ERROR_INVALID_EXTERNAL_HANDLE);
2065 return VK_SUCCESS;
2066 }
2067
2068 #endif
2069
lvp_QueueBindSparse(VkQueue queue,uint32_t bindInfoCount,const VkBindSparseInfo * pBindInfo,VkFence fence)2070 VKAPI_ATTR VkResult VKAPI_CALL lvp_QueueBindSparse(
2071 VkQueue queue,
2072 uint32_t bindInfoCount,
2073 const VkBindSparseInfo* pBindInfo,
2074 VkFence fence)
2075 {
2076 stub_return(VK_ERROR_INCOMPATIBLE_DRIVER);
2077 }
2078
lvp_CreateEvent(VkDevice _device,const VkEventCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkEvent * pEvent)2079 VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateEvent(
2080 VkDevice _device,
2081 const VkEventCreateInfo* pCreateInfo,
2082 const VkAllocationCallbacks* pAllocator,
2083 VkEvent* pEvent)
2084 {
2085 LVP_FROM_HANDLE(lvp_device, device, _device);
2086 struct lvp_event *event = vk_alloc2(&device->vk.alloc, pAllocator,
2087 sizeof(*event), 8,
2088 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
2089
2090 if (!event)
2091 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
2092
2093 vk_object_base_init(&device->vk, &event->base, VK_OBJECT_TYPE_EVENT);
2094 *pEvent = lvp_event_to_handle(event);
2095 event->event_storage = 0;
2096
2097 return VK_SUCCESS;
2098 }
2099
lvp_DestroyEvent(VkDevice _device,VkEvent _event,const VkAllocationCallbacks * pAllocator)2100 VKAPI_ATTR void VKAPI_CALL lvp_DestroyEvent(
2101 VkDevice _device,
2102 VkEvent _event,
2103 const VkAllocationCallbacks* pAllocator)
2104 {
2105 LVP_FROM_HANDLE(lvp_device, device, _device);
2106 LVP_FROM_HANDLE(lvp_event, event, _event);
2107
2108 if (!event)
2109 return;
2110
2111 vk_object_base_finish(&event->base);
2112 vk_free2(&device->vk.alloc, pAllocator, event);
2113 }
2114
lvp_GetEventStatus(VkDevice _device,VkEvent _event)2115 VKAPI_ATTR VkResult VKAPI_CALL lvp_GetEventStatus(
2116 VkDevice _device,
2117 VkEvent _event)
2118 {
2119 LVP_FROM_HANDLE(lvp_event, event, _event);
2120 if (event->event_storage == 1)
2121 return VK_EVENT_SET;
2122 return VK_EVENT_RESET;
2123 }
2124
lvp_SetEvent(VkDevice _device,VkEvent _event)2125 VKAPI_ATTR VkResult VKAPI_CALL lvp_SetEvent(
2126 VkDevice _device,
2127 VkEvent _event)
2128 {
2129 LVP_FROM_HANDLE(lvp_event, event, _event);
2130 event->event_storage = 1;
2131
2132 return VK_SUCCESS;
2133 }
2134
lvp_ResetEvent(VkDevice _device,VkEvent _event)2135 VKAPI_ATTR VkResult VKAPI_CALL lvp_ResetEvent(
2136 VkDevice _device,
2137 VkEvent _event)
2138 {
2139 LVP_FROM_HANDLE(lvp_event, event, _event);
2140 event->event_storage = 0;
2141
2142 return VK_SUCCESS;
2143 }
2144
lvp_CreateSampler(VkDevice _device,const VkSamplerCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSampler * pSampler)2145 VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateSampler(
2146 VkDevice _device,
2147 const VkSamplerCreateInfo* pCreateInfo,
2148 const VkAllocationCallbacks* pAllocator,
2149 VkSampler* pSampler)
2150 {
2151 LVP_FROM_HANDLE(lvp_device, device, _device);
2152 struct lvp_sampler *sampler;
2153 const VkSamplerReductionModeCreateInfo *reduction_mode_create_info =
2154 vk_find_struct_const(pCreateInfo->pNext,
2155 SAMPLER_REDUCTION_MODE_CREATE_INFO);
2156
2157 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO);
2158
2159 sampler = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*sampler), 8,
2160 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
2161 if (!sampler)
2162 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
2163
2164 vk_object_base_init(&device->vk, &sampler->base,
2165 VK_OBJECT_TYPE_SAMPLER);
2166 sampler->create_info = *pCreateInfo;
2167
2168 VkClearColorValue border_color =
2169 vk_sampler_border_color_value(pCreateInfo, NULL);
2170 STATIC_ASSERT(sizeof(sampler->border_color) == sizeof(border_color));
2171 memcpy(&sampler->border_color, &border_color, sizeof(border_color));
2172
2173 sampler->reduction_mode = VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE;
2174 if (reduction_mode_create_info)
2175 sampler->reduction_mode = reduction_mode_create_info->reductionMode;
2176
2177 *pSampler = lvp_sampler_to_handle(sampler);
2178
2179 return VK_SUCCESS;
2180 }
2181
lvp_DestroySampler(VkDevice _device,VkSampler _sampler,const VkAllocationCallbacks * pAllocator)2182 VKAPI_ATTR void VKAPI_CALL lvp_DestroySampler(
2183 VkDevice _device,
2184 VkSampler _sampler,
2185 const VkAllocationCallbacks* pAllocator)
2186 {
2187 LVP_FROM_HANDLE(lvp_device, device, _device);
2188 LVP_FROM_HANDLE(lvp_sampler, sampler, _sampler);
2189
2190 if (!_sampler)
2191 return;
2192 vk_object_base_finish(&sampler->base);
2193 vk_free2(&device->vk.alloc, pAllocator, sampler);
2194 }
2195
lvp_CreateSamplerYcbcrConversionKHR(VkDevice device,const VkSamplerYcbcrConversionCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSamplerYcbcrConversion * pYcbcrConversion)2196 VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateSamplerYcbcrConversionKHR(
2197 VkDevice device,
2198 const VkSamplerYcbcrConversionCreateInfo* pCreateInfo,
2199 const VkAllocationCallbacks* pAllocator,
2200 VkSamplerYcbcrConversion* pYcbcrConversion)
2201 {
2202 return VK_ERROR_OUT_OF_HOST_MEMORY;
2203 }
2204
lvp_DestroySamplerYcbcrConversionKHR(VkDevice device,VkSamplerYcbcrConversion ycbcrConversion,const VkAllocationCallbacks * pAllocator)2205 VKAPI_ATTR void VKAPI_CALL lvp_DestroySamplerYcbcrConversionKHR(
2206 VkDevice device,
2207 VkSamplerYcbcrConversion ycbcrConversion,
2208 const VkAllocationCallbacks* pAllocator)
2209 {
2210 }
2211
2212 /* vk_icd.h does not declare this function, so we declare it here to
2213 * suppress Wmissing-prototypes.
2214 */
2215 PUBLIC VKAPI_ATTR VkResult VKAPI_CALL
2216 vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion);
2217
2218 PUBLIC VKAPI_ATTR VkResult VKAPI_CALL
vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t * pSupportedVersion)2219 vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion)
2220 {
2221 /* For the full details on loader interface versioning, see
2222 * <https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/blob/master/loader/LoaderAndLayerInterface.md>.
2223 * What follows is a condensed summary, to help you navigate the large and
2224 * confusing official doc.
2225 *
2226 * - Loader interface v0 is incompatible with later versions. We don't
2227 * support it.
2228 *
2229 * - In loader interface v1:
2230 * - The first ICD entrypoint called by the loader is
2231 * vk_icdGetInstanceProcAddr(). The ICD must statically expose this
2232 * entrypoint.
2233 * - The ICD must statically expose no other Vulkan symbol unless it is
2234 * linked with -Bsymbolic.
2235 * - Each dispatchable Vulkan handle created by the ICD must be
2236 * a pointer to a struct whose first member is VK_LOADER_DATA. The
2237 * ICD must initialize VK_LOADER_DATA.loadMagic to ICD_LOADER_MAGIC.
2238 * - The loader implements vkCreate{PLATFORM}SurfaceKHR() and
2239 * vkDestroySurfaceKHR(). The ICD must be capable of working with
2240 * such loader-managed surfaces.
2241 *
2242 * - Loader interface v2 differs from v1 in:
2243 * - The first ICD entrypoint called by the loader is
2244 * vk_icdNegotiateLoaderICDInterfaceVersion(). The ICD must
2245 * statically expose this entrypoint.
2246 *
2247 * - Loader interface v3 differs from v2 in:
2248 * - The ICD must implement vkCreate{PLATFORM}SurfaceKHR(),
2249 * vkDestroySurfaceKHR(), and other API which uses VKSurfaceKHR,
2250 * because the loader no longer does so.
2251 *
2252 * - Loader interface v4 differs from v3 in:
2253 * - The ICD must implement vk_icdGetPhysicalDeviceProcAddr().
2254 *
2255 * - Loader interface v5 differs from v4 in:
2256 * - The ICD must support Vulkan API version 1.1 and must not return
2257 * VK_ERROR_INCOMPATIBLE_DRIVER from vkCreateInstance() unless a
2258 * Vulkan Loader with interface v4 or smaller is being used and the
2259 * application provides an API version that is greater than 1.0.
2260 */
2261 *pSupportedVersion = MIN2(*pSupportedVersion, 5u);
2262 return VK_SUCCESS;
2263 }
2264
lvp_CreatePrivateDataSlotEXT(VkDevice _device,const VkPrivateDataSlotCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkPrivateDataSlot * pPrivateDataSlot)2265 VKAPI_ATTR VkResult VKAPI_CALL lvp_CreatePrivateDataSlotEXT(
2266 VkDevice _device,
2267 const VkPrivateDataSlotCreateInfo* pCreateInfo,
2268 const VkAllocationCallbacks* pAllocator,
2269 VkPrivateDataSlot* pPrivateDataSlot)
2270 {
2271 LVP_FROM_HANDLE(lvp_device, device, _device);
2272 return vk_private_data_slot_create(&device->vk, pCreateInfo, pAllocator,
2273 pPrivateDataSlot);
2274 }
2275
lvp_DestroyPrivateDataSlotEXT(VkDevice _device,VkPrivateDataSlot privateDataSlot,const VkAllocationCallbacks * pAllocator)2276 VKAPI_ATTR void VKAPI_CALL lvp_DestroyPrivateDataSlotEXT(
2277 VkDevice _device,
2278 VkPrivateDataSlot privateDataSlot,
2279 const VkAllocationCallbacks* pAllocator)
2280 {
2281 LVP_FROM_HANDLE(lvp_device, device, _device);
2282 vk_private_data_slot_destroy(&device->vk, privateDataSlot, pAllocator);
2283 }
2284
lvp_SetPrivateDataEXT(VkDevice _device,VkObjectType objectType,uint64_t objectHandle,VkPrivateDataSlot privateDataSlot,uint64_t data)2285 VKAPI_ATTR VkResult VKAPI_CALL lvp_SetPrivateDataEXT(
2286 VkDevice _device,
2287 VkObjectType objectType,
2288 uint64_t objectHandle,
2289 VkPrivateDataSlot privateDataSlot,
2290 uint64_t data)
2291 {
2292 LVP_FROM_HANDLE(lvp_device, device, _device);
2293 return vk_object_base_set_private_data(&device->vk, objectType,
2294 objectHandle, privateDataSlot,
2295 data);
2296 }
2297
lvp_GetPrivateDataEXT(VkDevice _device,VkObjectType objectType,uint64_t objectHandle,VkPrivateDataSlot privateDataSlot,uint64_t * pData)2298 VKAPI_ATTR void VKAPI_CALL lvp_GetPrivateDataEXT(
2299 VkDevice _device,
2300 VkObjectType objectType,
2301 uint64_t objectHandle,
2302 VkPrivateDataSlot privateDataSlot,
2303 uint64_t* pData)
2304 {
2305 LVP_FROM_HANDLE(lvp_device, device, _device);
2306 vk_object_base_get_private_data(&device->vk, objectType, objectHandle,
2307 privateDataSlot, pData);
2308 }
2309
lvp_GetPhysicalDeviceExternalFenceProperties(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceExternalFenceInfo * pExternalFenceInfo,VkExternalFenceProperties * pExternalFenceProperties)2310 VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceExternalFenceProperties(
2311 VkPhysicalDevice physicalDevice,
2312 const VkPhysicalDeviceExternalFenceInfo *pExternalFenceInfo,
2313 VkExternalFenceProperties *pExternalFenceProperties)
2314 {
2315 pExternalFenceProperties->exportFromImportedHandleTypes = 0;
2316 pExternalFenceProperties->compatibleHandleTypes = 0;
2317 pExternalFenceProperties->externalFenceFeatures = 0;
2318 }
2319
lvp_GetPhysicalDeviceExternalSemaphoreProperties(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceExternalSemaphoreInfo * pExternalSemaphoreInfo,VkExternalSemaphoreProperties * pExternalSemaphoreProperties)2320 VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceExternalSemaphoreProperties(
2321 VkPhysicalDevice physicalDevice,
2322 const VkPhysicalDeviceExternalSemaphoreInfo *pExternalSemaphoreInfo,
2323 VkExternalSemaphoreProperties *pExternalSemaphoreProperties)
2324 {
2325 pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0;
2326 pExternalSemaphoreProperties->compatibleHandleTypes = 0;
2327 pExternalSemaphoreProperties->externalSemaphoreFeatures = 0;
2328 }
2329
2330 static const VkTimeDomainEXT lvp_time_domains[] = {
2331 VK_TIME_DOMAIN_DEVICE_EXT,
2332 VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT,
2333 };
2334
lvp_GetPhysicalDeviceCalibrateableTimeDomainsEXT(VkPhysicalDevice physicalDevice,uint32_t * pTimeDomainCount,VkTimeDomainEXT * pTimeDomains)2335 VKAPI_ATTR VkResult VKAPI_CALL lvp_GetPhysicalDeviceCalibrateableTimeDomainsEXT(
2336 VkPhysicalDevice physicalDevice,
2337 uint32_t *pTimeDomainCount,
2338 VkTimeDomainEXT *pTimeDomains)
2339 {
2340 int d;
2341 VK_OUTARRAY_MAKE_TYPED(VkTimeDomainEXT, out, pTimeDomains,
2342 pTimeDomainCount);
2343
2344 for (d = 0; d < ARRAY_SIZE(lvp_time_domains); d++) {
2345 vk_outarray_append_typed(VkTimeDomainEXT, &out, i) {
2346 *i = lvp_time_domains[d];
2347 }
2348 }
2349
2350 return vk_outarray_status(&out);
2351 }
2352
lvp_GetCalibratedTimestampsEXT(VkDevice device,uint32_t timestampCount,const VkCalibratedTimestampInfoEXT * pTimestampInfos,uint64_t * pTimestamps,uint64_t * pMaxDeviation)2353 VKAPI_ATTR VkResult VKAPI_CALL lvp_GetCalibratedTimestampsEXT(
2354 VkDevice device,
2355 uint32_t timestampCount,
2356 const VkCalibratedTimestampInfoEXT *pTimestampInfos,
2357 uint64_t *pTimestamps,
2358 uint64_t *pMaxDeviation)
2359 {
2360 *pMaxDeviation = 1;
2361
2362 uint64_t now = os_time_get_nano();
2363 for (unsigned i = 0; i < timestampCount; i++) {
2364 pTimestamps[i] = now;
2365 }
2366 return VK_SUCCESS;
2367 }
2368
lvp_GetDeviceGroupPeerMemoryFeaturesKHR(VkDevice device,uint32_t heapIndex,uint32_t localDeviceIndex,uint32_t remoteDeviceIndex,VkPeerMemoryFeatureFlags * pPeerMemoryFeatures)2369 VKAPI_ATTR void VKAPI_CALL lvp_GetDeviceGroupPeerMemoryFeaturesKHR(
2370 VkDevice device,
2371 uint32_t heapIndex,
2372 uint32_t localDeviceIndex,
2373 uint32_t remoteDeviceIndex,
2374 VkPeerMemoryFeatureFlags *pPeerMemoryFeatures)
2375 {
2376 *pPeerMemoryFeatures = 0;
2377 }
2378