for (uint32_t i = 0; i < pPresentInfo->swapchainCount; ++i) {
auto swapchain_data = getSwapchainNode(dev_data, pPresentInfo->pSwapchains[i]);
- if (swapchain_data && pPresentInfo->pImageIndices[i] < swapchain_data->images.size()) {
- VkImage image = swapchain_data->images[pPresentInfo->pImageIndices[i]];
- skip_call |= ValidateImageMemoryIsValid(dev_data, getImageNode(dev_data, image), "vkQueuePresentKHR()");
- vector<VkImageLayout> layouts;
- if (FindLayouts(dev_data, image, layouts)) {
- for (auto layout : layouts) {
- if (layout != VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) {
- skip_call |=
- log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT,
- reinterpret_cast<uint64_t &>(queue), __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS",
- "Images passed to present must be in layout "
- "VK_IMAGE_LAYOUT_PRESENT_SRC_KHR but is in %s",
- string_VkImageLayout(layout));
+ if (swapchain_data) {
+ if (pPresentInfo->pImageIndices[i] >= swapchain_data->images.size()) {
+ skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT,
+ reinterpret_cast<uint64_t const &>(pPresentInfo->pSwapchains[i]), __LINE__, DRAWSTATE_INVALID_SWAPCHAIN_IMAGE,
+ "DS", "vkQueuePresentKHR: Swapchain image index too large (%u). There are only %u images in this swapchain.",
+ pPresentInfo->pImageIndices[i], (uint32_t)swapchain_data->images.size());
+ }
+ else {
+ auto image = swapchain_data->images[pPresentInfo->pImageIndices[i]];
+ auto image_node = getImageNode(dev_data, image);
+ skip_call |= ValidateImageMemoryIsValid(dev_data, image_node, "vkQueuePresentKHR()");
+
+ if (!image_node->acquired) {
+ skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT,
+ reinterpret_cast<uint64_t const &>(pPresentInfo->pSwapchains[i]), __LINE__, DRAWSTATE_SWAPCHAIN_IMAGE_NOT_ACQUIRED,
+ "DS", "vkQueuePresentKHR: Swapchain image index %u has not been acquired.",
+ pPresentInfo->pImageIndices[i]);
+ }
+
+ vector<VkImageLayout> layouts;
+ if (FindLayouts(dev_data, image, layouts)) {
+ for (auto layout : layouts) {
+ if (layout != VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) {
+ skip_call |=
+ log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT,
+ reinterpret_cast<uint64_t &>(queue), __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS",
+ "Images passed to present must be in layout "
+ "VK_IMAGE_LAYOUT_PRESENT_SRC_KHR but is in %s",
+ string_VkImageLayout(layout));
+ }
}
}
}
DRAWSTATE_PUSH_CONSTANTS_ERROR, // Push constants exceed maxPushConstantSize
DRAWSTATE_INVALID_SUBPASS_INDEX, // Stepping beyond last subpass, or not reaching it
DRAWSTATE_NO_SYNC_FOR_ACQUIRE, // AcquireNextImageKHR with no sync object
+ DRAWSTATE_INVALID_SWAPCHAIN_IMAGE, // QueuePresentKHR with image index out of range
+ DRAWSTATE_SWAPCHAIN_IMAGE_NOT_ACQUIRED, // QueuePresentKHR with image not acquired by app
};
// Shader Checker ERROR codes
std::unique_lock<std::mutex> lock(global_lock);
for (uint32_t i = 0; pPresentInfo && (i < pPresentInfo->swapchainCount); i++) {
- uint32_t index = pPresentInfo->pImageIndices[i];
SwpSwapchain *pSwapchain = NULL;
{
auto it = my_data->swapchainMap.find(pPresentInfo->pSwapchains[i]);
"vkQueuePresentKHR() called even though the %s extension was not enabled for this VkDevice.",
VK_KHR_SWAPCHAIN_EXTENSION_NAME);
}
- if (index >= pSwapchain->imageCount) {
- skip_call |=
- log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT,
- reinterpret_cast<const uint64_t &>(pPresentInfo->pSwapchains[i]), __LINE__, SWAPCHAIN_INDEX_TOO_LARGE,
- swapchain_layer_name,
- "vkQueuePresentKHR() called for an index that is too large (i.e. %d). There are only %d images in "
- "this VkSwapchainKHR.",
- index, pSwapchain->imageCount);
- } else {
- if (!pSwapchain->images[index].acquiredByApp) {
- skip_call |= log_msg(
- my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT,
- reinterpret_cast<const uint64_t &>(pPresentInfo->pSwapchains[i]), __LINE__, SWAPCHAIN_INDEX_NOT_IN_USE,
- swapchain_layer_name,
- "vkQueuePresentKHR() returned an index (i.e. %d) for an image that is not acquired by the application.",
- index);
- }
- }
SwpQueue *pQueue = NULL;
{
auto it = my_data->queueMap.find(queue);
// than pCreateInfo->surface
SWAPCHAIN_DESTROY_SWAP_DIFF_DEVICE, // Called vkDestroySwapchainKHR() with a different VkDevice than vkCreateSwapchainKHR()
SWAPCHAIN_APP_ACQUIRES_TOO_MANY_IMAGES, // vkAcquireNextImageKHR() asked for more images than are available
- SWAPCHAIN_INDEX_TOO_LARGE, // Index is too large for swapchain
- SWAPCHAIN_INDEX_NOT_IN_USE, // vkQueuePresentKHR() given index that is not acquired by app
SWAPCHAIN_BAD_BOOL, // VkBool32 that doesn't have value of VK_TRUE or VK_FALSE (e.g. is a non-zero form of true)
SWAPCHAIN_PRIOR_COUNT, // Query must be called first to get value of pCount, then called second time
SWAPCHAIN_INVALID_COUNT, // Second time a query called, the pCount value didn't match first time
| NA | Enum used when VK_LAYER_LUNARG_core_validation attempts to allocate memory for its own internal use and is unable to. | OUT_OF_MEMORY | | TODO | None |
| Bad subpass indexing | Must not step beyond last subpass in a renderpass instance, and must reach the last subpass before CmdEndRenderPass. | INVALID_SUBPASS_INDEX | vkCmdNextSubpass | RenderPassExcessiveNextSubpass | NA |
| Proper synchronization of acquired images | vkAcquireNextImageKHR should be called with a valid semaphore and/or fence | NO_SYNC_FOR_ACQUIRE | vkAcquireNextImageKHR | TODO | None |
+| Swapchain image index too large | Validates that an image index is within the number of images in a swapchain | INVALID_SWAPCHAIN_IMAGE | vkQueuePresentKHR | VkWsiEnabledLayerTest.TestEnabledWsi | None |
+| Can't present a non-owned image | Validates that application only presents images that it owns | SWAPCHAIN_IMAGE_NOT_ACQUIRED | vkQueuePresentKHR | TODO | None |
### VK_LAYER_LUNARG_core_validation Draw State Pending Work
| vkCreateSwapchainKHR(pCreateInfo->oldSwapchain and pCreateInfo->surface) | pCreateInfo->surface must match pCreateInfo->oldSwapchain's surface | CREATE_SWAP_DIFF_SURFACE | vkCreateSwapchainKHR | TODO | None |
| Use same device for swapchain | Validates that vkDestroySwapchainKHR() called with the same VkDevice as vkCreateSwapchainKHR() | DESTROY_SWAP_DIFF_DEVICE | vkCreateSwapchainKHR vkDestroySwapchainKHR | TODO | None |
| Don't acquire too many images | Validates that app never tries to acquire too many swapchain images at a time | APP_ACQUIRES_TOO_MANY_IMAGES | vkAcquireNextImageKHR | TODO | None |
-| Index too large | Validates that an image index is within the number of images in a swapchain | INDEX_TOO_LARGE | vkQueuePresentKHR | VkWsiEnabledLayerTest.TestEnabledWsi | None |
-| Can't present a non-owned image | Validates that application only presents images that it owns | INDEX_NOT_IN_USE | vkQueuePresentKHR | TODO | None |
| A VkBool32 must have values of VK_TRUE or VK_FALSE | Validates that a VkBool32 must have values of VK_TRUE or VK_FALSE | BAD_BOOL | vkCreateSwapchainKHR | TODO | None |
| pCount must be set by the API before the other pointer is non-NULL | Validates that app queries for the value of pCount before trying to set it | PRIOR_COUNT | vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfacePresentModesKHR vkGetSwapchainImagesKHR | VkWsiEnabledLayerTest.TestEnabledWsi | None |
| pCount must point to same value regardless of whether other pointer is NULL | Validates that app doesn't change value of pCount returned by a query | INVALID_COUNT | vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfacePresentModesKHR vkGetSwapchainImagesKHR | VkWsiEnabledLayerTest.TestEnabledWsi | None |