demos: Add mem barrier to change layout to present
authorTony Barbour <tony@LunarG.com>
Wed, 21 Oct 2015 16:14:48 +0000 (10:14 -0600)
committerTony Barbour <tony@LunarG.com>
Wed, 21 Oct 2015 22:45:30 +0000 (16:45 -0600)
This addresses LunarExchange issue 168

demos/cube.c
demos/tri.c

index 8a2b223..c5b287a 100644 (file)
@@ -566,6 +566,24 @@ static void demo_draw_build_cmd(struct demo *demo, VkCmdBuffer cmd_buf)
     vkCmdDraw(cmd_buf, 12 * 3, 1, 0, 0);
     vkCmdEndRenderPass(cmd_buf);
 
+    VkImageMemoryBarrier prePresentBarrier = {
+        .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
+        .pNext = NULL,
+        .outputMask = VK_MEMORY_OUTPUT_COLOR_ATTACHMENT_BIT,
+        .inputMask = 0,
+        .oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+        .newLayout = VK_IMAGE_LAYOUT_PRESENT_SOURCE_KHR,
+        .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
+        .destQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
+        .subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }
+    };
+
+    prePresentBarrier.image = demo->buffers[demo->current_buffer].image;
+    VkImageMemoryBarrier *pmemory_barrier = &prePresentBarrier;
+    vkCmdPipelineBarrier(cmd_buf, VK_PIPELINE_STAGE_ALL_GPU_COMMANDS, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+                         VK_FALSE, 1, (const void * const*)&pmemory_barrier);
+
+
     err = vkEndCommandBuffer(cmd_buf);
     assert(!err);
 }
@@ -625,6 +643,14 @@ static void demo_draw(struct demo *demo)
     err = vkQueueWaitSemaphore(demo->queue, presentCompleteSemaphore);
     assert(!err);
 
+    // Assume the command buffer has been run on current_buffer before so
+    // we need to set the image layout back to COLOR_ATTACHMENT_OPTIMAL
+    demo_set_image_layout(demo, demo->buffers[demo->current_buffer].image,
+                           VK_IMAGE_ASPECT_COLOR_BIT,
+                           VK_IMAGE_LAYOUT_PRESENT_SOURCE_KHR,
+                           VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+    demo_flush_init_cmd(demo);
+
 // FIXME/TODO: DEAL WITH VK_IMAGE_LAYOUT_PRESENT_SOURCE_KHR
     err = vkQueueSubmit(demo->queue, 1, &demo->buffers[demo->current_buffer].cmd,
             nullFence);
@@ -788,10 +814,12 @@ static void demo_prepare_buffers(struct demo *demo)
 
         demo->buffers[i].image = swapchainImages[i];
 
+        // Render loop will expect image to have been used before and in VK_IMAGE_LAYOUT_PRESENT_SOURCE_KHR
+        // layout and will change to COLOR_ATTACHMENT_OPTIMAL, so init the image to that state
         demo_set_image_layout(demo, demo->buffers[i].image,
                                VK_IMAGE_ASPECT_COLOR_BIT,
                                VK_IMAGE_LAYOUT_UNDEFINED,
-                               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+                               VK_IMAGE_LAYOUT_PRESENT_SOURCE_KHR);
 
         color_image_view.image = demo->buffers[i].image;
 
index a749f42..dc12f07 100644 (file)
@@ -409,6 +409,23 @@ static void demo_draw_build_cmd(struct demo *demo)
     vkCmdDraw(demo->draw_cmd, 3, 1, 0, 0);
     vkCmdEndRenderPass(demo->draw_cmd);
 
+    VkImageMemoryBarrier prePresentBarrier = {
+        .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
+        .pNext = NULL,
+        .outputMask = VK_MEMORY_OUTPUT_COLOR_ATTACHMENT_BIT,
+        .inputMask = 0,
+        .oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+        .newLayout = VK_IMAGE_LAYOUT_PRESENT_SOURCE_KHR,
+        .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
+        .destQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
+        .subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }
+    };
+
+    prePresentBarrier.image = demo->buffers[demo->current_buffer].image;
+    VkImageMemoryBarrier *pmemory_barrier = &prePresentBarrier;
+    vkCmdPipelineBarrier(demo->draw_cmd, VK_PIPELINE_STAGE_ALL_GPU_COMMANDS, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+                         VK_FALSE, 1, (const void * const*)&pmemory_barrier);
+
     err = vkEndCommandBuffer(demo->draw_cmd);
     assert(!err);
 }
@@ -444,6 +461,14 @@ static void demo_draw(struct demo *demo)
     err = vkQueueWaitSemaphore(demo->queue, presentCompleteSemaphore);
     assert(!err);
 
+    // Assume the command buffer has been run on current_buffer before so
+    // we need to set the image layout back to COLOR_ATTACHMENT_OPTIMAL
+    demo_set_image_layout(demo, demo->buffers[demo->current_buffer].image,
+                           VK_IMAGE_ASPECT_COLOR_BIT,
+                           VK_IMAGE_LAYOUT_PRESENT_SOURCE_KHR,
+                           VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+    demo_flush_init_cmd(demo);
+
 // FIXME/TODO: DEAL WITH VK_IMAGE_LAYOUT_PRESENT_SOURCE_KHR
     demo_draw_build_cmd(demo);
     VkFence nullFence = { VK_NULL_HANDLE };
@@ -595,10 +620,12 @@ static void demo_prepare_buffers(struct demo *demo)
 
         demo->buffers[i].image = swapchainImages[i];
 
+        // Render loop will expect image to have been used before and in VK_IMAGE_LAYOUT_PRESENT_SOURCE_KHR
+        // layout and will change to COLOR_ATTACHMENT_OPTIMAL, so init the image to that state
         demo_set_image_layout(demo, demo->buffers[i].image,
                                VK_IMAGE_ASPECT_COLOR_BIT,
                                VK_IMAGE_LAYOUT_UNDEFINED,
-                               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+                               VK_IMAGE_LAYOUT_PRESENT_SOURCE_KHR);
 
         color_attachment_view.image = demo->buffers[i].image;