almost drawing, just fix shaders

This commit is contained in:
nek0 2022-07-14 07:02:10 +02:00
parent bfb3b1a814
commit 83950010ac
7 changed files with 174 additions and 38 deletions

View file

@ -19,7 +19,7 @@ createCommandPool
:: (MonadResource m) :: (MonadResource m)
=> Vk.PhysicalDevice => Vk.PhysicalDevice
-> Vk.Device -> Vk.Device
-> m Vk.CommandPool -> m (Vk.CommandPool, Vk.Queue)
createCommandPool physicalDevice logicalDevice = do createCommandPool physicalDevice logicalDevice = do
queueFamilyIndex <- getQueueFamily physicalDevice Vk.QUEUE_GRAPHICS_BIT queueFamilyIndex <- getQueueFamily physicalDevice Vk.QUEUE_GRAPHICS_BIT
@ -29,19 +29,23 @@ createCommandPool physicalDevice logicalDevice = do
, Vk.queueFamilyIndex = queueFamilyIndex , Vk.queueFamilyIndex = queueFamilyIndex
} :: Vk.CommandPoolCreateInfo } :: Vk.CommandPoolCreateInfo
snd <$> allocate graphicsQueue <- Vk.getDeviceQueue logicalDevice queueFamilyIndex 0
commandPool <- snd <$> allocate
(Vk.createCommandPool logicalDevice poolCreateInfo Nothing) (Vk.createCommandPool logicalDevice poolCreateInfo Nothing)
(\commandPool -> do (\commandPool -> do
putStrLn "destroying comman pool" putStrLn "destroying comman pool"
Vk.destroyCommandPool logicalDevice commandPool Nothing Vk.destroyCommandPool logicalDevice commandPool Nothing
) )
return (commandPool, graphicsQueue)
createCommandBuffer createCommandBuffer
:: (MonadResource m) :: (MonadResource m)
=> Vk.CommandPool => Vk.Device
-> Vk.Device -> Vk.CommandPool
-> m (V.Vector Vk.CommandBuffer) -> m (V.Vector Vk.CommandBuffer)
createCommandBuffer commandPool logicalDevice = do createCommandBuffer logicalDevice commandPool = do
let commandBufferAllocationInfo = Vk.zero let commandBufferAllocationInfo = Vk.zero
{ Vk.commandPool = commandPool { Vk.commandPool = commandPool
@ -123,6 +127,8 @@ createSyncObjects logicalDevice = do
let semaphoreCreateInfo = Vk.zero let semaphoreCreateInfo = Vk.zero
fenceCreateInfo = Vk.zero fenceCreateInfo = Vk.zero
{ Vk.flags = Vk.FENCE_CREATE_SIGNALED_BIT
} :: Vk.FenceCreateInfo '[]
[imageAvailableSemaphore, renderFinishedSemaphore] <- replicateM 2 [imageAvailableSemaphore, renderFinishedSemaphore] <- replicateM 2
(snd <$> allocate (snd <$> allocate

65
src/Draw.hs Normal file
View file

@ -0,0 +1,65 @@
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DuplicateRecordFields #-}
module Draw where
import Control.Monad
import Control.Monad.Trans.Resource
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
drawFrame
:: (MonadResource m)
=> Vk.Device
-> Khr.SwapchainKHR
-> Vk.Queue
-> Vk.CommandBuffer
-> Vk.Fence
-> Vk.Semaphore
-> Vk.Semaphore
-> m ()
drawFrame
logicalDevice
swapchain
graphicsQueue
commandBuffer
inFlightFence
imageAvailableSemaphore
renderFinishedSemaphore
= do
let fences = V.singleton inFlightFence
void $ Vk.waitForFences logicalDevice fences True maxBound
Vk.resetFences logicalDevice fences
(imageResult, index) <-
Khr.acquireNextImageKHR logicalDevice swapchain maxBound imageAvailableSemaphore inFlightFence
unless (imageResult == Vk.SUCCESS) $
error "drawFrame: Failed acquiring next image from swapchain"
Vk.resetCommandBuffer commandBuffer (Vk.CommandBufferResetFlagBits 0)
let submitInfo = Vk.zero
{ Vk.waitSemaphores = V.singleton imageAvailableSemaphore
, Vk.waitDstStageMask = V.singleton Vk.PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
, Vk.commandBuffers = V.singleton (Vk.commandBufferHandle commandBuffer)
, Vk.signalSemaphores = V.singleton renderFinishedSemaphore
}
Vk.queueSubmit graphicsQueue (V.singleton (Vk.SomeStruct submitInfo)) inFlightFence
let presentInfo = Vk.zero
{ Khr.waitSemaphores = V.singleton renderFinishedSemaphore
, Khr.swapchains = V.singleton swapchain
, Khr.imageIndices = V.singleton index
}
presentResult <- Khr.queuePresentKHR graphicsQueue presentInfo
unless (presentResult == Vk.SUCCESS) $
error "drawFrame: presentation failed"

View file

@ -4,26 +4,21 @@
module Framebuffers where module Framebuffers where
import Linear import Linear
import Control.Monad (unless)
import Control.Monad.IO.Class (liftIO)
import Control.Monad.Trans.Resource import Control.Monad.Trans.Resource
import Data.Bits
import qualified Data.ByteString as BS
import qualified Data.Vector as V import qualified Data.Vector as V
import Foreign.C.Types (CInt) import Foreign.C.Types (CInt)
import qualified Vulkan as Vk import qualified Vulkan as Vk
import qualified Vulkan.Zero as Vk import qualified Vulkan.Zero as Vk
import qualified Vulkan.CStruct.Extends as Vk
createFramebuffer createFramebuffer
:: (MonadResource m) :: (MonadResource m)
=> Vk.RenderPass => Vk.Device
-> Vk.RenderPass
-> V.Vector Vk.ImageView -> V.Vector Vk.ImageView
-> V2 CInt -> V2 CInt
-> Vk.Device
-> m Vk.Framebuffer -> m Vk.Framebuffer
createFramebuffer renderPass swapchainImageViews (V2 swapchainWidth swapcheinHeight) logicalDevice createFramebuffer logicalDevice renderPass swapchainImageViews (V2 swapchainWidth swapcheinHeight)
= do = do
let framebufferCreateInfo = Vk.zero let framebufferCreateInfo = Vk.zero

View file

@ -11,7 +11,7 @@ import Data.Bits
import qualified Data.ByteString as BS import qualified Data.ByteString as BS
import qualified Data.Vector as V import qualified Data.Vector as V
import Foreign.C.Types (CInt) import Foreign.C.Types (CInt)
import qualified Vulkan as Vk import qualified Vulkan.Core10 as Vk
import qualified Vulkan.Zero as Vk import qualified Vulkan.Zero as Vk
import qualified Vulkan.CStruct.Extends as Vk import qualified Vulkan.CStruct.Extends as Vk
@ -36,20 +36,20 @@ loadShader logicalDevice shaderPath = do
createGraphicsPipelines createGraphicsPipelines
:: (MonadResource m) :: (MonadResource m)
=> Vk.ShaderModule => Vk.Device
-> Vk.ShaderModule
-> Vk.ShaderModule -> Vk.ShaderModule
-> BS.ByteString -> BS.ByteString
-> V2 CInt -> V2 CInt
-> Vk.Format -> Vk.Format
-> Vk.Device -> m (V.Vector Vk.Pipeline, Vk.RenderPass)
-> m (V.Vector Vk.Pipeline)
createGraphicsPipelines createGraphicsPipelines
logicalDevice
vertexShaderModule vertexShaderModule
fragmentShaderModule fragmentShaderModule
stageName stageName
(V2 width height) (V2 width height)
swapchainImageFormat swapchainImageFormat
logicalDevice
= do = do
let vertexShaderStageCreateInfo = Vk.zero let vertexShaderStageCreateInfo = Vk.zero
@ -160,10 +160,16 @@ createGraphicsPipelines
{ Vk.pipelineBindPoint = Vk.PIPELINE_BIND_POINT_GRAPHICS { Vk.pipelineBindPoint = Vk.PIPELINE_BIND_POINT_GRAPHICS
, Vk.colorAttachments = V.singleton colorAttachmentReference , Vk.colorAttachments = V.singleton colorAttachmentReference
} }
subpassDependency = Vk.zero
{ Vk.srcSubpass = Vk.SUBPASS_EXTERNAL
, Vk.dstSubpass = 0
, Vk.srcStageMask = Vk.PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
, Vk.srcAccessMask = Vk.ACCESS_COLOR_ATTACHMENT_WRITE_BIT
}
renderPassCreateInfo = Vk.zero renderPassCreateInfo = Vk.zero
{ Vk.attachments = V.singleton colorAttachmentDescription { Vk.attachments = V.singleton colorAttachmentDescription
, Vk.subpasses = V.singleton subpassDescriptor , Vk.subpasses = V.singleton subpassDescriptor
, Vk.dependencies = V.empty , Vk.dependencies = V.singleton subpassDependency
} :: Vk.RenderPassCreateInfo '[] } :: Vk.RenderPassCreateInfo '[]
pipelineRenderPass <- snd <$> allocate pipelineRenderPass <- snd <$> allocate
@ -190,7 +196,7 @@ createGraphicsPipelines
, Vk.basePipelineIndex = -1 , Vk.basePipelineIndex = -1
} }
snd <$> allocate pipelines <- snd <$> allocate
(do (do
(result, pipelines) <- Vk.createGraphicsPipelines (result, pipelines) <- Vk.createGraphicsPipelines
logicalDevice logicalDevice
@ -209,3 +215,5 @@ createGraphicsPipelines
) )
pipelines pipelines
) )
return (pipelines, pipelineRenderPass)

View file

@ -10,16 +10,30 @@ import qualified Data.Vector as V
import qualified SDL hiding (V2) import qualified SDL hiding (V2)
import qualified SDL.Video.Vulkan as SDL import qualified SDL.Video.Vulkan as SDL
import Foreign.Ptr import Foreign.Ptr
import qualified Vulkan as Vk import qualified Vulkan.Core10 as Vk
import qualified Vulkan.Extensions.VK_KHR_swapchain as Khr
import qualified Vulkan.Extensions.VK_KHR_surface as Khr
-- internal imports -- internal imports
import Instance import Instance
import Devices import Devices
import GraphicsPipeline
import Framebuffers
import CommandBuffer
initEngine initEngine
:: MonadResource m :: (MonadResource m, MonadFail m)
=> m (SDL.Window, Vk.Instance, Vk.SurfaceKHR, Vk.SwapchainKHR, V.Vector Vk.ImageView) => m
( SDL.Window
, Vk.Device
, Khr.SwapchainKHR
, Vk.Queue
, V.Vector Vk.CommandBuffer
, Vk.Fence
, Vk.Semaphore
, Vk.Semaphore
)
initEngine = do initEngine = do
-- initialize SDL2 with all subsystems -- initialize SDL2 with all subsystems
void $ allocate_ void $ allocate_
@ -46,32 +60,68 @@ initEngine = do
SDL.destroyWindow window SDL.destroyWindow window
) )
-- create vulkan surface and vulkan instance from window -- initialize viúlkan data structures
(surface, inst, swapchain, images) <- initVulkan window initVulkan window
return (window, inst, surface, swapchain, images)
initVulkan initVulkan
:: MonadResource m :: (MonadResource m, MonadFail m)
=> SDL.Window => SDL.Window
-> m (Vk.SurfaceKHR, Vk.Instance, Vk.SwapchainKHR, V.Vector Vk.ImageView) -> m
( SDL.Window
, Vk.Device
, Khr.SwapchainKHR
, Vk.Queue
, V.Vector Vk.CommandBuffer
, Vk.Fence
, Vk.Semaphore
, Vk.Semaphore
)
initVulkan window = do initVulkan window = do
vulkanInstance <- createInstance window vulkanInstance <- createInstance window
(_, vulkanSurface) <- allocate (_, vulkanSurface) <- allocate
(Vk.SurfaceKHR <$> (Khr.SurfaceKHR <$>
SDL.vkCreateSurface window (castPtr (Vk.instanceHandle vulkanInstance)) SDL.vkCreateSurface window (castPtr (Vk.instanceHandle vulkanInstance))
) )
(\vulkanSurface -> do (\vulkanSurface -> do
putStrLn "destroying surface" putStrLn "destroying surface"
Vk.destroySurfaceKHR vulkanInstance vulkanSurface Nothing Khr.destroySurfaceKHR vulkanInstance vulkanSurface Nothing
) )
vulkanPhysicalDevice <- pickPhysicalDevice vulkanInstance vulkanPhysicalDevice <- pickPhysicalDevice vulkanInstance
(vulkanLogicalDevice, surfaceFormats) <- createLogicalDevice vulkanPhysicalDevice vulkanSurface (vulkanLogicalDevice, surfaceFormats) <- createLogicalDevice vulkanPhysicalDevice vulkanSurface
dimensions <- liftIO $ SDL.windowInitialSize <$> SDL.getWindowConfig window dimensions <- liftIO $ SDL.windowInitialSize <$> SDL.getWindowConfig window
(swapchain, surfaceFormat) <- createSwapchain vulkanSurface surfaceFormats dimensions vulkanLogicalDevice (swapchain, surfaceFormat) <-
createSwapchain vulkanSurface surfaceFormats dimensions vulkanLogicalDevice
imageViews <- getImageViewHandles swapchain surfaceFormat vulkanLogicalDevice imageViews <- getImageViewHandles swapchain surfaceFormat vulkanLogicalDevice
vertexShader <- loadShader vulkanLogicalDevice "shadersrc/shader.vert"
fragmentShader <- loadShader vulkanLogicalDevice "shadersrc/shader.frag"
(pipelines, renderPass) <-
createGraphicsPipelines
vulkanLogicalDevice
vertexShader
fragmentShader
"main"
dimensions
(Khr.format surfaceFormat)
return (vulkanSurface, vulkanInstance, swapchain, imageViews) frameBuffer <- createFramebuffer vulkanLogicalDevice renderPass imageViews dimensions
(commandPool, graphicsQueue) <- createCommandPool vulkanPhysicalDevice vulkanLogicalDevice
commandBuffer <- createCommandBuffer vulkanLogicalDevice commandPool
(imageAvailableSemaphore, renderFinishedSemaphore, inFlightFence) <-
createSyncObjects vulkanLogicalDevice
return
( window
, vulkanLogicalDevice
, swapchain
, graphicsQueue
, commandBuffer
, inFlightFence
, imageAvailableSemaphore
, renderFinishedSemaphore
)

