add depth stencil

This commit is contained in:
nek0 2022-12-28 04:18:54 +01:00
parent f1fb91685b
commit 95dc8b3d9a
11 changed files with 179 additions and 73 deletions

View File

@ -6,6 +6,7 @@ framebuffer
Framebuffer
Framebuffers
GLSL
Imageview
Keysym
KHRONOS
Memdiscrete

View File

@ -102,7 +102,7 @@ recordCommandBuffer
, Vk.height = fromIntegral height
}
}
, Vk.clearValues = V.replicate 4 (Vk.Color $ Vk.Float32 0 0 0 1)
, Vk.clearValues = V.fromList [ Vk.Color (Vk.Float32 0 0 0 1), Vk.DepthStencil (Vk.ClearDepthStencilValue 1 0)]
}
Vk.cmdBeginRenderPass commandBuffer renderPassInfo Vk.SUBPASS_CONTENTS_INLINE
@ -134,7 +134,7 @@ recordCommandBuffer
liftIO $ maybe
(Vk.cmdDraw commandBuffer 3 1 0 0)
(\jmesh -> do
let camPosition = V3 0 0 (-2)
let camPosition = V3 0 0 (-5)
camCenter = V3 0 0 0
camUp = V3 0 1 0
view = lookAt camPosition camCenter camUp

View File

@ -15,6 +15,12 @@ import Linear
import qualified Vulkan as Vk
import qualified Vulkan.Zero as Vk
import qualified Vulkan.CStruct.Extends as Vk
import qualified VulkanMemoryAllocator as VMA
-- internal imports
import Image
import Types
pickPhysicalDevice
:: (MonadResource m)
@ -119,8 +125,9 @@ createSwapchain
-> V.Vector Vk.SurfaceFormatKHR
-> V2 CInt
-> Vk.Device
-> m (Vk.SwapchainKHR, Vk.SurfaceFormatKHR)
createSwapchain surface surfaceFormats windowDimension logicalDevice = do
-> VMA.Allocator
-> m (Vk.SwapchainKHR, Vk.SurfaceFormatKHR, Vk.ImageView, AllocatedImage)
createSwapchain surface surfaceFormats windowDimension logicalDevice allocator = do
liftIO $ do
putStrLn "available formats:"
@ -166,7 +173,41 @@ createSwapchain surface surfaceFormats windowDimension logicalDevice = do
Vk.destroySwapchainKHR logicalDevice swapchain Nothing
)
return (swapchain, Vk.SurfaceFormatKHR surfaceFormat colorSpace)
let depthImageExtent =
(\(V2 w h) -> Vk.Extent3D (fromIntegral w) (fromIntegral h) 1)
windowDimension
let depthImageInfo = imageCreate
Vk.FORMAT_D32_SFLOAT
depthImageExtent
Vk.IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
let depthImageAllocationInfo = Vk.zero
{ VMA.usage = VMA.MEMORY_USAGE_GPU_ONLY
, VMA.requiredFlags = Vk.MEMORY_PROPERTY_DEVICE_LOCAL_BIT
}
(depthImage, depthAllocation, _) <- snd <$> allocate
(VMA.createImage allocator depthImageInfo depthImageAllocationInfo)
(\(depthImage, depthAllocation, _) -> do
putStrLn "destroying image"
VMA.destroyImage allocator depthImage depthAllocation
)
let allocatedImage = AllocatedImage depthImage depthAllocation
depthImageView = imageviewCreate
(image allocatedImage)
Vk.FORMAT_D32_SFLOAT
Vk.IMAGE_ASPECT_DEPTH_BIT
depthImageview <- snd <$> allocate
(Vk.createImageView logicalDevice depthImageView Nothing)
(\depthImageview -> do
putStrLn "destroying image view"
Vk.destroyImageView logicalDevice depthImageview Nothing
)
return (swapchain, Vk.SurfaceFormatKHR surfaceFormat colorSpace, depthImageview, allocatedImage)
getImageViewHandles
:: (MonadResource m)
@ -183,9 +224,9 @@ getImageViewHandles swapchain surfaceFormat logicalDevice = do
putStrLn ("number of images: " <> show (V.length handles))
V.mapM
(\image -> do
(\tmpImage -> do
let createInfo = Vk.zero
{ Vk.image = image
{ Vk.image = tmpImage
, Vk.viewType = Vk.IMAGE_VIEW_TYPE_2D
, Vk.format = (Vk.format :: Vk.SurfaceFormatKHR -> Vk.Format) surfaceFormat
, Vk.components = Vk.ComponentMapping

View File

@ -62,14 +62,7 @@ drawFrame engineData switch frameNumber = do
(engineRenderPass engineData)
(engineFramebuffers engineData V.! fromIntegral index)
(engineWindowDimensions engineData)
(case switchState of
Rainbow ->
redEnginePipelines engineData V.! fromIntegral index
Red ->
rainbowEnginePipelines engineData V.! fromIntegral index
Green ->
meshPipeline engineData V.! fromIntegral index
)
(meshPipeline engineData V.! fromIntegral index)
(meshPipelineLayout engineData)
(case switchState of
Green ->

View File

@ -16,22 +16,28 @@ createFramebuffer
=> Vk.Device
-> Vk.RenderPass
-> V.Vector Vk.ImageView
-> Vk.ImageView
-> V2 CInt
-> m (V.Vector Vk.Framebuffer)
createFramebuffer logicalDevice renderPass swapchainImageViews (V2 swapchainWidth swapcheinHeight)
createFramebuffer
logicalDevice
renderPass
swapchainImageViews
depthImageView
(V2 swapchainWidth swapchainHeight)
= do
let framebufferCreateInfo = Vk.zero
{ Vk.renderPass = renderPass
, Vk.width = fromIntegral swapchainWidth
, Vk.height = fromIntegral swapcheinHeight
, Vk.height = fromIntegral swapchainHeight
, Vk.layers = 1
}
V.mapM
(\imageView -> do
let createInfo = framebufferCreateInfo
{ Vk.attachments = V.singleton imageView
{ Vk.attachments = V.fromList [ imageView, depthImageView ]
} :: Vk.FramebufferCreateInfo '[]
snd <$> allocate
(Vk.createFramebuffer logicalDevice createInfo Nothing)

View File

@ -59,14 +59,14 @@ createRenderPass
:: (MonadResource m)
=> Vk.Device
-> Vk.Format
-> Vk.Format
-> m Vk.RenderPass
createRenderPass
logicalDevice
swapchainImageFormat
depthFormat
= do
let colorAttachmentDescription = (Vk.zero :: Vk.AttachmentDescription)
{ Vk.format = swapchainImageFormat
, Vk.samples = Vk.SAMPLE_COUNT_1_BIT
@ -81,23 +81,48 @@ createRenderPass
{ Vk.attachment = 0
, Vk.layout = Vk.IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
}
depthAttachmentDescription = (Vk.zero :: Vk.AttachmentDescription)
{ Vk.flags = bit 0
, Vk.format = depthFormat
, Vk.samples = Vk.SAMPLE_COUNT_1_BIT
, Vk.loadOp = Vk.ATTACHMENT_LOAD_OP_CLEAR
, Vk.storeOp = Vk.ATTACHMENT_STORE_OP_STORE
, Vk.stencilLoadOp = Vk.ATTACHMENT_LOAD_OP_CLEAR
, Vk.stencilStoreOp = Vk.ATTACHMENT_STORE_OP_DONT_CARE
, Vk.initialLayout = Vk.IMAGE_LAYOUT_UNDEFINED
, Vk.finalLayout = Vk.IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL
}
depthAttachmentReference = (Vk.zero :: Vk.AttachmentReference)
{ Vk.attachment = 1
, Vk.layout = Vk.IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
}
subpassDescriptor = (Vk.zero :: Vk.SubpassDescription)
{ Vk.pipelineBindPoint = Vk.PIPELINE_BIND_POINT_GRAPHICS
, Vk.colorAttachments = V.singleton colorAttachmentReference
{ Vk.pipelineBindPoint = Vk.PIPELINE_BIND_POINT_GRAPHICS
, Vk.colorAttachments = V.singleton colorAttachmentReference
, Vk.depthStencilAttachment = Just depthAttachmentReference
}
subpassDependency = Vk.zero
{ Vk.srcSubpass = Vk.SUBPASS_EXTERNAL
, Vk.dstSubpass = 0
, Vk.srcStageMask = Vk.PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
, Vk.dstStageMask = Vk.PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
, Vk.srcAccessMask = Vk.ACCESS_COLOR_ATTACHMENT_WRITE_BIT
, Vk.dstAccessMask =
Vk.ACCESS_COLOR_ATTACHMENT_READ_BIT .|. Vk.ACCESS_COLOR_ATTACHMENT_WRITE_BIT
, Vk.srcAccessMask = bit 0
, Vk.dstAccessMask = Vk.ACCESS_COLOR_ATTACHMENT_WRITE_BIT
}
subpassDepthDependency = Vk.zero
{ Vk.srcSubpass = Vk.SUBPASS_EXTERNAL
, Vk.dstSubpass = 0
, Vk.srcStageMask =
Vk.PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT .|. Vk.PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
, Vk.srcAccessMask = bit 0
, Vk.dstStageMask =
Vk.PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT .|. Vk.PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
, Vk.dstAccessMask = Vk.ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
}
renderPassCreateInfo = Vk.zero
{ Vk.attachments = V.singleton colorAttachmentDescription
{ Vk.attachments = V.fromList [ colorAttachmentDescription, depthAttachmentDescription ]
, Vk.subpasses = V.singleton subpassDescriptor
, Vk.dependencies = V.singleton subpassDependency
, Vk.dependencies = V.fromList [ subpassDependency, subpassDepthDependency ]
} :: Vk.RenderPassCreateInfo '[]
snd <$> allocate
@ -144,6 +169,22 @@ createRasterizationStateCreateInfo mode =
, Vk.depthBiasSlopeFactor = 0
}
createDepthStencilStateCreateInfo
:: Bool
-> Bool
-> Vk.CompareOp
-> Vk.PipelineDepthStencilStateCreateInfo
createDepthStencilStateCreateInfo depthTest depthWrite compareOperation =
Vk.zero
{ Vk.depthTestEnable = depthTest
, Vk.depthWriteEnable = depthWrite
, Vk.depthCompareOp = compareOperation
, Vk.depthBoundsTestEnable = False
, Vk.minDepthBounds = 0
, Vk.maxDepthBounds = 1
, Vk.stencilTestEnable = False
}
createMultisampleStateCreateInfo
:: Vk.SomeStruct Vk.PipelineMultisampleStateCreateInfo
createMultisampleStateCreateInfo =
@ -160,6 +201,7 @@ createGraphicsPipelines
-> V2 CInt
-> Int
-> Vk.PipelineLayout
-> Maybe Vk.PipelineDepthStencilStateCreateInfo
-> m (V.Vector Vk.Pipeline)
createGraphicsPipelines
logicalDevice
@ -168,6 +210,7 @@ createGraphicsPipelines
(V2 width height)
number
pipelineLayout
depthState
= do
let pipelineStagesCreateInfos =
V.fromList $ map Vk.SomeStruct
@ -249,6 +292,7 @@ createGraphicsPipelines
, Vk.multisampleState = Just createMultisampleStateCreateInfo
, Vk.colorBlendState = Just $ Vk.SomeStruct pipelineColorBlendStateCreateInfo
, Vk.dynamicState = Just pipelineDynamicStateCreateInfo
, Vk.depthStencilState = depthState
, Vk.layout = pipelineLayout
, Vk.renderPass = renderPass
, Vk.subpass = 0

47
src/Image.hs Normal file
View File

@ -0,0 +1,47 @@
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE DataKinds #-}
module Image where
import qualified Vulkan as Vk
import qualified Vulkan.Zero as Vk
imageCreate
:: Vk.Format
-> Vk.Extent3D
-> Vk.ImageUsageFlags
-> Vk.ImageCreateInfo '[]
imageCreate format extent usageFlags =
let imageCreateInfo = Vk.zero
{ Vk.imageType = Vk.IMAGE_TYPE_2D
, Vk.format = format
, Vk.extent = extent
, Vk.mipLevels = 1
, Vk.arrayLayers = 1
, Vk.samples = Vk.SAMPLE_COUNT_1_BIT
, Vk.tiling = Vk.IMAGE_TILING_OPTIMAL
, Vk.usage = usageFlags
}
in imageCreateInfo
imageviewCreate
:: Vk.Image
-> Vk.Format
-> Vk.ImageAspectFlags
-> Vk.ImageViewCreateInfo '[]
imageviewCreate image format aspectFlags =
let imageviewCreateInfo = Vk.zero
{ Vk.viewType = Vk.IMAGE_VIEW_TYPE_2D
, Vk.image = image
, Vk.format = format
, Vk.subresourceRange = Vk.zero
{ Vk.baseMipLevel = 0
, Vk.levelCount = 1
, Vk.baseArrayLayer = 0
, Vk.layerCount = 1
, Vk.aspectMask = aspectFlags
}
}
in imageviewCreateInfo

View File

@ -78,42 +78,18 @@ initVulkan window = do
(vulkanLogicalDevice, surfaceFormats) <- createLogicalDevice vulkanPhysicalDevice vulkanSurface
allocator <- initAllocator vulkanPhysicalDevice vulkanLogicalDevice vulkanInstance
mesh <- uploadMesh loadMeshes allocator
maskMesh <- loadFromObj "./assets/cat_mask_cyberpunk.obj" allocator
dimensions <- liftIO $ SDL.windowInitialSize <$> SDL.getWindowConfig window
(swapchain, surfaceFormat) <-
createSwapchain vulkanSurface surfaceFormats dimensions vulkanLogicalDevice
(swapchain, surfaceFormat, depthImageView, depthAllocatedImage) <-
createSwapchain vulkanSurface surfaceFormats dimensions vulkanLogicalDevice allocator
imageViews <- getImageViewHandles swapchain surfaceFormat vulkanLogicalDevice
redVertexShader <- loadShader vulkanLogicalDevice "shadersrc/red.vert" "vert"
redFragmentShader <- loadShader vulkanLogicalDevice "shadersrc/red.frag" "frag"
rainbowVertexShader <- loadShader vulkanLogicalDevice "shadersrc/rainbow.vert" "vert"
rainbowFragmentShader <- loadShader vulkanLogicalDevice "shadersrc/rainbow.frag" "frag"
meshVertexShader <- loadShader vulkanLogicalDevice "shadersrc/mesh.vert" "vert"
meshFragmentShader <- loadShader vulkanLogicalDevice "shadersrc/rainbow.frag" "frag"
renderPass <- createRenderPass vulkanLogicalDevice (Khr.format surfaceFormat)
pipelineLayout <- createPipelineLayout vulkanLogicalDevice
renderPass <- createRenderPass vulkanLogicalDevice (Khr.format surfaceFormat) Vk.FORMAT_D32_SFLOAT
meshLayout <- createMeshPipelineLayout vulkanLogicalDevice
let redContainer = ShaderContainer (Just redVertexShader) (Just redFragmentShader)
rainbowContainer = ShaderContainer (Just rainbowVertexShader) (Just rainbowFragmentShader)
meshContainer = ShaderContainer (Just meshVertexShader) (Just meshFragmentShader)
redPipelines <-
createGraphicsPipelines
vulkanLogicalDevice
renderPass
redContainer
dimensions
(length imageViews)
pipelineLayout
rainbowPipelines <-
createGraphicsPipelines
vulkanLogicalDevice
renderPass
rainbowContainer
dimensions
(length imageViews)
pipelineLayout
let meshContainer = ShaderContainer (Just meshVertexShader) (Just meshFragmentShader)
meshPipelines <-
createGraphicsPipelines
vulkanLogicalDevice
@ -122,8 +98,9 @@ initVulkan window = do
dimensions
(length imageViews)
meshLayout
(Just (createDepthStencilStateCreateInfo True True Vk.COMPARE_OP_LESS_OR_EQUAL))
frameBuffers <- createFramebuffer vulkanLogicalDevice renderPass imageViews dimensions
frameBuffers <- createFramebuffer vulkanLogicalDevice renderPass imageViews depthImageView dimensions
(commandPool, graphicsQueue) <- createCommandPool vulkanPhysicalDevice vulkanLogicalDevice
commandBuffer <- createCommandBuffer vulkanLogicalDevice commandPool (length frameBuffers)
@ -142,8 +119,6 @@ initVulkan window = do
commandBuffer
frameBuffers
meshLayout
redPipelines
rainbowPipelines
meshPipelines
renderPass
inFlightFence
@ -152,3 +127,6 @@ initVulkan window = do
maskMesh
maskMesh
allocator
depthImageView
depthAllocatedImage
Vk.FORMAT_D32_SFLOAT

View File

@ -47,19 +47,6 @@ main = runResourceT $ do
(\e -> case SDL.eventPayload e of
SDL.WindowClosedEvent _ ->
void $ liftIO $ STM.atomically $ STM.swapTMVar quit False
SDL.KeyboardEvent dat ->
case dat of
SDL.KeyboardEventData _ SDL.Released _ (SDL.Keysym _ SDL.KeycodeSpace _) ->
liftIO $ STM.atomically $ do
state <- STM.readTMVar showPipeline
void $ STM.swapTMVar showPipeline
(if state /= maxBound then succ state else state)
SDL.KeyboardEventData _ SDL.Released _ (SDL.Keysym _ SDL.KeycodeTab _) ->
liftIO $ STM.atomically $ do
state <- STM.readTMVar showPipeline
void $ STM.swapTMVar showPipeline
(if state /= minBound then pred state else state)
_ -> return ()
_ -> return ()
)
evs

View File

@ -33,8 +33,6 @@ data EngineData = EngineData
, engineCommandBuffers :: V.Vector Vk.CommandBuffer
, engineFramebuffers :: V.Vector Vk.Framebuffer
, meshPipelineLayout :: Vk.PipelineLayout
, redEnginePipelines :: V.Vector Vk.Pipeline
, rainbowEnginePipelines :: V.Vector Vk.Pipeline
, meshPipeline :: V.Vector Vk.Pipeline
, engineRenderPass :: Vk.RenderPass
, engineInFlightFence :: Vk.Fence
@ -43,6 +41,9 @@ data EngineData = EngineData
, engineMesh :: Mesh
, engineExternalMesh :: Mesh
, engineAllocator :: VMA.Allocator
, engineDepthImageView :: Vk.ImageView
, engineDepthImage :: AllocatedImage
, engineDepthFormat :: Vk.Format
}
data AllocatedBuffer = AllocatedBuffer
@ -116,6 +117,7 @@ data VertexInputDescription = VertexInputDescription
{ vidBindings :: V.Vector Vk.VertexInputBindingDescription
, vidAttributes :: V.Vector Vk.VertexInputAttributeDescription
}
deriving (Show)
data Mesh = Mesh
{ meshVertices :: V.Vector Vertex
@ -143,3 +145,9 @@ instance Storable MeshPushConstants where
poke (castPtr $ ptr `plusPtr` sizeOf dat) mat
alignment _ = 0
data AllocatedImage = AllocatedImage
{ image :: Vk.Image
, allocation :: VMA.Allocation
}
deriving (Show)

View File

@ -33,6 +33,7 @@ executable vulkan-tutorial
Draw
Memory
Mesh
Image
Types
-- LANGUAGE extensions used by modules in this package.