WSI Validation: Add error enum and document Swapchain layer.
authorIan Elliott <ian@lunarg.com>
Fri, 25 Sep 2015 21:50:55 +0000 (15:50 -0600)
committerIan Elliott <ian@lunarg.com>
Fri, 25 Sep 2015 21:51:31 +0000 (15:51 -0600)
layers/swapchain.cpp
layers/swapchain.h
layers/vk_validation_layer_details.md
vk_layer_documentation_generate.py

index 37864dae97fcccb5efbb213ee10ee4f854a1e42b..97fbd1457bb16f9d05bb0494b710b377d96ab7c8 100644 (file)
@@ -354,6 +354,7 @@ VK_LAYER_EXPORT void VKAPI vkDestroyDevice(VkDevice device)
         deviceMap.erase(device);
         if (!pDevice->swapchains.empty()) {
             LOG_ERROR(VK_OBJECT_TYPE_DEVICE, device, "VkDevice",
+                      SWAPCHAIN_DEL_DEVICE_BEFORE_SWAPCHAINS,
                       "%s() called before all of its associated "
                       "VkSwapchainKHRs were destroyed.",
                       __FUNCTION__);
@@ -384,6 +385,7 @@ VK_LAYER_EXPORT VkResult VKAPI vkGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDe
         skipCall |= LOG_ERROR(VK_OBJECT_TYPE_INSTANCE,
                               pPhysicalDevice->pInstance,
                               "VkInstance",
+                              SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
                               "%s() called even though the "
                               VK_EXT_KHR_SWAPCHAIN_EXTENSION_NAME,
                               "extension was not enabled for this VkInstance.",
@@ -424,6 +426,7 @@ VK_LAYER_EXPORT VkResult VKAPI vkGetSurfacePropertiesKHR(VkDevice device, const
                                             "VkDevice");
     } else if (!pDevice->deviceSwapchainExtensionEnabled) {
         skipCall |= LOG_ERROR(VK_OBJECT_TYPE_DEVICE, device, "VkDevice",
+                              SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
                               "%s() called even though the "
                               VK_EXT_KHR_DEVICE_SWAPCHAIN_EXTENSION_NAME,
                               "extension was not enabled for this VkDevice.",
@@ -459,6 +462,7 @@ VK_LAYER_EXPORT VkResult VKAPI vkGetSurfaceFormatsKHR(VkDevice device, const VkS
                                             "VkDevice");
     } else if (!pDevice->deviceSwapchainExtensionEnabled) {
         skipCall |= LOG_ERROR(VK_OBJECT_TYPE_DEVICE, device, "VkDevice",
+                              SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
                               "%s() called even though the "
                               VK_EXT_KHR_DEVICE_SWAPCHAIN_EXTENSION_NAME,
                               "extension was not enabled for this VkDevice.",
@@ -503,6 +507,7 @@ VK_LAYER_EXPORT VkResult VKAPI vkGetSurfacePresentModesKHR(VkDevice device, cons
                                             "VkDevice");
     } else if (!pDevice->deviceSwapchainExtensionEnabled) {
         skipCall |= LOG_ERROR(VK_OBJECT_TYPE_DEVICE, device, "VkDevice",
+                              SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
                               "%s() called even though the "
                               VK_EXT_KHR_DEVICE_SWAPCHAIN_EXTENSION_NAME,
                               "extension was not enabled for this VkDevice.",
@@ -549,11 +554,13 @@ static VkBool32 validateCreateSwapchainKHR(VkDevice device, const VkSwapchainCre
     SwpDevice *pDevice = &deviceMap[device];
     if (!pDevice) {
         return LOG_ERROR(VK_OBJECT_TYPE_DEVICE, device, "VkDevice",
+                         SWAPCHAIN_INVALID_HANDLE,
                          "%s() called with a non-valid %s.",
                          fn, "VkDevice");
 
     } else if (!pDevice->deviceSwapchainExtensionEnabled) {
         return LOG_ERROR(VK_OBJECT_TYPE_DEVICE, device, "VkDevice",
+                         SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
                          "%s() called even though the "
                          VK_EXT_KHR_DEVICE_SWAPCHAIN_EXTENSION_NAME,
                          "extension was not enabled for this VkDevice.",
@@ -563,6 +570,7 @@ static VkBool32 validateCreateSwapchainKHR(VkDevice device, const VkSwapchainCre
     // Validate pCreateInfo with the results for previous queries:
     if (!pDevice->gotSurfaceProperties) {
         skipCall |= LOG_ERROR(VK_OBJECT_TYPE_DEVICE, device, "VkDevice",
+                              SWAPCHAIN_CREATE_SWAP_WITHOUT_QUERY,
                               "%s() called before calling "
                               "vkGetSurfacePropertiesKHR().",
                               fn);
@@ -574,6 +582,7 @@ static VkBool32 validateCreateSwapchainKHR(VkDevice device, const VkSwapchainCre
             ((pProps->maxImageCount > 0) &&
              (pCreateInfo->minImageCount > pProps->maxImageCount))) {
             skipCall |= LOG_ERROR(VK_OBJECT_TYPE_DEVICE, device, "VkDevice",
+                                  SWAPCHAIN_CREATE_SWAP_BAD_MIN_IMG_COUNT,
                                   "%s() called with pCreateInfo->minImageCount "
                                   "= %d, which is outside the bounds returned "
                                   "by vkGetSurfacePropertiesKHR() (i.e. "
@@ -591,6 +600,7 @@ static VkBool32 validateCreateSwapchainKHR(VkDevice device, const VkSwapchainCre
              (pCreateInfo->imageExtent.height < pProps->minImageExtent.height) ||
              (pCreateInfo->imageExtent.height > pProps->maxImageExtent.height))) {
             skipCall |= LOG_ERROR(VK_OBJECT_TYPE_DEVICE, device, "VkDevice",
+                                  SWAPCHAIN_CREATE_SWAP_OUT_OF_BOUNDS_EXTENTS,
                                   "%s() called with pCreateInfo->imageExtent = "
                                   "(%d,%d), which is outside the bounds "
                                   "returned by vkGetSurfacePropertiesKHR(): "
@@ -610,6 +620,7 @@ static VkBool32 validateCreateSwapchainKHR(VkDevice device, const VkSwapchainCre
             ((pCreateInfo->imageExtent.width != pProps->currentExtent.width) ||
              (pCreateInfo->imageExtent.height != pProps->currentExtent.height))) {
             skipCall |= LOG_ERROR(VK_OBJECT_TYPE_DEVICE, device, "VkDevice",
+                                  SWAPCHAIN_CREATE_SWAP_EXTENTS_NO_MATCH_WIN,
                                   "%s() called with pCreateInfo->imageExtent = "
                                   "(%d,%d), which is not equal to the "
                                   "currentExtent = (%d,%d) returned by "
@@ -649,14 +660,16 @@ static VkBool32 validateCreateSwapchainKHR(VkDevice device, const VkSwapchainCre
             skipCall |= debug_report_log_msg(&mydata.report_data,
                                              VK_DBG_REPORT_ERROR_BIT,
                                              VK_OBJECT_TYPE_DEVICE,
-                                             (uint64_t) device,
-                                             0, 0, LAYER_NAME,
+                                             (uint64_t) device, 0, 
+                                             SWAPCHAIN_CREATE_SWAP_BAD_PRE_TRANSFORM,
+                                             LAYER_NAME,
                                              errorString.c_str());
         }
         // Validate pCreateInfo->imageArraySize against
         // VkSurfacePropertiesKHR::maxImageArraySize:
         if (pCreateInfo->imageArraySize <= pProps->maxImageArraySize) {
             skipCall |= LOG_ERROR(VK_OBJECT_TYPE_DEVICE, device, "VkDevice",
+                                  SWAPCHAIN_CREATE_SWAP_BAD_IMG_ARRAY_SIZE,
                                   "%s() called with a non-supported "
                                   "pCreateInfo->imageArraySize (i.e. %d).  "
                                   "Maximum value is %d.",
@@ -670,6 +683,7 @@ static VkBool32 validateCreateSwapchainKHR(VkDevice device, const VkSwapchainCre
             (pCreateInfo->imageUsageFlags !=
              (pCreateInfo->imageUsageFlags & pProps->supportedUsageFlags))) {
             skipCall |= LOG_ERROR(VK_OBJECT_TYPE_DEVICE, device, "VkDevice",
+                                  SWAPCHAIN_CREATE_SWAP_BAD_IMG_USAGE_FLAGS,
                                   "%s() called with a non-supported "
                                   "pCreateInfo->imageUsageFlags (i.e. 0x%08x)."
                                   "  Supported flag bits are 0x%08x.",
@@ -680,6 +694,7 @@ static VkBool32 validateCreateSwapchainKHR(VkDevice device, const VkSwapchainCre
     }
     if (!pDevice->surfaceFormatCount) {
         skipCall |= LOG_ERROR(VK_OBJECT_TYPE_DEVICE, device, "VkDevice",
+                              SWAPCHAIN_CREATE_SWAP_WITHOUT_QUERY,
                               "%s() called before calling "
                               "vkGetSurfaceFormatsKHR().",
                               fn);
@@ -709,6 +724,7 @@ static VkBool32 validateCreateSwapchainKHR(VkDevice device, const VkSwapchainCre
                 if (!foundColorSpace) {
                     skipCall |= LOG_ERROR(VK_OBJECT_TYPE_DEVICE, device,
                                           "VkDevice",
+                                          SWAPCHAIN_CREATE_SWAP_BAD_IMG_FMT_CLR_SP,
                                           "%s() called with neither a "
                                           "supported pCreateInfo->imageFormat "
                                           "(i.e. %d) nor a supported "
@@ -719,13 +735,15 @@ static VkBool32 validateCreateSwapchainKHR(VkDevice device, const VkSwapchainCre
                                           pCreateInfo->imageColorSpace);
                 } else {
                     skipCall |= LOG_ERROR(VK_OBJECT_TYPE_DEVICE, device,
-                                              "VkDevice",
+                                          "VkDevice",
+                                          SWAPCHAIN_CREATE_SWAP_BAD_IMG_FORMAT,
                                           "%s() called with a non-supported "
                                           "pCreateInfo->imageFormat (i.e. %d).",
                                           fn, pCreateInfo->imageFormat);
                 }
             } else if (!foundColorSpace) {
                 skipCall |= LOG_ERROR(VK_OBJECT_TYPE_DEVICE, device, "VkDevice",
+                                      SWAPCHAIN_CREATE_SWAP_BAD_IMG_COLOR_SPACE,
                                       "%s() called with a non-supported "
                                       "pCreateInfo->imageColorSpace (i.e. %d).",
                                       fn, pCreateInfo->imageColorSpace);
@@ -734,6 +752,7 @@ static VkBool32 validateCreateSwapchainKHR(VkDevice device, const VkSwapchainCre
     }
     if (!pDevice->presentModeCount) {
         skipCall |= LOG_ERROR(VK_OBJECT_TYPE_DEVICE, device, "VkDevice",
+                              SWAPCHAIN_CREATE_SWAP_WITHOUT_QUERY,
                               "%s() called before calling "
                               "vkGetSurfacePresentModesKHR().",
                               fn);
@@ -749,6 +768,7 @@ static VkBool32 validateCreateSwapchainKHR(VkDevice device, const VkSwapchainCre
         }
         if (!foundMatch) {
             skipCall |= LOG_ERROR(VK_OBJECT_TYPE_DEVICE, device, "VkDevice",
+                                  SWAPCHAIN_CREATE_SWAP_BAD_PRESENT_MODE,
                                   "%s() called with a non-supported "
                                   "pCreateInfo->presentMode (i.e. %s).",
                                   fn,
@@ -805,6 +825,7 @@ VK_LAYER_EXPORT VkResult VKAPI vkDestroySwapchainKHR(VkDevice device, VkSwapchai
                                             "VkDevice");
     } else if (!pDevice->deviceSwapchainExtensionEnabled) {
         skipCall |= LOG_ERROR(VK_OBJECT_TYPE_DEVICE, device, "VkDevice",
+                              SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
                               "%s() called even though the "
                               VK_EXT_KHR_DEVICE_SWAPCHAIN_EXTENSION_NAME,
                               "extension was not enabled for this VkDevice.",
@@ -819,6 +840,7 @@ VK_LAYER_EXPORT VkResult VKAPI vkDestroySwapchainKHR(VkDevice device, VkSwapchai
             pSwapchain->pDevice->swapchains.erase(swapchain.handle);
             if (device != pSwapchain->pDevice->device) {
                 LOG_ERROR(VK_OBJECT_TYPE_DEVICE, device, "VkDevice",
+                          SWAPCHAIN_DESTROY_SWAP_DIFF_DEVICE,
                           "%s() called with a different VkDevice than the "
                           "VkSwapchainKHR was created with.",
                           __FUNCTION__);
@@ -856,6 +878,7 @@ VK_LAYER_EXPORT VkResult VKAPI vkGetSwapchainImagesKHR(VkDevice device, VkSwapch
                                             "VkDevice");
     } else if (!pDevice->deviceSwapchainExtensionEnabled) {
         skipCall |= LOG_ERROR(VK_OBJECT_TYPE_DEVICE, device, "VkDevice",
+                              SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
                               "%s() called even though the "
                               VK_EXT_KHR_DEVICE_SWAPCHAIN_EXTENSION_NAME,
                               "extension was not enabled for this VkDevice.",
@@ -907,6 +930,7 @@ VK_LAYER_EXPORT VkResult VKAPI vkAcquireNextImageKHR(VkDevice device, VkSwapchai
                                             "VkDevice");
     } else if (!pDevice->deviceSwapchainExtensionEnabled) {
         skipCall |= LOG_ERROR(VK_OBJECT_TYPE_DEVICE, device, "VkDevice",
+                              SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
                               "%s() called even though the "
                               VK_EXT_KHR_DEVICE_SWAPCHAIN_EXTENSION_NAME,
                               "extension was not enabled for this VkDevice.",
@@ -931,6 +955,7 @@ VK_LAYER_EXPORT VkResult VKAPI vkAcquireNextImageKHR(VkDevice device, VkSwapchai
             skipCall |= LOG_PERF_WARNING(VK_OBJECT_TYPE_SWAPCHAIN_KHR,
                                          swapchain,
                                          "VkSwapchainKHR",
+                                         SWAPCHAIN_APP_OWNS_TOO_MANY_IMAGES,
                                          "%s() called when the application "
                                          "already owns all presentable images "
                                          "in this swapchain except for the "
@@ -955,6 +980,7 @@ VK_LAYER_EXPORT VkResult VKAPI vkAcquireNextImageKHR(VkDevice device, VkSwapchai
             if (*pImageIndex >= pSwapchain->imageCount) {
                 LOG_ERROR(VK_OBJECT_TYPE_SWAPCHAIN_KHR, swapchain,
                           "VkSwapchainKHR",
+                          SWAPCHAIN_INDEX_TOO_LARGE,
                           "%s() returned an index that's too large (i.e. %d).  "
                           "There are only %d images in this VkSwapchainKHR.",
                           __FUNCTION__, *pImageIndex, pSwapchain->imageCount);
@@ -962,6 +988,7 @@ VK_LAYER_EXPORT VkResult VKAPI vkAcquireNextImageKHR(VkDevice device, VkSwapchai
             if (pSwapchain->images[*pImageIndex].ownedByApp) {
                 LOG_ERROR(VK_OBJECT_TYPE_SWAPCHAIN_KHR, swapchain,
                           "VkSwapchainKHR",
+                          SWAPCHAIN_INDEX_ALREADY_IN_USE,
                           "%s() returned an index (i.e. %d) for an image that "
                           "is already owned by the application.\n",
                           __FUNCTION__, *pImageIndex);
@@ -994,6 +1021,7 @@ VK_LAYER_EXPORT VkResult VKAPI vkQueuePresentKHR(VkQueue queue, VkPresentInfoKHR
             if (!pSwapchain->pDevice->deviceSwapchainExtensionEnabled) {
                 skipCall |= LOG_ERROR(VK_OBJECT_TYPE_DEVICE,
                                       pSwapchain->pDevice, "VkDevice",
+                                      SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
                                       "%s() called even though the "
                                       VK_EXT_KHR_DEVICE_SWAPCHAIN_EXTENSION_NAME,
                                       "extension was not enabled for this "
@@ -1004,6 +1032,7 @@ VK_LAYER_EXPORT VkResult VKAPI vkQueuePresentKHR(VkQueue queue, VkPresentInfoKHR
                 skipCall |= LOG_ERROR(VK_OBJECT_TYPE_SWAPCHAIN_KHR,
                                       pPresentInfo->swapchains[i].handle,
                                       "VkSwapchainKHR",
+                                      SWAPCHAIN_INDEX_TOO_LARGE,
                                       "%s() called for an index that is too "
                                       "large (i.e. %d).  There are only %d "
                                       "images in this VkSwapchainKHR.\n",
@@ -1014,6 +1043,7 @@ VK_LAYER_EXPORT VkResult VKAPI vkQueuePresentKHR(VkQueue queue, VkPresentInfoKHR
                     skipCall |= LOG_ERROR(VK_OBJECT_TYPE_SWAPCHAIN_KHR,
                                           pPresentInfo->swapchains[i].handle,
                                           "VkSwapchainKHR",
+                                          SWAPCHAIN_INDEX_NOT_IN_USE,
                                           "%s() returned an index (i.e. %d) "
                                           "for an image that is not owned by "
                                           "the application.",
index e6b2a55ad2cc1afb69bcb8f6215ea45403e2cecc..286a23bf308ecacd2e32906979ded03a0700733c 100644 (file)
 
 using namespace std;
 
+
+// Swapchain ERROR codes
+typedef enum _SWAPCHAIN_ERROR
+{
+    SWAPCHAIN_INVALID_HANDLE,                   // Handle used that isn't currently valid
+    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_CREATE_SWAP_WITHOUT_QUERY,        // Called vkCreateSwapchainKHR() without calling a query (e.g. vkGetSurfacePropertiesKHR())
+    SWAPCHAIN_CREATE_SWAP_BAD_MIN_IMG_COUNT,    // Called vkCreateSwapchainKHR() with out-of-bounds minImageCount
+    SWAPCHAIN_CREATE_SWAP_OUT_OF_BOUNDS_EXTENTS,// Called vkCreateSwapchainKHR() with out-of-bounds imageExtent
+    SWAPCHAIN_CREATE_SWAP_EXTENTS_NO_MATCH_WIN, // Called vkCreateSwapchainKHR() with imageExtent that doesn't match window's extent
+    SWAPCHAIN_CREATE_SWAP_BAD_PRE_TRANSFORM,    // Called vkCreateSwapchainKHR() with a non-supported preTransform
+    SWAPCHAIN_CREATE_SWAP_BAD_IMG_ARRAY_SIZE,   // Called vkCreateSwapchainKHR() with a non-supported imageArraySize
+    SWAPCHAIN_CREATE_SWAP_BAD_IMG_USAGE_FLAGS,  // Called vkCreateSwapchainKHR() with a non-supported imageUsageFlags
+    SWAPCHAIN_CREATE_SWAP_BAD_IMG_COLOR_SPACE,  // Called vkCreateSwapchainKHR() with a non-supported imageColorSpace
+    SWAPCHAIN_CREATE_SWAP_BAD_IMG_FORMAT,       // Called vkCreateSwapchainKHR() with a non-supported imageFormat
+    SWAPCHAIN_CREATE_SWAP_BAD_IMG_FMT_CLR_SP,   // Called vkCreateSwapchainKHR() with a non-supported imageColorSpace
+    SWAPCHAIN_CREATE_SWAP_BAD_PRESENT_MODE,     // Called vkCreateSwapchainKHR() with a non-supported presentMode
+    SWAPCHAIN_DESTROY_SWAP_DIFF_DEVICE,         // Called vkDestroySwapchainKHR() with a different VkDevice than vkCreateSwapchainKHR()
+    SWAPCHAIN_APP_OWNS_TOO_MANY_IMAGES,         // vkAcquireNextImageKHR() asked for more images than are available
+    SWAPCHAIN_INDEX_TOO_LARGE,                  // Index is too large for swapchain
+    SWAPCHAIN_INDEX_ALREADY_IN_USE,             // vkAcquireNextImageKHR() returned index that is already owned by app
+    SWAPCHAIN_INDEX_NOT_IN_USE,                 // vkQueuePresentKHR() given index that is not owned by app
+} SWAPCHAIN_ERROR;
+
+
 // The following is for logging error messages:
 typedef struct _layer_data {
     debug_report_data report_data;
@@ -47,15 +73,15 @@ typedef struct _layer_data {
 #define LAYER_NAME (char *) "Swapchain"
 #define LOG_ERROR_NON_VALID_OBJ(objType, type, obj)                     \
     log_msg(&mydata.report_data, VK_DBG_REPORT_ERROR_BIT, (objType),    \
-            (uint64_t) (obj), 0, 0, LAYER_NAME,                         \
+            (uint64_t) (obj), 0, SWAPCHAIN_INVALID_HANDLE, LAYER_NAME,  \
             "%s() called with a non-valid %s.", __FUNCTION__, (obj))
 
-#define LOG_ERROR(objType, type, obj, fmt, ...)                         \
+#define LOG_ERROR(objType, type, obj, enm, fmt, ...)                    \
     log_msg(&mydata.report_data, VK_DBG_REPORT_ERROR_BIT, (objType),    \
-            (uint64_t) (obj), 0, 0, LAYER_NAME, (fmt), __VA_ARGS__)
-#define LOG_PERF_WARNING(objType, type, obj, fmt, ...)                  \
+            (uint64_t) (obj), 0, (enm), LAYER_NAME, (fmt), __VA_ARGS__)
+#define LOG_PERF_WARNING(objType, type, obj, enm, fmt, ...)             \
     log_msg(&mydata.report_data, VK_DBG_REPORT_PERF_WARN_BIT, (objType), \
-            (uint64_t) (obj), 0, 0, LAYER_NAME, (fmt), __VA_ARGS__)
+            (uint64_t) (obj), 0, (enm), LAYER_NAME, (fmt), __VA_ARGS__)
 
 
 // NOTE: The following struct's/typedef's are for keeping track of
index fa60fd28c0f3b0de3f6b5fca7265317c7a707059..1268264c32c4432f4c887641ac51315cd4618498 100644 (file)
@@ -298,6 +298,52 @@ APIDump layer is used for dumping a stream of all the Vulkan API calls that are
 
  1. vkAllocDescriptorSets does not correctly print out all of the created DescriptorSets (no array printing following main API txt)
 
+
+
+
+## Swapchain
+
+### Swapchain Overview
+
+This layer is a work in progress. DeviceLimits layer is intended to capture two broad categories of errors:
+ 1. Incorrect use of APIs to query device capabilities
+ 2. Attempt to use API functionality beyond the capability of the underlying device
+
+For the first category, the layer tracks which calls are made and flags errors if calls are excluded that should not be, or if call sequencing is incorrect. An example is an app that assumes attempts to Query and use queues without ever having called vkGetPhysicalDeviceQueueFamilyProperties(). Also, if an app is calling vkGetPhysicalDeviceQueueFamilyProperties() to retrieve properties with some assumed count for array size instead of first calling vkGetPhysicalDeviceQueueFamilyProperties() w/ a NULL pQueueFamilyProperties parameter in order to query the actual count.
+For the second category of errors, DeviceLimits stores its own internal record of underlying device capabilities and flags errors if requests are made beyond those limits. Most (all?) of the limits are queried via vkGetPhysicalDevice* calls.
+
+### Swapchain Details Table
+
+| Check | Overview | ENUM SWAPCHAIN_* | Relevant API | Testname | Notes/TODO |
+| ----- | -------- | ---------------- | ------------ | -------- | ---------- |
+| Valid handle | If an invalid handle is used, this error will be flagged | INVALID_HANDLE | vkDestroyInstance vkEnumeratePhysicalDevices vkCreateDevice vkDestroyDevice vkGetPhysicalDeviceSurfaceSupportKHR vkGetSurfacePropertiesKHR vkGetSurfaceFormatsKHR vkGetSurfacePresentModesKHR vkCreateSwapchainKHR vkDestroySwapchainKHR 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 vkGetSurfacePropertiesKHR vkGetSurfaceFormatsKHR vkGetSurfacePresentModesKHR 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 |
+| Queries occur before swapchain creation | Validates that vkGetSurfacePropertiesKHR(), vkGetSurfaceFormatsKHR() and vkGetSurfacePresentModesKHR() 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 |
+| vkCreateSwapchainKHR(pCreateInfo->imageExtent) | Validates vkCreateSwapchainKHR(pCreateInfo->imageExtent) when window has no fixed size | CREATE_SWAP_OUT_OF_BOUNDS_EXTENTS | vkCreateSwapchainKHR | NA | None |
+| vkCreateSwapchainKHR(pCreateInfo->imageExtent) | Validates vkCreateSwapchainKHR(pCreateInfo->imageExtent) when window has a fixed size | CREATE_SWAP_EXTENTS_NO_MATCH_WIN | vkCreateSwapchainKHR | NA | None |
+| vkCreateSwapchainKHR(pCreateInfo->preTransform) | Validates vkCreateSwapchainKHR(pCreateInfo->preTransform) | CREATE_SWAP_BAD_PRE_TRANSFORM | vkCreateSwapchainKHR | NA | None |
+| vkCreateSwapchainKHR(pCreateInfo->imageArraySize) | Validates vkCreateSwapchainKHR(pCreateInfo->imageArraySize) | CREATE_SWAP_BAD_IMG_ARRAY_SIZE | vkCreateSwapchainKHR | NA | None |
+| vkCreateSwapchainKHR(pCreateInfo->imageUsageFlags) | Validates vkCreateSwapchainKHR(pCreateInfo->imageUsageFlags) | CREATE_SWAP_BAD_IMG_USAGE_FLAGS | vkCreateSwapchainKHR | NA | None |
+| vkCreateSwapchainKHR(pCreateInfo->imageColorSpace) | Validates vkCreateSwapchainKHR(pCreateInfo->imageColorSpace) | CREATE_SWAP_BAD_IMG_COLOR_SPACE | vkCreateSwapchainKHR | NA | None |
+| vkCreateSwapchainKHR(pCreateInfo->imageFormat) | Validates vkCreateSwapchainKHR(pCreateInfo->imageFormat) | CREATE_SWAP_BAD_IMG_FORMAT | vkCreateSwapchainKHR | NA | None |
+| vkCreateSwapchainKHR(pCreateInfo->imageFormat and pCreateInfo->imageColorSpace) | Validates vkCreateSwapchainKHR(pCreateInfo->imageFormat and pCreateInfo->imageColorSpace) | CREATE_SWAP_BAD_IMG_FMT_CLR_SP | vkCreateSwapchainKHR | NA | None |
+| vkCreateSwapchainKHR(pCreateInfo->presentMode) | Validates vkCreateSwapchainKHR(pCreateInfo->presentMode) | CREATE_SWAP_BAD_PRESENT_MODE | vkCreateSwapchainKHR | NA | None |
+| Use same device for swapchain | Validates that vkDestroySwapchainKHR() called with the same VkDevice as vkCreateSwapchainKHR() | DESTROY_SWAP_DIFF_DEVICE | vkDestroySwapchainKHR | NA | None |
+| Don't use too many images | Validates that app never tries to own too many swapchain images at a time | APP_OWNS_TOO_MANY_IMAGES | vkAcquireNextImageKHR | NA | None |
+| Index too large | Validates that an image index is within the number of images in a swapchain | INDEX_TOO_LARGE | vkAcquireNextImageKHR vkQueuePresentKHR | NA | None |
+| Can't use an simultaneously use an image | If vkAcquireNextImageKHR() returns index of an image that is already owned by the application | INDEX_ALREADY_IN_USE | vkAcquireNextImageKHR | NA | None |
+| Can't present a non-owned image | Validates that application only presents images that it owns | INDEX_NOT_IN_USE | vkQueuePresentKHR | NA | None |
+
+### Swapchain Pending Work
+Additional checks to be added to Swapchain
+
+ 1. Check that the queue used for presenting was checked/valid during vkGetPhysicalDeviceSurfaceSupportKHR.
+ 2. One issue that has already come up is correct UsageFlags for WSI SwapChains and SurfaceProperties.
+ 3. Tons of other stuff including semaphore and synchronization validation.
+
+
 ## General Pending Work
 A place to capture general validation work to be done. This includes new checks that don't clearly fit into the above layers.
 
index a233c98e29b283a5f9ff6bfc68757a0b1d3da336..c7f18354b5e5b9f5e37b134abdf6efed9edc6fbe 100755 (executable)
@@ -81,6 +81,10 @@ layer_inputs = { 'draw_state' : {'header' : 'layers/draw_state.h',
                             'source' : 'layers/image.cpp',
                             'generated' : False,
                             'error_enum' : 'IMAGE_ERROR',},
+                 'swapchain' : {'header' : 'layers/swapchain.h',
+                            'source' : 'layers/swapchain.cpp',
+                            'generated' : False,
+                            'error_enum' : 'SWAPCHAIN_ERROR',},
     }
 
 builtin_headers = [layer_inputs[ln]['header'] for ln in layer_inputs]