• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2019 Red Hat.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 #include "lvp_private.h"
25 
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