{-# LANGUAGE OverloadedLists #-}

{-| Tiny helpers for the boilerplate that each rendering example needs:
a framebuffer over a single image view, and a vanilla 2D color image view.
-}
module Vulkan.Utils.Framebuffer
  ( allocateFramebuffer
  ) where

import Control.Monad.Trans.Resource (MonadResource, ReleaseKey, allocate)
import Vulkan.Core10 as Extent2D (Extent2D (..))
import qualified Vulkan.Core10 as Vk
import Vulkan.Zero (zero)

-- | Create a framebuffer covering the whole image with a single attachment.
allocateFramebuffer
  :: (MonadResource m)
  => Vk.Device
  -> Vk.RenderPass
  -> Vk.ImageView
  -> Vk.Extent2D
  -> m (ReleaseKey, Vk.Framebuffer)
allocateFramebuffer :: forall (m :: * -> *).
MonadResource m =>
Device
-> RenderPass
-> ImageView
-> Extent2D
-> m (ReleaseKey, Framebuffer)
allocateFramebuffer Device
dev RenderPass
renderPass ImageView
imageView Vk.Extent2D{Word32
width :: Word32
width :: Extent2D -> Word32
width, Word32
height :: Word32
height :: Extent2D -> Word32
height} =
  Device
-> FramebufferCreateInfo '[]
-> Maybe AllocationCallbacks
-> (IO Framebuffer
    -> (Framebuffer -> IO ()) -> m (ReleaseKey, Framebuffer))
-> m (ReleaseKey, Framebuffer)
forall (a :: [*]) (io :: * -> *) r.
(Extendss FramebufferCreateInfo a, PokeChain a, MonadIO io) =>
Device
-> FramebufferCreateInfo a
-> Maybe AllocationCallbacks
-> (io Framebuffer -> (Framebuffer -> io ()) -> r)
-> r
Vk.withFramebuffer Device
dev FramebufferCreateInfo '[]
framebufferCreateInfo Maybe AllocationCallbacks
forall a. Maybe a
Nothing IO Framebuffer
-> (Framebuffer -> IO ()) -> m (ReleaseKey, Framebuffer)
forall (m :: * -> *) a.
MonadResource m =>
IO a -> (a -> IO ()) -> m (ReleaseKey, a)
allocate
  where
    framebufferCreateInfo :: Vk.FramebufferCreateInfo '[]
    framebufferCreateInfo :: FramebufferCreateInfo '[]
framebufferCreateInfo =
      FramebufferCreateInfo '[]
forall a. Zero a => a
zero
        { Vk.renderPass = renderPass
        , Vk.attachments = [imageView]
        , Vk.width = width
        , Vk.height = height
        , Vk.layers = 1
        }