Vulkan Swapchain recreation and QueuePresent

#1

I’m struggling to make swap chain recreation correct, but I can’t find any clue on what i’m doing wrong.

my vulkan sdk version is 1.1.106.0.
The error message from validation error is

[ VUID-VkPresentInfoKHR-pImageIndices-01296 ] 
Object: 0x1684a097690 (Type = 4) | 
Images passed to present must be in layout VK_IMAGE_LAYOUT_PRESENT_SRC_KHR or 
VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR 
but is in VK_IMAGE_LAYOUT_UNDEFINED. 
The Vulkan spec states: 
Each element of pImageIndices must be the index of a presentable image acquired from the swapchain 
specified by the corresponding element of the pSwapchains array, 
and the presented image subresource must be in the VK_IMAGE_LAYOUT_PRESENT_SRC_KHR layout at the time 
the operation is executed on a VkDevice 
(https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkPresentInfoKHR-pImageIndices-01296)

Let me describe my code process on Vulkan.

I use only one renderpass with this createInfo from renderDoc:

flags           VkAttachmentDescriptionFlagBits(0)                
format          VK_FORMAT_B8G8R8A8_UNORM                          
samples         VK_SAMPLE_COUNT_1_BIT                             
loadOp          VK_ATTACHMENT_LOAD_OP_CLEAR                       
storeOp         VK_ATTACHMENT_STORE_OP_STORE                      
stencilLoadOp   VK_ATTACHMENT_LOAD_OP_DONT_CARE                   
stencilStoreOp  VK_ATTACHMENT_STORE_OP_DONT_CARE                  
initialLayout   VK_IMAGE_LAYOUT_UNDEFINED                         
finalLayout     VK_IMAGE_LAYOUT_PRESENT_SRC_KHR                   
flags           VkAttachmentDescriptionFlagBits(0)                
format          VK_FORMAT_D32_SFLOAT_S8_UINT                      
samples         VK_SAMPLE_COUNT_1_BIT                             
loadOp          VK_ATTACHMENT_LOAD_OP_CLEAR                       
storeOp         VK_ATTACHMENT_STORE_OP_STORE                      
stencilLoadOp   VK_ATTACHMENT_LOAD_OP_DONT_CARE                   
stencilStoreOp  VK_ATTACHMENT_STORE_OP_DONT_CARE                  
initialLayout   VK_IMAGE_LAYOUT_UNDEFINED                         
finalLayout     VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL  
[0]             VkAttachmentDescription()                         
[1]             VkAttachmentDescription()                         
[0]             VkSubpassDescription()                            
srcSubpass      UINT32_MAX                                        
dstSubpass      0                                                 
srcStageMask    VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT              
dstStageMask    VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT     
srcAccessMask   VK_ACCESS_MEMORY_READ_BIT                         
dstAccessMask   VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
dependencyFlags VK_DEPENDENCY_BY_REGION_BIT                       
srcSubpass      0                                                 
dstSubpass      UINT32_MAX                                        
srcStageMask    VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT     
dstStageMask    VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT              
srcAccessMask   VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
dstAccessMask   VK_ACCESS_MEMORY_READ_BIT                         
dependencyFlags VK_DEPENDENCY_BY_REGION_BIT                       
[0]             VkSubpassDependency()                             
[1]             VkSubpassDependency()                             
sType           VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO         
pNext           NULL                                              
flags           0                                                 
attachmentCount 2                                                 
pAttachments    VkAttachmentDescription[]                         
subpassCount    1                                                 
pSubpasses      VkSubpassDescription[]                            
dependencyCount 2                                                 
pDependencies   VkSubpassDependency[]                             
CreateInfo      VkRenderPassCreateInfo()                          
pAllocator      NULL                                              
RenderPass      ResourceId::145

with this renderpass, I render these:

beginCommandBuffer();
{
    beginRenderPass(renderPass, swapchainFramebuffer[index]);
    {
       DrawModelMesh();

       DrawGUI();
    }
    endRenderPass();
}
EndCommandBuffer();

When the time of recreating swap chain comes, My logic is next:

void restore()
{
    vkDeviceWaitIdle(device);
    
    KillSwapChainSyncObject();
    
    vkResetCommandPool(device, commandPool, 0);
    
    KillSwapChainFrameBuffer();
    
    RecreateSwapChainAfterKillingOldSwapChain();
    
    resetRenderPassRenderArea();
    
    RecordCommandAgain();
    
    AcquireNextImageIndex();
    
    QueueSubmit();
    
    QueuePresent();
}

I use VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, So I think I don’t need to recreate the renderpass and pipeline. after restore(), I just restart normal game loop (update, render).

The strangest thing on this, I don’t get any error from validation error sometimes when resizing the window. In addition, when debugging in renderDoc, There is no error when resizing the window. Even When I debug in Visual studio debug mode, If I just skip the debug log, My program just runs.

I ensure that my renderpass will transition the swapchain image layout from undefined to PRESENT_SRC_KHR. However, I can’t get why the validation gives me a error. I hope anyone will give me some tips for this. Thanks in advance.

#2

Firstly, your SDK is old.

This can be synchronization. Make sure Submit and Present are separated by a Semaphore.

Or maybe you accidentally render to wrong image. Hard to know anything from a pseudocode.

1 Like
#3

Hi @krOoze. your guess of rendering to wrong image is right.

I was confused with the swapchain image index and sync object resource index, which indicate nextSwapchainImageIndex and SubmissionNr in your HelloTriangle Example.

My thought was that the framebuffer index for triple buffering is not related to the swapchain index. So, I got validation error. After fixing that mistake, I make it work well to resize window correctly. Always Thank you for your good resources of Vulkan.