{-# LANGUAGE ImportQualifiedPost #-}
{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE MonoLocalBinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ViewPatterns #-}
{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
module Gpu.Vulkan.RenderPass.Internal (
create, R, CreateInfo(..),
group, Group, create', unsafeDestroy, lookup,
BeginInfo(..), beginInfoToMiddle
) where
import Prelude hiding (lookup)
import Foreign.Storable.PeekPoke
import Control.Concurrent.STM
import Control.Concurrent.STM.TSem
import Control.Exception
import Data.TypeLevel.Maybe qualified as TMaybe
import Data.TypeLevel.ParMaybe qualified as TPMaybe
import Data.TypeLevel.Tuple.Uncurry
import Data.Map qualified as Map
import Data.HeteroParList qualified as HeteroParList
import Gpu.Vulkan.RenderPass.Type
import qualified Gpu.Vulkan.AllocationCallbacks as AllocationCallbacks
import qualified Gpu.Vulkan.AllocationCallbacks.Type as AllocationCallbacks
import qualified Gpu.Vulkan.Device.Type as Device
import Gpu.Vulkan.RenderPass.Enum
import qualified Gpu.Vulkan.RenderPass.Middle as M
import qualified Gpu.Vulkan.Attachment as Attachment
import qualified Gpu.Vulkan.Subpass.Middle as Subpass
import qualified Gpu.Vulkan.Framebuffer.Type as Framebuffer
import Gpu.Vulkan.Middle
create :: (
WithPoked (TMaybe.M mn), Attachment.DescriptionListToMiddle fmts,
AllocationCallbacks.ToMiddle mac ) =>
Device.D sd -> CreateInfo mn fmts ->
TPMaybe.M (U2 AllocationCallbacks.A) mac ->
(forall s . R s -> IO a) -> IO a
create :: forall (mn :: Maybe (*)) (fmts :: [Format]) (mac :: Maybe (*, *))
sd a.
(WithPoked (M mn), DescriptionListToMiddle fmts, ToMiddle mac) =>
D sd
-> CreateInfo mn fmts
-> M (U2 A) mac
-> (forall s. R s -> IO a)
-> IO a
create (Device.D D
dvc) CreateInfo mn fmts
ci (M (U2 A) mac -> M A (Snd mac)
forall (msa :: Maybe (*, *)).
ToMiddle msa =>
M (U2 A) msa -> M A (Snd msa)
AllocationCallbacks.toMiddle -> M A (Snd mac)
mac) forall s. R s -> IO a
f = IO R -> (R -> IO ()) -> (R -> IO a) -> IO a
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket
(D -> CreateInfo mn -> M A (Snd mac) -> IO R
forall (mn :: Maybe (*)) (mc :: Maybe (*)).
WithPoked (M mn) =>
D -> CreateInfo mn -> M A mc -> IO R
M.create D
dvc (CreateInfo mn fmts -> CreateInfo mn
forall (fmts :: [Format]) (n :: Maybe (*)).
DescriptionListToMiddle fmts =>
CreateInfo n fmts -> CreateInfo n
createInfoToMiddle CreateInfo mn fmts
ci) M A (Snd mac)
mac)
(\R
r -> D -> R -> M A (Snd mac) -> IO ()
forall (md :: Maybe (*)). D -> R -> M A md -> IO ()
M.destroy D
dvc R
r M A (Snd mac)
mac) (R Any -> IO a
forall s. R s -> IO a
f (R Any -> IO a) -> (R -> R Any) -> R -> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. R -> R Any
forall s. R -> R s
R)
data CreateInfo mn fmts = CreateInfo {
forall (mn :: Maybe (*)) (fmts :: [Format]).
CreateInfo mn fmts -> M mn
createInfoNext :: TMaybe.M mn,
forall (mn :: Maybe (*)) (fmts :: [Format]).
CreateInfo mn fmts -> CreateFlags
createInfoFlags :: CreateFlags,
forall (mn :: Maybe (*)) (fmts :: [Format]).
CreateInfo mn fmts -> PL Description fmts
createInfoAttachments ::
HeteroParList.PL Attachment.Description fmts,
forall (mn :: Maybe (*)) (fmts :: [Format]).
CreateInfo mn fmts -> [Description]
createInfoSubpasses :: [Subpass.Description],
forall (mn :: Maybe (*)) (fmts :: [Format]).
CreateInfo mn fmts -> [Dependency]
createInfoDependencies :: [Subpass.Dependency] }
createInfoToMiddle :: Attachment.DescriptionListToMiddle fmts =>
CreateInfo n fmts -> M.CreateInfo n
createInfoToMiddle :: forall (fmts :: [Format]) (n :: Maybe (*)).
DescriptionListToMiddle fmts =>
CreateInfo n fmts -> CreateInfo n
createInfoToMiddle CreateInfo {
createInfoNext :: forall (mn :: Maybe (*)) (fmts :: [Format]).
CreateInfo mn fmts -> M mn
createInfoNext = M n
mnxt,
createInfoFlags :: forall (mn :: Maybe (*)) (fmts :: [Format]).
CreateInfo mn fmts -> CreateFlags
createInfoFlags = CreateFlags
flgs,
createInfoAttachments :: forall (mn :: Maybe (*)) (fmts :: [Format]).
CreateInfo mn fmts -> PL Description fmts
createInfoAttachments = PL Description fmts
atts,
createInfoSubpasses :: forall (mn :: Maybe (*)) (fmts :: [Format]).
CreateInfo mn fmts -> [Description]
createInfoSubpasses = [Description]
spss,
createInfoDependencies :: forall (mn :: Maybe (*)) (fmts :: [Format]).
CreateInfo mn fmts -> [Dependency]
createInfoDependencies = [Dependency]
dps } = M.CreateInfo {
createInfoNext :: M n
M.createInfoNext = M n
mnxt,
createInfoFlags :: CreateFlags
M.createInfoFlags = CreateFlags
flgs,
createInfoAttachments :: [Description]
M.createInfoAttachments = PL Description fmts -> [Description]
forall (fmts :: [Format]).
DescriptionListToMiddle fmts =>
PL Description fmts -> [Description]
Attachment.descriptionListToMiddle PL Description fmts
atts,
createInfoSubpasses :: [Description]
M.createInfoSubpasses = [Description]
spss,
createInfoDependencies :: [Dependency]
M.createInfoDependencies = [Dependency]
dps }
data Group sd ma sr k = Group (Device.D sd)
(TPMaybe.M (U2 AllocationCallbacks.A) ma)
TSem (TVar (Map.Map k (R sr)))
group :: AllocationCallbacks.ToMiddle ma =>
Device.D sd -> TPMaybe.M (U2 AllocationCallbacks.A) ma ->
(forall sr . Group sd ma sr k -> IO a) -> IO a
group :: forall (ma :: Maybe (*, *)) sd k a.
ToMiddle ma =>
D sd
-> M (U2 A) ma -> (forall sr. Group sd ma sr k -> IO a) -> IO a
group dvc :: D sd
dvc@(Device.D D
mdvc) mac :: M (U2 A) ma
mac@(M (U2 A) ma -> M A (Snd ma)
forall (msa :: Maybe (*, *)).
ToMiddle msa =>
M (U2 A) msa -> M A (Snd msa)
AllocationCallbacks.toMiddle -> M A (Snd ma)
mmac) forall sr. Group sd ma sr k -> IO a
f = do
(sem, m) <- STM (TSem, TVar (Map k (R Any))) -> IO (TSem, TVar (Map k (R Any)))
forall a. STM a -> IO a
atomically (STM (TSem, TVar (Map k (R Any)))
-> IO (TSem, TVar (Map k (R Any))))
-> STM (TSem, TVar (Map k (R Any)))
-> IO (TSem, TVar (Map k (R Any)))
forall a b. (a -> b) -> a -> b
$ (,) (TSem -> TVar (Map k (R Any)) -> (TSem, TVar (Map k (R Any))))
-> STM TSem
-> STM (TVar (Map k (R Any)) -> (TSem, TVar (Map k (R Any))))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Integer -> STM TSem
newTSem Integer
1 STM (TVar (Map k (R Any)) -> (TSem, TVar (Map k (R Any))))
-> STM (TVar (Map k (R Any))) -> STM (TSem, TVar (Map k (R Any)))
forall a b. STM (a -> b) -> STM a -> STM b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Map k (R Any) -> STM (TVar (Map k (R Any)))
forall a. a -> STM (TVar a)
newTVar Map k (R Any)
forall k a. Map k a
Map.empty
rtn <- f $ Group dvc mac sem m
((\(R R
mr) -> D -> R -> M A (Snd ma) -> IO ()
forall (md :: Maybe (*)). D -> R -> M A md -> IO ()
M.destroy D
mdvc R
mr M A (Snd ma)
mmac) `mapM_`)
=<< atomically (readTVar m)
pure rtn
create' :: (
Ord k, WithPoked (TMaybe.M mn), Attachment.DescriptionListToMiddle fmts,
AllocationCallbacks.ToMiddle mac ) =>
Group sd mac sr k -> k -> CreateInfo mn fmts ->
IO (Either String (R sr))
create' :: forall k (mn :: Maybe (*)) (fmts :: [Format]) (mac :: Maybe (*, *))
sd sr.
(Ord k, WithPoked (M mn), DescriptionListToMiddle fmts,
ToMiddle mac) =>
Group sd mac sr k
-> k -> CreateInfo mn fmts -> IO (Either String (R sr))
create' (Group (Device.D D
mdvc)
(M (U2 A) mac -> M A (Snd mac)
forall (msa :: Maybe (*, *)).
ToMiddle msa =>
M (U2 A) msa -> M A (Snd msa)
AllocationCallbacks.toMiddle -> M A (Snd mac)
mac) TSem
sem TVar (Map k (R sr))
rs) k
k CreateInfo mn fmts
ci = do
ok <- STM Bool -> IO Bool
forall a. STM a -> IO a
atomically do
mx <- k -> Map k (R sr) -> Maybe (R sr)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup k
k (Map k (R sr) -> Maybe (R sr))
-> STM (Map k (R sr)) -> STM (Maybe (R sr))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TVar (Map k (R sr)) -> STM (Map k (R sr))
forall a. TVar a -> STM a
readTVar TVar (Map k (R sr))
rs
case mx of
Maybe (R sr)
Nothing -> TSem -> STM ()
waitTSem TSem
sem STM () -> STM Bool -> STM Bool
forall a b. STM a -> STM b -> STM b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Bool -> STM Bool
forall a. a -> STM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True
Just R sr
_ -> Bool -> STM Bool
forall a. a -> STM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
False
if ok
then do r <- M.create mdvc (createInfoToMiddle ci) mac
let r' = R -> R sr
forall s. R -> R s
R R
r
atomically $ modifyTVar rs (Map.insert k r') >> signalTSem sem
pure $ Right r'
else pure . Left $
"Gpu.Vulkan.RenderPass.Internal.create': The key already exist"
unsafeDestroy :: (Ord k, AllocationCallbacks.ToMiddle ma) =>
Group sd ma sr k -> k -> IO (Either String ())
unsafeDestroy :: forall k (ma :: Maybe (*, *)) sd sr.
(Ord k, ToMiddle ma) =>
Group sd ma sr k -> k -> IO (Either String ())
unsafeDestroy (Group (Device.D D
mdvc)
(M (U2 A) ma -> M A (Snd ma)
forall (msa :: Maybe (*, *)).
ToMiddle msa =>
M (U2 A) msa -> M A (Snd msa)
AllocationCallbacks.toMiddle -> M A (Snd ma)
ma) TSem
sem TVar (Map k (R sr))
rs) k
k = do
mr <- STM (Maybe (R sr)) -> IO (Maybe (R sr))
forall a. STM a -> IO a
atomically do
mx <- k -> Map k (R sr) -> Maybe (R sr)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup k
k (Map k (R sr) -> Maybe (R sr))
-> STM (Map k (R sr)) -> STM (Maybe (R sr))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TVar (Map k (R sr)) -> STM (Map k (R sr))
forall a. TVar a -> STM a
readTVar TVar (Map k (R sr))
rs
case mx of
Maybe (R sr)
Nothing -> Maybe (R sr) -> STM (Maybe (R sr))
forall a. a -> STM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (R sr)
forall a. Maybe a
Nothing
Just R sr
_ -> TSem -> STM ()
waitTSem TSem
sem STM () -> STM (Maybe (R sr)) -> STM (Maybe (R sr))
forall a b. STM a -> STM b -> STM b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Maybe (R sr) -> STM (Maybe (R sr))
forall a. a -> STM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (R sr)
mx
case mr of
Maybe (R sr)
Nothing -> Either String () -> IO (Either String ())
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either String () -> IO (Either String ()))
-> Either String () -> IO (Either String ())
forall a b. (a -> b) -> a -> b
$ String -> Either String ()
forall a b. a -> Either a b
Left
String
"Gpu.Vulkan.RenderPass.Internal.unsafeDestroy: No such key"
Just (R R
r) -> do
D -> R -> M A (Snd ma) -> IO ()
forall (md :: Maybe (*)). D -> R -> M A md -> IO ()
M.destroy D
mdvc R
r M A (Snd ma)
ma
STM (Either String ()) -> IO (Either String ())
forall a. STM a -> IO a
atomically do
TVar (Map k (R sr)) -> (Map k (R sr) -> Map k (R sr)) -> STM ()
forall a. TVar a -> (a -> a) -> STM ()
modifyTVar TVar (Map k (R sr))
rs ((Map k (R sr) -> Map k (R sr)) -> STM ())
-> (Map k (R sr) -> Map k (R sr)) -> STM ()
forall a b. (a -> b) -> a -> b
$ k -> Map k (R sr) -> Map k (R sr)
forall k a. Ord k => k -> Map k a -> Map k a
Map.delete k
k
TSem -> STM ()
signalTSem TSem
sem
Either String () -> STM (Either String ())
forall a. a -> STM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either String () -> STM (Either String ()))
-> Either String () -> STM (Either String ())
forall a b. (a -> b) -> a -> b
$ () -> Either String ()
forall a b. b -> Either a b
Right ()
lookup :: Ord k => Group sd ma sr k -> k -> IO (Maybe (R sr))
lookup :: forall k sd (ma :: Maybe (*, *)) sr.
Ord k =>
Group sd ma sr k -> k -> IO (Maybe (R sr))
lookup (Group D sd
_ M (U2 A) ma
_ TSem
_sem TVar (Map k (R sr))
rs) k
k = STM (Maybe (R sr)) -> IO (Maybe (R sr))
forall a. STM a -> IO a
atomically (STM (Maybe (R sr)) -> IO (Maybe (R sr)))
-> STM (Maybe (R sr)) -> IO (Maybe (R sr))
forall a b. (a -> b) -> a -> b
$ k -> Map k (R sr) -> Maybe (R sr)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup k
k (Map k (R sr) -> Maybe (R sr))
-> STM (Map k (R sr)) -> STM (Maybe (R sr))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TVar (Map k (R sr)) -> STM (Map k (R sr))
forall a. TVar a -> STM a
readTVar TVar (Map k (R sr))
rs
data BeginInfo mn sr sf cts = BeginInfo {
forall (mn :: Maybe (*)) sr sf (cts :: [ClearType]).
BeginInfo mn sr sf cts -> M mn
beginInfoNext :: TMaybe.M mn,
forall (mn :: Maybe (*)) sr sf (cts :: [ClearType]).
BeginInfo mn sr sf cts -> R sr
beginInfoRenderPass :: R sr,
forall (mn :: Maybe (*)) sr sf (cts :: [ClearType]).
BeginInfo mn sr sf cts -> F sf
beginInfoFramebuffer :: Framebuffer.F sf,
forall (mn :: Maybe (*)) sr sf (cts :: [ClearType]).
BeginInfo mn sr sf cts -> Rect2d
beginInfoRenderArea :: Rect2d,
forall (mn :: Maybe (*)) sr sf (cts :: [ClearType]).
BeginInfo mn sr sf cts -> PL ClearValue cts
beginInfoClearValues :: HeteroParList.PL ClearValue cts }
beginInfoToMiddle :: BeginInfo n sr sf cts -> M.BeginInfo n cts
beginInfoToMiddle :: forall (n :: Maybe (*)) sr sf (cts :: [ClearType]).
BeginInfo n sr sf cts -> BeginInfo n cts
beginInfoToMiddle BeginInfo {
beginInfoNext :: forall (mn :: Maybe (*)) sr sf (cts :: [ClearType]).
BeginInfo mn sr sf cts -> M mn
beginInfoNext = M n
mnxt,
beginInfoRenderPass :: forall (mn :: Maybe (*)) sr sf (cts :: [ClearType]).
BeginInfo mn sr sf cts -> R sr
beginInfoRenderPass = R R
rp,
beginInfoFramebuffer :: forall (mn :: Maybe (*)) sr sf (cts :: [ClearType]).
BeginInfo mn sr sf cts -> F sf
beginInfoFramebuffer = Framebuffer.F F
fb,
beginInfoRenderArea :: forall (mn :: Maybe (*)) sr sf (cts :: [ClearType]).
BeginInfo mn sr sf cts -> Rect2d
beginInfoRenderArea = Rect2d
ra,
beginInfoClearValues :: forall (mn :: Maybe (*)) sr sf (cts :: [ClearType]).
BeginInfo mn sr sf cts -> PL ClearValue cts
beginInfoClearValues = PL ClearValue cts
cvs } = M.BeginInfo {
beginInfoNext :: M n
M.beginInfoNext = M n
mnxt,
beginInfoRenderPass :: R
M.beginInfoRenderPass = R
rp,
beginInfoFramebuffer :: F
M.beginInfoFramebuffer = F
fb,
beginInfoRenderArea :: Rect2d
M.beginInfoRenderArea = Rect2d
ra,
beginInfoClearValues :: PL ClearValue cts
M.beginInfoClearValues = PL ClearValue cts
cvs }