{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE DuplicateRecordFields #-} {-# LANGUAGE FlexibleContexts #-} module Draw where import qualified Control.Concurrent.STM as STM import Control.Monad import Control.Monad.IO.Class import Control.Monad.Reader import Control.Monad.Trans.Resource import qualified Data.Map.Strict as M import qualified Data.Vector as V import qualified Vulkan.Core10 as Vk import qualified Vulkan.Extensions.VK_KHR_swapchain as Khr import qualified Vulkan.CStruct.Extends as Vk import qualified Vulkan.Zero as Vk -- internal imports import CommandBuffer import Types import Util (getFrame) drawFrame :: (MonadResource m, MonadFail m, MonadReader ReadState m) => EngineData -> Int -> m () drawFrame engineData frameNumber = do let frame = getFrame engineData frameNumber void $ Vk.waitForFences (engineLogicalDevice engineData) (V.singleton $ frameRenderFence frame) True maxBound Vk.resetFences (engineLogicalDevice engineData) (V.singleton $ frameRenderFence frame) (imageResult, index) <- Khr.acquireNextImageKHR (engineLogicalDevice engineData) (engineSwapchain engineData) maxBound (frameRenderSemaphore frame) Vk.NULL_HANDLE unless (imageResult == Vk.SUCCESS) $ error "drawFrame: Failed acquiring next image from swapchain" -- liftIO $ putStrLn "resetting command buffer" Vk.resetCommandBuffer (frameMainCommandBuffer frame) (Vk.CommandBufferResetFlagBits 0) matLibrary <- (liftIO . STM.atomically. STM.readTMVar) =<< asks materialLibrary -- liftIO $ putStrLn "recording command buffer" recordCommandBuffer (frameMainCommandBuffer frame) (engineRenderPass engineData) (engineFramebuffers engineData V.! fromIntegral index) (engineWindowDimensions engineData) (materialPipeline $ matLibrary M.! "defaultMesh") (meshPipelineLayout engineData) let submitInfo = Vk.zero { Vk.waitSemaphores = V.singleton $ frameRenderSemaphore frame , Vk.waitDstStageMask = V.singleton Vk.PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT , Vk.commandBuffers = V.singleton (Vk.commandBufferHandle $ frameMainCommandBuffer frame) , Vk.signalSemaphores = V.singleton $ framePresentSemaphore frame } -- liftIO $ putStrLn "submitting to queue" Vk.queueSubmit (engineQueue engineData) (V.singleton (Vk.SomeStruct submitInfo)) (frameRenderFence frame) let presentInfo = Vk.zero { Khr.waitSemaphores = V.singleton $ framePresentSemaphore frame , Khr.swapchains = V.singleton $ engineSwapchain engineData , Khr.imageIndices = V.singleton index } -- liftIO $ putStrLn "presenting queue" presentResult <- Khr.queuePresentKHR (engineQueue engineData) presentInfo unless (presentResult == Vk.SUCCESS) $ error "drawFrame: presentation failed"