{-# language CPP #-}
module Vulkan.Core11.DeviceInitialization  (enumerateInstanceVersion) where

import Control.Exception.Base (bracket)
import Control.Monad (unless)
import Control.Monad.IO.Class (liftIO)
import Foreign.Marshal.Alloc (callocBytes)
import Foreign.Marshal.Alloc (free)
import GHC.Base (when)
import GHC.IO (throwIO)
import Foreign.Ptr (castFunPtr)
import GHC.Ptr (nullFunPtr)
import Foreign.Ptr (nullPtr)
import Control.Monad.Trans.Class (lift)
import Control.Monad.Trans.Cont (evalContT)
import Control.Monad.IO.Class (MonadIO)
import Foreign.Storable (Storable(peek))
import GHC.IO.Exception (IOErrorType(..))
import GHC.IO.Exception (IOException(..))
import Foreign.Ptr (FunPtr)
import Foreign.Ptr (Ptr)
import GHC.Ptr (Ptr(Ptr))
import Data.Word (Word32)
import Control.Monad.Trans.Cont (ContT(..))
import Vulkan.Dynamic (getInstanceProcAddr')
import Vulkan.NamedType ((:::))
import Vulkan.Core10.Enums.Result (Result)
import Vulkan.Core10.Enums.Result (Result(..))
import Vulkan.Exception (VulkanException(..))
import Vulkan.Core10.Enums.Result (Result(SUCCESS))
foreign import ccall
#if !defined(SAFE_FOREIGN_CALLS)
  unsafe
#endif
  "dynamic" mkVkEnumerateInstanceVersion
  :: FunPtr (Ptr Word32 -> IO Result) -> Ptr Word32 -> IO Result

-- | vkEnumerateInstanceVersion - Query instance-level version before
-- instance creation
--
-- = Description
--
-- Note
--
-- The intended behaviour of 'enumerateInstanceVersion' is that an
-- implementation /should/ not need to perform memory allocations and
-- /should/ unconditionally return 'Vulkan.Core10.Enums.Result.SUCCESS'.
-- The loader, and any enabled layers, /may/ return
-- 'Vulkan.Core10.Enums.Result.ERROR_OUT_OF_HOST_MEMORY' in the case of a
-- failed memory allocation.
--
-- == Return Codes
--
-- [<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#fundamentals-successcodes Success>]
--
--     -   'Vulkan.Core10.Enums.Result.SUCCESS'
--
-- [<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#fundamentals-errorcodes Failure>]
--
--     -   'Vulkan.Core10.Enums.Result.ERROR_OUT_OF_HOST_MEMORY'
--
-- = See Also
--
-- No cross-references are available
enumerateInstanceVersion :: forall io
                          . (MonadIO io)
                         => io (("apiVersion" ::: Word32))
enumerateInstanceVersion :: io ("apiVersion" ::: Word32)
enumerateInstanceVersion  = IO ("apiVersion" ::: Word32) -> io ("apiVersion" ::: Word32)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO ("apiVersion" ::: Word32) -> io ("apiVersion" ::: Word32))
-> (ContT ("apiVersion" ::: Word32) IO ("apiVersion" ::: Word32)
    -> IO ("apiVersion" ::: Word32))
-> ContT ("apiVersion" ::: Word32) IO ("apiVersion" ::: Word32)
-> io ("apiVersion" ::: Word32)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ContT ("apiVersion" ::: Word32) IO ("apiVersion" ::: Word32)
-> IO ("apiVersion" ::: Word32)
forall (m :: * -> *) r. Monad m => ContT r m r -> m r
evalContT (ContT ("apiVersion" ::: Word32) IO ("apiVersion" ::: Word32)
 -> io ("apiVersion" ::: Word32))
-> ContT ("apiVersion" ::: Word32) IO ("apiVersion" ::: Word32)
-> io ("apiVersion" ::: Word32)
forall a b. (a -> b) -> a -> b
$ do
  FunPtr
  (("pApiVersion" ::: Ptr ("apiVersion" ::: Word32)) -> IO Result)
vkEnumerateInstanceVersionPtr <- IO
  (FunPtr
     (("pApiVersion" ::: Ptr ("apiVersion" ::: Word32)) -> IO Result))
-> ContT
     ("apiVersion" ::: Word32)
     IO
     (FunPtr
        (("pApiVersion" ::: Ptr ("apiVersion" ::: Word32)) -> IO Result))
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (IO
   (FunPtr
      (("pApiVersion" ::: Ptr ("apiVersion" ::: Word32)) -> IO Result))
 -> ContT
      ("apiVersion" ::: Word32)
      IO
      (FunPtr
         (("pApiVersion" ::: Ptr ("apiVersion" ::: Word32)) -> IO Result)))
-> IO
     (FunPtr
        (("pApiVersion" ::: Ptr ("apiVersion" ::: Word32)) -> IO Result))
-> ContT
     ("apiVersion" ::: Word32)
     IO
     (FunPtr
        (("pApiVersion" ::: Ptr ("apiVersion" ::: Word32)) -> IO Result))
forall a b. (a -> b) -> a -> b
$ FunPtr FN_vkVoidFunction
-> FunPtr
     (("pApiVersion" ::: Ptr ("apiVersion" ::: Word32)) -> IO Result)
forall a b. FunPtr a -> FunPtr b
castFunPtr @_ @(("pApiVersion" ::: Ptr Word32) -> IO Result) (FunPtr FN_vkVoidFunction
 -> FunPtr
      (("pApiVersion" ::: Ptr ("apiVersion" ::: Word32)) -> IO Result))
-> IO (FunPtr FN_vkVoidFunction)
-> IO
     (FunPtr
        (("pApiVersion" ::: Ptr ("apiVersion" ::: Word32)) -> IO Result))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr Instance_T
-> ("pName" ::: Ptr CChar) -> IO (FunPtr FN_vkVoidFunction)
getInstanceProcAddr' Ptr Instance_T
forall a. Ptr a
nullPtr (Addr# -> "pName" ::: Ptr CChar
forall a. Addr# -> Ptr a
Ptr "vkEnumerateInstanceVersion"#)
  IO () -> ContT ("apiVersion" ::: Word32) IO ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (IO () -> ContT ("apiVersion" ::: Word32) IO ())
-> IO () -> ContT ("apiVersion" ::: Word32) IO ()
forall a b. (a -> b) -> a -> b
$ Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (FunPtr
  (("pApiVersion" ::: Ptr ("apiVersion" ::: Word32)) -> IO Result)
vkEnumerateInstanceVersionPtr FunPtr
  (("pApiVersion" ::: Ptr ("apiVersion" ::: Word32)) -> IO Result)
-> FunPtr
     (("pApiVersion" ::: Ptr ("apiVersion" ::: Word32)) -> IO Result)
-> Bool
forall a. Eq a => a -> a -> Bool
/= FunPtr
  (("pApiVersion" ::: Ptr ("apiVersion" ::: Word32)) -> IO Result)
forall a. FunPtr a
nullFunPtr) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
    IOException -> IO ()
forall e a. Exception e => e -> IO a
throwIO (IOException -> IO ()) -> IOException -> IO ()
forall a b. (a -> b) -> a -> b
$ Maybe Handle
-> IOErrorType
-> String
-> String
-> Maybe CInt
-> Maybe String
-> IOException
IOError Maybe Handle
forall a. Maybe a
Nothing IOErrorType
InvalidArgument "" "The function pointer for vkEnumerateInstanceVersion is null" Maybe CInt
forall a. Maybe a
Nothing Maybe String
forall a. Maybe a
Nothing
  let vkEnumerateInstanceVersion' :: ("pApiVersion" ::: Ptr ("apiVersion" ::: Word32)) -> IO Result
vkEnumerateInstanceVersion' = FunPtr
  (("pApiVersion" ::: Ptr ("apiVersion" ::: Word32)) -> IO Result)
-> ("pApiVersion" ::: Ptr ("apiVersion" ::: Word32)) -> IO Result
mkVkEnumerateInstanceVersion FunPtr
  (("pApiVersion" ::: Ptr ("apiVersion" ::: Word32)) -> IO Result)
vkEnumerateInstanceVersionPtr
  "pApiVersion" ::: Ptr ("apiVersion" ::: Word32)
pPApiVersion <- ((("pApiVersion" ::: Ptr ("apiVersion" ::: Word32))
  -> IO ("apiVersion" ::: Word32))
 -> IO ("apiVersion" ::: Word32))
-> ContT
     ("apiVersion" ::: Word32)
     IO
     ("pApiVersion" ::: Ptr ("apiVersion" ::: Word32))
forall k (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (((("pApiVersion" ::: Ptr ("apiVersion" ::: Word32))
   -> IO ("apiVersion" ::: Word32))
  -> IO ("apiVersion" ::: Word32))
 -> ContT
      ("apiVersion" ::: Word32)
      IO
      ("pApiVersion" ::: Ptr ("apiVersion" ::: Word32)))
-> ((("pApiVersion" ::: Ptr ("apiVersion" ::: Word32))
     -> IO ("apiVersion" ::: Word32))
    -> IO ("apiVersion" ::: Word32))
-> ContT
     ("apiVersion" ::: Word32)
     IO
     ("pApiVersion" ::: Ptr ("apiVersion" ::: Word32))
forall a b. (a -> b) -> a -> b
$ IO ("pApiVersion" ::: Ptr ("apiVersion" ::: Word32))
-> (("pApiVersion" ::: Ptr ("apiVersion" ::: Word32)) -> IO ())
-> (("pApiVersion" ::: Ptr ("apiVersion" ::: Word32))
    -> IO ("apiVersion" ::: Word32))
-> IO ("apiVersion" ::: Word32)
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket (Int -> IO ("pApiVersion" ::: Ptr ("apiVersion" ::: Word32))
forall a. Int -> IO (Ptr a)
callocBytes @Word32 4) ("pApiVersion" ::: Ptr ("apiVersion" ::: Word32)) -> IO ()
forall a. Ptr a -> IO ()
free
  Result
r <- IO Result -> ContT ("apiVersion" ::: Word32) IO Result
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (IO Result -> ContT ("apiVersion" ::: Word32) IO Result)
-> IO Result -> ContT ("apiVersion" ::: Word32) IO Result
forall a b. (a -> b) -> a -> b
$ ("pApiVersion" ::: Ptr ("apiVersion" ::: Word32)) -> IO Result
vkEnumerateInstanceVersion' ("pApiVersion" ::: Ptr ("apiVersion" ::: Word32)
pPApiVersion)
  IO () -> ContT ("apiVersion" ::: Word32) IO ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (IO () -> ContT ("apiVersion" ::: Word32) IO ())
-> IO () -> ContT ("apiVersion" ::: Word32) IO ()
forall a b. (a -> b) -> a -> b
$ Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Result
r Result -> Result -> Bool
forall a. Ord a => a -> a -> Bool
< Result
SUCCESS) (VulkanException -> IO ()
forall e a. Exception e => e -> IO a
throwIO (Result -> VulkanException
VulkanException Result
r))
  "apiVersion" ::: Word32
pApiVersion <- IO ("apiVersion" ::: Word32)
-> ContT ("apiVersion" ::: Word32) IO ("apiVersion" ::: Word32)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (IO ("apiVersion" ::: Word32)
 -> ContT ("apiVersion" ::: Word32) IO ("apiVersion" ::: Word32))
-> IO ("apiVersion" ::: Word32)
-> ContT ("apiVersion" ::: Word32) IO ("apiVersion" ::: Word32)
forall a b. (a -> b) -> a -> b
$ ("pApiVersion" ::: Ptr ("apiVersion" ::: Word32))
-> IO ("apiVersion" ::: Word32)
forall a. Storable a => Ptr a -> IO a
peek @Word32 "pApiVersion" ::: Ptr ("apiVersion" ::: Word32)
pPApiVersion
  ("apiVersion" ::: Word32)
-> ContT ("apiVersion" ::: Word32) IO ("apiVersion" ::: Word32)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (("apiVersion" ::: Word32)
 -> ContT ("apiVersion" ::: Word32) IO ("apiVersion" ::: Word32))
-> ("apiVersion" ::: Word32)
-> ContT ("apiVersion" ::: Word32) IO ("apiVersion" ::: Word32)
forall a b. (a -> b) -> a -> b
$ ("apiVersion" ::: Word32
pApiVersion)