From be10336228bfabe276ba61adf9d6092971d3bdb7 Mon Sep 17 00:00:00 2001 From: Courtney Goeltzenleuchter Date: Mon, 29 Jun 2015 15:39:26 -0600 Subject: loader: bug 12992: extension and layer support Much of layers and loader updated to work with final extension and layer mechanism. Not everything is working here. --- demos/cube.c | 149 ++++- demos/tri.c | 195 ++++++- demos/vulkaninfo.c | 362 ++++++++++--- icd/nulldrv/nulldrv.c | 56 +- include/vk_debug_marker_lunarg.h | 2 +- include/vk_debug_report_lunarg.h | 2 +- include/vk_layer.h | 2 +- include/vk_wsi_lunarg.h | 2 +- include/vulkan.h | 91 ++-- layers/CMakeLists.txt | 30 +- layers/apidump.h | 58 ++ layers/generic.h | 58 ++ layers/mem_tracker.cpp | 110 ++-- layers/vk_layer_extension_utils.cpp | 87 +++ layers/vk_layer_extension_utils.h | 52 ++ layers/vk_layer_logging.h | 4 +- layers/vk_layer_msg.h | 6 +- loader/debug_report.c | 20 +- loader/debug_report.h | 3 +- loader/gpa_helper.h | 8 +- loader/loader.c | 1014 ++++++++++++++++++++++------------- loader/loader.h | 67 ++- loader/table_ops.h | 6 +- loader/trampoline.c | 42 +- vk-generate.py | 4 +- vk-layer-generate.py | 147 ++--- vulkan.py | 17 +- 27 files changed, 1746 insertions(+), 848 deletions(-) create mode 100644 layers/apidump.h create mode 100644 layers/generic.h create mode 100644 layers/vk_layer_extension_utils.cpp create mode 100644 layers/vk_layer_extension_utils.h diff --git a/demos/cube.c b/demos/cube.c index e6154578..9ceb253f 100644 --- a/demos/cube.c +++ b/demos/cube.c @@ -1896,32 +1896,59 @@ static void demo_create_window(struct demo *demo) static void demo_init_vk(struct demo *demo) { VkResult err; + char *extension_names[64]; + char *layer_names[64]; VkExtensionProperties *instance_extensions; + VkLayerProperties *instance_layers; + VkLayerProperties *device_layers; uint32_t instance_extension_count = 0; - VkExtensionProperties *device_extensions; - uint32_t device_extension_count = 0; - uint32_t total_extension_count = 0; - err = vkGetGlobalExtensionCount(&total_extension_count); + uint32_t instance_layer_count = 0; + uint32_t enabled_extension_count = 0; + uint32_t enabled_layer_count = 0; + + /* Look for validation layers */ + bool32_t validation_found = 0; + err = vkGetGlobalLayerProperties(&instance_layer_count, NULL); + assert(!err); + + memset(layer_names, 0, sizeof(layer_names)); + instance_layers = malloc(sizeof(VkLayerProperties) * instance_layer_count); + err = vkGetGlobalLayerProperties(&instance_layer_count, instance_layers); + assert(!err); + for (uint32_t i = 0; i < instance_layer_count; i++) { + if (!validation_found && demo->validate && !strcmp("Validation", instance_layers[i].layerName)) { + layer_names[enabled_layer_count++] = "Validation"; + validation_found = 1; + } + assert(enabled_layer_count < 64); + } + if (demo->validate && !validation_found) { + ERR_EXIT("vkGetGlobalLayerProperties failed to find any " + "\"Validation\" layers.\n\n" + "Please look at the Getting Started guide for additional " + "information.\n", + "vkCreateInstance Failure"); + } + + err = vkGetGlobalExtensionProperties(NULL, &instance_extension_count, NULL); assert(!err); - VkExtensionProperties extProp; bool32_t WSIextFound = 0; - instance_extensions = malloc(sizeof(VkExtensionProperties) * total_extension_count); - device_extensions = malloc(sizeof(VkExtensionProperties) * total_extension_count); - for (uint32_t i = 0; i < total_extension_count; i++) { - err = vkGetGlobalExtensionProperties(i, &extProp); - if (!strcmp("VK_WSI_LunarG", extProp.name)) { + memset(extension_names, 0, sizeof(extension_names)); + instance_extensions = malloc(sizeof(VkExtensionProperties) * instance_extension_count); + err = vkGetGlobalExtensionProperties(NULL, &instance_extension_count, instance_extensions); + assert(!err); + for (uint32_t i = 0; i < instance_extension_count; i++) { + if (!strcmp(VK_WSI_LUNARG_EXTENSION_NAME, instance_extensions[i].extName)) { WSIextFound = 1; - memcpy(&instance_extensions[instance_extension_count++], &extProp, sizeof(VkExtensionProperties)); - memcpy(&device_extensions[device_extension_count++], &extProp, sizeof(VkExtensionProperties)); - } - if (!strcmp(DEBUG_REPORT_EXTENSION_NAME, extProp.name)) { - memcpy(&instance_extensions[instance_extension_count++], &extProp, sizeof(VkExtensionProperties)); + extension_names[enabled_extension_count++] = VK_WSI_LUNARG_EXTENSION_NAME; } - if (demo->validate && !strcmp("Validation",extProp.name)) { - memcpy(&instance_extensions[instance_extension_count++], &extProp, sizeof(VkExtensionProperties)); - memcpy(&device_extensions[device_extension_count++], &extProp, sizeof(VkExtensionProperties)); + if (!strcmp(DEBUG_REPORT_EXTENSION_NAME, instance_extensions[i].extName)) { + if (demo->validate) { + extension_names[enabled_extension_count++] = DEBUG_REPORT_EXTENSION_NAME; + } } + assert(enabled_extension_count < 64); } if (!WSIextFound) { ERR_EXIT("vkGetGlobalExtensionProperties failed to find the " @@ -1945,23 +1972,16 @@ static void demo_init_vk(struct demo *demo) .pNext = NULL, .pAppInfo = &app, .pAllocCb = NULL, - .extensionCount = instance_extension_count, - .pEnabledExtensions = instance_extensions, + .layerCount = enabled_layer_count, + .ppEnabledLayerNames = (const char *const*) layer_names, + .extensionCount = enabled_extension_count, + .ppEnabledExtensionNames = (const char *const*) extension_names, }; const VkDeviceQueueCreateInfo queue = { .queueNodeIndex = 0, .queueCount = 1, }; - VkDeviceCreateInfo device = { - .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, - .pNext = NULL, - .queueRecordCount = 1, - .pRequestedQueues = &queue, - .extensionCount = device_extension_count, - .pEnabledExtensions = device_extensions, - .flags = 0, - }; uint32_t gpu_count; uint32_t i; uint32_t queue_count; @@ -1983,11 +2003,80 @@ static void demo_init_vk(struct demo *demo) "vkCreateInstance Failure"); } + free(instance_layers); + free(instance_extensions); gpu_count = 1; err = vkEnumeratePhysicalDevices(demo->inst, &gpu_count, &demo->gpu); assert(!err && gpu_count == 1); + /* Look for validation layers */ + validation_found = 0; + enabled_layer_count = 0; + uint32_t device_layer_count = 0; + err = vkGetPhysicalDeviceLayerProperties(demo->gpu, &device_layer_count, NULL); + assert(!err); + + memset(layer_names, 0, sizeof(layer_names)); + device_layers = malloc(sizeof(VkLayerProperties) * device_layer_count); + err = vkGetPhysicalDeviceLayerProperties(demo->gpu, &device_layer_count, device_layers); + assert(!err); + for (uint32_t i = 0; i < device_layer_count; i++) { + if (!validation_found && demo->validate && + !strcmp("Validation", device_layers[i].layerName)) { + layer_names[enabled_layer_count++] = "Validation"; + validation_found = 1; + } + assert(enabled_layer_count < 64); + } + if (demo->validate && !validation_found) { + ERR_EXIT("vkGetGlobalLayerProperties failed to find any " + "\"Validation\" layers.\n\n" + "Please look at the Getting Started guide for additional " + "information.\n", + "vkCreateInstance Failure"); + } + + uint32_t device_extension_count = 0; + VkExtensionProperties *device_extensions = NULL; + err = vkGetPhysicalDeviceExtensionProperties( + demo->gpu, NULL, &device_extension_count, NULL); + assert(!err); + + WSIextFound = 0; + enabled_extension_count = 0; + memset(extension_names, 0, sizeof(extension_names)); + device_extensions = malloc(sizeof(VkExtensionProperties) * device_extension_count); + err = vkGetPhysicalDeviceExtensionProperties( + demo->gpu, NULL, &device_extension_count, device_extensions); + assert(!err); + for (uint32_t i = 0; i < device_extension_count; i++) { + if (!strcmp(VK_WSI_LUNARG_EXTENSION_NAME, device_extensions[i].extName)) { + WSIextFound = 1; + extension_names[enabled_extension_count++] = VK_WSI_LUNARG_EXTENSION_NAME; + } + assert(enabled_extension_count < 64); + } + if (!WSIextFound) { + ERR_EXIT("vkGetGlobalExtensionProperties failed to find the " + "\"VK_WSI_LunarG\" extension.\n\nDo you have a compatible " + "Vulkan installable client driver (ICD) installed?\nPlease " + "look at the Getting Started guide for additional " + "information.\n", + "vkCreateInstance Failure"); + } + + VkDeviceCreateInfo device = { + .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, + .pNext = NULL, + .queueRecordCount = 1, + .pRequestedQueues = &queue, + .layerCount = enabled_layer_count, + .ppEnabledLayerNames = (const char*const*) layer_names, + .extensionCount = enabled_extension_count, + .ppEnabledExtensionNames = (const char *const*) extension_names, + .flags = 0, + }; if (demo->validate) { demo->dbgCreateMsgCallback = vkGetInstanceProcAddr(demo->inst, "vkDbgCreateMsgCallback"); @@ -2026,6 +2115,8 @@ static void demo_init_vk(struct demo *demo) err = vkCreateDevice(demo->gpu, &device, &demo->device); assert(!err); + free(device_layers); + GET_DEVICE_PROC_ADDR(demo->device, CreateSwapChainWSI); GET_DEVICE_PROC_ADDR(demo->device, CreateSwapChainWSI); GET_DEVICE_PROC_ADDR(demo->device, DestroySwapChainWSI); diff --git a/demos/tri.c b/demos/tri.c index af6f05e1..73227f2d 100644 --- a/demos/tri.c +++ b/demos/tri.c @@ -43,6 +43,7 @@ #include #include +#include "vk_debug_report_lunarg.h" #include "icd-spv.h" @@ -99,6 +100,37 @@ struct texture_object { int32_t tex_width, tex_height; }; +void dbgFunc( + VkFlags msgFlags, + VkObjectType objType, + VkObject srcObject, + size_t location, + int32_t msgCode, + const char* pLayerPrefix, + const char* pMsg, + void* pUserData) +{ + char *message = (char *) malloc(strlen(pMsg)+100); + + assert (message); + + if (msgFlags & VK_DBG_REPORT_ERROR_BIT) { + sprintf(message,"ERROR: [%s] Code %d : %s", pLayerPrefix, msgCode, pMsg); + } else if (msgFlags & VK_DBG_REPORT_WARN_BIT) { + sprintf(message,"WARNING: [%s] Code %d : %s", pLayerPrefix, msgCode, pMsg); + } else { + return; + } + +#ifdef _WIN32 + MessageBox(NULL, message, "Alert", MB_OK); +#else + printf("%s\n",message); + fflush(stdout); +#endif + free(message); +} + struct demo { #ifdef _WIN32 #define APP_NAME_STR_LEN 80 @@ -174,6 +206,10 @@ struct demo { VkPhysicalDeviceMemoryProperties memory_properties; + bool validate; + PFN_vkDbgCreateMsgCallback dbgCreateMsgCallback; + VkDbgMsgCallback msg_callback; + bool quit; uint32_t current_buffer; }; @@ -1383,25 +1419,59 @@ static void demo_create_window(struct demo *demo) static void demo_init_vk(struct demo *demo) { VkResult err; + char *extension_names[64]; + char *layer_names[64]; VkExtensionProperties *instance_extensions; + VkLayerProperties *instance_layers; + VkLayerProperties *device_layers; uint32_t instance_extension_count = 0; - VkExtensionProperties *device_extensions; - uint32_t device_extension_count = 0; - uint32_t total_extension_count = 0; - err = vkGetGlobalExtensionCount(&total_extension_count); + uint32_t instance_layer_count = 0; + uint32_t enabled_extension_count = 0; + uint32_t enabled_layer_count = 0; + + /* Look for validation layers */ + bool32_t validation_found = 0; + err = vkGetGlobalLayerProperties(&instance_layer_count, NULL); + assert(!err); + + memset(layer_names, 0, sizeof(layer_names)); + instance_layers = malloc(sizeof(VkLayerProperties) * instance_layer_count); + err = vkGetGlobalLayerProperties(&instance_layer_count, instance_layers); + assert(!err); + for (uint32_t i = 0; i < instance_layer_count; i++) { + if (!validation_found && demo->validate && !strcmp("Validation", instance_layers[i].layerName)) { + layer_names[enabled_layer_count++] = "Validation"; + validation_found = 1; + } + assert(enabled_layer_count < 64); + } + if (demo->validate && !validation_found) { + ERR_EXIT("vkGetGlobalLayerProperties failed to find any " + "\"Validation\" layers.\n\n" + "Please look at the Getting Started guide for additional " + "information.\n", + "vkCreateInstance Failure"); + } + + err = vkGetGlobalExtensionProperties(NULL, &instance_extension_count, NULL); assert(!err); - VkExtensionProperties extProp; bool32_t WSIextFound = 0; - instance_extensions = malloc(sizeof(VkExtensionProperties) * total_extension_count); - device_extensions = malloc(sizeof(VkExtensionProperties) * total_extension_count); - for (uint32_t i = 0; i < total_extension_count; i++) { - err = vkGetGlobalExtensionProperties(i, &extProp); - if (!strcmp("VK_WSI_LunarG", extProp.name)) { + memset(extension_names, 0, sizeof(extension_names)); + instance_extensions = malloc(sizeof(VkExtensionProperties) * instance_extension_count); + err = vkGetGlobalExtensionProperties(NULL, &instance_extension_count, instance_extensions); + assert(!err); + for (uint32_t i = 0; i < instance_extension_count; i++) { + if (!strcmp(VK_WSI_LUNARG_EXTENSION_NAME, instance_extensions[i].extName)) { WSIextFound = 1; - memcpy(&instance_extensions[instance_extension_count++], &extProp, sizeof(VkExtensionProperties)); - memcpy(&device_extensions[device_extension_count++], &extProp, sizeof(VkExtensionProperties)); + extension_names[enabled_extension_count++] = VK_WSI_LUNARG_EXTENSION_NAME; + } + if (!strcmp(DEBUG_REPORT_EXTENSION_NAME, instance_extensions[i].extName)) { + if (demo->validate) { + extension_names[enabled_extension_count++] = DEBUG_REPORT_EXTENSION_NAME; + } } + assert(enabled_extension_count < 64); } if (!WSIextFound) { ERR_EXIT("vkGetGlobalExtensionProperties failed to find the " @@ -1420,27 +1490,21 @@ static void demo_init_vk(struct demo *demo) .engineVersion = 0, .apiVersion = VK_API_VERSION, }; - const VkInstanceCreateInfo inst_info = { + VkInstanceCreateInfo inst_info = { .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, .pNext = NULL, .pAppInfo = &app, .pAllocCb = NULL, - .extensionCount = instance_extension_count, - .pEnabledExtensions = instance_extensions, + .layerCount = enabled_layer_count, + .ppEnabledLayerNames = (const char *const*) layer_names, + .extensionCount = enabled_extension_count, + .ppEnabledExtensionNames = (const char *const*) extension_names, }; const VkDeviceQueueCreateInfo queue = { .queueNodeIndex = 0, .queueCount = 1, }; - const VkDeviceCreateInfo device = { - .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, - .pNext = NULL, - .queueRecordCount = 1, - .pRequestedQueues = &queue, - .extensionCount = device_extension_count, - .pEnabledExtensions = device_extensions, - .flags = 0, - }; + uint32_t gpu_count; uint32_t i; uint32_t queue_count; @@ -1451,6 +1515,10 @@ static void demo_init_vk(struct demo *demo) "(ICD).\n\nPlease look at the Getting Started guide for " "additional information.\n", "vkCreateInstance Failure"); + } else if (err == VK_ERROR_INVALID_EXTENSION) { + ERR_EXIT("Cannot find a specified extension library" + ".\nMake sure your layers path is set appropriately\n", + "vkCreateInstance Failure"); } else if (err) { ERR_EXIT("vkCreateInstance failed.\n\nDo you have a compatible Vulkan " "installable client driver (ICD) installed?\nPlease look at " @@ -1458,13 +1526,89 @@ static void demo_init_vk(struct demo *demo) "vkCreateInstance Failure"); } + free(instance_layers); + free(instance_extensions); + gpu_count = 1; err = vkEnumeratePhysicalDevices(demo->inst, &gpu_count, &demo->gpu); assert(!err && gpu_count == 1); + /* Look for validation layers */ + validation_found = 0; + enabled_layer_count = 0; + uint32_t device_layer_count = 0; + err = vkGetPhysicalDeviceLayerProperties(demo->gpu, &device_layer_count, NULL); + assert(!err); + + memset(layer_names, 0, sizeof(layer_names)); + device_layers = malloc(sizeof(VkLayerProperties) * device_layer_count); + err = vkGetPhysicalDeviceLayerProperties(demo->gpu, &device_layer_count, device_layers); + assert(!err); + for (uint32_t i = 0; i < device_layer_count; i++) { + if (!validation_found && demo->validate && + !strcmp("Validation", device_layers[i].layerName)) { + layer_names[enabled_layer_count++] = "Validation"; + validation_found = 1; + } + assert(enabled_layer_count < 64); + } + if (demo->validate && !validation_found) { + ERR_EXIT("vkGetGlobalLayerProperties failed to find any " + "\"Validation\" layers.\n\n" + "Please look at the Getting Started guide for additional " + "information.\n", + "vkCreateInstance Failure"); + } + + /* Don't need any device extensions */ + /* TODO: WSI device extension will go here eventually */ + + VkDeviceCreateInfo device = { + .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, + .pNext = NULL, + .queueRecordCount = 1, + .pRequestedQueues = &queue, + .layerCount = enabled_layer_count, + .ppEnabledLayerNames = (const char*const*) layer_names, + .extensionCount = 0, + .ppEnabledExtensionNames = NULL, + .flags = 0, + }; + + if (demo->validate) { + demo->dbgCreateMsgCallback = vkGetInstanceProcAddr((VkPhysicalDevice) NULL, "vkDbgCreateMsgCallback"); + if (!demo->dbgCreateMsgCallback) { + ERR_EXIT("GetProcAddr: Unable to find vkDbgCreateMsgCallback\n", + "vkGetProcAddr Failure"); + } + err = demo->dbgCreateMsgCallback( + demo->inst, + VK_DBG_REPORT_ERROR_BIT | VK_DBG_REPORT_WARN_BIT, + dbgFunc, NULL, + &demo->msg_callback); + switch (err) { + case VK_SUCCESS: + break; + case VK_ERROR_INVALID_POINTER: + ERR_EXIT("dbgCreateMsgCallback: Invalid pointer\n", + "dbgCreateMsgCallback Failure"); + break; + case VK_ERROR_OUT_OF_HOST_MEMORY: + ERR_EXIT("dbgCreateMsgCallback: out of host memory\n", + "dbgCreateMsgCallback Failure"); + break; + default: + ERR_EXIT("dbgCreateMsgCallback: unknown failure\n", + "dbgCreateMsgCallback Failure"); + break; + } + } + err = vkCreateDevice(demo->gpu, &device, &demo->device); assert(!err); + free(device_layers); + GET_DEVICE_PROC_ADDR(demo->device, CreateSwapChainWSI); GET_DEVICE_PROC_ADDR(demo->device, CreateSwapChainWSI); GET_DEVICE_PROC_ADDR(demo->device, DestroySwapChainWSI); @@ -1482,6 +1626,9 @@ static void demo_init_vk(struct demo *demo) assert(!err); assert(queue_count >= 1); + // Graphics queue and MemMgr queue can be separate. + // TODO: Add support for separate queues, including synchronization, + // and appropriate tracking for QueueSubmit for (i = 0; i < queue_count; i++) { if (demo->queue_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) break; diff --git a/demos/vulkaninfo.c b/demos/vulkaninfo.c index 9ea80882..ebd602b0 100644 --- a/demos/vulkaninfo.c +++ b/demos/vulkaninfo.c @@ -84,8 +84,16 @@ struct app_dev { VkFormatProperties format_props[VK_NUM_FORMAT]; }; +struct layer_extension_list { + VkLayerProperties layer_properties; + uint32_t extension_count; + VkExtensionProperties *extension_properties; +}; + struct app_instance { VkInstance instance; + uint32_t global_layer_count; + struct layer_extension_list *global_layers; uint32_t global_extension_count; VkExtensionProperties *global_extensions; }; @@ -105,6 +113,9 @@ struct app_gpu { VkPhysicalDeviceFeatures features; VkPhysicalDeviceLimits limits; + uint32_t device_layer_count; + struct layer_extension_list *device_layers; + uint32_t device_extension_count; VkExtensionProperties *device_extensions; @@ -363,6 +374,40 @@ static void app_dev_init_formats(struct app_dev *dev) } } +static void extract_version(uint32_t version, uint32_t *major, uint32_t *minor, uint32_t *patch) +{ + *major = version >> 22; + *minor = (version >> 12) & 0x3ff; + *patch = version & 0xfff; +} + +static void app_get_physical_device_layer_extensions( + struct app_gpu *gpu, + char *layer_name, + uint32_t *extension_count, + VkExtensionProperties **extension_properties) +{ + VkResult err; + uint32_t ext_count = 0; + VkExtensionProperties *ext_ptr = NULL; + + /* repeat get until VK_INCOMPLETE goes away */ + do { + err = vkGetPhysicalDeviceExtensionProperties(gpu->obj, layer_name, &ext_count, NULL); + assert(!err); + + if (ext_ptr) { + free(ext_ptr); + } + ext_ptr = malloc(ext_count * sizeof(VkExtensionProperties)); + err = vkGetPhysicalDeviceExtensionProperties(gpu->obj, layer_name, &ext_count, ext_ptr); + } while (err == VK_INCOMPLETE); + assert(!err); + + *extension_count = ext_count; + *extension_properties = ext_ptr; +} + static void app_dev_init(struct app_dev *dev, struct app_gpu *gpu) { VkDeviceCreateInfo info = { @@ -370,55 +415,95 @@ static void app_dev_init(struct app_dev *dev, struct app_gpu *gpu) .pNext = NULL, .queueRecordCount = 0, .pRequestedQueues = NULL, + .layerCount = 0, + .ppEnabledLayerNames = NULL, .extensionCount = 0, - .pEnabledExtensions = NULL, + .ppEnabledExtensionNames = NULL, .flags = 0, }; VkResult U_ASSERT_ONLY err; // Extensions to enable - VkExtensionProperties *enable_extension_list; - static char *known_extensions[] = { - "VK_WSI_LunarG", - "Validation", + static const char *known_extensions[] = { +// "VK_WSI_LunarG", }; - uint32_t extCount; - err = vkGetPhysicalDeviceExtensionCount(gpu->obj, &extCount); + uint32_t count = 0; + + /* Scan layers */ + VkLayerProperties *device_layer_properties = NULL; + struct layer_extension_list *device_layers = NULL; + + do { + err = vkGetPhysicalDeviceLayerProperties(gpu->obj, &count, NULL); + assert(!err); + + if (device_layer_properties) { + free(device_layer_properties); + } + device_layer_properties = malloc(sizeof(VkLayerProperties) * count); + assert(device_layer_properties); + + if (device_layers) { + free(device_layers); + } + device_layers = malloc(sizeof(struct layer_extension_list) * count); + assert(device_layers); + + err = vkGetPhysicalDeviceLayerProperties(gpu->obj, &count, device_layer_properties); + } while (err == VK_INCOMPLETE); assert(!err); - enable_extension_list = malloc(sizeof(VkExtensionProperties) * extCount); - if (!enable_extension_list) { - ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); + gpu->device_layer_count = count; + gpu->device_layers = device_layers; + + for (uint32_t i = 0; i < gpu->device_layer_count; i++) { + VkLayerProperties *src_info = &device_layer_properties[i]; + struct layer_extension_list *dst_info = &gpu->device_layers[i]; + memcpy(&dst_info->layer_properties, src_info, sizeof(VkLayerProperties)); + + /* Save away layer extension info for report */ + app_get_physical_device_layer_extensions( + gpu, + src_info->layerName, + &dst_info->extension_count, + &dst_info->extension_properties); } + free(device_layer_properties); + + app_get_physical_device_layer_extensions( + gpu, + NULL, + &gpu->device_extension_count, + &gpu->device_extensions); fflush(stdout); - VkExtensionProperties extProp; - gpu->device_extension_count = 0; - bool32_t U_ASSERT_ONLY extFound = 0; // TODO : Need to enhance this if/when we enable multiple extensions + uint32_t enabled_extension_count = 0; + for (uint32_t i = 0; i < ARRAY_SIZE(known_extensions); i++) { - for (uint32_t j = 0; j < extCount; j++) { - err = vkGetPhysicalDeviceExtensionProperties( - gpu->obj, j, &extProp); - if (!strcmp(known_extensions[i], extProp.name)) { - extFound = 1; - memcpy(&enable_extension_list[gpu->device_extension_count], &extProp, sizeof(extProp)); - gpu->device_extension_count++; - printf("%s: %s\n", extProp.name, extProp.description); - fflush(stdout); + bool32_t extension_found = 0; + for (uint32_t j = 0; j < gpu->device_extension_count; j++) { + VkExtensionProperties *ext_prop = &gpu->device_extensions[j]; + if (!strcmp(known_extensions[i], ext_prop->extName)) { + + extension_found = 1; + enabled_extension_count++; } } + if (!extension_found) { + printf("Cannot find extension: %s\n", known_extensions[i]); + ERR_EXIT(VK_ERROR_INVALID_EXTENSION); + } } - assert(extFound); - - gpu->device_extensions = enable_extension_list; /* request all queues */ info.queueRecordCount = gpu->queue_count; info.pRequestedQueues = gpu->queue_reqs; - info.extensionCount = gpu->device_extension_count; - info.pEnabledExtensions = enable_extension_list; + info.layerCount = 0; + info.ppEnabledLayerNames = NULL; + info.extensionCount = enabled_extension_count; + info.ppEnabledExtensionNames = (const char*const*) known_extensions; dev->gpu = gpu; err = vkCreateDevice(gpu->obj, &info, &dev->obj); if (err) @@ -431,6 +516,32 @@ static void app_dev_destroy(struct app_dev *dev) vkDestroyDevice(dev->obj); } +static void app_get_global_layer_extensions( + char *layer_name, + uint32_t *extension_count, + VkExtensionProperties **extension_properties) +{ + VkResult err; + uint32_t ext_count = 0; + VkExtensionProperties *ext_ptr = NULL; + + /* repeat get until VK_INCOMPLETE goes away */ + do { + err = vkGetGlobalExtensionProperties(layer_name, &ext_count, NULL); + assert(!err); + + if (ext_ptr) { + free(ext_ptr); + } + ext_ptr = malloc(ext_count * sizeof(VkExtensionProperties)); + err = vkGetGlobalExtensionProperties(layer_name, &ext_count, ext_ptr); + } while (err == VK_INCOMPLETE); + assert(!err); + + *extension_count = ext_count; + *extension_properties = ext_ptr; +} + static void app_create_instance(struct app_instance *inst) { const VkApplicationInfo app_info = { @@ -447,8 +558,10 @@ static void app_create_instance(struct app_instance *inst) .pNext = NULL, .pAppInfo = &app_info, .pAllocCb = NULL, + .layerCount = 0, + .ppEnabledLayerNames = NULL, .extensionCount = 0, - .pEnabledExtensions = NULL, + .ppEnabledExtensionNames = NULL, }; VkResult U_ASSERT_ONLY err; // Global Extensions to enable @@ -456,34 +569,74 @@ static void app_create_instance(struct app_instance *inst) "VK_WSI_LunarG", }; - uint32_t extCount = 0; - VkExtensionProperties extProp; - VkExtensionProperties *enable_extension_list; uint32_t global_extension_count = 0; + uint32_t count = 0; + + /* Scan layers */ + VkLayerProperties *global_layer_properties = NULL; + struct layer_extension_list *global_layers = NULL; + + do { + err = vkGetGlobalLayerProperties(&count, NULL); + assert(!err); + + if (global_layer_properties) { + free(global_layer_properties); + } + global_layer_properties = malloc(sizeof(VkLayerProperties) * count); + assert(global_layer_properties); + + if (global_layers) { + free(global_layers); + } + global_layers = malloc(sizeof(struct layer_extension_list) * count); + assert(global_layers); - err = vkGetGlobalExtensionCount(&extCount); + err = vkGetGlobalLayerProperties(&count, global_layer_properties); + } while (err == VK_INCOMPLETE); assert(!err); - enable_extension_list = malloc(sizeof(VkExtensionProperties) * extCount); - if (!enable_extension_list) { - ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); + inst->global_layer_count = count; + inst->global_layers = global_layers; + + for (uint32_t i = 0; i < inst->global_layer_count; i++) { + VkLayerProperties *src_info = &global_layer_properties[i]; + struct layer_extension_list *dst_info = &inst->global_layers[i]; + memcpy(&dst_info->layer_properties, src_info, sizeof(VkLayerProperties)); + + /* Save away layer extension info for report */ + app_get_global_layer_extensions( + src_info->layerName, + &dst_info->extension_count, + &dst_info->extension_properties); } + free(global_layer_properties); + + /* Collect global extensions */ + inst->global_extension_count = 0; + app_get_global_layer_extensions( + NULL, + &inst->global_extension_count, + &inst->global_extensions); - bool32_t U_ASSERT_ONLY extFound = 0; // TODO : Need to enhance this if/when we enable multiple extensions for (uint32_t i = 0; i < ARRAY_SIZE(known_extensions); i++) { - for (uint32_t j = 0; j < extCount; j++) { - err = vkGetGlobalExtensionProperties(j, &extProp); - if (!strcmp(known_extensions[i], extProp.name)) { - extFound = 1; - memcpy(&enable_extension_list[global_extension_count], &extProp, sizeof(extProp)); + bool32_t extension_found = 0; + for (uint32_t j = 0; j < inst->global_extension_count; j++) { + VkExtensionProperties *extension_prop = &inst->global_extensions[j]; + if (!strcmp(known_extensions[i], extension_prop->extName)) { + + extension_found = 1; global_extension_count++; } } + if (!extension_found) { + printf("Cannot find extension: %s\n", known_extensions[i]); + ERR_EXIT(VK_ERROR_INVALID_EXTENSION); + } } - assert(extFound); inst_info.extensionCount = global_extension_count; - inst_info.pEnabledExtensions = enable_extension_list; + inst_info.ppEnabledExtensionNames = (const char * const *) known_extensions; err = vkCreateInstance(&inst_info, &inst->instance); if (err == VK_ERROR_INCOMPATIBLE_DRIVER) { @@ -492,9 +645,6 @@ static void app_create_instance(struct app_instance *inst) } else if (err) { ERR_EXIT(err); } - - inst->global_extension_count = global_extension_count; - inst->global_extensions = enable_extension_list; } static void app_destroy_instance(struct app_instance *inst) @@ -627,19 +777,6 @@ app_dev_dump(const struct app_dev *dev) #define PRINTF_SIZE_T_SPECIFIER "%zu" #endif -static void app_gpu_dump_props(const struct app_gpu *gpu) -{ - const VkPhysicalDeviceProperties *props = &gpu->props; - - printf("VkPhysicalDeviceProperties\n"); - printf("\tapiVersion = %u\n", props->apiVersion); - printf("\tdriverVersion = %u\n", props->driverVersion); - printf("\tvendorId = 0x%04x\n", props->vendorId); - printf("\tdeviceId = 0x%04x\n", props->deviceId); - printf("\tdeviceType = %s\n", vk_physical_device_type_string(props->deviceType)); - printf("\tdeviceName = %s\n", props->deviceName); -} - static void app_gpu_dump_features(const struct app_gpu *gpu) { const VkPhysicalDeviceFeatures *features = &gpu->features; @@ -661,6 +798,20 @@ static void app_gpu_dump_limits(const struct app_gpu *gpu) printf("\ttimestampFrequency = %lu\n", limits->timestampFrequency); } +static void app_gpu_dump_props(const struct app_gpu *gpu) +{ + const VkPhysicalDeviceProperties *props = &gpu->props; + + printf("VkPhysicalDeviceProperties\n"); + printf("\tapiVersion = %u\n", props->apiVersion); + printf("\tdriverVersion = %u\n", props->driverVersion); + printf("\tvendorId = 0x%04x\n", props->vendorId); + printf("\tdeviceId = 0x%04x\n", props->deviceId); + printf("\tdeviceType = %s\n", vk_physical_device_type_string(props->deviceType)); + printf("\tdeviceName = %s\n", props->deviceName); + fflush(stdout); +} + static void app_gpu_dump_perf(const struct app_gpu *gpu) { const VkPhysicalDevicePerformance *perf = &gpu->perf; @@ -671,36 +822,40 @@ static void app_gpu_dump_perf(const struct app_gpu *gpu) printf("\ttexPerClock = %f\n", perf->texPerClock); printf("\tprimsPerClock = %f\n", perf->primsPerClock); printf("\tpixelsPerClock = %f\n", perf->pixelsPerClock); + fflush(stdout); } -static void app_gpu_dump_instance_extensions(const struct app_instance *inst) +static void app_dump_extensions( + const char *indent, + const char *layer_name, + const uint32_t extension_count, + const VkExtensionProperties *extension_properties) { uint32_t i; - printf("Extensions"); - printf("\tcount = %d\n", inst->global_extension_count); - printf("\t"); - for (i=0; i< inst->global_extension_count; i++) { - if (i>0) - printf(", "); // separator between extension names - printf("%s", inst->global_extensions[i].name); + if (layer_name && (strlen(layer_name) > 0)) { + printf("%s%s Extensions", indent, layer_name); + } else { + printf("Extensions"); } - printf("\n"); -} + printf("\tcount = %d\n", extension_count); + for (i=0; i< extension_count; i++) { + uint32_t major, minor, patch; + char spec_version[64], extension_version[64]; + VkExtensionProperties const *ext_prop = &extension_properties[i]; -static void app_gpu_dump_extensions(const struct app_gpu *gpu) -{ - uint32_t i; - printf("Extensions"); - printf("\tcount = %d\n", gpu->device_extension_count); - printf("\t"); - for (i=0; i< gpu->device_extension_count; i++) { if (i>0) - printf(", "); // separator between extension names - printf("%s(%d): %s", gpu->device_extensions[i].name, - gpu->device_extensions[i].version, - gpu->device_extensions[i].description); + printf("\n"); // separator between extensions + + printf("%s\t", indent); + extract_version(ext_prop->specVersion, &major, &minor, &patch); + snprintf(spec_version, sizeof(spec_version), "%d.%d.%d", major, minor, patch); + extract_version(ext_prop->version, &major, &minor, &patch); + snprintf(extension_version, sizeof(extension_version), "%d.%d.%d", major, minor, patch); + printf("%s: Vulkan version %s, extension version %s", + ext_prop->extName, spec_version, extension_version); } printf("\n"); + fflush(stdout); } static void app_gpu_dump_queue_props(const struct app_gpu *gpu, uint32_t id) @@ -715,6 +870,7 @@ static void app_gpu_dump_queue_props(const struct app_gpu *gpu, uint32_t id) (props->queueFlags & VK_QUEUE_EXTENDED_BIT) ? 'X' : '.'); printf("\tqueueCount = %u\n", props->queueCount); printf("\tsupportsTimestamps = %u\n", props->supportsTimestamps); + fflush(stdout); } static void app_gpu_dump_memory_props(const struct app_gpu *gpu) @@ -733,6 +889,7 @@ static void app_gpu_dump_memory_props(const struct app_gpu *gpu) printf("\tmemoryHeaps[%u] : \n", i); printf("\t\tsize = " PRINTF_SIZE_T_SPECIFIER "\n", props->memoryHeaps[i].size); } + fflush(stdout); } static void app_gpu_dump(const struct app_gpu *gpu) @@ -742,7 +899,29 @@ static void app_gpu_dump(const struct app_gpu *gpu) printf("GPU%u\n", gpu->id); app_gpu_dump_props(gpu); printf("\n"); - app_gpu_dump_extensions(gpu); + app_dump_extensions("", "", gpu->device_extension_count, gpu->device_extensions); + printf("\n"); + printf("Layers\tcount = %d\n", gpu->device_layer_count); + for (uint32_t i = 0; i < gpu->device_layer_count; i++) { + uint32_t major, minor, patch; + char spec_version[64], layer_version[64]; + struct layer_extension_list const *layer_info = &gpu->device_layers[i]; + + extract_version(layer_info->layer_properties.specVersion, &major, &minor, &patch); + snprintf(spec_version, sizeof(spec_version), "%d.%d.%d", major, minor, patch); + extract_version(layer_info->layer_properties.implVersion, &major, &minor, &patch); + snprintf(layer_version, sizeof(layer_version), "%d.%d.%d", major, minor, patch); + printf("\t%s (%s) Vulkan version %s, layer version %s\n", + layer_info->layer_properties.layerName, + layer_info->layer_properties.description, + spec_version, layer_version); + + app_dump_extensions("\t", + layer_info->layer_properties.layerName, + layer_info->extension_count, + layer_info->extension_properties); + fflush(stdout); + } printf("\n"); app_gpu_dump_perf(gpu); printf("\n"); @@ -768,7 +947,26 @@ int main(int argc, char **argv) struct app_instance inst; app_create_instance(&inst); - app_gpu_dump_instance_extensions(&inst); + app_dump_extensions("", "Global", inst.global_extension_count, inst.global_extensions); + + printf("Global Layers\tcount = %d\n", inst.global_layer_count); + for (uint32_t i = 0; i < inst.global_layer_count; i++) { + uint32_t major, minor, patch; + char spec_version[64], layer_version[64]; + VkLayerProperties const *layer_prop = &inst.global_layers[i].layer_properties; + + extract_version(layer_prop->specVersion, &major, &minor, &patch); + snprintf(spec_version, sizeof(spec_version), "%d.%d.%d", major, minor, patch); + extract_version(layer_prop->implVersion, &major, &minor, &patch); + snprintf(layer_version, sizeof(layer_version), "%d.%d.%d", major, minor, patch); + printf("\t%s (%s) Vulkan version %s, layer version %s\n", + layer_prop->layerName, layer_prop->description, spec_version, layer_version); + + app_dump_extensions("\t", + inst.global_layers[i].layer_properties.layerName, + inst.global_layers[i].extension_count, + inst.global_layers[i].extension_properties); + } err = vkEnumeratePhysicalDevices(inst.instance, &gpu_count, NULL); if (err) diff --git a/icd/nulldrv/nulldrv.c b/icd/nulldrv/nulldrv.c index fb043397..48065212 100644 --- a/icd/nulldrv/nulldrv.c +++ b/icd/nulldrv/nulldrv.c @@ -44,10 +44,9 @@ static const char * const nulldrv_gpu_exts[NULLDRV_EXT_COUNT] = { }; static const VkExtensionProperties intel_gpu_exts[NULLDRV_EXT_COUNT] = { { - .sType = VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES, - .name = VK_WSI_LUNARG_EXTENSION_NAME, + .extName = VK_WSI_LUNARG_EXTENSION_NAME, .version = VK_WSI_LUNARG_REVISION, - .description = "Null driver", + .specVersion = VK_API_VERSION, } }; @@ -158,12 +157,12 @@ static VkResult dev_create_queues(struct nulldrv_dev *dev, static enum nulldrv_ext_type nulldrv_gpu_lookup_extension( const struct nulldrv_gpu *gpu, - const VkExtensionProperties *ext) + const char* extName) { enum nulldrv_ext_type type; for (type = 0; type < ARRAY_SIZE(nulldrv_gpu_exts); type++) { - if (memcmp(&nulldrv_gpu_exts[type], ext, sizeof(VkExtensionProperties)) == 0) + if (strcmp(nulldrv_gpu_exts[type], extName) == 0) break; } @@ -207,7 +206,7 @@ static VkResult nulldrv_dev_create(struct nulldrv_gpu *gpu, for (i = 0; i < info->extensionCount; i++) { const enum nulldrv_ext_type ext = nulldrv_gpu_lookup_extension( gpu, - &info->pEnabledExtensions[i]); + info->ppEnabledExtensionNames[i]); if (ext == NULLDRV_EXT_INVALID) return VK_ERROR_INVALID_EXTENSION; @@ -1410,36 +1409,43 @@ ICD_EXPORT VkResult VKAPI vkGetPhysicalDeviceQueueProperties( } ICD_EXPORT VkResult VKAPI vkGetGlobalExtensionProperties( - uint32_t extensionIndex, - VkExtensionProperties* pProperties) + const char* pLayerName, + uint32_t* pCount, + VkExtensionProperties* pProperties) { - if (extensionIndex >= NULLDRV_EXT_COUNT) - return VK_ERROR_INVALID_VALUE; + uint32_t copy_size; - memcpy(pProperties, &intel_gpu_exts[extensionIndex], sizeof(VkExtensionProperties)); - return VK_SUCCESS; -} + if (pCount == NULL) { + return VK_ERROR_INVALID_POINTER; + } -ICD_EXPORT VkResult VKAPI vkGetGlobalExtensionCount(uint32_t *pCount) -{ - *pCount = NULLDRV_EXT_COUNT; + if (pProperties == NULL) { + *pCount = NULLDRV_EXT_COUNT; + return VK_SUCCESS; + } + copy_size = *pCount < NULLDRV_EXT_COUNT ? *pCount : NULLDRV_EXT_COUNT; + memcpy(pProperties, intel_gpu_exts, copy_size * sizeof(VkExtensionProperties)); + *pCount = copy_size; + if (copy_size < NULLDRV_EXT_COUNT) { + return VK_INCOMPLETE; + } return VK_SUCCESS; } VkResult VKAPI vkGetPhysicalDeviceExtensionProperties( - VkPhysicalDevice gpu, - uint32_t extesnionIndex, - VkExtensionProperties* pProperties) + VkPhysicalDevice physicalDevice, + const char* pLayerName, + uint32_t* pCount, + VkExtensionProperties* pProperties) { - return VK_ERROR_INVALID_EXTENSION; -} -VkResult VKAPI vkGetPhysicalDeviceExtensionCount( - VkPhysicalDevice gpu, - uint32_t* pCount) -{ + if (pCount == NULL) { + return VK_ERROR_INVALID_POINTER; + } + *pCount = 0; + return VK_SUCCESS; } diff --git a/include/vk_debug_marker_lunarg.h b/include/vk_debug_marker_lunarg.h index 2d3daa10..d0fdfdc4 100644 --- a/include/vk_debug_marker_lunarg.h +++ b/include/vk_debug_marker_lunarg.h @@ -34,7 +34,7 @@ #include "vulkan.h" #define VK_DEBUG_MARKER_EXTENSION_NUMBER 3 -#define VK_DEBUG_MARKER_EXTENSION_VERSION 1 +#define VK_DEBUG_MARKER_EXTENSION_VERSION VK_MAKE_VERSION(0, 1, 0) #ifdef __cplusplus extern "C" { diff --git a/include/vk_debug_report_lunarg.h b/include/vk_debug_report_lunarg.h index 3145d938..72770e08 100644 --- a/include/vk_debug_report_lunarg.h +++ b/include/vk_debug_report_lunarg.h @@ -35,7 +35,7 @@ #include "vulkan.h" #define VK_DEBUG_REPORT_EXTENSION_NUMBER 2 -#define VK_DEBUG_REPORT_EXTENSION_VERSION 0x10 +#define VK_DEBUG_REPORT_EXTENSION_VERSION VK_MAKE_VERSION(0, 1, 0) #ifdef __cplusplus extern "C" { diff --git a/include/vk_layer.h b/include/vk_layer.h index 85c41d6e..98a636bc 100644 --- a/include/vk_layer.h +++ b/include/vk_layer.h @@ -150,8 +150,8 @@ typedef struct VkLayerInstanceDispatchTable_ PFN_vkGetPhysicalDeviceQueueCount GetPhysicalDeviceQueueCount; PFN_vkGetPhysicalDeviceQueueProperties GetPhysicalDeviceQueueProperties; PFN_vkGetPhysicalDeviceMemoryProperties GetPhysicalDeviceMemoryProperties; - PFN_vkGetPhysicalDeviceExtensionCount GetPhysicalDeviceExtensionCount; PFN_vkGetPhysicalDeviceExtensionProperties GetPhysicalDeviceExtensionProperties; + PFN_vkGetPhysicalDeviceLayerProperties GetPhysicalDeviceLayerProperties; PFN_vkDbgCreateMsgCallback DbgCreateMsgCallback; PFN_vkDbgDestroyMsgCallback DbgDestroyMsgCallback; PFN_vkDbgStringCallback DbgStringCallback; diff --git a/include/vk_wsi_lunarg.h b/include/vk_wsi_lunarg.h index 5fea9679..9f95cc36 100644 --- a/include/vk_wsi_lunarg.h +++ b/include/vk_wsi_lunarg.h @@ -29,7 +29,7 @@ #include "vulkan.h" -#define VK_WSI_LUNARG_REVISION 3 +#define VK_WSI_LUNARG_REVISION VK_MAKE_VERSION(0, 3, 0) #define VK_WSI_LUNARG_EXTENSION_NUMBER 1 #define VK_WSI_LUNARG_EXTENSION_NAME "VK_WSI_LunarG" diff --git a/include/vulkan.h b/include/vulkan.h index 77098430..38567929 100644 --- a/include/vulkan.h +++ b/include/vulkan.h @@ -844,6 +844,7 @@ typedef enum VkResult_ VK_TIMEOUT = 0x0000003, VK_EVENT_SET = 0x0000004, VK_EVENT_RESET = 0x0000005, + VK_INCOMPLETE = 0x0000006, // Error codes (negative values) VK_ERROR_UNKNOWN = -(0x00000001), @@ -859,25 +860,26 @@ typedef enum VkResult_ VK_ERROR_INVALID_ORDINAL = -(0x0000000B), VK_ERROR_INVALID_MEMORY_SIZE = -(0x0000000C), VK_ERROR_INVALID_EXTENSION = -(0x0000000D), - VK_ERROR_INVALID_FLAGS = -(0x0000000E), - VK_ERROR_INVALID_ALIGNMENT = -(0x0000000F), - VK_ERROR_INVALID_FORMAT = -(0x00000010), - VK_ERROR_INVALID_IMAGE = -(0x00000011), - VK_ERROR_INVALID_DESCRIPTOR_SET_DATA = -(0x00000012), - VK_ERROR_INVALID_QUEUE_TYPE = -(0x00000013), - VK_ERROR_INVALID_OBJECT_TYPE = -(0x00000014), - VK_ERROR_UNSUPPORTED_SHADER_IL_VERSION = -(0x00000015), - VK_ERROR_BAD_SHADER_CODE = -(0x00000016), - VK_ERROR_BAD_PIPELINE_DATA = -(0x00000017), - VK_ERROR_NOT_MAPPABLE = -(0x00000018), - VK_ERROR_MEMORY_MAP_FAILED = -(0x00000019), - VK_ERROR_MEMORY_UNMAP_FAILED = -(0x0000001A), - VK_ERROR_INCOMPATIBLE_DEVICE = -(0x0000001B), - VK_ERROR_INCOMPATIBLE_DRIVER = -(0x0000001C), - VK_ERROR_INCOMPLETE_COMMAND_BUFFER = -(0x0000001D), - VK_ERROR_BUILDING_COMMAND_BUFFER = -(0x0000001E), - VK_ERROR_MEMORY_NOT_BOUND = -(0x0000001F), - VK_ERROR_INCOMPATIBLE_QUEUE = -(0x00000020), + VK_ERROR_INVALID_LAYER = -(0x0000000E), + VK_ERROR_INVALID_FLAGS = -(0x0000000F), + VK_ERROR_INVALID_ALIGNMENT = -(0x00000010), + VK_ERROR_INVALID_FORMAT = -(0x00000011), + VK_ERROR_INVALID_IMAGE = -(0x00000012), + VK_ERROR_INVALID_DESCRIPTOR_SET_DATA = -(0x00000013), + VK_ERROR_INVALID_QUEUE_TYPE = -(0x00000014), + VK_ERROR_INVALID_OBJECT_TYPE = -(0x00000015), + VK_ERROR_UNSUPPORTED_SHADER_IL_VERSION = -(0x00000016), + VK_ERROR_BAD_SHADER_CODE = -(0x00000017), + VK_ERROR_BAD_PIPELINE_DATA = -(0x00000018), + VK_ERROR_NOT_MAPPABLE = -(0x00000019), + VK_ERROR_MEMORY_MAP_FAILED = -(0x0000001A), + VK_ERROR_MEMORY_UNMAP_FAILED = -(0x0000001B), + VK_ERROR_INCOMPATIBLE_DEVICE = -(0x0000001C), + VK_ERROR_INCOMPATIBLE_DRIVER = -(0x0000001D), + VK_ERROR_INCOMPLETE_COMMAND_BUFFER = -(0x0000001E), + VK_ERROR_BUILDING_COMMAND_BUFFER = -(0x0000001F), + VK_ERROR_MEMORY_NOT_BOUND = -(0x00000020), + VK_ERROR_INCOMPATIBLE_QUEUE = -(0x00000021), VK_MAX_ENUM(RESULT) } VkResult; @@ -1371,12 +1373,19 @@ typedef struct VkPhysicalDevicePerformance_ typedef struct VkExtensionProperties_ { - VkStructureType sType; // Type of structure. Should be VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES - char name[VK_MAX_EXTENSION_NAME]; // extension name + char extName[VK_MAX_EXTENSION_NAME]; // extension name uint32_t version; // version of the extension specification - char description[VK_MAX_EXTENSION_NAME]; // Name of library implementing this extension + uint32_t specVersion; // version number constructed via VK_API_VERSION } VkExtensionProperties; +typedef struct VkLayerProperties_ +{ + char layerName[VK_MAX_EXTENSION_NAME]; // extension name + uint32_t specVersion; // version of spec this layer is compatible with + uint32_t implVersion; // version of the layer + char description[VK_MAX_DESCRIPTION]; // additional description +} VkLayerProperties; + typedef struct VkApplicationInfo_ { VkStructureType sType; // Type of structure. Should be VK_STRUCTURE_TYPE_APPLICATION_INFO @@ -1417,8 +1426,10 @@ typedef struct VkDeviceCreateInfo_ const void* pNext; // Pointer to next structure uint32_t queueRecordCount; const VkDeviceQueueCreateInfo* pRequestedQueues; + uint32_t layerCount; + const char*const* ppEnabledLayerNames; // Indicate extensions to enable by index value uint32_t extensionCount; - const VkExtensionProperties* pEnabledExtensions; // Indicate extensions to enable by index value + const char*const* ppEnabledExtensionNames; // Indicate extensions to enable by index value const VkPhysicalDeviceFeatures* pEnabledFeatures; VkDeviceCreateFlags flags; // Device creation flags } VkDeviceCreateInfo; @@ -1429,8 +1440,10 @@ typedef struct VkInstanceCreateInfo_ const void* pNext; // Pointer to next structure const VkApplicationInfo* pAppInfo; const VkAllocCallbacks* pAllocCb; + uint32_t layerCount; + const char*const* ppEnabledLayerNames; // Indicate extensions to enable by index value uint32_t extensionCount; - const VkExtensionProperties* pEnabledExtensions; // Indicate extensions to enable by index value + const char*const* ppEnabledExtensionNames; // Indicate extensions to enable by index value } VkInstanceCreateInfo; typedef struct VkPhysicalDeviceQueueProperties_ @@ -2168,10 +2181,10 @@ typedef VkResult (VKAPI *PFN_vkGetPhysicalDevicePerformance)(VkPhysicalDevice ph typedef VkResult (VKAPI *PFN_vkGetPhysicalDeviceQueueCount)(VkPhysicalDevice physicalDevice, uint32_t* pCount); typedef VkResult (VKAPI *PFN_vkGetPhysicalDeviceQueueProperties)(VkPhysicalDevice physicalDevice, uint32_t count, VkPhysicalDeviceQueueProperties* pQueueProperties); typedef VkResult (VKAPI *PFN_vkGetPhysicalDeviceMemoryProperties)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties* pMemoryProperies); -typedef VkResult (VKAPI *PFN_vkGetGlobalExtensionCount)(uint32_t* pCount); -typedef VkResult (VKAPI *PFN_vkGetGlobalExtensionProperties)(uint32_t extensionIndex, VkExtensionProperties* pProperties); -typedef VkResult (VKAPI *PFN_vkGetPhysicalDeviceExtensionCount)(VkPhysicalDevice physicalDevice, uint32_t* pCount); -typedef VkResult (VKAPI *PFN_vkGetPhysicalDeviceExtensionProperties)(VkPhysicalDevice physicalDevice, uint32_t extensionIndex, VkExtensionProperties* pProperties); +typedef VkResult (VKAPI *PFN_vkGetGlobalExtensionProperties)(const char * pLayerName, uint32_t* pCount, VkExtensionProperties* pProperties); +typedef VkResult (VKAPI *PFN_vkGetPhysicalDeviceExtensionProperties)(VkPhysicalDevice physicalDevice, const char* pLayerName, uint32_t *pCount, VkExtensionProperties* pProperties); +typedef VkResult (VKAPI *PFN_vkGetGlobalLayerProperties)(uint32_t* pCount, VkLayerProperties* pProperties); +typedef VkResult (VKAPI *PFN_vkGetPhysicalDeviceLayerProperties)(VkPhysicalDevice physicalDevice, uint32_t *pCount, VkLayerProperties* pProperties); typedef VkResult (VKAPI *PFN_vkGetDeviceQueue)(VkDevice device, uint32_t queueNodeIndex, uint32_t queueIndex, VkQueue* pQueue); typedef VkResult (VKAPI *PFN_vkQueueSubmit)(VkQueue queue, uint32_t cmdBufferCount, const VkCmdBuffer* pCmdBuffers, VkFence fence); typedef VkResult (VKAPI *PFN_vkQueueWaitIdle)(VkQueue queue); @@ -2337,22 +2350,26 @@ VkResult VKAPI vkGetPhysicalDeviceMemoryProperties( // Extension discovery functions -VkResult VKAPI vkGetGlobalExtensionCount( - uint32_t* pCount); - VkResult VKAPI vkGetGlobalExtensionProperties( - uint32_t extensionIndex, + const char* pLayerName, + uint32_t* pCount, VkExtensionProperties* pProperties); -VkResult VKAPI vkGetPhysicalDeviceExtensionCount( - VkPhysicalDevice physicalDevice, - uint32_t* pCount); - VkResult VKAPI vkGetPhysicalDeviceExtensionProperties( VkPhysicalDevice physicalDevice, - uint32_t extensionIndex, + const char* pLayerName, + uint32_t* pCount, VkExtensionProperties* pProperties); +VkResult VKAPI vkGetGlobalLayerProperties( + uint32_t* pCount, + VkLayerProperties* pProperties); + +VkResult VKAPI vkGetPhysicalDeviceLayerProperties( + VkPhysicalDevice physicalDevice, + uint32_t* pCount, + VkLayerProperties* pProperties); + // Queue functions VkResult VKAPI vkGetDeviceQueue( diff --git a/layers/CMakeLists.txt b/layers/CMakeLists.txt index 8f521d65..5cb10571 100644 --- a/layers/CMakeLists.txt +++ b/layers/CMakeLists.txt @@ -83,28 +83,28 @@ add_custom_target(generate_vk_layer_helpers DEPENDS vk_struct_graphviz_helper.h ) -run_vk_layer_generate(Generic generic_layer.cpp) +#run_vk_layer_generate(Generic generic_layer.cpp) run_vk_layer_generate(APIDump api_dump.cpp) -run_vk_layer_generate(ObjectTracker object_track.cpp) -run_vk_layer_generate(Threading threading.cpp) +#run_vk_layer_generate(ObjectTracker object_track.cpp) +#run_vk_layer_generate(Threading threading.cpp) -add_library(layer_utils SHARED vk_layer_config.cpp) +add_library(layer_utils SHARED vk_layer_config.cpp vk_layer_extension_utils.cpp) if (WIN32) - add_library(layer_utils_static STATIC vk_layer_config.cpp) + add_library(layer_utils_static STATIC vk_layer_config.cpp vk_layer_extension_utils.cpp) set_target_properties(layer_utils_static PROPERTIES OUTPUT_NAME layer_utils) target_link_libraries(layer_utils) endif() -add_vk_layer(Basic basic.cpp vk_layer_table.cpp) -add_vk_layer(Multi multi.cpp) -add_vk_layer(DrawState draw_state.cpp vk_layer_debug_marker_table.cpp vk_layer_table.cpp) +#add_vk_layer(Basic basic.cpp vk_layer_table.cpp) +#add_vk_layer(Multi multi.cpp) +#add_vk_layer(DrawState draw_state.cpp vk_layer_debug_marker_table.cpp vk_layer_table.cpp) add_vk_layer(MemTracker mem_tracker.cpp vk_layer_table.cpp) -add_vk_layer(ShaderChecker shader_checker.cpp vk_layer_table.cpp) -add_vk_layer(Image image.cpp vk_layer_table.cpp) +#add_vk_layer(ShaderChecker shader_checker.cpp vk_layer_table.cpp) +#add_vk_layer(Image image.cpp vk_layer_table.cpp) # generated -add_vk_layer(Generic generic_layer.cpp vk_layer_table.cpp) +#add_vk_layer(Generic generic_layer.cpp vk_layer_table.cpp) add_vk_layer(APIDump api_dump.cpp vk_layer_table.cpp) -add_vk_layer(ObjectTracker object_track.cpp vk_layer_table.cpp) -add_vk_layer(ParamChecker param_checker.cpp vk_layer_debug_marker_table.cpp vk_layer_table.cpp) -add_vk_layer(Threading threading.cpp vk_layer_table.cpp) -add_vk_layer(ScreenShot screenshot.cpp vk_layer_table.cpp) +#add_vk_layer(ObjectTracker object_track.cpp vk_layer_table.cpp) +#add_vk_layer(ParamChecker param_checker.cpp vk_layer_debug_marker_table.cpp vk_layer_table.cpp) +#add_vk_layer(Threading threading.cpp vk_layer_table.cpp) +#add_vk_layer(ScreenShot screenshot.cpp vk_layer_table.cpp) diff --git a/layers/apidump.h b/layers/apidump.h new file mode 100644 index 00000000..d72ab31f --- /dev/null +++ b/layers/apidump.h @@ -0,0 +1,58 @@ +/* + * Vulkan + * + * Copyright (C) 2014 LunarG, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Courtney Goeltzenleuchter + */ + +#ifndef GENERIC_H +#define GENERIC_H +#include "vkLayer.h" + +/* + * This file contains static functions for the generated layer Generic + */ + +#define LAYER_PROPS_ARRAY_SIZE 1 +static const VkLayerProperties layerProps[LAYER_PROPS_ARRAY_SIZE] = { + { + "Generic", + VK_API_VERSION, // specVersion + VK_MAKE_VERSION(0, 1, 0), // implVersion + "layer: Generic", + } +}; + +#define LAYER_DEV_PROPS_ARRAY_SIZE 1 +static const VkLayerProperties layerDevProps[LAYER_DEV_PROPS_ARRAY_SIZE] = { + { + "Generic", + VK_API_VERSION, // specVersion + VK_MAKE_VERSION(0, 1, 0), // implVersion + "layer: Generic", + } +}; + + +#endif // GENERIC_H + diff --git a/layers/generic.h b/layers/generic.h new file mode 100644 index 00000000..d72ab31f --- /dev/null +++ b/layers/generic.h @@ -0,0 +1,58 @@ +/* + * Vulkan + * + * Copyright (C) 2014 LunarG, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Courtney Goeltzenleuchter + */ + +#ifndef GENERIC_H +#define GENERIC_H +#include "vkLayer.h" + +/* + * This file contains static functions for the generated layer Generic + */ + +#define LAYER_PROPS_ARRAY_SIZE 1 +static const VkLayerProperties layerProps[LAYER_PROPS_ARRAY_SIZE] = { + { + "Generic", + VK_API_VERSION, // specVersion + VK_MAKE_VERSION(0, 1, 0), // implVersion + "layer: Generic", + } +}; + +#define LAYER_DEV_PROPS_ARRAY_SIZE 1 +static const VkLayerProperties layerDevProps[LAYER_DEV_PROPS_ARRAY_SIZE] = { + { + "Generic", + VK_API_VERSION, // specVersion + VK_MAKE_VERSION(0, 1, 0), // implVersion + "layer: Generic", + } +}; + + +#endif // GENERIC_H + diff --git a/layers/mem_tracker.cpp b/layers/mem_tracker.cpp index 7fe5e672..4a074ccc 100644 --- a/layers/mem_tracker.cpp +++ b/layers/mem_tracker.cpp @@ -37,6 +37,7 @@ using namespace std; #include "vk_struct_string_helper_cpp.h" #include "mem_tracker.h" #include "vk_layer_config.h" +#include "vk_layer_extension_utils.h" // The following is #included again to catch certain OS-specific functions // being used: #include "vk_loader_platform.h" @@ -869,7 +870,7 @@ VkResult VKAPI vkCreateInstance( pTable, *pInstance, pCreateInfo->extensionCount, - pCreateInfo->pEnabledExtensions); + pCreateInfo->ppEnabledExtensionNames); init_mem_tracker(my_data); } @@ -882,7 +883,7 @@ static void createDeviceRegisterExtensions(const VkDeviceCreateInfo* pCreateInfo VkLayerDispatchTable *pDisp = get_dispatch_table(mem_tracker_device_table_map, device); deviceExtMap[pDisp].wsi_lunarg_enabled = false; for (i = 0; i < pCreateInfo->extensionCount; i++) { - if (strcmp(pCreateInfo->pEnabledExtensions[i].name, VK_WSI_LUNARG_EXTENSION_NAME) == 0) + if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_WSI_LUNARG_EXTENSION_NAME) == 0) deviceExtMap[pDisp].wsi_lunarg_enabled = true; } @@ -965,77 +966,62 @@ VK_LAYER_EXPORT VkResult VKAPI vkGetPhysicalDeviceMemoryProperties( } -#define MEM_TRACKER_LAYER_EXT_ARRAY_SIZE 2 -static const VkExtensionProperties mtExts[MEM_TRACKER_LAYER_EXT_ARRAY_SIZE] = { +struct extProps { + uint32_t version; + const char * const name; +}; +#define MEM_TRACKER_EXT_ARRAY_SIZE 0 + +#define MEM_TRACKER_LAYER_ARRAY_SIZE 1 +static const VkLayerProperties mtGlobalLayers[MEM_TRACKER_LAYER_ARRAY_SIZE] = { { - VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES, "MemTracker", - 0x10, - "Validation layer: MemTracker", - }, - { - VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES, - "Validation", - 0x10, + VK_API_VERSION, + VK_MAKE_VERSION(0, 1, 0), "Validation layer: MemTracker", } }; VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionProperties( - uint32_t extensionIndex, - VkExtensionProperties* pData) + const char *pLayerName, + uint32_t *pCount, + VkExtensionProperties* pProperties) { - /* This entrypoint is NOT going to init it's own dispatch table since loader calls here early */ - - if (extensionIndex >= MEM_TRACKER_LAYER_EXT_ARRAY_SIZE) - return VK_ERROR_INVALID_VALUE; - memcpy((VkExtensionProperties *) pData, &mtExts[extensionIndex], sizeof(VkExtensionProperties)); - - return VK_SUCCESS; + /* Mem tracker does not have any global extensions */ + return util_GetExtensionProperties(MEM_TRACKER_EXT_ARRAY_SIZE, NULL, + pCount, pProperties); } -VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionCount(uint32_t* pCount) +VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalLayerProperties( + uint32_t *pCount, + VkLayerProperties* pProperties) { - *pCount = MEM_TRACKER_LAYER_EXT_ARRAY_SIZE; - - return VK_SUCCESS; + return util_GetLayerProperties(MEM_TRACKER_LAYER_ARRAY_SIZE, + (VkLayerProperties *) mtGlobalLayers, + pCount, pProperties); } -#define MEM_TRACKER_LAYER_DEV_EXT_ARRAY_SIZE 3 -static const VkExtensionProperties mtDevExts[MEM_TRACKER_LAYER_DEV_EXT_ARRAY_SIZE] = { - { - VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES, - "MemTracker", - 0x10, - "Validation layer: MemTracker", - }, - { - VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES, - "Validation", - 0x10, - "Validation layer: MemTracker", - } -}; - +#define MEM_TRACKER_DEV_EXT_ARRAY_SIZE 0 -VK_LAYER_EXPORT VkResult VKAPI vkGetPhysicalDeviceExtensionCount( - VkPhysicalDevice gpu, - uint32_t* pCount) +VK_LAYER_EXPORT VkResult VKAPI vkGetPhysicalDeviceExtensionProperties( + VkPhysicalDevice physicalDevice, + const char* pLayerName, + uint32_t* pCount, + VkExtensionProperties* pProperties) { - *pCount = MEM_TRACKER_LAYER_DEV_EXT_ARRAY_SIZE; - return VK_SUCCESS; + /* Mem tracker does not have any physical device extensions */ + return util_GetExtensionProperties(MEM_TRACKER_DEV_EXT_ARRAY_SIZE, NULL, + pCount, pProperties); } -VK_LAYER_EXPORT VkResult VKAPI vkGetPhysicalDeviceExtensionProperties( - VkPhysicalDevice gpu, - uint32_t extensionIndex, - VkExtensionProperties* pProperties) +VK_LAYER_EXPORT VkResult VKAPI vkGetPhysicalDeviceLayerProperties( + VkPhysicalDevice physicalDevice, + uint32_t* pCount, + VkLayerProperties* pProperties) { - if (extensionIndex >= MEM_TRACKER_LAYER_DEV_EXT_ARRAY_SIZE) - return VK_ERROR_INVALID_VALUE; - memcpy(pProperties, &mtDevExts[extensionIndex], sizeof(VkExtensionProperties)); - - return VK_SUCCESS; + /* Mem tracker's physical device layers are the same as global */ + return util_GetLayerProperties(MEM_TRACKER_LAYER_ARRAY_SIZE, mtGlobalLayers, + pCount, pProperties); } VK_LAYER_EXPORT VkResult VKAPI vkGetDeviceQueue( @@ -2278,10 +2264,6 @@ VK_LAYER_EXPORT void* VKAPI vkGetDeviceProcAddr( return (void*) vkCmdResetQueryPool; if (!strcmp(funcName, "vkGetDeviceQueue")) return (void*) vkGetDeviceQueue; - if (!strcmp(funcName, "vkGetGlobalExtensionCount")) - return (void*) vkGetGlobalExtensionCount; - if (!strcmp(funcName, "vkGetGlobalExtensionProperties")) - return (void*) vkGetGlobalExtensionProperties; VkLayerDispatchTable *pDisp = get_dispatch_table(mem_tracker_device_table_map, dev); if (deviceExtMap.size() == 0 || deviceExtMap[pDisp].wsi_lunarg_enabled) @@ -2322,10 +2304,14 @@ VK_LAYER_EXPORT void* VKAPI vkGetInstanceProcAddr( return (void*) vkCreateInstance; if (!strcmp(funcName, "vkGetPhysicalDeviceMemoryProperties")) return (void*) vkGetPhysicalDeviceMemoryProperties; - if (!strcmp(funcName, "vkGetPhysicalDeviceExtensionCount")) - return (void*) vkGetGlobalExtensionCount; - if (!strcmp(funcName, "vkGetPhysicalDeviceExtensionProperties")) + if (!strcmp(funcName, "vkGetGlobalLayerProperties")) + return (void*) vkGetGlobalLayerProperties; + if (!strcmp(funcName, "vkGetGlobalExtensionProperties")) return (void*) vkGetGlobalExtensionProperties; + if (!strcmp(funcName, "vkGetPhysicalDeviceLayerProperties")) + return (void*) vkGetPhysicalDeviceLayerProperties; + if (!strcmp(funcName, "vkGetPhysicalDeviceExtensionProperties")) + return (void*) vkGetPhysicalDeviceExtensionProperties; layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); fptr = debug_report_get_instance_proc_addr(my_data->report_data, funcName); diff --git a/layers/vk_layer_extension_utils.cpp b/layers/vk_layer_extension_utils.cpp new file mode 100644 index 00000000..71c3cba0 --- /dev/null +++ b/layers/vk_layer_extension_utils.cpp @@ -0,0 +1,87 @@ +/* + * Vulkan + * + * Copyright (C) 2015 LunarG, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Courtney Goeltzenleuchter + */ + +#include "string.h" +#include "vk_layer_extension_utils.h" + +/* + * This file contains utility functions for layers + */ + +VkResult util_GetExtensionProperties( + const uint32_t count, + const VkExtensionProperties *layer_extensions, + uint32_t* pCount, + VkExtensionProperties* pProperties) +{ + uint32_t copy_size; + + if (pCount == NULL) { + return VK_ERROR_INVALID_POINTER; + } + + if (pProperties == NULL || layer_extensions == NULL) { + *pCount = count; + return VK_SUCCESS; + } + + copy_size = *pCount < count ? *pCount : count; + memcpy(pProperties, layer_extensions, copy_size * sizeof(VkExtensionProperties)); + *pCount = copy_size; + if (copy_size < count) { + return VK_INCOMPLETE; + } + + return VK_SUCCESS; +} + +VkResult util_GetLayerProperties( + const uint32_t count, + const VkLayerProperties *layer_properties, + uint32_t* pCount, + VkLayerProperties* pProperties) +{ + uint32_t copy_size; + + if (pCount == NULL) { + return VK_ERROR_INVALID_POINTER; + } + + if (pProperties == NULL || layer_properties == NULL) { + *pCount = count; + return VK_SUCCESS; + } + + copy_size = *pCount < count ? *pCount : count; + memcpy(pProperties, layer_properties, copy_size * sizeof(VkLayerProperties)); + *pCount = copy_size; + if (copy_size < count) { + return VK_INCOMPLETE; + } + + return VK_SUCCESS; +} diff --git a/layers/vk_layer_extension_utils.h b/layers/vk_layer_extension_utils.h new file mode 100644 index 00000000..f05385ae --- /dev/null +++ b/layers/vk_layer_extension_utils.h @@ -0,0 +1,52 @@ +/* + * Vulkan + * + * Copyright (C) 2014 LunarG, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Courtney Goeltzenleuchter + */ + +#include "vk_layer.h" + +#ifndef LAYER_EXTENSION_UTILS_H +#define LAYER_EXTENSION_UTILS_H + +/* + * This file contains static functions for the generated layers + */ +extern "C" { + +VkResult util_GetExtensionProperties( + const uint32_t count, + const VkExtensionProperties *layer_extensions, + uint32_t* pCount, + VkExtensionProperties* pProperties); + +VkResult util_GetLayerProperties( + const uint32_t count, + const VkLayerProperties *layer_properties, + uint32_t* pCount, + VkLayerProperties* pProperties); + +} // extern "C" +#endif // LAYER_EXTENSION_UTILS_H + diff --git a/layers/vk_layer_logging.h b/layers/vk_layer_logging.h index 617c3b2d..be0a09ce 100644 --- a/layers/vk_layer_logging.h +++ b/layers/vk_layer_logging.h @@ -76,7 +76,7 @@ static inline debug_report_data *debug_report_create_instance( VkLayerInstanceDispatchTable *table, VkInstance inst, uint32_t extension_count, - const VkExtensionProperties* pEnabledExtensions) // layer or extension name to be enabled + const char*const* ppEnabledExtensions) // layer or extension name to be enabled { debug_report_data *debug_data; PFN_vkGetInstanceProcAddr gpa = table->GetInstanceProcAddr; @@ -90,7 +90,7 @@ static inline debug_report_data *debug_report_create_instance( memset(debug_data, 0, sizeof(debug_report_data)); for (uint32_t i = 0; i < extension_count; i++) { /* TODO: Check other property fields */ - if (strcmp(pEnabledExtensions[i].name, DEBUG_REPORT_EXTENSION_NAME) == 0) { + if (strcmp(ppEnabledExtensions[i], DEBUG_REPORT_EXTENSION_NAME) == 0) { debug_data->g_DEBUG_REPORT = true; } } diff --git a/layers/vk_layer_msg.h b/layers/vk_layer_msg.h index 2d0e31d6..1e6fe4ce 100644 --- a/layers/vk_layer_msg.h +++ b/layers/vk_layer_msg.h @@ -33,12 +33,12 @@ static bool g_DEBUG_REPORT = false; static FILE *g_logFile = NULL; static void enable_debug_report( - uint32_t extension_count, - const VkExtensionProperties* pEnabledExtensions) // layer or extension name to be enabled + uint32_t extension_count, + const char * const * ppEnabledExtensionNames) // extension name to be enabled { for (uint32_t i = 0; i < extension_count; i++) { /* TODO: Check other property fields */ - if (strcmp(pEnabledExtensions[i].name, DEBUG_REPORT_EXTENSION_NAME) == 0) { + if (strcmp(ppEnabledExtensionNames[i], DEBUG_REPORT_EXTENSION_NAME) == 0) { g_DEBUG_REPORT = true; } } diff --git a/loader/debug_report.c b/loader/debug_report.c index 757ad3ff..2ad0782e 100644 --- a/loader/debug_report.c +++ b/loader/debug_report.c @@ -40,10 +40,9 @@ typedef void (VKAPI *PFN_stringCallback)(char *message); static const struct loader_extension_property debug_report_extension_info = { .info = { - .sType = VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES, - .name = DEBUG_REPORT_EXTENSION_NAME, + .extName = DEBUG_REPORT_EXTENSION_NAME, .version = VK_DEBUG_REPORT_EXTENSION_VERSION, - .description = "loader: debug report extension", + .specVersion = VK_API_VERSION, }, .origin = VK_EXTENSION_ORIGIN_LOADER, }; @@ -55,12 +54,17 @@ void debug_report_add_instance_extensions( } void debug_report_create_instance( - struct loader_instance *ptr_instance) + struct loader_instance *ptr_instance, + const VkInstanceCreateInfo *pCreateInfo) { - ptr_instance->debug_report_enabled = has_vk_extension_property_array( - &debug_report_extension_info.info, - ptr_instance->app_extension_count, - ptr_instance->app_extension_props); + ptr_instance->debug_report_enabled = false; + + for (uint32_t i = 0; i < pCreateInfo->extensionCount; i++) { + if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], DEBUG_REPORT_EXTENSION_NAME) == 0) { + ptr_instance->debug_report_enabled = true; + return; + } + } } static VkResult debug_report_DbgCreateMsgCallback( diff --git a/loader/debug_report.h b/loader/debug_report.h index 5d6fd92a..1958577a 100644 --- a/loader/debug_report.h +++ b/loader/debug_report.h @@ -34,7 +34,8 @@ void debug_report_add_instance_extensions( struct loader_extension_list *ext_list); void debug_report_create_instance( - struct loader_instance *ptr_instance); + struct loader_instance *ptr_instance, + const VkInstanceCreateInfo *pCreateInfo); void *debug_report_instance_gpa( struct loader_instance *ptr_instance, diff --git a/loader/gpa_helper.h b/loader/gpa_helper.h index 26eefc6e..65c52d41 100644 --- a/loader/gpa_helper.h +++ b/loader/gpa_helper.h @@ -63,12 +63,12 @@ static inline void* globalGetProcAddr(const char *name) return (void*) vkDestroyDevice; if (!strcmp(name, "GetGlobalExtensionProperties")) return (void*) vkGetGlobalExtensionProperties; - if (!strcmp(name, "GetGlobalExtensionCount")) - return (void*) vkGetGlobalExtensionCount; if (!strcmp(name, "GetPhysicalDeviceExtensionProperties")) return (void*) vkGetPhysicalDeviceExtensionProperties; - if (!strcmp(name, "GetPhysicalDeviceExtensionCount")) - return (void*) vkGetPhysicalDeviceExtensionCount; + if (!strcmp(name, "GetGlobalLayerProperties")) + return (void*) vkGetGlobalLayerProperties; + if (!strcmp(name, "GetPhysicalDeviceLayerProperties")) + return (void*) vkGetPhysicalDeviceLayerProperties; if (!strcmp(name, "GetDeviceQueue")) return (void*) vkGetDeviceQueue; if (!strcmp(name, "QueueSubmit")) diff --git a/loader/loader.c b/loader/loader.c index 5b193769..f3e8559f 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -56,15 +56,16 @@ void loader_add_to_ext_list( static loader_platform_dl_handle loader_add_layer_lib( const char *chain_type, - struct loader_extension_property *ext_prop); + struct loader_layer_properties *layer_prop); static void loader_remove_layer_lib( struct loader_instance *inst, - struct loader_extension_property *ext_prop); + struct loader_layer_properties *layer_prop); struct loader_struct loader = {0}; static void * VKAPI loader_GetInstanceProcAddr(VkInstance instance, const char * pName); +static bool loader_init_ext_list(struct loader_extension_list *ext_info); enum loader_debug { LOADER_INFO_BIT = VK_BIT(0), @@ -95,8 +96,8 @@ const VkLayerInstanceDispatchTable instance_disp = { .GetPhysicalDeviceQueueCount = loader_GetPhysicalDeviceQueueCount, .GetPhysicalDeviceQueueProperties = loader_GetPhysicalDeviceQueueProperties, .GetPhysicalDeviceMemoryProperties = loader_GetPhysicalDeviceMemoryProperties, - .GetPhysicalDeviceExtensionCount = loader_GetPhysicalDeviceExtensionCount, .GetPhysicalDeviceExtensionProperties = loader_GetPhysicalDeviceExtensionProperties, + .GetPhysicalDeviceLayerProperties = loader_GetPhysicalDeviceLayerProperties, .DbgCreateMsgCallback = loader_DbgCreateMsgCallback, .DbgDestroyMsgCallback = loader_DbgDestroyMsgCallback, }; @@ -296,7 +297,7 @@ static char *loader_get_registry_and_env(const char *env_var, bool compare_vk_extension_properties(const VkExtensionProperties *op1, const VkExtensionProperties *op2) { - return memcmp(op1, op2, sizeof(VkExtensionProperties)) == 0 ? true : false; + return strcmp(op1->extName, op2->extName) == 0 ? true : false; } /* @@ -331,25 +332,23 @@ bool has_vk_extension_property( } /* - * Search the given ext_list for an extension - * matching the given vk_ext_prop + * Search the given layer list for a layer + * matching the given layer name */ -static struct loader_extension_property *get_extension_property_from_vkext( - const VkExtensionProperties *vk_ext_prop, - const struct loader_extension_list *ext_list) +static struct loader_layer_properties *get_layer_property( + const char *name, + const struct loader_layer_list *layer_list) { - for (uint32_t i = 0; i < ext_list->count; i++) { - const VkExtensionProperties *item = &ext_list->list[i].info; - if (compare_vk_extension_properties(item, vk_ext_prop)) - return &ext_list->list[i]; + for (uint32_t i = 0; i < layer_list->count; i++) { + const VkLayerProperties *item = &layer_list->list[i].info; + if (strcmp(name, item->layerName) == 0) + return &layer_list->list[i]; } return NULL; } -static void loader_get_global_extensions( - const PFN_vkGetGlobalExtensionCount fp_get_count, +static void loader_add_global_extensions( const PFN_vkGetGlobalExtensionProperties fp_get_props, - const PFN_vkGPA get_proc_addr, const char *lib_name, const loader_platform_dl_handle lib_handle, const enum extension_origin origin, @@ -357,97 +356,256 @@ static void loader_get_global_extensions( { uint32_t i, count; struct loader_extension_property ext_props; + VkExtensionProperties *extension_properties; VkResult res; - PFN_vkGPA ext_get_proc_addr; - PFN_vkGetInstanceProcAddr get_instance_proc_addr; - res = fp_get_count(&count); + res = fp_get_props(NULL, &count, NULL); if (res != VK_SUCCESS) { - loader_log(VK_DBG_REPORT_WARN_BIT, 0, "Error getting global extension count from ICD"); + loader_log(VK_DBG_REPORT_WARN_BIT, 0, "Error getting global extension count from %s", lib_name); return; } - if (get_proc_addr == NULL) - get_instance_proc_addr = (PFN_vkGetInstanceProcAddr) loader_platform_get_proc_address(lib_handle, "vkGetInstanceProcAddr"); +#ifdef WIN32 + extension_properties = _alloca(count * sizeof(VkExtensionProperties)); +#else + extension_properties = alloca(count * sizeof(VkExtensionProperties)); +#endif + + res = fp_get_props(NULL, &count, extension_properties); + if (res != VK_SUCCESS) { + loader_log(VK_DBG_REPORT_WARN_BIT, 0, "Error getting global extensions from %s", lib_name); + return; + } for (i = 0; i < count; i++) { memset(&ext_props, 0, sizeof(ext_props)); - res = fp_get_props(i, &ext_props.info); - if (res == VK_SUCCESS) { - //TODO eventually get this from the layer config file - if (get_proc_addr == NULL) { - char funcStr[MAX_EXTENSION_NAME_SIZE+1]; - snprintf(funcStr, MAX_EXTENSION_NAME_SIZE, "%sGetInstanceProcAddr", ext_props.info.name); - - if ((ext_get_proc_addr = (PFN_vkGPA) loader_platform_get_proc_address(lib_handle, funcStr)) == NULL) - ext_get_proc_addr = get_instance_proc_addr; - } - ext_props.origin = origin; - ext_props.lib_name = lib_name; - loader_log(VK_DBG_REPORT_DEBUG_BIT, 0, - "Global Extension: %s: %s", ext_props.info.name, ext_props.info.description); - ext_props.get_proc_addr = (get_proc_addr == NULL) ? ext_get_proc_addr : get_proc_addr; - loader_add_to_ext_list(ext_list, 1, &ext_props); - } + memcpy(&ext_props.info, &extension_properties[i], sizeof(VkExtensionProperties)); + //TODO eventually get this from the layer config file + ext_props.origin = origin; + ext_props.lib_name = lib_name; + + char spec_version[64], version[64]; + + snprintf(spec_version, sizeof(spec_version), "%d.%d.%d", + VK_MAJOR(ext_props.info.specVersion), + VK_MINOR(ext_props.info.specVersion), + VK_PATCH(ext_props.info.specVersion)); + snprintf(version, sizeof(version), "%d.%d.%d", + VK_MAJOR(ext_props.info.version), + VK_MINOR(ext_props.info.version), + VK_PATCH(ext_props.info.version)); + + loader_log(VK_DBG_REPORT_DEBUG_BIT, 0, + "Global Extension: %s (%s) version %s, Vulkan version %s", + ext_props.info.extName, lib_name, version, spec_version); + loader_add_to_ext_list(ext_list, 1, &ext_props); } return; } -static void loader_get_physical_device_layer_extensions( - struct loader_instance *ptr_instance, - VkPhysicalDevice physical_device, - const struct loader_layer_properties *layer_props, - struct loader_extension_list *ext_list) +static void loader_add_global_layer_properties( + const char *lib_name, + const loader_platform_dl_handle lib_handle, + struct loader_layer_list *layer_list) { uint32_t i, count; + VkLayerProperties *layer_properties; + PFN_vkGetGlobalExtensionProperties fp_get_ext_props; + PFN_vkGetGlobalLayerProperties fp_get_layer_props; VkResult res; - loader_platform_dl_handle lib_handle; - PFN_vkGetPhysicalDeviceExtensionProperties get_phys_dev_ext_props; - PFN_vkGetPhysicalDeviceExtensionCount get_phys_dev_ext_count; - struct loader_extension_property ext_props; - PFN_vkGPA ext_get_proc_addr; - PFN_vkGetDeviceProcAddr get_device_proc_addr; - if (layer_props->device_extension_list.count == 0) { + fp_get_ext_props = loader_platform_get_proc_address(lib_handle, "vkGetGlobalExtensionProperties"); + if (!fp_get_ext_props) { + loader_log(VK_DBG_REPORT_WARN_BIT, 0, + "Couldn't dlsym vkGetGlobalExtensionProperties from library %s", + lib_name); + return; + } + + fp_get_layer_props = loader_platform_get_proc_address(lib_handle, "vkGetGlobalLayerProperties"); + if (!fp_get_layer_props) { + loader_log(VK_DBG_REPORT_WARN_BIT, 0, + "Couldn't dlsym vkGetGlobalLayerProperties from library %s", + lib_name); + return; + } + + res = fp_get_layer_props(&count, NULL); + if (res != VK_SUCCESS) { + loader_log(VK_DBG_REPORT_WARN_BIT, 0, "Error getting global layer count from %s", lib_name); return; } - ext_props.origin = VK_EXTENSION_ORIGIN_LAYER; - ext_props.lib_name = layer_props->lib_info.lib_name; - char funcStr[MAX_EXTENSION_NAME_SIZE+1]; // add one character for 0 termination + if (count == 0) { + return; + } - lib_handle = loader_add_layer_lib("device", &ext_props); +#ifdef WIN32 + layer_properties = _alloca(count * sizeof(VkLayerProperties)); +#else + layer_properties = alloca(count * sizeof(VkLayerProperties)); +#endif + + res = fp_get_layer_props(&count, layer_properties); + if (res != VK_SUCCESS) { + loader_log(VK_DBG_REPORT_WARN_BIT, 0, "Error getting %d global layer properties from %s", + count, lib_name); + return; + } - get_phys_dev_ext_props = (PFN_vkGetPhysicalDeviceExtensionProperties) loader_platform_get_proc_address(lib_handle, "vkGetPhysicalDeviceExtensionProperties"); - get_phys_dev_ext_count = (PFN_vkGetPhysicalDeviceExtensionCount) loader_platform_get_proc_address(lib_handle, "vkGetPhysicalDeviceExtensionCount"); - get_device_proc_addr = (PFN_vkGetDeviceProcAddr) loader_platform_get_proc_address(lib_handle, "vkGetDeviceProcAddr"); - if (get_phys_dev_ext_count) { - res = get_phys_dev_ext_count(physical_device, &count); - if (res == VK_SUCCESS) { + for (i = 0; i < count; i++) { + struct loader_layer_properties *layer = &layer_list->list[layer_list->count]; + layer->lib_info.lib_name = malloc(strlen(lib_name) + 1); + if (layer->lib_info.lib_name == NULL) { + loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "layer library %s ignored: out of memory", lib_name); + return; + } + + strcpy(layer->lib_info.lib_name, lib_name); + memcpy(&layer->info, &layer_properties[i], sizeof(VkLayerProperties)); + loader_init_ext_list(&layer->instance_extension_list); + loader_init_ext_list(&layer->device_extension_list); + loader_log(VK_DBG_REPORT_DEBUG_BIT, 0, "Collecting global extensions for layer %s (%s)", + layer->info.layerName, layer->info.description); + + loader_add_to_layer_list(layer_list, 1, layer); + + loader_add_global_extensions( + fp_get_ext_props, + lib_name, + lib_handle, + VK_EXTENSION_ORIGIN_LAYER, + &layer->instance_extension_list); + } + + return; +} + +static void loader_add_physical_device_extensions( + PFN_vkGetPhysicalDeviceExtensionProperties get_phys_dev_ext_props, + VkPhysicalDevice physical_device, + const enum extension_origin origin, + const char *lib_name, + struct loader_extension_list *ext_list) +{ + uint32_t i, count; + VkResult res; + struct loader_extension_property ext_props; + VkExtensionProperties *extension_properties; + + memset(&ext_props, 0, sizeof(ext_props)); + ext_props.origin = origin; + ext_props.lib_name = lib_name; + + if (get_phys_dev_ext_props) { + res = get_phys_dev_ext_props(physical_device, NULL, &count, NULL); + if (res == VK_SUCCESS && count > 0) { +#ifdef WIN32 + extension_properties = _alloca(count * sizeof(VkExtensionProperties)); +#else + extension_properties = alloca(count * sizeof(VkExtensionProperties)); +#endif + res = get_phys_dev_ext_props(physical_device, NULL, &count, extension_properties); for (i = 0; i < count; i++) { - memset(&ext_props, 0, sizeof(ext_props)); - res = get_phys_dev_ext_props(physical_device, i, &ext_props.info); - if (res == VK_SUCCESS && (ext_props.info.sType == VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES)) { - ext_props.origin = VK_EXTENSION_ORIGIN_LAYER; - //TODO eventually get this from the layer config file - snprintf(funcStr, MAX_EXTENSION_NAME_SIZE, "%sGetDeviceProcAddr", ext_props.info.name); - - if ((ext_get_proc_addr = (PFN_vkGPA) loader_platform_get_proc_address(lib_handle, funcStr)) == NULL) - ext_get_proc_addr = get_device_proc_addr; - ext_props.get_proc_addr = ext_get_proc_addr; - ext_props.lib_name = layer_props->lib_info.lib_name; - loader_log(VK_DBG_REPORT_DEBUG_BIT, 0, - "PhysicalDevice Extension: %s: %s", ext_props.info.name, ext_props.info.description); - loader_add_to_ext_list(ext_list, 1, &ext_props); - } + char spec_version[64], version[64]; + + memcpy(&ext_props.info, &extension_properties[i], sizeof(VkExtensionProperties)); + + snprintf(spec_version, sizeof(spec_version), "%d.%d.%d", + VK_MAJOR(ext_props.info.specVersion), + VK_MINOR(ext_props.info.specVersion), + VK_PATCH(ext_props.info.specVersion)); + snprintf(version, sizeof(version), "%d.%d.%d", + VK_MAJOR(ext_props.info.version), + VK_MINOR(ext_props.info.version), + VK_PATCH(ext_props.info.version)); + + loader_log(VK_DBG_REPORT_DEBUG_BIT, 0, + "PhysicalDevice Extension: %s (%s) version %s, Vulkan version %s", + ext_props.info.extName, lib_name, version, spec_version); + loader_add_to_ext_list(ext_list, 1, &ext_props); } } else { - loader_log(VK_DBG_REPORT_WARN_BIT, 0, "Error getting physical device extension info count from Layer %s", ext_props.lib_name); + loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "Error getting physical device extension info count from Layer %s", ext_props.lib_name); } } - loader_remove_layer_lib(ptr_instance, &ext_props); + return; +} + +static void loader_add_physical_device_layer_properties( + struct loader_icd *icd, + char *lib_name, + const loader_platform_dl_handle lib_handle) +{ + uint32_t i, count; + VkLayerProperties *layer_properties; + PFN_vkGetPhysicalDeviceExtensionProperties fp_get_ext_props; + PFN_vkGetPhysicalDeviceLayerProperties fp_get_layer_props; + VkPhysicalDevice gpu = icd->gpus[0]; + VkResult res; + + fp_get_ext_props = loader_platform_get_proc_address(lib_handle, "vkGetPhysicalDeviceExtensionProperties"); + if (!fp_get_ext_props) { + loader_log(VK_DBG_REPORT_INFO_BIT, 0, + "Couldn't dlsym vkGetPhysicalDeviceExtensionProperties from library %s", + lib_name); + return; + } + + fp_get_layer_props = loader_platform_get_proc_address(lib_handle, "vkGetPhysicalDeviceLayerProperties"); + if (!fp_get_layer_props) { + loader_log(VK_DBG_REPORT_INFO_BIT, 0, + "Couldn't dlsym vkGetPhysicalDeviceLayerProperties from library %s", + lib_name); + return; + } + + /* + * NOTE: We assume that all GPUs of an ICD support the same PhysicalDevice + * layers and extensions. Thus only ask for info about the first gpu. + */ + res = fp_get_layer_props(gpu, &count, NULL); + if (res != VK_SUCCESS) { + loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "Error getting PhysicalDevice layer count from %s", lib_name); + return; + } + + if (count == 0) { + return; + } + +#ifdef WIN32 + layer_properties = _alloca(count * sizeof(VkLayerProperties)); +#else + layer_properties = alloca(count * sizeof(VkLayerProperties)); +#endif + + res = fp_get_layer_props(gpu, &count, layer_properties); + if (res != VK_SUCCESS) { + loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "Error getting %d PhysicalDevice layer properties from %s", + count, lib_name); + return; + } + + for (i = 0; i < count; i++) { + struct loader_layer_properties layer; + memset(&layer, 0, sizeof(struct loader_layer_properties)); + layer.lib_info.lib_name = lib_name; + memcpy(&layer.info, &layer_properties[i], sizeof(VkLayerProperties)); + loader_init_ext_list(&layer.instance_extension_list); + loader_init_ext_list(&layer.device_extension_list); + loader_log(VK_DBG_REPORT_DEBUG_BIT, 0, "Collecting PhysicalDevice extensions for layer %s (%s)", + layer.info.layerName, layer.info.description); + loader_add_to_layer_list(&icd->layer_properties_cache, 1, &layer); + loader_add_physical_device_extensions( + fp_get_ext_props, + icd->gpus[i], + VK_EXTENSION_ORIGIN_LAYER, + lib_name, + &layer.device_extension_list); + } return; } @@ -471,37 +629,26 @@ void loader_destroy_ext_list(struct loader_extension_list *ext_info) } /** - * Search the given search_list for an any layer extensions in the props list. - * Add these to the output ext_list. Don't add duplicates to the output ext_list. - * Search is limited to extensions having the origin of layer libraries. - * Appending to output list handles layer aliases + * Search the given search_list for any layers in the props list. + * Add these to the output layer_list. Don't add duplicates to the output layer_list. */ -static void loader_add_layer_ext_to_ext_list( - struct loader_extension_list *out_ext_list, - uint32_t prop_list_count, - const VkExtensionProperties *props, - const struct loader_extension_list *search_list) -{ - struct loader_extension_property *ext_prop; - - for (uint32_t i = 0; i < prop_list_count; i++) { - const VkExtensionProperties *search_target = &props[i]; - // look for duplicates - if (has_vk_extension_property(search_target, out_ext_list)) { - continue; - } - - ext_prop = get_extension_property_from_vkext(search_target, search_list); - if (!ext_prop) { - loader_log(VK_DBG_REPORT_WARN_BIT, 0, "Unable to find extension %s", search_target->name); +static void loader_add_layer_names_to_list( + struct loader_layer_list *output_list, + uint32_t name_count, + const char * const *names, + const struct loader_layer_list *search_list) +{ + struct loader_layer_properties *layer_prop; + + for (uint32_t i = 0; i < name_count; i++) { + const char *search_target = names[i]; + layer_prop = get_layer_property(search_target, search_list); + if (!layer_prop) { + loader_log(VK_DBG_REPORT_WARN_BIT, 0, "Unable to find extension %s", search_target); continue; } - if (ext_prop->origin != VK_EXTENSION_ORIGIN_LAYER) - continue; - if (ext_prop->alias) - ext_prop = ext_prop->alias; - loader_add_to_ext_list(out_ext_list, 1, ext_prop); + loader_add_to_layer_list(output_list, 1, layer_prop); } } @@ -541,51 +688,118 @@ void loader_add_to_ext_list( ext_list->list = realloc(ext_list->list, ext_list->capacity); } - /* - * Check if any extensions already on the list come from the same - * library and use the same Get*ProcAddr. If so, link this - * extension to the previous as an alias. That way when we activate - * extensions we only activiate the associated layer once no - * matter how many extensions are used. - */ - for (uint32_t j = 0; j < ext_list->count; j++) { - struct loader_extension_property *active_property = &ext_list->list[j]; - if (cur_ext->lib_name && - cur_ext->origin == VK_EXTENSION_ORIGIN_LAYER && - active_property->origin == VK_EXTENSION_ORIGIN_LAYER && - strcmp(cur_ext->lib_name, active_property->lib_name) == 0 && - (cur_ext->get_proc_addr == active_property->get_proc_addr) && - active_property->alias == NULL) { - cur_ext->alias = active_property; - break; - } - } - memcpy(&ext_list->list[ext_list->count], cur_ext, sizeof(struct loader_extension_property)); ext_list->count++; } } +static bool loader_init_layer_list(struct loader_layer_list *list) +{ + list->capacity = 32 * sizeof(struct loader_layer_properties); + list->list = malloc(list->capacity); + if (list->list == NULL) { + return false; + } + memset(list->list, 0, list->capacity); + list->count = 0; + return true; +} + +void loader_destroy_layer_list(struct loader_layer_list *layer_list) +{ + free(layer_list->list); + layer_list->count = 0; + layer_list->capacity = 0; +} + +/* + * Search the given layer list for a list + * matching the given VkLayerProperties + */ +bool has_vk_layer_property( + const VkLayerProperties *vk_layer_prop, + const struct loader_layer_list *list) +{ + for (uint32_t i = 0; i < list->count; i++) { + if (strcmp(vk_layer_prop->layerName, list->list[i].info.layerName) == 0) + return true; + } + return false; +} + +/* + * Search the given layer list for a layer + * matching the given name + */ +bool has_layer_name( + const char *name, + const struct loader_layer_list *list) +{ + for (uint32_t i = 0; i < list->count; i++) { + if (strcmp(name, list->list[i].info.layerName) == 0) + return true; + } + return false; +} + /* - * Search the search_list for any extension with - * a name that matches the given ext_name. - * Add all matching extensions to the found_list - * Do not add if found VkExtensionProperties is already - * on the found_list. Add the aliased layer if needed. + * Append non-duplicate layer properties defined in prop_list + * to the given layer_info list + */ +void loader_add_to_layer_list( + struct loader_layer_list *list, + uint32_t prop_list_count, + const struct loader_layer_properties *props) +{ + uint32_t i; + struct loader_layer_properties *layer; + + if (list->list == NULL || list->capacity == 0) { + loader_init_layer_list(list); + } + + if (list->list == NULL) + return; + + for (i = 0; i < prop_list_count; i++) { + layer = (struct loader_layer_properties *) &props[i]; + + // look for duplicates + if (has_vk_layer_property(&layer->info, list)) { + continue; + } + + // add to list at end + // check for enough capacity + if (list->count * sizeof(struct loader_layer_properties) + >= list->capacity) { + // double capacity + list->capacity *= 2; + list->list = realloc(list->list, list->capacity); + } + + memcpy(&list->list[list->count], layer, sizeof(struct loader_layer_properties)); + list->count++; + } +} + +/* + * Search the search_list for any layer with + * a name that matches the given layer_name. + * Add all matching layers to the found_list + * Do not add if found VkLayerProperties is already + * on the found_list. */ static void loader_find_layer_name_add_list( const char *name, - const struct loader_extension_list *search_list, - struct loader_extension_list *found_list) + const struct loader_layer_list *search_list, + struct loader_layer_list *found_list) { for (uint32_t i = 0; i < search_list->count; i++) { - struct loader_extension_property *ext_prop = &search_list->list[i]; - if (ext_prop->origin == VK_EXTENSION_ORIGIN_LAYER && - 0 == strcmp(ext_prop->info.name, name)) { - if (ext_prop->alias) - ext_prop = ext_prop->alias; - /* Found an extension with the same name, add to found_list */ - loader_add_to_ext_list(found_list, 1, ext_prop); + struct loader_layer_properties *layer_prop = &search_list->list[i]; + if (0 == strcmp(layer_prop->info.layerName, name)) { + /* Found a layer with the same name, add to found_list */ + loader_add_to_layer_list(found_list, 1, layer_prop); } } } @@ -662,7 +876,7 @@ static void loader_destroy_logical_device(struct loader_device *dev) { free(dev->app_extension_props); if (dev->activated_layer_list.count) - loader_destroy_ext_list(&dev->activated_layer_list); + loader_destroy_layer_list(&dev->activated_layer_list); free(dev); } @@ -761,9 +975,7 @@ static void loader_scanned_icd_add(const char *filename) loader_platform_dl_handle handle; void *fp_create_inst; void *fp_get_global_ext_props; - void *fp_get_global_ext_count; void *fp_get_device_ext_props; - void *fp_get_device_ext_count; PFN_vkGPA fp_get_proc_addr; struct loader_scanned_icds *new_node; @@ -784,9 +996,7 @@ static void loader_scanned_icd_add(const char *filename) LOOKUP(fp_create_inst, CreateInstance); LOOKUP(fp_get_global_ext_props, GetGlobalExtensionProperties); - LOOKUP(fp_get_global_ext_count, GetGlobalExtensionCount); LOOKUP(fp_get_device_ext_props, GetPhysicalDeviceExtensionProperties); - LOOKUP(fp_get_device_ext_count, GetPhysicalDeviceExtensionCount); LOOKUP(fp_get_proc_addr, GetDeviceProcAddr); #undef LOOKUP @@ -800,7 +1010,6 @@ static void loader_scanned_icd_add(const char *filename) new_node->handle = handle; new_node->CreateInstance = fp_create_inst; new_node->GetGlobalExtensionProperties = fp_get_global_ext_props; - new_node->GetGlobalExtensionCount = fp_get_global_ext_count; loader_init_ext_list(&new_node->global_extension_list); loader_init_ext_list(&new_node->device_extension_list); new_node->next = loader.scanned_icd_list; @@ -814,16 +1023,65 @@ static void loader_scanned_icd_add(const char *filename) loader.scanned_icd_list = new_node; - loader_get_global_extensions( - (PFN_vkGetGlobalExtensionCount) fp_get_global_ext_count, + loader_add_global_extensions( (PFN_vkGetGlobalExtensionProperties) fp_get_global_ext_props, - fp_get_proc_addr, new_node->lib_name, handle, VK_EXTENSION_ORIGIN_ICD, &new_node->global_extension_list); } +static struct loader_extension_list *loader_global_extensions(const char *pLayerName) +{ + if (pLayerName == NULL || (strlen(pLayerName) == 0)) { + return &loader.global_extensions; + } + + /* TODO: Add code to query global extensions from layer */ + for (uint32_t i = 0; i < loader.scanned_layers.count; i++) { + struct loader_layer_properties *work_layer = &loader.scanned_layers.list[i]; + if (strcmp(work_layer->info.layerName, pLayerName) == 0) { + return &work_layer->instance_extension_list; + } + } + + return NULL; +} + +static struct loader_layer_list *loader_global_layers() +{ + return &loader.scanned_layers; +} + +static void loader_physical_device_layers( + struct loader_icd *icd, + uint32_t *count, + struct loader_layer_list **list) +{ + *count = icd->layer_properties_cache.count; + *list = &icd->layer_properties_cache; +} + +static void loader_physical_device_extensions( + struct loader_icd *icd, + uint32_t gpu_idx, + const char *layer_name, + uint32_t *count, + struct loader_extension_list **list) +{ + if (layer_name == NULL || (strlen(layer_name) == 0)) { + *count = icd->device_extension_cache[gpu_idx].count; + *list = &icd->device_extension_cache[gpu_idx]; + return; + } + for (uint32_t i = 0; i < icd->layer_properties_cache.count; i++) { + if (strcmp(layer_name, icd->layer_properties_cache.list[i].info.layerName) == 0) { + *count = icd->layer_properties_cache.list[i].device_extension_list.count; + *list = &icd->layer_properties_cache.list[i].device_extension_list; + } + } +} + static void loader_icd_init_entrys(struct loader_icd *icd, struct loader_scanned_icds *scanned_icds) { @@ -851,7 +1109,6 @@ static void loader_icd_init_entrys(struct loader_icd *icd, LOOKUP(GetPhysicalDeviceQueueCount); LOOKUP(GetPhysicalDeviceQueueProperties); LOOKUP(GetPhysicalDeviceExtensionProperties); - LOOKUP(GetPhysicalDeviceExtensionCount); LOOKUP(DbgCreateMsgCallback); LOOKUP(DbgDestroyMsgCallback); #undef LOOKUP @@ -1252,9 +1509,6 @@ void loader_layer_scan(void) struct dirent *dent; size_t len, i; char temp_str[1024]; - uint32_t count; - PFN_vkGetGlobalExtensionProperties fp_get_props; - PFN_vkGetGlobalExtensionCount fp_get_count; #if defined(WIN32) bool must_free_libPaths; @@ -1314,14 +1568,12 @@ void loader_layer_scan(void) for (i = 0; i < loader.scanned_layers.count; i++) { if (loader.scanned_layers.list[i].lib_info.lib_name != NULL) free(loader.scanned_layers.list[i].lib_info.lib_name); - free(loader.scanned_layers.list[i].name); loader_destroy_ext_list(&loader.scanned_layers.list[i].instance_extension_list); loader_destroy_ext_list(&loader.scanned_layers.list[i].device_extension_list); loader.scanned_layers.list[i].lib_info.lib_name = NULL; } loader.scanned_layers.count = 0; } - count = 0; for (p = libPaths; *p; p = next) { next = strchr(p, PATH_SEPERATOR); @@ -1365,49 +1617,10 @@ void loader_layer_scan(void) loader_log(VK_DBG_REPORT_DEBUG_BIT, 0, "Opened library: %s", temp_str); - if (count * sizeof(struct loader_layer_properties) >= loader.scanned_layers.capacity) { - loader.scanned_layers.list = realloc(loader.scanned_layers.list, - loader.scanned_layers.capacity * 2); - if (loader.scanned_layers.list == NULL) { - loader_log(VK_DBG_REPORT_ERROR_BIT, 0, - "realloc failed for scanned layers"); - break; - } - loader.scanned_layers.capacity *= 2; - } - - fp_get_count = loader_platform_get_proc_address(handle, "vkGetGlobalExtensionCount"); - fp_get_props = loader_platform_get_proc_address(handle, "vkGetGlobalExtensionProperties"); - if (!fp_get_props || !fp_get_count) { - loader_log(VK_DBG_REPORT_WARN_BIT, 0, - "Couldn't dlsym vkGetGlobalExtensionCount and/or vkGetGlobalExtensionProperties from library %s", - temp_str); - dent = readdir(curdir); - loader_platform_close_library(handle); - continue; - } - - loader.scanned_layers.list[count].lib_info.lib_name = - malloc(strlen(temp_str) + 1); - if (loader.scanned_layers.list[count].lib_info.lib_name == NULL) { - loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "%s ignored: out of memory", temp_str); - break; - } - - strcpy(loader.scanned_layers.list[count].lib_info.lib_name, temp_str); - loader_log(VK_DBG_REPORT_DEBUG_BIT, 0, "Collecting global extensions for %s", temp_str); - loader_get_global_extensions( - fp_get_count, - fp_get_props, - NULL, - loader.scanned_layers.list[count].lib_info.lib_name, - handle, - VK_EXTENSION_ORIGIN_LAYER, - &loader.scanned_layers.list[count].instance_extension_list); + loader_add_global_layer_properties(temp_str, handle, &loader.scanned_layers); - count++; loader_platform_close_library(handle); } } @@ -1417,8 +1630,6 @@ void loader_layer_scan(void) closedir(curdir); } // if (curdir)) } // for (libpaths) - - loader.scanned_layers.count = count; } static void* VKAPI loader_gpa_instance_internal(VkInstance inst, const char * pName) @@ -1464,22 +1675,17 @@ struct loader_icd * loader_get_icd(const VkPhysicalDevice gpu, uint32_t *gpu_ind static loader_platform_dl_handle loader_add_layer_lib( const char *chain_type, - struct loader_extension_property *ext_prop) + struct loader_layer_properties *layer_prop) { struct loader_lib_info *new_layer_lib_list, *my_lib; - /* Only loader layer libraries here */ - if (ext_prop->origin != VK_EXTENSION_ORIGIN_LAYER) { - return NULL; - } - for (uint32_t i = 0; i < loader.loaded_layer_lib_count; i++) { - if (strcmp(loader.loaded_layer_lib_list[i].lib_name, ext_prop->lib_name) == 0) { + if (strcmp(loader.loaded_layer_lib_list[i].lib_name, layer_prop->lib_info.lib_name) == 0) { /* Have already loaded this library, just increment ref count */ loader.loaded_layer_lib_list[i].ref_count++; loader_log(VK_DBG_REPORT_DEBUG_BIT, 0, "%s Chain: Increment layer reference count for layer library %s", - chain_type, ext_prop->lib_name); + chain_type, layer_prop->lib_info.lib_name); return loader.loaded_layer_lib_list[i].lib_handle; } } @@ -1494,8 +1700,8 @@ static loader_platform_dl_handle loader_add_layer_lib( my_lib = &new_layer_lib_list[loader.loaded_layer_lib_count]; - /* NOTE: We require that the extension property be immutable */ - my_lib->lib_name = (char *) ext_prop->lib_name; + /* NOTE: We require that the layer property be immutable */ + my_lib->lib_name = (char *) layer_prop->lib_info.lib_name; my_lib->ref_count = 0; my_lib->lib_handle = NULL; @@ -1506,7 +1712,7 @@ static loader_platform_dl_handle loader_add_layer_lib( } else { loader_log(VK_DBG_REPORT_DEBUG_BIT, 0, "Chain: %s: Loading layer library %s", - chain_type, ext_prop->lib_name); + chain_type, layer_prop->lib_info.lib_name); } loader.loaded_layer_lib_count++; loader.loaded_layer_lib_list = new_layer_lib_list; @@ -1517,18 +1723,13 @@ static loader_platform_dl_handle loader_add_layer_lib( static void loader_remove_layer_lib( struct loader_instance *inst, - struct loader_extension_property *ext_prop) + struct loader_layer_properties *layer_prop) { uint32_t idx; struct loader_lib_info *new_layer_lib_list, *my_lib; - /* Only loader layer libraries here */ - if (ext_prop->origin != VK_EXTENSION_ORIGIN_LAYER) { - return; - } - for (uint32_t i = 0; i < loader.loaded_layer_lib_count; i++) { - if (strcmp(loader.loaded_layer_lib_list[i].lib_name, ext_prop->lib_name) == 0) { + if (strcmp(loader.loaded_layer_lib_list[i].lib_name, layer_prop->lib_info.lib_name) == 0) { /* found matching library */ idx = i; my_lib = &loader.loaded_layer_lib_list[i]; @@ -1539,13 +1740,13 @@ static void loader_remove_layer_lib( my_lib->ref_count--; if (my_lib->ref_count > 0) { loader_log(VK_DBG_REPORT_DEBUG_BIT, 0, - "Decrement reference count for layer library %s", ext_prop->lib_name); + "Decrement reference count for layer library %s", layer_prop->lib_info.lib_name); return; } loader_platform_close_library(my_lib->lib_handle); loader_log(VK_DBG_REPORT_DEBUG_BIT, 0, - "Unloading layer library %s", ext_prop->lib_name); + "Unloading layer library %s", layer_prop->lib_info.lib_name); /* Need to remove unused library from list */ new_layer_lib_list = malloc((loader.loaded_layer_lib_count - 1) * sizeof(struct loader_lib_info)); @@ -1570,47 +1771,17 @@ static void loader_remove_layer_lib( loader.loaded_layer_lib_list = new_layer_lib_list; } -/** - * Initialize ext_prop from layer_prop. - */ -static void loader_init_ext_prop_from_layer_prop( - struct loader_extension_property *ext_prop, - const struct loader_layer_properties *layer_prop) -{ - memset(ext_prop, 0, sizeof(*ext_prop)); - ext_prop->info.sType = VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES; - strncpy(ext_prop->info.name, layer_prop->name, sizeof(ext_prop->info.name)); - ext_prop->info.name[sizeof(ext_prop->info.name) - 1] = '\0'; - - //TODO from list of string versions to an int, for now just use build version - ext_prop->info.version = VK_API_VERSION; - - strncpy(ext_prop->info.description, layer_prop->description, sizeof(ext_prop->info.description)); - ext_prop->info.description[sizeof(ext_prop->info.name) - 1] = '\0'; - ext_prop->lib_name = layer_prop->lib_info.lib_name; - ext_prop->origin = VK_EXTENSION_ORIGIN_LAYER; - ext_prop->alias = NULL; - ext_prop->get_proc_addr = layer_prop->functions.get_instance_proc_addr; -} - -/** - * Go through the search_list and find any layers which match type. If layer - * type match is found in then add it to ext_list. - */ static void loader_add_layer_implicit( const enum layer_type type, - struct loader_extension_list *ext_list, - const uint32_t count, - const struct loader_layer_properties *search_list) + struct loader_layer_list *list, + struct loader_layer_list *search_list) { uint32_t i; - for (i = 0; i < count; i++) { - const struct loader_layer_properties *prop = &search_list[i]; - struct loader_extension_property ext_prop; + for (i = 0; i < search_list->count; i++) { + const struct loader_layer_properties *prop = &search_list->list[i]; if (prop->type & type) { - loader_init_ext_prop_from_layer_prop(&ext_prop, prop); - /* Found an extension with the same type, add to ext_list */ - loader_add_to_ext_list(ext_list, 1, &ext_prop); + /* Found an layer with the same type, add to layer_list */ + loader_add_to_layer_list(list, 1, prop); } } @@ -1618,12 +1789,12 @@ static void loader_add_layer_implicit( /** * Get the layer name(s) from the env_name environment variable. If layer - * is found in search_list then add it to ext_list. + * is found in search_list then add it to layer_list. */ static void loader_add_layer_env( const char *env_name, - struct loader_extension_list *ext_list, - const struct loader_extension_list *search_list) + struct loader_layer_list *layer_list, + const struct loader_layer_list *search_list) { char *layerEnv; char *next, *name; @@ -1640,7 +1811,7 @@ static void loader_add_layer_env( while (name && *name ) { next = loader_get_next_path(name); - loader_find_layer_name_add_list(name, search_list, ext_list); + loader_find_layer_name_add_list(name, search_list, layer_list); name = next; } @@ -1655,24 +1826,21 @@ void loader_deactivate_instance_layers(struct loader_instance *instance) /* Create instance chain of enabled layers */ for (uint32_t i = 0; i < instance->activated_layer_list.count; i++) { - struct loader_extension_property *ext_prop = &instance->activated_layer_list.list[i]; + struct loader_layer_properties *layer_prop = &instance->activated_layer_list.list[i]; - loader_remove_layer_lib(instance, ext_prop); + loader_remove_layer_lib(instance, layer_prop); } - loader_destroy_ext_list(&instance->activated_layer_list); - instance->activated_layer_list.count = 0; + loader_destroy_layer_list(&instance->activated_layer_list); } -void loader_enable_instance_layers(struct loader_instance *inst) +void loader_enable_instance_layers( + struct loader_instance *inst, + const VkInstanceCreateInfo *pCreateInfo) { if (inst == NULL) return; - if (inst->activated_layer_list.list == NULL || inst->activated_layer_list.capacity == 0) { - loader_init_ext_list(&inst->activated_layer_list); - } - - if (inst->activated_layer_list.list == NULL) { + if (!loader_init_layer_list(&inst->activated_layer_list)) { loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "Failed to malloc Instance activated layer list"); return; } @@ -1681,21 +1849,20 @@ void loader_enable_instance_layers(struct loader_instance *inst) loader_add_layer_implicit( VK_LAYER_TYPE_INSTANCE_IMPLICIT, &inst->activated_layer_list, - loader.scanned_layers.count, - loader.scanned_layers.list); + &loader.scanned_layers); /* Add any layers specified via environment variable first */ loader_add_layer_env( "VK_INSTANCE_LAYERS", &inst->activated_layer_list, - &loader.global_extensions); + &loader.scanned_layers); /* Add layers specified by the application */ - loader_add_layer_ext_to_ext_list( - &inst->activated_layer_list, - inst->app_extension_count, - inst->app_extension_props, - &loader.global_extensions); + loader_add_layer_names_to_list( + &inst->activated_layer_list, + pCreateInfo->layerCount, + pCreateInfo->ppEnabledLayerNames, + &loader.scanned_layers); } uint32_t loader_activate_instance_layers(struct loader_instance *inst) @@ -1727,7 +1894,7 @@ uint32_t loader_activate_instance_layers(struct loader_instance *inst) /* Create instance chain of enabled layers */ layer_idx = inst->activated_layer_list.count - 1; for (int32_t i = inst->activated_layer_list.count - 1; i >= 0; i--) { - struct loader_extension_property *ext_prop = &inst->activated_layer_list.list[i]; + struct loader_layer_properties *layer_prop = &inst->activated_layer_list.list[i]; loader_platform_dl_handle lib_handle; /* @@ -1744,8 +1911,6 @@ uint32_t loader_activate_instance_layers(struct loader_instance *inst) * will not use a wrapped object and must look up their local dispatch table from * the given baseObject. */ - assert(ext_prop->origin == VK_EXTENSION_ORIGIN_LAYER); - nextInstObj = (wrappedInstance + layer_idx); nextInstObj->pGPA = nextGPA; nextInstObj->baseObject = baseObj; @@ -1753,20 +1918,21 @@ uint32_t loader_activate_instance_layers(struct loader_instance *inst) nextObj = (VkObject) nextInstObj; char funcStr[256]; - snprintf(funcStr, 256, "%sGetInstanceProcAddr", ext_prop->info.name); - lib_handle = loader_add_layer_lib("instance", ext_prop); + snprintf(funcStr, 256, "%sGetInstanceProcAddr", layer_prop->info.layerName); + lib_handle = loader_add_layer_lib("instance", layer_prop); if ((nextGPA = (PFN_vkGetInstanceProcAddr) loader_platform_get_proc_address(lib_handle, funcStr)) == NULL) nextGPA = (PFN_vkGetInstanceProcAddr) loader_platform_get_proc_address(lib_handle, "vkGetInstanceProcAddr"); if (!nextGPA) { - loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "Failed to find vkGetInstanceProcAddr in layer %s", ext_prop->lib_name); + loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "Failed to find vkGetInstanceProcAddr in layer %s", layer_prop->lib_info.lib_name); /* TODO: Should we return nextObj, nextGPA to previous? */ continue; } loader_log(VK_DBG_REPORT_INFO_BIT, 0, - "Insert instance layer library %s for extension: %s", - ext_prop->lib_name, ext_prop->info.name); + "Insert instance layer %s (%s)", + layer_prop->info.layerName, + layer_prop->lib_info.lib_name); layer_idx--; } @@ -1786,14 +1952,14 @@ void loader_activate_instance_layer_extensions(struct loader_instance *inst) } static void loader_enable_device_layers( - struct loader_device *dev, - struct loader_extension_list *ext_list) + struct loader_device *dev, + const VkDeviceCreateInfo *pCreateInfo) { if (dev == NULL) return; if (dev->activated_layer_list.list == NULL || dev->activated_layer_list.capacity == 0) { - loader_init_ext_list(&dev->activated_layer_list); + loader_init_layer_list(&dev->activated_layer_list); } if (dev->activated_layer_list.list == NULL) { @@ -1803,25 +1969,31 @@ static void loader_enable_device_layers( /* Add any implicit layers first */ loader_add_layer_implicit( - VK_LAYER_TYPE_DEVICE_IMPLICIT, - &dev->activated_layer_list, - loader.scanned_layers.count, - loader.scanned_layers.list); + VK_LAYER_TYPE_DEVICE_IMPLICIT, + &dev->activated_layer_list, + &loader.scanned_layers); /* Add any layers specified via environment variable next */ loader_add_layer_env( - "VK_DEVICE_LAYERS", - &dev->activated_layer_list, - &loader.global_extensions); + "VK_DEVICE_LAYERS", + &dev->activated_layer_list, + &loader.scanned_layers); /* Add layers specified by the application */ - loader_add_layer_ext_to_ext_list( - &dev->activated_layer_list, - dev->app_extension_count, - dev->app_extension_props, - ext_list); + loader_add_layer_names_to_list( + &dev->activated_layer_list, + pCreateInfo->layerCount, + pCreateInfo->ppEnabledLayerNames, + &loader.scanned_layers); } +/* + * This function terminates the device chain fro CreateDevice. + * CreateDevice is a special case and so the loader call's + * the ICD's CreateDevice before creating the chain. Since + * we can't call CreateDevice twice we must terminate the + * device chain with something else. + */ static VkResult scratch_vkCreateDevice( VkPhysicalDevice gpu, const VkDeviceCreateInfo *pCreateInfo, @@ -1832,10 +2004,6 @@ static VkResult scratch_vkCreateDevice( static void * VKAPI loader_GetDeviceChainProcAddr(VkDevice device, const char * name) { - /* CreateDevice workaround: Make the terminator be a scratch function - * that does nothing since we have already called the ICD's create device. - * We can then call down the device chain and have all the layers get set up. - */ if (!strcmp(name, "vkGetDeviceProcAddr")) return (void *) loader_GetDeviceChainProcAddr; if (!strcmp(name, "vkCreateDevice")) @@ -1850,9 +2018,7 @@ static uint32_t loader_activate_device_layers( VkPhysicalDevice gpu, VkDevice device, struct loader_device *dev, - struct loader_icd *icd, - uint32_t ext_count, - const VkExtensionProperties *ext_props) + struct loader_icd *icd) { if (!icd) return 0; @@ -1868,7 +2034,6 @@ static uint32_t loader_activate_device_layers( PFN_vkGetDeviceProcAddr nextGPA = loader_GetDeviceChainProcAddr; VkBaseLayerObject *wrappedGpus; - if (!dev->activated_layer_list.count) return 0; @@ -1880,11 +2045,9 @@ static uint32_t loader_activate_device_layers( for (int32_t i = dev->activated_layer_list.count - 1; i >= 0; i--) { - struct loader_extension_property *ext_prop = &dev->activated_layer_list.list[i]; + struct loader_layer_properties *layer_prop = &dev->activated_layer_list.list[i]; loader_platform_dl_handle lib_handle; - assert(ext_prop->origin == VK_EXTENSION_ORIGIN_LAYER); - nextGpuObj = (wrappedGpus + i); nextGpuObj->pGPA = nextGPA; nextGpuObj->baseObject = baseObj; @@ -1892,18 +2055,19 @@ static uint32_t loader_activate_device_layers( nextObj = (VkObject) nextGpuObj; char funcStr[256]; - snprintf(funcStr, 256, "%sGetDeviceProcAddr", ext_prop->info.name); - lib_handle = loader_add_layer_lib("device", ext_prop); + snprintf(funcStr, 256, "%sGetDeviceProcAddr", layer_prop->info.layerName); + lib_handle = loader_add_layer_lib("device", layer_prop); if ((nextGPA = (PFN_vkGetDeviceProcAddr) loader_platform_get_proc_address(lib_handle, funcStr)) == NULL) nextGPA = (PFN_vkGetDeviceProcAddr) loader_platform_get_proc_address(lib_handle, "vkGetDeviceProcAddr"); if (!nextGPA) { - loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "Failed to find vkGetDeviceProcAddr in layer %s", ext_prop->info.name); + loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "Failed to find vkGetDeviceProcAddr in layer %s", layer_prop->info.layerName); continue; } loader_log(VK_DBG_REPORT_INFO_BIT, 0, - "Insert device layer library %s for extension: %s", - ext_prop->lib_name, ext_prop->info.name); + "Insert device layer library %s (%s)", + layer_prop->info.layerName, + layer_prop->lib_info.lib_name); } @@ -1965,7 +2129,6 @@ VkResult loader_DestroyInstance( while (next != NULL) { if (next == ptr_instance) { // Remove this instance from the list: - free(ptr_instance->app_extension_props); if (prev) prev->next = next->next; else @@ -2040,33 +2203,31 @@ VkResult loader_init_physical_device_info( /* TODO: Add cleanup code here */ res = VK_ERROR_OUT_OF_HOST_MEMORY; } - if (res == VK_SUCCESS && icd->GetPhysicalDeviceExtensionProperties && icd->GetPhysicalDeviceExtensionCount) { - uint32_t extension_count; - - res = icd->GetPhysicalDeviceExtensionCount(icd->gpus[i], &extension_count); - if (res == VK_SUCCESS) { - struct loader_extension_property ext_props; - - /* Gather all the ICD extensions */ - for (uint32_t extension_id = 0; extension_id < extension_count; extension_id++) { - res = icd->GetPhysicalDeviceExtensionProperties(icd->gpus[i], - extension_id, &ext_props.info); - if (res == VK_SUCCESS) { - ext_props.origin = VK_EXTENSION_ORIGIN_ICD; - ext_props.lib_name = icd->scanned_icds->lib_name; - ext_props.get_proc_addr = icd->GetDeviceProcAddr; - loader_add_to_ext_list(&icd->device_extension_cache[i], 1, &ext_props); - } + if (res == VK_SUCCESS) { + + loader_add_physical_device_extensions( + icd->GetPhysicalDeviceExtensionProperties, + icd->gpus[0], + VK_EXTENSION_ORIGIN_ICD, + icd->scanned_icds->lib_name, + &icd->device_extension_cache[i]); + + for (uint32_t l = 0; l < loader.scanned_layers.count; l++) { + loader_platform_dl_handle lib_handle; + char *lib_name = loader.scanned_layers.list[i].lib_info.lib_name; + + lib_handle = loader_platform_open_library(lib_name); + if (lib_handle == NULL) { + loader_log(VK_DBG_REPORT_DEBUG_BIT, 0, "open library failed: %s", lib_name); + continue; } + loader_log(VK_DBG_REPORT_DEBUG_BIT, 0, + "library: %s", lib_name); - // Traverse layers list adding non-duplicate extensions to the list - for (uint32_t l = 0; l < loader.scanned_layers.count; l++) { - loader_get_physical_device_layer_extensions( - ptr_instance, - icd->gpus[i], - &loader.scanned_layers.list[i], - &icd->device_extension_cache[i]); - } + loader_add_physical_device_layer_properties( + icd, lib_name, lib_handle); + + loader_platform_close_library(lib_handle); } } @@ -2075,6 +2236,8 @@ VkResult loader_init_physical_device_info( for (uint32_t j = 0; j < i; j++) { loader_destroy_ext_list(&icd->device_extension_cache[i]); } + + loader_destroy_layer_list(&icd->layer_properties_cache); return res; } } @@ -2244,6 +2407,13 @@ VkResult loader_CreateDevice( return VK_ERROR_INITIALIZATION_FAILED; } + /* + * TODO: Must filter CreateInfo extension list to only + * those extensions supported by the ICD. + * TODO: Probably should verify that every extension is + * covered by either the ICD or some layer. + */ + res = icd->CreateDevice(gpu, pCreateInfo, pDevice); if (res != VK_SUCCESS) { return res; @@ -2260,31 +2430,17 @@ VkResult loader_CreateDevice( dev->loader_dispatch.CreateDevice = scratch_vkCreateDevice; loader_init_dispatch(*pDevice, &dev->loader_dispatch); - dev->app_extension_count = pCreateInfo->extensionCount; - dev->app_extension_props = (VkExtensionProperties *) malloc(sizeof(VkExtensionProperties) * pCreateInfo->extensionCount); - if (dev->app_extension_props == NULL && (dev->app_extension_count > 0)) { - return VK_ERROR_OUT_OF_HOST_MEMORY; - } - - /* Make local copy of extension list */ - if (dev->app_extension_count > 0 && dev->app_extension_props != NULL) { - memcpy(dev->app_extension_props, pCreateInfo->pEnabledExtensions, sizeof(VkExtensionProperties) * pCreateInfo->extensionCount); - } - /* * Put together the complete list of extensions to enable * This includes extensions requested via environment variables. */ - loader_enable_device_layers(dev, &icd->device_extension_cache[gpu_index]); + loader_enable_device_layers(dev, pCreateInfo); /* - * Load the libraries needed by the extensions on the - * enabled extension list. This will build the device chain + * Load the libraries and build the device chain * terminating with the selected device. */ - loader_activate_device_layers(gpu, *pDevice, dev, icd, - dev->app_extension_count, - dev->app_extension_props); + loader_activate_device_layers(gpu, *pDevice, dev, icd); res = dev->loader_dispatch.CreateDevice(gpu, pCreateInfo, pDevice); @@ -2377,9 +2533,13 @@ LOADER_EXPORT void * VKAPI vkGetDeviceProcAddr(VkDevice device, const char * pNa return loader_GetDeviceProcAddr(device, pName); } -LOADER_EXPORT VkResult VKAPI vkGetGlobalExtensionCount( - uint32_t* pCount) +LOADER_EXPORT VkResult VKAPI vkGetGlobalExtensionProperties( + const char* pLayerName, + uint32_t* pCount, + VkExtensionProperties* pProperties) { + struct loader_extension_list *global_extension_list; + /* Scan/discover all ICD libraries in a single-threaded manner */ loader_platform_thread_once(&once_icd, loader_icd_scan); @@ -2389,15 +2549,46 @@ LOADER_EXPORT VkResult VKAPI vkGetGlobalExtensionCount( /* merge any duplicate extensions */ loader_platform_thread_once(&once_exts, loader_coalesce_extensions); + uint32_t copy_size; + + if (pCount == NULL) { + return VK_ERROR_INVALID_POINTER; + } + loader_platform_thread_lock_mutex(&loader_lock); - *pCount = loader.global_extensions.count; + + global_extension_list = loader_global_extensions(pLayerName); + if (global_extension_list == NULL) { + loader_platform_thread_unlock_mutex(&loader_lock); + return VK_ERROR_INVALID_LAYER; + } + + if (pProperties == NULL) { + *pCount = global_extension_list->count; + loader_platform_thread_unlock_mutex(&loader_lock); + return VK_SUCCESS; + } + + copy_size = *pCount < global_extension_list->count ? *pCount : global_extension_list->count; + for (uint32_t i = 0; i < copy_size; i++) { + memcpy(&pProperties[i], + &global_extension_list->list[i].info, + sizeof(VkExtensionProperties)); + } + *pCount = copy_size; + loader_platform_thread_unlock_mutex(&loader_lock); + + if (copy_size < global_extension_list->count) { + return VK_INCOMPLETE; + } + return VK_SUCCESS; } -LOADER_EXPORT VkResult VKAPI vkGetGlobalExtensionProperties( - uint32_t extensionIndex, - VkExtensionProperties* pProperties) +LOADER_EXPORT VkResult VKAPI vkGetGlobalLayerProperties( + uint32_t* pCount, + VkLayerProperties* pProperties) { /* Scan/discover all ICD libraries in a single-threaded manner */ @@ -2409,43 +2600,110 @@ LOADER_EXPORT VkResult VKAPI vkGetGlobalExtensionProperties( /* merge any duplicate extensions */ loader_platform_thread_once(&once_exts, loader_coalesce_extensions); - if (extensionIndex >= loader.global_extensions.count) - return VK_ERROR_INVALID_VALUE; + uint32_t copy_size; + + if (pCount == NULL) { + return VK_ERROR_INVALID_POINTER; + } + /* TODO: do we still need to lock */ loader_platform_thread_lock_mutex(&loader_lock); - memcpy(pProperties, - &loader.global_extensions.list[extensionIndex], - sizeof(VkExtensionProperties)); + + struct loader_layer_list *layer_list; + layer_list = loader_global_layers(); + + if (pProperties == NULL) { + *pCount = layer_list->count; + loader_platform_thread_unlock_mutex(&loader_lock); + return VK_SUCCESS; + } + + copy_size = *pCount < layer_list->count ? *pCount : layer_list->count; + for (uint32_t i = 0; i < copy_size; i++) { + memcpy(&pProperties[i], &layer_list->list[i].info, sizeof(VkLayerProperties)); + } + *pCount = copy_size; loader_platform_thread_unlock_mutex(&loader_lock); + + if (copy_size < layer_list->count) { + return VK_INCOMPLETE; + } + return VK_SUCCESS; } -VkResult loader_GetPhysicalDeviceExtensionCount( +VkResult loader_GetPhysicalDeviceExtensionProperties( VkPhysicalDevice gpu, - uint32_t* pCount) + const char* pLayerName, + uint32_t* pCount, + VkExtensionProperties* pProperties) { uint32_t gpu_index; struct loader_icd *icd = loader_get_icd(gpu, &gpu_index); - *pCount = icd->device_extension_cache[gpu_index].count; + uint32_t copy_size; + + if (pCount == NULL) { + return VK_ERROR_INVALID_POINTER; + } + + uint32_t count; + struct loader_extension_list *list; + loader_physical_device_extensions(icd, gpu_index, pLayerName, &count, &list); + + if (pProperties == NULL) { + *pCount = count; + return VK_SUCCESS; + } + + copy_size = *pCount < count ? *pCount : count; + for (uint32_t i = 0; i < copy_size; i++) { + memcpy(&pProperties[i], + &list->list[i].info, + sizeof(VkExtensionProperties)); + } + *pCount = copy_size; + + if (copy_size < count) { + return VK_INCOMPLETE; + } return VK_SUCCESS; } -VkResult loader_GetPhysicalDeviceExtensionProperties( +VkResult loader_GetPhysicalDeviceLayerProperties( VkPhysicalDevice gpu, - uint32_t extensionIndex, - VkExtensionProperties* pProperties) + uint32_t* pCount, + VkLayerProperties* pProperties) { uint32_t gpu_index; struct loader_icd *icd = loader_get_icd(gpu, &gpu_index); + uint32_t copy_size; - if (extensionIndex >= icd->device_extension_cache[gpu_index].count) - return VK_ERROR_INVALID_VALUE; + if (pCount == NULL) { + return VK_ERROR_INVALID_POINTER; + } + + uint32_t count; + struct loader_layer_list *layer_list; + loader_physical_device_layers(icd, &count, &layer_list); - memcpy( pProperties, - &icd->device_extension_cache[gpu_index].list[extensionIndex], - sizeof(VkExtensionProperties)); + if (pProperties == NULL) { + *pCount = count; + return VK_SUCCESS; + } + + copy_size = *pCount < count ? *pCount : count; + for (uint32_t i = 0; i < copy_size; i++) { + memcpy(&pProperties[i], + &layer_list->list[i].info, + sizeof(VkLayerProperties)); + } + *pCount = copy_size; + + if (copy_size < count) { + return VK_INCOMPLETE; + } return VK_SUCCESS; } diff --git a/loader/loader.h b/loader/loader.h index 5f4aabd4..d4e8b354 100644 --- a/loader/loader.h +++ b/loader/loader.h @@ -43,9 +43,12 @@ # define LOADER_EXPORT #endif -#define MAX_EXTENSION_NAME_SIZE 255 +#define MAX_EXTENSION_NAME_SIZE (VK_MAX_EXTENSION_NAME-1) #define MAX_GPUS_PER_ICD 16 +#define VK_MAJOR(version) (version >> 22) +#define VK_MINOR(version) ((version >> 12) & 0x3ff) +#define VK_PATCH(version) (version & 0xfff) enum extension_origin { VK_EXTENSION_ORIGIN_ICD, VK_EXTENSION_ORIGIN_LAYER, @@ -65,18 +68,6 @@ struct loader_extension_property { VkExtensionProperties info; const char *lib_name; enum extension_origin origin; - // An extension library can export the same extension - // under different names. Handy to provide a "grouping" - // such as Validation. However, the loader requires - // that a layer be included only once in a chain. - // During layer scanning the loader will check if - // the vkGetInstanceProcAddr is the same as an existing extension - // If so, it will link them together via the alias pointer. - // At initialization time we'll follow the alias pointer - // to the "base" extension and then use that extension - // internally to ensure we reject duplicates - PFN_vkGPA get_proc_addr; - struct loader_extension_property *alias; }; struct loader_extension_list { @@ -102,12 +93,9 @@ struct loader_layer_functions { }; struct loader_layer_properties { - char *name; + VkLayerProperties info; enum layer_type type; struct loader_lib_info lib_info; - char *abi_versions; - char *impl_version; - char *description; struct loader_layer_functions functions; struct loader_extension_list instance_extension_list; struct loader_extension_list device_extension_list; @@ -129,7 +117,7 @@ struct loader_device { uint32_t app_extension_count; VkExtensionProperties *app_extension_props; - struct loader_extension_list activated_layer_list; + struct loader_layer_list activated_layer_list; struct loader_device *next; }; @@ -154,14 +142,22 @@ struct loader_icd { PFN_vkGetPhysicalDeviceQueueCount GetPhysicalDeviceQueueCount; PFN_vkGetPhysicalDeviceQueueProperties GetPhysicalDeviceQueueProperties; PFN_vkGetPhysicalDeviceMemoryProperties GetPhysicalDeviceMemoryProperties; - PFN_vkGetPhysicalDeviceExtensionCount GetPhysicalDeviceExtensionCount; PFN_vkGetPhysicalDeviceExtensionProperties GetPhysicalDeviceExtensionProperties; + PFN_vkGetPhysicalDeviceLayerProperties GetPhysicalDeviceLayerProperties; PFN_vkDbgCreateMsgCallback DbgCreateMsgCallback; PFN_vkDbgDestroyMsgCallback DbgDestroyMsgCallback; + /* - * Fill in the cache of available extensions from all layers that - * operate with this physical device. - * This cache will be used to satisfy calls to GetPhysicalDeviceExtensionProperties + * Fill in the cache of available layers that operate + * with this physical device. This cache will be used to satisfy + * calls to GetPhysicalDeviceLayerProperties + */ + struct loader_layer_list layer_properties_cache; + + /* + * Fill in the cache of available global extensions that operate + * with this physical device. This cache will be used to satisfy + * calls to GetPhysicalDeviceExtensionProperties */ struct loader_extension_list device_extension_cache[MAX_GPUS_PER_ICD]; struct loader_icd *next; @@ -240,10 +236,7 @@ struct loader_instance { */ struct loader_msg_callback_map_entry *icd_msg_callback_map; - struct loader_extension_list activated_layer_list; - - uint32_t app_extension_count; - VkExtensionProperties *app_extension_props; + struct loader_layer_list activated_layer_list; bool debug_report_enabled; VkLayerDbgFunctionNode *DbgFunctionHead; @@ -271,10 +264,9 @@ struct loader_scanned_icds { PFN_vkCreateInstance CreateInstance; PFN_vkDestroyInstance DestroyInstance; PFN_vkEnumeratePhysicalDevices EnumeratePhysicalDevices; - PFN_vkGetGlobalExtensionCount GetGlobalExtensionCount; PFN_vkGetGlobalExtensionProperties GetGlobalExtensionProperties; - PFN_vkGetPhysicalDeviceExtensionCount GetPhysicalDeviceExtensionCount; - PFN_vkGetPhysicalDeviceExtensionProperties GetPhysicalDeviceExtensionProperties; + PFN_vkGetGlobalLayerProperties GetGlobalLayerProperties; + PFN_vkGetPhysicalDeviceLayerProperties GetPhysicalDeviceLayerProperties; VkInstance instance; struct loader_scanned_icds *next; @@ -369,14 +361,13 @@ VkResult loader_GetPhysicalDevicePerformance ( VkPhysicalDevice physicalDevice, VkPhysicalDevicePerformance* pPerformance); -VkResult loader_GetPhysicalDeviceExtensionProperties ( - VkPhysicalDevice physicalDevice, - uint32_t extensionIndex, +VkResult loader_GetPhysicalDeviceExtensionProperties (VkPhysicalDevice physicalDevice, + const char *pLayerName, uint32_t *pCount, VkExtensionProperties* pProperties); -VkResult loader_GetPhysicalDeviceExtensionCount ( - VkPhysicalDevice physicalDevice, - uint32_t* pCount); +VkResult loader_GetPhysicalDeviceLayerProperties (VkPhysicalDevice physicalDevice, + uint32_t *pCount, + VkLayerProperties* pProperties); VkResult loader_GetPhysicalDeviceQueueCount ( VkPhysicalDevice physicalDevice, @@ -411,6 +402,10 @@ void loader_add_to_ext_list( const struct loader_extension_property *props); void loader_destroy_ext_list(struct loader_extension_list *ext_info); +void loader_add_to_layer_list( + struct loader_layer_list *list, + uint32_t prop_list_count, + const struct loader_layer_properties *props); bool loader_is_extension_scanned(const VkExtensionProperties *ext_prop); void loader_icd_scan(void); void loader_layer_scan(void); @@ -419,7 +414,7 @@ void loader_coalesce_extensions(void); struct loader_icd * loader_get_icd(const VkPhysicalDevice gpu, uint32_t *gpu_index); void loader_remove_logical_device(VkDevice device); -void loader_enable_instance_layers(struct loader_instance *inst); +void loader_enable_instance_layers(struct loader_instance *inst, const VkInstanceCreateInfo *pCreateInfo); void loader_deactivate_instance_layers(struct loader_instance *instance); uint32_t loader_activate_instance_layers(struct loader_instance *inst); void loader_activate_instance_layer_extensions(struct loader_instance *inst); diff --git a/loader/table_ops.h b/loader/table_ops.h index d65fd30c..430d8113 100644 --- a/loader/table_ops.h +++ b/loader/table_ops.h @@ -370,7 +370,7 @@ static inline void loader_init_instance_core_dispatch_table(VkLayerInstanceDispa table->GetPhysicalDeviceQueueProperties = (PFN_vkGetPhysicalDeviceQueueProperties) gpa(inst, "vkGetPhysicalDeviceQueueProperties"); table->GetPhysicalDeviceMemoryProperties = (PFN_vkGetPhysicalDeviceMemoryProperties) gpa(inst, "vkGetPhysicalDeviceMemoryProperties"); table->GetPhysicalDeviceExtensionProperties = (PFN_vkGetPhysicalDeviceExtensionProperties) gpa(inst, "vkGetPhysicalDeviceExtensionProperties"); - table->GetPhysicalDeviceExtensionCount = (PFN_vkGetPhysicalDeviceExtensionCount) gpa(inst, "vkGetPhysicalDeviceExtensionCount"); + table->GetPhysicalDeviceLayerProperties = (PFN_vkGetPhysicalDeviceLayerProperties) gpa(inst, "vkGetPhysicalDeviceLayerProperties"); } static inline void loader_init_instance_extension_dispatch_table( @@ -414,10 +414,10 @@ static inline void *loader_lookup_instance_dispatch_table( return (void *) table->GetPhysicalDeviceMemoryProperties; if (!strcmp(name, "GetInstanceProcAddr")) return (void *) table->GetInstanceProcAddr; - if (!strcmp(name, "GetPhysicalDeviceExtensionCount")) - return (void *) table->GetPhysicalDeviceExtensionCount; if (!strcmp(name, "GetPhysicalDeviceExtensionProperties")) return (void *) table->GetPhysicalDeviceExtensionProperties; + if (!strcmp(name, "GetPhysicalDeviceLayerProperties")) + return (void *) table->GetPhysicalDeviceLayerProperties; if (!strcmp(name, "DbgCreateMsgCallback")) return (void *) table->DbgCreateMsgCallback; if (!strcmp(name, "DbgDestroyMsgCallback")) diff --git a/loader/trampoline.c b/loader/trampoline.c index 1f9c3635..6df6f68c 100644 --- a/loader/trampoline.c +++ b/loader/trampoline.c @@ -58,22 +58,6 @@ LOADER_EXPORT VkResult VKAPI vkCreateInstance( } loader_platform_thread_lock_mutex(&loader_lock); memset(ptr_instance, 0, sizeof(struct loader_instance)); - ptr_instance->app_extension_count = pCreateInfo->extensionCount; - ptr_instance->app_extension_props = (ptr_instance->app_extension_count > 0) ? - malloc(sizeof (VkExtensionProperties) * ptr_instance->app_extension_count) : NULL; - if (ptr_instance->app_extension_props == NULL && (ptr_instance->app_extension_count > 0)) { - loader_platform_thread_unlock_mutex(&loader_lock); - return VK_ERROR_OUT_OF_HOST_MEMORY; - } - - /* - * Make local copy of extension properties indicated by application. - */ - if (ptr_instance->app_extension_props) { - memcpy(ptr_instance->app_extension_props, - pCreateInfo->pEnabledExtensions, - sizeof(VkExtensionProperties) * ptr_instance->app_extension_count); - } ptr_instance->disp = malloc(sizeof(VkLayerInstanceDispatchTable)); if (ptr_instance->disp == NULL) { @@ -84,9 +68,9 @@ LOADER_EXPORT VkResult VKAPI vkCreateInstance( ptr_instance->next = loader.instances; loader.instances = ptr_instance; - loader_enable_instance_layers(ptr_instance); + loader_enable_instance_layers(ptr_instance, pCreateInfo); - debug_report_create_instance(ptr_instance); + debug_report_create_instance(ptr_instance, pCreateInfo); /* enable any layers on instance chain */ loader_activate_instance_layers(ptr_instance); @@ -273,23 +257,29 @@ LOADER_EXPORT VkResult VKAPI vkDestroyDevice(VkDevice device) } LOADER_EXPORT VkResult VKAPI vkGetPhysicalDeviceExtensionProperties( - VkPhysicalDevice gpu, - uint32_t extensionIndex, - VkExtensionProperties* pProperties) + VkPhysicalDevice physicalDevice, + const char* pLayerName, + uint32_t* pCount, + VkExtensionProperties* pProperties) { VkResult res; - res = loader_GetPhysicalDeviceExtensionProperties(gpu, extensionIndex, pProperties); + loader_platform_thread_lock_mutex(&loader_lock); + res = loader_GetPhysicalDeviceExtensionProperties(physicalDevice, pLayerName, pCount, pProperties); + loader_platform_thread_unlock_mutex(&loader_lock); return res; } -LOADER_EXPORT VkResult VKAPI vkGetPhysicalDeviceExtensionCount( - VkPhysicalDevice gpu, - uint32_t* pCount) +LOADER_EXPORT VkResult VKAPI vkGetPhysicalDeviceLayerProperties( + VkPhysicalDevice physicalDevice, + uint32_t* pCount, + VkLayerProperties* pProperties) { VkResult res; - res = loader_GetPhysicalDeviceExtensionCount(gpu, pCount); + loader_platform_thread_lock_mutex(&loader_lock); + res = loader_GetPhysicalDeviceLayerProperties(physicalDevice, pCount, pProperties); + loader_platform_thread_unlock_mutex(&loader_lock); return res; } diff --git a/vk-generate.py b/vk-generate.py index 14341651..eb3a32aa 100755 --- a/vk-generate.py +++ b/vk-generate.py @@ -122,7 +122,7 @@ class DispatchTableOpsSubcommand(Subcommand): stmts.append("memset(table, 0, sizeof(*table));") stmts.append("table->GetDeviceProcAddr =(PFN_vkGetDeviceProcAddr) gpa(device,\"vkGetDeviceProcAddr\");") for proto in self.protos: - if proto.name == "CreateInstance" or proto.name == "GetGlobalExtensionProperties" or proto.name == "GetGlobalExtensionCount" or proto.params[0].ty == "VkInstance" or (proto.params[0].ty == "VkPhysicalDevice" and proto.name != "CreateDevice"): + if proto.name == "CreateInstance" or proto.name == "GetGlobalExtensionProperties" or proto.name == "GetGlobalLayerProperties" or proto.params[0].ty == "VkInstance" or (proto.params[0].ty == "VkPhysicalDevice" and proto.name != "CreateDevice"): continue if proto.name != "GetDeviceProcAddr": stmts.append("table->%s = (PFN_vk%s) gpa(baseDevice, \"vk%s\");" % @@ -251,7 +251,7 @@ class WinDefFileSubcommand(Subcommand): "GetInstanceProcAddr", "GetDeviceProcAddr", "EnumerateLayers", - "GetGlobalExtensionCount", + "GetGlobalLayerProperties", "GetGlobalExtensionProperties" ], } diff --git a/vk-layer-generate.py b/vk-layer-generate.py index 5d9fa186..19cc8ff3 100755 --- a/vk-layer-generate.py +++ b/vk-layer-generate.py @@ -34,7 +34,7 @@ import vk_helper from source_line_info import sourcelineinfo def proto_is_global(proto): - if proto.params[0].ty == "VkInstance" or proto.params[0].ty == "VkPhysicalDevice" or proto.name == "CreateInstance" or proto.name == "GetGlobalExtensionCount" or proto.name == "GetGlobalExtensionProperties" or proto.name == "GetPhysicalDeviceExtensionCount" or proto.name == "GetPhysicalDeviceExtensionProperties": + if proto.params[0].ty == "VkInstance" or proto.params[0].ty == "VkPhysicalDevice" or proto.name == "CreateInstance" or proto.name == "GetGlobalLayerProperties" or proto.name == "GetGlobalExtensionProperties" or proto.name == "GetPhysicalDeviceLayerProperties" or proto.name == "GetPhysicalDeviceExtensionProperties": return True else: return False @@ -199,31 +199,29 @@ class Subcommand(object): def _gen_layer_get_global_extension_props(self, layer="Generic"): ggep_body = [] - if layer == 'APIDump' or layer == 'Generic': + # generated layers do not provide any global extensions + ggep_body.append('%s' % self.lineinfo.get()) + + ggep_body.append('') + ggep_body.append('VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionProperties(const char *pLayerName, uint32_t *pCount, VkExtensionProperties* pProperties)') + ggep_body.append('{') + ggep_body.append(' return util_GetExtensionProperties(0, NULL, pCount, pProperties);') + ggep_body.append('}') + return "\n".join(ggep_body) + + def _gen_layer_get_global_layer_props(self, layer="Generic"): + ggep_body = [] + if layer == 'Generic': + # Do nothing, extension definition part of generic.h ggep_body.append('%s' % self.lineinfo.get()) - ggep_body.append('#define LAYER_EXT_ARRAY_SIZE 1') - ggep_body.append('static const VkExtensionProperties layerExts[LAYER_EXT_ARRAY_SIZE] = {') - ggep_body.append(' {') - ggep_body.append(' VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES,') - ggep_body.append(' "%s",' % layer) - ggep_body.append(' 0x10,') - ggep_body.append(' "layer: %s",' % layer) - ggep_body.append(' }') - ggep_body.append('};') else: ggep_body.append('%s' % self.lineinfo.get()) - ggep_body.append('#define LAYER_EXT_ARRAY_SIZE 2') - ggep_body.append('static const VkExtensionProperties layerExts[LAYER_EXT_ARRAY_SIZE] = {') + ggep_body.append('#define LAYER_DEVICE_PROPS_ARRAY_SIZE 1') + ggep_body.append('static const VkLayerProperties deviceLayerProps[LAYER_DEVICE_PROPS_ARRAY_SIZE] = {') ggep_body.append(' {') - ggep_body.append(' VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES,') ggep_body.append(' "%s",' % layer) - ggep_body.append(' 0x10,') - ggep_body.append(' "layer: %s",' % layer) - ggep_body.append(' },') - ggep_body.append(' {') - ggep_body.append(' VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES,') - ggep_body.append(' "Validation",') - ggep_body.append(' 0x10,') + ggep_body.append(' VK_API_VERSION, // specVersion') + ggep_body.append(' VK_MAKE_VERSION(0, 1, 0), // implVersion') ggep_body.append(' "layer: %s",' % layer) ggep_body.append(' }') ggep_body.append('};') @@ -231,89 +229,34 @@ class Subcommand(object): ggep_body.append('%s' % self.lineinfo.get()) ggep_body.append('') - ggep_body.append('VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionProperties(uint32_t extensionIndex, VkExtensionProperties* pProperties)') + ggep_body.append('VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalLayerProperties(uint32_t *pCount, VkLayerProperties* pProperties)') ggep_body.append('{') - ggep_body.append(' if (extensionIndex >= LAYER_EXT_ARRAY_SIZE)') - ggep_body.append(' return VK_ERROR_INVALID_VALUE;') - ggep_body.append(' memcpy(pProperties, &layerExts[extensionIndex], sizeof(VkExtensionProperties));') - ggep_body.append(' return VK_SUCCESS;') + ggep_body.append(' return util_GetLayerProperties(LAYER_DEVICE_PROPS_ARRAY_SIZE, deviceLayerProps, pCount, pProperties);') ggep_body.append('}') return "\n".join(ggep_body) - def _gen_layer_get_global_extension_count(self, layer="Generic"): - ggec_body = [] - ggec_body.append('VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionCount(uint32_t* pCount)') - ggec_body.append('{') - ggec_body.append(' *pCount = LAYER_EXT_ARRAY_SIZE;') - ggec_body.append(' return VK_SUCCESS;') - ggec_body.append('}') - return "\n".join(ggec_body) - - def _gen_layer_get_physical_device_extension_props(self, layer="Generic"): + def _gen_layer_get_physical_device_layer_props(self, layer="Generic"): gpdep_body = [] - if layer == 'APIDump' or layer == 'Generic': - gpdep_body.append('#define LAYER_DEV_EXT_ARRAY_SIZE 1') - gpdep_body.append('static const VkExtensionProperties layerDevExts[LAYER_DEV_EXT_ARRAY_SIZE] = {') - gpdep_body.append(' {') - gpdep_body.append(' VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES,') - gpdep_body.append(' "%s",' % layer) - gpdep_body.append(' 0x10,') - gpdep_body.append(' "layer: %s",' % layer) - gpdep_body.append(' }') - gpdep_body.append('};') - elif layer == 'ObjectTracker': - gpdep_body.append('#define LAYER_DEV_EXT_ARRAY_SIZE 2') - gpdep_body.append('static const VkExtensionProperties layerDevExts[LAYER_DEV_EXT_ARRAY_SIZE] = {') - gpdep_body.append(' {') - gpdep_body.append(' VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES,') - gpdep_body.append(' "%s",' % layer) - gpdep_body.append(' 0x10,') - gpdep_body.append(' "layer: %s",' % layer) - gpdep_body.append(' },') - gpdep_body.append(' {') - gpdep_body.append(' VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES,') - gpdep_body.append(' "Validation",') - gpdep_body.append(' 0x10,') - gpdep_body.append(' "layer: %s",' % layer) - gpdep_body.append(' }') - gpdep_body.append('};') + if layer == 'Generic': + # Do nothing, extension definition part of generic.h + ggep_body.append('%s' % self.lineinfo.get()) else: - gpdep_body.append('#define LAYER_DEV_EXT_ARRAY_SIZE 2') - gpdep_body.append('static const VkExtensionProperties layerDevExts[LAYER_DEV_EXT_ARRAY_SIZE] = {') + gpdep_body.append('#define LAYER_DEV_EXT_ARRAY_SIZE 1') + gpdep_body.append('static const VkLayerProperties layerDevProps[LAYER_DEV_EXT_ARRAY_SIZE] = {') gpdep_body.append(' {') - gpdep_body.append(' VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES,') gpdep_body.append(' "%s",' % layer) - gpdep_body.append(' 0x10,') - gpdep_body.append(' "layer: %s",' % layer) - gpdep_body.append(' },') - gpdep_body.append(' {') - gpdep_body.append(' VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES,') - gpdep_body.append(' "Validation",') - gpdep_body.append(' 0x10,') + gpdep_body.append(' VK_API_VERSION,') + gpdep_body.append(' VK_MAKE_VERSION(0, 1, 0),') gpdep_body.append(' "layer: %s",' % layer) gpdep_body.append(' }') gpdep_body.append('};') - gpdep_body.append('VK_LAYER_EXPORT VkResult VKAPI vkGetPhysicalDeviceExtensionProperties(VkPhysicalDevice physicalDevice, uint32_t extensionIndex, VkExtensionProperties* pProperties)') + gpdep_body.append('VK_LAYER_EXPORT VkResult VKAPI vkGetPhysicalDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, VkLayerProperties* pProperties)') gpdep_body.append('{') - gpdep_body.append(' if (extensionIndex >= LAYER_DEV_EXT_ARRAY_SIZE)') - gpdep_body.append(' return VK_ERROR_INVALID_VALUE;') - gpdep_body.append(' memcpy(pProperties, &layerDevExts[extensionIndex], sizeof(VkExtensionProperties));') - gpdep_body.append(' return VK_SUCCESS;') + gpdep_body.append(' return util_GetLayerProperties(LAYER_DEV_EXT_ARRAY_SIZE, layerDevProps, pCount, pProperties);') gpdep_body.append('}') gpdep_body.append('') return "\n".join(gpdep_body) - def _gen_layer_get_physical_device_extension_count(self, layer="Generic"): - gpdec_body = [] - gpdec_body.append('VK_LAYER_EXPORT VkResult VKAPI vkGetPhysicalDeviceExtensionCount(VkPhysicalDevice physicalDevice, uint32_t* pCount)') - gpdec_body.append('{') - gpdec_body.append(' *pCount = LAYER_DEV_EXT_ARRAY_SIZE;') - gpdec_body.append(' return VK_SUCCESS;') - gpdec_body.append('}') - gpdec_body.append('') - return "\n".join(gpdec_body) - - def _generate_dispatch_entrypoints(self, qual=""): if qual: qual += " " @@ -335,12 +278,10 @@ class Subcommand(object): funcs.append('/* CreateDevice HERE */') elif 'GetGlobalExtensionProperties' == proto.name: intercept = self._gen_layer_get_global_extension_props(self.layer_name) - elif 'GetGlobalExtensionCount' == proto.name: - intercept = self._gen_layer_get_global_extension_count(self.layer_name) - elif 'GetPhysicalDeviceExtensionProperties' == proto.name: - intercept = self._gen_layer_get_physical_device_extension_props(self.layer_name) - elif 'GetPhysicalDeviceExtensionCount' == proto.name: - intercept = self._gen_layer_get_physical_device_extension_count(self.layer_name) + elif 'GetGlobalLayerProperties' == proto.name: + intercept = self._gen_layer_get_global_layer_props(self.layer_name) + elif 'GetPhysicalDeviceLayerProperties' == proto.name: + intercept = self._gen_layer_get_physical_device_layer_props(self.layer_name) if intercept is not None: @@ -590,6 +531,7 @@ class LayerDispatchSubcommand(Subcommand): class GenericLayerSubcommand(Subcommand): def generate_header(self): gen_header = [] + func_body.append('%s' % self.lineinfo.get()) gen_header.append('#include ') gen_header.append('#include ') gen_header.append('#include ') @@ -603,6 +545,8 @@ class GenericLayerSubcommand(Subcommand): gen_header.append('#include "vk_layer_msg.h"') gen_header.append('#include "vk_layer_table.h"') gen_header.append('') + gen_header.append('#include "generic.h') + gen_header.append('') gen_header.append('static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(initOnce);') gen_header.append('struct devExts {') gen_header.append(' bool wsi_lunarg_enabled;') @@ -615,7 +559,7 @@ class GenericLayerSubcommand(Subcommand): gen_header.append(' VkLayerDispatchTable *pDisp = device_dispatch_table(device);') gen_header.append(' deviceExtMap[pDisp].wsi_lunarg_enabled = false;') gen_header.append(' for (i = 0; i < pCreateInfo->extensionCount; i++) {') - gen_header.append(' if (strcmp(pCreateInfo->pEnabledExtensions[i].name, VK_WSI_LUNARG_EXTENSION_NAME) == 0)') + gen_header.append(' if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_WSI_LUNARG_EXTENSION_NAME) == 0)') gen_header.append(' deviceExtMap[pDisp].wsi_lunarg_enabled = true;') gen_header.append('') gen_header.append(' }') @@ -623,7 +567,7 @@ class GenericLayerSubcommand(Subcommand): gen_header.append('') return "\n".join(gen_header) def generate_intercept(self, proto, qual): - if proto.name in [ 'GetGlobalExtensionCount', 'GetGlobalExtensionProperties', 'GetPhysicalDeviceExtensionCount', 'GetPhysicalDeviceExtensionProperties' ]: + if proto.name in [ 'GetGlobalLayerProperties', 'GetGlobalExtensionProperties', 'GetPhysicalDeviceLayerProperties', 'GetPhysicalDeviceExtensionProperties' ]: # use default version return None decl = proto.c_func(prefix="vk", attr="VKAPI") @@ -646,7 +590,7 @@ class GenericLayerSubcommand(Subcommand): ' layerCbMsg(VK_DBG_REPORT_INFO_BIT,VK_OBJECT_TYPE_PHYSICAL_DEVICE, gpu, 0, 0, (char *) "GENERIC", (char *) str);\n' ' %sdevice_dispatch_table(*pDevice)->%s;\n' ' if (result == VK_SUCCESS) {\n' - ' enable_debug_report(pCreateInfo->extensionCount, pCreateInfo->pEnabledExtensions);\n' + ' enable_debug_report(pCreateInfo->extensionCount, pCreateInfo->ppEnabledExtensionNames);\n' ' createDeviceRegisterExtensions(pCreateInfo, *pDevice);\n' ' }\n' ' sprintf(str, "Completed layered %s\\n");\n' @@ -745,6 +689,7 @@ class APIDumpSubcommand(Subcommand): header_txt.append('#include "vk_layer.h"') header_txt.append('#include "vk_struct_string_helper_cpp.h"') header_txt.append('#include "vk_layer_table.h"') + header_txt.append('#include "vk_layer_extension_utils.h"') header_txt.append('#include ') header_txt.append('') header_txt.append('// The following is #included again to catch certain OS-specific functions being used:') @@ -788,7 +733,7 @@ class APIDumpSubcommand(Subcommand): header_txt.append(' VkLayerDispatchTable *pDisp = device_dispatch_table(device);') header_txt.append(' deviceExtMap[pDisp].wsi_lunarg_enabled = false;') header_txt.append(' for (i = 0; i < pCreateInfo->extensionCount; i++) {') - header_txt.append(' if (strcmp(pCreateInfo->pEnabledExtensions[i].name, VK_WSI_LUNARG_EXTENSION_NAME) == 0)') + header_txt.append(' if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_WSI_LUNARG_EXTENSION_NAME) == 0)') header_txt.append(' deviceExtMap[pDisp].wsi_lunarg_enabled = true;') header_txt.append('') header_txt.append(' }') @@ -875,7 +820,7 @@ class APIDumpSubcommand(Subcommand): return "\n".join(func_body) def generate_intercept(self, proto, qual): - if proto.name in [ 'GetGlobalExtensionCount','GetGlobalExtensionProperties','GetPhysicalDeviceExtensionCount','GetPhysicalDeviceExtensionProperties']: + if proto.name in [ 'GetGlobalLayerProperties','GetGlobalExtensionProperties','GetPhysicalDeviceLayerProperties','GetPhysicalDeviceExtensionProperties']: return None decl = proto.c_func(prefix="vk", attr="VKAPI") ret_val = '' @@ -1091,7 +1036,7 @@ class ObjectTrackerSubcommand(Subcommand): return "\n".join(header_txt) def generate_intercept(self, proto, qual): - if proto.name in [ 'DbgCreateMsgCallback', 'GetGlobalExtensionCount', 'GetGlobalExtensionProperties','GetPhysicalDeviceExtensionCount', 'GetPhysicalDeviceExtensionProperties' ]: + if proto.name in [ 'DbgCreateMsgCallback', 'GetGlobalLayerProperties', 'GetGlobalExtensionProperties','GetPhysicalDeviceLayerProperties', 'GetPhysicalDeviceExtensionProperties' ]: # use default version return None @@ -1391,7 +1336,7 @@ class ThreadingSubcommand(Subcommand): ' %s %s_dispatch_table(*pInstance)->CreateInstance(pCreateInfo, pInstance);\n' '\n' ' if (result == VK_SUCCESS) {\n' - ' enable_debug_report(pCreateInfo->extensionCount, pCreateInfo->pEnabledExtensions);\n' + ' enable_debug_report(pCreateInfo->extensionCount, pCreateInfo->ppEnabledExtensionNames);\n' ' VkLayerInstanceDispatchTable *pTable = instance_dispatch_table(*pInstance);\n' ' debug_report_init_instance_extension_dispatch_table(\n' ' pTable,\n' diff --git a/vulkan.py b/vulkan.py index ffba32c1..b3b69753 100755 --- a/vulkan.py +++ b/vulkan.py @@ -281,19 +281,24 @@ core = Extension( Proto("VkResult", "GetPhysicalDeviceExtensionProperties", [Param("VkPhysicalDevice", "gpu"), - Param("uint32_t", "extensionIndex"), + Param("const char*", "pLayerName"), + Param("uint32_t*", "pCount"), Param("VkExtensionProperties*", "pProperties")]), - Proto("VkResult", "GetPhysicalDeviceExtensionCount", + Proto("VkResult", "GetPhysicalDeviceLayerProperties", [Param("VkPhysicalDevice", "gpu"), - Param("uint32_t*", "pCount")]), + Param("const char*", "pLayerName"), + Param("uint32_t*", "pCount"), + Param("VkLayerProperties*", "pProperties")]), Proto("VkResult", "GetGlobalExtensionProperties", - [Param("uint32_t", "extensionIndex"), + [Param("const char*", "pLayerName"), + Param("uint32_t*", "pCount"), Param("VkExtensionProperties*", "pProperties")]), - Proto("VkResult", "GetGlobalExtensionCount", - [Param("uint32_t*", "pCount")]), + Proto("VkResult", "GetGlobalLayerProperties", + [Param("uint32_t*", "pCount"), + Param("VkExtensionProperties*", "pProperties")]), Proto("VkResult", "GetDeviceQueue", [Param("VkDevice", "device"), -- cgit v1.2.3