typedef struct VkLayerDispatchTable_
{
PFN_vkGetDeviceProcAddr GetDeviceProcAddr;
- PFN_vkCreateDevice CreateDevice;
PFN_vkDestroyDevice DestroyDevice;
PFN_vkGetDeviceQueue GetDeviceQueue;
PFN_vkQueueSubmit QueueSubmit;
PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
PFN_vkCreateInstance CreateInstance;
PFN_vkDestroyInstance DestroyInstance;
+ PFN_vkCreateDevice CreateDevice;
PFN_vkEnumeratePhysicalDevices EnumeratePhysicalDevices;
PFN_vkGetPhysicalDeviceFeatures GetPhysicalDeviceFeatures;
PFN_vkGetPhysicalDeviceImageFormatProperties GetPhysicalDeviceImageFormatProperties;
// ------------------------------------------------------------------------------------------------
// CreateInstance and CreateDevice support structures
+
+typedef enum VkLayerFunction_
+{
+ VK_LAYER_LINK_INFO = 0,
+ VK_LAYER_DEVICE_INFO = 1,
+ VK_LAYER_INSTANCE_INFO = 2
+} VkLayerFunction;
+
+/*
+ * When creating the device chain the loader needs to pass
+ * down information about it's device structure needed at
+ * the end of the chain. Passing the data via the
+ * VkLayerDeviceInfo avoids issues with finding the
+ * exact instance being used.
+ */
+typedef struct VkLayerInstanceInfo_ {
+ void *instance_info;
+ PFN_vkGetInstanceProcAddr pfnNextGetInstanceProcAddr;
+} VkLayerInstanceInfo;
+
typedef struct VkLayerInstanceLink_ {
struct VkLayerInstanceLink_* pNext;
PFN_vkGetInstanceProcAddr pfnNextGetInstanceProcAddr;
} VkLayerInstanceLink;
+/*
+ * When creating the device chain the loader needs to pass
+ * down information about it's device structure needed at
+ * the end of the chain. Passing the data via the
+ * VkLayerDeviceInfo avoids issues with finding the
+ * exact instance being used.
+ */
+typedef struct VkLayerDeviceInfo_ {
+ void *device_info;
+ PFN_vkGetInstanceProcAddr pfnNextGetInstanceProcAddr;
+} VkLayerDeviceInfo;
+
typedef struct {
VkStructureType sType; // VK_STRUCTURE_TYPE_LAYER_INSTANCE_CREATE_INFO
const void* pNext;
- VkLayerInstanceLink* pLayerInfo;
+ VkLayerFunction function;
+ union {
+ VkLayerInstanceLink* pLayerInfo;
+ VkLayerInstanceInfo instanceInfo;
+ } u;
} VkLayerInstanceCreateInfo;
typedef struct VkLayerDeviceLink_ {
typedef struct {
VkStructureType sType; // VK_STRUCTURE_TYPE_LAYER_DEVICE_CREATE_INFO
const void* pNext;
- VkLayerDeviceLink* pLayerInfo;
+ VkLayerFunction function;
+ union {
+ VkLayerDeviceLink* pLayerInfo;
+ VkLayerDeviceInfo deviceInfo;
+ } u;
} VkLayerDeviceCreateInfo;
// ------------------------------------------------------------------------------------------------
}
}
+VkResult
+explicit_CreateDevice(
+ VkPhysicalDevice gpu,
+ const VkDeviceCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkDevice *pDevice)
+{
+ VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
+
+ assert(chain_info->u.pLayerInfo);
+ PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
+ PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
+ PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice) fpGetInstanceProcAddr(NULL, "vkCreateDevice");
+ if (fpCreateDevice == NULL) {
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ // Advance the link info for the next element on the chain
+ chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
+
+ VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
+ if (result != VK_SUCCESS) {
+ return result;
+ }
+
+ initDeviceTable(*pDevice, fpGetDeviceProcAddr);
+
+ createDeviceRegisterExtensions(pCreateInfo, *pDevice);
+
+ return result;
+}
}
}
+VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL basic_CreateInstance(
+ const VkInstanceCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkInstance* pInstance)
+{
+ VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
+
+ assert(chain_info->u.pLayerInfo);
+ PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
+ PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance) fpGetInstanceProcAddr(NULL, "vkCreateInstance");
+ if (fpCreateInstance == NULL) {
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ // Advance the link info for the next element on the chain
+ chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
+
+ VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
+ if (result != VK_SUCCESS)
+ return result;
+
+ initInstanceTable(*pInstance, fpGetInstanceProcAddr);
+
+ return result;
+}
+
VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL basic_EnumeratePhysicalDevices(
VkInstance instance,
uint32_t* pPhysicalDeviceCount,
return result;
}
-VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL basic_CreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice)
+VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL basic_CreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice)
{
- printf("At start of wrapped vkCreateDevice() call w/ gpu: %p\n", (void*)gpu);
- VkResult result = device_dispatch_table(*pDevice)->CreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
- printf("Completed wrapped vkCreateDevice() call w/ pDevice, Device %p: %p\n", (void*)pDevice, (void *) *pDevice);
+ printf("VK_LAYER_LUNARG_Basic: At start of vkCreateDevice() call w/ gpu: %p\n", (void*)physicalDevice);
+
+ VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
+
+ assert(chain_info->u.pLayerInfo);
+ PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
+ PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
+ PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice) fpGetInstanceProcAddr(NULL, "vkCreateDevice");
+ if (fpCreateDevice == NULL) {
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ // Advance the link info for the next element on the chain
+ chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
+
+ VkResult result = fpCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);
+ if (result != VK_SUCCESS) {
+ return result;
+ }
+
+ initDeviceTable(*pDevice, fpGetDeviceProcAddr);
+
+ printf("VK_LAYER_LUNARG_Basic: Completed vkCreateDevice() call w/ pDevice, Device %p: %p\n", (void*)pDevice, (void *) *pDevice);
return result;
}
VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char* pName)
{
- if (device == NULL)
- return NULL;
-
- /* loader uses this to force layer initialization; device object is wrapped */
- if (!strcmp("vkGetDeviceProcAddr", pName)) {
- initDeviceTable((const VkBaseLayerObject *) device);
+ if (!strcmp("vkGetDeviceProcAddr", pName))
return (PFN_vkVoidFunction) vkGetDeviceProcAddr;
- }
-
- if (!strcmp("vkCreateDevice", pName))
- return (PFN_vkVoidFunction) basic_CreateDevice;
if (!strcmp("vkDestroyDevice", pName))
return (PFN_vkVoidFunction) basic_DestroyDevice;
if (!strcmp("vkLayerExtension1", pName))
return (PFN_vkVoidFunction) vkLayerExtension1;
- else
- {
- if (device_dispatch_table(device)->GetDeviceProcAddr == NULL)
- return NULL;
- return device_dispatch_table(device)->GetDeviceProcAddr(device, pName);
- }
+
+ if (device == NULL)
+ return NULL;
+
+ if (device_dispatch_table(device)->GetDeviceProcAddr == NULL)
+ return NULL;
+ return device_dispatch_table(device)->GetDeviceProcAddr(device, pName);
}
VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* pName)
{
- if (instance == NULL)
- return NULL;
-
- /* loader uses this to force layer initialization; instance object is wrapped */
- if (!strcmp("vkGetInstanceProcAddr", pName)) {
- initInstanceTable((const VkBaseLayerObject *) instance);
+ if (!strcmp("vkGetInstanceProcAddr", pName))
return (PFN_vkVoidFunction) vkGetInstanceProcAddr;
- }
-
if (!strcmp("vkEnumerateDeviceLayerProperties", pName))
return (PFN_vkVoidFunction) vkEnumerateDeviceLayerProperties;
if (!strcmp("vkEnumerateDeviceExtensionProperties", pName))
return (PFN_vkVoidFunction) vkEnumerateDeviceExtensionProperties;
if (!strcmp("vkGetPhysicalDeviceFormatProperties", pName))
return (PFN_vkVoidFunction) basic_GetPhysicalDeviceFormatProperties;
+ if (!strcmp("vkCreateInstance", pName))
+ return (PFN_vkVoidFunction) basic_CreateInstance;
if (!strcmp("vkDestroyInstance", pName))
return (PFN_vkVoidFunction) basic_DestroyInstance;
+ if (!strcmp("vkCreateDevice", pName))
+ return (PFN_vkVoidFunction) basic_CreateDevice;
if (!strcmp("vkEnumeratePhysicalDevices", pName))
return (PFN_vkVoidFunction) basic_EnumeratePhysicalDevices;
+ if (instance == NULL)
+ return NULL;
+
if (instance_dispatch_table(instance)->GetInstanceProcAddr == NULL)
return NULL;
return instance_dispatch_table(instance)->GetInstanceProcAddr(instance, pName);
#endif
#include "vk_struct_size_helper.h"
#include "device_limits.h"
+#include "vulkan/vk_layer.h"
#include "vk_layer_config.h"
#include "vulkan/vk_debug_marker_layer.h"
#include "vk_layer_table.h"
VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance)
{
- layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
- VkLayerInstanceDispatchTable* pTable = my_data->instance_dispatch_table;
- VkResult result = pTable->CreateInstance(pCreateInfo, pAllocator, pInstance);
-
- if (result == VK_SUCCESS) {
- my_data->report_data = debug_report_create_instance(
- pTable,
- *pInstance,
- pCreateInfo->enabledExtensionCount,
- pCreateInfo->ppEnabledExtensionNames);
-
- init_device_limits(my_data, pAllocator);
- my_data->instanceState = unique_ptr<INSTANCE_STATE>(new INSTANCE_STATE());
+ VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
+
+ assert(chain_info->u.pLayerInfo);
+ PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
+ PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance) fpGetInstanceProcAddr(NULL, "vkCreateInstance");
+ if (fpCreateInstance == NULL) {
+ return VK_ERROR_INITIALIZATION_FAILED;
}
- return result;
+
+ // Advance the link info for the next element on the chain
+ chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
+
+ VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
+ if (result != VK_SUCCESS)
+ return result;
+
+ layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
+ my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable;
+ layer_init_instance_dispatch_table(*pInstance, my_data->instance_dispatch_table, fpGetInstanceProcAddr);
+
+ my_data->report_data = debug_report_create_instance(
+ my_data->instance_dispatch_table,
+ *pInstance,
+ pCreateInfo->enabledExtensionCount,
+ pCreateInfo->ppEnabledExtensionNames);
+
+ init_device_limits(my_data, pAllocator);
+ my_data->instanceState = unique_ptr<INSTANCE_STATE>(new INSTANCE_STATE());
+
+ return VK_SUCCESS;
}
/* hook DestroyInstance to remove tableInstanceMap entry */
if (skipCall)
return VK_ERROR_VALIDATION_FAILED_EXT;
- layer_data *device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
- VkResult result = device_data->device_dispatch_table->CreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
- if (result == VK_SUCCESS) {
- device_data->report_data = layer_debug_report_create_device(phy_dev_data->report_data, *pDevice);
- createDeviceRegisterExtensions(pCreateInfo, *pDevice);
- device_data->physicalDevice = gpu;
+ VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
- // Get physical device properties for this device
- phy_dev_data->instance_dispatch_table->GetPhysicalDeviceProperties(gpu, &(phy_dev_data->physDevPropertyMap[*pDevice]));
+ assert(chain_info->u.pLayerInfo);
+ PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
+ PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
+ PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice) fpGetInstanceProcAddr(NULL, "vkCreateDevice");
+ if (fpCreateDevice == NULL) {
+ return VK_ERROR_INITIALIZATION_FAILED;
}
+ // Advance the link info for the next element on the chain
+ chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
+
+ VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
+ if (result != VK_SUCCESS) {
+ return result;
+ }
+
+ layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
+ layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
+ my_device_data->device_dispatch_table = new VkLayerDispatchTable;
+ layer_init_device_dispatch_table(*pDevice, my_device_data->device_dispatch_table, fpGetDeviceProcAddr);
+ my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
+ my_device_data->physicalDevice = gpu;
+ createDeviceRegisterExtensions(pCreateInfo, *pDevice);
+
+ // Get physical device properties for this device
+ phy_dev_data->instance_dispatch_table->GetPhysicalDeviceProperties(gpu, &(phy_dev_data->physDevPropertyMap[*pDevice]));
return result;
}
VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice dev, const char* funcName)
{
- if (dev == NULL)
- return NULL;
-
- layer_data *my_data;
- /* loader uses this to force layer initialization; device object is wrapped */
- if (!strcmp(funcName, "vkGetDeviceProcAddr")) {
- VkBaseLayerObject* wrapped_dev = (VkBaseLayerObject*) dev;
- my_data = get_my_data_ptr(get_dispatch_key(wrapped_dev->baseObject), layer_data_map);
- my_data->device_dispatch_table = new VkLayerDispatchTable;
- layer_initialize_dispatch_table(my_data->device_dispatch_table, wrapped_dev);
+ if (!strcmp(funcName, "vkGetDeviceProcAddr"))
return (PFN_vkVoidFunction) vkGetDeviceProcAddr;
- }
- my_data = get_my_data_ptr(get_dispatch_key(dev), layer_data_map);
- if (!strcmp(funcName, "vkCreateDevice"))
- return (PFN_vkVoidFunction) vkCreateDevice;
if (!strcmp(funcName, "vkDestroyDevice"))
return (PFN_vkVoidFunction) vkDestroyDevice;
if (!strcmp(funcName, "vkGetDeviceQueue"))
if (!strcmp(funcName, "vkCmdFillBuffer"))
return (PFN_vkVoidFunction) vkCmdFillBuffer;
+ if (dev == NULL)
+ return NULL;
+
+ layer_data *my_data = get_my_data_ptr(get_dispatch_key(dev), layer_data_map);
VkLayerDispatchTable* pTable = my_data->device_dispatch_table;
{
if (pTable->GetDeviceProcAddr == NULL)
VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* funcName)
{
PFN_vkVoidFunction fptr;
- if (instance == NULL)
- return NULL;
layer_data *my_data;
- /* loader uses this to force layer initialization; instance object is wrapped */
- if (!strcmp(funcName, "vkGetInstanceProcAddr")) {
- VkBaseLayerObject* wrapped_inst = (VkBaseLayerObject*) instance;
- my_data = get_my_data_ptr(get_dispatch_key(wrapped_inst->baseObject), layer_data_map);
- my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable;
- layer_init_instance_dispatch_table(my_data->instance_dispatch_table, wrapped_inst);
+ if (!strcmp(funcName, "vkGetInstanceProcAddr"))
return (PFN_vkVoidFunction) vkGetInstanceProcAddr;
- }
- my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
+ if (!strcmp(funcName, "vkGetDeviceProcAddr"))
+ return (PFN_vkVoidFunction) vkGetDeviceProcAddr;
if (!strcmp(funcName, "vkCreateInstance"))
return (PFN_vkVoidFunction) vkCreateInstance;
if (!strcmp(funcName, "vkDestroyInstance"))
return (PFN_vkVoidFunction) vkDestroyInstance;
+ if (!strcmp(funcName, "vkCreateDevice"))
+ return (PFN_vkVoidFunction) vkCreateDevice;
if (!strcmp(funcName, "vkEnumeratePhysicalDevices"))
return (PFN_vkVoidFunction) vkEnumeratePhysicalDevices;
if (!strcmp(funcName, "vkGetPhysicalDeviceFeatures"))
if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties"))
return (PFN_vkVoidFunction) vkEnumerateInstanceExtensionProperties;
+ if (!instance) return NULL;
+
+ 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);
if (fptr)
return fptr;
VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance)
{
- // TODOSC : Shouldn't need any customization here
+ VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
+
+ assert(chain_info->u.pLayerInfo);
+ PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
+ PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance) fpGetInstanceProcAddr(NULL, "vkCreateInstance");
+ if (fpCreateInstance == NULL) {
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ // Advance the link info for the next element on the chain
+ chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
+
+ VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
+ if (result != VK_SUCCESS)
+ return result;
+
layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
- VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
- VkResult result = pTable->CreateInstance(pCreateInfo, pAllocator, pInstance);
+ my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable;
+ layer_init_instance_dispatch_table(*pInstance, my_data->instance_dispatch_table, fpGetInstanceProcAddr);
- if (result == VK_SUCCESS) {
- layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
- my_data->report_data = debug_report_create_instance(
- pTable,
- *pInstance,
- pCreateInfo->enabledExtensionCount,
- pCreateInfo->ppEnabledExtensionNames);
+ my_data->report_data = debug_report_create_instance(
+ my_data->instance_dispatch_table,
+ *pInstance,
+ pCreateInfo->enabledExtensionCount,
+ pCreateInfo->ppEnabledExtensionNames);
+
+ init_draw_state(my_data, pAllocator);
- init_draw_state(my_data, pAllocator);
- }
return result;
}
VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice)
{
- layer_data *instance_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
- layer_data *dev_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
- VkResult result = dev_data->device_dispatch_table->CreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
+ VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
- if (result == VK_SUCCESS) {
- dev_data->report_data = layer_debug_report_create_device(instance_data->report_data, *pDevice);
- createDeviceRegisterExtensions(pCreateInfo, *pDevice);
- // Get physical device limits for this device
- instance_data->instance_dispatch_table->GetPhysicalDeviceProperties(gpu, &(instance_data->physDevPropertyMap[*pDevice]));
+ assert(chain_info->u.pLayerInfo);
+ PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
+ PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
+ PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice) fpGetInstanceProcAddr(NULL, "vkCreateDevice");
+ if (fpCreateDevice == NULL) {
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ // Advance the link info for the next element on the chain
+ chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
+
+ VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
+ if (result != VK_SUCCESS) {
+ return result;
}
+
+ layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
+ layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
+
+ // Setup device dispatch table
+ my_device_data->device_dispatch_table = new VkLayerDispatchTable;
+ layer_init_device_dispatch_table(*pDevice, my_device_data->device_dispatch_table, fpGetDeviceProcAddr);
+
+ my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
+ createDeviceRegisterExtensions(pCreateInfo, *pDevice);
+ // Get physical device limits for this device
+ my_instance_data->instance_dispatch_table->GetPhysicalDeviceProperties(gpu, &(my_instance_data->physDevPropertyMap[*pDevice]));
return result;
}
VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice dev, const char* funcName)
{
- if (dev == NULL)
- return NULL;
-
- layer_data *dev_data;
- /* loader uses this to force layer initialization; device object is wrapped */
- if (!strcmp(funcName, "vkGetDeviceProcAddr")) {
- VkBaseLayerObject* wrapped_dev = (VkBaseLayerObject*) dev;
- dev_data = get_my_data_ptr(get_dispatch_key(wrapped_dev->baseObject), layer_data_map);
- dev_data->device_dispatch_table = new VkLayerDispatchTable;
- layer_initialize_dispatch_table(dev_data->device_dispatch_table, wrapped_dev);
+ if (!strcmp(funcName, "vkGetDeviceProcAddr"))
return (PFN_vkVoidFunction) vkGetDeviceProcAddr;
- }
- dev_data = get_my_data_ptr(get_dispatch_key(dev), layer_data_map);
- if (!strcmp(funcName, "vkCreateDevice"))
- return (PFN_vkVoidFunction) vkCreateDevice;
if (!strcmp(funcName, "vkDestroyDevice"))
return (PFN_vkVoidFunction) vkDestroyDevice;
if (!strcmp(funcName, "vkQueueSubmit"))
if (!strcmp(funcName, "vkCreateSemaphore"))
return (PFN_vkVoidFunction) vkCreateSemaphore;
+ if (dev == NULL)
+ return NULL;
+
+ layer_data *dev_data;
+ dev_data = get_my_data_ptr(get_dispatch_key(dev), layer_data_map);
+
if (dev_data->device_extensions.wsi_enabled)
{
if (!strcmp(funcName, "vkCreateSwapchainKHR"))
VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* funcName)
{
- PFN_vkVoidFunction fptr;
- if (instance == NULL)
- return NULL;
-
- layer_data* my_data;
- /* loader uses this to force layer initialization; instance object is wrapped */
- if (!strcmp(funcName, "vkGetInstanceProcAddr")) {
- VkBaseLayerObject* wrapped_inst = (VkBaseLayerObject*) instance;
- my_data = get_my_data_ptr(get_dispatch_key(wrapped_inst->baseObject), layer_data_map);
- my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable;
- layer_init_instance_dispatch_table(my_data->instance_dispatch_table, wrapped_inst);
+ if (!strcmp(funcName, "vkGetInstanceProcAddr"))
return (PFN_vkVoidFunction) vkGetInstanceProcAddr;
- }
+ if (!strcmp(funcName, "vkGetDeviceProcAddr"))
+ return (PFN_vkVoidFunction) vkGetDeviceProcAddr;
if (!strcmp(funcName, "vkCreateInstance"))
return (PFN_vkVoidFunction) vkCreateInstance;
+ if (!strcmp(funcName, "vkCreateDevice"))
+ return (PFN_vkVoidFunction) vkCreateDevice;
if (!strcmp(funcName, "vkDestroyInstance"))
return (PFN_vkVoidFunction) vkDestroyInstance;
if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties"))
if (!strcmp(funcName, "vkEnumerateDeviceExtensionProperties"))
return (PFN_vkVoidFunction) vkEnumerateDeviceExtensionProperties;
+ if (instance == NULL)
+ return NULL;
+
+ PFN_vkVoidFunction fptr;
+
+ layer_data* my_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);
if (fptr)
return fptr;
- {
- VkLayerInstanceDispatchTable* pTable = my_data->instance_dispatch_table;
- if (pTable->GetInstanceProcAddr == NULL)
- return NULL;
- return pTable->GetInstanceProcAddr(instance, funcName);
- }
+ VkLayerInstanceDispatchTable* pTable = my_data->instance_dispatch_table;
+ if (pTable->GetInstanceProcAddr == NULL)
+ return NULL;
+ return pTable->GetInstanceProcAddr(instance, funcName);
}
VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance)
{
+ VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
+
+ assert(chain_info->u.pLayerInfo);
+ PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
+ PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance) fpGetInstanceProcAddr(NULL, "vkCreateInstance");
+ if (fpCreateInstance == NULL) {
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ // Advance the link info for the next element on the chain
+ chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
+
+ VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
+ if (result != VK_SUCCESS)
+ return result;
+
layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
- VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
- VkResult result = pTable->CreateInstance(pCreateInfo, pAllocator, pInstance);
+ my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable;
+ layer_init_instance_dispatch_table(*pInstance, my_data->instance_dispatch_table, fpGetInstanceProcAddr);
- if (result == VK_SUCCESS) {
- my_data->report_data = debug_report_create_instance(pTable, *pInstance, pCreateInfo->enabledExtensionCount,
- pCreateInfo->ppEnabledExtensionNames);
+ my_data->report_data = debug_report_create_instance(
+ my_data->instance_dispatch_table,
+ *pInstance,
+ pCreateInfo->enabledExtensionCount,
+ pCreateInfo->ppEnabledExtensionNames);
+
+ InitImage(my_data, pAllocator);
- InitImage(my_data, pAllocator);
- }
return result;
}
VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice)
{
- layer_data *instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
- layer_data *device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
- VkResult result = device_data->device_dispatch_table->CreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);
- if(result == VK_SUCCESS)
- {
- device_data->report_data = layer_debug_report_create_device(instance_data->report_data, *pDevice);
- device_data->physicalDevice = physicalDevice;
+ VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
+
+ assert(chain_info->u.pLayerInfo);
+ PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
+ PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
+ PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice) fpGetInstanceProcAddr(NULL, "vkCreateDevice");
+ if (fpCreateDevice == NULL) {
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ // Advance the link info for the next element on the chain
+ chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
+
+ VkResult result = fpCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);
+ if (result != VK_SUCCESS) {
+ return result;
}
- instance_data->instance_dispatch_table->GetPhysicalDeviceProperties(physicalDevice, &(device_data->physicalDeviceProperties));
+ layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
+ layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
+
+ // Setup device dispatch table
+ my_device_data->device_dispatch_table = new VkLayerDispatchTable;
+ layer_init_device_dispatch_table(*pDevice, my_device_data->device_dispatch_table, fpGetDeviceProcAddr);
+
+ my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
+ my_device_data->physicalDevice = physicalDevice;
+
+ my_instance_data->instance_dispatch_table->GetPhysicalDeviceProperties(physicalDevice, &(my_device_data->physicalDeviceProperties));
return result;
}
VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char* funcName)
{
- if (device == NULL) {
- return NULL;
- }
-
- layer_data *my_data;
- // loader uses this to force layer initialization; device object is wrapped
- if (!strcmp(funcName, "vkGetDeviceProcAddr")) {
- VkBaseLayerObject* wrapped_dev = (VkBaseLayerObject*) device;
- my_data = get_my_data_ptr(get_dispatch_key(wrapped_dev->baseObject), layer_data_map);
- my_data->device_dispatch_table = new VkLayerDispatchTable;
- layer_initialize_dispatch_table(my_data->device_dispatch_table, wrapped_dev);
+ if (!strcmp(funcName, "vkGetDeviceProcAddr"))
return (PFN_vkVoidFunction) vkGetDeviceProcAddr;
- }
-
- my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
- if (!strcmp(funcName, "vkCreateDevice"))
- return (PFN_vkVoidFunction) vkCreateDevice;
if (!strcmp(funcName, "vkDestroyDevice"))
return (PFN_vkVoidFunction) vkDestroyDevice;
if (!strcmp(funcName, "vkCreateImage"))
if (!strcmp(funcName, "vkGetImageSubresourceLayout"))
return (PFN_vkVoidFunction) vkGetImageSubresourceLayout;
+ if (device == NULL) {
+ return NULL;
+ }
+
+ layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+
VkLayerDispatchTable* pTable = my_data->device_dispatch_table;
{
if (pTable->GetDeviceProcAddr == NULL)
VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* funcName)
{
- if (instance == NULL) {
- return NULL;
- }
-
- layer_data *my_data;
- // loader uses this to force layer initialization; instance object is wrapped
- if (!strcmp(funcName, "vkGetInstanceProcAddr")) {
- VkBaseLayerObject* wrapped_inst = (VkBaseLayerObject*) instance;
- my_data = get_my_data_ptr(get_dispatch_key(wrapped_inst->baseObject), layer_data_map);
- my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable;
- layer_init_instance_dispatch_table(my_data->instance_dispatch_table, wrapped_inst);
+ if (!strcmp(funcName, "vkGetInstanceProcAddr"))
return (PFN_vkVoidFunction) vkGetInstanceProcAddr;
- }
-
- my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
if (!strcmp(funcName, "vkCreateInstance"))
return (PFN_vkVoidFunction) vkCreateInstance;
if (!strcmp(funcName, "vkDestroyInstance"))
return (PFN_vkVoidFunction) vkDestroyInstance;
+ if (!strcmp(funcName, "vkCreateDevice"))
+ return (PFN_vkVoidFunction) vkCreateDevice;
if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties"))
return (PFN_vkVoidFunction) vkEnumerateInstanceLayerProperties;
if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties"))
if (!strcmp(funcName, "vkGetPhysicalDeviceProperties"))
return (PFN_vkVoidFunction) vkGetPhysicalDeviceProperties;
+ if (instance == NULL) {
+ return NULL;
+ }
+
+ layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
+
PFN_vkVoidFunction fptr = debug_report_get_instance_proc_addr(my_data->report_data, funcName);
if(fptr)
return fptr;
- {
- VkLayerInstanceDispatchTable* pTable = my_data->instance_dispatch_table;
- if (pTable->GetInstanceProcAddr == NULL)
- return NULL;
- return pTable->GetInstanceProcAddr(instance, funcName);
- }
+ VkLayerInstanceDispatchTable* pTable = my_data->instance_dispatch_table;
+ if (pTable->GetInstanceProcAddr == NULL)
+ return NULL;
+ return pTable->GetInstanceProcAddr(instance, funcName);
}
const VkAllocationCallbacks* pAllocator,
VkInstance* pInstance)
{
- layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
- VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
- VkResult result = pTable->CreateInstance(pCreateInfo, pAllocator, pInstance);
+ VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
- if (result == VK_SUCCESS) {
- my_data->report_data = debug_report_create_instance(
- pTable,
- *pInstance,
- pCreateInfo->enabledExtensionCount,
- pCreateInfo->ppEnabledExtensionNames);
+ assert(chain_info->u.pLayerInfo);
+ PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
+ PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance) fpGetInstanceProcAddr(NULL, "vkCreateInstance");
+ if (fpCreateInstance == NULL) {
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ // Advance the link info for the next element on the chain
+ chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
- init_mem_tracker(my_data, pAllocator);
+ VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
+ if (result != VK_SUCCESS) {
+ return result;
}
+
+ layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
+ my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable;
+ layer_init_instance_dispatch_table(*pInstance, my_data->instance_dispatch_table, fpGetInstanceProcAddr);
+
+ my_data->report_data = debug_report_create_instance(
+ my_data->instance_dispatch_table,
+ *pInstance,
+ pCreateInfo->enabledExtensionCount,
+ pCreateInfo->ppEnabledExtensionNames);
+
+ init_mem_tracker(my_data, pAllocator);
+
return result;
}
const VkAllocationCallbacks *pAllocator,
VkDevice *pDevice)
{
- layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
- VkLayerDispatchTable *pDeviceTable = my_device_data->device_dispatch_table;
- VkResult result = pDeviceTable->CreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
- if (result == VK_SUCCESS) {
- layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
- my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
- createDeviceRegisterExtensions(pCreateInfo, *pDevice);
- my_instance_data->instance_dispatch_table->GetPhysicalDeviceProperties(gpu, &my_device_data->properties);
+ VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
+
+ assert(chain_info->u.pLayerInfo);
+ PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
+ PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
+ PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice) fpGetInstanceProcAddr(NULL, "vkCreateDevice");
+ if (fpCreateDevice == NULL) {
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ // Advance the link info for the next element on the chain
+ chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
+
+ VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
+ if (result != VK_SUCCESS) {
+ return result;
}
+
+ layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
+ layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
+
+ // Setup device dispatch table
+ my_device_data->device_dispatch_table = new VkLayerDispatchTable;
+ layer_init_device_dispatch_table(*pDevice, my_device_data->device_dispatch_table, fpGetDeviceProcAddr);
+
+ my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
+ createDeviceRegisterExtensions(pCreateInfo, *pDevice);
+ my_instance_data->instance_dispatch_table->GetPhysicalDeviceProperties(gpu, &my_device_data->properties);
+
return result;
}
VkDevice dev,
const char *funcName)
{
- if (dev == NULL)
- return NULL;
-
- layer_data *my_data;
- /* loader uses this to force layer initialization; device object is wrapped */
- if (!strcmp(funcName, "vkGetDeviceProcAddr")) {
- VkBaseLayerObject* wrapped_dev = (VkBaseLayerObject*) dev;
- my_data = get_my_data_ptr(get_dispatch_key(wrapped_dev->baseObject), layer_data_map);
- my_data->device_dispatch_table = new VkLayerDispatchTable;
- layer_initialize_dispatch_table(my_data->device_dispatch_table, wrapped_dev);
+ if (!strcmp(funcName, "vkGetDeviceProcAddr"))
return (PFN_vkVoidFunction) vkGetDeviceProcAddr;
- }
- if (!strcmp(funcName, "vkCreateDevice"))
- return (PFN_vkVoidFunction) vkCreateDevice;
if (!strcmp(funcName, "vkDestroyDevice"))
return (PFN_vkVoidFunction) vkDestroyDevice;
if (!strcmp(funcName, "vkQueueSubmit"))
return (PFN_vkVoidFunction) vkDestroyFramebuffer;
+ if (dev == NULL)
+ return NULL;
+
+ layer_data *my_data;
my_data = get_my_data_ptr(get_dispatch_key(dev), layer_data_map);
if (my_data->wsi_enabled)
{
const char *funcName)
{
PFN_vkVoidFunction fptr;
- if (instance == NULL)
- return NULL;
- layer_data *my_data;
- /* loader uses this to force layer initialization; instance object is wrapped */
- if (!strcmp(funcName, "vkGetInstanceProcAddr")) {
- VkBaseLayerObject* wrapped_inst = (VkBaseLayerObject*) instance;
- my_data = get_my_data_ptr(get_dispatch_key(wrapped_inst->baseObject), layer_data_map);
- my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable;
- layer_init_instance_dispatch_table(my_data->instance_dispatch_table, wrapped_inst);
+ if (!strcmp(funcName, "vkGetInstanceProcAddr"))
return (PFN_vkVoidFunction) vkGetInstanceProcAddr;
- }
- my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
+ if (!strcmp(funcName, "vkGetDeviceProcAddr"))
+ return (PFN_vkVoidFunction) vkGetDeviceProcAddr;
if (!strcmp(funcName, "vkDestroyInstance"))
return (PFN_vkVoidFunction) vkDestroyInstance;
if (!strcmp(funcName, "vkCreateInstance"))
return (PFN_vkVoidFunction) vkCreateInstance;
if (!strcmp(funcName, "vkGetPhysicalDeviceMemoryProperties"))
return (PFN_vkVoidFunction) vkGetPhysicalDeviceMemoryProperties;
+ if (!strcmp(funcName, "vkCreateDevice"))
+ return (PFN_vkVoidFunction) vkCreateDevice;
if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties"))
return (PFN_vkVoidFunction) vkEnumerateInstanceLayerProperties;
if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties"))
if (!strcmp(funcName, "vkEnumerateDeviceExtensionProperties"))
return (PFN_vkVoidFunction) vkEnumerateDeviceExtensionProperties;
+ if (instance == NULL) return NULL;
+
+ layer_data *my_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);
- if (fptr)
- return fptr;
+ if (fptr) return fptr;
- {
- VkLayerInstanceDispatchTable* pTable = my_data->instance_dispatch_table;
- if (pTable->GetInstanceProcAddr == NULL)
- return NULL;
- return pTable->GetInstanceProcAddr(instance, funcName);
- }
+ VkLayerInstanceDispatchTable* pTable = my_data->instance_dispatch_table;
+ if (pTable->GetInstanceProcAddr == NULL)
+ return NULL;
+ return pTable->GetInstanceProcAddr(instance, funcName);
}
VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL multi1GetDeviceProcAddr(VkDevice device, const char* pName)
{
-
- if (device == NULL)
- return NULL;
-
- /* loader uses this to force layer initialization; device object is wrapped */
- if (!strcmp(pName, "multi1GetDeviceProcAddr") || !strcmp(pName, "vkGetDeviceProcAddr")) {
- initDeviceTable(multi1_device_table_map, (const VkBaseLayerObject *) device);
+ if (!strcmp(pName, "multi1GetDeviceProcAddr") || !strcmp(pName, "vkGetDeviceProcAddr"))
return (PFN_vkVoidFunction) multi1GetDeviceProcAddr;
- }
-
if (!strcmp("vkDestroyDevice", pName))
return (PFN_vkVoidFunction) multi1DestroyDevice;
if (!strcmp("vkCreateSampler", pName))
return (PFN_vkVoidFunction) multi1CreateSampler;
if (!strcmp("vkCreateGraphicsPipelines", pName))
return (PFN_vkVoidFunction) multi1CreateGraphicsPipelines;
- else {
- VkLayerDispatchTable *pTable = get_dispatch_table(multi1_device_table_map, device);
- if (pTable->GetDeviceProcAddr == NULL)
- return NULL;
- return pTable->GetDeviceProcAddr(device, pName);
- }
+
+ if (device == NULL)
+ return NULL;
+
+ VkLayerDispatchTable *pTable = get_dispatch_table(multi1_device_table_map, device);
+ if (pTable->GetDeviceProcAddr == NULL)
+ return NULL;
+ return pTable->GetDeviceProcAddr(device, pName);
}
VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL multi2GetInstanceProcAddr(VkInstance inst, const char* pName)
{
- if (inst == NULL)
- return NULL;
-
- /* loader uses this to force layer initialization; device object is wrapped */
- if (!strcmp(pName, "multi2GetInstanceProcAddr") || !strcmp(pName, "vkGetInstanceProcAddr")) {
- initInstanceTable(multi2_instance_table_map, (const VkBaseLayerObject *) inst);
+ if (!strcmp(pName, "multi2GetInstanceProcAddr") || !strcmp(pName, "vkGetInstanceProcAddr"))
return (PFN_vkVoidFunction) multi2GetInstanceProcAddr;
- }
-
if (!strcmp("vkEnumeratePhysicalDevices", pName))
return (PFN_vkVoidFunction) multi2EnumeratePhysicalDevices;
if (!strcmp("GetPhysicalDeviceProperties", pName))
return (PFN_vkVoidFunction) multi2GetPhysicalDeviceFeatures;
if (!strcmp("vkDestroyInstance", pName))
return (PFN_vkVoidFunction) multi2DestroyInstance;
- else {
- VkLayerInstanceDispatchTable *pTable = get_dispatch_table(multi2_instance_table_map, inst);
- if (pTable->GetInstanceProcAddr == NULL)
- return NULL;
- return pTable->GetInstanceProcAddr(inst, pName);
- }
+
+ if (inst == NULL)
+ return NULL;
+
+ VkLayerInstanceDispatchTable *pTable = get_dispatch_table(multi2_instance_table_map, inst);
+ if (pTable->GetInstanceProcAddr == NULL)
+ return NULL;
+ return pTable->GetInstanceProcAddr(inst, pName);
}
#ifdef __cplusplus
#include "vulkan/vk_layer.h"
#include "vk_layer_extension_utils.h"
#include "vk_enum_string_helper.h"
+#include "vk_layer_table.h"
// Object Tracker ERROR codes
typedef enum _OBJECT_TRACK_ERROR
const VkAllocationCallbacks *pAllocator,
VkInstance *pInstance)
{
+ VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
- VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(object_tracker_instance_table_map, *pInstance);
- VkResult result = pInstanceTable->CreateInstance(pCreateInfo, pAllocator, pInstance);
+ assert(chain_info->u.pLayerInfo);
+ PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
+ PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance) fpGetInstanceProcAddr(NULL, "vkCreateInstance");
+ if (fpCreateInstance == NULL) {
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
- if (result == VK_SUCCESS) {
- layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
- my_data->report_data = debug_report_create_instance(
- pInstanceTable,
- *pInstance,
- pCreateInfo->enabledExtensionCount,
- pCreateInfo->ppEnabledExtensionNames);
- createInstanceRegisterExtensions(pCreateInfo, *pInstance);
-
- initObjectTracker(my_data, pAllocator);
- create_instance(*pInstance, *pInstance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT);
+ // Advance the link info for the next element on the chain
+ chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
+
+ VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
+ if (result != VK_SUCCESS) {
+ return result;
}
+
+ layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
+ initInstanceTable(*pInstance, fpGetInstanceProcAddr, object_tracker_instance_table_map);
+ VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(object_tracker_instance_table_map, *pInstance);
+
+ my_data->report_data = debug_report_create_instance(
+ pInstanceTable,
+ *pInstance,
+ pCreateInfo->enabledExtensionCount,
+ pCreateInfo->ppEnabledExtensionNames);
+
+ initObjectTracker(my_data, pAllocator);
+ createInstanceRegisterExtensions(pCreateInfo, *pInstance);
+
+ create_instance(*pInstance, *pInstance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT);
+
return result;
}
VkDevice *pDevice)
{
loader_platform_thread_lock_mutex(&objLock);
- VkLayerDispatchTable *pDeviceTable = get_dispatch_table(object_tracker_device_table_map, *pDevice);
- VkResult result = pDeviceTable->CreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
- if (result == VK_SUCCESS) {
- layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
- layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
- my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
- create_device(*pDevice, *pDevice, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT);
- createDeviceRegisterExtensions(pCreateInfo, *pDevice);
+ VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
+
+ assert(chain_info->u.pLayerInfo);
+ PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
+ PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
+ PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice) fpGetInstanceProcAddr(NULL, "vkCreateDevice");
+ if (fpCreateDevice == NULL) {
+ loader_platform_thread_unlock_mutex(&objLock);
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ // Advance the link info for the next element on the chain
+ chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
+
+ VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
+ if (result != VK_SUCCESS) {
+ loader_platform_thread_unlock_mutex(&objLock);
+ return result;
}
+ layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
+ layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
+ my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
+
+ initDeviceTable(*pDevice, fpGetDeviceProcAddr, object_tracker_device_table_map);
+
+ createDeviceRegisterExtensions(pCreateInfo, *pDevice);
+
+ create_device(*pDevice, *pDevice, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT);
+
loader_platform_thread_unlock_mutex(&objLock);
return result;
}
const VkAllocationCallbacks* pAllocator,
VkInstance* pInstance)
{
- VkLayerInstanceDispatchTable *pTable = get_dispatch_table(pc_instance_table_map, *pInstance);
- VkResult result = pTable->CreateInstance(pCreateInfo, pAllocator, pInstance);
+ VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
- if (result == VK_SUCCESS) {
- layer_data *data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
- data->report_data = debug_report_create_instance(pTable, *pInstance, pCreateInfo->enabledExtensionCount,
- pCreateInfo->ppEnabledExtensionNames);
-
- InitParamChecker(data, pAllocator);
+ assert(chain_info->u.pLayerInfo);
+ PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
+ PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance) fpGetInstanceProcAddr(NULL, "vkCreateInstance");
+ if (fpCreateInstance == NULL) {
+ return VK_ERROR_INITIALIZATION_FAILED;
}
+ // Advance the link info for the next element on the chain
+ chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
+
+ VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
+ if (result != VK_SUCCESS)
return result;
+
+ layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
+ VkLayerInstanceDispatchTable *pTable = initInstanceTable(*pInstance, fpGetInstanceProcAddr, pc_instance_table_map);
+
+ my_data->report_data = debug_report_create_instance(
+ pTable,
+ *pInstance,
+ pCreateInfo->enabledExtensionCount,
+ pCreateInfo->ppEnabledExtensionNames);
+
+ InitParamChecker(my_data, pAllocator);
+
+ return result;
}
VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyInstance(
VkDevice* pDevice)
{
/*
- * NOTE: The loader fills in the ICD's device object in *pDevice.
- * Use that object to get the dispatch table.
- *
* NOTE: We do not validate physicalDevice or any dispatchable
* object as the first parameter. We couldn't get here if it was wrong!
*/
- VkLayerDispatchTable *pTable = get_dispatch_table(pc_device_table_map, *pDevice);
- VkResult result = pTable->CreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);
- if(result == VK_SUCCESS)
- {
- layer_data *instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
- layer_data *device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
- device_data->report_data = layer_debug_report_create_device(instance_data->report_data, *pDevice);
+ VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
+
+ assert(chain_info->u.pLayerInfo);
+ PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
+ PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
+ PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice) fpGetInstanceProcAddr(NULL, "vkCreateDevice");
+ if (fpCreateDevice == NULL) {
+ return VK_ERROR_INITIALIZATION_FAILED;
}
+ // Advance the link info for the next element on the chain
+ chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
+
+ VkResult result = fpCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);
+ if (result != VK_SUCCESS) {
+ return result;
+ }
+
+ layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
+ layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
+ my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
+ initDeviceTable(*pDevice, fpGetDeviceProcAddr, pc_device_table_map);
+
return result;
}
VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char* funcName)
{
- if (device == NULL) {
- return NULL;
- }
-
- /* loader uses this to force layer initialization; device object is wrapped */
- if (!strcmp(funcName, "vkGetDeviceProcAddr")) {
- initDeviceTable(pc_device_table_map, (const VkBaseLayerObject *) device);
+ if (!strcmp(funcName, "vkGetDeviceProcAddr"))
return (PFN_vkVoidFunction) vkGetDeviceProcAddr;
- }
-
- if (!strcmp(funcName, "vkCreateDevice"))
- return (PFN_vkVoidFunction) vkCreateDevice;
if (!strcmp(funcName, "vkDestroyDevice"))
return (PFN_vkVoidFunction) vkDestroyDevice;
if (!strcmp(funcName, "vkGetDeviceQueue"))
if (!strcmp(funcName, "vkCmdNextSubpass"))
return (PFN_vkVoidFunction) vkCmdNextSubpass;
- {
- if (get_dispatch_table(pc_device_table_map, device)->GetDeviceProcAddr == NULL)
- return NULL;
- return get_dispatch_table(pc_device_table_map, device)->GetDeviceProcAddr(device, funcName);
+ if (device == NULL) {
+ return NULL;
}
+
+ if (get_dispatch_table(pc_device_table_map, device)->GetDeviceProcAddr == NULL)
+ return NULL;
+ return get_dispatch_table(pc_device_table_map, device)->GetDeviceProcAddr(device, funcName);
}
VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* funcName)
{
- if (instance == NULL) {
- return NULL;
- }
-
- /* loader uses this to force layer initialization; instance object is wrapped */
- if (!strcmp(funcName, "vkGetInstanceProcAddr")) {
- initInstanceTable(pc_instance_table_map, (const VkBaseLayerObject *) instance);
+ if (!strcmp(funcName, "vkGetInstanceProcAddr"))
return (PFN_vkVoidFunction) vkGetInstanceProcAddr;
- }
-
if (!strcmp(funcName, "vkCreateInstance"))
return (PFN_vkVoidFunction) vkCreateInstance;
if (!strcmp(funcName, "vkDestroyInstance"))
return (PFN_vkVoidFunction) vkDestroyInstance;
+ if (!strcmp(funcName, "vkCreateDevice"))
+ return (PFN_vkVoidFunction) vkCreateDevice;
if (!strcmp(funcName, "vkEnumeratePhysicalDevices"))
return (PFN_vkVoidFunction) vkEnumeratePhysicalDevices;
if (!strcmp(funcName, "vkGetPhysicalDeviceProperties"))
if (!strcmp(funcName, "vkEnumerateDeviceExtensionProperties"))
return (PFN_vkVoidFunction) vkEnumerateDeviceExtensionProperties;
+ if (instance == NULL) {
+ return NULL;
+ }
+
layer_data *data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
PFN_vkVoidFunction fptr = debug_report_get_instance_proc_addr(data->report_data, funcName);
if(fptr)
return fptr;
- {
- if (get_dispatch_table(pc_instance_table_map, instance)->GetInstanceProcAddr == NULL)
- return NULL;
- return get_dispatch_table(pc_instance_table_map, instance)->GetInstanceProcAddr(instance, funcName);
- }
+ if (get_dispatch_table(pc_instance_table_map, instance)->GetInstanceProcAddr == NULL)
+ return NULL;
+ return get_dispatch_table(pc_instance_table_map, instance)->GetInstanceProcAddr(instance, funcName);
}
const VkAllocationCallbacks* pAllocator,
VkDevice *pDevice)
{
- VkLayerDispatchTable *pDisp = get_dispatch_table(screenshot_device_table_map, *pDevice);
- VkResult result = pDisp->CreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
-
- if (result == VK_SUCCESS) {
- init_screenshot();
- createDeviceRegisterExtensions(pCreateInfo, *pDevice);
- // Create a mapping from a device to a physicalDevice
- if (deviceMap[*pDevice] == NULL)
- {
- DeviceMapStruct *deviceMapElem = new DeviceMapStruct;
- deviceMap[*pDevice] = deviceMapElem;
- }
- deviceMap[*pDevice]->physicalDevice = gpu;
+ VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
+
+ assert(chain_info->u.pLayerInfo);
+ PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
+ PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
+ PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice) fpGetInstanceProcAddr(NULL, "vkCreateDevice");
+ if (fpCreateDevice == NULL) {
+ return VK_ERROR_INITIALIZATION_FAILED;
}
+ // Advance the link info for the next element on the chain
+ chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
+
+ VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
+ if (result != VK_SUCCESS) {
+ return result;
+ }
+
+ initDeviceTable(*pDevice, fpGetDeviceProcAddr, screenshot_device_table_map);
+
+ init_screenshot();
+ createDeviceRegisterExtensions(pCreateInfo, *pDevice);
+ // Create a mapping from a device to a physicalDevice
+ if (deviceMap[*pDevice] == NULL)
+ {
+ DeviceMapStruct *deviceMapElem = new DeviceMapStruct;
+ deviceMap[*pDevice] = deviceMapElem;
+ }
+ deviceMap[*pDevice]->physicalDevice = gpu;
+
return result;
}
VkDevice dev,
const char *funcName)
{
- if (dev == NULL) {
- return NULL;
- }
-
- /* loader uses this to force layer initialization; device object is wrapped */
if (!strcmp(funcName, "vkGetDeviceProcAddr")) {
- initDeviceTable(screenshot_device_table_map, (const VkBaseLayerObject *) dev);
return (PFN_vkVoidFunction)vkGetDeviceProcAddr;
}
- if (!strcmp(funcName, "vkCreateDevice"))
- return (PFN_vkVoidFunction) vkCreateDevice;
if (!strcmp(funcName, "vkGetDeviceQueue"))
return (PFN_vkVoidFunction) vkGetDeviceQueue;
if (!strcmp(funcName, "vkCreateCommandPool"))
return (PFN_vkVoidFunction) vkCreateCommandPool;
+ if (dev == NULL) {
+ return NULL;
+ }
+
VkLayerDispatchTable *pDisp = get_dispatch_table(screenshot_device_table_map, dev);
if (deviceExtMap.size() != 0 && deviceExtMap[pDisp].wsi_enabled)
{
VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* funcName)
{
- if (instance == VK_NULL_HANDLE) {
- return NULL;
- }
-
- /* loader uses this to force layer initialization; instance object is wrapped */
- if (!strcmp("vkGetInstanceProcAddr", funcName)) {
- initInstanceTable((const VkBaseLayerObject *) instance);
+ if (!strcmp("vkGetInstanceProcAddr", funcName))
return (PFN_vkVoidFunction) vkGetInstanceProcAddr;
- }
-
+ if (!strcmp(funcName, "vkCreateDevice"))
+ return (PFN_vkVoidFunction) vkCreateDevice;
if (!strcmp(funcName, "vkEnumeratePhysicalDevices"))
return (PFN_vkVoidFunction)vkEnumeratePhysicalDevices;
if (!strcmp(funcName, "vkEnumerateDeviceExtensionProperties"))
return (PFN_vkVoidFunction)vkEnumerateDeviceExtensionProperties;
+ if (instance == VK_NULL_HANDLE) {
+ return NULL;
+ }
+
VkLayerInstanceDispatchTable* pTable = instance_dispatch_table(instance);
if (pTable->GetInstanceProcAddr == NULL)
return NULL;
VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance)
{
- layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
- // Call down the call chain:
- VkLayerInstanceDispatchTable* pTable = my_data->instance_dispatch_table;
- VkResult result = pTable->CreateInstance(pCreateInfo, pAllocator, pInstance);
- if (result == VK_SUCCESS) {
- // Since it succeeded, do layer-specific work:
- layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
- my_data->report_data = debug_report_create_instance(
- pTable,
- *pInstance,
- pCreateInfo->enabledExtensionCount,
- pCreateInfo->ppEnabledExtensionNames);
- // Call the following function after my_data is initialized:
- createInstanceRegisterExtensions(pCreateInfo, *pInstance);
- initSwapchain(my_data, pAllocator);
+ VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
+
+ assert(chain_info->u.pLayerInfo);
+ PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
+ PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance) fpGetInstanceProcAddr(NULL, "vkCreateInstance");
+ if (fpCreateInstance == NULL) {
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ // Advance the link info for the next element on the chain
+ chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
+
+ VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
+ if (result != VK_SUCCESS) {
+ return result;
}
+
+ layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
+ my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable;
+ layer_init_instance_dispatch_table(*pInstance, my_data->instance_dispatch_table, fpGetInstanceProcAddr);
+
+ my_data->report_data = debug_report_create_instance(
+ my_data->instance_dispatch_table,
+ *pInstance,
+ pCreateInfo->enabledExtensionCount,
+ pCreateInfo->ppEnabledExtensionNames);
+
+ // Call the following function after my_data is initialized:
+ createInstanceRegisterExtensions(pCreateInfo, *pInstance);
+ initSwapchain(my_data, pAllocator);
+
return result;
}
VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice)
{
- VkResult result = VK_SUCCESS;
- VkBool32 skipCall = VK_FALSE;
- layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
+ VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
- if (VK_FALSE == skipCall) {
- layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
- // Call down the call chain:
- result = my_device_data->device_dispatch_table->CreateDevice(
- physicalDevice, pCreateInfo, pAllocator, pDevice);
- if (result == VK_SUCCESS) {
- // Since it succeeded, do layer-specific work:
- layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
- my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
- createDeviceRegisterExtensions(physicalDevice, pCreateInfo, *pDevice);
- }
+ assert(chain_info->u.pLayerInfo);
+ PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
+ PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
+ PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice) fpGetInstanceProcAddr(NULL, "vkCreateDevice");
+ if (fpCreateDevice == NULL) {
+ return VK_ERROR_INITIALIZATION_FAILED;
}
+
+ // Advance the link info for the next element on the chain
+ chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
+
+ VkResult result = fpCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);
+ if (result != VK_SUCCESS) {
+ return result;
+ }
+
+ layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
+ layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
+
+ // Setup device dispatch table
+ my_device_data->device_dispatch_table = new VkLayerDispatchTable;
+ layer_init_device_dispatch_table(*pDevice, my_device_data->device_dispatch_table, fpGetDeviceProcAddr);
+
+ my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
+ createDeviceRegisterExtensions(physicalDevice, pCreateInfo, *pDevice);
+
return result;
}
return VK_ERROR_VALIDATION_FAILED_EXT;
}
-static inline PFN_vkVoidFunction layer_intercept_proc(const char *name)
-{
- if (!name || name[0] != 'v' || name[1] != 'k')
- return NULL;
-
- name += 2;
- if (!strcmp(name, "CreateInstance"))
- return (PFN_vkVoidFunction) vkCreateInstance;
- if (!strcmp(name, "DestroyInstance"))
- return (PFN_vkVoidFunction) vkDestroyInstance;
- if (!strcmp(name, "EnumeratePhysicalDevices"))
- return (PFN_vkVoidFunction) vkEnumeratePhysicalDevices;
- if (!strcmp(name, "CreateDevice"))
- return (PFN_vkVoidFunction) vkCreateDevice;
- if (!strcmp(name, "DestroyDevice"))
- return (PFN_vkVoidFunction) vkDestroyDevice;
-
- return NULL;
-}
-static inline PFN_vkVoidFunction layer_intercept_instance_proc(const char *name)
-{
- if (!name || name[0] != 'v' || name[1] != 'k')
- return NULL;
-
- name += 2;
- if (!strcmp(name, "CreateInstance"))
- return (PFN_vkVoidFunction) vkCreateInstance;
- if (!strcmp(name, "DestroyInstance"))
- return (PFN_vkVoidFunction) vkDestroyInstance;
- if (!strcmp(name, "EnumeratePhysicalDevices"))
- return (PFN_vkVoidFunction) vkEnumeratePhysicalDevices;
-
- return NULL;
-}
-
VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugReportCallbackEXT(
VkInstance instance,
const VkDebugReportCallbackCreateInfoEXT* pCreateInfo,
VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char* funcName)
{
- PFN_vkVoidFunction addr;
+ if (!strcmp("vkGetDeviceProcAddr", funcName))
+ return (PFN_vkVoidFunction) vkGetDeviceProcAddr;
+ if (!strcmp(funcName, "vkDestroyDevice"))
+ return (PFN_vkVoidFunction) vkDestroyDevice;
+
if (device == VK_NULL_HANDLE) {
return NULL;
}
layer_data *my_data;
- /* loader uses this to force layer initialization; device object is wrapped */
- if (!strcmp("vkGetDeviceProcAddr", funcName)) {
- VkBaseLayerObject* wrapped_dev = (VkBaseLayerObject*) device;
- my_data = get_my_data_ptr(get_dispatch_key(wrapped_dev->baseObject), layer_data_map);
- my_data->device_dispatch_table = new VkLayerDispatchTable;
- layer_initialize_dispatch_table(my_data->device_dispatch_table, wrapped_dev);
- return (PFN_vkVoidFunction) vkGetDeviceProcAddr;
- }
-
- addr = layer_intercept_proc(funcName);
- if (addr)
- return addr;
my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
VkLayerDispatchTable *pDisp = my_data->device_dispatch_table;
if (!strcmp("vkQueuePresentKHR", funcName))
return reinterpret_cast<PFN_vkVoidFunction>(vkQueuePresentKHR);
}
- {
- if (pDisp->GetDeviceProcAddr == NULL)
- return NULL;
- return pDisp->GetDeviceProcAddr(device, funcName);
- }
+
+ if (pDisp->GetDeviceProcAddr == NULL)
+ return NULL;
+ return pDisp->GetDeviceProcAddr(device, funcName);
}
VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* funcName)
{
- PFN_vkVoidFunction addr;
- if (instance == VK_NULL_HANDLE) {
- return NULL;
- }
-
- layer_data *my_data;
- /* loader uses this to force layer initialization; instance object is wrapped */
- if (!strcmp("vkGetInstanceProcAddr", funcName)) {
- VkBaseLayerObject* wrapped_inst = (VkBaseLayerObject*) instance;
- my_data = get_my_data_ptr(get_dispatch_key(wrapped_inst->baseObject), layer_data_map);
- my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable;
- layer_init_instance_dispatch_table(my_data->instance_dispatch_table, wrapped_inst);
+ if (!strcmp("vkGetInstanceProcAddr", funcName))
return (PFN_vkVoidFunction) vkGetInstanceProcAddr;
- }
-
+ if (!strcmp(funcName, "vkCreateInstance"))
+ return (PFN_vkVoidFunction) vkCreateInstance;
+ if (!strcmp(funcName, "vkDestroyInstance"))
+ return (PFN_vkVoidFunction) vkDestroyInstance;
+ if (!strcmp(funcName, "vkCreateDevice"))
+ return (PFN_vkVoidFunction) vkCreateDevice;
+ if (!strcmp(funcName, "vkEnumeratePhysicalDevices"))
+ return (PFN_vkVoidFunction) vkEnumeratePhysicalDevices;
if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties"))
return (PFN_vkVoidFunction) vkEnumerateInstanceLayerProperties;
if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties"))
return (PFN_vkVoidFunction) vkEnumerateInstanceExtensionProperties;
- addr = layer_intercept_instance_proc(funcName);
- if (addr)
- return addr;
+ if (instance == VK_NULL_HANDLE) {
+ return NULL;
+ }
+
+ PFN_vkVoidFunction addr;
+ layer_data *my_data;
my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
VkLayerInstanceDispatchTable* pTable = my_data->instance_dispatch_table;
addr = debug_report_get_instance_proc_addr(my_data->report_data, funcName);
const VkAllocationCallbacks *pAllocator,
VkInstance *pInstance)
{
+ VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
- VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(unique_objects_instance_table_map, *pInstance);
- VkResult result = pInstanceTable->CreateInstance(pCreateInfo, pAllocator, pInstance);
+ assert(chain_info->u.pLayerInfo);
+ PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
+ PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance) fpGetInstanceProcAddr(NULL, "vkCreateInstance");
+ if (fpCreateInstance == NULL) {
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ // Advance the link info for the next element on the chain
+ chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
- if (result == VK_SUCCESS) {
- createInstanceRegisterExtensions(pCreateInfo, *pInstance);
+ VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
+ if (result != VK_SUCCESS) {
+ return result;
}
+
+ initInstanceTable(*pInstance, fpGetInstanceProcAddr, unique_objects_instance_table_map);
+
+ createInstanceRegisterExtensions(pCreateInfo, *pInstance);
+
return result;
}
const VkAllocationCallbacks *pAllocator,
VkDevice *pDevice)
{
- VkLayerDispatchTable *pDeviceTable = get_dispatch_table(unique_objects_device_table_map, *pDevice);
- VkResult result = pDeviceTable->CreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
- if (result == VK_SUCCESS) {
- createDeviceRegisterExtensions(pCreateInfo, *pDevice);
+ VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
+
+ assert(chain_info->u.pLayerInfo);
+ PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
+ PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
+ PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice) fpGetInstanceProcAddr(NULL, "vkCreateDevice");
+ if (fpCreateDevice == NULL) {
+ return VK_ERROR_INITIALIZATION_FAILED;
}
+
+ // Advance the link info for the next element on the chain
+ chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
+
+ VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
+ if (result != VK_SUCCESS) {
+ return result;
+ }
+
+ // Setup layer's device dispatch table
+ initDeviceTable(*pDevice, fpGetDeviceProcAddr, unique_objects_device_table_map);
+
+ createDeviceRegisterExtensions(pCreateInfo, *pDevice);
+
return result;
}
device_table_map::const_iterator it = map.find((void *) key);
#if DISPATCH_MAP_DEBUG
if (it != map.end()) {
- fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: %p\n", &tableInstanceMap, object, key, it->second);
+ fprintf(stderr, "device_dispatch_table: map: %p, object: %p, key: %p, table: %p\n", &tableInstanceMap, object, key, it->second);
} else {
- fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: UNKNOWN\n", &tableInstanceMap, object, key);
+ fprintf(stderr, "device_dispatch_table: map: %p, object: %p, key: %p, table: UNKNOWN\n", &tableInstanceMap, object, key);
}
#endif
assert(it != map.end() && "Not able to find device dispatch entry");
return it->second;
}
-VkLayerInstanceCreateInfo *get_chain_info(const VkInstanceCreateInfo *pCreateInfo)
+VkLayerInstanceCreateInfo *get_chain_info(const VkInstanceCreateInfo *pCreateInfo, VkLayerFunction func)
{
VkLayerInstanceCreateInfo *chain_info = (VkLayerInstanceCreateInfo *) pCreateInfo->pNext;
- while (chain_info && chain_info->sType != VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO) {
+ while (chain_info && !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO
+ && chain_info->function == func)) {
chain_info = (VkLayerInstanceCreateInfo *) chain_info->pNext;
}
assert(chain_info != NULL);
return chain_info;
}
-VkLayerDeviceCreateInfo *get_chain_info(const VkDeviceCreateInfo *pCreateInfo)
+VkLayerDeviceCreateInfo *get_chain_info(const VkDeviceCreateInfo *pCreateInfo, VkLayerFunction func)
{
VkLayerDeviceCreateInfo *chain_info = (VkLayerDeviceCreateInfo *) pCreateInfo->pNext;
- while (chain_info && chain_info->sType != VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO) {
+ while (chain_info && !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO
+ && chain_info->function == func)) {
chain_info = (VkLayerDeviceCreateInfo *) chain_info->pNext;
}
assert(chain_info != NULL);
* Device -> CommandBuffer or Queue
* If use the object themselves as key to map then implies Create entrypoints have to be intercepted
* and a new key inserted into map */
-VkLayerInstanceDispatchTable * initInstanceTable(instance_table_map &map, const VkBaseLayerObject *instancew)
+VkLayerInstanceDispatchTable * initInstanceTable(VkInstance instance, const PFN_vkGetInstanceProcAddr gpa, instance_table_map &map)
{
VkLayerInstanceDispatchTable *pTable;
- assert(instancew);
- VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) instancew->baseObject;
+ dispatch_key key = get_dispatch_key(instance);
+ instance_table_map::const_iterator it = map.find((void *) key);
- std::unordered_map<void *, VkLayerInstanceDispatchTable *>::const_iterator it = map.find((void *) *ppDisp);
if (it == map.end())
{
pTable = new VkLayerInstanceDispatchTable;
- map[(void *) *ppDisp] = pTable;
+ map[(void *) key] = pTable;
#if DISPATCH_MAP_DEBUG
- fprintf(stderr, "New, Instance: map: %p, base object: %p, key: %p, table: %p\n", &map, instancew, *ppDisp, pTable);
+ fprintf(stderr, "New, Instance: map: %p, key: %p, table: %p\n", &map, key, pTable);
#endif
} else
{
#if DISPATCH_MAP_DEBUG
- fprintf(stderr, "Instance: map: %p, base object: %p, key: %p, table: %p\n", &map, instancew, *ppDisp, it->second);
+ fprintf(stderr, "Instance: map: %p, key: %p, table: %p\n", &map, key, it->second);
#endif
return it->second;
}
- layer_init_instance_dispatch_table(pTable, instancew);
+ layer_init_instance_dispatch_table(instance, pTable, gpa);
return pTable;
}
-VkLayerInstanceDispatchTable * initInstanceTable(const VkBaseLayerObject *instancew)
+VkLayerInstanceDispatchTable * initInstanceTable(VkInstance instance, const PFN_vkGetInstanceProcAddr gpa)
{
- return initInstanceTable(tableInstanceMap, instancew);
+ return initInstanceTable(instance, gpa, tableInstanceMap);
}
-VkLayerDispatchTable * initDeviceTable(device_table_map &map, const VkBaseLayerObject *devw)
+VkLayerDispatchTable * initDeviceTable(VkDevice device, const PFN_vkGetDeviceProcAddr gpa, device_table_map &map)
{
- VkLayerDispatchTable *layer_device_table = NULL;
- assert(devw);
- VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) (devw->baseObject);
- VkLayerDispatchTable *base_device_table = *ppDisp;
+ VkLayerDispatchTable *pTable;
+ dispatch_key key = get_dispatch_key(device);
+ device_table_map::const_iterator it = map.find((void *) key);
- std::unordered_map<void *, VkLayerDispatchTable *>::const_iterator it = map.find((void *) base_device_table);
if (it == map.end())
{
- layer_device_table = new VkLayerDispatchTable;
- map[(void *) base_device_table] = layer_device_table;
+ pTable = new VkLayerDispatchTable;
+ map[(void *) key] = pTable;
#if DISPATCH_MAP_DEBUG
- fprintf(stderr, "New, Device: map: %p, base object: %p, key: %p, table: %p\n", &map, devw, *ppDisp, layer_device_table);
+ fprintf(stderr, "New, Device: map: %p, key: %p, table: %p\n", &map, key, pTable);
#endif
} else
{
#if DISPATCH_MAP_DEBUG
- fprintf(stderr, "Device: map: %p, base object: %p, key: %p, table: %p\n", &map, devw, *ppDisp, it->second);
+ fprintf(stderr, "Device: map: %p, key: %p, table: %p\n", &map, key, it->second);
#endif
return it->second;
}
- layer_initialize_dispatch_table(layer_device_table, devw);
+ layer_init_device_dispatch_table(device, pTable, gpa);
- return layer_device_table;
+ return pTable;
}
-VkLayerDispatchTable * initDeviceTable(const VkBaseLayerObject *devw)
+VkLayerDispatchTable * initDeviceTable(VkDevice device, const PFN_vkGetDeviceProcAddr gpa)
{
- return initDeviceTable(tableMap, devw);
+ return initDeviceTable(device, gpa, tableMap);
}
typedef std::unordered_map<void *, VkLayerDispatchTable *> device_table_map;
typedef std::unordered_map<void *, VkLayerInstanceDispatchTable *> instance_table_map;
-VkLayerDispatchTable * initDeviceTable(const VkBaseLayerObject *devw);
-VkLayerDispatchTable * initDeviceTable(device_table_map &map, const VkBaseLayerObject *devw);
-VkLayerInstanceDispatchTable * initInstanceTable(const VkBaseLayerObject *instancew);
-VkLayerInstanceDispatchTable * initInstanceTable(instance_table_map &map, const VkBaseLayerObject *instancew);
+VkLayerDispatchTable * initDeviceTable(VkDevice device, const PFN_vkGetDeviceProcAddr gpa, device_table_map &map);
+VkLayerDispatchTable * initDeviceTable(VkDevice device, const PFN_vkGetDeviceProcAddr gpa);
+VkLayerInstanceDispatchTable * initInstanceTable(VkInstance instance, const PFN_vkGetInstanceProcAddr gpa, instance_table_map &map);
+VkLayerInstanceDispatchTable * initInstanceTable(VkInstance instance, const PFN_vkGetInstanceProcAddr gpa);
+
typedef void *dispatch_key;
VkLayerInstanceDispatchTable *get_dispatch_table(instance_table_map &map, void* object);
-VkLayerInstanceCreateInfo *get_chain_info(const VkInstanceCreateInfo *pCreateInfo);
-VkLayerDeviceCreateInfo *get_chain_info(const VkDeviceCreateInfo *pCreateInfo);
+VkLayerInstanceCreateInfo *get_chain_info(const VkInstanceCreateInfo *pCreateInfo, VkLayerFunction func);
+VkLayerDeviceCreateInfo *get_chain_info(const VkDeviceCreateInfo *pCreateInfo, VkLayerFunction func);
void destroy_device_dispatch_table(dispatch_key key);
void destroy_instance_dispatch_table(dispatch_key key);
static struct loader_device *loader_add_logical_device(
const struct loader_instance *inst,
- const VkDevice dev,
struct loader_device **device_list)
{
struct loader_device *new_dev;
new_dev = loader_heap_alloc(inst, sizeof(struct loader_device), VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
if (!new_dev) {
- loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Failed to alloc struct laoder-device");
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Failed to alloc struct loader-device");
return NULL;
}
memset(new_dev, 0, sizeof(struct loader_device));
new_dev->next = *device_list;
- new_dev->device = dev;
*device_list = new_dev;
return new_dev;
}
static VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL loader_gpa_instance_internal(VkInstance inst, const char * pName)
{
+ if (!strcmp(pName, "vkGetInstanceProcAddr"))
+ return (void *) loader_gpa_instance_internal;
+ if (!strcmp(pName, "vkCreateInstance"))
+ return (void *) loader_CreateInstance;
+ if (!strcmp(pName, "vkCreateDevice"))
+ return (void *) loader_create_device_terminator;
+
// inst is not wrapped
if (inst == VK_NULL_HANDLE) {
return NULL;
VkLayerInstanceDispatchTable* disp_table = * (VkLayerInstanceDispatchTable **) inst;
void *addr;
- if (!strcmp(pName, "vkGetInstanceProcAddr"))
- return (void *) loader_gpa_instance_internal;
-
if (disp_table == NULL)
return NULL;
}
/* Add any implicit layers first */
- loader_add_layer_implicit(
- inst,
- VK_LAYER_TYPE_INSTANCE_IMPLICIT,
- &inst->activated_layer_list,
- instance_layers);
+ loader_add_layer_implicit(inst,
+ VK_LAYER_TYPE_INSTANCE_IMPLICIT,
+ &inst->activated_layer_list,
+ instance_layers);
/* Add any layers specified via environment variable next */
- loader_add_layer_env(
- inst,
- VK_LAYER_TYPE_INSTANCE_EXPLICIT,
- "VK_INSTANCE_LAYERS",
- &inst->activated_layer_list,
- instance_layers);
+ loader_add_layer_env(inst,
+ VK_LAYER_TYPE_INSTANCE_EXPLICIT,
+ "VK_INSTANCE_LAYERS",
+ &inst->activated_layer_list,
+ instance_layers);
/* Add layers specified by the application */
err = loader_add_layer_names_to_list(
return err;
}
-uint32_t loader_activate_instance_layers(struct loader_instance *inst)
-{
- uint32_t layer_idx;
- VkBaseLayerObject *wrappedInstance;
+/*
+ * Given the list of layers to activate in the loader_instance
+ * structure. This function will add a VkLayerInstanceCreateInfo
+ * structure to the VkInstanceCreateInfo.pNext pointer.
+ * Each activated layer will have it's own VkLayerInstanceLink
+ * structure that tells the layer what Get*ProcAddr to call to
+ * get function pointers to the next layer down.
+ * Once the chain info has been created this function will
+ * execute the CreateInstance call chain. Each layer will
+ * then have an opportunity in it's CreateInstance function
+ * to setup it's dispatch table when the lower layer returns
+ * successfully.
+ * Each layer can wrap or not-wrap the returned VkInstance object
+ * as it sees fit.
+ * The instance chain is terminated by a loader function
+ * that will call CreateInstance on all available ICD's and
+ * cache those VkInstance objects for future use.
+ */
+VkResult loader_create_instance_chain(const VkInstanceCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ struct loader_instance *inst)
+{
+ uint32_t activated_layers = 0;
+ VkLayerInstanceCreateInfo chain_info;
+ VkLayerInstanceLink *layer_instance_link_info = NULL;
+ VkInstanceCreateInfo loader_create_info;
+ VkResult res;
- if (inst == NULL) {
- return 0;
- }
+ PFN_vkGetInstanceProcAddr nextGIPA = loader_gpa_instance_internal;
+ PFN_vkGetInstanceProcAddr fpGIPA = loader_gpa_instance_internal;
- // NOTE inst is unwrapped at this point in time
- void* baseObj = (void*) inst;
- void* nextObj = (void*) inst;
- VkBaseLayerObject *nextInstObj;
- PFN_vkGetInstanceProcAddr nextGPA = loader_gpa_instance_internal;
+ memcpy(&loader_create_info, pCreateInfo, sizeof(VkInstanceCreateInfo));
- if (!inst->activated_layer_list.count) {
- loader_init_instance_core_dispatch_table(inst->disp, nextGPA, (VkInstance) nextObj, (VkInstance) baseObj);
- return 0;
- }
+ if (inst->activated_layer_list.count > 0) {
- wrappedInstance = loader_stack_alloc(sizeof(VkBaseLayerObject)
- * inst->activated_layer_list.count);
- if (!wrappedInstance) {
- loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Failed to alloc Instance objects for layer");
- return 0;
- }
+ chain_info.u.pLayerInfo = NULL;
+ chain_info.pNext = pCreateInfo->pNext;
+ chain_info.sType = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO;
+ chain_info.function = VK_LAYER_LINK_INFO;
+ loader_create_info.pNext = &chain_info;
- /* 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_layer_properties *layer_prop = &inst->activated_layer_list.list[i];
- loader_platform_dl_handle lib_handle;
-
- /*
- * Note: An extension's Get*ProcAddr should not return a function pointer for
- * any extension entry points until the extension has been enabled.
- * To do this requires a different behavior from Get*ProcAddr functions implemented
- * in layers.
- * The very first call to a layer will be it's Get*ProcAddr function requesting
- * the layer's vkGet*ProcAddr. The layer should initialize its internal dispatch table
- * with the wrapped object given (either Instance or Device) and return the layer's
- * Get*ProcAddr function. The layer should also use this opportunity to record the
- * baseObject so that it can find the correct local dispatch table on future calls.
- * Subsequent calls to Get*ProcAddr, CreateInstance, CreateDevice
- * will not use a wrapped object and must look up their local dispatch table from
- * the given baseObject.
- */
- nextInstObj = (wrappedInstance + layer_idx);
- nextInstObj->pGPA = (PFN_vkGPA) nextGPA;
- nextInstObj->baseObject = baseObj;
- nextInstObj->nextObject = nextObj;
- nextObj = (void*) nextInstObj;
-
- lib_handle = loader_add_layer_lib(inst, "instance", layer_prop);
- if (!lib_handle)
- continue; // TODO what should we do in this case
- if ((nextGPA = layer_prop->functions.get_instance_proc_addr) == NULL) {
- if (layer_prop->functions.str_gipa == NULL || strlen(layer_prop->functions.str_gipa) == 0) {
- nextGPA = (PFN_vkGetInstanceProcAddr) loader_platform_get_proc_address(lib_handle, "vkGetInstanceProcAddr");
- layer_prop->functions.get_instance_proc_addr = nextGPA;
- } else
- nextGPA = (PFN_vkGetInstanceProcAddr) loader_platform_get_proc_address(lib_handle, layer_prop->functions.str_gipa);
- if (!nextGPA) {
- loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Failed to find vkGetInstanceProcAddr in layer %s", layer_prop->lib_name);
-
- /* TODO: Should we return nextObj, nextGPA to previous? or decrement layer_list count*/
- continue;
+ layer_instance_link_info = loader_stack_alloc(sizeof(VkLayerInstanceLink)
+ * inst->activated_layer_list.count);
+ if (!layer_instance_link_info) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Failed to alloc Instance objects for layer");
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+
+ /* Create instance chain of enabled layers */
+ for (int32_t i = inst->activated_layer_list.count - 1; i >= 0; i--) {
+ struct loader_layer_properties *layer_prop = &inst->activated_layer_list.list[i];
+ loader_platform_dl_handle lib_handle;
+
+ lib_handle = loader_add_layer_lib(inst, "instance", layer_prop);
+ if (!lib_handle)
+ continue; // TODO what should we do in this case
+ if ((fpGIPA = layer_prop->functions.get_instance_proc_addr) == NULL) {
+ if (layer_prop->functions.str_gipa == NULL || strlen(layer_prop->functions.str_gipa) == 0) {
+ fpGIPA = (PFN_vkGetInstanceProcAddr) loader_platform_get_proc_address(lib_handle, "vkGetInstanceProcAddr");
+ layer_prop->functions.get_instance_proc_addr = fpGIPA;
+ } else
+ fpGIPA = (PFN_vkGetInstanceProcAddr) loader_platform_get_proc_address(lib_handle, layer_prop->functions.str_gipa);
+ if (!fpGIPA) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Failed to find vkGetInstanceProcAddr in layer %s", layer_prop->lib_name);
+
+ /* TODO: Should we return nextObj, nextGPA to previous? or decrement layer_list count*/
+ continue;
+ }
}
+
+ layer_instance_link_info[activated_layers].pNext = chain_info.u.pLayerInfo;
+ layer_instance_link_info[activated_layers].pfnNextGetInstanceProcAddr = nextGIPA;
+ chain_info.u.pLayerInfo = &layer_instance_link_info[activated_layers];
+ nextGIPA = fpGIPA;
+
+ loader_log(inst, VK_DEBUG_REPORT_INFO_BIT_EXT, 0,
+ "Insert instance layer %s (%s)",
+ layer_prop->info.layerName,
+ layer_prop->lib_name);
+
+ activated_layers++;
}
+ }
+
+ PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance) nextGIPA(VK_NULL_HANDLE, "vkCreateInstance");
+ if (fpCreateInstance) {
+ VkLayerInstanceCreateInfo instance_create_info;
+
+ instance_create_info.sType = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO;
+ instance_create_info.function = VK_LAYER_INSTANCE_INFO;
+
+ instance_create_info.u.instanceInfo.instance_info = inst;
+ instance_create_info.u.instanceInfo.pfnNextGetInstanceProcAddr= nextGIPA;
- loader_log(inst, VK_DEBUG_REPORT_INFO_BIT_EXT, 0,
- "Insert instance layer %s (%s)",
- layer_prop->info.layerName,
- layer_prop->lib_name);
+ instance_create_info.pNext = loader_create_info.pNext;
+ loader_create_info.pNext = &instance_create_info;
- layer_idx--;
+ res = fpCreateInstance(&loader_create_info, pAllocator, &inst->instance);
+ } else {
+ // Couldn't find CreateInstance function!
+ res = VK_ERROR_INITIALIZATION_FAILED;
}
- loader_init_instance_core_dispatch_table(inst->disp, nextGPA, (VkInstance) nextObj, (VkInstance) baseObj);
+ if (res != VK_SUCCESS) {
+ // TODO: Need to clean up here
+ } else {
+ loader_init_instance_core_dispatch_table(inst->disp, nextGIPA, inst->instance);
+ }
- return inst->activated_layer_list.count;
+ return res;
}
void loader_activate_instance_layer_extensions(struct loader_instance *inst, VkInstance created_inst)
return err;
}
-/*
- * This function terminates the device chain for 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 VKAPI_ATTR VkResult VKAPI_CALL scratch_vkCreateDevice(
- VkPhysicalDevice physicalDevice,
- const VkDeviceCreateInfo *pCreateInfo,
- const VkAllocationCallbacks* pAllocator,
- VkDevice *pDevice)
+VkResult loader_create_device_terminator(
+ VkPhysicalDevice physicalDevice,
+ const VkDeviceCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkDevice* pDevice)
{
- return VK_SUCCESS;
+ struct loader_physical_device *phys_dev;
+ phys_dev = loader_get_physical_device(physicalDevice);
+
+ VkLayerDeviceCreateInfo *chain_info = (VkLayerDeviceCreateInfo *) pCreateInfo->pNext;
+ while (chain_info && !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO
+ && chain_info->function == VK_LAYER_DEVICE_INFO)) {
+ chain_info = (VkLayerDeviceCreateInfo *) chain_info->pNext;
+ }
+ assert(chain_info != NULL);
+
+ struct loader_device *dev = (struct loader_device *) chain_info->u.deviceInfo.device_info;
+ PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.deviceInfo.pfnNextGetInstanceProcAddr;
+ PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice) fpGetInstanceProcAddr(phys_dev->this_icd->instance, "vkCreateDevice");
+ if (fpCreateDevice == NULL) {
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ VkDeviceCreateInfo localCreateInfo;
+ memcpy(&localCreateInfo, pCreateInfo, sizeof(localCreateInfo));
+ localCreateInfo.pNext = NULL;
+ // ICDs do not support layers
+ localCreateInfo.enabledLayerCount = 0;
+ localCreateInfo.ppEnabledLayerNames = NULL;
+
+ VkDevice localDevice;
+ VkResult res = fpCreateDevice(phys_dev->phys_dev, &localCreateInfo, pAllocator, &localDevice);
+
+ if (res != VK_SUCCESS) {
+ return res;
+ }
+
+ *pDevice = localDevice;
+
+ /* Init dispatch pointer in new device object */
+ loader_init_dispatch(*pDevice, &dev->loader_dispatch);
+
+ return res;
}
-static VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL loader_GetDeviceChainProcAddr(VkDevice device, const char * name)
+VkResult loader_create_device_chain(
+ VkPhysicalDevice physicalDevice,
+ const VkDeviceCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ struct loader_instance *inst,
+ struct loader_icd *icd,
+ struct loader_device *dev)
{
- if (!strcmp(name, "vkGetDeviceProcAddr"))
- return (PFN_vkVoidFunction) loader_GetDeviceChainProcAddr;
- if (!strcmp(name, "vkCreateDevice"))
- return (PFN_vkVoidFunction) scratch_vkCreateDevice;
+ uint32_t activated_layers = 0;
+ VkLayerDeviceLink *layer_device_link_info;
+ VkLayerDeviceCreateInfo chain_info;
+ VkLayerDeviceCreateInfo device_info;
+ VkDeviceCreateInfo loader_create_info;
+ VkResult res;
- struct loader_device *found_dev;
- struct loader_icd *icd = loader_get_icd_and_device(device, &found_dev);
- return icd->GetDeviceProcAddr(device, name);
-}
+ PFN_vkGetDeviceProcAddr fpGDPA, nextGDPA = icd->GetDeviceProcAddr;
+ PFN_vkGetInstanceProcAddr fpGIPA, nextGIPA = loader_gpa_instance_internal;
-static uint32_t loader_activate_device_layers(
- const struct loader_instance *inst,
- struct loader_device *dev,
- VkDevice device)
-{
- if (!dev) {
- return 0;
- }
-
- /* activate any layer libraries */
- void* nextObj = (void*) device;
- void* baseObj = nextObj;
- VkBaseLayerObject *nextGpuObj;
- PFN_vkGetDeviceProcAddr nextGPA = loader_GetDeviceChainProcAddr;
- VkBaseLayerObject *wrappedGpus;
-
- if (!dev->activated_layer_list.count) {
- loader_init_device_dispatch_table(&dev->loader_dispatch, nextGPA,
- (VkDevice) nextObj, (VkDevice) baseObj);
- return 0;
- }
-
- wrappedGpus = loader_heap_alloc(inst,
- sizeof (VkBaseLayerObject) * dev->activated_layer_list.count,
- VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
- if (!wrappedGpus) {
- loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Failed to alloc Gpu objects for layer");
- return 0;
- }
-
- for (int32_t i = dev->activated_layer_list.count - 1; i >= 0; i--) {
-
- struct loader_layer_properties *layer_prop = &dev->activated_layer_list.list[i];
- loader_platform_dl_handle lib_handle;
-
- nextGpuObj = (wrappedGpus + i);
- nextGpuObj->pGPA = (PFN_vkGPA)nextGPA;
- nextGpuObj->baseObject = baseObj;
- nextGpuObj->nextObject = nextObj;
- nextObj = (void*) nextGpuObj;
-
- lib_handle = loader_add_layer_lib(inst, "device", layer_prop);
- if ((nextGPA = layer_prop->functions.get_device_proc_addr) == NULL) {
- if (layer_prop->functions.str_gdpa == NULL || strlen(layer_prop->functions.str_gdpa) == 0) {
- nextGPA = (PFN_vkGetDeviceProcAddr) loader_platform_get_proc_address(lib_handle, "vkGetDeviceProcAddr");
- layer_prop->functions.get_device_proc_addr = nextGPA;
- } else
- nextGPA = (PFN_vkGetDeviceProcAddr) loader_platform_get_proc_address(lib_handle, layer_prop->functions.str_gdpa);
- if (!nextGPA) {
- loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Failed to find vkGetDeviceProcAddr in layer %s", layer_prop->lib_name);
- continue;
+ memcpy(&loader_create_info, pCreateInfo, sizeof(VkDeviceCreateInfo));
+
+ chain_info.sType = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO;
+ chain_info.function = VK_LAYER_LINK_INFO;
+ chain_info.u.pLayerInfo = NULL;
+ chain_info.pNext = pCreateInfo->pNext;
+
+ layer_device_link_info = loader_stack_alloc(sizeof(VkLayerDeviceLink)
+ * dev->activated_layer_list.count);
+ if (!layer_device_link_info) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Failed to alloc Device objects for layer");
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+
+ /*
+ * This structure is used by loader_create_device_terminator
+ * so that it can intialize the device dispatch table pointer
+ * in the device object returned by the ICD. Without this
+ * structure the code wouldn't know where the loader's device_info
+ * structure is located.
+ */
+ device_info.sType = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO;
+ device_info.function = VK_LAYER_DEVICE_INFO;
+ device_info.pNext = &chain_info;
+ device_info.u.deviceInfo.device_info = dev;
+ device_info.u.deviceInfo.pfnNextGetInstanceProcAddr = icd->this_icd_lib->GetInstanceProcAddr;
+
+ loader_create_info.pNext = &device_info;
+
+ if (dev->activated_layer_list.count > 0) {
+ /* Create instance chain of enabled layers */
+ for (int32_t i = dev->activated_layer_list.count - 1; i >= 0; i--) {
+ struct loader_layer_properties *layer_prop = &dev->activated_layer_list.list[i];
+ loader_platform_dl_handle lib_handle;
+
+ lib_handle = loader_add_layer_lib(inst, "device", layer_prop);
+ if (!lib_handle)
+ continue; // TODO what should we do in this case
+ if ((fpGIPA = layer_prop->functions.get_instance_proc_addr) == NULL) {
+ if (layer_prop->functions.str_gipa == NULL || strlen(layer_prop->functions.str_gipa) == 0) {
+ fpGIPA = (PFN_vkGetInstanceProcAddr) loader_platform_get_proc_address(lib_handle, "vkGetInstanceProcAddr");
+ layer_prop->functions.get_instance_proc_addr = fpGIPA;
+ } else
+ fpGIPA = (PFN_vkGetInstanceProcAddr) loader_platform_get_proc_address(lib_handle, layer_prop->functions.str_gipa);
+ if (!fpGIPA) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Failed to find vkGetInstanceProcAddr in layer %s", layer_prop->lib_name);
+
+ /* TODO: Should we return nextObj, nextGPA to previous? or decrement layer_list count*/
+ continue;
+ }
}
- }
+ if ((fpGDPA = layer_prop->functions.get_device_proc_addr) == NULL) {
+ if (layer_prop->functions.str_gdpa == NULL || strlen(layer_prop->functions.str_gdpa) == 0) {
+ fpGDPA = (PFN_vkGetDeviceProcAddr) loader_platform_get_proc_address(lib_handle, "vkGetDeviceProcAddr");
+ layer_prop->functions.get_device_proc_addr = fpGDPA;
+ } else
+ fpGDPA = (PFN_vkGetDeviceProcAddr) loader_platform_get_proc_address(lib_handle, layer_prop->functions.str_gdpa);
+ if (!fpGDPA) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Failed to find vkGetDeviceProcAddr in layer %s", layer_prop->lib_name);
+
+ /* TODO: Should we return nextObj, nextGPA to previous? or decrement layer_list count*/
+ continue;
+ }
+ }
+
+ layer_device_link_info[activated_layers].pNext = chain_info.u.pLayerInfo;
+ layer_device_link_info[activated_layers].pfnNextGetInstanceProcAddr = nextGIPA;
+ layer_device_link_info[activated_layers].pfnNextGetDeviceProcAddr = nextGDPA;
+ chain_info.u.pLayerInfo = &layer_device_link_info[activated_layers];
+ nextGIPA = fpGIPA;
+ nextGDPA = fpGDPA;
- loader_log(inst, VK_DEBUG_REPORT_INFO_BIT_EXT, 0,
- "Insert device layer library %s (%s)",
- layer_prop->info.layerName,
- layer_prop->lib_name);
+ loader_log(inst, VK_DEBUG_REPORT_INFO_BIT_EXT, 0,
+ "Insert device layer %s (%s)",
+ layer_prop->info.layerName,
+ layer_prop->lib_name);
+ activated_layers++;
+ }
}
- loader_init_device_dispatch_table(&dev->loader_dispatch, nextGPA,
- (VkDevice) nextObj, (VkDevice) baseObj);
- loader_heap_free(inst, wrappedGpus);
+ PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice) nextGIPA(VK_NULL_HANDLE, "vkCreateDevice");
+ if (fpCreateDevice) {
+ res = fpCreateDevice(physicalDevice, &loader_create_info, pAllocator, &dev->device);
+ } else {
+ // Couldn't find CreateDevice function!
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ /* Initialize device dispatch table */
+ loader_init_device_dispatch_table(&dev->loader_dispatch,
+ nextGDPA,
+ dev->device);
- return dev->activated_layer_list.count;
+ return res;
}
VkResult loader_validate_layers(
const VkAllocationCallbacks* pAllocator,
VkInstance* pInstance)
{
- struct loader_instance *ptr_instance = *(struct loader_instance **) pInstance;
struct loader_icd *icd;
VkExtensionProperties *prop;
char **filtered_extension_names = NULL;
VkResult res = VK_SUCCESS;
bool success = false;
+ VkLayerInstanceCreateInfo *chain_info = (VkLayerInstanceCreateInfo *) pCreateInfo->pNext;
+ while (chain_info && !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO
+ && chain_info->function == VK_LAYER_INSTANCE_INFO)) {
+ chain_info = (VkLayerInstanceCreateInfo *) chain_info->pNext;
+ }
+ assert(chain_info != NULL);
+
+ struct loader_instance *ptr_instance = (struct loader_instance *) chain_info->u.instanceInfo.instance_info;
memcpy(&icd_create_info, pCreateInfo, sizeof(icd_create_info));
icd_create_info.enabledLayerCount = 0;
icd_create_info.ppEnabledLayerNames = NULL;
+ // TODO: Should really strip off the VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO entries
+ icd_create_info.pNext = NULL;
+
/*
* NOTE: Need to filter the extensions to only those
* supported by the ICD.
}
}
+ *pInstance = (VkInstance) ptr_instance;
+
return VK_SUCCESS;
}
VkPhysicalDevice* pPhysicalDevices)
{
uint32_t i;
+ uint32_t copy_count = 0;
struct loader_instance *ptr_instance = (struct loader_instance *) instance;
VkResult res = VK_SUCCESS;
return res;
}
- for (i = 0; i < ptr_instance->total_gpu_count; i++) {
+ copy_count = (ptr_instance->total_gpu_count < *pPhysicalDeviceCount) ? ptr_instance->total_gpu_count : *pPhysicalDeviceCount;
+ for (i = 0; i < copy_count; i++) {
pPhysicalDevices[i] = (VkPhysicalDevice) &ptr_instance->phys_devs[i];
}
+ *pPhysicalDeviceCount = copy_count;
+
+ if (copy_count < ptr_instance->total_gpu_count) {
+ return VK_INCOMPLETE;
+ }
return res;
}
}
}
- // since physicalDevice object maybe wrapped by a layer need to get unwrapped version
- // we haven't yet called down the chain for the layer to unwrap the object
- res = icd->CreateDevice(phys_dev->phys_dev, &device_create_info, pAllocator, pDevice);
- if (res != VK_SUCCESS) {
- loader_destroy_generic_list(inst, (struct loader_generic_list *) &activated_layer_list);
- return res;
- }
-
- dev = loader_add_logical_device(inst, *pDevice, &icd->logical_device_list);
+ dev = loader_add_logical_device(inst, &icd->logical_device_list);
if (dev == NULL) {
loader_destroy_generic_list(inst, (struct loader_generic_list *) &activated_layer_list);
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
- loader_init_dispatch(*pDevice, &dev->loader_dispatch);
/* move the locally filled layer list into the device, and pass ownership of the memory */
dev->activated_layer_list.capacity = activated_layer_list.capacity;
dev->activated_layer_list.list = activated_layer_list.list;
memset(&activated_layer_list, 0, sizeof(activated_layer_list));
- /* activate any layers on device chain which terminates with device*/
- loader_activate_device_layers(inst, dev, *pDevice);
+ /* activate any layers on device chain which terminates with device*/
+ res = loader_enable_device_layers(inst, icd, &dev->activated_layer_list, pCreateInfo, &inst->device_layer_list);
+ if (res != VK_SUCCESS) {
+ loader_destroy_logical_device(inst, dev);
+ return res;
+ }
+
+ res = loader_create_device_chain(physicalDevice, pCreateInfo, pAllocator, inst, icd, dev);
+ if (res != VK_SUCCESS) {
+ loader_destroy_logical_device(inst, dev);
+ return res;
+ }
- /* finally can call down the chain */
- res = dev->loader_dispatch.core_dispatch.CreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);
+ *pDevice = dev->device;
/* initialize any device extension dispatch entry's from the instance list*/
loader_init_dispatch_dev_ext(inst, dev);
loader_init_device_extension_dispatch_table(&dev->loader_dispatch,
dev->loader_dispatch.core_dispatch.GetDeviceProcAddr,
*pDevice);
- dev->loader_dispatch.core_dispatch.CreateDevice = icd->CreateDevice;
return res;
}
struct loader_layer_list activated_layer_list;
+ VkInstance instance;
+
bool debug_report_enabled;
VkLayerDbgFunctionNode *DbgFunctionHead;
VkPhysicalDevice physicalDevice,
VkPhysicalDeviceMemoryProperties * pProperties);
+VkResult loader_create_device_terminator(
+ VkPhysicalDevice physicalDevice,
+ const VkDeviceCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkDevice* pDevice);
+
VKAPI_ATTR VkResult VKAPI_CALL loader_CreateDevice(
VkPhysicalDevice gpu,
const VkDeviceCreateInfo* pCreateInfo,
const VkInstanceCreateInfo *pCreateInfo,
const struct loader_layer_list *instance_layers);
void loader_deactivate_instance_layers(struct loader_instance *instance);
-uint32_t loader_activate_instance_layers(struct loader_instance *inst);
+
+VkResult loader_create_instance_chain(const VkInstanceCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ struct loader_instance *inst);
+
void loader_activate_instance_layer_extensions(struct loader_instance *inst, VkInstance created_inst);
void* loader_heap_alloc(
static inline void loader_init_device_dispatch_table(struct loader_dev_dispatch_table *dev_table,
PFN_vkGetDeviceProcAddr gpa,
- VkDevice dev_next,
VkDevice dev)
{
VkLayerDispatchTable *table = &dev_table->core_dispatch;
for (uint32_t i = 0; i < MAX_NUM_DEV_EXTS; i++)
dev_table->ext_dispatch.DevExt[i] = (PFN_vkDevExt) vkDevExtError;
- // If layer is next, this will trigger layers to initialize their dispatch tables
- //then use the gpa in their dispatch for subsequent layers in the chain
- table->GetDeviceProcAddr = (PFN_vkGetDeviceProcAddr) gpa(dev_next, "vkGetDeviceProcAddr");
- table->CreateDevice = (PFN_vkCreateDevice) gpa(dev, "vkCreateDevice");
+ table->GetDeviceProcAddr = (PFN_vkGetDeviceProcAddr) gpa(dev, "vkGetDeviceProcAddr");
+// table->CreateDevice = (PFN_vkCreateDevice) gpa(dev, "vkCreateDevice");
table->DestroyDevice = (PFN_vkDestroyDevice) gpa(dev, "vkDestroyDevice");
table->GetDeviceQueue = (PFN_vkGetDeviceQueue) gpa(dev, "vkGetDeviceQueue");
table->QueueSubmit = (PFN_vkQueueSubmit) gpa(dev, "vkQueueSubmit");
name += 2;
if (!strcmp(name, "GetDeviceProcAddr"))
return (void *) table->GetDeviceProcAddr;
- if (!strcmp(name, "CreateDevice"))
- return (void *) table->CreateDevice;
+// if (!strcmp(name, "CreateDevice"))
+// return (void *) table->CreateDevice;
if (!strcmp(name, "DestroyDevice"))
return (void *) table->DestroyDevice;
if (!strcmp(name, "GetDeviceQueue"))
return NULL;
}
-static inline void loader_init_instance_core_dispatch_table(VkLayerInstanceDispatchTable *table,
- PFN_vkGetInstanceProcAddr gpa,
- VkInstance inst_next,
- VkInstance inst)
+static inline void loader_init_instance_core_dispatch_table(
+ VkLayerInstanceDispatchTable *table,
+ PFN_vkGetInstanceProcAddr gpa,
+ VkInstance inst)
{
- // If layer is next, this will trigger layers to initialize their dispatch tables
- //then use the gpa in their dispatch for subsequent layers in the chain
- table->GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) gpa(inst_next, "vkGetInstanceProcAddr");
-
+ table->GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) gpa(inst, "vkGetInstanceProcAddr");
table->CreateInstance = (PFN_vkCreateInstance) gpa(inst, "vkCreateInstance");
table->DestroyInstance = (PFN_vkDestroyInstance) gpa(inst, "vkDestroyInstance");
+ table->CreateDevice = (PFN_vkCreateDevice) gpa(inst, "vkCreateDevice");
table->EnumeratePhysicalDevices = (PFN_vkEnumeratePhysicalDevices) gpa(inst, "vkEnumeratePhysicalDevices");
table->GetPhysicalDeviceFeatures = (PFN_vkGetPhysicalDeviceFeatures) gpa(inst, "vkGetPhysicalDeviceFeatures");
table->GetPhysicalDeviceImageFormatProperties = (PFN_vkGetPhysicalDeviceImageFormatProperties) gpa(inst, "vkGetPhysicalDeviceImageFormatProperties");
return (void *) table->CreateInstance;
if (!strcmp(name, "DestroyInstance"))
return (void *) table->DestroyInstance;
+ if (!strcmp(name, "CreateDevice"))
+ return (void *) table->CreateDevice;
if (!strcmp(name, "EnumeratePhysicalDevices"))
return (void *) table->EnumeratePhysicalDevices;
if (!strcmp(name, "GetPhysicalDeviceFeatures"))
loader_heap_free(ptr_instance, ptr_instance);
return res;
}
- loader_activate_instance_layers(ptr_instance);
-
- wsi_create_instance(ptr_instance, pCreateInfo);
- debug_report_create_instance(ptr_instance, pCreateInfo);
created_instance = (VkInstance) ptr_instance;
- res = ptr_instance->disp->CreateInstance(pCreateInfo, pAllocator, &created_instance);
+ res = loader_create_instance_chain(pCreateInfo, pAllocator, ptr_instance);
if (res == VK_SUCCESS) {
+ wsi_create_instance(ptr_instance, pCreateInfo);
+ debug_report_create_instance(ptr_instance, pCreateInfo);
+
*pInstance = created_instance;
+
/*
+ * TODO: This can go away now?
* Finally have the layers in place and everyone has seen
* the CreateInstance command go by. This allows the layer's
* GetInstanceProcAddr functions to return valid extension functions
* if enabled.
*/
loader_activate_instance_layer_extensions(ptr_instance, *pInstance);
+ } else {
+ // TODO: cleanup here.
}
+
/* Remove temporary debug_report callback */
util_DestroyDebugReportCallback(ptr_instance, instance_callback, pAllocator);
func = []
if type == "device":
# GPA has to be first one and uses wrapped object
- stmts.append("VkDevice device = (VkDevice) devw->nextObject;")
- stmts.append("PFN_vkGetDeviceProcAddr gpa = (PFN_vkGetDeviceProcAddr) devw->pGPA;")
- stmts.append("VkDevice baseDevice = (VkDevice) devw->baseObject;")
- stmts.append("// GPA has to be first entry inited and uses wrapped object since it triggers init")
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 == "EnumerateInstanceExtensionProperties" or proto.name == "EnumerateInstanceLayerProperties" or proto.params[0].ty == "VkInstance" or (proto.params[0].ty == "VkPhysicalDevice" and proto.name != "CreateDevice"):
+ if proto.name == "CreateInstance" or proto.name == "EnumerateInstanceExtensionProperties" or proto.name == "EnumerateInstanceLayerProperties" or proto.params[0].ty == "VkInstance" or proto.params[0].ty == "VkPhysicalDevice":
continue
if proto.name != "GetDeviceProcAddr" and 'KHR' not in proto.name:
- stmts.append("table->%s = (PFN_vk%s) gpa(baseDevice, \"vk%s\");" %
+ stmts.append("table->%s = (PFN_vk%s) gpa(device, \"vk%s\");" %
(proto.name, proto.name, proto.name))
- func.append("static inline void %s_initialize_dispatch_table(VkLayerDispatchTable *table,"
+ func.append("static inline void %s_init_device_dispatch_table(VkDevice device,"
% self.prefix)
- func.append("%s const VkBaseLayerObject *devw)"
+ func.append("%s VkLayerDispatchTable *table,"
+ % (" " * len(self.prefix)))
+ func.append("%s PFN_vkGetDeviceProcAddr gpa)"
% (" " * len(self.prefix)))
else:
- # GPA has to be first one and uses wrapped object
- stmts.append("VkInstance instance = (VkInstance) instw->nextObject;")
- stmts.append("PFN_vkGetInstanceProcAddr gpa = (PFN_vkGetInstanceProcAddr) instw->pGPA;")
- stmts.append("VkInstance baseInstance = (VkInstance) instw->baseObject;")
- stmts.append("// GPA has to be first entry inited and uses wrapped object since it triggers init")
stmts.append("table->GetInstanceProcAddr =(PFN_vkGetInstanceProcAddr) gpa(instance,\"vkGetInstanceProcAddr\");")
for proto in self.protos:
- if proto.name != "CreateInstance" and proto.params[0].ty != "VkInstance" and proto.params[0].ty != "VkPhysicalDevice":
+ if proto.params[0].ty != "VkInstance" and proto.params[0].ty != "VkPhysicalDevice":
continue
if proto.name == "CreateDevice":
continue
if proto.name != "GetInstanceProcAddr" and 'KHR' not in proto.name:
- stmts.append("table->%s = (PFN_vk%s) gpa(baseInstance, \"vk%s\");" %
+ stmts.append("table->%s = (PFN_vk%s) gpa(instance, \"vk%s\");" %
(proto.name, proto.name, proto.name))
- func.append("static inline void %s_init_instance_dispatch_table(VkLayerInstanceDispatchTable *table,"
- % self.prefix)
- func.append("%s const VkBaseLayerObject *instw)"
- % (" " * len(self.prefix)))
+ func.append("static inline void %s_init_instance_dispatch_table(" % self.prefix)
+ func.append("%s VkInstance instance," % (" " * len(self.prefix)))
+ func.append("%s VkLayerInstanceDispatchTable *table," % (" " * len(self.prefix)))
+ func.append("%s PFN_vkGetInstanceProcAddr gpa)" % (" " * len(self.prefix)))
func.append("{")
func.append(" %s" % "\n ".join(stmts))
func.append("}")
if not proto in intercepted:
continue
+ if proto.name == "CreateInstance":
+ continue
if proto.name == "CreateDevice":
continue
lookups.append("if (!strcmp(name, \"%s\"))" % proto.name)
func_body.append("VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char* funcName)\n"
"{\n"
" PFN_vkVoidFunction addr;\n"
- " if (device == VK_NULL_HANDLE) {\n"
- " return NULL;\n"
- " }\n"
- " /* loader uses this to force layer initialization; device object is wrapped */\n"
" if (!strcmp(\"vkGetDeviceProcAddr\", funcName)) {\n"
- " initDeviceTable(%s_device_table_map, (const VkBaseLayerObject *) device);\n"
" return (PFN_vkVoidFunction) vkGetDeviceProcAddr;\n"
" }\n\n"
" addr = layer_intercept_proc(funcName);\n"
" if (addr)\n"
- " return addr;" % self.layer_name)
+ " return addr;\n"
+ " if (device == VK_NULL_HANDLE) {\n"
+ " return NULL;\n"
+ " }\n")
if 0 != len(extensions):
func_body.append('%s' % self.lineinfo.get())
func_body.append(' layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);')
func_body.append("VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* funcName)\n"
"{\n"
" PFN_vkVoidFunction addr;\n"
- " if (instance == VK_NULL_HANDLE) {\n"
- " return NULL;\n"
- " }\n"
- " /* loader uses this to force layer initialization; instance object is wrapped */\n"
- " if (!strcmp(\"vkGetInstanceProcAddr\", funcName)) {\n"
- " initInstanceTable(%s_instance_table_map, (const VkBaseLayerObject *) instance);\n"
+ " if (!strcmp(funcName, \"vkGetInstanceProcAddr\"))\n"
" return (PFN_vkVoidFunction) vkGetInstanceProcAddr;\n"
- " }\n\n"
+ " if (!strcmp(funcName, \"vkCreateInstance\"))\n"
+ " return (PFN_vkVoidFunction) vkCreateInstance;\n"
+ " if (!strcmp(funcName, \"vkCreateDevice\"))\n"
+ " return (PFN_vkVoidFunction) vkCreateDevice;\n"
" addr = layer_intercept_instance_proc(funcName);\n"
" if (addr) {\n"
" return addr;"
- " }\n" % self.layer_name)
+ " }\n"
+ " if (instance == VK_NULL_HANDLE) {\n"
+ " return NULL;\n"
+ " }\n"
+ )
table_declared = False
if 0 != len(instance_extensions):
func_body.append('%s' % self.lineinfo.get())
func_body.append("VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char* funcName)\n"
"{\n"
- " PFN_vkVoidFunction addr;\n"
- " if (device == VK_NULL_HANDLE) {\n"
- " return NULL;\n"
- " }\n")
+ " PFN_vkVoidFunction addr;\n")
if self.layer_name == 'generic':
func_body.append("\n"
- " /* loader uses this to force layer initialization; device object is wrapped */\n"
" if (!strcmp(\"vkGetDeviceProcAddr\", funcName)) {\n"
- " initDeviceTable((const VkBaseLayerObject *) device);\n"
" return (PFN_vkVoidFunction) vkGetDeviceProcAddr;\n"
" }\n\n"
" addr = layer_intercept_proc(funcName);\n"
else:
func_body.append("\n"
" loader_platform_thread_once(&initOnce, init%s);\n\n"
- " /* loader uses this to force layer initialization; device object is wrapped */\n"
" if (!strcmp(\"vkGetDeviceProcAddr\", funcName)) {\n"
- " initDeviceTable((const VkBaseLayerObject *) device);\n"
" return (PFN_vkVoidFunction) vkGetDeviceProcAddr;\n"
" }\n\n"
" addr = layer_intercept_proc(funcName);\n"
" if (addr)\n"
" return addr;" % self.layer_name)
+ func_body.append(" if (device == VK_NULL_HANDLE) {\n"
+ " return NULL;\n"
+ " }\n")
func_body.append('')
func_body.append(' VkLayerDispatchTable *pDisp = device_dispatch_table(device);')
if 0 != len(extensions):
func_body.append("VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* funcName)\n"
"{\n"
" PFN_vkVoidFunction addr;\n"
- " if (instance == VK_NULL_HANDLE) {\n"
- " return NULL;\n"
- " }\n")
+ " if (!strcmp(funcName, \"vkGetInstanceProcAddr\"))\n"
+ " return (PFN_vkVoidFunction) vkGetInstanceProcAddr;\n"
+ " if (!strcmp(funcName, \"vkCreateInstance\"))\n"
+ " return (PFN_vkVoidFunction) vkCreateInstance;\n"
+ " if (!strcmp(funcName, \"vkCreateDevice\"))\n"
+ " return (PFN_vkVoidFunction) vkCreateDevice;\n"
+ )
if self.layer_name == 'generic':
func_body.append("\n"
- " /* loader uses this to force layer initialization; instance object is wrapped */\n"
- " if (!strcmp(\"vkGetInstanceProcAddr\", funcName)) {\n"
- " initInstanceTable((const VkBaseLayerObject *) instance);\n"
- " return (PFN_vkVoidFunction) vkGetInstanceProcAddr;\n"
- " }\n\n"
" addr = layer_intercept_instance_proc(funcName);\n"
" if (addr)\n"
" return addr;")
else:
func_body.append(
" loader_platform_thread_once(&initOnce, init%s);\n\n"
- " /* loader uses this to force layer initialization; instance object is wrapped */\n"
- " if (!strcmp(\"vkGetInstanceProcAddr\", funcName)) {\n"
- " initInstanceTable((const VkBaseLayerObject *) instance);\n"
- " return (PFN_vkVoidFunction) vkGetInstanceProcAddr;\n"
- " }\n\n"
" addr = layer_intercept_instance_proc(funcName);\n"
" if (addr)\n"
" return addr;" % self.layer_name)
+ func_body.append(" if (instance == VK_NULL_HANDLE) {\n"
+ " return NULL;\n"
+ " }\n")
func_body.append("")
- func_body.append(" VkLayerInstanceDispatchTable* pTable = instance_dispatch_table(instance);")
+ func_body.append(" VkLayerInstanceDispatchTable* pTable = instance_dispatch_table(instance);\n")
if 0 != len(instance_extensions):
extra_space = ""
for (ext_enable, ext_list) in instance_extensions:
funcs.append('%s' % self.lineinfo.get())
funcs.append('%s%s\n'
'{\n'
+ ' layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);\n'
' char str[1024];\n'
- ' layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);\n'
' sprintf(str, "At start of Generic layered %s\\n");\n'
- ' log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,'
+ ' log_msg(my_instance_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,'
' (uint64_t)physicalDevice, __LINE__, 0, (char *) "generic", "%%s", (char *) str);\n'
- ' %sdevice_dispatch_table(*pDevice)->%s;\n'
- ' if (result == VK_SUCCESS) {\n'
- ' my_data->report_data = layer_debug_report_create_device(my_data->report_data, *pDevice);\n'
- ' createDeviceRegisterExtensions(pCreateInfo, *pDevice);\n'
+ ' VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);\n'
+ ' PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;\n'
+ ' PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;\n'
+ ' PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice) fpGetInstanceProcAddr(NULL, "vkCreateDevice");\n'
+ ' if (fpCreateDevice == NULL) {\n'
+ ' return VK_ERROR_INITIALIZATION_FAILED;\n'
' }\n'
+ ' // Advance the link info for the next element on the chain\n'
+ ' chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;\n'
+ ' VkResult result = fpCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);\n'
+ ' if (result != VK_SUCCESS) {\n'
+ ' return result;\n'
+ ' }\n'
+ ' layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);\n'
+ ' initDeviceTable(*pDevice, fpGetDeviceProcAddr);\n'
+ ' my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);\n'
+ ' createDeviceRegisterExtensions(pCreateInfo, *pDevice);\n'
' sprintf(str, "Completed generic layered %s\\n");\n'
- ' log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, (uint64_t)physicalDevice, __LINE__, 0, (char *) "generic", "%%s", (char *) str);\n'
+ ' log_msg(my_device_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, (uint64_t)physicalDevice, __LINE__, 0, (char *) "generic", "%%s", (char *) str);\n'
' %s'
- '}' % (qual, decl, proto.name, ret_val, proto.c_call(), proto.name, stmt))
+ '}' % (qual, decl, proto.name, proto.name, stmt))
elif proto.name == "DestroyDevice":
funcs.append('%s' % self.lineinfo.get())
funcs.append('%s%s\n'
funcs.append('%s%s\n'
'{\n'
' char str[1024];\n'
- ' %sinstance_dispatch_table(*pInstance)->%s;\n'
- ' if (result == VK_SUCCESS) {\n'
- ' createInstanceRegisterExtensions(pCreateInfo, *pInstance);\n'
- ' layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);\n'
- ' my_data->report_data = debug_report_create_instance(\n'
- ' instance_dispatch_table(*pInstance),\n'
- ' *pInstance,\n'
- ' pCreateInfo->enabledExtensionCount,\n'
- ' pCreateInfo->ppEnabledExtensionNames);\n'
- ' init_generic(my_data, pAllocator);\n'
- ' sprintf(str, "Completed generic layered %s\\n");\n'
- ' log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, (uint64_t)*pInstance, __LINE__, 0, (char *) "generic", "%%s", (char *) str);\n'
+ ' VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);\n'
+ ' PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;\n'
+ ' PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance) fpGetInstanceProcAddr(NULL, "vkCreateInstance");\n'
+ ' if (fpCreateInstance == NULL) {\n'
+ ' return VK_ERROR_INITIALIZATION_FAILED;\n'
+ ' }\n'
+ ' // Advance the link info for the next element on the chain\n'
+ ' chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;\n'
+ ' VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);\n'
+ ' if (result != VK_SUCCESS) {\n'
+ ' return result;\n'
' }\n'
+ ' VkLayerInstanceDispatchTable *pTable = initInstanceTable(*pInstance, fpGetInstanceProcAddr);\n'
+ ' createInstanceRegisterExtensions(pCreateInfo, *pInstance);\n'
+ ' layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);\n'
+ ' my_data->report_data = debug_report_create_instance(\n'
+ ' pTable,\n'
+ ' *pInstance,\n'
+ ' pCreateInfo->enabledExtensionCount,\n'
+ ' pCreateInfo->ppEnabledExtensionNames);\n'
+ ' init_generic(my_data, pAllocator);\n'
+ ' sprintf(str, "Completed generic layered %s\\n");\n'
+ ' log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, (uint64_t)*pInstance, __LINE__, 0, (char *) "generic", "%%s", (char *) str);\n'
' return result;\n'
- '}\n' % (qual, decl, ret_val, proto.c_call(), proto.name))
+ '}\n' % (qual, decl, proto.name))
else:
if wsi_name(proto.name):
funcs.append('%s' % wsi_ifdef(proto.name))
funcs.append('%s%s\n'
'{\n'
' using namespace StreamControl;\n'
- ' %sinstance_dispatch_table(*pInstance)->%s;\n'
- ' if (result == VK_SUCCESS) {\n'
- ' createInstanceRegisterExtensions(pCreateInfo, *pInstance);\n'
+ ' loader_platform_thread_once(&initOnce, initapi_dump);\n'
+ ' VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);\n'
+ ' PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;\n'
+ ' PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance) fpGetInstanceProcAddr(NULL, "vkCreateInstance");\n'
+ ' if (fpCreateInstance == NULL) {\n'
+ ' return VK_ERROR_INITIALIZATION_FAILED;\n'
' }\n'
+ ' // Advance the link info for the next element on the chain\n'
+ ' assert(chain_info->u.pLayerInfo);\n'
+ ' chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;\n'
+ ' VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);\n'
+ ' if (result != VK_SUCCESS)\n'
+ ' return result;\n'
+ ' initInstanceTable(*pInstance, fpGetInstanceProcAddr);\n'
+ ' createInstanceRegisterExtensions(pCreateInfo, *pInstance);\n'
' %s%s%s\n'
'%s'
- '}\n' % (qual, decl, ret_val, proto.c_call(), f_open, log_func, f_close, stmt))
+ '}\n' % (qual, decl, f_open, log_func, f_close, stmt))
elif proto.name == "CreateDevice":
funcs.append('%s\n' % self.lineinfo.get())
funcs.append('%s%s\n'
'{\n'
' using namespace StreamControl;\n'
- ' %sdevice_dispatch_table(*pDevice)->%s;\n'
- ' if (result == VK_SUCCESS)\n'
- ' createDeviceRegisterExtensions(pCreateInfo, *pDevice);\n'
+ ' %sexplicit_CreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);\n'
' %s%s%s\n'
'%s'
- '}' % (qual, decl, ret_val, proto.c_call(), f_open, log_func, f_close, stmt))
+ '}' % (qual, decl, ret_val, f_open, log_func, f_close, stmt))
elif proto.name == "DestroyDevice":
funcs.append('%s%s\n'
'{\n'
funcs.append('%s' % self.lineinfo.get())
funcs.append('%s%s\n' % (qual, decl) +
'{\n'
- ' VkLayerDispatchTable *pDeviceTable = get_dispatch_table(threading_device_table_map, (void *) *pDevice);\n'
- ' VkResult result = pDeviceTable->%s;\n' % (proto.c_call()) +
- ' if (result == VK_SUCCESS) {\n'
- ' layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(%s), layer_data_map);\n' % proto.params[0].name +
- ' layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);\n'
- ' my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);\n'
+ ' VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);\n'
+ ' PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;\n'
+ ' PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;\n'
+ ' PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice) fpGetInstanceProcAddr(NULL, "vkCreateDevice");\n'
+ ' if (fpCreateDevice == NULL) {\n'
+ ' return VK_ERROR_INITIALIZATION_FAILED;\n'
' }\n'
- '\n'
- ' return result;'
- '}')
+ ' // Advance the link info for the next element on the chain\n'
+ ' chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;\n'
+ ' VkResult result = fpCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);\n'
+ ' if (result != VK_SUCCESS) {\n'
+ ' return result;\n'
+ ' }\n'
+ ' layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);\n'
+ ' layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);\n'
+ ' initDeviceTable(*pDevice, fpGetDeviceProcAddr, threading_device_table_map);\n'
+ ' my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);\n'
+ ' return result;\n'
+ '}\n')
return "\n".join(funcs)
elif proto.params[0].ty == "VkPhysicalDevice":
return None
elif proto.name == "CreateInstance":
funcs.append('%s%s\n'
'{\n'
- ' VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(threading_instance_table_map, *pInstance);\n'
- ' VkResult result = pInstanceTable->CreateInstance(pCreateInfo, pAllocator, pInstance);\n'
- '\n'
- ' if (result == VK_SUCCESS) {\n'
- ' layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);\n'
- ' my_data->report_data = debug_report_create_instance(\n'
- ' pInstanceTable,\n'
- ' *pInstance,\n'
- ' pCreateInfo->enabledExtensionCount,\n'
- ' pCreateInfo->ppEnabledExtensionNames);\n'
- ' init_threading(my_data, pAllocator);\n'
+ ' VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);\n'
+ ' PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;\n'
+ ' PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance) fpGetInstanceProcAddr(NULL, "vkCreateInstance");\n'
+ ' if (fpCreateInstance == NULL) {\n'
+ ' return VK_ERROR_INITIALIZATION_FAILED;\n'
+ ' }\n'
+ ' // Advance the link info for the next element on the chain\n'
+ ' chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;\n'
+ ' VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);\n'
+ ' if (result != VK_SUCCESS) {\n'
+ ' return result;\n'
' }\n'
+ ' VkLayerInstanceDispatchTable *pTable = initInstanceTable(*pInstance, fpGetInstanceProcAddr, threading_instance_table_map);\n'
+ ' layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);\n'
+ ' my_data->report_data = debug_report_create_instance(\n'
+ ' pTable,\n'
+ ' *pInstance,\n'
+ ' pCreateInfo->enabledExtensionCount,\n'
+ ' pCreateInfo->ppEnabledExtensionNames);\n'
+ ' init_threading(my_data, pAllocator);\n'
' return result;\n'
'}\n' % (qual, decl))
return "\n".join(funcs);