}
#endif // VK_USE_PLATFORM_ANDROID_KHR
+VKAPI_ATTR VkResult VKAPI_CALL CreateSharedSwapchainsKHR(VkDevice device, uint32_t swapchainCount,
+ const VkSwapchainCreateInfoKHR *pCreateInfos,
+ const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchains) {
+ bool skip_call = false;
+ uint32_t i = 0;
+ {
+ std::lock_guard<std::mutex> lock(global_lock);
+ skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+ if (NULL != pCreateInfos) {
+ for (i = 0; i < swapchainCount; i++) {
+ skip_call |= ValidateNonDispatchableObject(device, pCreateInfos[i].oldSwapchain,
+ VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, true);
+ layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+ skip_call |= ValidateNonDispatchableObject(device_data->physical_device, pCreateInfos[i].surface,
+ VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT, false);
+ }
+ }
+ }
+ if (skip_call) {
+ return VK_ERROR_VALIDATION_FAILED_EXT;
+ }
+ VkResult result =
+ get_dispatch_table(ot_device_table_map, device)->CreateSharedSwapchainsKHR(device, swapchainCount, pCreateInfos, pAllocator, pSwapchains);
+ {
+ std::lock_guard<std::mutex> lock(global_lock);
+ if (result == VK_SUCCESS) {
+ for (i = 0; i < swapchainCount; i++) {
+ CreateNonDispatchableObject(device, pSwapchains[i], VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT);
+ }
+ }
+ }
+ return result;
+}
+
VKAPI_ATTR VkResult VKAPI_CALL CreateDebugReportCallbackEXT(VkInstance instance,
const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
static void CheckDeviceRegisterExtensions(const VkDeviceCreateInfo *pCreateInfo, VkDevice device) {
layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
device_data->wsi_enabled = false;
+ device_data->wsi_display_swapchain_enabled = false;
+ device_data->objtrack_extensions_enabled = false;
for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SWAPCHAIN_EXTENSION_NAME) == 0) {
device_data->wsi_enabled = true;
}
+ if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_DISPLAY_SWAPCHAIN_EXTENSION_NAME) == 0) {
+ device_data->wsi_display_swapchain_enabled = true;
+ }
if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], "OBJTRACK_EXTENSIONS") == 0) {
device_data->objtrack_extensions_enabled = true;
}
static inline PFN_vkVoidFunction InterceptWsiEnabledCommand(const char *name, VkDevice device) {
if (device) {
layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
- if (!device_data->wsi_enabled)
- return nullptr;
- }
- if (!strcmp("vkCreateSwapchainKHR", name))
- return reinterpret_cast<PFN_vkVoidFunction>(CreateSwapchainKHR);
- if (!strcmp("vkDestroySwapchainKHR", name))
- return reinterpret_cast<PFN_vkVoidFunction>(DestroySwapchainKHR);
- if (!strcmp("vkGetSwapchainImagesKHR", name))
- return reinterpret_cast<PFN_vkVoidFunction>(GetSwapchainImagesKHR);
- if (!strcmp("vkAcquireNextImageKHR", name))
- return reinterpret_cast<PFN_vkVoidFunction>(AcquireNextImageKHR);
- if (!strcmp("vkQueuePresentKHR", name))
- return reinterpret_cast<PFN_vkVoidFunction>(QueuePresentKHR);
+
+ if (device_data->wsi_enabled) {
+ if (!strcmp("vkCreateSwapchainKHR", name))
+ return reinterpret_cast<PFN_vkVoidFunction>(CreateSwapchainKHR);
+ if (!strcmp("vkDestroySwapchainKHR", name))
+ return reinterpret_cast<PFN_vkVoidFunction>(DestroySwapchainKHR);
+ if (!strcmp("vkGetSwapchainImagesKHR", name))
+ return reinterpret_cast<PFN_vkVoidFunction>(GetSwapchainImagesKHR);
+ if (!strcmp("vkAcquireNextImageKHR", name))
+ return reinterpret_cast<PFN_vkVoidFunction>(AcquireNextImageKHR);
+ if (!strcmp("vkQueuePresentKHR", name))
+ return reinterpret_cast<PFN_vkVoidFunction>(QueuePresentKHR);
+ }
+
+ if (device_data->wsi_display_swapchain_enabled) {
+ if (!strcmp("vkCreateSharedSwapchainsKHR", name)) {
+ return reinterpret_cast<PFN_vkVoidFunction>(CreateSharedSwapchainsKHR);
+ }
+ }
+ }
return nullptr;
}
debug_report_data *report_data;
std::vector<VkDebugReportCallbackEXT> logging_callback;
bool wsi_enabled;
+ bool wsi_display_swapchain_enabled;
bool objtrack_extensions_enabled;
// The following are for keeping track of the temporary callbacks that can
// Default constructor
layer_data()
: instance(nullptr), physical_device(nullptr), num_objects{}, num_total_objects(0), report_data(nullptr),
- wsi_enabled(false), objtrack_extensions_enabled(false), num_tmp_callbacks(0), tmp_dbg_create_infos(nullptr),
- tmp_callbacks(nullptr), object_map{} {
+ wsi_enabled(false), wsi_display_swapchain_enabled(false), objtrack_extensions_enabled(false), num_tmp_callbacks(0),
+ tmp_dbg_create_infos(nullptr), tmp_callbacks(nullptr), object_map{} {
object_map.resize(VK_DEBUG_REPORT_OBJECT_TYPE_RANGE_SIZE_EXT + 1);
}
};
VkPhysicalDevice physical_device;
bool wsi_enabled;
+ bool wsi_display_swapchain_enabled;
layer_data()
: report_data(nullptr), num_tmp_callbacks(0), tmp_dbg_create_infos(nullptr), tmp_callbacks(nullptr), device_limits{},
- physical_device_features{}, physical_device{}, wsi_enabled(false){};
+ physical_device_features{}, physical_device{}, wsi_enabled(false), wsi_display_swapchain_enabled(false) {};
};
static std::unordered_map<void *, struct instance_extension_enables> instance_extension_map;
static void CheckDeviceRegisterExtensions(const VkDeviceCreateInfo *pCreateInfo, VkDevice device) {
layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
device_data->wsi_enabled = false;
+ device_data->wsi_display_swapchain_enabled = false;
for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SWAPCHAIN_EXTENSION_NAME) == 0) {
device_data->wsi_enabled = true;
}
+ if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_DISPLAY_SWAPCHAIN_EXTENSION_NAME) == 0) {
+ device_data->wsi_display_swapchain_enabled = true;
+ }
}
}
}
#endif // VK_USE_PLATFORM_ANDROID_KHR
+VKAPI_ATTR VkResult VKAPI_CALL CreateSharedSwapchainsKHR(VkDevice device, uint32_t swapchainCount,
+ const VkSwapchainCreateInfoKHR *pCreateInfos,
+ const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchains) {
+ VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
+ bool skip_call = false;
+ layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+ assert(my_data != NULL);
+
+ skip_call |= parameter_validation_vkCreateSharedSwapchainsKHR(my_data->report_data, swapchainCount, pCreateInfos, pAllocator,
+ pSwapchains);
+
+ if (!skip_call) {
+ result = get_dispatch_table(pc_device_table_map, device)
+ ->CreateSharedSwapchainsKHR(device, swapchainCount, pCreateInfos, pAllocator, pSwapchains);
+
+ validate_result(my_data->report_data, "vkCreateSharedSwapchainsKHR", result);
+ }
+
+ return result;
+}
+
static PFN_vkVoidFunction intercept_core_instance_command(const char *name);
static PFN_vkVoidFunction intercept_core_device_command(const char *name);
if (device) {
layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
- if (!device_data->wsi_enabled)
- return nullptr;
- }
- for (size_t i = 0; i < ARRAY_SIZE(wsi_device_commands); i++) {
- if (!strcmp(wsi_device_commands[i].name, name))
- return wsi_device_commands[i].proc;
+ if (device_data->wsi_enabled) {
+ for (size_t i = 0; i < ARRAY_SIZE(wsi_device_commands); i++) {
+ if (!strcmp(wsi_device_commands[i].name, name))
+ return wsi_device_commands[i].proc;
+ }
+ }
+
+ if (device_data->wsi_display_swapchain_enabled) {
+ if (!strcmp("vkCreateSharedSwapchainsKHR", name)) {
+ return reinterpret_cast<PFN_vkVoidFunction>(CreateSharedSwapchainsKHR);
+ }
+ }
}
return nullptr;
}
}
+ wsi_create_device(dev, pCreateInfo);
extensions_create_device(dev, pCreateInfo);
// TODO: Why does fpCreateDevice behave differently than
union loader_device_extension_enables {
struct {
+ uint8_t khr_display_swapchain : 1;
uint8_t ext_debug_marker : 1;
uint8_t amd_draw_indirect_count : 1;
uint8_t nv_external_memory_win32 : 1;
}
}
+void wsi_create_device(struct loader_device *dev,
+ const VkDeviceCreateInfo *pCreateInfo) {
+ dev->loader_dispatch.enabled_known_extensions.khr_display_swapchain = 0;
+
+ for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
+ if (strcmp(pCreateInfo->ppEnabledExtensionNames[i],
+ VK_KHR_DISPLAY_SWAPCHAIN_EXTENSION_NAME) == 0) {
+ dev->loader_dispatch.enabled_known_extensions
+ .khr_display_swapchain = 1;
+ return;
+ }
+ }
+}
+
// Linux WSI surface extensions are not always compiled into the loader. (Assume
// for Windows the KHR_win32_surface is always compiled into loader). A given
// Linux build environment might not have the headers required for building one
const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain) {
const VkLayerDispatchTable *disp;
disp = loader_get_dispatch(device);
- VkResult res =
- disp->CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
- return res;
+ return disp->CreateSwapchainKHR(device, pCreateInfo, pAllocator,
+ pSwapchain);
}
// This is the trampoline entrypoint for DestroySwapchainKHR
VkImage *pSwapchainImages) {
const VkLayerDispatchTable *disp;
disp = loader_get_dispatch(device);
- VkResult res = disp->GetSwapchainImagesKHR(
+ return disp->GetSwapchainImagesKHR(
device, swapchain, pSwapchainImageCount, pSwapchainImages);
- return res;
}
// This is the trampoline entrypoint for AcquireNextImageKHR
uint32_t *pImageIndex) {
const VkLayerDispatchTable *disp;
disp = loader_get_dispatch(device);
- VkResult res = disp->AcquireNextImageKHR(device, swapchain, timeout,
- semaphore, fence, pImageIndex);
- return res;
+ return disp->AcquireNextImageKHR(device, swapchain, timeout,
+ semaphore, fence, pImageIndex);
}
// This is the trampoline entrypoint for QueuePresentKHR
vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo) {
const VkLayerDispatchTable *disp;
disp = loader_get_dispatch(queue);
- VkResult res = disp->QueuePresentKHR(queue, pPresentInfo);
- return res;
+ return disp->QueuePresentKHR(queue, pPresentInfo);
}
#ifdef VK_USE_PLATFORM_WIN32_KHR
VkDevice device, uint32_t swapchainCount,
const VkSwapchainCreateInfoKHR *pCreateInfos,
const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchains) {
- const VkLayerDispatchTable *disp;
- disp = loader_get_dispatch(device);
- return disp->CreateSharedSwapchainsKHR(
- device, swapchainCount, pCreateInfos, pAllocator, pSwapchains);
+ struct loader_dev_dispatch_table *disp = loader_get_dev_dispatch(device);
+ if (0 == disp->enabled_known_extensions.khr_display_swapchain ||
+ NULL == disp->core_dispatch.CreateSharedSwapchainsKHR) {
+ return VK_ERROR_EXTENSION_NOT_PRESENT;
+ } else {
+ return disp->core_dispatch.CreateSharedSwapchainsKHR(
+ device, swapchainCount, pCreateInfos, pAllocator, pSwapchains);
+ }
}
bool wsi_swapchain_instance_gpa(struct loader_instance *ptr_instance,
void wsi_create_instance(struct loader_instance *ptr_instance,
const VkInstanceCreateInfo *pCreateInfo);
+void wsi_create_device(struct loader_device *dev,
+ const VkDeviceCreateInfo *pCreateInfo);
bool wsi_unsupported_instance_extension(const VkExtensionProperties *ext_prop);
VKAPI_ATTR void VKAPI_CALL