Changeset 4e2c709 in opengl-game


Ignore:
Timestamp:
Feb 14, 2021, 2:44:21 AM (3 years ago)
Author:
Dmitry Portnoy <dportnoy@…>
Branches:
feature/imgui-sdl
Children:
28ea92f
Parents:
9c0a614
Message:

In VulkanGame, separate renderScene() into renderFrame() and presentFrame(), and in SDLGame, rename FrameRender() and FramePresent() to renderFrame() and presentFrame()

Files:
4 edited

Legend:

Unmodified
Added
Removed
  • sdl-game.cpp

    r9c0a614 r4e2c709  
    3131   }
    3232}
    33 
    34 void VulkanGame::FrameRender(ImDrawData* draw_data) {
    35    VkResult result = vkAcquireNextImageKHR(device, swapChain, numeric_limits<uint64_t>::max(),
    36       imageAcquiredSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex);
    37 
    38    if (result == VK_ERROR_OUT_OF_DATE_KHR) {
    39       g_SwapChainRebuild = true;
    40       return;
    41    } else {
    42       VKUTIL_CHECK_RESULT(result, "failed to acquire swap chain image!");
    43    }
    44 
    45    VKUTIL_CHECK_RESULT(vkWaitForFences(device, 1, &inFlightFences[imageIndex], VK_TRUE, numeric_limits<uint64_t>::max()),
    46       "failed waiting for fence!");
    47 
    48    VKUTIL_CHECK_RESULT(vkResetFences(device, 1, &inFlightFences[imageIndex]),
    49       "failed to reset fence!");
    50 
    51    // START OF NEW CODE
    52    // I don't have analogous code in vulkan-game right now because I record command buffers once
    53    // before the render loop ever starts. I should change this
    54 
    55    VKUTIL_CHECK_RESULT(vkResetCommandPool(device, commandPools[imageIndex], 0),
    56       "failed to reset command pool!");
    57 
    58    VkCommandBufferBeginInfo info = {};
    59    info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
    60    info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
    61 
    62    VKUTIL_CHECK_RESULT(vkBeginCommandBuffer(commandBuffers[imageIndex], &info),
    63       "failed to begin recording command buffer!");
    64 
    65    VkRenderPassBeginInfo renderPassInfo = {};
    66    renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
    67    renderPassInfo.renderPass = renderPass;
    68    renderPassInfo.framebuffer = swapChainFramebuffers[imageIndex];
    69    renderPassInfo.renderArea.extent = swapChainExtent;
    70 
    71    array<VkClearValue, 2> clearValues = {};
    72    clearValues[0].color = { { 0.45f, 0.55f, 0.60f, 1.00f } };
    73    clearValues[1].depthStencil = { 1.0f, 0 };
    74 
    75    renderPassInfo.clearValueCount = static_cast<uint32_t>(clearValues.size());
    76    renderPassInfo.pClearValues = clearValues.data();
    77 
    78    vkCmdBeginRenderPass(commandBuffers[imageIndex], &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
    79 
    80    // Record dear imgui primitives into command buffer
    81    ImGui_ImplVulkan_RenderDrawData(draw_data, commandBuffers[imageIndex]);
    82 
    83    // Submit command buffer
    84    vkCmdEndRenderPass(commandBuffers[imageIndex]);
    85 
    86    VKUTIL_CHECK_RESULT(vkEndCommandBuffer(commandBuffers[imageIndex]),
    87       "failed to record command buffer!");
    88 
    89    // END OF NEW CODE
    90 
    91    VkSemaphore waitSemaphores[] = { imageAcquiredSemaphores[currentFrame] };
    92    VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
    93    VkSemaphore signalSemaphores[] = { renderCompleteSemaphores[currentFrame] };
    94 
    95    VkSubmitInfo submitInfo = {};
    96    submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
    97    submitInfo.waitSemaphoreCount = 1;
    98    submitInfo.pWaitSemaphores = waitSemaphores;
    99    submitInfo.pWaitDstStageMask = &wait_stage;
    100    submitInfo.commandBufferCount = 1;
    101    submitInfo.pCommandBuffers = &commandBuffers[imageIndex];
    102    submitInfo.signalSemaphoreCount = 1;
    103    submitInfo.pSignalSemaphores = signalSemaphores;
    104 
    105    VKUTIL_CHECK_RESULT(vkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFences[imageIndex]),
    106       "failed to submit draw command buffer!");
    107 }
    108 
    109 void VulkanGame::FramePresent() {
    110    if (g_SwapChainRebuild)
    111       return;
    112 
    113    VkSemaphore signalSemaphores[] = { renderCompleteSemaphores[currentFrame] };
    114 
    115    VkPresentInfoKHR presentInfo = {};
    116    presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
    117    presentInfo.waitSemaphoreCount = 1;
    118    presentInfo.pWaitSemaphores = signalSemaphores;
    119    presentInfo.swapchainCount = 1;
    120    presentInfo.pSwapchains = &swapChain;
    121    presentInfo.pImageIndices = &imageIndex;
    122    presentInfo.pResults = nullptr;
    123 
    124    VkResult result = vkQueuePresentKHR(presentQueue, &presentInfo);
    125 
    126    // In vulkan-game, I also handle VK_SUBOPTIMAL_KHR and framebufferResized. g_SwapChainRebuild is kind of similar
    127    // to framebufferResized, but not quite the same
    128    if (result == VK_ERROR_OUT_OF_DATE_KHR) {
    129       g_SwapChainRebuild = true;
    130       return;
    131    } else if (result != VK_SUCCESS) {
    132       throw runtime_error("failed to present swap chain image!");
    133    }
    134 
    135    currentFrame = (currentFrame + 1) % swapChainImageCount;
    136 }
    137 
    138 /********************************************* START OF NEW CODE *********************************************/
    13933
    14034VKAPI_ATTR VkBool32 VKAPI_CALL VulkanGame::debugCallback(
     
    337231      const bool is_minimized = (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f);
    338232      if (!is_minimized) {
    339          FrameRender(draw_data);
    340          FramePresent();
     233         renderFrame(draw_data);
     234         presentFrame();
    341235      }
    342236   }
     
    924818}
    925819
     820void VulkanGame::renderFrame(ImDrawData* draw_data) {
     821   VkResult result = vkAcquireNextImageKHR(device, swapChain, numeric_limits<uint64_t>::max(),
     822      imageAcquiredSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex);
     823
     824   if (result == VK_ERROR_OUT_OF_DATE_KHR) {
     825      g_SwapChainRebuild = true;
     826      return;
     827   }
     828   else {
     829      VKUTIL_CHECK_RESULT(result, "failed to acquire swap chain image!");
     830   }
     831
     832   VKUTIL_CHECK_RESULT(vkWaitForFences(device, 1, &inFlightFences[imageIndex], VK_TRUE, numeric_limits<uint64_t>::max()),
     833      "failed waiting for fence!");
     834
     835   VKUTIL_CHECK_RESULT(vkResetFences(device, 1, &inFlightFences[imageIndex]),
     836      "failed to reset fence!");
     837
     838   // START OF NEW CODE
     839   // I don't have analogous code in vulkan-game right now because I record command buffers once
     840   // before the render loop ever starts. I should change this
     841
     842   VKUTIL_CHECK_RESULT(vkResetCommandPool(device, commandPools[imageIndex], 0),
     843      "failed to reset command pool!");
     844
     845   VkCommandBufferBeginInfo info = {};
     846   info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
     847   info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
     848
     849   VKUTIL_CHECK_RESULT(vkBeginCommandBuffer(commandBuffers[imageIndex], &info),
     850      "failed to begin recording command buffer!");
     851
     852   VkRenderPassBeginInfo renderPassInfo = {};
     853   renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
     854   renderPassInfo.renderPass = renderPass;
     855   renderPassInfo.framebuffer = swapChainFramebuffers[imageIndex];
     856   renderPassInfo.renderArea.extent = swapChainExtent;
     857
     858   array<VkClearValue, 2> clearValues = {};
     859   clearValues[0].color = { { 0.45f, 0.55f, 0.60f, 1.00f } };
     860   clearValues[1].depthStencil = { 1.0f, 0 };
     861
     862   renderPassInfo.clearValueCount = static_cast<uint32_t>(clearValues.size());
     863   renderPassInfo.pClearValues = clearValues.data();
     864
     865   vkCmdBeginRenderPass(commandBuffers[imageIndex], &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
     866
     867   // Record dear imgui primitives into command buffer
     868   ImGui_ImplVulkan_RenderDrawData(draw_data, commandBuffers[imageIndex]);
     869
     870   // Submit command buffer
     871   vkCmdEndRenderPass(commandBuffers[imageIndex]);
     872
     873   VKUTIL_CHECK_RESULT(vkEndCommandBuffer(commandBuffers[imageIndex]),
     874      "failed to record command buffer!");
     875
     876   // END OF NEW CODE
     877
     878   VkSemaphore waitSemaphores[] = { imageAcquiredSemaphores[currentFrame] };
     879   VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
     880   VkSemaphore signalSemaphores[] = { renderCompleteSemaphores[currentFrame] };
     881
     882   VkSubmitInfo submitInfo = {};
     883   submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
     884   submitInfo.waitSemaphoreCount = 1;
     885   submitInfo.pWaitSemaphores = waitSemaphores;
     886   submitInfo.pWaitDstStageMask = &wait_stage;
     887   submitInfo.commandBufferCount = 1;
     888   submitInfo.pCommandBuffers = &commandBuffers[imageIndex];
     889   submitInfo.signalSemaphoreCount = 1;
     890   submitInfo.pSignalSemaphores = signalSemaphores;
     891
     892   VKUTIL_CHECK_RESULT(vkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFences[imageIndex]),
     893      "failed to submit draw command buffer!");
     894}
     895
     896void VulkanGame::presentFrame() {
     897   if (g_SwapChainRebuild)
     898      return;
     899
     900   VkSemaphore signalSemaphores[] = { renderCompleteSemaphores[currentFrame] };
     901
     902   VkPresentInfoKHR presentInfo = {};
     903   presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
     904   presentInfo.waitSemaphoreCount = 1;
     905   presentInfo.pWaitSemaphores = signalSemaphores;
     906   presentInfo.swapchainCount = 1;
     907   presentInfo.pSwapchains = &swapChain;
     908   presentInfo.pImageIndices = &imageIndex;
     909   presentInfo.pResults = nullptr;
     910
     911   VkResult result = vkQueuePresentKHR(presentQueue, &presentInfo);
     912
     913   // In vulkan-game, I also handle VK_SUBOPTIMAL_KHR and framebufferResized. g_SwapChainRebuild is kind of similar
     914   // to framebufferResized, but not quite the same
     915   if (result == VK_ERROR_OUT_OF_DATE_KHR) {
     916      g_SwapChainRebuild = true;
     917      return;
     918   }
     919   else if (result != VK_SUCCESS) {
     920      throw runtime_error("failed to present swap chain image!");
     921   }
     922
     923   currentFrame = (currentFrame + 1) % swapChainImageCount;
     924}
     925
    926926void VulkanGame::recreateSwapChain() {
    927927   if (vkDeviceWaitIdle(device) != VK_SUCCESS) {
     
    977977   vkDestroySwapchainKHR(device, swapChain, nullptr);
    978978}
    979 
    980 /********************************************** END OF NEW CODE **********************************************/
  • sdl-game.hpp

    r9c0a614 r4e2c709  
    111111      void createSyncObjects();
    112112
     113      void renderFrame(ImDrawData* draw_data);
     114      void presentFrame();
     115
    113116      void recreateSwapChain();
    114117
     
    118121      VkDescriptorPool descriptorPool;
    119122
    120    // Helper methods from imgui_impl_vulkan that were moved into VulkanGame to give them access to class instance variables
    121    public:
    122       void FrameRender(ImDrawData* draw_data);
    123       void FramePresent();
    124 
    125123};
    126124
  • vulkan-game.cpp

    r9c0a614 r4e2c709  
    942942         sdlOverlayImage, graphicsQueue);
    943943
    944       renderScene();
     944      renderFrame();
     945      presentFrame();
    945946   }
    946947}
     
    11391140}
    11401141
    1141 // TODO: Maybe move all/most of this to the base Screen class
    1142 void VulkanGame::renderScene() {
    1143    // TODO: Recreate the swap chain here if the user went to a new screen
    1144 
    1145    VkResult result = vkAcquireNextImageKHR(device, swapChain, numeric_limits<uint64_t>::max(),
    1146       imageAcquiredSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex);
    1147 
    1148    if (result == VK_ERROR_OUT_OF_DATE_KHR) {
    1149       recreateSwapChain();
    1150       return;
    1151    } else if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) {
    1152       throw runtime_error("failed to acquire swap chain image!");
    1153    }
    1154 
    1155    if (vkWaitForFences(device, 1, &inFlightFences[imageIndex], VK_TRUE, numeric_limits<uint64_t>::max()) != VK_SUCCESS) {
    1156       throw runtime_error("failed waiting for fence!");
    1157    }
    1158    if (vkResetFences(device, 1, &inFlightFences[imageIndex]) != VK_SUCCESS) {
    1159       throw runtime_error("failed to reset fence!");
    1160    }
    1161 
    1162    updateScene();
    1163 
    1164    VkSemaphore waitSemaphores[] = { imageAcquiredSemaphores[currentFrame] };
    1165    VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
    1166    VkSemaphore signalSemaphores[] = { renderCompleteSemaphores[currentFrame] };
    1167 
    1168    VkSubmitInfo submitInfo = {};
    1169    submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
    1170    submitInfo.waitSemaphoreCount = 1;
    1171    submitInfo.pWaitSemaphores = waitSemaphores;
    1172    submitInfo.pWaitDstStageMask = waitStages;
    1173    submitInfo.commandBufferCount = 1;
    1174    submitInfo.pCommandBuffers = &commandBuffers[imageIndex];
    1175    submitInfo.signalSemaphoreCount = 1;
    1176    submitInfo.pSignalSemaphores = signalSemaphores;
    1177 
    1178    if (vkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFences[imageIndex]) != VK_SUCCESS) {
    1179       throw runtime_error("failed to submit draw command buffer!");
    1180    }
    1181 
    1182    VkPresentInfoKHR presentInfo = {};
    1183    presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
    1184    presentInfo.waitSemaphoreCount = 1;
    1185    presentInfo.pWaitSemaphores = signalSemaphores;
    1186    presentInfo.swapchainCount = 1;
    1187    presentInfo.pSwapchains = &swapChain;
    1188    presentInfo.pImageIndices = &imageIndex;
    1189    presentInfo.pResults = nullptr;
    1190 
    1191    result = vkQueuePresentKHR(presentQueue, &presentInfo);
    1192 
    1193    if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || framebufferResized) {
    1194       framebufferResized = false;
    1195       recreateSwapChain();
    1196    } else if (result != VK_SUCCESS) {
    1197       throw runtime_error("failed to present swap chain image!");
    1198    }
    1199 
    1200    currentFrame = (currentFrame + 1) % swapChainImageCount;
    1201 }
    1202 
    12031142void VulkanGame::cleanup() {
    12041143   if (vkDeviceWaitIdle(device) != VK_SUCCESS) {
     
    18061745      }
    18071746   }
     1747}
     1748
     1749void VulkanGame::renderFrame() {
     1750   VkResult result = vkAcquireNextImageKHR(device, swapChain, numeric_limits<uint64_t>::max(),
     1751      imageAcquiredSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex);
     1752
     1753   if (result == VK_ERROR_OUT_OF_DATE_KHR) {
     1754      recreateSwapChain();
     1755      return;
     1756   } else if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) {
     1757      throw runtime_error("failed to acquire swap chain image!");
     1758   }
     1759
     1760   if (vkWaitForFences(device, 1, &inFlightFences[imageIndex], VK_TRUE, numeric_limits<uint64_t>::max()) != VK_SUCCESS) {
     1761      throw runtime_error("failed waiting for fence!");
     1762   }
     1763   if (vkResetFences(device, 1, &inFlightFences[imageIndex]) != VK_SUCCESS) {
     1764      throw runtime_error("failed to reset fence!");
     1765   }
     1766
     1767   updateScene();
     1768
     1769   VkSemaphore waitSemaphores[] = { imageAcquiredSemaphores[currentFrame] };
     1770   VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
     1771   VkSemaphore signalSemaphores[] = { renderCompleteSemaphores[currentFrame] };
     1772
     1773   VkSubmitInfo submitInfo = {};
     1774   submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
     1775   submitInfo.waitSemaphoreCount = 1;
     1776   submitInfo.pWaitSemaphores = waitSemaphores;
     1777   submitInfo.pWaitDstStageMask = waitStages;
     1778   submitInfo.commandBufferCount = 1;
     1779   submitInfo.pCommandBuffers = &commandBuffers[imageIndex];
     1780   submitInfo.signalSemaphoreCount = 1;
     1781   submitInfo.pSignalSemaphores = signalSemaphores;
     1782
     1783   if (vkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFences[imageIndex]) != VK_SUCCESS) {
     1784      throw runtime_error("failed to submit draw command buffer!");
     1785   }
     1786}
     1787
     1788void VulkanGame::presentFrame() {
     1789   VkSemaphore signalSemaphores[] = { renderCompleteSemaphores[currentFrame] };
     1790
     1791   VkPresentInfoKHR presentInfo = {};
     1792   presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
     1793   presentInfo.waitSemaphoreCount = 1;
     1794   presentInfo.pWaitSemaphores = signalSemaphores;
     1795   presentInfo.swapchainCount = 1;
     1796   presentInfo.pSwapchains = &swapChain;
     1797   presentInfo.pImageIndices = &imageIndex;
     1798   presentInfo.pResults = nullptr;
     1799
     1800   VkResult result = vkQueuePresentKHR(presentQueue, &presentInfo);
     1801
     1802   if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || framebufferResized) {
     1803      framebufferResized = false;
     1804      recreateSwapChain();
     1805   } else if (result != VK_SUCCESS) {
     1806      throw runtime_error("failed to present swap chain image!");
     1807   }
     1808
     1809   currentFrame = (currentFrame + 1) % swapChainImageCount;
    18081810}
    18091811
  • vulkan-game.hpp

    r9c0a614 r4e2c709  
    386386      void mainLoop();
    387387      void updateScene();
    388       void renderScene();
    389388      void cleanup();
    390389
     
    452451            vector<VkDescriptorBufferInfo>& bufferInfoList);
    453452
     453      void renderFrame();
     454      void presentFrame();
     455
    454456      void recreateSwapChain();
    455457
Note: See TracChangeset for help on using the changeset viewer.