#include "loader.h"
#include "extensions.h"
#include <vulkan/vk_icd.h>
+#include "wsi.h"
+
+// Definitions for the VK_EXT_debug_marker extension commands which
+// need to have a terminator function
+
+VKAPI_ATTR VkResult VKAPI_CALL vkDebugMarkerSetObjectTagEXT(
+ VkDevice device, VkDebugMarkerObjectTagInfoEXT *pTagInfo) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ // If this is a physical device, we have to replace it with the proper one
+ // for the next call.
+ if (pTagInfo->objectType ==
+ VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT) {
+ struct loader_physical_device_tramp *phys_dev_tramp =
+ (struct loader_physical_device_tramp *)pTagInfo->object;
+ pTagInfo->object = (uint64_t)phys_dev_tramp->phys_dev;
+ }
+ return disp->DebugMarkerSetObjectTagEXT(device, pTagInfo);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_DebugMarkerSetObjectTagEXT(
+ VkDevice device, VkDebugMarkerObjectTagInfoEXT *pTagInfo) {
+ uint32_t icd_index = 0;
+ struct loader_device *dev;
+ struct loader_icd_term *icd_term =
+ loader_get_icd_and_device(device, &dev, &icd_index);
+ // If this is a physical device, we have to replace it with the proper one
+ // for the next call.
+ if (pTagInfo->objectType ==
+ VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT) {
+ struct loader_physical_device_term *phys_dev_term =
+ (struct loader_physical_device_term *)pTagInfo->object;
+ pTagInfo->object = (uint64_t)phys_dev_term->phys_dev;
+
+ // If this is a KHR_surface, and the ICD has created its own, we have to
+ // replace it with the proper one for the next call.
+ } else if (pTagInfo->objectType ==
+ VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT) {
+ if (NULL != icd_term && NULL != icd_term->CreateSwapchainKHR) {
+ VkIcdSurface *icd_surface = (VkIcdSurface *)(pTagInfo->object);
+ if (NULL != icd_surface->real_icd_surfaces) {
+ pTagInfo->object =
+ (uint64_t)icd_surface->real_icd_surfaces[icd_index];
+ }
+ }
+ }
+ assert(icd_term != NULL && icd_term->DebugMarkerSetObjectTagEXT &&
+ "loader: null DebugMarkerSetObjectTagEXT ICD pointer");
+ return icd_term->DebugMarkerSetObjectTagEXT(device, pTagInfo);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL vkDebugMarkerSetObjectNameEXT(
+ VkDevice device, VkDebugMarkerObjectNameInfoEXT *pNameInfo) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ // If this is a physical device, we have to replace it with the proper one
+ // for the next call.
+ if (pNameInfo->objectType ==
+ VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT) {
+ struct loader_physical_device_tramp *phys_dev_tramp =
+ (struct loader_physical_device_tramp *)pNameInfo->object;
+ pNameInfo->object = (uint64_t)phys_dev_tramp->phys_dev;
+ }
+ return disp->DebugMarkerSetObjectNameEXT(device, pNameInfo);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_DebugMarkerSetObjectNameEXT(
+ VkDevice device, VkDebugMarkerObjectNameInfoEXT *pNameInfo) {
+ uint32_t icd_index = 0;
+ struct loader_device *dev;
+ struct loader_icd_term *icd_term =
+ loader_get_icd_and_device(device, &dev, &icd_index);
+ // If this is a physical device, we have to replace it with the proper one
+ // for the next call.
+ if (pNameInfo->objectType ==
+ VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT) {
+ struct loader_physical_device_term *phys_dev_term =
+ (struct loader_physical_device_term *)pNameInfo->object;
+ pNameInfo->object = (uint64_t)phys_dev_term->phys_dev;
+
+ // If this is a KHR_surface, and the ICD has created its own, we have to
+ // replace it with the proper one for the next call.
+ } else if (pNameInfo->objectType ==
+ VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT) {
+ if (NULL != icd_term && NULL != icd_term->CreateSwapchainKHR) {
+ VkIcdSurface *icd_surface = (VkIcdSurface *)(pNameInfo->object);
+ if (NULL != icd_surface->real_icd_surfaces) {
+ pNameInfo->object =
+ (uint64_t)icd_surface->real_icd_surfaces[icd_index];
+ }
+ }
+ }
+ assert(icd_term != NULL && icd_term->DebugMarkerSetObjectNameEXT &&
+ "loader: null DebugMarkerSetObjectNameEXT ICD pointer");
+ return icd_term->DebugMarkerSetObjectNameEXT(device, pNameInfo);
+}
// Definitions for the VK_NV_external_memory_capabilities extension
const char *name, void **addr) {
*addr = NULL;
+ // Definitions for the VK_EXT_debug_marker extension commands which
+ // need to have a terminator function. Since these are device
+ // commands, we always need to return a valid value for them.
+
+ if (!strcmp("vkDebugMarkerSetObjectTagEXT", name)) {
+ *addr = (void *)vkDebugMarkerSetObjectTagEXT;
+ return true;
+ }
+ if (!strcmp("vkDebugMarkerSetObjectNameEXT", name)) {
+ *addr = (void *)vkDebugMarkerSetObjectNameEXT;
+ return true;
+ }
+
// Functions for the VK_NV_external_memory_capabilities extension
if (!strcmp("vkGetPhysicalDeviceExternalImageFormatPropertiesNV", name)) {
void extensions_create_instance(struct loader_instance *ptr_instance,
const VkInstanceCreateInfo *pCreateInfo);
+// Definitions for the VK_EXT_debug_marker extension
+
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_DebugMarkerSetObjectTagEXT(
+ VkDevice device, VkDebugMarkerObjectTagInfoEXT *pTagInfo);
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_DebugMarkerSetObjectNameEXT(
+ VkDevice device, VkDebugMarkerObjectNameInfoEXT *pNameInfo);
+
// Definitions for the VK_NV_external_memory_capabilities extension
VKAPI_ATTR VkResult VKAPI_CALL
icd_term = icd_term->next) {
for (struct loader_device *dev = icd_term->logical_device_list; dev;
dev = dev->next)
- /* Value comparison of device prevents object wrapping by layers
- */
- if (loader_get_dispatch(dev->device) ==
+ // Value comparison of device prevents object wrapping by layers
+ if (loader_get_dispatch(dev->icd_device) ==
+ loader_get_dispatch(device) ||
+ loader_get_dispatch(dev->chain_device) ==
loader_get_dispatch(device)) {
*found_dev = dev;
if (NULL != icd_index) {
LOOKUP_GIPA(GetPhysicalDeviceSparseImageFormatProperties, true);
LOOKUP_GIPA(CreateDebugReportCallbackEXT, false);
LOOKUP_GIPA(DestroyDebugReportCallbackEXT, false);
+ LOOKUP_GIPA(DebugMarkerSetObjectTagEXT, false);
+ LOOKUP_GIPA(DebugMarkerSetObjectNameEXT, false);
LOOKUP_GIPA(GetPhysicalDeviceSurfaceSupportKHR, false);
LOOKUP_GIPA(GetPhysicalDeviceSurfaceCapabilitiesKHR, false);
LOOKUP_GIPA(GetPhysicalDeviceSurfaceFormatsKHR, false);
return NULL;
}
-void loader_override_terminating_device_proc(
- VkDevice device, struct loader_dev_dispatch_table *disp_table) {
- struct loader_device *dev;
- struct loader_icd_term *icd_term =
- loader_get_icd_and_device(device, &dev, NULL);
-
- // Certain device entry-points still need to go through a terminator before
- // hitting the ICD. This could be for several reasons, but the main one
- // is currently unwrapping an object before passing the appropriate info
- // along to the ICD.
- if ((PFN_vkVoidFunction)disp_table->core_dispatch.CreateSwapchainKHR ==
- (PFN_vkVoidFunction)icd_term->GetDeviceProcAddr(
- device, "vkCreateSwapchainKHR")) {
- disp_table->core_dispatch.CreateSwapchainKHR =
- terminator_vkCreateSwapchainKHR;
- }
-}
-
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
loader_gpa_device_internal(VkDevice device, const char *pName) {
struct loader_device *dev;
struct loader_icd_term *icd_term =
loader_get_icd_and_device(device, &dev, NULL);
- // Certain device entry-points still need to go through a terminator before
- // hitting the ICD. This could be for several reasons, but the main one
- // is currently unwrapping an object before passing the appropriate info
- // along to the ICD.
- if (!strcmp(pName, "vkCreateSwapchainKHR")) {
+ // NOTE: Device Funcs needing Trampoline/Terminator.
+ // Overrides for device functions needing a trampoline and
+ // a terminator because certain device entry-points still need to go
+ // through a terminator before hitting the ICD. This could be for
+ // several reasons, but the main one is currently unwrapping an
+ // object before passing the appropriate info along to the ICD.
+ // This is why we also have to override the direct ICD call to
+ // vkGetDeviceProcAddr to intercept those calls.
+ if (!strcmp(pName, "vkGetDeviceProcAddr")) {
+ return (PFN_vkVoidFunction)loader_gpa_device_internal;
+ } else if (!strcmp(pName, "vkCreateSwapchainKHR")) {
return (PFN_vkVoidFunction)terminator_vkCreateSwapchainKHR;
+ } else if (!strcmp(pName, "vkDebugMarkerSetObjectTagEXT")) {
+ return (PFN_vkVoidFunction)terminator_DebugMarkerSetObjectTagEXT;
+ } else if (!strcmp(pName, "vkDebugMarkerSetObjectNameEXT")) {
+ return (PFN_vkVoidFunction)terminator_DebugMarkerSetObjectNameEXT;
}
return icd_term->GetDeviceProcAddr(device, pName);
void *gdpa_value;
if (dev != NULL) {
gdpa_value = dev->loader_dispatch.core_dispatch.GetDeviceProcAddr(
- dev->device, funcName);
+ dev->chain_device, funcName);
if (gdpa_value != NULL)
dev->loader_dispatch.ext_dispatch.dev_ext[idx] =
(PFN_vkDevExt)gdpa_value;
while (ldev) {
gdpa_value =
ldev->loader_dispatch.core_dispatch.GetDeviceProcAddr(
- ldev->device, funcName);
+ ldev->chain_device, funcName);
if (gdpa_value != NULL)
ldev->loader_dispatch.ext_dispatch.dev_ext[idx] =
(PFN_vkDevExt)gdpa_value;
if (res != VK_SUCCESS) {
return res;
}
- dev->device = created_device;
+ dev->chain_device = created_device;
} else {
// Couldn't find CreateDevice function!
return VK_ERROR_INITIALIZATION_FAILED;
}
- /* Initialize device dispatch table */
+ // Initialize device dispatch table
loader_init_device_dispatch_table(&dev->loader_dispatch, nextGDPA,
- dev->device);
+ dev->chain_device);
return res;
}
PFN_vkCreateDevice fpCreateDevice = icd_term->CreateDevice;
struct loader_extension_list icd_exts;
+ dev->phys_dev_term = phys_dev_term;
+
icd_exts.list = NULL;
if (fpCreateDevice == NULL) {
}
res = fpCreateDevice(phys_dev_term->phys_dev, &localCreateInfo, pAllocator,
- &dev->device);
+ &dev->icd_device);
if (res != VK_SUCCESS) {
loader_log(icd_term->this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
"vkCreateDevice call failed in ICD %s",
goto out;
}
- *pDevice = dev->device;
+ *pDevice = dev->icd_device;
loader_add_logical_device(icd_term->this_instance, icd_term, dev);
/* Init dispatch pointer in new device object */
// per CreateDevice structure
struct loader_device {
struct loader_dev_dispatch_table loader_dispatch;
- VkDevice device; // device object from the icd
+ VkDevice chain_device; // device object from the dispatch chain
+ VkDevice icd_device; // device object from the icd
+ struct loader_physical_device_term *phys_dev_term;
struct loader_layer_list activated_layer_list;
PFN_vkCreateDebugReportCallbackEXT CreateDebugReportCallbackEXT;
PFN_vkDestroyDebugReportCallbackEXT DestroyDebugReportCallbackEXT;
PFN_vkDebugReportMessageEXT DebugReportMessageEXT;
+ PFN_vkDebugMarkerSetObjectTagEXT DebugMarkerSetObjectTagEXT;
+ PFN_vkDebugMarkerSetObjectNameEXT DebugMarkerSetObjectNameEXT;
PFN_vkGetPhysicalDeviceSurfaceSupportKHR GetPhysicalDeviceSurfaceSupportKHR;
PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR
GetPhysicalDeviceSurfaceCapabilitiesKHR;
struct loader_device *dev);
void *loader_dev_ext_gpa(struct loader_instance *inst, const char *funcName);
void *loader_get_dev_ext_trampoline(uint32_t index);
-void loader_override_terminating_device_proc(
- VkDevice device, struct loader_dev_dispatch_table *disp_table);
+void loader_override_terminating_device_proc(struct loader_device *dev);
struct loader_instance *loader_get_instance(const VkInstance instance);
void loader_deactivate_layers(const struct loader_instance *instance,
struct loader_device *device,
static VkResult vkDevExtError(VkDevice dev) {
struct loader_device *found_dev;
+ // The device going in is a trampoline device
struct loader_icd_term *icd_term =
loader_get_icd_and_device(dev, &found_dev, NULL);
if (!strcmp(name, "CmdExecuteCommands"))
return (void *)table->CmdExecuteCommands;
- if (!strcmp(name, "CreateSwapchainKHR")) {
- // For CreateSwapChainKHR we need to use trampoline and terminator
- // functions to properly unwrap the SurfaceKHR object.
- return (void *)vkCreateSwapchainKHR;
- }
if (!strcmp(name, "DestroySwapchainKHR"))
return (void *)table->DestroySwapchainKHR;
if (!strcmp(name, "GetSwapchainImagesKHR"))
if (!strcmp(name, "QueuePresentKHR"))
return (void *)table->QueuePresentKHR;
+ // NOTE: Device Funcs needing Trampoline/Terminator.
+ // Overrides for device functions needing a trampoline and
+ // a terminator because certain device entry-points still need to go
+ // through a terminator before hitting the ICD. This could be for
+ // several reasons, but the main one is currently unwrapping an
+ // object before passing the appropriate info along to the ICD.
+ if (!strcmp(name, "CreateSwapchainKHR")) {
+ return (void *)vkCreateSwapchainKHR;
+ } else if (!strcmp(name, "DebugMarkerSetObjectTagEXT")) {
+ return (void *)vkDebugMarkerSetObjectTagEXT;
+ } else if (!strcmp(name, "DebugMarkerSetObjectNameEXT")) {
+ return (void *)vkDebugMarkerSetObjectNameEXT;
+ }
+
return NULL;
}
goto out;
}
- *pDevice = dev->device;
+ *pDevice = dev->chain_device;
// Initialize any device extension dispatch entry's from the instance list
loader_init_dispatch_dev_ext(inst, dev);
&dev->loader_dispatch,
dev->loader_dispatch.core_dispatch.GetDeviceProcAddr, *pDevice);
- // The loader needs to override some terminating device procs. Usually,
- // these are device procs which need to go through a loader terminator.
- // This needs to occur if the loader needs to perform some work prior
- // to passing the work along to the ICD.
- loader_override_terminating_device_proc(*pDevice, &dev->loader_dispatch);
-
out:
// Failure cleanup
disp = loader_get_dispatch(device);
disp->DestroyDevice(device, pAllocator);
- dev->device = NULL;
+ dev->chain_device = NULL;
loader_remove_logical_device(inst, icd_term, dev, pAllocator);
+ dev->icd_device = NULL;
loader_platform_thread_unlock_mutex(&loader_lock);
}