2022-07-14 05:02:10 +00:00
|
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
|
|
{-# LANGUAGE DuplicateRecordFields #-}
|
2023-01-05 22:07:21 +00:00
|
|
|
{-# LANGUAGE FlexibleContexts #-}
|
2022-07-14 05:02:10 +00:00
|
|
|
module Draw where
|
|
|
|
|
2023-01-05 22:07:21 +00:00
|
|
|
import qualified Control.Concurrent.STM as STM
|
2022-07-14 05:02:10 +00:00
|
|
|
import Control.Monad
|
2023-01-05 22:07:21 +00:00
|
|
|
import Control.Monad.IO.Class
|
|
|
|
import Control.Monad.Reader
|
2022-07-14 05:02:10 +00:00
|
|
|
import Control.Monad.Trans.Resource
|
2023-01-05 22:07:21 +00:00
|
|
|
import qualified Data.Map.Strict as M
|
2022-07-14 05:02:10 +00:00
|
|
|
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
|
|
|
|
|
2022-07-14 09:02:12 +00:00
|
|
|
-- internal imports
|
|
|
|
|
|
|
|
import CommandBuffer
|
2022-07-16 19:50:22 +00:00
|
|
|
import Types
|
2022-07-14 05:02:10 +00:00
|
|
|
|
|
|
|
drawFrame
|
2023-01-05 22:07:21 +00:00
|
|
|
:: (MonadResource m, MonadFail m, MonadReader ReadState m)
|
2022-07-16 19:50:22 +00:00
|
|
|
=> EngineData
|
2022-07-14 05:02:10 +00:00
|
|
|
-> m ()
|
2023-01-05 22:07:21 +00:00
|
|
|
drawFrame engineData = do
|
2022-07-16 19:50:22 +00:00
|
|
|
|
|
|
|
unless (all (V.length (engineCommandBuffers engineData) ==)
|
|
|
|
[ V.length (engineCommandBuffers engineData)
|
|
|
|
, V.length (engineFramebuffers engineData)
|
|
|
|
]) $
|
|
|
|
error ("Numbers of elements mismatch: command buffers " <>
|
|
|
|
show (V.length $ engineCommandBuffers engineData) <>
|
2022-10-26 14:52:55 +00:00
|
|
|
", frame buffers " <> show (V.length $ engineFramebuffers engineData)
|
|
|
|
)
|
2022-07-16 19:50:22 +00:00
|
|
|
|
|
|
|
let fences = V.singleton $ engineInFlightFence engineData
|
|
|
|
|
|
|
|
void $ Vk.waitForFences (engineLogicalDevice engineData) fences True maxBound
|
|
|
|
Vk.resetFences (engineLogicalDevice engineData) fences
|
|
|
|
|
|
|
|
(imageResult, index) <-
|
|
|
|
Khr.acquireNextImageKHR
|
|
|
|
(engineLogicalDevice engineData)
|
|
|
|
(engineSwapchain engineData)
|
|
|
|
maxBound
|
|
|
|
(engineImageAvailableSemaphore engineData)
|
|
|
|
Vk.NULL_HANDLE
|
|
|
|
|
|
|
|
unless (imageResult == Vk.SUCCESS) $
|
|
|
|
error "drawFrame: Failed acquiring next image from swapchain"
|
|
|
|
|
|
|
|
-- liftIO $ putStrLn "resetting command buffer"
|
|
|
|
Vk.resetCommandBuffer
|
|
|
|
(engineCommandBuffers engineData V.! fromIntegral index) (Vk.CommandBufferResetFlagBits 0)
|
|
|
|
|
2023-01-05 22:07:21 +00:00
|
|
|
matLibrary <- (liftIO . STM.atomically. STM.readTMVar) =<< asks materialLibrary
|
|
|
|
|
2022-07-16 19:50:22 +00:00
|
|
|
-- liftIO $ putStrLn "recording command buffer"
|
|
|
|
recordCommandBuffer
|
|
|
|
(engineCommandBuffers engineData V.! fromIntegral index)
|
|
|
|
(engineRenderPass engineData)
|
|
|
|
(engineFramebuffers engineData V.! fromIntegral index)
|
|
|
|
(engineWindowDimensions engineData)
|
2023-01-05 22:07:21 +00:00
|
|
|
(materialPipeline $ matLibrary M.! "defaultMesh")
|
2022-12-11 08:02:17 +00:00
|
|
|
(meshPipelineLayout engineData)
|
2022-07-16 19:50:22 +00:00
|
|
|
|
|
|
|
let submitInfo = Vk.zero
|
|
|
|
{ Vk.waitSemaphores =
|
|
|
|
V.singleton $ engineImageAvailableSemaphore engineData
|
|
|
|
, Vk.waitDstStageMask =
|
|
|
|
V.singleton Vk.PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
|
|
|
|
, Vk.commandBuffers =
|
|
|
|
V.singleton (Vk.commandBufferHandle $ engineCommandBuffers engineData V.! fromIntegral index)
|
|
|
|
, Vk.signalSemaphores =
|
|
|
|
V.singleton $ engineRenderFinishedSemaphore engineData
|
|
|
|
}
|
|
|
|
|
|
|
|
-- liftIO $ putStrLn "submitting to queue"
|
|
|
|
Vk.queueSubmit
|
|
|
|
(engineQueue engineData)
|
|
|
|
(V.singleton (Vk.SomeStruct submitInfo))
|
|
|
|
(engineInFlightFence engineData)
|
|
|
|
|
|
|
|
let presentInfo = Vk.zero
|
|
|
|
{ Khr.waitSemaphores = V.singleton $ engineRenderFinishedSemaphore engineData
|
|
|
|
, 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"
|