2022-07-13 17:29:38 +00:00
|
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
|
|
{-# LANGUAGE DuplicateRecordFields #-}
|
|
|
|
{-# LANGUAGE DataKinds #-}
|
|
|
|
module CommandBuffer where
|
|
|
|
|
|
|
|
import Control.Monad
|
2022-12-11 08:02:17 +00:00
|
|
|
import Control.Monad.IO.Class
|
2022-07-13 17:29:38 +00:00
|
|
|
import Control.Monad.Trans.Resource
|
|
|
|
import qualified Data.Vector as V
|
2022-12-11 08:02:17 +00:00
|
|
|
import Foreign
|
2022-07-13 17:29:38 +00:00
|
|
|
import Foreign.C.Types (CInt)
|
|
|
|
import Linear
|
|
|
|
import qualified Vulkan as Vk
|
|
|
|
import qualified Vulkan.Zero as Vk
|
|
|
|
|
|
|
|
-- internal imports
|
|
|
|
|
|
|
|
import Devices
|
2022-12-03 00:44:06 +00:00
|
|
|
import Types
|
2022-07-13 17:29:38 +00:00
|
|
|
|
|
|
|
createCommandPool
|
|
|
|
:: (MonadResource m)
|
|
|
|
=> Vk.PhysicalDevice
|
|
|
|
-> Vk.Device
|
2022-07-14 05:02:10 +00:00
|
|
|
-> m (Vk.CommandPool, Vk.Queue)
|
2022-07-13 17:29:38 +00:00
|
|
|
createCommandPool physicalDevice logicalDevice = do
|
|
|
|
|
|
|
|
queueFamilyIndex <- getQueueFamily physicalDevice Vk.QUEUE_GRAPHICS_BIT
|
|
|
|
|
|
|
|
let poolCreateInfo = Vk.zero
|
|
|
|
{ Vk.flags = Vk.COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT
|
|
|
|
, Vk.queueFamilyIndex = queueFamilyIndex
|
|
|
|
} :: Vk.CommandPoolCreateInfo
|
|
|
|
|
2022-07-14 05:02:10 +00:00
|
|
|
graphicsQueue <- Vk.getDeviceQueue logicalDevice queueFamilyIndex 0
|
|
|
|
|
|
|
|
commandPool <- snd <$> allocate
|
2022-07-13 17:29:38 +00:00
|
|
|
(Vk.createCommandPool logicalDevice poolCreateInfo Nothing)
|
|
|
|
(\commandPool -> do
|
2022-07-16 19:50:22 +00:00
|
|
|
putStrLn "destroying command pool"
|
2022-07-13 17:29:38 +00:00
|
|
|
Vk.destroyCommandPool logicalDevice commandPool Nothing
|
|
|
|
)
|
|
|
|
|
2022-07-14 05:02:10 +00:00
|
|
|
return (commandPool, graphicsQueue)
|
|
|
|
|
2022-07-13 17:29:38 +00:00
|
|
|
createCommandBuffer
|
|
|
|
:: (MonadResource m)
|
2022-07-14 05:02:10 +00:00
|
|
|
=> Vk.Device
|
|
|
|
-> Vk.CommandPool
|
2022-07-16 14:36:51 +00:00
|
|
|
-> Int
|
2022-07-13 17:29:38 +00:00
|
|
|
-> m (V.Vector Vk.CommandBuffer)
|
2022-07-16 14:36:51 +00:00
|
|
|
createCommandBuffer logicalDevice commandPool number = do
|
2022-07-13 17:29:38 +00:00
|
|
|
|
|
|
|
let commandBufferAllocationInfo = Vk.zero
|
|
|
|
{ Vk.commandPool = commandPool
|
|
|
|
, Vk.level = Vk.COMMAND_BUFFER_LEVEL_PRIMARY
|
|
|
|
, Vk.commandBufferCount = 1
|
|
|
|
}
|
|
|
|
|
2022-07-16 14:36:51 +00:00
|
|
|
V.concat <$>
|
|
|
|
replicateM number (Vk.allocateCommandBuffers logicalDevice commandBufferAllocationInfo)
|
2022-07-13 17:29:38 +00:00
|
|
|
|
|
|
|
recordCommandBuffer
|
|
|
|
:: (MonadResource m)
|
|
|
|
=> Vk.CommandBuffer
|
|
|
|
-> Vk.RenderPass
|
|
|
|
-> Vk.Framebuffer
|
|
|
|
-> V2 CInt
|
|
|
|
-> Vk.Pipeline
|
2022-12-11 08:02:17 +00:00
|
|
|
-> Vk.PipelineLayout
|
2022-12-03 00:44:06 +00:00
|
|
|
-> Maybe Mesh
|
2022-12-11 08:02:17 +00:00
|
|
|
-> Int
|
2022-07-13 17:29:38 +00:00
|
|
|
-> m ()
|
2022-12-03 00:44:06 +00:00
|
|
|
recordCommandBuffer
|
|
|
|
commandBuffer
|
|
|
|
renderPass
|
|
|
|
frameBuffer
|
|
|
|
(V2 width height)
|
|
|
|
graphicsPipeline
|
2022-12-11 08:02:17 +00:00
|
|
|
meshLayout
|
2022-12-03 00:44:06 +00:00
|
|
|
mesh
|
2022-12-11 08:02:17 +00:00
|
|
|
frameNumber
|
2022-12-03 00:44:06 +00:00
|
|
|
= do
|
|
|
|
|
|
|
|
let commandBufferBeginInfo = Vk.zero
|
|
|
|
{ Vk.flags = Vk.COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT
|
|
|
|
, Vk.inheritanceInfo = Nothing
|
|
|
|
}
|
2022-07-13 17:29:38 +00:00
|
|
|
|
2022-12-03 00:44:06 +00:00
|
|
|
Vk.beginCommandBuffer commandBuffer commandBufferBeginInfo
|
|
|
|
|
|
|
|
let renderPassInfo = Vk.zero
|
|
|
|
{ Vk.renderPass = renderPass
|
|
|
|
, Vk.framebuffer = frameBuffer
|
|
|
|
, Vk.renderArea = Vk.Rect2D
|
|
|
|
{ offset = Vk.Offset2D
|
|
|
|
{ Vk.x = 0
|
|
|
|
, Vk.y = 0
|
|
|
|
}
|
|
|
|
, extent = Vk.Extent2D
|
|
|
|
{ Vk.width = fromIntegral width
|
|
|
|
, Vk.height = fromIntegral height
|
|
|
|
}
|
|
|
|
}
|
2022-12-28 03:18:54 +00:00
|
|
|
, Vk.clearValues = V.fromList [ Vk.Color (Vk.Float32 0 0 0 1), Vk.DepthStencil (Vk.ClearDepthStencilValue 1 0)]
|
2022-12-03 00:44:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Vk.cmdBeginRenderPass commandBuffer renderPassInfo Vk.SUBPASS_CONTENTS_INLINE
|
2022-07-13 17:29:38 +00:00
|
|
|
|
2022-12-03 00:44:06 +00:00
|
|
|
Vk.cmdBindPipeline commandBuffer Vk.PIPELINE_BIND_POINT_GRAPHICS graphicsPipeline
|
2022-07-13 17:29:38 +00:00
|
|
|
|
2022-12-03 00:44:06 +00:00
|
|
|
let viewport = Vk.zero
|
|
|
|
{ Vk.x = 0
|
|
|
|
, Vk.y = 0
|
|
|
|
, Vk.width = fromIntegral width
|
|
|
|
, Vk.height = fromIntegral height
|
|
|
|
, Vk.minDepth = 0
|
|
|
|
, Vk.maxDepth = 1
|
|
|
|
}
|
|
|
|
scissor = Vk.Rect2D
|
|
|
|
{ Vk.offset = Vk.Offset2D
|
2022-07-13 17:29:38 +00:00
|
|
|
{ Vk.x = 0
|
|
|
|
, Vk.y = 0
|
|
|
|
}
|
2022-12-03 00:44:06 +00:00
|
|
|
, Vk.extent = Vk.Extent2D
|
|
|
|
{ Vk.width = fromIntegral width
|
2022-07-13 17:29:38 +00:00
|
|
|
, Vk.height = fromIntegral height
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-03 00:44:06 +00:00
|
|
|
Vk.cmdSetViewport commandBuffer 0 (V.singleton viewport)
|
|
|
|
Vk.cmdSetScissor commandBuffer 0 (V.singleton scissor)
|
2022-07-13 17:29:38 +00:00
|
|
|
|
2022-12-11 08:02:17 +00:00
|
|
|
liftIO $ maybe
|
2022-12-03 00:44:06 +00:00
|
|
|
(Vk.cmdDraw commandBuffer 3 1 0 0)
|
|
|
|
(\jmesh -> do
|
2022-12-28 03:18:54 +00:00
|
|
|
let camPosition = V3 0 0 (-5)
|
2022-12-11 08:02:17 +00:00
|
|
|
camCenter = V3 0 0 0
|
|
|
|
camUp = V3 0 1 0
|
|
|
|
view = lookAt camPosition camCenter camUp
|
|
|
|
projection = perspective (pi/4) (800 / 600) 0.1 200
|
|
|
|
modelRot = axisAngle (V3 0 1 0) (fromIntegral frameNumber / (10 * pi))
|
|
|
|
model = mkTransformation modelRot (V3 0 0 0)
|
|
|
|
pvm = projection !*! view !*! model
|
|
|
|
constants = MeshPushConstants (V4 0 0 0 0) (transpose pvm)
|
|
|
|
|
|
|
|
pointer <- castPtr <$> new constants
|
|
|
|
Vk.cmdPushConstants
|
|
|
|
commandBuffer
|
|
|
|
meshLayout
|
|
|
|
Vk.SHADER_STAGE_VERTEX_BIT
|
|
|
|
0
|
|
|
|
(fromIntegral $ sizeOf constants)
|
|
|
|
pointer
|
|
|
|
|
2022-12-03 00:44:06 +00:00
|
|
|
Vk.cmdBindVertexBuffers
|
|
|
|
commandBuffer
|
|
|
|
0
|
|
|
|
(V.fromList [ allocatedBuffer $ meshBuffer jmesh ])
|
|
|
|
(V.fromList [ 0 ])
|
2022-07-13 17:29:38 +00:00
|
|
|
|
2022-12-03 00:44:06 +00:00
|
|
|
Vk.cmdDraw commandBuffer (fromIntegral $ V.length $ meshVertices jmesh) 1 0 0
|
|
|
|
)
|
|
|
|
mesh
|
2022-07-13 17:29:38 +00:00
|
|
|
|
2022-12-03 00:44:06 +00:00
|
|
|
Vk.cmdEndRenderPass commandBuffer
|
2022-07-14 00:23:29 +00:00
|
|
|
|
2022-12-03 00:44:06 +00:00
|
|
|
Vk.endCommandBuffer commandBuffer
|
2022-07-14 00:23:29 +00:00
|
|
|
|
|
|
|
createSyncObjects
|
|
|
|
:: (MonadResource m, MonadFail m)
|
|
|
|
=> Vk.Device
|
|
|
|
-> m (Vk.Semaphore, Vk.Semaphore, Vk.Fence)
|
|
|
|
createSyncObjects logicalDevice = do
|
|
|
|
|
|
|
|
let semaphoreCreateInfo = Vk.zero
|
|
|
|
fenceCreateInfo = Vk.zero
|
2022-07-14 05:02:10 +00:00
|
|
|
{ Vk.flags = Vk.FENCE_CREATE_SIGNALED_BIT
|
|
|
|
} :: Vk.FenceCreateInfo '[]
|
2022-07-14 00:23:29 +00:00
|
|
|
|
|
|
|
[imageAvailableSemaphore, renderFinishedSemaphore] <- replicateM 2
|
|
|
|
(snd <$> allocate
|
|
|
|
(Vk.createSemaphore logicalDevice semaphoreCreateInfo Nothing)
|
|
|
|
(\semaphore -> do
|
|
|
|
putStrLn "destroying semaphore"
|
|
|
|
Vk.destroySemaphore logicalDevice semaphore Nothing
|
|
|
|
)
|
|
|
|
)
|
2022-07-14 09:02:12 +00:00
|
|
|
inFlightFence <- snd <$> allocate
|
|
|
|
(Vk.createFence logicalDevice fenceCreateInfo Nothing)
|
|
|
|
(\fence -> do
|
|
|
|
putStrLn "destroying fence"
|
|
|
|
Vk.destroyFence logicalDevice fence Nothing
|
|
|
|
)
|
2022-07-14 00:23:29 +00:00
|
|
|
|
2022-07-14 05:02:10 +00:00
|
|
|
return (imageAvailableSemaphore, renderFinishedSemaphore, inFlightFence)
|