vkr: further break up vkr_device.c

Break it up into vkr_{device,instance,physical_device}.c.  Suggested by
Ryan Neph.

Signed-off-by: Chia-I Wu <olvaffe@gmail.com>
Reviewed-by: Yiwei Zhang <zzyiwei@chromium.org>
Reviewed-by: Ryan Neph <ryanneph@google.com>
macos/master
Chia-I Wu 3 years ago
parent 9489ba1174
commit 5a1387cde8
  1. 2
      src/meson.build
  2. 900
      src/venus/vkr_device.c
  3. 3
      src/venus/vkr_device.h
  4. 304
      src/venus/vkr_instance.c
  5. 613
      src/venus/vkr_physical_device.c
  6. 4
      src/venus/vkr_physical_device.h

@ -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',

@ -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)
{

@ -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 */

@ -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;
}

@ -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;
}

@ -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 */

Loading…
Cancel
Save