Path: blob/21.2-virgl/src/virtio/vulkan/vn_device.c
4560 views
/*1* Copyright 2019 Google LLC2* SPDX-License-Identifier: MIT3*4* based in part on anv and radv which are:5* Copyright © 2015 Intel Corporation6* Copyright © 2016 Red Hat.7* Copyright © 2016 Bas Nieuwenhuizen8*/910#include "vn_device.h"1112#include <stdio.h>1314#include "git_sha1.h"15#include "util/driconf.h"16#include "util/mesa-sha1.h"17#include "venus-protocol/vn_protocol_driver_device.h"18#include "venus-protocol/vn_protocol_driver_info.h"19#include "venus-protocol/vn_protocol_driver_instance.h"20#include "venus-protocol/vn_protocol_driver_transport.h"2122#include "vn_android.h"23#include "vn_device_memory.h"24#include "vn_icd.h"25#include "vn_queue.h"26#include "vn_renderer.h"2728/* require and request at least Vulkan 1.1 at both instance and device levels29*/30#define VN_MIN_RENDERER_VERSION VK_API_VERSION_1_13132/* max advertised version at both instance and device levels */33#ifdef ANDROID34#define VN_MAX_API_VERSION VK_MAKE_VERSION(1, 1, VK_HEADER_VERSION)35#else36#define VN_MAX_API_VERSION VK_MAKE_VERSION(1, 2, VK_HEADER_VERSION)37#endif3839#define VN_EXTENSION_TABLE_INDEX(tbl, ext) \40((const bool *)((const void *)(&(tbl)) + \41offsetof(__typeof__(tbl), ext)) - \42(tbl).extensions)4344/*45* Instance extensions add instance-level or physical-device-level46* functionalities. It seems renderer support is either unnecessary or47* optional. We should be able to advertise them or lie about them locally.48*/49static const struct vk_instance_extension_table50vn_instance_supported_extensions = {51/* promoted to VK_VERSION_1_1 */52.KHR_device_group_creation = true,53.KHR_external_fence_capabilities = true,54.KHR_external_memory_capabilities = true,55.KHR_external_semaphore_capabilities = true,56.KHR_get_physical_device_properties2 = true,5758#ifdef VN_USE_WSI_PLATFORM59.KHR_get_surface_capabilities2 = true,60.KHR_surface = true,61.KHR_surface_protected_capabilities = true,62#endif63#ifdef VK_USE_PLATFORM_WAYLAND_KHR64.KHR_wayland_surface = true,65#endif66#ifdef VK_USE_PLATFORM_XCB_KHR67.KHR_xcb_surface = true,68#endif69#ifdef VK_USE_PLATFORM_XLIB_KHR70.KHR_xlib_surface = true,71#endif72};7374static const driOptionDescription vn_dri_options[] = {75/* clang-format off */76DRI_CONF_SECTION_PERFORMANCE77DRI_CONF_VK_X11_ENSURE_MIN_IMAGE_COUNT(false)78DRI_CONF_VK_X11_OVERRIDE_MIN_IMAGE_COUNT(0)79DRI_CONF_VK_X11_STRICT_IMAGE_COUNT(false)80DRI_CONF_SECTION_END81DRI_CONF_SECTION_DEBUG82DRI_CONF_VK_WSI_FORCE_BGRA8_UNORM_FIRST(false)83DRI_CONF_SECTION_END84/* clang-format on */85};8687static VkResult88vn_instance_init_renderer_versions(struct vn_instance *instance)89{90uint32_t instance_version = 0;91VkResult result =92vn_call_vkEnumerateInstanceVersion(instance, &instance_version);93if (result != VK_SUCCESS) {94if (VN_DEBUG(INIT))95vn_log(instance, "failed to enumerate renderer instance version");96return result;97}9899if (instance_version < VN_MIN_RENDERER_VERSION) {100if (VN_DEBUG(INIT)) {101vn_log(instance, "unsupported renderer instance version %d.%d",102VK_VERSION_MAJOR(instance_version),103VK_VERSION_MINOR(instance_version));104}105return VK_ERROR_INITIALIZATION_FAILED;106}107108if (VN_DEBUG(INIT)) {109vn_log(instance, "renderer instance version %d.%d.%d",110VK_VERSION_MAJOR(instance_version),111VK_VERSION_MINOR(instance_version),112VK_VERSION_PATCH(instance_version));113}114115/* request at least VN_MIN_RENDERER_VERSION internally */116instance->renderer_api_version =117MAX2(instance->base.base.app_info.api_version, VN_MIN_RENDERER_VERSION);118119/* instance version for internal use is capped */120instance_version = MIN3(instance_version, instance->renderer_api_version,121instance->renderer_info.vk_xml_version);122assert(instance_version >= VN_MIN_RENDERER_VERSION);123124instance->renderer_version = instance_version;125126return VK_SUCCESS;127}128129static VkResult130vn_instance_init_ring(struct vn_instance *instance)131{132/* 32-bit seqno for renderer roundtrips */133const size_t extra_size = sizeof(uint32_t);134struct vn_ring_layout layout;135vn_ring_get_layout(extra_size, &layout);136137instance->ring.shmem =138vn_renderer_shmem_create(instance->renderer, layout.shmem_size);139if (!instance->ring.shmem) {140if (VN_DEBUG(INIT))141vn_log(instance, "failed to allocate/map ring shmem");142return VK_ERROR_OUT_OF_HOST_MEMORY;143}144145mtx_init(&instance->ring.mutex, mtx_plain);146147struct vn_ring *ring = &instance->ring.ring;148vn_ring_init(ring, instance->renderer, &layout,149instance->ring.shmem->mmap_ptr);150151instance->ring.id = (uintptr_t)ring;152153const struct VkRingCreateInfoMESA info = {154.sType = VK_STRUCTURE_TYPE_RING_CREATE_INFO_MESA,155.resourceId = instance->ring.shmem->res_id,156.size = layout.shmem_size,157.idleTimeout = 50ull * 1000 * 1000,158.headOffset = layout.head_offset,159.tailOffset = layout.tail_offset,160.statusOffset = layout.status_offset,161.bufferOffset = layout.buffer_offset,162.bufferSize = layout.buffer_size,163.extraOffset = layout.extra_offset,164.extraSize = layout.extra_size,165};166167uint32_t create_ring_data[64];168struct vn_cs_encoder local_enc = VN_CS_ENCODER_INITIALIZER_LOCAL(169create_ring_data, sizeof(create_ring_data));170vn_encode_vkCreateRingMESA(&local_enc, 0, instance->ring.id, &info);171vn_renderer_submit_simple(instance->renderer, create_ring_data,172vn_cs_encoder_get_len(&local_enc));173174vn_cs_encoder_init_indirect(&instance->ring.upload, instance,1751 * 1024 * 1024);176177return VK_SUCCESS;178}179180static void181vn_instance_init_experimental_features(struct vn_instance *instance)182{183if (instance->renderer_info.vk_mesa_venus_protocol_spec_version !=184100000) {185if (VN_DEBUG(INIT))186vn_log(instance, "renderer supports no experimental features");187return;188}189190size_t size = sizeof(instance->experimental);191vn_call_vkGetVenusExperimentalFeatureData100000MESA(192instance, &size, &instance->experimental);193if (VN_DEBUG(INIT)) {194vn_log(instance,195"VkVenusExperimentalFeatures100000MESA is as below:"196"\n\tmemoryResourceAllocationSize = %u"197"\n\tglobalFencing = %u",198instance->experimental.memoryResourceAllocationSize,199instance->experimental.globalFencing);200}201}202203static VkResult204vn_instance_init_renderer(struct vn_instance *instance)205{206const VkAllocationCallbacks *alloc = &instance->base.base.alloc;207208VkResult result = vn_renderer_create(instance, alloc, &instance->renderer);209if (result != VK_SUCCESS)210return result;211212mtx_init(&instance->roundtrip_mutex, mtx_plain);213instance->roundtrip_next = 1;214215vn_renderer_get_info(instance->renderer, &instance->renderer_info);216217uint32_t version = vn_info_wire_format_version();218if (instance->renderer_info.wire_format_version != version) {219if (VN_DEBUG(INIT)) {220vn_log(instance, "wire format version %d != %d",221instance->renderer_info.wire_format_version, version);222}223return VK_ERROR_INITIALIZATION_FAILED;224}225226version = vn_info_vk_xml_version();227if (instance->renderer_info.vk_xml_version > version)228instance->renderer_info.vk_xml_version = version;229if (instance->renderer_info.vk_xml_version < VN_MIN_RENDERER_VERSION) {230if (VN_DEBUG(INIT)) {231vn_log(instance, "vk xml version %d.%d.%d < %d.%d.%d",232VK_VERSION_MAJOR(instance->renderer_info.vk_xml_version),233VK_VERSION_MINOR(instance->renderer_info.vk_xml_version),234VK_VERSION_PATCH(instance->renderer_info.vk_xml_version),235VK_VERSION_MAJOR(VN_MIN_RENDERER_VERSION),236VK_VERSION_MINOR(VN_MIN_RENDERER_VERSION),237VK_VERSION_PATCH(VN_MIN_RENDERER_VERSION));238}239return VK_ERROR_INITIALIZATION_FAILED;240}241242version = vn_info_extension_spec_version("VK_EXT_command_serialization");243if (instance->renderer_info.vk_ext_command_serialization_spec_version >244version) {245instance->renderer_info.vk_ext_command_serialization_spec_version =246version;247}248249version = vn_info_extension_spec_version("VK_MESA_venus_protocol");250if (instance->renderer_info.vk_mesa_venus_protocol_spec_version >251version) {252instance->renderer_info.vk_mesa_venus_protocol_spec_version = version;253}254255if (VN_DEBUG(INIT)) {256vn_log(instance, "connected to renderer");257vn_log(instance, "wire format version %d",258instance->renderer_info.wire_format_version);259vn_log(instance, "vk xml version %d.%d.%d",260VK_VERSION_MAJOR(instance->renderer_info.vk_xml_version),261VK_VERSION_MINOR(instance->renderer_info.vk_xml_version),262VK_VERSION_PATCH(instance->renderer_info.vk_xml_version));263vn_log(264instance, "VK_EXT_command_serialization spec version %d",265instance->renderer_info.vk_ext_command_serialization_spec_version);266vn_log(instance, "VK_MESA_venus_protocol spec version %d",267instance->renderer_info.vk_mesa_venus_protocol_spec_version);268}269270return VK_SUCCESS;271}272273VkResult274vn_instance_submit_roundtrip(struct vn_instance *instance,275uint32_t *roundtrip_seqno)276{277uint32_t write_ring_extra_data[8];278struct vn_cs_encoder local_enc = VN_CS_ENCODER_INITIALIZER_LOCAL(279write_ring_extra_data, sizeof(write_ring_extra_data));280281/* submit a vkWriteRingExtraMESA through the renderer */282mtx_lock(&instance->roundtrip_mutex);283const uint32_t seqno = instance->roundtrip_next++;284vn_encode_vkWriteRingExtraMESA(&local_enc, 0, instance->ring.id, 0, seqno);285VkResult result =286vn_renderer_submit_simple(instance->renderer, write_ring_extra_data,287vn_cs_encoder_get_len(&local_enc));288mtx_unlock(&instance->roundtrip_mutex);289290*roundtrip_seqno = seqno;291return result;292}293294void295vn_instance_wait_roundtrip(struct vn_instance *instance,296uint32_t roundtrip_seqno)297{298const struct vn_ring *ring = &instance->ring.ring;299const volatile atomic_uint *ptr = ring->shared.extra;300uint32_t iter = 0;301do {302const uint32_t cur = atomic_load_explicit(ptr, memory_order_acquire);303if (cur >= roundtrip_seqno || roundtrip_seqno - cur >= INT32_MAX)304break;305vn_relax(&iter);306} while (true);307}308309struct vn_instance_submission {310uint32_t local_cs_data[64];311312void *cs_data;313size_t cs_size;314struct vn_ring_submit *submit;315};316317static void *318vn_instance_submission_indirect_cs(struct vn_instance_submission *submit,319const struct vn_cs_encoder *cs,320size_t *cs_size)321{322VkCommandStreamDescriptionMESA local_descs[8];323VkCommandStreamDescriptionMESA *descs = local_descs;324if (cs->buffer_count > ARRAY_SIZE(local_descs)) {325descs =326malloc(sizeof(VkCommandStreamDescriptionMESA) * cs->buffer_count);327if (!descs)328return NULL;329}330331uint32_t desc_count = 0;332for (uint32_t i = 0; i < cs->buffer_count; i++) {333const struct vn_cs_encoder_buffer *buf = &cs->buffers[i];334if (buf->committed_size) {335descs[desc_count++] = (VkCommandStreamDescriptionMESA){336.resourceId = buf->shmem->res_id,337.offset = buf->offset,338.size = buf->committed_size,339};340}341}342343const size_t exec_size = vn_sizeof_vkExecuteCommandStreamsMESA(344desc_count, descs, NULL, 0, NULL, 0);345void *exec_data = submit->local_cs_data;346if (exec_size > sizeof(submit->local_cs_data)) {347exec_data = malloc(exec_size);348if (!exec_data)349goto out;350}351352struct vn_cs_encoder local_enc =353VN_CS_ENCODER_INITIALIZER_LOCAL(exec_data, exec_size);354vn_encode_vkExecuteCommandStreamsMESA(&local_enc, 0, desc_count, descs,355NULL, 0, NULL, 0);356357*cs_size = vn_cs_encoder_get_len(&local_enc);358359out:360if (descs != local_descs)361free(descs);362363return exec_data;364}365366static void *367vn_instance_submission_direct_cs(struct vn_instance_submission *submit,368const struct vn_cs_encoder *cs,369size_t *cs_size)370{371if (cs->buffer_count == 1) {372*cs_size = cs->buffers[0].committed_size;373return cs->buffers[0].base;374}375376assert(vn_cs_encoder_get_len(cs) <= sizeof(submit->local_cs_data));377void *dst = submit->local_cs_data;378for (uint32_t i = 0; i < cs->buffer_count; i++) {379const struct vn_cs_encoder_buffer *buf = &cs->buffers[i];380memcpy(dst, buf->base, buf->committed_size);381dst += buf->committed_size;382}383384*cs_size = dst - (void *)submit->local_cs_data;385return submit->local_cs_data;386}387388static struct vn_ring_submit *389vn_instance_submission_get_ring_submit(struct vn_ring *ring,390const struct vn_cs_encoder *cs,391struct vn_renderer_shmem *extra_shmem,392bool direct)393{394const uint32_t shmem_count =395(direct ? 0 : cs->buffer_count) + (extra_shmem ? 1 : 0);396struct vn_ring_submit *submit = vn_ring_get_submit(ring, shmem_count);397if (!submit)398return NULL;399400submit->shmem_count = shmem_count;401if (!direct) {402for (uint32_t i = 0; i < cs->buffer_count; i++) {403submit->shmems[i] =404vn_renderer_shmem_ref(ring->renderer, cs->buffers[i].shmem);405}406}407if (extra_shmem) {408submit->shmems[shmem_count - 1] =409vn_renderer_shmem_ref(ring->renderer, extra_shmem);410}411412return submit;413}414415static void416vn_instance_submission_cleanup(struct vn_instance_submission *submit,417const struct vn_cs_encoder *cs)418{419if (submit->cs_data != submit->local_cs_data &&420submit->cs_data != cs->buffers[0].base)421free(submit->cs_data);422}423424static VkResult425vn_instance_submission_prepare(struct vn_instance_submission *submit,426const struct vn_cs_encoder *cs,427struct vn_ring *ring,428struct vn_renderer_shmem *extra_shmem,429bool direct)430{431if (direct) {432submit->cs_data =433vn_instance_submission_direct_cs(submit, cs, &submit->cs_size);434} else {435submit->cs_data =436vn_instance_submission_indirect_cs(submit, cs, &submit->cs_size);437}438if (!submit->cs_data)439return VK_ERROR_OUT_OF_HOST_MEMORY;440441submit->submit =442vn_instance_submission_get_ring_submit(ring, cs, extra_shmem, direct);443if (!submit->submit) {444vn_instance_submission_cleanup(submit, cs);445return VK_ERROR_OUT_OF_HOST_MEMORY;446}447448return VK_SUCCESS;449}450451static bool452vn_instance_submission_can_direct(const struct vn_cs_encoder *cs)453{454struct vn_instance_submission submit;455return vn_cs_encoder_get_len(cs) <= sizeof(submit.local_cs_data);456}457458static struct vn_cs_encoder *459vn_instance_ring_cs_upload_locked(struct vn_instance *instance,460const struct vn_cs_encoder *cs)461{462assert(!cs->indirect && cs->buffer_count == 1);463const void *cs_data = cs->buffers[0].base;464const size_t cs_size = cs->total_committed_size;465assert(cs_size == vn_cs_encoder_get_len(cs));466467struct vn_cs_encoder *upload = &instance->ring.upload;468vn_cs_encoder_reset(upload);469470if (!vn_cs_encoder_reserve(upload, cs_size))471return NULL;472473vn_cs_encoder_write(upload, cs_size, cs_data, cs_size);474vn_cs_encoder_commit(upload);475vn_instance_wait_roundtrip(instance, upload->current_buffer_roundtrip);476477return upload;478}479480static VkResult481vn_instance_ring_submit_locked(struct vn_instance *instance,482const struct vn_cs_encoder *cs,483struct vn_renderer_shmem *extra_shmem,484uint32_t *ring_seqno)485{486struct vn_ring *ring = &instance->ring.ring;487488const bool direct = vn_instance_submission_can_direct(cs);489if (!direct && !cs->indirect) {490cs = vn_instance_ring_cs_upload_locked(instance, cs);491if (!cs)492return VK_ERROR_OUT_OF_HOST_MEMORY;493assert(cs->indirect);494}495496struct vn_instance_submission submit;497VkResult result =498vn_instance_submission_prepare(&submit, cs, ring, extra_shmem, direct);499if (result != VK_SUCCESS)500return result;501502uint32_t seqno;503const bool notify = vn_ring_submit(ring, submit.submit, submit.cs_data,504submit.cs_size, &seqno);505if (notify) {506uint32_t notify_ring_data[8];507struct vn_cs_encoder local_enc = VN_CS_ENCODER_INITIALIZER_LOCAL(508notify_ring_data, sizeof(notify_ring_data));509vn_encode_vkNotifyRingMESA(&local_enc, 0, instance->ring.id, seqno, 0);510vn_renderer_submit_simple(instance->renderer, notify_ring_data,511vn_cs_encoder_get_len(&local_enc));512}513514vn_instance_submission_cleanup(&submit, cs);515516if (ring_seqno)517*ring_seqno = seqno;518519return VK_SUCCESS;520}521522VkResult523vn_instance_ring_submit(struct vn_instance *instance,524const struct vn_cs_encoder *cs)525{526mtx_lock(&instance->ring.mutex);527VkResult result = vn_instance_ring_submit_locked(instance, cs, NULL, NULL);528mtx_unlock(&instance->ring.mutex);529530return result;531}532533static bool534vn_instance_grow_reply_shmem_locked(struct vn_instance *instance, size_t size)535{536const size_t min_shmem_size = 1 << 20;537538size_t shmem_size =539instance->reply.size ? instance->reply.size : min_shmem_size;540while (shmem_size < size) {541shmem_size <<= 1;542if (!shmem_size)543return false;544}545546struct vn_renderer_shmem *shmem =547vn_renderer_shmem_create(instance->renderer, shmem_size);548if (!shmem)549return false;550551if (instance->reply.shmem)552vn_renderer_shmem_unref(instance->renderer, instance->reply.shmem);553instance->reply.shmem = shmem;554instance->reply.size = shmem_size;555instance->reply.used = 0;556instance->reply.ptr = shmem->mmap_ptr;557558return true;559}560561static struct vn_renderer_shmem *562vn_instance_get_reply_shmem_locked(struct vn_instance *instance,563size_t size,564void **ptr)565{566if (unlikely(instance->reply.used + size > instance->reply.size)) {567if (!vn_instance_grow_reply_shmem_locked(instance, size))568return NULL;569570uint32_t set_reply_command_stream_data[16];571struct vn_cs_encoder local_enc = VN_CS_ENCODER_INITIALIZER_LOCAL(572set_reply_command_stream_data,573sizeof(set_reply_command_stream_data));574const struct VkCommandStreamDescriptionMESA stream = {575.resourceId = instance->reply.shmem->res_id,576.size = instance->reply.size,577};578vn_encode_vkSetReplyCommandStreamMESA(&local_enc, 0, &stream);579vn_cs_encoder_commit(&local_enc);580581vn_instance_roundtrip(instance);582vn_instance_ring_submit_locked(instance, &local_enc, NULL, NULL);583}584585/* TODO avoid this seek command and go lock-free? */586uint32_t seek_reply_command_stream_data[8];587struct vn_cs_encoder local_enc = VN_CS_ENCODER_INITIALIZER_LOCAL(588seek_reply_command_stream_data, sizeof(seek_reply_command_stream_data));589const size_t offset = instance->reply.used;590vn_encode_vkSeekReplyCommandStreamMESA(&local_enc, 0, offset);591vn_cs_encoder_commit(&local_enc);592vn_instance_ring_submit_locked(instance, &local_enc, NULL, NULL);593594*ptr = instance->reply.ptr + offset;595instance->reply.used += size;596597return vn_renderer_shmem_ref(instance->renderer, instance->reply.shmem);598}599600void601vn_instance_submit_command(struct vn_instance *instance,602struct vn_instance_submit_command *submit)603{604void *reply_ptr = NULL;605submit->reply_shmem = NULL;606607mtx_lock(&instance->ring.mutex);608609if (vn_cs_encoder_is_empty(&submit->command))610goto fail;611vn_cs_encoder_commit(&submit->command);612613if (submit->reply_size) {614submit->reply_shmem = vn_instance_get_reply_shmem_locked(615instance, submit->reply_size, &reply_ptr);616if (!submit->reply_shmem)617goto fail;618}619620uint32_t ring_seqno;621VkResult result = vn_instance_ring_submit_locked(622instance, &submit->command, submit->reply_shmem, &ring_seqno);623624mtx_unlock(&instance->ring.mutex);625626submit->reply = VN_CS_DECODER_INITIALIZER(reply_ptr, submit->reply_size);627628if (submit->reply_size && result == VK_SUCCESS)629vn_ring_wait(&instance->ring.ring, ring_seqno);630631return;632633fail:634instance->ring.command_dropped++;635mtx_unlock(&instance->ring.mutex);636}637638static struct vn_physical_device *639vn_instance_find_physical_device(struct vn_instance *instance,640vn_object_id id)641{642for (uint32_t i = 0; i < instance->physical_device_count; i++) {643if (instance->physical_devices[i].base.id == id)644return &instance->physical_devices[i];645}646return NULL;647}648649static void650vn_physical_device_init_features(struct vn_physical_device *physical_dev)651{652struct vn_instance *instance = physical_dev->instance;653struct {654/* Vulkan 1.1 */655VkPhysicalDevice16BitStorageFeatures sixteen_bit_storage;656VkPhysicalDeviceMultiviewFeatures multiview;657VkPhysicalDeviceVariablePointersFeatures variable_pointers;658VkPhysicalDeviceProtectedMemoryFeatures protected_memory;659VkPhysicalDeviceSamplerYcbcrConversionFeatures sampler_ycbcr_conversion;660VkPhysicalDeviceShaderDrawParametersFeatures shader_draw_parameters;661662/* Vulkan 1.2 */663VkPhysicalDevice8BitStorageFeatures eight_bit_storage;664VkPhysicalDeviceShaderAtomicInt64Features shader_atomic_int64;665VkPhysicalDeviceShaderFloat16Int8Features shader_float16_int8;666VkPhysicalDeviceDescriptorIndexingFeatures descriptor_indexing;667VkPhysicalDeviceScalarBlockLayoutFeatures scalar_block_layout;668VkPhysicalDeviceImagelessFramebufferFeatures imageless_framebuffer;669VkPhysicalDeviceUniformBufferStandardLayoutFeatures670uniform_buffer_standard_layout;671VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures672shader_subgroup_extended_types;673VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures674separate_depth_stencil_layouts;675VkPhysicalDeviceHostQueryResetFeatures host_query_reset;676VkPhysicalDeviceTimelineSemaphoreFeatures timeline_semaphore;677VkPhysicalDeviceBufferDeviceAddressFeatures buffer_device_address;678VkPhysicalDeviceVulkanMemoryModelFeatures vulkan_memory_model;679} local_feats;680681physical_dev->features.sType =682VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;683if (physical_dev->renderer_version >= VK_API_VERSION_1_2) {684physical_dev->features.pNext = &physical_dev->vulkan_1_1_features;685686physical_dev->vulkan_1_1_features.sType =687VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;688physical_dev->vulkan_1_1_features.pNext =689&physical_dev->vulkan_1_2_features;690physical_dev->vulkan_1_2_features.sType =691VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;692physical_dev->vulkan_1_2_features.pNext = NULL;693} else {694physical_dev->features.pNext = &local_feats.sixteen_bit_storage;695696local_feats.sixteen_bit_storage.sType =697VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES;698local_feats.sixteen_bit_storage.pNext = &local_feats.multiview;699local_feats.multiview.sType =700VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES;701local_feats.multiview.pNext = &local_feats.variable_pointers;702local_feats.variable_pointers.sType =703VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES;704local_feats.variable_pointers.pNext = &local_feats.protected_memory;705local_feats.protected_memory.sType =706VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES;707local_feats.protected_memory.pNext =708&local_feats.sampler_ycbcr_conversion;709local_feats.sampler_ycbcr_conversion.sType =710VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES;711local_feats.sampler_ycbcr_conversion.pNext =712&local_feats.shader_draw_parameters;713local_feats.shader_draw_parameters.sType =714VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES;715local_feats.shader_draw_parameters.pNext =716&local_feats.eight_bit_storage;717718local_feats.eight_bit_storage.sType =719VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES;720local_feats.eight_bit_storage.pNext = &local_feats.shader_atomic_int64;721local_feats.shader_atomic_int64.sType =722VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES;723local_feats.shader_atomic_int64.pNext =724&local_feats.shader_float16_int8;725local_feats.shader_float16_int8.sType =726VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES;727local_feats.shader_float16_int8.pNext =728&local_feats.descriptor_indexing;729local_feats.descriptor_indexing.sType =730VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES;731local_feats.descriptor_indexing.pNext =732&local_feats.scalar_block_layout;733local_feats.scalar_block_layout.sType =734VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES;735local_feats.scalar_block_layout.pNext =736&local_feats.imageless_framebuffer;737local_feats.imageless_framebuffer.sType =738VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES;739local_feats.imageless_framebuffer.pNext =740&local_feats.uniform_buffer_standard_layout;741local_feats.uniform_buffer_standard_layout.sType =742VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES;743local_feats.uniform_buffer_standard_layout.pNext =744&local_feats.shader_subgroup_extended_types;745local_feats.shader_subgroup_extended_types.sType =746VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES;747local_feats.shader_subgroup_extended_types.pNext =748&local_feats.separate_depth_stencil_layouts;749local_feats.separate_depth_stencil_layouts.sType =750VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES;751local_feats.separate_depth_stencil_layouts.pNext =752&local_feats.host_query_reset;753local_feats.host_query_reset.sType =754VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES;755local_feats.host_query_reset.pNext = &local_feats.timeline_semaphore;756local_feats.timeline_semaphore.sType =757VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES;758local_feats.timeline_semaphore.pNext =759&local_feats.buffer_device_address;760local_feats.buffer_device_address.sType =761VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES;762local_feats.buffer_device_address.pNext =763&local_feats.vulkan_memory_model;764local_feats.vulkan_memory_model.sType =765VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES;766local_feats.vulkan_memory_model.pNext = NULL;767}768769if (physical_dev->renderer_extensions.EXT_transform_feedback) {770physical_dev->transform_feedback_features.sType =771VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT;772physical_dev->transform_feedback_features.pNext =773physical_dev->features.pNext;774physical_dev->features.pNext =775&physical_dev->transform_feedback_features;776}777778vn_call_vkGetPhysicalDeviceFeatures2(779instance, vn_physical_device_to_handle(physical_dev),780&physical_dev->features);781782const struct vk_device_extension_table *exts =783&physical_dev->renderer_extensions;784struct VkPhysicalDeviceVulkan11Features *vk11_feats =785&physical_dev->vulkan_1_1_features;786struct VkPhysicalDeviceVulkan12Features *vk12_feats =787&physical_dev->vulkan_1_2_features;788789if (physical_dev->renderer_version < VK_API_VERSION_1_2) {790vk11_feats->storageBuffer16BitAccess =791local_feats.sixteen_bit_storage.storageBuffer16BitAccess;792vk11_feats->uniformAndStorageBuffer16BitAccess =793local_feats.sixteen_bit_storage.uniformAndStorageBuffer16BitAccess;794vk11_feats->storagePushConstant16 =795local_feats.sixteen_bit_storage.storagePushConstant16;796vk11_feats->storageInputOutput16 =797local_feats.sixteen_bit_storage.storageInputOutput16;798799vk11_feats->multiview = local_feats.multiview.multiview;800vk11_feats->multiviewGeometryShader =801local_feats.multiview.multiviewGeometryShader;802vk11_feats->multiviewTessellationShader =803local_feats.multiview.multiviewTessellationShader;804805vk11_feats->variablePointersStorageBuffer =806local_feats.variable_pointers.variablePointersStorageBuffer;807vk11_feats->variablePointers =808local_feats.variable_pointers.variablePointers;809810vk11_feats->protectedMemory =811local_feats.protected_memory.protectedMemory;812813vk11_feats->samplerYcbcrConversion =814local_feats.sampler_ycbcr_conversion.samplerYcbcrConversion;815816vk11_feats->shaderDrawParameters =817local_feats.shader_draw_parameters.shaderDrawParameters;818819vk12_feats->samplerMirrorClampToEdge =820exts->KHR_sampler_mirror_clamp_to_edge;821vk12_feats->drawIndirectCount = exts->KHR_draw_indirect_count;822823if (exts->KHR_8bit_storage) {824vk12_feats->storageBuffer8BitAccess =825local_feats.eight_bit_storage.storageBuffer8BitAccess;826vk12_feats->uniformAndStorageBuffer8BitAccess =827local_feats.eight_bit_storage.uniformAndStorageBuffer8BitAccess;828vk12_feats->storagePushConstant8 =829local_feats.eight_bit_storage.storagePushConstant8;830}831if (exts->KHR_shader_atomic_int64) {832vk12_feats->shaderBufferInt64Atomics =833local_feats.shader_atomic_int64.shaderBufferInt64Atomics;834vk12_feats->shaderSharedInt64Atomics =835local_feats.shader_atomic_int64.shaderSharedInt64Atomics;836}837if (exts->KHR_shader_float16_int8) {838vk12_feats->shaderFloat16 =839local_feats.shader_float16_int8.shaderFloat16;840vk12_feats->shaderInt8 = local_feats.shader_float16_int8.shaderInt8;841}842if (exts->EXT_descriptor_indexing) {843vk12_feats->descriptorIndexing = true;844vk12_feats->shaderInputAttachmentArrayDynamicIndexing =845local_feats.descriptor_indexing846.shaderInputAttachmentArrayDynamicIndexing;847vk12_feats->shaderUniformTexelBufferArrayDynamicIndexing =848local_feats.descriptor_indexing849.shaderUniformTexelBufferArrayDynamicIndexing;850vk12_feats->shaderStorageTexelBufferArrayDynamicIndexing =851local_feats.descriptor_indexing852.shaderStorageTexelBufferArrayDynamicIndexing;853vk12_feats->shaderUniformBufferArrayNonUniformIndexing =854local_feats.descriptor_indexing855.shaderUniformBufferArrayNonUniformIndexing;856vk12_feats->shaderSampledImageArrayNonUniformIndexing =857local_feats.descriptor_indexing858.shaderSampledImageArrayNonUniformIndexing;859vk12_feats->shaderStorageBufferArrayNonUniformIndexing =860local_feats.descriptor_indexing861.shaderStorageBufferArrayNonUniformIndexing;862vk12_feats->shaderStorageImageArrayNonUniformIndexing =863local_feats.descriptor_indexing864.shaderStorageImageArrayNonUniformIndexing;865vk12_feats->shaderInputAttachmentArrayNonUniformIndexing =866local_feats.descriptor_indexing867.shaderInputAttachmentArrayNonUniformIndexing;868vk12_feats->shaderUniformTexelBufferArrayNonUniformIndexing =869local_feats.descriptor_indexing870.shaderUniformTexelBufferArrayNonUniformIndexing;871vk12_feats->shaderStorageTexelBufferArrayNonUniformIndexing =872local_feats.descriptor_indexing873.shaderStorageTexelBufferArrayNonUniformIndexing;874vk12_feats->descriptorBindingUniformBufferUpdateAfterBind =875local_feats.descriptor_indexing876.descriptorBindingUniformBufferUpdateAfterBind;877vk12_feats->descriptorBindingSampledImageUpdateAfterBind =878local_feats.descriptor_indexing879.descriptorBindingSampledImageUpdateAfterBind;880vk12_feats->descriptorBindingStorageImageUpdateAfterBind =881local_feats.descriptor_indexing882.descriptorBindingStorageImageUpdateAfterBind;883vk12_feats->descriptorBindingStorageBufferUpdateAfterBind =884local_feats.descriptor_indexing885.descriptorBindingStorageBufferUpdateAfterBind;886vk12_feats->descriptorBindingUniformTexelBufferUpdateAfterBind =887local_feats.descriptor_indexing888.descriptorBindingUniformTexelBufferUpdateAfterBind;889vk12_feats->descriptorBindingStorageTexelBufferUpdateAfterBind =890local_feats.descriptor_indexing891.descriptorBindingStorageTexelBufferUpdateAfterBind;892vk12_feats->descriptorBindingUpdateUnusedWhilePending =893local_feats.descriptor_indexing894.descriptorBindingUpdateUnusedWhilePending;895vk12_feats->descriptorBindingPartiallyBound =896local_feats.descriptor_indexing.descriptorBindingPartiallyBound;897vk12_feats->descriptorBindingVariableDescriptorCount =898local_feats.descriptor_indexing899.descriptorBindingVariableDescriptorCount;900vk12_feats->runtimeDescriptorArray =901local_feats.descriptor_indexing.runtimeDescriptorArray;902}903904vk12_feats->samplerFilterMinmax = exts->EXT_sampler_filter_minmax;905906if (exts->EXT_scalar_block_layout) {907vk12_feats->scalarBlockLayout =908local_feats.scalar_block_layout.scalarBlockLayout;909}910if (exts->KHR_imageless_framebuffer) {911vk12_feats->imagelessFramebuffer =912local_feats.imageless_framebuffer.imagelessFramebuffer;913}914if (exts->KHR_uniform_buffer_standard_layout) {915vk12_feats->uniformBufferStandardLayout =916local_feats.uniform_buffer_standard_layout917.uniformBufferStandardLayout;918}919if (exts->KHR_shader_subgroup_extended_types) {920vk12_feats->shaderSubgroupExtendedTypes =921local_feats.shader_subgroup_extended_types922.shaderSubgroupExtendedTypes;923}924if (exts->KHR_separate_depth_stencil_layouts) {925vk12_feats->separateDepthStencilLayouts =926local_feats.separate_depth_stencil_layouts927.separateDepthStencilLayouts;928}929if (exts->EXT_host_query_reset) {930vk12_feats->hostQueryReset =931local_feats.host_query_reset.hostQueryReset;932}933if (exts->KHR_timeline_semaphore) {934vk12_feats->timelineSemaphore =935local_feats.timeline_semaphore.timelineSemaphore;936}937if (exts->KHR_buffer_device_address) {938vk12_feats->bufferDeviceAddress =939local_feats.buffer_device_address.bufferDeviceAddress;940vk12_feats->bufferDeviceAddressCaptureReplay =941local_feats.buffer_device_address.bufferDeviceAddressCaptureReplay;942vk12_feats->bufferDeviceAddressMultiDevice =943local_feats.buffer_device_address.bufferDeviceAddressMultiDevice;944}945if (exts->KHR_vulkan_memory_model) {946vk12_feats->vulkanMemoryModel =947local_feats.vulkan_memory_model.vulkanMemoryModel;948vk12_feats->vulkanMemoryModelDeviceScope =949local_feats.vulkan_memory_model.vulkanMemoryModelDeviceScope;950vk12_feats->vulkanMemoryModelAvailabilityVisibilityChains =951local_feats.vulkan_memory_model952.vulkanMemoryModelAvailabilityVisibilityChains;953}954955vk12_feats->shaderOutputViewportIndex =956exts->EXT_shader_viewport_index_layer;957vk12_feats->shaderOutputLayer = exts->EXT_shader_viewport_index_layer;958vk12_feats->subgroupBroadcastDynamicId = false;959}960}961962static void963vn_physical_device_init_uuids(struct vn_physical_device *physical_dev)964{965struct VkPhysicalDeviceProperties *props =966&physical_dev->properties.properties;967struct VkPhysicalDeviceVulkan11Properties *vk11_props =968&physical_dev->vulkan_1_1_properties;969struct VkPhysicalDeviceVulkan12Properties *vk12_props =970&physical_dev->vulkan_1_2_properties;971struct mesa_sha1 sha1_ctx;972uint8_t sha1[SHA1_DIGEST_LENGTH];973974static_assert(VK_UUID_SIZE <= SHA1_DIGEST_LENGTH, "");975976_mesa_sha1_init(&sha1_ctx);977_mesa_sha1_update(&sha1_ctx, &props->pipelineCacheUUID,978sizeof(props->pipelineCacheUUID));979_mesa_sha1_final(&sha1_ctx, sha1);980981memcpy(props->pipelineCacheUUID, sha1, VK_UUID_SIZE);982983_mesa_sha1_init(&sha1_ctx);984_mesa_sha1_update(&sha1_ctx, &props->vendorID, sizeof(props->vendorID));985_mesa_sha1_update(&sha1_ctx, &props->deviceID, sizeof(props->deviceID));986_mesa_sha1_final(&sha1_ctx, sha1);987988memcpy(vk11_props->deviceUUID, sha1, VK_UUID_SIZE);989990_mesa_sha1_init(&sha1_ctx);991_mesa_sha1_update(&sha1_ctx, vk12_props->driverName,992strlen(vk12_props->driverName));993_mesa_sha1_update(&sha1_ctx, vk12_props->driverInfo,994strlen(vk12_props->driverInfo));995_mesa_sha1_final(&sha1_ctx, sha1);996997memcpy(vk11_props->driverUUID, sha1, VK_UUID_SIZE);998999memset(vk11_props->deviceLUID, 0, VK_LUID_SIZE);1000vk11_props->deviceNodeMask = 0;1001vk11_props->deviceLUIDValid = false;1002}10031004static void1005vn_physical_device_init_properties(struct vn_physical_device *physical_dev)1006{1007struct vn_instance *instance = physical_dev->instance;1008struct {1009/* Vulkan 1.1 */1010VkPhysicalDeviceIDProperties id;1011VkPhysicalDeviceSubgroupProperties subgroup;1012VkPhysicalDevicePointClippingProperties point_clipping;1013VkPhysicalDeviceMultiviewProperties multiview;1014VkPhysicalDeviceProtectedMemoryProperties protected_memory;1015VkPhysicalDeviceMaintenance3Properties maintenance_3;10161017/* Vulkan 1.2 */1018VkPhysicalDeviceDriverProperties driver;1019VkPhysicalDeviceFloatControlsProperties float_controls;1020VkPhysicalDeviceDescriptorIndexingProperties descriptor_indexing;1021VkPhysicalDeviceDepthStencilResolveProperties depth_stencil_resolve;1022VkPhysicalDeviceSamplerFilterMinmaxProperties sampler_filter_minmax;1023VkPhysicalDeviceTimelineSemaphoreProperties timeline_semaphore;1024} local_props;10251026physical_dev->properties.sType =1027VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;1028if (physical_dev->renderer_version >= VK_API_VERSION_1_2) {1029physical_dev->properties.pNext = &physical_dev->vulkan_1_1_properties;10301031physical_dev->vulkan_1_1_properties.sType =1032VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES;1033physical_dev->vulkan_1_1_properties.pNext =1034&physical_dev->vulkan_1_2_properties;1035physical_dev->vulkan_1_2_properties.sType =1036VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES;1037physical_dev->vulkan_1_2_properties.pNext = NULL;1038} else {1039physical_dev->properties.pNext = &local_props.id;10401041local_props.id.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES;1042local_props.id.pNext = &local_props.subgroup;1043local_props.subgroup.sType =1044VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES;1045local_props.subgroup.pNext = &local_props.point_clipping;1046local_props.point_clipping.sType =1047VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES;1048local_props.point_clipping.pNext = &local_props.multiview;1049local_props.multiview.sType =1050VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES;1051local_props.multiview.pNext = &local_props.protected_memory;1052local_props.protected_memory.sType =1053VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES;1054local_props.protected_memory.pNext = &local_props.maintenance_3;1055local_props.maintenance_3.sType =1056VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES;1057local_props.maintenance_3.pNext = &local_props.driver;10581059local_props.driver.sType =1060VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES;1061local_props.driver.pNext = &local_props.float_controls;1062local_props.float_controls.sType =1063VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES;1064local_props.float_controls.pNext = &local_props.descriptor_indexing;1065local_props.descriptor_indexing.sType =1066VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES;1067local_props.descriptor_indexing.pNext =1068&local_props.depth_stencil_resolve;1069local_props.depth_stencil_resolve.sType =1070VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES;1071local_props.depth_stencil_resolve.pNext =1072&local_props.sampler_filter_minmax;1073local_props.sampler_filter_minmax.sType =1074VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES;1075local_props.sampler_filter_minmax.pNext =1076&local_props.timeline_semaphore;1077local_props.timeline_semaphore.sType =1078VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES;1079local_props.timeline_semaphore.pNext = NULL;1080}10811082if (physical_dev->renderer_extensions.EXT_transform_feedback) {1083physical_dev->transform_feedback_properties.sType =1084VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT;1085physical_dev->transform_feedback_properties.pNext =1086physical_dev->properties.pNext;1087physical_dev->properties.pNext =1088&physical_dev->transform_feedback_properties;1089}10901091vn_call_vkGetPhysicalDeviceProperties2(1092instance, vn_physical_device_to_handle(physical_dev),1093&physical_dev->properties);10941095const struct vk_device_extension_table *exts =1096&physical_dev->renderer_extensions;1097struct VkPhysicalDeviceProperties *props =1098&physical_dev->properties.properties;1099struct VkPhysicalDeviceVulkan11Properties *vk11_props =1100&physical_dev->vulkan_1_1_properties;1101struct VkPhysicalDeviceVulkan12Properties *vk12_props =1102&physical_dev->vulkan_1_2_properties;11031104if (physical_dev->renderer_version < VK_API_VERSION_1_2) {1105memcpy(vk11_props->deviceUUID, local_props.id.deviceUUID,1106sizeof(vk11_props->deviceUUID));1107memcpy(vk11_props->driverUUID, local_props.id.driverUUID,1108sizeof(vk11_props->driverUUID));1109memcpy(vk11_props->deviceLUID, local_props.id.deviceLUID,1110sizeof(vk11_props->deviceLUID));1111vk11_props->deviceNodeMask = local_props.id.deviceNodeMask;1112vk11_props->deviceLUIDValid = local_props.id.deviceLUIDValid;11131114vk11_props->subgroupSize = local_props.subgroup.subgroupSize;1115vk11_props->subgroupSupportedStages =1116local_props.subgroup.supportedStages;1117vk11_props->subgroupSupportedOperations =1118local_props.subgroup.supportedOperations;1119vk11_props->subgroupQuadOperationsInAllStages =1120local_props.subgroup.quadOperationsInAllStages;11211122vk11_props->pointClippingBehavior =1123local_props.point_clipping.pointClippingBehavior;11241125vk11_props->maxMultiviewViewCount =1126local_props.multiview.maxMultiviewViewCount;1127vk11_props->maxMultiviewInstanceIndex =1128local_props.multiview.maxMultiviewInstanceIndex;11291130vk11_props->protectedNoFault =1131local_props.protected_memory.protectedNoFault;11321133vk11_props->maxPerSetDescriptors =1134local_props.maintenance_3.maxPerSetDescriptors;1135vk11_props->maxMemoryAllocationSize =1136local_props.maintenance_3.maxMemoryAllocationSize;11371138if (exts->KHR_driver_properties) {1139vk12_props->driverID = local_props.driver.driverID;1140memcpy(vk12_props->driverName, local_props.driver.driverName,1141VK_MAX_DRIVER_NAME_SIZE);1142memcpy(vk12_props->driverInfo, local_props.driver.driverInfo,1143VK_MAX_DRIVER_INFO_SIZE);1144vk12_props->conformanceVersion =1145local_props.driver.conformanceVersion;1146}1147if (exts->KHR_shader_float_controls) {1148vk12_props->denormBehaviorIndependence =1149local_props.float_controls.denormBehaviorIndependence;1150vk12_props->roundingModeIndependence =1151local_props.float_controls.roundingModeIndependence;1152vk12_props->shaderSignedZeroInfNanPreserveFloat16 =1153local_props.float_controls.shaderSignedZeroInfNanPreserveFloat16;1154vk12_props->shaderSignedZeroInfNanPreserveFloat32 =1155local_props.float_controls.shaderSignedZeroInfNanPreserveFloat32;1156vk12_props->shaderSignedZeroInfNanPreserveFloat64 =1157local_props.float_controls.shaderSignedZeroInfNanPreserveFloat64;1158vk12_props->shaderDenormPreserveFloat16 =1159local_props.float_controls.shaderDenormPreserveFloat16;1160vk12_props->shaderDenormPreserveFloat32 =1161local_props.float_controls.shaderDenormPreserveFloat32;1162vk12_props->shaderDenormPreserveFloat64 =1163local_props.float_controls.shaderDenormPreserveFloat64;1164vk12_props->shaderDenormFlushToZeroFloat16 =1165local_props.float_controls.shaderDenormFlushToZeroFloat16;1166vk12_props->shaderDenormFlushToZeroFloat32 =1167local_props.float_controls.shaderDenormFlushToZeroFloat32;1168vk12_props->shaderDenormFlushToZeroFloat64 =1169local_props.float_controls.shaderDenormFlushToZeroFloat64;1170vk12_props->shaderRoundingModeRTEFloat16 =1171local_props.float_controls.shaderRoundingModeRTEFloat16;1172vk12_props->shaderRoundingModeRTEFloat32 =1173local_props.float_controls.shaderRoundingModeRTEFloat32;1174vk12_props->shaderRoundingModeRTEFloat64 =1175local_props.float_controls.shaderRoundingModeRTEFloat64;1176vk12_props->shaderRoundingModeRTZFloat16 =1177local_props.float_controls.shaderRoundingModeRTZFloat16;1178vk12_props->shaderRoundingModeRTZFloat32 =1179local_props.float_controls.shaderRoundingModeRTZFloat32;1180vk12_props->shaderRoundingModeRTZFloat64 =1181local_props.float_controls.shaderRoundingModeRTZFloat64;1182}1183if (exts->EXT_descriptor_indexing) {1184vk12_props->maxUpdateAfterBindDescriptorsInAllPools =1185local_props.descriptor_indexing1186.maxUpdateAfterBindDescriptorsInAllPools;1187vk12_props->shaderUniformBufferArrayNonUniformIndexingNative =1188local_props.descriptor_indexing1189.shaderUniformBufferArrayNonUniformIndexingNative;1190vk12_props->shaderSampledImageArrayNonUniformIndexingNative =1191local_props.descriptor_indexing1192.shaderSampledImageArrayNonUniformIndexingNative;1193vk12_props->shaderStorageBufferArrayNonUniformIndexingNative =1194local_props.descriptor_indexing1195.shaderStorageBufferArrayNonUniformIndexingNative;1196vk12_props->shaderStorageImageArrayNonUniformIndexingNative =1197local_props.descriptor_indexing1198.shaderStorageImageArrayNonUniformIndexingNative;1199vk12_props->shaderInputAttachmentArrayNonUniformIndexingNative =1200local_props.descriptor_indexing1201.shaderInputAttachmentArrayNonUniformIndexingNative;1202vk12_props->robustBufferAccessUpdateAfterBind =1203local_props.descriptor_indexing.robustBufferAccessUpdateAfterBind;1204vk12_props->quadDivergentImplicitLod =1205local_props.descriptor_indexing.quadDivergentImplicitLod;1206vk12_props->maxPerStageDescriptorUpdateAfterBindSamplers =1207local_props.descriptor_indexing1208.maxPerStageDescriptorUpdateAfterBindSamplers;1209vk12_props->maxPerStageDescriptorUpdateAfterBindUniformBuffers =1210local_props.descriptor_indexing1211.maxPerStageDescriptorUpdateAfterBindUniformBuffers;1212vk12_props->maxPerStageDescriptorUpdateAfterBindStorageBuffers =1213local_props.descriptor_indexing1214.maxPerStageDescriptorUpdateAfterBindStorageBuffers;1215vk12_props->maxPerStageDescriptorUpdateAfterBindSampledImages =1216local_props.descriptor_indexing1217.maxPerStageDescriptorUpdateAfterBindSampledImages;1218vk12_props->maxPerStageDescriptorUpdateAfterBindStorageImages =1219local_props.descriptor_indexing1220.maxPerStageDescriptorUpdateAfterBindStorageImages;1221vk12_props->maxPerStageDescriptorUpdateAfterBindInputAttachments =1222local_props.descriptor_indexing1223.maxPerStageDescriptorUpdateAfterBindInputAttachments;1224vk12_props->maxPerStageUpdateAfterBindResources =1225local_props.descriptor_indexing1226.maxPerStageUpdateAfterBindResources;1227vk12_props->maxDescriptorSetUpdateAfterBindSamplers =1228local_props.descriptor_indexing1229.maxDescriptorSetUpdateAfterBindSamplers;1230vk12_props->maxDescriptorSetUpdateAfterBindUniformBuffers =1231local_props.descriptor_indexing1232.maxDescriptorSetUpdateAfterBindUniformBuffers;1233vk12_props->maxDescriptorSetUpdateAfterBindUniformBuffersDynamic =1234local_props.descriptor_indexing1235.maxDescriptorSetUpdateAfterBindUniformBuffersDynamic;1236vk12_props->maxDescriptorSetUpdateAfterBindStorageBuffers =1237local_props.descriptor_indexing1238.maxDescriptorSetUpdateAfterBindStorageBuffers;1239vk12_props->maxDescriptorSetUpdateAfterBindStorageBuffersDynamic =1240local_props.descriptor_indexing1241.maxDescriptorSetUpdateAfterBindStorageBuffersDynamic;1242vk12_props->maxDescriptorSetUpdateAfterBindSampledImages =1243local_props.descriptor_indexing1244.maxDescriptorSetUpdateAfterBindSampledImages;1245vk12_props->maxDescriptorSetUpdateAfterBindStorageImages =1246local_props.descriptor_indexing1247.maxDescriptorSetUpdateAfterBindStorageImages;1248vk12_props->maxDescriptorSetUpdateAfterBindInputAttachments =1249local_props.descriptor_indexing1250.maxDescriptorSetUpdateAfterBindInputAttachments;1251}1252if (exts->KHR_depth_stencil_resolve) {1253vk12_props->supportedDepthResolveModes =1254local_props.depth_stencil_resolve.supportedDepthResolveModes;1255vk12_props->supportedStencilResolveModes =1256local_props.depth_stencil_resolve.supportedStencilResolveModes;1257vk12_props->independentResolveNone =1258local_props.depth_stencil_resolve.independentResolveNone;1259vk12_props->independentResolve =1260local_props.depth_stencil_resolve.independentResolve;1261}1262if (exts->EXT_sampler_filter_minmax) {1263vk12_props->filterMinmaxSingleComponentFormats =1264local_props.sampler_filter_minmax1265.filterMinmaxSingleComponentFormats;1266vk12_props->filterMinmaxImageComponentMapping =1267local_props.sampler_filter_minmax1268.filterMinmaxImageComponentMapping;1269}1270if (exts->KHR_timeline_semaphore) {1271vk12_props->maxTimelineSemaphoreValueDifference =1272local_props.timeline_semaphore.maxTimelineSemaphoreValueDifference;1273}12741275vk12_props->framebufferIntegerColorSampleCounts = VK_SAMPLE_COUNT_1_BIT;1276}12771278const uint32_t version_override = vk_get_version_override();1279if (version_override) {1280props->apiVersion = version_override;1281} else {1282/* cap the advertised api version */1283uint32_t version = MIN3(props->apiVersion, VN_MAX_API_VERSION,1284instance->renderer_info.vk_xml_version);1285if (VK_VERSION_PATCH(version) > VK_VERSION_PATCH(props->apiVersion)) {1286version = version - VK_VERSION_PATCH(version) +1287VK_VERSION_PATCH(props->apiVersion);1288}1289props->apiVersion = version;1290}12911292props->driverVersion = vk_get_driver_version();12931294char device_name[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE];1295int device_name_len = snprintf(device_name, sizeof(device_name),1296"Virtio-GPU Venus (%s)", props->deviceName);1297if (device_name_len >= VK_MAX_PHYSICAL_DEVICE_NAME_SIZE) {1298memcpy(device_name + VK_MAX_PHYSICAL_DEVICE_NAME_SIZE - 5, "...)", 4);1299device_name_len = VK_MAX_PHYSICAL_DEVICE_NAME_SIZE - 1;1300}1301memcpy(props->deviceName, device_name, device_name_len + 1);13021303vk12_props->driverID = 0;1304snprintf(vk12_props->driverName, sizeof(vk12_props->driverName), "venus");1305snprintf(vk12_props->driverInfo, sizeof(vk12_props->driverInfo),1306"Mesa " PACKAGE_VERSION MESA_GIT_SHA1);1307vk12_props->conformanceVersion = (VkConformanceVersionKHR){1308.major = 0,1309.minor = 0,1310.subminor = 0,1311.patch = 0,1312};13131314vn_physical_device_init_uuids(physical_dev);1315}13161317static VkResult1318vn_physical_device_init_queue_family_properties(1319struct vn_physical_device *physical_dev)1320{1321struct vn_instance *instance = physical_dev->instance;1322const VkAllocationCallbacks *alloc = &instance->base.base.alloc;1323uint32_t count;13241325vn_call_vkGetPhysicalDeviceQueueFamilyProperties2(1326instance, vn_physical_device_to_handle(physical_dev), &count, NULL);13271328VkQueueFamilyProperties2 *props =1329vk_alloc(alloc, sizeof(*props) * count, VN_DEFAULT_ALIGN,1330VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);1331if (!props)1332return VK_ERROR_OUT_OF_HOST_MEMORY;13331334for (uint32_t i = 0; i < count; i++) {1335props[i].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2;1336props[i].pNext = NULL;1337}1338vn_call_vkGetPhysicalDeviceQueueFamilyProperties2(1339instance, vn_physical_device_to_handle(physical_dev), &count, props);13401341physical_dev->queue_family_properties = props;1342physical_dev->queue_family_count = count;13431344return VK_SUCCESS;1345}13461347static void1348vn_physical_device_init_memory_properties(1349struct vn_physical_device *physical_dev)1350{1351struct vn_instance *instance = physical_dev->instance;13521353physical_dev->memory_properties.sType =1354VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2;13551356vn_call_vkGetPhysicalDeviceMemoryProperties2(1357instance, vn_physical_device_to_handle(physical_dev),1358&physical_dev->memory_properties);13591360if (!instance->renderer_info.has_cache_management) {1361VkPhysicalDeviceMemoryProperties *props =1362&physical_dev->memory_properties.memoryProperties;1363const uint32_t host_flags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |1364VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |1365VK_MEMORY_PROPERTY_HOST_CACHED_BIT;13661367for (uint32_t i = 0; i < props->memoryTypeCount; i++) {1368const bool coherent = props->memoryTypes[i].propertyFlags &1369VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;1370if (!coherent)1371props->memoryTypes[i].propertyFlags &= ~host_flags;1372}1373}1374}13751376static void1377vn_physical_device_init_external_memory(1378struct vn_physical_device *physical_dev)1379{1380/* When a renderer VkDeviceMemory is exportable, we can create a1381* vn_renderer_bo from it. The vn_renderer_bo can be freely exported as an1382* opaque fd or a dma-buf.1383*1384* However, to know if a rendender VkDeviceMemory is exportable, we have to1385* start from VkPhysicalDeviceExternalImageFormatInfo (or1386* vkGetPhysicalDeviceExternalBufferProperties). That means we need to1387* know the handle type that the renderer will use to make those queries.1388*1389* XXX We also assume that a vn_renderer_bo can be created as long as the1390* renderer VkDeviceMemory has a mappable memory type. That is plain1391* wrong. It is impossible to fix though until some new extension is1392* created and supported by the driver, and that the renderer switches to1393* the extension.1394*/13951396if (!physical_dev->instance->renderer_info.has_dma_buf_import)1397return;13981399/* TODO We assume the renderer uses dma-bufs here. This should be1400* negotiated by adding a new function to VK_MESA_venus_protocol.1401*/1402if (physical_dev->renderer_extensions.EXT_external_memory_dma_buf) {1403physical_dev->external_memory.renderer_handle_type =1404VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;14051406#ifdef ANDROID1407physical_dev->external_memory.supported_handle_types =1408VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;1409#else1410physical_dev->external_memory.supported_handle_types =1411VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT |1412VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;1413#endif1414}1415}14161417static void1418vn_physical_device_init_external_fence_handles(1419struct vn_physical_device *physical_dev)1420{1421/* The current code manipulates the host-side VkFence directly.1422* vkWaitForFences is translated to repeated vkGetFenceStatus.1423*1424* External fence is not possible currently. At best, we could cheat by1425* translating vkGetFenceFdKHR to vkWaitForFences and returning -1, when1426* the handle type is sync file.1427*1428* We would like to create a vn_renderer_sync from a host-side VkFence,1429* similar to how a vn_renderer_bo is created from a host-side1430* VkDeviceMemory. That would require kernel support and tons of works on1431* the host side. If we had that, and we kept both the vn_renderer_sync1432* and the host-side VkFence in sync, we would have the freedom to use1433* either of them depending on the occasions, and support external fences1434* and idle waiting.1435*/1436physical_dev->external_fence_handles = 0;14371438#ifdef ANDROID1439if (physical_dev->instance->experimental.globalFencing) {1440physical_dev->external_fence_handles =1441VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT;1442}1443#endif1444}14451446static void1447vn_physical_device_init_external_semaphore_handles(1448struct vn_physical_device *physical_dev)1449{1450/* The current code manipulates the host-side VkSemaphore directly. It1451* works very well for binary semaphores because there is no CPU operation.1452* But for timeline semaphores, the situation is similar to that of fences.1453* vkWaitSemaphores is translated to repeated vkGetSemaphoreCounterValue.1454*1455* External semaphore is not possible currently. We could cheat when the1456* semaphore is binary and the handle type is sync file, but that would1457* require associating a fence with the semaphore and doing vkWaitForFences1458* in vkGetSemaphoreFdKHR.1459*1460* We would like to create a vn_renderer_sync from a host-side VkSemaphore,1461* similar to how a vn_renderer_bo is created from a host-side1462* VkDeviceMemory. The reasoning is the same as that for fences.1463* Additionally, we would like the sync file exported from the1464* vn_renderer_sync to carry the necessary information to identify the1465* host-side VkSemaphore. That would allow the consumers to wait on the1466* host side rather than the guest side.1467*/1468physical_dev->external_binary_semaphore_handles = 0;1469physical_dev->external_timeline_semaphore_handles = 0;14701471#ifdef ANDROID1472if (physical_dev->instance->experimental.globalFencing) {1473physical_dev->external_binary_semaphore_handles =1474VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;1475}1476#endif1477}14781479static void1480vn_physical_device_get_native_extensions(1481const struct vn_physical_device *physical_dev,1482struct vk_device_extension_table *exts)1483{1484const struct vn_instance *instance = physical_dev->instance;1485const struct vn_renderer_info *renderer_info = &instance->renderer_info;1486const struct vk_device_extension_table *renderer_exts =1487&physical_dev->renderer_extensions;14881489memset(exts, 0, sizeof(*exts));14901491/* see vn_physical_device_init_external_memory */1492const bool can_external_mem = renderer_exts->EXT_external_memory_dma_buf &&1493renderer_info->has_dma_buf_import;14941495#ifdef ANDROID1496if (can_external_mem && renderer_exts->EXT_image_drm_format_modifier &&1497renderer_exts->EXT_queue_family_foreign &&1498instance->experimental.memoryResourceAllocationSize == VK_TRUE) {1499exts->ANDROID_external_memory_android_hardware_buffer = true;1500exts->ANDROID_native_buffer = true;1501}15021503/* we have a very poor implementation */1504if (instance->experimental.globalFencing) {1505exts->KHR_external_fence_fd = true;1506exts->KHR_external_semaphore_fd = true;1507}1508#else /* ANDROID */1509if (can_external_mem) {1510exts->KHR_external_memory_fd = true;1511exts->EXT_external_memory_dma_buf = true;1512}15131514#ifdef VN_USE_WSI_PLATFORM1515/* XXX we should check for EXT_queue_family_foreign */1516exts->KHR_incremental_present = true;1517exts->KHR_swapchain = true;1518exts->KHR_swapchain_mutable_format = true;1519#endif1520#endif /* ANDROID */1521}15221523static void1524vn_physical_device_get_passthrough_extensions(1525const struct vn_physical_device *physical_dev,1526struct vk_device_extension_table *exts)1527{1528*exts = (struct vk_device_extension_table){1529/* promoted to VK_VERSION_1_1 */1530.KHR_16bit_storage = true,1531.KHR_bind_memory2 = true,1532.KHR_dedicated_allocation = true,1533.KHR_descriptor_update_template = true,1534.KHR_device_group = true,1535.KHR_external_fence = true,1536.KHR_external_memory = true,1537.KHR_external_semaphore = true,1538.KHR_get_memory_requirements2 = true,1539.KHR_maintenance1 = true,1540.KHR_maintenance2 = true,1541.KHR_maintenance3 = true,1542.KHR_multiview = true,1543.KHR_relaxed_block_layout = true,1544.KHR_sampler_ycbcr_conversion = true,1545.KHR_shader_draw_parameters = true,1546.KHR_storage_buffer_storage_class = true,1547.KHR_variable_pointers = true,15481549/* promoted to VK_VERSION_1_2 */1550.KHR_8bit_storage = true,1551.KHR_buffer_device_address = true,1552.KHR_create_renderpass2 = true,1553.KHR_depth_stencil_resolve = true,1554.KHR_draw_indirect_count = true,1555#ifndef ANDROID1556/* xxx remove the #ifndef after venus has a driver id */1557.KHR_driver_properties = true,1558#endif1559.KHR_image_format_list = true,1560.KHR_imageless_framebuffer = true,1561.KHR_sampler_mirror_clamp_to_edge = true,1562.KHR_separate_depth_stencil_layouts = true,1563.KHR_shader_atomic_int64 = true,1564.KHR_shader_float16_int8 = true,1565.KHR_shader_float_controls = true,1566.KHR_shader_subgroup_extended_types = true,1567.KHR_spirv_1_4 = true,1568.KHR_timeline_semaphore = true,1569.KHR_uniform_buffer_standard_layout = true,1570.KHR_vulkan_memory_model = true,1571.EXT_descriptor_indexing = true,1572.EXT_host_query_reset = true,1573.EXT_sampler_filter_minmax = true,1574.EXT_scalar_block_layout = true,1575.EXT_separate_stencil_usage = true,1576.EXT_shader_viewport_index_layer = true,15771578/* EXT */1579#ifndef ANDROID1580.EXT_image_drm_format_modifier = true,1581#endif1582.EXT_queue_family_foreign = true,1583.EXT_transform_feedback = true,1584};1585}15861587static void1588vn_physical_device_init_supported_extensions(1589struct vn_physical_device *physical_dev)1590{1591struct vk_device_extension_table native;1592struct vk_device_extension_table passthrough;1593vn_physical_device_get_native_extensions(physical_dev, &native);1594vn_physical_device_get_passthrough_extensions(physical_dev, &passthrough);15951596for (uint32_t i = 0; i < VK_DEVICE_EXTENSION_COUNT; i++) {1597const VkExtensionProperties *props = &vk_device_extensions[i];15981599#ifdef ANDROID1600if (!vk_android_allowed_device_extensions.extensions[i])1601continue;1602#endif16031604if (native.extensions[i]) {1605physical_dev->base.base.supported_extensions.extensions[i] = true;1606physical_dev->extension_spec_versions[i] = props->specVersion;1607} else if (passthrough.extensions[i] &&1608physical_dev->renderer_extensions.extensions[i]) {1609physical_dev->base.base.supported_extensions.extensions[i] = true;1610physical_dev->extension_spec_versions[i] = MIN2(1611physical_dev->extension_spec_versions[i], props->specVersion);1612}1613}16141615/* override VK_ANDROID_native_buffer spec version */1616if (native.ANDROID_native_buffer) {1617const uint32_t index =1618VN_EXTENSION_TABLE_INDEX(native, ANDROID_native_buffer);1619physical_dev->extension_spec_versions[index] =1620VN_ANDROID_NATIVE_BUFFER_SPEC_VERSION;1621}1622}16231624static VkResult1625vn_physical_device_init_renderer_extensions(1626struct vn_physical_device *physical_dev)1627{1628struct vn_instance *instance = physical_dev->instance;1629const VkAllocationCallbacks *alloc = &instance->base.base.alloc;16301631/* get renderer extensions */1632uint32_t count;1633VkResult result = vn_call_vkEnumerateDeviceExtensionProperties(1634instance, vn_physical_device_to_handle(physical_dev), NULL, &count,1635NULL);1636if (result != VK_SUCCESS)1637return result;16381639VkExtensionProperties *exts = NULL;1640if (count) {1641exts = vk_alloc(alloc, sizeof(*exts) * count, VN_DEFAULT_ALIGN,1642VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);1643if (!exts)1644return VK_ERROR_OUT_OF_HOST_MEMORY;16451646result = vn_call_vkEnumerateDeviceExtensionProperties(1647instance, vn_physical_device_to_handle(physical_dev), NULL, &count,1648exts);1649if (result < VK_SUCCESS) {1650vk_free(alloc, exts);1651return result;1652}1653}16541655physical_dev->extension_spec_versions =1656vk_zalloc(alloc,1657sizeof(*physical_dev->extension_spec_versions) *1658VK_DEVICE_EXTENSION_COUNT,1659VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);1660if (!physical_dev->extension_spec_versions) {1661vk_free(alloc, exts);1662return VK_ERROR_OUT_OF_HOST_MEMORY;1663}16641665for (uint32_t i = 0; i < VK_DEVICE_EXTENSION_COUNT; i++) {1666const VkExtensionProperties *props = &vk_device_extensions[i];1667for (uint32_t j = 0; j < count; j++) {1668if (strcmp(props->extensionName, exts[j].extensionName))1669continue;16701671/* check encoder support */1672const uint32_t spec_version =1673vn_info_extension_spec_version(props->extensionName);1674if (!spec_version)1675continue;16761677physical_dev->renderer_extensions.extensions[i] = true;1678physical_dev->extension_spec_versions[i] =1679MIN2(exts[j].specVersion, spec_version);16801681break;1682}1683}16841685vk_free(alloc, exts);16861687return VK_SUCCESS;1688}16891690static VkResult1691vn_physical_device_init_renderer_version(1692struct vn_physical_device *physical_dev)1693{1694struct vn_instance *instance = physical_dev->instance;16951696/*1697* We either check and enable VK_KHR_get_physical_device_properties2, or we1698* must use vkGetPhysicalDeviceProperties to get the device-level version.1699*/1700VkPhysicalDeviceProperties props;1701vn_call_vkGetPhysicalDeviceProperties(1702instance, vn_physical_device_to_handle(physical_dev), &props);1703if (props.apiVersion < VN_MIN_RENDERER_VERSION) {1704if (VN_DEBUG(INIT)) {1705vn_log(instance, "%s has unsupported renderer device version %d.%d",1706props.deviceName, VK_VERSION_MAJOR(props.apiVersion),1707VK_VERSION_MINOR(props.apiVersion));1708}1709return VK_ERROR_INITIALIZATION_FAILED;1710}17111712/* device version for internal use is capped */1713physical_dev->renderer_version =1714MIN3(props.apiVersion, instance->renderer_api_version,1715instance->renderer_info.vk_xml_version);17161717return VK_SUCCESS;1718}17191720static VkResult1721vn_physical_device_init(struct vn_physical_device *physical_dev)1722{1723struct vn_instance *instance = physical_dev->instance;1724const VkAllocationCallbacks *alloc = &instance->base.base.alloc;17251726VkResult result = vn_physical_device_init_renderer_version(physical_dev);1727if (result != VK_SUCCESS)1728return result;17291730result = vn_physical_device_init_renderer_extensions(physical_dev);1731if (result != VK_SUCCESS)1732return result;17331734vn_physical_device_init_supported_extensions(physical_dev);17351736/* TODO query all caps with minimal round trips */1737vn_physical_device_init_features(physical_dev);1738vn_physical_device_init_properties(physical_dev);17391740result = vn_physical_device_init_queue_family_properties(physical_dev);1741if (result != VK_SUCCESS)1742goto fail;17431744vn_physical_device_init_memory_properties(physical_dev);17451746vn_physical_device_init_external_memory(physical_dev);1747vn_physical_device_init_external_fence_handles(physical_dev);1748vn_physical_device_init_external_semaphore_handles(physical_dev);17491750result = vn_wsi_init(physical_dev);1751if (result != VK_SUCCESS)1752goto fail;17531754return VK_SUCCESS;17551756fail:1757vk_free(alloc, physical_dev->extension_spec_versions);1758vk_free(alloc, physical_dev->queue_family_properties);1759return result;1760}17611762static void1763vn_physical_device_fini(struct vn_physical_device *physical_dev)1764{1765struct vn_instance *instance = physical_dev->instance;1766const VkAllocationCallbacks *alloc = &instance->base.base.alloc;17671768vn_wsi_fini(physical_dev);1769vk_free(alloc, physical_dev->extension_spec_versions);1770vk_free(alloc, physical_dev->queue_family_properties);17711772vn_physical_device_base_fini(&physical_dev->base);1773}17741775static VkResult1776vn_instance_enumerate_physical_devices(struct vn_instance *instance)1777{1778/* TODO cache device group info here as well */1779const VkAllocationCallbacks *alloc = &instance->base.base.alloc;1780struct vn_physical_device *physical_devs = NULL;1781VkResult result;17821783mtx_lock(&instance->physical_device_mutex);17841785if (instance->physical_devices) {1786result = VK_SUCCESS;1787goto out;1788}17891790uint32_t count;1791result = vn_call_vkEnumeratePhysicalDevices(1792instance, vn_instance_to_handle(instance), &count, NULL);1793if (result != VK_SUCCESS || !count)1794goto out;17951796physical_devs =1797vk_zalloc(alloc, sizeof(*physical_devs) * count, VN_DEFAULT_ALIGN,1798VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);1799if (!physical_devs) {1800result = VK_ERROR_OUT_OF_HOST_MEMORY;1801goto out;1802}18031804VkPhysicalDevice *handles =1805vk_alloc(alloc, sizeof(*handles) * count, VN_DEFAULT_ALIGN,1806VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);1807if (!handles) {1808result = VK_ERROR_OUT_OF_HOST_MEMORY;1809goto out;1810}18111812for (uint32_t i = 0; i < count; i++) {1813struct vn_physical_device *physical_dev = &physical_devs[i];18141815struct vk_physical_device_dispatch_table dispatch_table;1816vk_physical_device_dispatch_table_from_entrypoints(1817&dispatch_table, &vn_physical_device_entrypoints, true);1818result = vn_physical_device_base_init(1819&physical_dev->base, &instance->base, NULL, &dispatch_table);1820if (result != VK_SUCCESS) {1821count = i;1822goto out;1823}18241825physical_dev->instance = instance;18261827handles[i] = vn_physical_device_to_handle(physical_dev);1828}18291830result = vn_call_vkEnumeratePhysicalDevices(1831instance, vn_instance_to_handle(instance), &count, handles);1832vk_free(alloc, handles);18331834if (result != VK_SUCCESS)1835goto out;18361837uint32_t i = 0;1838while (i < count) {1839struct vn_physical_device *physical_dev = &physical_devs[i];18401841result = vn_physical_device_init(physical_dev);1842if (result != VK_SUCCESS) {1843vn_physical_device_base_fini(&physical_devs[i].base);1844memmove(&physical_devs[i], &physical_devs[i + 1],1845sizeof(*physical_devs) * (count - i - 1));1846count--;1847continue;1848}18491850i++;1851}18521853if (count) {1854instance->physical_devices = physical_devs;1855instance->physical_device_count = count;1856result = VK_SUCCESS;1857}18581859out:1860if (result != VK_SUCCESS && physical_devs) {1861for (uint32_t i = 0; i < count; i++)1862vn_physical_device_base_fini(&physical_devs[i].base);1863vk_free(alloc, physical_devs);1864}18651866mtx_unlock(&instance->physical_device_mutex);1867return result;1868}18691870/* instance commands */18711872VkResult1873vn_EnumerateInstanceVersion(uint32_t *pApiVersion)1874{1875*pApiVersion = VN_MAX_API_VERSION;1876return VK_SUCCESS;1877}18781879VkResult1880vn_EnumerateInstanceExtensionProperties(const char *pLayerName,1881uint32_t *pPropertyCount,1882VkExtensionProperties *pProperties)1883{1884if (pLayerName)1885return vn_error(NULL, VK_ERROR_LAYER_NOT_PRESENT);18861887return vk_enumerate_instance_extension_properties(1888&vn_instance_supported_extensions, pPropertyCount, pProperties);1889}18901891VkResult1892vn_EnumerateInstanceLayerProperties(uint32_t *pPropertyCount,1893VkLayerProperties *pProperties)1894{1895*pPropertyCount = 0;1896return VK_SUCCESS;1897}18981899VkResult1900vn_CreateInstance(const VkInstanceCreateInfo *pCreateInfo,1901const VkAllocationCallbacks *pAllocator,1902VkInstance *pInstance)1903{1904const VkAllocationCallbacks *alloc =1905pAllocator ? pAllocator : vk_default_allocator();1906struct vn_instance *instance;1907VkResult result;19081909vn_debug_init();19101911instance = vk_zalloc(alloc, sizeof(*instance), VN_DEFAULT_ALIGN,1912VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);1913if (!instance)1914return vn_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY);19151916struct vk_instance_dispatch_table dispatch_table;1917vk_instance_dispatch_table_from_entrypoints(1918&dispatch_table, &vn_instance_entrypoints, true);1919result = vn_instance_base_init(&instance->base,1920&vn_instance_supported_extensions,1921&dispatch_table, pCreateInfo, alloc);1922if (result != VK_SUCCESS) {1923vk_free(alloc, instance);1924return vn_error(NULL, result);1925}19261927mtx_init(&instance->physical_device_mutex, mtx_plain);19281929if (!vn_icd_supports_api_version(1930instance->base.base.app_info.api_version)) {1931result = VK_ERROR_INCOMPATIBLE_DRIVER;1932goto fail;1933}19341935if (pCreateInfo->enabledLayerCount) {1936result = VK_ERROR_LAYER_NOT_PRESENT;1937goto fail;1938}19391940result = vn_instance_init_renderer(instance);1941if (result != VK_SUCCESS)1942goto fail;19431944result = vn_instance_init_ring(instance);1945if (result != VK_SUCCESS)1946goto fail;19471948vn_instance_init_experimental_features(instance);19491950result = vn_instance_init_renderer_versions(instance);1951if (result != VK_SUCCESS)1952goto fail;19531954VkInstanceCreateInfo local_create_info = *pCreateInfo;1955local_create_info.ppEnabledExtensionNames = NULL;1956local_create_info.enabledExtensionCount = 0;1957pCreateInfo = &local_create_info;19581959VkApplicationInfo local_app_info;1960if (instance->base.base.app_info.api_version <1961instance->renderer_api_version) {1962if (pCreateInfo->pApplicationInfo) {1963local_app_info = *pCreateInfo->pApplicationInfo;1964local_app_info.apiVersion = instance->renderer_api_version;1965} else {1966local_app_info = (const VkApplicationInfo){1967.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,1968.apiVersion = instance->renderer_api_version,1969};1970}1971local_create_info.pApplicationInfo = &local_app_info;1972}19731974VkInstance instance_handle = vn_instance_to_handle(instance);1975result =1976vn_call_vkCreateInstance(instance, pCreateInfo, NULL, &instance_handle);1977if (result != VK_SUCCESS)1978goto fail;19791980driParseOptionInfo(&instance->available_dri_options, vn_dri_options,1981ARRAY_SIZE(vn_dri_options));1982driParseConfigFiles(&instance->dri_options,1983&instance->available_dri_options, 0, "venus", NULL,1984instance->base.base.app_info.app_name,1985instance->base.base.app_info.app_version,1986instance->base.base.app_info.engine_name,1987instance->base.base.app_info.engine_version);19881989*pInstance = instance_handle;19901991return VK_SUCCESS;19921993fail:1994if (instance->reply.shmem)1995vn_renderer_shmem_unref(instance->renderer, instance->reply.shmem);19961997if (instance->ring.shmem) {1998uint32_t destroy_ring_data[4];1999struct vn_cs_encoder local_enc = VN_CS_ENCODER_INITIALIZER_LOCAL(2000destroy_ring_data, sizeof(destroy_ring_data));2001vn_encode_vkDestroyRingMESA(&local_enc, 0, instance->ring.id);2002vn_renderer_submit_simple(instance->renderer, destroy_ring_data,2003vn_cs_encoder_get_len(&local_enc));20042005vn_cs_encoder_fini(&instance->ring.upload);2006vn_renderer_shmem_unref(instance->renderer, instance->ring.shmem);2007vn_ring_fini(&instance->ring.ring);2008mtx_destroy(&instance->ring.mutex);2009}20102011if (instance->renderer) {2012mtx_destroy(&instance->roundtrip_mutex);2013vn_renderer_destroy(instance->renderer, alloc);2014}20152016mtx_destroy(&instance->physical_device_mutex);20172018vn_instance_base_fini(&instance->base);2019vk_free(alloc, instance);20202021return vn_error(NULL, result);2022}20232024void2025vn_DestroyInstance(VkInstance _instance,2026const VkAllocationCallbacks *pAllocator)2027{2028struct vn_instance *instance = vn_instance_from_handle(_instance);2029const VkAllocationCallbacks *alloc =2030pAllocator ? pAllocator : &instance->base.base.alloc;20312032if (!instance)2033return;20342035if (instance->physical_devices) {2036for (uint32_t i = 0; i < instance->physical_device_count; i++)2037vn_physical_device_fini(&instance->physical_devices[i]);2038vk_free(alloc, instance->physical_devices);2039}20402041vn_call_vkDestroyInstance(instance, _instance, NULL);20422043vn_renderer_shmem_unref(instance->renderer, instance->reply.shmem);20442045uint32_t destroy_ring_data[4];2046struct vn_cs_encoder local_enc = VN_CS_ENCODER_INITIALIZER_LOCAL(2047destroy_ring_data, sizeof(destroy_ring_data));2048vn_encode_vkDestroyRingMESA(&local_enc, 0, instance->ring.id);2049vn_renderer_submit_simple(instance->renderer, destroy_ring_data,2050vn_cs_encoder_get_len(&local_enc));20512052vn_cs_encoder_fini(&instance->ring.upload);2053vn_ring_fini(&instance->ring.ring);2054mtx_destroy(&instance->ring.mutex);2055vn_renderer_shmem_unref(instance->renderer, instance->ring.shmem);20562057mtx_destroy(&instance->roundtrip_mutex);2058vn_renderer_destroy(instance->renderer, alloc);20592060mtx_destroy(&instance->physical_device_mutex);20612062driDestroyOptionCache(&instance->dri_options);2063driDestroyOptionInfo(&instance->available_dri_options);20642065vn_instance_base_fini(&instance->base);2066vk_free(alloc, instance);2067}20682069PFN_vkVoidFunction2070vn_GetInstanceProcAddr(VkInstance _instance, const char *pName)2071{2072struct vn_instance *instance = vn_instance_from_handle(_instance);2073return vk_instance_get_proc_addr(&instance->base.base,2074&vn_instance_entrypoints, pName);2075}20762077/* physical device commands */20782079VkResult2080vn_EnumeratePhysicalDevices(VkInstance _instance,2081uint32_t *pPhysicalDeviceCount,2082VkPhysicalDevice *pPhysicalDevices)2083{2084struct vn_instance *instance = vn_instance_from_handle(_instance);20852086VkResult result = vn_instance_enumerate_physical_devices(instance);2087if (result != VK_SUCCESS)2088return vn_error(instance, result);20892090VK_OUTARRAY_MAKE(out, pPhysicalDevices, pPhysicalDeviceCount);2091for (uint32_t i = 0; i < instance->physical_device_count; i++) {2092vk_outarray_append(&out, physical_dev) {2093*physical_dev =2094vn_physical_device_to_handle(&instance->physical_devices[i]);2095}2096}20972098return vk_outarray_status(&out);2099}21002101VkResult2102vn_EnumeratePhysicalDeviceGroups(2103VkInstance _instance,2104uint32_t *pPhysicalDeviceGroupCount,2105VkPhysicalDeviceGroupProperties *pPhysicalDeviceGroupProperties)2106{2107struct vn_instance *instance = vn_instance_from_handle(_instance);2108const VkAllocationCallbacks *alloc = &instance->base.base.alloc;2109struct vn_physical_device_base *dummy = NULL;2110VkResult result;21112112result = vn_instance_enumerate_physical_devices(instance);2113if (result != VK_SUCCESS)2114return vn_error(instance, result);21152116if (pPhysicalDeviceGroupProperties && *pPhysicalDeviceGroupCount == 0)2117return instance->physical_device_count ? VK_INCOMPLETE : VK_SUCCESS;21182119/* make sure VkPhysicalDevice point to objects, as they are considered2120* inputs by the encoder2121*/2122if (pPhysicalDeviceGroupProperties) {2123const uint32_t count = *pPhysicalDeviceGroupCount;2124const size_t size = sizeof(*dummy) * VK_MAX_DEVICE_GROUP_SIZE * count;21252126dummy = vk_zalloc(alloc, size, VN_DEFAULT_ALIGN,2127VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);2128if (!dummy)2129return vn_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY);21302131for (uint32_t i = 0; i < count; i++) {2132VkPhysicalDeviceGroupProperties *props =2133&pPhysicalDeviceGroupProperties[i];21342135for (uint32_t j = 0; j < VK_MAX_DEVICE_GROUP_SIZE; j++) {2136struct vn_physical_device_base *obj =2137&dummy[VK_MAX_DEVICE_GROUP_SIZE * i + j];2138obj->base.base.type = VK_OBJECT_TYPE_PHYSICAL_DEVICE;2139props->physicalDevices[j] = (VkPhysicalDevice)obj;2140}2141}2142}21432144result = vn_call_vkEnumeratePhysicalDeviceGroups(2145instance, _instance, pPhysicalDeviceGroupCount,2146pPhysicalDeviceGroupProperties);2147if (result != VK_SUCCESS) {2148if (dummy)2149vk_free(alloc, dummy);2150return vn_error(instance, result);2151}21522153if (pPhysicalDeviceGroupProperties) {2154for (uint32_t i = 0; i < *pPhysicalDeviceGroupCount; i++) {2155VkPhysicalDeviceGroupProperties *props =2156&pPhysicalDeviceGroupProperties[i];2157for (uint32_t j = 0; j < props->physicalDeviceCount; j++) {2158const vn_object_id id =2159dummy[VK_MAX_DEVICE_GROUP_SIZE * i + j].id;2160struct vn_physical_device *physical_dev =2161vn_instance_find_physical_device(instance, id);2162props->physicalDevices[j] =2163vn_physical_device_to_handle(physical_dev);2164}2165}2166}21672168if (dummy)2169vk_free(alloc, dummy);21702171return VK_SUCCESS;2172}21732174void2175vn_GetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice,2176VkPhysicalDeviceFeatures *pFeatures)2177{2178struct vn_physical_device *physical_dev =2179vn_physical_device_from_handle(physicalDevice);21802181*pFeatures = physical_dev->features.features;2182}21832184void2185vn_GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,2186VkPhysicalDeviceProperties *pProperties)2187{2188struct vn_physical_device *physical_dev =2189vn_physical_device_from_handle(physicalDevice);21902191*pProperties = physical_dev->properties.properties;2192}21932194void2195vn_GetPhysicalDeviceQueueFamilyProperties(2196VkPhysicalDevice physicalDevice,2197uint32_t *pQueueFamilyPropertyCount,2198VkQueueFamilyProperties *pQueueFamilyProperties)2199{2200struct vn_physical_device *physical_dev =2201vn_physical_device_from_handle(physicalDevice);22022203VK_OUTARRAY_MAKE(out, pQueueFamilyProperties, pQueueFamilyPropertyCount);2204for (uint32_t i = 0; i < physical_dev->queue_family_count; i++) {2205vk_outarray_append(&out, props) {2206*props =2207physical_dev->queue_family_properties[i].queueFamilyProperties;2208}2209}2210}22112212void2213vn_GetPhysicalDeviceMemoryProperties(2214VkPhysicalDevice physicalDevice,2215VkPhysicalDeviceMemoryProperties *pMemoryProperties)2216{2217struct vn_physical_device *physical_dev =2218vn_physical_device_from_handle(physicalDevice);22192220*pMemoryProperties = physical_dev->memory_properties.memoryProperties;2221}22222223void2224vn_GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice,2225VkFormat format,2226VkFormatProperties *pFormatProperties)2227{2228struct vn_physical_device *physical_dev =2229vn_physical_device_from_handle(physicalDevice);22302231/* TODO query all formats during init */2232vn_call_vkGetPhysicalDeviceFormatProperties(2233physical_dev->instance, physicalDevice, format, pFormatProperties);2234}22352236VkResult2237vn_GetPhysicalDeviceImageFormatProperties(2238VkPhysicalDevice physicalDevice,2239VkFormat format,2240VkImageType type,2241VkImageTiling tiling,2242VkImageUsageFlags usage,2243VkImageCreateFlags flags,2244VkImageFormatProperties *pImageFormatProperties)2245{2246struct vn_physical_device *physical_dev =2247vn_physical_device_from_handle(physicalDevice);22482249/* TODO per-device cache */2250VkResult result = vn_call_vkGetPhysicalDeviceImageFormatProperties(2251physical_dev->instance, physicalDevice, format, type, tiling, usage,2252flags, pImageFormatProperties);22532254return vn_result(physical_dev->instance, result);2255}22562257void2258vn_GetPhysicalDeviceSparseImageFormatProperties(2259VkPhysicalDevice physicalDevice,2260VkFormat format,2261VkImageType type,2262uint32_t samples,2263VkImageUsageFlags usage,2264VkImageTiling tiling,2265uint32_t *pPropertyCount,2266VkSparseImageFormatProperties *pProperties)2267{2268struct vn_physical_device *physical_dev =2269vn_physical_device_from_handle(physicalDevice);22702271/* TODO per-device cache */2272vn_call_vkGetPhysicalDeviceSparseImageFormatProperties(2273physical_dev->instance, physicalDevice, format, type, samples, usage,2274tiling, pPropertyCount, pProperties);2275}22762277void2278vn_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,2279VkPhysicalDeviceFeatures2 *pFeatures)2280{2281struct vn_physical_device *physical_dev =2282vn_physical_device_from_handle(physicalDevice);2283const struct VkPhysicalDeviceVulkan11Features *vk11_feats =2284&physical_dev->vulkan_1_1_features;2285const struct VkPhysicalDeviceVulkan12Features *vk12_feats =2286&physical_dev->vulkan_1_2_features;2287union {2288VkBaseOutStructure *pnext;22892290/* Vulkan 1.1 */2291VkPhysicalDevice16BitStorageFeatures *sixteen_bit_storage;2292VkPhysicalDeviceMultiviewFeatures *multiview;2293VkPhysicalDeviceVariablePointersFeatures *variable_pointers;2294VkPhysicalDeviceProtectedMemoryFeatures *protected_memory;2295VkPhysicalDeviceSamplerYcbcrConversionFeatures *sampler_ycbcr_conversion;2296VkPhysicalDeviceShaderDrawParametersFeatures *shader_draw_parameters;22972298/* Vulkan 1.2 */2299VkPhysicalDevice8BitStorageFeatures *eight_bit_storage;2300VkPhysicalDeviceShaderAtomicInt64Features *shader_atomic_int64;2301VkPhysicalDeviceShaderFloat16Int8Features *shader_float16_int8;2302VkPhysicalDeviceDescriptorIndexingFeatures *descriptor_indexing;2303VkPhysicalDeviceScalarBlockLayoutFeatures *scalar_block_layout;2304VkPhysicalDeviceImagelessFramebufferFeatures *imageless_framebuffer;2305VkPhysicalDeviceUniformBufferStandardLayoutFeatures2306*uniform_buffer_standard_layout;2307VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures2308*shader_subgroup_extended_types;2309VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures2310*separate_depth_stencil_layouts;2311VkPhysicalDeviceHostQueryResetFeatures *host_query_reset;2312VkPhysicalDeviceTimelineSemaphoreFeatures *timeline_semaphore;2313VkPhysicalDeviceBufferDeviceAddressFeatures *buffer_device_address;2314VkPhysicalDeviceVulkanMemoryModelFeatures *vulkan_memory_model;23152316VkPhysicalDeviceTransformFeedbackFeaturesEXT *transform_feedback;2317} u;23182319u.pnext = (VkBaseOutStructure *)pFeatures;2320while (u.pnext) {2321void *saved = u.pnext->pNext;2322switch (u.pnext->sType) {2323case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2:2324memcpy(u.pnext, &physical_dev->features,2325sizeof(physical_dev->features));2326break;2327case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES:2328memcpy(u.pnext, vk11_feats, sizeof(*vk11_feats));2329break;2330case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES:2331memcpy(u.pnext, vk12_feats, sizeof(*vk12_feats));2332break;2333case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES:2334u.sixteen_bit_storage->storageBuffer16BitAccess =2335vk11_feats->storageBuffer16BitAccess;2336u.sixteen_bit_storage->uniformAndStorageBuffer16BitAccess =2337vk11_feats->uniformAndStorageBuffer16BitAccess;2338u.sixteen_bit_storage->storagePushConstant16 =2339vk11_feats->storagePushConstant16;2340u.sixteen_bit_storage->storageInputOutput16 =2341vk11_feats->storageInputOutput16;2342break;2343case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES:2344u.multiview->multiview = vk11_feats->multiview;2345u.multiview->multiviewGeometryShader =2346vk11_feats->multiviewGeometryShader;2347u.multiview->multiviewTessellationShader =2348vk11_feats->multiviewTessellationShader;2349break;2350case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES:2351u.variable_pointers->variablePointersStorageBuffer =2352vk11_feats->variablePointersStorageBuffer;2353u.variable_pointers->variablePointers = vk11_feats->variablePointers;2354break;2355case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES:2356u.protected_memory->protectedMemory = vk11_feats->protectedMemory;2357break;2358case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES:2359u.sampler_ycbcr_conversion->samplerYcbcrConversion =2360vk11_feats->samplerYcbcrConversion;2361break;2362case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES:2363u.shader_draw_parameters->shaderDrawParameters =2364vk11_feats->shaderDrawParameters;2365break;2366case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES:2367u.eight_bit_storage->storageBuffer8BitAccess =2368vk12_feats->storageBuffer8BitAccess;2369u.eight_bit_storage->uniformAndStorageBuffer8BitAccess =2370vk12_feats->uniformAndStorageBuffer8BitAccess;2371u.eight_bit_storage->storagePushConstant8 =2372vk12_feats->storagePushConstant8;2373break;2374case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES:2375u.shader_atomic_int64->shaderBufferInt64Atomics =2376vk12_feats->shaderBufferInt64Atomics;2377u.shader_atomic_int64->shaderSharedInt64Atomics =2378vk12_feats->shaderSharedInt64Atomics;2379break;2380case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES:2381u.shader_float16_int8->shaderFloat16 = vk12_feats->shaderFloat16;2382u.shader_float16_int8->shaderInt8 = vk12_feats->shaderInt8;2383break;2384case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES:2385u.descriptor_indexing->shaderInputAttachmentArrayDynamicIndexing =2386vk12_feats->shaderInputAttachmentArrayDynamicIndexing;2387u.descriptor_indexing->shaderUniformTexelBufferArrayDynamicIndexing =2388vk12_feats->shaderUniformTexelBufferArrayDynamicIndexing;2389u.descriptor_indexing->shaderStorageTexelBufferArrayDynamicIndexing =2390vk12_feats->shaderStorageTexelBufferArrayDynamicIndexing;2391u.descriptor_indexing->shaderUniformBufferArrayNonUniformIndexing =2392vk12_feats->shaderUniformBufferArrayNonUniformIndexing;2393u.descriptor_indexing->shaderSampledImageArrayNonUniformIndexing =2394vk12_feats->shaderSampledImageArrayNonUniformIndexing;2395u.descriptor_indexing->shaderStorageBufferArrayNonUniformIndexing =2396vk12_feats->shaderStorageBufferArrayNonUniformIndexing;2397u.descriptor_indexing->shaderStorageImageArrayNonUniformIndexing =2398vk12_feats->shaderStorageImageArrayNonUniformIndexing;2399u.descriptor_indexing->shaderInputAttachmentArrayNonUniformIndexing =2400vk12_feats->shaderInputAttachmentArrayNonUniformIndexing;2401u.descriptor_indexing2402->shaderUniformTexelBufferArrayNonUniformIndexing =2403vk12_feats->shaderUniformTexelBufferArrayNonUniformIndexing;2404u.descriptor_indexing2405->shaderStorageTexelBufferArrayNonUniformIndexing =2406vk12_feats->shaderStorageTexelBufferArrayNonUniformIndexing;2407u.descriptor_indexing->descriptorBindingUniformBufferUpdateAfterBind =2408vk12_feats->descriptorBindingUniformBufferUpdateAfterBind;2409u.descriptor_indexing->descriptorBindingSampledImageUpdateAfterBind =2410vk12_feats->descriptorBindingSampledImageUpdateAfterBind;2411u.descriptor_indexing->descriptorBindingStorageImageUpdateAfterBind =2412vk12_feats->descriptorBindingStorageImageUpdateAfterBind;2413u.descriptor_indexing->descriptorBindingStorageBufferUpdateAfterBind =2414vk12_feats->descriptorBindingStorageBufferUpdateAfterBind;2415u.descriptor_indexing2416->descriptorBindingUniformTexelBufferUpdateAfterBind =2417vk12_feats->descriptorBindingUniformTexelBufferUpdateAfterBind;2418u.descriptor_indexing2419->descriptorBindingStorageTexelBufferUpdateAfterBind =2420vk12_feats->descriptorBindingStorageTexelBufferUpdateAfterBind;2421u.descriptor_indexing->descriptorBindingUpdateUnusedWhilePending =2422vk12_feats->descriptorBindingUpdateUnusedWhilePending;2423u.descriptor_indexing->descriptorBindingPartiallyBound =2424vk12_feats->descriptorBindingPartiallyBound;2425u.descriptor_indexing->descriptorBindingVariableDescriptorCount =2426vk12_feats->descriptorBindingVariableDescriptorCount;2427u.descriptor_indexing->runtimeDescriptorArray =2428vk12_feats->runtimeDescriptorArray;2429break;2430case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES:2431u.scalar_block_layout->scalarBlockLayout =2432vk12_feats->scalarBlockLayout;2433break;2434case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES:2435u.imageless_framebuffer->imagelessFramebuffer =2436vk12_feats->imagelessFramebuffer;2437break;2438case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES:2439u.uniform_buffer_standard_layout->uniformBufferStandardLayout =2440vk12_feats->uniformBufferStandardLayout;2441break;2442case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES:2443u.shader_subgroup_extended_types->shaderSubgroupExtendedTypes =2444vk12_feats->shaderSubgroupExtendedTypes;2445break;2446case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES:2447u.separate_depth_stencil_layouts->separateDepthStencilLayouts =2448vk12_feats->separateDepthStencilLayouts;2449break;2450case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES:2451u.host_query_reset->hostQueryReset = vk12_feats->hostQueryReset;2452break;2453case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES:2454u.timeline_semaphore->timelineSemaphore =2455vk12_feats->timelineSemaphore;2456break;2457case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES:2458u.buffer_device_address->bufferDeviceAddress =2459vk12_feats->bufferDeviceAddress;2460u.buffer_device_address->bufferDeviceAddressCaptureReplay =2461vk12_feats->bufferDeviceAddressCaptureReplay;2462u.buffer_device_address->bufferDeviceAddressMultiDevice =2463vk12_feats->bufferDeviceAddressMultiDevice;2464break;2465case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES:2466u.vulkan_memory_model->vulkanMemoryModel =2467vk12_feats->vulkanMemoryModel;2468u.vulkan_memory_model->vulkanMemoryModelDeviceScope =2469vk12_feats->vulkanMemoryModelDeviceScope;2470u.vulkan_memory_model->vulkanMemoryModelAvailabilityVisibilityChains =2471vk12_feats->vulkanMemoryModelAvailabilityVisibilityChains;2472break;2473case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT:2474memcpy(u.transform_feedback,2475&physical_dev->transform_feedback_features,2476sizeof(physical_dev->transform_feedback_features));2477break;2478default:2479break;2480}2481u.pnext->pNext = saved;24822483u.pnext = u.pnext->pNext;2484}2485}24862487void2488vn_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,2489VkPhysicalDeviceProperties2 *pProperties)2490{2491struct vn_physical_device *physical_dev =2492vn_physical_device_from_handle(physicalDevice);2493const struct VkPhysicalDeviceVulkan11Properties *vk11_props =2494&physical_dev->vulkan_1_1_properties;2495const struct VkPhysicalDeviceVulkan12Properties *vk12_props =2496&physical_dev->vulkan_1_2_properties;2497union {2498VkBaseOutStructure *pnext;24992500/* Vulkan 1.1 */2501VkPhysicalDeviceIDProperties *id;2502VkPhysicalDeviceSubgroupProperties *subgroup;2503VkPhysicalDevicePointClippingProperties *point_clipping;2504VkPhysicalDeviceMultiviewProperties *multiview;2505VkPhysicalDeviceProtectedMemoryProperties *protected_memory;2506VkPhysicalDeviceMaintenance3Properties *maintenance_3;25072508/* Vulkan 1.2 */2509VkPhysicalDeviceDriverProperties *driver;2510VkPhysicalDeviceFloatControlsProperties *float_controls;2511VkPhysicalDeviceDescriptorIndexingProperties *descriptor_indexing;2512VkPhysicalDeviceDepthStencilResolveProperties *depth_stencil_resolve;2513VkPhysicalDeviceSamplerFilterMinmaxProperties *sampler_filter_minmax;2514VkPhysicalDeviceTimelineSemaphoreProperties *timeline_semaphore;25152516VkPhysicalDevicePCIBusInfoPropertiesEXT *pci_bus_info;2517VkPhysicalDeviceTransformFeedbackPropertiesEXT *transform_feedback;2518VkPhysicalDevicePresentationPropertiesANDROID *presentation_properties;2519} u;25202521u.pnext = (VkBaseOutStructure *)pProperties;2522while (u.pnext) {2523void *saved = u.pnext->pNext;2524switch ((int32_t)u.pnext->sType) {2525case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2:2526memcpy(u.pnext, &physical_dev->properties,2527sizeof(physical_dev->properties));2528break;2529case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES:2530memcpy(u.pnext, vk11_props, sizeof(*vk11_props));2531break;2532case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES:2533memcpy(u.pnext, vk12_props, sizeof(*vk12_props));2534break;2535case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES:2536memcpy(u.id->deviceUUID, vk11_props->deviceUUID,2537sizeof(vk11_props->deviceUUID));2538memcpy(u.id->driverUUID, vk11_props->driverUUID,2539sizeof(vk11_props->driverUUID));2540memcpy(u.id->deviceLUID, vk11_props->deviceLUID,2541sizeof(vk11_props->deviceLUID));2542u.id->deviceNodeMask = vk11_props->deviceNodeMask;2543u.id->deviceLUIDValid = vk11_props->deviceLUIDValid;2544break;2545case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES:2546u.subgroup->subgroupSize = vk11_props->subgroupSize;2547u.subgroup->supportedStages = vk11_props->subgroupSupportedStages;2548u.subgroup->supportedOperations =2549vk11_props->subgroupSupportedOperations;2550u.subgroup->quadOperationsInAllStages =2551vk11_props->subgroupQuadOperationsInAllStages;2552break;2553case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES:2554u.point_clipping->pointClippingBehavior =2555vk11_props->pointClippingBehavior;2556break;2557case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES:2558u.multiview->maxMultiviewViewCount =2559vk11_props->maxMultiviewViewCount;2560u.multiview->maxMultiviewInstanceIndex =2561vk11_props->maxMultiviewInstanceIndex;2562break;2563case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES:2564u.protected_memory->protectedNoFault = vk11_props->protectedNoFault;2565break;2566case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES:2567u.maintenance_3->maxPerSetDescriptors =2568vk11_props->maxPerSetDescriptors;2569u.maintenance_3->maxMemoryAllocationSize =2570vk11_props->maxMemoryAllocationSize;2571break;2572case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES:2573u.driver->driverID = vk12_props->driverID;2574memcpy(u.driver->driverName, vk12_props->driverName,2575sizeof(vk12_props->driverName));2576memcpy(u.driver->driverInfo, vk12_props->driverInfo,2577sizeof(vk12_props->driverInfo));2578u.driver->conformanceVersion = vk12_props->conformanceVersion;2579break;2580case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES:2581u.float_controls->denormBehaviorIndependence =2582vk12_props->denormBehaviorIndependence;2583u.float_controls->roundingModeIndependence =2584vk12_props->roundingModeIndependence;2585u.float_controls->shaderSignedZeroInfNanPreserveFloat16 =2586vk12_props->shaderSignedZeroInfNanPreserveFloat16;2587u.float_controls->shaderSignedZeroInfNanPreserveFloat32 =2588vk12_props->shaderSignedZeroInfNanPreserveFloat32;2589u.float_controls->shaderSignedZeroInfNanPreserveFloat64 =2590vk12_props->shaderSignedZeroInfNanPreserveFloat64;2591u.float_controls->shaderDenormPreserveFloat16 =2592vk12_props->shaderDenormPreserveFloat16;2593u.float_controls->shaderDenormPreserveFloat32 =2594vk12_props->shaderDenormPreserveFloat32;2595u.float_controls->shaderDenormPreserveFloat64 =2596vk12_props->shaderDenormPreserveFloat64;2597u.float_controls->shaderDenormFlushToZeroFloat16 =2598vk12_props->shaderDenormFlushToZeroFloat16;2599u.float_controls->shaderDenormFlushToZeroFloat32 =2600vk12_props->shaderDenormFlushToZeroFloat32;2601u.float_controls->shaderDenormFlushToZeroFloat64 =2602vk12_props->shaderDenormFlushToZeroFloat64;2603u.float_controls->shaderRoundingModeRTEFloat16 =2604vk12_props->shaderRoundingModeRTEFloat16;2605u.float_controls->shaderRoundingModeRTEFloat32 =2606vk12_props->shaderRoundingModeRTEFloat32;2607u.float_controls->shaderRoundingModeRTEFloat64 =2608vk12_props->shaderRoundingModeRTEFloat64;2609u.float_controls->shaderRoundingModeRTZFloat16 =2610vk12_props->shaderRoundingModeRTZFloat16;2611u.float_controls->shaderRoundingModeRTZFloat32 =2612vk12_props->shaderRoundingModeRTZFloat32;2613u.float_controls->shaderRoundingModeRTZFloat64 =2614vk12_props->shaderRoundingModeRTZFloat64;2615break;2616case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES:2617u.descriptor_indexing->maxUpdateAfterBindDescriptorsInAllPools =2618vk12_props->maxUpdateAfterBindDescriptorsInAllPools;2619u.descriptor_indexing2620->shaderUniformBufferArrayNonUniformIndexingNative =2621vk12_props->shaderUniformBufferArrayNonUniformIndexingNative;2622u.descriptor_indexing2623->shaderSampledImageArrayNonUniformIndexingNative =2624vk12_props->shaderSampledImageArrayNonUniformIndexingNative;2625u.descriptor_indexing2626->shaderStorageBufferArrayNonUniformIndexingNative =2627vk12_props->shaderStorageBufferArrayNonUniformIndexingNative;2628u.descriptor_indexing2629->shaderStorageImageArrayNonUniformIndexingNative =2630vk12_props->shaderStorageImageArrayNonUniformIndexingNative;2631u.descriptor_indexing2632->shaderInputAttachmentArrayNonUniformIndexingNative =2633vk12_props->shaderInputAttachmentArrayNonUniformIndexingNative;2634u.descriptor_indexing->robustBufferAccessUpdateAfterBind =2635vk12_props->robustBufferAccessUpdateAfterBind;2636u.descriptor_indexing->quadDivergentImplicitLod =2637vk12_props->quadDivergentImplicitLod;2638u.descriptor_indexing->maxPerStageDescriptorUpdateAfterBindSamplers =2639vk12_props->maxPerStageDescriptorUpdateAfterBindSamplers;2640u.descriptor_indexing2641->maxPerStageDescriptorUpdateAfterBindUniformBuffers =2642vk12_props->maxPerStageDescriptorUpdateAfterBindUniformBuffers;2643u.descriptor_indexing2644->maxPerStageDescriptorUpdateAfterBindStorageBuffers =2645vk12_props->maxPerStageDescriptorUpdateAfterBindStorageBuffers;2646u.descriptor_indexing2647->maxPerStageDescriptorUpdateAfterBindSampledImages =2648vk12_props->maxPerStageDescriptorUpdateAfterBindSampledImages;2649u.descriptor_indexing2650->maxPerStageDescriptorUpdateAfterBindStorageImages =2651vk12_props->maxPerStageDescriptorUpdateAfterBindStorageImages;2652u.descriptor_indexing2653->maxPerStageDescriptorUpdateAfterBindInputAttachments =2654vk12_props->maxPerStageDescriptorUpdateAfterBindInputAttachments;2655u.descriptor_indexing->maxPerStageUpdateAfterBindResources =2656vk12_props->maxPerStageUpdateAfterBindResources;2657u.descriptor_indexing->maxDescriptorSetUpdateAfterBindSamplers =2658vk12_props->maxDescriptorSetUpdateAfterBindSamplers;2659u.descriptor_indexing->maxDescriptorSetUpdateAfterBindUniformBuffers =2660vk12_props->maxDescriptorSetUpdateAfterBindUniformBuffers;2661u.descriptor_indexing2662->maxDescriptorSetUpdateAfterBindUniformBuffersDynamic =2663vk12_props->maxDescriptorSetUpdateAfterBindUniformBuffersDynamic;2664u.descriptor_indexing->maxDescriptorSetUpdateAfterBindStorageBuffers =2665vk12_props->maxDescriptorSetUpdateAfterBindStorageBuffers;2666u.descriptor_indexing2667->maxDescriptorSetUpdateAfterBindStorageBuffersDynamic =2668vk12_props->maxDescriptorSetUpdateAfterBindStorageBuffersDynamic;2669u.descriptor_indexing->maxDescriptorSetUpdateAfterBindSampledImages =2670vk12_props->maxDescriptorSetUpdateAfterBindSampledImages;2671u.descriptor_indexing->maxDescriptorSetUpdateAfterBindStorageImages =2672vk12_props->maxDescriptorSetUpdateAfterBindStorageImages;2673u.descriptor_indexing2674->maxDescriptorSetUpdateAfterBindInputAttachments =2675vk12_props->maxDescriptorSetUpdateAfterBindInputAttachments;2676break;2677case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES:2678u.depth_stencil_resolve->supportedDepthResolveModes =2679vk12_props->supportedDepthResolveModes;2680u.depth_stencil_resolve->supportedStencilResolveModes =2681vk12_props->supportedStencilResolveModes;2682u.depth_stencil_resolve->independentResolveNone =2683vk12_props->independentResolveNone;2684u.depth_stencil_resolve->independentResolve =2685vk12_props->independentResolve;2686break;2687case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES:2688u.sampler_filter_minmax->filterMinmaxSingleComponentFormats =2689vk12_props->filterMinmaxSingleComponentFormats;2690u.sampler_filter_minmax->filterMinmaxImageComponentMapping =2691vk12_props->filterMinmaxImageComponentMapping;2692break;2693case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES:2694u.timeline_semaphore->maxTimelineSemaphoreValueDifference =2695vk12_props->maxTimelineSemaphoreValueDifference;2696break;2697case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT:2698/* this is used by WSI */2699if (physical_dev->instance->renderer_info.pci.has_bus_info) {2700u.pci_bus_info->pciDomain =2701physical_dev->instance->renderer_info.pci.domain;2702u.pci_bus_info->pciBus =2703physical_dev->instance->renderer_info.pci.bus;2704u.pci_bus_info->pciDevice =2705physical_dev->instance->renderer_info.pci.device;2706u.pci_bus_info->pciFunction =2707physical_dev->instance->renderer_info.pci.function;2708}2709break;2710case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT:2711memcpy(u.transform_feedback,2712&physical_dev->transform_feedback_properties,2713sizeof(physical_dev->transform_feedback_properties));2714break;2715case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENTATION_PROPERTIES_ANDROID:2716u.presentation_properties->sharedImage = VK_FALSE;2717break;2718default:2719break;2720}2721u.pnext->pNext = saved;27222723u.pnext = u.pnext->pNext;2724}2725}27262727void2728vn_GetPhysicalDeviceQueueFamilyProperties2(2729VkPhysicalDevice physicalDevice,2730uint32_t *pQueueFamilyPropertyCount,2731VkQueueFamilyProperties2 *pQueueFamilyProperties)2732{2733struct vn_physical_device *physical_dev =2734vn_physical_device_from_handle(physicalDevice);27352736VK_OUTARRAY_MAKE(out, pQueueFamilyProperties, pQueueFamilyPropertyCount);2737for (uint32_t i = 0; i < physical_dev->queue_family_count; i++) {2738vk_outarray_append(&out, props) {2739*props = physical_dev->queue_family_properties[i];2740}2741}2742}27432744void2745vn_GetPhysicalDeviceMemoryProperties2(2746VkPhysicalDevice physicalDevice,2747VkPhysicalDeviceMemoryProperties2 *pMemoryProperties)2748{2749struct vn_physical_device *physical_dev =2750vn_physical_device_from_handle(physicalDevice);27512752pMemoryProperties->memoryProperties =2753physical_dev->memory_properties.memoryProperties;2754}27552756void2757vn_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,2758VkFormat format,2759VkFormatProperties2 *pFormatProperties)2760{2761struct vn_physical_device *physical_dev =2762vn_physical_device_from_handle(physicalDevice);27632764/* TODO query all formats during init */2765vn_call_vkGetPhysicalDeviceFormatProperties2(2766physical_dev->instance, physicalDevice, format, pFormatProperties);2767}27682769struct vn_physical_device_image_format_info {2770VkPhysicalDeviceImageFormatInfo2 format;2771VkPhysicalDeviceExternalImageFormatInfo external;2772VkImageFormatListCreateInfo list;2773VkImageStencilUsageCreateInfo stencil_usage;2774VkPhysicalDeviceImageDrmFormatModifierInfoEXT modifier;2775};27762777static const VkPhysicalDeviceImageFormatInfo2 *2778vn_physical_device_fix_image_format_info(2779struct vn_physical_device *physical_dev,2780const VkPhysicalDeviceImageFormatInfo2 *info,2781struct vn_physical_device_image_format_info *local_info)2782{2783local_info->format = *info;2784VkBaseOutStructure *dst = (void *)&local_info->format;27852786bool use_modifier = false;2787/* we should generate deep copy functions... */2788vk_foreach_struct_const(src, info->pNext) {2789void *pnext = NULL;2790switch (src->sType) {2791case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO:2792memcpy(&local_info->external, src, sizeof(local_info->external));2793use_modifier =2794local_info->external.handleType ==2795VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;2796local_info->external.handleType =2797physical_dev->external_memory.renderer_handle_type;2798pnext = &local_info->external;2799break;2800case VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO:2801memcpy(&local_info->list, src, sizeof(local_info->list));2802pnext = &local_info->list;2803break;2804case VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT:2805memcpy(&local_info->stencil_usage, src,2806sizeof(local_info->stencil_usage));2807pnext = &local_info->stencil_usage;2808break;2809default:2810break;2811}28122813if (pnext) {2814dst->pNext = pnext;2815dst = pnext;2816}2817}28182819if (use_modifier) {2820local_info->format.tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;2821if (!vn_android_get_drm_format_modifier_info(&local_info->format,2822&local_info->modifier))2823return NULL;2824}28252826dst->pNext = use_modifier ? (void *)&local_info->modifier : NULL;28272828return &local_info->format;2829}28302831VkResult2832vn_GetPhysicalDeviceImageFormatProperties2(2833VkPhysicalDevice physicalDevice,2834const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo,2835VkImageFormatProperties2 *pImageFormatProperties)2836{2837struct vn_physical_device *physical_dev =2838vn_physical_device_from_handle(physicalDevice);2839const VkExternalMemoryHandleTypeFlagBits renderer_handle_type =2840physical_dev->external_memory.renderer_handle_type;2841const VkExternalMemoryHandleTypeFlags supported_handle_types =2842physical_dev->external_memory.supported_handle_types;28432844const VkPhysicalDeviceExternalImageFormatInfo *external_info =2845vk_find_struct_const(pImageFormatInfo->pNext,2846PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO);2847if (external_info && !external_info->handleType)2848external_info = NULL;28492850struct vn_physical_device_image_format_info local_info;2851if (external_info) {2852if (!(external_info->handleType & supported_handle_types)) {2853return vn_error(physical_dev->instance,2854VK_ERROR_FORMAT_NOT_SUPPORTED);2855}28562857if (external_info->handleType != renderer_handle_type) {2858pImageFormatInfo = vn_physical_device_fix_image_format_info(2859physical_dev, pImageFormatInfo, &local_info);2860if (!pImageFormatInfo) {2861return vn_error(physical_dev->instance,2862VK_ERROR_FORMAT_NOT_SUPPORTED);2863}2864}2865}28662867VkResult result;2868/* TODO per-device cache */2869result = vn_call_vkGetPhysicalDeviceImageFormatProperties2(2870physical_dev->instance, physicalDevice, pImageFormatInfo,2871pImageFormatProperties);2872if (result != VK_SUCCESS || !external_info)2873return vn_result(physical_dev->instance, result);28742875VkExternalImageFormatProperties *img_props = vk_find_struct(2876pImageFormatProperties->pNext, EXTERNAL_IMAGE_FORMAT_PROPERTIES);2877VkExternalMemoryProperties *mem_props =2878&img_props->externalMemoryProperties;28792880if (external_info->handleType ==2881VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID) {2882/* AHB backed image requires renderer to support import bit */2883if (!(mem_props->externalMemoryFeatures &2884VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT))2885return vn_error(physical_dev->instance,2886VK_ERROR_FORMAT_NOT_SUPPORTED);28872888mem_props->externalMemoryFeatures =2889VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT |2890VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT |2891VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;2892mem_props->exportFromImportedHandleTypes =2893VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;2894mem_props->compatibleHandleTypes =2895VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;28962897VkAndroidHardwareBufferUsageANDROID *ahb_usage =2898vk_find_struct(pImageFormatProperties->pNext,2899ANDROID_HARDWARE_BUFFER_USAGE_ANDROID);2900if (ahb_usage) {2901ahb_usage->androidHardwareBufferUsage = vn_android_get_ahb_usage(2902pImageFormatInfo->usage, pImageFormatInfo->flags);2903}2904} else {2905mem_props->compatibleHandleTypes = supported_handle_types;2906mem_props->exportFromImportedHandleTypes =2907(mem_props->exportFromImportedHandleTypes & renderer_handle_type)2908? supported_handle_types2909: 0;2910}29112912return vn_result(physical_dev->instance, result);2913}29142915void2916vn_GetPhysicalDeviceSparseImageFormatProperties2(2917VkPhysicalDevice physicalDevice,2918const VkPhysicalDeviceSparseImageFormatInfo2 *pFormatInfo,2919uint32_t *pPropertyCount,2920VkSparseImageFormatProperties2 *pProperties)2921{2922struct vn_physical_device *physical_dev =2923vn_physical_device_from_handle(physicalDevice);29242925/* TODO per-device cache */2926vn_call_vkGetPhysicalDeviceSparseImageFormatProperties2(2927physical_dev->instance, physicalDevice, pFormatInfo, pPropertyCount,2928pProperties);2929}29302931void2932vn_GetPhysicalDeviceExternalBufferProperties(2933VkPhysicalDevice physicalDevice,2934const VkPhysicalDeviceExternalBufferInfo *pExternalBufferInfo,2935VkExternalBufferProperties *pExternalBufferProperties)2936{2937struct vn_physical_device *physical_dev =2938vn_physical_device_from_handle(physicalDevice);2939const VkExternalMemoryHandleTypeFlagBits renderer_handle_type =2940physical_dev->external_memory.renderer_handle_type;2941const VkExternalMemoryHandleTypeFlags supported_handle_types =2942physical_dev->external_memory.supported_handle_types;29432944VkExternalMemoryProperties *props =2945&pExternalBufferProperties->externalMemoryProperties;2946if (!(pExternalBufferInfo->handleType & supported_handle_types)) {2947props->compatibleHandleTypes = pExternalBufferInfo->handleType;2948props->exportFromImportedHandleTypes = 0;2949props->externalMemoryFeatures = 0;2950return;2951}29522953VkPhysicalDeviceExternalBufferInfo local_info;2954if (pExternalBufferInfo->handleType != renderer_handle_type) {2955local_info = *pExternalBufferInfo;2956local_info.handleType = renderer_handle_type;2957pExternalBufferInfo = &local_info;2958}29592960/* TODO per-device cache */2961vn_call_vkGetPhysicalDeviceExternalBufferProperties(2962physical_dev->instance, physicalDevice, pExternalBufferInfo,2963pExternalBufferProperties);29642965if (pExternalBufferInfo->handleType ==2966VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID) {2967props->compatibleHandleTypes =2968VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;2969/* AHB backed buffer requires renderer to support import bit while it2970* also requires the renderer to must not advertise dedicated only bit2971*/2972if (!(props->externalMemoryFeatures &2973VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT) ||2974(props->externalMemoryFeatures &2975VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT)) {2976props->externalMemoryFeatures = 0;2977props->exportFromImportedHandleTypes = 0;2978return;2979}2980props->externalMemoryFeatures =2981VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT |2982VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;2983props->exportFromImportedHandleTypes =2984VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;2985} else {2986props->compatibleHandleTypes = supported_handle_types;2987props->exportFromImportedHandleTypes =2988(props->exportFromImportedHandleTypes & renderer_handle_type)2989? supported_handle_types2990: 0;2991}2992}29932994void2995vn_GetPhysicalDeviceExternalFenceProperties(2996VkPhysicalDevice physicalDevice,2997const VkPhysicalDeviceExternalFenceInfo *pExternalFenceInfo,2998VkExternalFenceProperties *pExternalFenceProperties)2999{3000struct vn_physical_device *physical_dev =3001vn_physical_device_from_handle(physicalDevice);30023003if (pExternalFenceInfo->handleType &3004physical_dev->external_fence_handles) {3005pExternalFenceProperties->compatibleHandleTypes =3006physical_dev->external_fence_handles;3007pExternalFenceProperties->exportFromImportedHandleTypes =3008physical_dev->external_fence_handles;3009pExternalFenceProperties->externalFenceFeatures =3010VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT |3011VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT;3012} else {3013pExternalFenceProperties->compatibleHandleTypes =3014pExternalFenceInfo->handleType;3015pExternalFenceProperties->exportFromImportedHandleTypes = 0;3016pExternalFenceProperties->externalFenceFeatures = 0;3017}3018}30193020void3021vn_GetPhysicalDeviceExternalSemaphoreProperties(3022VkPhysicalDevice physicalDevice,3023const VkPhysicalDeviceExternalSemaphoreInfo *pExternalSemaphoreInfo,3024VkExternalSemaphoreProperties *pExternalSemaphoreProperties)3025{3026struct vn_physical_device *physical_dev =3027vn_physical_device_from_handle(physicalDevice);30283029const VkSemaphoreTypeCreateInfoKHR *type_info = vk_find_struct_const(3030pExternalSemaphoreInfo->pNext, SEMAPHORE_TYPE_CREATE_INFO_KHR);3031const VkSemaphoreType sem_type =3032type_info ? type_info->semaphoreType : VK_SEMAPHORE_TYPE_BINARY;3033const VkExternalSemaphoreHandleTypeFlags valid_handles =3034sem_type == VK_SEMAPHORE_TYPE_BINARY3035? physical_dev->external_binary_semaphore_handles3036: physical_dev->external_timeline_semaphore_handles;3037if (pExternalSemaphoreInfo->handleType & valid_handles) {3038pExternalSemaphoreProperties->compatibleHandleTypes = valid_handles;3039pExternalSemaphoreProperties->exportFromImportedHandleTypes =3040valid_handles;3041pExternalSemaphoreProperties->externalSemaphoreFeatures =3042VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT |3043VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT;3044} else {3045pExternalSemaphoreProperties->compatibleHandleTypes =3046pExternalSemaphoreInfo->handleType;3047pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0;3048pExternalSemaphoreProperties->externalSemaphoreFeatures = 0;3049}3050}30513052/* device commands */30533054VkResult3055vn_EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,3056const char *pLayerName,3057uint32_t *pPropertyCount,3058VkExtensionProperties *pProperties)3059{3060struct vn_physical_device *physical_dev =3061vn_physical_device_from_handle(physicalDevice);30623063if (pLayerName)3064return vn_error(physical_dev->instance, VK_ERROR_LAYER_NOT_PRESENT);30653066VK_OUTARRAY_MAKE(out, pProperties, pPropertyCount);3067for (uint32_t i = 0; i < VK_DEVICE_EXTENSION_COUNT; i++) {3068if (physical_dev->base.base.supported_extensions.extensions[i]) {3069vk_outarray_append(&out, prop) {3070*prop = vk_device_extensions[i];3071prop->specVersion = physical_dev->extension_spec_versions[i];3072}3073}3074}30753076return vk_outarray_status(&out);3077}30783079VkResult3080vn_EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,3081uint32_t *pPropertyCount,3082VkLayerProperties *pProperties)3083{3084*pPropertyCount = 0;3085return VK_SUCCESS;3086}30873088static void3089vn_queue_fini(struct vn_queue *queue)3090{3091if (queue->wait_fence != VK_NULL_HANDLE) {3092vn_DestroyFence(vn_device_to_handle(queue->device), queue->wait_fence,3093NULL);3094}3095vn_object_base_fini(&queue->base);3096}30973098static VkResult3099vn_queue_init(struct vn_device *dev,3100struct vn_queue *queue,3101const VkDeviceQueueCreateInfo *queue_info,3102uint32_t queue_index)3103{3104vn_object_base_init(&queue->base, VK_OBJECT_TYPE_QUEUE, &dev->base);31053106VkQueue queue_handle = vn_queue_to_handle(queue);3107vn_async_vkGetDeviceQueue2(3108dev->instance, vn_device_to_handle(dev),3109&(VkDeviceQueueInfo2){3110.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2,3111.flags = queue_info->flags,3112.queueFamilyIndex = queue_info->queueFamilyIndex,3113.queueIndex = queue_index,3114},3115&queue_handle);31163117queue->device = dev;3118queue->family = queue_info->queueFamilyIndex;3119queue->index = queue_index;3120queue->flags = queue_info->flags;31213122const VkExportFenceCreateInfo export_fence_info = {3123.sType = VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO,3124.pNext = NULL,3125.handleTypes = VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT,3126};3127const VkFenceCreateInfo fence_info = {3128.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,3129.pNext = dev->instance->experimental.globalFencing == VK_TRUE3130? &export_fence_info3131: NULL,3132.flags = 0,3133};3134VkResult result = vn_CreateFence(vn_device_to_handle(dev), &fence_info,3135NULL, &queue->wait_fence);3136if (result != VK_SUCCESS)3137return result;31383139return VK_SUCCESS;3140}31413142static VkResult3143vn_device_init_queues(struct vn_device *dev,3144const VkDeviceCreateInfo *create_info)3145{3146const VkAllocationCallbacks *alloc = &dev->base.base.alloc;31473148uint32_t count = 0;3149for (uint32_t i = 0; i < create_info->queueCreateInfoCount; i++)3150count += create_info->pQueueCreateInfos[i].queueCount;31513152struct vn_queue *queues =3153vk_zalloc(alloc, sizeof(*queues) * count, VN_DEFAULT_ALIGN,3154VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);3155if (!queues)3156return VK_ERROR_OUT_OF_HOST_MEMORY;31573158VkResult result = VK_SUCCESS;3159count = 0;3160for (uint32_t i = 0; i < create_info->queueCreateInfoCount; i++) {3161const VkDeviceQueueCreateInfo *queue_info =3162&create_info->pQueueCreateInfos[i];3163for (uint32_t j = 0; j < queue_info->queueCount; j++) {3164result = vn_queue_init(dev, &queues[count], queue_info, j);3165if (result != VK_SUCCESS)3166break;31673168count++;3169}3170}31713172if (result != VK_SUCCESS) {3173for (uint32_t i = 0; i < count; i++)3174vn_queue_fini(&queues[i]);3175vk_free(alloc, queues);31763177return result;3178}31793180dev->queues = queues;3181dev->queue_count = count;31823183return VK_SUCCESS;3184}31853186static bool3187find_extension_names(const char *const *exts,3188uint32_t ext_count,3189const char *name)3190{3191for (uint32_t i = 0; i < ext_count; i++) {3192if (!strcmp(exts[i], name))3193return true;3194}3195return false;3196}31973198static bool3199merge_extension_names(const char *const *exts,3200uint32_t ext_count,3201const char *const *extra_exts,3202uint32_t extra_count,3203const char *const *block_exts,3204uint32_t block_count,3205const VkAllocationCallbacks *alloc,3206const char *const **out_exts,3207uint32_t *out_count)3208{3209const char **merged =3210vk_alloc(alloc, sizeof(*merged) * (ext_count + extra_count),3211VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);3212if (!merged)3213return false;32143215uint32_t count = 0;3216for (uint32_t i = 0; i < ext_count; i++) {3217if (!find_extension_names(block_exts, block_count, exts[i]))3218merged[count++] = exts[i];3219}3220for (uint32_t i = 0; i < extra_count; i++) {3221if (!find_extension_names(exts, ext_count, extra_exts[i]))3222merged[count++] = extra_exts[i];3223}32243225*out_exts = merged;3226*out_count = count;3227return true;3228}32293230static const VkDeviceCreateInfo *3231vn_device_fix_create_info(const struct vn_device *dev,3232const VkDeviceCreateInfo *dev_info,3233const VkAllocationCallbacks *alloc,3234VkDeviceCreateInfo *local_info)3235{3236const struct vn_physical_device *physical_dev = dev->physical_device;3237const struct vk_device_extension_table *app_exts =3238&dev->base.base.enabled_extensions;3239/* extra_exts and block_exts must not overlap */3240const char *extra_exts[16];3241const char *block_exts[16];3242uint32_t extra_count = 0;3243uint32_t block_count = 0;32443245/* fix for WSI (treat AHB as WSI extension for simplicity) */3246const bool has_wsi =3247app_exts->KHR_swapchain || app_exts->ANDROID_native_buffer ||3248app_exts->ANDROID_external_memory_android_hardware_buffer;3249if (has_wsi) {3250/* KHR_swapchain may be advertised without the renderer support for3251* EXT_image_drm_format_modifier3252*/3253if (!app_exts->EXT_image_drm_format_modifier &&3254physical_dev->renderer_extensions.EXT_image_drm_format_modifier) {3255extra_exts[extra_count++] =3256VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME;32573258if (physical_dev->renderer_version < VK_API_VERSION_1_2 &&3259!app_exts->KHR_image_format_list) {3260extra_exts[extra_count++] =3261VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME;3262}3263}32643265/* XXX KHR_swapchain may be advertised without the renderer support for3266* EXT_queue_family_foreign3267*/3268if (!app_exts->EXT_queue_family_foreign &&3269physical_dev->renderer_extensions.EXT_queue_family_foreign) {3270extra_exts[extra_count++] =3271VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME;3272}32733274if (app_exts->KHR_swapchain) {3275/* see vn_physical_device_get_native_extensions */3276block_exts[block_count++] = VK_KHR_SWAPCHAIN_EXTENSION_NAME;3277block_exts[block_count++] =3278VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME;3279block_exts[block_count++] =3280VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME;3281}32823283if (app_exts->ANDROID_native_buffer)3284block_exts[block_count++] = VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME;32853286if (app_exts->ANDROID_external_memory_android_hardware_buffer) {3287block_exts[block_count++] =3288VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME;3289}3290}32913292if (app_exts->KHR_external_memory_fd ||3293app_exts->EXT_external_memory_dma_buf || has_wsi) {3294switch (physical_dev->external_memory.renderer_handle_type) {3295case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:3296if (!app_exts->EXT_external_memory_dma_buf) {3297extra_exts[extra_count++] =3298VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME;3299}3300FALLTHROUGH;3301case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:3302if (!app_exts->KHR_external_memory_fd) {3303extra_exts[extra_count++] =3304VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME;3305}3306break;3307default:3308/* TODO other handle types */3309break;3310}3311}33123313assert(extra_count <= ARRAY_SIZE(extra_exts));3314assert(block_count <= ARRAY_SIZE(block_exts));33153316if (!extra_count && (!block_count || !dev_info->enabledExtensionCount))3317return dev_info;33183319*local_info = *dev_info;3320if (!merge_extension_names(dev_info->ppEnabledExtensionNames,3321dev_info->enabledExtensionCount, extra_exts,3322extra_count, block_exts, block_count, alloc,3323&local_info->ppEnabledExtensionNames,3324&local_info->enabledExtensionCount))3325return NULL;33263327return local_info;3328}33293330VkResult3331vn_CreateDevice(VkPhysicalDevice physicalDevice,3332const VkDeviceCreateInfo *pCreateInfo,3333const VkAllocationCallbacks *pAllocator,3334VkDevice *pDevice)3335{3336struct vn_physical_device *physical_dev =3337vn_physical_device_from_handle(physicalDevice);3338struct vn_instance *instance = physical_dev->instance;3339const VkAllocationCallbacks *alloc =3340pAllocator ? pAllocator : &instance->base.base.alloc;3341struct vn_device *dev;3342VkResult result;33433344dev = vk_zalloc(alloc, sizeof(*dev), VN_DEFAULT_ALIGN,3345VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);3346if (!dev)3347return vn_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY);33483349struct vk_device_dispatch_table dispatch_table;3350vk_device_dispatch_table_from_entrypoints(&dispatch_table,3351&vn_device_entrypoints, true);3352result = vn_device_base_init(&dev->base, &physical_dev->base,3353&dispatch_table, pCreateInfo, alloc);3354if (result != VK_SUCCESS) {3355vk_free(alloc, dev);3356return vn_error(instance, result);3357}33583359dev->instance = instance;3360dev->physical_device = physical_dev;3361dev->renderer = instance->renderer;33623363VkDeviceCreateInfo local_create_info;3364pCreateInfo =3365vn_device_fix_create_info(dev, pCreateInfo, alloc, &local_create_info);3366if (!pCreateInfo) {3367result = VK_ERROR_OUT_OF_HOST_MEMORY;3368goto fail;3369}33703371VkDevice dev_handle = vn_device_to_handle(dev);3372result = vn_call_vkCreateDevice(instance, physicalDevice, pCreateInfo,3373NULL, &dev_handle);3374if (result != VK_SUCCESS)3375goto fail;33763377result = vn_device_init_queues(dev, pCreateInfo);3378if (result != VK_SUCCESS) {3379vn_call_vkDestroyDevice(instance, dev_handle, NULL);3380goto fail;3381}33823383for (uint32_t i = 0; i < ARRAY_SIZE(dev->memory_pools); i++) {3384struct vn_device_memory_pool *pool = &dev->memory_pools[i];3385mtx_init(&pool->mutex, mtx_plain);3386}33873388if (dev->base.base.enabled_extensions3389.ANDROID_external_memory_android_hardware_buffer) {3390result = vn_android_init_ahb_buffer_memory_type_bits(dev);3391if (result != VK_SUCCESS) {3392vn_call_vkDestroyDevice(instance, dev_handle, NULL);3393goto fail;3394}3395}33963397*pDevice = dev_handle;33983399if (pCreateInfo == &local_create_info)3400vk_free(alloc, (void *)pCreateInfo->ppEnabledExtensionNames);34013402return VK_SUCCESS;34033404fail:3405if (pCreateInfo == &local_create_info)3406vk_free(alloc, (void *)pCreateInfo->ppEnabledExtensionNames);3407vn_device_base_fini(&dev->base);3408vk_free(alloc, dev);3409return vn_error(instance, result);3410}34113412void3413vn_DestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator)3414{3415struct vn_device *dev = vn_device_from_handle(device);3416const VkAllocationCallbacks *alloc =3417pAllocator ? pAllocator : &dev->base.base.alloc;34183419if (!dev)3420return;34213422for (uint32_t i = 0; i < ARRAY_SIZE(dev->memory_pools); i++)3423vn_device_memory_pool_fini(dev, i);34243425for (uint32_t i = 0; i < dev->queue_count; i++)3426vn_queue_fini(&dev->queues[i]);34273428/* We must emit vkDestroyDevice before freeing dev->queues. Otherwise,3429* another thread might reuse their object ids while they still refer to3430* the queues in the renderer.3431*/3432vn_async_vkDestroyDevice(dev->instance, device, NULL);34333434vk_free(alloc, dev->queues);34353436vn_device_base_fini(&dev->base);3437vk_free(alloc, dev);3438}34393440PFN_vkVoidFunction3441vn_GetDeviceProcAddr(VkDevice device, const char *pName)3442{3443struct vn_device *dev = vn_device_from_handle(device);3444return vk_device_get_proc_addr(&dev->base.base, pName);3445}34463447void3448vn_GetDeviceGroupPeerMemoryFeatures(3449VkDevice device,3450uint32_t heapIndex,3451uint32_t localDeviceIndex,3452uint32_t remoteDeviceIndex,3453VkPeerMemoryFeatureFlags *pPeerMemoryFeatures)3454{3455struct vn_device *dev = vn_device_from_handle(device);34563457/* TODO get and cache the values in vkCreateDevice */3458vn_call_vkGetDeviceGroupPeerMemoryFeatures(3459dev->instance, device, heapIndex, localDeviceIndex, remoteDeviceIndex,3460pPeerMemoryFeatures);3461}34623463VkResult3464vn_DeviceWaitIdle(VkDevice device)3465{3466struct vn_device *dev = vn_device_from_handle(device);34673468for (uint32_t i = 0; i < dev->queue_count; i++) {3469struct vn_queue *queue = &dev->queues[i];3470VkResult result = vn_QueueWaitIdle(vn_queue_to_handle(queue));3471if (result != VK_SUCCESS)3472return vn_error(dev->instance, result);3473}34743475return VK_SUCCESS;3476}347734783479