summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOliverCharles <>2019-06-11 21:25:00 (GMT)
committerhdiff <hdiff@hdiff.luite.com>2019-06-11 21:25:00 (GMT)
commit83cafd28fee76051835c9abbe10f1afd0e0baaa2 (patch)
tree5cdf61b0a423795e8abd5f8653639262d17b65fe
parent04609cd12cfa4dda0f6ef46b76ae1ab602c5084a (diff)
version 2.5.0.0HEAD2.5.0.0master
-rwxr-xr-x[-rw-r--r--]ChangeLog.md12
-rw-r--r--bench/Space.hs4
-rwxr-xr-x[-rw-r--r--]cbits/sdlhelper.c0
-rw-r--r--examples/EventWatch.hs18
-rw-r--r--examples/OpenGLExample.hs2
-rwxr-xr-x[-rw-r--r--]include/sdlhelper.h0
-rw-r--r--sdl2.cabal10
-rw-r--r--src/SDL/Raw/Enum.hsc2
-rw-r--r--src/SDL/Raw/Types.hsc8
-rw-r--r--src/SDL/Raw/Video.hs41
-rw-r--r--src/SDL/Video.hs107
-rw-r--r--src/SDL/Video/Vulkan.hs110
12 files changed, 253 insertions, 61 deletions
diff --git a/ChangeLog.md b/ChangeLog.md
index ab3d450..ae2f480 100644..100755
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,13 @@
+2.5.0.0
+=======
+
+* Version 2.0.6 of the SDL2 C library is now required.
+
+* Added Vulkan support. See `SDL.Video.WindowGraphicsContext` data type and `SDL.Video.Vulkan` module.
+
+* Support `StateVar` < 1.3
+
+
2.4.1.0
=======
@@ -11,7 +21,7 @@
https://github.com/haskell-game/sdl2/pull/177 for more information. Thanks to
@Linearity for identifying and fixing this bug.
-
+
2.4.0.1
=======
* Raise upper bounds for `exceptions` to <0.11
diff --git a/bench/Space.hs b/bench/Space.hs
index 1b047b5..64917fa 100644
--- a/bench/Space.hs
+++ b/bench/Space.hs
@@ -44,9 +44,9 @@ main =
(\weight ->
if weightGCs weight > 0
then Just "Non-zero number of garbage collections!"
- else if weightAllocatedBytes weight > 3000
+ else if weightAllocatedBytes weight > 4000
then Just
- "Allocated >3KB! Allocations should be constant."
+ "Allocated >4KB! Allocations should be constant."
else Nothing)
| i <- [1, 10, 100, 1000, 10000]
])
diff --git a/cbits/sdlhelper.c b/cbits/sdlhelper.c
index 97ac752..97ac752 100644..100755
--- a/cbits/sdlhelper.c
+++ b/cbits/sdlhelper.c
diff --git a/examples/EventWatch.hs b/examples/EventWatch.hs
index 3dfcf5b..85e4e30 100644
--- a/examples/EventWatch.hs
+++ b/examples/EventWatch.hs
@@ -18,15 +18,15 @@ main :: IO ()
main = do
initializeAll
window <- createWindow "resize" WindowConfig {
- windowBorder = True
- , windowHighDPI = False
- , windowInputGrabbed = False
- , windowMode = Windowed
- , windowOpenGL = Nothing
- , windowPosition = Wherever
- , windowResizable = True
- , windowInitialSize = V2 800 600
- , windowVisible = True
+ windowBorder = True
+ , windowHighDPI = False
+ , windowInputGrabbed = False
+ , windowMode = Windowed
+ , windowGraphicsContext = NoGraphicsContext
+ , windowPosition = Wherever
+ , windowResizable = True
+ , windowInitialSize = V2 800 600
+ , windowVisible = True
}
renderer <- createRenderer window (-1) defaultRenderer
addEventWatch $ \ev ->
diff --git a/examples/OpenGLExample.hs b/examples/OpenGLExample.hs
index d56e5cc..5953fe9 100644
--- a/examples/OpenGLExample.hs
+++ b/examples/OpenGLExample.hs
@@ -31,7 +31,7 @@ main = do
SDL.createWindow
"SDL / OpenGL Example"
SDL.defaultWindow {SDL.windowInitialSize = V2 screenWidth screenHeight,
- SDL.windowOpenGL = Just SDL.defaultOpenGL}
+ SDL.windowGraphicsContext = SDL.OpenGLContext SDL.defaultOpenGL}
SDL.showWindow window
_ <- SDL.glCreateContext window
diff --git a/include/sdlhelper.h b/include/sdlhelper.h
index 51784c9..51784c9 100644..100755
--- a/include/sdlhelper.h
+++ b/include/sdlhelper.h
diff --git a/sdl2.cabal b/sdl2.cabal
index 1494a0f..5a1aa4d 100644
--- a/sdl2.cabal
+++ b/sdl2.cabal
@@ -1,6 +1,6 @@
name: sdl2
-version: 2.4.1.0
-synopsis: Both high- and low-level bindings to the SDL library (version 2.0.4+).
+version: 2.5.0.0
+synopsis: Both high- and low-level bindings to the SDL library (version 2.0.6+).
description:
This package contains bindings to the SDL 2 library, in both high- and
low-level forms:
@@ -78,6 +78,7 @@ library
SDL.Video
SDL.Video.OpenGL
SDL.Video.Renderer
+ SDL.Video.Vulkan
SDL.Internal.Exception
SDL.Internal.Numbered
@@ -113,19 +114,20 @@ library
includes:
SDL.h
+ SDL_vulkan.h
sdlhelper.h
extra-libraries:
SDL2
pkgconfig-depends:
- sdl2 >= 2.0.4
+ sdl2 >= 2.0.6
build-depends:
base >= 4.7 && < 5,
bytestring >= 0.10.4.0 && < 0.11,
exceptions >= 0.4 && < 0.11,
- StateVar >= 1.1.0.0 && < 1.2,
+ StateVar >= 1.1.0.0 && < 1.3,
text >= 1.1.0.0 && < 1.3,
transformers >= 0.2 && < 0.6,
vector >= 0.10.9.0 && < 0.13
diff --git a/src/SDL/Raw/Enum.hsc b/src/SDL/Raw/Enum.hsc
index b322181..a0bd370 100644
--- a/src/SDL/Raw/Enum.hsc
+++ b/src/SDL/Raw/Enum.hsc
@@ -898,6 +898,7 @@ module SDL.Raw.Enum (
pattern SDL_WINDOW_FOREIGN,
pattern SDL_WINDOW_ALLOW_HIGHDPI,
pattern SDL_WINDOW_MOUSE_CAPTURE,
+ pattern SDL_WINDOW_VULKAN,
-- ** Window Positioning
pattern SDL_WINDOWPOS_UNDEFINED,
@@ -1767,6 +1768,7 @@ pattern SDL_WINDOW_FULLSCREEN_DESKTOP = (#const SDL_WINDOW_FULLSCREEN_DESKTOP)
pattern SDL_WINDOW_FOREIGN = (#const SDL_WINDOW_FOREIGN)
pattern SDL_WINDOW_ALLOW_HIGHDPI = (#const SDL_WINDOW_ALLOW_HIGHDPI)
pattern SDL_WINDOW_MOUSE_CAPTURE = (#const SDL_WINDOW_MOUSE_CAPTURE)
+pattern SDL_WINDOW_VULKAN = (#const SDL_WINDOW_VULKAN)
pattern SDL_WINDOWPOS_UNDEFINED = (#const SDL_WINDOWPOS_UNDEFINED)
pattern SDL_WINDOWPOS_CENTERED = (#const SDL_WINDOWPOS_CENTERED)
diff --git a/src/SDL/Raw/Types.hsc b/src/SDL/Raw/Types.hsc
index eaf1ac8..37d8d14 100644
--- a/src/SDL/Raw/Types.hsc
+++ b/src/SDL/Raw/Types.hsc
@@ -2,6 +2,8 @@
module SDL.Raw.Types (
-- * Type Aliases
-- ** Function Types
+ VkGetInstanceProcAddrFunc,
+
AudioCallback,
EventFilter,
HintCallback,
@@ -40,6 +42,8 @@ module SDL.Raw.Types (
TimerID,
TLSID,
TouchID,
+ VkInstance,
+ VkSurfaceKHR,
Window,
-- * Data Structures
@@ -81,6 +85,8 @@ import Foreign.Ptr
import Foreign.Storable
import SDL.Raw.Enum
+type VkGetInstanceProcAddrFunc = VkInstance -> CString -> IO (FunPtr ())
+
type AudioCallback = FunPtr (Ptr () -> Ptr Word8 -> CInt -> IO ())
type EventFilter = FunPtr (Ptr () -> Ptr Event -> IO CInt)
type HintCallback = FunPtr (Ptr () -> CString -> CString -> CString -> IO ())
@@ -140,6 +146,8 @@ type ThreadID = CULong
type TimerID = CInt
type TLSID = CUInt
type TouchID = Int64
+type VkInstance = Ptr ()
+type VkSurfaceKHR = Word64
type Window = Ptr ()
data Atomic = Atomic
diff --git a/src/SDL/Raw/Video.hs b/src/SDL/Raw/Video.hs
index b4dea24..08c8855 100644
--- a/src/SDL/Raw/Video.hs
+++ b/src/SDL/Raw/Video.hs
@@ -195,7 +195,15 @@ module SDL.Raw.Video (
-- * Clipboard Handling
getClipboardText,
hasClipboardText,
- setClipboardText
+ setClipboardText,
+
+ -- * Vulkan support functions
+ vkLoadLibrary,
+ vkGetVkGetInstanceProcAddr,
+ vkUnloadLibrary,
+ vkGetInstanceExtensions,
+ vkCreateSurface,
+ vkGetDrawableSize
) where
import Control.Monad.IO.Class
@@ -396,6 +404,13 @@ foreign import ccall "SDL.h SDL_GetClipboardText" getClipboardTextFFI :: IO CStr
foreign import ccall "SDL.h SDL_HasClipboardText" hasClipboardTextFFI :: IO Bool
foreign import ccall "SDL.h SDL_SetClipboardText" setClipboardTextFFI :: CString -> IO CInt
+foreign import ccall "SDL_vulkan.h SDL_Vulkan_LoadLibrary" vkLoadLibraryFFI :: CString -> IO CInt
+foreign import ccall "SDL_vulkan.h SDL_Vulkan_GetVkGetInstanceProcAddr" vkGetVkGetInstanceProcAddrFFI :: IO (FunPtr VkGetInstanceProcAddrFunc)
+foreign import ccall "SDL_vulkan.h SDL_Vulkan_UnloadLibrary" vkUnloadLibraryFFI :: IO ()
+foreign import ccall "SDL_vulkan.h SDL_Vulkan_GetInstanceExtensions" vkGetInstanceExtensionsFFI :: Window -> Ptr CUInt -> Ptr CString -> IO Bool
+foreign import ccall "SDL_vulkan.h SDL_Vulkan_CreateSurface" vkCreateSurfaceFFI :: Window -> VkInstance -> Ptr VkSurfaceKHR -> IO Bool
+foreign import ccall "SDL_vulkan.h SDL_Vulkan_GetDrawableSize" vkGetDrawableSizeFFI :: Window -> Ptr CInt -> Ptr CInt -> IO ()
+
createWindow :: MonadIO m => CString -> CInt -> CInt -> CInt -> CInt -> Word32 -> m Window
createWindow v1 v2 v3 v4 v5 v6 = liftIO $ createWindowFFI v1 v2 v3 v4 v5 v6
{-# INLINE createWindow #-}
@@ -1135,3 +1150,27 @@ hasClipboardText = liftIO hasClipboardTextFFI
setClipboardText :: MonadIO m => CString -> m CInt
setClipboardText v1 = liftIO $ setClipboardTextFFI v1
{-# INLINE setClipboardText #-}
+
+vkLoadLibrary :: MonadIO m => CString -> m CInt
+vkLoadLibrary v1 = liftIO $ setClipboardTextFFI v1
+{-# INLINE vkLoadLibrary #-}
+
+vkGetVkGetInstanceProcAddr :: MonadIO m => m (FunPtr VkGetInstanceProcAddrFunc)
+vkGetVkGetInstanceProcAddr = liftIO vkGetVkGetInstanceProcAddrFFI
+{-# INLINE vkGetVkGetInstanceProcAddr #-}
+
+vkUnloadLibrary :: MonadIO m => m ()
+vkUnloadLibrary = liftIO vkUnloadLibraryFFI
+{-# INLINE vkUnloadLibrary #-}
+
+vkGetInstanceExtensions :: MonadIO m => Window -> Ptr CUInt -> Ptr CString -> m Bool
+vkGetInstanceExtensions v1 v2 v3 = liftIO $ vkGetInstanceExtensionsFFI v1 v2 v3
+{-# INLINE vkGetInstanceExtensions #-}
+
+vkCreateSurface :: MonadIO m => Window -> VkInstance -> Ptr VkSurfaceKHR -> m Bool
+vkCreateSurface v1 v2 v3 = liftIO $ vkCreateSurfaceFFI v1 v2 v3
+{-# INLINE vkCreateSurface #-}
+
+vkGetDrawableSize :: MonadIO m => Window -> Ptr CInt -> Ptr CInt -> m ()
+vkGetDrawableSize v1 v2 v3 = liftIO $ vkGetDrawableSizeFFI v1 v2 v3
+{-# INLINE vkGetDrawableSize #-}
diff --git a/src/SDL/Video.hs b/src/SDL/Video.hs
index 955a334..8bd582f 100644
--- a/src/SDL/Video.hs
+++ b/src/SDL/Video.hs
@@ -12,6 +12,7 @@ module SDL.Video
, createWindow
, defaultWindow
, WindowConfig(..)
+ , WindowGraphicsContext(..)
, WindowMode(..)
, WindowPosition(..)
, destroyWindow
@@ -103,9 +104,9 @@ import qualified SDL.Raw as Raw
-- Throws 'SDLException' on failure.
createWindow :: MonadIO m => Text -> WindowConfig -> m Window
createWindow title config = liftIO $ do
- case windowOpenGL config of
- Just glcfg -> setGLAttributes glcfg
- Nothing -> return ()
+ case windowGraphicsContext config of
+ OpenGLContext glcfg -> setGLAttributes glcfg
+ _ -> return ()
BS.useAsCString (Text.encodeUtf8 title) $ \title' -> do
let create = Raw.createWindow title'
@@ -120,9 +121,10 @@ createWindow title config = liftIO $ do
, if windowHighDPI config then Raw.SDL_WINDOW_ALLOW_HIGHDPI else 0
, if windowInputGrabbed config then Raw.SDL_WINDOW_INPUT_GRABBED else 0
, toNumber $ windowMode config
- , if isJust $ windowOpenGL config then Raw.SDL_WINDOW_OPENGL else 0
+ , if ctxIsOpenGL (windowGraphicsContext config) then Raw.SDL_WINDOW_OPENGL else 0
, if windowResizable config then Raw.SDL_WINDOW_RESIZABLE else 0
, if windowVisible config then 0 else Raw.SDL_WINDOW_HIDDEN
+ , if windowGraphicsContext config == VulkanContext then Raw.SDL_WINDOW_VULKAN else 0
]
setGLAttributes (OpenGLConfig (V4 r g b a) d s ms p) = do
let (msk, v0, v1, flg) = case p of
@@ -152,42 +154,59 @@ createWindow title config = liftIO $ do
--
-- @
-- 'defaultWindow' = 'WindowConfig'
--- { 'windowBorder' = True
--- , 'windowHighDPI' = False
--- , 'windowInputGrabbed' = False
--- , 'windowMode' = 'Windowed'
--- , 'windowOpenGL' = Nothing
--- , 'windowPosition' = 'Wherever'
--- , 'windowResizable' = False
--- , 'windowInitialSize' = V2 800 600
--- , 'windowVisible' = True
+-- { 'windowBorder' = True
+-- , 'windowHighDPI' = False
+-- , 'windowInputGrabbed' = False
+-- , 'windowMode' = 'Windowed'
+-- , 'windowGraphicsContext' = NoGraphicsContext
+-- , 'windowPosition' = 'Wherever'
+-- , 'windowResizable' = False
+-- , 'windowInitialSize' = V2 800 600
+-- , 'windowVisible' = True
-- }
-- @
defaultWindow :: WindowConfig
defaultWindow = WindowConfig
- { windowBorder = True
- , windowHighDPI = False
- , windowInputGrabbed = False
- , windowMode = Windowed
- , windowOpenGL = Nothing
- , windowPosition = Wherever
- , windowResizable = False
- , windowInitialSize = V2 800 600
- , windowVisible = True
+ { windowBorder = True
+ , windowHighDPI = False
+ , windowInputGrabbed = False
+ , windowMode = Windowed
+ , windowGraphicsContext = NoGraphicsContext
+ , windowPosition = Wherever
+ , windowResizable = False
+ , windowInitialSize = V2 800 600
+ , windowVisible = True
}
data WindowConfig = WindowConfig
- { windowBorder :: Bool -- ^ Defaults to 'True'.
- , windowHighDPI :: Bool -- ^ Defaults to 'False'. Can not be changed after window creation.
- , windowInputGrabbed :: Bool -- ^ Defaults to 'False'. Whether the mouse shall be confined to the window.
- , windowMode :: WindowMode -- ^ Defaults to 'Windowed'.
- , windowOpenGL :: Maybe OpenGLConfig -- ^ Defaults to 'Nothing'. Can not be changed after window creation.
- , windowPosition :: WindowPosition -- ^ Defaults to 'Wherever'.
- , windowResizable :: Bool -- ^ Defaults to 'False'. Whether the window can be resized by the user. It is still possible to programatically change the size by changing 'windowSize'.
- , windowInitialSize :: V2 CInt -- ^ Defaults to @(800, 600)@. If you set 'windowHighDPI' flag, window size in screen coordinates may differ from the size in pixels. Use 'glGetDrawableSize' to get size in pixels.
- , windowVisible :: Bool -- ^ Defaults to 'True'.
+ { windowBorder :: Bool -- ^ Defaults to 'True'.
+ , windowHighDPI :: Bool -- ^ Defaults to 'False'. Can not be changed after window creation.
+ , windowInputGrabbed :: Bool -- ^ Defaults to 'False'. Whether the mouse shall be confined to the window.
+ , windowMode :: WindowMode -- ^ Defaults to 'Windowed'.
+ , windowGraphicsContext :: WindowGraphicsContext -- ^ Defaults to 'NoGraphicsContext'. Can not be changed after window creation.
+ , windowPosition :: WindowPosition -- ^ Defaults to 'Wherever'.
+ , windowResizable :: Bool -- ^ Defaults to 'False'. Whether the window can be resized by the user. It is still possible to programatically change the size by changing 'windowSize'.
+ , windowInitialSize :: V2 CInt -- ^ Defaults to @(800, 600)@. If you set 'windowHighDPI' flag, window size in screen coordinates may differ from the size in pixels. Use 'glGetDrawableSize' or 'SDL.Video.Vulkan.vkGetDrawableSize' to get size in pixels.
+ , windowVisible :: Bool -- ^ Defaults to 'True'.
} deriving (Eq, Generic, Ord, Read, Show, Typeable)
+-- | Configuration of additional graphics context that will be created for window.
+--
+-- Can not be changed after window creation.
+data WindowGraphicsContext
+ = NoGraphicsContext -- ^ Window will be created without any additional graphics context.
+ | OpenGLContext OpenGLConfig -- ^ Window will be created with OpenGL support with parameters from 'OpenGLConfig'.
+ | VulkanContext -- ^ Window will be created with Vulkan support.
+ -- The following functions will be implicitly called by SDL C library:
+ --
+ -- 1. analogue of 'SDL.Video.Vulkan.vkLoadLibrary' 'Nothing' will be called automatically before first window creation;
+ -- 2. analogue of 'SDL.Video.Vulkan.vkUnloadLibrary' will be called after last window destruction.
+ deriving (Eq, Generic, Ord, Read, Show, Typeable)
+
+ctxIsOpenGL :: WindowGraphicsContext -> Bool
+ctxIsOpenGL (OpenGLContext _) = True
+ctxIsOpenGL _ = False
+
data WindowMode
= Fullscreen -- ^ Real fullscreen with a video mode change
| FullscreenDesktop -- ^ Fake fullscreen that takes the size of the desktop
@@ -294,7 +313,8 @@ getWindowAbsolutePosition (Window w) =
-- | Get or set the size of a window's client area. Values beyond the maximum supported size are clamped.
--
--- If window was created with 'windowHighDPI' flag, this size may differ from the size in pixels. Use 'glGetDrawableSize' to get size in pixels.
+-- If window was created with 'windowHighDPI' flag, this size may differ from the size in pixels.
+-- Use 'glGetDrawableSize' or 'SDL.Video.Vulkan.vkGetDrawableSize' to get size in pixels.
--
-- This 'StateVar' can be modified using '$=' and the current value retrieved with 'get'.
--
@@ -339,7 +359,7 @@ windowData (Window w) key = makeStateVar getWindowData setWindowData
-- | Retrieve the configuration of the given window.
--
--- Note that 'Nothing' will be returned instead of potential OpenGL parameters
+-- Note that 'NoGraphicsContext' will be returned instead of potential OpenGL parameters
-- used during the creation of the window.
getWindowConfig :: MonadIO m => Window -> m WindowConfig
getWindowConfig (Window w) = do
@@ -349,16 +369,17 @@ getWindowConfig (Window w) = do
wPos <- getWindowAbsolutePosition (Window w)
return WindowConfig {
- windowBorder = wFlags .&. Raw.SDL_WINDOW_BORDERLESS == 0
- , windowHighDPI = wFlags .&. Raw.SDL_WINDOW_ALLOW_HIGHDPI > 0
- , windowInputGrabbed = wFlags .&. Raw.SDL_WINDOW_INPUT_GRABBED > 0
- , windowMode = fromNumber wFlags
- -- Should we store the openGL config that was used to create the window?
- , windowOpenGL = Nothing
- , windowPosition = Absolute (P wPos)
- , windowResizable = wFlags .&. Raw.SDL_WINDOW_RESIZABLE > 0
- , windowInitialSize = wSize
- , windowVisible = wFlags .&. Raw.SDL_WINDOW_SHOWN > 0
+ windowBorder = wFlags .&. Raw.SDL_WINDOW_BORDERLESS == 0
+ , windowHighDPI = wFlags .&. Raw.SDL_WINDOW_ALLOW_HIGHDPI > 0
+ , windowInputGrabbed = wFlags .&. Raw.SDL_WINDOW_INPUT_GRABBED > 0
+ , windowMode = fromNumber wFlags
+ -- Should we store the OpenGL config that was used to create the window?
+ , windowGraphicsContext = if wFlags .&. Raw.SDL_WINDOW_VULKAN > 0
+ then VulkanContext else NoGraphicsContext
+ , windowPosition = Absolute (P wPos)
+ , windowResizable = wFlags .&. Raw.SDL_WINDOW_RESIZABLE > 0
+ , windowInitialSize = wSize
+ , windowVisible = wFlags .&. Raw.SDL_WINDOW_SHOWN > 0
}
-- | Get the pixel format that is used for the given window.
diff --git a/src/SDL/Video/Vulkan.hs b/src/SDL/Video/Vulkan.hs
new file mode 100644
index 0000000..0c626f1
--- /dev/null
+++ b/src/SDL/Video/Vulkan.hs
@@ -0,0 +1,110 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE LambdaCase #-}
+
+module SDL.Video.Vulkan (
+ -- * Vulkan types
+ VkInstance, VkSurfaceKHR, VkGetInstanceProcAddrFunc,
+ -- * Vulkan loader
+ vkLoadLibrary, vkUnloadLibrary, vkGetVkGetInstanceProcAddr,
+ -- * Vulkan surface
+ vkGetInstanceExtensions, vkCreateSurface,
+ -- * Querying for the drawable size
+ vkGetDrawableSize
+) where
+
+import Control.Monad.IO.Class (MonadIO, liftIO)
+import Foreign hiding (throwIf_, throwIfNeg_)
+import Foreign.C.Types (CInt)
+import Foreign.C.String (CString, withCString)
+import SDL.Vect (V2 (V2))
+import SDL.Internal.Exception (throwIf_, throwIfNeg_)
+import SDL.Internal.Types (Window (Window))
+import SDL.Raw.Types (VkInstance, VkSurfaceKHR, VkGetInstanceProcAddrFunc)
+import qualified SDL.Raw as Raw
+
+#if !MIN_VERSION_base(4,8,0)
+import Control.Applicative
+#endif
+
+-- | Dynamically load a Vulkan loader library.
+--
+-- If a filePath is 'Nothing', SDL will use the value of the environment variable
+-- SDL_VULKAN_LIBRARY, if set, otherwise it loads the default Vulkan
+-- loader library.
+--
+-- This function should be called after initializing the video driver
+-- (i.e. 'SDL.Init.initialize' ['SDL.Init.InitVideo']), but before
+-- creating any windows with 'SDL.Video.windowGraphicsContext' = 'SDL.Video.VulkanContext'.
+--
+-- If no Vulkan loader library is loaded, analogue of 'vkLoadLibrary' 'Nothing'
+-- will be automatically called by SDL C library upon creation of the first Vulkan window.
+--
+-- Throws 'SDL.Exception.SDLException' if there are no working Vulkan drivers installed.
+vkLoadLibrary :: MonadIO m => Maybe FilePath -> m ()
+vkLoadLibrary = \case
+ Nothing -> liftIO . testNeg $ Raw.vkLoadLibrary nullPtr
+ Just filePath -> liftIO . withCString filePath $ testNeg . Raw.vkLoadLibrary
+ where
+ testNeg = throwIfNeg_ "SDL.Video.Vulkan.vkLoadLibrary" "SDL_Vulkan_LoadLibrary"
+
+-- | Unload the Vulkan loader library previously loaded by 'vkLoadLibrary'.
+--
+-- Analogue of this function will be automatically called by SDL C library
+-- after destruction of the last window with
+-- 'SDL.Video.windowGraphicsContext' = 'SDL.Video.VulkanContext'.
+vkUnloadLibrary :: MonadIO m => m ()
+vkUnloadLibrary = Raw.vkUnloadLibrary
+
+foreign import ccall "dynamic" mkVkGetInstanceProcAddrFunc ::
+ FunPtr VkGetInstanceProcAddrFunc -> VkGetInstanceProcAddrFunc
+
+-- | Get the vkGetInstanceProcAddr function, which can be used to obtain another Vulkan functions
+-- (see <https://www.khronos.org/registry/vulkan/specs/1.0/man/html/vkGetInstanceProcAddr.html>).
+--
+-- The 'vkGetVkGetInstanceProcAddr' function should be called after either calling 'vkLoadLibrary'
+-- function or creating first Vulkan window.
+vkGetVkGetInstanceProcAddr :: (Functor m, MonadIO m) => m VkGetInstanceProcAddrFunc
+vkGetVkGetInstanceProcAddr = mkVkGetInstanceProcAddrFunc <$> Raw.vkGetVkGetInstanceProcAddr
+
+-- | Get the names of the Vulkan instance extensions needed to create
+-- a surface with 'vkCreateSurface'.
+--
+-- The extension names queried here must be enabled when calling vkCreateInstance
+-- (see <https://www.khronos.org/registry/vulkan/specs/1.0/man/html/vkCreateInstance.html>),
+-- otherwise 'vkCreateSurface' will fail.
+--
+-- Window should have been created with 'SDL.Video.windowGraphicsContext' = 'SDL.Video.VulkanContext'.
+--
+-- Throws 'SDL.Exception.SDLException' on failure.
+vkGetInstanceExtensions :: MonadIO m => Window -> m [CString]
+vkGetInstanceExtensions (Window w) = liftIO . alloca $ \countPtr -> do
+ throwIf_ not "SDL.Video.Vulkan.vkGetInstanceExtensions (1)" "SDL_Vulkan_GetInstanceExtensions" $
+ Raw.vkGetInstanceExtensions w countPtr nullPtr
+ count <- fromIntegral <$> peek countPtr
+ allocaArray count $ \sPtr ->
+ throwIf_ not "SDL.Video.Vulkan.vkGetInstanceExtensions (2)" "SDL_Vulkan_GetInstanceExtensions"
+ (Raw.vkGetInstanceExtensions w countPtr sPtr) >> peekArray count sPtr
+
+-- | Create a Vulkan rendering surface for a window.
+--
+-- Window should have been created with 'SDL.Video.windowGraphicsContext' = 'SDL.Video.VulkanContext'.
+--
+-- Instance should have been created with the extensions returned
+-- by 'vkGetInstanceExtensions' enabled.
+--
+-- Throws 'SDL.Exception.SDLException' on failure.
+vkCreateSurface :: MonadIO m => Window -> VkInstance -> m VkSurfaceKHR
+vkCreateSurface (Window w) vkInstance = liftIO . alloca $ \vkSurfacePtr ->
+ throwIf_ not "SDL.Video.Vulkan.vkCreateSurface" "SDL_Vulkan_CreateSurface"
+ (Raw.vkCreateSurface w vkInstance vkSurfacePtr) >> peek vkSurfacePtr
+
+-- | Get the size of a window's underlying drawable area in pixels (for use
+-- with setting viewport, scissor & etc).
+--
+-- It may differ from 'SDL.Video.windowSize' if window was created with 'SDL.Video.windowHighDPI' flag.
+vkGetDrawableSize :: MonadIO m => Window -> m (V2 CInt)
+vkGetDrawableSize (Window w) = liftIO . alloca $ \wptr ->
+ alloca $ \hptr -> do
+ Raw.vkGetDrawableSize w wptr hptr
+ V2 <$> peek wptr <*> peek hptr