// Call down the call chain:
result = my_data->instance_dispatch_table->CreateAndroidSurfaceKHR(
instance, pCreateInfo, pAllocator, pSurface);
+
+ if ((result == VK_SUCCESS) && pInstance && pSurface) {
+ // Record the VkSurfaceKHR returned by the ICD:
+ my_data->surfaceMap[*pSurface].surface = *pSurface;
+ my_data->surfaceMap[*pSurface].pInstance = pInstance;
+ // Point to the associated SwpInstance:
+ pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface];
+ }
+
return result;
}
return VK_ERROR_VALIDATION_FAILED_EXT;
// Call down the call chain:
result = my_data->instance_dispatch_table->CreateMirSurfaceKHR(
instance, pCreateInfo, pAllocator, pSurface);
+
+ if ((result == VK_SUCCESS) && pInstance && pSurface) {
+ // Record the VkSurfaceKHR returned by the ICD:
+ my_data->surfaceMap[*pSurface].surface = *pSurface;
+ my_data->surfaceMap[*pSurface].pInstance = pInstance;
+ // Point to the associated SwpInstance:
+ pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface];
+ }
+
return result;
}
return VK_ERROR_VALIDATION_FAILED_EXT;
// Call down the call chain:
result = my_data->instance_dispatch_table->CreateWaylandSurfaceKHR(
instance, pCreateInfo, pAllocator, pSurface);
+
+ if ((result == VK_SUCCESS) && pInstance && pSurface) {
+ // Record the VkSurfaceKHR returned by the ICD:
+ my_data->surfaceMap[*pSurface].surface = *pSurface;
+ my_data->surfaceMap[*pSurface].pInstance = pInstance;
+ // Point to the associated SwpInstance:
+ pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface];
+ }
+
return result;
}
return VK_ERROR_VALIDATION_FAILED_EXT;
// Call down the call chain:
result = my_data->instance_dispatch_table->CreateWin32SurfaceKHR(
instance, pCreateInfo, pAllocator, pSurface);
+
+ if ((result == VK_SUCCESS) && pInstance && pSurface) {
+ // Record the VkSurfaceKHR returned by the ICD:
+ my_data->surfaceMap[*pSurface].surface = *pSurface;
+ my_data->surfaceMap[*pSurface].pInstance = pInstance;
+ // Point to the associated SwpInstance:
+ pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface];
+ }
+
return result;
}
return VK_ERROR_VALIDATION_FAILED_EXT;
// Call down the call chain:
result = my_data->instance_dispatch_table->CreateXcbSurfaceKHR(
instance, pCreateInfo, pAllocator, pSurface);
+
+ if ((result == VK_SUCCESS) && pInstance && pSurface) {
+ // Record the VkSurfaceKHR returned by the ICD:
+ my_data->surfaceMap[*pSurface].surface = *pSurface;
+ my_data->surfaceMap[*pSurface].pInstance = pInstance;
+ // Point to the associated SwpInstance:
+ pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface];
+ }
+
return result;
}
return VK_ERROR_VALIDATION_FAILED_EXT;
// Call down the call chain:
result = my_data->instance_dispatch_table->CreateXlibSurfaceKHR(
instance, pCreateInfo, pAllocator, pSurface);
+
+ if ((result == VK_SUCCESS) && pInstance && pSurface) {
+ // Record the VkSurfaceKHR returned by the ICD:
+ my_data->surfaceMap[*pSurface].surface = *pSurface;
+ my_data->surfaceMap[*pSurface].pInstance = pInstance;
+ // Point to the associated SwpInstance:
+ pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface];
+ }
+
return result;
}
return VK_ERROR_VALIDATION_FAILED_EXT;
{
VkBool32 skipCall = VK_FALSE;
layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
+ SwpInstance *pInstance = &(my_data->instanceMap[instance]);
+ SwpSurface *pSurface = &my_data->surfaceMap[surface];
+
+ // Regardless of skipCall value, do some internal cleanup:
+ if (pSurface) {
+ // Delete the SwpSurface associated with this surface:
+ if (pSurface->pInstance) {
+ pSurface->pInstance->surfaces.erase(surface);
+ }
+ if (!pSurface->swapchains.empty()) {
+ LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, instance, "VkInstance",
+ SWAPCHAIN_DEL_OBJECT_BEFORE_SWAPCHAINS,
+ "%s() called before all of its associated "
+ "VkSwapchainKHRs were destroyed.",
+ __FUNCTION__);
+ // Empty and then delete all SwpSwapchain's
+ for (auto it = pSurface->swapchains.begin() ;
+ it != pSurface->swapchains.end() ; it++) {
+ // Delete all SwpImage's
+ it->second->images.clear();
+ }
+ pSurface->swapchains.clear();
+ }
+ my_data->surfaceMap.erase(surface);
+ }
if (VK_FALSE == skipCall) {
// Call down the call chain:
my_data->instance_dispatch_table->DestroySurfaceKHR(
instance, surface, pAllocator);
}
-
- // No need to do any cleanup--rely on object_tracker to track VkSurfaceKHR
}
VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDevices(VkInstance instance, uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices)
}
if (!pDevice->swapchains.empty()) {
LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
- SWAPCHAIN_DEL_DEVICE_BEFORE_SWAPCHAINS,
+ SWAPCHAIN_DEL_OBJECT_BEFORE_SWAPCHAINS,
"%s() called before all of its associated "
"VkSwapchainKHRs were destroyed.",
__FUNCTION__);
"than the VkSwapchainKHR was created with.",
__FUNCTION__);
}
- if (pCreateInfo->surface != pOldSwapchain->surface) {
+ if (pCreateInfo->surface != pOldSwapchain->pSurface->surface) {
skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
device, "VkDevice",
SWAPCHAIN_CREATE_SWAP_DIFF_SURFACE,
pDevice->swapchains[*pSwapchain] =
&my_data->swapchainMap[*pSwapchain];
my_data->swapchainMap[*pSwapchain].pDevice = pDevice;
- my_data->swapchainMap[*pSwapchain].surface =
- (pCreateInfo) ? pCreateInfo->surface : 0;
my_data->swapchainMap[*pSwapchain].imageCount = 0;
+ // Store a pointer to the surface
+ SwpPhysicalDevice *pPhysicalDevice = pDevice->pPhysicalDevice;
+ SwpInstance *pInstance =
+ (pPhysicalDevice) ? pPhysicalDevice->pInstance : NULL;
+ layer_data *my_instance_data =
+ ((pInstance) ?
+ get_my_data_ptr(get_dispatch_key(pInstance->instance), layer_data_map) :
+ NULL);
+ SwpSurface *pSurface =
+ ((my_data && pCreateInfo) ?
+ &my_instance_data->surfaceMap[pCreateInfo->surface] : NULL);
+ my_data->swapchainMap[*pSwapchain].pSurface = pSurface;
+ if (pSurface) {
+ pSurface->swapchains[*pSwapchain] =
+ &my_data->swapchainMap[*pSwapchain];
+ }
}
return result;
SWAPCHAIN_INVALID_HANDLE, // Handle used that isn't currently valid
SWAPCHAIN_NULL_POINTER, // Pointer set to NULL, instead of being a valid pointer
SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, // Did not enable WSI extension, but called WSI function
- SWAPCHAIN_DEL_DEVICE_BEFORE_SWAPCHAINS, // Called vkDestroyDevice() before vkDestroySwapchainKHR()
+ SWAPCHAIN_DEL_OBJECT_BEFORE_SWAPCHAINS, // Called vkDestroyDevice() before vkDestroySwapchainKHR()
SWAPCHAIN_CREATE_UNSUPPORTED_SURFACE, // Called vkCreateSwapchainKHR() with a pCreateInfo->surface that wasn't seen as supported by vkGetPhysicalDeviceSurfaceSupportKHR for the device
SWAPCHAIN_CREATE_SWAP_WITHOUT_QUERY, // Called vkCreateSwapchainKHR() without calling a query (e.g. vkGetPhysicalDeviceSurfaceCapabilitiesKHR())
SWAPCHAIN_CREATE_SWAP_BAD_MIN_IMG_COUNT, // Called vkCreateSwapchainKHR() with out-of-bounds minImageCount
// Forward declarations:
struct _SwpInstance;
+struct _SwpSurface;
struct _SwpPhysicalDevice;
struct _SwpDevice;
struct _SwpSwapchain;
struct _SwpImage;
typedef _SwpInstance SwpInstance;
+typedef _SwpSurface SwpSurface;;
typedef _SwpPhysicalDevice SwpPhysicalDevice;
typedef _SwpDevice SwpDevice;
typedef _SwpSwapchain SwpSwapchain;
// The actual handle for this VkInstance:
VkInstance instance;
+ // Remember the VkSurfaceKHR's that are created for this VkInstance:
+ unordered_map<const void*, SwpSurface*> surfaces;
+
// When vkEnumeratePhysicalDevices is called, the VkPhysicalDevice's are
// remembered:
unordered_map<const void*, SwpPhysicalDevice*> physicalDevices;
bool xlibSurfaceExtensionEnabled;
#endif // VK_USE_PLATFORM_XLIB_KHR
};
+
+// Create one of these for each VkSurfaceKHR:
+struct _SwpSurface {
+ // The actual handle for this VkSurfaceKHR:
+ VkSurfaceKHR surface;
+
+ // VkInstance that this VkSurfaceKHR is associated with:
+ SwpInstance *pInstance;
+
+ // When vkCreateSwapchainKHR is called, the VkSwapchainKHR's are
+ // remembered:
+ unordered_map<VkSwapchainKHR, SwpSwapchain*> swapchains;
+};
// Create one of these for each VkPhysicalDevice within a VkInstance:
struct _SwpPhysicalDevice {
SwpDevice *pDevice;
// Corresponding VkSurfaceKHR to this VkSwapchainKHR:
- VkSurfaceKHR surface;
+ SwpSurface *pSurface;
// When vkGetSwapchainImagesKHR is called, the VkImage's are
// remembered:
// NOTE: The following are for keeping track of info that is used for
// validating the WSI extensions.
std::unordered_map<void *, SwpInstance> instanceMap;
+ std::unordered_map<void *, SwpSurface> surfaceMap;
std::unordered_map<void *, SwpPhysicalDevice> physicalDeviceMap;
std::unordered_map<void *, SwpDevice> deviceMap;
std::unordered_map<VkSwapchainKHR, SwpSwapchain> swapchainMap;