@@ -60,8 +60,9 @@ struct VulkanSwapchainInfo {
6060 VkFormat displayFormat_;
6161
6262 // array of frame buffers and views
63- VkFramebuffer* framebuffers_;
64- VkImageView* displayViews_;
63+ std::vector<VkImage> displayImages_;
64+ std::vector<VkImageView> displayViews_;
65+ std::vector<VkFramebuffer> framebuffers_;
6566};
6667VulkanSwapchainInfo swapchain;
6768
@@ -78,6 +79,15 @@ VulkanRenderInfo render;
7879// Android Native App pointer...
7980android_app* androidAppCtx = nullptr ;
8081
82+ /*
83+ * setImageLayout():
84+ * Helper function to transition color buffer layout
85+ */
86+ void setImageLayout (VkCommandBuffer cmdBuffer, VkImage image,
87+ VkImageLayout oldImageLayout, VkImageLayout newImageLayout,
88+ VkPipelineStageFlags srcStages,
89+ VkPipelineStageFlags destStages);
90+
8191// Create vulkan device
8292void CreateVulkanDevice (ANativeWindow* platformWindow,
8393 VkApplicationInfo* appInfo) {
@@ -122,16 +132,18 @@ void CreateVulkanDevice(ANativeWindow* platformWindow,
122132
123133 // Find a GFX queue family
124134 uint32_t queueFamilyCount;
125- vkGetPhysicalDeviceQueueFamilyProperties (device.gpuDevice_ , &queueFamilyCount, nullptr );
135+ vkGetPhysicalDeviceQueueFamilyProperties (device.gpuDevice_ , &queueFamilyCount,
136+ nullptr );
126137 assert (queueFamilyCount);
127- std::vector<VkQueueFamilyProperties> queueFamilyProperties (queueFamilyCount);
138+ std::vector<VkQueueFamilyProperties> queueFamilyProperties (queueFamilyCount);
128139 vkGetPhysicalDeviceQueueFamilyProperties (device.gpuDevice_ , &queueFamilyCount,
129140 queueFamilyProperties.data ());
130141
131142 uint32_t queueFamilyIndex;
132- for (queueFamilyIndex= 0 ; queueFamilyIndex < queueFamilyCount;
143+ for (queueFamilyIndex = 0 ; queueFamilyIndex < queueFamilyCount;
133144 queueFamilyIndex++) {
134- if (queueFamilyProperties[queueFamilyIndex].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
145+ if (queueFamilyProperties[queueFamilyIndex].queueFlags &
146+ VK_QUEUE_GRAPHICS_BIT) {
135147 break ;
136148 }
137149 }
@@ -165,7 +177,7 @@ void CreateVulkanDevice(ANativeWindow* platformWindow,
165177
166178 CALL_VK (vkCreateDevice (device.gpuDevice_ , &deviceCreateInfo, nullptr ,
167179 &device.device_ ));
168- vkGetDeviceQueue (device.device_ , 0 , 0 , &device.queue_ );
180+ vkGetDeviceQueue (device.device_ , device. queueFamilyIndex_ , 0 , &device.queue_ );
169181}
170182
171183void CreateSwapChain (void ) {
@@ -233,10 +245,8 @@ void DeleteSwapChain(void) {
233245 for (int i = 0 ; i < swapchain.swapchainLength_ ; i++) {
234246 vkDestroyFramebuffer (device.device_ , swapchain.framebuffers_ [i], nullptr );
235247 vkDestroyImageView (device.device_ , swapchain.displayViews_ [i], nullptr );
248+ vkDestroyImage (device.device_ , swapchain.displayImages_ [i], nullptr );
236249 }
237- delete[] swapchain.framebuffers_ ;
238- delete[] swapchain.displayViews_ ;
239-
240250 vkDestroySwapchainKHR (device.device_ , swapchain.swapchain_ , nullptr );
241251}
242252
@@ -246,17 +256,18 @@ void CreateFrameBuffers(VkRenderPass& renderPass,
246256 uint32_t SwapchainImagesCount = 0 ;
247257 CALL_VK (vkGetSwapchainImagesKHR (device.device_ , swapchain.swapchain_ ,
248258 &SwapchainImagesCount, nullptr ));
249- VkImage* displayImages = new VkImage[ SwapchainImagesCount] ;
259+ swapchain. displayImages_ . resize ( SwapchainImagesCount) ;
250260 CALL_VK (vkGetSwapchainImagesKHR (device.device_ , swapchain.swapchain_ ,
251- &SwapchainImagesCount, displayImages));
261+ &SwapchainImagesCount,
262+ swapchain.displayImages_ .data ()));
252263
253264 // create image view for each swapchain image
254- swapchain.displayViews_ = new VkImageView[ SwapchainImagesCount] ;
265+ swapchain.displayViews_ . resize ( SwapchainImagesCount) ;
255266 for (uint32_t i = 0 ; i < SwapchainImagesCount; i++) {
256267 VkImageViewCreateInfo viewCreateInfo = {
257268 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
258269 .pNext = nullptr ,
259- .image = displayImages [i],
270+ .image = swapchain. displayImages_ [i],
260271 .viewType = VK_IMAGE_VIEW_TYPE_2D,
261272 .format = swapchain.displayFormat_ ,
262273 .components =
@@ -279,10 +290,9 @@ void CreateFrameBuffers(VkRenderPass& renderPass,
279290 CALL_VK (vkCreateImageView (device.device_ , &viewCreateInfo, nullptr ,
280291 &swapchain.displayViews_ [i]));
281292 }
282- delete[] displayImages;
283293
284294 // create a framebuffer from each swapchain image
285- swapchain.framebuffers_ = new VkFramebuffer[ swapchain.swapchainLength_ ] ;
295+ swapchain.framebuffers_ . resize ( swapchain.swapchainLength_ ) ;
286296 for (uint32_t i = 0 ; i < swapchain.swapchainLength_ ; i++) {
287297 VkImageView attachments[2 ] = {
288298 swapchain.displayViews_ [i], depthView,
@@ -412,7 +422,13 @@ bool InitVulkan(android_app* app) {
412422 };
413423 CALL_VK (vkBeginCommandBuffer (render.cmdBuffer_ [bufferIndex],
414424 &cmdBufferBeginInfo));
415-
425+ // transition the display image to color attachment layout
426+ setImageLayout (render.cmdBuffer_ [bufferIndex],
427+ swapchain.displayImages_ [bufferIndex],
428+ VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
429+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
430+ VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
431+ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
416432 // Now we start a renderpass. Any draw command has to be recorded in a
417433 // renderpass
418434 VkClearValue clearVals{
@@ -438,6 +454,13 @@ bool InitVulkan(android_app* app) {
438454 // Do more drawing !
439455
440456 vkCmdEndRenderPass (render.cmdBuffer_ [bufferIndex]);
457+ // transition back to swapchain image to PRESENT_SRC_KHR
458+ setImageLayout (render.cmdBuffer_ [bufferIndex],
459+ swapchain.displayImages_ [bufferIndex],
460+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
461+ VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
462+ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
463+ VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
441464 CALL_VK (vkEndCommandBuffer (render.cmdBuffer_ [bufferIndex]));
442465 }
443466
@@ -520,3 +543,78 @@ bool VulkanDrawFrame(void) {
520543 vkQueuePresentKHR (device.queue_ , &presentInfo);
521544 return true ;
522545}
546+
547+ /*
548+ * setImageLayout():
549+ * Helper function to transition color buffer layout
550+ */
551+ void setImageLayout (VkCommandBuffer cmdBuffer, VkImage image,
552+ VkImageLayout oldImageLayout, VkImageLayout newImageLayout,
553+ VkPipelineStageFlags srcStages,
554+ VkPipelineStageFlags destStages) {
555+ VkImageMemoryBarrier imageMemoryBarrier = {
556+ .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
557+ .pNext = NULL ,
558+ .srcAccessMask = 0 ,
559+ .dstAccessMask = 0 ,
560+ .oldLayout = oldImageLayout,
561+ .newLayout = newImageLayout,
562+ .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
563+ .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
564+ .image = image,
565+ .subresourceRange =
566+ {
567+ .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
568+ .baseMipLevel = 0 ,
569+ .levelCount = 1 ,
570+ .baseArrayLayer = 0 ,
571+ .layerCount = 1 ,
572+ },
573+ };
574+
575+ switch (oldImageLayout) {
576+ case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
577+ imageMemoryBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
578+ break ;
579+
580+ case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
581+ imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
582+ break ;
583+
584+ case VK_IMAGE_LAYOUT_PREINITIALIZED:
585+ imageMemoryBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
586+ break ;
587+
588+ default :
589+ break ;
590+ }
591+
592+ switch (newImageLayout) {
593+ case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
594+ imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
595+ break ;
596+
597+ case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
598+ imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
599+ break ;
600+
601+ case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
602+ imageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
603+ break ;
604+
605+ case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
606+ imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
607+ break ;
608+
609+ case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
610+ imageMemoryBarrier.dstAccessMask =
611+ VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
612+ break ;
613+
614+ default :
615+ break ;
616+ }
617+
618+ vkCmdPipelineBarrier (cmdBuffer, srcStages, destStages, 0 , 0 , NULL , 0 , NULL , 1 ,
619+ &imageMemoryBarrier);
620+ }
0 commit comments