View file

@ -8,6 +8,7 @@ import Control.Monad.Loops
import Control.Monad.IO.Class import Control.Monad.IO.Class
import Control.Monad.Trans.Resource import Control.Monad.Trans.Resource
import Data.Bits import Data.Bits
import qualified Data.Vector as V
import Data.Word import Data.Word
import qualified SDL hiding (V2) import qualified SDL hiding (V2)
import qualified Control.Concurrent.STM as STM import qualified Control.Concurrent.STM as STM
@ -17,10 +18,11 @@ import qualified Vulkan.Zero as Vk
-- internal imports -- internal imports
import Init import Init
import Draw (drawFrame)
main :: IO () main :: IO ()
main = runResourceT $ do main = runResourceT $ do
(window, inst, surface, swapchain, images) <- initEngine (window, logicalDevice, swapchain, graphicsQueue, commandBuffer, inFlightFence, imageAvailableSemaphore, renderFinishedSemaphore) <- initEngine
SDL.showWindow window SDL.showWindow window
@ -28,17 +30,26 @@ main = runResourceT $ do
quit <- liftIO $ STM.newTMVarIO True quit <- liftIO $ STM.newTMVarIO True
-- main loop -- main loop
liftIO $ whileM_ whileM_
(STM.atomically $ STM.readTMVar quit (liftIO $ STM.atomically $ STM.readTMVar quit
) )
( do ( do
-- draw
drawFrame
logicalDevice
swapchain
graphicsQueue
(V.head commandBuffer)
inFlightFence
imageAvailableSemaphore
renderFinishedSemaphore
-- poll events -- poll events
evs <- SDL.pollEvents evs <- liftIO SDL.pollEvents
-- flip abort condition on window close -- flip abort condition on window close
mapM_ mapM_
(\e -> case SDL.eventPayload e of (\e -> case SDL.eventPayload e of
SDL.WindowClosedEvent _ -> SDL.WindowClosedEvent _ ->
void $ STM.atomically $ STM.swapTMVar quit False void $ liftIO $ STM.atomically $ STM.swapTMVar quit False
_ -> return () _ -> return ()
) )
evs evs

View file

@ -30,6 +30,7 @@ executable vulkan-tutorial
GraphicsPipeline GraphicsPipeline
Framebuffers Framebuffers
CommandBuffer CommandBuffer
Draw
-- LANGUAGE extensions used by modules in this package. -- LANGUAGE extensions used by modules in this package.
-- other-extensions: -- other-extensions: