Path: blob/21.2-virgl/src/gallium/frontends/lavapipe/lvp_device.c
4565 views
/*1* Copyright © 2019 Red Hat.2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*/2223#include "lvp_private.h"2425#include "pipe-loader/pipe_loader.h"26#include "git_sha1.h"27#include "vk_util.h"28#include "pipe/p_state.h"29#include "pipe/p_context.h"30#include "frontend/drisw_api.h"3132#include "util/u_inlines.h"33#include "util/os_memory.h"34#include "util/u_thread.h"35#include "util/u_atomic.h"36#include "util/timespec.h"37#include "os_time.h"3839#if defined(VK_USE_PLATFORM_WAYLAND_KHR) || \40defined(VK_USE_PLATFORM_WIN32_KHR) || \41defined(VK_USE_PLATFORM_XCB_KHR) || \42defined(VK_USE_PLATFORM_XLIB_KHR) || \43defined(VK_USE_PLATFORM_DISPLAY_KHR)44#define LVP_USE_WSI_PLATFORM45#endif46#define LVP_API_VERSION VK_MAKE_VERSION(1, 1, VK_HEADER_VERSION)4748VKAPI_ATTR VkResult VKAPI_CALL lvp_EnumerateInstanceVersion(uint32_t* pApiVersion)49{50*pApiVersion = LVP_API_VERSION;51return VK_SUCCESS;52}5354static const struct vk_instance_extension_table lvp_instance_extensions_supported = {55.KHR_device_group_creation = true,56.KHR_external_fence_capabilities = true,57.KHR_external_memory_capabilities = true,58.KHR_external_semaphore_capabilities = true,59.KHR_get_physical_device_properties2 = true,60.EXT_debug_report = true,61#ifdef LVP_USE_WSI_PLATFORM62.KHR_get_surface_capabilities2 = true,63.KHR_surface = true,64.KHR_surface_protected_capabilities = true,65#endif66#ifdef VK_USE_PLATFORM_WAYLAND_KHR67.KHR_wayland_surface = true,68#endif69#ifdef VK_USE_PLATFORM_WIN32_KHR70.KHR_win32_surface = true,71#endif72#ifdef VK_USE_PLATFORM_XCB_KHR73.KHR_xcb_surface = true,74#endif75#ifdef VK_USE_PLATFORM_XLIB_KHR76.KHR_xlib_surface = true,77#endif78#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT79.EXT_acquire_xlib_display = true,80#endif81#ifdef VK_USE_PLATFORM_DISPLAY_KHR82.KHR_display = true,83.KHR_get_display_properties2 = true,84.EXT_direct_mode_display = true,85.EXT_display_surface_counter = true,86#endif87};8889static const struct vk_device_extension_table lvp_device_extensions_supported = {90.KHR_8bit_storage = true,91.KHR_16bit_storage = true,92.KHR_bind_memory2 = true,93.KHR_buffer_device_address = true,94.KHR_create_renderpass2 = true,95.KHR_copy_commands2 = true,96.KHR_dedicated_allocation = true,97.KHR_descriptor_update_template = true,98.KHR_device_group = true,99.KHR_draw_indirect_count = true,100.KHR_driver_properties = true,101.KHR_external_fence = true,102.KHR_external_memory = true,103.KHR_external_semaphore = true,104.KHR_get_memory_requirements2 = true,105#ifdef LVP_USE_WSI_PLATFORM106.KHR_incremental_present = true,107#endif108.KHR_image_format_list = true,109.KHR_imageless_framebuffer = true,110.KHR_maintenance1 = true,111.KHR_maintenance2 = true,112.KHR_maintenance3 = true,113.KHR_multiview = true,114.KHR_push_descriptor = true,115.KHR_relaxed_block_layout = true,116.KHR_sampler_mirror_clamp_to_edge = true,117.KHR_separate_depth_stencil_layouts = true,118.KHR_shader_atomic_int64 = true,119.KHR_shader_draw_parameters = true,120.KHR_storage_buffer_storage_class = true,121#ifdef LVP_USE_WSI_PLATFORM122.KHR_swapchain = true,123#endif124.KHR_uniform_buffer_standard_layout = true,125.KHR_variable_pointers = true,126.EXT_calibrated_timestamps = true,127.EXT_conditional_rendering = true,128.EXT_extended_dynamic_state = true,129.EXT_extended_dynamic_state2 = true,130.EXT_host_query_reset = true,131.EXT_index_type_uint8 = true,132.EXT_multi_draw = true,133.EXT_post_depth_coverage = true,134.EXT_private_data = true,135.EXT_sampler_filter_minmax = true,136.EXT_scalar_block_layout = true,137.EXT_separate_stencil_usage = true,138.EXT_shader_stencil_export = true,139.EXT_shader_viewport_index_layer = true,140.EXT_transform_feedback = true,141.EXT_vertex_attribute_divisor = true,142.EXT_vertex_input_dynamic_state = true,143.EXT_custom_border_color = true,144.EXT_provoking_vertex = true,145.EXT_line_rasterization = true,146.GOOGLE_decorate_string = true,147.GOOGLE_hlsl_functionality1 = true,148};149150static VkResult VKAPI_CALL151lvp_physical_device_init(struct lvp_physical_device *device,152struct lvp_instance *instance,153struct pipe_loader_device *pld)154{155VkResult result;156157struct vk_physical_device_dispatch_table dispatch_table;158vk_physical_device_dispatch_table_from_entrypoints(159&dispatch_table, &lvp_physical_device_entrypoints, true);160result = vk_physical_device_init(&device->vk, &instance->vk,161NULL, &dispatch_table);162if (result != VK_SUCCESS) {163vk_error(instance, result);164goto fail;165}166device->pld = pld;167168device->pscreen = pipe_loader_create_screen_vk(device->pld, true);169if (!device->pscreen)170return vk_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY);171172device->max_images = device->pscreen->get_shader_param(device->pscreen, PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_MAX_SHADER_IMAGES);173device->vk.supported_extensions = lvp_device_extensions_supported;174result = lvp_init_wsi(device);175if (result != VK_SUCCESS) {176vk_physical_device_finish(&device->vk);177vk_error(instance, result);178goto fail;179}180181return VK_SUCCESS;182fail:183return result;184}185186static void VKAPI_CALL187lvp_physical_device_finish(struct lvp_physical_device *device)188{189lvp_finish_wsi(device);190device->pscreen->destroy(device->pscreen);191vk_physical_device_finish(&device->vk);192}193194VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateInstance(195const VkInstanceCreateInfo* pCreateInfo,196const VkAllocationCallbacks* pAllocator,197VkInstance* pInstance)198{199struct lvp_instance *instance;200VkResult result;201202assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO);203204if (pAllocator == NULL)205pAllocator = vk_default_allocator();206207instance = vk_zalloc(pAllocator, sizeof(*instance), 8,208VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);209if (!instance)210return vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY);211212struct vk_instance_dispatch_table dispatch_table;213vk_instance_dispatch_table_from_entrypoints(214&dispatch_table, &lvp_instance_entrypoints, true);215216result = vk_instance_init(&instance->vk,217&lvp_instance_extensions_supported,218&dispatch_table,219pCreateInfo,220pAllocator);221if (result != VK_SUCCESS) {222vk_free(pAllocator, instance);223return vk_error(instance, result);224}225226instance->apiVersion = LVP_API_VERSION;227instance->physicalDeviceCount = -1;228229// _mesa_locale_init();230// VG(VALGRIND_CREATE_MEMPOOL(instance, 0, false));231232*pInstance = lvp_instance_to_handle(instance);233234return VK_SUCCESS;235}236237VKAPI_ATTR void VKAPI_CALL lvp_DestroyInstance(238VkInstance _instance,239const VkAllocationCallbacks* pAllocator)240{241LVP_FROM_HANDLE(lvp_instance, instance, _instance);242243if (!instance)244return;245if (instance->physicalDeviceCount > 0)246lvp_physical_device_finish(&instance->physicalDevice);247// _mesa_locale_fini();248249pipe_loader_release(&instance->devs, instance->num_devices);250251vk_instance_finish(&instance->vk);252vk_free(&instance->vk.alloc, instance);253}254255#if defined(HAVE_PIPE_LOADER_DRI)256static void lvp_get_image(struct dri_drawable *dri_drawable,257int x, int y, unsigned width, unsigned height, unsigned stride,258void *data)259{260261}262263static void lvp_put_image(struct dri_drawable *dri_drawable,264void *data, unsigned width, unsigned height)265{266fprintf(stderr, "put image %dx%d\n", width, height);267}268269static void lvp_put_image2(struct dri_drawable *dri_drawable,270void *data, int x, int y, unsigned width, unsigned height,271unsigned stride)272{273fprintf(stderr, "put image 2 %d,%d %dx%d\n", x, y, width, height);274}275276static struct drisw_loader_funcs lvp_sw_lf = {277.get_image = lvp_get_image,278.put_image = lvp_put_image,279.put_image2 = lvp_put_image2,280};281#endif282283static VkResult284lvp_enumerate_physical_devices(struct lvp_instance *instance)285{286VkResult result;287288if (instance->physicalDeviceCount != -1)289return VK_SUCCESS;290291/* sw only for now */292instance->num_devices = pipe_loader_sw_probe(NULL, 0);293294assert(instance->num_devices == 1);295296#if defined(HAVE_PIPE_LOADER_DRI)297pipe_loader_sw_probe_dri(&instance->devs, &lvp_sw_lf);298#else299pipe_loader_sw_probe_null(&instance->devs);300#endif301302result = lvp_physical_device_init(&instance->physicalDevice,303instance, &instance->devs[0]);304if (result == VK_ERROR_INCOMPATIBLE_DRIVER) {305instance->physicalDeviceCount = 0;306} else if (result == VK_SUCCESS) {307instance->physicalDeviceCount = 1;308}309310return result;311}312313VKAPI_ATTR VkResult VKAPI_CALL lvp_EnumeratePhysicalDevices(314VkInstance _instance,315uint32_t* pPhysicalDeviceCount,316VkPhysicalDevice* pPhysicalDevices)317{318LVP_FROM_HANDLE(lvp_instance, instance, _instance);319VkResult result;320321result = lvp_enumerate_physical_devices(instance);322if (result != VK_SUCCESS)323return result;324325if (!pPhysicalDevices) {326*pPhysicalDeviceCount = instance->physicalDeviceCount;327} else if (*pPhysicalDeviceCount >= 1) {328pPhysicalDevices[0] = lvp_physical_device_to_handle(&instance->physicalDevice);329*pPhysicalDeviceCount = 1;330} else {331*pPhysicalDeviceCount = 0;332}333334return VK_SUCCESS;335}336337VKAPI_ATTR VkResult VKAPI_CALL lvp_EnumeratePhysicalDeviceGroups(338VkInstance _instance,339uint32_t* pPhysicalDeviceGroupCount,340VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties)341{342LVP_FROM_HANDLE(lvp_instance, instance, _instance);343VK_OUTARRAY_MAKE_TYPED(VkPhysicalDeviceGroupProperties, out,344pPhysicalDeviceGroupProperties,345pPhysicalDeviceGroupCount);346347VkResult result = lvp_enumerate_physical_devices(instance);348if (result != VK_SUCCESS)349return result;350351vk_outarray_append_typed(VkPhysicalDeviceGroupProperties, &out, p) {352p->physicalDeviceCount = 1;353memset(p->physicalDevices, 0, sizeof(p->physicalDevices));354p->physicalDevices[0] = lvp_physical_device_to_handle(&instance->physicalDevice);355p->subsetAllocation = false;356}357358return vk_outarray_status(&out);359}360361static int362min_vertex_pipeline_param(struct pipe_screen *pscreen, enum pipe_shader_cap param)363{364int val = INT_MAX;365for (int i = 0; i < PIPE_SHADER_COMPUTE; ++i) {366if (i == PIPE_SHADER_FRAGMENT ||367!pscreen->get_shader_param(pscreen, i,368PIPE_SHADER_CAP_MAX_INSTRUCTIONS))369continue;370371val = MAX2(val, pscreen->get_shader_param(pscreen, i, param));372}373return val;374}375376static int377min_shader_param(struct pipe_screen *pscreen, enum pipe_shader_cap param)378{379return MIN3(min_vertex_pipeline_param(pscreen, param),380pscreen->get_shader_param(pscreen, PIPE_SHADER_FRAGMENT, param),381pscreen->get_shader_param(pscreen, PIPE_SHADER_COMPUTE, param));382}383384VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceFeatures(385VkPhysicalDevice physicalDevice,386VkPhysicalDeviceFeatures* pFeatures)387{388LVP_FROM_HANDLE(lvp_physical_device, pdevice, physicalDevice);389bool indirect = false;//pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_GLSL_FEATURE_LEVEL) >= 400;390memset(pFeatures, 0, sizeof(*pFeatures));391*pFeatures = (VkPhysicalDeviceFeatures) {392.robustBufferAccess = true,393.fullDrawIndexUint32 = true,394.imageCubeArray = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_CUBE_MAP_ARRAY) != 0),395.independentBlend = true,396.geometryShader = (pdevice->pscreen->get_shader_param(pdevice->pscreen, PIPE_SHADER_GEOMETRY, PIPE_SHADER_CAP_MAX_INSTRUCTIONS) != 0),397.tessellationShader = (pdevice->pscreen->get_shader_param(pdevice->pscreen, PIPE_SHADER_TESS_EVAL, PIPE_SHADER_CAP_MAX_INSTRUCTIONS) != 0),398.sampleRateShading = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_SAMPLE_SHADING) != 0),399.dualSrcBlend = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS) != 0),400.logicOp = true,401.multiDrawIndirect = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MULTI_DRAW_INDIRECT) != 0),402.drawIndirectFirstInstance = true,403.depthClamp = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_DEPTH_CLIP_DISABLE) != 0),404.depthBiasClamp = true,405.fillModeNonSolid = true,406.depthBounds = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_DEPTH_BOUNDS_TEST) != 0),407.wideLines = true,408.largePoints = true,409.alphaToOne = true,410.multiViewport = true,411.samplerAnisotropy = false, /* FINISHME */412.textureCompressionETC2 = false,413.textureCompressionASTC_LDR = false,414.textureCompressionBC = true,415.occlusionQueryPrecise = true,416.pipelineStatisticsQuery = true,417.vertexPipelineStoresAndAtomics = (min_vertex_pipeline_param(pdevice->pscreen, PIPE_SHADER_CAP_MAX_SHADER_BUFFERS) != 0),418.fragmentStoresAndAtomics = (pdevice->pscreen->get_shader_param(pdevice->pscreen, PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_MAX_SHADER_BUFFERS) != 0),419.shaderTessellationAndGeometryPointSize = true,420.shaderImageGatherExtended = true,421.shaderStorageImageExtendedFormats = (min_shader_param(pdevice->pscreen, PIPE_SHADER_CAP_MAX_SHADER_IMAGES) != 0),422.shaderStorageImageMultisample = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_TEXTURE_MULTISAMPLE) != 0),423.shaderUniformBufferArrayDynamicIndexing = indirect,424.shaderSampledImageArrayDynamicIndexing = indirect,425.shaderStorageBufferArrayDynamicIndexing = indirect,426.shaderStorageImageArrayDynamicIndexing = indirect,427.shaderStorageImageReadWithoutFormat = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_IMAGE_LOAD_FORMATTED) != 0),428.shaderStorageImageWriteWithoutFormat = (min_shader_param(pdevice->pscreen, PIPE_SHADER_CAP_MAX_SHADER_IMAGES) != 0),429.shaderClipDistance = true,430.shaderCullDistance = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_CULL_DISTANCE) == 1),431.shaderFloat64 = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_DOUBLES) == 1),432.shaderInt64 = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_INT64) == 1),433.shaderInt16 = (min_shader_param(pdevice->pscreen, PIPE_SHADER_CAP_INT16) == 1),434.variableMultisampleRate = false,435.inheritedQueries = false,436};437}438439static void440lvp_get_physical_device_features_1_1(struct lvp_physical_device *pdevice,441VkPhysicalDeviceVulkan11Features *f)442{443assert(f->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES);444445f->storageBuffer16BitAccess = true;446f->uniformAndStorageBuffer16BitAccess = true;447f->storagePushConstant16 = true;448f->storageInputOutput16 = false;449f->multiview = true;450f->multiviewGeometryShader = true;451f->multiviewTessellationShader = true;452f->variablePointersStorageBuffer = true;453f->variablePointers = false;454f->protectedMemory = false;455f->samplerYcbcrConversion = false;456f->shaderDrawParameters = true;457}458459VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceFeatures2(460VkPhysicalDevice physicalDevice,461VkPhysicalDeviceFeatures2 *pFeatures)462{463LVP_FROM_HANDLE(lvp_physical_device, pdevice, physicalDevice);464lvp_GetPhysicalDeviceFeatures(physicalDevice, &pFeatures->features);465466VkPhysicalDeviceVulkan11Features core_1_1 = {467.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES,468};469lvp_get_physical_device_features_1_1(pdevice, &core_1_1);470471#define CORE_FEATURE(major, minor, feature) \472features->feature = core_##major##_##minor.feature473474vk_foreach_struct(ext, pFeatures->pNext) {475switch (ext->sType) {476case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES: {477VkPhysicalDeviceVariablePointersFeatures *features = (void *)ext;478CORE_FEATURE(1, 1, variablePointersStorageBuffer);479CORE_FEATURE(1, 1, variablePointers);480break;481}482case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES: {483VkPhysicalDeviceShaderDrawParametersFeatures *features =484(VkPhysicalDeviceShaderDrawParametersFeatures*)ext;485CORE_FEATURE(1, 1, shaderDrawParameters);486break;487}488case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES: {489VkPhysicalDeviceProtectedMemoryFeatures *features =490(VkPhysicalDeviceProtectedMemoryFeatures*)ext;491CORE_FEATURE(1, 1, protectedMemory);492break;493}494case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES: {495VkPhysicalDevice8BitStorageFeaturesKHR *features =496(VkPhysicalDevice8BitStorageFeaturesKHR *)ext;497features->storageBuffer8BitAccess = true;498features->uniformAndStorageBuffer8BitAccess = true;499features->storagePushConstant8 = true;500break;501}502case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES: {503VkPhysicalDevice16BitStorageFeatures *features =504(VkPhysicalDevice16BitStorageFeatures*)ext;505CORE_FEATURE(1, 1, storageBuffer16BitAccess);506CORE_FEATURE(1, 1, uniformAndStorageBuffer16BitAccess);507CORE_FEATURE(1, 1, storagePushConstant16);508CORE_FEATURE(1, 1, storageInputOutput16);509break;510}511case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT: {512VkPhysicalDevicePrivateDataFeaturesEXT *features =513(VkPhysicalDevicePrivateDataFeaturesEXT *)ext;514features->privateData = true;515break;516}517case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT: {518VkPhysicalDeviceLineRasterizationFeaturesEXT *features =519(VkPhysicalDeviceLineRasterizationFeaturesEXT *)ext;520features->rectangularLines = true;521features->bresenhamLines = true;522features->smoothLines = true;523features->stippledRectangularLines = true;524features->stippledBresenhamLines = true;525features->stippledSmoothLines = true;526break;527}528case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT: {529VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *features =530(VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *)ext;531features->vertexAttributeInstanceRateZeroDivisor = false;532if (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR) != 0) {533features->vertexAttributeInstanceRateDivisor = true;534} else {535features->vertexAttributeInstanceRateDivisor = false;536}537break;538}539540case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT: {541VkPhysicalDeviceIndexTypeUint8FeaturesEXT *features =542(VkPhysicalDeviceIndexTypeUint8FeaturesEXT *)ext;543features->indexTypeUint8 = true;544break;545}546547case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_INPUT_DYNAMIC_STATE_FEATURES_EXT: {548VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT *features =549(VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT *)ext;550features->vertexInputDynamicState = true;551break;552}553case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT: {554VkPhysicalDeviceTransformFeedbackFeaturesEXT *features =555(VkPhysicalDeviceTransformFeedbackFeaturesEXT*)ext;556557features->transformFeedback = true;558features->geometryStreams = true;559break;560}561case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT: {562VkPhysicalDeviceConditionalRenderingFeaturesEXT *features =563(VkPhysicalDeviceConditionalRenderingFeaturesEXT*)ext;564features->conditionalRendering = true;565features->inheritedConditionalRendering = false;566break;567}568case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT: {569VkPhysicalDeviceExtendedDynamicStateFeaturesEXT *features =570(VkPhysicalDeviceExtendedDynamicStateFeaturesEXT*)ext;571features->extendedDynamicState = true;572break;573}574case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES: {575VkPhysicalDeviceMultiviewFeatures *features = (VkPhysicalDeviceMultiviewFeatures*)ext;576CORE_FEATURE(1, 1, multiview);577CORE_FEATURE(1, 1, multiviewGeometryShader);578CORE_FEATURE(1, 1, multiviewTessellationShader);579break;580}581case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES: {582lvp_get_physical_device_features_1_1(pdevice, (void *)ext);583break;584}585case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR: {586VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR *features =587(VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR *)ext;588features->uniformBufferStandardLayout = true;589break;590}591case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT: {592VkPhysicalDeviceScalarBlockLayoutFeaturesEXT *features =593(VkPhysicalDeviceScalarBlockLayoutFeaturesEXT *)ext;594features->scalarBlockLayout = true;595break;596}597case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES: {598VkPhysicalDeviceSamplerYcbcrConversionFeatures *features =599(VkPhysicalDeviceSamplerYcbcrConversionFeatures *) ext;600CORE_FEATURE(1, 1, samplerYcbcrConversion);601break;602}603case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT: {604VkPhysicalDeviceHostQueryResetFeaturesEXT *features =605(VkPhysicalDeviceHostQueryResetFeaturesEXT *)ext;606features->hostQueryReset = true;607break;608}609case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR: {610VkPhysicalDeviceBufferDeviceAddressFeaturesKHR *features = (void *)ext;611features->bufferDeviceAddress = true;612features->bufferDeviceAddressCaptureReplay = false;613features->bufferDeviceAddressMultiDevice = false;614break;615}616case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR: {617VkPhysicalDeviceShaderAtomicInt64FeaturesKHR *features = (void *)ext;618features->shaderBufferInt64Atomics = true;619features->shaderSharedInt64Atomics = true;620break;621}622case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES: {623VkPhysicalDeviceImagelessFramebufferFeatures *features =624(VkPhysicalDeviceImagelessFramebufferFeatures*)ext;625features->imagelessFramebuffer = true;626break;627}628case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES_KHR: {629VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR *features =630(VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR *)ext;631features->separateDepthStencilLayouts = true;632break;633}634case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT: {635VkPhysicalDeviceCustomBorderColorFeaturesEXT *features =636(VkPhysicalDeviceCustomBorderColorFeaturesEXT *)ext;637features->customBorderColors = true;638features->customBorderColorWithoutFormat = true;639break;640}641case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT: {642VkPhysicalDeviceProvokingVertexFeaturesEXT *features =643(VkPhysicalDeviceProvokingVertexFeaturesEXT*)ext;644features->provokingVertexLast = true;645features->transformFeedbackPreservesProvokingVertex = true;646break;647}648case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_FEATURES_EXT: {649VkPhysicalDeviceMultiDrawFeaturesEXT *features = (VkPhysicalDeviceMultiDrawFeaturesEXT *)ext;650features->multiDraw = true;651break;652}653case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT: {654VkPhysicalDeviceExtendedDynamicState2FeaturesEXT *features = (VkPhysicalDeviceExtendedDynamicState2FeaturesEXT *)ext;655features->extendedDynamicState2 = true;656features->extendedDynamicState2LogicOp = true;657features->extendedDynamicState2PatchControlPoints = true;658break;659}660default:661break;662}663}664}665666void667lvp_device_get_cache_uuid(void *uuid)668{669memset(uuid, 0, VK_UUID_SIZE);670snprintf(uuid, VK_UUID_SIZE, "val-%s", MESA_GIT_SHA1 + 4);671}672673VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,674VkPhysicalDeviceProperties *pProperties)675{676LVP_FROM_HANDLE(lvp_physical_device, pdevice, physicalDevice);677678VkSampleCountFlags sample_counts = VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT;679680uint64_t grid_size[3], block_size[3];681uint64_t max_threads_per_block, max_local_size;682683pdevice->pscreen->get_compute_param(pdevice->pscreen, PIPE_SHADER_IR_NIR,684PIPE_COMPUTE_CAP_MAX_GRID_SIZE, grid_size);685pdevice->pscreen->get_compute_param(pdevice->pscreen, PIPE_SHADER_IR_NIR,686PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE, block_size);687pdevice->pscreen->get_compute_param(pdevice->pscreen, PIPE_SHADER_IR_NIR,688PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK,689&max_threads_per_block);690pdevice->pscreen->get_compute_param(pdevice->pscreen, PIPE_SHADER_IR_NIR,691PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE,692&max_local_size);693694VkPhysicalDeviceLimits limits = {695.maxImageDimension1D = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_TEXTURE_2D_SIZE),696.maxImageDimension2D = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_TEXTURE_2D_SIZE),697.maxImageDimension3D = (1 << pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_TEXTURE_3D_LEVELS)),698.maxImageDimensionCube = (1 << pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS)),699.maxImageArrayLayers = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS),700.maxTexelBufferElements = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE),701.maxUniformBufferRange = min_shader_param(pdevice->pscreen, PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE),702.maxStorageBufferRange = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_SHADER_BUFFER_SIZE),703.maxPushConstantsSize = MAX_PUSH_CONSTANTS_SIZE,704.maxMemoryAllocationCount = UINT32_MAX,705.maxSamplerAllocationCount = 32 * 1024,706.bufferImageGranularity = 64, /* A cache line */707.sparseAddressSpaceSize = 0,708.maxBoundDescriptorSets = MAX_SETS,709.maxPerStageDescriptorSamplers = min_shader_param(pdevice->pscreen, PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS),710.maxPerStageDescriptorUniformBuffers = min_shader_param(pdevice->pscreen, PIPE_SHADER_CAP_MAX_CONST_BUFFERS) - 1,711.maxPerStageDescriptorStorageBuffers = min_shader_param(pdevice->pscreen, PIPE_SHADER_CAP_MAX_SHADER_BUFFERS),712.maxPerStageDescriptorSampledImages = min_shader_param(pdevice->pscreen, PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS),713.maxPerStageDescriptorStorageImages = min_shader_param(pdevice->pscreen, PIPE_SHADER_CAP_MAX_SHADER_IMAGES),714.maxPerStageDescriptorInputAttachments = 8,715.maxPerStageResources = 128,716.maxDescriptorSetSamplers = 32 * 1024,717.maxDescriptorSetUniformBuffers = 256,718.maxDescriptorSetUniformBuffersDynamic = 256,719.maxDescriptorSetStorageBuffers = 256,720.maxDescriptorSetStorageBuffersDynamic = 256,721.maxDescriptorSetSampledImages = 256,722.maxDescriptorSetStorageImages = 256,723.maxDescriptorSetInputAttachments = 256,724.maxVertexInputAttributes = 32,725.maxVertexInputBindings = 32,726.maxVertexInputAttributeOffset = 2047,727.maxVertexInputBindingStride = 2048,728.maxVertexOutputComponents = 128,729.maxTessellationGenerationLevel = 64,730.maxTessellationPatchSize = 32,731.maxTessellationControlPerVertexInputComponents = 128,732.maxTessellationControlPerVertexOutputComponents = 128,733.maxTessellationControlPerPatchOutputComponents = 128,734.maxTessellationControlTotalOutputComponents = 4096,735.maxTessellationEvaluationInputComponents = 128,736.maxTessellationEvaluationOutputComponents = 128,737.maxGeometryShaderInvocations = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_GS_INVOCATIONS),738.maxGeometryInputComponents = 64,739.maxGeometryOutputComponents = 128,740.maxGeometryOutputVertices = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES),741.maxGeometryTotalOutputComponents = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS),742.maxFragmentInputComponents = 128,743.maxFragmentOutputAttachments = 8,744.maxFragmentDualSrcAttachments = 2,745.maxFragmentCombinedOutputResources = 8,746.maxComputeSharedMemorySize = max_local_size,747.maxComputeWorkGroupCount = { grid_size[0], grid_size[1], grid_size[2] },748.maxComputeWorkGroupInvocations = max_threads_per_block,749.maxComputeWorkGroupSize = { block_size[0], block_size[1], block_size[2] },750.subPixelPrecisionBits = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_RASTERIZER_SUBPIXEL_BITS),751.subTexelPrecisionBits = 8,752.mipmapPrecisionBits = 8,753.maxDrawIndexedIndexValue = UINT32_MAX,754.maxDrawIndirectCount = UINT32_MAX,755.maxSamplerLodBias = 16,756.maxSamplerAnisotropy = 16,757.maxViewports = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_VIEWPORTS),758.maxViewportDimensions = { (1 << 14), (1 << 14) },759.viewportBoundsRange = { -32768.0, 32768.0 },760.viewportSubPixelBits = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_VIEWPORT_SUBPIXEL_BITS),761.minMemoryMapAlignment = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT),762.minTexelBufferOffsetAlignment = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT),763.minUniformBufferOffsetAlignment = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT),764.minStorageBufferOffsetAlignment = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT),765.minTexelOffset = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MIN_TEXEL_OFFSET),766.maxTexelOffset = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_TEXEL_OFFSET),767.minTexelGatherOffset = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET),768.maxTexelGatherOffset = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET),769.minInterpolationOffset = -2, /* FIXME */770.maxInterpolationOffset = 2, /* FIXME */771.subPixelInterpolationOffsetBits = 8, /* FIXME */772.maxFramebufferWidth = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_TEXTURE_2D_SIZE),773.maxFramebufferHeight = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_TEXTURE_2D_SIZE),774.maxFramebufferLayers = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS),775.framebufferColorSampleCounts = sample_counts,776.framebufferDepthSampleCounts = sample_counts,777.framebufferStencilSampleCounts = sample_counts,778.framebufferNoAttachmentsSampleCounts = sample_counts,779.maxColorAttachments = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_RENDER_TARGETS),780.sampledImageColorSampleCounts = sample_counts,781.sampledImageIntegerSampleCounts = sample_counts,782.sampledImageDepthSampleCounts = sample_counts,783.sampledImageStencilSampleCounts = sample_counts,784.storageImageSampleCounts = sample_counts,785.maxSampleMaskWords = 1,786.timestampComputeAndGraphics = true,787.timestampPeriod = 1,788.maxClipDistances = 8,789.maxCullDistances = 8,790.maxCombinedClipAndCullDistances = 8,791.discreteQueuePriorities = 2,792.pointSizeRange = { 0.0, pdevice->pscreen->get_paramf(pdevice->pscreen, PIPE_CAPF_MAX_POINT_WIDTH) },793.lineWidthRange = { 1.0, pdevice->pscreen->get_paramf(pdevice->pscreen, PIPE_CAPF_MAX_LINE_WIDTH) },794.pointSizeGranularity = (1.0 / 8.0),795.lineWidthGranularity = 1.0 / 128.0,796.strictLines = true,797.standardSampleLocations = true,798.optimalBufferCopyOffsetAlignment = 128,799.optimalBufferCopyRowPitchAlignment = 128,800.nonCoherentAtomSize = 64,801};802803*pProperties = (VkPhysicalDeviceProperties) {804.apiVersion = LVP_API_VERSION,805.driverVersion = 1,806.vendorID = VK_VENDOR_ID_MESA,807.deviceID = 0,808.deviceType = VK_PHYSICAL_DEVICE_TYPE_CPU,809.limits = limits,810.sparseProperties = {0},811};812813strcpy(pProperties->deviceName, pdevice->pscreen->get_name(pdevice->pscreen));814lvp_device_get_cache_uuid(pProperties->pipelineCacheUUID);815816}817818extern unsigned lp_native_vector_width;819static void820lvp_get_physical_device_properties_1_1(struct lvp_physical_device *pdevice,821VkPhysicalDeviceVulkan11Properties *p)822{823assert(p->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES);824825memset(p->deviceUUID, 0, VK_UUID_SIZE);826memset(p->driverUUID, 0, VK_UUID_SIZE);827memset(p->deviceLUID, 0, VK_LUID_SIZE);828/* The LUID is for Windows. */829p->deviceLUIDValid = false;830p->deviceNodeMask = 0;831832p->subgroupSize = lp_native_vector_width / 32;833p->subgroupSupportedStages = VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT;834p->subgroupSupportedOperations = VK_SUBGROUP_FEATURE_BASIC_BIT | VK_SUBGROUP_FEATURE_VOTE_BIT | VK_SUBGROUP_FEATURE_ARITHMETIC_BIT | VK_SUBGROUP_FEATURE_BALLOT_BIT;835p->subgroupQuadOperationsInAllStages = false;836837p->pointClippingBehavior = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES;838p->maxMultiviewViewCount = 6;839p->maxMultiviewInstanceIndex = INT_MAX;840p->protectedNoFault = false;841p->maxPerSetDescriptors = 1024;842p->maxMemoryAllocationSize = (1u << 31);843}844845VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceProperties2(846VkPhysicalDevice physicalDevice,847VkPhysicalDeviceProperties2 *pProperties)848{849LVP_FROM_HANDLE(lvp_physical_device, pdevice, physicalDevice);850lvp_GetPhysicalDeviceProperties(physicalDevice, &pProperties->properties);851852VkPhysicalDeviceVulkan11Properties core_1_1 = {853.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES,854};855lvp_get_physical_device_properties_1_1(pdevice, &core_1_1);856857#define CORE_RENAMED_PROPERTY(major, minor, ext_property, core_property) \858memcpy(&properties->ext_property, &core_##major##_##minor.core_property, \859sizeof(core_##major##_##minor.core_property))860861#define CORE_PROPERTY(major, minor, property) \862CORE_RENAMED_PROPERTY(major, minor, property, property)863864vk_foreach_struct(ext, pProperties->pNext) {865switch (ext->sType) {866867case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR: {868VkPhysicalDevicePushDescriptorPropertiesKHR *properties =869(VkPhysicalDevicePushDescriptorPropertiesKHR *) ext;870properties->maxPushDescriptors = MAX_PUSH_DESCRIPTORS;871break;872}873case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES: {874VkPhysicalDeviceMaintenance3Properties *properties =875(VkPhysicalDeviceMaintenance3Properties*)ext;876CORE_PROPERTY(1, 1, maxPerSetDescriptors);877CORE_PROPERTY(1, 1, maxMemoryAllocationSize);878break;879}880case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR: {881VkPhysicalDeviceDriverPropertiesKHR *driver_props =882(VkPhysicalDeviceDriverPropertiesKHR *) ext;883driver_props->driverID = VK_DRIVER_ID_MESA_LLVMPIPE;884snprintf(driver_props->driverName, VK_MAX_DRIVER_NAME_SIZE_KHR, "llvmpipe");885snprintf(driver_props->driverInfo, VK_MAX_DRIVER_INFO_SIZE_KHR,886"Mesa " PACKAGE_VERSION MESA_GIT_SHA1887#ifdef MESA_LLVM_VERSION_STRING888" (LLVM " MESA_LLVM_VERSION_STRING ")"889#endif890);891driver_props->conformanceVersion.major = 1;892driver_props->conformanceVersion.minor = 0;893driver_props->conformanceVersion.subminor = 0;894driver_props->conformanceVersion.patch = 0;;895break;896}897case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES: {898VkPhysicalDevicePointClippingProperties *properties =899(VkPhysicalDevicePointClippingProperties*)ext;900properties->pointClippingBehavior = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES;901break;902}903case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT: {904VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *props =905(VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *)ext;906if (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR) != 0)907props->maxVertexAttribDivisor = UINT32_MAX;908else909props->maxVertexAttribDivisor = 1;910break;911}912case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT: {913VkPhysicalDeviceTransformFeedbackPropertiesEXT *properties =914(VkPhysicalDeviceTransformFeedbackPropertiesEXT*)ext;915properties->maxTransformFeedbackStreams = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_VERTEX_STREAMS);916properties->maxTransformFeedbackBuffers = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS);917properties->maxTransformFeedbackBufferSize = UINT32_MAX;918properties->maxTransformFeedbackStreamDataSize = 512;919properties->maxTransformFeedbackBufferDataSize = 512;920properties->maxTransformFeedbackBufferDataStride = 512;921properties->transformFeedbackQueries = true;922properties->transformFeedbackStreamsLinesTriangles = false;923properties->transformFeedbackRasterizationStreamSelect = false;924properties->transformFeedbackDraw = true;925break;926}927case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES: {928VkPhysicalDeviceMultiviewProperties *properties =929(VkPhysicalDeviceMultiviewProperties *)ext;930CORE_PROPERTY(1, 1, maxMultiviewViewCount);931CORE_PROPERTY(1, 1, maxMultiviewInstanceIndex);932break;933}934case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES: {935VkPhysicalDeviceIDProperties *properties =936(VkPhysicalDeviceIDProperties *)ext;937CORE_PROPERTY(1, 1, deviceUUID);938CORE_PROPERTY(1, 1, driverUUID);939CORE_PROPERTY(1, 1, deviceLUID);940CORE_PROPERTY(1, 1, deviceLUIDValid);941break;942}943case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES: {944VkPhysicalDeviceProtectedMemoryProperties *properties =945(VkPhysicalDeviceProtectedMemoryProperties *)ext;946CORE_PROPERTY(1, 1, protectedNoFault);947break;948}949case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT: {950VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT *properties =951(VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT *)ext;952properties->filterMinmaxImageComponentMapping = true;953properties->filterMinmaxSingleComponentFormats = true;954break;955}956case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT: {957VkPhysicalDeviceLineRasterizationPropertiesEXT *properties =958(VkPhysicalDeviceLineRasterizationPropertiesEXT *)ext;959properties->lineSubPixelPrecisionBits = 4;960break;961}962case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES: {963VkPhysicalDeviceSubgroupProperties *properties =964(VkPhysicalDeviceSubgroupProperties*)ext;965CORE_PROPERTY(1, 1, subgroupSize);966CORE_RENAMED_PROPERTY(1, 1, supportedStages,967subgroupSupportedStages);968CORE_RENAMED_PROPERTY(1, 1, supportedOperations,969subgroupSupportedOperations);970CORE_RENAMED_PROPERTY(1, 1, quadOperationsInAllStages,971subgroupQuadOperationsInAllStages);972break;973}974case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES:975lvp_get_physical_device_properties_1_1(pdevice, (void *)ext);976break;977case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_PROPERTIES_EXT: {978VkPhysicalDeviceCustomBorderColorPropertiesEXT *properties =979(VkPhysicalDeviceCustomBorderColorPropertiesEXT *)ext;980properties->maxCustomBorderColorSamplers = 32 * 1024;981break;982}983case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_PROPERTIES_EXT: {984VkPhysicalDeviceProvokingVertexPropertiesEXT *properties =985(VkPhysicalDeviceProvokingVertexPropertiesEXT*)ext;986properties->provokingVertexModePerPipeline = true;987properties->transformFeedbackPreservesTriangleFanProvokingVertex = true;988break;989}990case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_PROPERTIES_EXT: {991VkPhysicalDeviceMultiDrawPropertiesEXT *props = (VkPhysicalDeviceMultiDrawPropertiesEXT *)ext;992props->maxMultiDrawCount = 2048;993break;994}995default:996break;997}998}999}10001001static void lvp_get_physical_device_queue_family_properties(1002VkQueueFamilyProperties* pQueueFamilyProperties)1003{1004*pQueueFamilyProperties = (VkQueueFamilyProperties) {1005.queueFlags = VK_QUEUE_GRAPHICS_BIT |1006VK_QUEUE_COMPUTE_BIT |1007VK_QUEUE_TRANSFER_BIT,1008.queueCount = 1,1009.timestampValidBits = 64,1010.minImageTransferGranularity = (VkExtent3D) { 1, 1, 1 },1011};1012}10131014VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceQueueFamilyProperties(1015VkPhysicalDevice physicalDevice,1016uint32_t* pCount,1017VkQueueFamilyProperties* pQueueFamilyProperties)1018{1019if (pQueueFamilyProperties == NULL) {1020*pCount = 1;1021return;1022}10231024assert(*pCount >= 1);1025lvp_get_physical_device_queue_family_properties(pQueueFamilyProperties);1026}10271028VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceQueueFamilyProperties2(1029VkPhysicalDevice physicalDevice,1030uint32_t* pCount,1031VkQueueFamilyProperties2 *pQueueFamilyProperties)1032{1033if (pQueueFamilyProperties == NULL) {1034*pCount = 1;1035return;1036}10371038assert(*pCount >= 1);1039lvp_get_physical_device_queue_family_properties(&pQueueFamilyProperties->queueFamilyProperties);1040}10411042VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceMemoryProperties(1043VkPhysicalDevice physicalDevice,1044VkPhysicalDeviceMemoryProperties* pMemoryProperties)1045{1046pMemoryProperties->memoryTypeCount = 1;1047pMemoryProperties->memoryTypes[0] = (VkMemoryType) {1048.propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |1049VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |1050VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |1051VK_MEMORY_PROPERTY_HOST_CACHED_BIT,1052.heapIndex = 0,1053};10541055pMemoryProperties->memoryHeapCount = 1;1056pMemoryProperties->memoryHeaps[0] = (VkMemoryHeap) {1057.size = 2ULL*1024*1024*1024,1058.flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT,1059};1060}10611062VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceMemoryProperties2(1063VkPhysicalDevice physicalDevice,1064VkPhysicalDeviceMemoryProperties2 *pMemoryProperties)1065{1066lvp_GetPhysicalDeviceMemoryProperties(physicalDevice,1067&pMemoryProperties->memoryProperties);1068}10691070VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL lvp_GetInstanceProcAddr(1071VkInstance _instance,1072const char* pName)1073{1074LVP_FROM_HANDLE(lvp_instance, instance, _instance);1075return vk_instance_get_proc_addr(&instance->vk,1076&lvp_instance_entrypoints,1077pName);1078}10791080/* Windows will use a dll definition file to avoid build errors. */1081#ifdef _WIN321082#undef PUBLIC1083#define PUBLIC1084#endif10851086/* The loader wants us to expose a second GetInstanceProcAddr function1087* to work around certain LD_PRELOAD issues seen in apps.1088*/1089PUBLIC1090VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(1091VkInstance instance,1092const char* pName);10931094PUBLIC1095VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(1096VkInstance instance,1097const char* pName)1098{1099return lvp_GetInstanceProcAddr(instance, pName);1100}11011102PUBLIC1103VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetPhysicalDeviceProcAddr(1104VkInstance _instance,1105const char* pName);11061107PUBLIC1108VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetPhysicalDeviceProcAddr(1109VkInstance _instance,1110const char* pName)1111{1112LVP_FROM_HANDLE(lvp_instance, instance, _instance);1113return vk_instance_get_physical_device_proc_addr(&instance->vk, pName);1114}11151116static int queue_thread(void *data)1117{1118struct lvp_queue *queue = data;11191120mtx_lock(&queue->m);1121while (!queue->shutdown) {1122struct lvp_queue_work *task;1123while (list_is_empty(&queue->workqueue) && !queue->shutdown)1124cnd_wait(&queue->new_work, &queue->m);11251126if (queue->shutdown)1127break;11281129task = list_first_entry(&queue->workqueue, struct lvp_queue_work,1130list);11311132mtx_unlock(&queue->m);1133//execute1134for (unsigned i = 0; i < task->cmd_buffer_count; i++) {1135lvp_execute_cmds(queue->device, queue, task->cmd_buffers[i]);1136}11371138if (task->cmd_buffer_count) {1139struct pipe_fence_handle *handle = NULL;1140queue->ctx->flush(queue->ctx, task->fence ? &handle : NULL, 0);1141if (task->fence) {1142mtx_lock(&queue->device->fence_lock);1143task->fence->handle = handle;1144mtx_unlock(&queue->device->fence_lock);1145}1146} else if (task->fence)1147task->fence->signaled = true;1148p_atomic_dec(&queue->count);1149mtx_lock(&queue->m);1150list_del(&task->list);1151free(task);1152}1153mtx_unlock(&queue->m);1154return 0;1155}11561157static VkResult1158lvp_queue_init(struct lvp_device *device, struct lvp_queue *queue)1159{1160queue->device = device;11611162queue->flags = 0;1163queue->ctx = device->pscreen->context_create(device->pscreen, NULL, PIPE_CONTEXT_ROBUST_BUFFER_ACCESS);1164queue->cso = cso_create_context(queue->ctx, CSO_NO_VBUF);1165list_inithead(&queue->workqueue);1166p_atomic_set(&queue->count, 0);1167mtx_init(&queue->m, mtx_plain);1168queue->exec_thread = u_thread_create(queue_thread, queue);11691170vk_object_base_init(&device->vk, &queue->base, VK_OBJECT_TYPE_QUEUE);1171return VK_SUCCESS;1172}11731174static void1175lvp_queue_finish(struct lvp_queue *queue)1176{1177mtx_lock(&queue->m);1178queue->shutdown = true;1179cnd_broadcast(&queue->new_work);1180mtx_unlock(&queue->m);11811182thrd_join(queue->exec_thread, NULL);11831184cnd_destroy(&queue->new_work);1185mtx_destroy(&queue->m);1186cso_destroy_context(queue->cso);1187queue->ctx->destroy(queue->ctx);1188}11891190VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateDevice(1191VkPhysicalDevice physicalDevice,1192const VkDeviceCreateInfo* pCreateInfo,1193const VkAllocationCallbacks* pAllocator,1194VkDevice* pDevice)1195{1196fprintf(stderr, "WARNING: lavapipe is not a conformant vulkan implementation, testing use only.\n");11971198LVP_FROM_HANDLE(lvp_physical_device, physical_device, physicalDevice);1199struct lvp_device *device;1200struct lvp_instance *instance = (struct lvp_instance *)physical_device->vk.instance;12011202assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO);12031204/* Check enabled features */1205if (pCreateInfo->pEnabledFeatures) {1206VkPhysicalDeviceFeatures supported_features;1207lvp_GetPhysicalDeviceFeatures(physicalDevice, &supported_features);1208VkBool32 *supported_feature = (VkBool32 *)&supported_features;1209VkBool32 *enabled_feature = (VkBool32 *)pCreateInfo->pEnabledFeatures;1210unsigned num_features = sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32);1211for (uint32_t i = 0; i < num_features; i++) {1212if (enabled_feature[i] && !supported_feature[i])1213return vk_error(instance, VK_ERROR_FEATURE_NOT_PRESENT);1214}1215}12161217device = vk_zalloc2(&physical_device->vk.instance->alloc, pAllocator,1218sizeof(*device), 8,1219VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);1220if (!device)1221return vk_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY);12221223struct vk_device_dispatch_table dispatch_table;1224vk_device_dispatch_table_from_entrypoints(&dispatch_table,1225&lvp_device_entrypoints, true);1226VkResult result = vk_device_init(&device->vk,1227&physical_device->vk,1228&dispatch_table, pCreateInfo,1229pAllocator);1230if (result != VK_SUCCESS) {1231vk_free(&device->vk.alloc, device);1232return vk_error(instance, result);1233}12341235device->instance = (struct lvp_instance *)physical_device->vk.instance;1236device->physical_device = physical_device;12371238mtx_init(&device->fence_lock, mtx_plain);1239device->pscreen = physical_device->pscreen;12401241lvp_queue_init(device, &device->queue);12421243*pDevice = lvp_device_to_handle(device);12441245return VK_SUCCESS;12461247}12481249VKAPI_ATTR void VKAPI_CALL lvp_DestroyDevice(1250VkDevice _device,1251const VkAllocationCallbacks* pAllocator)1252{1253LVP_FROM_HANDLE(lvp_device, device, _device);12541255lvp_queue_finish(&device->queue);1256vk_device_finish(&device->vk);1257vk_free(&device->vk.alloc, device);1258}12591260VKAPI_ATTR VkResult VKAPI_CALL lvp_EnumerateInstanceExtensionProperties(1261const char* pLayerName,1262uint32_t* pPropertyCount,1263VkExtensionProperties* pProperties)1264{1265if (pLayerName)1266return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT);12671268return vk_enumerate_instance_extension_properties(1269&lvp_instance_extensions_supported, pPropertyCount, pProperties);1270}12711272VKAPI_ATTR VkResult VKAPI_CALL lvp_EnumerateInstanceLayerProperties(1273uint32_t* pPropertyCount,1274VkLayerProperties* pProperties)1275{1276if (pProperties == NULL) {1277*pPropertyCount = 0;1278return VK_SUCCESS;1279}12801281/* None supported at this time */1282return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT);1283}12841285VKAPI_ATTR VkResult VKAPI_CALL lvp_EnumerateDeviceLayerProperties(1286VkPhysicalDevice physicalDevice,1287uint32_t* pPropertyCount,1288VkLayerProperties* pProperties)1289{1290if (pProperties == NULL) {1291*pPropertyCount = 0;1292return VK_SUCCESS;1293}12941295/* None supported at this time */1296return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT);1297}12981299VKAPI_ATTR void VKAPI_CALL lvp_GetDeviceQueue2(1300VkDevice _device,1301const VkDeviceQueueInfo2* pQueueInfo,1302VkQueue* pQueue)1303{1304LVP_FROM_HANDLE(lvp_device, device, _device);1305struct lvp_queue *queue;13061307queue = &device->queue;1308if (pQueueInfo->flags != queue->flags) {1309/* From the Vulkan 1.1.70 spec:1310*1311* "The queue returned by vkGetDeviceQueue2 must have the same1312* flags value from this structure as that used at device1313* creation time in a VkDeviceQueueCreateInfo instance. If no1314* matching flags were specified at device creation time then1315* pQueue will return VK_NULL_HANDLE."1316*/1317*pQueue = VK_NULL_HANDLE;1318return;1319}13201321*pQueue = lvp_queue_to_handle(queue);1322}132313241325VKAPI_ATTR void VKAPI_CALL lvp_GetDeviceQueue(1326VkDevice _device,1327uint32_t queueFamilyIndex,1328uint32_t queueIndex,1329VkQueue* pQueue)1330{1331const VkDeviceQueueInfo2 info = (VkDeviceQueueInfo2) {1332.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2,1333.queueFamilyIndex = queueFamilyIndex,1334.queueIndex = queueIndex1335};13361337lvp_GetDeviceQueue2(_device, &info, pQueue);1338}133913401341VKAPI_ATTR VkResult VKAPI_CALL lvp_QueueSubmit(1342VkQueue _queue,1343uint32_t submitCount,1344const VkSubmitInfo* pSubmits,1345VkFence _fence)1346{1347LVP_FROM_HANDLE(lvp_queue, queue, _queue);1348LVP_FROM_HANDLE(lvp_fence, fence, _fence);13491350if (submitCount == 0)1351goto just_signal_fence;1352for (uint32_t i = 0; i < submitCount; i++) {1353uint32_t task_size = sizeof(struct lvp_queue_work) + pSubmits[i].commandBufferCount * sizeof(struct lvp_cmd_buffer *);1354struct lvp_queue_work *task = malloc(task_size);13551356task->cmd_buffer_count = pSubmits[i].commandBufferCount;1357task->fence = fence;1358task->cmd_buffers = (struct lvp_cmd_buffer **)(task + 1);1359for (uint32_t j = 0; j < pSubmits[i].commandBufferCount; j++) {1360task->cmd_buffers[j] = lvp_cmd_buffer_from_handle(pSubmits[i].pCommandBuffers[j]);1361}13621363mtx_lock(&queue->m);1364p_atomic_inc(&queue->count);1365list_addtail(&task->list, &queue->workqueue);1366cnd_signal(&queue->new_work);1367mtx_unlock(&queue->m);1368}1369return VK_SUCCESS;1370just_signal_fence:1371fence->signaled = true;1372return VK_SUCCESS;1373}13741375static VkResult queue_wait_idle(struct lvp_queue *queue, uint64_t timeout)1376{1377if (timeout == 0)1378return p_atomic_read(&queue->count) == 0 ? VK_SUCCESS : VK_TIMEOUT;1379if (timeout == UINT64_MAX)1380while (p_atomic_read(&queue->count))1381os_time_sleep(100);1382else {1383int64_t atime = os_time_get_absolute_timeout(timeout);1384if (!os_wait_until_zero_abs_timeout(&queue->count, atime))1385return VK_TIMEOUT;1386}1387return VK_SUCCESS;1388}13891390VKAPI_ATTR VkResult VKAPI_CALL lvp_QueueWaitIdle(1391VkQueue _queue)1392{1393LVP_FROM_HANDLE(lvp_queue, queue, _queue);13941395return queue_wait_idle(queue, UINT64_MAX);1396}13971398VKAPI_ATTR VkResult VKAPI_CALL lvp_DeviceWaitIdle(1399VkDevice _device)1400{1401LVP_FROM_HANDLE(lvp_device, device, _device);14021403return queue_wait_idle(&device->queue, UINT64_MAX);1404}14051406VKAPI_ATTR VkResult VKAPI_CALL lvp_AllocateMemory(1407VkDevice _device,1408const VkMemoryAllocateInfo* pAllocateInfo,1409const VkAllocationCallbacks* pAllocator,1410VkDeviceMemory* pMem)1411{1412LVP_FROM_HANDLE(lvp_device, device, _device);1413struct lvp_device_memory *mem;1414assert(pAllocateInfo->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);14151416if (pAllocateInfo->allocationSize == 0) {1417/* Apparently, this is allowed */1418*pMem = VK_NULL_HANDLE;1419return VK_SUCCESS;1420}14211422mem = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*mem), 8,1423VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);1424if (mem == NULL)1425return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);14261427vk_object_base_init(&device->vk, &mem->base,1428VK_OBJECT_TYPE_DEVICE_MEMORY);1429mem->pmem = device->pscreen->allocate_memory(device->pscreen, pAllocateInfo->allocationSize);1430if (!mem->pmem) {1431vk_free2(&device->vk.alloc, pAllocator, mem);1432return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);1433}14341435mem->type_index = pAllocateInfo->memoryTypeIndex;14361437*pMem = lvp_device_memory_to_handle(mem);14381439return VK_SUCCESS;1440}14411442VKAPI_ATTR void VKAPI_CALL lvp_FreeMemory(1443VkDevice _device,1444VkDeviceMemory _mem,1445const VkAllocationCallbacks* pAllocator)1446{1447LVP_FROM_HANDLE(lvp_device, device, _device);1448LVP_FROM_HANDLE(lvp_device_memory, mem, _mem);14491450if (mem == NULL)1451return;14521453device->pscreen->free_memory(device->pscreen, mem->pmem);1454vk_object_base_finish(&mem->base);1455vk_free2(&device->vk.alloc, pAllocator, mem);14561457}14581459VKAPI_ATTR VkResult VKAPI_CALL lvp_MapMemory(1460VkDevice _device,1461VkDeviceMemory _memory,1462VkDeviceSize offset,1463VkDeviceSize size,1464VkMemoryMapFlags flags,1465void** ppData)1466{1467LVP_FROM_HANDLE(lvp_device, device, _device);1468LVP_FROM_HANDLE(lvp_device_memory, mem, _memory);1469void *map;1470if (mem == NULL) {1471*ppData = NULL;1472return VK_SUCCESS;1473}14741475map = device->pscreen->map_memory(device->pscreen, mem->pmem);14761477*ppData = (char *)map + offset;1478return VK_SUCCESS;1479}14801481VKAPI_ATTR void VKAPI_CALL lvp_UnmapMemory(1482VkDevice _device,1483VkDeviceMemory _memory)1484{1485LVP_FROM_HANDLE(lvp_device, device, _device);1486LVP_FROM_HANDLE(lvp_device_memory, mem, _memory);14871488if (mem == NULL)1489return;14901491device->pscreen->unmap_memory(device->pscreen, mem->pmem);1492}14931494VKAPI_ATTR VkResult VKAPI_CALL lvp_FlushMappedMemoryRanges(1495VkDevice _device,1496uint32_t memoryRangeCount,1497const VkMappedMemoryRange* pMemoryRanges)1498{1499return VK_SUCCESS;1500}15011502VKAPI_ATTR VkResult VKAPI_CALL lvp_InvalidateMappedMemoryRanges(1503VkDevice _device,1504uint32_t memoryRangeCount,1505const VkMappedMemoryRange* pMemoryRanges)1506{1507return VK_SUCCESS;1508}15091510VKAPI_ATTR void VKAPI_CALL lvp_GetBufferMemoryRequirements(1511VkDevice device,1512VkBuffer _buffer,1513VkMemoryRequirements* pMemoryRequirements)1514{1515LVP_FROM_HANDLE(lvp_buffer, buffer, _buffer);15161517/* The Vulkan spec (git aaed022) says:1518*1519* memoryTypeBits is a bitfield and contains one bit set for every1520* supported memory type for the resource. The bit `1<<i` is set if and1521* only if the memory type `i` in the VkPhysicalDeviceMemoryProperties1522* structure for the physical device is supported.1523*1524* We support exactly one memory type.1525*/1526pMemoryRequirements->memoryTypeBits = 1;15271528pMemoryRequirements->size = buffer->total_size;1529pMemoryRequirements->alignment = 64;1530}15311532VKAPI_ATTR void VKAPI_CALL lvp_GetBufferMemoryRequirements2(1533VkDevice device,1534const VkBufferMemoryRequirementsInfo2 *pInfo,1535VkMemoryRequirements2 *pMemoryRequirements)1536{1537lvp_GetBufferMemoryRequirements(device, pInfo->buffer,1538&pMemoryRequirements->memoryRequirements);1539vk_foreach_struct(ext, pMemoryRequirements->pNext) {1540switch (ext->sType) {1541case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {1542VkMemoryDedicatedRequirements *req =1543(VkMemoryDedicatedRequirements *) ext;1544req->requiresDedicatedAllocation = false;1545req->prefersDedicatedAllocation = req->requiresDedicatedAllocation;1546break;1547}1548default:1549break;1550}1551}1552}15531554VKAPI_ATTR void VKAPI_CALL lvp_GetImageMemoryRequirements(1555VkDevice device,1556VkImage _image,1557VkMemoryRequirements* pMemoryRequirements)1558{1559LVP_FROM_HANDLE(lvp_image, image, _image);1560pMemoryRequirements->memoryTypeBits = 1;15611562pMemoryRequirements->size = image->size;1563pMemoryRequirements->alignment = image->alignment;1564}15651566VKAPI_ATTR void VKAPI_CALL lvp_GetImageMemoryRequirements2(1567VkDevice device,1568const VkImageMemoryRequirementsInfo2 *pInfo,1569VkMemoryRequirements2 *pMemoryRequirements)1570{1571lvp_GetImageMemoryRequirements(device, pInfo->image,1572&pMemoryRequirements->memoryRequirements);15731574vk_foreach_struct(ext, pMemoryRequirements->pNext) {1575switch (ext->sType) {1576case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {1577VkMemoryDedicatedRequirements *req =1578(VkMemoryDedicatedRequirements *) ext;1579req->requiresDedicatedAllocation = false;1580req->prefersDedicatedAllocation = req->requiresDedicatedAllocation;1581break;1582}1583default:1584break;1585}1586}1587}15881589VKAPI_ATTR void VKAPI_CALL lvp_GetImageSparseMemoryRequirements(1590VkDevice device,1591VkImage image,1592uint32_t* pSparseMemoryRequirementCount,1593VkSparseImageMemoryRequirements* pSparseMemoryRequirements)1594{1595stub();1596}15971598VKAPI_ATTR void VKAPI_CALL lvp_GetImageSparseMemoryRequirements2(1599VkDevice device,1600const VkImageSparseMemoryRequirementsInfo2* pInfo,1601uint32_t* pSparseMemoryRequirementCount,1602VkSparseImageMemoryRequirements2* pSparseMemoryRequirements)1603{1604stub();1605}16061607VKAPI_ATTR void VKAPI_CALL lvp_GetDeviceMemoryCommitment(1608VkDevice device,1609VkDeviceMemory memory,1610VkDeviceSize* pCommittedMemoryInBytes)1611{1612*pCommittedMemoryInBytes = 0;1613}16141615VKAPI_ATTR VkResult VKAPI_CALL lvp_BindBufferMemory2(VkDevice _device,1616uint32_t bindInfoCount,1617const VkBindBufferMemoryInfo *pBindInfos)1618{1619LVP_FROM_HANDLE(lvp_device, device, _device);1620for (uint32_t i = 0; i < bindInfoCount; ++i) {1621LVP_FROM_HANDLE(lvp_device_memory, mem, pBindInfos[i].memory);1622LVP_FROM_HANDLE(lvp_buffer, buffer, pBindInfos[i].buffer);16231624buffer->pmem = mem->pmem;1625device->pscreen->resource_bind_backing(device->pscreen,1626buffer->bo,1627mem->pmem,1628pBindInfos[i].memoryOffset);1629}1630return VK_SUCCESS;1631}16321633VKAPI_ATTR VkResult VKAPI_CALL lvp_BindImageMemory2(VkDevice _device,1634uint32_t bindInfoCount,1635const VkBindImageMemoryInfo *pBindInfos)1636{1637LVP_FROM_HANDLE(lvp_device, device, _device);1638for (uint32_t i = 0; i < bindInfoCount; ++i) {1639const VkBindImageMemoryInfo *bind_info = &pBindInfos[i];1640LVP_FROM_HANDLE(lvp_device_memory, mem, bind_info->memory);1641LVP_FROM_HANDLE(lvp_image, image, bind_info->image);1642bool did_bind = false;16431644vk_foreach_struct_const(s, bind_info->pNext) {1645switch (s->sType) {1646case VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR: {1647const VkBindImageMemorySwapchainInfoKHR *swapchain_info =1648(const VkBindImageMemorySwapchainInfoKHR *) s;1649struct lvp_image *swapchain_image =1650lvp_swapchain_get_image(swapchain_info->swapchain,1651swapchain_info->imageIndex);16521653image->pmem = swapchain_image->pmem;1654image->memory_offset = swapchain_image->memory_offset;1655device->pscreen->resource_bind_backing(device->pscreen,1656image->bo,1657image->pmem,1658image->memory_offset);1659did_bind = true;1660}1661default:1662break;1663}1664}16651666if (!did_bind) {1667if (!device->pscreen->resource_bind_backing(device->pscreen,1668image->bo,1669mem->pmem,1670bind_info->memoryOffset)) {1671/* This is probably caused by the texture being too large, so let's1672* report this as the *closest* allowed error-code. It's not ideal,1673* but it's unlikely that anyone will care too much.1674*/1675return vk_error(device->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY);1676}1677image->pmem = mem->pmem;1678image->memory_offset = bind_info->memoryOffset;1679}1680}1681return VK_SUCCESS;1682}16831684VKAPI_ATTR VkResult VKAPI_CALL lvp_QueueBindSparse(1685VkQueue queue,1686uint32_t bindInfoCount,1687const VkBindSparseInfo* pBindInfo,1688VkFence fence)1689{1690stub_return(VK_ERROR_INCOMPATIBLE_DRIVER);1691}169216931694VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateFence(1695VkDevice _device,1696const VkFenceCreateInfo* pCreateInfo,1697const VkAllocationCallbacks* pAllocator,1698VkFence* pFence)1699{1700LVP_FROM_HANDLE(lvp_device, device, _device);1701struct lvp_fence *fence;17021703fence = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*fence), 8,1704VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);1705if (fence == NULL)1706return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);17071708vk_object_base_init(&device->vk, &fence->base, VK_OBJECT_TYPE_FENCE);1709fence->signaled = pCreateInfo->flags & VK_FENCE_CREATE_SIGNALED_BIT;17101711fence->handle = NULL;1712*pFence = lvp_fence_to_handle(fence);17131714return VK_SUCCESS;1715}17161717VKAPI_ATTR void VKAPI_CALL lvp_DestroyFence(1718VkDevice _device,1719VkFence _fence,1720const VkAllocationCallbacks* pAllocator)1721{1722LVP_FROM_HANDLE(lvp_device, device, _device);1723LVP_FROM_HANDLE(lvp_fence, fence, _fence);17241725if (!_fence)1726return;1727if (fence->handle)1728device->pscreen->fence_reference(device->pscreen, &fence->handle, NULL);17291730vk_object_base_finish(&fence->base);1731vk_free2(&device->vk.alloc, pAllocator, fence);1732}17331734VKAPI_ATTR VkResult VKAPI_CALL lvp_ResetFences(1735VkDevice _device,1736uint32_t fenceCount,1737const VkFence* pFences)1738{1739LVP_FROM_HANDLE(lvp_device, device, _device);1740for (unsigned i = 0; i < fenceCount; i++) {1741struct lvp_fence *fence = lvp_fence_from_handle(pFences[i]);17421743fence->signaled = false;17441745mtx_lock(&device->fence_lock);1746if (fence->handle)1747device->pscreen->fence_reference(device->pscreen, &fence->handle, NULL);1748mtx_unlock(&device->fence_lock);1749}1750return VK_SUCCESS;1751}17521753VKAPI_ATTR VkResult VKAPI_CALL lvp_GetFenceStatus(1754VkDevice _device,1755VkFence _fence)1756{1757LVP_FROM_HANDLE(lvp_device, device, _device);1758LVP_FROM_HANDLE(lvp_fence, fence, _fence);17591760if (fence->signaled)1761return VK_SUCCESS;17621763mtx_lock(&device->fence_lock);17641765if (!fence->handle) {1766mtx_unlock(&device->fence_lock);1767return VK_NOT_READY;1768}17691770bool signalled = device->pscreen->fence_finish(device->pscreen,1771NULL,1772fence->handle,17730);1774mtx_unlock(&device->fence_lock);1775if (signalled)1776return VK_SUCCESS;1777else1778return VK_NOT_READY;1779}17801781VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateFramebuffer(1782VkDevice _device,1783const VkFramebufferCreateInfo* pCreateInfo,1784const VkAllocationCallbacks* pAllocator,1785VkFramebuffer* pFramebuffer)1786{1787LVP_FROM_HANDLE(lvp_device, device, _device);1788struct lvp_framebuffer *framebuffer;1789const VkFramebufferAttachmentsCreateInfo *imageless_create_info =1790vk_find_struct_const(pCreateInfo->pNext,1791FRAMEBUFFER_ATTACHMENTS_CREATE_INFO);17921793assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO);17941795size_t size = sizeof(*framebuffer);17961797if (!imageless_create_info)1798size += sizeof(struct lvp_image_view *) * pCreateInfo->attachmentCount;1799framebuffer = vk_alloc2(&device->vk.alloc, pAllocator, size, 8,1800VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);1801if (framebuffer == NULL)1802return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);18031804vk_object_base_init(&device->vk, &framebuffer->base,1805VK_OBJECT_TYPE_FRAMEBUFFER);18061807if (!imageless_create_info) {1808framebuffer->attachment_count = pCreateInfo->attachmentCount;1809for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {1810VkImageView _iview = pCreateInfo->pAttachments[i];1811framebuffer->attachments[i] = lvp_image_view_from_handle(_iview);1812}1813}18141815framebuffer->width = pCreateInfo->width;1816framebuffer->height = pCreateInfo->height;1817framebuffer->layers = pCreateInfo->layers;1818framebuffer->imageless = !!imageless_create_info;18191820*pFramebuffer = lvp_framebuffer_to_handle(framebuffer);18211822return VK_SUCCESS;1823}18241825VKAPI_ATTR void VKAPI_CALL lvp_DestroyFramebuffer(1826VkDevice _device,1827VkFramebuffer _fb,1828const VkAllocationCallbacks* pAllocator)1829{1830LVP_FROM_HANDLE(lvp_device, device, _device);1831LVP_FROM_HANDLE(lvp_framebuffer, fb, _fb);18321833if (!fb)1834return;1835vk_object_base_finish(&fb->base);1836vk_free2(&device->vk.alloc, pAllocator, fb);1837}18381839VKAPI_ATTR VkResult VKAPI_CALL lvp_WaitForFences(1840VkDevice _device,1841uint32_t fenceCount,1842const VkFence* pFences,1843VkBool32 waitAll,1844uint64_t timeout)1845{1846LVP_FROM_HANDLE(lvp_device, device, _device);18471848VkResult qret = queue_wait_idle(&device->queue, timeout);1849bool timeout_status = false;1850if (qret == VK_TIMEOUT)1851return VK_TIMEOUT;18521853mtx_lock(&device->fence_lock);1854for (unsigned i = 0; i < fenceCount; i++) {1855struct lvp_fence *fence = lvp_fence_from_handle(pFences[i]);18561857if (fence->signaled)1858continue;1859if (!fence->handle) {1860timeout_status |= true;1861continue;1862}1863bool ret = device->pscreen->fence_finish(device->pscreen,1864NULL,1865fence->handle,1866timeout);1867if (ret && !waitAll) {1868timeout_status = false;1869break;1870}18711872if (!ret)1873timeout_status |= true;1874}1875mtx_unlock(&device->fence_lock);1876return timeout_status ? VK_TIMEOUT : VK_SUCCESS;1877}18781879VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateSemaphore(1880VkDevice _device,1881const VkSemaphoreCreateInfo* pCreateInfo,1882const VkAllocationCallbacks* pAllocator,1883VkSemaphore* pSemaphore)1884{1885LVP_FROM_HANDLE(lvp_device, device, _device);18861887struct lvp_semaphore *sema = vk_alloc2(&device->vk.alloc, pAllocator,1888sizeof(*sema), 8,1889VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);18901891if (!sema)1892return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);1893vk_object_base_init(&device->vk, &sema->base,1894VK_OBJECT_TYPE_SEMAPHORE);1895*pSemaphore = lvp_semaphore_to_handle(sema);18961897return VK_SUCCESS;1898}18991900VKAPI_ATTR void VKAPI_CALL lvp_DestroySemaphore(1901VkDevice _device,1902VkSemaphore _semaphore,1903const VkAllocationCallbacks* pAllocator)1904{1905LVP_FROM_HANDLE(lvp_device, device, _device);1906LVP_FROM_HANDLE(lvp_semaphore, semaphore, _semaphore);19071908if (!_semaphore)1909return;1910vk_object_base_finish(&semaphore->base);1911vk_free2(&device->vk.alloc, pAllocator, semaphore);1912}19131914VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateEvent(1915VkDevice _device,1916const VkEventCreateInfo* pCreateInfo,1917const VkAllocationCallbacks* pAllocator,1918VkEvent* pEvent)1919{1920LVP_FROM_HANDLE(lvp_device, device, _device);1921struct lvp_event *event = vk_alloc2(&device->vk.alloc, pAllocator,1922sizeof(*event), 8,1923VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);19241925if (!event)1926return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);19271928vk_object_base_init(&device->vk, &event->base, VK_OBJECT_TYPE_EVENT);1929*pEvent = lvp_event_to_handle(event);1930event->event_storage = 0;19311932return VK_SUCCESS;1933}19341935VKAPI_ATTR void VKAPI_CALL lvp_DestroyEvent(1936VkDevice _device,1937VkEvent _event,1938const VkAllocationCallbacks* pAllocator)1939{1940LVP_FROM_HANDLE(lvp_device, device, _device);1941LVP_FROM_HANDLE(lvp_event, event, _event);19421943if (!event)1944return;19451946vk_object_base_finish(&event->base);1947vk_free2(&device->vk.alloc, pAllocator, event);1948}19491950VKAPI_ATTR VkResult VKAPI_CALL lvp_GetEventStatus(1951VkDevice _device,1952VkEvent _event)1953{1954LVP_FROM_HANDLE(lvp_event, event, _event);1955if (event->event_storage == 1)1956return VK_EVENT_SET;1957return VK_EVENT_RESET;1958}19591960VKAPI_ATTR VkResult VKAPI_CALL lvp_SetEvent(1961VkDevice _device,1962VkEvent _event)1963{1964LVP_FROM_HANDLE(lvp_event, event, _event);1965event->event_storage = 1;19661967return VK_SUCCESS;1968}19691970VKAPI_ATTR VkResult VKAPI_CALL lvp_ResetEvent(1971VkDevice _device,1972VkEvent _event)1973{1974LVP_FROM_HANDLE(lvp_event, event, _event);1975event->event_storage = 0;19761977return VK_SUCCESS;1978}19791980VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateSampler(1981VkDevice _device,1982const VkSamplerCreateInfo* pCreateInfo,1983const VkAllocationCallbacks* pAllocator,1984VkSampler* pSampler)1985{1986LVP_FROM_HANDLE(lvp_device, device, _device);1987struct lvp_sampler *sampler;1988const VkSamplerReductionModeCreateInfo *reduction_mode_create_info =1989vk_find_struct_const(pCreateInfo->pNext,1990SAMPLER_REDUCTION_MODE_CREATE_INFO);1991const VkSamplerCustomBorderColorCreateInfoEXT *custom_border_color_create_info =1992vk_find_struct_const(pCreateInfo->pNext,1993SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT);19941995assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO);19961997sampler = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*sampler), 8,1998VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);1999if (!sampler)2000return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);20012002vk_object_base_init(&device->vk, &sampler->base,2003VK_OBJECT_TYPE_SAMPLER);2004sampler->create_info = *pCreateInfo;20052006switch (pCreateInfo->borderColor) {2007case VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK:2008case VK_BORDER_COLOR_INT_TRANSPARENT_BLACK:2009default:2010memset(&sampler->border_color, 0, sizeof(union pipe_color_union));2011break;2012case VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK:2013sampler->border_color.f[0] = sampler->border_color.f[1] =2014sampler->border_color.f[2] = 0.0f;2015sampler->border_color.f[3] = 1.0f;2016break;2017case VK_BORDER_COLOR_INT_OPAQUE_BLACK:2018sampler->border_color.i[0] = sampler->border_color.i[1] =2019sampler->border_color.i[2] = 0;2020sampler->border_color.i[3] = 1;2021break;2022case VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE:2023sampler->border_color.f[0] = sampler->border_color.f[1] =2024sampler->border_color.f[2] = 1.0f;2025sampler->border_color.f[3] = 1.0f;2026break;2027case VK_BORDER_COLOR_INT_OPAQUE_WHITE:2028sampler->border_color.i[0] = sampler->border_color.i[1] =2029sampler->border_color.i[2] = 1;2030sampler->border_color.i[3] = 1;2031break;2032case VK_BORDER_COLOR_FLOAT_CUSTOM_EXT:2033case VK_BORDER_COLOR_INT_CUSTOM_EXT:2034assert(custom_border_color_create_info != NULL);2035memcpy(&sampler->border_color,2036&custom_border_color_create_info->customBorderColor,2037sizeof(union pipe_color_union));2038break;2039}20402041sampler->reduction_mode = VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE;2042if (reduction_mode_create_info)2043sampler->reduction_mode = reduction_mode_create_info->reductionMode;20442045*pSampler = lvp_sampler_to_handle(sampler);20462047return VK_SUCCESS;2048}20492050VKAPI_ATTR void VKAPI_CALL lvp_DestroySampler(2051VkDevice _device,2052VkSampler _sampler,2053const VkAllocationCallbacks* pAllocator)2054{2055LVP_FROM_HANDLE(lvp_device, device, _device);2056LVP_FROM_HANDLE(lvp_sampler, sampler, _sampler);20572058if (!_sampler)2059return;2060vk_object_base_finish(&sampler->base);2061vk_free2(&device->vk.alloc, pAllocator, sampler);2062}20632064VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateSamplerYcbcrConversionKHR(2065VkDevice device,2066const VkSamplerYcbcrConversionCreateInfo* pCreateInfo,2067const VkAllocationCallbacks* pAllocator,2068VkSamplerYcbcrConversion* pYcbcrConversion)2069{2070return VK_ERROR_OUT_OF_HOST_MEMORY;2071}20722073VKAPI_ATTR void VKAPI_CALL lvp_DestroySamplerYcbcrConversionKHR(2074VkDevice device,2075VkSamplerYcbcrConversion ycbcrConversion,2076const VkAllocationCallbacks* pAllocator)2077{2078}20792080/* vk_icd.h does not declare this function, so we declare it here to2081* suppress Wmissing-prototypes.2082*/2083PUBLIC VKAPI_ATTR VkResult VKAPI_CALL2084vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion);20852086PUBLIC VKAPI_ATTR VkResult VKAPI_CALL2087vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion)2088{2089/* For the full details on loader interface versioning, see2090* <https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/blob/master/loader/LoaderAndLayerInterface.md>.2091* What follows is a condensed summary, to help you navigate the large and2092* confusing official doc.2093*2094* - Loader interface v0 is incompatible with later versions. We don't2095* support it.2096*2097* - In loader interface v1:2098* - The first ICD entrypoint called by the loader is2099* vk_icdGetInstanceProcAddr(). The ICD must statically expose this2100* entrypoint.2101* - The ICD must statically expose no other Vulkan symbol unless it is2102* linked with -Bsymbolic.2103* - Each dispatchable Vulkan handle created by the ICD must be2104* a pointer to a struct whose first member is VK_LOADER_DATA. The2105* ICD must initialize VK_LOADER_DATA.loadMagic to ICD_LOADER_MAGIC.2106* - The loader implements vkCreate{PLATFORM}SurfaceKHR() and2107* vkDestroySurfaceKHR(). The ICD must be capable of working with2108* such loader-managed surfaces.2109*2110* - Loader interface v2 differs from v1 in:2111* - The first ICD entrypoint called by the loader is2112* vk_icdNegotiateLoaderICDInterfaceVersion(). The ICD must2113* statically expose this entrypoint.2114*2115* - Loader interface v3 differs from v2 in:2116* - The ICD must implement vkCreate{PLATFORM}SurfaceKHR(),2117* vkDestroySurfaceKHR(), and other API which uses VKSurfaceKHR,2118* because the loader no longer does so.2119*2120* - Loader interface v4 differs from v3 in:2121* - The ICD must implement vk_icdGetPhysicalDeviceProcAddr().2122*/2123*pSupportedVersion = MIN2(*pSupportedVersion, 4u);2124return VK_SUCCESS;2125}21262127VKAPI_ATTR VkResult VKAPI_CALL lvp_CreatePrivateDataSlotEXT(2128VkDevice _device,2129const VkPrivateDataSlotCreateInfoEXT* pCreateInfo,2130const VkAllocationCallbacks* pAllocator,2131VkPrivateDataSlotEXT* pPrivateDataSlot)2132{2133LVP_FROM_HANDLE(lvp_device, device, _device);2134return vk_private_data_slot_create(&device->vk, pCreateInfo, pAllocator,2135pPrivateDataSlot);2136}21372138VKAPI_ATTR void VKAPI_CALL lvp_DestroyPrivateDataSlotEXT(2139VkDevice _device,2140VkPrivateDataSlotEXT privateDataSlot,2141const VkAllocationCallbacks* pAllocator)2142{2143LVP_FROM_HANDLE(lvp_device, device, _device);2144vk_private_data_slot_destroy(&device->vk, privateDataSlot, pAllocator);2145}21462147VKAPI_ATTR VkResult VKAPI_CALL lvp_SetPrivateDataEXT(2148VkDevice _device,2149VkObjectType objectType,2150uint64_t objectHandle,2151VkPrivateDataSlotEXT privateDataSlot,2152uint64_t data)2153{2154LVP_FROM_HANDLE(lvp_device, device, _device);2155return vk_object_base_set_private_data(&device->vk, objectType,2156objectHandle, privateDataSlot,2157data);2158}21592160VKAPI_ATTR void VKAPI_CALL lvp_GetPrivateDataEXT(2161VkDevice _device,2162VkObjectType objectType,2163uint64_t objectHandle,2164VkPrivateDataSlotEXT privateDataSlot,2165uint64_t* pData)2166{2167LVP_FROM_HANDLE(lvp_device, device, _device);2168vk_object_base_get_private_data(&device->vk, objectType, objectHandle,2169privateDataSlot, pData);2170}21712172VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceExternalFenceProperties(2173VkPhysicalDevice physicalDevice,2174const VkPhysicalDeviceExternalFenceInfo *pExternalFenceInfo,2175VkExternalFenceProperties *pExternalFenceProperties)2176{2177pExternalFenceProperties->exportFromImportedHandleTypes = 0;2178pExternalFenceProperties->compatibleHandleTypes = 0;2179pExternalFenceProperties->externalFenceFeatures = 0;2180}21812182VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceExternalSemaphoreProperties(2183VkPhysicalDevice physicalDevice,2184const VkPhysicalDeviceExternalSemaphoreInfo *pExternalSemaphoreInfo,2185VkExternalSemaphoreProperties *pExternalSemaphoreProperties)2186{2187pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0;2188pExternalSemaphoreProperties->compatibleHandleTypes = 0;2189pExternalSemaphoreProperties->externalSemaphoreFeatures = 0;2190}21912192static const VkTimeDomainEXT lvp_time_domains[] = {2193VK_TIME_DOMAIN_DEVICE_EXT,2194VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT,2195};21962197VKAPI_ATTR VkResult VKAPI_CALL lvp_GetPhysicalDeviceCalibrateableTimeDomainsEXT(2198VkPhysicalDevice physicalDevice,2199uint32_t *pTimeDomainCount,2200VkTimeDomainEXT *pTimeDomains)2201{2202int d;2203VK_OUTARRAY_MAKE_TYPED(VkTimeDomainEXT, out, pTimeDomains,2204pTimeDomainCount);22052206for (d = 0; d < ARRAY_SIZE(lvp_time_domains); d++) {2207vk_outarray_append_typed(VkTimeDomainEXT, &out, i) {2208*i = lvp_time_domains[d];2209}2210}22112212return vk_outarray_status(&out);2213}22142215VKAPI_ATTR VkResult VKAPI_CALL lvp_GetCalibratedTimestampsEXT(2216VkDevice device,2217uint32_t timestampCount,2218const VkCalibratedTimestampInfoEXT *pTimestampInfos,2219uint64_t *pTimestamps,2220uint64_t *pMaxDeviation)2221{2222*pMaxDeviation = 1;22232224uint64_t now = os_time_get_nano();2225for (unsigned i = 0; i < timestampCount; i++) {2226pTimestamps[i] = now;2227}2228return VK_SUCCESS;2229}22302231VKAPI_ATTR void VKAPI_CALL lvp_GetDeviceGroupPeerMemoryFeaturesKHR(2232VkDevice device,2233uint32_t heapIndex,2234uint32_t localDeviceIndex,2235uint32_t remoteDeviceIndex,2236VkPeerMemoryFeatureFlags *pPeerMemoryFeatures)2237{2238*pPeerMemoryFeatures = 0;2239}224022412242