{-# LANGUAGE ImportQualifiedPost #-}
{-# LANGUAGE MonoLocalBinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE FlexibleContexts, FlexibleInstances #-}
{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}

module Gpu.Vulkan.Queue (

	-- * SUBMIT AND WAIT IDLE

	submit, submit2, M.waitIdle, M.Q,

	-- * TYPE SYNONYM

	Index,

	-- * SPARSE RESOURCES

	bindSparse, BindSparseInfo(..), BindSparseInfosToMiddle,

	-- * ENUM

	module Gpu.Vulkan.Queue.Enum

	) where

import Data.TypeLevel.Tuple.Uncurry
import Data.TypeLevel.Tuple.MapIndex
import Data.HeteroParList qualified as HeteroParList
import Data.Word

import Gpu.Vulkan.Internal

import qualified Gpu.Vulkan.Fence.Type as Fence

import Gpu.Vulkan.Queue.Middle qualified as M
import Gpu.Vulkan.Queue.Enum

import Data.TypeLevel.Maybe qualified as TMaybe
import Data.HeteroParList (pattern (:**))
import Data.HeteroParList qualified as HPList

import Foreign.Storable.PeekPoke
import Gpu.Vulkan.Device qualified as Device
import Gpu.Vulkan.Semaphore.Internal qualified as Semaphore
import Gpu.Vulkan.Sparse.Buffer.Internal qualified as Sparse.Buffer
import Gpu.Vulkan.Sparse.Image.Internal qualified as Sparse.Image

import Control.Monad
import Debug

submit :: SubmitInfoListToMiddle sias => M.Q ->
	HeteroParList.PL (U4 SubmitInfo) sias -> Maybe (Fence.F sf) -> IO ()
submit :: forall (sias :: [(Maybe (*), [*], [*], [*])]) sf.
SubmitInfoListToMiddle sias =>
Q -> PL (U4 SubmitInfo) sias -> Maybe (F sf) -> IO ()
submit Q
q PL (U4 SubmitInfo) sias
sis Maybe (F sf)
mf =
	Q -> PL SubmitInfo (MiddleNextList sias) -> Maybe F -> IO ()
forall (ns :: [Maybe (*)]).
SubmitInfoListToCore ns =>
Q -> PL SubmitInfo ns -> Maybe F -> IO ()
M.submit Q
q (PL (U4 SubmitInfo) sias -> PL SubmitInfo (MiddleNextList sias)
forall (ns3s2s4 :: [(Maybe (*), [*], [*], [*])]).
SubmitInfoListToMiddle ns3s2s4 =>
PL (U4 SubmitInfo) ns3s2s4
-> PL SubmitInfo (MiddleNextList ns3s2s4)
submitInfoListToMiddle PL (U4 SubmitInfo) sias
sis) (Maybe F -> IO ()) -> Maybe F -> IO ()
forall a b. (a -> b) -> a -> b
$ (\(Fence.F F
f) -> F
f) (F sf -> F) -> Maybe (F sf) -> Maybe F
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (F sf)
mf

submit2 :: SubmitInfo2ListToMiddle sias => M.Q ->
	HeteroParList.PL (U4 SubmitInfo2) sias -> Maybe (Fence.F sf) -> IO ()
submit2 :: forall (sias :: [(Maybe (*), [(Maybe (*), *)], [(Maybe (*), *)],
                  [(Maybe (*), *)])])
       sf.
SubmitInfo2ListToMiddle sias =>
Q -> PL (U4 SubmitInfo2) sias -> Maybe (F sf) -> IO ()
submit2 Q
q PL (U4 SubmitInfo2) sias
sis Maybe (F sf)
mf =
	Q
-> PL (U4 SubmitInfo2) (SubmitInfo2ArgsListToMiddle sias)
-> Maybe F
-> IO ()
forall (sias :: [(Maybe (*), [Maybe (*)], [Maybe (*)],
                  [Maybe (*)])]).
SubmitInfo2ListToCore sias =>
Q -> PL (U4 SubmitInfo2) sias -> Maybe F -> IO ()
M.submit2 Q
q (PL (U4 SubmitInfo2) sias
-> PL (U4 SubmitInfo2) (SubmitInfo2ArgsListToMiddle sias)
forall (sias :: [(Maybe (*), [(Maybe (*), *)], [(Maybe (*), *)],
                  [(Maybe (*), *)])]).
SubmitInfo2ListToMiddle sias =>
PL (U4 SubmitInfo2) sias
-> PL (U4 SubmitInfo2) (SubmitInfo2ArgsListToMiddle sias)
submitInfo2ListToMiddle PL (U4 SubmitInfo2) sias
sis) (Maybe F -> IO ()) -> Maybe F -> IO ()
forall a b. (a -> b) -> a -> b
$ (\(Fence.F F
f) -> F
f) (F sf -> F) -> Maybe (F sf) -> Maybe F
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (F sf)
mf

type Index = Word32

bindSparse :: (
	BindSparseInfosToMiddle ias,
	HPList.ToListWithCCpsM' WithPoked TMaybe.M (M0_6 ias) ) =>
	Device.D sd -> M.Q ->
	HPList.PL (U6 BindSparseInfo) ias -> Maybe (Fence.F sf) -> IO ()
bindSparse :: forall (ias :: [(Maybe (*), [*],
                 [(*, Symbol, [O], [(*, [(*, ImageBufferArg)], Nat)])],
                 [(*, Symbol, Format, [(*, [(*, ImageBufferArg)], Nat)])],
                 [(*, Symbol, Format, [(*, [(*, ImageBufferArg)], Nat)])], [*])])
       sd sf.
(BindSparseInfosToMiddle ias,
 ToListWithCCpsM' WithPoked M (M0_6 ias)) =>
D sd -> Q -> PL (U6 BindSparseInfo) ias -> Maybe (F sf) -> IO ()
bindSparse D sd
dv Q
q PL (U6 BindSparseInfo) ias
is Maybe (F sf)
mf = do
	let	mmf :: Maybe F
mmf = case Maybe (F sf)
mf of
			Just (Fence.F F
f) -> F -> Maybe F
forall a. a -> Maybe a
Just F
f
			Maybe (F sf)
Nothing -> Maybe F
forall a. Maybe a
Nothing
	Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
debug (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ String -> IO ()
putStrLn
		String
"Gpu.Vulkan.Queue.bindSparse: before bindSparseInfoToMiddle"
	mis <- D sd
-> PL (U6 BindSparseInfo) ias -> IO (PL BindSparseInfo (M0_6 ias))
forall (bsias :: [(Maybe (*), [*],
                   [(*, Symbol, [O], [(*, [(*, ImageBufferArg)], Nat)])],
                   [(*, Symbol, Format, [(*, [(*, ImageBufferArg)], Nat)])],
                   [(*, Symbol, Format, [(*, [(*, ImageBufferArg)], Nat)])], [*])])
       sd.
BindSparseInfosToMiddle bsias =>
D sd
-> PL (U6 BindSparseInfo) bsias
-> IO (PL BindSparseInfo (M0_6 bsias))
forall sd.
D sd
-> PL (U6 BindSparseInfo) ias -> IO (PL BindSparseInfo (M0_6 ias))
bindSparseInfosToMiddle D sd
dv PL (U6 BindSparseInfo) ias
is
	when debug $ putStrLn
		"Gpu.Vulkan.Queue.bindSparse: before M.bindSparse"
	M.bindSparse q mis mmf

data BindSparseInfo mn swss bbs iobs ibs ssss = BindSparseInfo {
	forall (mn :: Maybe (*)) (swss :: [*])
       (bbs :: [(*, Symbol, [O], [(*, [(*, ImageBufferArg)], Nat)])])
       (iobs :: [(*, Symbol, Format, [(*, [(*, ImageBufferArg)], Nat)])])
       (ibs :: [(*, Symbol, Format, [(*, [(*, ImageBufferArg)], Nat)])])
       (ssss :: [*]).
BindSparseInfo mn swss bbs iobs ibs ssss -> M mn
bindSparseInfoNext :: TMaybe.M mn,
	forall (mn :: Maybe (*)) (swss :: [*])
       (bbs :: [(*, Symbol, [O], [(*, [(*, ImageBufferArg)], Nat)])])
       (iobs :: [(*, Symbol, Format, [(*, [(*, ImageBufferArg)], Nat)])])
       (ibs :: [(*, Symbol, Format, [(*, [(*, ImageBufferArg)], Nat)])])
       (ssss :: [*]).
BindSparseInfo mn swss bbs iobs ibs ssss -> PL S swss
bindSparseInfoWaitSemaphores :: HPList.PL Semaphore.S swss,
	forall (mn :: Maybe (*)) (swss :: [*])
       (bbs :: [(*, Symbol, [O], [(*, [(*, ImageBufferArg)], Nat)])])
       (iobs :: [(*, Symbol, Format, [(*, [(*, ImageBufferArg)], Nat)])])
       (ibs :: [(*, Symbol, Format, [(*, [(*, ImageBufferArg)], Nat)])])
       (ssss :: [*]).
BindSparseInfo mn swss bbs iobs ibs ssss
-> PL (U4 MemoryBindInfo) bbs
bindSparseInfoBufferBinds ::
		HPList.PL (U4 Sparse.Buffer.MemoryBindInfo) bbs,
	forall (mn :: Maybe (*)) (swss :: [*])
       (bbs :: [(*, Symbol, [O], [(*, [(*, ImageBufferArg)], Nat)])])
       (iobs :: [(*, Symbol, Format, [(*, [(*, ImageBufferArg)], Nat)])])
       (ibs :: [(*, Symbol, Format, [(*, [(*, ImageBufferArg)], Nat)])])
       (ssss :: [*]).
BindSparseInfo mn swss bbs iobs ibs ssss
-> PL (U4 OpaqueMemoryBindInfo) iobs
bindSparseInfoImageOpaqueBinds ::
		HPList.PL (U4 Sparse.Image.OpaqueMemoryBindInfo) iobs,
	forall (mn :: Maybe (*)) (swss :: [*])
       (bbs :: [(*, Symbol, [O], [(*, [(*, ImageBufferArg)], Nat)])])
       (iobs :: [(*, Symbol, Format, [(*, [(*, ImageBufferArg)], Nat)])])
       (ibs :: [(*, Symbol, Format, [(*, [(*, ImageBufferArg)], Nat)])])
       (ssss :: [*]).
BindSparseInfo mn swss bbs iobs ibs ssss
-> PL (U4 MemoryBindInfo) ibs
bindSparseInfoImageBinds ::
		HPList.PL (U4 Sparse.Image.MemoryBindInfo) ibs,
	forall (mn :: Maybe (*)) (swss :: [*])
       (bbs :: [(*, Symbol, [O], [(*, [(*, ImageBufferArg)], Nat)])])
       (iobs :: [(*, Symbol, Format, [(*, [(*, ImageBufferArg)], Nat)])])
       (ibs :: [(*, Symbol, Format, [(*, [(*, ImageBufferArg)], Nat)])])
       (ssss :: [*]).
BindSparseInfo mn swss bbs iobs ibs ssss -> PL S ssss
bindSparseInfoSignalSemaphores :: HPList.PL Semaphore.S ssss }

bindSparseInfoToMiddle :: (
	Sparse.Buffer.MemoryBindInfosToMiddle bbs,
	Sparse.Image.OpaqueMemoryBindInfosToMiddle iobs,
	Sparse.Image.MemoryBindInfosToMiddle ibs ) =>
	Device.D sd ->
	BindSparseInfo mn swss bbs iobs ibs ssss -> IO (M.BindSparseInfo mn)
bindSparseInfoToMiddle :: forall (bbs :: [(*, Symbol, [O],
                 [(*, [(*, ImageBufferArg)], Nat)])])
       (iobs :: [(*, Symbol, Format, [(*, [(*, ImageBufferArg)], Nat)])])
       (ibs :: [(*, Symbol, Format, [(*, [(*, ImageBufferArg)], Nat)])])
       sd (mn :: Maybe (*)) (swss :: [*]) (ssss :: [*]).
(MemoryBindInfosToMiddle bbs, OpaqueMemoryBindInfosToMiddle iobs,
 MemoryBindInfosToMiddle ibs) =>
D sd
-> BindSparseInfo mn swss bbs iobs ibs ssss
-> IO (BindSparseInfo mn)
bindSparseInfoToMiddle D sd
dv BindSparseInfo {
	bindSparseInfoNext :: forall (mn :: Maybe (*)) (swss :: [*])
       (bbs :: [(*, Symbol, [O], [(*, [(*, ImageBufferArg)], Nat)])])
       (iobs :: [(*, Symbol, Format, [(*, [(*, ImageBufferArg)], Nat)])])
       (ibs :: [(*, Symbol, Format, [(*, [(*, ImageBufferArg)], Nat)])])
       (ssss :: [*]).
BindSparseInfo mn swss bbs iobs ibs ssss -> M mn
bindSparseInfoNext = M mn
mn,
	bindSparseInfoWaitSemaphores :: forall (mn :: Maybe (*)) (swss :: [*])
       (bbs :: [(*, Symbol, [O], [(*, [(*, ImageBufferArg)], Nat)])])
       (iobs :: [(*, Symbol, Format, [(*, [(*, ImageBufferArg)], Nat)])])
       (ibs :: [(*, Symbol, Format, [(*, [(*, ImageBufferArg)], Nat)])])
       (ssss :: [*]).
BindSparseInfo mn swss bbs iobs ibs ssss -> PL S swss
bindSparseInfoWaitSemaphores =
		(forall s. S s -> S) -> PL S swss -> [S]
forall k (t :: k -> *) a (ss :: [k]).
(forall (s :: k). t s -> a) -> PL t ss -> [a]
HPList.toList (\(Semaphore.S S
s) -> S
s) -> [S]
wss,
	bindSparseInfoBufferBinds :: forall (mn :: Maybe (*)) (swss :: [*])
       (bbs :: [(*, Symbol, [O], [(*, [(*, ImageBufferArg)], Nat)])])
       (iobs :: [(*, Symbol, Format, [(*, [(*, ImageBufferArg)], Nat)])])
       (ibs :: [(*, Symbol, Format, [(*, [(*, ImageBufferArg)], Nat)])])
       (ssss :: [*]).
BindSparseInfo mn swss bbs iobs ibs ssss
-> PL (U4 MemoryBindInfo) bbs
bindSparseInfoBufferBinds = PL (U4 MemoryBindInfo) bbs
bbs,
	bindSparseInfoImageOpaqueBinds :: forall (mn :: Maybe (*)) (swss :: [*])
       (bbs :: [(*, Symbol, [O], [(*, [(*, ImageBufferArg)], Nat)])])
       (iobs :: [(*, Symbol, Format, [(*, [(*, ImageBufferArg)], Nat)])])
       (ibs :: [(*, Symbol, Format, [(*, [(*, ImageBufferArg)], Nat)])])
       (ssss :: [*]).
BindSparseInfo mn swss bbs iobs ibs ssss
-> PL (U4 OpaqueMemoryBindInfo) iobs
bindSparseInfoImageOpaqueBinds = PL (U4 OpaqueMemoryBindInfo) iobs
iobs,
	bindSparseInfoImageBinds :: forall (mn :: Maybe (*)) (swss :: [*])
       (bbs :: [(*, Symbol, [O], [(*, [(*, ImageBufferArg)], Nat)])])
       (iobs :: [(*, Symbol, Format, [(*, [(*, ImageBufferArg)], Nat)])])
       (ibs :: [(*, Symbol, Format, [(*, [(*, ImageBufferArg)], Nat)])])
       (ssss :: [*]).
BindSparseInfo mn swss bbs iobs ibs ssss
-> PL (U4 MemoryBindInfo) ibs
bindSparseInfoImageBinds = PL (U4 MemoryBindInfo) ibs
ibs,
	bindSparseInfoSignalSemaphores :: forall (mn :: Maybe (*)) (swss :: [*])
       (bbs :: [(*, Symbol, [O], [(*, [(*, ImageBufferArg)], Nat)])])
       (iobs :: [(*, Symbol, Format, [(*, [(*, ImageBufferArg)], Nat)])])
       (ibs :: [(*, Symbol, Format, [(*, [(*, ImageBufferArg)], Nat)])])
       (ssss :: [*]).
BindSparseInfo mn swss bbs iobs ibs ssss -> PL S ssss
bindSparseInfoSignalSemaphores =
		(forall s. S s -> S) -> PL S ssss -> [S]
forall k (t :: k -> *) a (ss :: [k]).
(forall (s :: k). t s -> a) -> PL t ss -> [a]
HPList.toList (\(Semaphore.S S
s) -> S
s) -> [S]
sss
	} = do
	mbbs <- D sd -> PL (U4 MemoryBindInfo) bbs -> IO [MemoryBindInfo]
forall (mbias :: [(*, Symbol, [O],
                   [(*, [(*, ImageBufferArg)], Nat)])])
       sd.
MemoryBindInfosToMiddle mbias =>
D sd -> PL (U4 MemoryBindInfo) mbias -> IO [MemoryBindInfo]
forall sd.
D sd -> PL (U4 MemoryBindInfo) bbs -> IO [MemoryBindInfo]
Sparse.Buffer.memoryBindInfosToMiddle D sd
dv PL (U4 MemoryBindInfo) bbs
bbs
	miobs <- Sparse.Image.opaqueMemoryBindInfosToMiddle dv iobs
	mibs <- Sparse.Image.memoryBindInfosToMiddle dv ibs
	pure M.BindSparseInfo {
		M.bindSparseInfoNext = mn,
		M.bindSparseInfoWaitSemaphores = wss,
		M.bindSparseInfoBufferBinds = mbbs,
		M.bindSparseInfoImageOpaqueBinds = miobs,
		M.bindSparseInfoImageBinds = mibs,
		M.bindSparseInfoSignalSemaphores = sss }

class BindSparseInfosToMiddle bsias where
	bindSparseInfosToMiddle :: Device.D sd ->
		HPList.PL (U6 BindSparseInfo) bsias ->
		IO (HPList.PL M.BindSparseInfo (M0_6 bsias))

instance BindSparseInfosToMiddle '[] where
	bindSparseInfosToMiddle :: forall sd.
D sd
-> PL (U6 BindSparseInfo) '[] -> IO (PL BindSparseInfo (M0_6 '[]))
bindSparseInfosToMiddle D sd
_ PL (U6 BindSparseInfo) '[]
HPList.Nil = PL BindSparseInfo '[] -> IO (PL BindSparseInfo '[])
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PL BindSparseInfo '[]
forall {k} (t :: k -> *). PL t '[]
HPList.Nil

instance (
	Sparse.Buffer.MemoryBindInfosToMiddle bbs,
	Sparse.Image.OpaqueMemoryBindInfosToMiddle iobs,
	Sparse.Image.MemoryBindInfosToMiddle ibs,
	BindSparseInfosToMiddle bsias ) =>
	BindSparseInfosToMiddle
		('(mn, swss, bbs, iobs, ibs, ssss) ': bsias) where
	bindSparseInfosToMiddle :: forall sd.
D sd
-> PL
     (U6 BindSparseInfo) ('(mn, swss, bbs, iobs, ibs, ssss) : bsias)
-> IO
     (PL
        BindSparseInfo (M0_6 ('(mn, swss, bbs, iobs, ibs, ssss) : bsias)))
bindSparseInfosToMiddle D sd
dv (U6 BindSparseInfo s1 s2 s3 s4 s5 s6
i :** PL (U6 BindSparseInfo) ss1
is) = BindSparseInfo s1
-> PL BindSparseInfo (M0_6 bsias)
-> PL BindSparseInfo (s1 : M0_6 bsias)
forall {k} (t :: k -> *) (s :: k) (ss1 :: [k]).
t s -> PL t ss1 -> PL t (s : ss1)
(:**)
		(BindSparseInfo s1
 -> PL BindSparseInfo (M0_6 bsias)
 -> PL BindSparseInfo (s1 : M0_6 bsias))
-> IO (BindSparseInfo s1)
-> IO
     (PL BindSparseInfo (M0_6 bsias)
      -> PL BindSparseInfo (s1 : M0_6 bsias))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> D sd -> BindSparseInfo s1 s2 s3 s4 s5 s6 -> IO (BindSparseInfo s1)
forall (bbs :: [(*, Symbol, [O],
                 [(*, [(*, ImageBufferArg)], Nat)])])
       (iobs :: [(*, Symbol, Format, [(*, [(*, ImageBufferArg)], Nat)])])
       (ibs :: [(*, Symbol, Format, [(*, [(*, ImageBufferArg)], Nat)])])
       sd (mn :: Maybe (*)) (swss :: [*]) (ssss :: [*]).
(MemoryBindInfosToMiddle bbs, OpaqueMemoryBindInfosToMiddle iobs,
 MemoryBindInfosToMiddle ibs) =>
D sd
-> BindSparseInfo mn swss bbs iobs ibs ssss
-> IO (BindSparseInfo mn)
bindSparseInfoToMiddle D sd
dv BindSparseInfo s1 s2 s3 s4 s5 s6
i
		IO
  (PL BindSparseInfo (M0_6 bsias)
   -> PL BindSparseInfo (s1 : M0_6 bsias))
-> IO (PL BindSparseInfo (M0_6 bsias))
-> IO (PL BindSparseInfo (s1 : M0_6 bsias))
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> D sd
-> PL (U6 BindSparseInfo) ss1 -> IO (PL BindSparseInfo (M0_6 ss1))
forall (bsias :: [(Maybe (*), [*],
                   [(*, Symbol, [O], [(*, [(*, ImageBufferArg)], Nat)])],
                   [(*, Symbol, Format, [(*, [(*, ImageBufferArg)], Nat)])],
                   [(*, Symbol, Format, [(*, [(*, ImageBufferArg)], Nat)])], [*])])
       sd.
BindSparseInfosToMiddle bsias =>
D sd
-> PL (U6 BindSparseInfo) bsias
-> IO (PL BindSparseInfo (M0_6 bsias))
forall sd.
D sd
-> PL (U6 BindSparseInfo) ss1 -> IO (PL BindSparseInfo (M0_6 ss1))
bindSparseInfosToMiddle D sd
dv PL (U6 BindSparseInfo) ss1
is

-- instance BindSparse