diff options
| author | Mark Young <marky@lunarg.com> | 2016-09-08 12:28:38 -0600 |
|---|---|---|
| committer | Mark Young <marky@lunarg.com> | 2016-09-08 15:10:40 -0600 |
| commit | 73bffc29ff1ad005d4125713014c826fca52739f (patch) | |
| tree | 6fecfa552bf879cf60deadf929b69d7d6ce1e3aa | |
| parent | db4d533441e56f95e27cae5e5f9ae6260c8ae4b8 (diff) | |
| download | usermoji-73bffc29ff1ad005d4125713014c826fca52739f.tar.xz | |
loader: Add checks for usage of wsi extensions
The loader really should validate that the WSI extensions are
enabled before being called. Additionally, I needed to add
more checks for the KHR_display_swapchain extension in the
parameter_validation and object_tracker layers.
Change-Id: I3d07d46baf551be6f5f07e5374d6c683e3f52e7e
| -rw-r--r-- | layers/object_tracker.cpp | 72 | ||||
| -rw-r--r-- | layers/object_tracker.h | 5 | ||||
| -rw-r--r-- | layers/parameter_validation.cpp | 46 | ||||
| -rw-r--r-- | loader/loader.c | 1 | ||||
| -rw-r--r-- | loader/loader.h | 1 | ||||
| -rw-r--r-- | loader/wsi.c | 42 | ||||
| -rw-r--r-- | loader/wsi.h | 2 |
7 files changed, 133 insertions, 36 deletions
diff --git a/layers/object_tracker.cpp b/layers/object_tracker.cpp index e3d49b5e..3c906aca 100644 --- a/layers/object_tracker.cpp +++ b/layers/object_tracker.cpp @@ -2940,6 +2940,40 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateAndroidSurfaceKHR(VkInstance instance, cons } #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, @@ -3066,11 +3100,16 @@ static inline PFN_vkVoidFunction InterceptWsiEnabledCommand(const char *name, Vk 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; } @@ -3885,19 +3924,26 @@ static inline PFN_vkVoidFunction InterceptCoreInstanceCommand(const char *name) 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; } diff --git a/layers/object_tracker.h b/layers/object_tracker.h index 8f514a6d..c4088a99 100644 --- a/layers/object_tracker.h +++ b/layers/object_tracker.h @@ -92,6 +92,7 @@ struct layer_data { 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 @@ -112,8 +113,8 @@ struct layer_data { // 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); } }; diff --git a/layers/parameter_validation.cpp b/layers/parameter_validation.cpp index bf452851..2bc8d386 100644 --- a/layers/parameter_validation.cpp +++ b/layers/parameter_validation.cpp @@ -73,10 +73,11 @@ struct layer_data { 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; @@ -1633,11 +1634,15 @@ static void CheckInstanceRegisterExtensions(const VkInstanceCreateInfo *pCreateI 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; + } } } @@ -5051,6 +5056,27 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateAndroidSurfaceKHR(VkInstance instance, cons } #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); @@ -5285,13 +5311,19 @@ static PFN_vkVoidFunction InterceptWsiEnabledCommand(const char *name, VkDevice 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; diff --git a/loader/loader.c b/loader/loader.c index ac8f4fc3..5a347db4 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -4324,6 +4324,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDevice( } } + wsi_create_device(dev, pCreateInfo); extensions_create_device(dev, pCreateInfo); // TODO: Why does fpCreateDevice behave differently than diff --git a/loader/loader.h b/loader/loader.h index 9b57372d..651d5076 100644 --- a/loader/loader.h +++ b/loader/loader.h @@ -160,6 +160,7 @@ struct loader_dev_ext_dispatch_table { 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; diff --git a/loader/wsi.c b/loader/wsi.c index 10c5260e..13d30047 100644 --- a/loader/wsi.c +++ b/loader/wsi.c @@ -158,6 +158,20 @@ void wsi_create_instance(struct loader_instance *ptr_instance, } } +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 @@ -403,9 +417,8 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateSwapchainKHR( 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 @@ -424,9 +437,8 @@ vkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, 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 @@ -436,9 +448,8 @@ vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, 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 @@ -446,8 +457,7 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL 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 @@ -1268,10 +1278,14 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateSharedSwapchainsKHR( 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, diff --git a/loader/wsi.h b/loader/wsi.h index fa600888..7409e7d7 100644 --- a/loader/wsi.h +++ b/loader/wsi.h @@ -27,6 +27,8 @@ 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 |
