diff --git a/VulkanMemoryAllocator.cabal b/VulkanMemoryAllocator.cabal
--- a/VulkanMemoryAllocator.cabal
+++ b/VulkanMemoryAllocator.cabal
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           VulkanMemoryAllocator
-version:        0.10.2
+version:        0.10.3.1
 synopsis:       Bindings to the VulkanMemoryAllocator library
 category:       Graphics
 homepage:       https://github.com/expipiplus1/vulkan#readme
@@ -84,7 +84,7 @@
       UndecidableInstances
       ViewPatterns
   ghc-options: -Wall -Wno-unticked-promoted-constructors -Wno-missing-pattern-synonym-signatures -Wno-unused-imports -Wno-missing-signatures -Wno-partial-type-signatures
-  cxx-options: -std=c++14
+  cxx-options: -std=c++17
   include-dirs:
       VulkanMemoryAllocator/include
   cxx-sources:
@@ -106,5 +106,5 @@
   if flag(generic-instances)
     cpp-options: -DGENERIC_INSTANCES
   if impl(ghc >= 8.10)
-    ghc-options: -optcxx -std=c++14
+    ghc-options: -optcxx -std=c++17
   default-language: Haskell2010
diff --git a/VulkanMemoryAllocator/include/vk_mem_alloc.h b/VulkanMemoryAllocator/include/vk_mem_alloc.h
--- a/VulkanMemoryAllocator/include/vk_mem_alloc.h
+++ b/VulkanMemoryAllocator/include/vk_mem_alloc.h
@@ -2693,6 +2693,30 @@
    #define VMA_NULL   nullptr
 #endif
 
+// Normal assert to check for programmer's errors, especially in Debug configuration.
+#ifndef VMA_ASSERT
+   #ifdef NDEBUG
+       #define VMA_ASSERT(expr)
+   #else
+       #define VMA_ASSERT(expr)         assert(expr)
+   #endif
+#endif
+
+// Assert that will be called very often, like inside data structures e.g. operator[].
+// Making it non-empty can make program slow.
+#ifndef VMA_HEAVY_ASSERT
+   #ifdef NDEBUG
+       #define VMA_HEAVY_ASSERT(expr)
+   #else
+       #define VMA_HEAVY_ASSERT(expr)   //VMA_ASSERT(expr)
+   #endif
+#endif
+
+// If your compiler is not compatible with C++17 and definition of
+// aligned_alloc() function is missing, uncommenting following line may help:
+
+//#include <malloc.h>
+
 #if defined(__ANDROID_API__) && (__ANDROID_API__ < 16)
 #include <cstdlib>
 static void* vma_aligned_alloc(size_t alignment, size_t size)
@@ -2745,11 +2769,17 @@
 {
     return _aligned_malloc(size, alignment);
 }
-#else
+#elif __cplusplus >= 201703L // Compiler conforms to C++17.
 static void* vma_aligned_alloc(size_t alignment, size_t size)
 {
     return aligned_alloc(alignment, size);
 }
+#else
+static void* vma_aligned_alloc(size_t alignment, size_t size)
+{
+    VMA_ASSERT(0 && "Could not implement aligned_alloc automatically. Please enable C++17 or later in your compiler or provide custom implementation of macro VMA_SYSTEM_ALIGNED_MALLOC (and VMA_SYSTEM_ALIGNED_FREE if needed) using the API of your system.");
+    return VMA_NULL;
+}
 #endif
 
 #if defined(_WIN32)
@@ -2764,30 +2794,6 @@
 }
 #endif
 
-// If your compiler is not compatible with C++11 and definition of
-// aligned_alloc() function is missing, uncommeting following line may help:
-
-//#include <malloc.h>
-
-// Normal assert to check for programmer's errors, especially in Debug configuration.
-#ifndef VMA_ASSERT
-   #ifdef NDEBUG
-       #define VMA_ASSERT(expr)
-   #else
-       #define VMA_ASSERT(expr)         assert(expr)
-   #endif
-#endif
-
-// Assert that will be called very often, like inside data structures e.g. operator[].
-// Making it non-empty can make program slow.
-#ifndef VMA_HEAVY_ASSERT
-   #ifdef NDEBUG
-       #define VMA_HEAVY_ASSERT(expr)
-   #else
-       #define VMA_HEAVY_ASSERT(expr)   //VMA_ASSERT(expr)
-   #endif
-#endif
-
 #ifndef VMA_ALIGN_OF
    #define VMA_ALIGN_OF(type)       (__alignof(type))
 #endif
@@ -3025,7 +3031,7 @@
 or a persistently mapped allocation is created and destroyed several times in a row.
 It keeps additional +1 mapping of a device memory block to prevent calling actual
 vkMapMemory/vkUnmapMemory too many times, which may improve performance and help
-tools like RenderDOc.
+tools like RenderDoc.
 */
 #ifndef VMA_MAPPING_HYSTERESIS_ENABLED
     #define VMA_MAPPING_HYSTERESIS_ENABLED 1
@@ -3335,7 +3341,7 @@
     return (val + alignment - 1) & ~(alignment - 1);
 }
 
-// Aligns given value down to nearest multiply of align value. For example: VmaAlignUp(11, 8) = 8.
+// Aligns given value down to nearest multiply of align value. For example: VmaAlignDown(11, 8) = 8.
 // Use types like uint32_t, uint64_t as T.
 template <typename T>
 static inline T VmaAlignDown(T val, T alignment)
@@ -16163,11 +16169,11 @@
 
                 json.WriteString("apiVersion");
                 json.BeginString();
-                json.ContinueString(VK_API_VERSION_MAJOR(deviceProperties.apiVersion));
+                json.ContinueString(VK_VERSION_MAJOR(deviceProperties.apiVersion));
                 json.ContinueString(".");
-                json.ContinueString(VK_API_VERSION_MINOR(deviceProperties.apiVersion));
+                json.ContinueString(VK_VERSION_MINOR(deviceProperties.apiVersion));
                 json.ContinueString(".");
-                json.ContinueString(VK_API_VERSION_PATCH(deviceProperties.apiVersion));
+                json.ContinueString(VK_VERSION_PATCH(deviceProperties.apiVersion));
                 json.EndString();
 
                 json.WriteString("GPU");
@@ -17825,7 +17831,7 @@
 
 For example, a staging buffer that will be filled via mapped pointer and then
 used as a source of transfer to the buffer described previously can be created like this.
-It will likely and up in a memory type that is `HOST_VISIBLE` and `HOST_COHERENT`
+It will likely end up in a memory type that is `HOST_VISIBLE` and `HOST_COHERENT`
 but not `HOST_CACHED` (meaning uncached, write-combined) and not `DEVICE_LOCAL` (meaning system RAM).
 
 \code
@@ -19068,7 +19074,7 @@
 \section usage_patterns_staging_copy_upload Staging copy for upload
 
 <b>When:</b>
-A "staging" buffer than you want to map and fill from CPU code, then use as a source od transfer
+A "staging" buffer than you want to map and fill from CPU code, then use as a source of transfer
 to some GPU resource.
 
 <b>What to do:</b>
@@ -19135,7 +19141,7 @@
 \section usage_patterns_advanced_data_uploading Advanced data uploading
 
 For resources that you frequently write on CPU via mapped pointer and
-freqnently read on GPU e.g. as a uniform buffer (also called "dynamic"), multiple options are possible:
+frequently read on GPU e.g. as a uniform buffer (also called "dynamic"), multiple options are possible:
 
 -# Easiest solution is to have one copy of the resource in `HOST_VISIBLE` memory,
    even if it means system RAM (not `DEVICE_LOCAL`) on systems with a discrete graphics card,
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -2,6 +2,12 @@
 
 ## WIP
 
+## [0.10.3.1] - 2022-09-27
+- Enable c++17 to get VMA aligned alloc
+
+## [0.10.3] - 2022-09-25
+- Add Vulkan 1.3 functions to VulkanFunctions
+
 ## [0.10.2] - 2022-09-24
 - Raise upper bound on `vulkan`
 
diff --git a/package.yaml b/package.yaml
--- a/package.yaml
+++ b/package.yaml
@@ -1,5 +1,5 @@
 name: VulkanMemoryAllocator
-version: "0.10.2"
+version: "0.10.3.1"
 synopsis: Bindings to the VulkanMemoryAllocator library
 category: Graphics
 maintainer: Ellie Hermaszewska <live.long.and.prosper@monoid.al>
@@ -36,7 +36,7 @@
     # Work around https://github.com/haskell/cabal/pull/7074
     - condition: "impl(ghc >= 8.10)"
       ghc-options:
-        - -optcxx -std=c++14
+        - -optcxx -std=c++17
     - condition: false
       other-modules: Paths_VulkanMemoryAllocator
   ghc-options:
@@ -47,7 +47,7 @@
     - -Wno-missing-signatures
     - -Wno-partial-type-signatures
   cxx-options:
-    - -std=c++14
+    - -std=c++17
   verbatim:
     other-modules:
 
diff --git a/src/VulkanMemoryAllocator.hs b/src/VulkanMemoryAllocator.hs
--- a/src/VulkanMemoryAllocator.hs
+++ b/src/VulkanMemoryAllocator.hs
@@ -193,4697 +193,5237 @@
 import Vulkan (BufferCreateInfo)
 import Vulkan (BufferMemoryRequirementsInfo2)
 import Vulkan (CommandBuffer_T)
-import Vulkan (DeviceMemory)
-import Vulkan (DeviceSize)
-import Vulkan (Device_T)
-import Vulkan (ExternalMemoryHandleTypeFlagsKHR)
-import Vulkan (Flags)
-import Vulkan (Image)
-import Vulkan (ImageCreateInfo)
-import Vulkan (ImageMemoryRequirementsInfo2)
-import Vulkan (Instance_T)
-import Vulkan (MappedMemoryRange)
-import Vulkan (MemoryAllocateInfo)
-import Vulkan (MemoryMapFlags)
-import Vulkan (MemoryPropertyFlags)
-import Vulkan (MemoryRequirements)
-import Vulkan (MemoryRequirements2)
-import Vulkan (PhysicalDeviceMemoryProperties)
-import Vulkan (PhysicalDeviceMemoryProperties2)
-import Vulkan (PhysicalDeviceProperties)
-import Vulkan (PhysicalDevice_T)
-import Vulkan (Result)
-import Vulkan.CStruct.Utils (FixedArray)
-import Vulkan.Internal.Utils (enumReadPrec)
-import Vulkan.Internal.Utils (enumShowsPrec)
-import Vulkan.Internal.Utils (traceAroundEvent)
-import Vulkan.CStruct.Extends (forgetExtensions)
-import Vulkan.CStruct.Utils (advancePtrBytes)
-import Vulkan.CStruct.Utils (lowerArrayPtr)
-import Vulkan.Core10.FundamentalTypes (bool32ToBool)
-import Vulkan.Core10.FundamentalTypes (boolToBool32)
-import Control.Exception.Base (bracket)
-import Control.Monad (unless)
-import Control.Monad.IO.Class (liftIO)
-import Foreign.Marshal.Alloc (allocaBytes)
-import Foreign.Marshal.Alloc (callocBytes)
-import Foreign.Marshal.Alloc (free)
-import Foreign.Marshal.Utils (maybePeek)
-import GHC.Base (when)
-import GHC.IO (throwIO)
-import Foreign.Ptr (nullPtr)
-import Foreign.Ptr (plusPtr)
-import GHC.Show (showParen)
-import GHC.Show (showString)
-import GHC.Show (showsPrec)
-import Numeric (showHex)
-import Data.ByteString (packCString)
-import Data.ByteString (useAsCString)
-import Data.Coerce (coerce)
-import Control.Monad.Trans.Class (lift)
-import Control.Monad.Trans.Cont (evalContT)
-import Data.Vector (generateM)
-import qualified Data.Vector (imapM_)
-import qualified Data.Vector (length)
-import qualified Data.Vector (null)
-import Vulkan.Core10.APIConstants (pattern MAX_MEMORY_HEAPS)
-import Vulkan.Core10.APIConstants (pattern MAX_MEMORY_TYPES)
-import Vulkan.Core10.Enums.Result (pattern SUCCESS)
-import Foreign.C.Types (CChar(..))
-import Foreign.C.Types (CSize(..))
-import Vulkan (Bool32(..))
-import Vulkan (Buffer(..))
-import Vulkan (Image(..))
-import Vulkan (MemoryPropertyFlagBits(..))
-import Vulkan (Result(..))
-import Vulkan.CStruct (FromCStruct)
-import Vulkan.CStruct (FromCStruct(..))
-import Vulkan.CStruct (ToCStruct)
-import Vulkan.CStruct (ToCStruct(..))
-import Vulkan.CStruct.Extends (Extendss)
-import Vulkan.CStruct.Extends (PokeChain)
-import Vulkan.CStruct.Extends (SomeStruct)
-import Vulkan.Core10.APIConstants (IsHandle)
-import Vulkan.Core10.APIConstants (MAX_MEMORY_HEAPS)
-import Vulkan.Core10.APIConstants (MAX_MEMORY_TYPES)
-import Vulkan.Exception (VulkanException(..))
-import Vulkan.NamedType ((:::))
-import Vulkan.Zero (Zero)
-import Vulkan.Zero (Zero(..))
-import Control.Monad.IO.Class (MonadIO)
-import Data.Bits (Bits)
-import Data.Bits (FiniteBits)
-import Data.Typeable (Typeable)
-import Foreign.C.Types (CChar)
-import Foreign.C.Types (CFloat)
-import Foreign.C.Types (CFloat(..))
-import Foreign.C.Types (CFloat(CFloat))
-import Foreign.C.Types (CSize)
-import Foreign.C.Types (CSize(..))
-import Foreign.C.Types (CSize(CSize))
-import Foreign.Storable (Storable)
-import Foreign.Storable (Storable(peek))
-import Foreign.Storable (Storable(poke))
-import qualified Foreign.Storable (Storable(..))
-import GHC.Generics (Generic)
-import GHC.IO.Exception (IOErrorType(..))
-import GHC.IO.Exception (IOException(..))
-import Data.Int (Int32)
-import Foreign.Ptr (FunPtr)
-import Foreign.Ptr (Ptr)
-import GHC.Read (Read(readPrec))
-import GHC.Show (Show(showsPrec))
-import Data.Word (Word32)
-import Data.Word (Word64)
-import Data.ByteString (ByteString)
-import Data.Kind (Type)
-import Control.Monad.Trans.Cont (ContT(..))
-import Data.Vector (Vector)
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaCreateAllocator" ffiVmaCreateAllocator
-  :: Ptr AllocatorCreateInfo -> Ptr Allocator -> IO Result
-
--- | Creates 'Allocator' object.
-createAllocator :: forall io
-                 . (MonadIO io)
-                => -- No documentation found for Nested "vmaCreateAllocator" "pCreateInfo"
-                   AllocatorCreateInfo
-                -> io (Allocator)
-createAllocator createInfo = liftIO . evalContT $ do
-  pCreateInfo <- ContT $ withCStruct (createInfo)
-  pPAllocator <- ContT $ bracket (callocBytes @Allocator 8) free
-  r <- lift $ traceAroundEvent "vmaCreateAllocator" ((ffiVmaCreateAllocator) pCreateInfo (pPAllocator))
-  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
-  pAllocator <- lift $ peek @Allocator pPAllocator
-  pure $ (pAllocator)
-
--- | A convenience wrapper to make a compatible pair of calls to
--- 'createAllocator' and 'destroyAllocator'
---
--- To ensure that 'destroyAllocator' is always called: pass
--- 'Control.Exception.bracket' (or the allocate function from your
--- favourite resource management library) as the last argument.
--- To just extract the pair pass '(,)' as the last argument.
---
-withAllocator :: forall io r . MonadIO io => AllocatorCreateInfo -> (io Allocator -> (Allocator -> io ()) -> r) -> r
-withAllocator pCreateInfo b =
-  b (createAllocator pCreateInfo)
-    (\(o0) -> destroyAllocator o0)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaDestroyAllocator" ffiVmaDestroyAllocator
-  :: Allocator -> IO ()
-
--- | Destroys allocator object.
-destroyAllocator :: forall io
-                  . (MonadIO io)
-                 => -- No documentation found for Nested "vmaDestroyAllocator" "allocator"
-                    Allocator
-                 -> io ()
-destroyAllocator allocator = liftIO $ do
-  traceAroundEvent "vmaDestroyAllocator" ((ffiVmaDestroyAllocator) (allocator))
-  pure $ ()
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaGetAllocatorInfo" ffiVmaGetAllocatorInfo
-  :: Allocator -> Ptr AllocatorInfo -> IO ()
-
--- | Returns information about existing 'Allocator' object - handle to Vulkan
--- device etc.
---
--- It might be useful if you want to keep just the 'Allocator' handle and
--- fetch other required handles to @VkPhysicalDevice@, @VkDevice@ etc.
--- every time using this function.
-getAllocatorInfo :: forall io
-                  . (MonadIO io)
-                 => -- No documentation found for Nested "vmaGetAllocatorInfo" "allocator"
-                    Allocator
-                 -> io (AllocatorInfo)
-getAllocatorInfo allocator = liftIO . evalContT $ do
-  pPAllocatorInfo <- ContT (withZeroCStruct @AllocatorInfo)
-  lift $ traceAroundEvent "vmaGetAllocatorInfo" ((ffiVmaGetAllocatorInfo) (allocator) (pPAllocatorInfo))
-  pAllocatorInfo <- lift $ peekCStruct @AllocatorInfo pPAllocatorInfo
-  pure $ (pAllocatorInfo)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaGetPhysicalDeviceProperties" ffiVmaGetPhysicalDeviceProperties
-  :: Allocator -> Ptr (Ptr PhysicalDeviceProperties) -> IO ()
-
--- | PhysicalDeviceProperties are fetched from physicalDevice by the
--- allocator. You can access it here, without fetching it again on your
--- own.
-getPhysicalDeviceProperties :: forall io
-                             . (MonadIO io)
-                            => -- No documentation found for Nested "vmaGetPhysicalDeviceProperties" "allocator"
-                               Allocator
-                            -> io (Ptr PhysicalDeviceProperties)
-getPhysicalDeviceProperties allocator = liftIO . evalContT $ do
-  pPpPhysicalDeviceProperties <- ContT $ bracket (callocBytes @(Ptr PhysicalDeviceProperties) 8) free
-  lift $ traceAroundEvent "vmaGetPhysicalDeviceProperties" ((ffiVmaGetPhysicalDeviceProperties) (allocator) (pPpPhysicalDeviceProperties))
-  ppPhysicalDeviceProperties <- lift $ peek @(Ptr PhysicalDeviceProperties) pPpPhysicalDeviceProperties
-  pure $ (ppPhysicalDeviceProperties)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaGetMemoryProperties" ffiVmaGetMemoryProperties
-  :: Allocator -> Ptr (Ptr PhysicalDeviceMemoryProperties) -> IO ()
-
--- | PhysicalDeviceMemoryProperties are fetched from physicalDevice by the
--- allocator. You can access it here, without fetching it again on your
--- own.
-getMemoryProperties :: forall io
-                     . (MonadIO io)
-                    => -- No documentation found for Nested "vmaGetMemoryProperties" "allocator"
-                       Allocator
-                    -> io (Ptr PhysicalDeviceMemoryProperties)
-getMemoryProperties allocator = liftIO . evalContT $ do
-  pPpPhysicalDeviceMemoryProperties <- ContT $ bracket (callocBytes @(Ptr PhysicalDeviceMemoryProperties) 8) free
-  lift $ traceAroundEvent "vmaGetMemoryProperties" ((ffiVmaGetMemoryProperties) (allocator) (pPpPhysicalDeviceMemoryProperties))
-  ppPhysicalDeviceMemoryProperties <- lift $ peek @(Ptr PhysicalDeviceMemoryProperties) pPpPhysicalDeviceMemoryProperties
-  pure $ (ppPhysicalDeviceMemoryProperties)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaGetMemoryTypeProperties" ffiVmaGetMemoryTypeProperties
-  :: Allocator -> Word32 -> Ptr MemoryPropertyFlags -> IO ()
-
--- | Given Memory Type Index, returns Property Flags of this memory type.
---
--- This is just a convenience function. Same information can be obtained
--- using 'getMemoryProperties'.
-getMemoryTypeProperties :: forall io
-                         . (MonadIO io)
-                        => -- No documentation found for Nested "vmaGetMemoryTypeProperties" "allocator"
-                           Allocator
-                        -> -- No documentation found for Nested "vmaGetMemoryTypeProperties" "memoryTypeIndex"
-                           ("memoryTypeIndex" ::: Word32)
-                        -> io (MemoryPropertyFlags)
-getMemoryTypeProperties allocator memoryTypeIndex = liftIO . evalContT $ do
-  pPFlags <- ContT $ bracket (callocBytes @MemoryPropertyFlags 4) free
-  lift $ traceAroundEvent "vmaGetMemoryTypeProperties" ((ffiVmaGetMemoryTypeProperties) (allocator) (memoryTypeIndex) (pPFlags))
-  pFlags <- lift $ peek @MemoryPropertyFlags pPFlags
-  pure $ (pFlags)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaSetCurrentFrameIndex" ffiVmaSetCurrentFrameIndex
-  :: Allocator -> Word32 -> IO ()
-
--- | Sets index of the current frame.
-setCurrentFrameIndex :: forall io
-                      . (MonadIO io)
-                     => -- No documentation found for Nested "vmaSetCurrentFrameIndex" "allocator"
-                        Allocator
-                     -> -- No documentation found for Nested "vmaSetCurrentFrameIndex" "frameIndex"
-                        ("frameIndex" ::: Word32)
-                     -> io ()
-setCurrentFrameIndex allocator frameIndex = liftIO $ do
-  traceAroundEvent "vmaSetCurrentFrameIndex" ((ffiVmaSetCurrentFrameIndex) (allocator) (frameIndex))
-  pure $ ()
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaCalculateStatistics" ffiVmaCalculateStatistics
-  :: Allocator -> Ptr TotalStatistics -> IO ()
-
--- | Retrieves statistics from current state of the Allocator.
---
--- This function is called \"calculate\" not \"get\" because it has to
--- traverse all internal data structures, so it may be quite slow. Use it
--- for debugging purposes. For faster but more brief statistics suitable to
--- be called every frame or every allocation, use 'getHeapBudgets'.
---
--- Note that when using allocator from multiple threads, returned
--- information may immediately become outdated.
-calculateStatistics :: forall io
-                     . (MonadIO io)
-                    => -- No documentation found for Nested "vmaCalculateStatistics" "allocator"
-                       Allocator
-                    -> io (("stats" ::: TotalStatistics))
-calculateStatistics allocator = liftIO . evalContT $ do
-  pPStats <- ContT (withZeroCStruct @TotalStatistics)
-  lift $ traceAroundEvent "vmaCalculateStatistics" ((ffiVmaCalculateStatistics) (allocator) (pPStats))
-  pStats <- lift $ peekCStruct @TotalStatistics pPStats
-  pure $ (pStats)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaGetHeapBudgets" ffiVmaGetHeapBudgets
-  :: Allocator -> Ptr Budget -> IO ()
-
--- | Retrieves information about current memory usage and budget for all
--- memory heaps.
---
--- __Parameters__
---
--- +-----------+-----------+-----------------------------------------------+
--- |           | allocator |                                               |
--- +-----------+-----------+-----------------------------------------------+
--- | out       | pBudgets  | Must point to array with number of elements   |
--- |           |           | at least equal to number of memory heaps in   |
--- |           |           | physical device used.                         |
--- +-----------+-----------+-----------------------------------------------+
---
--- This function is called \"get\" not \"calculate\" because it is very
--- fast, suitable to be called every frame or every allocation. For more
--- detailed statistics use 'calculateStatistics'.
---
--- Note that when using allocator from multiple threads, returned
--- information may immediately become outdated.
-getHeapBudgets :: forall io
-                . (MonadIO io)
-               => -- No documentation found for Nested "vmaGetHeapBudgets" "allocator"
-                  Allocator
-               -> -- No documentation found for Nested "vmaGetHeapBudgets" "pBudgets"
-                  ("budgets" ::: Ptr Budget)
-               -> io ()
-getHeapBudgets allocator budgets = liftIO $ do
-  traceAroundEvent "vmaGetHeapBudgets" ((ffiVmaGetHeapBudgets) (allocator) (budgets))
-  pure $ ()
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaFindMemoryTypeIndex" ffiVmaFindMemoryTypeIndex
-  :: Allocator -> Word32 -> Ptr AllocationCreateInfo -> Ptr Word32 -> IO Result
-
--- | Helps to find memoryTypeIndex, given memoryTypeBits and
--- 'AllocationCreateInfo'.
---
--- This algorithm tries to find a memory type that:
---
--- -   Is allowed by memoryTypeBits.
---
--- -   Contains all the flags from pAllocationCreateInfo->requiredFlags.
---
--- -   Matches intended usage.
---
--- -   Has as many flags from pAllocationCreateInfo->preferredFlags as
---     possible.
---
--- __Returns__
---
--- Returns VK_ERROR_FEATURE_NOT_PRESENT if not found. Receiving such result
--- from this function or any other allocating function probably means that
--- your device doesn\'t support any memory type with requested features for
--- the specific type of resource you want to use it for. Please check
--- parameters of your resource, like image layout (OPTIMAL versus LINEAR)
--- or mip level count.
-findMemoryTypeIndex :: forall io
-                     . (MonadIO io)
-                    => -- No documentation found for Nested "vmaFindMemoryTypeIndex" "allocator"
-                       Allocator
-                    -> -- No documentation found for Nested "vmaFindMemoryTypeIndex" "memoryTypeBits"
-                       ("memoryTypeBits" ::: Word32)
-                    -> -- No documentation found for Nested "vmaFindMemoryTypeIndex" "pAllocationCreateInfo"
-                       AllocationCreateInfo
-                    -> io (("memoryTypeIndex" ::: Word32))
-findMemoryTypeIndex allocator memoryTypeBits allocationCreateInfo = liftIO . evalContT $ do
-  pAllocationCreateInfo <- ContT $ withCStruct (allocationCreateInfo)
-  pPMemoryTypeIndex <- ContT $ bracket (callocBytes @Word32 4) free
-  r <- lift $ traceAroundEvent "vmaFindMemoryTypeIndex" ((ffiVmaFindMemoryTypeIndex) (allocator) (memoryTypeBits) pAllocationCreateInfo (pPMemoryTypeIndex))
-  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
-  pMemoryTypeIndex <- lift $ peek @Word32 pPMemoryTypeIndex
-  pure $ (pMemoryTypeIndex)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaFindMemoryTypeIndexForBufferInfo" ffiVmaFindMemoryTypeIndexForBufferInfo
-  :: Allocator -> Ptr (SomeStruct BufferCreateInfo) -> Ptr AllocationCreateInfo -> Ptr Word32 -> IO Result
-
--- | Helps to find memoryTypeIndex, given VkBufferCreateInfo and
--- 'AllocationCreateInfo'.
---
--- It can be useful e.g. to determine value to be used as
--- /VmaPoolCreateInfo::memoryTypeIndex/. It internally creates a temporary,
--- dummy buffer that never has memory bound.
-findMemoryTypeIndexForBufferInfo :: forall a io
-                                  . (Extendss BufferCreateInfo a, PokeChain a, MonadIO io)
-                                 => -- No documentation found for Nested "vmaFindMemoryTypeIndexForBufferInfo" "allocator"
-                                    Allocator
-                                 -> -- No documentation found for Nested "vmaFindMemoryTypeIndexForBufferInfo" "pBufferCreateInfo"
-                                    (BufferCreateInfo a)
-                                 -> -- No documentation found for Nested "vmaFindMemoryTypeIndexForBufferInfo" "pAllocationCreateInfo"
-                                    AllocationCreateInfo
-                                 -> io (("memoryTypeIndex" ::: Word32))
-findMemoryTypeIndexForBufferInfo allocator bufferCreateInfo allocationCreateInfo = liftIO . evalContT $ do
-  pBufferCreateInfo <- ContT $ withCStruct (bufferCreateInfo)
-  pAllocationCreateInfo <- ContT $ withCStruct (allocationCreateInfo)
-  pPMemoryTypeIndex <- ContT $ bracket (callocBytes @Word32 4) free
-  r <- lift $ traceAroundEvent "vmaFindMemoryTypeIndexForBufferInfo" ((ffiVmaFindMemoryTypeIndexForBufferInfo) (allocator) (forgetExtensions pBufferCreateInfo) pAllocationCreateInfo (pPMemoryTypeIndex))
-  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
-  pMemoryTypeIndex <- lift $ peek @Word32 pPMemoryTypeIndex
-  pure $ (pMemoryTypeIndex)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaFindMemoryTypeIndexForImageInfo" ffiVmaFindMemoryTypeIndexForImageInfo
-  :: Allocator -> Ptr (SomeStruct ImageCreateInfo) -> Ptr AllocationCreateInfo -> Ptr Word32 -> IO Result
-
--- | Helps to find memoryTypeIndex, given VkImageCreateInfo and
--- 'AllocationCreateInfo'.
---
--- It can be useful e.g. to determine value to be used as
--- /VmaPoolCreateInfo::memoryTypeIndex/. It internally creates a temporary,
--- dummy image that never has memory bound.
-findMemoryTypeIndexForImageInfo :: forall a io
-                                 . (Extendss ImageCreateInfo a, PokeChain a, MonadIO io)
-                                => -- No documentation found for Nested "vmaFindMemoryTypeIndexForImageInfo" "allocator"
-                                   Allocator
-                                -> -- No documentation found for Nested "vmaFindMemoryTypeIndexForImageInfo" "pImageCreateInfo"
-                                   (ImageCreateInfo a)
-                                -> -- No documentation found for Nested "vmaFindMemoryTypeIndexForImageInfo" "pAllocationCreateInfo"
-                                   AllocationCreateInfo
-                                -> io (("memoryTypeIndex" ::: Word32))
-findMemoryTypeIndexForImageInfo allocator imageCreateInfo allocationCreateInfo = liftIO . evalContT $ do
-  pImageCreateInfo <- ContT $ withCStruct (imageCreateInfo)
-  pAllocationCreateInfo <- ContT $ withCStruct (allocationCreateInfo)
-  pPMemoryTypeIndex <- ContT $ bracket (callocBytes @Word32 4) free
-  r <- lift $ traceAroundEvent "vmaFindMemoryTypeIndexForImageInfo" ((ffiVmaFindMemoryTypeIndexForImageInfo) (allocator) (forgetExtensions pImageCreateInfo) pAllocationCreateInfo (pPMemoryTypeIndex))
-  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
-  pMemoryTypeIndex <- lift $ peek @Word32 pPMemoryTypeIndex
-  pure $ (pMemoryTypeIndex)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaCreatePool" ffiVmaCreatePool
-  :: Allocator -> Ptr PoolCreateInfo -> Ptr Pool -> IO Result
-
--- | Allocates Vulkan device memory and creates 'Pool' object.
---
--- __Parameters__
---
--- +-----------+-------------+-----------------------------------------------+
--- |           | allocator   | Allocator object.                             |
--- +-----------+-------------+-----------------------------------------------+
--- |           | pCreateInfo | Parameters of pool to create.                 |
--- +-----------+-------------+-----------------------------------------------+
--- | out       | pPool       | Handle to created pool.                       |
--- +-----------+-------------+-----------------------------------------------+
-createPool :: forall io
-            . (MonadIO io)
-           => -- No documentation found for Nested "vmaCreatePool" "allocator"
-              Allocator
-           -> -- No documentation found for Nested "vmaCreatePool" "pCreateInfo"
-              PoolCreateInfo
-           -> io (Pool)
-createPool allocator createInfo = liftIO . evalContT $ do
-  pCreateInfo <- ContT $ withCStruct (createInfo)
-  pPPool <- ContT $ bracket (callocBytes @Pool 8) free
-  r <- lift $ traceAroundEvent "vmaCreatePool" ((ffiVmaCreatePool) (allocator) pCreateInfo (pPPool))
-  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
-  pPool <- lift $ peek @Pool pPPool
-  pure $ (pPool)
-
--- | A convenience wrapper to make a compatible pair of calls to 'createPool'
--- and 'destroyPool'
---
--- To ensure that 'destroyPool' is always called: pass
--- 'Control.Exception.bracket' (or the allocate function from your
--- favourite resource management library) as the last argument.
--- To just extract the pair pass '(,)' as the last argument.
---
-withPool :: forall io r . MonadIO io => Allocator -> PoolCreateInfo -> (io Pool -> (Pool -> io ()) -> r) -> r
-withPool allocator pCreateInfo b =
-  b (createPool allocator pCreateInfo)
-    (\(o0) -> destroyPool allocator o0)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaDestroyPool" ffiVmaDestroyPool
-  :: Allocator -> Pool -> IO ()
-
--- | Destroys 'Pool' object and frees Vulkan device memory.
-destroyPool :: forall io
-             . (MonadIO io)
-            => -- No documentation found for Nested "vmaDestroyPool" "allocator"
-               Allocator
-            -> -- No documentation found for Nested "vmaDestroyPool" "pool"
-               Pool
-            -> io ()
-destroyPool allocator pool = liftIO $ do
-  traceAroundEvent "vmaDestroyPool" ((ffiVmaDestroyPool) (allocator) (pool))
-  pure $ ()
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaGetPoolStatistics" ffiVmaGetPoolStatistics
-  :: Allocator -> Pool -> Ptr Statistics -> IO ()
-
--- | Retrieves statistics of existing 'Pool' object.
---
--- __Parameters__
---
--- +-----------+------------+-----------------------------------------------+
--- |           | allocator  | Allocator object.                             |
--- +-----------+------------+-----------------------------------------------+
--- |           | pool       | Pool object.                                  |
--- +-----------+------------+-----------------------------------------------+
--- | out       | pPoolStats | Statistics of specified pool.                 |
--- +-----------+------------+-----------------------------------------------+
-getPoolStatistics :: forall io
-                   . (MonadIO io)
-                  => -- No documentation found for Nested "vmaGetPoolStatistics" "allocator"
-                     Allocator
-                  -> -- No documentation found for Nested "vmaGetPoolStatistics" "pool"
-                     Pool
-                  -> io (("poolStats" ::: Statistics))
-getPoolStatistics allocator pool = liftIO . evalContT $ do
-  pPPoolStats <- ContT (withZeroCStruct @Statistics)
-  lift $ traceAroundEvent "vmaGetPoolStatistics" ((ffiVmaGetPoolStatistics) (allocator) (pool) (pPPoolStats))
-  pPoolStats <- lift $ peekCStruct @Statistics pPPoolStats
-  pure $ (pPoolStats)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaCalculatePoolStatistics" ffiVmaCalculatePoolStatistics
-  :: Allocator -> Pool -> Ptr DetailedStatistics -> IO ()
-
--- | Retrieves detailed statistics of existing 'Pool' object.
---
--- __Parameters__
---
--- +-----------+------------+-----------------------------------------------+
--- |           | allocator  | Allocator object.                             |
--- +-----------+------------+-----------------------------------------------+
--- |           | pool       | Pool object.                                  |
--- +-----------+------------+-----------------------------------------------+
--- | out       | pPoolStats | Statistics of specified pool.                 |
--- +-----------+------------+-----------------------------------------------+
-calculatePoolStatistics :: forall io
-                         . (MonadIO io)
-                        => -- No documentation found for Nested "vmaCalculatePoolStatistics" "allocator"
-                           Allocator
-                        -> -- No documentation found for Nested "vmaCalculatePoolStatistics" "pool"
-                           Pool
-                        -> io (("poolStats" ::: DetailedStatistics))
-calculatePoolStatistics allocator pool = liftIO . evalContT $ do
-  pPPoolStats <- ContT (withZeroCStruct @DetailedStatistics)
-  lift $ traceAroundEvent "vmaCalculatePoolStatistics" ((ffiVmaCalculatePoolStatistics) (allocator) (pool) (pPPoolStats))
-  pPoolStats <- lift $ peekCStruct @DetailedStatistics pPPoolStats
-  pure $ (pPoolStats)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaCheckPoolCorruption" ffiVmaCheckPoolCorruption
-  :: Allocator -> Pool -> IO Result
-
--- | Checks magic number in margins around all allocations in given memory
--- pool in search for corruptions.
---
--- Corruption detection is enabled only when @VMA_DEBUG_DETECT_CORRUPTION@
--- macro is defined to nonzero, @VMA_DEBUG_MARGIN@ is defined to nonzero
--- and the pool is created in memory type that is @HOST_VISIBLE@ and
--- @HOST_COHERENT@. For more information, see /Corruption detection/.
---
--- Possible return values:
---
--- -   @VK_ERROR_FEATURE_NOT_PRESENT@ - corruption detection is not enabled
---     for specified pool.
---
--- -   @VK_SUCCESS@ - corruption detection has been performed and
---     succeeded.
---
--- -   @VK_ERROR_UNKNOWN@ - corruption detection has been performed and
---     found memory corruptions around one of the allocations. @VMA_ASSERT@
---     is also fired in that case.
---
--- -   Other value: Error returned by Vulkan, e.g. memory mapping failure.
-checkPoolCorruption :: forall io
-                     . (MonadIO io)
-                    => -- No documentation found for Nested "vmaCheckPoolCorruption" "allocator"
-                       Allocator
-                    -> -- No documentation found for Nested "vmaCheckPoolCorruption" "pool"
-                       Pool
-                    -> io ()
-checkPoolCorruption allocator pool = liftIO $ do
-  r <- traceAroundEvent "vmaCheckPoolCorruption" ((ffiVmaCheckPoolCorruption) (allocator) (pool))
-  when (r < SUCCESS) (throwIO (VulkanException r))
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaGetPoolName" ffiVmaGetPoolName
-  :: Allocator -> Pool -> Ptr (Ptr CChar) -> IO ()
-
--- | Retrieves name of a custom pool.
---
--- After the call @ppName@ is either null or points to an internally-owned
--- null-terminated string containing name of the pool that was previously
--- set. The pointer becomes invalid when the pool is destroyed or its name
--- is changed using 'setPoolName'.
-getPoolName :: forall io
-             . (MonadIO io)
-            => -- No documentation found for Nested "vmaGetPoolName" "allocator"
-               Allocator
-            -> -- No documentation found for Nested "vmaGetPoolName" "pool"
-               Pool
-            -> io (("name" ::: Ptr CChar))
-getPoolName allocator pool = liftIO . evalContT $ do
-  pPpName <- ContT $ bracket (callocBytes @(Ptr CChar) 8) free
-  lift $ traceAroundEvent "vmaGetPoolName" ((ffiVmaGetPoolName) (allocator) (pool) (pPpName))
-  ppName <- lift $ peek @(Ptr CChar) pPpName
-  pure $ (ppName)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaSetPoolName" ffiVmaSetPoolName
-  :: Allocator -> Pool -> Ptr CChar -> IO ()
-
--- | Sets name of a custom pool.
---
--- @pName@ can be either null or pointer to a null-terminated string with
--- new name for the pool. Function makes internal copy of the string, so it
--- can be changed or freed immediately after this call.
-setPoolName :: forall io
-             . (MonadIO io)
-            => -- No documentation found for Nested "vmaSetPoolName" "allocator"
-               Allocator
-            -> -- No documentation found for Nested "vmaSetPoolName" "pool"
-               Pool
-            -> -- No documentation found for Nested "vmaSetPoolName" "pName"
-               ("name" ::: Maybe ByteString)
-            -> io ()
-setPoolName allocator pool name = liftIO . evalContT $ do
-  pName <- case (name) of
-    Nothing -> pure nullPtr
-    Just j -> ContT $ useAsCString (j)
-  lift $ traceAroundEvent "vmaSetPoolName" ((ffiVmaSetPoolName) (allocator) (pool) pName)
-  pure $ ()
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaAllocateMemory" ffiVmaAllocateMemory
-  :: Allocator -> Ptr MemoryRequirements -> Ptr AllocationCreateInfo -> Ptr Allocation -> Ptr AllocationInfo -> IO Result
-
--- | General purpose memory allocation.
---
--- __Parameters__
---
--- +-----------+-----------------------+-----------------------------------------------+
--- |           | allocator             |                                               |
--- +-----------+-----------------------+-----------------------------------------------+
--- |           | pVkMemoryRequirements |                                               |
--- +-----------+-----------------------+-----------------------------------------------+
--- |           | pCreateInfo           |                                               |
--- +-----------+-----------------------+-----------------------------------------------+
--- | out       | pAllocation           | Handle to allocated memory.                   |
--- +-----------+-----------------------+-----------------------------------------------+
--- | out       | pAllocationInfo       | Optional. Information about allocated memory. |
--- |           |                       | It can be later fetched using function        |
--- |           |                       | 'getAllocationInfo'.                          |
--- +-----------+-----------------------+-----------------------------------------------+
---
--- You should free the memory using 'freeMemory' or 'freeMemoryPages'.
---
--- It is recommended to use 'allocateMemoryForBuffer',
--- 'allocateMemoryForImage', 'createBuffer', 'createImage' instead whenever
--- possible.
-allocateMemory :: forall io
-                . (MonadIO io)
-               => -- No documentation found for Nested "vmaAllocateMemory" "allocator"
-                  Allocator
-               -> -- No documentation found for Nested "vmaAllocateMemory" "pVkMemoryRequirements"
-                  ("vkMemoryRequirements" ::: MemoryRequirements)
-               -> -- No documentation found for Nested "vmaAllocateMemory" "pCreateInfo"
-                  AllocationCreateInfo
-               -> io (Allocation, AllocationInfo)
-allocateMemory allocator vkMemoryRequirements createInfo = liftIO . evalContT $ do
-  pVkMemoryRequirements <- ContT $ withCStruct (vkMemoryRequirements)
-  pCreateInfo <- ContT $ withCStruct (createInfo)
-  pPAllocation <- ContT $ bracket (callocBytes @Allocation 8) free
-  pPAllocationInfo <- ContT (withZeroCStruct @AllocationInfo)
-  r <- lift $ traceAroundEvent "vmaAllocateMemory" ((ffiVmaAllocateMemory) (allocator) pVkMemoryRequirements pCreateInfo (pPAllocation) (pPAllocationInfo))
-  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
-  pAllocation <- lift $ peek @Allocation pPAllocation
-  pAllocationInfo <- lift $ peekCStruct @AllocationInfo pPAllocationInfo
-  pure $ (pAllocation, pAllocationInfo)
-
--- | A convenience wrapper to make a compatible pair of calls to
--- 'allocateMemory' and 'freeMemory'
---
--- To ensure that 'freeMemory' is always called: pass
--- 'Control.Exception.bracket' (or the allocate function from your
--- favourite resource management library) as the last argument.
--- To just extract the pair pass '(,)' as the last argument.
---
-withMemory :: forall io r . MonadIO io => Allocator -> MemoryRequirements -> AllocationCreateInfo -> (io (Allocation, AllocationInfo) -> ((Allocation, AllocationInfo) -> io ()) -> r) -> r
-withMemory allocator pVkMemoryRequirements pCreateInfo b =
-  b (allocateMemory allocator pVkMemoryRequirements pCreateInfo)
-    (\(o0, _) -> freeMemory allocator o0)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaAllocateMemoryPages" ffiVmaAllocateMemoryPages
-  :: Allocator -> Ptr MemoryRequirements -> Ptr AllocationCreateInfo -> CSize -> Ptr Allocation -> Ptr AllocationInfo -> IO Result
-
--- | General purpose memory allocation for multiple allocation objects at
--- once.
---
--- __Parameters__
---
--- +-----------+-----------------------+-----------------------------------------------+
--- |           | allocator             | Allocator object.                             |
--- +-----------+-----------------------+-----------------------------------------------+
--- |           | pVkMemoryRequirements | Memory requirements for each allocation.      |
--- +-----------+-----------------------+-----------------------------------------------+
--- |           | pCreateInfo           | Creation parameters for each allocation.      |
--- +-----------+-----------------------+-----------------------------------------------+
--- |           | allocationCount       | Number of allocations to make.                |
--- +-----------+-----------------------+-----------------------------------------------+
--- | out       | pAllocations          | Pointer to array that will be filled with     |
--- |           |                       | handles to created allocations.               |
--- +-----------+-----------------------+-----------------------------------------------+
--- | out       | pAllocationInfo       | Optional. Pointer to array that will be       |
--- |           |                       | filled with parameters of created             |
--- |           |                       | allocations.                                  |
--- +-----------+-----------------------+-----------------------------------------------+
---
--- You should free the memory using 'freeMemory' or 'freeMemoryPages'.
---
--- Word \"pages\" is just a suggestion to use this function to allocate
--- pieces of memory needed for sparse binding. It is just a general purpose
--- allocation function able to make multiple allocations at once. It may be
--- internally optimized to be more efficient than calling 'allocateMemory'
--- @allocationCount@ times.
---
--- All allocations are made using same parameters. All of them are created
--- out of the same memory pool and type. If any allocation fails, all
--- allocations already made within this function call are also freed, so
--- that when returned result is not @VK_SUCCESS@, @pAllocation@ array is
--- always entirely filled with @VK_NULL_HANDLE@.
-allocateMemoryPages :: forall io
-                     . (MonadIO io)
-                    => -- No documentation found for Nested "vmaAllocateMemoryPages" "allocator"
-                       Allocator
-                    -> -- No documentation found for Nested "vmaAllocateMemoryPages" "pVkMemoryRequirements"
-                       ("vkMemoryRequirements" ::: Vector MemoryRequirements)
-                    -> -- No documentation found for Nested "vmaAllocateMemoryPages" "pCreateInfo"
-                       ("createInfo" ::: Vector AllocationCreateInfo)
-                    -> io (("allocations" ::: Vector Allocation), ("allocationInfo" ::: Vector AllocationInfo))
-allocateMemoryPages allocator vkMemoryRequirements createInfo = liftIO . evalContT $ do
-  pPVkMemoryRequirements <- ContT $ allocaBytes @MemoryRequirements ((Data.Vector.length (vkMemoryRequirements)) * 24)
-  Data.Vector.imapM_ (\i e -> ContT $ pokeCStruct (pPVkMemoryRequirements `plusPtr` (24 * (i)) :: Ptr MemoryRequirements) (e) . ($ ())) (vkMemoryRequirements)
-  pPCreateInfo <- ContT $ allocaBytes @AllocationCreateInfo ((Data.Vector.length (createInfo)) * 48)
-  lift $ Data.Vector.imapM_ (\i e -> poke (pPCreateInfo `plusPtr` (48 * (i)) :: Ptr AllocationCreateInfo) (e)) (createInfo)
-  let pVkMemoryRequirementsLength = Data.Vector.length $ (vkMemoryRequirements)
-  lift $ unless ((Data.Vector.length $ (createInfo)) == pVkMemoryRequirementsLength) $
-    throwIO $ IOError Nothing InvalidArgument "" "pCreateInfo and pVkMemoryRequirements must have the same length" Nothing Nothing
-  pPAllocations <- ContT $ bracket (callocBytes @Allocation ((fromIntegral ((fromIntegral pVkMemoryRequirementsLength :: CSize))) * 8)) free
-  pPAllocationInfo <- ContT $ bracket (callocBytes @AllocationInfo ((fromIntegral ((fromIntegral pVkMemoryRequirementsLength :: CSize))) * 56)) free
-  _ <- traverse (\i -> ContT $ pokeZeroCStruct (pPAllocationInfo `advancePtrBytes` (i * 56) :: Ptr AllocationInfo) . ($ ())) [0..(fromIntegral ((fromIntegral pVkMemoryRequirementsLength :: CSize))) - 1]
-  r <- lift $ traceAroundEvent "vmaAllocateMemoryPages" ((ffiVmaAllocateMemoryPages) (allocator) (pPVkMemoryRequirements) (pPCreateInfo) ((fromIntegral pVkMemoryRequirementsLength :: CSize)) (pPAllocations) ((pPAllocationInfo)))
-  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
-  pAllocations <- lift $ generateM (fromIntegral ((fromIntegral pVkMemoryRequirementsLength :: CSize))) (\i -> peek @Allocation ((pPAllocations `advancePtrBytes` (8 * (i)) :: Ptr Allocation)))
-  pAllocationInfo <- lift $ generateM (fromIntegral ((fromIntegral pVkMemoryRequirementsLength :: CSize))) (\i -> peekCStruct @AllocationInfo (((pPAllocationInfo) `advancePtrBytes` (56 * (i)) :: Ptr AllocationInfo)))
-  pure $ (pAllocations, pAllocationInfo)
-
--- | A convenience wrapper to make a compatible pair of calls to
--- 'allocateMemoryPages' and 'freeMemoryPages'
---
--- To ensure that 'freeMemoryPages' is always called: pass
--- 'Control.Exception.bracket' (or the allocate function from your
--- favourite resource management library) as the last argument.
--- To just extract the pair pass '(,)' as the last argument.
---
-withMemoryPages :: forall io r . MonadIO io => Allocator -> Vector MemoryRequirements -> Vector AllocationCreateInfo -> (io (Vector Allocation, Vector AllocationInfo) -> ((Vector Allocation, Vector AllocationInfo) -> io ()) -> r) -> r
-withMemoryPages allocator pVkMemoryRequirements pCreateInfo b =
-  b (allocateMemoryPages allocator pVkMemoryRequirements pCreateInfo)
-    (\(o0, _) -> freeMemoryPages allocator o0)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaAllocateMemoryForBuffer" ffiVmaAllocateMemoryForBuffer
-  :: Allocator -> Buffer -> Ptr AllocationCreateInfo -> Ptr Allocation -> Ptr AllocationInfo -> IO Result
-
--- | Allocates memory suitable for given @VkBuffer@.
---
--- __Parameters__
---
--- +-----------+-----------------+-----------------------------------------------+
--- |           | allocator       |                                               |
--- +-----------+-----------------+-----------------------------------------------+
--- |           | buffer          |                                               |
--- +-----------+-----------------+-----------------------------------------------+
--- |           | pCreateInfo     |                                               |
--- +-----------+-----------------+-----------------------------------------------+
--- | out       | pAllocation     | Handle to allocated memory.                   |
--- +-----------+-----------------+-----------------------------------------------+
--- | out       | pAllocationInfo | Optional. Information about allocated memory. |
--- |           |                 | It can be later fetched using function        |
--- |           |                 | 'getAllocationInfo'.                          |
--- +-----------+-----------------+-----------------------------------------------+
---
--- It only creates 'Allocation'. To bind the memory to the buffer, use
--- 'bindBufferMemory'.
---
--- This is a special-purpose function. In most cases you should use
--- 'createBuffer'.
---
--- You must free the allocation using 'freeMemory' when no longer needed.
-allocateMemoryForBuffer :: forall io
-                         . (MonadIO io)
-                        => -- No documentation found for Nested "vmaAllocateMemoryForBuffer" "allocator"
-                           Allocator
-                        -> -- No documentation found for Nested "vmaAllocateMemoryForBuffer" "buffer"
-                           Buffer
-                        -> -- No documentation found for Nested "vmaAllocateMemoryForBuffer" "pCreateInfo"
-                           AllocationCreateInfo
-                        -> io (Allocation, AllocationInfo)
-allocateMemoryForBuffer allocator buffer createInfo = liftIO . evalContT $ do
-  pCreateInfo <- ContT $ withCStruct (createInfo)
-  pPAllocation <- ContT $ bracket (callocBytes @Allocation 8) free
-  pPAllocationInfo <- ContT (withZeroCStruct @AllocationInfo)
-  r <- lift $ traceAroundEvent "vmaAllocateMemoryForBuffer" ((ffiVmaAllocateMemoryForBuffer) (allocator) (buffer) pCreateInfo (pPAllocation) (pPAllocationInfo))
-  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
-  pAllocation <- lift $ peek @Allocation pPAllocation
-  pAllocationInfo <- lift $ peekCStruct @AllocationInfo pPAllocationInfo
-  pure $ (pAllocation, pAllocationInfo)
-
--- | A convenience wrapper to make a compatible pair of calls to
--- 'allocateMemoryForBuffer' and 'freeMemory'
---
--- To ensure that 'freeMemory' is always called: pass
--- 'Control.Exception.bracket' (or the allocate function from your
--- favourite resource management library) as the last argument.
--- To just extract the pair pass '(,)' as the last argument.
---
-withMemoryForBuffer :: forall io r . MonadIO io => Allocator -> Buffer -> AllocationCreateInfo -> (io (Allocation, AllocationInfo) -> ((Allocation, AllocationInfo) -> io ()) -> r) -> r
-withMemoryForBuffer allocator buffer pCreateInfo b =
-  b (allocateMemoryForBuffer allocator buffer pCreateInfo)
-    (\(o0, _) -> freeMemory allocator o0)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaAllocateMemoryForImage" ffiVmaAllocateMemoryForImage
-  :: Allocator -> Image -> Ptr AllocationCreateInfo -> Ptr Allocation -> Ptr AllocationInfo -> IO Result
-
--- | Allocates memory suitable for given @VkImage@.
---
--- __Parameters__
---
--- +-----------+-----------------+-----------------------------------------------+
--- |           | allocator       |                                               |
--- +-----------+-----------------+-----------------------------------------------+
--- |           | image           |                                               |
--- +-----------+-----------------+-----------------------------------------------+
--- |           | pCreateInfo     |                                               |
--- +-----------+-----------------+-----------------------------------------------+
--- | out       | pAllocation     | Handle to allocated memory.                   |
--- +-----------+-----------------+-----------------------------------------------+
--- | out       | pAllocationInfo | Optional. Information about allocated memory. |
--- |           |                 | It can be later fetched using function        |
--- |           |                 | 'getAllocationInfo'.                          |
--- +-----------+-----------------+-----------------------------------------------+
---
--- It only creates 'Allocation'. To bind the memory to the buffer, use
--- 'bindImageMemory'.
---
--- This is a special-purpose function. In most cases you should use
--- 'createImage'.
---
--- You must free the allocation using 'freeMemory' when no longer needed.
-allocateMemoryForImage :: forall io
-                        . (MonadIO io)
-                       => -- No documentation found for Nested "vmaAllocateMemoryForImage" "allocator"
-                          Allocator
-                       -> -- No documentation found for Nested "vmaAllocateMemoryForImage" "image"
-                          Image
-                       -> -- No documentation found for Nested "vmaAllocateMemoryForImage" "pCreateInfo"
-                          AllocationCreateInfo
-                       -> io (Allocation, AllocationInfo)
-allocateMemoryForImage allocator image createInfo = liftIO . evalContT $ do
-  pCreateInfo <- ContT $ withCStruct (createInfo)
-  pPAllocation <- ContT $ bracket (callocBytes @Allocation 8) free
-  pPAllocationInfo <- ContT (withZeroCStruct @AllocationInfo)
-  r <- lift $ traceAroundEvent "vmaAllocateMemoryForImage" ((ffiVmaAllocateMemoryForImage) (allocator) (image) pCreateInfo (pPAllocation) (pPAllocationInfo))
-  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
-  pAllocation <- lift $ peek @Allocation pPAllocation
-  pAllocationInfo <- lift $ peekCStruct @AllocationInfo pPAllocationInfo
-  pure $ (pAllocation, pAllocationInfo)
-
--- | A convenience wrapper to make a compatible pair of calls to
--- 'allocateMemoryForImage' and 'freeMemory'
---
--- To ensure that 'freeMemory' is always called: pass
--- 'Control.Exception.bracket' (or the allocate function from your
--- favourite resource management library) as the last argument.
--- To just extract the pair pass '(,)' as the last argument.
---
-withMemoryForImage :: forall io r . MonadIO io => Allocator -> Image -> AllocationCreateInfo -> (io (Allocation, AllocationInfo) -> ((Allocation, AllocationInfo) -> io ()) -> r) -> r
-withMemoryForImage allocator image pCreateInfo b =
-  b (allocateMemoryForImage allocator image pCreateInfo)
-    (\(o0, _) -> freeMemory allocator o0)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaFreeMemory" ffiVmaFreeMemory
-  :: Allocator -> Allocation -> IO ()
-
--- | Frees memory previously allocated using 'allocateMemory',
--- 'allocateMemoryForBuffer', or 'allocateMemoryForImage'.
---
--- Passing @VK_NULL_HANDLE@ as @allocation@ is valid. Such function call is
--- just skipped.
-freeMemory :: forall io
-            . (MonadIO io)
-           => -- No documentation found for Nested "vmaFreeMemory" "allocator"
-              Allocator
-           -> -- No documentation found for Nested "vmaFreeMemory" "allocation"
-              Allocation
-           -> io ()
-freeMemory allocator allocation = liftIO $ do
-  traceAroundEvent "vmaFreeMemory" ((ffiVmaFreeMemory) (allocator) (allocation))
-  pure $ ()
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaFreeMemoryPages" ffiVmaFreeMemoryPages
-  :: Allocator -> CSize -> Ptr Allocation -> IO ()
-
--- | Frees memory and destroys multiple allocations.
---
--- Word \"pages\" is just a suggestion to use this function to free pieces
--- of memory used for sparse binding. It is just a general purpose function
--- to free memory and destroy allocations made using e.g. 'allocateMemory',
--- 'allocateMemoryPages' and other functions. It may be internally
--- optimized to be more efficient than calling 'freeMemory'
--- @allocationCount@ times.
---
--- Allocations in @pAllocations@ array can come from any memory pools and
--- types. Passing @VK_NULL_HANDLE@ as elements of @pAllocations@ array is
--- valid. Such entries are just skipped.
-freeMemoryPages :: forall io
-                 . (MonadIO io)
-                => -- No documentation found for Nested "vmaFreeMemoryPages" "allocator"
-                   Allocator
-                -> -- No documentation found for Nested "vmaFreeMemoryPages" "pAllocations"
-                   ("allocations" ::: Vector Allocation)
-                -> io ()
-freeMemoryPages allocator allocations = liftIO . evalContT $ do
-  pPAllocations <- ContT $ allocaBytes @Allocation ((Data.Vector.length (allocations)) * 8)
-  lift $ Data.Vector.imapM_ (\i e -> poke (pPAllocations `plusPtr` (8 * (i)) :: Ptr Allocation) (e)) (allocations)
-  lift $ traceAroundEvent "vmaFreeMemoryPages" ((ffiVmaFreeMemoryPages) (allocator) ((fromIntegral (Data.Vector.length $ (allocations)) :: CSize)) (pPAllocations))
-  pure $ ()
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaGetAllocationInfo" ffiVmaGetAllocationInfo
-  :: Allocator -> Allocation -> Ptr AllocationInfo -> IO ()
-
--- | Returns current information about specified allocation.
---
--- Current parameters of given allocation are returned in
--- @pAllocationInfo@.
---
--- Although this function doesn\'t lock any mutex, so it should be quite
--- efficient, you should avoid calling it too often. You can retrieve same
--- 'AllocationInfo' structure while creating your resource, from function
--- 'createBuffer', 'createImage'. You can remember it if you are sure
--- parameters don\'t change (e.g. due to defragmentation).
-getAllocationInfo :: forall io
-                   . (MonadIO io)
-                  => -- No documentation found for Nested "vmaGetAllocationInfo" "allocator"
-                     Allocator
-                  -> -- No documentation found for Nested "vmaGetAllocationInfo" "allocation"
-                     Allocation
-                  -> io (AllocationInfo)
-getAllocationInfo allocator allocation = liftIO . evalContT $ do
-  pPAllocationInfo <- ContT (withZeroCStruct @AllocationInfo)
-  lift $ traceAroundEvent "vmaGetAllocationInfo" ((ffiVmaGetAllocationInfo) (allocator) (allocation) (pPAllocationInfo))
-  pAllocationInfo <- lift $ peekCStruct @AllocationInfo pPAllocationInfo
-  pure $ (pAllocationInfo)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaSetAllocationUserData" ffiVmaSetAllocationUserData
-  :: Allocator -> Allocation -> Ptr () -> IO ()
-
--- | Sets pUserData in given allocation to new value.
---
--- The value of pointer @pUserData@ is copied to allocation\'s @pUserData@.
--- It is opaque, so you can use it however you want - e.g. as a pointer,
--- ordinal number or some handle to you own data.
-setAllocationUserData :: forall io
-                       . (MonadIO io)
-                      => -- No documentation found for Nested "vmaSetAllocationUserData" "allocator"
-                         Allocator
-                      -> -- No documentation found for Nested "vmaSetAllocationUserData" "allocation"
-                         Allocation
-                      -> -- No documentation found for Nested "vmaSetAllocationUserData" "pUserData"
-                         ("userData" ::: Ptr ())
-                      -> io ()
-setAllocationUserData allocator allocation userData = liftIO $ do
-  traceAroundEvent "vmaSetAllocationUserData" ((ffiVmaSetAllocationUserData) (allocator) (allocation) (userData))
-  pure $ ()
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaSetAllocationName" ffiVmaSetAllocationName
-  :: Allocator -> Allocation -> Ptr CChar -> IO ()
-
--- | Sets pName in given allocation to new value.
---
--- @pName@ must be either null, or pointer to a null-terminated string. The
--- function makes local copy of the string and sets it as allocation\'s
--- @pName@. String passed as pName doesn\'t need to be valid for whole
--- lifetime of the allocation - you can free it after this call. String
--- previously pointed by allocation\'s @pName@ is freed from memory.
-setAllocationName :: forall io
-                   . (MonadIO io)
-                  => -- No documentation found for Nested "vmaSetAllocationName" "allocator"
-                     Allocator
-                  -> -- No documentation found for Nested "vmaSetAllocationName" "allocation"
-                     Allocation
-                  -> -- No documentation found for Nested "vmaSetAllocationName" "pName"
-                     ("name" ::: Maybe ByteString)
-                  -> io ()
-setAllocationName allocator allocation name = liftIO . evalContT $ do
-  pName <- case (name) of
-    Nothing -> pure nullPtr
-    Just j -> ContT $ useAsCString (j)
-  lift $ traceAroundEvent "vmaSetAllocationName" ((ffiVmaSetAllocationName) (allocator) (allocation) pName)
-  pure $ ()
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaGetAllocationMemoryProperties" ffiVmaGetAllocationMemoryProperties
-  :: Allocator -> Allocation -> Ptr MemoryPropertyFlags -> IO ()
-
--- | Given an allocation, returns Property Flags of its memory type.
---
--- This is just a convenience function. Same information can be obtained
--- using 'getAllocationInfo' + 'getMemoryProperties'.
-getAllocationMemoryProperties :: forall io
-                               . (MonadIO io)
-                              => -- No documentation found for Nested "vmaGetAllocationMemoryProperties" "allocator"
-                                 Allocator
-                              -> -- No documentation found for Nested "vmaGetAllocationMemoryProperties" "allocation"
-                                 Allocation
-                              -> io (MemoryPropertyFlags)
-getAllocationMemoryProperties allocator allocation = liftIO . evalContT $ do
-  pPFlags <- ContT $ bracket (callocBytes @MemoryPropertyFlags 4) free
-  lift $ traceAroundEvent "vmaGetAllocationMemoryProperties" ((ffiVmaGetAllocationMemoryProperties) (allocator) (allocation) (pPFlags))
-  pFlags <- lift $ peek @MemoryPropertyFlags pPFlags
-  pure $ (pFlags)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaMapMemory" ffiVmaMapMemory
-  :: Allocator -> Allocation -> Ptr (Ptr ()) -> IO Result
-
--- | Maps memory represented by given allocation and returns pointer to it.
---
--- Maps memory represented by given allocation to make it accessible to CPU
--- code. When succeeded, @*ppData@ contains pointer to first byte of this
--- memory.
---
--- Warning
---
--- If the allocation is part of a bigger @VkDeviceMemory@ block, returned
--- pointer is correctly offsetted to the beginning of region assigned to
--- this particular allocation. Unlike the result of @vkMapMemory@, it
--- points to the allocation, not to the beginning of the whole block. You
--- should not add /VmaAllocationInfo::offset/ to it!
---
--- Mapping is internally reference-counted and synchronized, so despite raw
--- Vulkan function @vkMapMemory()@ cannot be used to map same block of
--- @VkDeviceMemory@ multiple times simultaneously, it is safe to call this
--- function on allocations assigned to the same memory block. Actual Vulkan
--- memory will be mapped on first mapping and unmapped on last unmapping.
---
--- If the function succeeded, you must call 'unmapMemory' to unmap the
--- allocation when mapping is no longer needed or before freeing the
--- allocation, at the latest.
---
--- It also safe to call this function multiple times on the same
--- allocation. You must call 'unmapMemory' same number of times as you
--- called 'mapMemory'.
---
--- It is also safe to call this function on allocation created with
--- 'ALLOCATION_CREATE_MAPPED_BIT' flag. Its memory stays mapped all the
--- time. You must still call 'unmapMemory' same number of times as you
--- called 'mapMemory'. You must not call 'unmapMemory' additional time to
--- free the \"0-th\" mapping made automatically due to
--- 'ALLOCATION_CREATE_MAPPED_BIT' flag.
---
--- This function fails when used on allocation made in memory type that is
--- not @HOST_VISIBLE@.
---
--- This function doesn\'t automatically flush or invalidate caches. If the
--- allocation is made from a memory types that is not @HOST_COHERENT@, you
--- also need to use 'invalidateAllocation' \/ 'flushAllocation', as
--- required by Vulkan specification.
-mapMemory :: forall io
-           . (MonadIO io)
-          => -- No documentation found for Nested "vmaMapMemory" "allocator"
-             Allocator
-          -> -- No documentation found for Nested "vmaMapMemory" "allocation"
-             Allocation
-          -> io (("data" ::: Ptr ()))
-mapMemory allocator allocation = liftIO . evalContT $ do
-  pPpData <- ContT $ bracket (callocBytes @(Ptr ()) 8) free
-  r <- lift $ traceAroundEvent "vmaMapMemory" ((ffiVmaMapMemory) (allocator) (allocation) (pPpData))
-  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
-  ppData <- lift $ peek @(Ptr ()) pPpData
-  pure $ (ppData)
-
--- | A convenience wrapper to make a compatible pair of calls to 'mapMemory'
--- and 'unmapMemory'
---
--- To ensure that 'unmapMemory' is always called: pass
--- 'Control.Exception.bracket' (or the allocate function from your
--- favourite resource management library) as the last argument.
--- To just extract the pair pass '(,)' as the last argument.
---
-withMappedMemory :: forall io r . MonadIO io => Allocator -> Allocation -> (io (Ptr ()) -> (Ptr () -> io ()) -> r) -> r
-withMappedMemory allocator allocation b =
-  b (mapMemory allocator allocation)
-    (\(_) -> unmapMemory allocator allocation)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaUnmapMemory" ffiVmaUnmapMemory
-  :: Allocator -> Allocation -> IO ()
-
--- | Unmaps memory represented by given allocation, mapped previously using
--- 'mapMemory'.
---
--- For details, see description of 'mapMemory'.
---
--- This function doesn\'t automatically flush or invalidate caches. If the
--- allocation is made from a memory types that is not @HOST_COHERENT@, you
--- also need to use 'invalidateAllocation' \/ 'flushAllocation', as
--- required by Vulkan specification.
-unmapMemory :: forall io
-             . (MonadIO io)
-            => -- No documentation found for Nested "vmaUnmapMemory" "allocator"
-               Allocator
-            -> -- No documentation found for Nested "vmaUnmapMemory" "allocation"
-               Allocation
-            -> io ()
-unmapMemory allocator allocation = liftIO $ do
-  traceAroundEvent "vmaUnmapMemory" ((ffiVmaUnmapMemory) (allocator) (allocation))
-  pure $ ()
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaFlushAllocation" ffiVmaFlushAllocation
-  :: Allocator -> Allocation -> DeviceSize -> DeviceSize -> IO Result
-
--- | Flushes memory of given allocation.
---
--- Calls @vkFlushMappedMemoryRanges()@ for memory associated with given
--- range of given allocation. It needs to be called after writing to a
--- mapped memory for memory types that are not @HOST_COHERENT@. Unmap
--- operation doesn\'t do that automatically.
---
--- -   @offset@ must be relative to the beginning of allocation.
---
--- -   @size@ can be @VK_WHOLE_SIZE@. It means all memory from @offset@ the
---     the end of given allocation.
---
--- -   @offset@ and @size@ don\'t have to be aligned. They are internally
---     rounded down\/up to multiply of @nonCoherentAtomSize@.
---
--- -   If @size@ is 0, this call is ignored.
---
--- -   If memory type that the @allocation@ belongs to is not
---     @HOST_VISIBLE@ or it is @HOST_COHERENT@, this call is ignored.
---
--- Warning! @offset@ and @size@ are relative to the contents of given
--- @allocation@. If you mean whole allocation, you can pass 0 and
--- @VK_WHOLE_SIZE@, respectively. Do not pass allocation\'s offset as
--- @offset@!!!
---
--- This function returns the @VkResult@ from @vkFlushMappedMemoryRanges@ if
--- it is called, otherwise @VK_SUCCESS@.
-flushAllocation :: forall io
-                 . (MonadIO io)
-                => -- No documentation found for Nested "vmaFlushAllocation" "allocator"
-                   Allocator
-                -> -- No documentation found for Nested "vmaFlushAllocation" "allocation"
-                   Allocation
-                -> -- No documentation found for Nested "vmaFlushAllocation" "offset"
-                   ("offset" ::: DeviceSize)
-                -> -- No documentation found for Nested "vmaFlushAllocation" "size"
-                   DeviceSize
-                -> io ()
-flushAllocation allocator allocation offset size = liftIO $ do
-  r <- traceAroundEvent "vmaFlushAllocation" ((ffiVmaFlushAllocation) (allocator) (allocation) (offset) (size))
-  when (r < SUCCESS) (throwIO (VulkanException r))
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaInvalidateAllocation" ffiVmaInvalidateAllocation
-  :: Allocator -> Allocation -> DeviceSize -> DeviceSize -> IO Result
-
--- | Invalidates memory of given allocation.
---
--- Calls @vkInvalidateMappedMemoryRanges()@ for memory associated with
--- given range of given allocation. It needs to be called before reading
--- from a mapped memory for memory types that are not @HOST_COHERENT@. Map
--- operation doesn\'t do that automatically.
---
--- -   @offset@ must be relative to the beginning of allocation.
---
--- -   @size@ can be @VK_WHOLE_SIZE@. It means all memory from @offset@ the
---     the end of given allocation.
---
--- -   @offset@ and @size@ don\'t have to be aligned. They are internally
---     rounded down\/up to multiply of @nonCoherentAtomSize@.
---
--- -   If @size@ is 0, this call is ignored.
---
--- -   If memory type that the @allocation@ belongs to is not
---     @HOST_VISIBLE@ or it is @HOST_COHERENT@, this call is ignored.
---
--- Warning! @offset@ and @size@ are relative to the contents of given
--- @allocation@. If you mean whole allocation, you can pass 0 and
--- @VK_WHOLE_SIZE@, respectively. Do not pass allocation\'s offset as
--- @offset@!!!
---
--- This function returns the @VkResult@ from
--- @vkInvalidateMappedMemoryRanges@ if it is called, otherwise
--- @VK_SUCCESS@.
-invalidateAllocation :: forall io
-                      . (MonadIO io)
-                     => -- No documentation found for Nested "vmaInvalidateAllocation" "allocator"
-                        Allocator
-                     -> -- No documentation found for Nested "vmaInvalidateAllocation" "allocation"
-                        Allocation
-                     -> -- No documentation found for Nested "vmaInvalidateAllocation" "offset"
-                        ("offset" ::: DeviceSize)
-                     -> -- No documentation found for Nested "vmaInvalidateAllocation" "size"
-                        DeviceSize
-                     -> io ()
-invalidateAllocation allocator allocation offset size = liftIO $ do
-  r <- traceAroundEvent "vmaInvalidateAllocation" ((ffiVmaInvalidateAllocation) (allocator) (allocation) (offset) (size))
-  when (r < SUCCESS) (throwIO (VulkanException r))
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaFlushAllocations" ffiVmaFlushAllocations
-  :: Allocator -> Word32 -> Ptr Allocation -> Ptr DeviceSize -> Ptr DeviceSize -> IO Result
-
--- | Flushes memory of given set of allocations.
---
--- Calls @vkFlushMappedMemoryRanges()@ for memory associated with given
--- ranges of given allocations. For more information, see documentation of
--- 'flushAllocation'.
---
--- __Parameters__
---
--- +-----------------+--------------------------------------------------------+
--- | allocator       |                                                        |
--- +-----------------+--------------------------------------------------------+
--- | allocationCount |                                                        |
--- +-----------------+--------------------------------------------------------+
--- | allocations     |                                                        |
--- +-----------------+--------------------------------------------------------+
--- | offsets         | If not null, it must point to an array of offsets of   |
--- |                 | regions to flush, relative to the beginning of         |
--- |                 | respective allocations. Null means all ofsets are      |
--- |                 | zero.                                                  |
--- +-----------------+--------------------------------------------------------+
--- | sizes           | If not null, it must point to an array of sizes of     |
--- |                 | regions to flush in respective allocations. Null means |
--- |                 | @VK_WHOLE_SIZE@ for all allocations.                   |
--- +-----------------+--------------------------------------------------------+
---
--- This function returns the @VkResult@ from @vkFlushMappedMemoryRanges@ if
--- it is called, otherwise @VK_SUCCESS@.
-flushAllocations :: forall io
-                  . (MonadIO io)
-                 => -- No documentation found for Nested "vmaFlushAllocations" "allocator"
-                    Allocator
-                 -> -- No documentation found for Nested "vmaFlushAllocations" "allocations"
-                    ("allocations" ::: Vector Allocation)
-                 -> -- No documentation found for Nested "vmaFlushAllocations" "offsets"
-                    ("offsets" ::: Vector DeviceSize)
-                 -> -- No documentation found for Nested "vmaFlushAllocations" "sizes"
-                    ("sizes" ::: Vector DeviceSize)
-                 -> io ()
-flushAllocations allocator allocations offsets sizes = liftIO . evalContT $ do
-  let allocationsLength = Data.Vector.length $ (allocations)
-  let offsetsLength = Data.Vector.length $ (offsets)
-  lift $ unless (fromIntegral offsetsLength == allocationsLength || offsetsLength == 0) $
-    throwIO $ IOError Nothing InvalidArgument "" "offsets and allocations must have the same length" Nothing Nothing
-  let sizesLength = Data.Vector.length $ (sizes)
-  lift $ unless (fromIntegral sizesLength == allocationsLength || sizesLength == 0) $
-    throwIO $ IOError Nothing InvalidArgument "" "sizes and allocations must have the same length" Nothing Nothing
-  pAllocations <- ContT $ allocaBytes @Allocation ((Data.Vector.length (allocations)) * 8)
-  lift $ Data.Vector.imapM_ (\i e -> poke (pAllocations `plusPtr` (8 * (i)) :: Ptr Allocation) (e)) (allocations)
-  offsets' <- if Data.Vector.null (offsets)
-    then pure nullPtr
-    else do
-      pOffsets <- ContT $ allocaBytes @DeviceSize (((Data.Vector.length (offsets))) * 8)
-      lift $ Data.Vector.imapM_ (\i e -> poke (pOffsets `plusPtr` (8 * (i)) :: Ptr DeviceSize) (e)) ((offsets))
-      pure $ pOffsets
-  sizes' <- if Data.Vector.null (sizes)
-    then pure nullPtr
-    else do
-      pSizes <- ContT $ allocaBytes @DeviceSize (((Data.Vector.length (sizes))) * 8)
-      lift $ Data.Vector.imapM_ (\i e -> poke (pSizes `plusPtr` (8 * (i)) :: Ptr DeviceSize) (e)) ((sizes))
-      pure $ pSizes
-  r <- lift $ traceAroundEvent "vmaFlushAllocations" ((ffiVmaFlushAllocations) (allocator) ((fromIntegral allocationsLength :: Word32)) (pAllocations) offsets' sizes')
-  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaInvalidateAllocations" ffiVmaInvalidateAllocations
-  :: Allocator -> Word32 -> Ptr Allocation -> Ptr DeviceSize -> Ptr DeviceSize -> IO Result
-
--- | Invalidates memory of given set of allocations.
---
--- Calls @vkInvalidateMappedMemoryRanges()@ for memory associated with
--- given ranges of given allocations. For more information, see
--- documentation of 'invalidateAllocation'.
---
--- __Parameters__
---
--- +-----------------+--------------------------------------------------------+
--- | allocator       |                                                        |
--- +-----------------+--------------------------------------------------------+
--- | allocationCount |                                                        |
--- +-----------------+--------------------------------------------------------+
--- | allocations     |                                                        |
--- +-----------------+--------------------------------------------------------+
--- | offsets         | If not null, it must point to an array of offsets of   |
--- |                 | regions to flush, relative to the beginning of         |
--- |                 | respective allocations. Null means all ofsets are      |
--- |                 | zero.                                                  |
--- +-----------------+--------------------------------------------------------+
--- | sizes           | If not null, it must point to an array of sizes of     |
--- |                 | regions to flush in respective allocations. Null means |
--- |                 | @VK_WHOLE_SIZE@ for all allocations.                   |
--- +-----------------+--------------------------------------------------------+
---
--- This function returns the @VkResult@ from
--- @vkInvalidateMappedMemoryRanges@ if it is called, otherwise
--- @VK_SUCCESS@.
-invalidateAllocations :: forall io
-                       . (MonadIO io)
-                      => -- No documentation found for Nested "vmaInvalidateAllocations" "allocator"
-                         Allocator
-                      -> -- No documentation found for Nested "vmaInvalidateAllocations" "allocations"
-                         ("allocations" ::: Vector Allocation)
-                      -> -- No documentation found for Nested "vmaInvalidateAllocations" "offsets"
-                         ("offsets" ::: Vector DeviceSize)
-                      -> -- No documentation found for Nested "vmaInvalidateAllocations" "sizes"
-                         ("sizes" ::: Vector DeviceSize)
-                      -> io ()
-invalidateAllocations allocator allocations offsets sizes = liftIO . evalContT $ do
-  let allocationsLength = Data.Vector.length $ (allocations)
-  let offsetsLength = Data.Vector.length $ (offsets)
-  lift $ unless (fromIntegral offsetsLength == allocationsLength || offsetsLength == 0) $
-    throwIO $ IOError Nothing InvalidArgument "" "offsets and allocations must have the same length" Nothing Nothing
-  let sizesLength = Data.Vector.length $ (sizes)
-  lift $ unless (fromIntegral sizesLength == allocationsLength || sizesLength == 0) $
-    throwIO $ IOError Nothing InvalidArgument "" "sizes and allocations must have the same length" Nothing Nothing
-  pAllocations <- ContT $ allocaBytes @Allocation ((Data.Vector.length (allocations)) * 8)
-  lift $ Data.Vector.imapM_ (\i e -> poke (pAllocations `plusPtr` (8 * (i)) :: Ptr Allocation) (e)) (allocations)
-  offsets' <- if Data.Vector.null (offsets)
-    then pure nullPtr
-    else do
-      pOffsets <- ContT $ allocaBytes @DeviceSize (((Data.Vector.length (offsets))) * 8)
-      lift $ Data.Vector.imapM_ (\i e -> poke (pOffsets `plusPtr` (8 * (i)) :: Ptr DeviceSize) (e)) ((offsets))
-      pure $ pOffsets
-  sizes' <- if Data.Vector.null (sizes)
-    then pure nullPtr
-    else do
-      pSizes <- ContT $ allocaBytes @DeviceSize (((Data.Vector.length (sizes))) * 8)
-      lift $ Data.Vector.imapM_ (\i e -> poke (pSizes `plusPtr` (8 * (i)) :: Ptr DeviceSize) (e)) ((sizes))
-      pure $ pSizes
-  r <- lift $ traceAroundEvent "vmaInvalidateAllocations" ((ffiVmaInvalidateAllocations) (allocator) ((fromIntegral allocationsLength :: Word32)) (pAllocations) offsets' sizes')
-  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaCheckCorruption" ffiVmaCheckCorruption
-  :: Allocator -> Word32 -> IO Result
-
--- | Checks magic number in margins around all allocations in given memory
--- types (in both default and custom pools) in search for corruptions.
---
--- __Parameters__
---
--- +----------------+--------------------------------------------------------+
--- | allocator      |                                                        |
--- +----------------+--------------------------------------------------------+
--- | memoryTypeBits | Bit mask, where each bit set means that a memory type  |
--- |                | with that index should be checked.                     |
--- +----------------+--------------------------------------------------------+
---
--- Corruption detection is enabled only when @VMA_DEBUG_DETECT_CORRUPTION@
--- macro is defined to nonzero, @VMA_DEBUG_MARGIN@ is defined to nonzero
--- and only for memory types that are @HOST_VISIBLE@ and @HOST_COHERENT@.
--- For more information, see /Corruption detection/.
---
--- Possible return values:
---
--- -   @VK_ERROR_FEATURE_NOT_PRESENT@ - corruption detection is not enabled
---     for any of specified memory types.
---
--- -   @VK_SUCCESS@ - corruption detection has been performed and
---     succeeded.
---
--- -   @VK_ERROR_UNKNOWN@ - corruption detection has been performed and
---     found memory corruptions around one of the allocations. @VMA_ASSERT@
---     is also fired in that case.
---
--- -   Other value: Error returned by Vulkan, e.g. memory mapping failure.
-checkCorruption :: forall io
-                 . (MonadIO io)
-                => -- No documentation found for Nested "vmaCheckCorruption" "allocator"
-                   Allocator
-                -> -- No documentation found for Nested "vmaCheckCorruption" "memoryTypeBits"
-                   ("memoryTypeBits" ::: Word32)
-                -> io ()
-checkCorruption allocator memoryTypeBits = liftIO $ do
-  r <- traceAroundEvent "vmaCheckCorruption" ((ffiVmaCheckCorruption) (allocator) (memoryTypeBits))
-  when (r < SUCCESS) (throwIO (VulkanException r))
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaBeginDefragmentation" ffiVmaBeginDefragmentation
-  :: Allocator -> Ptr DefragmentationInfo -> Ptr DefragmentationContext -> IO Result
-
--- | Begins defragmentation process.
---
--- __Parameters__
---
--- +-----------+-----------+-----------------------------------------------+
--- |           | allocator | Allocator object.                             |
--- +-----------+-----------+-----------------------------------------------+
--- |           | pInfo     | Structure filled with parameters of           |
--- |           |           | defragmentation.                              |
--- +-----------+-----------+-----------------------------------------------+
--- | out       | pContext  | Context object that must be passed to         |
--- |           |           | 'endDefragmentation' to finish                |
--- |           |           | defragmentation.                              |
--- +-----------+-----------+-----------------------------------------------+
---
--- __Returns__
---
--- -   @VK_SUCCESS@ if defragmentation can begin.
---
--- -   @VK_ERROR_FEATURE_NOT_PRESENT@ if defragmentation is not supported.
---
--- For more information about defragmentation, see documentation chapter:
--- /Defragmentation/.
-beginDefragmentation :: forall io
-                      . (MonadIO io)
-                     => -- No documentation found for Nested "vmaBeginDefragmentation" "allocator"
-                        Allocator
-                     -> -- No documentation found for Nested "vmaBeginDefragmentation" "pInfo"
-                        DefragmentationInfo
-                     -> io (DefragmentationContext)
-beginDefragmentation allocator info = liftIO . evalContT $ do
-  pInfo <- ContT $ withCStruct (info)
-  pPContext <- ContT $ bracket (callocBytes @DefragmentationContext 8) free
-  r <- lift $ traceAroundEvent "vmaBeginDefragmentation" ((ffiVmaBeginDefragmentation) (allocator) pInfo (pPContext))
-  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
-  pContext <- lift $ peek @DefragmentationContext pPContext
-  pure $ (pContext)
-
--- | A convenience wrapper to make a compatible pair of calls to
--- 'beginDefragmentation' and 'endDefragmentation'
---
--- To ensure that 'endDefragmentation' is always called: pass
--- 'Control.Exception.bracket' (or the allocate function from your
--- favourite resource management library) as the last argument.
--- To just extract the pair pass '(,)' as the last argument.
---
-withDefragmentation :: forall io r . MonadIO io => Allocator -> DefragmentationInfo -> (io DefragmentationContext -> (DefragmentationContext -> io (DefragmentationStats)) -> r) -> r
-withDefragmentation allocator pInfo b =
-  b (beginDefragmentation allocator pInfo)
-    (\(o0) -> endDefragmentation allocator o0)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaEndDefragmentation" ffiVmaEndDefragmentation
-  :: Allocator -> DefragmentationContext -> Ptr DefragmentationStats -> IO ()
-
--- | Ends defragmentation process.
---
--- __Parameters__
---
--- +-----------+-----------+-----------------------------------------------+
--- |           | allocator | Allocator object.                             |
--- +-----------+-----------+-----------------------------------------------+
--- |           | context   | Context object that has been created by       |
--- |           |           | 'beginDefragmentation'.                       |
--- +-----------+-----------+-----------------------------------------------+
--- | out       | pStats    | Optional stats for the defragmentation. Can   |
--- |           |           | be null.                                      |
--- +-----------+-----------+-----------------------------------------------+
---
--- Use this function to finish defragmentation started by
--- 'beginDefragmentation'.
-endDefragmentation :: forall io
-                    . (MonadIO io)
-                   => -- No documentation found for Nested "vmaEndDefragmentation" "allocator"
-                      Allocator
-                   -> -- No documentation found for Nested "vmaEndDefragmentation" "context"
-                      DefragmentationContext
-                   -> io (DefragmentationStats)
-endDefragmentation allocator context = liftIO . evalContT $ do
-  pPStats <- ContT (withZeroCStruct @DefragmentationStats)
-  lift $ traceAroundEvent "vmaEndDefragmentation" ((ffiVmaEndDefragmentation) (allocator) (context) (pPStats))
-  pStats <- lift $ peekCStruct @DefragmentationStats pPStats
-  pure $ (pStats)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaBeginDefragmentationPass" ffiVmaBeginDefragmentationPass
-  :: Allocator -> DefragmentationContext -> Ptr DefragmentationPassMoveInfo -> IO Result
-
--- | Starts single defragmentation pass.
---
--- __Parameters__
---
--- +-----------+-----------+-----------------------------------------------+
--- |           | allocator | Allocator object.                             |
--- +-----------+-----------+-----------------------------------------------+
--- |           | context   | Context object that has been created by       |
--- |           |           | 'beginDefragmentation'.                       |
--- +-----------+-----------+-----------------------------------------------+
--- | out       | pPassInfo | Computed information for current pass.        |
--- +-----------+-----------+-----------------------------------------------+
---
--- __Returns__
---
--- -   @VK_SUCCESS@ if no more moves are possible. Then you can omit call
---     to 'endDefragmentationPass' and simply end whole defragmentation.
---
--- -   @VK_INCOMPLETE@ if there are pending moves returned in @pPassInfo@.
---     You need to perform them, call 'endDefragmentationPass', and then
---     preferably try another pass with 'beginDefragmentationPass'.
-beginDefragmentationPass :: forall io
-                          . (MonadIO io)
-                         => -- No documentation found for Nested "vmaBeginDefragmentationPass" "allocator"
-                            Allocator
-                         -> -- No documentation found for Nested "vmaBeginDefragmentationPass" "context"
-                            DefragmentationContext
-                         -> io (("passInfo" ::: DefragmentationPassMoveInfo))
-beginDefragmentationPass allocator context = liftIO . evalContT $ do
-  pPPassInfo <- ContT (withZeroCStruct @DefragmentationPassMoveInfo)
-  r <- lift $ traceAroundEvent "vmaBeginDefragmentationPass" ((ffiVmaBeginDefragmentationPass) (allocator) (context) (pPPassInfo))
-  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
-  pPassInfo <- lift $ peekCStruct @DefragmentationPassMoveInfo pPPassInfo
-  pure $ (pPassInfo)
-
--- | This function will call the supplied action between calls to
--- 'beginDefragmentationPass' and 'endDefragmentationPass'
---
--- Note that 'endDefragmentationPass' is *not* called if an exception is
--- thrown by the inner action.
-useDefragmentationPass :: forall io r . MonadIO io => Allocator -> DefragmentationContext -> (DefragmentationPassMoveInfo -> io r) -> io (("passInfo" ::: DefragmentationPassMoveInfo), r)
-useDefragmentationPass allocator context a =
-  do
-    x <- beginDefragmentationPass allocator context
-    r <- a x
-    d <- (\(_) -> endDefragmentationPass allocator context) x
-    pure (d, r)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaEndDefragmentationPass" ffiVmaEndDefragmentationPass
-  :: Allocator -> DefragmentationContext -> Ptr DefragmentationPassMoveInfo -> IO Result
-
--- | Ends single defragmentation pass.
---
--- __Parameters__
---
--- +-------------+--------------------------------------------------------+
--- | allocator   | Allocator object.                                      |
--- +-------------+--------------------------------------------------------+
--- | context     | Context object that has been created by                |
--- |             | 'beginDefragmentation'.                                |
--- +-------------+--------------------------------------------------------+
--- | pPassInfo   | Computed information for current pass filled by        |
--- |             | 'beginDefragmentationPass' and possibly modified by    |
--- |             | you.                                                   |
--- +-------------+--------------------------------------------------------+
---
--- Returns @VK_SUCCESS@ if no more moves are possible or @VK_INCOMPLETE@ if
--- more defragmentations are possible.
---
--- Ends incremental defragmentation pass and commits all defragmentation
--- moves from @pPassInfo@. After this call:
---
--- -   Allocations at @pPassInfo[i].srcAllocation@ that had
---     @pPassInfo[i].operation ==@ 'DEFRAGMENTATION_MOVE_OPERATION_COPY'
---     (which is the default) will be pointing to the new destination
---     place.
---
--- -   Allocation at @pPassInfo[i].srcAllocation@ that had
---     @pPassInfo[i].operation ==@ 'DEFRAGMENTATION_MOVE_OPERATION_DESTROY'
---     will be freed.
---
--- If no more moves are possible you can end whole defragmentation.
-endDefragmentationPass :: forall io
-                        . (MonadIO io)
-                       => -- No documentation found for Nested "vmaEndDefragmentationPass" "allocator"
-                          Allocator
-                       -> -- No documentation found for Nested "vmaEndDefragmentationPass" "context"
-                          DefragmentationContext
-                       -> io (("passInfo" ::: DefragmentationPassMoveInfo))
-endDefragmentationPass allocator context = liftIO . evalContT $ do
-  pPPassInfo <- ContT (withZeroCStruct @DefragmentationPassMoveInfo)
-  r <- lift $ traceAroundEvent "vmaEndDefragmentationPass" ((ffiVmaEndDefragmentationPass) (allocator) (context) (pPPassInfo))
-  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
-  pPassInfo <- lift $ peekCStruct @DefragmentationPassMoveInfo pPPassInfo
-  pure $ (pPassInfo)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaBindBufferMemory" ffiVmaBindBufferMemory
-  :: Allocator -> Allocation -> Buffer -> IO Result
-
--- | Binds buffer to allocation.
---
--- Binds specified buffer to region of memory represented by specified
--- allocation. Gets @VkDeviceMemory@ handle and offset from the allocation.
--- If you want to create a buffer, allocate memory for it and bind them
--- together separately, you should use this function for binding instead of
--- standard @vkBindBufferMemory()@, because it ensures proper
--- synchronization so that when a @VkDeviceMemory@ object is used by
--- multiple allocations, calls to @vkBind*Memory()@ or @vkMapMemory()@
--- won\'t happen from multiple threads simultaneously (which is illegal in
--- Vulkan).
---
--- It is recommended to use function 'createBuffer' instead of this one.
-bindBufferMemory :: forall io
-                  . (MonadIO io)
-                 => -- No documentation found for Nested "vmaBindBufferMemory" "allocator"
-                    Allocator
-                 -> -- No documentation found for Nested "vmaBindBufferMemory" "allocation"
-                    Allocation
-                 -> -- No documentation found for Nested "vmaBindBufferMemory" "buffer"
-                    Buffer
-                 -> io ()
-bindBufferMemory allocator allocation buffer = liftIO $ do
-  r <- traceAroundEvent "vmaBindBufferMemory" ((ffiVmaBindBufferMemory) (allocator) (allocation) (buffer))
-  when (r < SUCCESS) (throwIO (VulkanException r))
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaBindBufferMemory2" ffiVmaBindBufferMemory2
-  :: Allocator -> Allocation -> DeviceSize -> Buffer -> Ptr () -> IO Result
-
--- | Binds buffer to allocation with additional parameters.
---
--- __Parameters__
---
--- +-----------------------+--------------------------------------------------------+
--- | allocator             |                                                        |
--- +-----------------------+--------------------------------------------------------+
--- | allocation            |                                                        |
--- +-----------------------+--------------------------------------------------------+
--- | allocationLocalOffset | Additional offset to be added while binding, relative  |
--- |                       | to the beginning of the @allocation@. Normally it      |
--- |                       | should be 0.                                           |
--- +-----------------------+--------------------------------------------------------+
--- | buffer                |                                                        |
--- +-----------------------+--------------------------------------------------------+
--- | pNext                 | A chain of structures to be attached to                |
--- |                       | @VkBindBufferMemoryInfoKHR@ structure used internally. |
--- |                       | Normally it should be null.                            |
--- +-----------------------+--------------------------------------------------------+
---
--- This function is similar to 'bindBufferMemory', but it provides
--- additional parameters.
---
--- If @pNext@ is not null, 'Allocator' object must have been created with
--- 'ALLOCATOR_CREATE_KHR_BIND_MEMORY2_BIT' flag or with
--- /VmaAllocatorCreateInfo::vulkanApiVersion/ @>= VK_API_VERSION_1_1@.
--- Otherwise the call fails.
-bindBufferMemory2 :: forall io
-                   . (MonadIO io)
-                  => -- No documentation found for Nested "vmaBindBufferMemory2" "allocator"
-                     Allocator
-                  -> -- No documentation found for Nested "vmaBindBufferMemory2" "allocation"
-                     Allocation
-                  -> -- No documentation found for Nested "vmaBindBufferMemory2" "allocationLocalOffset"
-                     ("allocationLocalOffset" ::: DeviceSize)
-                  -> -- No documentation found for Nested "vmaBindBufferMemory2" "buffer"
-                     Buffer
-                  -> -- No documentation found for Nested "vmaBindBufferMemory2" "pNext"
-                     ("next" ::: Ptr ())
-                  -> io ()
-bindBufferMemory2 allocator allocation allocationLocalOffset buffer next = liftIO $ do
-  r <- traceAroundEvent "vmaBindBufferMemory2" ((ffiVmaBindBufferMemory2) (allocator) (allocation) (allocationLocalOffset) (buffer) (next))
-  when (r < SUCCESS) (throwIO (VulkanException r))
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaBindImageMemory" ffiVmaBindImageMemory
-  :: Allocator -> Allocation -> Image -> IO Result
-
--- | Binds image to allocation.
---
--- Binds specified image to region of memory represented by specified
--- allocation. Gets @VkDeviceMemory@ handle and offset from the allocation.
--- If you want to create an image, allocate memory for it and bind them
--- together separately, you should use this function for binding instead of
--- standard @vkBindImageMemory()@, because it ensures proper
--- synchronization so that when a @VkDeviceMemory@ object is used by
--- multiple allocations, calls to @vkBind*Memory()@ or @vkMapMemory()@
--- won\'t happen from multiple threads simultaneously (which is illegal in
--- Vulkan).
---
--- It is recommended to use function 'createImage' instead of this one.
-bindImageMemory :: forall io
-                 . (MonadIO io)
-                => -- No documentation found for Nested "vmaBindImageMemory" "allocator"
-                   Allocator
-                -> -- No documentation found for Nested "vmaBindImageMemory" "allocation"
-                   Allocation
-                -> -- No documentation found for Nested "vmaBindImageMemory" "image"
-                   Image
-                -> io ()
-bindImageMemory allocator allocation image = liftIO $ do
-  r <- traceAroundEvent "vmaBindImageMemory" ((ffiVmaBindImageMemory) (allocator) (allocation) (image))
-  when (r < SUCCESS) (throwIO (VulkanException r))
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaBindImageMemory2" ffiVmaBindImageMemory2
-  :: Allocator -> Allocation -> DeviceSize -> Image -> Ptr () -> IO Result
-
--- | Binds image to allocation with additional parameters.
---
--- __Parameters__
---
--- +-----------------------+--------------------------------------------------------+
--- | allocator             |                                                        |
--- +-----------------------+--------------------------------------------------------+
--- | allocation            |                                                        |
--- +-----------------------+--------------------------------------------------------+
--- | allocationLocalOffset | Additional offset to be added while binding, relative  |
--- |                       | to the beginning of the @allocation@. Normally it      |
--- |                       | should be 0.                                           |
--- +-----------------------+--------------------------------------------------------+
--- | image                 |                                                        |
--- +-----------------------+--------------------------------------------------------+
--- | pNext                 | A chain of structures to be attached to                |
--- |                       | @VkBindImageMemoryInfoKHR@ structure used internally.  |
--- |                       | Normally it should be null.                            |
--- +-----------------------+--------------------------------------------------------+
---
--- This function is similar to 'bindImageMemory', but it provides
--- additional parameters.
---
--- If @pNext@ is not null, 'Allocator' object must have been created with
--- 'ALLOCATOR_CREATE_KHR_BIND_MEMORY2_BIT' flag or with
--- /VmaAllocatorCreateInfo::vulkanApiVersion/ @>= VK_API_VERSION_1_1@.
--- Otherwise the call fails.
-bindImageMemory2 :: forall io
-                  . (MonadIO io)
-                 => -- No documentation found for Nested "vmaBindImageMemory2" "allocator"
-                    Allocator
-                 -> -- No documentation found for Nested "vmaBindImageMemory2" "allocation"
-                    Allocation
-                 -> -- No documentation found for Nested "vmaBindImageMemory2" "allocationLocalOffset"
-                    ("allocationLocalOffset" ::: DeviceSize)
-                 -> -- No documentation found for Nested "vmaBindImageMemory2" "image"
-                    Image
-                 -> -- No documentation found for Nested "vmaBindImageMemory2" "pNext"
-                    ("next" ::: Ptr ())
-                 -> io ()
-bindImageMemory2 allocator allocation allocationLocalOffset image next = liftIO $ do
-  r <- traceAroundEvent "vmaBindImageMemory2" ((ffiVmaBindImageMemory2) (allocator) (allocation) (allocationLocalOffset) (image) (next))
-  when (r < SUCCESS) (throwIO (VulkanException r))
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaCreateBuffer" ffiVmaCreateBuffer
-  :: Allocator -> Ptr (SomeStruct BufferCreateInfo) -> Ptr AllocationCreateInfo -> Ptr Buffer -> Ptr Allocation -> Ptr AllocationInfo -> IO Result
-
--- | Creates a new @VkBuffer@, allocates and binds memory for it.
---
--- __Parameters__
---
--- +-----------+-----------------------+-----------------------------------------------+
--- |           | allocator             |                                               |
--- +-----------+-----------------------+-----------------------------------------------+
--- |           | pBufferCreateInfo     |                                               |
--- +-----------+-----------------------+-----------------------------------------------+
--- |           | pAllocationCreateInfo |                                               |
--- +-----------+-----------------------+-----------------------------------------------+
--- | out       | pBuffer               | Buffer that was created.                      |
--- +-----------+-----------------------+-----------------------------------------------+
--- | out       | pAllocation           | Allocation that was created.                  |
--- +-----------+-----------------------+-----------------------------------------------+
--- | out       | pAllocationInfo       | Optional. Information about allocated memory. |
--- |           |                       | It can be later fetched using function        |
--- |           |                       | 'getAllocationInfo'.                          |
--- +-----------+-----------------------+-----------------------------------------------+
---
--- This function automatically:
---
--- 1.  Creates buffer.
---
--- 2.  Allocates appropriate memory for it.
---
--- 3.  Binds the buffer with the memory.
---
--- If any of these operations fail, buffer and allocation are not created,
--- returned value is negative error code, @*pBuffer@ and @*pAllocation@ are
--- null.
---
--- If the function succeeded, you must destroy both buffer and allocation
--- when you no longer need them using either convenience function
--- 'destroyBuffer' or separately, using @vkDestroyBuffer()@ and
--- 'freeMemory'.
---
--- If 'ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT' flag was used,
--- VK_KHR_dedicated_allocation extension is used internally to query driver
--- whether it requires or prefers the new buffer to have dedicated
--- allocation. If yes, and if dedicated allocation is possible
--- ('ALLOCATION_CREATE_NEVER_ALLOCATE_BIT' is not used), it creates
--- dedicated allocation for this buffer, just like when using
--- 'ALLOCATION_CREATE_DEDICATED_MEMORY_BIT'.
---
--- Note
---
--- This function creates a new @VkBuffer@. Sub-allocation of parts of one
--- large buffer, although recommended as a good practice, is out of scope
--- of this library and could be implemented by the user as a higher-level
--- logic on top of VMA.
-createBuffer :: forall a io
-              . (Extendss BufferCreateInfo a, PokeChain a, MonadIO io)
-             => -- No documentation found for Nested "vmaCreateBuffer" "allocator"
-                Allocator
-             -> -- No documentation found for Nested "vmaCreateBuffer" "pBufferCreateInfo"
-                (BufferCreateInfo a)
-             -> -- No documentation found for Nested "vmaCreateBuffer" "pAllocationCreateInfo"
-                AllocationCreateInfo
-             -> io (Buffer, Allocation, AllocationInfo)
-createBuffer allocator bufferCreateInfo allocationCreateInfo = liftIO . evalContT $ do
-  pBufferCreateInfo <- ContT $ withCStruct (bufferCreateInfo)
-  pAllocationCreateInfo <- ContT $ withCStruct (allocationCreateInfo)
-  pPBuffer <- ContT $ bracket (callocBytes @Buffer 8) free
-  pPAllocation <- ContT $ bracket (callocBytes @Allocation 8) free
-  pPAllocationInfo <- ContT (withZeroCStruct @AllocationInfo)
-  r <- lift $ traceAroundEvent "vmaCreateBuffer" ((ffiVmaCreateBuffer) (allocator) (forgetExtensions pBufferCreateInfo) pAllocationCreateInfo (pPBuffer) (pPAllocation) (pPAllocationInfo))
-  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
-  pBuffer <- lift $ peek @Buffer pPBuffer
-  pAllocation <- lift $ peek @Allocation pPAllocation
-  pAllocationInfo <- lift $ peekCStruct @AllocationInfo pPAllocationInfo
-  pure $ (pBuffer, pAllocation, pAllocationInfo)
-
--- | A convenience wrapper to make a compatible pair of calls to
--- 'createBuffer' and 'destroyBuffer'
---
--- To ensure that 'destroyBuffer' is always called: pass
--- 'Control.Exception.bracket' (or the allocate function from your
--- favourite resource management library) as the last argument.
--- To just extract the pair pass '(,)' as the last argument.
---
-withBuffer :: forall a io r . (Extendss BufferCreateInfo a, PokeChain a, MonadIO io) => Allocator -> BufferCreateInfo a -> AllocationCreateInfo -> (io (Buffer, Allocation, AllocationInfo) -> ((Buffer, Allocation, AllocationInfo) -> io ()) -> r) -> r
-withBuffer allocator pBufferCreateInfo pAllocationCreateInfo b =
-  b (createBuffer allocator pBufferCreateInfo pAllocationCreateInfo)
-    (\(o0, o1, _) -> destroyBuffer allocator o0 o1)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaCreateBufferWithAlignment" ffiVmaCreateBufferWithAlignment
-  :: Allocator -> Ptr (SomeStruct BufferCreateInfo) -> Ptr AllocationCreateInfo -> DeviceSize -> Ptr Buffer -> Ptr Allocation -> Ptr AllocationInfo -> IO Result
-
--- | Creates a buffer with additional minimum alignment.
---
--- Similar to 'createBuffer' but provides additional parameter
--- @minAlignment@ which allows to specify custom, minimum alignment to be
--- used when placing the buffer inside a larger memory block, which may be
--- needed e.g. for interop with OpenGL.
-createBufferWithAlignment :: forall a io
-                           . (Extendss BufferCreateInfo a, PokeChain a, MonadIO io)
-                          => -- No documentation found for Nested "vmaCreateBufferWithAlignment" "allocator"
-                             Allocator
-                          -> -- No documentation found for Nested "vmaCreateBufferWithAlignment" "pBufferCreateInfo"
-                             (BufferCreateInfo a)
-                          -> -- No documentation found for Nested "vmaCreateBufferWithAlignment" "pAllocationCreateInfo"
-                             AllocationCreateInfo
-                          -> -- No documentation found for Nested "vmaCreateBufferWithAlignment" "minAlignment"
-                             ("minAlignment" ::: DeviceSize)
-                          -> io (Buffer, Allocation, AllocationInfo)
-createBufferWithAlignment allocator bufferCreateInfo allocationCreateInfo minAlignment = liftIO . evalContT $ do
-  pBufferCreateInfo <- ContT $ withCStruct (bufferCreateInfo)
-  pAllocationCreateInfo <- ContT $ withCStruct (allocationCreateInfo)
-  pPBuffer <- ContT $ bracket (callocBytes @Buffer 8) free
-  pPAllocation <- ContT $ bracket (callocBytes @Allocation 8) free
-  pPAllocationInfo <- ContT (withZeroCStruct @AllocationInfo)
-  r <- lift $ traceAroundEvent "vmaCreateBufferWithAlignment" ((ffiVmaCreateBufferWithAlignment) (allocator) (forgetExtensions pBufferCreateInfo) pAllocationCreateInfo (minAlignment) (pPBuffer) (pPAllocation) (pPAllocationInfo))
-  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
-  pBuffer <- lift $ peek @Buffer pPBuffer
-  pAllocation <- lift $ peek @Allocation pPAllocation
-  pAllocationInfo <- lift $ peekCStruct @AllocationInfo pPAllocationInfo
-  pure $ (pBuffer, pAllocation, pAllocationInfo)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaCreateAliasingBuffer" ffiVmaCreateAliasingBuffer
-  :: Allocator -> Allocation -> Ptr (SomeStruct BufferCreateInfo) -> Ptr Buffer -> IO Result
-
--- | Creates a new @VkBuffer@, binds already created memory for it.
---
--- __Parameters__
---
--- +-----------+-------------------+-----------------------------------------------+
--- |           | allocator         |                                               |
--- +-----------+-------------------+-----------------------------------------------+
--- |           | allocation        | Allocation that provides memory to be used    |
--- |           |                   | for binding new buffer to it.                 |
--- +-----------+-------------------+-----------------------------------------------+
--- |           | pBufferCreateInfo |                                               |
--- +-----------+-------------------+-----------------------------------------------+
--- | out       | pBuffer           | Buffer that was created.                      |
--- +-----------+-------------------+-----------------------------------------------+
---
--- This function automatically:
---
--- 1.  Creates buffer.
---
--- 2.  Binds the buffer with the supplied memory.
---
--- If any of these operations fail, buffer is not created, returned value
--- is negative error code and @*pBuffer@ is null.
---
--- If the function succeeded, you must destroy the buffer when you no
--- longer need it using @vkDestroyBuffer()@. If you want to also destroy
--- the corresponding allocation you can use convenience function
--- 'destroyBuffer'.
---
--- Note
---
--- There is a new version of this function augmented with parameter
--- @allocationLocalOffset@ - see 'createAliasingBuffer2'.
-createAliasingBuffer :: forall a io
-                      . (Extendss BufferCreateInfo a, PokeChain a, MonadIO io)
-                     => -- No documentation found for Nested "vmaCreateAliasingBuffer" "allocator"
-                        Allocator
-                     -> -- No documentation found for Nested "vmaCreateAliasingBuffer" "allocation"
-                        Allocation
-                     -> -- No documentation found for Nested "vmaCreateAliasingBuffer" "pBufferCreateInfo"
-                        (BufferCreateInfo a)
-                     -> io (Buffer)
-createAliasingBuffer allocator allocation bufferCreateInfo = liftIO . evalContT $ do
-  pBufferCreateInfo <- ContT $ withCStruct (bufferCreateInfo)
-  pPBuffer <- ContT $ bracket (callocBytes @Buffer 8) free
-  r <- lift $ traceAroundEvent "vmaCreateAliasingBuffer" ((ffiVmaCreateAliasingBuffer) (allocator) (allocation) (forgetExtensions pBufferCreateInfo) (pPBuffer))
-  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
-  pBuffer <- lift $ peek @Buffer pPBuffer
-  pure $ (pBuffer)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaCreateAliasingBuffer2" ffiVmaCreateAliasingBuffer2
-  :: Allocator -> Allocation -> DeviceSize -> Ptr (SomeStruct BufferCreateInfo) -> Ptr Buffer -> IO Result
-
--- | Creates a new @VkBuffer@, binds already created memory for it.
---
--- __Parameters__
---
--- +-----------+-----------------------+-----------------------------------------------+
--- |           | allocator             |                                               |
--- +-----------+-----------------------+-----------------------------------------------+
--- |           | allocation            | Allocation that provides memory to be used    |
--- |           |                       | for binding new buffer to it.                 |
--- +-----------+-----------------------+-----------------------------------------------+
--- |           | allocationLocalOffset | Additional offset to be added while binding,  |
--- |           |                       | relative to the beginning of the allocation.  |
--- |           |                       | Normally it should be 0.                      |
--- +-----------+-----------------------+-----------------------------------------------+
--- |           | pBufferCreateInfo     |                                               |
--- +-----------+-----------------------+-----------------------------------------------+
--- | out       | pBuffer               | Buffer that was created.                      |
--- +-----------+-----------------------+-----------------------------------------------+
---
--- This function automatically:
---
--- 1.  Creates buffer.
---
--- 2.  Binds the buffer with the supplied memory.
---
--- If any of these operations fail, buffer is not created, returned value
--- is negative error code and @*pBuffer@ is null.
---
--- If the function succeeded, you must destroy the buffer when you no
--- longer need it using @vkDestroyBuffer()@. If you want to also destroy
--- the corresponding allocation you can use convenience function
--- 'destroyBuffer'.
---
--- Note
---
--- This is a new version of the function augmented with parameter
--- @allocationLocalOffset@.
-createAliasingBuffer2 :: forall a io
-                       . (Extendss BufferCreateInfo a, PokeChain a, MonadIO io)
-                      => -- No documentation found for Nested "vmaCreateAliasingBuffer2" "allocator"
-                         Allocator
-                      -> -- No documentation found for Nested "vmaCreateAliasingBuffer2" "allocation"
-                         Allocation
-                      -> -- No documentation found for Nested "vmaCreateAliasingBuffer2" "allocationLocalOffset"
-                         ("allocationLocalOffset" ::: DeviceSize)
-                      -> -- No documentation found for Nested "vmaCreateAliasingBuffer2" "pBufferCreateInfo"
-                         (BufferCreateInfo a)
-                      -> io (Buffer)
-createAliasingBuffer2 allocator allocation allocationLocalOffset bufferCreateInfo = liftIO . evalContT $ do
-  pBufferCreateInfo <- ContT $ withCStruct (bufferCreateInfo)
-  pPBuffer <- ContT $ bracket (callocBytes @Buffer 8) free
-  r <- lift $ traceAroundEvent "vmaCreateAliasingBuffer2" ((ffiVmaCreateAliasingBuffer2) (allocator) (allocation) (allocationLocalOffset) (forgetExtensions pBufferCreateInfo) (pPBuffer))
-  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
-  pBuffer <- lift $ peek @Buffer pPBuffer
-  pure $ (pBuffer)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaDestroyBuffer" ffiVmaDestroyBuffer
-  :: Allocator -> Buffer -> Allocation -> IO ()
-
--- | Destroys Vulkan buffer and frees allocated memory.
---
--- This is just a convenience function equivalent to:
---
--- > vkDestroyBuffer(device, buffer, allocationCallbacks);
--- > vmaFreeMemory(allocator, allocation);
---
--- It is safe to pass null as buffer and\/or allocation.
-destroyBuffer :: forall io
-               . (MonadIO io)
-              => -- No documentation found for Nested "vmaDestroyBuffer" "allocator"
-                 Allocator
-              -> -- No documentation found for Nested "vmaDestroyBuffer" "buffer"
-                 Buffer
-              -> -- No documentation found for Nested "vmaDestroyBuffer" "allocation"
-                 Allocation
-              -> io ()
-destroyBuffer allocator buffer allocation = liftIO $ do
-  traceAroundEvent "vmaDestroyBuffer" ((ffiVmaDestroyBuffer) (allocator) (buffer) (allocation))
-  pure $ ()
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaCreateImage" ffiVmaCreateImage
-  :: Allocator -> Ptr (SomeStruct ImageCreateInfo) -> Ptr AllocationCreateInfo -> Ptr Image -> Ptr Allocation -> Ptr AllocationInfo -> IO Result
-
--- | Function similar to 'createBuffer'.
-createImage :: forall a io
-             . (Extendss ImageCreateInfo a, PokeChain a, MonadIO io)
-            => -- No documentation found for Nested "vmaCreateImage" "allocator"
-               Allocator
-            -> -- No documentation found for Nested "vmaCreateImage" "pImageCreateInfo"
-               (ImageCreateInfo a)
-            -> -- No documentation found for Nested "vmaCreateImage" "pAllocationCreateInfo"
-               AllocationCreateInfo
-            -> io (Image, Allocation, AllocationInfo)
-createImage allocator imageCreateInfo allocationCreateInfo = liftIO . evalContT $ do
-  pImageCreateInfo <- ContT $ withCStruct (imageCreateInfo)
-  pAllocationCreateInfo <- ContT $ withCStruct (allocationCreateInfo)
-  pPImage <- ContT $ bracket (callocBytes @Image 8) free
-  pPAllocation <- ContT $ bracket (callocBytes @Allocation 8) free
-  pPAllocationInfo <- ContT (withZeroCStruct @AllocationInfo)
-  r <- lift $ traceAroundEvent "vmaCreateImage" ((ffiVmaCreateImage) (allocator) (forgetExtensions pImageCreateInfo) pAllocationCreateInfo (pPImage) (pPAllocation) (pPAllocationInfo))
-  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
-  pImage <- lift $ peek @Image pPImage
-  pAllocation <- lift $ peek @Allocation pPAllocation
-  pAllocationInfo <- lift $ peekCStruct @AllocationInfo pPAllocationInfo
-  pure $ (pImage, pAllocation, pAllocationInfo)
-
--- | A convenience wrapper to make a compatible pair of calls to
--- 'createImage' and 'destroyImage'
---
--- To ensure that 'destroyImage' is always called: pass
--- 'Control.Exception.bracket' (or the allocate function from your
--- favourite resource management library) as the last argument.
--- To just extract the pair pass '(,)' as the last argument.
---
-withImage :: forall a io r . (Extendss ImageCreateInfo a, PokeChain a, MonadIO io) => Allocator -> ImageCreateInfo a -> AllocationCreateInfo -> (io (Image, Allocation, AllocationInfo) -> ((Image, Allocation, AllocationInfo) -> io ()) -> r) -> r
-withImage allocator pImageCreateInfo pAllocationCreateInfo b =
-  b (createImage allocator pImageCreateInfo pAllocationCreateInfo)
-    (\(o0, o1, _) -> destroyImage allocator o0 o1)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaCreateAliasingImage" ffiVmaCreateAliasingImage
-  :: Allocator -> Allocation -> Ptr (SomeStruct ImageCreateInfo) -> Ptr Image -> IO Result
-
--- | Function similar to 'createAliasingBuffer' but for images.
-createAliasingImage :: forall a io
-                     . (Extendss ImageCreateInfo a, PokeChain a, MonadIO io)
-                    => -- No documentation found for Nested "vmaCreateAliasingImage" "allocator"
-                       Allocator
-                    -> -- No documentation found for Nested "vmaCreateAliasingImage" "allocation"
-                       Allocation
-                    -> -- No documentation found for Nested "vmaCreateAliasingImage" "pImageCreateInfo"
-                       (ImageCreateInfo a)
-                    -> io (Image)
-createAliasingImage allocator allocation imageCreateInfo = liftIO . evalContT $ do
-  pImageCreateInfo <- ContT $ withCStruct (imageCreateInfo)
-  pPImage <- ContT $ bracket (callocBytes @Image 8) free
-  r <- lift $ traceAroundEvent "vmaCreateAliasingImage" ((ffiVmaCreateAliasingImage) (allocator) (allocation) (forgetExtensions pImageCreateInfo) (pPImage))
-  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
-  pImage <- lift $ peek @Image pPImage
-  pure $ (pImage)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaCreateAliasingImage2" ffiVmaCreateAliasingImage2
-  :: Allocator -> Allocation -> DeviceSize -> Ptr (SomeStruct ImageCreateInfo) -> Ptr Image -> IO Result
-
--- | Function similar to 'createAliasingBuffer2' but for images.
-createAliasingImage2 :: forall a io
-                      . (Extendss ImageCreateInfo a, PokeChain a, MonadIO io)
-                     => -- No documentation found for Nested "vmaCreateAliasingImage2" "allocator"
-                        Allocator
-                     -> -- No documentation found for Nested "vmaCreateAliasingImage2" "allocation"
-                        Allocation
-                     -> -- No documentation found for Nested "vmaCreateAliasingImage2" "allocationLocalOffset"
-                        ("allocationLocalOffset" ::: DeviceSize)
-                     -> -- No documentation found for Nested "vmaCreateAliasingImage2" "pImageCreateInfo"
-                        (ImageCreateInfo a)
-                     -> io (Image)
-createAliasingImage2 allocator allocation allocationLocalOffset imageCreateInfo = liftIO . evalContT $ do
-  pImageCreateInfo <- ContT $ withCStruct (imageCreateInfo)
-  pPImage <- ContT $ bracket (callocBytes @Image 8) free
-  r <- lift $ traceAroundEvent "vmaCreateAliasingImage2" ((ffiVmaCreateAliasingImage2) (allocator) (allocation) (allocationLocalOffset) (forgetExtensions pImageCreateInfo) (pPImage))
-  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
-  pImage <- lift $ peek @Image pPImage
-  pure $ (pImage)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaDestroyImage" ffiVmaDestroyImage
-  :: Allocator -> Image -> Allocation -> IO ()
-
--- | Destroys Vulkan image and frees allocated memory.
---
--- This is just a convenience function equivalent to:
---
--- > vkDestroyImage(device, image, allocationCallbacks);
--- > vmaFreeMemory(allocator, allocation);
---
--- It is safe to pass null as image and\/or allocation.
-destroyImage :: forall io
-              . (MonadIO io)
-             => -- No documentation found for Nested "vmaDestroyImage" "allocator"
-                Allocator
-             -> -- No documentation found for Nested "vmaDestroyImage" "image"
-                Image
-             -> -- No documentation found for Nested "vmaDestroyImage" "allocation"
-                Allocation
-             -> io ()
-destroyImage allocator image allocation = liftIO $ do
-  traceAroundEvent "vmaDestroyImage" ((ffiVmaDestroyImage) (allocator) (image) (allocation))
-  pure $ ()
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaCreateVirtualBlock" ffiVmaCreateVirtualBlock
-  :: Ptr VirtualBlockCreateInfo -> Ptr VirtualBlock -> IO Result
-
--- | Creates new 'VirtualBlock' object.
---
--- __Parameters__
---
--- +-----------+---------------+-----------------------------------------------+
--- |           | pCreateInfo   | Parameters for creation.                      |
--- +-----------+---------------+-----------------------------------------------+
--- | out       | pVirtualBlock | Returned virtual block object or @VMA_NULL@   |
--- |           |               | if creation failed.                           |
--- +-----------+---------------+-----------------------------------------------+
-createVirtualBlock :: forall io
-                    . (MonadIO io)
-                   => -- No documentation found for Nested "vmaCreateVirtualBlock" "pCreateInfo"
-                      VirtualBlockCreateInfo
-                   -> io (VirtualBlock)
-createVirtualBlock createInfo = liftIO . evalContT $ do
-  pCreateInfo <- ContT $ withCStruct (createInfo)
-  pPVirtualBlock <- ContT $ bracket (callocBytes @VirtualBlock 8) free
-  r <- lift $ traceAroundEvent "vmaCreateVirtualBlock" ((ffiVmaCreateVirtualBlock) pCreateInfo (pPVirtualBlock))
-  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
-  pVirtualBlock <- lift $ peek @VirtualBlock pPVirtualBlock
-  pure $ (pVirtualBlock)
-
--- | A convenience wrapper to make a compatible pair of calls to
--- 'createVirtualBlock' and 'destroyVirtualBlock'
---
--- To ensure that 'destroyVirtualBlock' is always called: pass
--- 'Control.Exception.bracket' (or the allocate function from your
--- favourite resource management library) as the last argument.
--- To just extract the pair pass '(,)' as the last argument.
---
-withVirtualBlock :: forall io r . MonadIO io => VirtualBlockCreateInfo -> (io VirtualBlock -> (VirtualBlock -> io ()) -> r) -> r
-withVirtualBlock pCreateInfo b =
-  b (createVirtualBlock pCreateInfo)
-    (\(o0) -> destroyVirtualBlock o0)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaDestroyVirtualBlock" ffiVmaDestroyVirtualBlock
-  :: VirtualBlock -> IO ()
-
--- | Destroys 'VirtualBlock' object.
---
--- Please note that you should consciously handle virtual allocations that
--- could remain unfreed in the block. You should either free them
--- individually using 'virtualFree' or call 'clearVirtualBlock' if you are
--- sure this is what you want. If you do neither, an assert is called.
---
--- If you keep pointers to some additional metadata associated with your
--- virtual allocations in their @pUserData@, don\'t forget to free them.
-destroyVirtualBlock :: forall io
-                     . (MonadIO io)
-                    => -- No documentation found for Nested "vmaDestroyVirtualBlock" "virtualBlock"
-                       VirtualBlock
-                    -> io ()
-destroyVirtualBlock virtualBlock = liftIO $ do
-  traceAroundEvent "vmaDestroyVirtualBlock" ((ffiVmaDestroyVirtualBlock) (virtualBlock))
-  pure $ ()
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaIsVirtualBlockEmpty" ffiVmaIsVirtualBlockEmpty
-  :: VirtualBlock -> IO Bool32
-
--- | Returns true of the 'VirtualBlock' is empty - contains 0 virtual
--- allocations and has all its space available for new allocations.
-isVirtualBlockEmpty :: forall io
-                     . (MonadIO io)
-                    => -- No documentation found for Nested "vmaIsVirtualBlockEmpty" "virtualBlock"
-                       VirtualBlock
-                    -> io (Bool)
-isVirtualBlockEmpty virtualBlock = liftIO $ do
-  r <- traceAroundEvent "vmaIsVirtualBlockEmpty" ((ffiVmaIsVirtualBlockEmpty) (virtualBlock))
-  pure $ ((bool32ToBool r))
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaGetVirtualAllocationInfo" ffiVmaGetVirtualAllocationInfo
-  :: VirtualBlock -> VirtualAllocation -> Ptr VirtualAllocationInfo -> IO ()
-
--- | Returns information about a specific virtual allocation within a virtual
--- block, like its size and @pUserData@ pointer.
-getVirtualAllocationInfo :: forall io
-                          . (MonadIO io)
-                         => -- No documentation found for Nested "vmaGetVirtualAllocationInfo" "virtualBlock"
-                            VirtualBlock
-                         -> -- No documentation found for Nested "vmaGetVirtualAllocationInfo" "allocation"
-                            VirtualAllocation
-                         -> io (("virtualAllocInfo" ::: VirtualAllocationInfo))
-getVirtualAllocationInfo virtualBlock allocation = liftIO . evalContT $ do
-  pPVirtualAllocInfo <- ContT (withZeroCStruct @VirtualAllocationInfo)
-  lift $ traceAroundEvent "vmaGetVirtualAllocationInfo" ((ffiVmaGetVirtualAllocationInfo) (virtualBlock) (allocation) (pPVirtualAllocInfo))
-  pVirtualAllocInfo <- lift $ peekCStruct @VirtualAllocationInfo pPVirtualAllocInfo
-  pure $ (pVirtualAllocInfo)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaVirtualAllocate" ffiVmaVirtualAllocate
-  :: VirtualBlock -> Ptr VirtualAllocationCreateInfo -> Ptr VirtualAllocation -> Ptr DeviceSize -> IO Result
-
--- | Allocates new virtual allocation inside given 'VirtualBlock'.
---
--- If the allocation fails due to not enough free space available,
--- @VK_ERROR_OUT_OF_DEVICE_MEMORY@ is returned (despite the function
--- doesn\'t ever allocate actual GPU memory). @pAllocation@ is then set to
--- @VK_NULL_HANDLE@ and @pOffset@, if not null, it set to @UINT64_MAX@.
---
--- __Parameters__
---
--- +-----------+--------------+-----------------------------------------------+
--- |           | virtualBlock | Virtual block                                 |
--- +-----------+--------------+-----------------------------------------------+
--- |           | pCreateInfo  | Parameters for the allocation                 |
--- +-----------+--------------+-----------------------------------------------+
--- | out       | pAllocation  | Returned handle of the new allocation         |
--- +-----------+--------------+-----------------------------------------------+
--- | out       | pOffset      | Returned offset of the new allocation.        |
--- |           |              | Optional, can be null.                        |
--- +-----------+--------------+-----------------------------------------------+
-virtualAllocate :: forall io
-                 . (MonadIO io)
-                => -- No documentation found for Nested "vmaVirtualAllocate" "virtualBlock"
-                   VirtualBlock
-                -> -- No documentation found for Nested "vmaVirtualAllocate" "pCreateInfo"
-                   VirtualAllocationCreateInfo
-                -> io (VirtualAllocation, ("offset" ::: DeviceSize))
-virtualAllocate virtualBlock createInfo = liftIO . evalContT $ do
-  pCreateInfo <- ContT $ withCStruct (createInfo)
-  pPAllocation <- ContT $ bracket (callocBytes @VirtualAllocation 8) free
-  pPOffset <- ContT $ bracket (callocBytes @DeviceSize 8) free
-  r <- lift $ traceAroundEvent "vmaVirtualAllocate" ((ffiVmaVirtualAllocate) (virtualBlock) pCreateInfo (pPAllocation) (pPOffset))
-  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
-  pAllocation <- lift $ peek @VirtualAllocation pPAllocation
-  pOffset <- lift $ peek @DeviceSize pPOffset
-  pure $ (pAllocation, pOffset)
-
--- | A convenience wrapper to make a compatible pair of calls to
--- 'virtualAllocate' and 'virtualFree'
---
--- To ensure that 'virtualFree' is always called: pass
--- 'Control.Exception.bracket' (or the allocate function from your
--- favourite resource management library) as the last argument.
--- To just extract the pair pass '(,)' as the last argument.
---
-withVirtualAllocation :: forall io r . MonadIO io => VirtualBlock -> VirtualAllocationCreateInfo -> (io (VirtualAllocation, DeviceSize) -> ((VirtualAllocation, DeviceSize) -> io ()) -> r) -> r
-withVirtualAllocation virtualBlock pCreateInfo b =
-  b (virtualAllocate virtualBlock pCreateInfo)
-    (\(o0, _) -> virtualFree virtualBlock o0)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaVirtualFree" ffiVmaVirtualFree
-  :: VirtualBlock -> VirtualAllocation -> IO ()
-
--- | Frees virtual allocation inside given 'VirtualBlock'.
---
--- It is correct to call this function with @allocation == VK_NULL_HANDLE@
--- - it does nothing.
-virtualFree :: forall io
-             . (MonadIO io)
-            => -- No documentation found for Nested "vmaVirtualFree" "virtualBlock"
-               VirtualBlock
-            -> -- No documentation found for Nested "vmaVirtualFree" "allocation"
-               VirtualAllocation
-            -> io ()
-virtualFree virtualBlock allocation = liftIO $ do
-  traceAroundEvent "vmaVirtualFree" ((ffiVmaVirtualFree) (virtualBlock) (allocation))
-  pure $ ()
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaClearVirtualBlock" ffiVmaClearVirtualBlock
-  :: VirtualBlock -> IO ()
-
--- | Frees all virtual allocations inside given 'VirtualBlock'.
---
--- You must either call this function or free each virtual allocation
--- individually with 'virtualFree' before destroying a virtual block.
--- Otherwise, an assert is called.
---
--- If you keep pointer to some additional metadata associated with your
--- virtual allocation in its @pUserData@, don\'t forget to free it as well.
-clearVirtualBlock :: forall io
-                   . (MonadIO io)
-                  => -- No documentation found for Nested "vmaClearVirtualBlock" "virtualBlock"
-                     VirtualBlock
-                  -> io ()
-clearVirtualBlock virtualBlock = liftIO $ do
-  traceAroundEvent "vmaClearVirtualBlock" ((ffiVmaClearVirtualBlock) (virtualBlock))
-  pure $ ()
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaSetVirtualAllocationUserData" ffiVmaSetVirtualAllocationUserData
-  :: VirtualBlock -> VirtualAllocation -> Ptr () -> IO ()
-
--- | Changes custom pointer associated with given virtual allocation.
-setVirtualAllocationUserData :: forall io
-                              . (MonadIO io)
-                             => -- No documentation found for Nested "vmaSetVirtualAllocationUserData" "virtualBlock"
-                                VirtualBlock
-                             -> -- No documentation found for Nested "vmaSetVirtualAllocationUserData" "allocation"
-                                VirtualAllocation
-                             -> -- No documentation found for Nested "vmaSetVirtualAllocationUserData" "pUserData"
-                                ("userData" ::: Ptr ())
-                             -> io ()
-setVirtualAllocationUserData virtualBlock allocation userData = liftIO $ do
-  traceAroundEvent "vmaSetVirtualAllocationUserData" ((ffiVmaSetVirtualAllocationUserData) (virtualBlock) (allocation) (userData))
-  pure $ ()
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaGetVirtualBlockStatistics" ffiVmaGetVirtualBlockStatistics
-  :: VirtualBlock -> Ptr Statistics -> IO ()
-
--- | Calculates and returns statistics about virtual allocations and memory
--- usage in given 'VirtualBlock'.
---
--- This function is fast to call. For more detailed statistics, see
--- 'calculateVirtualBlockStatistics'.
-getVirtualBlockStatistics :: forall io
-                           . (MonadIO io)
-                          => -- No documentation found for Nested "vmaGetVirtualBlockStatistics" "virtualBlock"
-                             VirtualBlock
-                          -> io (("stats" ::: Statistics))
-getVirtualBlockStatistics virtualBlock = liftIO . evalContT $ do
-  pPStats <- ContT (withZeroCStruct @Statistics)
-  lift $ traceAroundEvent "vmaGetVirtualBlockStatistics" ((ffiVmaGetVirtualBlockStatistics) (virtualBlock) (pPStats))
-  pStats <- lift $ peekCStruct @Statistics pPStats
-  pure $ (pStats)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaCalculateVirtualBlockStatistics" ffiVmaCalculateVirtualBlockStatistics
-  :: VirtualBlock -> Ptr DetailedStatistics -> IO ()
-
--- | Calculates and returns detailed statistics about virtual allocations and
--- memory usage in given 'VirtualBlock'.
---
--- This function is slow to call. Use for debugging purposes. For less
--- detailed statistics, see 'getVirtualBlockStatistics'.
-calculateVirtualBlockStatistics :: forall io
-                                 . (MonadIO io)
-                                => -- No documentation found for Nested "vmaCalculateVirtualBlockStatistics" "virtualBlock"
-                                   VirtualBlock
-                                -> io (("stats" ::: DetailedStatistics))
-calculateVirtualBlockStatistics virtualBlock = liftIO . evalContT $ do
-  pPStats <- ContT (withZeroCStruct @DetailedStatistics)
-  lift $ traceAroundEvent "vmaCalculateVirtualBlockStatistics" ((ffiVmaCalculateVirtualBlockStatistics) (virtualBlock) (pPStats))
-  pStats <- lift $ peekCStruct @DetailedStatistics pPStats
-  pure $ (pStats)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaBuildVirtualBlockStatsString" ffiVmaBuildVirtualBlockStatsString
-  :: VirtualBlock -> Ptr (Ptr CChar) -> Bool32 -> IO ()
-
--- | Builds and returns a null-terminated string in JSON format with
--- information about given 'VirtualBlock'.
---
--- __Parameters__
---
--- +-----------+---------------+-----------------------------------------------+
--- |           | virtualBlock  | Virtual block.                                |
--- +-----------+---------------+-----------------------------------------------+
--- | out       | ppStatsString | Returned string.                              |
--- +-----------+---------------+-----------------------------------------------+
--- |           | detailedMap   | Pass @VK_FALSE@ to only obtain statistics as  |
--- |           |               | returned by                                   |
--- |           |               | 'calculateVirtualBlockStatistics'. Pass       |
--- |           |               | @VK_TRUE@ to also obtain full list of         |
--- |           |               | allocations and free spaces.                  |
--- +-----------+---------------+-----------------------------------------------+
---
--- Returned string must be freed using 'freeVirtualBlockStatsString'.
-buildVirtualBlockStatsString :: forall io
-                              . (MonadIO io)
-                             => -- No documentation found for Nested "vmaBuildVirtualBlockStatsString" "virtualBlock"
-                                VirtualBlock
-                             -> -- No documentation found for Nested "vmaBuildVirtualBlockStatsString" "detailedMap"
-                                ("detailedMap" ::: Bool)
-                             -> io (("statsString" ::: Ptr CChar))
-buildVirtualBlockStatsString virtualBlock detailedMap = liftIO . evalContT $ do
-  pPpStatsString <- ContT $ bracket (callocBytes @(Ptr CChar) 8) free
-  lift $ traceAroundEvent "vmaBuildVirtualBlockStatsString" ((ffiVmaBuildVirtualBlockStatsString) (virtualBlock) (pPpStatsString) (boolToBool32 (detailedMap)))
-  ppStatsString <- lift $ peek @(Ptr CChar) pPpStatsString
-  pure $ (ppStatsString)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaFreeVirtualBlockStatsString" ffiVmaFreeVirtualBlockStatsString
-  :: VirtualBlock -> Ptr CChar -> IO ()
-
--- | Frees a string returned by 'buildVirtualBlockStatsString'.
-freeVirtualBlockStatsString :: forall io
-                             . (MonadIO io)
-                            => -- No documentation found for Nested "vmaFreeVirtualBlockStatsString" "virtualBlock"
-                               VirtualBlock
-                            -> -- No documentation found for Nested "vmaFreeVirtualBlockStatsString" "pStatsString"
-                               ("statsString" ::: Ptr CChar)
-                            -> io ()
-freeVirtualBlockStatsString virtualBlock statsString = liftIO $ do
-  traceAroundEvent "vmaFreeVirtualBlockStatsString" ((ffiVmaFreeVirtualBlockStatsString) (virtualBlock) (statsString))
-  pure $ ()
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaBuildStatsString" ffiVmaBuildStatsString
-  :: Allocator -> Ptr (Ptr CChar) -> Bool32 -> IO ()
-
--- | Builds and returns statistics as a null-terminated string in JSON
--- format.
---
--- __Parameters__
---
--- +-----------+---------------+-----------------------------------------------+
--- |           | allocator     |                                               |
--- +-----------+---------------+-----------------------------------------------+
--- | out       | ppStatsString | Must be freed using 'freeStatsString'         |
--- |           |               | function.                                     |
--- +-----------+---------------+-----------------------------------------------+
--- |           | detailedMap   |                                               |
--- +-----------+---------------+-----------------------------------------------+
-buildStatsString :: forall io
-                  . (MonadIO io)
-                 => -- No documentation found for Nested "vmaBuildStatsString" "allocator"
-                    Allocator
-                 -> -- No documentation found for Nested "vmaBuildStatsString" "detailedMap"
-                    ("detailedMap" ::: Bool)
-                 -> io (("statsString" ::: Ptr CChar))
-buildStatsString allocator detailedMap = liftIO . evalContT $ do
-  pPpStatsString <- ContT $ bracket (callocBytes @(Ptr CChar) 8) free
-  lift $ traceAroundEvent "vmaBuildStatsString" ((ffiVmaBuildStatsString) (allocator) (pPpStatsString) (boolToBool32 (detailedMap)))
-  ppStatsString <- lift $ peek @(Ptr CChar) pPpStatsString
-  pure $ (ppStatsString)
-
-
-foreign import ccall
-#if !defined(SAFE_FOREIGN_CALLS)
-  unsafe
-#endif
-  "vmaFreeStatsString" ffiVmaFreeStatsString
-  :: Allocator -> Ptr CChar -> IO ()
-
-
-freeStatsString :: forall io
-                 . (MonadIO io)
-                => -- No documentation found for Nested "vmaFreeStatsString" "allocator"
-                   Allocator
-                -> -- No documentation found for Nested "vmaFreeStatsString" "pStatsString"
-                   ("statsString" ::: Ptr CChar)
-                -> io ()
-freeStatsString allocator statsString = liftIO $ do
-  traceAroundEvent "vmaFreeStatsString" ((ffiVmaFreeStatsString) (allocator) (statsString))
-  pure $ ()
-
-
-type FN_vkAllocateMemory = Ptr Device_T -> ("pAllocateInfo" ::: Ptr (SomeStruct MemoryAllocateInfo)) -> ("pAllocator" ::: Ptr AllocationCallbacks) -> ("pMemory" ::: Ptr DeviceMemory) -> IO Result
--- No documentation found for TopLevel "PFN_vkAllocateMemory"
-type PFN_vkAllocateMemory = FunPtr FN_vkAllocateMemory
-
-
-type FN_vkBindBufferMemory = Ptr Device_T -> Buffer -> DeviceMemory -> ("memoryOffset" ::: DeviceSize) -> IO Result
--- No documentation found for TopLevel "PFN_vkBindBufferMemory"
-type PFN_vkBindBufferMemory = FunPtr FN_vkBindBufferMemory
-
-
-type FN_vkBindBufferMemory2KHR = Ptr Device_T -> ("bindInfoCount" ::: Word32) -> ("pBindInfos" ::: Ptr (SomeStruct BindBufferMemoryInfo)) -> IO Result
--- No documentation found for TopLevel "PFN_vkBindBufferMemory2KHR"
-type PFN_vkBindBufferMemory2KHR = FunPtr FN_vkBindBufferMemory2KHR
-
-
-type FN_vkBindImageMemory = Ptr Device_T -> Image -> DeviceMemory -> ("memoryOffset" ::: DeviceSize) -> IO Result
--- No documentation found for TopLevel "PFN_vkBindImageMemory"
-type PFN_vkBindImageMemory = FunPtr FN_vkBindImageMemory
-
-
-type FN_vkBindImageMemory2KHR = Ptr Device_T -> ("bindInfoCount" ::: Word32) -> ("pBindInfos" ::: Ptr (SomeStruct BindImageMemoryInfo)) -> IO Result
--- No documentation found for TopLevel "PFN_vkBindImageMemory2KHR"
-type PFN_vkBindImageMemory2KHR = FunPtr FN_vkBindImageMemory2KHR
-
-
-type FN_vkCmdCopyBuffer = Ptr CommandBuffer_T -> ("srcBuffer" ::: Buffer) -> ("dstBuffer" ::: Buffer) -> ("regionCount" ::: Word32) -> ("pRegions" ::: Ptr BufferCopy) -> IO ()
--- No documentation found for TopLevel "PFN_vkCmdCopyBuffer"
-type PFN_vkCmdCopyBuffer = FunPtr FN_vkCmdCopyBuffer
-
-
-type FN_vkCreateBuffer = Ptr Device_T -> ("pCreateInfo" ::: Ptr (SomeStruct BufferCreateInfo)) -> ("pAllocator" ::: Ptr AllocationCallbacks) -> ("pBuffer" ::: Ptr Buffer) -> IO Result
--- No documentation found for TopLevel "PFN_vkCreateBuffer"
-type PFN_vkCreateBuffer = FunPtr FN_vkCreateBuffer
-
-
-type FN_vkCreateImage = Ptr Device_T -> ("pCreateInfo" ::: Ptr (SomeStruct ImageCreateInfo)) -> ("pAllocator" ::: Ptr AllocationCallbacks) -> ("pImage" ::: Ptr Image) -> IO Result
--- No documentation found for TopLevel "PFN_vkCreateImage"
-type PFN_vkCreateImage = FunPtr FN_vkCreateImage
-
-
-type FN_vkDestroyBuffer = Ptr Device_T -> Buffer -> ("pAllocator" ::: Ptr AllocationCallbacks) -> IO ()
--- No documentation found for TopLevel "PFN_vkDestroyBuffer"
-type PFN_vkDestroyBuffer = FunPtr FN_vkDestroyBuffer
-
-
-type FN_vkDestroyImage = Ptr Device_T -> Image -> ("pAllocator" ::: Ptr AllocationCallbacks) -> IO ()
--- No documentation found for TopLevel "PFN_vkDestroyImage"
-type PFN_vkDestroyImage = FunPtr FN_vkDestroyImage
-
-
-type FN_vkFlushMappedMemoryRanges = Ptr Device_T -> ("memoryRangeCount" ::: Word32) -> ("pMemoryRanges" ::: Ptr MappedMemoryRange) -> IO Result
--- No documentation found for TopLevel "PFN_vkFlushMappedMemoryRanges"
-type PFN_vkFlushMappedMemoryRanges = FunPtr FN_vkFlushMappedMemoryRanges
-
-
-type FN_vkFreeMemory = Ptr Device_T -> DeviceMemory -> ("pAllocator" ::: Ptr AllocationCallbacks) -> IO ()
--- No documentation found for TopLevel "PFN_vkFreeMemory"
-type PFN_vkFreeMemory = FunPtr FN_vkFreeMemory
-
-
-type FN_vkGetBufferMemoryRequirements = Ptr Device_T -> Buffer -> ("pMemoryRequirements" ::: Ptr MemoryRequirements) -> IO ()
--- No documentation found for TopLevel "PFN_vkGetBufferMemoryRequirements"
-type PFN_vkGetBufferMemoryRequirements = FunPtr FN_vkGetBufferMemoryRequirements
-
-
-type FN_vkGetBufferMemoryRequirements2KHR = Ptr Device_T -> ("pInfo" ::: Ptr BufferMemoryRequirementsInfo2) -> ("pMemoryRequirements" ::: Ptr (SomeStruct MemoryRequirements2)) -> IO ()
--- No documentation found for TopLevel "PFN_vkGetBufferMemoryRequirements2KHR"
-type PFN_vkGetBufferMemoryRequirements2KHR = FunPtr FN_vkGetBufferMemoryRequirements2KHR
-
-
-type FN_vkGetImageMemoryRequirements = Ptr Device_T -> Image -> ("pMemoryRequirements" ::: Ptr MemoryRequirements) -> IO ()
--- No documentation found for TopLevel "PFN_vkGetImageMemoryRequirements"
-type PFN_vkGetImageMemoryRequirements = FunPtr FN_vkGetImageMemoryRequirements
-
-
-type FN_vkGetImageMemoryRequirements2KHR = Ptr Device_T -> ("pInfo" ::: Ptr (SomeStruct ImageMemoryRequirementsInfo2)) -> ("pMemoryRequirements" ::: Ptr (SomeStruct MemoryRequirements2)) -> IO ()
--- No documentation found for TopLevel "PFN_vkGetImageMemoryRequirements2KHR"
-type PFN_vkGetImageMemoryRequirements2KHR = FunPtr FN_vkGetImageMemoryRequirements2KHR
-
-
-type FN_vkGetPhysicalDeviceMemoryProperties = Ptr PhysicalDevice_T -> ("pMemoryProperties" ::: Ptr PhysicalDeviceMemoryProperties) -> IO ()
--- No documentation found for TopLevel "PFN_vkGetPhysicalDeviceMemoryProperties"
-type PFN_vkGetPhysicalDeviceMemoryProperties = FunPtr FN_vkGetPhysicalDeviceMemoryProperties
-
-
-type FN_vkGetPhysicalDeviceMemoryProperties2KHR = Ptr PhysicalDevice_T -> ("pMemoryProperties" ::: Ptr (SomeStruct PhysicalDeviceMemoryProperties2)) -> IO ()
--- No documentation found for TopLevel "PFN_vkGetPhysicalDeviceMemoryProperties2KHR"
-type PFN_vkGetPhysicalDeviceMemoryProperties2KHR = FunPtr FN_vkGetPhysicalDeviceMemoryProperties2KHR
-
-
-type FN_vkGetPhysicalDeviceProperties = Ptr PhysicalDevice_T -> ("pProperties" ::: Ptr PhysicalDeviceProperties) -> IO ()
--- No documentation found for TopLevel "PFN_vkGetPhysicalDeviceProperties"
-type PFN_vkGetPhysicalDeviceProperties = FunPtr FN_vkGetPhysicalDeviceProperties
-
-
-type FN_vkGetDeviceProcAddr = Ptr Device_T -> ("pName" ::: Ptr CChar) -> IO PFN_vkVoidFunction
--- No documentation found for TopLevel "PFN_vkGetDeviceProcAddr"
-type PFN_vkGetDeviceProcAddr = FunPtr FN_vkGetDeviceProcAddr
-
-
-type FN_vkGetInstanceProcAddr = Ptr Instance_T -> ("pName" ::: Ptr CChar) -> IO PFN_vkVoidFunction
--- No documentation found for TopLevel "PFN_vkGetInstanceProcAddr"
-type PFN_vkGetInstanceProcAddr = FunPtr FN_vkGetInstanceProcAddr
-
-
-type FN_vkInvalidateMappedMemoryRanges = Ptr Device_T -> ("memoryRangeCount" ::: Word32) -> ("pMemoryRanges" ::: Ptr MappedMemoryRange) -> IO Result
--- No documentation found for TopLevel "PFN_vkInvalidateMappedMemoryRanges"
-type PFN_vkInvalidateMappedMemoryRanges = FunPtr FN_vkInvalidateMappedMemoryRanges
-
-
-type FN_vkVoidFunction = IO ()
--- No documentation found for TopLevel "PFN_vkVoidFunction"
-type PFN_vkVoidFunction = FunPtr FN_vkVoidFunction
-
-
-type FN_vkMapMemory = Ptr Device_T -> DeviceMemory -> ("offset" ::: DeviceSize) -> DeviceSize -> MemoryMapFlags -> ("ppData" ::: Ptr (Ptr ())) -> IO Result
--- No documentation found for TopLevel "PFN_vkMapMemory"
-type PFN_vkMapMemory = FunPtr FN_vkMapMemory
-
-
-type FN_vkUnmapMemory = Ptr Device_T -> DeviceMemory -> IO ()
--- No documentation found for TopLevel "PFN_vkUnmapMemory"
-type PFN_vkUnmapMemory = FunPtr FN_vkUnmapMemory
-
-
-type AllocatorCreateFlags = AllocatorCreateFlagBits
-
--- | Flags for created 'Allocator'.
-newtype AllocatorCreateFlagBits = AllocatorCreateFlagBits Flags
-  deriving newtype (Eq, Ord, Storable, Zero, Bits, FiniteBits)
-
--- | Allocator and all objects created from it will not be synchronized
--- internally, so you must guarantee they are used from only one thread at
--- a time or synchronized externally by you.
---
--- Using this flag may increase performance because internal mutexes are
--- not used.
-pattern ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT    = AllocatorCreateFlagBits 0x00000001
--- | Enables usage of VK_KHR_dedicated_allocation extension.
---
--- The flag works only if /VmaAllocatorCreateInfo::vulkanApiVersion/
--- @== VK_API_VERSION_1_0@. When it is @VK_API_VERSION_1_1@, the flag is
--- ignored because the extension has been promoted to Vulkan 1.1.
---
--- Using this extension will automatically allocate dedicated blocks of
--- memory for some buffers and images instead of suballocating place for
--- them out of bigger memory blocks (as if you explicitly used
--- 'ALLOCATION_CREATE_DEDICATED_MEMORY_BIT' flag) when it is recommended by
--- the driver. It may improve performance on some GPUs.
---
--- You may set this flag only if you found out that following device
--- extensions are supported, you enabled them while creating Vulkan device
--- passed as /VmaAllocatorCreateInfo::device/, and you want them to be used
--- internally by this library:
---
--- -   VK_KHR_get_memory_requirements2 (device extension)
---
--- -   VK_KHR_dedicated_allocation (device extension)
---
--- When this flag is set, you can experience following warnings reported by
--- Vulkan validation layer. You can ignore them.
---
--- ‍vkBindBufferMemory(): Binding memory to buffer 0x2d but
--- vkGetBufferMemoryRequirements() has not been called on that buffer.
-pattern ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT   = AllocatorCreateFlagBits 0x00000002
--- | Enables usage of VK_KHR_bind_memory2 extension.
---
--- The flag works only if /VmaAllocatorCreateInfo::vulkanApiVersion/
--- @== VK_API_VERSION_1_0@. When it is @VK_API_VERSION_1_1@, the flag is
--- ignored because the extension has been promoted to Vulkan 1.1.
---
--- You may set this flag only if you found out that this device extension
--- is supported, you enabled it while creating Vulkan device passed as
--- /VmaAllocatorCreateInfo::device/, and you want it to be used internally
--- by this library.
---
--- The extension provides functions @vkBindBufferMemory2KHR@ and
--- @vkBindImageMemory2KHR@, which allow to pass a chain of @pNext@
--- structures while binding. This flag is required if you use @pNext@
--- parameter in 'bindBufferMemory2' or 'bindImageMemory2'.
-pattern ALLOCATOR_CREATE_KHR_BIND_MEMORY2_BIT           = AllocatorCreateFlagBits 0x00000004
--- | Enables usage of VK_EXT_memory_budget extension.
---
--- You may set this flag only if you found out that this device extension
--- is supported, you enabled it while creating Vulkan device passed as
--- /VmaAllocatorCreateInfo::device/, and you want it to be used internally
--- by this library, along with another instance extension
--- VK_KHR_get_physical_device_properties2, which is required by it (or
--- Vulkan 1.1, where this extension is promoted).
---
--- The extension provides query for current memory usage and budget, which
--- will probably be more accurate than an estimation used by the library
--- otherwise.
-pattern ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT          = AllocatorCreateFlagBits 0x00000008
--- | Enables usage of VK_AMD_device_coherent_memory extension.
---
--- You may set this flag only if you:
---
--- -   found out that this device extension is supported and enabled it
---     while creating Vulkan device passed as
---     /VmaAllocatorCreateInfo::device/,
---
--- -   checked that
---     @VkPhysicalDeviceCoherentMemoryFeaturesAMD::deviceCoherentMemory@ is
---     true and set it while creating the Vulkan device,
---
--- -   want it to be used internally by this library.
---
--- The extension and accompanying device feature provide access to memory
--- types with @VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD@ and
--- @VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD@ flags. They are useful
--- mostly for writing breadcrumb markers - a common method for debugging
--- GPU crash\/hang\/TDR.
---
--- When the extension is not enabled, such memory types are still
--- enumerated, but their usage is illegal. To protect from this error, if
--- you don\'t create the allocator with this flag, it will refuse to
--- allocate any memory or create a custom pool in such memory type,
--- returning @VK_ERROR_FEATURE_NOT_PRESENT@.
-pattern ALLOCATOR_CREATE_AMD_DEVICE_COHERENT_MEMORY_BIT = AllocatorCreateFlagBits 0x00000010
--- | Enables usage of \"buffer device address\" feature, which allows you to
--- use function @vkGetBufferDeviceAddress*@ to get raw GPU pointer to a
--- buffer and pass it for usage inside a shader.
---
--- You may set this flag only if you:
---
--- 1.  (For Vulkan version \< 1.2) Found as available and enabled device
---     extension VK_KHR_buffer_device_address. This extension is promoted
---     to core Vulkan 1.2.
---
--- 2.  Found as available and enabled device feature
---     @VkPhysicalDeviceBufferDeviceAddressFeatures::bufferDeviceAddress@.
---
--- When this flag is set, you can create buffers with
--- @VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT@ using VMA. The library
--- automatically adds @VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT@ to allocated
--- memory blocks wherever it might be needed.
---
--- For more information, see documentation chapter /Enabling buffer device
--- address/.
-pattern ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT      = AllocatorCreateFlagBits 0x00000020
--- | Enables usage of VK_EXT_memory_priority extension in the library.
---
--- You may set this flag only if you found available and enabled this
--- device extension, along with
--- @VkPhysicalDeviceMemoryPriorityFeaturesEXT::memoryPriority == VK_TRUE@,
--- while creating Vulkan device passed as /VmaAllocatorCreateInfo::device/.
---
--- When this flag is used, /VmaAllocationCreateInfo::priority/ and
--- /VmaPoolCreateInfo::priority/ are used to set priorities of allocated
--- Vulkan memory. Without it, these variables are ignored.
---
--- A priority must be a floating-point value between 0 and 1, indicating
--- the priority of the allocation relative to other memory allocations.
--- Larger values are higher priority. The granularity of the priorities is
--- implementation-dependent. It is automatically passed to every call to
--- @vkAllocateMemory@ done by the library using structure
--- @VkMemoryPriorityAllocateInfoEXT@. The value to be used for default
--- priority is 0.5. For more details, see the documentation of the
--- VK_EXT_memory_priority extension.
-pattern ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT        = AllocatorCreateFlagBits 0x00000040
-
-conNameAllocatorCreateFlagBits :: String
-conNameAllocatorCreateFlagBits = "AllocatorCreateFlagBits"
-
-enumPrefixAllocatorCreateFlagBits :: String
-enumPrefixAllocatorCreateFlagBits = "ALLOCATOR_CREATE_"
-
-showTableAllocatorCreateFlagBits :: [(AllocatorCreateFlagBits, String)]
-showTableAllocatorCreateFlagBits =
-  [ (ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT   , "EXTERNALLY_SYNCHRONIZED_BIT")
-  , (ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT  , "KHR_DEDICATED_ALLOCATION_BIT")
-  , (ALLOCATOR_CREATE_KHR_BIND_MEMORY2_BIT          , "KHR_BIND_MEMORY2_BIT")
-  , (ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT         , "EXT_MEMORY_BUDGET_BIT")
-  , (ALLOCATOR_CREATE_AMD_DEVICE_COHERENT_MEMORY_BIT, "AMD_DEVICE_COHERENT_MEMORY_BIT")
-  , (ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT     , "BUFFER_DEVICE_ADDRESS_BIT")
-  , (ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT       , "EXT_MEMORY_PRIORITY_BIT")
-  ]
-
-instance Show AllocatorCreateFlagBits where
-  showsPrec = enumShowsPrec enumPrefixAllocatorCreateFlagBits
-                            showTableAllocatorCreateFlagBits
-                            conNameAllocatorCreateFlagBits
-                            (\(AllocatorCreateFlagBits x) -> x)
-                            (\x -> showString "0x" . showHex x)
-
-instance Read AllocatorCreateFlagBits where
-  readPrec = enumReadPrec enumPrefixAllocatorCreateFlagBits
-                          showTableAllocatorCreateFlagBits
-                          conNameAllocatorCreateFlagBits
-                          AllocatorCreateFlagBits
-
-
--- | Intended usage of the allocated memory.
-newtype MemoryUsage = MemoryUsage Int32
-  deriving newtype (Eq, Ord, Storable, Zero)
-
--- | No intended memory usage specified. Use other members of
--- 'AllocationCreateInfo' to specify your requirements.
-pattern MEMORY_USAGE_UNKNOWN              = MemoryUsage 0
--- | /Deprecated/
---
--- Obsolete, preserved for backward compatibility. Prefers
--- @VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT@.
-pattern MEMORY_USAGE_GPU_ONLY             = MemoryUsage 1
--- | /Deprecated/
---
--- Obsolete, preserved for backward compatibility. Guarantees
--- @VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT@ and
--- @VK_MEMORY_PROPERTY_HOST_COHERENT_BIT@.
-pattern MEMORY_USAGE_CPU_ONLY             = MemoryUsage 2
--- | /Deprecated/
---
--- Obsolete, preserved for backward compatibility. Guarantees
--- @VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT@, prefers
--- @VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT@.
-pattern MEMORY_USAGE_CPU_TO_GPU           = MemoryUsage 3
--- | /Deprecated/
---
--- Obsolete, preserved for backward compatibility. Guarantees
--- @VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT@, prefers
--- @VK_MEMORY_PROPERTY_HOST_CACHED_BIT@.
-pattern MEMORY_USAGE_GPU_TO_CPU           = MemoryUsage 4
--- | /Deprecated/
---
--- Obsolete, preserved for backward compatibility. Prefers not
--- @VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT@.
-pattern MEMORY_USAGE_CPU_COPY             = MemoryUsage 5
--- | Lazily allocated GPU memory having
--- @VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT@. Exists mostly on mobile
--- platforms. Using it on desktop PC or other GPUs with no such memory type
--- present will fail the allocation.
---
--- Usage: Memory for transient attachment images (color attachments, depth
--- attachments etc.), created with
--- @VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT@.
---
--- Allocations with this usage are always created as dedicated - it implies
--- 'ALLOCATION_CREATE_DEDICATED_MEMORY_BIT'.
-pattern MEMORY_USAGE_GPU_LAZILY_ALLOCATED = MemoryUsage 6
--- | Selects best memory type automatically. This flag is recommended for
--- most common use cases.
---
--- When using this flag, if you want to map the allocation (using
--- 'mapMemory' or 'ALLOCATION_CREATE_MAPPED_BIT'), you must pass one of the
--- flags: 'ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT' or
--- 'ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT' in
--- /VmaAllocationCreateInfo::flags/.
---
--- It can be used only with functions that let the library know
--- @VkBufferCreateInfo@ or @VkImageCreateInfo@, e.g. 'createBuffer',
--- 'createImage', 'findMemoryTypeIndexForBufferInfo',
--- 'findMemoryTypeIndexForImageInfo' and not with generic memory allocation
--- functions.
-pattern MEMORY_USAGE_AUTO                 = MemoryUsage 7
--- | Selects best memory type automatically with preference for GPU (device)
--- memory.
---
--- When using this flag, if you want to map the allocation (using
--- 'mapMemory' or 'ALLOCATION_CREATE_MAPPED_BIT'), you must pass one of the
--- flags: 'ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT' or
--- 'ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT' in
--- /VmaAllocationCreateInfo::flags/.
---
--- It can be used only with functions that let the library know
--- @VkBufferCreateInfo@ or @VkImageCreateInfo@, e.g. 'createBuffer',
--- 'createImage', 'findMemoryTypeIndexForBufferInfo',
--- 'findMemoryTypeIndexForImageInfo' and not with generic memory allocation
--- functions.
-pattern MEMORY_USAGE_AUTO_PREFER_DEVICE   = MemoryUsage 8
--- | Selects best memory type automatically with preference for CPU (host)
--- memory.
---
--- When using this flag, if you want to map the allocation (using
--- 'mapMemory' or 'ALLOCATION_CREATE_MAPPED_BIT'), you must pass one of the
--- flags: 'ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT' or
--- 'ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT' in
--- /VmaAllocationCreateInfo::flags/.
---
--- It can be used only with functions that let the library know
--- @VkBufferCreateInfo@ or @VkImageCreateInfo@, e.g. 'createBuffer',
--- 'createImage', 'findMemoryTypeIndexForBufferInfo',
--- 'findMemoryTypeIndexForImageInfo' and not with generic memory allocation
--- functions.
-pattern MEMORY_USAGE_AUTO_PREFER_HOST     = MemoryUsage 9
-{-# complete MEMORY_USAGE_UNKNOWN,
-             MEMORY_USAGE_GPU_ONLY,
-             MEMORY_USAGE_CPU_ONLY,
-             MEMORY_USAGE_CPU_TO_GPU,
-             MEMORY_USAGE_GPU_TO_CPU,
-             MEMORY_USAGE_CPU_COPY,
-             MEMORY_USAGE_GPU_LAZILY_ALLOCATED,
-             MEMORY_USAGE_AUTO,
-             MEMORY_USAGE_AUTO_PREFER_DEVICE,
-             MEMORY_USAGE_AUTO_PREFER_HOST :: MemoryUsage #-}
-
-conNameMemoryUsage :: String
-conNameMemoryUsage = "MemoryUsage"
-
-enumPrefixMemoryUsage :: String
-enumPrefixMemoryUsage = "MEMORY_USAGE_"
-
-showTableMemoryUsage :: [(MemoryUsage, String)]
-showTableMemoryUsage =
-  [ (MEMORY_USAGE_UNKNOWN             , "UNKNOWN")
-  , (MEMORY_USAGE_GPU_ONLY            , "GPU_ONLY")
-  , (MEMORY_USAGE_CPU_ONLY            , "CPU_ONLY")
-  , (MEMORY_USAGE_CPU_TO_GPU          , "CPU_TO_GPU")
-  , (MEMORY_USAGE_GPU_TO_CPU          , "GPU_TO_CPU")
-  , (MEMORY_USAGE_CPU_COPY            , "CPU_COPY")
-  , (MEMORY_USAGE_GPU_LAZILY_ALLOCATED, "GPU_LAZILY_ALLOCATED")
-  , (MEMORY_USAGE_AUTO                , "AUTO")
-  , (MEMORY_USAGE_AUTO_PREFER_DEVICE  , "AUTO_PREFER_DEVICE")
-  , (MEMORY_USAGE_AUTO_PREFER_HOST    , "AUTO_PREFER_HOST")
-  ]
-
-instance Show MemoryUsage where
-  showsPrec =
-    enumShowsPrec enumPrefixMemoryUsage showTableMemoryUsage conNameMemoryUsage (\(MemoryUsage x) -> x) (showsPrec 11)
-
-instance Read MemoryUsage where
-  readPrec = enumReadPrec enumPrefixMemoryUsage showTableMemoryUsage conNameMemoryUsage MemoryUsage
-
-
-type AllocationCreateFlags = AllocationCreateFlagBits
-
--- | Flags to be passed as /VmaAllocationCreateInfo::flags/.
-newtype AllocationCreateFlagBits = AllocationCreateFlagBits Flags
-  deriving newtype (Eq, Ord, Storable, Zero, Bits, FiniteBits)
-
--- | Set this flag if the allocation should have its own memory block.
---
--- Use it for special, big resources, like fullscreen images used as
--- attachments.
-pattern ALLOCATION_CREATE_DEDICATED_MEMORY_BIT                   = AllocationCreateFlagBits 0x00000001
--- | Set this flag to only try to allocate from existing @VkDeviceMemory@
--- blocks and never create new such block.
---
--- If new allocation cannot be placed in any of the existing blocks,
--- allocation fails with @VK_ERROR_OUT_OF_DEVICE_MEMORY@ error.
---
--- You should not use 'ALLOCATION_CREATE_DEDICATED_MEMORY_BIT' and
--- 'ALLOCATION_CREATE_NEVER_ALLOCATE_BIT' at the same time. It makes no
--- sense.
-pattern ALLOCATION_CREATE_NEVER_ALLOCATE_BIT                     = AllocationCreateFlagBits 0x00000002
--- | Set this flag to use a memory that will be persistently mapped and
--- retrieve pointer to it.
---
--- Pointer to mapped memory will be returned through
--- /VmaAllocationInfo::pMappedData/.
---
--- It is valid to use this flag for allocation made from memory type that
--- is not @HOST_VISIBLE@. This flag is then ignored and memory is not
--- mapped. This is useful if you need an allocation that is efficient to
--- use on GPU (@DEVICE_LOCAL@) and still want to map it directly if
--- possible on platforms that support it (e.g. Intel GPU).
-pattern ALLOCATION_CREATE_MAPPED_BIT                             = AllocationCreateFlagBits 0x00000004
--- | /Deprecated/
---
--- Preserved for backward compatibility. Consider using 'setAllocationName'
--- instead.
---
--- Set this flag to treat /VmaAllocationCreateInfo::pUserData/ as pointer
--- to a null-terminated string. Instead of copying pointer value, a local
--- copy of the string is made and stored in allocation\'s @pName@. The
--- string is automatically freed together with the allocation. It is also
--- used in 'buildStatsString'.
-pattern ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT              = AllocationCreateFlagBits 0x00000020
--- | Allocation will be created from upper stack in a double stack pool.
---
--- This flag is only allowed for custom pools created with
--- 'POOL_CREATE_LINEAR_ALGORITHM_BIT' flag.
-pattern ALLOCATION_CREATE_UPPER_ADDRESS_BIT                      = AllocationCreateFlagBits 0x00000040
--- | Create both buffer\/image and allocation, but don\'t bind them together.
--- It is useful when you want to bind yourself to do some more advanced
--- binding, e.g. using some extensions. The flag is meaningful only with
--- functions that bind by default: 'createBuffer', 'createImage'. Otherwise
--- it is ignored.
---
--- If you want to make sure the new buffer\/image is not tied to the new
--- memory allocation through @VkMemoryDedicatedAllocateInfoKHR@ structure
--- in case the allocation ends up in its own memory block, use also flag
--- 'ALLOCATION_CREATE_CAN_ALIAS_BIT'.
-pattern ALLOCATION_CREATE_DONT_BIND_BIT                          = AllocationCreateFlagBits 0x00000080
--- | Create allocation only if additional device memory required for it, if
--- any, won\'t exceed memory budget. Otherwise return
--- @VK_ERROR_OUT_OF_DEVICE_MEMORY@.
-pattern ALLOCATION_CREATE_WITHIN_BUDGET_BIT                      = AllocationCreateFlagBits 0x00000100
--- | Set this flag if the allocated memory will have aliasing resources.
---
--- Usage of this flag prevents supplying @VkMemoryDedicatedAllocateInfoKHR@
--- when 'ALLOCATION_CREATE_DEDICATED_MEMORY_BIT' is specified. Otherwise
--- created dedicated memory will not be suitable for aliasing resources,
--- resulting in Vulkan Validation Layer errors.
-pattern ALLOCATION_CREATE_CAN_ALIAS_BIT                          = AllocationCreateFlagBits 0x00000200
--- | Requests possibility to map the allocation (using 'mapMemory' or
--- 'ALLOCATION_CREATE_MAPPED_BIT').
---
--- -   If you use 'MEMORY_USAGE_AUTO' or other @VMA_MEMORY_USAGE_AUTO*@
---     value, you must use this flag to be able to map the allocation.
---     Otherwise, mapping is incorrect.
---
--- -   If you use other value of 'MemoryUsage', this flag is ignored and
---     mapping is always possible in memory types that are @HOST_VISIBLE@.
---     This includes allocations created in /Custom memory pools/.
---
--- Declares that mapped memory will only be written sequentially, e.g.
--- using @memcpy()@ or a loop writing number-by-number, never read or
--- accessed randomly, so a memory type can be selected that is uncached and
--- write-combined.
---
--- Warning
---
--- Violating this declaration may work correctly, but will likely be very
--- slow. Watch out for implicit reads introduced by doing e.g.
--- @pMappedData[i] += x;@ Better prepare your data in a local variable and
--- @memcpy()@ it to the mapped pointer all at once.
-pattern ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT       = AllocationCreateFlagBits 0x00000400
--- | Requests possibility to map the allocation (using 'mapMemory' or
--- 'ALLOCATION_CREATE_MAPPED_BIT').
---
--- -   If you use 'MEMORY_USAGE_AUTO' or other @VMA_MEMORY_USAGE_AUTO*@
---     value, you must use this flag to be able to map the allocation.
---     Otherwise, mapping is incorrect.
---
--- -   If you use other value of 'MemoryUsage', this flag is ignored and
---     mapping is always possible in memory types that are @HOST_VISIBLE@.
---     This includes allocations created in /Custom memory pools/.
---
--- Declares that mapped memory can be read, written, and accessed in random
--- order, so a @HOST_CACHED@ memory type is required.
-pattern ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT                 = AllocationCreateFlagBits 0x00000800
--- | Together with 'ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT' or
--- 'ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT', it says that despite request
--- for host access, a not-@HOST_VISIBLE@ memory type can be selected if it
--- may improve performance.
---
--- By using this flag, you declare that you will check if the allocation
--- ended up in a @HOST_VISIBLE@ memory type (e.g. using
--- 'getAllocationMemoryProperties') and if not, you will create some
--- \"staging\" buffer and issue an explicit transfer to write\/read your
--- data. To prepare for this possibility, don\'t forget to add appropriate
--- flags like @VK_BUFFER_USAGE_TRANSFER_DST_BIT@,
--- @VK_BUFFER_USAGE_TRANSFER_SRC_BIT@ to the parameters of created buffer
--- or image.
-pattern ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT = AllocationCreateFlagBits 0x00001000
--- | Allocation strategy that chooses smallest possible free range for the
--- allocation to minimize memory usage and fragmentation, possibly at the
--- expense of allocation time.
-pattern ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT                = AllocationCreateFlagBits 0x00010000
--- | Allocation strategy that chooses first suitable free range for the
--- allocation - not necessarily in terms of the smallest offset but the one
--- that is easiest and fastest to find to minimize allocation time,
--- possibly at the expense of allocation quality.
-pattern ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT                  = AllocationCreateFlagBits 0x00020000
--- | Allocation strategy that chooses always the lowest offset in available
--- space. This is not the most efficient strategy but achieves highly
--- packed data. Used internally by defragmentation, not recommended in
--- typical usage.
-pattern ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT                = AllocationCreateFlagBits 0x00040000
--- | Alias to 'ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT'.
-pattern ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT                  = AllocationCreateFlagBits 0x00010000
--- | Alias to 'ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT'.
-pattern ALLOCATION_CREATE_STRATEGY_FIRST_FIT_BIT                 = AllocationCreateFlagBits 0x00020000
--- | A bit mask to extract only @STRATEGY@ bits from entire set of flags.
-pattern ALLOCATION_CREATE_STRATEGY_MASK                          = AllocationCreateFlagBits 0x00070000
-
-conNameAllocationCreateFlagBits :: String
-conNameAllocationCreateFlagBits = "AllocationCreateFlagBits"
-
-enumPrefixAllocationCreateFlagBits :: String
-enumPrefixAllocationCreateFlagBits = "ALLOCATION_CREATE_"
-
-showTableAllocationCreateFlagBits :: [(AllocationCreateFlagBits, String)]
-showTableAllocationCreateFlagBits =
-  [ (ALLOCATION_CREATE_DEDICATED_MEMORY_BIT                  , "DEDICATED_MEMORY_BIT")
-  , (ALLOCATION_CREATE_NEVER_ALLOCATE_BIT                    , "NEVER_ALLOCATE_BIT")
-  , (ALLOCATION_CREATE_MAPPED_BIT                            , "MAPPED_BIT")
-  , (ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT             , "USER_DATA_COPY_STRING_BIT")
-  , (ALLOCATION_CREATE_UPPER_ADDRESS_BIT                     , "UPPER_ADDRESS_BIT")
-  , (ALLOCATION_CREATE_DONT_BIND_BIT                         , "DONT_BIND_BIT")
-  , (ALLOCATION_CREATE_WITHIN_BUDGET_BIT                     , "WITHIN_BUDGET_BIT")
-  , (ALLOCATION_CREATE_CAN_ALIAS_BIT                         , "CAN_ALIAS_BIT")
-  , (ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT      , "HOST_ACCESS_SEQUENTIAL_WRITE_BIT")
-  , (ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT                , "HOST_ACCESS_RANDOM_BIT")
-  , (ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT, "HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT")
-  , (ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT               , "STRATEGY_MIN_MEMORY_BIT")
-  , (ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT                 , "STRATEGY_MIN_TIME_BIT")
-  , (ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT               , "STRATEGY_MIN_OFFSET_BIT")
-  , (ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT                 , "STRATEGY_BEST_FIT_BIT")
-  , (ALLOCATION_CREATE_STRATEGY_FIRST_FIT_BIT                , "STRATEGY_FIRST_FIT_BIT")
-  , (ALLOCATION_CREATE_STRATEGY_MASK                         , "STRATEGY_MASK")
-  ]
-
-instance Show AllocationCreateFlagBits where
-  showsPrec = enumShowsPrec enumPrefixAllocationCreateFlagBits
-                            showTableAllocationCreateFlagBits
-                            conNameAllocationCreateFlagBits
-                            (\(AllocationCreateFlagBits x) -> x)
-                            (\x -> showString "0x" . showHex x)
-
-instance Read AllocationCreateFlagBits where
-  readPrec = enumReadPrec enumPrefixAllocationCreateFlagBits
-                          showTableAllocationCreateFlagBits
-                          conNameAllocationCreateFlagBits
-                          AllocationCreateFlagBits
-
-
-type PoolCreateFlags = PoolCreateFlagBits
-
--- | Flags to be passed as /VmaPoolCreateInfo::flags/.
-newtype PoolCreateFlagBits = PoolCreateFlagBits Flags
-  deriving newtype (Eq, Ord, Storable, Zero, Bits, FiniteBits)
-
--- | Use this flag if you always allocate only buffers and linear images or
--- only optimal images out of this pool and so Buffer-Image Granularity can
--- be ignored.
---
--- This is an optional optimization flag.
---
--- If you always allocate using 'createBuffer', 'createImage',
--- 'allocateMemoryForBuffer', then you don\'t need to use it because
--- allocator knows exact type of your allocations so it can handle
--- Buffer-Image Granularity in the optimal way.
---
--- If you also allocate using 'allocateMemoryForImage' or 'allocateMemory',
--- exact type of such allocations is not known, so allocator must be
--- conservative in handling Buffer-Image Granularity, which can lead to
--- suboptimal allocation (wasted memory). In that case, if you can make
--- sure you always allocate only buffers and linear images or only optimal
--- images out of this pool, use this flag to make allocator disregard
--- Buffer-Image Granularity and so make allocations faster and more
--- optimal.
-pattern POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT = PoolCreateFlagBits 0x00000002
--- | Enables alternative, linear allocation algorithm in this pool.
---
--- Specify this flag to enable linear allocation algorithm, which always
--- creates new allocations after last one and doesn\'t reuse space from
--- allocations freed in between. It trades memory consumption for
--- simplified algorithm and data structure, which has better performance
--- and uses less memory for metadata.
---
--- By using this flag, you can achieve behavior of free-at-once, stack,
--- ring buffer, and double stack. For details, see documentation chapter
--- /Linear allocation algorithm/.
-pattern POOL_CREATE_LINEAR_ALGORITHM_BIT                = PoolCreateFlagBits 0x00000004
--- | Bit mask to extract only @ALGORITHM@ bits from entire set of flags.
-pattern POOL_CREATE_ALGORITHM_MASK                      = PoolCreateFlagBits 0x00000004
-
-conNamePoolCreateFlagBits :: String
-conNamePoolCreateFlagBits = "PoolCreateFlagBits"
-
-enumPrefixPoolCreateFlagBits :: String
-enumPrefixPoolCreateFlagBits = "POOL_CREATE_"
-
-showTablePoolCreateFlagBits :: [(PoolCreateFlagBits, String)]
-showTablePoolCreateFlagBits =
-  [ (POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT, "IGNORE_BUFFER_IMAGE_GRANULARITY_BIT")
-  , (POOL_CREATE_LINEAR_ALGORITHM_BIT               , "LINEAR_ALGORITHM_BIT")
-  , (POOL_CREATE_ALGORITHM_MASK                     , "ALGORITHM_MASK")
-  ]
-
-instance Show PoolCreateFlagBits where
-  showsPrec = enumShowsPrec enumPrefixPoolCreateFlagBits
-                            showTablePoolCreateFlagBits
-                            conNamePoolCreateFlagBits
-                            (\(PoolCreateFlagBits x) -> x)
-                            (\x -> showString "0x" . showHex x)
-
-instance Read PoolCreateFlagBits where
-  readPrec =
-    enumReadPrec enumPrefixPoolCreateFlagBits showTablePoolCreateFlagBits conNamePoolCreateFlagBits PoolCreateFlagBits
-
-
-type DefragmentationFlags = DefragmentationFlagBits
-
--- | Flags to be passed as /VmaDefragmentationInfo::flags/.
-newtype DefragmentationFlagBits = DefragmentationFlagBits Flags
-  deriving newtype (Eq, Ord, Storable, Zero, Bits, FiniteBits)
-
-
-pattern DEFRAGMENTATION_FLAG_ALGORITHM_FAST_BIT      = DefragmentationFlagBits 0x00000001
-
-pattern DEFRAGMENTATION_FLAG_ALGORITHM_BALANCED_BIT  = DefragmentationFlagBits 0x00000002
-
-pattern DEFRAGMENTATION_FLAG_ALGORITHM_FULL_BIT      = DefragmentationFlagBits 0x00000004
--- | Use the most roboust algorithm at the cost of time to compute and number
--- of copies to make. Only available when bufferImageGranularity is greater
--- than 1, since it aims to reduce alignment issues between different types
--- of resources. Otherwise falls back to same behavior as
--- 'DEFRAGMENTATION_FLAG_ALGORITHM_FULL_BIT'.
-pattern DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT = DefragmentationFlagBits 0x00000008
--- | A bit mask to extract only @ALGORITHM@ bits from entire set of flags.
-pattern DEFRAGMENTATION_FLAG_ALGORITHM_MASK          = DefragmentationFlagBits 0x0000000f
-
-conNameDefragmentationFlagBits :: String
-conNameDefragmentationFlagBits = "DefragmentationFlagBits"
-
-enumPrefixDefragmentationFlagBits :: String
-enumPrefixDefragmentationFlagBits = "DEFRAGMENTATION_FLAG_ALGORITHM_"
-
-showTableDefragmentationFlagBits :: [(DefragmentationFlagBits, String)]
-showTableDefragmentationFlagBits =
-  [ (DEFRAGMENTATION_FLAG_ALGORITHM_FAST_BIT     , "FAST_BIT")
-  , (DEFRAGMENTATION_FLAG_ALGORITHM_BALANCED_BIT , "BALANCED_BIT")
-  , (DEFRAGMENTATION_FLAG_ALGORITHM_FULL_BIT     , "FULL_BIT")
-  , (DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT, "EXTENSIVE_BIT")
-  , (DEFRAGMENTATION_FLAG_ALGORITHM_MASK         , "MASK")
-  ]
-
-instance Show DefragmentationFlagBits where
-  showsPrec = enumShowsPrec enumPrefixDefragmentationFlagBits
-                            showTableDefragmentationFlagBits
-                            conNameDefragmentationFlagBits
-                            (\(DefragmentationFlagBits x) -> x)
-                            (\x -> showString "0x" . showHex x)
-
-instance Read DefragmentationFlagBits where
-  readPrec = enumReadPrec enumPrefixDefragmentationFlagBits
-                          showTableDefragmentationFlagBits
-                          conNameDefragmentationFlagBits
-                          DefragmentationFlagBits
-
-
--- | Operation performed on single defragmentation move. See structure
--- 'DefragmentationMove'.
-newtype DefragmentationMoveOperation = DefragmentationMoveOperation Int32
-  deriving newtype (Eq, Ord, Storable, Zero)
-
--- | Buffer\/image has been recreated at @dstTmpAllocation@, data has been
--- copied, old buffer\/image has been destroyed. @srcAllocation@ should be
--- changed to point to the new place. This is the default value set by
--- 'beginDefragmentationPass'.
-pattern DEFRAGMENTATION_MOVE_OPERATION_COPY    = DefragmentationMoveOperation 0
--- | Set this value if you cannot move the allocation. New place reserved at
--- @dstTmpAllocation@ will be freed. @srcAllocation@ will remain unchanged.
-pattern DEFRAGMENTATION_MOVE_OPERATION_IGNORE  = DefragmentationMoveOperation 1
--- | Set this value if you decide to abandon the allocation and you destroyed
--- the buffer\/image. New place reserved at @dstTmpAllocation@ will be
--- freed, along with @srcAllocation@, which will be destroyed.
-pattern DEFRAGMENTATION_MOVE_OPERATION_DESTROY = DefragmentationMoveOperation 2
-{-# complete DEFRAGMENTATION_MOVE_OPERATION_COPY,
-             DEFRAGMENTATION_MOVE_OPERATION_IGNORE,
-             DEFRAGMENTATION_MOVE_OPERATION_DESTROY :: DefragmentationMoveOperation #-}
-
-conNameDefragmentationMoveOperation :: String
-conNameDefragmentationMoveOperation = "DefragmentationMoveOperation"
-
-enumPrefixDefragmentationMoveOperation :: String
-enumPrefixDefragmentationMoveOperation = "DEFRAGMENTATION_MOVE_OPERATION_"
-
-showTableDefragmentationMoveOperation :: [(DefragmentationMoveOperation, String)]
-showTableDefragmentationMoveOperation =
-  [ (DEFRAGMENTATION_MOVE_OPERATION_COPY   , "COPY")
-  , (DEFRAGMENTATION_MOVE_OPERATION_IGNORE , "IGNORE")
-  , (DEFRAGMENTATION_MOVE_OPERATION_DESTROY, "DESTROY")
-  ]
-
-instance Show DefragmentationMoveOperation where
-  showsPrec = enumShowsPrec enumPrefixDefragmentationMoveOperation
-                            showTableDefragmentationMoveOperation
-                            conNameDefragmentationMoveOperation
-                            (\(DefragmentationMoveOperation x) -> x)
-                            (showsPrec 11)
-
-instance Read DefragmentationMoveOperation where
-  readPrec = enumReadPrec enumPrefixDefragmentationMoveOperation
-                          showTableDefragmentationMoveOperation
-                          conNameDefragmentationMoveOperation
-                          DefragmentationMoveOperation
-
-
-type VirtualBlockCreateFlags = VirtualBlockCreateFlagBits
-
--- | Flags to be passed as /VmaVirtualBlockCreateInfo::flags/.
-newtype VirtualBlockCreateFlagBits = VirtualBlockCreateFlagBits Flags
-  deriving newtype (Eq, Ord, Storable, Zero, Bits, FiniteBits)
-
--- | Enables alternative, linear allocation algorithm in this virtual block.
---
--- Specify this flag to enable linear allocation algorithm, which always
--- creates new allocations after last one and doesn\'t reuse space from
--- allocations freed in between. It trades memory consumption for
--- simplified algorithm and data structure, which has better performance
--- and uses less memory for metadata.
---
--- By using this flag, you can achieve behavior of free-at-once, stack,
--- ring buffer, and double stack. For details, see documentation chapter
--- /Linear allocation algorithm/.
-pattern VIRTUAL_BLOCK_CREATE_LINEAR_ALGORITHM_BIT = VirtualBlockCreateFlagBits 0x00000001
--- | Bit mask to extract only @ALGORITHM@ bits from entire set of flags.
-pattern VIRTUAL_BLOCK_CREATE_ALGORITHM_MASK       = VirtualBlockCreateFlagBits 0x00000001
-
-conNameVirtualBlockCreateFlagBits :: String
-conNameVirtualBlockCreateFlagBits = "VirtualBlockCreateFlagBits"
-
-enumPrefixVirtualBlockCreateFlagBits :: String
-enumPrefixVirtualBlockCreateFlagBits = "VIRTUAL_BLOCK_CREATE_"
-
-showTableVirtualBlockCreateFlagBits :: [(VirtualBlockCreateFlagBits, String)]
-showTableVirtualBlockCreateFlagBits =
-  [ (VIRTUAL_BLOCK_CREATE_LINEAR_ALGORITHM_BIT, "LINEAR_ALGORITHM_BIT")
-  , (VIRTUAL_BLOCK_CREATE_ALGORITHM_MASK      , "ALGORITHM_MASK")
-  ]
-
-instance Show VirtualBlockCreateFlagBits where
-  showsPrec = enumShowsPrec enumPrefixVirtualBlockCreateFlagBits
-                            showTableVirtualBlockCreateFlagBits
-                            conNameVirtualBlockCreateFlagBits
-                            (\(VirtualBlockCreateFlagBits x) -> x)
-                            (\x -> showString "0x" . showHex x)
-
-instance Read VirtualBlockCreateFlagBits where
-  readPrec = enumReadPrec enumPrefixVirtualBlockCreateFlagBits
-                          showTableVirtualBlockCreateFlagBits
-                          conNameVirtualBlockCreateFlagBits
-                          VirtualBlockCreateFlagBits
-
-
-type VirtualAllocationCreateFlags = VirtualAllocationCreateFlagBits
-
--- | Flags to be passed as /VmaVirtualAllocationCreateInfo::flags/.
-newtype VirtualAllocationCreateFlagBits = VirtualAllocationCreateFlagBits Flags
-  deriving newtype (Eq, Ord, Storable, Zero, Bits, FiniteBits)
-
--- | Allocation will be created from upper stack in a double stack pool.
---
--- This flag is only allowed for virtual blocks created with
--- 'VIRTUAL_BLOCK_CREATE_LINEAR_ALGORITHM_BIT' flag.
-pattern VIRTUAL_ALLOCATION_CREATE_UPPER_ADDRESS_BIT       = VirtualAllocationCreateFlagBits 0x00000040
--- | Allocation strategy that tries to minimize memory usage.
-pattern VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT = VirtualAllocationCreateFlagBits 0x00010000
--- | Allocation strategy that tries to minimize allocation time.
-pattern VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT   = VirtualAllocationCreateFlagBits 0x00020000
--- | Allocation strategy that chooses always the lowest offset in available
--- space. This is not the most efficient strategy but achieves highly
--- packed data.
-pattern VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT = VirtualAllocationCreateFlagBits 0x00040000
--- | A bit mask to extract only @STRATEGY@ bits from entire set of flags.
---
--- These strategy flags are binary compatible with equivalent flags in
--- 'AllocationCreateFlagBits'.
-pattern VIRTUAL_ALLOCATION_CREATE_STRATEGY_MASK           = VirtualAllocationCreateFlagBits 0x00070000
-
-conNameVirtualAllocationCreateFlagBits :: String
-conNameVirtualAllocationCreateFlagBits = "VirtualAllocationCreateFlagBits"
-
-enumPrefixVirtualAllocationCreateFlagBits :: String
-enumPrefixVirtualAllocationCreateFlagBits = "VIRTUAL_ALLOCATION_CREATE_"
-
-showTableVirtualAllocationCreateFlagBits :: [(VirtualAllocationCreateFlagBits, String)]
-showTableVirtualAllocationCreateFlagBits =
-  [ (VIRTUAL_ALLOCATION_CREATE_UPPER_ADDRESS_BIT      , "UPPER_ADDRESS_BIT")
-  , (VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT, "STRATEGY_MIN_MEMORY_BIT")
-  , (VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT  , "STRATEGY_MIN_TIME_BIT")
-  , (VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT, "STRATEGY_MIN_OFFSET_BIT")
-  , (VIRTUAL_ALLOCATION_CREATE_STRATEGY_MASK          , "STRATEGY_MASK")
-  ]
-
-instance Show VirtualAllocationCreateFlagBits where
-  showsPrec = enumShowsPrec enumPrefixVirtualAllocationCreateFlagBits
-                            showTableVirtualAllocationCreateFlagBits
-                            conNameVirtualAllocationCreateFlagBits
-                            (\(VirtualAllocationCreateFlagBits x) -> x)
-                            (\x -> showString "0x" . showHex x)
-
-instance Read VirtualAllocationCreateFlagBits where
-  readPrec = enumReadPrec enumPrefixVirtualAllocationCreateFlagBits
-                          showTableVirtualAllocationCreateFlagBits
-                          conNameVirtualAllocationCreateFlagBits
-                          VirtualAllocationCreateFlagBits
-
-
--- | VmaAllocator
---
--- Represents main object of this library initialized.
---
--- Fill structure 'AllocatorCreateInfo' and call function 'createAllocator'
--- to create it. Call function 'destroyAllocator' to destroy it.
---
--- It is recommended to create just one object of this type per @VkDevice@
--- object, right after Vulkan is initialized and keep it alive until before
--- Vulkan device is destroyed.
-newtype Allocator = Allocator Word64
-  deriving newtype (Eq, Ord, Storable, Zero)
-  deriving anyclass (IsHandle)
-instance Show Allocator where
-  showsPrec p (Allocator x) = showParen (p >= 11) (showString "Allocator 0x" . showHex x)
-
-
--- | VmaPool
---
--- Represents custom memory pool.
---
--- Fill structure 'PoolCreateInfo' and call function 'createPool' to create
--- it. Call function 'destroyPool' to destroy it.
---
--- For more information see /Custom memory pools/.
-newtype Pool = Pool Word64
-  deriving newtype (Eq, Ord, Storable, Zero)
-  deriving anyclass (IsHandle)
-instance Show Pool where
-  showsPrec p (Pool x) = showParen (p >= 11) (showString "Pool 0x" . showHex x)
-
-
--- | VmaAllocation
---
--- Represents single memory allocation.
---
--- It may be either dedicated block of @VkDeviceMemory@ or a specific
--- region of a bigger block of this type plus unique offset.
---
--- There are multiple ways to create such object. You need to fill
--- structure 'AllocationCreateInfo'. For more information see /Choosing
--- memory type/.
---
--- Although the library provides convenience functions that create Vulkan
--- buffer or image, allocate memory for it and bind them together, binding
--- of the allocation to a buffer or an image is out of scope of the
--- allocation itself. Allocation object can exist without buffer\/image
--- bound, binding can be done manually by the user, and destruction of it
--- can be done independently of destruction of the allocation.
---
--- The object also remembers its size and some other information. To
--- retrieve this information, use function 'getAllocationInfo' and inspect
--- returned structure 'AllocationInfo'.
-newtype Allocation = Allocation Word64
-  deriving newtype (Eq, Ord, Storable, Zero)
-  deriving anyclass (IsHandle)
-instance Show Allocation where
-  showsPrec p (Allocation x) = showParen (p >= 11) (showString "Allocation 0x" . showHex x)
-
-
--- | VmaDefragmentationContext
---
--- An opaque object that represents started defragmentation process.
---
--- Fill structure 'DefragmentationInfo' and call function
--- 'beginDefragmentation' to create it. Call function 'endDefragmentation'
--- to destroy it.
-newtype DefragmentationContext = DefragmentationContext Word64
-  deriving newtype (Eq, Ord, Storable, Zero)
-  deriving anyclass (IsHandle)
-instance Show DefragmentationContext where
-  showsPrec p (DefragmentationContext x) = showParen (p >= 11) (showString "DefragmentationContext 0x" . showHex x)
-
-
--- | VmaVirtualAllocation
---
--- Represents single memory allocation done inside 'VirtualBlock'.
---
--- Use it as a unique identifier to virtual allocation within the single
--- block.
---
--- Use value @VK_NULL_HANDLE@ to represent a null\/invalid allocation.
-newtype VirtualAllocation = VirtualAllocation Word64
-  deriving newtype (Eq, Ord, Storable, Zero)
-  deriving anyclass (IsHandle)
-instance Show VirtualAllocation where
-  showsPrec p (VirtualAllocation x) = showParen (p >= 11) (showString "VirtualAllocation 0x" . showHex x)
-
-
--- | VmaVirtualBlock
---
--- Handle to a virtual block object that allows to use core allocation
--- algorithm without allocating any real GPU memory.
---
--- Fill in 'VirtualBlockCreateInfo' structure and use 'createVirtualBlock'
--- to create it. Use 'destroyVirtualBlock' to destroy it. For more
--- information, see documentation chapter /Virtual allocator/.
---
--- This object is not thread-safe - should not be used from multiple
--- threads simultaneously, must be synchronized externally.
-newtype VirtualBlock = VirtualBlock Word64
-  deriving newtype (Eq, Ord, Storable, Zero)
-  deriving anyclass (IsHandle)
-instance Show VirtualBlock where
-  showsPrec p (VirtualBlock x) = showParen (p >= 11) (showString "VirtualBlock 0x" . showHex x)
-
-
-type FN_vmaAllocateDeviceMemoryFunction = Allocator -> ("memoryType" ::: Word32) -> DeviceMemory -> DeviceSize -> ("pUserData" ::: Ptr ()) -> IO ()
--- No documentation found for TopLevel "PFN_vmaAllocateDeviceMemoryFunction"
-type PFN_vmaAllocateDeviceMemoryFunction = FunPtr FN_vmaAllocateDeviceMemoryFunction
-
-
-type FN_vmaFreeDeviceMemoryFunction = Allocator -> ("memoryType" ::: Word32) -> DeviceMemory -> DeviceSize -> ("pUserData" ::: Ptr ()) -> IO ()
--- No documentation found for TopLevel "PFN_vmaFreeDeviceMemoryFunction"
-type PFN_vmaFreeDeviceMemoryFunction = FunPtr FN_vmaFreeDeviceMemoryFunction
-
-
--- | VmaDeviceMemoryCallbacks
---
--- Set of callbacks that the library will call for @vkAllocateMemory@ and
--- @vkFreeMemory@.
---
--- Provided for informative purpose, e.g. to gather statistics about number
--- of allocations or total amount of memory allocated in Vulkan.
---
--- Used in /VmaAllocatorCreateInfo::pDeviceMemoryCallbacks/.
-data DeviceMemoryCallbacks = DeviceMemoryCallbacks
-  { -- | Optional, can be null.
-    pfnAllocate :: PFN_vmaAllocateDeviceMemoryFunction
-  , -- | Optional, can be null.
-    pfnFree :: PFN_vmaFreeDeviceMemoryFunction
-  , -- | Optional, can be null.
-    userData :: Ptr ()
-  }
-  deriving (Typeable)
-#if defined(GENERIC_INSTANCES)
-deriving instance Generic (DeviceMemoryCallbacks)
-#endif
-deriving instance Show DeviceMemoryCallbacks
-
-instance ToCStruct DeviceMemoryCallbacks where
-  withCStruct x f = allocaBytes 24 $ \p -> pokeCStruct p x (f p)
-  pokeCStruct p DeviceMemoryCallbacks{..} f = do
-    poke ((p `plusPtr` 0 :: Ptr PFN_vmaAllocateDeviceMemoryFunction)) (pfnAllocate)
-    poke ((p `plusPtr` 8 :: Ptr PFN_vmaFreeDeviceMemoryFunction)) (pfnFree)
-    poke ((p `plusPtr` 16 :: Ptr (Ptr ()))) (userData)
-    f
-  cStructSize = 24
-  cStructAlignment = 8
-  pokeZeroCStruct _ f = f
-
-instance FromCStruct DeviceMemoryCallbacks where
-  peekCStruct p = do
-    pfnAllocate <- peek @PFN_vmaAllocateDeviceMemoryFunction ((p `plusPtr` 0 :: Ptr PFN_vmaAllocateDeviceMemoryFunction))
-    pfnFree <- peek @PFN_vmaFreeDeviceMemoryFunction ((p `plusPtr` 8 :: Ptr PFN_vmaFreeDeviceMemoryFunction))
-    pUserData <- peek @(Ptr ()) ((p `plusPtr` 16 :: Ptr (Ptr ())))
-    pure $ DeviceMemoryCallbacks
-             pfnAllocate pfnFree pUserData
-
-instance Storable DeviceMemoryCallbacks where
-  sizeOf ~_ = 24
-  alignment ~_ = 8
-  peek = peekCStruct
-  poke ptr poked = pokeCStruct ptr poked (pure ())
-
-instance Zero DeviceMemoryCallbacks where
-  zero = DeviceMemoryCallbacks
-           zero
-           zero
-           zero
-
-
--- | VmaVulkanFunctions
---
--- Pointers to some Vulkan functions - a subset used by the library.
---
--- Used in /VmaAllocatorCreateInfo::pVulkanFunctions/.
-data VulkanFunctions = VulkanFunctions
-  { -- | Required when using VMA_DYNAMIC_VULKAN_FUNCTIONS.
-    vkGetInstanceProcAddr :: PFN_vkGetInstanceProcAddr
-  , -- | Required when using VMA_DYNAMIC_VULKAN_FUNCTIONS.
-    vkGetDeviceProcAddr :: PFN_vkGetDeviceProcAddr
-  , 
-    vkGetPhysicalDeviceProperties :: PFN_vkGetPhysicalDeviceProperties
-  , 
-    vkGetPhysicalDeviceMemoryProperties :: PFN_vkGetPhysicalDeviceMemoryProperties
-  , 
-    vkAllocateMemory :: PFN_vkAllocateMemory
-  , 
-    vkFreeMemory :: PFN_vkFreeMemory
-  , 
-    vkMapMemory :: PFN_vkMapMemory
-  , 
-    vkUnmapMemory :: PFN_vkUnmapMemory
-  , 
-    vkFlushMappedMemoryRanges :: PFN_vkFlushMappedMemoryRanges
-  , 
-    vkInvalidateMappedMemoryRanges :: PFN_vkInvalidateMappedMemoryRanges
-  , 
-    vkBindBufferMemory :: PFN_vkBindBufferMemory
-  , 
-    vkBindImageMemory :: PFN_vkBindImageMemory
-  , 
-    vkGetBufferMemoryRequirements :: PFN_vkGetBufferMemoryRequirements
-  , 
-    vkGetImageMemoryRequirements :: PFN_vkGetImageMemoryRequirements
-  , 
-    vkCreateBuffer :: PFN_vkCreateBuffer
-  , 
-    vkDestroyBuffer :: PFN_vkDestroyBuffer
-  , 
-    vkCreateImage :: PFN_vkCreateImage
-  , 
-    vkDestroyImage :: PFN_vkDestroyImage
-  , 
-    vkCmdCopyBuffer :: PFN_vkCmdCopyBuffer
-  , -- | Fetch \"vkGetBufferMemoryRequirements2\" on Vulkan >= 1.1, fetch
-    -- \"vkGetBufferMemoryRequirements2KHR\" when using
-    -- VK_KHR_dedicated_allocation extension.
-    vkGetBufferMemoryRequirements2KHR :: PFN_vkGetBufferMemoryRequirements2KHR
-  , -- | Fetch \"vkGetImageMemoryRequirements2\" on Vulkan >= 1.1, fetch
-    -- \"vkGetImageMemoryRequirements2KHR\" when using
-    -- VK_KHR_dedicated_allocation extension.
-    vkGetImageMemoryRequirements2KHR :: PFN_vkGetImageMemoryRequirements2KHR
-  , -- | Fetch \"vkBindBufferMemory2\" on Vulkan >= 1.1, fetch
-    -- \"vkBindBufferMemory2KHR\" when using VK_KHR_bind_memory2 extension.
-    vkBindBufferMemory2KHR :: PFN_vkBindBufferMemory2KHR
-  , -- | Fetch \"vkBindImageMemory2\" on Vulkan >= 1.1, fetch
-    -- \"vkBindImageMemory2KHR\" when using VK_KHR_bind_memory2 extension.
-    vkBindImageMemory2KHR :: PFN_vkBindImageMemory2KHR
-  , 
-    vkGetPhysicalDeviceMemoryProperties2KHR :: PFN_vkGetPhysicalDeviceMemoryProperties2KHR
-  }
-  deriving (Typeable, Eq)
-#if defined(GENERIC_INSTANCES)
-deriving instance Generic (VulkanFunctions)
-#endif
-deriving instance Show VulkanFunctions
-
-instance ToCStruct VulkanFunctions where
-  withCStruct x f = allocaBytes 192 $ \p -> pokeCStruct p x (f p)
-  pokeCStruct p VulkanFunctions{..} f = do
-    poke ((p `plusPtr` 0 :: Ptr PFN_vkGetInstanceProcAddr)) (vkGetInstanceProcAddr)
-    poke ((p `plusPtr` 8 :: Ptr PFN_vkGetDeviceProcAddr)) (vkGetDeviceProcAddr)
-    poke ((p `plusPtr` 16 :: Ptr PFN_vkGetPhysicalDeviceProperties)) (vkGetPhysicalDeviceProperties)
-    poke ((p `plusPtr` 24 :: Ptr PFN_vkGetPhysicalDeviceMemoryProperties)) (vkGetPhysicalDeviceMemoryProperties)
-    poke ((p `plusPtr` 32 :: Ptr PFN_vkAllocateMemory)) (vkAllocateMemory)
-    poke ((p `plusPtr` 40 :: Ptr PFN_vkFreeMemory)) (vkFreeMemory)
-    poke ((p `plusPtr` 48 :: Ptr PFN_vkMapMemory)) (vkMapMemory)
-    poke ((p `plusPtr` 56 :: Ptr PFN_vkUnmapMemory)) (vkUnmapMemory)
-    poke ((p `plusPtr` 64 :: Ptr PFN_vkFlushMappedMemoryRanges)) (vkFlushMappedMemoryRanges)
-    poke ((p `plusPtr` 72 :: Ptr PFN_vkInvalidateMappedMemoryRanges)) (vkInvalidateMappedMemoryRanges)
-    poke ((p `plusPtr` 80 :: Ptr PFN_vkBindBufferMemory)) (vkBindBufferMemory)
-    poke ((p `plusPtr` 88 :: Ptr PFN_vkBindImageMemory)) (vkBindImageMemory)
-    poke ((p `plusPtr` 96 :: Ptr PFN_vkGetBufferMemoryRequirements)) (vkGetBufferMemoryRequirements)
-    poke ((p `plusPtr` 104 :: Ptr PFN_vkGetImageMemoryRequirements)) (vkGetImageMemoryRequirements)
-    poke ((p `plusPtr` 112 :: Ptr PFN_vkCreateBuffer)) (vkCreateBuffer)
-    poke ((p `plusPtr` 120 :: Ptr PFN_vkDestroyBuffer)) (vkDestroyBuffer)
-    poke ((p `plusPtr` 128 :: Ptr PFN_vkCreateImage)) (vkCreateImage)
-    poke ((p `plusPtr` 136 :: Ptr PFN_vkDestroyImage)) (vkDestroyImage)
-    poke ((p `plusPtr` 144 :: Ptr PFN_vkCmdCopyBuffer)) (vkCmdCopyBuffer)
-    poke ((p `plusPtr` 152 :: Ptr PFN_vkGetBufferMemoryRequirements2KHR)) (vkGetBufferMemoryRequirements2KHR)
-    poke ((p `plusPtr` 160 :: Ptr PFN_vkGetImageMemoryRequirements2KHR)) (vkGetImageMemoryRequirements2KHR)
-    poke ((p `plusPtr` 168 :: Ptr PFN_vkBindBufferMemory2KHR)) (vkBindBufferMemory2KHR)
-    poke ((p `plusPtr` 176 :: Ptr PFN_vkBindImageMemory2KHR)) (vkBindImageMemory2KHR)
-    poke ((p `plusPtr` 184 :: Ptr PFN_vkGetPhysicalDeviceMemoryProperties2KHR)) (vkGetPhysicalDeviceMemoryProperties2KHR)
-    f
-  cStructSize = 192
-  cStructAlignment = 8
-  pokeZeroCStruct _ f = f
-
-instance FromCStruct VulkanFunctions where
-  peekCStruct p = do
-    vkGetInstanceProcAddr <- peek @PFN_vkGetInstanceProcAddr ((p `plusPtr` 0 :: Ptr PFN_vkGetInstanceProcAddr))
-    vkGetDeviceProcAddr <- peek @PFN_vkGetDeviceProcAddr ((p `plusPtr` 8 :: Ptr PFN_vkGetDeviceProcAddr))
-    vkGetPhysicalDeviceProperties <- peek @PFN_vkGetPhysicalDeviceProperties ((p `plusPtr` 16 :: Ptr PFN_vkGetPhysicalDeviceProperties))
-    vkGetPhysicalDeviceMemoryProperties <- peek @PFN_vkGetPhysicalDeviceMemoryProperties ((p `plusPtr` 24 :: Ptr PFN_vkGetPhysicalDeviceMemoryProperties))
-    vkAllocateMemory <- peek @PFN_vkAllocateMemory ((p `plusPtr` 32 :: Ptr PFN_vkAllocateMemory))
-    vkFreeMemory <- peek @PFN_vkFreeMemory ((p `plusPtr` 40 :: Ptr PFN_vkFreeMemory))
-    vkMapMemory <- peek @PFN_vkMapMemory ((p `plusPtr` 48 :: Ptr PFN_vkMapMemory))
-    vkUnmapMemory <- peek @PFN_vkUnmapMemory ((p `plusPtr` 56 :: Ptr PFN_vkUnmapMemory))
-    vkFlushMappedMemoryRanges <- peek @PFN_vkFlushMappedMemoryRanges ((p `plusPtr` 64 :: Ptr PFN_vkFlushMappedMemoryRanges))
-    vkInvalidateMappedMemoryRanges <- peek @PFN_vkInvalidateMappedMemoryRanges ((p `plusPtr` 72 :: Ptr PFN_vkInvalidateMappedMemoryRanges))
-    vkBindBufferMemory <- peek @PFN_vkBindBufferMemory ((p `plusPtr` 80 :: Ptr PFN_vkBindBufferMemory))
-    vkBindImageMemory <- peek @PFN_vkBindImageMemory ((p `plusPtr` 88 :: Ptr PFN_vkBindImageMemory))
-    vkGetBufferMemoryRequirements <- peek @PFN_vkGetBufferMemoryRequirements ((p `plusPtr` 96 :: Ptr PFN_vkGetBufferMemoryRequirements))
-    vkGetImageMemoryRequirements <- peek @PFN_vkGetImageMemoryRequirements ((p `plusPtr` 104 :: Ptr PFN_vkGetImageMemoryRequirements))
-    vkCreateBuffer <- peek @PFN_vkCreateBuffer ((p `plusPtr` 112 :: Ptr PFN_vkCreateBuffer))
-    vkDestroyBuffer <- peek @PFN_vkDestroyBuffer ((p `plusPtr` 120 :: Ptr PFN_vkDestroyBuffer))
-    vkCreateImage <- peek @PFN_vkCreateImage ((p `plusPtr` 128 :: Ptr PFN_vkCreateImage))
-    vkDestroyImage <- peek @PFN_vkDestroyImage ((p `plusPtr` 136 :: Ptr PFN_vkDestroyImage))
-    vkCmdCopyBuffer <- peek @PFN_vkCmdCopyBuffer ((p `plusPtr` 144 :: Ptr PFN_vkCmdCopyBuffer))
-    vkGetBufferMemoryRequirements2KHR <- peek @PFN_vkGetBufferMemoryRequirements2KHR ((p `plusPtr` 152 :: Ptr PFN_vkGetBufferMemoryRequirements2KHR))
-    vkGetImageMemoryRequirements2KHR <- peek @PFN_vkGetImageMemoryRequirements2KHR ((p `plusPtr` 160 :: Ptr PFN_vkGetImageMemoryRequirements2KHR))
-    vkBindBufferMemory2KHR <- peek @PFN_vkBindBufferMemory2KHR ((p `plusPtr` 168 :: Ptr PFN_vkBindBufferMemory2KHR))
-    vkBindImageMemory2KHR <- peek @PFN_vkBindImageMemory2KHR ((p `plusPtr` 176 :: Ptr PFN_vkBindImageMemory2KHR))
-    vkGetPhysicalDeviceMemoryProperties2KHR <- peek @PFN_vkGetPhysicalDeviceMemoryProperties2KHR ((p `plusPtr` 184 :: Ptr PFN_vkGetPhysicalDeviceMemoryProperties2KHR))
-    pure $ VulkanFunctions
-             vkGetInstanceProcAddr vkGetDeviceProcAddr vkGetPhysicalDeviceProperties vkGetPhysicalDeviceMemoryProperties vkAllocateMemory vkFreeMemory vkMapMemory vkUnmapMemory vkFlushMappedMemoryRanges vkInvalidateMappedMemoryRanges vkBindBufferMemory vkBindImageMemory vkGetBufferMemoryRequirements vkGetImageMemoryRequirements vkCreateBuffer vkDestroyBuffer vkCreateImage vkDestroyImage vkCmdCopyBuffer vkGetBufferMemoryRequirements2KHR vkGetImageMemoryRequirements2KHR vkBindBufferMemory2KHR vkBindImageMemory2KHR vkGetPhysicalDeviceMemoryProperties2KHR
-
-instance Storable VulkanFunctions where
-  sizeOf ~_ = 192
-  alignment ~_ = 8
-  peek = peekCStruct
-  poke ptr poked = pokeCStruct ptr poked (pure ())
-
-instance Zero VulkanFunctions where
-  zero = VulkanFunctions
-           zero
-           zero
-           zero
-           zero
-           zero
-           zero
-           zero
-           zero
-           zero
-           zero
-           zero
-           zero
-           zero
-           zero
-           zero
-           zero
-           zero
-           zero
-           zero
-           zero
-           zero
-           zero
-           zero
-           zero
-
-
--- | VmaAllocatorCreateInfo
---
--- Description of a Allocator to be created.
-data AllocatorCreateInfo = AllocatorCreateInfo
-  { -- | Flags for created allocator. Use 'AllocatorCreateFlagBits' enum.
-    flags :: AllocatorCreateFlags
-  , -- | Vulkan physical device.
-    --
-    -- It must be valid throughout whole lifetime of created allocator.
-    physicalDevice :: Ptr PhysicalDevice_T
-  , -- | Vulkan device.
-    --
-    -- It must be valid throughout whole lifetime of created allocator.
-    device :: Ptr Device_T
-  , -- | Preferred size of a single @VkDeviceMemory@ block to be allocated from
-    -- large heaps > 1 GiB. Optional.
-    --
-    -- Set to 0 to use default, which is currently 256 MiB.
-    preferredLargeHeapBlockSize :: DeviceSize
-  , -- | Custom CPU memory allocation callbacks. Optional.
-    --
-    -- Optional, can be null. When specified, will also be used for all
-    -- CPU-side memory allocations.
-    allocationCallbacks :: Maybe AllocationCallbacks
-  , -- | Informative callbacks for @vkAllocateMemory@, @vkFreeMemory@. Optional.
-    --
-    -- Optional, can be null.
-    deviceMemoryCallbacks :: Maybe DeviceMemoryCallbacks
-  , -- | Either null or a pointer to an array of limits on maximum number of
-    -- bytes that can be allocated out of particular Vulkan memory heap.
-    --
-    -- If not NULL, it must be a pointer to an array of
-    -- @VkPhysicalDeviceMemoryProperties::memoryHeapCount@ elements, defining
-    -- limit on maximum number of bytes that can be allocated out of particular
-    -- Vulkan memory heap.
-    --
-    -- Any of the elements may be equal to @VK_WHOLE_SIZE@, which means no
-    -- limit on that heap. This is also the default in case of @pHeapSizeLimit@
-    -- = NULL.
-    --
-    -- If there is a limit defined for a heap:
-    --
-    -- -   If user tries to allocate more memory from that heap using this
-    --     allocator, the allocation fails with
-    --     @VK_ERROR_OUT_OF_DEVICE_MEMORY@.
-    --
-    -- -   If the limit is smaller than heap size reported in
-    --     @VkMemoryHeap::size@, the value of this limit will be reported
-    --     instead when using 'getMemoryProperties'.
-    --
-    -- Warning! Using this feature may not be equivalent to installing a GPU
-    -- with smaller amount of memory, because graphics driver doesn\'t
-    -- necessary fail new allocations with @VK_ERROR_OUT_OF_DEVICE_MEMORY@
-    -- result when memory capacity is exceeded. It may return success and just
-    -- silently migrate some device memory blocks to system RAM. This driver
-    -- behavior can also be controlled using
-    -- VK_AMD_memory_overallocation_behavior extension.
-    heapSizeLimit :: Ptr DeviceSize
-  , -- | Pointers to Vulkan functions. Can be null.
-    --
-    -- For details see /Pointers to Vulkan functions/.
-    vulkanFunctions :: Maybe VulkanFunctions
-  , -- | Handle to Vulkan instance object.
-    --
-    -- Starting from version 3.0.0 this member is no longer optional, it must
-    -- be set!
-    instance' :: Ptr Instance_T
-  , -- | Optional. The highest version of Vulkan that the application is designed
-    -- to use.
-    --
-    -- It must be a value in the format as created by macro @VK_MAKE_VERSION@
-    -- or a constant like: @VK_API_VERSION_1_1@, @VK_API_VERSION_1_0@. The
-    -- patch version number specified is ignored. Only the major and minor
-    -- versions are considered. It must be less or equal (preferably equal) to
-    -- value as passed to @vkCreateInstance@ as
-    -- @VkApplicationInfo::apiVersion@. Only versions 1.0, 1.1, 1.2, 1.3 are
-    -- supported by the current implementation. Leaving it initialized to zero
-    -- is equivalent to @VK_API_VERSION_1_0@.
-    vulkanApiVersion :: Word32
-  , -- | Either null or a pointer to an array of external memory handle types for
-    -- each Vulkan memory type.
-    --
-    -- If not NULL, it must be a pointer to an array of
-    -- @VkPhysicalDeviceMemoryProperties::memoryTypeCount@ elements, defining
-    -- external memory handle types of particular Vulkan memory type, to be
-    -- passed using @VkExportMemoryAllocateInfoKHR@.
-    --
-    -- Any of the elements may be equal to 0, which means not to use
-    -- @VkExportMemoryAllocateInfoKHR@ on this memory type. This is also the
-    -- default in case of @pTypeExternalMemoryHandleTypes@ = NULL.
-    typeExternalMemoryHandleTypes :: Ptr ExternalMemoryHandleTypeFlagsKHR
-  }
-  deriving (Typeable)
-#if defined(GENERIC_INSTANCES)
-deriving instance Generic (AllocatorCreateInfo)
-#endif
-deriving instance Show AllocatorCreateInfo
-
-instance ToCStruct AllocatorCreateInfo where
-  withCStruct x f = allocaBytes 88 $ \p -> pokeCStruct p x (f p)
-  pokeCStruct p AllocatorCreateInfo{..} f = evalContT $ do
-    lift $ poke ((p `plusPtr` 0 :: Ptr AllocatorCreateFlags)) (flags)
-    lift $ poke ((p `plusPtr` 8 :: Ptr (Ptr PhysicalDevice_T))) (physicalDevice)
-    lift $ poke ((p `plusPtr` 16 :: Ptr (Ptr Device_T))) (device)
-    lift $ poke ((p `plusPtr` 24 :: Ptr DeviceSize)) (preferredLargeHeapBlockSize)
-    pAllocationCallbacks'' <- case (allocationCallbacks) of
-      Nothing -> pure nullPtr
-      Just j -> ContT $ withCStruct (j)
-    lift $ poke ((p `plusPtr` 32 :: Ptr (Ptr AllocationCallbacks))) pAllocationCallbacks''
-    pDeviceMemoryCallbacks'' <- case (deviceMemoryCallbacks) of
-      Nothing -> pure nullPtr
-      Just j -> ContT $ withCStruct (j)
-    lift $ poke ((p `plusPtr` 40 :: Ptr (Ptr DeviceMemoryCallbacks))) pDeviceMemoryCallbacks''
-    lift $ poke ((p `plusPtr` 48 :: Ptr (Ptr DeviceSize))) (heapSizeLimit)
-    pVulkanFunctions'' <- case (vulkanFunctions) of
-      Nothing -> pure nullPtr
-      Just j -> ContT $ withCStruct (j)
-    lift $ poke ((p `plusPtr` 56 :: Ptr (Ptr VulkanFunctions))) pVulkanFunctions''
-    lift $ poke ((p `plusPtr` 64 :: Ptr (Ptr Instance_T))) (instance')
-    lift $ poke ((p `plusPtr` 72 :: Ptr Word32)) (vulkanApiVersion)
-    lift $ poke ((p `plusPtr` 80 :: Ptr (Ptr ExternalMemoryHandleTypeFlagsKHR))) (typeExternalMemoryHandleTypes)
-    lift $ f
-  cStructSize = 88
-  cStructAlignment = 8
-  pokeZeroCStruct p f = do
-    poke ((p `plusPtr` 0 :: Ptr AllocatorCreateFlags)) (zero)
-    poke ((p `plusPtr` 8 :: Ptr (Ptr PhysicalDevice_T))) (zero)
-    poke ((p `plusPtr` 16 :: Ptr (Ptr Device_T))) (zero)
-    poke ((p `plusPtr` 24 :: Ptr DeviceSize)) (zero)
-    poke ((p `plusPtr` 64 :: Ptr (Ptr Instance_T))) (zero)
-    poke ((p `plusPtr` 72 :: Ptr Word32)) (zero)
-    f
-
-instance FromCStruct AllocatorCreateInfo where
-  peekCStruct p = do
-    flags <- peek @AllocatorCreateFlags ((p `plusPtr` 0 :: Ptr AllocatorCreateFlags))
-    physicalDevice <- peek @(Ptr PhysicalDevice_T) ((p `plusPtr` 8 :: Ptr (Ptr PhysicalDevice_T)))
-    device <- peek @(Ptr Device_T) ((p `plusPtr` 16 :: Ptr (Ptr Device_T)))
-    preferredLargeHeapBlockSize <- peek @DeviceSize ((p `plusPtr` 24 :: Ptr DeviceSize))
-    pAllocationCallbacks <- peek @(Ptr AllocationCallbacks) ((p `plusPtr` 32 :: Ptr (Ptr AllocationCallbacks)))
-    pAllocationCallbacks' <- maybePeek (\j -> peekCStruct @AllocationCallbacks (j)) pAllocationCallbacks
-    pDeviceMemoryCallbacks <- peek @(Ptr DeviceMemoryCallbacks) ((p `plusPtr` 40 :: Ptr (Ptr DeviceMemoryCallbacks)))
-    pDeviceMemoryCallbacks' <- maybePeek (\j -> peekCStruct @DeviceMemoryCallbacks (j)) pDeviceMemoryCallbacks
-    pHeapSizeLimit <- peek @(Ptr DeviceSize) ((p `plusPtr` 48 :: Ptr (Ptr DeviceSize)))
-    pVulkanFunctions <- peek @(Ptr VulkanFunctions) ((p `plusPtr` 56 :: Ptr (Ptr VulkanFunctions)))
-    pVulkanFunctions' <- maybePeek (\j -> peekCStruct @VulkanFunctions (j)) pVulkanFunctions
-    instance' <- peek @(Ptr Instance_T) ((p `plusPtr` 64 :: Ptr (Ptr Instance_T)))
-    vulkanApiVersion <- peek @Word32 ((p `plusPtr` 72 :: Ptr Word32))
-    pTypeExternalMemoryHandleTypes <- peek @(Ptr ExternalMemoryHandleTypeFlagsKHR) ((p `plusPtr` 80 :: Ptr (Ptr ExternalMemoryHandleTypeFlagsKHR)))
-    pure $ AllocatorCreateInfo
-             flags physicalDevice device preferredLargeHeapBlockSize pAllocationCallbacks' pDeviceMemoryCallbacks' pHeapSizeLimit pVulkanFunctions' instance' vulkanApiVersion pTypeExternalMemoryHandleTypes
-
-instance Zero AllocatorCreateInfo where
-  zero = AllocatorCreateInfo
-           zero
-           zero
-           zero
-           zero
-           Nothing
-           Nothing
-           zero
-           Nothing
-           zero
-           zero
-           zero
-
-
--- | VmaAllocatorInfo
---
--- Information about existing 'Allocator' object.
-data AllocatorInfo = AllocatorInfo
-  { -- | Handle to Vulkan instance object.
-    --
-    -- This is the same value as has been passed through
-    -- /VmaAllocatorCreateInfo::instance/.
-    instance' :: Ptr Instance_T
-  , -- | Handle to Vulkan physical device object.
-    --
-    -- This is the same value as has been passed through
-    -- /VmaAllocatorCreateInfo::physicalDevice/.
-    physicalDevice :: Ptr PhysicalDevice_T
-  , -- | Handle to Vulkan device object.
-    --
-    -- This is the same value as has been passed through
-    -- /VmaAllocatorCreateInfo::device/.
-    device :: Ptr Device_T
-  }
-  deriving (Typeable, Eq)
-#if defined(GENERIC_INSTANCES)
-deriving instance Generic (AllocatorInfo)
-#endif
-deriving instance Show AllocatorInfo
-
-instance ToCStruct AllocatorInfo where
-  withCStruct x f = allocaBytes 24 $ \p -> pokeCStruct p x (f p)
-  pokeCStruct p AllocatorInfo{..} f = do
-    poke ((p `plusPtr` 0 :: Ptr (Ptr Instance_T))) (instance')
-    poke ((p `plusPtr` 8 :: Ptr (Ptr PhysicalDevice_T))) (physicalDevice)
-    poke ((p `plusPtr` 16 :: Ptr (Ptr Device_T))) (device)
-    f
-  cStructSize = 24
-  cStructAlignment = 8
-  pokeZeroCStruct p f = do
-    poke ((p `plusPtr` 0 :: Ptr (Ptr Instance_T))) (zero)
-    poke ((p `plusPtr` 8 :: Ptr (Ptr PhysicalDevice_T))) (zero)
-    poke ((p `plusPtr` 16 :: Ptr (Ptr Device_T))) (zero)
-    f
-
-instance FromCStruct AllocatorInfo where
-  peekCStruct p = do
-    instance' <- peek @(Ptr Instance_T) ((p `plusPtr` 0 :: Ptr (Ptr Instance_T)))
-    physicalDevice <- peek @(Ptr PhysicalDevice_T) ((p `plusPtr` 8 :: Ptr (Ptr PhysicalDevice_T)))
-    device <- peek @(Ptr Device_T) ((p `plusPtr` 16 :: Ptr (Ptr Device_T)))
-    pure $ AllocatorInfo
-             instance' physicalDevice device
-
-instance Storable AllocatorInfo where
-  sizeOf ~_ = 24
-  alignment ~_ = 8
-  peek = peekCStruct
-  poke ptr poked = pokeCStruct ptr poked (pure ())
-
-instance Zero AllocatorInfo where
-  zero = AllocatorInfo
-           zero
-           zero
-           zero
-
-
--- | VmaStatistics
---
--- Calculated statistics of memory usage e.g. in a specific memory type,
--- heap, custom pool, or total.
---
--- These are fast to calculate. See functions: 'getHeapBudgets',
--- 'getPoolStatistics'.
-data Statistics = Statistics
-  { -- | Number of @VkDeviceMemory@ objects - Vulkan memory blocks allocated.
-    blockCount :: Word32
-  , -- | Number of 'Allocation' objects allocated.
-    --
-    -- Dedicated allocations have their own blocks, so each one adds 1 to
-    -- @allocationCount@ as well as @blockCount@.
-    allocationCount :: Word32
-  , -- | Number of bytes allocated in @VkDeviceMemory@ blocks.
-    --
-    -- Note
-    --
-    -- To avoid confusion, please be aware that what Vulkan calls an
-    -- \"allocation\" - a whole @VkDeviceMemory@ object (e.g. as in
-    -- @VkPhysicalDeviceLimits::maxMemoryAllocationCount@) is called a
-    -- \"block\" in VMA, while VMA calls \"allocation\" a 'Allocation' object
-    -- that represents a memory region sub-allocated from such block, usually
-    -- for a single buffer or image.
-    blockBytes :: DeviceSize
-  , -- | Total number of bytes occupied by all 'Allocation' objects.
-    --
-    -- Always less or equal than @blockBytes@. Difference
-    -- @(blockBytes - allocationBytes)@ is the amount of memory allocated from
-    -- Vulkan but unused by any 'Allocation'.
-    allocationBytes :: DeviceSize
-  }
-  deriving (Typeable, Eq)
-#if defined(GENERIC_INSTANCES)
-deriving instance Generic (Statistics)
-#endif
-deriving instance Show Statistics
-
-instance ToCStruct Statistics where
-  withCStruct x f = allocaBytes 24 $ \p -> pokeCStruct p x (f p)
-  pokeCStruct p Statistics{..} f = do
-    poke ((p `plusPtr` 0 :: Ptr Word32)) (blockCount)
-    poke ((p `plusPtr` 4 :: Ptr Word32)) (allocationCount)
-    poke ((p `plusPtr` 8 :: Ptr DeviceSize)) (blockBytes)
-    poke ((p `plusPtr` 16 :: Ptr DeviceSize)) (allocationBytes)
-    f
-  cStructSize = 24
-  cStructAlignment = 8
-  pokeZeroCStruct p f = do
-    poke ((p `plusPtr` 0 :: Ptr Word32)) (zero)
-    poke ((p `plusPtr` 4 :: Ptr Word32)) (zero)
-    poke ((p `plusPtr` 8 :: Ptr DeviceSize)) (zero)
-    poke ((p `plusPtr` 16 :: Ptr DeviceSize)) (zero)
-    f
-
-instance FromCStruct Statistics where
-  peekCStruct p = do
-    blockCount <- peek @Word32 ((p `plusPtr` 0 :: Ptr Word32))
-    allocationCount <- peek @Word32 ((p `plusPtr` 4 :: Ptr Word32))
-    blockBytes <- peek @DeviceSize ((p `plusPtr` 8 :: Ptr DeviceSize))
-    allocationBytes <- peek @DeviceSize ((p `plusPtr` 16 :: Ptr DeviceSize))
-    pure $ Statistics
-             blockCount allocationCount blockBytes allocationBytes
-
-instance Storable Statistics where
-  sizeOf ~_ = 24
-  alignment ~_ = 8
-  peek = peekCStruct
-  poke ptr poked = pokeCStruct ptr poked (pure ())
-
-instance Zero Statistics where
-  zero = Statistics
-           zero
-           zero
-           zero
-           zero
-
-
--- | VmaDetailedStatistics
---
--- More detailed statistics than 'Statistics'.
---
--- These are slower to calculate. Use for debugging purposes. See
--- functions: 'calculateStatistics', 'calculatePoolStatistics'.
---
--- Previous version of the statistics API provided averages, but they have
--- been removed because they can be easily calculated as:
---
--- > VkDeviceSize allocationSizeAvg = detailedStats.statistics.allocationBytes / detailedStats.statistics.allocationCount;
--- > VkDeviceSize unusedBytes = detailedStats.statistics.blockBytes - detailedStats.statistics.allocationBytes;
--- > VkDeviceSize unusedRangeSizeAvg = unusedBytes / detailedStats.unusedRangeCount;
-data DetailedStatistics = DetailedStatistics
-  { -- | Basic statistics.
-    statistics :: Statistics
-  , -- | Number of free ranges of memory between allocations.
-    unusedRangeCount :: Word32
-  , -- | Smallest allocation size. @VK_WHOLE_SIZE@ if there are 0 allocations.
-    allocationSizeMin :: DeviceSize
-  , -- | Largest allocation size. 0 if there are 0 allocations.
-    allocationSizeMax :: DeviceSize
-  , -- | Smallest empty range size. @VK_WHOLE_SIZE@ if there are 0 empty ranges.
-    unusedRangeSizeMin :: DeviceSize
-  , -- | Largest empty range size. 0 if there are 0 empty ranges.
-    unusedRangeSizeMax :: DeviceSize
-  }
-  deriving (Typeable)
-#if defined(GENERIC_INSTANCES)
-deriving instance Generic (DetailedStatistics)
-#endif
-deriving instance Show DetailedStatistics
-
-instance ToCStruct DetailedStatistics where
-  withCStruct x f = allocaBytes 64 $ \p -> pokeCStruct p x (f p)
-  pokeCStruct p DetailedStatistics{..} f = do
-    poke ((p `plusPtr` 0 :: Ptr Statistics)) (statistics)
-    poke ((p `plusPtr` 24 :: Ptr Word32)) (unusedRangeCount)
-    poke ((p `plusPtr` 32 :: Ptr DeviceSize)) (allocationSizeMin)
-    poke ((p `plusPtr` 40 :: Ptr DeviceSize)) (allocationSizeMax)
-    poke ((p `plusPtr` 48 :: Ptr DeviceSize)) (unusedRangeSizeMin)
-    poke ((p `plusPtr` 56 :: Ptr DeviceSize)) (unusedRangeSizeMax)
-    f
-  cStructSize = 64
-  cStructAlignment = 8
-  pokeZeroCStruct p f = do
-    poke ((p `plusPtr` 0 :: Ptr Statistics)) (zero)
-    poke ((p `plusPtr` 24 :: Ptr Word32)) (zero)
-    poke ((p `plusPtr` 32 :: Ptr DeviceSize)) (zero)
-    poke ((p `plusPtr` 40 :: Ptr DeviceSize)) (zero)
-    poke ((p `plusPtr` 48 :: Ptr DeviceSize)) (zero)
-    poke ((p `plusPtr` 56 :: Ptr DeviceSize)) (zero)
-    f
-
-instance FromCStruct DetailedStatistics where
-  peekCStruct p = do
-    statistics <- peekCStruct @Statistics ((p `plusPtr` 0 :: Ptr Statistics))
-    unusedRangeCount <- peek @Word32 ((p `plusPtr` 24 :: Ptr Word32))
-    allocationSizeMin <- peek @DeviceSize ((p `plusPtr` 32 :: Ptr DeviceSize))
-    allocationSizeMax <- peek @DeviceSize ((p `plusPtr` 40 :: Ptr DeviceSize))
-    unusedRangeSizeMin <- peek @DeviceSize ((p `plusPtr` 48 :: Ptr DeviceSize))
-    unusedRangeSizeMax <- peek @DeviceSize ((p `plusPtr` 56 :: Ptr DeviceSize))
-    pure $ DetailedStatistics
-             statistics unusedRangeCount allocationSizeMin allocationSizeMax unusedRangeSizeMin unusedRangeSizeMax
-
-instance Storable DetailedStatistics where
-  sizeOf ~_ = 64
-  alignment ~_ = 8
-  peek = peekCStruct
-  poke ptr poked = pokeCStruct ptr poked (pure ())
-
-instance Zero DetailedStatistics where
-  zero = DetailedStatistics
-           zero
-           zero
-           zero
-           zero
-           zero
-           zero
-
-
--- | VmaTotalStatistics
---
--- -   'DetailedStatistics' /memoryType/ [VK_MAX_MEMORY_TYPES]
---
--- -   'DetailedStatistics' /memoryHeap/ [VK_MAX_MEMORY_HEAPS]
---
--- -   'DetailedStatistics' /total/
---
--- General statistics from current state of the Allocator - total memory
--- usage across all memory heaps and types.
---
--- These are slower to calculate. Use for debugging purposes. See function
--- 'calculateStatistics'.
---
--- === memoryHeap
---
--- memoryHeap
--- VmaTotalStatistics
--- VmaTotalStatistics
--- memoryHeap
--- @VmaDetailedStatistics VmaTotalStatistics::memoryHeap[VK_MAX_MEMORY_HEAPS]@
---
--- === memoryType
---
--- memoryType
--- VmaTotalStatistics
--- VmaTotalStatistics
--- memoryType
--- @VmaDetailedStatistics VmaTotalStatistics::memoryType[VK_MAX_MEMORY_TYPES]@
-data TotalStatistics = TotalStatistics
-  { -- No documentation found for Nested "VmaTotalStatistics" "memoryType"
-    memoryType :: Vector DetailedStatistics
-  , -- No documentation found for Nested "VmaTotalStatistics" "memoryHeap"
-    memoryHeap :: Vector DetailedStatistics
-  , 
-    total :: DetailedStatistics
-  }
-  deriving (Typeable)
-#if defined(GENERIC_INSTANCES)
-deriving instance Generic (TotalStatistics)
-#endif
-deriving instance Show TotalStatistics
-
-instance ToCStruct TotalStatistics where
-  withCStruct x f = allocaBytes 3136 $ \p -> pokeCStruct p x (f p)
-  pokeCStruct p TotalStatistics{..} f = do
-    unless ((Data.Vector.length $ (memoryType)) <= MAX_MEMORY_TYPES) $
-      throwIO $ IOError Nothing InvalidArgument "" "memoryType is too long, a maximum of MAX_MEMORY_TYPES elements are allowed" Nothing Nothing
-    Data.Vector.imapM_ (\i e -> poke ((lowerArrayPtr ((p `plusPtr` 0 :: Ptr (FixedArray MAX_MEMORY_TYPES DetailedStatistics)))) `plusPtr` (64 * (i)) :: Ptr DetailedStatistics) (e)) (memoryType)
-    unless ((Data.Vector.length $ (memoryHeap)) <= MAX_MEMORY_HEAPS) $
-      throwIO $ IOError Nothing InvalidArgument "" "memoryHeap is too long, a maximum of MAX_MEMORY_HEAPS elements are allowed" Nothing Nothing
-    Data.Vector.imapM_ (\i e -> poke ((lowerArrayPtr ((p `plusPtr` 2048 :: Ptr (FixedArray MAX_MEMORY_HEAPS DetailedStatistics)))) `plusPtr` (64 * (i)) :: Ptr DetailedStatistics) (e)) (memoryHeap)
-    poke ((p `plusPtr` 3072 :: Ptr DetailedStatistics)) (total)
-    f
-  cStructSize = 3136
-  cStructAlignment = 8
-  pokeZeroCStruct p f = do
-    poke ((p `plusPtr` 3072 :: Ptr DetailedStatistics)) (zero)
-    f
-
-instance FromCStruct TotalStatistics where
-  peekCStruct p = do
-    memoryType <- generateM (MAX_MEMORY_TYPES) (\i -> peekCStruct @DetailedStatistics (((lowerArrayPtr @DetailedStatistics ((p `plusPtr` 0 :: Ptr (FixedArray MAX_MEMORY_TYPES DetailedStatistics)))) `advancePtrBytes` (64 * (i)) :: Ptr DetailedStatistics)))
-    memoryHeap <- generateM (MAX_MEMORY_HEAPS) (\i -> peekCStruct @DetailedStatistics (((lowerArrayPtr @DetailedStatistics ((p `plusPtr` 2048 :: Ptr (FixedArray MAX_MEMORY_HEAPS DetailedStatistics)))) `advancePtrBytes` (64 * (i)) :: Ptr DetailedStatistics)))
-    total <- peekCStruct @DetailedStatistics ((p `plusPtr` 3072 :: Ptr DetailedStatistics))
-    pure $ TotalStatistics
-             memoryType memoryHeap total
-
-instance Storable TotalStatistics where
-  sizeOf ~_ = 3136
-  alignment ~_ = 8
-  peek = peekCStruct
-  poke ptr poked = pokeCStruct ptr poked (pure ())
-
-instance Zero TotalStatistics where
-  zero = TotalStatistics
-           mempty
-           mempty
-           zero
-
-
--- | VmaBudget
---
--- Statistics of current memory usage and available budget for a specific
--- memory heap.
---
--- These are fast to calculate. See function 'getHeapBudgets'.
-data Budget = Budget
-  { -- | Statistics fetched from the library.
-    statistics :: Statistics
-  , -- | Estimated current memory usage of the program, in bytes.
-    --
-    -- Fetched from system using VK_EXT_memory_budget extension if enabled.
-    --
-    -- It might be different than @statistics.blockBytes@ (usually higher) due
-    -- to additional implicit objects also occupying the memory, like
-    -- swapchain, pipelines, descriptor heaps, command buffers, or
-    -- @VkDeviceMemory@ blocks allocated outside of this library, if any.
-    usage :: DeviceSize
-  , -- | Estimated amount of memory available to the program, in bytes.
-    --
-    -- Fetched from system using VK_EXT_memory_budget extension if enabled.
-    --
-    -- It might be different (most probably smaller) than
-    -- @VkMemoryHeap::size[heapIndex]@ due to factors external to the program,
-    -- decided by the operating system. Difference @budget - usage@ is the
-    -- amount of additional memory that can probably be allocated without
-    -- problems. Exceeding the budget may result in various problems.
-    budget :: DeviceSize
-  }
-  deriving (Typeable)
-#if defined(GENERIC_INSTANCES)
-deriving instance Generic (Budget)
-#endif
-deriving instance Show Budget
-
-instance ToCStruct Budget where
-  withCStruct x f = allocaBytes 40 $ \p -> pokeCStruct p x (f p)
-  pokeCStruct p Budget{..} f = do
-    poke ((p `plusPtr` 0 :: Ptr Statistics)) (statistics)
-    poke ((p `plusPtr` 24 :: Ptr DeviceSize)) (usage)
-    poke ((p `plusPtr` 32 :: Ptr DeviceSize)) (budget)
-    f
-  cStructSize = 40
-  cStructAlignment = 8
-  pokeZeroCStruct p f = do
-    poke ((p `plusPtr` 0 :: Ptr Statistics)) (zero)
-    poke ((p `plusPtr` 24 :: Ptr DeviceSize)) (zero)
-    poke ((p `plusPtr` 32 :: Ptr DeviceSize)) (zero)
-    f
-
-instance FromCStruct Budget where
-  peekCStruct p = do
-    statistics <- peekCStruct @Statistics ((p `plusPtr` 0 :: Ptr Statistics))
-    usage <- peek @DeviceSize ((p `plusPtr` 24 :: Ptr DeviceSize))
-    budget <- peek @DeviceSize ((p `plusPtr` 32 :: Ptr DeviceSize))
-    pure $ Budget
-             statistics usage budget
-
-instance Storable Budget where
-  sizeOf ~_ = 40
-  alignment ~_ = 8
-  peek = peekCStruct
-  poke ptr poked = pokeCStruct ptr poked (pure ())
-
-instance Zero Budget where
-  zero = Budget
-           zero
-           zero
-           zero
-
-
--- | VmaAllocationCreateInfo
---
--- Parameters of new 'Allocation'.
---
--- To be used with functions like 'createBuffer', 'createImage', and many
--- others.
-data AllocationCreateInfo = AllocationCreateInfo
-  { -- | Use 'AllocationCreateFlagBits' enum.
-    flags :: AllocationCreateFlags
-  , -- | Intended usage of memory.
-    --
-    -- You can leave 'MEMORY_USAGE_UNKNOWN' if you specify memory requirements
-    -- in other way.
-    --
-    -- >  
-    --
-    -- If @pool@ is not null, this member is ignored.
-    usage :: MemoryUsage
-  , -- | Flags that must be set in a Memory Type chosen for an allocation.
-    --
-    -- Leave 0 if you specify memory requirements in other way.
-    --
-    -- >  
-    --
-    -- If @pool@ is not null, this member is ignored.
-    requiredFlags :: MemoryPropertyFlags
-  , -- | Flags that preferably should be set in a memory type chosen for an
-    -- allocation.
-    --
-    -- Set to 0 if no additional flags are preferred.
-    --
-    -- >  
-    --
-    -- If @pool@ is not null, this member is ignored.
-    preferredFlags :: MemoryPropertyFlags
-  , -- | Bitmask containing one bit set for every memory type acceptable for this
-    -- allocation.
-    --
-    -- Value 0 is equivalent to @UINT32_MAX@ - it means any memory type is
-    -- accepted if it meets other requirements specified by this structure,
-    -- with no further restrictions on memory type index.
-    --
-    -- >  
-    --
-    -- If @pool@ is not null, this member is ignored.
-    memoryTypeBits :: Word32
-  , -- | Pool that this allocation should be created in.
-    --
-    -- Leave @VK_NULL_HANDLE@ to allocate from default pool. If not null,
-    -- members: @usage@, @requiredFlags@, @preferredFlags@, @memoryTypeBits@
-    -- are ignored.
-    pool :: Pool
-  , -- | Custom general-purpose pointer that will be stored in 'Allocation', can
-    -- be read as /VmaAllocationInfo::pUserData/ and changed using
-    -- 'setAllocationUserData'.
-    --
-    -- If 'ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT' is used, it must be
-    -- either null or pointer to a null-terminated string. The string will be
-    -- then copied to internal buffer, so it doesn\'t need to be valid after
-    -- allocation call.
-    userData :: Ptr ()
-  , -- | A floating-point value between 0 and 1, indicating the priority of the
-    -- allocation relative to other memory allocations.
-    --
-    -- It is used only when 'ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT' flag was
-    -- used during creation of the 'Allocator' object and this allocation ends
-    -- up as dedicated or is explicitly forced as dedicated using
-    -- 'ALLOCATION_CREATE_DEDICATED_MEMORY_BIT'. Otherwise, it has the priority
-    -- of a memory block where it is placed and this variable is ignored.
-    priority :: Float
-  }
-  deriving (Typeable)
-#if defined(GENERIC_INSTANCES)
-deriving instance Generic (AllocationCreateInfo)
-#endif
-deriving instance Show AllocationCreateInfo
-
-instance ToCStruct AllocationCreateInfo where
-  withCStruct x f = allocaBytes 48 $ \p -> pokeCStruct p x (f p)
-  pokeCStruct p AllocationCreateInfo{..} f = do
-    poke ((p `plusPtr` 0 :: Ptr AllocationCreateFlags)) (flags)
-    poke ((p `plusPtr` 4 :: Ptr MemoryUsage)) (usage)
-    poke ((p `plusPtr` 8 :: Ptr MemoryPropertyFlags)) (requiredFlags)
-    poke ((p `plusPtr` 12 :: Ptr MemoryPropertyFlags)) (preferredFlags)
-    poke ((p `plusPtr` 16 :: Ptr Word32)) (memoryTypeBits)
-    poke ((p `plusPtr` 24 :: Ptr Pool)) (pool)
-    poke ((p `plusPtr` 32 :: Ptr (Ptr ()))) (userData)
-    poke ((p `plusPtr` 40 :: Ptr CFloat)) (CFloat (priority))
-    f
-  cStructSize = 48
-  cStructAlignment = 8
-  pokeZeroCStruct p f = do
-    poke ((p `plusPtr` 0 :: Ptr AllocationCreateFlags)) (zero)
-    poke ((p `plusPtr` 4 :: Ptr MemoryUsage)) (zero)
-    poke ((p `plusPtr` 8 :: Ptr MemoryPropertyFlags)) (zero)
-    poke ((p `plusPtr` 12 :: Ptr MemoryPropertyFlags)) (zero)
-    poke ((p `plusPtr` 16 :: Ptr Word32)) (zero)
-    poke ((p `plusPtr` 40 :: Ptr CFloat)) (CFloat (zero))
-    f
-
-instance FromCStruct AllocationCreateInfo where
-  peekCStruct p = do
-    flags <- peek @AllocationCreateFlags ((p `plusPtr` 0 :: Ptr AllocationCreateFlags))
-    usage <- peek @MemoryUsage ((p `plusPtr` 4 :: Ptr MemoryUsage))
-    requiredFlags <- peek @MemoryPropertyFlags ((p `plusPtr` 8 :: Ptr MemoryPropertyFlags))
-    preferredFlags <- peek @MemoryPropertyFlags ((p `plusPtr` 12 :: Ptr MemoryPropertyFlags))
-    memoryTypeBits <- peek @Word32 ((p `plusPtr` 16 :: Ptr Word32))
-    pool <- peek @Pool ((p `plusPtr` 24 :: Ptr Pool))
-    pUserData <- peek @(Ptr ()) ((p `plusPtr` 32 :: Ptr (Ptr ())))
-    priority <- peek @CFloat ((p `plusPtr` 40 :: Ptr CFloat))
-    pure $ AllocationCreateInfo
-             flags usage requiredFlags preferredFlags memoryTypeBits pool pUserData (coerce @CFloat @Float priority)
-
-instance Storable AllocationCreateInfo where
-  sizeOf ~_ = 48
-  alignment ~_ = 8
-  peek = peekCStruct
-  poke ptr poked = pokeCStruct ptr poked (pure ())
-
-instance Zero AllocationCreateInfo where
-  zero = AllocationCreateInfo
-           zero
-           zero
-           zero
-           zero
-           zero
-           zero
-           zero
-           zero
-
-
--- | VmaPoolCreateInfo
---
--- Describes parameter of created 'Pool'.
-data PoolCreateInfo = PoolCreateInfo
-  { -- | Vulkan memory type index to allocate this pool from.
-    memoryTypeIndex :: Word32
-  , -- | Use combination of 'PoolCreateFlagBits'.
-    flags :: PoolCreateFlags
-  , -- | Size of a single @VkDeviceMemory@ block to be allocated as part of this
-    -- pool, in bytes. Optional.
-    --
-    -- Specify nonzero to set explicit, constant size of memory blocks used by
-    -- this pool.
-    --
-    -- Leave 0 to use default and let the library manage block sizes
-    -- automatically. Sizes of particular blocks may vary. In this case, the
-    -- pool will also support dedicated allocations.
-    blockSize :: DeviceSize
-  , -- | Minimum number of blocks to be always allocated in this pool, even if
-    -- they stay empty.
-    --
-    -- Set to 0 to have no preallocated blocks and allow the pool be completely
-    -- empty.
-    minBlockCount :: Word64
-  , -- | Maximum number of blocks that can be allocated in this pool. Optional.
-    --
-    -- Set to 0 to use default, which is @SIZE_MAX@, which means no limit.
-    --
-    -- Set to same value as /VmaPoolCreateInfo::minBlockCount/ to have fixed
-    -- amount of memory allocated throughout whole lifetime of this pool.
-    maxBlockCount :: Word64
-  , -- | A floating-point value between 0 and 1, indicating the priority of the
-    -- allocations in this pool relative to other memory allocations.
-    --
-    -- It is used only when 'ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT' flag was
-    -- used during creation of the 'Allocator' object. Otherwise, this variable
-    -- is ignored.
-    priority :: Float
-  , -- | Additional minimum alignment to be used for all allocations created from
-    -- this pool. Can be 0.
-    --
-    -- Leave 0 (default) not to impose any additional alignment. If not 0, it
-    -- must be a power of two. It can be useful in cases where alignment
-    -- returned by Vulkan by functions like @vkGetBufferMemoryRequirements@ is
-    -- not enough, e.g. when doing interop with OpenGL.
-    minAllocationAlignment :: DeviceSize
-  , -- | Additional @pNext@ chain to be attached to @VkMemoryAllocateInfo@ used
-    -- for every allocation made by this pool. Optional.
-    --
-    -- Optional, can be null. If not null, it must point to a @pNext@ chain of
-    -- structures that can be attached to @VkMemoryAllocateInfo@. It can be
-    -- useful for special needs such as adding @VkExportMemoryAllocateInfoKHR@.
-    -- Structures pointed by this member must remain alive and unchanged for
-    -- the whole lifetime of the custom pool.
-    --
-    -- Please note that some structures, e.g.
-    -- @VkMemoryPriorityAllocateInfoEXT@, @VkMemoryDedicatedAllocateInfoKHR@,
-    -- can be attached automatically by this library when using other, more
-    -- convenient of its features.
-    memoryAllocateNext :: Ptr ()
-  }
-  deriving (Typeable)
-#if defined(GENERIC_INSTANCES)
-deriving instance Generic (PoolCreateInfo)
-#endif
-deriving instance Show PoolCreateInfo
-
-instance ToCStruct PoolCreateInfo where
-  withCStruct x f = allocaBytes 56 $ \p -> pokeCStruct p x (f p)
-  pokeCStruct p PoolCreateInfo{..} f = do
-    poke ((p `plusPtr` 0 :: Ptr Word32)) (memoryTypeIndex)
-    poke ((p `plusPtr` 4 :: Ptr PoolCreateFlags)) (flags)
-    poke ((p `plusPtr` 8 :: Ptr DeviceSize)) (blockSize)
-    poke ((p `plusPtr` 16 :: Ptr CSize)) (CSize (minBlockCount))
-    poke ((p `plusPtr` 24 :: Ptr CSize)) (CSize (maxBlockCount))
-    poke ((p `plusPtr` 32 :: Ptr CFloat)) (CFloat (priority))
-    poke ((p `plusPtr` 40 :: Ptr DeviceSize)) (minAllocationAlignment)
-    poke ((p `plusPtr` 48 :: Ptr (Ptr ()))) (memoryAllocateNext)
-    f
-  cStructSize = 56
-  cStructAlignment = 8
-  pokeZeroCStruct p f = do
-    poke ((p `plusPtr` 0 :: Ptr Word32)) (zero)
-    poke ((p `plusPtr` 4 :: Ptr PoolCreateFlags)) (zero)
-    poke ((p `plusPtr` 8 :: Ptr DeviceSize)) (zero)
-    poke ((p `plusPtr` 16 :: Ptr CSize)) (CSize (zero))
-    poke ((p `plusPtr` 24 :: Ptr CSize)) (CSize (zero))
-    poke ((p `plusPtr` 32 :: Ptr CFloat)) (CFloat (zero))
-    poke ((p `plusPtr` 40 :: Ptr DeviceSize)) (zero)
-    f
-
-instance FromCStruct PoolCreateInfo where
-  peekCStruct p = do
-    memoryTypeIndex <- peek @Word32 ((p `plusPtr` 0 :: Ptr Word32))
-    flags <- peek @PoolCreateFlags ((p `plusPtr` 4 :: Ptr PoolCreateFlags))
-    blockSize <- peek @DeviceSize ((p `plusPtr` 8 :: Ptr DeviceSize))
-    minBlockCount <- peek @CSize ((p `plusPtr` 16 :: Ptr CSize))
-    maxBlockCount <- peek @CSize ((p `plusPtr` 24 :: Ptr CSize))
-    priority <- peek @CFloat ((p `plusPtr` 32 :: Ptr CFloat))
-    minAllocationAlignment <- peek @DeviceSize ((p `plusPtr` 40 :: Ptr DeviceSize))
-    pMemoryAllocateNext <- peek @(Ptr ()) ((p `plusPtr` 48 :: Ptr (Ptr ())))
-    pure $ PoolCreateInfo
-             memoryTypeIndex flags blockSize (coerce @CSize @Word64 minBlockCount) (coerce @CSize @Word64 maxBlockCount) (coerce @CFloat @Float priority) minAllocationAlignment pMemoryAllocateNext
+import Vulkan (DeviceBufferMemoryRequirements)
+import Vulkan (DeviceImageMemoryRequirements)
+import Vulkan (DeviceMemory)
+import Vulkan (DeviceSize)
+import Vulkan (Device_T)
+import Vulkan (ExternalMemoryHandleTypeFlagsKHR)
+import Vulkan (Flags)
+import Vulkan (Image)
+import Vulkan (ImageCreateInfo)
+import Vulkan (ImageMemoryRequirementsInfo2)
+import Vulkan (Instance_T)
+import Vulkan (MappedMemoryRange)
+import Vulkan (MemoryAllocateInfo)
+import Vulkan (MemoryMapFlags)
+import Vulkan (MemoryPropertyFlags)
+import Vulkan (MemoryRequirements)
+import Vulkan (MemoryRequirements2)
+import Vulkan (PhysicalDeviceMemoryProperties)
+import Vulkan (PhysicalDeviceMemoryProperties2)
+import Vulkan (PhysicalDeviceProperties)
+import Vulkan (PhysicalDevice_T)
+import Vulkan (Result)
+import Vulkan.CStruct.Utils (FixedArray)
+import Vulkan.Internal.Utils (enumReadPrec)
+import Vulkan.Internal.Utils (enumShowsPrec)
+import Vulkan.Internal.Utils (traceAroundEvent)
+import Vulkan.CStruct.Extends (forgetExtensions)
+import Vulkan.CStruct.Utils (advancePtrBytes)
+import Vulkan.CStruct.Utils (lowerArrayPtr)
+import Vulkan.Core10.FundamentalTypes (bool32ToBool)
+import Vulkan.Core10.FundamentalTypes (boolToBool32)
+import Control.Exception.Base (bracket)
+import Control.Monad (unless)
+import Control.Monad.IO.Class (liftIO)
+import Foreign.Marshal.Alloc (allocaBytes)
+import Foreign.Marshal.Alloc (callocBytes)
+import Foreign.Marshal.Alloc (free)
+import Foreign.Marshal.Utils (maybePeek)
+import GHC.Base (when)
+import GHC.IO (throwIO)
+import Foreign.Ptr (nullPtr)
+import Foreign.Ptr (plusPtr)
+import GHC.Show (showParen)
+import GHC.Show (showString)
+import GHC.Show (showsPrec)
+import Numeric (showHex)
+import Data.ByteString (packCString)
+import Data.ByteString (useAsCString)
+import Data.Coerce (coerce)
+import Control.Monad.Trans.Class (lift)
+import Control.Monad.Trans.Cont (evalContT)
+import Data.Vector (generateM)
+import qualified Data.Vector (imapM_)
+import qualified Data.Vector (length)
+import qualified Data.Vector (null)
+import Vulkan.Core10.APIConstants (pattern MAX_MEMORY_HEAPS)
+import Vulkan.Core10.APIConstants (pattern MAX_MEMORY_TYPES)
+import Vulkan.Core10.Enums.Result (pattern SUCCESS)
+import Foreign.C.Types (CChar(..))
+import Foreign.C.Types (CSize(..))
+import Vulkan (Bool32(..))
+import Vulkan (Buffer(..))
+import Vulkan (Image(..))
+import Vulkan (MemoryPropertyFlagBits(..))
+import Vulkan (Result(..))
+import Vulkan.CStruct (FromCStruct)
+import Vulkan.CStruct (FromCStruct(..))
+import Vulkan.CStruct (ToCStruct)
+import Vulkan.CStruct (ToCStruct(..))
+import Vulkan.CStruct.Extends (Extendss)
+import Vulkan.CStruct.Extends (PokeChain)
+import Vulkan.CStruct.Extends (SomeStruct)
+import Vulkan.Core10.APIConstants (IsHandle)
+import Vulkan.Core10.APIConstants (MAX_MEMORY_HEAPS)
+import Vulkan.Core10.APIConstants (MAX_MEMORY_TYPES)
+import Vulkan.Exception (VulkanException(..))
+import Vulkan.NamedType ((:::))
+import Vulkan.Zero (Zero)
+import Vulkan.Zero (Zero(..))
+import Control.Monad.IO.Class (MonadIO)
+import Data.Bits (Bits)
+import Data.Bits (FiniteBits)
+import Data.Typeable (Typeable)
+import Foreign.C.Types (CChar)
+import Foreign.C.Types (CFloat)
+import Foreign.C.Types (CFloat(..))
+import Foreign.C.Types (CFloat(CFloat))
+import Foreign.C.Types (CSize)
+import Foreign.C.Types (CSize(..))
+import Foreign.C.Types (CSize(CSize))
+import Foreign.Storable (Storable)
+import Foreign.Storable (Storable(peek))
+import Foreign.Storable (Storable(poke))
+import qualified Foreign.Storable (Storable(..))
+import GHC.Generics (Generic)
+import GHC.IO.Exception (IOErrorType(..))
+import GHC.IO.Exception (IOException(..))
+import Data.Int (Int32)
+import Foreign.Ptr (FunPtr)
+import Foreign.Ptr (Ptr)
+import GHC.Read (Read(readPrec))
+import GHC.Show (Show(showsPrec))
+import Data.Word (Word32)
+import Data.Word (Word64)
+import Data.ByteString (ByteString)
+import Data.Kind (Type)
+import Control.Monad.Trans.Cont (ContT(..))
+import Data.Vector (Vector)
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaCreateAllocator" ffiVmaCreateAllocator
+  :: Ptr AllocatorCreateInfo -> Ptr Allocator -> IO Result
+
+-- | Creates 'Allocator' object.
+createAllocator :: forall io
+                 . (MonadIO io)
+                => -- No documentation found for Nested "vmaCreateAllocator" "pCreateInfo"
+                   AllocatorCreateInfo
+                -> io (Allocator)
+createAllocator createInfo = liftIO . evalContT $ do
+  pCreateInfo <- ContT $ withCStruct (createInfo)
+  pPAllocator <- ContT $ bracket (callocBytes @Allocator 8) free
+  r <- lift $ traceAroundEvent "vmaCreateAllocator" ((ffiVmaCreateAllocator)
+                                                       pCreateInfo
+                                                       (pPAllocator))
+  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
+  pAllocator <- lift $ peek @Allocator pPAllocator
+  pure $ (pAllocator)
+
+-- | A convenience wrapper to make a compatible pair of calls to
+-- 'createAllocator' and 'destroyAllocator'
+--
+-- To ensure that 'destroyAllocator' is always called: pass
+-- 'Control.Exception.bracket' (or the allocate function from your
+-- favourite resource management library) as the last argument.
+-- To just extract the pair pass '(,)' as the last argument.
+--
+withAllocator :: forall io r . MonadIO io => AllocatorCreateInfo -> (io Allocator -> (Allocator -> io ()) -> r) -> r
+withAllocator pCreateInfo b =
+  b (createAllocator pCreateInfo)
+    (\(o0) -> destroyAllocator o0)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaDestroyAllocator" ffiVmaDestroyAllocator
+  :: Allocator -> IO ()
+
+-- | Destroys allocator object.
+destroyAllocator :: forall io
+                  . (MonadIO io)
+                 => -- No documentation found for Nested "vmaDestroyAllocator" "allocator"
+                    Allocator
+                 -> io ()
+destroyAllocator allocator = liftIO $ do
+  traceAroundEvent "vmaDestroyAllocator" ((ffiVmaDestroyAllocator) (allocator))
+  pure $ ()
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaGetAllocatorInfo" ffiVmaGetAllocatorInfo
+  :: Allocator -> Ptr AllocatorInfo -> IO ()
+
+-- | Returns information about existing 'Allocator' object - handle to Vulkan
+-- device etc.
+--
+-- It might be useful if you want to keep just the 'Allocator' handle and
+-- fetch other required handles to @VkPhysicalDevice@, @VkDevice@ etc.
+-- every time using this function.
+getAllocatorInfo :: forall io
+                  . (MonadIO io)
+                 => -- No documentation found for Nested "vmaGetAllocatorInfo" "allocator"
+                    Allocator
+                 -> io (AllocatorInfo)
+getAllocatorInfo allocator = liftIO . evalContT $ do
+  pPAllocatorInfo <- ContT (withZeroCStruct @AllocatorInfo)
+  lift $ traceAroundEvent "vmaGetAllocatorInfo" ((ffiVmaGetAllocatorInfo)
+                                                   (allocator)
+                                                   (pPAllocatorInfo))
+  pAllocatorInfo <- lift $ peekCStruct @AllocatorInfo pPAllocatorInfo
+  pure $ (pAllocatorInfo)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaGetPhysicalDeviceProperties" ffiVmaGetPhysicalDeviceProperties
+  :: Allocator -> Ptr (Ptr PhysicalDeviceProperties) -> IO ()
+
+-- | PhysicalDeviceProperties are fetched from physicalDevice by the
+-- allocator. You can access it here, without fetching it again on your
+-- own.
+getPhysicalDeviceProperties :: forall io
+                             . (MonadIO io)
+                            => -- No documentation found for Nested "vmaGetPhysicalDeviceProperties" "allocator"
+                               Allocator
+                            -> io (Ptr PhysicalDeviceProperties)
+getPhysicalDeviceProperties allocator = liftIO . evalContT $ do
+  pPpPhysicalDeviceProperties <- ContT $ bracket (callocBytes @(Ptr PhysicalDeviceProperties) 8) free
+  lift $ traceAroundEvent "vmaGetPhysicalDeviceProperties" ((ffiVmaGetPhysicalDeviceProperties)
+                                                              (allocator)
+                                                              (pPpPhysicalDeviceProperties))
+  ppPhysicalDeviceProperties <- lift $ peek @(Ptr PhysicalDeviceProperties) pPpPhysicalDeviceProperties
+  pure $ (ppPhysicalDeviceProperties)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaGetMemoryProperties" ffiVmaGetMemoryProperties
+  :: Allocator -> Ptr (Ptr PhysicalDeviceMemoryProperties) -> IO ()
+
+-- | PhysicalDeviceMemoryProperties are fetched from physicalDevice by the
+-- allocator. You can access it here, without fetching it again on your
+-- own.
+getMemoryProperties :: forall io
+                     . (MonadIO io)
+                    => -- No documentation found for Nested "vmaGetMemoryProperties" "allocator"
+                       Allocator
+                    -> io (Ptr PhysicalDeviceMemoryProperties)
+getMemoryProperties allocator = liftIO . evalContT $ do
+  pPpPhysicalDeviceMemoryProperties <- ContT $ bracket (callocBytes @(Ptr PhysicalDeviceMemoryProperties) 8) free
+  lift $ traceAroundEvent "vmaGetMemoryProperties" ((ffiVmaGetMemoryProperties)
+                                                      (allocator)
+                                                      (pPpPhysicalDeviceMemoryProperties))
+  ppPhysicalDeviceMemoryProperties <- lift $ peek @(Ptr PhysicalDeviceMemoryProperties) pPpPhysicalDeviceMemoryProperties
+  pure $ (ppPhysicalDeviceMemoryProperties)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaGetMemoryTypeProperties" ffiVmaGetMemoryTypeProperties
+  :: Allocator -> Word32 -> Ptr MemoryPropertyFlags -> IO ()
+
+-- | Given Memory Type Index, returns Property Flags of this memory type.
+--
+-- This is just a convenience function. Same information can be obtained
+-- using 'getMemoryProperties'.
+getMemoryTypeProperties :: forall io
+                         . (MonadIO io)
+                        => -- No documentation found for Nested "vmaGetMemoryTypeProperties" "allocator"
+                           Allocator
+                        -> -- No documentation found for Nested "vmaGetMemoryTypeProperties" "memoryTypeIndex"
+                           ("memoryTypeIndex" ::: Word32)
+                        -> io (MemoryPropertyFlags)
+getMemoryTypeProperties allocator memoryTypeIndex = liftIO . evalContT $ do
+  pPFlags <- ContT $ bracket (callocBytes @MemoryPropertyFlags 4) free
+  lift $ traceAroundEvent "vmaGetMemoryTypeProperties" ((ffiVmaGetMemoryTypeProperties)
+                                                          (allocator)
+                                                          (memoryTypeIndex)
+                                                          (pPFlags))
+  pFlags <- lift $ peek @MemoryPropertyFlags pPFlags
+  pure $ (pFlags)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaSetCurrentFrameIndex" ffiVmaSetCurrentFrameIndex
+  :: Allocator -> Word32 -> IO ()
+
+-- | Sets index of the current frame.
+setCurrentFrameIndex :: forall io
+                      . (MonadIO io)
+                     => -- No documentation found for Nested "vmaSetCurrentFrameIndex" "allocator"
+                        Allocator
+                     -> -- No documentation found for Nested "vmaSetCurrentFrameIndex" "frameIndex"
+                        ("frameIndex" ::: Word32)
+                     -> io ()
+setCurrentFrameIndex allocator frameIndex = liftIO $ do
+  traceAroundEvent "vmaSetCurrentFrameIndex" ((ffiVmaSetCurrentFrameIndex)
+                                                (allocator)
+                                                (frameIndex))
+  pure $ ()
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaCalculateStatistics" ffiVmaCalculateStatistics
+  :: Allocator -> Ptr TotalStatistics -> IO ()
+
+-- | Retrieves statistics from current state of the Allocator.
+--
+-- This function is called \"calculate\" not \"get\" because it has to
+-- traverse all internal data structures, so it may be quite slow. Use it
+-- for debugging purposes. For faster but more brief statistics suitable to
+-- be called every frame or every allocation, use 'getHeapBudgets'.
+--
+-- Note that when using allocator from multiple threads, returned
+-- information may immediately become outdated.
+calculateStatistics :: forall io
+                     . (MonadIO io)
+                    => -- No documentation found for Nested "vmaCalculateStatistics" "allocator"
+                       Allocator
+                    -> io (("stats" ::: TotalStatistics))
+calculateStatistics allocator = liftIO . evalContT $ do
+  pPStats <- ContT (withZeroCStruct @TotalStatistics)
+  lift $ traceAroundEvent "vmaCalculateStatistics" ((ffiVmaCalculateStatistics)
+                                                      (allocator)
+                                                      (pPStats))
+  pStats <- lift $ peekCStruct @TotalStatistics pPStats
+  pure $ (pStats)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaGetHeapBudgets" ffiVmaGetHeapBudgets
+  :: Allocator -> Ptr Budget -> IO ()
+
+-- | Retrieves information about current memory usage and budget for all
+-- memory heaps.
+--
+-- __Parameters__
+--
+-- +-----------+-----------+-----------------------------------------------+
+-- |           | allocator |                                               |
+-- +-----------+-----------+-----------------------------------------------+
+-- | out       | pBudgets  | Must point to array with number of elements   |
+-- |           |           | at least equal to number of memory heaps in   |
+-- |           |           | physical device used.                         |
+-- +-----------+-----------+-----------------------------------------------+
+--
+-- This function is called \"get\" not \"calculate\" because it is very
+-- fast, suitable to be called every frame or every allocation. For more
+-- detailed statistics use 'calculateStatistics'.
+--
+-- Note that when using allocator from multiple threads, returned
+-- information may immediately become outdated.
+getHeapBudgets :: forall io
+                . (MonadIO io)
+               => -- No documentation found for Nested "vmaGetHeapBudgets" "allocator"
+                  Allocator
+               -> -- No documentation found for Nested "vmaGetHeapBudgets" "pBudgets"
+                  ("budgets" ::: Ptr Budget)
+               -> io ()
+getHeapBudgets allocator budgets = liftIO $ do
+  traceAroundEvent "vmaGetHeapBudgets" ((ffiVmaGetHeapBudgets)
+                                          (allocator)
+                                          (budgets))
+  pure $ ()
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaFindMemoryTypeIndex" ffiVmaFindMemoryTypeIndex
+  :: Allocator -> Word32 -> Ptr AllocationCreateInfo -> Ptr Word32 -> IO Result
+
+-- | Helps to find memoryTypeIndex, given memoryTypeBits and
+-- 'AllocationCreateInfo'.
+--
+-- This algorithm tries to find a memory type that:
+--
+-- -   Is allowed by memoryTypeBits.
+--
+-- -   Contains all the flags from pAllocationCreateInfo->requiredFlags.
+--
+-- -   Matches intended usage.
+--
+-- -   Has as many flags from pAllocationCreateInfo->preferredFlags as
+--     possible.
+--
+-- __Returns__
+--
+-- Returns VK_ERROR_FEATURE_NOT_PRESENT if not found. Receiving such result
+-- from this function or any other allocating function probably means that
+-- your device doesn\'t support any memory type with requested features for
+-- the specific type of resource you want to use it for. Please check
+-- parameters of your resource, like image layout (OPTIMAL versus LINEAR)
+-- or mip level count.
+findMemoryTypeIndex :: forall io
+                     . (MonadIO io)
+                    => -- No documentation found for Nested "vmaFindMemoryTypeIndex" "allocator"
+                       Allocator
+                    -> -- No documentation found for Nested "vmaFindMemoryTypeIndex" "memoryTypeBits"
+                       ("memoryTypeBits" ::: Word32)
+                    -> -- No documentation found for Nested "vmaFindMemoryTypeIndex" "pAllocationCreateInfo"
+                       AllocationCreateInfo
+                    -> io (("memoryTypeIndex" ::: Word32))
+findMemoryTypeIndex allocator
+                      memoryTypeBits
+                      allocationCreateInfo = liftIO . evalContT $ do
+  pAllocationCreateInfo <- ContT $ withCStruct (allocationCreateInfo)
+  pPMemoryTypeIndex <- ContT $ bracket (callocBytes @Word32 4) free
+  r <- lift $ traceAroundEvent "vmaFindMemoryTypeIndex" ((ffiVmaFindMemoryTypeIndex)
+                                                           (allocator)
+                                                           (memoryTypeBits)
+                                                           pAllocationCreateInfo
+                                                           (pPMemoryTypeIndex))
+  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
+  pMemoryTypeIndex <- lift $ peek @Word32 pPMemoryTypeIndex
+  pure $ (pMemoryTypeIndex)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaFindMemoryTypeIndexForBufferInfo" ffiVmaFindMemoryTypeIndexForBufferInfo
+  :: Allocator -> Ptr (SomeStruct BufferCreateInfo) -> Ptr AllocationCreateInfo -> Ptr Word32 -> IO Result
+
+-- | Helps to find memoryTypeIndex, given VkBufferCreateInfo and
+-- 'AllocationCreateInfo'.
+--
+-- It can be useful e.g. to determine value to be used as
+-- /VmaPoolCreateInfo::memoryTypeIndex/. It internally creates a temporary,
+-- dummy buffer that never has memory bound.
+findMemoryTypeIndexForBufferInfo :: forall a io
+                                  . ( Extendss BufferCreateInfo a
+                                    , PokeChain a
+                                    , MonadIO io )
+                                 => -- No documentation found for Nested "vmaFindMemoryTypeIndexForBufferInfo" "allocator"
+                                    Allocator
+                                 -> -- No documentation found for Nested "vmaFindMemoryTypeIndexForBufferInfo" "pBufferCreateInfo"
+                                    (BufferCreateInfo a)
+                                 -> -- No documentation found for Nested "vmaFindMemoryTypeIndexForBufferInfo" "pAllocationCreateInfo"
+                                    AllocationCreateInfo
+                                 -> io (("memoryTypeIndex" ::: Word32))
+findMemoryTypeIndexForBufferInfo allocator
+                                   bufferCreateInfo
+                                   allocationCreateInfo = liftIO . evalContT $ do
+  pBufferCreateInfo <- ContT $ withCStruct (bufferCreateInfo)
+  pAllocationCreateInfo <- ContT $ withCStruct (allocationCreateInfo)
+  pPMemoryTypeIndex <- ContT $ bracket (callocBytes @Word32 4) free
+  r <- lift $ traceAroundEvent "vmaFindMemoryTypeIndexForBufferInfo" ((ffiVmaFindMemoryTypeIndexForBufferInfo)
+                                                                        (allocator)
+                                                                        (forgetExtensions pBufferCreateInfo)
+                                                                        pAllocationCreateInfo
+                                                                        (pPMemoryTypeIndex))
+  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
+  pMemoryTypeIndex <- lift $ peek @Word32 pPMemoryTypeIndex
+  pure $ (pMemoryTypeIndex)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaFindMemoryTypeIndexForImageInfo" ffiVmaFindMemoryTypeIndexForImageInfo
+  :: Allocator -> Ptr (SomeStruct ImageCreateInfo) -> Ptr AllocationCreateInfo -> Ptr Word32 -> IO Result
+
+-- | Helps to find memoryTypeIndex, given VkImageCreateInfo and
+-- 'AllocationCreateInfo'.
+--
+-- It can be useful e.g. to determine value to be used as
+-- /VmaPoolCreateInfo::memoryTypeIndex/. It internally creates a temporary,
+-- dummy image that never has memory bound.
+findMemoryTypeIndexForImageInfo :: forall a io
+                                 . ( Extendss ImageCreateInfo a
+                                   , PokeChain a
+                                   , MonadIO io )
+                                => -- No documentation found for Nested "vmaFindMemoryTypeIndexForImageInfo" "allocator"
+                                   Allocator
+                                -> -- No documentation found for Nested "vmaFindMemoryTypeIndexForImageInfo" "pImageCreateInfo"
+                                   (ImageCreateInfo a)
+                                -> -- No documentation found for Nested "vmaFindMemoryTypeIndexForImageInfo" "pAllocationCreateInfo"
+                                   AllocationCreateInfo
+                                -> io (("memoryTypeIndex" ::: Word32))
+findMemoryTypeIndexForImageInfo allocator
+                                  imageCreateInfo
+                                  allocationCreateInfo = liftIO . evalContT $ do
+  pImageCreateInfo <- ContT $ withCStruct (imageCreateInfo)
+  pAllocationCreateInfo <- ContT $ withCStruct (allocationCreateInfo)
+  pPMemoryTypeIndex <- ContT $ bracket (callocBytes @Word32 4) free
+  r <- lift $ traceAroundEvent "vmaFindMemoryTypeIndexForImageInfo" ((ffiVmaFindMemoryTypeIndexForImageInfo)
+                                                                       (allocator)
+                                                                       (forgetExtensions pImageCreateInfo)
+                                                                       pAllocationCreateInfo
+                                                                       (pPMemoryTypeIndex))
+  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
+  pMemoryTypeIndex <- lift $ peek @Word32 pPMemoryTypeIndex
+  pure $ (pMemoryTypeIndex)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaCreatePool" ffiVmaCreatePool
+  :: Allocator -> Ptr PoolCreateInfo -> Ptr Pool -> IO Result
+
+-- | Allocates Vulkan device memory and creates 'Pool' object.
+--
+-- __Parameters__
+--
+-- +-----------+-------------+-----------------------------------------------+
+-- |           | allocator   | Allocator object.                             |
+-- +-----------+-------------+-----------------------------------------------+
+-- |           | pCreateInfo | Parameters of pool to create.                 |
+-- +-----------+-------------+-----------------------------------------------+
+-- | out       | pPool       | Handle to created pool.                       |
+-- +-----------+-------------+-----------------------------------------------+
+createPool :: forall io
+            . (MonadIO io)
+           => -- No documentation found for Nested "vmaCreatePool" "allocator"
+              Allocator
+           -> -- No documentation found for Nested "vmaCreatePool" "pCreateInfo"
+              PoolCreateInfo
+           -> io (Pool)
+createPool allocator createInfo = liftIO . evalContT $ do
+  pCreateInfo <- ContT $ withCStruct (createInfo)
+  pPPool <- ContT $ bracket (callocBytes @Pool 8) free
+  r <- lift $ traceAroundEvent "vmaCreatePool" ((ffiVmaCreatePool)
+                                                  (allocator)
+                                                  pCreateInfo
+                                                  (pPPool))
+  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
+  pPool <- lift $ peek @Pool pPPool
+  pure $ (pPool)
+
+-- | A convenience wrapper to make a compatible pair of calls to 'createPool'
+-- and 'destroyPool'
+--
+-- To ensure that 'destroyPool' is always called: pass
+-- 'Control.Exception.bracket' (or the allocate function from your
+-- favourite resource management library) as the last argument.
+-- To just extract the pair pass '(,)' as the last argument.
+--
+withPool :: forall io r . MonadIO io => Allocator -> PoolCreateInfo -> (io Pool -> (Pool -> io ()) -> r) -> r
+withPool allocator pCreateInfo b =
+  b (createPool allocator pCreateInfo)
+    (\(o0) -> destroyPool allocator o0)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaDestroyPool" ffiVmaDestroyPool
+  :: Allocator -> Pool -> IO ()
+
+-- | Destroys 'Pool' object and frees Vulkan device memory.
+destroyPool :: forall io
+             . (MonadIO io)
+            => -- No documentation found for Nested "vmaDestroyPool" "allocator"
+               Allocator
+            -> -- No documentation found for Nested "vmaDestroyPool" "pool"
+               Pool
+            -> io ()
+destroyPool allocator pool = liftIO $ do
+  traceAroundEvent "vmaDestroyPool" ((ffiVmaDestroyPool) (allocator) (pool))
+  pure $ ()
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaGetPoolStatistics" ffiVmaGetPoolStatistics
+  :: Allocator -> Pool -> Ptr Statistics -> IO ()
+
+-- | Retrieves statistics of existing 'Pool' object.
+--
+-- __Parameters__
+--
+-- +-----------+------------+-----------------------------------------------+
+-- |           | allocator  | Allocator object.                             |
+-- +-----------+------------+-----------------------------------------------+
+-- |           | pool       | Pool object.                                  |
+-- +-----------+------------+-----------------------------------------------+
+-- | out       | pPoolStats | Statistics of specified pool.                 |
+-- +-----------+------------+-----------------------------------------------+
+getPoolStatistics :: forall io
+                   . (MonadIO io)
+                  => -- No documentation found for Nested "vmaGetPoolStatistics" "allocator"
+                     Allocator
+                  -> -- No documentation found for Nested "vmaGetPoolStatistics" "pool"
+                     Pool
+                  -> io (("poolStats" ::: Statistics))
+getPoolStatistics allocator pool = liftIO . evalContT $ do
+  pPPoolStats <- ContT (withZeroCStruct @Statistics)
+  lift $ traceAroundEvent "vmaGetPoolStatistics" ((ffiVmaGetPoolStatistics)
+                                                    (allocator)
+                                                    (pool)
+                                                    (pPPoolStats))
+  pPoolStats <- lift $ peekCStruct @Statistics pPPoolStats
+  pure $ (pPoolStats)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaCalculatePoolStatistics" ffiVmaCalculatePoolStatistics
+  :: Allocator -> Pool -> Ptr DetailedStatistics -> IO ()
+
+-- | Retrieves detailed statistics of existing 'Pool' object.
+--
+-- __Parameters__
+--
+-- +-----------+------------+-----------------------------------------------+
+-- |           | allocator  | Allocator object.                             |
+-- +-----------+------------+-----------------------------------------------+
+-- |           | pool       | Pool object.                                  |
+-- +-----------+------------+-----------------------------------------------+
+-- | out       | pPoolStats | Statistics of specified pool.                 |
+-- +-----------+------------+-----------------------------------------------+
+calculatePoolStatistics :: forall io
+                         . (MonadIO io)
+                        => -- No documentation found for Nested "vmaCalculatePoolStatistics" "allocator"
+                           Allocator
+                        -> -- No documentation found for Nested "vmaCalculatePoolStatistics" "pool"
+                           Pool
+                        -> io (("poolStats" ::: DetailedStatistics))
+calculatePoolStatistics allocator pool = liftIO . evalContT $ do
+  pPPoolStats <- ContT (withZeroCStruct @DetailedStatistics)
+  lift $ traceAroundEvent "vmaCalculatePoolStatistics" ((ffiVmaCalculatePoolStatistics)
+                                                          (allocator)
+                                                          (pool)
+                                                          (pPPoolStats))
+  pPoolStats <- lift $ peekCStruct @DetailedStatistics pPPoolStats
+  pure $ (pPoolStats)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaCheckPoolCorruption" ffiVmaCheckPoolCorruption
+  :: Allocator -> Pool -> IO Result
+
+-- | Checks magic number in margins around all allocations in given memory
+-- pool in search for corruptions.
+--
+-- Corruption detection is enabled only when @VMA_DEBUG_DETECT_CORRUPTION@
+-- macro is defined to nonzero, @VMA_DEBUG_MARGIN@ is defined to nonzero
+-- and the pool is created in memory type that is @HOST_VISIBLE@ and
+-- @HOST_COHERENT@. For more information, see /Corruption detection/.
+--
+-- Possible return values:
+--
+-- -   @VK_ERROR_FEATURE_NOT_PRESENT@ - corruption detection is not enabled
+--     for specified pool.
+--
+-- -   @VK_SUCCESS@ - corruption detection has been performed and
+--     succeeded.
+--
+-- -   @VK_ERROR_UNKNOWN@ - corruption detection has been performed and
+--     found memory corruptions around one of the allocations. @VMA_ASSERT@
+--     is also fired in that case.
+--
+-- -   Other value: Error returned by Vulkan, e.g. memory mapping failure.
+checkPoolCorruption :: forall io
+                     . (MonadIO io)
+                    => -- No documentation found for Nested "vmaCheckPoolCorruption" "allocator"
+                       Allocator
+                    -> -- No documentation found for Nested "vmaCheckPoolCorruption" "pool"
+                       Pool
+                    -> io ()
+checkPoolCorruption allocator pool = liftIO $ do
+  r <- traceAroundEvent "vmaCheckPoolCorruption" ((ffiVmaCheckPoolCorruption)
+                                                    (allocator)
+                                                    (pool))
+  when (r < SUCCESS) (throwIO (VulkanException r))
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaGetPoolName" ffiVmaGetPoolName
+  :: Allocator -> Pool -> Ptr (Ptr CChar) -> IO ()
+
+-- | Retrieves name of a custom pool.
+--
+-- After the call @ppName@ is either null or points to an internally-owned
+-- null-terminated string containing name of the pool that was previously
+-- set. The pointer becomes invalid when the pool is destroyed or its name
+-- is changed using 'setPoolName'.
+getPoolName :: forall io
+             . (MonadIO io)
+            => -- No documentation found for Nested "vmaGetPoolName" "allocator"
+               Allocator
+            -> -- No documentation found for Nested "vmaGetPoolName" "pool"
+               Pool
+            -> io (("name" ::: Ptr CChar))
+getPoolName allocator pool = liftIO . evalContT $ do
+  pPpName <- ContT $ bracket (callocBytes @(Ptr CChar) 8) free
+  lift $ traceAroundEvent "vmaGetPoolName" ((ffiVmaGetPoolName)
+                                              (allocator)
+                                              (pool)
+                                              (pPpName))
+  ppName <- lift $ peek @(Ptr CChar) pPpName
+  pure $ (ppName)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaSetPoolName" ffiVmaSetPoolName
+  :: Allocator -> Pool -> Ptr CChar -> IO ()
+
+-- | Sets name of a custom pool.
+--
+-- @pName@ can be either null or pointer to a null-terminated string with
+-- new name for the pool. Function makes internal copy of the string, so it
+-- can be changed or freed immediately after this call.
+setPoolName :: forall io
+             . (MonadIO io)
+            => -- No documentation found for Nested "vmaSetPoolName" "allocator"
+               Allocator
+            -> -- No documentation found for Nested "vmaSetPoolName" "pool"
+               Pool
+            -> -- No documentation found for Nested "vmaSetPoolName" "pName"
+               ("name" ::: Maybe ByteString)
+            -> io ()
+setPoolName allocator pool name = liftIO . evalContT $ do
+  pName <- case (name) of
+    Nothing -> pure nullPtr
+    Just j -> ContT $ useAsCString (j)
+  lift $ traceAroundEvent "vmaSetPoolName" ((ffiVmaSetPoolName)
+                                              (allocator)
+                                              (pool)
+                                              pName)
+  pure $ ()
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaAllocateMemory" ffiVmaAllocateMemory
+  :: Allocator -> Ptr MemoryRequirements -> Ptr AllocationCreateInfo -> Ptr Allocation -> Ptr AllocationInfo -> IO Result
+
+-- | General purpose memory allocation.
+--
+-- __Parameters__
+--
+-- +-----------+-----------------------+-----------------------------------------------+
+-- |           | allocator             |                                               |
+-- +-----------+-----------------------+-----------------------------------------------+
+-- |           | pVkMemoryRequirements |                                               |
+-- +-----------+-----------------------+-----------------------------------------------+
+-- |           | pCreateInfo           |                                               |
+-- +-----------+-----------------------+-----------------------------------------------+
+-- | out       | pAllocation           | Handle to allocated memory.                   |
+-- +-----------+-----------------------+-----------------------------------------------+
+-- | out       | pAllocationInfo       | Optional. Information about allocated memory. |
+-- |           |                       | It can be later fetched using function        |
+-- |           |                       | 'getAllocationInfo'.                          |
+-- +-----------+-----------------------+-----------------------------------------------+
+--
+-- You should free the memory using 'freeMemory' or 'freeMemoryPages'.
+--
+-- It is recommended to use 'allocateMemoryForBuffer',
+-- 'allocateMemoryForImage', 'createBuffer', 'createImage' instead whenever
+-- possible.
+allocateMemory :: forall io
+                . (MonadIO io)
+               => -- No documentation found for Nested "vmaAllocateMemory" "allocator"
+                  Allocator
+               -> -- No documentation found for Nested "vmaAllocateMemory" "pVkMemoryRequirements"
+                  ("vkMemoryRequirements" ::: MemoryRequirements)
+               -> -- No documentation found for Nested "vmaAllocateMemory" "pCreateInfo"
+                  AllocationCreateInfo
+               -> io (Allocation, AllocationInfo)
+allocateMemory allocator
+                 vkMemoryRequirements
+                 createInfo = liftIO . evalContT $ do
+  pVkMemoryRequirements <- ContT $ withCStruct (vkMemoryRequirements)
+  pCreateInfo <- ContT $ withCStruct (createInfo)
+  pPAllocation <- ContT $ bracket (callocBytes @Allocation 8) free
+  pPAllocationInfo <- ContT (withZeroCStruct @AllocationInfo)
+  r <- lift $ traceAroundEvent "vmaAllocateMemory" ((ffiVmaAllocateMemory)
+                                                      (allocator)
+                                                      pVkMemoryRequirements
+                                                      pCreateInfo
+                                                      (pPAllocation)
+                                                      (pPAllocationInfo))
+  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
+  pAllocation <- lift $ peek @Allocation pPAllocation
+  pAllocationInfo <- lift $ peekCStruct @AllocationInfo pPAllocationInfo
+  pure $ (pAllocation, pAllocationInfo)
+
+-- | A convenience wrapper to make a compatible pair of calls to
+-- 'allocateMemory' and 'freeMemory'
+--
+-- To ensure that 'freeMemory' is always called: pass
+-- 'Control.Exception.bracket' (or the allocate function from your
+-- favourite resource management library) as the last argument.
+-- To just extract the pair pass '(,)' as the last argument.
+--
+withMemory :: forall io r . MonadIO io => Allocator -> MemoryRequirements -> AllocationCreateInfo -> (io (Allocation, AllocationInfo) -> ((Allocation, AllocationInfo) -> io ()) -> r) -> r
+withMemory allocator pVkMemoryRequirements pCreateInfo b =
+  b (allocateMemory allocator pVkMemoryRequirements pCreateInfo)
+    (\(o0, _) -> freeMemory allocator o0)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaAllocateMemoryPages" ffiVmaAllocateMemoryPages
+  :: Allocator -> Ptr MemoryRequirements -> Ptr AllocationCreateInfo -> CSize -> Ptr Allocation -> Ptr AllocationInfo -> IO Result
+
+-- | General purpose memory allocation for multiple allocation objects at
+-- once.
+--
+-- __Parameters__
+--
+-- +-----------+-----------------------+-----------------------------------------------+
+-- |           | allocator             | Allocator object.                             |
+-- +-----------+-----------------------+-----------------------------------------------+
+-- |           | pVkMemoryRequirements | Memory requirements for each allocation.      |
+-- +-----------+-----------------------+-----------------------------------------------+
+-- |           | pCreateInfo           | Creation parameters for each allocation.      |
+-- +-----------+-----------------------+-----------------------------------------------+
+-- |           | allocationCount       | Number of allocations to make.                |
+-- +-----------+-----------------------+-----------------------------------------------+
+-- | out       | pAllocations          | Pointer to array that will be filled with     |
+-- |           |                       | handles to created allocations.               |
+-- +-----------+-----------------------+-----------------------------------------------+
+-- | out       | pAllocationInfo       | Optional. Pointer to array that will be       |
+-- |           |                       | filled with parameters of created             |
+-- |           |                       | allocations.                                  |
+-- +-----------+-----------------------+-----------------------------------------------+
+--
+-- You should free the memory using 'freeMemory' or 'freeMemoryPages'.
+--
+-- Word \"pages\" is just a suggestion to use this function to allocate
+-- pieces of memory needed for sparse binding. It is just a general purpose
+-- allocation function able to make multiple allocations at once. It may be
+-- internally optimized to be more efficient than calling 'allocateMemory'
+-- @allocationCount@ times.
+--
+-- All allocations are made using same parameters. All of them are created
+-- out of the same memory pool and type. If any allocation fails, all
+-- allocations already made within this function call are also freed, so
+-- that when returned result is not @VK_SUCCESS@, @pAllocation@ array is
+-- always entirely filled with @VK_NULL_HANDLE@.
+allocateMemoryPages :: forall io
+                     . (MonadIO io)
+                    => -- No documentation found for Nested "vmaAllocateMemoryPages" "allocator"
+                       Allocator
+                    -> -- No documentation found for Nested "vmaAllocateMemoryPages" "pVkMemoryRequirements"
+                       ("vkMemoryRequirements" ::: Vector MemoryRequirements)
+                    -> -- No documentation found for Nested "vmaAllocateMemoryPages" "pCreateInfo"
+                       ("createInfo" ::: Vector AllocationCreateInfo)
+                    -> io (("allocations" ::: Vector Allocation), ("allocationInfo" ::: Vector AllocationInfo))
+allocateMemoryPages allocator
+                      vkMemoryRequirements
+                      createInfo = liftIO . evalContT $ do
+  pPVkMemoryRequirements <- ContT $ allocaBytes @MemoryRequirements ((Data.Vector.length (vkMemoryRequirements)) * 24)
+  Data.Vector.imapM_ (\i e -> ContT $ pokeCStruct (pPVkMemoryRequirements `plusPtr` (24 * (i)) :: Ptr MemoryRequirements) (e) . ($ ())) (vkMemoryRequirements)
+  pPCreateInfo <- ContT $ allocaBytes @AllocationCreateInfo ((Data.Vector.length (createInfo)) * 48)
+  lift $ Data.Vector.imapM_ (\i e -> poke (pPCreateInfo `plusPtr` (48 * (i)) :: Ptr AllocationCreateInfo) (e)) (createInfo)
+  let pVkMemoryRequirementsLength = Data.Vector.length $ (vkMemoryRequirements)
+  lift $ unless ((Data.Vector.length $ (createInfo)) == pVkMemoryRequirementsLength) $
+    throwIO $ IOError Nothing InvalidArgument "" "pCreateInfo and pVkMemoryRequirements must have the same length" Nothing Nothing
+  pPAllocations <- ContT $ bracket (callocBytes @Allocation ((fromIntegral ((fromIntegral pVkMemoryRequirementsLength :: CSize))) * 8)) free
+  pPAllocationInfo <- ContT $ bracket (callocBytes @AllocationInfo ((fromIntegral ((fromIntegral pVkMemoryRequirementsLength :: CSize))) * 56)) free
+  _ <- traverse (\i -> ContT $ pokeZeroCStruct (pPAllocationInfo `advancePtrBytes` (i * 56) :: Ptr AllocationInfo) . ($ ())) [0..(fromIntegral ((fromIntegral pVkMemoryRequirementsLength :: CSize))) - 1]
+  r <- lift $ traceAroundEvent "vmaAllocateMemoryPages" ((ffiVmaAllocateMemoryPages)
+                                                           (allocator)
+                                                           (pPVkMemoryRequirements)
+                                                           (pPCreateInfo)
+                                                           ((fromIntegral pVkMemoryRequirementsLength :: CSize))
+                                                           (pPAllocations)
+                                                           ((pPAllocationInfo)))
+  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
+  pAllocations <- lift $ generateM (fromIntegral ((fromIntegral pVkMemoryRequirementsLength :: CSize))) (\i -> peek @Allocation ((pPAllocations `advancePtrBytes` (8 * (i)) :: Ptr Allocation)))
+  pAllocationInfo <- lift $ generateM (fromIntegral ((fromIntegral pVkMemoryRequirementsLength :: CSize))) (\i -> peekCStruct @AllocationInfo (((pPAllocationInfo) `advancePtrBytes` (56 * (i)) :: Ptr AllocationInfo)))
+  pure $ (pAllocations, pAllocationInfo)
+
+-- | A convenience wrapper to make a compatible pair of calls to
+-- 'allocateMemoryPages' and 'freeMemoryPages'
+--
+-- To ensure that 'freeMemoryPages' is always called: pass
+-- 'Control.Exception.bracket' (or the allocate function from your
+-- favourite resource management library) as the last argument.
+-- To just extract the pair pass '(,)' as the last argument.
+--
+withMemoryPages :: forall io r . MonadIO io => Allocator -> Vector MemoryRequirements -> Vector AllocationCreateInfo -> (io (Vector Allocation, Vector AllocationInfo) -> ((Vector Allocation, Vector AllocationInfo) -> io ()) -> r) -> r
+withMemoryPages allocator pVkMemoryRequirements pCreateInfo b =
+  b (allocateMemoryPages allocator pVkMemoryRequirements pCreateInfo)
+    (\(o0, _) -> freeMemoryPages allocator o0)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaAllocateMemoryForBuffer" ffiVmaAllocateMemoryForBuffer
+  :: Allocator -> Buffer -> Ptr AllocationCreateInfo -> Ptr Allocation -> Ptr AllocationInfo -> IO Result
+
+-- | Allocates memory suitable for given @VkBuffer@.
+--
+-- __Parameters__
+--
+-- +-----------+-----------------+-----------------------------------------------+
+-- |           | allocator       |                                               |
+-- +-----------+-----------------+-----------------------------------------------+
+-- |           | buffer          |                                               |
+-- +-----------+-----------------+-----------------------------------------------+
+-- |           | pCreateInfo     |                                               |
+-- +-----------+-----------------+-----------------------------------------------+
+-- | out       | pAllocation     | Handle to allocated memory.                   |
+-- +-----------+-----------------+-----------------------------------------------+
+-- | out       | pAllocationInfo | Optional. Information about allocated memory. |
+-- |           |                 | It can be later fetched using function        |
+-- |           |                 | 'getAllocationInfo'.                          |
+-- +-----------+-----------------+-----------------------------------------------+
+--
+-- It only creates 'Allocation'. To bind the memory to the buffer, use
+-- 'bindBufferMemory'.
+--
+-- This is a special-purpose function. In most cases you should use
+-- 'createBuffer'.
+--
+-- You must free the allocation using 'freeMemory' when no longer needed.
+allocateMemoryForBuffer :: forall io
+                         . (MonadIO io)
+                        => -- No documentation found for Nested "vmaAllocateMemoryForBuffer" "allocator"
+                           Allocator
+                        -> -- No documentation found for Nested "vmaAllocateMemoryForBuffer" "buffer"
+                           Buffer
+                        -> -- No documentation found for Nested "vmaAllocateMemoryForBuffer" "pCreateInfo"
+                           AllocationCreateInfo
+                        -> io (Allocation, AllocationInfo)
+allocateMemoryForBuffer allocator buffer createInfo = liftIO . evalContT $ do
+  pCreateInfo <- ContT $ withCStruct (createInfo)
+  pPAllocation <- ContT $ bracket (callocBytes @Allocation 8) free
+  pPAllocationInfo <- ContT (withZeroCStruct @AllocationInfo)
+  r <- lift $ traceAroundEvent "vmaAllocateMemoryForBuffer" ((ffiVmaAllocateMemoryForBuffer)
+                                                               (allocator)
+                                                               (buffer)
+                                                               pCreateInfo
+                                                               (pPAllocation)
+                                                               (pPAllocationInfo))
+  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
+  pAllocation <- lift $ peek @Allocation pPAllocation
+  pAllocationInfo <- lift $ peekCStruct @AllocationInfo pPAllocationInfo
+  pure $ (pAllocation, pAllocationInfo)
+
+-- | A convenience wrapper to make a compatible pair of calls to
+-- 'allocateMemoryForBuffer' and 'freeMemory'
+--
+-- To ensure that 'freeMemory' is always called: pass
+-- 'Control.Exception.bracket' (or the allocate function from your
+-- favourite resource management library) as the last argument.
+-- To just extract the pair pass '(,)' as the last argument.
+--
+withMemoryForBuffer :: forall io r . MonadIO io => Allocator -> Buffer -> AllocationCreateInfo -> (io (Allocation, AllocationInfo) -> ((Allocation, AllocationInfo) -> io ()) -> r) -> r
+withMemoryForBuffer allocator buffer pCreateInfo b =
+  b (allocateMemoryForBuffer allocator buffer pCreateInfo)
+    (\(o0, _) -> freeMemory allocator o0)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaAllocateMemoryForImage" ffiVmaAllocateMemoryForImage
+  :: Allocator -> Image -> Ptr AllocationCreateInfo -> Ptr Allocation -> Ptr AllocationInfo -> IO Result
+
+-- | Allocates memory suitable for given @VkImage@.
+--
+-- __Parameters__
+--
+-- +-----------+-----------------+-----------------------------------------------+
+-- |           | allocator       |                                               |
+-- +-----------+-----------------+-----------------------------------------------+
+-- |           | image           |                                               |
+-- +-----------+-----------------+-----------------------------------------------+
+-- |           | pCreateInfo     |                                               |
+-- +-----------+-----------------+-----------------------------------------------+
+-- | out       | pAllocation     | Handle to allocated memory.                   |
+-- +-----------+-----------------+-----------------------------------------------+
+-- | out       | pAllocationInfo | Optional. Information about allocated memory. |
+-- |           |                 | It can be later fetched using function        |
+-- |           |                 | 'getAllocationInfo'.                          |
+-- +-----------+-----------------+-----------------------------------------------+
+--
+-- It only creates 'Allocation'. To bind the memory to the buffer, use
+-- 'bindImageMemory'.
+--
+-- This is a special-purpose function. In most cases you should use
+-- 'createImage'.
+--
+-- You must free the allocation using 'freeMemory' when no longer needed.
+allocateMemoryForImage :: forall io
+                        . (MonadIO io)
+                       => -- No documentation found for Nested "vmaAllocateMemoryForImage" "allocator"
+                          Allocator
+                       -> -- No documentation found for Nested "vmaAllocateMemoryForImage" "image"
+                          Image
+                       -> -- No documentation found for Nested "vmaAllocateMemoryForImage" "pCreateInfo"
+                          AllocationCreateInfo
+                       -> io (Allocation, AllocationInfo)
+allocateMemoryForImage allocator image createInfo = liftIO . evalContT $ do
+  pCreateInfo <- ContT $ withCStruct (createInfo)
+  pPAllocation <- ContT $ bracket (callocBytes @Allocation 8) free
+  pPAllocationInfo <- ContT (withZeroCStruct @AllocationInfo)
+  r <- lift $ traceAroundEvent "vmaAllocateMemoryForImage" ((ffiVmaAllocateMemoryForImage)
+                                                              (allocator)
+                                                              (image)
+                                                              pCreateInfo
+                                                              (pPAllocation)
+                                                              (pPAllocationInfo))
+  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
+  pAllocation <- lift $ peek @Allocation pPAllocation
+  pAllocationInfo <- lift $ peekCStruct @AllocationInfo pPAllocationInfo
+  pure $ (pAllocation, pAllocationInfo)
+
+-- | A convenience wrapper to make a compatible pair of calls to
+-- 'allocateMemoryForImage' and 'freeMemory'
+--
+-- To ensure that 'freeMemory' is always called: pass
+-- 'Control.Exception.bracket' (or the allocate function from your
+-- favourite resource management library) as the last argument.
+-- To just extract the pair pass '(,)' as the last argument.
+--
+withMemoryForImage :: forall io r . MonadIO io => Allocator -> Image -> AllocationCreateInfo -> (io (Allocation, AllocationInfo) -> ((Allocation, AllocationInfo) -> io ()) -> r) -> r
+withMemoryForImage allocator image pCreateInfo b =
+  b (allocateMemoryForImage allocator image pCreateInfo)
+    (\(o0, _) -> freeMemory allocator o0)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaFreeMemory" ffiVmaFreeMemory
+  :: Allocator -> Allocation -> IO ()
+
+-- | Frees memory previously allocated using 'allocateMemory',
+-- 'allocateMemoryForBuffer', or 'allocateMemoryForImage'.
+--
+-- Passing @VK_NULL_HANDLE@ as @allocation@ is valid. Such function call is
+-- just skipped.
+freeMemory :: forall io
+            . (MonadIO io)
+           => -- No documentation found for Nested "vmaFreeMemory" "allocator"
+              Allocator
+           -> -- No documentation found for Nested "vmaFreeMemory" "allocation"
+              Allocation
+           -> io ()
+freeMemory allocator allocation = liftIO $ do
+  traceAroundEvent "vmaFreeMemory" ((ffiVmaFreeMemory) (allocator) (allocation))
+  pure $ ()
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaFreeMemoryPages" ffiVmaFreeMemoryPages
+  :: Allocator -> CSize -> Ptr Allocation -> IO ()
+
+-- | Frees memory and destroys multiple allocations.
+--
+-- Word \"pages\" is just a suggestion to use this function to free pieces
+-- of memory used for sparse binding. It is just a general purpose function
+-- to free memory and destroy allocations made using e.g. 'allocateMemory',
+-- 'allocateMemoryPages' and other functions. It may be internally
+-- optimized to be more efficient than calling 'freeMemory'
+-- @allocationCount@ times.
+--
+-- Allocations in @pAllocations@ array can come from any memory pools and
+-- types. Passing @VK_NULL_HANDLE@ as elements of @pAllocations@ array is
+-- valid. Such entries are just skipped.
+freeMemoryPages :: forall io
+                 . (MonadIO io)
+                => -- No documentation found for Nested "vmaFreeMemoryPages" "allocator"
+                   Allocator
+                -> -- No documentation found for Nested "vmaFreeMemoryPages" "pAllocations"
+                   ("allocations" ::: Vector Allocation)
+                -> io ()
+freeMemoryPages allocator allocations = liftIO . evalContT $ do
+  pPAllocations <- ContT $ allocaBytes @Allocation ((Data.Vector.length (allocations)) * 8)
+  lift $ Data.Vector.imapM_ (\i e -> poke (pPAllocations `plusPtr` (8 * (i)) :: Ptr Allocation) (e)) (allocations)
+  lift $ traceAroundEvent "vmaFreeMemoryPages" ((ffiVmaFreeMemoryPages)
+                                                  (allocator)
+                                                  ((fromIntegral (Data.Vector.length $ (allocations)) :: CSize))
+                                                  (pPAllocations))
+  pure $ ()
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaGetAllocationInfo" ffiVmaGetAllocationInfo
+  :: Allocator -> Allocation -> Ptr AllocationInfo -> IO ()
+
+-- | Returns current information about specified allocation.
+--
+-- Current parameters of given allocation are returned in
+-- @pAllocationInfo@.
+--
+-- Although this function doesn\'t lock any mutex, so it should be quite
+-- efficient, you should avoid calling it too often. You can retrieve same
+-- 'AllocationInfo' structure while creating your resource, from function
+-- 'createBuffer', 'createImage'. You can remember it if you are sure
+-- parameters don\'t change (e.g. due to defragmentation).
+getAllocationInfo :: forall io
+                   . (MonadIO io)
+                  => -- No documentation found for Nested "vmaGetAllocationInfo" "allocator"
+                     Allocator
+                  -> -- No documentation found for Nested "vmaGetAllocationInfo" "allocation"
+                     Allocation
+                  -> io (AllocationInfo)
+getAllocationInfo allocator allocation = liftIO . evalContT $ do
+  pPAllocationInfo <- ContT (withZeroCStruct @AllocationInfo)
+  lift $ traceAroundEvent "vmaGetAllocationInfo" ((ffiVmaGetAllocationInfo)
+                                                    (allocator)
+                                                    (allocation)
+                                                    (pPAllocationInfo))
+  pAllocationInfo <- lift $ peekCStruct @AllocationInfo pPAllocationInfo
+  pure $ (pAllocationInfo)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaSetAllocationUserData" ffiVmaSetAllocationUserData
+  :: Allocator -> Allocation -> Ptr () -> IO ()
+
+-- | Sets pUserData in given allocation to new value.
+--
+-- The value of pointer @pUserData@ is copied to allocation\'s @pUserData@.
+-- It is opaque, so you can use it however you want - e.g. as a pointer,
+-- ordinal number or some handle to you own data.
+setAllocationUserData :: forall io
+                       . (MonadIO io)
+                      => -- No documentation found for Nested "vmaSetAllocationUserData" "allocator"
+                         Allocator
+                      -> -- No documentation found for Nested "vmaSetAllocationUserData" "allocation"
+                         Allocation
+                      -> -- No documentation found for Nested "vmaSetAllocationUserData" "pUserData"
+                         ("userData" ::: Ptr ())
+                      -> io ()
+setAllocationUserData allocator allocation userData = liftIO $ do
+  traceAroundEvent "vmaSetAllocationUserData" ((ffiVmaSetAllocationUserData)
+                                                 (allocator)
+                                                 (allocation)
+                                                 (userData))
+  pure $ ()
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaSetAllocationName" ffiVmaSetAllocationName
+  :: Allocator -> Allocation -> Ptr CChar -> IO ()
+
+-- | Sets pName in given allocation to new value.
+--
+-- @pName@ must be either null, or pointer to a null-terminated string. The
+-- function makes local copy of the string and sets it as allocation\'s
+-- @pName@. String passed as pName doesn\'t need to be valid for whole
+-- lifetime of the allocation - you can free it after this call. String
+-- previously pointed by allocation\'s @pName@ is freed from memory.
+setAllocationName :: forall io
+                   . (MonadIO io)
+                  => -- No documentation found for Nested "vmaSetAllocationName" "allocator"
+                     Allocator
+                  -> -- No documentation found for Nested "vmaSetAllocationName" "allocation"
+                     Allocation
+                  -> -- No documentation found for Nested "vmaSetAllocationName" "pName"
+                     ("name" ::: Maybe ByteString)
+                  -> io ()
+setAllocationName allocator allocation name = liftIO . evalContT $ do
+  pName <- case (name) of
+    Nothing -> pure nullPtr
+    Just j -> ContT $ useAsCString (j)
+  lift $ traceAroundEvent "vmaSetAllocationName" ((ffiVmaSetAllocationName)
+                                                    (allocator)
+                                                    (allocation)
+                                                    pName)
+  pure $ ()
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaGetAllocationMemoryProperties" ffiVmaGetAllocationMemoryProperties
+  :: Allocator -> Allocation -> Ptr MemoryPropertyFlags -> IO ()
+
+-- | Given an allocation, returns Property Flags of its memory type.
+--
+-- This is just a convenience function. Same information can be obtained
+-- using 'getAllocationInfo' + 'getMemoryProperties'.
+getAllocationMemoryProperties :: forall io
+                               . (MonadIO io)
+                              => -- No documentation found for Nested "vmaGetAllocationMemoryProperties" "allocator"
+                                 Allocator
+                              -> -- No documentation found for Nested "vmaGetAllocationMemoryProperties" "allocation"
+                                 Allocation
+                              -> io (MemoryPropertyFlags)
+getAllocationMemoryProperties allocator allocation = liftIO . evalContT $ do
+  pPFlags <- ContT $ bracket (callocBytes @MemoryPropertyFlags 4) free
+  lift $ traceAroundEvent "vmaGetAllocationMemoryProperties" ((ffiVmaGetAllocationMemoryProperties)
+                                                                (allocator)
+                                                                (allocation)
+                                                                (pPFlags))
+  pFlags <- lift $ peek @MemoryPropertyFlags pPFlags
+  pure $ (pFlags)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaMapMemory" ffiVmaMapMemory
+  :: Allocator -> Allocation -> Ptr (Ptr ()) -> IO Result
+
+-- | Maps memory represented by given allocation and returns pointer to it.
+--
+-- Maps memory represented by given allocation to make it accessible to CPU
+-- code. When succeeded, @*ppData@ contains pointer to first byte of this
+-- memory.
+--
+-- Warning
+--
+-- If the allocation is part of a bigger @VkDeviceMemory@ block, returned
+-- pointer is correctly offsetted to the beginning of region assigned to
+-- this particular allocation. Unlike the result of @vkMapMemory@, it
+-- points to the allocation, not to the beginning of the whole block. You
+-- should not add /VmaAllocationInfo::offset/ to it!
+--
+-- Mapping is internally reference-counted and synchronized, so despite raw
+-- Vulkan function @vkMapMemory()@ cannot be used to map same block of
+-- @VkDeviceMemory@ multiple times simultaneously, it is safe to call this
+-- function on allocations assigned to the same memory block. Actual Vulkan
+-- memory will be mapped on first mapping and unmapped on last unmapping.
+--
+-- If the function succeeded, you must call 'unmapMemory' to unmap the
+-- allocation when mapping is no longer needed or before freeing the
+-- allocation, at the latest.
+--
+-- It also safe to call this function multiple times on the same
+-- allocation. You must call 'unmapMemory' same number of times as you
+-- called 'mapMemory'.
+--
+-- It is also safe to call this function on allocation created with
+-- 'ALLOCATION_CREATE_MAPPED_BIT' flag. Its memory stays mapped all the
+-- time. You must still call 'unmapMemory' same number of times as you
+-- called 'mapMemory'. You must not call 'unmapMemory' additional time to
+-- free the \"0-th\" mapping made automatically due to
+-- 'ALLOCATION_CREATE_MAPPED_BIT' flag.
+--
+-- This function fails when used on allocation made in memory type that is
+-- not @HOST_VISIBLE@.
+--
+-- This function doesn\'t automatically flush or invalidate caches. If the
+-- allocation is made from a memory types that is not @HOST_COHERENT@, you
+-- also need to use 'invalidateAllocation' \/ 'flushAllocation', as
+-- required by Vulkan specification.
+mapMemory :: forall io
+           . (MonadIO io)
+          => -- No documentation found for Nested "vmaMapMemory" "allocator"
+             Allocator
+          -> -- No documentation found for Nested "vmaMapMemory" "allocation"
+             Allocation
+          -> io (("data" ::: Ptr ()))
+mapMemory allocator allocation = liftIO . evalContT $ do
+  pPpData <- ContT $ bracket (callocBytes @(Ptr ()) 8) free
+  r <- lift $ traceAroundEvent "vmaMapMemory" ((ffiVmaMapMemory)
+                                                 (allocator)
+                                                 (allocation)
+                                                 (pPpData))
+  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
+  ppData <- lift $ peek @(Ptr ()) pPpData
+  pure $ (ppData)
+
+-- | A convenience wrapper to make a compatible pair of calls to 'mapMemory'
+-- and 'unmapMemory'
+--
+-- To ensure that 'unmapMemory' is always called: pass
+-- 'Control.Exception.bracket' (or the allocate function from your
+-- favourite resource management library) as the last argument.
+-- To just extract the pair pass '(,)' as the last argument.
+--
+withMappedMemory :: forall io r . MonadIO io => Allocator -> Allocation -> (io (Ptr ()) -> (Ptr () -> io ()) -> r) -> r
+withMappedMemory allocator allocation b =
+  b (mapMemory allocator allocation)
+    (\(_) -> unmapMemory allocator allocation)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaUnmapMemory" ffiVmaUnmapMemory
+  :: Allocator -> Allocation -> IO ()
+
+-- | Unmaps memory represented by given allocation, mapped previously using
+-- 'mapMemory'.
+--
+-- For details, see description of 'mapMemory'.
+--
+-- This function doesn\'t automatically flush or invalidate caches. If the
+-- allocation is made from a memory types that is not @HOST_COHERENT@, you
+-- also need to use 'invalidateAllocation' \/ 'flushAllocation', as
+-- required by Vulkan specification.
+unmapMemory :: forall io
+             . (MonadIO io)
+            => -- No documentation found for Nested "vmaUnmapMemory" "allocator"
+               Allocator
+            -> -- No documentation found for Nested "vmaUnmapMemory" "allocation"
+               Allocation
+            -> io ()
+unmapMemory allocator allocation = liftIO $ do
+  traceAroundEvent "vmaUnmapMemory" ((ffiVmaUnmapMemory)
+                                       (allocator)
+                                       (allocation))
+  pure $ ()
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaFlushAllocation" ffiVmaFlushAllocation
+  :: Allocator -> Allocation -> DeviceSize -> DeviceSize -> IO Result
+
+-- | Flushes memory of given allocation.
+--
+-- Calls @vkFlushMappedMemoryRanges()@ for memory associated with given
+-- range of given allocation. It needs to be called after writing to a
+-- mapped memory for memory types that are not @HOST_COHERENT@. Unmap
+-- operation doesn\'t do that automatically.
+--
+-- -   @offset@ must be relative to the beginning of allocation.
+--
+-- -   @size@ can be @VK_WHOLE_SIZE@. It means all memory from @offset@ the
+--     the end of given allocation.
+--
+-- -   @offset@ and @size@ don\'t have to be aligned. They are internally
+--     rounded down\/up to multiply of @nonCoherentAtomSize@.
+--
+-- -   If @size@ is 0, this call is ignored.
+--
+-- -   If memory type that the @allocation@ belongs to is not
+--     @HOST_VISIBLE@ or it is @HOST_COHERENT@, this call is ignored.
+--
+-- Warning! @offset@ and @size@ are relative to the contents of given
+-- @allocation@. If you mean whole allocation, you can pass 0 and
+-- @VK_WHOLE_SIZE@, respectively. Do not pass allocation\'s offset as
+-- @offset@!!!
+--
+-- This function returns the @VkResult@ from @vkFlushMappedMemoryRanges@ if
+-- it is called, otherwise @VK_SUCCESS@.
+flushAllocation :: forall io
+                 . (MonadIO io)
+                => -- No documentation found for Nested "vmaFlushAllocation" "allocator"
+                   Allocator
+                -> -- No documentation found for Nested "vmaFlushAllocation" "allocation"
+                   Allocation
+                -> -- No documentation found for Nested "vmaFlushAllocation" "offset"
+                   ("offset" ::: DeviceSize)
+                -> -- No documentation found for Nested "vmaFlushAllocation" "size"
+                   DeviceSize
+                -> io ()
+flushAllocation allocator allocation offset size = liftIO $ do
+  r <- traceAroundEvent "vmaFlushAllocation" ((ffiVmaFlushAllocation)
+                                                (allocator)
+                                                (allocation)
+                                                (offset)
+                                                (size))
+  when (r < SUCCESS) (throwIO (VulkanException r))
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaInvalidateAllocation" ffiVmaInvalidateAllocation
+  :: Allocator -> Allocation -> DeviceSize -> DeviceSize -> IO Result
+
+-- | Invalidates memory of given allocation.
+--
+-- Calls @vkInvalidateMappedMemoryRanges()@ for memory associated with
+-- given range of given allocation. It needs to be called before reading
+-- from a mapped memory for memory types that are not @HOST_COHERENT@. Map
+-- operation doesn\'t do that automatically.
+--
+-- -   @offset@ must be relative to the beginning of allocation.
+--
+-- -   @size@ can be @VK_WHOLE_SIZE@. It means all memory from @offset@ the
+--     the end of given allocation.
+--
+-- -   @offset@ and @size@ don\'t have to be aligned. They are internally
+--     rounded down\/up to multiply of @nonCoherentAtomSize@.
+--
+-- -   If @size@ is 0, this call is ignored.
+--
+-- -   If memory type that the @allocation@ belongs to is not
+--     @HOST_VISIBLE@ or it is @HOST_COHERENT@, this call is ignored.
+--
+-- Warning! @offset@ and @size@ are relative to the contents of given
+-- @allocation@. If you mean whole allocation, you can pass 0 and
+-- @VK_WHOLE_SIZE@, respectively. Do not pass allocation\'s offset as
+-- @offset@!!!
+--
+-- This function returns the @VkResult@ from
+-- @vkInvalidateMappedMemoryRanges@ if it is called, otherwise
+-- @VK_SUCCESS@.
+invalidateAllocation :: forall io
+                      . (MonadIO io)
+                     => -- No documentation found for Nested "vmaInvalidateAllocation" "allocator"
+                        Allocator
+                     -> -- No documentation found for Nested "vmaInvalidateAllocation" "allocation"
+                        Allocation
+                     -> -- No documentation found for Nested "vmaInvalidateAllocation" "offset"
+                        ("offset" ::: DeviceSize)
+                     -> -- No documentation found for Nested "vmaInvalidateAllocation" "size"
+                        DeviceSize
+                     -> io ()
+invalidateAllocation allocator allocation offset size = liftIO $ do
+  r <- traceAroundEvent "vmaInvalidateAllocation" ((ffiVmaInvalidateAllocation)
+                                                     (allocator)
+                                                     (allocation)
+                                                     (offset)
+                                                     (size))
+  when (r < SUCCESS) (throwIO (VulkanException r))
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaFlushAllocations" ffiVmaFlushAllocations
+  :: Allocator -> Word32 -> Ptr Allocation -> Ptr DeviceSize -> Ptr DeviceSize -> IO Result
+
+-- | Flushes memory of given set of allocations.
+--
+-- Calls @vkFlushMappedMemoryRanges()@ for memory associated with given
+-- ranges of given allocations. For more information, see documentation of
+-- 'flushAllocation'.
+--
+-- __Parameters__
+--
+-- +-----------------+--------------------------------------------------------+
+-- | allocator       |                                                        |
+-- +-----------------+--------------------------------------------------------+
+-- | allocationCount |                                                        |
+-- +-----------------+--------------------------------------------------------+
+-- | allocations     |                                                        |
+-- +-----------------+--------------------------------------------------------+
+-- | offsets         | If not null, it must point to an array of offsets of   |
+-- |                 | regions to flush, relative to the beginning of         |
+-- |                 | respective allocations. Null means all ofsets are      |
+-- |                 | zero.                                                  |
+-- +-----------------+--------------------------------------------------------+
+-- | sizes           | If not null, it must point to an array of sizes of     |
+-- |                 | regions to flush in respective allocations. Null means |
+-- |                 | @VK_WHOLE_SIZE@ for all allocations.                   |
+-- +-----------------+--------------------------------------------------------+
+--
+-- This function returns the @VkResult@ from @vkFlushMappedMemoryRanges@ if
+-- it is called, otherwise @VK_SUCCESS@.
+flushAllocations :: forall io
+                  . (MonadIO io)
+                 => -- No documentation found for Nested "vmaFlushAllocations" "allocator"
+                    Allocator
+                 -> -- No documentation found for Nested "vmaFlushAllocations" "allocations"
+                    ("allocations" ::: Vector Allocation)
+                 -> -- No documentation found for Nested "vmaFlushAllocations" "offsets"
+                    ("offsets" ::: Vector DeviceSize)
+                 -> -- No documentation found for Nested "vmaFlushAllocations" "sizes"
+                    ("sizes" ::: Vector DeviceSize)
+                 -> io ()
+flushAllocations allocator allocations offsets sizes = liftIO . evalContT $ do
+  let allocationsLength = Data.Vector.length $ (allocations)
+  let offsetsLength = Data.Vector.length $ (offsets)
+  lift $ unless (fromIntegral offsetsLength == allocationsLength || offsetsLength == 0) $
+    throwIO $ IOError Nothing InvalidArgument "" "offsets and allocations must have the same length" Nothing Nothing
+  let sizesLength = Data.Vector.length $ (sizes)
+  lift $ unless (fromIntegral sizesLength == allocationsLength || sizesLength == 0) $
+    throwIO $ IOError Nothing InvalidArgument "" "sizes and allocations must have the same length" Nothing Nothing
+  pAllocations <- ContT $ allocaBytes @Allocation ((Data.Vector.length (allocations)) * 8)
+  lift $ Data.Vector.imapM_ (\i e -> poke (pAllocations `plusPtr` (8 * (i)) :: Ptr Allocation) (e)) (allocations)
+  offsets' <- if Data.Vector.null (offsets)
+    then pure nullPtr
+    else do
+      pOffsets <- ContT $ allocaBytes @DeviceSize (((Data.Vector.length (offsets))) * 8)
+      lift $ Data.Vector.imapM_ (\i e -> poke (pOffsets `plusPtr` (8 * (i)) :: Ptr DeviceSize) (e)) ((offsets))
+      pure $ pOffsets
+  sizes' <- if Data.Vector.null (sizes)
+    then pure nullPtr
+    else do
+      pSizes <- ContT $ allocaBytes @DeviceSize (((Data.Vector.length (sizes))) * 8)
+      lift $ Data.Vector.imapM_ (\i e -> poke (pSizes `plusPtr` (8 * (i)) :: Ptr DeviceSize) (e)) ((sizes))
+      pure $ pSizes
+  r <- lift $ traceAroundEvent "vmaFlushAllocations" ((ffiVmaFlushAllocations)
+                                                        (allocator)
+                                                        ((fromIntegral allocationsLength :: Word32))
+                                                        (pAllocations)
+                                                        offsets'
+                                                        sizes')
+  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaInvalidateAllocations" ffiVmaInvalidateAllocations
+  :: Allocator -> Word32 -> Ptr Allocation -> Ptr DeviceSize -> Ptr DeviceSize -> IO Result
+
+-- | Invalidates memory of given set of allocations.
+--
+-- Calls @vkInvalidateMappedMemoryRanges()@ for memory associated with
+-- given ranges of given allocations. For more information, see
+-- documentation of 'invalidateAllocation'.
+--
+-- __Parameters__
+--
+-- +-----------------+--------------------------------------------------------+
+-- | allocator       |                                                        |
+-- +-----------------+--------------------------------------------------------+
+-- | allocationCount |                                                        |
+-- +-----------------+--------------------------------------------------------+
+-- | allocations     |                                                        |
+-- +-----------------+--------------------------------------------------------+
+-- | offsets         | If not null, it must point to an array of offsets of   |
+-- |                 | regions to flush, relative to the beginning of         |
+-- |                 | respective allocations. Null means all ofsets are      |
+-- |                 | zero.                                                  |
+-- +-----------------+--------------------------------------------------------+
+-- | sizes           | If not null, it must point to an array of sizes of     |
+-- |                 | regions to flush in respective allocations. Null means |
+-- |                 | @VK_WHOLE_SIZE@ for all allocations.                   |
+-- +-----------------+--------------------------------------------------------+
+--
+-- This function returns the @VkResult@ from
+-- @vkInvalidateMappedMemoryRanges@ if it is called, otherwise
+-- @VK_SUCCESS@.
+invalidateAllocations :: forall io
+                       . (MonadIO io)
+                      => -- No documentation found for Nested "vmaInvalidateAllocations" "allocator"
+                         Allocator
+                      -> -- No documentation found for Nested "vmaInvalidateAllocations" "allocations"
+                         ("allocations" ::: Vector Allocation)
+                      -> -- No documentation found for Nested "vmaInvalidateAllocations" "offsets"
+                         ("offsets" ::: Vector DeviceSize)
+                      -> -- No documentation found for Nested "vmaInvalidateAllocations" "sizes"
+                         ("sizes" ::: Vector DeviceSize)
+                      -> io ()
+invalidateAllocations allocator
+                        allocations
+                        offsets
+                        sizes = liftIO . evalContT $ do
+  let allocationsLength = Data.Vector.length $ (allocations)
+  let offsetsLength = Data.Vector.length $ (offsets)
+  lift $ unless (fromIntegral offsetsLength == allocationsLength || offsetsLength == 0) $
+    throwIO $ IOError Nothing InvalidArgument "" "offsets and allocations must have the same length" Nothing Nothing
+  let sizesLength = Data.Vector.length $ (sizes)
+  lift $ unless (fromIntegral sizesLength == allocationsLength || sizesLength == 0) $
+    throwIO $ IOError Nothing InvalidArgument "" "sizes and allocations must have the same length" Nothing Nothing
+  pAllocations <- ContT $ allocaBytes @Allocation ((Data.Vector.length (allocations)) * 8)
+  lift $ Data.Vector.imapM_ (\i e -> poke (pAllocations `plusPtr` (8 * (i)) :: Ptr Allocation) (e)) (allocations)
+  offsets' <- if Data.Vector.null (offsets)
+    then pure nullPtr
+    else do
+      pOffsets <- ContT $ allocaBytes @DeviceSize (((Data.Vector.length (offsets))) * 8)
+      lift $ Data.Vector.imapM_ (\i e -> poke (pOffsets `plusPtr` (8 * (i)) :: Ptr DeviceSize) (e)) ((offsets))
+      pure $ pOffsets
+  sizes' <- if Data.Vector.null (sizes)
+    then pure nullPtr
+    else do
+      pSizes <- ContT $ allocaBytes @DeviceSize (((Data.Vector.length (sizes))) * 8)
+      lift $ Data.Vector.imapM_ (\i e -> poke (pSizes `plusPtr` (8 * (i)) :: Ptr DeviceSize) (e)) ((sizes))
+      pure $ pSizes
+  r <- lift $ traceAroundEvent "vmaInvalidateAllocations" ((ffiVmaInvalidateAllocations)
+                                                             (allocator)
+                                                             ((fromIntegral allocationsLength :: Word32))
+                                                             (pAllocations)
+                                                             offsets'
+                                                             sizes')
+  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaCheckCorruption" ffiVmaCheckCorruption
+  :: Allocator -> Word32 -> IO Result
+
+-- | Checks magic number in margins around all allocations in given memory
+-- types (in both default and custom pools) in search for corruptions.
+--
+-- __Parameters__
+--
+-- +----------------+--------------------------------------------------------+
+-- | allocator      |                                                        |
+-- +----------------+--------------------------------------------------------+
+-- | memoryTypeBits | Bit mask, where each bit set means that a memory type  |
+-- |                | with that index should be checked.                     |
+-- +----------------+--------------------------------------------------------+
+--
+-- Corruption detection is enabled only when @VMA_DEBUG_DETECT_CORRUPTION@
+-- macro is defined to nonzero, @VMA_DEBUG_MARGIN@ is defined to nonzero
+-- and only for memory types that are @HOST_VISIBLE@ and @HOST_COHERENT@.
+-- For more information, see /Corruption detection/.
+--
+-- Possible return values:
+--
+-- -   @VK_ERROR_FEATURE_NOT_PRESENT@ - corruption detection is not enabled
+--     for any of specified memory types.
+--
+-- -   @VK_SUCCESS@ - corruption detection has been performed and
+--     succeeded.
+--
+-- -   @VK_ERROR_UNKNOWN@ - corruption detection has been performed and
+--     found memory corruptions around one of the allocations. @VMA_ASSERT@
+--     is also fired in that case.
+--
+-- -   Other value: Error returned by Vulkan, e.g. memory mapping failure.
+checkCorruption :: forall io
+                 . (MonadIO io)
+                => -- No documentation found for Nested "vmaCheckCorruption" "allocator"
+                   Allocator
+                -> -- No documentation found for Nested "vmaCheckCorruption" "memoryTypeBits"
+                   ("memoryTypeBits" ::: Word32)
+                -> io ()
+checkCorruption allocator memoryTypeBits = liftIO $ do
+  r <- traceAroundEvent "vmaCheckCorruption" ((ffiVmaCheckCorruption)
+                                                (allocator)
+                                                (memoryTypeBits))
+  when (r < SUCCESS) (throwIO (VulkanException r))
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaBeginDefragmentation" ffiVmaBeginDefragmentation
+  :: Allocator -> Ptr DefragmentationInfo -> Ptr DefragmentationContext -> IO Result
+
+-- | Begins defragmentation process.
+--
+-- __Parameters__
+--
+-- +-----------+-----------+-----------------------------------------------+
+-- |           | allocator | Allocator object.                             |
+-- +-----------+-----------+-----------------------------------------------+
+-- |           | pInfo     | Structure filled with parameters of           |
+-- |           |           | defragmentation.                              |
+-- +-----------+-----------+-----------------------------------------------+
+-- | out       | pContext  | Context object that must be passed to         |
+-- |           |           | 'endDefragmentation' to finish                |
+-- |           |           | defragmentation.                              |
+-- +-----------+-----------+-----------------------------------------------+
+--
+-- __Returns__
+--
+-- -   @VK_SUCCESS@ if defragmentation can begin.
+--
+-- -   @VK_ERROR_FEATURE_NOT_PRESENT@ if defragmentation is not supported.
+--
+-- For more information about defragmentation, see documentation chapter:
+-- /Defragmentation/.
+beginDefragmentation :: forall io
+                      . (MonadIO io)
+                     => -- No documentation found for Nested "vmaBeginDefragmentation" "allocator"
+                        Allocator
+                     -> -- No documentation found for Nested "vmaBeginDefragmentation" "pInfo"
+                        DefragmentationInfo
+                     -> io (DefragmentationContext)
+beginDefragmentation allocator info = liftIO . evalContT $ do
+  pInfo <- ContT $ withCStruct (info)
+  pPContext <- ContT $ bracket (callocBytes @DefragmentationContext 8) free
+  r <- lift $ traceAroundEvent "vmaBeginDefragmentation" ((ffiVmaBeginDefragmentation)
+                                                            (allocator)
+                                                            pInfo
+                                                            (pPContext))
+  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
+  pContext <- lift $ peek @DefragmentationContext pPContext
+  pure $ (pContext)
+
+-- | A convenience wrapper to make a compatible pair of calls to
+-- 'beginDefragmentation' and 'endDefragmentation'
+--
+-- To ensure that 'endDefragmentation' is always called: pass
+-- 'Control.Exception.bracket' (or the allocate function from your
+-- favourite resource management library) as the last argument.
+-- To just extract the pair pass '(,)' as the last argument.
+--
+withDefragmentation :: forall io r . MonadIO io => Allocator -> DefragmentationInfo -> (io DefragmentationContext -> (DefragmentationContext -> io (DefragmentationStats)) -> r) -> r
+withDefragmentation allocator pInfo b =
+  b (beginDefragmentation allocator pInfo)
+    (\(o0) -> endDefragmentation allocator o0)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaEndDefragmentation" ffiVmaEndDefragmentation
+  :: Allocator -> DefragmentationContext -> Ptr DefragmentationStats -> IO ()
+
+-- | Ends defragmentation process.
+--
+-- __Parameters__
+--
+-- +-----------+-----------+-----------------------------------------------+
+-- |           | allocator | Allocator object.                             |
+-- +-----------+-----------+-----------------------------------------------+
+-- |           | context   | Context object that has been created by       |
+-- |           |           | 'beginDefragmentation'.                       |
+-- +-----------+-----------+-----------------------------------------------+
+-- | out       | pStats    | Optional stats for the defragmentation. Can   |
+-- |           |           | be null.                                      |
+-- +-----------+-----------+-----------------------------------------------+
+--
+-- Use this function to finish defragmentation started by
+-- 'beginDefragmentation'.
+endDefragmentation :: forall io
+                    . (MonadIO io)
+                   => -- No documentation found for Nested "vmaEndDefragmentation" "allocator"
+                      Allocator
+                   -> -- No documentation found for Nested "vmaEndDefragmentation" "context"
+                      DefragmentationContext
+                   -> io (DefragmentationStats)
+endDefragmentation allocator context = liftIO . evalContT $ do
+  pPStats <- ContT (withZeroCStruct @DefragmentationStats)
+  lift $ traceAroundEvent "vmaEndDefragmentation" ((ffiVmaEndDefragmentation)
+                                                     (allocator)
+                                                     (context)
+                                                     (pPStats))
+  pStats <- lift $ peekCStruct @DefragmentationStats pPStats
+  pure $ (pStats)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaBeginDefragmentationPass" ffiVmaBeginDefragmentationPass
+  :: Allocator -> DefragmentationContext -> Ptr DefragmentationPassMoveInfo -> IO Result
+
+-- | Starts single defragmentation pass.
+--
+-- __Parameters__
+--
+-- +-----------+-----------+-----------------------------------------------+
+-- |           | allocator | Allocator object.                             |
+-- +-----------+-----------+-----------------------------------------------+
+-- |           | context   | Context object that has been created by       |
+-- |           |           | 'beginDefragmentation'.                       |
+-- +-----------+-----------+-----------------------------------------------+
+-- | out       | pPassInfo | Computed information for current pass.        |
+-- +-----------+-----------+-----------------------------------------------+
+--
+-- __Returns__
+--
+-- -   @VK_SUCCESS@ if no more moves are possible. Then you can omit call
+--     to 'endDefragmentationPass' and simply end whole defragmentation.
+--
+-- -   @VK_INCOMPLETE@ if there are pending moves returned in @pPassInfo@.
+--     You need to perform them, call 'endDefragmentationPass', and then
+--     preferably try another pass with 'beginDefragmentationPass'.
+beginDefragmentationPass :: forall io
+                          . (MonadIO io)
+                         => -- No documentation found for Nested "vmaBeginDefragmentationPass" "allocator"
+                            Allocator
+                         -> -- No documentation found for Nested "vmaBeginDefragmentationPass" "context"
+                            DefragmentationContext
+                         -> io (("passInfo" ::: DefragmentationPassMoveInfo))
+beginDefragmentationPass allocator context = liftIO . evalContT $ do
+  pPPassInfo <- ContT (withZeroCStruct @DefragmentationPassMoveInfo)
+  r <- lift $ traceAroundEvent "vmaBeginDefragmentationPass" ((ffiVmaBeginDefragmentationPass)
+                                                                (allocator)
+                                                                (context)
+                                                                (pPPassInfo))
+  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
+  pPassInfo <- lift $ peekCStruct @DefragmentationPassMoveInfo pPPassInfo
+  pure $ (pPassInfo)
+
+-- | This function will call the supplied action between calls to
+-- 'beginDefragmentationPass' and 'endDefragmentationPass'
+--
+-- Note that 'endDefragmentationPass' is *not* called if an exception is
+-- thrown by the inner action.
+useDefragmentationPass :: forall io r . MonadIO io => Allocator -> DefragmentationContext -> (DefragmentationPassMoveInfo -> io r) -> io (("passInfo" ::: DefragmentationPassMoveInfo), r)
+useDefragmentationPass allocator context a =
+  do
+    x <- beginDefragmentationPass allocator context
+    r <- a x
+    d <- (\(_) -> endDefragmentationPass allocator context) x
+    pure (d, r)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaEndDefragmentationPass" ffiVmaEndDefragmentationPass
+  :: Allocator -> DefragmentationContext -> Ptr DefragmentationPassMoveInfo -> IO Result
+
+-- | Ends single defragmentation pass.
+--
+-- __Parameters__
+--
+-- +-------------+--------------------------------------------------------+
+-- | allocator   | Allocator object.                                      |
+-- +-------------+--------------------------------------------------------+
+-- | context     | Context object that has been created by                |
+-- |             | 'beginDefragmentation'.                                |
+-- +-------------+--------------------------------------------------------+
+-- | pPassInfo   | Computed information for current pass filled by        |
+-- |             | 'beginDefragmentationPass' and possibly modified by    |
+-- |             | you.                                                   |
+-- +-------------+--------------------------------------------------------+
+--
+-- Returns @VK_SUCCESS@ if no more moves are possible or @VK_INCOMPLETE@ if
+-- more defragmentations are possible.
+--
+-- Ends incremental defragmentation pass and commits all defragmentation
+-- moves from @pPassInfo@. After this call:
+--
+-- -   Allocations at @pPassInfo[i].srcAllocation@ that had
+--     @pPassInfo[i].operation ==@ 'DEFRAGMENTATION_MOVE_OPERATION_COPY'
+--     (which is the default) will be pointing to the new destination
+--     place.
+--
+-- -   Allocation at @pPassInfo[i].srcAllocation@ that had
+--     @pPassInfo[i].operation ==@ 'DEFRAGMENTATION_MOVE_OPERATION_DESTROY'
+--     will be freed.
+--
+-- If no more moves are possible you can end whole defragmentation.
+endDefragmentationPass :: forall io
+                        . (MonadIO io)
+                       => -- No documentation found for Nested "vmaEndDefragmentationPass" "allocator"
+                          Allocator
+                       -> -- No documentation found for Nested "vmaEndDefragmentationPass" "context"
+                          DefragmentationContext
+                       -> io (("passInfo" ::: DefragmentationPassMoveInfo))
+endDefragmentationPass allocator context = liftIO . evalContT $ do
+  pPPassInfo <- ContT (withZeroCStruct @DefragmentationPassMoveInfo)
+  r <- lift $ traceAroundEvent "vmaEndDefragmentationPass" ((ffiVmaEndDefragmentationPass)
+                                                              (allocator)
+                                                              (context)
+                                                              (pPPassInfo))
+  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
+  pPassInfo <- lift $ peekCStruct @DefragmentationPassMoveInfo pPPassInfo
+  pure $ (pPassInfo)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaBindBufferMemory" ffiVmaBindBufferMemory
+  :: Allocator -> Allocation -> Buffer -> IO Result
+
+-- | Binds buffer to allocation.
+--
+-- Binds specified buffer to region of memory represented by specified
+-- allocation. Gets @VkDeviceMemory@ handle and offset from the allocation.
+-- If you want to create a buffer, allocate memory for it and bind them
+-- together separately, you should use this function for binding instead of
+-- standard @vkBindBufferMemory()@, because it ensures proper
+-- synchronization so that when a @VkDeviceMemory@ object is used by
+-- multiple allocations, calls to @vkBind*Memory()@ or @vkMapMemory()@
+-- won\'t happen from multiple threads simultaneously (which is illegal in
+-- Vulkan).
+--
+-- It is recommended to use function 'createBuffer' instead of this one.
+bindBufferMemory :: forall io
+                  . (MonadIO io)
+                 => -- No documentation found for Nested "vmaBindBufferMemory" "allocator"
+                    Allocator
+                 -> -- No documentation found for Nested "vmaBindBufferMemory" "allocation"
+                    Allocation
+                 -> -- No documentation found for Nested "vmaBindBufferMemory" "buffer"
+                    Buffer
+                 -> io ()
+bindBufferMemory allocator allocation buffer = liftIO $ do
+  r <- traceAroundEvent "vmaBindBufferMemory" ((ffiVmaBindBufferMemory)
+                                                 (allocator)
+                                                 (allocation)
+                                                 (buffer))
+  when (r < SUCCESS) (throwIO (VulkanException r))
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaBindBufferMemory2" ffiVmaBindBufferMemory2
+  :: Allocator -> Allocation -> DeviceSize -> Buffer -> Ptr () -> IO Result
+
+-- | Binds buffer to allocation with additional parameters.
+--
+-- __Parameters__
+--
+-- +-----------------------+--------------------------------------------------------+
+-- | allocator             |                                                        |
+-- +-----------------------+--------------------------------------------------------+
+-- | allocation            |                                                        |
+-- +-----------------------+--------------------------------------------------------+
+-- | allocationLocalOffset | Additional offset to be added while binding, relative  |
+-- |                       | to the beginning of the @allocation@. Normally it      |
+-- |                       | should be 0.                                           |
+-- +-----------------------+--------------------------------------------------------+
+-- | buffer                |                                                        |
+-- +-----------------------+--------------------------------------------------------+
+-- | pNext                 | A chain of structures to be attached to                |
+-- |                       | @VkBindBufferMemoryInfoKHR@ structure used internally. |
+-- |                       | Normally it should be null.                            |
+-- +-----------------------+--------------------------------------------------------+
+--
+-- This function is similar to 'bindBufferMemory', but it provides
+-- additional parameters.
+--
+-- If @pNext@ is not null, 'Allocator' object must have been created with
+-- 'ALLOCATOR_CREATE_KHR_BIND_MEMORY2_BIT' flag or with
+-- /VmaAllocatorCreateInfo::vulkanApiVersion/ @>= VK_API_VERSION_1_1@.
+-- Otherwise the call fails.
+bindBufferMemory2 :: forall io
+                   . (MonadIO io)
+                  => -- No documentation found for Nested "vmaBindBufferMemory2" "allocator"
+                     Allocator
+                  -> -- No documentation found for Nested "vmaBindBufferMemory2" "allocation"
+                     Allocation
+                  -> -- No documentation found for Nested "vmaBindBufferMemory2" "allocationLocalOffset"
+                     ("allocationLocalOffset" ::: DeviceSize)
+                  -> -- No documentation found for Nested "vmaBindBufferMemory2" "buffer"
+                     Buffer
+                  -> -- No documentation found for Nested "vmaBindBufferMemory2" "pNext"
+                     ("next" ::: Ptr ())
+                  -> io ()
+bindBufferMemory2 allocator
+                    allocation
+                    allocationLocalOffset
+                    buffer
+                    next = liftIO $ do
+  r <- traceAroundEvent "vmaBindBufferMemory2" ((ffiVmaBindBufferMemory2)
+                                                  (allocator)
+                                                  (allocation)
+                                                  (allocationLocalOffset)
+                                                  (buffer)
+                                                  (next))
+  when (r < SUCCESS) (throwIO (VulkanException r))
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaBindImageMemory" ffiVmaBindImageMemory
+  :: Allocator -> Allocation -> Image -> IO Result
+
+-- | Binds image to allocation.
+--
+-- Binds specified image to region of memory represented by specified
+-- allocation. Gets @VkDeviceMemory@ handle and offset from the allocation.
+-- If you want to create an image, allocate memory for it and bind them
+-- together separately, you should use this function for binding instead of
+-- standard @vkBindImageMemory()@, because it ensures proper
+-- synchronization so that when a @VkDeviceMemory@ object is used by
+-- multiple allocations, calls to @vkBind*Memory()@ or @vkMapMemory()@
+-- won\'t happen from multiple threads simultaneously (which is illegal in
+-- Vulkan).
+--
+-- It is recommended to use function 'createImage' instead of this one.
+bindImageMemory :: forall io
+                 . (MonadIO io)
+                => -- No documentation found for Nested "vmaBindImageMemory" "allocator"
+                   Allocator
+                -> -- No documentation found for Nested "vmaBindImageMemory" "allocation"
+                   Allocation
+                -> -- No documentation found for Nested "vmaBindImageMemory" "image"
+                   Image
+                -> io ()
+bindImageMemory allocator allocation image = liftIO $ do
+  r <- traceAroundEvent "vmaBindImageMemory" ((ffiVmaBindImageMemory)
+                                                (allocator)
+                                                (allocation)
+                                                (image))
+  when (r < SUCCESS) (throwIO (VulkanException r))
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaBindImageMemory2" ffiVmaBindImageMemory2
+  :: Allocator -> Allocation -> DeviceSize -> Image -> Ptr () -> IO Result
+
+-- | Binds image to allocation with additional parameters.
+--
+-- __Parameters__
+--
+-- +-----------------------+--------------------------------------------------------+
+-- | allocator             |                                                        |
+-- +-----------------------+--------------------------------------------------------+
+-- | allocation            |                                                        |
+-- +-----------------------+--------------------------------------------------------+
+-- | allocationLocalOffset | Additional offset to be added while binding, relative  |
+-- |                       | to the beginning of the @allocation@. Normally it      |
+-- |                       | should be 0.                                           |
+-- +-----------------------+--------------------------------------------------------+
+-- | image                 |                                                        |
+-- +-----------------------+--------------------------------------------------------+
+-- | pNext                 | A chain of structures to be attached to                |
+-- |                       | @VkBindImageMemoryInfoKHR@ structure used internally.  |
+-- |                       | Normally it should be null.                            |
+-- +-----------------------+--------------------------------------------------------+
+--
+-- This function is similar to 'bindImageMemory', but it provides
+-- additional parameters.
+--
+-- If @pNext@ is not null, 'Allocator' object must have been created with
+-- 'ALLOCATOR_CREATE_KHR_BIND_MEMORY2_BIT' flag or with
+-- /VmaAllocatorCreateInfo::vulkanApiVersion/ @>= VK_API_VERSION_1_1@.
+-- Otherwise the call fails.
+bindImageMemory2 :: forall io
+                  . (MonadIO io)
+                 => -- No documentation found for Nested "vmaBindImageMemory2" "allocator"
+                    Allocator
+                 -> -- No documentation found for Nested "vmaBindImageMemory2" "allocation"
+                    Allocation
+                 -> -- No documentation found for Nested "vmaBindImageMemory2" "allocationLocalOffset"
+                    ("allocationLocalOffset" ::: DeviceSize)
+                 -> -- No documentation found for Nested "vmaBindImageMemory2" "image"
+                    Image
+                 -> -- No documentation found for Nested "vmaBindImageMemory2" "pNext"
+                    ("next" ::: Ptr ())
+                 -> io ()
+bindImageMemory2 allocator
+                   allocation
+                   allocationLocalOffset
+                   image
+                   next = liftIO $ do
+  r <- traceAroundEvent "vmaBindImageMemory2" ((ffiVmaBindImageMemory2)
+                                                 (allocator)
+                                                 (allocation)
+                                                 (allocationLocalOffset)
+                                                 (image)
+                                                 (next))
+  when (r < SUCCESS) (throwIO (VulkanException r))
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaCreateBuffer" ffiVmaCreateBuffer
+  :: Allocator -> Ptr (SomeStruct BufferCreateInfo) -> Ptr AllocationCreateInfo -> Ptr Buffer -> Ptr Allocation -> Ptr AllocationInfo -> IO Result
+
+-- | Creates a new @VkBuffer@, allocates and binds memory for it.
+--
+-- __Parameters__
+--
+-- +-----------+-----------------------+-----------------------------------------------+
+-- |           | allocator             |                                               |
+-- +-----------+-----------------------+-----------------------------------------------+
+-- |           | pBufferCreateInfo     |                                               |
+-- +-----------+-----------------------+-----------------------------------------------+
+-- |           | pAllocationCreateInfo |                                               |
+-- +-----------+-----------------------+-----------------------------------------------+
+-- | out       | pBuffer               | Buffer that was created.                      |
+-- +-----------+-----------------------+-----------------------------------------------+
+-- | out       | pAllocation           | Allocation that was created.                  |
+-- +-----------+-----------------------+-----------------------------------------------+
+-- | out       | pAllocationInfo       | Optional. Information about allocated memory. |
+-- |           |                       | It can be later fetched using function        |
+-- |           |                       | 'getAllocationInfo'.                          |
+-- +-----------+-----------------------+-----------------------------------------------+
+--
+-- This function automatically:
+--
+-- 1.  Creates buffer.
+--
+-- 2.  Allocates appropriate memory for it.
+--
+-- 3.  Binds the buffer with the memory.
+--
+-- If any of these operations fail, buffer and allocation are not created,
+-- returned value is negative error code, @*pBuffer@ and @*pAllocation@ are
+-- null.
+--
+-- If the function succeeded, you must destroy both buffer and allocation
+-- when you no longer need them using either convenience function
+-- 'destroyBuffer' or separately, using @vkDestroyBuffer()@ and
+-- 'freeMemory'.
+--
+-- If 'ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT' flag was used,
+-- VK_KHR_dedicated_allocation extension is used internally to query driver
+-- whether it requires or prefers the new buffer to have dedicated
+-- allocation. If yes, and if dedicated allocation is possible
+-- ('ALLOCATION_CREATE_NEVER_ALLOCATE_BIT' is not used), it creates
+-- dedicated allocation for this buffer, just like when using
+-- 'ALLOCATION_CREATE_DEDICATED_MEMORY_BIT'.
+--
+-- Note
+--
+-- This function creates a new @VkBuffer@. Sub-allocation of parts of one
+-- large buffer, although recommended as a good practice, is out of scope
+-- of this library and could be implemented by the user as a higher-level
+-- logic on top of VMA.
+createBuffer :: forall a io
+              . (Extendss BufferCreateInfo a, PokeChain a, MonadIO io)
+             => -- No documentation found for Nested "vmaCreateBuffer" "allocator"
+                Allocator
+             -> -- No documentation found for Nested "vmaCreateBuffer" "pBufferCreateInfo"
+                (BufferCreateInfo a)
+             -> -- No documentation found for Nested "vmaCreateBuffer" "pAllocationCreateInfo"
+                AllocationCreateInfo
+             -> io (Buffer, Allocation, AllocationInfo)
+createBuffer allocator
+               bufferCreateInfo
+               allocationCreateInfo = liftIO . evalContT $ do
+  pBufferCreateInfo <- ContT $ withCStruct (bufferCreateInfo)
+  pAllocationCreateInfo <- ContT $ withCStruct (allocationCreateInfo)
+  pPBuffer <- ContT $ bracket (callocBytes @Buffer 8) free
+  pPAllocation <- ContT $ bracket (callocBytes @Allocation 8) free
+  pPAllocationInfo <- ContT (withZeroCStruct @AllocationInfo)
+  r <- lift $ traceAroundEvent "vmaCreateBuffer" ((ffiVmaCreateBuffer)
+                                                    (allocator)
+                                                    (forgetExtensions pBufferCreateInfo)
+                                                    pAllocationCreateInfo
+                                                    (pPBuffer)
+                                                    (pPAllocation)
+                                                    (pPAllocationInfo))
+  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
+  pBuffer <- lift $ peek @Buffer pPBuffer
+  pAllocation <- lift $ peek @Allocation pPAllocation
+  pAllocationInfo <- lift $ peekCStruct @AllocationInfo pPAllocationInfo
+  pure $ (pBuffer, pAllocation, pAllocationInfo)
+
+-- | A convenience wrapper to make a compatible pair of calls to
+-- 'createBuffer' and 'destroyBuffer'
+--
+-- To ensure that 'destroyBuffer' is always called: pass
+-- 'Control.Exception.bracket' (or the allocate function from your
+-- favourite resource management library) as the last argument.
+-- To just extract the pair pass '(,)' as the last argument.
+--
+withBuffer :: forall a io r . (Extendss BufferCreateInfo a, PokeChain a, MonadIO io) => Allocator -> BufferCreateInfo a -> AllocationCreateInfo -> (io (Buffer, Allocation, AllocationInfo) -> ((Buffer, Allocation, AllocationInfo) -> io ()) -> r) -> r
+withBuffer allocator pBufferCreateInfo pAllocationCreateInfo b =
+  b (createBuffer allocator pBufferCreateInfo pAllocationCreateInfo)
+    (\(o0, o1, _) -> destroyBuffer allocator o0 o1)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaCreateBufferWithAlignment" ffiVmaCreateBufferWithAlignment
+  :: Allocator -> Ptr (SomeStruct BufferCreateInfo) -> Ptr AllocationCreateInfo -> DeviceSize -> Ptr Buffer -> Ptr Allocation -> Ptr AllocationInfo -> IO Result
+
+-- | Creates a buffer with additional minimum alignment.
+--
+-- Similar to 'createBuffer' but provides additional parameter
+-- @minAlignment@ which allows to specify custom, minimum alignment to be
+-- used when placing the buffer inside a larger memory block, which may be
+-- needed e.g. for interop with OpenGL.
+createBufferWithAlignment :: forall a io
+                           . ( Extendss BufferCreateInfo a
+                             , PokeChain a
+                             , MonadIO io )
+                          => -- No documentation found for Nested "vmaCreateBufferWithAlignment" "allocator"
+                             Allocator
+                          -> -- No documentation found for Nested "vmaCreateBufferWithAlignment" "pBufferCreateInfo"
+                             (BufferCreateInfo a)
+                          -> -- No documentation found for Nested "vmaCreateBufferWithAlignment" "pAllocationCreateInfo"
+                             AllocationCreateInfo
+                          -> -- No documentation found for Nested "vmaCreateBufferWithAlignment" "minAlignment"
+                             ("minAlignment" ::: DeviceSize)
+                          -> io (Buffer, Allocation, AllocationInfo)
+createBufferWithAlignment allocator
+                            bufferCreateInfo
+                            allocationCreateInfo
+                            minAlignment = liftIO . evalContT $ do
+  pBufferCreateInfo <- ContT $ withCStruct (bufferCreateInfo)
+  pAllocationCreateInfo <- ContT $ withCStruct (allocationCreateInfo)
+  pPBuffer <- ContT $ bracket (callocBytes @Buffer 8) free
+  pPAllocation <- ContT $ bracket (callocBytes @Allocation 8) free
+  pPAllocationInfo <- ContT (withZeroCStruct @AllocationInfo)
+  r <- lift $ traceAroundEvent "vmaCreateBufferWithAlignment" ((ffiVmaCreateBufferWithAlignment)
+                                                                 (allocator)
+                                                                 (forgetExtensions pBufferCreateInfo)
+                                                                 pAllocationCreateInfo
+                                                                 (minAlignment)
+                                                                 (pPBuffer)
+                                                                 (pPAllocation)
+                                                                 (pPAllocationInfo))
+  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
+  pBuffer <- lift $ peek @Buffer pPBuffer
+  pAllocation <- lift $ peek @Allocation pPAllocation
+  pAllocationInfo <- lift $ peekCStruct @AllocationInfo pPAllocationInfo
+  pure $ (pBuffer, pAllocation, pAllocationInfo)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaCreateAliasingBuffer" ffiVmaCreateAliasingBuffer
+  :: Allocator -> Allocation -> Ptr (SomeStruct BufferCreateInfo) -> Ptr Buffer -> IO Result
+
+-- | Creates a new @VkBuffer@, binds already created memory for it.
+--
+-- __Parameters__
+--
+-- +-----------+-------------------+-----------------------------------------------+
+-- |           | allocator         |                                               |
+-- +-----------+-------------------+-----------------------------------------------+
+-- |           | allocation        | Allocation that provides memory to be used    |
+-- |           |                   | for binding new buffer to it.                 |
+-- +-----------+-------------------+-----------------------------------------------+
+-- |           | pBufferCreateInfo |                                               |
+-- +-----------+-------------------+-----------------------------------------------+
+-- | out       | pBuffer           | Buffer that was created.                      |
+-- +-----------+-------------------+-----------------------------------------------+
+--
+-- This function automatically:
+--
+-- 1.  Creates buffer.
+--
+-- 2.  Binds the buffer with the supplied memory.
+--
+-- If any of these operations fail, buffer is not created, returned value
+-- is negative error code and @*pBuffer@ is null.
+--
+-- If the function succeeded, you must destroy the buffer when you no
+-- longer need it using @vkDestroyBuffer()@. If you want to also destroy
+-- the corresponding allocation you can use convenience function
+-- 'destroyBuffer'.
+--
+-- Note
+--
+-- There is a new version of this function augmented with parameter
+-- @allocationLocalOffset@ - see 'createAliasingBuffer2'.
+createAliasingBuffer :: forall a io
+                      . (Extendss BufferCreateInfo a, PokeChain a, MonadIO io)
+                     => -- No documentation found for Nested "vmaCreateAliasingBuffer" "allocator"
+                        Allocator
+                     -> -- No documentation found for Nested "vmaCreateAliasingBuffer" "allocation"
+                        Allocation
+                     -> -- No documentation found for Nested "vmaCreateAliasingBuffer" "pBufferCreateInfo"
+                        (BufferCreateInfo a)
+                     -> io (Buffer)
+createAliasingBuffer allocator
+                       allocation
+                       bufferCreateInfo = liftIO . evalContT $ do
+  pBufferCreateInfo <- ContT $ withCStruct (bufferCreateInfo)
+  pPBuffer <- ContT $ bracket (callocBytes @Buffer 8) free
+  r <- lift $ traceAroundEvent "vmaCreateAliasingBuffer" ((ffiVmaCreateAliasingBuffer)
+                                                            (allocator)
+                                                            (allocation)
+                                                            (forgetExtensions pBufferCreateInfo)
+                                                            (pPBuffer))
+  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
+  pBuffer <- lift $ peek @Buffer pPBuffer
+  pure $ (pBuffer)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaCreateAliasingBuffer2" ffiVmaCreateAliasingBuffer2
+  :: Allocator -> Allocation -> DeviceSize -> Ptr (SomeStruct BufferCreateInfo) -> Ptr Buffer -> IO Result
+
+-- | Creates a new @VkBuffer@, binds already created memory for it.
+--
+-- __Parameters__
+--
+-- +-----------+-----------------------+-----------------------------------------------+
+-- |           | allocator             |                                               |
+-- +-----------+-----------------------+-----------------------------------------------+
+-- |           | allocation            | Allocation that provides memory to be used    |
+-- |           |                       | for binding new buffer to it.                 |
+-- +-----------+-----------------------+-----------------------------------------------+
+-- |           | allocationLocalOffset | Additional offset to be added while binding,  |
+-- |           |                       | relative to the beginning of the allocation.  |
+-- |           |                       | Normally it should be 0.                      |
+-- +-----------+-----------------------+-----------------------------------------------+
+-- |           | pBufferCreateInfo     |                                               |
+-- +-----------+-----------------------+-----------------------------------------------+
+-- | out       | pBuffer               | Buffer that was created.                      |
+-- +-----------+-----------------------+-----------------------------------------------+
+--
+-- This function automatically:
+--
+-- 1.  Creates buffer.
+--
+-- 2.  Binds the buffer with the supplied memory.
+--
+-- If any of these operations fail, buffer is not created, returned value
+-- is negative error code and @*pBuffer@ is null.
+--
+-- If the function succeeded, you must destroy the buffer when you no
+-- longer need it using @vkDestroyBuffer()@. If you want to also destroy
+-- the corresponding allocation you can use convenience function
+-- 'destroyBuffer'.
+--
+-- Note
+--
+-- This is a new version of the function augmented with parameter
+-- @allocationLocalOffset@.
+createAliasingBuffer2 :: forall a io
+                       . (Extendss BufferCreateInfo a, PokeChain a, MonadIO io)
+                      => -- No documentation found for Nested "vmaCreateAliasingBuffer2" "allocator"
+                         Allocator
+                      -> -- No documentation found for Nested "vmaCreateAliasingBuffer2" "allocation"
+                         Allocation
+                      -> -- No documentation found for Nested "vmaCreateAliasingBuffer2" "allocationLocalOffset"
+                         ("allocationLocalOffset" ::: DeviceSize)
+                      -> -- No documentation found for Nested "vmaCreateAliasingBuffer2" "pBufferCreateInfo"
+                         (BufferCreateInfo a)
+                      -> io (Buffer)
+createAliasingBuffer2 allocator
+                        allocation
+                        allocationLocalOffset
+                        bufferCreateInfo = liftIO . evalContT $ do
+  pBufferCreateInfo <- ContT $ withCStruct (bufferCreateInfo)
+  pPBuffer <- ContT $ bracket (callocBytes @Buffer 8) free
+  r <- lift $ traceAroundEvent "vmaCreateAliasingBuffer2" ((ffiVmaCreateAliasingBuffer2)
+                                                             (allocator)
+                                                             (allocation)
+                                                             (allocationLocalOffset)
+                                                             (forgetExtensions pBufferCreateInfo)
+                                                             (pPBuffer))
+  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
+  pBuffer <- lift $ peek @Buffer pPBuffer
+  pure $ (pBuffer)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaDestroyBuffer" ffiVmaDestroyBuffer
+  :: Allocator -> Buffer -> Allocation -> IO ()
+
+-- | Destroys Vulkan buffer and frees allocated memory.
+--
+-- This is just a convenience function equivalent to:
+--
+-- > vkDestroyBuffer(device, buffer, allocationCallbacks);
+-- > vmaFreeMemory(allocator, allocation);
+--
+-- It is safe to pass null as buffer and\/or allocation.
+destroyBuffer :: forall io
+               . (MonadIO io)
+              => -- No documentation found for Nested "vmaDestroyBuffer" "allocator"
+                 Allocator
+              -> -- No documentation found for Nested "vmaDestroyBuffer" "buffer"
+                 Buffer
+              -> -- No documentation found for Nested "vmaDestroyBuffer" "allocation"
+                 Allocation
+              -> io ()
+destroyBuffer allocator buffer allocation = liftIO $ do
+  traceAroundEvent "vmaDestroyBuffer" ((ffiVmaDestroyBuffer)
+                                         (allocator)
+                                         (buffer)
+                                         (allocation))
+  pure $ ()
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaCreateImage" ffiVmaCreateImage
+  :: Allocator -> Ptr (SomeStruct ImageCreateInfo) -> Ptr AllocationCreateInfo -> Ptr Image -> Ptr Allocation -> Ptr AllocationInfo -> IO Result
+
+-- | Function similar to 'createBuffer'.
+createImage :: forall a io
+             . (Extendss ImageCreateInfo a, PokeChain a, MonadIO io)
+            => -- No documentation found for Nested "vmaCreateImage" "allocator"
+               Allocator
+            -> -- No documentation found for Nested "vmaCreateImage" "pImageCreateInfo"
+               (ImageCreateInfo a)
+            -> -- No documentation found for Nested "vmaCreateImage" "pAllocationCreateInfo"
+               AllocationCreateInfo
+            -> io (Image, Allocation, AllocationInfo)
+createImage allocator
+              imageCreateInfo
+              allocationCreateInfo = liftIO . evalContT $ do
+  pImageCreateInfo <- ContT $ withCStruct (imageCreateInfo)
+  pAllocationCreateInfo <- ContT $ withCStruct (allocationCreateInfo)
+  pPImage <- ContT $ bracket (callocBytes @Image 8) free
+  pPAllocation <- ContT $ bracket (callocBytes @Allocation 8) free
+  pPAllocationInfo <- ContT (withZeroCStruct @AllocationInfo)
+  r <- lift $ traceAroundEvent "vmaCreateImage" ((ffiVmaCreateImage)
+                                                   (allocator)
+                                                   (forgetExtensions pImageCreateInfo)
+                                                   pAllocationCreateInfo
+                                                   (pPImage)
+                                                   (pPAllocation)
+                                                   (pPAllocationInfo))
+  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
+  pImage <- lift $ peek @Image pPImage
+  pAllocation <- lift $ peek @Allocation pPAllocation
+  pAllocationInfo <- lift $ peekCStruct @AllocationInfo pPAllocationInfo
+  pure $ (pImage, pAllocation, pAllocationInfo)
+
+-- | A convenience wrapper to make a compatible pair of calls to
+-- 'createImage' and 'destroyImage'
+--
+-- To ensure that 'destroyImage' is always called: pass
+-- 'Control.Exception.bracket' (or the allocate function from your
+-- favourite resource management library) as the last argument.
+-- To just extract the pair pass '(,)' as the last argument.
+--
+withImage :: forall a io r . (Extendss ImageCreateInfo a, PokeChain a, MonadIO io) => Allocator -> ImageCreateInfo a -> AllocationCreateInfo -> (io (Image, Allocation, AllocationInfo) -> ((Image, Allocation, AllocationInfo) -> io ()) -> r) -> r
+withImage allocator pImageCreateInfo pAllocationCreateInfo b =
+  b (createImage allocator pImageCreateInfo pAllocationCreateInfo)
+    (\(o0, o1, _) -> destroyImage allocator o0 o1)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaCreateAliasingImage" ffiVmaCreateAliasingImage
+  :: Allocator -> Allocation -> Ptr (SomeStruct ImageCreateInfo) -> Ptr Image -> IO Result
+
+-- | Function similar to 'createAliasingBuffer' but for images.
+createAliasingImage :: forall a io
+                     . (Extendss ImageCreateInfo a, PokeChain a, MonadIO io)
+                    => -- No documentation found for Nested "vmaCreateAliasingImage" "allocator"
+                       Allocator
+                    -> -- No documentation found for Nested "vmaCreateAliasingImage" "allocation"
+                       Allocation
+                    -> -- No documentation found for Nested "vmaCreateAliasingImage" "pImageCreateInfo"
+                       (ImageCreateInfo a)
+                    -> io (Image)
+createAliasingImage allocator
+                      allocation
+                      imageCreateInfo = liftIO . evalContT $ do
+  pImageCreateInfo <- ContT $ withCStruct (imageCreateInfo)
+  pPImage <- ContT $ bracket (callocBytes @Image 8) free
+  r <- lift $ traceAroundEvent "vmaCreateAliasingImage" ((ffiVmaCreateAliasingImage)
+                                                           (allocator)
+                                                           (allocation)
+                                                           (forgetExtensions pImageCreateInfo)
+                                                           (pPImage))
+  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
+  pImage <- lift $ peek @Image pPImage
+  pure $ (pImage)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaCreateAliasingImage2" ffiVmaCreateAliasingImage2
+  :: Allocator -> Allocation -> DeviceSize -> Ptr (SomeStruct ImageCreateInfo) -> Ptr Image -> IO Result
+
+-- | Function similar to 'createAliasingBuffer2' but for images.
+createAliasingImage2 :: forall a io
+                      . (Extendss ImageCreateInfo a, PokeChain a, MonadIO io)
+                     => -- No documentation found for Nested "vmaCreateAliasingImage2" "allocator"
+                        Allocator
+                     -> -- No documentation found for Nested "vmaCreateAliasingImage2" "allocation"
+                        Allocation
+                     -> -- No documentation found for Nested "vmaCreateAliasingImage2" "allocationLocalOffset"
+                        ("allocationLocalOffset" ::: DeviceSize)
+                     -> -- No documentation found for Nested "vmaCreateAliasingImage2" "pImageCreateInfo"
+                        (ImageCreateInfo a)
+                     -> io (Image)
+createAliasingImage2 allocator
+                       allocation
+                       allocationLocalOffset
+                       imageCreateInfo = liftIO . evalContT $ do
+  pImageCreateInfo <- ContT $ withCStruct (imageCreateInfo)
+  pPImage <- ContT $ bracket (callocBytes @Image 8) free
+  r <- lift $ traceAroundEvent "vmaCreateAliasingImage2" ((ffiVmaCreateAliasingImage2)
+                                                            (allocator)
+                                                            (allocation)
+                                                            (allocationLocalOffset)
+                                                            (forgetExtensions pImageCreateInfo)
+                                                            (pPImage))
+  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
+  pImage <- lift $ peek @Image pPImage
+  pure $ (pImage)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaDestroyImage" ffiVmaDestroyImage
+  :: Allocator -> Image -> Allocation -> IO ()
+
+-- | Destroys Vulkan image and frees allocated memory.
+--
+-- This is just a convenience function equivalent to:
+--
+-- > vkDestroyImage(device, image, allocationCallbacks);
+-- > vmaFreeMemory(allocator, allocation);
+--
+-- It is safe to pass null as image and\/or allocation.
+destroyImage :: forall io
+              . (MonadIO io)
+             => -- No documentation found for Nested "vmaDestroyImage" "allocator"
+                Allocator
+             -> -- No documentation found for Nested "vmaDestroyImage" "image"
+                Image
+             -> -- No documentation found for Nested "vmaDestroyImage" "allocation"
+                Allocation
+             -> io ()
+destroyImage allocator image allocation = liftIO $ do
+  traceAroundEvent "vmaDestroyImage" ((ffiVmaDestroyImage)
+                                        (allocator)
+                                        (image)
+                                        (allocation))
+  pure $ ()
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaCreateVirtualBlock" ffiVmaCreateVirtualBlock
+  :: Ptr VirtualBlockCreateInfo -> Ptr VirtualBlock -> IO Result
+
+-- | Creates new 'VirtualBlock' object.
+--
+-- __Parameters__
+--
+-- +-----------+---------------+-----------------------------------------------+
+-- |           | pCreateInfo   | Parameters for creation.                      |
+-- +-----------+---------------+-----------------------------------------------+
+-- | out       | pVirtualBlock | Returned virtual block object or @VMA_NULL@   |
+-- |           |               | if creation failed.                           |
+-- +-----------+---------------+-----------------------------------------------+
+createVirtualBlock :: forall io
+                    . (MonadIO io)
+                   => -- No documentation found for Nested "vmaCreateVirtualBlock" "pCreateInfo"
+                      VirtualBlockCreateInfo
+                   -> io (VirtualBlock)
+createVirtualBlock createInfo = liftIO . evalContT $ do
+  pCreateInfo <- ContT $ withCStruct (createInfo)
+  pPVirtualBlock <- ContT $ bracket (callocBytes @VirtualBlock 8) free
+  r <- lift $ traceAroundEvent "vmaCreateVirtualBlock" ((ffiVmaCreateVirtualBlock)
+                                                          pCreateInfo
+                                                          (pPVirtualBlock))
+  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
+  pVirtualBlock <- lift $ peek @VirtualBlock pPVirtualBlock
+  pure $ (pVirtualBlock)
+
+-- | A convenience wrapper to make a compatible pair of calls to
+-- 'createVirtualBlock' and 'destroyVirtualBlock'
+--
+-- To ensure that 'destroyVirtualBlock' is always called: pass
+-- 'Control.Exception.bracket' (or the allocate function from your
+-- favourite resource management library) as the last argument.
+-- To just extract the pair pass '(,)' as the last argument.
+--
+withVirtualBlock :: forall io r . MonadIO io => VirtualBlockCreateInfo -> (io VirtualBlock -> (VirtualBlock -> io ()) -> r) -> r
+withVirtualBlock pCreateInfo b =
+  b (createVirtualBlock pCreateInfo)
+    (\(o0) -> destroyVirtualBlock o0)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaDestroyVirtualBlock" ffiVmaDestroyVirtualBlock
+  :: VirtualBlock -> IO ()
+
+-- | Destroys 'VirtualBlock' object.
+--
+-- Please note that you should consciously handle virtual allocations that
+-- could remain unfreed in the block. You should either free them
+-- individually using 'virtualFree' or call 'clearVirtualBlock' if you are
+-- sure this is what you want. If you do neither, an assert is called.
+--
+-- If you keep pointers to some additional metadata associated with your
+-- virtual allocations in their @pUserData@, don\'t forget to free them.
+destroyVirtualBlock :: forall io
+                     . (MonadIO io)
+                    => -- No documentation found for Nested "vmaDestroyVirtualBlock" "virtualBlock"
+                       VirtualBlock
+                    -> io ()
+destroyVirtualBlock virtualBlock = liftIO $ do
+  traceAroundEvent "vmaDestroyVirtualBlock" ((ffiVmaDestroyVirtualBlock)
+                                               (virtualBlock))
+  pure $ ()
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaIsVirtualBlockEmpty" ffiVmaIsVirtualBlockEmpty
+  :: VirtualBlock -> IO Bool32
+
+-- | Returns true of the 'VirtualBlock' is empty - contains 0 virtual
+-- allocations and has all its space available for new allocations.
+isVirtualBlockEmpty :: forall io
+                     . (MonadIO io)
+                    => -- No documentation found for Nested "vmaIsVirtualBlockEmpty" "virtualBlock"
+                       VirtualBlock
+                    -> io (Bool)
+isVirtualBlockEmpty virtualBlock = liftIO $ do
+  r <- traceAroundEvent "vmaIsVirtualBlockEmpty" ((ffiVmaIsVirtualBlockEmpty)
+                                                    (virtualBlock))
+  pure $ ((bool32ToBool r))
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaGetVirtualAllocationInfo" ffiVmaGetVirtualAllocationInfo
+  :: VirtualBlock -> VirtualAllocation -> Ptr VirtualAllocationInfo -> IO ()
+
+-- | Returns information about a specific virtual allocation within a virtual
+-- block, like its size and @pUserData@ pointer.
+getVirtualAllocationInfo :: forall io
+                          . (MonadIO io)
+                         => -- No documentation found for Nested "vmaGetVirtualAllocationInfo" "virtualBlock"
+                            VirtualBlock
+                         -> -- No documentation found for Nested "vmaGetVirtualAllocationInfo" "allocation"
+                            VirtualAllocation
+                         -> io (("virtualAllocInfo" ::: VirtualAllocationInfo))
+getVirtualAllocationInfo virtualBlock allocation = liftIO . evalContT $ do
+  pPVirtualAllocInfo <- ContT (withZeroCStruct @VirtualAllocationInfo)
+  lift $ traceAroundEvent "vmaGetVirtualAllocationInfo" ((ffiVmaGetVirtualAllocationInfo)
+                                                           (virtualBlock)
+                                                           (allocation)
+                                                           (pPVirtualAllocInfo))
+  pVirtualAllocInfo <- lift $ peekCStruct @VirtualAllocationInfo pPVirtualAllocInfo
+  pure $ (pVirtualAllocInfo)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaVirtualAllocate" ffiVmaVirtualAllocate
+  :: VirtualBlock -> Ptr VirtualAllocationCreateInfo -> Ptr VirtualAllocation -> Ptr DeviceSize -> IO Result
+
+-- | Allocates new virtual allocation inside given 'VirtualBlock'.
+--
+-- If the allocation fails due to not enough free space available,
+-- @VK_ERROR_OUT_OF_DEVICE_MEMORY@ is returned (despite the function
+-- doesn\'t ever allocate actual GPU memory). @pAllocation@ is then set to
+-- @VK_NULL_HANDLE@ and @pOffset@, if not null, it set to @UINT64_MAX@.
+--
+-- __Parameters__
+--
+-- +-----------+--------------+-----------------------------------------------+
+-- |           | virtualBlock | Virtual block                                 |
+-- +-----------+--------------+-----------------------------------------------+
+-- |           | pCreateInfo  | Parameters for the allocation                 |
+-- +-----------+--------------+-----------------------------------------------+
+-- | out       | pAllocation  | Returned handle of the new allocation         |
+-- +-----------+--------------+-----------------------------------------------+
+-- | out       | pOffset      | Returned offset of the new allocation.        |
+-- |           |              | Optional, can be null.                        |
+-- +-----------+--------------+-----------------------------------------------+
+virtualAllocate :: forall io
+                 . (MonadIO io)
+                => -- No documentation found for Nested "vmaVirtualAllocate" "virtualBlock"
+                   VirtualBlock
+                -> -- No documentation found for Nested "vmaVirtualAllocate" "pCreateInfo"
+                   VirtualAllocationCreateInfo
+                -> io (VirtualAllocation, ("offset" ::: DeviceSize))
+virtualAllocate virtualBlock createInfo = liftIO . evalContT $ do
+  pCreateInfo <- ContT $ withCStruct (createInfo)
+  pPAllocation <- ContT $ bracket (callocBytes @VirtualAllocation 8) free
+  pPOffset <- ContT $ bracket (callocBytes @DeviceSize 8) free
+  r <- lift $ traceAroundEvent "vmaVirtualAllocate" ((ffiVmaVirtualAllocate)
+                                                       (virtualBlock)
+                                                       pCreateInfo
+                                                       (pPAllocation)
+                                                       (pPOffset))
+  lift $ when (r < SUCCESS) (throwIO (VulkanException r))
+  pAllocation <- lift $ peek @VirtualAllocation pPAllocation
+  pOffset <- lift $ peek @DeviceSize pPOffset
+  pure $ (pAllocation, pOffset)
+
+-- | A convenience wrapper to make a compatible pair of calls to
+-- 'virtualAllocate' and 'virtualFree'
+--
+-- To ensure that 'virtualFree' is always called: pass
+-- 'Control.Exception.bracket' (or the allocate function from your
+-- favourite resource management library) as the last argument.
+-- To just extract the pair pass '(,)' as the last argument.
+--
+withVirtualAllocation :: forall io r . MonadIO io => VirtualBlock -> VirtualAllocationCreateInfo -> (io (VirtualAllocation, DeviceSize) -> ((VirtualAllocation, DeviceSize) -> io ()) -> r) -> r
+withVirtualAllocation virtualBlock pCreateInfo b =
+  b (virtualAllocate virtualBlock pCreateInfo)
+    (\(o0, _) -> virtualFree virtualBlock o0)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaVirtualFree" ffiVmaVirtualFree
+  :: VirtualBlock -> VirtualAllocation -> IO ()
+
+-- | Frees virtual allocation inside given 'VirtualBlock'.
+--
+-- It is correct to call this function with @allocation == VK_NULL_HANDLE@
+-- - it does nothing.
+virtualFree :: forall io
+             . (MonadIO io)
+            => -- No documentation found for Nested "vmaVirtualFree" "virtualBlock"
+               VirtualBlock
+            -> -- No documentation found for Nested "vmaVirtualFree" "allocation"
+               VirtualAllocation
+            -> io ()
+virtualFree virtualBlock allocation = liftIO $ do
+  traceAroundEvent "vmaVirtualFree" ((ffiVmaVirtualFree)
+                                       (virtualBlock)
+                                       (allocation))
+  pure $ ()
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaClearVirtualBlock" ffiVmaClearVirtualBlock
+  :: VirtualBlock -> IO ()
+
+-- | Frees all virtual allocations inside given 'VirtualBlock'.
+--
+-- You must either call this function or free each virtual allocation
+-- individually with 'virtualFree' before destroying a virtual block.
+-- Otherwise, an assert is called.
+--
+-- If you keep pointer to some additional metadata associated with your
+-- virtual allocation in its @pUserData@, don\'t forget to free it as well.
+clearVirtualBlock :: forall io
+                   . (MonadIO io)
+                  => -- No documentation found for Nested "vmaClearVirtualBlock" "virtualBlock"
+                     VirtualBlock
+                  -> io ()
+clearVirtualBlock virtualBlock = liftIO $ do
+  traceAroundEvent "vmaClearVirtualBlock" ((ffiVmaClearVirtualBlock)
+                                             (virtualBlock))
+  pure $ ()
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaSetVirtualAllocationUserData" ffiVmaSetVirtualAllocationUserData
+  :: VirtualBlock -> VirtualAllocation -> Ptr () -> IO ()
+
+-- | Changes custom pointer associated with given virtual allocation.
+setVirtualAllocationUserData :: forall io
+                              . (MonadIO io)
+                             => -- No documentation found for Nested "vmaSetVirtualAllocationUserData" "virtualBlock"
+                                VirtualBlock
+                             -> -- No documentation found for Nested "vmaSetVirtualAllocationUserData" "allocation"
+                                VirtualAllocation
+                             -> -- No documentation found for Nested "vmaSetVirtualAllocationUserData" "pUserData"
+                                ("userData" ::: Ptr ())
+                             -> io ()
+setVirtualAllocationUserData virtualBlock allocation userData = liftIO $ do
+  traceAroundEvent "vmaSetVirtualAllocationUserData" ((ffiVmaSetVirtualAllocationUserData)
+                                                        (virtualBlock)
+                                                        (allocation)
+                                                        (userData))
+  pure $ ()
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaGetVirtualBlockStatistics" ffiVmaGetVirtualBlockStatistics
+  :: VirtualBlock -> Ptr Statistics -> IO ()
+
+-- | Calculates and returns statistics about virtual allocations and memory
+-- usage in given 'VirtualBlock'.
+--
+-- This function is fast to call. For more detailed statistics, see
+-- 'calculateVirtualBlockStatistics'.
+getVirtualBlockStatistics :: forall io
+                           . (MonadIO io)
+                          => -- No documentation found for Nested "vmaGetVirtualBlockStatistics" "virtualBlock"
+                             VirtualBlock
+                          -> io (("stats" ::: Statistics))
+getVirtualBlockStatistics virtualBlock = liftIO . evalContT $ do
+  pPStats <- ContT (withZeroCStruct @Statistics)
+  lift $ traceAroundEvent "vmaGetVirtualBlockStatistics" ((ffiVmaGetVirtualBlockStatistics)
+                                                            (virtualBlock)
+                                                            (pPStats))
+  pStats <- lift $ peekCStruct @Statistics pPStats
+  pure $ (pStats)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaCalculateVirtualBlockStatistics" ffiVmaCalculateVirtualBlockStatistics
+  :: VirtualBlock -> Ptr DetailedStatistics -> IO ()
+
+-- | Calculates and returns detailed statistics about virtual allocations and
+-- memory usage in given 'VirtualBlock'.
+--
+-- This function is slow to call. Use for debugging purposes. For less
+-- detailed statistics, see 'getVirtualBlockStatistics'.
+calculateVirtualBlockStatistics :: forall io
+                                 . (MonadIO io)
+                                => -- No documentation found for Nested "vmaCalculateVirtualBlockStatistics" "virtualBlock"
+                                   VirtualBlock
+                                -> io (("stats" ::: DetailedStatistics))
+calculateVirtualBlockStatistics virtualBlock = liftIO . evalContT $ do
+  pPStats <- ContT (withZeroCStruct @DetailedStatistics)
+  lift $ traceAroundEvent "vmaCalculateVirtualBlockStatistics" ((ffiVmaCalculateVirtualBlockStatistics)
+                                                                  (virtualBlock)
+                                                                  (pPStats))
+  pStats <- lift $ peekCStruct @DetailedStatistics pPStats
+  pure $ (pStats)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaBuildVirtualBlockStatsString" ffiVmaBuildVirtualBlockStatsString
+  :: VirtualBlock -> Ptr (Ptr CChar) -> Bool32 -> IO ()
+
+-- | Builds and returns a null-terminated string in JSON format with
+-- information about given 'VirtualBlock'.
+--
+-- __Parameters__
+--
+-- +-----------+---------------+-----------------------------------------------+
+-- |           | virtualBlock  | Virtual block.                                |
+-- +-----------+---------------+-----------------------------------------------+
+-- | out       | ppStatsString | Returned string.                              |
+-- +-----------+---------------+-----------------------------------------------+
+-- |           | detailedMap   | Pass @VK_FALSE@ to only obtain statistics as  |
+-- |           |               | returned by                                   |
+-- |           |               | 'calculateVirtualBlockStatistics'. Pass       |
+-- |           |               | @VK_TRUE@ to also obtain full list of         |
+-- |           |               | allocations and free spaces.                  |
+-- +-----------+---------------+-----------------------------------------------+
+--
+-- Returned string must be freed using 'freeVirtualBlockStatsString'.
+buildVirtualBlockStatsString :: forall io
+                              . (MonadIO io)
+                             => -- No documentation found for Nested "vmaBuildVirtualBlockStatsString" "virtualBlock"
+                                VirtualBlock
+                             -> -- No documentation found for Nested "vmaBuildVirtualBlockStatsString" "detailedMap"
+                                ("detailedMap" ::: Bool)
+                             -> io (("statsString" ::: Ptr CChar))
+buildVirtualBlockStatsString virtualBlock detailedMap = liftIO . evalContT $ do
+  pPpStatsString <- ContT $ bracket (callocBytes @(Ptr CChar) 8) free
+  lift $ traceAroundEvent "vmaBuildVirtualBlockStatsString" ((ffiVmaBuildVirtualBlockStatsString)
+                                                               (virtualBlock)
+                                                               (pPpStatsString)
+                                                               (boolToBool32 (detailedMap)))
+  ppStatsString <- lift $ peek @(Ptr CChar) pPpStatsString
+  pure $ (ppStatsString)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaFreeVirtualBlockStatsString" ffiVmaFreeVirtualBlockStatsString
+  :: VirtualBlock -> Ptr CChar -> IO ()
+
+-- | Frees a string returned by 'buildVirtualBlockStatsString'.
+freeVirtualBlockStatsString :: forall io
+                             . (MonadIO io)
+                            => -- No documentation found for Nested "vmaFreeVirtualBlockStatsString" "virtualBlock"
+                               VirtualBlock
+                            -> -- No documentation found for Nested "vmaFreeVirtualBlockStatsString" "pStatsString"
+                               ("statsString" ::: Ptr CChar)
+                            -> io ()
+freeVirtualBlockStatsString virtualBlock statsString = liftIO $ do
+  traceAroundEvent "vmaFreeVirtualBlockStatsString" ((ffiVmaFreeVirtualBlockStatsString)
+                                                       (virtualBlock)
+                                                       (statsString))
+  pure $ ()
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaBuildStatsString" ffiVmaBuildStatsString
+  :: Allocator -> Ptr (Ptr CChar) -> Bool32 -> IO ()
+
+-- | Builds and returns statistics as a null-terminated string in JSON
+-- format.
+--
+-- __Parameters__
+--
+-- +-----------+---------------+-----------------------------------------------+
+-- |           | allocator     |                                               |
+-- +-----------+---------------+-----------------------------------------------+
+-- | out       | ppStatsString | Must be freed using 'freeStatsString'         |
+-- |           |               | function.                                     |
+-- +-----------+---------------+-----------------------------------------------+
+-- |           | detailedMap   |                                               |
+-- +-----------+---------------+-----------------------------------------------+
+buildStatsString :: forall io
+                  . (MonadIO io)
+                 => -- No documentation found for Nested "vmaBuildStatsString" "allocator"
+                    Allocator
+                 -> -- No documentation found for Nested "vmaBuildStatsString" "detailedMap"
+                    ("detailedMap" ::: Bool)
+                 -> io (("statsString" ::: Ptr CChar))
+buildStatsString allocator detailedMap = liftIO . evalContT $ do
+  pPpStatsString <- ContT $ bracket (callocBytes @(Ptr CChar) 8) free
+  lift $ traceAroundEvent "vmaBuildStatsString" ((ffiVmaBuildStatsString)
+                                                   (allocator)
+                                                   (pPpStatsString)
+                                                   (boolToBool32 (detailedMap)))
+  ppStatsString <- lift $ peek @(Ptr CChar) pPpStatsString
+  pure $ (ppStatsString)
+
+
+foreign import ccall
+#if !defined(SAFE_FOREIGN_CALLS)
+  unsafe
+#endif
+  "vmaFreeStatsString" ffiVmaFreeStatsString
+  :: Allocator -> Ptr CChar -> IO ()
+
+
+freeStatsString :: forall io
+                 . (MonadIO io)
+                => -- No documentation found for Nested "vmaFreeStatsString" "allocator"
+                   Allocator
+                -> -- No documentation found for Nested "vmaFreeStatsString" "pStatsString"
+                   ("statsString" ::: Ptr CChar)
+                -> io ()
+freeStatsString allocator statsString = liftIO $ do
+  traceAroundEvent "vmaFreeStatsString" ((ffiVmaFreeStatsString)
+                                           (allocator)
+                                           (statsString))
+  pure $ ()
+
+
+type FN_vkAllocateMemory = Ptr Device_T -> ("pAllocateInfo" ::: Ptr (SomeStruct MemoryAllocateInfo)) -> ("pAllocator" ::: Ptr AllocationCallbacks) -> ("pMemory" ::: Ptr DeviceMemory) -> IO Result
+-- No documentation found for TopLevel "PFN_vkAllocateMemory"
+type PFN_vkAllocateMemory = FunPtr FN_vkAllocateMemory
+
+
+type FN_vkBindBufferMemory = Ptr Device_T -> Buffer -> DeviceMemory -> ("memoryOffset" ::: DeviceSize) -> IO Result
+-- No documentation found for TopLevel "PFN_vkBindBufferMemory"
+type PFN_vkBindBufferMemory = FunPtr FN_vkBindBufferMemory
+
+
+type FN_vkBindBufferMemory2KHR = Ptr Device_T -> ("bindInfoCount" ::: Word32) -> ("pBindInfos" ::: Ptr (SomeStruct BindBufferMemoryInfo)) -> IO Result
+-- No documentation found for TopLevel "PFN_vkBindBufferMemory2KHR"
+type PFN_vkBindBufferMemory2KHR = FunPtr FN_vkBindBufferMemory2KHR
+
+
+type FN_vkBindImageMemory = Ptr Device_T -> Image -> DeviceMemory -> ("memoryOffset" ::: DeviceSize) -> IO Result
+-- No documentation found for TopLevel "PFN_vkBindImageMemory"
+type PFN_vkBindImageMemory = FunPtr FN_vkBindImageMemory
+
+
+type FN_vkBindImageMemory2KHR = Ptr Device_T -> ("bindInfoCount" ::: Word32) -> ("pBindInfos" ::: Ptr (SomeStruct BindImageMemoryInfo)) -> IO Result
+-- No documentation found for TopLevel "PFN_vkBindImageMemory2KHR"
+type PFN_vkBindImageMemory2KHR = FunPtr FN_vkBindImageMemory2KHR
+
+
+type FN_vkCmdCopyBuffer = Ptr CommandBuffer_T -> ("srcBuffer" ::: Buffer) -> ("dstBuffer" ::: Buffer) -> ("regionCount" ::: Word32) -> ("pRegions" ::: Ptr BufferCopy) -> IO ()
+-- No documentation found for TopLevel "PFN_vkCmdCopyBuffer"
+type PFN_vkCmdCopyBuffer = FunPtr FN_vkCmdCopyBuffer
+
+
+type FN_vkCreateBuffer = Ptr Device_T -> ("pCreateInfo" ::: Ptr (SomeStruct BufferCreateInfo)) -> ("pAllocator" ::: Ptr AllocationCallbacks) -> ("pBuffer" ::: Ptr Buffer) -> IO Result
+-- No documentation found for TopLevel "PFN_vkCreateBuffer"
+type PFN_vkCreateBuffer = FunPtr FN_vkCreateBuffer
+
+
+type FN_vkCreateImage = Ptr Device_T -> ("pCreateInfo" ::: Ptr (SomeStruct ImageCreateInfo)) -> ("pAllocator" ::: Ptr AllocationCallbacks) -> ("pImage" ::: Ptr Image) -> IO Result
+-- No documentation found for TopLevel "PFN_vkCreateImage"
+type PFN_vkCreateImage = FunPtr FN_vkCreateImage
+
+
+type FN_vkDestroyBuffer = Ptr Device_T -> Buffer -> ("pAllocator" ::: Ptr AllocationCallbacks) -> IO ()
+-- No documentation found for TopLevel "PFN_vkDestroyBuffer"
+type PFN_vkDestroyBuffer = FunPtr FN_vkDestroyBuffer
+
+
+type FN_vkDestroyImage = Ptr Device_T -> Image -> ("pAllocator" ::: Ptr AllocationCallbacks) -> IO ()
+-- No documentation found for TopLevel "PFN_vkDestroyImage"
+type PFN_vkDestroyImage = FunPtr FN_vkDestroyImage
+
+
+type FN_vkFlushMappedMemoryRanges = Ptr Device_T -> ("memoryRangeCount" ::: Word32) -> ("pMemoryRanges" ::: Ptr MappedMemoryRange) -> IO Result
+-- No documentation found for TopLevel "PFN_vkFlushMappedMemoryRanges"
+type PFN_vkFlushMappedMemoryRanges = FunPtr FN_vkFlushMappedMemoryRanges
+
+
+type FN_vkFreeMemory = Ptr Device_T -> DeviceMemory -> ("pAllocator" ::: Ptr AllocationCallbacks) -> IO ()
+-- No documentation found for TopLevel "PFN_vkFreeMemory"
+type PFN_vkFreeMemory = FunPtr FN_vkFreeMemory
+
+
+type FN_vkGetBufferMemoryRequirements = Ptr Device_T -> Buffer -> ("pMemoryRequirements" ::: Ptr MemoryRequirements) -> IO ()
+-- No documentation found for TopLevel "PFN_vkGetBufferMemoryRequirements"
+type PFN_vkGetBufferMemoryRequirements = FunPtr FN_vkGetBufferMemoryRequirements
+
+
+type FN_vkGetBufferMemoryRequirements2KHR = Ptr Device_T -> ("pInfo" ::: Ptr BufferMemoryRequirementsInfo2) -> ("pMemoryRequirements" ::: Ptr (SomeStruct MemoryRequirements2)) -> IO ()
+-- No documentation found for TopLevel "PFN_vkGetBufferMemoryRequirements2KHR"
+type PFN_vkGetBufferMemoryRequirements2KHR = FunPtr FN_vkGetBufferMemoryRequirements2KHR
+
+
+type FN_vkGetImageMemoryRequirements = Ptr Device_T -> Image -> ("pMemoryRequirements" ::: Ptr MemoryRequirements) -> IO ()
+-- No documentation found for TopLevel "PFN_vkGetImageMemoryRequirements"
+type PFN_vkGetImageMemoryRequirements = FunPtr FN_vkGetImageMemoryRequirements
+
+
+type FN_vkGetImageMemoryRequirements2KHR = Ptr Device_T -> ("pInfo" ::: Ptr (SomeStruct ImageMemoryRequirementsInfo2)) -> ("pMemoryRequirements" ::: Ptr (SomeStruct MemoryRequirements2)) -> IO ()
+-- No documentation found for TopLevel "PFN_vkGetImageMemoryRequirements2KHR"
+type PFN_vkGetImageMemoryRequirements2KHR = FunPtr FN_vkGetImageMemoryRequirements2KHR
+
+
+type FN_vkGetPhysicalDeviceMemoryProperties = Ptr PhysicalDevice_T -> ("pMemoryProperties" ::: Ptr PhysicalDeviceMemoryProperties) -> IO ()
+-- No documentation found for TopLevel "PFN_vkGetPhysicalDeviceMemoryProperties"
+type PFN_vkGetPhysicalDeviceMemoryProperties = FunPtr FN_vkGetPhysicalDeviceMemoryProperties
+
+
+type FN_vkGetPhysicalDeviceMemoryProperties2KHR = Ptr PhysicalDevice_T -> ("pMemoryProperties" ::: Ptr (SomeStruct PhysicalDeviceMemoryProperties2)) -> IO ()
+-- No documentation found for TopLevel "PFN_vkGetPhysicalDeviceMemoryProperties2KHR"
+type PFN_vkGetPhysicalDeviceMemoryProperties2KHR = FunPtr FN_vkGetPhysicalDeviceMemoryProperties2KHR
+
+
+type FN_vkGetPhysicalDeviceProperties = Ptr PhysicalDevice_T -> ("pProperties" ::: Ptr PhysicalDeviceProperties) -> IO ()
+-- No documentation found for TopLevel "PFN_vkGetPhysicalDeviceProperties"
+type PFN_vkGetPhysicalDeviceProperties = FunPtr FN_vkGetPhysicalDeviceProperties
+
+
+type FN_vkGetDeviceProcAddr = Ptr Device_T -> ("pName" ::: Ptr CChar) -> IO PFN_vkVoidFunction
+-- No documentation found for TopLevel "PFN_vkGetDeviceProcAddr"
+type PFN_vkGetDeviceProcAddr = FunPtr FN_vkGetDeviceProcAddr
+
+
+type FN_vkGetInstanceProcAddr = Ptr Instance_T -> ("pName" ::: Ptr CChar) -> IO PFN_vkVoidFunction
+-- No documentation found for TopLevel "PFN_vkGetInstanceProcAddr"
+type PFN_vkGetInstanceProcAddr = FunPtr FN_vkGetInstanceProcAddr
+
+
+type FN_vkInvalidateMappedMemoryRanges = Ptr Device_T -> ("memoryRangeCount" ::: Word32) -> ("pMemoryRanges" ::: Ptr MappedMemoryRange) -> IO Result
+-- No documentation found for TopLevel "PFN_vkInvalidateMappedMemoryRanges"
+type PFN_vkInvalidateMappedMemoryRanges = FunPtr FN_vkInvalidateMappedMemoryRanges
+
+
+type FN_vkVoidFunction = IO ()
+-- No documentation found for TopLevel "PFN_vkVoidFunction"
+type PFN_vkVoidFunction = FunPtr FN_vkVoidFunction
+
+
+type FN_vkMapMemory = Ptr Device_T -> DeviceMemory -> ("offset" ::: DeviceSize) -> DeviceSize -> MemoryMapFlags -> ("ppData" ::: Ptr (Ptr ())) -> IO Result
+-- No documentation found for TopLevel "PFN_vkMapMemory"
+type PFN_vkMapMemory = FunPtr FN_vkMapMemory
+
+
+type FN_vkUnmapMemory = Ptr Device_T -> DeviceMemory -> IO ()
+-- No documentation found for TopLevel "PFN_vkUnmapMemory"
+type PFN_vkUnmapMemory = FunPtr FN_vkUnmapMemory
+
+
+type FN_vkGetDeviceBufferMemoryRequirements = Ptr Device_T -> ("pInfo" ::: Ptr DeviceBufferMemoryRequirements) -> ("pMemoryRequirements" ::: Ptr (SomeStruct MemoryRequirements2)) -> IO ()
+-- No documentation found for TopLevel "PFN_vkGetDeviceBufferMemoryRequirements"
+type PFN_vkGetDeviceBufferMemoryRequirements = FunPtr FN_vkGetDeviceBufferMemoryRequirements
+
+
+type FN_vkGetDeviceImageMemoryRequirements = Ptr Device_T -> ("pInfo" ::: Ptr DeviceImageMemoryRequirements) -> ("pMemoryRequirements" ::: Ptr (SomeStruct MemoryRequirements2)) -> IO ()
+-- No documentation found for TopLevel "PFN_vkGetDeviceImageMemoryRequirements"
+type PFN_vkGetDeviceImageMemoryRequirements = FunPtr FN_vkGetDeviceImageMemoryRequirements
+
+
+type AllocatorCreateFlags = AllocatorCreateFlagBits
+
+-- | Flags for created 'Allocator'.
+newtype AllocatorCreateFlagBits = AllocatorCreateFlagBits Flags
+  deriving newtype (Eq, Ord, Storable, Zero, Bits, FiniteBits)
+
+-- | Allocator and all objects created from it will not be synchronized
+-- internally, so you must guarantee they are used from only one thread at
+-- a time or synchronized externally by you.
+--
+-- Using this flag may increase performance because internal mutexes are
+-- not used.
+pattern ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT = AllocatorCreateFlagBits 0x00000001
+
+-- | Enables usage of VK_KHR_dedicated_allocation extension.
+--
+-- The flag works only if /VmaAllocatorCreateInfo::vulkanApiVersion/
+-- @== VK_API_VERSION_1_0@. When it is @VK_API_VERSION_1_1@, the flag is
+-- ignored because the extension has been promoted to Vulkan 1.1.
+--
+-- Using this extension will automatically allocate dedicated blocks of
+-- memory for some buffers and images instead of suballocating place for
+-- them out of bigger memory blocks (as if you explicitly used
+-- 'ALLOCATION_CREATE_DEDICATED_MEMORY_BIT' flag) when it is recommended by
+-- the driver. It may improve performance on some GPUs.
+--
+-- You may set this flag only if you found out that following device
+-- extensions are supported, you enabled them while creating Vulkan device
+-- passed as /VmaAllocatorCreateInfo::device/, and you want them to be used
+-- internally by this library:
+--
+-- -   VK_KHR_get_memory_requirements2 (device extension)
+--
+-- -   VK_KHR_dedicated_allocation (device extension)
+--
+-- When this flag is set, you can experience following warnings reported by
+-- Vulkan validation layer. You can ignore them.
+--
+-- ‍vkBindBufferMemory(): Binding memory to buffer 0x2d but
+-- vkGetBufferMemoryRequirements() has not been called on that buffer.
+pattern ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT = AllocatorCreateFlagBits 0x00000002
+
+-- | Enables usage of VK_KHR_bind_memory2 extension.
+--
+-- The flag works only if /VmaAllocatorCreateInfo::vulkanApiVersion/
+-- @== VK_API_VERSION_1_0@. When it is @VK_API_VERSION_1_1@, the flag is
+-- ignored because the extension has been promoted to Vulkan 1.1.
+--
+-- You may set this flag only if you found out that this device extension
+-- is supported, you enabled it while creating Vulkan device passed as
+-- /VmaAllocatorCreateInfo::device/, and you want it to be used internally
+-- by this library.
+--
+-- The extension provides functions @vkBindBufferMemory2KHR@ and
+-- @vkBindImageMemory2KHR@, which allow to pass a chain of @pNext@
+-- structures while binding. This flag is required if you use @pNext@
+-- parameter in 'bindBufferMemory2' or 'bindImageMemory2'.
+pattern ALLOCATOR_CREATE_KHR_BIND_MEMORY2_BIT = AllocatorCreateFlagBits 0x00000004
+
+-- | Enables usage of VK_EXT_memory_budget extension.
+--
+-- You may set this flag only if you found out that this device extension
+-- is supported, you enabled it while creating Vulkan device passed as
+-- /VmaAllocatorCreateInfo::device/, and you want it to be used internally
+-- by this library, along with another instance extension
+-- VK_KHR_get_physical_device_properties2, which is required by it (or
+-- Vulkan 1.1, where this extension is promoted).
+--
+-- The extension provides query for current memory usage and budget, which
+-- will probably be more accurate than an estimation used by the library
+-- otherwise.
+pattern ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT = AllocatorCreateFlagBits 0x00000008
+
+-- | Enables usage of VK_AMD_device_coherent_memory extension.
+--
+-- You may set this flag only if you:
+--
+-- -   found out that this device extension is supported and enabled it
+--     while creating Vulkan device passed as
+--     /VmaAllocatorCreateInfo::device/,
+--
+-- -   checked that
+--     @VkPhysicalDeviceCoherentMemoryFeaturesAMD::deviceCoherentMemory@ is
+--     true and set it while creating the Vulkan device,
+--
+-- -   want it to be used internally by this library.
+--
+-- The extension and accompanying device feature provide access to memory
+-- types with @VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD@ and
+-- @VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD@ flags. They are useful
+-- mostly for writing breadcrumb markers - a common method for debugging
+-- GPU crash\/hang\/TDR.
+--
+-- When the extension is not enabled, such memory types are still
+-- enumerated, but their usage is illegal. To protect from this error, if
+-- you don\'t create the allocator with this flag, it will refuse to
+-- allocate any memory or create a custom pool in such memory type,
+-- returning @VK_ERROR_FEATURE_NOT_PRESENT@.
+pattern ALLOCATOR_CREATE_AMD_DEVICE_COHERENT_MEMORY_BIT = AllocatorCreateFlagBits 0x00000010
+
+-- | Enables usage of \"buffer device address\" feature, which allows you to
+-- use function @vkGetBufferDeviceAddress*@ to get raw GPU pointer to a
+-- buffer and pass it for usage inside a shader.
+--
+-- You may set this flag only if you:
+--
+-- 1.  (For Vulkan version \< 1.2) Found as available and enabled device
+--     extension VK_KHR_buffer_device_address. This extension is promoted
+--     to core Vulkan 1.2.
+--
+-- 2.  Found as available and enabled device feature
+--     @VkPhysicalDeviceBufferDeviceAddressFeatures::bufferDeviceAddress@.
+--
+-- When this flag is set, you can create buffers with
+-- @VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT@ using VMA. The library
+-- automatically adds @VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT@ to allocated
+-- memory blocks wherever it might be needed.
+--
+-- For more information, see documentation chapter /Enabling buffer device
+-- address/.
+pattern ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT = AllocatorCreateFlagBits 0x00000020
+
+-- | Enables usage of VK_EXT_memory_priority extension in the library.
+--
+-- You may set this flag only if you found available and enabled this
+-- device extension, along with
+-- @VkPhysicalDeviceMemoryPriorityFeaturesEXT::memoryPriority == VK_TRUE@,
+-- while creating Vulkan device passed as /VmaAllocatorCreateInfo::device/.
+--
+-- When this flag is used, /VmaAllocationCreateInfo::priority/ and
+-- /VmaPoolCreateInfo::priority/ are used to set priorities of allocated
+-- Vulkan memory. Without it, these variables are ignored.
+--
+-- A priority must be a floating-point value between 0 and 1, indicating
+-- the priority of the allocation relative to other memory allocations.
+-- Larger values are higher priority. The granularity of the priorities is
+-- implementation-dependent. It is automatically passed to every call to
+-- @vkAllocateMemory@ done by the library using structure
+-- @VkMemoryPriorityAllocateInfoEXT@. The value to be used for default
+-- priority is 0.5. For more details, see the documentation of the
+-- VK_EXT_memory_priority extension.
+pattern ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT = AllocatorCreateFlagBits 0x00000040
+
+conNameAllocatorCreateFlagBits :: String
+conNameAllocatorCreateFlagBits = "AllocatorCreateFlagBits"
+
+enumPrefixAllocatorCreateFlagBits :: String
+enumPrefixAllocatorCreateFlagBits = "ALLOCATOR_CREATE_"
+
+showTableAllocatorCreateFlagBits :: [(AllocatorCreateFlagBits, String)]
+showTableAllocatorCreateFlagBits =
+  [
+    ( ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT
+    , "EXTERNALLY_SYNCHRONIZED_BIT"
+    )
+  ,
+    ( ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT
+    , "KHR_DEDICATED_ALLOCATION_BIT"
+    )
+  ,
+    ( ALLOCATOR_CREATE_KHR_BIND_MEMORY2_BIT
+    , "KHR_BIND_MEMORY2_BIT"
+    )
+  ,
+    ( ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT
+    , "EXT_MEMORY_BUDGET_BIT"
+    )
+  ,
+    ( ALLOCATOR_CREATE_AMD_DEVICE_COHERENT_MEMORY_BIT
+    , "AMD_DEVICE_COHERENT_MEMORY_BIT"
+    )
+  ,
+    ( ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT
+    , "BUFFER_DEVICE_ADDRESS_BIT"
+    )
+  ,
+    ( ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT
+    , "EXT_MEMORY_PRIORITY_BIT"
+    )
+  ]
+
+instance Show AllocatorCreateFlagBits where
+  showsPrec =
+    enumShowsPrec
+      enumPrefixAllocatorCreateFlagBits
+      showTableAllocatorCreateFlagBits
+      conNameAllocatorCreateFlagBits
+      (\(AllocatorCreateFlagBits x) -> x)
+      (\x -> showString "0x" . showHex x)
+
+instance Read AllocatorCreateFlagBits where
+  readPrec =
+    enumReadPrec
+      enumPrefixAllocatorCreateFlagBits
+      showTableAllocatorCreateFlagBits
+      conNameAllocatorCreateFlagBits
+      AllocatorCreateFlagBits
+
+-- | Intended usage of the allocated memory.
+newtype MemoryUsage = MemoryUsage Int32
+  deriving newtype (Eq, Ord, Storable, Zero)
+
+-- | No intended memory usage specified. Use other members of
+-- 'AllocationCreateInfo' to specify your requirements.
+pattern MEMORY_USAGE_UNKNOWN = MemoryUsage 0
+
+-- | /Deprecated/
+--
+-- Obsolete, preserved for backward compatibility. Prefers
+-- @VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT@.
+pattern MEMORY_USAGE_GPU_ONLY = MemoryUsage 1
+
+-- | /Deprecated/
+--
+-- Obsolete, preserved for backward compatibility. Guarantees
+-- @VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT@ and
+-- @VK_MEMORY_PROPERTY_HOST_COHERENT_BIT@.
+pattern MEMORY_USAGE_CPU_ONLY = MemoryUsage 2
+
+-- | /Deprecated/
+--
+-- Obsolete, preserved for backward compatibility. Guarantees
+-- @VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT@, prefers
+-- @VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT@.
+pattern MEMORY_USAGE_CPU_TO_GPU = MemoryUsage 3
+
+-- | /Deprecated/
+--
+-- Obsolete, preserved for backward compatibility. Guarantees
+-- @VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT@, prefers
+-- @VK_MEMORY_PROPERTY_HOST_CACHED_BIT@.
+pattern MEMORY_USAGE_GPU_TO_CPU = MemoryUsage 4
+
+-- | /Deprecated/
+--
+-- Obsolete, preserved for backward compatibility. Prefers not
+-- @VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT@.
+pattern MEMORY_USAGE_CPU_COPY = MemoryUsage 5
+
+-- | Lazily allocated GPU memory having
+-- @VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT@. Exists mostly on mobile
+-- platforms. Using it on desktop PC or other GPUs with no such memory type
+-- present will fail the allocation.
+--
+-- Usage: Memory for transient attachment images (color attachments, depth
+-- attachments etc.), created with
+-- @VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT@.
+--
+-- Allocations with this usage are always created as dedicated - it implies
+-- 'ALLOCATION_CREATE_DEDICATED_MEMORY_BIT'.
+pattern MEMORY_USAGE_GPU_LAZILY_ALLOCATED = MemoryUsage 6
+
+-- | Selects best memory type automatically. This flag is recommended for
+-- most common use cases.
+--
+-- When using this flag, if you want to map the allocation (using
+-- 'mapMemory' or 'ALLOCATION_CREATE_MAPPED_BIT'), you must pass one of the
+-- flags: 'ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT' or
+-- 'ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT' in
+-- /VmaAllocationCreateInfo::flags/.
+--
+-- It can be used only with functions that let the library know
+-- @VkBufferCreateInfo@ or @VkImageCreateInfo@, e.g. 'createBuffer',
+-- 'createImage', 'findMemoryTypeIndexForBufferInfo',
+-- 'findMemoryTypeIndexForImageInfo' and not with generic memory allocation
+-- functions.
+pattern MEMORY_USAGE_AUTO = MemoryUsage 7
+
+-- | Selects best memory type automatically with preference for GPU (device)
+-- memory.
+--
+-- When using this flag, if you want to map the allocation (using
+-- 'mapMemory' or 'ALLOCATION_CREATE_MAPPED_BIT'), you must pass one of the
+-- flags: 'ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT' or
+-- 'ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT' in
+-- /VmaAllocationCreateInfo::flags/.
+--
+-- It can be used only with functions that let the library know
+-- @VkBufferCreateInfo@ or @VkImageCreateInfo@, e.g. 'createBuffer',
+-- 'createImage', 'findMemoryTypeIndexForBufferInfo',
+-- 'findMemoryTypeIndexForImageInfo' and not with generic memory allocation
+-- functions.
+pattern MEMORY_USAGE_AUTO_PREFER_DEVICE = MemoryUsage 8
+
+-- | Selects best memory type automatically with preference for CPU (host)
+-- memory.
+--
+-- When using this flag, if you want to map the allocation (using
+-- 'mapMemory' or 'ALLOCATION_CREATE_MAPPED_BIT'), you must pass one of the
+-- flags: 'ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT' or
+-- 'ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT' in
+-- /VmaAllocationCreateInfo::flags/.
+--
+-- It can be used only with functions that let the library know
+-- @VkBufferCreateInfo@ or @VkImageCreateInfo@, e.g. 'createBuffer',
+-- 'createImage', 'findMemoryTypeIndexForBufferInfo',
+-- 'findMemoryTypeIndexForImageInfo' and not with generic memory allocation
+-- functions.
+pattern MEMORY_USAGE_AUTO_PREFER_HOST = MemoryUsage 9
+
+{-# COMPLETE
+  MEMORY_USAGE_UNKNOWN
+  , MEMORY_USAGE_GPU_ONLY
+  , MEMORY_USAGE_CPU_ONLY
+  , MEMORY_USAGE_CPU_TO_GPU
+  , MEMORY_USAGE_GPU_TO_CPU
+  , MEMORY_USAGE_CPU_COPY
+  , MEMORY_USAGE_GPU_LAZILY_ALLOCATED
+  , MEMORY_USAGE_AUTO
+  , MEMORY_USAGE_AUTO_PREFER_DEVICE
+  , MEMORY_USAGE_AUTO_PREFER_HOST ::
+    MemoryUsage
+  #-}
+
+conNameMemoryUsage :: String
+conNameMemoryUsage = "MemoryUsage"
+
+enumPrefixMemoryUsage :: String
+enumPrefixMemoryUsage = "MEMORY_USAGE_"
+
+showTableMemoryUsage :: [(MemoryUsage, String)]
+showTableMemoryUsage =
+  [ (MEMORY_USAGE_UNKNOWN, "UNKNOWN")
+  , (MEMORY_USAGE_GPU_ONLY, "GPU_ONLY")
+  , (MEMORY_USAGE_CPU_ONLY, "CPU_ONLY")
+  , (MEMORY_USAGE_CPU_TO_GPU, "CPU_TO_GPU")
+  , (MEMORY_USAGE_GPU_TO_CPU, "GPU_TO_CPU")
+  , (MEMORY_USAGE_CPU_COPY, "CPU_COPY")
+  ,
+    ( MEMORY_USAGE_GPU_LAZILY_ALLOCATED
+    , "GPU_LAZILY_ALLOCATED"
+    )
+  , (MEMORY_USAGE_AUTO, "AUTO")
+  , (MEMORY_USAGE_AUTO_PREFER_DEVICE, "AUTO_PREFER_DEVICE")
+  , (MEMORY_USAGE_AUTO_PREFER_HOST, "AUTO_PREFER_HOST")
+  ]
+
+instance Show MemoryUsage where
+  showsPrec =
+    enumShowsPrec
+      enumPrefixMemoryUsage
+      showTableMemoryUsage
+      conNameMemoryUsage
+      (\(MemoryUsage x) -> x)
+      (showsPrec 11)
+
+instance Read MemoryUsage where
+  readPrec =
+    enumReadPrec
+      enumPrefixMemoryUsage
+      showTableMemoryUsage
+      conNameMemoryUsage
+      MemoryUsage
+
+type AllocationCreateFlags = AllocationCreateFlagBits
+
+-- | Flags to be passed as /VmaAllocationCreateInfo::flags/.
+newtype AllocationCreateFlagBits = AllocationCreateFlagBits Flags
+  deriving newtype (Eq, Ord, Storable, Zero, Bits, FiniteBits)
+
+-- | Set this flag if the allocation should have its own memory block.
+--
+-- Use it for special, big resources, like fullscreen images used as
+-- attachments.
+pattern ALLOCATION_CREATE_DEDICATED_MEMORY_BIT = AllocationCreateFlagBits 0x00000001
+
+-- | Set this flag to only try to allocate from existing @VkDeviceMemory@
+-- blocks and never create new such block.
+--
+-- If new allocation cannot be placed in any of the existing blocks,
+-- allocation fails with @VK_ERROR_OUT_OF_DEVICE_MEMORY@ error.
+--
+-- You should not use 'ALLOCATION_CREATE_DEDICATED_MEMORY_BIT' and
+-- 'ALLOCATION_CREATE_NEVER_ALLOCATE_BIT' at the same time. It makes no
+-- sense.
+pattern ALLOCATION_CREATE_NEVER_ALLOCATE_BIT = AllocationCreateFlagBits 0x00000002
+
+-- | Set this flag to use a memory that will be persistently mapped and
+-- retrieve pointer to it.
+--
+-- Pointer to mapped memory will be returned through
+-- /VmaAllocationInfo::pMappedData/.
+--
+-- It is valid to use this flag for allocation made from memory type that
+-- is not @HOST_VISIBLE@. This flag is then ignored and memory is not
+-- mapped. This is useful if you need an allocation that is efficient to
+-- use on GPU (@DEVICE_LOCAL@) and still want to map it directly if
+-- possible on platforms that support it (e.g. Intel GPU).
+pattern ALLOCATION_CREATE_MAPPED_BIT = AllocationCreateFlagBits 0x00000004
+
+-- | /Deprecated/
+--
+-- Preserved for backward compatibility. Consider using 'setAllocationName'
+-- instead.
+--
+-- Set this flag to treat /VmaAllocationCreateInfo::pUserData/ as pointer
+-- to a null-terminated string. Instead of copying pointer value, a local
+-- copy of the string is made and stored in allocation\'s @pName@. The
+-- string is automatically freed together with the allocation. It is also
+-- used in 'buildStatsString'.
+pattern ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT = AllocationCreateFlagBits 0x00000020
+
+-- | Allocation will be created from upper stack in a double stack pool.
+--
+-- This flag is only allowed for custom pools created with
+-- 'POOL_CREATE_LINEAR_ALGORITHM_BIT' flag.
+pattern ALLOCATION_CREATE_UPPER_ADDRESS_BIT = AllocationCreateFlagBits 0x00000040
+
+-- | Create both buffer\/image and allocation, but don\'t bind them together.
+-- It is useful when you want to bind yourself to do some more advanced
+-- binding, e.g. using some extensions. The flag is meaningful only with
+-- functions that bind by default: 'createBuffer', 'createImage'. Otherwise
+-- it is ignored.
+--
+-- If you want to make sure the new buffer\/image is not tied to the new
+-- memory allocation through @VkMemoryDedicatedAllocateInfoKHR@ structure
+-- in case the allocation ends up in its own memory block, use also flag
+-- 'ALLOCATION_CREATE_CAN_ALIAS_BIT'.
+pattern ALLOCATION_CREATE_DONT_BIND_BIT = AllocationCreateFlagBits 0x00000080
+
+-- | Create allocation only if additional device memory required for it, if
+-- any, won\'t exceed memory budget. Otherwise return
+-- @VK_ERROR_OUT_OF_DEVICE_MEMORY@.
+pattern ALLOCATION_CREATE_WITHIN_BUDGET_BIT = AllocationCreateFlagBits 0x00000100
+
+-- | Set this flag if the allocated memory will have aliasing resources.
+--
+-- Usage of this flag prevents supplying @VkMemoryDedicatedAllocateInfoKHR@
+-- when 'ALLOCATION_CREATE_DEDICATED_MEMORY_BIT' is specified. Otherwise
+-- created dedicated memory will not be suitable for aliasing resources,
+-- resulting in Vulkan Validation Layer errors.
+pattern ALLOCATION_CREATE_CAN_ALIAS_BIT = AllocationCreateFlagBits 0x00000200
+
+-- | Requests possibility to map the allocation (using 'mapMemory' or
+-- 'ALLOCATION_CREATE_MAPPED_BIT').
+--
+-- -   If you use 'MEMORY_USAGE_AUTO' or other @VMA_MEMORY_USAGE_AUTO*@
+--     value, you must use this flag to be able to map the allocation.
+--     Otherwise, mapping is incorrect.
+--
+-- -   If you use other value of 'MemoryUsage', this flag is ignored and
+--     mapping is always possible in memory types that are @HOST_VISIBLE@.
+--     This includes allocations created in /Custom memory pools/.
+--
+-- Declares that mapped memory will only be written sequentially, e.g.
+-- using @memcpy()@ or a loop writing number-by-number, never read or
+-- accessed randomly, so a memory type can be selected that is uncached and
+-- write-combined.
+--
+-- Warning
+--
+-- Violating this declaration may work correctly, but will likely be very
+-- slow. Watch out for implicit reads introduced by doing e.g.
+-- @pMappedData[i] += x;@ Better prepare your data in a local variable and
+-- @memcpy()@ it to the mapped pointer all at once.
+pattern ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT = AllocationCreateFlagBits 0x00000400
+
+-- | Requests possibility to map the allocation (using 'mapMemory' or
+-- 'ALLOCATION_CREATE_MAPPED_BIT').
+--
+-- -   If you use 'MEMORY_USAGE_AUTO' or other @VMA_MEMORY_USAGE_AUTO*@
+--     value, you must use this flag to be able to map the allocation.
+--     Otherwise, mapping is incorrect.
+--
+-- -   If you use other value of 'MemoryUsage', this flag is ignored and
+--     mapping is always possible in memory types that are @HOST_VISIBLE@.
+--     This includes allocations created in /Custom memory pools/.
+--
+-- Declares that mapped memory can be read, written, and accessed in random
+-- order, so a @HOST_CACHED@ memory type is required.
+pattern ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT = AllocationCreateFlagBits 0x00000800
+
+-- | Together with 'ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT' or
+-- 'ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT', it says that despite request
+-- for host access, a not-@HOST_VISIBLE@ memory type can be selected if it
+-- may improve performance.
+--
+-- By using this flag, you declare that you will check if the allocation
+-- ended up in a @HOST_VISIBLE@ memory type (e.g. using
+-- 'getAllocationMemoryProperties') and if not, you will create some
+-- \"staging\" buffer and issue an explicit transfer to write\/read your
+-- data. To prepare for this possibility, don\'t forget to add appropriate
+-- flags like @VK_BUFFER_USAGE_TRANSFER_DST_BIT@,
+-- @VK_BUFFER_USAGE_TRANSFER_SRC_BIT@ to the parameters of created buffer
+-- or image.
+pattern ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT = AllocationCreateFlagBits 0x00001000
+
+-- | Allocation strategy that chooses smallest possible free range for the
+-- allocation to minimize memory usage and fragmentation, possibly at the
+-- expense of allocation time.
+pattern ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT = AllocationCreateFlagBits 0x00010000
+
+-- | Allocation strategy that chooses first suitable free range for the
+-- allocation - not necessarily in terms of the smallest offset but the one
+-- that is easiest and fastest to find to minimize allocation time,
+-- possibly at the expense of allocation quality.
+pattern ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT = AllocationCreateFlagBits 0x00020000
+
+-- | Allocation strategy that chooses always the lowest offset in available
+-- space. This is not the most efficient strategy but achieves highly
+-- packed data. Used internally by defragmentation, not recommended in
+-- typical usage.
+pattern ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT = AllocationCreateFlagBits 0x00040000
+
+-- | Alias to 'ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT'.
+pattern ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT = AllocationCreateFlagBits 0x00010000
+
+-- | Alias to 'ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT'.
+pattern ALLOCATION_CREATE_STRATEGY_FIRST_FIT_BIT = AllocationCreateFlagBits 0x00020000
+
+-- | A bit mask to extract only @STRATEGY@ bits from entire set of flags.
+pattern ALLOCATION_CREATE_STRATEGY_MASK = AllocationCreateFlagBits 0x00070000
+
+conNameAllocationCreateFlagBits :: String
+conNameAllocationCreateFlagBits = "AllocationCreateFlagBits"
+
+enumPrefixAllocationCreateFlagBits :: String
+enumPrefixAllocationCreateFlagBits = "ALLOCATION_CREATE_"
+
+showTableAllocationCreateFlagBits :: [(AllocationCreateFlagBits, String)]
+showTableAllocationCreateFlagBits =
+  [
+    ( ALLOCATION_CREATE_DEDICATED_MEMORY_BIT
+    , "DEDICATED_MEMORY_BIT"
+    )
+  ,
+    ( ALLOCATION_CREATE_NEVER_ALLOCATE_BIT
+    , "NEVER_ALLOCATE_BIT"
+    )
+  ,
+    ( ALLOCATION_CREATE_MAPPED_BIT
+    , "MAPPED_BIT"
+    )
+  ,
+    ( ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT
+    , "USER_DATA_COPY_STRING_BIT"
+    )
+  ,
+    ( ALLOCATION_CREATE_UPPER_ADDRESS_BIT
+    , "UPPER_ADDRESS_BIT"
+    )
+  ,
+    ( ALLOCATION_CREATE_DONT_BIND_BIT
+    , "DONT_BIND_BIT"
+    )
+  ,
+    ( ALLOCATION_CREATE_WITHIN_BUDGET_BIT
+    , "WITHIN_BUDGET_BIT"
+    )
+  ,
+    ( ALLOCATION_CREATE_CAN_ALIAS_BIT
+    , "CAN_ALIAS_BIT"
+    )
+  ,
+    ( ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT
+    , "HOST_ACCESS_SEQUENTIAL_WRITE_BIT"
+    )
+  ,
+    ( ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT
+    , "HOST_ACCESS_RANDOM_BIT"
+    )
+  ,
+    ( ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT
+    , "HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT"
+    )
+  ,
+    ( ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT
+    , "STRATEGY_MIN_MEMORY_BIT"
+    )
+  ,
+    ( ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT
+    , "STRATEGY_MIN_TIME_BIT"
+    )
+  ,
+    ( ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT
+    , "STRATEGY_MIN_OFFSET_BIT"
+    )
+  ,
+    ( ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT
+    , "STRATEGY_BEST_FIT_BIT"
+    )
+  ,
+    ( ALLOCATION_CREATE_STRATEGY_FIRST_FIT_BIT
+    , "STRATEGY_FIRST_FIT_BIT"
+    )
+  ,
+    ( ALLOCATION_CREATE_STRATEGY_MASK
+    , "STRATEGY_MASK"
+    )
+  ]
+
+instance Show AllocationCreateFlagBits where
+  showsPrec =
+    enumShowsPrec
+      enumPrefixAllocationCreateFlagBits
+      showTableAllocationCreateFlagBits
+      conNameAllocationCreateFlagBits
+      (\(AllocationCreateFlagBits x) -> x)
+      (\x -> showString "0x" . showHex x)
+
+instance Read AllocationCreateFlagBits where
+  readPrec =
+    enumReadPrec
+      enumPrefixAllocationCreateFlagBits
+      showTableAllocationCreateFlagBits
+      conNameAllocationCreateFlagBits
+      AllocationCreateFlagBits
+
+type PoolCreateFlags = PoolCreateFlagBits
+
+-- | Flags to be passed as /VmaPoolCreateInfo::flags/.
+newtype PoolCreateFlagBits = PoolCreateFlagBits Flags
+  deriving newtype (Eq, Ord, Storable, Zero, Bits, FiniteBits)
+
+-- | Use this flag if you always allocate only buffers and linear images or
+-- only optimal images out of this pool and so Buffer-Image Granularity can
+-- be ignored.
+--
+-- This is an optional optimization flag.
+--
+-- If you always allocate using 'createBuffer', 'createImage',
+-- 'allocateMemoryForBuffer', then you don\'t need to use it because
+-- allocator knows exact type of your allocations so it can handle
+-- Buffer-Image Granularity in the optimal way.
+--
+-- If you also allocate using 'allocateMemoryForImage' or 'allocateMemory',
+-- exact type of such allocations is not known, so allocator must be
+-- conservative in handling Buffer-Image Granularity, which can lead to
+-- suboptimal allocation (wasted memory). In that case, if you can make
+-- sure you always allocate only buffers and linear images or only optimal
+-- images out of this pool, use this flag to make allocator disregard
+-- Buffer-Image Granularity and so make allocations faster and more
+-- optimal.
+pattern POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT = PoolCreateFlagBits 0x00000002
+
+-- | Enables alternative, linear allocation algorithm in this pool.
+--
+-- Specify this flag to enable linear allocation algorithm, which always
+-- creates new allocations after last one and doesn\'t reuse space from
+-- allocations freed in between. It trades memory consumption for
+-- simplified algorithm and data structure, which has better performance
+-- and uses less memory for metadata.
+--
+-- By using this flag, you can achieve behavior of free-at-once, stack,
+-- ring buffer, and double stack. For details, see documentation chapter
+-- /Linear allocation algorithm/.
+pattern POOL_CREATE_LINEAR_ALGORITHM_BIT = PoolCreateFlagBits 0x00000004
+
+-- | Bit mask to extract only @ALGORITHM@ bits from entire set of flags.
+pattern POOL_CREATE_ALGORITHM_MASK = PoolCreateFlagBits 0x00000004
+
+conNamePoolCreateFlagBits :: String
+conNamePoolCreateFlagBits = "PoolCreateFlagBits"
+
+enumPrefixPoolCreateFlagBits :: String
+enumPrefixPoolCreateFlagBits = "POOL_CREATE_"
+
+showTablePoolCreateFlagBits :: [(PoolCreateFlagBits, String)]
+showTablePoolCreateFlagBits =
+  [
+    ( POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT
+    , "IGNORE_BUFFER_IMAGE_GRANULARITY_BIT"
+    )
+  ,
+    ( POOL_CREATE_LINEAR_ALGORITHM_BIT
+    , "LINEAR_ALGORITHM_BIT"
+    )
+  , (POOL_CREATE_ALGORITHM_MASK, "ALGORITHM_MASK")
+  ]
+
+instance Show PoolCreateFlagBits where
+  showsPrec =
+    enumShowsPrec
+      enumPrefixPoolCreateFlagBits
+      showTablePoolCreateFlagBits
+      conNamePoolCreateFlagBits
+      (\(PoolCreateFlagBits x) -> x)
+      (\x -> showString "0x" . showHex x)
+
+instance Read PoolCreateFlagBits where
+  readPrec =
+    enumReadPrec
+      enumPrefixPoolCreateFlagBits
+      showTablePoolCreateFlagBits
+      conNamePoolCreateFlagBits
+      PoolCreateFlagBits
+
+type DefragmentationFlags = DefragmentationFlagBits
+
+-- | Flags to be passed as /VmaDefragmentationInfo::flags/.
+newtype DefragmentationFlagBits = DefragmentationFlagBits Flags
+  deriving newtype (Eq, Ord, Storable, Zero, Bits, FiniteBits)
+
+pattern DEFRAGMENTATION_FLAG_ALGORITHM_FAST_BIT = DefragmentationFlagBits 0x00000001
+
+pattern DEFRAGMENTATION_FLAG_ALGORITHM_BALANCED_BIT = DefragmentationFlagBits 0x00000002
+
+pattern DEFRAGMENTATION_FLAG_ALGORITHM_FULL_BIT = DefragmentationFlagBits 0x00000004
+
+-- | Use the most roboust algorithm at the cost of time to compute and number
+-- of copies to make. Only available when bufferImageGranularity is greater
+-- than 1, since it aims to reduce alignment issues between different types
+-- of resources. Otherwise falls back to same behavior as
+-- 'DEFRAGMENTATION_FLAG_ALGORITHM_FULL_BIT'.
+pattern DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT = DefragmentationFlagBits 0x00000008
+
+-- | A bit mask to extract only @ALGORITHM@ bits from entire set of flags.
+pattern DEFRAGMENTATION_FLAG_ALGORITHM_MASK = DefragmentationFlagBits 0x0000000f
+
+conNameDefragmentationFlagBits :: String
+conNameDefragmentationFlagBits = "DefragmentationFlagBits"
+
+enumPrefixDefragmentationFlagBits :: String
+enumPrefixDefragmentationFlagBits = "DEFRAGMENTATION_FLAG_ALGORITHM_"
+
+showTableDefragmentationFlagBits :: [(DefragmentationFlagBits, String)]
+showTableDefragmentationFlagBits =
+  [
+    ( DEFRAGMENTATION_FLAG_ALGORITHM_FAST_BIT
+    , "FAST_BIT"
+    )
+  ,
+    ( DEFRAGMENTATION_FLAG_ALGORITHM_BALANCED_BIT
+    , "BALANCED_BIT"
+    )
+  ,
+    ( DEFRAGMENTATION_FLAG_ALGORITHM_FULL_BIT
+    , "FULL_BIT"
+    )
+  ,
+    ( DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT
+    , "EXTENSIVE_BIT"
+    )
+  ,
+    ( DEFRAGMENTATION_FLAG_ALGORITHM_MASK
+    , "MASK"
+    )
+  ]
+
+instance Show DefragmentationFlagBits where
+  showsPrec =
+    enumShowsPrec
+      enumPrefixDefragmentationFlagBits
+      showTableDefragmentationFlagBits
+      conNameDefragmentationFlagBits
+      (\(DefragmentationFlagBits x) -> x)
+      (\x -> showString "0x" . showHex x)
+
+instance Read DefragmentationFlagBits where
+  readPrec =
+    enumReadPrec
+      enumPrefixDefragmentationFlagBits
+      showTableDefragmentationFlagBits
+      conNameDefragmentationFlagBits
+      DefragmentationFlagBits
+
+-- | Operation performed on single defragmentation move. See structure
+-- 'DefragmentationMove'.
+newtype DefragmentationMoveOperation = DefragmentationMoveOperation Int32
+  deriving newtype (Eq, Ord, Storable, Zero)
+
+-- | Buffer\/image has been recreated at @dstTmpAllocation@, data has been
+-- copied, old buffer\/image has been destroyed. @srcAllocation@ should be
+-- changed to point to the new place. This is the default value set by
+-- 'beginDefragmentationPass'.
+pattern DEFRAGMENTATION_MOVE_OPERATION_COPY = DefragmentationMoveOperation 0
+
+-- | Set this value if you cannot move the allocation. New place reserved at
+-- @dstTmpAllocation@ will be freed. @srcAllocation@ will remain unchanged.
+pattern DEFRAGMENTATION_MOVE_OPERATION_IGNORE = DefragmentationMoveOperation 1
+
+-- | Set this value if you decide to abandon the allocation and you destroyed
+-- the buffer\/image. New place reserved at @dstTmpAllocation@ will be
+-- freed, along with @srcAllocation@, which will be destroyed.
+pattern DEFRAGMENTATION_MOVE_OPERATION_DESTROY = DefragmentationMoveOperation 2
+
+{-# COMPLETE
+  DEFRAGMENTATION_MOVE_OPERATION_COPY
+  , DEFRAGMENTATION_MOVE_OPERATION_IGNORE
+  , DEFRAGMENTATION_MOVE_OPERATION_DESTROY ::
+    DefragmentationMoveOperation
+  #-}
+
+conNameDefragmentationMoveOperation :: String
+conNameDefragmentationMoveOperation = "DefragmentationMoveOperation"
+
+enumPrefixDefragmentationMoveOperation :: String
+enumPrefixDefragmentationMoveOperation = "DEFRAGMENTATION_MOVE_OPERATION_"
+
+showTableDefragmentationMoveOperation :: [(DefragmentationMoveOperation, String)]
+showTableDefragmentationMoveOperation =
+  [
+    ( DEFRAGMENTATION_MOVE_OPERATION_COPY
+    , "COPY"
+    )
+  ,
+    ( DEFRAGMENTATION_MOVE_OPERATION_IGNORE
+    , "IGNORE"
+    )
+  ,
+    ( DEFRAGMENTATION_MOVE_OPERATION_DESTROY
+    , "DESTROY"
+    )
+  ]
+
+instance Show DefragmentationMoveOperation where
+  showsPrec =
+    enumShowsPrec
+      enumPrefixDefragmentationMoveOperation
+      showTableDefragmentationMoveOperation
+      conNameDefragmentationMoveOperation
+      (\(DefragmentationMoveOperation x) -> x)
+      (showsPrec 11)
+
+instance Read DefragmentationMoveOperation where
+  readPrec =
+    enumReadPrec
+      enumPrefixDefragmentationMoveOperation
+      showTableDefragmentationMoveOperation
+      conNameDefragmentationMoveOperation
+      DefragmentationMoveOperation
+
+type VirtualBlockCreateFlags = VirtualBlockCreateFlagBits
+
+-- | Flags to be passed as /VmaVirtualBlockCreateInfo::flags/.
+newtype VirtualBlockCreateFlagBits = VirtualBlockCreateFlagBits Flags
+  deriving newtype (Eq, Ord, Storable, Zero, Bits, FiniteBits)
+
+-- | Enables alternative, linear allocation algorithm in this virtual block.
+--
+-- Specify this flag to enable linear allocation algorithm, which always
+-- creates new allocations after last one and doesn\'t reuse space from
+-- allocations freed in between. It trades memory consumption for
+-- simplified algorithm and data structure, which has better performance
+-- and uses less memory for metadata.
+--
+-- By using this flag, you can achieve behavior of free-at-once, stack,
+-- ring buffer, and double stack. For details, see documentation chapter
+-- /Linear allocation algorithm/.
+pattern VIRTUAL_BLOCK_CREATE_LINEAR_ALGORITHM_BIT = VirtualBlockCreateFlagBits 0x00000001
+
+-- | Bit mask to extract only @ALGORITHM@ bits from entire set of flags.
+pattern VIRTUAL_BLOCK_CREATE_ALGORITHM_MASK = VirtualBlockCreateFlagBits 0x00000001
+
+conNameVirtualBlockCreateFlagBits :: String
+conNameVirtualBlockCreateFlagBits = "VirtualBlockCreateFlagBits"
+
+enumPrefixVirtualBlockCreateFlagBits :: String
+enumPrefixVirtualBlockCreateFlagBits = "VIRTUAL_BLOCK_CREATE_"
+
+showTableVirtualBlockCreateFlagBits :: [(VirtualBlockCreateFlagBits, String)]
+showTableVirtualBlockCreateFlagBits =
+  [
+    ( VIRTUAL_BLOCK_CREATE_LINEAR_ALGORITHM_BIT
+    , "LINEAR_ALGORITHM_BIT"
+    )
+  ,
+    ( VIRTUAL_BLOCK_CREATE_ALGORITHM_MASK
+    , "ALGORITHM_MASK"
+    )
+  ]
+
+instance Show VirtualBlockCreateFlagBits where
+  showsPrec =
+    enumShowsPrec
+      enumPrefixVirtualBlockCreateFlagBits
+      showTableVirtualBlockCreateFlagBits
+      conNameVirtualBlockCreateFlagBits
+      (\(VirtualBlockCreateFlagBits x) -> x)
+      (\x -> showString "0x" . showHex x)
+
+instance Read VirtualBlockCreateFlagBits where
+  readPrec =
+    enumReadPrec
+      enumPrefixVirtualBlockCreateFlagBits
+      showTableVirtualBlockCreateFlagBits
+      conNameVirtualBlockCreateFlagBits
+      VirtualBlockCreateFlagBits
+
+type VirtualAllocationCreateFlags = VirtualAllocationCreateFlagBits
+
+-- | Flags to be passed as /VmaVirtualAllocationCreateInfo::flags/.
+newtype VirtualAllocationCreateFlagBits = VirtualAllocationCreateFlagBits Flags
+  deriving newtype (Eq, Ord, Storable, Zero, Bits, FiniteBits)
+
+-- | Allocation will be created from upper stack in a double stack pool.
+--
+-- This flag is only allowed for virtual blocks created with
+-- 'VIRTUAL_BLOCK_CREATE_LINEAR_ALGORITHM_BIT' flag.
+pattern VIRTUAL_ALLOCATION_CREATE_UPPER_ADDRESS_BIT = VirtualAllocationCreateFlagBits 0x00000040
+
+-- | Allocation strategy that tries to minimize memory usage.
+pattern VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT = VirtualAllocationCreateFlagBits 0x00010000
+
+-- | Allocation strategy that tries to minimize allocation time.
+pattern VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT = VirtualAllocationCreateFlagBits 0x00020000
+
+-- | Allocation strategy that chooses always the lowest offset in available
+-- space. This is not the most efficient strategy but achieves highly
+-- packed data.
+pattern VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT = VirtualAllocationCreateFlagBits 0x00040000
+
+-- | A bit mask to extract only @STRATEGY@ bits from entire set of flags.
+--
+-- These strategy flags are binary compatible with equivalent flags in
+-- 'AllocationCreateFlagBits'.
+pattern VIRTUAL_ALLOCATION_CREATE_STRATEGY_MASK = VirtualAllocationCreateFlagBits 0x00070000
+
+conNameVirtualAllocationCreateFlagBits :: String
+conNameVirtualAllocationCreateFlagBits = "VirtualAllocationCreateFlagBits"
+
+enumPrefixVirtualAllocationCreateFlagBits :: String
+enumPrefixVirtualAllocationCreateFlagBits = "VIRTUAL_ALLOCATION_CREATE_"
+
+showTableVirtualAllocationCreateFlagBits :: [(VirtualAllocationCreateFlagBits, String)]
+showTableVirtualAllocationCreateFlagBits =
+  [
+    ( VIRTUAL_ALLOCATION_CREATE_UPPER_ADDRESS_BIT
+    , "UPPER_ADDRESS_BIT"
+    )
+  ,
+    ( VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT
+    , "STRATEGY_MIN_MEMORY_BIT"
+    )
+  ,
+    ( VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT
+    , "STRATEGY_MIN_TIME_BIT"
+    )
+  ,
+    ( VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT
+    , "STRATEGY_MIN_OFFSET_BIT"
+    )
+  ,
+    ( VIRTUAL_ALLOCATION_CREATE_STRATEGY_MASK
+    , "STRATEGY_MASK"
+    )
+  ]
+
+instance Show VirtualAllocationCreateFlagBits where
+  showsPrec =
+    enumShowsPrec
+      enumPrefixVirtualAllocationCreateFlagBits
+      showTableVirtualAllocationCreateFlagBits
+      conNameVirtualAllocationCreateFlagBits
+      (\(VirtualAllocationCreateFlagBits x) -> x)
+      (\x -> showString "0x" . showHex x)
+
+instance Read VirtualAllocationCreateFlagBits where
+  readPrec =
+    enumReadPrec
+      enumPrefixVirtualAllocationCreateFlagBits
+      showTableVirtualAllocationCreateFlagBits
+      conNameVirtualAllocationCreateFlagBits
+      VirtualAllocationCreateFlagBits
+
+-- | VmaAllocator
+--
+-- Represents main object of this library initialized.
+--
+-- Fill structure 'AllocatorCreateInfo' and call function 'createAllocator'
+-- to create it. Call function 'destroyAllocator' to destroy it.
+--
+-- It is recommended to create just one object of this type per @VkDevice@
+-- object, right after Vulkan is initialized and keep it alive until before
+-- Vulkan device is destroyed.
+newtype Allocator = Allocator Word64
+  deriving newtype (Eq, Ord, Storable, Zero)
+  deriving anyclass (IsHandle)
+instance Show Allocator where
+  showsPrec p (Allocator x) = showParen (p >= 11) (showString "Allocator 0x" . showHex x)
+
+
+-- | VmaPool
+--
+-- Represents custom memory pool.
+--
+-- Fill structure 'PoolCreateInfo' and call function 'createPool' to create
+-- it. Call function 'destroyPool' to destroy it.
+--
+-- For more information see /Custom memory pools/.
+newtype Pool = Pool Word64
+  deriving newtype (Eq, Ord, Storable, Zero)
+  deriving anyclass (IsHandle)
+instance Show Pool where
+  showsPrec p (Pool x) = showParen (p >= 11) (showString "Pool 0x" . showHex x)
+
+
+-- | VmaAllocation
+--
+-- Represents single memory allocation.
+--
+-- It may be either dedicated block of @VkDeviceMemory@ or a specific
+-- region of a bigger block of this type plus unique offset.
+--
+-- There are multiple ways to create such object. You need to fill
+-- structure 'AllocationCreateInfo'. For more information see /Choosing
+-- memory type/.
+--
+-- Although the library provides convenience functions that create Vulkan
+-- buffer or image, allocate memory for it and bind them together, binding
+-- of the allocation to a buffer or an image is out of scope of the
+-- allocation itself. Allocation object can exist without buffer\/image
+-- bound, binding can be done manually by the user, and destruction of it
+-- can be done independently of destruction of the allocation.
+--
+-- The object also remembers its size and some other information. To
+-- retrieve this information, use function 'getAllocationInfo' and inspect
+-- returned structure 'AllocationInfo'.
+newtype Allocation = Allocation Word64
+  deriving newtype (Eq, Ord, Storable, Zero)
+  deriving anyclass (IsHandle)
+instance Show Allocation where
+  showsPrec p (Allocation x) = showParen (p >= 11) (showString "Allocation 0x" . showHex x)
+
+
+-- | VmaDefragmentationContext
+--
+-- An opaque object that represents started defragmentation process.
+--
+-- Fill structure 'DefragmentationInfo' and call function
+-- 'beginDefragmentation' to create it. Call function 'endDefragmentation'
+-- to destroy it.
+newtype DefragmentationContext = DefragmentationContext Word64
+  deriving newtype (Eq, Ord, Storable, Zero)
+  deriving anyclass (IsHandle)
+instance Show DefragmentationContext where
+  showsPrec p (DefragmentationContext x) = showParen (p >= 11) (showString "DefragmentationContext 0x" . showHex x)
+
+
+-- | VmaVirtualAllocation
+--
+-- Represents single memory allocation done inside 'VirtualBlock'.
+--
+-- Use it as a unique identifier to virtual allocation within the single
+-- block.
+--
+-- Use value @VK_NULL_HANDLE@ to represent a null\/invalid allocation.
+newtype VirtualAllocation = VirtualAllocation Word64
+  deriving newtype (Eq, Ord, Storable, Zero)
+  deriving anyclass (IsHandle)
+instance Show VirtualAllocation where
+  showsPrec p (VirtualAllocation x) = showParen (p >= 11) (showString "VirtualAllocation 0x" . showHex x)
+
+
+-- | VmaVirtualBlock
+--
+-- Handle to a virtual block object that allows to use core allocation
+-- algorithm without allocating any real GPU memory.
+--
+-- Fill in 'VirtualBlockCreateInfo' structure and use 'createVirtualBlock'
+-- to create it. Use 'destroyVirtualBlock' to destroy it. For more
+-- information, see documentation chapter /Virtual allocator/.
+--
+-- This object is not thread-safe - should not be used from multiple
+-- threads simultaneously, must be synchronized externally.
+newtype VirtualBlock = VirtualBlock Word64
+  deriving newtype (Eq, Ord, Storable, Zero)
+  deriving anyclass (IsHandle)
+instance Show VirtualBlock where
+  showsPrec p (VirtualBlock x) = showParen (p >= 11) (showString "VirtualBlock 0x" . showHex x)
+
+
+type FN_vmaAllocateDeviceMemoryFunction = Allocator -> ("memoryType" ::: Word32) -> DeviceMemory -> DeviceSize -> ("pUserData" ::: Ptr ()) -> IO ()
+-- No documentation found for TopLevel "PFN_vmaAllocateDeviceMemoryFunction"
+type PFN_vmaAllocateDeviceMemoryFunction = FunPtr FN_vmaAllocateDeviceMemoryFunction
+
+
+type FN_vmaFreeDeviceMemoryFunction = Allocator -> ("memoryType" ::: Word32) -> DeviceMemory -> DeviceSize -> ("pUserData" ::: Ptr ()) -> IO ()
+-- No documentation found for TopLevel "PFN_vmaFreeDeviceMemoryFunction"
+type PFN_vmaFreeDeviceMemoryFunction = FunPtr FN_vmaFreeDeviceMemoryFunction
+
+
+-- | VmaDeviceMemoryCallbacks
+--
+-- Set of callbacks that the library will call for @vkAllocateMemory@ and
+-- @vkFreeMemory@.
+--
+-- Provided for informative purpose, e.g. to gather statistics about number
+-- of allocations or total amount of memory allocated in Vulkan.
+--
+-- Used in /VmaAllocatorCreateInfo::pDeviceMemoryCallbacks/.
+data DeviceMemoryCallbacks = DeviceMemoryCallbacks
+  { -- | Optional, can be null.
+    pfnAllocate :: PFN_vmaAllocateDeviceMemoryFunction
+  , -- | Optional, can be null.
+    pfnFree :: PFN_vmaFreeDeviceMemoryFunction
+  , -- | Optional, can be null.
+    userData :: Ptr ()
+  }
+  deriving (Typeable)
+#if defined(GENERIC_INSTANCES)
+deriving instance Generic (DeviceMemoryCallbacks)
+#endif
+deriving instance Show DeviceMemoryCallbacks
+
+instance ToCStruct DeviceMemoryCallbacks where
+  withCStruct x f = allocaBytes 24 $ \p -> pokeCStruct p x (f p)
+  pokeCStruct p DeviceMemoryCallbacks{..} f = do
+    poke ((p `plusPtr` 0 :: Ptr PFN_vmaAllocateDeviceMemoryFunction)) (pfnAllocate)
+    poke ((p `plusPtr` 8 :: Ptr PFN_vmaFreeDeviceMemoryFunction)) (pfnFree)
+    poke ((p `plusPtr` 16 :: Ptr (Ptr ()))) (userData)
+    f
+  cStructSize = 24
+  cStructAlignment = 8
+  pokeZeroCStruct _ f = f
+
+instance FromCStruct DeviceMemoryCallbacks where
+  peekCStruct p = do
+    pfnAllocate <- peek @PFN_vmaAllocateDeviceMemoryFunction ((p `plusPtr` 0 :: Ptr PFN_vmaAllocateDeviceMemoryFunction))
+    pfnFree <- peek @PFN_vmaFreeDeviceMemoryFunction ((p `plusPtr` 8 :: Ptr PFN_vmaFreeDeviceMemoryFunction))
+    pUserData <- peek @(Ptr ()) ((p `plusPtr` 16 :: Ptr (Ptr ())))
+    pure $ DeviceMemoryCallbacks
+             pfnAllocate pfnFree pUserData
+
+instance Storable DeviceMemoryCallbacks where
+  sizeOf ~_ = 24
+  alignment ~_ = 8
+  peek = peekCStruct
+  poke ptr poked = pokeCStruct ptr poked (pure ())
+
+instance Zero DeviceMemoryCallbacks where
+  zero = DeviceMemoryCallbacks
+           zero
+           zero
+           zero
+
+
+-- | VmaVulkanFunctions
+--
+-- Pointers to some Vulkan functions - a subset used by the library.
+--
+-- Used in /VmaAllocatorCreateInfo::pVulkanFunctions/.
+data VulkanFunctions = VulkanFunctions
+  { -- | Required when using VMA_DYNAMIC_VULKAN_FUNCTIONS.
+    vkGetInstanceProcAddr :: PFN_vkGetInstanceProcAddr
+  , -- | Required when using VMA_DYNAMIC_VULKAN_FUNCTIONS.
+    vkGetDeviceProcAddr :: PFN_vkGetDeviceProcAddr
+  , 
+    vkGetPhysicalDeviceProperties :: PFN_vkGetPhysicalDeviceProperties
+  , 
+    vkGetPhysicalDeviceMemoryProperties :: PFN_vkGetPhysicalDeviceMemoryProperties
+  , 
+    vkAllocateMemory :: PFN_vkAllocateMemory
+  , 
+    vkFreeMemory :: PFN_vkFreeMemory
+  , 
+    vkMapMemory :: PFN_vkMapMemory
+  , 
+    vkUnmapMemory :: PFN_vkUnmapMemory
+  , 
+    vkFlushMappedMemoryRanges :: PFN_vkFlushMappedMemoryRanges
+  , 
+    vkInvalidateMappedMemoryRanges :: PFN_vkInvalidateMappedMemoryRanges
+  , 
+    vkBindBufferMemory :: PFN_vkBindBufferMemory
+  , 
+    vkBindImageMemory :: PFN_vkBindImageMemory
+  , 
+    vkGetBufferMemoryRequirements :: PFN_vkGetBufferMemoryRequirements
+  , 
+    vkGetImageMemoryRequirements :: PFN_vkGetImageMemoryRequirements
+  , 
+    vkCreateBuffer :: PFN_vkCreateBuffer
+  , 
+    vkDestroyBuffer :: PFN_vkDestroyBuffer
+  , 
+    vkCreateImage :: PFN_vkCreateImage
+  , 
+    vkDestroyImage :: PFN_vkDestroyImage
+  , 
+    vkCmdCopyBuffer :: PFN_vkCmdCopyBuffer
+  , -- | Fetch \"vkGetBufferMemoryRequirements2\" on Vulkan >= 1.1, fetch
+    -- \"vkGetBufferMemoryRequirements2KHR\" when using
+    -- VK_KHR_dedicated_allocation extension.
+    vkGetBufferMemoryRequirements2KHR :: PFN_vkGetBufferMemoryRequirements2KHR
+  , -- | Fetch \"vkGetImageMemoryRequirements2\" on Vulkan >= 1.1, fetch
+    -- \"vkGetImageMemoryRequirements2KHR\" when using
+    -- VK_KHR_dedicated_allocation extension.
+    vkGetImageMemoryRequirements2KHR :: PFN_vkGetImageMemoryRequirements2KHR
+  , -- | Fetch \"vkBindBufferMemory2\" on Vulkan >= 1.1, fetch
+    -- \"vkBindBufferMemory2KHR\" when using VK_KHR_bind_memory2 extension.
+    vkBindBufferMemory2KHR :: PFN_vkBindBufferMemory2KHR
+  , -- | Fetch \"vkBindImageMemory2\" on Vulkan >= 1.1, fetch
+    -- \"vkBindImageMemory2KHR\" when using VK_KHR_bind_memory2 extension.
+    vkBindImageMemory2KHR :: PFN_vkBindImageMemory2KHR
+  , 
+    vkGetPhysicalDeviceMemoryProperties2KHR :: PFN_vkGetPhysicalDeviceMemoryProperties2KHR
+  , -- | Fetch from \"vkGetDeviceBufferMemoryRequirements\" on Vulkan >= 1.3, but
+    -- you can also fetch it from \"vkGetDeviceBufferMemoryRequirementsKHR\" if
+    -- you enabled extension VK_KHR_maintenance4.
+    vkGetDeviceBufferMemoryRequirements :: PFN_vkGetDeviceBufferMemoryRequirements
+  , -- | Fetch from \"vkGetDeviceImageMemoryRequirements\" on Vulkan >= 1.3, but
+    -- you can also fetch it from \"vkGetDeviceImageMemoryRequirementsKHR\" if
+    -- you enabled extension VK_KHR_maintenance4.
+    vkGetDeviceImageMemoryRequirements :: PFN_vkGetDeviceImageMemoryRequirements
+  }
+  deriving (Typeable, Eq)
+#if defined(GENERIC_INSTANCES)
+deriving instance Generic (VulkanFunctions)
+#endif
+deriving instance Show VulkanFunctions
+
+instance ToCStruct VulkanFunctions where
+  withCStruct x f = allocaBytes 208 $ \p -> pokeCStruct p x (f p)
+  pokeCStruct p VulkanFunctions{..} f = do
+    poke ((p `plusPtr` 0 :: Ptr PFN_vkGetInstanceProcAddr)) (vkGetInstanceProcAddr)
+    poke ((p `plusPtr` 8 :: Ptr PFN_vkGetDeviceProcAddr)) (vkGetDeviceProcAddr)
+    poke ((p `plusPtr` 16 :: Ptr PFN_vkGetPhysicalDeviceProperties)) (vkGetPhysicalDeviceProperties)
+    poke ((p `plusPtr` 24 :: Ptr PFN_vkGetPhysicalDeviceMemoryProperties)) (vkGetPhysicalDeviceMemoryProperties)
+    poke ((p `plusPtr` 32 :: Ptr PFN_vkAllocateMemory)) (vkAllocateMemory)
+    poke ((p `plusPtr` 40 :: Ptr PFN_vkFreeMemory)) (vkFreeMemory)
+    poke ((p `plusPtr` 48 :: Ptr PFN_vkMapMemory)) (vkMapMemory)
+    poke ((p `plusPtr` 56 :: Ptr PFN_vkUnmapMemory)) (vkUnmapMemory)
+    poke ((p `plusPtr` 64 :: Ptr PFN_vkFlushMappedMemoryRanges)) (vkFlushMappedMemoryRanges)
+    poke ((p `plusPtr` 72 :: Ptr PFN_vkInvalidateMappedMemoryRanges)) (vkInvalidateMappedMemoryRanges)
+    poke ((p `plusPtr` 80 :: Ptr PFN_vkBindBufferMemory)) (vkBindBufferMemory)
+    poke ((p `plusPtr` 88 :: Ptr PFN_vkBindImageMemory)) (vkBindImageMemory)
+    poke ((p `plusPtr` 96 :: Ptr PFN_vkGetBufferMemoryRequirements)) (vkGetBufferMemoryRequirements)
+    poke ((p `plusPtr` 104 :: Ptr PFN_vkGetImageMemoryRequirements)) (vkGetImageMemoryRequirements)
+    poke ((p `plusPtr` 112 :: Ptr PFN_vkCreateBuffer)) (vkCreateBuffer)
+    poke ((p `plusPtr` 120 :: Ptr PFN_vkDestroyBuffer)) (vkDestroyBuffer)
+    poke ((p `plusPtr` 128 :: Ptr PFN_vkCreateImage)) (vkCreateImage)
+    poke ((p `plusPtr` 136 :: Ptr PFN_vkDestroyImage)) (vkDestroyImage)
+    poke ((p `plusPtr` 144 :: Ptr PFN_vkCmdCopyBuffer)) (vkCmdCopyBuffer)
+    poke ((p `plusPtr` 152 :: Ptr PFN_vkGetBufferMemoryRequirements2KHR)) (vkGetBufferMemoryRequirements2KHR)
+    poke ((p `plusPtr` 160 :: Ptr PFN_vkGetImageMemoryRequirements2KHR)) (vkGetImageMemoryRequirements2KHR)
+    poke ((p `plusPtr` 168 :: Ptr PFN_vkBindBufferMemory2KHR)) (vkBindBufferMemory2KHR)
+    poke ((p `plusPtr` 176 :: Ptr PFN_vkBindImageMemory2KHR)) (vkBindImageMemory2KHR)
+    poke ((p `plusPtr` 184 :: Ptr PFN_vkGetPhysicalDeviceMemoryProperties2KHR)) (vkGetPhysicalDeviceMemoryProperties2KHR)
+    poke ((p `plusPtr` 192 :: Ptr PFN_vkGetDeviceBufferMemoryRequirements)) (vkGetDeviceBufferMemoryRequirements)
+    poke ((p `plusPtr` 200 :: Ptr PFN_vkGetDeviceImageMemoryRequirements)) (vkGetDeviceImageMemoryRequirements)
+    f
+  cStructSize = 208
+  cStructAlignment = 8
+  pokeZeroCStruct _ f = f
+
+instance FromCStruct VulkanFunctions where
+  peekCStruct p = do
+    vkGetInstanceProcAddr <- peek @PFN_vkGetInstanceProcAddr ((p `plusPtr` 0 :: Ptr PFN_vkGetInstanceProcAddr))
+    vkGetDeviceProcAddr <- peek @PFN_vkGetDeviceProcAddr ((p `plusPtr` 8 :: Ptr PFN_vkGetDeviceProcAddr))
+    vkGetPhysicalDeviceProperties <- peek @PFN_vkGetPhysicalDeviceProperties ((p `plusPtr` 16 :: Ptr PFN_vkGetPhysicalDeviceProperties))
+    vkGetPhysicalDeviceMemoryProperties <- peek @PFN_vkGetPhysicalDeviceMemoryProperties ((p `plusPtr` 24 :: Ptr PFN_vkGetPhysicalDeviceMemoryProperties))
+    vkAllocateMemory <- peek @PFN_vkAllocateMemory ((p `plusPtr` 32 :: Ptr PFN_vkAllocateMemory))
+    vkFreeMemory <- peek @PFN_vkFreeMemory ((p `plusPtr` 40 :: Ptr PFN_vkFreeMemory))
+    vkMapMemory <- peek @PFN_vkMapMemory ((p `plusPtr` 48 :: Ptr PFN_vkMapMemory))
+    vkUnmapMemory <- peek @PFN_vkUnmapMemory ((p `plusPtr` 56 :: Ptr PFN_vkUnmapMemory))
+    vkFlushMappedMemoryRanges <- peek @PFN_vkFlushMappedMemoryRanges ((p `plusPtr` 64 :: Ptr PFN_vkFlushMappedMemoryRanges))
+    vkInvalidateMappedMemoryRanges <- peek @PFN_vkInvalidateMappedMemoryRanges ((p `plusPtr` 72 :: Ptr PFN_vkInvalidateMappedMemoryRanges))
+    vkBindBufferMemory <- peek @PFN_vkBindBufferMemory ((p `plusPtr` 80 :: Ptr PFN_vkBindBufferMemory))
+    vkBindImageMemory <- peek @PFN_vkBindImageMemory ((p `plusPtr` 88 :: Ptr PFN_vkBindImageMemory))
+    vkGetBufferMemoryRequirements <- peek @PFN_vkGetBufferMemoryRequirements ((p `plusPtr` 96 :: Ptr PFN_vkGetBufferMemoryRequirements))
+    vkGetImageMemoryRequirements <- peek @PFN_vkGetImageMemoryRequirements ((p `plusPtr` 104 :: Ptr PFN_vkGetImageMemoryRequirements))
+    vkCreateBuffer <- peek @PFN_vkCreateBuffer ((p `plusPtr` 112 :: Ptr PFN_vkCreateBuffer))
+    vkDestroyBuffer <- peek @PFN_vkDestroyBuffer ((p `plusPtr` 120 :: Ptr PFN_vkDestroyBuffer))
+    vkCreateImage <- peek @PFN_vkCreateImage ((p `plusPtr` 128 :: Ptr PFN_vkCreateImage))
+    vkDestroyImage <- peek @PFN_vkDestroyImage ((p `plusPtr` 136 :: Ptr PFN_vkDestroyImage))
+    vkCmdCopyBuffer <- peek @PFN_vkCmdCopyBuffer ((p `plusPtr` 144 :: Ptr PFN_vkCmdCopyBuffer))
+    vkGetBufferMemoryRequirements2KHR <- peek @PFN_vkGetBufferMemoryRequirements2KHR ((p `plusPtr` 152 :: Ptr PFN_vkGetBufferMemoryRequirements2KHR))
+    vkGetImageMemoryRequirements2KHR <- peek @PFN_vkGetImageMemoryRequirements2KHR ((p `plusPtr` 160 :: Ptr PFN_vkGetImageMemoryRequirements2KHR))
+    vkBindBufferMemory2KHR <- peek @PFN_vkBindBufferMemory2KHR ((p `plusPtr` 168 :: Ptr PFN_vkBindBufferMemory2KHR))
+    vkBindImageMemory2KHR <- peek @PFN_vkBindImageMemory2KHR ((p `plusPtr` 176 :: Ptr PFN_vkBindImageMemory2KHR))
+    vkGetPhysicalDeviceMemoryProperties2KHR <- peek @PFN_vkGetPhysicalDeviceMemoryProperties2KHR ((p `plusPtr` 184 :: Ptr PFN_vkGetPhysicalDeviceMemoryProperties2KHR))
+    vkGetDeviceBufferMemoryRequirements <- peek @PFN_vkGetDeviceBufferMemoryRequirements ((p `plusPtr` 192 :: Ptr PFN_vkGetDeviceBufferMemoryRequirements))
+    vkGetDeviceImageMemoryRequirements <- peek @PFN_vkGetDeviceImageMemoryRequirements ((p `plusPtr` 200 :: Ptr PFN_vkGetDeviceImageMemoryRequirements))
+    pure $ VulkanFunctions
+             vkGetInstanceProcAddr
+             vkGetDeviceProcAddr
+             vkGetPhysicalDeviceProperties
+             vkGetPhysicalDeviceMemoryProperties
+             vkAllocateMemory
+             vkFreeMemory
+             vkMapMemory
+             vkUnmapMemory
+             vkFlushMappedMemoryRanges
+             vkInvalidateMappedMemoryRanges
+             vkBindBufferMemory
+             vkBindImageMemory
+             vkGetBufferMemoryRequirements
+             vkGetImageMemoryRequirements
+             vkCreateBuffer
+             vkDestroyBuffer
+             vkCreateImage
+             vkDestroyImage
+             vkCmdCopyBuffer
+             vkGetBufferMemoryRequirements2KHR
+             vkGetImageMemoryRequirements2KHR
+             vkBindBufferMemory2KHR
+             vkBindImageMemory2KHR
+             vkGetPhysicalDeviceMemoryProperties2KHR
+             vkGetDeviceBufferMemoryRequirements
+             vkGetDeviceImageMemoryRequirements
+
+instance Storable VulkanFunctions where
+  sizeOf ~_ = 208
+  alignment ~_ = 8
+  peek = peekCStruct
+  poke ptr poked = pokeCStruct ptr poked (pure ())
+
+instance Zero VulkanFunctions where
+  zero = VulkanFunctions
+           zero
+           zero
+           zero
+           zero
+           zero
+           zero
+           zero
+           zero
+           zero
+           zero
+           zero
+           zero
+           zero
+           zero
+           zero
+           zero
+           zero
+           zero
+           zero
+           zero
+           zero
+           zero
+           zero
+           zero
+           zero
+           zero
+
+
+-- | VmaAllocatorCreateInfo
+--
+-- Description of a Allocator to be created.
+data AllocatorCreateInfo = AllocatorCreateInfo
+  { -- | Flags for created allocator. Use 'AllocatorCreateFlagBits' enum.
+    flags :: AllocatorCreateFlags
+  , -- | Vulkan physical device.
+    --
+    -- It must be valid throughout whole lifetime of created allocator.
+    physicalDevice :: Ptr PhysicalDevice_T
+  , -- | Vulkan device.
+    --
+    -- It must be valid throughout whole lifetime of created allocator.
+    device :: Ptr Device_T
+  , -- | Preferred size of a single @VkDeviceMemory@ block to be allocated from
+    -- large heaps > 1 GiB. Optional.
+    --
+    -- Set to 0 to use default, which is currently 256 MiB.
+    preferredLargeHeapBlockSize :: DeviceSize
+  , -- | Custom CPU memory allocation callbacks. Optional.
+    --
+    -- Optional, can be null. When specified, will also be used for all
+    -- CPU-side memory allocations.
+    allocationCallbacks :: Maybe AllocationCallbacks
+  , -- | Informative callbacks for @vkAllocateMemory@, @vkFreeMemory@. Optional.
+    --
+    -- Optional, can be null.
+    deviceMemoryCallbacks :: Maybe DeviceMemoryCallbacks
+  , -- | Either null or a pointer to an array of limits on maximum number of
+    -- bytes that can be allocated out of particular Vulkan memory heap.
+    --
+    -- If not NULL, it must be a pointer to an array of
+    -- @VkPhysicalDeviceMemoryProperties::memoryHeapCount@ elements, defining
+    -- limit on maximum number of bytes that can be allocated out of particular
+    -- Vulkan memory heap.
+    --
+    -- Any of the elements may be equal to @VK_WHOLE_SIZE@, which means no
+    -- limit on that heap. This is also the default in case of @pHeapSizeLimit@
+    -- = NULL.
+    --
+    -- If there is a limit defined for a heap:
+    --
+    -- -   If user tries to allocate more memory from that heap using this
+    --     allocator, the allocation fails with
+    --     @VK_ERROR_OUT_OF_DEVICE_MEMORY@.
+    --
+    -- -   If the limit is smaller than heap size reported in
+    --     @VkMemoryHeap::size@, the value of this limit will be reported
+    --     instead when using 'getMemoryProperties'.
+    --
+    -- Warning! Using this feature may not be equivalent to installing a GPU
+    -- with smaller amount of memory, because graphics driver doesn\'t
+    -- necessary fail new allocations with @VK_ERROR_OUT_OF_DEVICE_MEMORY@
+    -- result when memory capacity is exceeded. It may return success and just
+    -- silently migrate some device memory blocks to system RAM. This driver
+    -- behavior can also be controlled using
+    -- VK_AMD_memory_overallocation_behavior extension.
+    heapSizeLimit :: Ptr DeviceSize
+  , -- | Pointers to Vulkan functions. Can be null.
+    --
+    -- For details see /Pointers to Vulkan functions/.
+    vulkanFunctions :: Maybe VulkanFunctions
+  , -- | Handle to Vulkan instance object.
+    --
+    -- Starting from version 3.0.0 this member is no longer optional, it must
+    -- be set!
+    instance' :: Ptr Instance_T
+  , -- | Optional. The highest version of Vulkan that the application is designed
+    -- to use.
+    --
+    -- It must be a value in the format as created by macro @VK_MAKE_VERSION@
+    -- or a constant like: @VK_API_VERSION_1_1@, @VK_API_VERSION_1_0@. The
+    -- patch version number specified is ignored. Only the major and minor
+    -- versions are considered. It must be less or equal (preferably equal) to
+    -- value as passed to @vkCreateInstance@ as
+    -- @VkApplicationInfo::apiVersion@. Only versions 1.0, 1.1, 1.2, 1.3 are
+    -- supported by the current implementation. Leaving it initialized to zero
+    -- is equivalent to @VK_API_VERSION_1_0@.
+    vulkanApiVersion :: Word32
+  , -- | Either null or a pointer to an array of external memory handle types for
+    -- each Vulkan memory type.
+    --
+    -- If not NULL, it must be a pointer to an array of
+    -- @VkPhysicalDeviceMemoryProperties::memoryTypeCount@ elements, defining
+    -- external memory handle types of particular Vulkan memory type, to be
+    -- passed using @VkExportMemoryAllocateInfoKHR@.
+    --
+    -- Any of the elements may be equal to 0, which means not to use
+    -- @VkExportMemoryAllocateInfoKHR@ on this memory type. This is also the
+    -- default in case of @pTypeExternalMemoryHandleTypes@ = NULL.
+    typeExternalMemoryHandleTypes :: Ptr ExternalMemoryHandleTypeFlagsKHR
+  }
+  deriving (Typeable)
+#if defined(GENERIC_INSTANCES)
+deriving instance Generic (AllocatorCreateInfo)
+#endif
+deriving instance Show AllocatorCreateInfo
+
+instance ToCStruct AllocatorCreateInfo where
+  withCStruct x f = allocaBytes 88 $ \p -> pokeCStruct p x (f p)
+  pokeCStruct p AllocatorCreateInfo{..} f = evalContT $ do
+    lift $ poke ((p `plusPtr` 0 :: Ptr AllocatorCreateFlags)) (flags)
+    lift $ poke ((p `plusPtr` 8 :: Ptr (Ptr PhysicalDevice_T))) (physicalDevice)
+    lift $ poke ((p `plusPtr` 16 :: Ptr (Ptr Device_T))) (device)
+    lift $ poke ((p `plusPtr` 24 :: Ptr DeviceSize)) (preferredLargeHeapBlockSize)
+    pAllocationCallbacks'' <- case (allocationCallbacks) of
+      Nothing -> pure nullPtr
+      Just j -> ContT $ withCStruct (j)
+    lift $ poke ((p `plusPtr` 32 :: Ptr (Ptr AllocationCallbacks))) pAllocationCallbacks''
+    pDeviceMemoryCallbacks'' <- case (deviceMemoryCallbacks) of
+      Nothing -> pure nullPtr
+      Just j -> ContT $ withCStruct (j)
+    lift $ poke ((p `plusPtr` 40 :: Ptr (Ptr DeviceMemoryCallbacks))) pDeviceMemoryCallbacks''
+    lift $ poke ((p `plusPtr` 48 :: Ptr (Ptr DeviceSize))) (heapSizeLimit)
+    pVulkanFunctions'' <- case (vulkanFunctions) of
+      Nothing -> pure nullPtr
+      Just j -> ContT $ withCStruct (j)
+    lift $ poke ((p `plusPtr` 56 :: Ptr (Ptr VulkanFunctions))) pVulkanFunctions''
+    lift $ poke ((p `plusPtr` 64 :: Ptr (Ptr Instance_T))) (instance')
+    lift $ poke ((p `plusPtr` 72 :: Ptr Word32)) (vulkanApiVersion)
+    lift $ poke ((p `plusPtr` 80 :: Ptr (Ptr ExternalMemoryHandleTypeFlagsKHR))) (typeExternalMemoryHandleTypes)
+    lift $ f
+  cStructSize = 88
+  cStructAlignment = 8
+  pokeZeroCStruct p f = do
+    poke ((p `plusPtr` 0 :: Ptr AllocatorCreateFlags)) (zero)
+    poke ((p `plusPtr` 8 :: Ptr (Ptr PhysicalDevice_T))) (zero)
+    poke ((p `plusPtr` 16 :: Ptr (Ptr Device_T))) (zero)
+    poke ((p `plusPtr` 24 :: Ptr DeviceSize)) (zero)
+    poke ((p `plusPtr` 64 :: Ptr (Ptr Instance_T))) (zero)
+    poke ((p `plusPtr` 72 :: Ptr Word32)) (zero)
+    f
+
+instance FromCStruct AllocatorCreateInfo where
+  peekCStruct p = do
+    flags <- peek @AllocatorCreateFlags ((p `plusPtr` 0 :: Ptr AllocatorCreateFlags))
+    physicalDevice <- peek @(Ptr PhysicalDevice_T) ((p `plusPtr` 8 :: Ptr (Ptr PhysicalDevice_T)))
+    device <- peek @(Ptr Device_T) ((p `plusPtr` 16 :: Ptr (Ptr Device_T)))
+    preferredLargeHeapBlockSize <- peek @DeviceSize ((p `plusPtr` 24 :: Ptr DeviceSize))
+    pAllocationCallbacks <- peek @(Ptr AllocationCallbacks) ((p `plusPtr` 32 :: Ptr (Ptr AllocationCallbacks)))
+    pAllocationCallbacks' <- maybePeek (\j -> peekCStruct @AllocationCallbacks (j)) pAllocationCallbacks
+    pDeviceMemoryCallbacks <- peek @(Ptr DeviceMemoryCallbacks) ((p `plusPtr` 40 :: Ptr (Ptr DeviceMemoryCallbacks)))
+    pDeviceMemoryCallbacks' <- maybePeek (\j -> peekCStruct @DeviceMemoryCallbacks (j)) pDeviceMemoryCallbacks
+    pHeapSizeLimit <- peek @(Ptr DeviceSize) ((p `plusPtr` 48 :: Ptr (Ptr DeviceSize)))
+    pVulkanFunctions <- peek @(Ptr VulkanFunctions) ((p `plusPtr` 56 :: Ptr (Ptr VulkanFunctions)))
+    pVulkanFunctions' <- maybePeek (\j -> peekCStruct @VulkanFunctions (j)) pVulkanFunctions
+    instance' <- peek @(Ptr Instance_T) ((p `plusPtr` 64 :: Ptr (Ptr Instance_T)))
+    vulkanApiVersion <- peek @Word32 ((p `plusPtr` 72 :: Ptr Word32))
+    pTypeExternalMemoryHandleTypes <- peek @(Ptr ExternalMemoryHandleTypeFlagsKHR) ((p `plusPtr` 80 :: Ptr (Ptr ExternalMemoryHandleTypeFlagsKHR)))
+    pure $ AllocatorCreateInfo
+             flags
+             physicalDevice
+             device
+             preferredLargeHeapBlockSize
+             pAllocationCallbacks'
+             pDeviceMemoryCallbacks'
+             pHeapSizeLimit
+             pVulkanFunctions'
+             instance'
+             vulkanApiVersion
+             pTypeExternalMemoryHandleTypes
+
+instance Zero AllocatorCreateInfo where
+  zero = AllocatorCreateInfo
+           zero
+           zero
+           zero
+           zero
+           Nothing
+           Nothing
+           zero
+           Nothing
+           zero
+           zero
+           zero
+
+
+-- | VmaAllocatorInfo
+--
+-- Information about existing 'Allocator' object.
+data AllocatorInfo = AllocatorInfo
+  { -- | Handle to Vulkan instance object.
+    --
+    -- This is the same value as has been passed through
+    -- /VmaAllocatorCreateInfo::instance/.
+    instance' :: Ptr Instance_T
+  , -- | Handle to Vulkan physical device object.
+    --
+    -- This is the same value as has been passed through
+    -- /VmaAllocatorCreateInfo::physicalDevice/.
+    physicalDevice :: Ptr PhysicalDevice_T
+  , -- | Handle to Vulkan device object.
+    --
+    -- This is the same value as has been passed through
+    -- /VmaAllocatorCreateInfo::device/.
+    device :: Ptr Device_T
+  }
+  deriving (Typeable, Eq)
+#if defined(GENERIC_INSTANCES)
+deriving instance Generic (AllocatorInfo)
+#endif
+deriving instance Show AllocatorInfo
+
+instance ToCStruct AllocatorInfo where
+  withCStruct x f = allocaBytes 24 $ \p -> pokeCStruct p x (f p)
+  pokeCStruct p AllocatorInfo{..} f = do
+    poke ((p `plusPtr` 0 :: Ptr (Ptr Instance_T))) (instance')
+    poke ((p `plusPtr` 8 :: Ptr (Ptr PhysicalDevice_T))) (physicalDevice)
+    poke ((p `plusPtr` 16 :: Ptr (Ptr Device_T))) (device)
+    f
+  cStructSize = 24
+  cStructAlignment = 8
+  pokeZeroCStruct p f = do
+    poke ((p `plusPtr` 0 :: Ptr (Ptr Instance_T))) (zero)
+    poke ((p `plusPtr` 8 :: Ptr (Ptr PhysicalDevice_T))) (zero)
+    poke ((p `plusPtr` 16 :: Ptr (Ptr Device_T))) (zero)
+    f
+
+instance FromCStruct AllocatorInfo where
+  peekCStruct p = do
+    instance' <- peek @(Ptr Instance_T) ((p `plusPtr` 0 :: Ptr (Ptr Instance_T)))
+    physicalDevice <- peek @(Ptr PhysicalDevice_T) ((p `plusPtr` 8 :: Ptr (Ptr PhysicalDevice_T)))
+    device <- peek @(Ptr Device_T) ((p `plusPtr` 16 :: Ptr (Ptr Device_T)))
+    pure $ AllocatorInfo
+             instance' physicalDevice device
+
+instance Storable AllocatorInfo where
+  sizeOf ~_ = 24
+  alignment ~_ = 8
+  peek = peekCStruct
+  poke ptr poked = pokeCStruct ptr poked (pure ())
+
+instance Zero AllocatorInfo where
+  zero = AllocatorInfo
+           zero
+           zero
+           zero
+
+
+-- | VmaStatistics
+--
+-- Calculated statistics of memory usage e.g. in a specific memory type,
+-- heap, custom pool, or total.
+--
+-- These are fast to calculate. See functions: 'getHeapBudgets',
+-- 'getPoolStatistics'.
+data Statistics = Statistics
+  { -- | Number of @VkDeviceMemory@ objects - Vulkan memory blocks allocated.
+    blockCount :: Word32
+  , -- | Number of 'Allocation' objects allocated.
+    --
+    -- Dedicated allocations have their own blocks, so each one adds 1 to
+    -- @allocationCount@ as well as @blockCount@.
+    allocationCount :: Word32
+  , -- | Number of bytes allocated in @VkDeviceMemory@ blocks.
+    --
+    -- Note
+    --
+    -- To avoid confusion, please be aware that what Vulkan calls an
+    -- \"allocation\" - a whole @VkDeviceMemory@ object (e.g. as in
+    -- @VkPhysicalDeviceLimits::maxMemoryAllocationCount@) is called a
+    -- \"block\" in VMA, while VMA calls \"allocation\" a 'Allocation' object
+    -- that represents a memory region sub-allocated from such block, usually
+    -- for a single buffer or image.
+    blockBytes :: DeviceSize
+  , -- | Total number of bytes occupied by all 'Allocation' objects.
+    --
+    -- Always less or equal than @blockBytes@. Difference
+    -- @(blockBytes - allocationBytes)@ is the amount of memory allocated from
+    -- Vulkan but unused by any 'Allocation'.
+    allocationBytes :: DeviceSize
+  }
+  deriving (Typeable, Eq)
+#if defined(GENERIC_INSTANCES)
+deriving instance Generic (Statistics)
+#endif
+deriving instance Show Statistics
+
+instance ToCStruct Statistics where
+  withCStruct x f = allocaBytes 24 $ \p -> pokeCStruct p x (f p)
+  pokeCStruct p Statistics{..} f = do
+    poke ((p `plusPtr` 0 :: Ptr Word32)) (blockCount)
+    poke ((p `plusPtr` 4 :: Ptr Word32)) (allocationCount)
+    poke ((p `plusPtr` 8 :: Ptr DeviceSize)) (blockBytes)
+    poke ((p `plusPtr` 16 :: Ptr DeviceSize)) (allocationBytes)
+    f
+  cStructSize = 24
+  cStructAlignment = 8
+  pokeZeroCStruct p f = do
+    poke ((p `plusPtr` 0 :: Ptr Word32)) (zero)
+    poke ((p `plusPtr` 4 :: Ptr Word32)) (zero)
+    poke ((p `plusPtr` 8 :: Ptr DeviceSize)) (zero)
+    poke ((p `plusPtr` 16 :: Ptr DeviceSize)) (zero)
+    f
+
+instance FromCStruct Statistics where
+  peekCStruct p = do
+    blockCount <- peek @Word32 ((p `plusPtr` 0 :: Ptr Word32))
+    allocationCount <- peek @Word32 ((p `plusPtr` 4 :: Ptr Word32))
+    blockBytes <- peek @DeviceSize ((p `plusPtr` 8 :: Ptr DeviceSize))
+    allocationBytes <- peek @DeviceSize ((p `plusPtr` 16 :: Ptr DeviceSize))
+    pure $ Statistics
+             blockCount allocationCount blockBytes allocationBytes
+
+instance Storable Statistics where
+  sizeOf ~_ = 24
+  alignment ~_ = 8
+  peek = peekCStruct
+  poke ptr poked = pokeCStruct ptr poked (pure ())
+
+instance Zero Statistics where
+  zero = Statistics
+           zero
+           zero
+           zero
+           zero
+
+
+-- | VmaDetailedStatistics
+--
+-- More detailed statistics than 'Statistics'.
+--
+-- These are slower to calculate. Use for debugging purposes. See
+-- functions: 'calculateStatistics', 'calculatePoolStatistics'.
+--
+-- Previous version of the statistics API provided averages, but they have
+-- been removed because they can be easily calculated as:
+--
+-- > VkDeviceSize allocationSizeAvg = detailedStats.statistics.allocationBytes / detailedStats.statistics.allocationCount;
+-- > VkDeviceSize unusedBytes = detailedStats.statistics.blockBytes - detailedStats.statistics.allocationBytes;
+-- > VkDeviceSize unusedRangeSizeAvg = unusedBytes / detailedStats.unusedRangeCount;
+data DetailedStatistics = DetailedStatistics
+  { -- | Basic statistics.
+    statistics :: Statistics
+  , -- | Number of free ranges of memory between allocations.
+    unusedRangeCount :: Word32
+  , -- | Smallest allocation size. @VK_WHOLE_SIZE@ if there are 0 allocations.
+    allocationSizeMin :: DeviceSize
+  , -- | Largest allocation size. 0 if there are 0 allocations.
+    allocationSizeMax :: DeviceSize
+  , -- | Smallest empty range size. @VK_WHOLE_SIZE@ if there are 0 empty ranges.
+    unusedRangeSizeMin :: DeviceSize
+  , -- | Largest empty range size. 0 if there are 0 empty ranges.
+    unusedRangeSizeMax :: DeviceSize
+  }
+  deriving (Typeable)
+#if defined(GENERIC_INSTANCES)
+deriving instance Generic (DetailedStatistics)
+#endif
+deriving instance Show DetailedStatistics
+
+instance ToCStruct DetailedStatistics where
+  withCStruct x f = allocaBytes 64 $ \p -> pokeCStruct p x (f p)
+  pokeCStruct p DetailedStatistics{..} f = do
+    poke ((p `plusPtr` 0 :: Ptr Statistics)) (statistics)
+    poke ((p `plusPtr` 24 :: Ptr Word32)) (unusedRangeCount)
+    poke ((p `plusPtr` 32 :: Ptr DeviceSize)) (allocationSizeMin)
+    poke ((p `plusPtr` 40 :: Ptr DeviceSize)) (allocationSizeMax)
+    poke ((p `plusPtr` 48 :: Ptr DeviceSize)) (unusedRangeSizeMin)
+    poke ((p `plusPtr` 56 :: Ptr DeviceSize)) (unusedRangeSizeMax)
+    f
+  cStructSize = 64
+  cStructAlignment = 8
+  pokeZeroCStruct p f = do
+    poke ((p `plusPtr` 0 :: Ptr Statistics)) (zero)
+    poke ((p `plusPtr` 24 :: Ptr Word32)) (zero)
+    poke ((p `plusPtr` 32 :: Ptr DeviceSize)) (zero)
+    poke ((p `plusPtr` 40 :: Ptr DeviceSize)) (zero)
+    poke ((p `plusPtr` 48 :: Ptr DeviceSize)) (zero)
+    poke ((p `plusPtr` 56 :: Ptr DeviceSize)) (zero)
+    f
+
+instance FromCStruct DetailedStatistics where
+  peekCStruct p = do
+    statistics <- peekCStruct @Statistics ((p `plusPtr` 0 :: Ptr Statistics))
+    unusedRangeCount <- peek @Word32 ((p `plusPtr` 24 :: Ptr Word32))
+    allocationSizeMin <- peek @DeviceSize ((p `plusPtr` 32 :: Ptr DeviceSize))
+    allocationSizeMax <- peek @DeviceSize ((p `plusPtr` 40 :: Ptr DeviceSize))
+    unusedRangeSizeMin <- peek @DeviceSize ((p `plusPtr` 48 :: Ptr DeviceSize))
+    unusedRangeSizeMax <- peek @DeviceSize ((p `plusPtr` 56 :: Ptr DeviceSize))
+    pure $ DetailedStatistics
+             statistics
+             unusedRangeCount
+             allocationSizeMin
+             allocationSizeMax
+             unusedRangeSizeMin
+             unusedRangeSizeMax
+
+instance Storable DetailedStatistics where
+  sizeOf ~_ = 64
+  alignment ~_ = 8
+  peek = peekCStruct
+  poke ptr poked = pokeCStruct ptr poked (pure ())
+
+instance Zero DetailedStatistics where
+  zero = DetailedStatistics
+           zero
+           zero
+           zero
+           zero
+           zero
+           zero
+
+
+-- | VmaTotalStatistics
+--
+-- -   'DetailedStatistics' /memoryType/ [VK_MAX_MEMORY_TYPES]
+--
+-- -   'DetailedStatistics' /memoryHeap/ [VK_MAX_MEMORY_HEAPS]
+--
+-- -   'DetailedStatistics' /total/
+--
+-- General statistics from current state of the Allocator - total memory
+-- usage across all memory heaps and types.
+--
+-- These are slower to calculate. Use for debugging purposes. See function
+-- 'calculateStatistics'.
+--
+-- === memoryHeap
+--
+-- memoryHeap
+-- VmaTotalStatistics
+-- VmaTotalStatistics
+-- memoryHeap
+-- @VmaDetailedStatistics VmaTotalStatistics::memoryHeap[VK_MAX_MEMORY_HEAPS]@
+--
+-- === memoryType
+--
+-- memoryType
+-- VmaTotalStatistics
+-- VmaTotalStatistics
+-- memoryType
+-- @VmaDetailedStatistics VmaTotalStatistics::memoryType[VK_MAX_MEMORY_TYPES]@
+data TotalStatistics = TotalStatistics
+  { -- No documentation found for Nested "VmaTotalStatistics" "memoryType"
+    memoryType :: Vector DetailedStatistics
+  , -- No documentation found for Nested "VmaTotalStatistics" "memoryHeap"
+    memoryHeap :: Vector DetailedStatistics
+  , 
+    total :: DetailedStatistics
+  }
+  deriving (Typeable)
+#if defined(GENERIC_INSTANCES)
+deriving instance Generic (TotalStatistics)
+#endif
+deriving instance Show TotalStatistics
+
+instance ToCStruct TotalStatistics where
+  withCStruct x f = allocaBytes 3136 $ \p -> pokeCStruct p x (f p)
+  pokeCStruct p TotalStatistics{..} f = do
+    unless ((Data.Vector.length $ (memoryType)) <= MAX_MEMORY_TYPES) $
+      throwIO $ IOError Nothing InvalidArgument "" "memoryType is too long, a maximum of MAX_MEMORY_TYPES elements are allowed" Nothing Nothing
+    Data.Vector.imapM_ (\i e -> poke ((lowerArrayPtr ((p `plusPtr` 0 :: Ptr (FixedArray MAX_MEMORY_TYPES DetailedStatistics)))) `plusPtr` (64 * (i)) :: Ptr DetailedStatistics) (e)) (memoryType)
+    unless ((Data.Vector.length $ (memoryHeap)) <= MAX_MEMORY_HEAPS) $
+      throwIO $ IOError Nothing InvalidArgument "" "memoryHeap is too long, a maximum of MAX_MEMORY_HEAPS elements are allowed" Nothing Nothing
+    Data.Vector.imapM_ (\i e -> poke ((lowerArrayPtr ((p `plusPtr` 2048 :: Ptr (FixedArray MAX_MEMORY_HEAPS DetailedStatistics)))) `plusPtr` (64 * (i)) :: Ptr DetailedStatistics) (e)) (memoryHeap)
+    poke ((p `plusPtr` 3072 :: Ptr DetailedStatistics)) (total)
+    f
+  cStructSize = 3136
+  cStructAlignment = 8
+  pokeZeroCStruct p f = do
+    poke ((p `plusPtr` 3072 :: Ptr DetailedStatistics)) (zero)
+    f
+
+instance FromCStruct TotalStatistics where
+  peekCStruct p = do
+    memoryType <- generateM (MAX_MEMORY_TYPES) (\i -> peekCStruct @DetailedStatistics (((lowerArrayPtr @DetailedStatistics ((p `plusPtr` 0 :: Ptr (FixedArray MAX_MEMORY_TYPES DetailedStatistics)))) `advancePtrBytes` (64 * (i)) :: Ptr DetailedStatistics)))
+    memoryHeap <- generateM (MAX_MEMORY_HEAPS) (\i -> peekCStruct @DetailedStatistics (((lowerArrayPtr @DetailedStatistics ((p `plusPtr` 2048 :: Ptr (FixedArray MAX_MEMORY_HEAPS DetailedStatistics)))) `advancePtrBytes` (64 * (i)) :: Ptr DetailedStatistics)))
+    total <- peekCStruct @DetailedStatistics ((p `plusPtr` 3072 :: Ptr DetailedStatistics))
+    pure $ TotalStatistics
+             memoryType memoryHeap total
+
+instance Storable TotalStatistics where
+  sizeOf ~_ = 3136
+  alignment ~_ = 8
+  peek = peekCStruct
+  poke ptr poked = pokeCStruct ptr poked (pure ())
+
+instance Zero TotalStatistics where
+  zero = TotalStatistics
+           mempty
+           mempty
+           zero
+
+
+-- | VmaBudget
+--
+-- Statistics of current memory usage and available budget for a specific
+-- memory heap.
+--
+-- These are fast to calculate. See function 'getHeapBudgets'.
+data Budget = Budget
+  { -- | Statistics fetched from the library.
+    statistics :: Statistics
+  , -- | Estimated current memory usage of the program, in bytes.
+    --
+    -- Fetched from system using VK_EXT_memory_budget extension if enabled.
+    --
+    -- It might be different than @statistics.blockBytes@ (usually higher) due
+    -- to additional implicit objects also occupying the memory, like
+    -- swapchain, pipelines, descriptor heaps, command buffers, or
+    -- @VkDeviceMemory@ blocks allocated outside of this library, if any.
+    usage :: DeviceSize
+  , -- | Estimated amount of memory available to the program, in bytes.
+    --
+    -- Fetched from system using VK_EXT_memory_budget extension if enabled.
+    --
+    -- It might be different (most probably smaller) than
+    -- @VkMemoryHeap::size[heapIndex]@ due to factors external to the program,
+    -- decided by the operating system. Difference @budget - usage@ is the
+    -- amount of additional memory that can probably be allocated without
+    -- problems. Exceeding the budget may result in various problems.
+    budget :: DeviceSize
+  }
+  deriving (Typeable)
+#if defined(GENERIC_INSTANCES)
+deriving instance Generic (Budget)
+#endif
+deriving instance Show Budget
+
+instance ToCStruct Budget where
+  withCStruct x f = allocaBytes 40 $ \p -> pokeCStruct p x (f p)
+  pokeCStruct p Budget{..} f = do
+    poke ((p `plusPtr` 0 :: Ptr Statistics)) (statistics)
+    poke ((p `plusPtr` 24 :: Ptr DeviceSize)) (usage)
+    poke ((p `plusPtr` 32 :: Ptr DeviceSize)) (budget)
+    f
+  cStructSize = 40
+  cStructAlignment = 8
+  pokeZeroCStruct p f = do
+    poke ((p `plusPtr` 0 :: Ptr Statistics)) (zero)
+    poke ((p `plusPtr` 24 :: Ptr DeviceSize)) (zero)
+    poke ((p `plusPtr` 32 :: Ptr DeviceSize)) (zero)
+    f
+
+instance FromCStruct Budget where
+  peekCStruct p = do
+    statistics <- peekCStruct @Statistics ((p `plusPtr` 0 :: Ptr Statistics))
+    usage <- peek @DeviceSize ((p `plusPtr` 24 :: Ptr DeviceSize))
+    budget <- peek @DeviceSize ((p `plusPtr` 32 :: Ptr DeviceSize))
+    pure $ Budget
+             statistics usage budget
+
+instance Storable Budget where
+  sizeOf ~_ = 40
+  alignment ~_ = 8
+  peek = peekCStruct
+  poke ptr poked = pokeCStruct ptr poked (pure ())
+
+instance Zero Budget where
+  zero = Budget
+           zero
+           zero
+           zero
+
+
+-- | VmaAllocationCreateInfo
+--
+-- Parameters of new 'Allocation'.
+--
+-- To be used with functions like 'createBuffer', 'createImage', and many
+-- others.
+data AllocationCreateInfo = AllocationCreateInfo
+  { -- | Use 'AllocationCreateFlagBits' enum.
+    flags :: AllocationCreateFlags
+  , -- | Intended usage of memory.
+    --
+    -- You can leave 'MEMORY_USAGE_UNKNOWN' if you specify memory requirements
+    -- in other way.
+    --
+    -- >  
+    --
+    -- If @pool@ is not null, this member is ignored.
+    usage :: MemoryUsage
+  , -- | Flags that must be set in a Memory Type chosen for an allocation.
+    --
+    -- Leave 0 if you specify memory requirements in other way.
+    --
+    -- >  
+    --
+    -- If @pool@ is not null, this member is ignored.
+    requiredFlags :: MemoryPropertyFlags
+  , -- | Flags that preferably should be set in a memory type chosen for an
+    -- allocation.
+    --
+    -- Set to 0 if no additional flags are preferred.
+    --
+    -- >  
+    --
+    -- If @pool@ is not null, this member is ignored.
+    preferredFlags :: MemoryPropertyFlags
+  , -- | Bitmask containing one bit set for every memory type acceptable for this
+    -- allocation.
+    --
+    -- Value 0 is equivalent to @UINT32_MAX@ - it means any memory type is
+    -- accepted if it meets other requirements specified by this structure,
+    -- with no further restrictions on memory type index.
+    --
+    -- >  
+    --
+    -- If @pool@ is not null, this member is ignored.
+    memoryTypeBits :: Word32
+  , -- | Pool that this allocation should be created in.
+    --
+    -- Leave @VK_NULL_HANDLE@ to allocate from default pool. If not null,
+    -- members: @usage@, @requiredFlags@, @preferredFlags@, @memoryTypeBits@
+    -- are ignored.
+    pool :: Pool
+  , -- | Custom general-purpose pointer that will be stored in 'Allocation', can
+    -- be read as /VmaAllocationInfo::pUserData/ and changed using
+    -- 'setAllocationUserData'.
+    --
+    -- If 'ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT' is used, it must be
+    -- either null or pointer to a null-terminated string. The string will be
+    -- then copied to internal buffer, so it doesn\'t need to be valid after
+    -- allocation call.
+    userData :: Ptr ()
+  , -- | A floating-point value between 0 and 1, indicating the priority of the
+    -- allocation relative to other memory allocations.
+    --
+    -- It is used only when 'ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT' flag was
+    -- used during creation of the 'Allocator' object and this allocation ends
+    -- up as dedicated or is explicitly forced as dedicated using
+    -- 'ALLOCATION_CREATE_DEDICATED_MEMORY_BIT'. Otherwise, it has the priority
+    -- of a memory block where it is placed and this variable is ignored.
+    priority :: Float
+  }
+  deriving (Typeable)
+#if defined(GENERIC_INSTANCES)
+deriving instance Generic (AllocationCreateInfo)
+#endif
+deriving instance Show AllocationCreateInfo
+
+instance ToCStruct AllocationCreateInfo where
+  withCStruct x f = allocaBytes 48 $ \p -> pokeCStruct p x (f p)
+  pokeCStruct p AllocationCreateInfo{..} f = do
+    poke ((p `plusPtr` 0 :: Ptr AllocationCreateFlags)) (flags)
+    poke ((p `plusPtr` 4 :: Ptr MemoryUsage)) (usage)
+    poke ((p `plusPtr` 8 :: Ptr MemoryPropertyFlags)) (requiredFlags)
+    poke ((p `plusPtr` 12 :: Ptr MemoryPropertyFlags)) (preferredFlags)
+    poke ((p `plusPtr` 16 :: Ptr Word32)) (memoryTypeBits)
+    poke ((p `plusPtr` 24 :: Ptr Pool)) (pool)
+    poke ((p `plusPtr` 32 :: Ptr (Ptr ()))) (userData)
+    poke ((p `plusPtr` 40 :: Ptr CFloat)) (CFloat (priority))
+    f
+  cStructSize = 48
+  cStructAlignment = 8
+  pokeZeroCStruct p f = do
+    poke ((p `plusPtr` 0 :: Ptr AllocationCreateFlags)) (zero)
+    poke ((p `plusPtr` 4 :: Ptr MemoryUsage)) (zero)
+    poke ((p `plusPtr` 8 :: Ptr MemoryPropertyFlags)) (zero)
+    poke ((p `plusPtr` 12 :: Ptr MemoryPropertyFlags)) (zero)
+    poke ((p `plusPtr` 16 :: Ptr Word32)) (zero)
+    poke ((p `plusPtr` 40 :: Ptr CFloat)) (CFloat (zero))
+    f
+
+instance FromCStruct AllocationCreateInfo where
+  peekCStruct p = do
+    flags <- peek @AllocationCreateFlags ((p `plusPtr` 0 :: Ptr AllocationCreateFlags))
+    usage <- peek @MemoryUsage ((p `plusPtr` 4 :: Ptr MemoryUsage))
+    requiredFlags <- peek @MemoryPropertyFlags ((p `plusPtr` 8 :: Ptr MemoryPropertyFlags))
+    preferredFlags <- peek @MemoryPropertyFlags ((p `plusPtr` 12 :: Ptr MemoryPropertyFlags))
+    memoryTypeBits <- peek @Word32 ((p `plusPtr` 16 :: Ptr Word32))
+    pool <- peek @Pool ((p `plusPtr` 24 :: Ptr Pool))
+    pUserData <- peek @(Ptr ()) ((p `plusPtr` 32 :: Ptr (Ptr ())))
+    priority <- peek @CFloat ((p `plusPtr` 40 :: Ptr CFloat))
+    pure $ AllocationCreateInfo
+             flags
+             usage
+             requiredFlags
+             preferredFlags
+             memoryTypeBits
+             pool
+             pUserData
+             (coerce @CFloat @Float priority)
+
+instance Storable AllocationCreateInfo where
+  sizeOf ~_ = 48
+  alignment ~_ = 8
+  peek = peekCStruct
+  poke ptr poked = pokeCStruct ptr poked (pure ())
+
+instance Zero AllocationCreateInfo where
+  zero = AllocationCreateInfo
+           zero
+           zero
+           zero
+           zero
+           zero
+           zero
+           zero
+           zero
+
+
+-- | VmaPoolCreateInfo
+--
+-- Describes parameter of created 'Pool'.
+data PoolCreateInfo = PoolCreateInfo
+  { -- | Vulkan memory type index to allocate this pool from.
+    memoryTypeIndex :: Word32
+  , -- | Use combination of 'PoolCreateFlagBits'.
+    flags :: PoolCreateFlags
+  , -- | Size of a single @VkDeviceMemory@ block to be allocated as part of this
+    -- pool, in bytes. Optional.
+    --
+    -- Specify nonzero to set explicit, constant size of memory blocks used by
+    -- this pool.
+    --
+    -- Leave 0 to use default and let the library manage block sizes
+    -- automatically. Sizes of particular blocks may vary. In this case, the
+    -- pool will also support dedicated allocations.
+    blockSize :: DeviceSize
+  , -- | Minimum number of blocks to be always allocated in this pool, even if
+    -- they stay empty.
+    --
+    -- Set to 0 to have no preallocated blocks and allow the pool be completely
+    -- empty.
+    minBlockCount :: Word64
+  , -- | Maximum number of blocks that can be allocated in this pool. Optional.
+    --
+    -- Set to 0 to use default, which is @SIZE_MAX@, which means no limit.
+    --
+    -- Set to same value as /VmaPoolCreateInfo::minBlockCount/ to have fixed
+    -- amount of memory allocated throughout whole lifetime of this pool.
+    maxBlockCount :: Word64
+  , -- | A floating-point value between 0 and 1, indicating the priority of the
+    -- allocations in this pool relative to other memory allocations.
+    --
+    -- It is used only when 'ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT' flag was
+    -- used during creation of the 'Allocator' object. Otherwise, this variable
+    -- is ignored.
+    priority :: Float
+  , -- | Additional minimum alignment to be used for all allocations created from
+    -- this pool. Can be 0.
+    --
+    -- Leave 0 (default) not to impose any additional alignment. If not 0, it
+    -- must be a power of two. It can be useful in cases where alignment
+    -- returned by Vulkan by functions like @vkGetBufferMemoryRequirements@ is
+    -- not enough, e.g. when doing interop with OpenGL.
+    minAllocationAlignment :: DeviceSize
+  , -- | Additional @pNext@ chain to be attached to @VkMemoryAllocateInfo@ used
+    -- for every allocation made by this pool. Optional.
+    --
+    -- Optional, can be null. If not null, it must point to a @pNext@ chain of
+    -- structures that can be attached to @VkMemoryAllocateInfo@. It can be
+    -- useful for special needs such as adding @VkExportMemoryAllocateInfoKHR@.
+    -- Structures pointed by this member must remain alive and unchanged for
+    -- the whole lifetime of the custom pool.
+    --
+    -- Please note that some structures, e.g.
+    -- @VkMemoryPriorityAllocateInfoEXT@, @VkMemoryDedicatedAllocateInfoKHR@,
+    -- can be attached automatically by this library when using other, more
+    -- convenient of its features.
+    memoryAllocateNext :: Ptr ()
+  }
+  deriving (Typeable)
+#if defined(GENERIC_INSTANCES)
+deriving instance Generic (PoolCreateInfo)
+#endif
+deriving instance Show PoolCreateInfo
+
+instance ToCStruct PoolCreateInfo where
+  withCStruct x f = allocaBytes 56 $ \p -> pokeCStruct p x (f p)
+  pokeCStruct p PoolCreateInfo{..} f = do
+    poke ((p `plusPtr` 0 :: Ptr Word32)) (memoryTypeIndex)
+    poke ((p `plusPtr` 4 :: Ptr PoolCreateFlags)) (flags)
+    poke ((p `plusPtr` 8 :: Ptr DeviceSize)) (blockSize)
+    poke ((p `plusPtr` 16 :: Ptr CSize)) (CSize (minBlockCount))
+    poke ((p `plusPtr` 24 :: Ptr CSize)) (CSize (maxBlockCount))
+    poke ((p `plusPtr` 32 :: Ptr CFloat)) (CFloat (priority))
+    poke ((p `plusPtr` 40 :: Ptr DeviceSize)) (minAllocationAlignment)
+    poke ((p `plusPtr` 48 :: Ptr (Ptr ()))) (memoryAllocateNext)
+    f
+  cStructSize = 56
+  cStructAlignment = 8
+  pokeZeroCStruct p f = do
+    poke ((p `plusPtr` 0 :: Ptr Word32)) (zero)
+    poke ((p `plusPtr` 4 :: Ptr PoolCreateFlags)) (zero)
+    poke ((p `plusPtr` 8 :: Ptr DeviceSize)) (zero)
+    poke ((p `plusPtr` 16 :: Ptr CSize)) (CSize (zero))
+    poke ((p `plusPtr` 24 :: Ptr CSize)) (CSize (zero))
+    poke ((p `plusPtr` 32 :: Ptr CFloat)) (CFloat (zero))
+    poke ((p `plusPtr` 40 :: Ptr DeviceSize)) (zero)
+    f
+
+instance FromCStruct PoolCreateInfo where
+  peekCStruct p = do
+    memoryTypeIndex <- peek @Word32 ((p `plusPtr` 0 :: Ptr Word32))
+    flags <- peek @PoolCreateFlags ((p `plusPtr` 4 :: Ptr PoolCreateFlags))
+    blockSize <- peek @DeviceSize ((p `plusPtr` 8 :: Ptr DeviceSize))
+    minBlockCount <- peek @CSize ((p `plusPtr` 16 :: Ptr CSize))
+    maxBlockCount <- peek @CSize ((p `plusPtr` 24 :: Ptr CSize))
+    priority <- peek @CFloat ((p `plusPtr` 32 :: Ptr CFloat))
+    minAllocationAlignment <- peek @DeviceSize ((p `plusPtr` 40 :: Ptr DeviceSize))
+    pMemoryAllocateNext <- peek @(Ptr ()) ((p `plusPtr` 48 :: Ptr (Ptr ())))
+    pure $ PoolCreateInfo
+             memoryTypeIndex
+             flags
+             blockSize
+             (coerce @CSize @Word64 minBlockCount)
+             (coerce @CSize @Word64 maxBlockCount)
+             (coerce @CFloat @Float priority)
+             minAllocationAlignment
+             pMemoryAllocateNext
 
 instance Storable PoolCreateInfo where
   sizeOf ~_ = 56
