2022-07-10 23:58:58 +00:00
|
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
|
|
{-# LANGUAGE DuplicateRecordFields #-}
|
|
|
|
{-# LANGUAGE DataKinds #-}
|
|
|
|
module Init where
|
|
|
|
|
|
|
|
import Control.Monad
|
|
|
|
import Control.Monad.IO.Class
|
|
|
|
import Control.Monad.Trans.Resource
|
|
|
|
import qualified Data.Vector as V
|
2022-07-14 09:02:12 +00:00
|
|
|
import Linear (V2)
|
2022-07-10 23:58:58 +00:00
|
|
|
import qualified SDL hiding (V2)
|
|
|
|
import qualified SDL.Video.Vulkan as SDL
|
2022-07-14 09:02:12 +00:00
|
|
|
import Foreign.C.Types (CInt)
|
2022-07-10 23:58:58 +00:00
|
|
|
import Foreign.Ptr
|
2022-07-14 05:02:10 +00:00
|
|
|
import qualified Vulkan.Core10 as Vk
|
|
|
|
import qualified Vulkan.Extensions.VK_KHR_swapchain as Khr
|
|
|
|
import qualified Vulkan.Extensions.VK_KHR_surface as Khr
|
2022-07-10 23:58:58 +00:00
|
|
|
|
|
|
|
-- internal imports
|
|
|
|
|
|
|
|
import Instance
|
|
|
|
import Devices
|
2022-07-14 05:02:10 +00:00
|
|
|
import GraphicsPipeline
|
|
|
|
import Framebuffers
|
|
|
|
import CommandBuffer
|
2022-07-10 23:58:58 +00:00
|
|
|
|
|
|
|
initEngine
|
2022-07-14 05:02:10 +00:00
|
|
|
:: (MonadResource m, MonadFail m)
|
|
|
|
=> m
|
|
|
|
( SDL.Window
|
2022-07-14 09:02:12 +00:00
|
|
|
, V2 CInt
|
2022-07-14 05:02:10 +00:00
|
|
|
, Vk.Device
|
|
|
|
, Khr.SwapchainKHR
|
|
|
|
, Vk.Queue
|
|
|
|
, V.Vector Vk.CommandBuffer
|
2022-07-16 14:36:51 +00:00
|
|
|
, V.Vector Vk.Framebuffer
|
2022-07-14 09:02:12 +00:00
|
|
|
, V.Vector Vk.Pipeline
|
|
|
|
, Vk.RenderPass
|
2022-07-14 05:02:10 +00:00
|
|
|
, Vk.Fence
|
|
|
|
, Vk.Semaphore
|
|
|
|
, Vk.Semaphore
|
|
|
|
)
|
2022-07-10 23:58:58 +00:00
|
|
|
initEngine = do
|
|
|
|
-- initialize SDL2 with all subsystems
|
|
|
|
void $ allocate_
|
|
|
|
SDL.initializeAll
|
|
|
|
(do
|
2022-07-12 14:31:40 +00:00
|
|
|
putStrLn "This is the end!"
|
2022-07-10 23:58:58 +00:00
|
|
|
SDL.quit
|
|
|
|
)
|
|
|
|
|
|
|
|
-- create a window configuration
|
|
|
|
let windowConfig = SDL.defaultWindow
|
|
|
|
{ SDL.windowGraphicsContext = SDL.VulkanContext -- enable Vulkan support
|
|
|
|
}
|
|
|
|
|
|
|
|
-- load vulkan library
|
|
|
|
SDL.vkLoadLibrary Nothing
|
|
|
|
|
|
|
|
-- create the window
|
|
|
|
(_, window) <-
|
|
|
|
allocate
|
|
|
|
(SDL.createWindow "Haskell ❤️ Vulkan" windowConfig)
|
|
|
|
(\window -> do
|
2022-07-12 14:31:40 +00:00
|
|
|
liftIO $ putStrLn "destroying window"
|
2022-07-10 23:58:58 +00:00
|
|
|
SDL.destroyWindow window
|
|
|
|
)
|
|
|
|
|
2022-07-14 05:02:10 +00:00
|
|
|
-- initialize viúlkan data structures
|
|
|
|
initVulkan window
|
2022-07-10 23:58:58 +00:00
|
|
|
|
|
|
|
initVulkan
|
2022-07-14 05:02:10 +00:00
|
|
|
:: (MonadResource m, MonadFail m)
|
2022-07-10 23:58:58 +00:00
|
|
|
=> SDL.Window
|
2022-07-14 05:02:10 +00:00
|
|
|
-> m
|
|
|
|
( SDL.Window
|
2022-07-14 09:02:12 +00:00
|
|
|
, V2 CInt
|
2022-07-14 05:02:10 +00:00
|
|
|
, Vk.Device
|
|
|
|
, Khr.SwapchainKHR
|
|
|
|
, Vk.Queue
|
|
|
|
, V.Vector Vk.CommandBuffer
|
2022-07-16 14:36:51 +00:00
|
|
|
, V.Vector Vk.Framebuffer
|
2022-07-14 09:02:12 +00:00
|
|
|
, V.Vector Vk.Pipeline
|
|
|
|
, Vk.RenderPass
|
2022-07-14 05:02:10 +00:00
|
|
|
, Vk.Fence
|
|
|
|
, Vk.Semaphore
|
|
|
|
, Vk.Semaphore
|
|
|
|
)
|
2022-07-10 23:58:58 +00:00
|
|
|
initVulkan window = do
|
|
|
|
|
|
|
|
vulkanInstance <- createInstance window
|
|
|
|
|
|
|
|
(_, vulkanSurface) <- allocate
|
2022-07-14 05:02:10 +00:00
|
|
|
(Khr.SurfaceKHR <$>
|
2022-07-10 23:58:58 +00:00
|
|
|
SDL.vkCreateSurface window (castPtr (Vk.instanceHandle vulkanInstance))
|
|
|
|
)
|
|
|
|
(\vulkanSurface -> do
|
2022-07-12 14:31:40 +00:00
|
|
|
putStrLn "destroying surface"
|
2022-07-14 05:02:10 +00:00
|
|
|
Khr.destroySurfaceKHR vulkanInstance vulkanSurface Nothing
|
2022-07-10 23:58:58 +00:00
|
|
|
)
|
|
|
|
|
2022-07-11 11:14:59 +00:00
|
|
|
vulkanPhysicalDevice <- pickPhysicalDevice vulkanInstance
|
|
|
|
(vulkanLogicalDevice, surfaceFormats) <- createLogicalDevice vulkanPhysicalDevice vulkanSurface
|
|
|
|
|
2022-07-10 23:58:58 +00:00
|
|
|
dimensions <- liftIO $ SDL.windowInitialSize <$> SDL.getWindowConfig window
|
2022-07-14 05:02:10 +00:00
|
|
|
(swapchain, surfaceFormat) <-
|
|
|
|
createSwapchain vulkanSurface surfaceFormats dimensions vulkanLogicalDevice
|
2022-07-11 12:01:04 +00:00
|
|
|
imageViews <- getImageViewHandles swapchain surfaceFormat vulkanLogicalDevice
|
2022-07-14 09:02:12 +00:00
|
|
|
vertexShader <- loadShader vulkanLogicalDevice "shadersrc/shader.vert" "vert"
|
|
|
|
fragmentShader <- loadShader vulkanLogicalDevice "shadersrc/shader.frag" "frag"
|
2022-07-14 05:02:10 +00:00
|
|
|
(pipelines, renderPass) <-
|
|
|
|
createGraphicsPipelines
|
|
|
|
vulkanLogicalDevice
|
|
|
|
vertexShader
|
|
|
|
fragmentShader
|
|
|
|
"main"
|
|
|
|
dimensions
|
|
|
|
(Khr.format surfaceFormat)
|
2022-07-16 14:36:51 +00:00
|
|
|
(length imageViews)
|
2022-07-10 23:58:58 +00:00
|
|
|
|
2022-07-16 14:36:51 +00:00
|
|
|
frameBuffers <- createFramebuffer vulkanLogicalDevice renderPass imageViews dimensions
|
2022-07-14 05:02:10 +00:00
|
|
|
|
|
|
|
(commandPool, graphicsQueue) <- createCommandPool vulkanPhysicalDevice vulkanLogicalDevice
|
2022-07-16 14:36:51 +00:00
|
|
|
commandBuffer <- createCommandBuffer vulkanLogicalDevice commandPool (length frameBuffers)
|
2022-07-14 05:02:10 +00:00
|
|
|
|
|
|
|
(imageAvailableSemaphore, renderFinishedSemaphore, inFlightFence) <-
|
|
|
|
createSyncObjects vulkanLogicalDevice
|
|
|
|
|
|
|
|
return
|
|
|
|
( window
|
2022-07-14 09:02:12 +00:00
|
|
|
, dimensions
|
2022-07-14 05:02:10 +00:00
|
|
|
, vulkanLogicalDevice
|
|
|
|
, swapchain
|
|
|
|
, graphicsQueue
|
|
|
|
, commandBuffer
|
2022-07-16 14:36:51 +00:00
|
|
|
, frameBuffers
|
2022-07-14 09:02:12 +00:00
|
|
|
, pipelines
|
|
|
|
, renderPass
|
2022-07-14 05:02:10 +00:00
|
|
|
, inFlightFence
|
|
|
|
, imageAvailableSemaphore
|
|
|
|
, renderFinishedSemaphore
|
|
|
|
)
|