96 lines
2.9 KiB
Haskell
96 lines
2.9 KiB
Haskell
{-# 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)
|
|
(engineAllocator engineData)
|
|
frame
|
|
frameNumber
|
|
|
|
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"
|