aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Elliott <ianelliott@google.com>2016-01-20 16:33:34 -0700
committerJon Ashburn <jon@lunarg.com>2016-01-28 11:18:56 -0700
commit46b88bca67b586be0459fd01f38b50ed70746f0d (patch)
tree0554fffc0290ebb4c66ba98a8a9d309118ac87b7
parentf7d4210cf40e59fad6a1f1dad6a55aac6a546958 (diff)
downloadusermoji-46b88bca67b586be0459fd01f38b50ed70746f0d.tar.xz
Swapchain: Keep/check relationships between surfaces and swapchains.
-rw-r--r--layers/swapchain.cpp103
-rw-r--r--layers/swapchain.h23
-rw-r--r--layers/vk_validation_layer_details.md2
3 files changed, 119 insertions, 9 deletions
diff --git a/layers/swapchain.cpp b/layers/swapchain.cpp
index 4690e7fc..23388366 100644
--- a/layers/swapchain.cpp
+++ b/layers/swapchain.cpp
@@ -435,6 +435,15 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateAndroidSurfaceKHR(
// 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;
@@ -485,6 +494,15 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateMirSurfaceKHR(
// 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;
@@ -572,6 +590,15 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateWaylandSurfaceKHR(
// 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;
@@ -659,6 +686,15 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateWin32SurfaceKHR(
// 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;
@@ -745,6 +781,15 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateXcbSurfaceKHR(
// 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;
@@ -833,6 +878,15 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateXlibSurfaceKHR(
// 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;
@@ -881,14 +935,37 @@ VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR(VkInstance insta
{
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)
@@ -983,7 +1060,7 @@ VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyDevice(VkDevice device, cons
}
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__);
@@ -1605,7 +1682,7 @@ static VkBool32 validateCreateSwapchainKHR(
"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,
@@ -1649,9 +1726,23 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateSwapchainKHR(
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;
diff --git a/layers/swapchain.h b/layers/swapchain.h
index ba80a0e3..d60f9568 100644
--- a/layers/swapchain.h
+++ b/layers/swapchain.h
@@ -63,7 +63,7 @@ typedef enum _SWAPCHAIN_ERROR
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
@@ -165,12 +165,14 @@ typedef enum _SWAPCHAIN_ERROR
// 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;
@@ -181,6 +183,9 @@ struct _SwpInstance {
// 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;
@@ -214,6 +219,19 @@ struct _SwpInstance {
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 {
@@ -296,7 +314,7 @@ struct _SwpSwapchain {
SwpDevice *pDevice;
// Corresponding VkSurfaceKHR to this VkSwapchainKHR:
- VkSurfaceKHR surface;
+ SwpSurface *pSurface;
// When vkGetSwapchainImagesKHR is called, the VkImage's are
// remembered:
@@ -312,6 +330,7 @@ struct layer_data {
// 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;
diff --git a/layers/vk_validation_layer_details.md b/layers/vk_validation_layer_details.md
index 43c3b646..6298693a 100644
--- a/layers/vk_validation_layer_details.md
+++ b/layers/vk_validation_layer_details.md
@@ -347,7 +347,7 @@ This layer is a work in progress. VK_LAYER_LUNARG_swapchain layer is intended to
| Valid handle | If an invalid handle is used, this error will be flagged | INVALID_HANDLE | vkCreateDevice vkCreateSwapchainKHR | NA | None |
| Valid pointer | If a NULL pointer is used, this error will be flagged | NULL_POINTER | vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfacePresentModesKHR vkCreateSwapchainKHR vkGetSwapchainImagesKHR vkAcquireNextImageKHR vkQueuePresentKHR | NA | None |
| Extension enabled before use | Validates that a WSI extension is enabled before its functions are used | EXT_NOT_ENABLED_BUT_USED | vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfacePresentModesKHR vkCreateSwapchainKHR vkDestroySwapchainKHR vkGetSwapchainImagesKHR vkAcquireNextImageKHR vkQueuePresentKHR | NA | None |
-| Swapchains destroyed before devices | Validates that vkDestroySwapchainKHR() is called for all swapchains associated with a device before vkDestroyDevice() is called | DEL_DEVICE_BEFORE_SWAPCHAINS | vkDestroyDevice | NA | None |
+| Swapchains destroyed before devices | Validates that vkDestroySwapchainKHR() is called for all swapchains associated with a device before vkDestroyDevice() is called | DEL_OBJECT_BEFORE_SWAPCHAINS | vkDestroyDevice vkDestroySurfaceKHR | NA | None |
| Supported surface used with a swapchain | Validates that vkGetPhysicalDeviceSurfaceSupportKHR() was seen to support the surface used with a swapchain | CREATE_SWAP_UNSUPPORTED_SURFACE | vkCreateSwapchainKHR | NA | None |
| Queries occur before swapchain creation | Validates that vkGetPhysicalDeviceSurfaceCapabilitiesKHR(), vkGetPhysicalDeviceSurfaceFormatsKHR() and vkGetPhysicalDeviceSurfacePresentModesKHR() are called before vkCreateSwapchainKHR() | CREATE_SWAP_WITHOUT_QUERY | vkCreateSwapchainKHR | NA | None |
| vkCreateSwapchainKHR(pCreateInfo->minImageCount) | Validates vkCreateSwapchainKHR(pCreateInfo->minImageCount) | CREATE_SWAP_BAD_MIN_IMG_COUNT | vkCreateSwapchainKHR | NA | None |