diff --git a/src/meson.build b/src/meson.build index 760f1f8..6542ad4 100644 --- a/src/meson.build +++ b/src/meson.build @@ -95,7 +95,9 @@ venus_sources = [ 'venus/vkr_device_memory.h', 'venus/vkr_image.c', 'venus/vkr_image.h', + 'venus/vkr_instance.c', 'venus/vkr_instance.h', + 'venus/vkr_physical_device.c', 'venus/vkr_physical_device.h', 'venus/vkr_pipeline.c', 'venus/vkr_pipeline.h', diff --git a/src/venus/vkr_device.c b/src/venus/vkr_device.c index 086ca25..49e00d9 100644 --- a/src/venus/vkr_device.c +++ b/src/venus/vkr_device.c @@ -6,845 +6,14 @@ #include "vkr_device.h" #include "venus-protocol/vn_protocol_renderer_device.h" -#include "venus-protocol/vn_protocol_renderer_info.h" -#include "venus-protocol/vn_protocol_renderer_instance.h" #include "vkr_command_buffer.h" #include "vkr_context.h" #include "vkr_descriptor_set.h" #include "vkr_device_memory.h" -#include "vkr_instance.h" #include "vkr_physical_device.h" #include "vkr_queue.h" -static void -vkr_dispatch_vkEnumerateInstanceVersion(struct vn_dispatch_context *dispatch, - struct vn_command_vkEnumerateInstanceVersion *args) -{ - struct vkr_context *ctx = dispatch->data; - - if (!args->pApiVersion) { - vkr_cs_decoder_set_fatal(&ctx->decoder); - return; - } - - vn_replace_vkEnumerateInstanceVersion_args_handle(args); - args->ret = vkEnumerateInstanceVersion(args->pApiVersion); -} - -static void -vkr_dispatch_vkEnumerateInstanceExtensionProperties( - struct vn_dispatch_context *dispatch, - struct vn_command_vkEnumerateInstanceExtensionProperties *args) -{ - struct vkr_context *ctx = dispatch->data; - - VkExtensionProperties private_extensions[] = { - { - .extensionName = "VK_EXT_command_serialization", - }, - { - .extensionName = "VK_MESA_venus_protocol", - }, - }; - - if (!args->pPropertyCount) { - vkr_cs_decoder_set_fatal(&ctx->decoder); - return; - } - - if (!args->pProperties) { - *args->pPropertyCount = ARRAY_SIZE(private_extensions); - args->ret = VK_SUCCESS; - return; - } - - for (uint32_t i = 0; i < ARRAY_SIZE(private_extensions); i++) { - VkExtensionProperties *props = &private_extensions[i]; - props->specVersion = vn_info_extension_spec_version(props->extensionName); - } - - const uint32_t count = MIN2(*args->pPropertyCount, ARRAY_SIZE(private_extensions)); - memcpy(args->pProperties, private_extensions, sizeof(*args->pProperties) * count); - *args->pPropertyCount = count; - args->ret = count == ARRAY_SIZE(private_extensions) ? VK_SUCCESS : VK_INCOMPLETE; -} - -static VkBool32 -vkr_validation_callback(UNUSED VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, - UNUSED VkDebugUtilsMessageTypeFlagsEXT messageTypes, - const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData, - void *pUserData) -{ - struct vkr_context *ctx = pUserData; - - vrend_printf("%s\n", pCallbackData->pMessage); - - if (!ctx->validate_fatal) - return false; - - vkr_cs_decoder_set_fatal(&ctx->decoder); - - /* The spec says we "should" return false, because the meaning of true is - * layer-defined and is reserved for layer development. And we know that, - * for VK_LAYER_KHRONOS_validation, the return value indicates whether the - * call should be skipped. Let's do it for now and seek advices. - */ - return true; -} - -static void -vkr_dispatch_vkCreateInstance(struct vn_dispatch_context *dispatch, - struct vn_command_vkCreateInstance *args) -{ - struct vkr_context *ctx = dispatch->data; - - if (ctx->instance) { - vkr_cs_decoder_set_fatal(&ctx->decoder); - return; - } - - if (!args->pCreateInfo) { - vkr_cs_decoder_set_fatal(&ctx->decoder); - return; - } - - if (args->pCreateInfo->enabledLayerCount) { - args->ret = VK_ERROR_LAYER_NOT_PRESENT; - return; - } - - if (args->pCreateInfo->enabledExtensionCount) { - args->ret = VK_ERROR_EXTENSION_NOT_PRESENT; - return; - } - - uint32_t instance_version; - args->ret = vkEnumerateInstanceVersion(&instance_version); - if (args->ret != VK_SUCCESS) - return; - - /* require Vulkan 1.1 */ - if (instance_version < VK_API_VERSION_1_1) { - args->ret = VK_ERROR_INITIALIZATION_FAILED; - return; - } - - VkInstanceCreateInfo *create_info = (VkInstanceCreateInfo *)args->pCreateInfo; - const char *layer_names[8]; - const char *ext_names[8]; - uint32_t layer_count = 0; - uint32_t ext_count = 0; - - /* TODO enable more validation features */ - const VkValidationFeatureDisableEXT validation_feature_disables_on[] = { - VK_VALIDATION_FEATURE_DISABLE_THREAD_SAFETY_EXT, - VK_VALIDATION_FEATURE_DISABLE_SHADERS_EXT, - VK_VALIDATION_FEATURE_DISABLE_OBJECT_LIFETIMES_EXT, - VK_VALIDATION_FEATURE_DISABLE_CORE_CHECKS_EXT, - VK_VALIDATION_FEATURE_DISABLE_UNIQUE_HANDLES_EXT, - }; - /* we are single-threaded */ - const VkValidationFeatureDisableEXT validation_feature_disables_full[] = { - VK_VALIDATION_FEATURE_DISABLE_THREAD_SAFETY_EXT, - }; - VkValidationFeaturesEXT validation_features; - VkDebugUtilsMessengerCreateInfoEXT messenger_create_info; - if (ctx->validate_level != VKR_CONTEXT_VALIDATE_NONE) { - /* let vkCreateInstance return VK_ERROR_LAYER_NOT_PRESENT or - * VK_ERROR_EXTENSION_NOT_PRESENT when the layer or extensions are - * missing - */ - layer_names[layer_count++] = "VK_LAYER_KHRONOS_validation"; - ext_names[ext_count++] = VK_EXT_DEBUG_UTILS_EXTENSION_NAME; - ext_names[ext_count++] = VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME; - - validation_features = (const VkValidationFeaturesEXT){ - .sType = VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT, - .pNext = create_info->pNext, - }; - if (ctx->validate_level == VKR_CONTEXT_VALIDATE_ON) { - validation_features.disabledValidationFeatureCount = - ARRAY_SIZE(validation_feature_disables_on); - validation_features.pDisabledValidationFeatures = validation_feature_disables_on; - } else { - validation_features.disabledValidationFeatureCount = - ARRAY_SIZE(validation_feature_disables_full); - validation_features.pDisabledValidationFeatures = - validation_feature_disables_full; - } - messenger_create_info = (VkDebugUtilsMessengerCreateInfoEXT){ - .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT, - .pNext = &validation_features, - .messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, - .messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT, - .pfnUserCallback = vkr_validation_callback, - .pUserData = ctx, - }; - - create_info->pNext = &messenger_create_info; - } - - assert(layer_count <= ARRAY_SIZE(layer_names)); - create_info->enabledLayerCount = layer_count; - create_info->ppEnabledLayerNames = layer_names; - - assert(ext_count <= ARRAY_SIZE(ext_names)); - create_info->enabledExtensionCount = ext_count; - create_info->ppEnabledExtensionNames = ext_names; - - /* patch apiVersion */ - VkApplicationInfo app_info = { - .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, - .apiVersion = VK_API_VERSION_1_1, - }; - if (create_info->pApplicationInfo) { - app_info = *create_info->pApplicationInfo; - if (app_info.apiVersion < VK_API_VERSION_1_1) - app_info.apiVersion = VK_API_VERSION_1_1; - } - create_info->pApplicationInfo = &app_info; - - struct vkr_instance *instance = calloc(1, sizeof(*instance)); - if (!instance) { - args->ret = VK_ERROR_OUT_OF_HOST_MEMORY; - return; - } - - instance->base.type = VK_OBJECT_TYPE_INSTANCE; - instance->base.id = - vkr_cs_handle_load_id((const void **)args->pInstance, instance->base.type); - instance->api_version = app_info.apiVersion; - - vn_replace_vkCreateInstance_args_handle(args); - args->ret = vkCreateInstance(create_info, NULL, &instance->base.handle.instance); - if (args->ret != VK_SUCCESS) { - free(instance); - return; - } - - instance->get_memory_fd = (PFN_vkGetMemoryFdKHR)vkGetInstanceProcAddr( - instance->base.handle.instance, "vkGetMemoryFdKHR"); - instance->get_fence_fd = (PFN_vkGetFenceFdKHR)vkGetInstanceProcAddr( - instance->base.handle.instance, "vkGetFenceFdKHR"); - - if (ctx->validate_level != VKR_CONTEXT_VALIDATE_NONE) { - instance->create_debug_utils_messenger = - (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr( - instance->base.handle.instance, "vkCreateDebugUtilsMessengerEXT"); - instance->destroy_debug_utils_messenger = - (PFN_vkDestroyDebugUtilsMessengerEXT)vkGetInstanceProcAddr( - instance->base.handle.instance, "vkDestroyDebugUtilsMessengerEXT"); - - messenger_create_info.pNext = NULL; - args->ret = instance->create_debug_utils_messenger(instance->base.handle.instance, - &messenger_create_info, NULL, - &instance->validation_messenger); - if (args->ret != VK_SUCCESS) { - vkDestroyInstance(instance->base.handle.instance, NULL); - free(instance); - return; - } - } - - util_hash_table_set_u64(ctx->object_table, instance->base.id, instance); - - ctx->instance = instance; -} - -static void -vkr_device_destroy(struct vkr_context *ctx, struct vkr_device *dev); - -static void -vkr_physical_device_destroy(struct vkr_context *ctx, - struct vkr_physical_device *physical_dev) -{ - struct vkr_device *dev, *tmp; - LIST_FOR_EACH_ENTRY_SAFE (dev, tmp, &physical_dev->devices, base.track_head) - vkr_device_destroy(ctx, dev); - - free(physical_dev->extensions); - - util_hash_table_remove_u64(ctx->object_table, physical_dev->base.id); -} - -void -vkr_instance_destroy(struct vkr_context *ctx, struct vkr_instance *instance) -{ - for (uint32_t i = 0; i < instance->physical_device_count; i++) { - struct vkr_physical_device *physical_dev = instance->physical_devices[i]; - if (!physical_dev) - break; - - vkr_physical_device_destroy(ctx, physical_dev); - } - - if (ctx->validate_level != VKR_CONTEXT_VALIDATE_NONE) { - instance->destroy_debug_utils_messenger(instance->base.handle.instance, - instance->validation_messenger, NULL); - } - - vkDestroyInstance(instance->base.handle.instance, NULL); - - free(instance->physical_device_handles); - free(instance->physical_devices); - - util_hash_table_remove_u64(ctx->object_table, instance->base.id); -} - -static void -vkr_dispatch_vkDestroyInstance(struct vn_dispatch_context *dispatch, - struct vn_command_vkDestroyInstance *args) -{ - struct vkr_context *ctx = dispatch->data; - struct vkr_instance *instance = (struct vkr_instance *)args->instance; - - if (ctx->instance != instance) { - vkr_cs_decoder_set_fatal(&ctx->decoder); - return; - } - - vkr_instance_destroy(ctx, instance); - - ctx->instance = NULL; -} - -static VkResult -vkr_instance_enumerate_physical_devices(struct vkr_instance *instance) -{ - if (instance->physical_device_count) - return VK_SUCCESS; - - uint32_t count; - VkResult result = - vkEnumeratePhysicalDevices(instance->base.handle.instance, &count, NULL); - if (result != VK_SUCCESS) - return result; - - VkPhysicalDevice *handles = calloc(count, sizeof(*handles)); - struct vkr_physical_device **physical_devs = calloc(count, sizeof(*physical_devs)); - if (!handles || !physical_devs) { - free(physical_devs); - free(handles); - return VK_ERROR_OUT_OF_HOST_MEMORY; - } - - result = vkEnumeratePhysicalDevices(instance->base.handle.instance, &count, handles); - if (result != VK_SUCCESS) { - free(physical_devs); - free(handles); - return result; - } - - instance->physical_device_count = count; - instance->physical_device_handles = handles; - instance->physical_devices = physical_devs; - - return VK_SUCCESS; -} - -static struct vkr_physical_device * -vkr_instance_lookup_physical_device(struct vkr_instance *instance, - VkPhysicalDevice handle) -{ - for (uint32_t i = 0; i < instance->physical_device_count; i++) { - /* XXX this assumes VkPhysicalDevice handles are unique */ - if (instance->physical_device_handles[i] == handle) - return instance->physical_devices[i]; - } - return NULL; -} - -static void -vkr_physical_device_init_memory_properties(struct vkr_physical_device *physical_dev) -{ - VkPhysicalDevice handle = physical_dev->base.handle.physical_device; - vkGetPhysicalDeviceMemoryProperties(handle, &physical_dev->memory_properties); -} - -static void -vkr_physical_device_init_extensions(struct vkr_physical_device *physical_dev, - struct vkr_instance *instance) -{ - VkPhysicalDevice handle = physical_dev->base.handle.physical_device; - - VkExtensionProperties *exts; - uint32_t count; - VkResult result = vkEnumerateDeviceExtensionProperties(handle, NULL, &count, NULL); - if (result != VK_SUCCESS) - return; - - exts = malloc(sizeof(*exts) * count); - if (!exts) - return; - - result = vkEnumerateDeviceExtensionProperties(handle, NULL, &count, exts); - if (result != VK_SUCCESS) { - free(exts); - return; - } - - uint32_t advertised_count = 0; - for (uint32_t i = 0; i < count; i++) { - VkExtensionProperties *props = &exts[i]; - - if (!strcmp(props->extensionName, "VK_KHR_external_memory_fd")) - physical_dev->KHR_external_memory_fd = true; - else if (!strcmp(props->extensionName, "VK_EXT_external_memory_dma_buf")) - physical_dev->EXT_external_memory_dma_buf = true; - else if (!strcmp(props->extensionName, "VK_KHR_external_fence_fd")) - physical_dev->KHR_external_fence_fd = true; - - const uint32_t spec_ver = vn_info_extension_spec_version(props->extensionName); - if (spec_ver) { - if (props->specVersion > spec_ver) - props->specVersion = spec_ver; - exts[advertised_count++] = exts[i]; - } - } - - if (physical_dev->KHR_external_fence_fd) { - const VkPhysicalDeviceExternalFenceInfo fence_info = { - .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO, - .handleType = VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT, - }; - VkExternalFenceProperties fence_props = { - .sType = VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES, - }; - PFN_vkGetPhysicalDeviceExternalFenceProperties get_fence_props = - (PFN_vkGetPhysicalDeviceExternalFenceProperties)vkGetInstanceProcAddr( - instance->base.handle.instance, "vkGetPhysicalDeviceExternalFenceProperties"); - get_fence_props(handle, &fence_info, &fence_props); - - if (!(fence_props.externalFenceFeatures & VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT)) - physical_dev->KHR_external_fence_fd = false; - } - - physical_dev->extensions = exts; - physical_dev->extension_count = advertised_count; -} - -static void -vkr_physical_device_init_properties(struct vkr_physical_device *physical_dev) -{ - VkPhysicalDevice handle = physical_dev->base.handle.physical_device; - vkGetPhysicalDeviceProperties(handle, &physical_dev->properties); - - VkPhysicalDeviceProperties *props = &physical_dev->properties; - props->driverVersion = 0; - - /* TODO lie about props->pipelineCacheUUID and patch cache header */ -} - -static void -vkr_dispatch_vkEnumeratePhysicalDevices(struct vn_dispatch_context *dispatch, - struct vn_command_vkEnumeratePhysicalDevices *args) -{ - struct vkr_context *ctx = dispatch->data; - - struct vkr_instance *instance = (struct vkr_instance *)args->instance; - if (instance != ctx->instance) { - vkr_cs_decoder_set_fatal(&ctx->decoder); - return; - } - - args->ret = vkr_instance_enumerate_physical_devices(instance); - if (args->ret != VK_SUCCESS) - return; - - uint32_t count = instance->physical_device_count; - if (!args->pPhysicalDevices) { - *args->pPhysicalDeviceCount = count; - args->ret = VK_SUCCESS; - return; - } - - if (count > *args->pPhysicalDeviceCount) { - count = *args->pPhysicalDeviceCount; - args->ret = VK_INCOMPLETE; - } else { - *args->pPhysicalDeviceCount = count; - args->ret = VK_SUCCESS; - } - - uint32_t i; - for (i = 0; i < count; i++) { - struct vkr_physical_device *physical_dev = instance->physical_devices[i]; - const vkr_object_id id = vkr_cs_handle_load_id( - (const void **)&args->pPhysicalDevices[i], VK_OBJECT_TYPE_PHYSICAL_DEVICE); - - if (physical_dev) { - if (physical_dev->base.id != id) { - vkr_cs_decoder_set_fatal(&ctx->decoder); - break; - } - continue; - } - - physical_dev = calloc(1, sizeof(*physical_dev)); - if (!physical_dev) { - args->ret = VK_ERROR_OUT_OF_HOST_MEMORY; - break; - } - - physical_dev->base.type = VK_OBJECT_TYPE_PHYSICAL_DEVICE; - physical_dev->base.id = id; - physical_dev->base.handle.physical_device = instance->physical_device_handles[i]; - - vkr_physical_device_init_properties(physical_dev); - physical_dev->api_version = - MIN2(physical_dev->properties.apiVersion, instance->api_version); - vkr_physical_device_init_extensions(physical_dev, instance); - vkr_physical_device_init_memory_properties(physical_dev); - - list_inithead(&physical_dev->devices); - - instance->physical_devices[i] = physical_dev; - - util_hash_table_set_u64(ctx->object_table, physical_dev->base.id, physical_dev); - } - /* remove all physical devices on errors */ - if (i < count) { - for (i = 0; i < instance->physical_device_count; i++) { - struct vkr_physical_device *physical_dev = instance->physical_devices[i]; - if (!physical_dev) - break; - free(physical_dev->extensions); - util_hash_table_remove_u64(ctx->object_table, physical_dev->base.id); - instance->physical_devices[i] = NULL; - } - } -} - -static void -vkr_dispatch_vkEnumeratePhysicalDeviceGroups( - struct vn_dispatch_context *dispatch, - struct vn_command_vkEnumeratePhysicalDeviceGroups *args) -{ - struct vkr_context *ctx = dispatch->data; - - struct vkr_instance *instance = (struct vkr_instance *)args->instance; - if (instance != ctx->instance) { - vkr_cs_decoder_set_fatal(&ctx->decoder); - return; - } - - args->ret = vkr_instance_enumerate_physical_devices(instance); - if (args->ret != VK_SUCCESS) - return; - - VkPhysicalDeviceGroupProperties *orig_props = args->pPhysicalDeviceGroupProperties; - if (orig_props) { - args->pPhysicalDeviceGroupProperties = - malloc(sizeof(*orig_props) * *args->pPhysicalDeviceGroupCount); - if (!args->pPhysicalDeviceGroupProperties) { - args->ret = VK_ERROR_OUT_OF_HOST_MEMORY; - return; - } - } - - vn_replace_vkEnumeratePhysicalDeviceGroups_args_handle(args); - args->ret = - vkEnumeratePhysicalDeviceGroups(args->instance, args->pPhysicalDeviceGroupCount, - args->pPhysicalDeviceGroupProperties); - if (args->ret != VK_SUCCESS) - return; - - if (!orig_props) - return; - - /* XXX this assumes vkEnumeratePhysicalDevices is called first */ - /* replace VkPhysicalDevice handles by object ids */ - for (uint32_t i = 0; i < *args->pPhysicalDeviceGroupCount; i++) { - const VkPhysicalDeviceGroupProperties *props = - &args->pPhysicalDeviceGroupProperties[i]; - VkPhysicalDeviceGroupProperties *out = &orig_props[i]; - - out->physicalDeviceCount = props->physicalDeviceCount; - out->subsetAllocation = props->subsetAllocation; - for (uint32_t j = 0; j < props->physicalDeviceCount; j++) { - const struct vkr_physical_device *physical_dev = - vkr_instance_lookup_physical_device(instance, props->physicalDevices[j]); - vkr_cs_handle_store_id((void **)&out->physicalDevices[j], physical_dev->base.id, - VK_OBJECT_TYPE_PHYSICAL_DEVICE); - } - } - - free(args->pPhysicalDeviceGroupProperties); - args->pPhysicalDeviceGroupProperties = orig_props; -} - -static void -vkr_dispatch_vkEnumerateDeviceExtensionProperties( - struct vn_dispatch_context *dispatch, - struct vn_command_vkEnumerateDeviceExtensionProperties *args) -{ - struct vkr_context *ctx = dispatch->data; - - struct vkr_physical_device *physical_dev = - (struct vkr_physical_device *)args->physicalDevice; - if (!physical_dev || physical_dev->base.type != VK_OBJECT_TYPE_PHYSICAL_DEVICE) { - vkr_cs_decoder_set_fatal(&ctx->decoder); - return; - } - if (args->pLayerName) { - vkr_cs_decoder_set_fatal(&ctx->decoder); - return; - } - - if (!args->pProperties) { - *args->pPropertyCount = physical_dev->extension_count; - args->ret = VK_SUCCESS; - return; - } - - uint32_t count = physical_dev->extension_count; - if (count > *args->pPropertyCount) { - count = *args->pPropertyCount; - args->ret = VK_INCOMPLETE; - } else { - *args->pPropertyCount = count; - args->ret = VK_SUCCESS; - } - - memcpy(args->pProperties, physical_dev->extensions, - sizeof(*args->pProperties) * count); -} - -static void -vkr_dispatch_vkGetPhysicalDeviceFeatures( - UNUSED struct vn_dispatch_context *dispatch, - struct vn_command_vkGetPhysicalDeviceFeatures *args) -{ - vn_replace_vkGetPhysicalDeviceFeatures_args_handle(args); - vkGetPhysicalDeviceFeatures(args->physicalDevice, args->pFeatures); -} - -static void -vkr_dispatch_vkGetPhysicalDeviceProperties( - struct vn_dispatch_context *dispatch, - struct vn_command_vkGetPhysicalDeviceProperties *args) -{ - struct vkr_context *ctx = dispatch->data; - struct vkr_physical_device *physical_dev = - (struct vkr_physical_device *)args->physicalDevice; - if (!physical_dev || physical_dev->base.type != VK_OBJECT_TYPE_PHYSICAL_DEVICE) { - vkr_cs_decoder_set_fatal(&ctx->decoder); - return; - } - - *args->pProperties = physical_dev->properties; -} - -static void -vkr_dispatch_vkGetPhysicalDeviceQueueFamilyProperties( - UNUSED struct vn_dispatch_context *dispatch, - struct vn_command_vkGetPhysicalDeviceQueueFamilyProperties *args) -{ - vn_replace_vkGetPhysicalDeviceQueueFamilyProperties_args_handle(args); - vkGetPhysicalDeviceQueueFamilyProperties(args->physicalDevice, - args->pQueueFamilyPropertyCount, - args->pQueueFamilyProperties); -} - -static void -vkr_dispatch_vkGetPhysicalDeviceMemoryProperties( - UNUSED struct vn_dispatch_context *dispatch, - struct vn_command_vkGetPhysicalDeviceMemoryProperties *args) -{ - /* TODO lie about this */ - vn_replace_vkGetPhysicalDeviceMemoryProperties_args_handle(args); - vkGetPhysicalDeviceMemoryProperties(args->physicalDevice, args->pMemoryProperties); -} - -static void -vkr_dispatch_vkGetPhysicalDeviceFormatProperties( - UNUSED struct vn_dispatch_context *dispatch, - struct vn_command_vkGetPhysicalDeviceFormatProperties *args) -{ - vn_replace_vkGetPhysicalDeviceFormatProperties_args_handle(args); - vkGetPhysicalDeviceFormatProperties(args->physicalDevice, args->format, - args->pFormatProperties); -} - -static void -vkr_dispatch_vkGetPhysicalDeviceImageFormatProperties( - UNUSED struct vn_dispatch_context *dispatch, - struct vn_command_vkGetPhysicalDeviceImageFormatProperties *args) -{ - vn_replace_vkGetPhysicalDeviceImageFormatProperties_args_handle(args); - args->ret = vkGetPhysicalDeviceImageFormatProperties( - args->physicalDevice, args->format, args->type, args->tiling, args->usage, - args->flags, args->pImageFormatProperties); -} - -static void -vkr_dispatch_vkGetPhysicalDeviceSparseImageFormatProperties( - UNUSED struct vn_dispatch_context *dispatch, - struct vn_command_vkGetPhysicalDeviceSparseImageFormatProperties *args) -{ - vn_replace_vkGetPhysicalDeviceSparseImageFormatProperties_args_handle(args); - vkGetPhysicalDeviceSparseImageFormatProperties( - args->physicalDevice, args->format, args->type, args->samples, args->usage, - args->tiling, args->pPropertyCount, args->pProperties); -} - -static void -vkr_dispatch_vkGetPhysicalDeviceFeatures2( - UNUSED struct vn_dispatch_context *dispatch, - struct vn_command_vkGetPhysicalDeviceFeatures2 *args) -{ - vn_replace_vkGetPhysicalDeviceFeatures2_args_handle(args); - vkGetPhysicalDeviceFeatures2(args->physicalDevice, args->pFeatures); -} - -static void -vkr_dispatch_vkGetPhysicalDeviceProperties2( - struct vn_dispatch_context *dispatch, - struct vn_command_vkGetPhysicalDeviceProperties2 *args) -{ - struct vkr_context *ctx = dispatch->data; - struct vkr_physical_device *physical_dev = - (struct vkr_physical_device *)args->physicalDevice; - if (!physical_dev || physical_dev->base.type != VK_OBJECT_TYPE_PHYSICAL_DEVICE) { - vkr_cs_decoder_set_fatal(&ctx->decoder); - return; - } - - vn_replace_vkGetPhysicalDeviceProperties2_args_handle(args); - vkGetPhysicalDeviceProperties2(args->physicalDevice, args->pProperties); - - union { - VkBaseOutStructure *pnext; - VkPhysicalDeviceProperties2 *props; - VkPhysicalDeviceVulkan11Properties *vk11; - VkPhysicalDeviceVulkan12Properties *vk12; - VkPhysicalDeviceIDProperties *id; - VkPhysicalDeviceDriverProperties *driver; - } u; - - u.pnext = (VkBaseOutStructure *)args->pProperties; - while (u.pnext) { - switch (u.pnext->sType) { - case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2: - u.props->properties = physical_dev->properties; - break; - case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES: - memset(u.vk11->deviceUUID, 0, sizeof(u.vk11->deviceUUID)); - memset(u.vk11->driverUUID, 0, sizeof(u.vk11->driverUUID)); - memset(u.vk11->deviceLUID, 0, sizeof(u.vk11->deviceLUID)); - u.vk11->deviceNodeMask = 0; - u.vk11->deviceLUIDValid = false; - break; - case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES: - u.vk12->driverID = 0; - memset(u.vk12->driverName, 0, sizeof(u.vk12->driverName)); - memset(u.vk12->driverInfo, 0, sizeof(u.vk12->driverInfo)); - memset(&u.vk12->conformanceVersion, 0, sizeof(u.vk12->conformanceVersion)); - break; - case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES: - memset(u.id->deviceUUID, 0, sizeof(u.id->deviceUUID)); - memset(u.id->driverUUID, 0, sizeof(u.id->driverUUID)); - memset(u.id->deviceLUID, 0, sizeof(u.id->deviceLUID)); - u.id->deviceNodeMask = 0; - u.id->deviceLUIDValid = false; - break; - case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES: - u.driver->driverID = 0; - memset(u.driver->driverName, 0, sizeof(u.driver->driverName)); - memset(u.driver->driverInfo, 0, sizeof(u.driver->driverInfo)); - memset(&u.driver->conformanceVersion, 0, sizeof(u.driver->conformanceVersion)); - break; - default: - break; - } - - u.pnext = u.pnext->pNext; - } -} - -static void -vkr_dispatch_vkGetPhysicalDeviceQueueFamilyProperties2( - UNUSED struct vn_dispatch_context *dispatch, - struct vn_command_vkGetPhysicalDeviceQueueFamilyProperties2 *args) -{ - vn_replace_vkGetPhysicalDeviceQueueFamilyProperties2_args_handle(args); - vkGetPhysicalDeviceQueueFamilyProperties2(args->physicalDevice, - args->pQueueFamilyPropertyCount, - args->pQueueFamilyProperties); -} - -static void -vkr_dispatch_vkGetPhysicalDeviceMemoryProperties2( - UNUSED struct vn_dispatch_context *dispatch, - struct vn_command_vkGetPhysicalDeviceMemoryProperties2 *args) -{ - /* TODO lie about this */ - vn_replace_vkGetPhysicalDeviceMemoryProperties2_args_handle(args); - vkGetPhysicalDeviceMemoryProperties2(args->physicalDevice, args->pMemoryProperties); -} - -static void -vkr_dispatch_vkGetPhysicalDeviceFormatProperties2( - UNUSED struct vn_dispatch_context *dispatch, - struct vn_command_vkGetPhysicalDeviceFormatProperties2 *args) -{ - vn_replace_vkGetPhysicalDeviceFormatProperties2_args_handle(args); - vkGetPhysicalDeviceFormatProperties2(args->physicalDevice, args->format, - args->pFormatProperties); -} - -static void -vkr_dispatch_vkGetPhysicalDeviceImageFormatProperties2( - UNUSED struct vn_dispatch_context *dispatch, - struct vn_command_vkGetPhysicalDeviceImageFormatProperties2 *args) -{ - vn_replace_vkGetPhysicalDeviceImageFormatProperties2_args_handle(args); - args->ret = vkGetPhysicalDeviceImageFormatProperties2( - args->physicalDevice, args->pImageFormatInfo, args->pImageFormatProperties); -} - -static void -vkr_dispatch_vkGetPhysicalDeviceSparseImageFormatProperties2( - UNUSED struct vn_dispatch_context *dispatch, - struct vn_command_vkGetPhysicalDeviceSparseImageFormatProperties2 *args) -{ - vn_replace_vkGetPhysicalDeviceSparseImageFormatProperties2_args_handle(args); - vkGetPhysicalDeviceSparseImageFormatProperties2( - args->physicalDevice, args->pFormatInfo, args->pPropertyCount, args->pProperties); -} - -static void -vkr_dispatch_vkGetPhysicalDeviceExternalBufferProperties( - UNUSED struct vn_dispatch_context *dispatch, - struct vn_command_vkGetPhysicalDeviceExternalBufferProperties *args) -{ - vn_replace_vkGetPhysicalDeviceExternalBufferProperties_args_handle(args); - vkGetPhysicalDeviceExternalBufferProperties( - args->physicalDevice, args->pExternalBufferInfo, args->pExternalBufferProperties); -} - -static void -vkr_dispatch_vkGetPhysicalDeviceExternalSemaphoreProperties( - UNUSED struct vn_dispatch_context *dispatch, - struct vn_command_vkGetPhysicalDeviceExternalSemaphoreProperties *args) -{ - vn_replace_vkGetPhysicalDeviceExternalSemaphoreProperties_args_handle(args); - vkGetPhysicalDeviceExternalSemaphoreProperties(args->physicalDevice, - args->pExternalSemaphoreInfo, - args->pExternalSemaphoreProperties); -} - -static void -vkr_dispatch_vkGetPhysicalDeviceExternalFenceProperties( - UNUSED struct vn_dispatch_context *dispatch, - struct vn_command_vkGetPhysicalDeviceExternalFenceProperties *args) -{ - vn_replace_vkGetPhysicalDeviceExternalFenceProperties_args_handle(args); - vkGetPhysicalDeviceExternalFenceProperties( - args->physicalDevice, args->pExternalFenceInfo, args->pExternalFenceProperties); -} - static void vkr_dispatch_vkCreateDevice(struct vn_dispatch_context *dispatch, struct vn_command_vkCreateDevice *args) @@ -1120,7 +289,7 @@ vkr_device_object_destroy(struct vkr_context *ctx, util_hash_table_remove_u64(ctx->object_table, obj->id); } -static void +void vkr_device_destroy(struct vkr_context *ctx, struct vkr_device *dev) { VkDevice device = dev->base.handle.device; @@ -1191,73 +360,6 @@ vkr_dispatch_vkDeviceWaitIdle(struct vn_dispatch_context *dispatch, vkr_cs_decoder_set_fatal(&ctx->decoder); } -void -vkr_context_init_instance_dispatch(struct vkr_context *ctx) -{ - struct vn_dispatch_context *dispatch = &ctx->dispatch; - - dispatch->dispatch_vkEnumerateInstanceVersion = - vkr_dispatch_vkEnumerateInstanceVersion; - dispatch->dispatch_vkEnumerateInstanceExtensionProperties = - vkr_dispatch_vkEnumerateInstanceExtensionProperties; - /* we don't advertise layers (and should never) */ - dispatch->dispatch_vkEnumerateInstanceLayerProperties = NULL; - dispatch->dispatch_vkCreateInstance = vkr_dispatch_vkCreateInstance; - dispatch->dispatch_vkDestroyInstance = vkr_dispatch_vkDestroyInstance; - dispatch->dispatch_vkGetInstanceProcAddr = NULL; -} - -void -vkr_context_init_physical_device_dispatch(struct vkr_context *ctx) -{ - struct vn_dispatch_context *dispatch = &ctx->dispatch; - - dispatch->dispatch_vkEnumeratePhysicalDevices = - vkr_dispatch_vkEnumeratePhysicalDevices; - dispatch->dispatch_vkEnumeratePhysicalDeviceGroups = - vkr_dispatch_vkEnumeratePhysicalDeviceGroups; - dispatch->dispatch_vkEnumerateDeviceExtensionProperties = - vkr_dispatch_vkEnumerateDeviceExtensionProperties; - dispatch->dispatch_vkEnumerateDeviceLayerProperties = NULL; - - dispatch->dispatch_vkGetPhysicalDeviceFeatures = - vkr_dispatch_vkGetPhysicalDeviceFeatures; - dispatch->dispatch_vkGetPhysicalDeviceProperties = - vkr_dispatch_vkGetPhysicalDeviceProperties; - dispatch->dispatch_vkGetPhysicalDeviceQueueFamilyProperties = - vkr_dispatch_vkGetPhysicalDeviceQueueFamilyProperties; - dispatch->dispatch_vkGetPhysicalDeviceMemoryProperties = - vkr_dispatch_vkGetPhysicalDeviceMemoryProperties; - dispatch->dispatch_vkGetPhysicalDeviceFormatProperties = - vkr_dispatch_vkGetPhysicalDeviceFormatProperties; - dispatch->dispatch_vkGetPhysicalDeviceImageFormatProperties = - vkr_dispatch_vkGetPhysicalDeviceImageFormatProperties; - dispatch->dispatch_vkGetPhysicalDeviceSparseImageFormatProperties = - vkr_dispatch_vkGetPhysicalDeviceSparseImageFormatProperties; - dispatch->dispatch_vkGetPhysicalDeviceFeatures2 = - vkr_dispatch_vkGetPhysicalDeviceFeatures2; - dispatch->dispatch_vkGetPhysicalDeviceProperties2 = - vkr_dispatch_vkGetPhysicalDeviceProperties2; - dispatch->dispatch_vkGetPhysicalDeviceQueueFamilyProperties2 = - vkr_dispatch_vkGetPhysicalDeviceQueueFamilyProperties2; - dispatch->dispatch_vkGetPhysicalDeviceMemoryProperties2 = - vkr_dispatch_vkGetPhysicalDeviceMemoryProperties2; - dispatch->dispatch_vkGetPhysicalDeviceFormatProperties2 = - vkr_dispatch_vkGetPhysicalDeviceFormatProperties2; - dispatch->dispatch_vkGetPhysicalDeviceImageFormatProperties2 = - vkr_dispatch_vkGetPhysicalDeviceImageFormatProperties2; - dispatch->dispatch_vkGetPhysicalDeviceSparseImageFormatProperties2 = - vkr_dispatch_vkGetPhysicalDeviceSparseImageFormatProperties2; - dispatch->dispatch_vkGetPhysicalDeviceExternalBufferProperties = - vkr_dispatch_vkGetPhysicalDeviceExternalBufferProperties; - dispatch->dispatch_vkGetMemoryFdKHR = NULL; - dispatch->dispatch_vkGetMemoryFdPropertiesKHR = NULL; - dispatch->dispatch_vkGetPhysicalDeviceExternalSemaphoreProperties = - vkr_dispatch_vkGetPhysicalDeviceExternalSemaphoreProperties; - dispatch->dispatch_vkGetPhysicalDeviceExternalFenceProperties = - vkr_dispatch_vkGetPhysicalDeviceExternalFenceProperties; -} - void vkr_context_init_device_dispatch(struct vkr_context *ctx) { diff --git a/src/venus/vkr_device.h b/src/venus/vkr_device.h index 822d919..4a1d4c4 100644 --- a/src/venus/vkr_device.h +++ b/src/venus/vkr_device.h @@ -50,4 +50,7 @@ struct vkr_device { void vkr_context_init_device_dispatch(struct vkr_context *ctx); +void +vkr_device_destroy(struct vkr_context *ctx, struct vkr_device *dev); + #endif /* VKR_DEVICE_H */ diff --git a/src/venus/vkr_instance.c b/src/venus/vkr_instance.c new file mode 100644 index 0000000..4cae288 --- /dev/null +++ b/src/venus/vkr_instance.c @@ -0,0 +1,304 @@ +/* + * Copyright 2020 Google LLC + * SPDX-License-Identifier: MIT + */ + +#include "vkr_instance.h" + +#include "venus-protocol/vn_protocol_renderer_info.h" +#include "venus-protocol/vn_protocol_renderer_instance.h" + +#include "vkr_context.h" +#include "vkr_physical_device.h" + +static void +vkr_dispatch_vkEnumerateInstanceVersion(struct vn_dispatch_context *dispatch, + struct vn_command_vkEnumerateInstanceVersion *args) +{ + struct vkr_context *ctx = dispatch->data; + + if (!args->pApiVersion) { + vkr_cs_decoder_set_fatal(&ctx->decoder); + return; + } + + vn_replace_vkEnumerateInstanceVersion_args_handle(args); + args->ret = vkEnumerateInstanceVersion(args->pApiVersion); +} + +static void +vkr_dispatch_vkEnumerateInstanceExtensionProperties( + struct vn_dispatch_context *dispatch, + struct vn_command_vkEnumerateInstanceExtensionProperties *args) +{ + struct vkr_context *ctx = dispatch->data; + + VkExtensionProperties private_extensions[] = { + { + .extensionName = "VK_EXT_command_serialization", + }, + { + .extensionName = "VK_MESA_venus_protocol", + }, + }; + + if (!args->pPropertyCount) { + vkr_cs_decoder_set_fatal(&ctx->decoder); + return; + } + + if (!args->pProperties) { + *args->pPropertyCount = ARRAY_SIZE(private_extensions); + args->ret = VK_SUCCESS; + return; + } + + for (uint32_t i = 0; i < ARRAY_SIZE(private_extensions); i++) { + VkExtensionProperties *props = &private_extensions[i]; + props->specVersion = vn_info_extension_spec_version(props->extensionName); + } + + const uint32_t count = MIN2(*args->pPropertyCount, ARRAY_SIZE(private_extensions)); + memcpy(args->pProperties, private_extensions, sizeof(*args->pProperties) * count); + *args->pPropertyCount = count; + args->ret = count == ARRAY_SIZE(private_extensions) ? VK_SUCCESS : VK_INCOMPLETE; +} + +static VkBool32 +vkr_validation_callback(UNUSED VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, + UNUSED VkDebugUtilsMessageTypeFlagsEXT messageTypes, + const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData, + void *pUserData) +{ + struct vkr_context *ctx = pUserData; + + vrend_printf("%s\n", pCallbackData->pMessage); + + if (!ctx->validate_fatal) + return false; + + vkr_cs_decoder_set_fatal(&ctx->decoder); + + /* The spec says we "should" return false, because the meaning of true is + * layer-defined and is reserved for layer development. And we know that, + * for VK_LAYER_KHRONOS_validation, the return value indicates whether the + * call should be skipped. Let's do it for now and seek advices. + */ + return true; +} + +static void +vkr_dispatch_vkCreateInstance(struct vn_dispatch_context *dispatch, + struct vn_command_vkCreateInstance *args) +{ + struct vkr_context *ctx = dispatch->data; + + if (ctx->instance) { + vkr_cs_decoder_set_fatal(&ctx->decoder); + return; + } + + if (!args->pCreateInfo) { + vkr_cs_decoder_set_fatal(&ctx->decoder); + return; + } + + if (args->pCreateInfo->enabledLayerCount) { + args->ret = VK_ERROR_LAYER_NOT_PRESENT; + return; + } + + if (args->pCreateInfo->enabledExtensionCount) { + args->ret = VK_ERROR_EXTENSION_NOT_PRESENT; + return; + } + + uint32_t instance_version; + args->ret = vkEnumerateInstanceVersion(&instance_version); + if (args->ret != VK_SUCCESS) + return; + + /* require Vulkan 1.1 */ + if (instance_version < VK_API_VERSION_1_1) { + args->ret = VK_ERROR_INITIALIZATION_FAILED; + return; + } + + VkInstanceCreateInfo *create_info = (VkInstanceCreateInfo *)args->pCreateInfo; + const char *layer_names[8]; + const char *ext_names[8]; + uint32_t layer_count = 0; + uint32_t ext_count = 0; + + /* TODO enable more validation features */ + const VkValidationFeatureDisableEXT validation_feature_disables_on[] = { + VK_VALIDATION_FEATURE_DISABLE_THREAD_SAFETY_EXT, + VK_VALIDATION_FEATURE_DISABLE_SHADERS_EXT, + VK_VALIDATION_FEATURE_DISABLE_OBJECT_LIFETIMES_EXT, + VK_VALIDATION_FEATURE_DISABLE_CORE_CHECKS_EXT, + VK_VALIDATION_FEATURE_DISABLE_UNIQUE_HANDLES_EXT, + }; + /* we are single-threaded */ + const VkValidationFeatureDisableEXT validation_feature_disables_full[] = { + VK_VALIDATION_FEATURE_DISABLE_THREAD_SAFETY_EXT, + }; + VkValidationFeaturesEXT validation_features; + VkDebugUtilsMessengerCreateInfoEXT messenger_create_info; + if (ctx->validate_level != VKR_CONTEXT_VALIDATE_NONE) { + /* let vkCreateInstance return VK_ERROR_LAYER_NOT_PRESENT or + * VK_ERROR_EXTENSION_NOT_PRESENT when the layer or extensions are + * missing + */ + layer_names[layer_count++] = "VK_LAYER_KHRONOS_validation"; + ext_names[ext_count++] = VK_EXT_DEBUG_UTILS_EXTENSION_NAME; + ext_names[ext_count++] = VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME; + + validation_features = (const VkValidationFeaturesEXT){ + .sType = VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT, + .pNext = create_info->pNext, + }; + if (ctx->validate_level == VKR_CONTEXT_VALIDATE_ON) { + validation_features.disabledValidationFeatureCount = + ARRAY_SIZE(validation_feature_disables_on); + validation_features.pDisabledValidationFeatures = validation_feature_disables_on; + } else { + validation_features.disabledValidationFeatureCount = + ARRAY_SIZE(validation_feature_disables_full); + validation_features.pDisabledValidationFeatures = + validation_feature_disables_full; + } + messenger_create_info = (VkDebugUtilsMessengerCreateInfoEXT){ + .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT, + .pNext = &validation_features, + .messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, + .messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT, + .pfnUserCallback = vkr_validation_callback, + .pUserData = ctx, + }; + + create_info->pNext = &messenger_create_info; + } + + assert(layer_count <= ARRAY_SIZE(layer_names)); + create_info->enabledLayerCount = layer_count; + create_info->ppEnabledLayerNames = layer_names; + + assert(ext_count <= ARRAY_SIZE(ext_names)); + create_info->enabledExtensionCount = ext_count; + create_info->ppEnabledExtensionNames = ext_names; + + /* patch apiVersion */ + VkApplicationInfo app_info = { + .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, + .apiVersion = VK_API_VERSION_1_1, + }; + if (create_info->pApplicationInfo) { + app_info = *create_info->pApplicationInfo; + if (app_info.apiVersion < VK_API_VERSION_1_1) + app_info.apiVersion = VK_API_VERSION_1_1; + } + create_info->pApplicationInfo = &app_info; + + struct vkr_instance *instance = calloc(1, sizeof(*instance)); + if (!instance) { + args->ret = VK_ERROR_OUT_OF_HOST_MEMORY; + return; + } + + instance->base.type = VK_OBJECT_TYPE_INSTANCE; + instance->base.id = + vkr_cs_handle_load_id((const void **)args->pInstance, instance->base.type); + instance->api_version = app_info.apiVersion; + + vn_replace_vkCreateInstance_args_handle(args); + args->ret = vkCreateInstance(create_info, NULL, &instance->base.handle.instance); + if (args->ret != VK_SUCCESS) { + free(instance); + return; + } + + instance->get_memory_fd = (PFN_vkGetMemoryFdKHR)vkGetInstanceProcAddr( + instance->base.handle.instance, "vkGetMemoryFdKHR"); + instance->get_fence_fd = (PFN_vkGetFenceFdKHR)vkGetInstanceProcAddr( + instance->base.handle.instance, "vkGetFenceFdKHR"); + + if (ctx->validate_level != VKR_CONTEXT_VALIDATE_NONE) { + instance->create_debug_utils_messenger = + (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr( + instance->base.handle.instance, "vkCreateDebugUtilsMessengerEXT"); + instance->destroy_debug_utils_messenger = + (PFN_vkDestroyDebugUtilsMessengerEXT)vkGetInstanceProcAddr( + instance->base.handle.instance, "vkDestroyDebugUtilsMessengerEXT"); + + messenger_create_info.pNext = NULL; + args->ret = instance->create_debug_utils_messenger(instance->base.handle.instance, + &messenger_create_info, NULL, + &instance->validation_messenger); + if (args->ret != VK_SUCCESS) { + vkDestroyInstance(instance->base.handle.instance, NULL); + free(instance); + return; + } + } + + util_hash_table_set_u64(ctx->object_table, instance->base.id, instance); + + ctx->instance = instance; +} + +void +vkr_instance_destroy(struct vkr_context *ctx, struct vkr_instance *instance) +{ + for (uint32_t i = 0; i < instance->physical_device_count; i++) { + struct vkr_physical_device *physical_dev = instance->physical_devices[i]; + if (!physical_dev) + break; + + vkr_physical_device_destroy(ctx, physical_dev); + } + + if (ctx->validate_level != VKR_CONTEXT_VALIDATE_NONE) { + instance->destroy_debug_utils_messenger(instance->base.handle.instance, + instance->validation_messenger, NULL); + } + + vkDestroyInstance(instance->base.handle.instance, NULL); + + free(instance->physical_device_handles); + free(instance->physical_devices); + + util_hash_table_remove_u64(ctx->object_table, instance->base.id); +} + +static void +vkr_dispatch_vkDestroyInstance(struct vn_dispatch_context *dispatch, + struct vn_command_vkDestroyInstance *args) +{ + struct vkr_context *ctx = dispatch->data; + struct vkr_instance *instance = (struct vkr_instance *)args->instance; + + if (ctx->instance != instance) { + vkr_cs_decoder_set_fatal(&ctx->decoder); + return; + } + + vkr_instance_destroy(ctx, instance); + + ctx->instance = NULL; +} + +void +vkr_context_init_instance_dispatch(struct vkr_context *ctx) +{ + struct vn_dispatch_context *dispatch = &ctx->dispatch; + + dispatch->dispatch_vkEnumerateInstanceVersion = + vkr_dispatch_vkEnumerateInstanceVersion; + dispatch->dispatch_vkEnumerateInstanceExtensionProperties = + vkr_dispatch_vkEnumerateInstanceExtensionProperties; + /* we don't advertise layers (and should never) */ + dispatch->dispatch_vkEnumerateInstanceLayerProperties = NULL; + dispatch->dispatch_vkCreateInstance = vkr_dispatch_vkCreateInstance; + dispatch->dispatch_vkDestroyInstance = vkr_dispatch_vkDestroyInstance; + dispatch->dispatch_vkGetInstanceProcAddr = NULL; +} diff --git a/src/venus/vkr_physical_device.c b/src/venus/vkr_physical_device.c new file mode 100644 index 0000000..97b953c --- /dev/null +++ b/src/venus/vkr_physical_device.c @@ -0,0 +1,613 @@ +/* + * Copyright 2020 Google LLC + * SPDX-License-Identifier: MIT + */ + +#include "vkr_physical_device.h" + +#include "venus-protocol/vn_protocol_renderer_device.h" +#include "venus-protocol/vn_protocol_renderer_info.h" + +#include "vkr_context.h" +#include "vkr_device.h" +#include "vkr_instance.h" + +void +vkr_physical_device_destroy(struct vkr_context *ctx, + struct vkr_physical_device *physical_dev) +{ + struct vkr_device *dev, *tmp; + LIST_FOR_EACH_ENTRY_SAFE (dev, tmp, &physical_dev->devices, base.track_head) + vkr_device_destroy(ctx, dev); + + free(physical_dev->extensions); + + util_hash_table_remove_u64(ctx->object_table, physical_dev->base.id); +} + +static VkResult +vkr_instance_enumerate_physical_devices(struct vkr_instance *instance) +{ + if (instance->physical_device_count) + return VK_SUCCESS; + + uint32_t count; + VkResult result = + vkEnumeratePhysicalDevices(instance->base.handle.instance, &count, NULL); + if (result != VK_SUCCESS) + return result; + + VkPhysicalDevice *handles = calloc(count, sizeof(*handles)); + struct vkr_physical_device **physical_devs = calloc(count, sizeof(*physical_devs)); + if (!handles || !physical_devs) { + free(physical_devs); + free(handles); + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + + result = vkEnumeratePhysicalDevices(instance->base.handle.instance, &count, handles); + if (result != VK_SUCCESS) { + free(physical_devs); + free(handles); + return result; + } + + instance->physical_device_count = count; + instance->physical_device_handles = handles; + instance->physical_devices = physical_devs; + + return VK_SUCCESS; +} + +static struct vkr_physical_device * +vkr_instance_lookup_physical_device(struct vkr_instance *instance, + VkPhysicalDevice handle) +{ + for (uint32_t i = 0; i < instance->physical_device_count; i++) { + /* XXX this assumes VkPhysicalDevice handles are unique */ + if (instance->physical_device_handles[i] == handle) + return instance->physical_devices[i]; + } + return NULL; +} + +static void +vkr_physical_device_init_memory_properties(struct vkr_physical_device *physical_dev) +{ + VkPhysicalDevice handle = physical_dev->base.handle.physical_device; + vkGetPhysicalDeviceMemoryProperties(handle, &physical_dev->memory_properties); +} + +static void +vkr_physical_device_init_extensions(struct vkr_physical_device *physical_dev, + struct vkr_instance *instance) +{ + VkPhysicalDevice handle = physical_dev->base.handle.physical_device; + + VkExtensionProperties *exts; + uint32_t count; + VkResult result = vkEnumerateDeviceExtensionProperties(handle, NULL, &count, NULL); + if (result != VK_SUCCESS) + return; + + exts = malloc(sizeof(*exts) * count); + if (!exts) + return; + + result = vkEnumerateDeviceExtensionProperties(handle, NULL, &count, exts); + if (result != VK_SUCCESS) { + free(exts); + return; + } + + uint32_t advertised_count = 0; + for (uint32_t i = 0; i < count; i++) { + VkExtensionProperties *props = &exts[i]; + + if (!strcmp(props->extensionName, "VK_KHR_external_memory_fd")) + physical_dev->KHR_external_memory_fd = true; + else if (!strcmp(props->extensionName, "VK_EXT_external_memory_dma_buf")) + physical_dev->EXT_external_memory_dma_buf = true; + else if (!strcmp(props->extensionName, "VK_KHR_external_fence_fd")) + physical_dev->KHR_external_fence_fd = true; + + const uint32_t spec_ver = vn_info_extension_spec_version(props->extensionName); + if (spec_ver) { + if (props->specVersion > spec_ver) + props->specVersion = spec_ver; + exts[advertised_count++] = exts[i]; + } + } + + if (physical_dev->KHR_external_fence_fd) { + const VkPhysicalDeviceExternalFenceInfo fence_info = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO, + .handleType = VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT, + }; + VkExternalFenceProperties fence_props = { + .sType = VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES, + }; + PFN_vkGetPhysicalDeviceExternalFenceProperties get_fence_props = + (PFN_vkGetPhysicalDeviceExternalFenceProperties)vkGetInstanceProcAddr( + instance->base.handle.instance, "vkGetPhysicalDeviceExternalFenceProperties"); + get_fence_props(handle, &fence_info, &fence_props); + + if (!(fence_props.externalFenceFeatures & VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT)) + physical_dev->KHR_external_fence_fd = false; + } + + physical_dev->extensions = exts; + physical_dev->extension_count = advertised_count; +} + +static void +vkr_physical_device_init_properties(struct vkr_physical_device *physical_dev) +{ + VkPhysicalDevice handle = physical_dev->base.handle.physical_device; + vkGetPhysicalDeviceProperties(handle, &physical_dev->properties); + + VkPhysicalDeviceProperties *props = &physical_dev->properties; + props->driverVersion = 0; + + /* TODO lie about props->pipelineCacheUUID and patch cache header */ +} + +static void +vkr_dispatch_vkEnumeratePhysicalDevices(struct vn_dispatch_context *dispatch, + struct vn_command_vkEnumeratePhysicalDevices *args) +{ + struct vkr_context *ctx = dispatch->data; + + struct vkr_instance *instance = (struct vkr_instance *)args->instance; + if (instance != ctx->instance) { + vkr_cs_decoder_set_fatal(&ctx->decoder); + return; + } + + args->ret = vkr_instance_enumerate_physical_devices(instance); + if (args->ret != VK_SUCCESS) + return; + + uint32_t count = instance->physical_device_count; + if (!args->pPhysicalDevices) { + *args->pPhysicalDeviceCount = count; + args->ret = VK_SUCCESS; + return; + } + + if (count > *args->pPhysicalDeviceCount) { + count = *args->pPhysicalDeviceCount; + args->ret = VK_INCOMPLETE; + } else { + *args->pPhysicalDeviceCount = count; + args->ret = VK_SUCCESS; + } + + uint32_t i; + for (i = 0; i < count; i++) { + struct vkr_physical_device *physical_dev = instance->physical_devices[i]; + const vkr_object_id id = vkr_cs_handle_load_id( + (const void **)&args->pPhysicalDevices[i], VK_OBJECT_TYPE_PHYSICAL_DEVICE); + + if (physical_dev) { + if (physical_dev->base.id != id) { + vkr_cs_decoder_set_fatal(&ctx->decoder); + break; + } + continue; + } + + physical_dev = calloc(1, sizeof(*physical_dev)); + if (!physical_dev) { + args->ret = VK_ERROR_OUT_OF_HOST_MEMORY; + break; + } + + physical_dev->base.type = VK_OBJECT_TYPE_PHYSICAL_DEVICE; + physical_dev->base.id = id; + physical_dev->base.handle.physical_device = instance->physical_device_handles[i]; + + vkr_physical_device_init_properties(physical_dev); + physical_dev->api_version = + MIN2(physical_dev->properties.apiVersion, instance->api_version); + vkr_physical_device_init_extensions(physical_dev, instance); + vkr_physical_device_init_memory_properties(physical_dev); + + list_inithead(&physical_dev->devices); + + instance->physical_devices[i] = physical_dev; + + util_hash_table_set_u64(ctx->object_table, physical_dev->base.id, physical_dev); + } + /* remove all physical devices on errors */ + if (i < count) { + for (i = 0; i < instance->physical_device_count; i++) { + struct vkr_physical_device *physical_dev = instance->physical_devices[i]; + if (!physical_dev) + break; + free(physical_dev->extensions); + util_hash_table_remove_u64(ctx->object_table, physical_dev->base.id); + instance->physical_devices[i] = NULL; + } + } +} + +static void +vkr_dispatch_vkEnumeratePhysicalDeviceGroups( + struct vn_dispatch_context *dispatch, + struct vn_command_vkEnumeratePhysicalDeviceGroups *args) +{ + struct vkr_context *ctx = dispatch->data; + + struct vkr_instance *instance = (struct vkr_instance *)args->instance; + if (instance != ctx->instance) { + vkr_cs_decoder_set_fatal(&ctx->decoder); + return; + } + + args->ret = vkr_instance_enumerate_physical_devices(instance); + if (args->ret != VK_SUCCESS) + return; + + VkPhysicalDeviceGroupProperties *orig_props = args->pPhysicalDeviceGroupProperties; + if (orig_props) { + args->pPhysicalDeviceGroupProperties = + malloc(sizeof(*orig_props) * *args->pPhysicalDeviceGroupCount); + if (!args->pPhysicalDeviceGroupProperties) { + args->ret = VK_ERROR_OUT_OF_HOST_MEMORY; + return; + } + } + + vn_replace_vkEnumeratePhysicalDeviceGroups_args_handle(args); + args->ret = + vkEnumeratePhysicalDeviceGroups(args->instance, args->pPhysicalDeviceGroupCount, + args->pPhysicalDeviceGroupProperties); + if (args->ret != VK_SUCCESS) + return; + + if (!orig_props) + return; + + /* XXX this assumes vkEnumeratePhysicalDevices is called first */ + /* replace VkPhysicalDevice handles by object ids */ + for (uint32_t i = 0; i < *args->pPhysicalDeviceGroupCount; i++) { + const VkPhysicalDeviceGroupProperties *props = + &args->pPhysicalDeviceGroupProperties[i]; + VkPhysicalDeviceGroupProperties *out = &orig_props[i]; + + out->physicalDeviceCount = props->physicalDeviceCount; + out->subsetAllocation = props->subsetAllocation; + for (uint32_t j = 0; j < props->physicalDeviceCount; j++) { + const struct vkr_physical_device *physical_dev = + vkr_instance_lookup_physical_device(instance, props->physicalDevices[j]); + vkr_cs_handle_store_id((void **)&out->physicalDevices[j], physical_dev->base.id, + VK_OBJECT_TYPE_PHYSICAL_DEVICE); + } + } + + free(args->pPhysicalDeviceGroupProperties); + args->pPhysicalDeviceGroupProperties = orig_props; +} + +static void +vkr_dispatch_vkEnumerateDeviceExtensionProperties( + struct vn_dispatch_context *dispatch, + struct vn_command_vkEnumerateDeviceExtensionProperties *args) +{ + struct vkr_context *ctx = dispatch->data; + + struct vkr_physical_device *physical_dev = + (struct vkr_physical_device *)args->physicalDevice; + if (!physical_dev || physical_dev->base.type != VK_OBJECT_TYPE_PHYSICAL_DEVICE) { + vkr_cs_decoder_set_fatal(&ctx->decoder); + return; + } + if (args->pLayerName) { + vkr_cs_decoder_set_fatal(&ctx->decoder); + return; + } + + if (!args->pProperties) { + *args->pPropertyCount = physical_dev->extension_count; + args->ret = VK_SUCCESS; + return; + } + + uint32_t count = physical_dev->extension_count; + if (count > *args->pPropertyCount) { + count = *args->pPropertyCount; + args->ret = VK_INCOMPLETE; + } else { + *args->pPropertyCount = count; + args->ret = VK_SUCCESS; + } + + memcpy(args->pProperties, physical_dev->extensions, + sizeof(*args->pProperties) * count); +} + +static void +vkr_dispatch_vkGetPhysicalDeviceFeatures( + UNUSED struct vn_dispatch_context *dispatch, + struct vn_command_vkGetPhysicalDeviceFeatures *args) +{ + vn_replace_vkGetPhysicalDeviceFeatures_args_handle(args); + vkGetPhysicalDeviceFeatures(args->physicalDevice, args->pFeatures); +} + +static void +vkr_dispatch_vkGetPhysicalDeviceProperties( + struct vn_dispatch_context *dispatch, + struct vn_command_vkGetPhysicalDeviceProperties *args) +{ + struct vkr_context *ctx = dispatch->data; + struct vkr_physical_device *physical_dev = + (struct vkr_physical_device *)args->physicalDevice; + if (!physical_dev || physical_dev->base.type != VK_OBJECT_TYPE_PHYSICAL_DEVICE) { + vkr_cs_decoder_set_fatal(&ctx->decoder); + return; + } + + *args->pProperties = physical_dev->properties; +} + +static void +vkr_dispatch_vkGetPhysicalDeviceQueueFamilyProperties( + UNUSED struct vn_dispatch_context *dispatch, + struct vn_command_vkGetPhysicalDeviceQueueFamilyProperties *args) +{ + vn_replace_vkGetPhysicalDeviceQueueFamilyProperties_args_handle(args); + vkGetPhysicalDeviceQueueFamilyProperties(args->physicalDevice, + args->pQueueFamilyPropertyCount, + args->pQueueFamilyProperties); +} + +static void +vkr_dispatch_vkGetPhysicalDeviceMemoryProperties( + UNUSED struct vn_dispatch_context *dispatch, + struct vn_command_vkGetPhysicalDeviceMemoryProperties *args) +{ + /* TODO lie about this */ + vn_replace_vkGetPhysicalDeviceMemoryProperties_args_handle(args); + vkGetPhysicalDeviceMemoryProperties(args->physicalDevice, args->pMemoryProperties); +} + +static void +vkr_dispatch_vkGetPhysicalDeviceFormatProperties( + UNUSED struct vn_dispatch_context *dispatch, + struct vn_command_vkGetPhysicalDeviceFormatProperties *args) +{ + vn_replace_vkGetPhysicalDeviceFormatProperties_args_handle(args); + vkGetPhysicalDeviceFormatProperties(args->physicalDevice, args->format, + args->pFormatProperties); +} + +static void +vkr_dispatch_vkGetPhysicalDeviceImageFormatProperties( + UNUSED struct vn_dispatch_context *dispatch, + struct vn_command_vkGetPhysicalDeviceImageFormatProperties *args) +{ + vn_replace_vkGetPhysicalDeviceImageFormatProperties_args_handle(args); + args->ret = vkGetPhysicalDeviceImageFormatProperties( + args->physicalDevice, args->format, args->type, args->tiling, args->usage, + args->flags, args->pImageFormatProperties); +} + +static void +vkr_dispatch_vkGetPhysicalDeviceSparseImageFormatProperties( + UNUSED struct vn_dispatch_context *dispatch, + struct vn_command_vkGetPhysicalDeviceSparseImageFormatProperties *args) +{ + vn_replace_vkGetPhysicalDeviceSparseImageFormatProperties_args_handle(args); + vkGetPhysicalDeviceSparseImageFormatProperties( + args->physicalDevice, args->format, args->type, args->samples, args->usage, + args->tiling, args->pPropertyCount, args->pProperties); +} + +static void +vkr_dispatch_vkGetPhysicalDeviceFeatures2( + UNUSED struct vn_dispatch_context *dispatch, + struct vn_command_vkGetPhysicalDeviceFeatures2 *args) +{ + vn_replace_vkGetPhysicalDeviceFeatures2_args_handle(args); + vkGetPhysicalDeviceFeatures2(args->physicalDevice, args->pFeatures); +} + +static void +vkr_dispatch_vkGetPhysicalDeviceProperties2( + struct vn_dispatch_context *dispatch, + struct vn_command_vkGetPhysicalDeviceProperties2 *args) +{ + struct vkr_context *ctx = dispatch->data; + struct vkr_physical_device *physical_dev = + (struct vkr_physical_device *)args->physicalDevice; + if (!physical_dev || physical_dev->base.type != VK_OBJECT_TYPE_PHYSICAL_DEVICE) { + vkr_cs_decoder_set_fatal(&ctx->decoder); + return; + } + + vn_replace_vkGetPhysicalDeviceProperties2_args_handle(args); + vkGetPhysicalDeviceProperties2(args->physicalDevice, args->pProperties); + + union { + VkBaseOutStructure *pnext; + VkPhysicalDeviceProperties2 *props; + VkPhysicalDeviceVulkan11Properties *vk11; + VkPhysicalDeviceVulkan12Properties *vk12; + VkPhysicalDeviceIDProperties *id; + VkPhysicalDeviceDriverProperties *driver; + } u; + + u.pnext = (VkBaseOutStructure *)args->pProperties; + while (u.pnext) { + switch (u.pnext->sType) { + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2: + u.props->properties = physical_dev->properties; + break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES: + memset(u.vk11->deviceUUID, 0, sizeof(u.vk11->deviceUUID)); + memset(u.vk11->driverUUID, 0, sizeof(u.vk11->driverUUID)); + memset(u.vk11->deviceLUID, 0, sizeof(u.vk11->deviceLUID)); + u.vk11->deviceNodeMask = 0; + u.vk11->deviceLUIDValid = false; + break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES: + u.vk12->driverID = 0; + memset(u.vk12->driverName, 0, sizeof(u.vk12->driverName)); + memset(u.vk12->driverInfo, 0, sizeof(u.vk12->driverInfo)); + memset(&u.vk12->conformanceVersion, 0, sizeof(u.vk12->conformanceVersion)); + break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES: + memset(u.id->deviceUUID, 0, sizeof(u.id->deviceUUID)); + memset(u.id->driverUUID, 0, sizeof(u.id->driverUUID)); + memset(u.id->deviceLUID, 0, sizeof(u.id->deviceLUID)); + u.id->deviceNodeMask = 0; + u.id->deviceLUIDValid = false; + break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES: + u.driver->driverID = 0; + memset(u.driver->driverName, 0, sizeof(u.driver->driverName)); + memset(u.driver->driverInfo, 0, sizeof(u.driver->driverInfo)); + memset(&u.driver->conformanceVersion, 0, sizeof(u.driver->conformanceVersion)); + break; + default: + break; + } + + u.pnext = u.pnext->pNext; + } +} + +static void +vkr_dispatch_vkGetPhysicalDeviceQueueFamilyProperties2( + UNUSED struct vn_dispatch_context *dispatch, + struct vn_command_vkGetPhysicalDeviceQueueFamilyProperties2 *args) +{ + vn_replace_vkGetPhysicalDeviceQueueFamilyProperties2_args_handle(args); + vkGetPhysicalDeviceQueueFamilyProperties2(args->physicalDevice, + args->pQueueFamilyPropertyCount, + args->pQueueFamilyProperties); +} + +static void +vkr_dispatch_vkGetPhysicalDeviceMemoryProperties2( + UNUSED struct vn_dispatch_context *dispatch, + struct vn_command_vkGetPhysicalDeviceMemoryProperties2 *args) +{ + /* TODO lie about this */ + vn_replace_vkGetPhysicalDeviceMemoryProperties2_args_handle(args); + vkGetPhysicalDeviceMemoryProperties2(args->physicalDevice, args->pMemoryProperties); +} + +static void +vkr_dispatch_vkGetPhysicalDeviceFormatProperties2( + UNUSED struct vn_dispatch_context *dispatch, + struct vn_command_vkGetPhysicalDeviceFormatProperties2 *args) +{ + vn_replace_vkGetPhysicalDeviceFormatProperties2_args_handle(args); + vkGetPhysicalDeviceFormatProperties2(args->physicalDevice, args->format, + args->pFormatProperties); +} + +static void +vkr_dispatch_vkGetPhysicalDeviceImageFormatProperties2( + UNUSED struct vn_dispatch_context *dispatch, + struct vn_command_vkGetPhysicalDeviceImageFormatProperties2 *args) +{ + vn_replace_vkGetPhysicalDeviceImageFormatProperties2_args_handle(args); + args->ret = vkGetPhysicalDeviceImageFormatProperties2( + args->physicalDevice, args->pImageFormatInfo, args->pImageFormatProperties); +} + +static void +vkr_dispatch_vkGetPhysicalDeviceSparseImageFormatProperties2( + UNUSED struct vn_dispatch_context *dispatch, + struct vn_command_vkGetPhysicalDeviceSparseImageFormatProperties2 *args) +{ + vn_replace_vkGetPhysicalDeviceSparseImageFormatProperties2_args_handle(args); + vkGetPhysicalDeviceSparseImageFormatProperties2( + args->physicalDevice, args->pFormatInfo, args->pPropertyCount, args->pProperties); +} + +static void +vkr_dispatch_vkGetPhysicalDeviceExternalBufferProperties( + UNUSED struct vn_dispatch_context *dispatch, + struct vn_command_vkGetPhysicalDeviceExternalBufferProperties *args) +{ + vn_replace_vkGetPhysicalDeviceExternalBufferProperties_args_handle(args); + vkGetPhysicalDeviceExternalBufferProperties( + args->physicalDevice, args->pExternalBufferInfo, args->pExternalBufferProperties); +} + +static void +vkr_dispatch_vkGetPhysicalDeviceExternalSemaphoreProperties( + UNUSED struct vn_dispatch_context *dispatch, + struct vn_command_vkGetPhysicalDeviceExternalSemaphoreProperties *args) +{ + vn_replace_vkGetPhysicalDeviceExternalSemaphoreProperties_args_handle(args); + vkGetPhysicalDeviceExternalSemaphoreProperties(args->physicalDevice, + args->pExternalSemaphoreInfo, + args->pExternalSemaphoreProperties); +} + +static void +vkr_dispatch_vkGetPhysicalDeviceExternalFenceProperties( + UNUSED struct vn_dispatch_context *dispatch, + struct vn_command_vkGetPhysicalDeviceExternalFenceProperties *args) +{ + vn_replace_vkGetPhysicalDeviceExternalFenceProperties_args_handle(args); + vkGetPhysicalDeviceExternalFenceProperties( + args->physicalDevice, args->pExternalFenceInfo, args->pExternalFenceProperties); +} + +void +vkr_context_init_physical_device_dispatch(struct vkr_context *ctx) +{ + struct vn_dispatch_context *dispatch = &ctx->dispatch; + + dispatch->dispatch_vkEnumeratePhysicalDevices = + vkr_dispatch_vkEnumeratePhysicalDevices; + dispatch->dispatch_vkEnumeratePhysicalDeviceGroups = + vkr_dispatch_vkEnumeratePhysicalDeviceGroups; + dispatch->dispatch_vkEnumerateDeviceExtensionProperties = + vkr_dispatch_vkEnumerateDeviceExtensionProperties; + dispatch->dispatch_vkEnumerateDeviceLayerProperties = NULL; + + dispatch->dispatch_vkGetPhysicalDeviceFeatures = + vkr_dispatch_vkGetPhysicalDeviceFeatures; + dispatch->dispatch_vkGetPhysicalDeviceProperties = + vkr_dispatch_vkGetPhysicalDeviceProperties; + dispatch->dispatch_vkGetPhysicalDeviceQueueFamilyProperties = + vkr_dispatch_vkGetPhysicalDeviceQueueFamilyProperties; + dispatch->dispatch_vkGetPhysicalDeviceMemoryProperties = + vkr_dispatch_vkGetPhysicalDeviceMemoryProperties; + dispatch->dispatch_vkGetPhysicalDeviceFormatProperties = + vkr_dispatch_vkGetPhysicalDeviceFormatProperties; + dispatch->dispatch_vkGetPhysicalDeviceImageFormatProperties = + vkr_dispatch_vkGetPhysicalDeviceImageFormatProperties; + dispatch->dispatch_vkGetPhysicalDeviceSparseImageFormatProperties = + vkr_dispatch_vkGetPhysicalDeviceSparseImageFormatProperties; + dispatch->dispatch_vkGetPhysicalDeviceFeatures2 = + vkr_dispatch_vkGetPhysicalDeviceFeatures2; + dispatch->dispatch_vkGetPhysicalDeviceProperties2 = + vkr_dispatch_vkGetPhysicalDeviceProperties2; + dispatch->dispatch_vkGetPhysicalDeviceQueueFamilyProperties2 = + vkr_dispatch_vkGetPhysicalDeviceQueueFamilyProperties2; + dispatch->dispatch_vkGetPhysicalDeviceMemoryProperties2 = + vkr_dispatch_vkGetPhysicalDeviceMemoryProperties2; + dispatch->dispatch_vkGetPhysicalDeviceFormatProperties2 = + vkr_dispatch_vkGetPhysicalDeviceFormatProperties2; + dispatch->dispatch_vkGetPhysicalDeviceImageFormatProperties2 = + vkr_dispatch_vkGetPhysicalDeviceImageFormatProperties2; + dispatch->dispatch_vkGetPhysicalDeviceSparseImageFormatProperties2 = + vkr_dispatch_vkGetPhysicalDeviceSparseImageFormatProperties2; + dispatch->dispatch_vkGetPhysicalDeviceExternalBufferProperties = + vkr_dispatch_vkGetPhysicalDeviceExternalBufferProperties; + dispatch->dispatch_vkGetMemoryFdKHR = NULL; + dispatch->dispatch_vkGetMemoryFdPropertiesKHR = NULL; + dispatch->dispatch_vkGetPhysicalDeviceExternalSemaphoreProperties = + vkr_dispatch_vkGetPhysicalDeviceExternalSemaphoreProperties; + dispatch->dispatch_vkGetPhysicalDeviceExternalFenceProperties = + vkr_dispatch_vkGetPhysicalDeviceExternalFenceProperties; +} diff --git a/src/venus/vkr_physical_device.h b/src/venus/vkr_physical_device.h index 12d9452..a309e49 100644 --- a/src/venus/vkr_physical_device.h +++ b/src/venus/vkr_physical_device.h @@ -30,4 +30,8 @@ struct vkr_physical_device { void vkr_context_init_physical_device_dispatch(struct vkr_context *ctx); +void +vkr_physical_device_destroy(struct vkr_context *ctx, + struct vkr_physical_device *physical_dev); + #endif /* VKR_PHYSICAL_DEVICE_H */