diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,11 @@
+# Changelog for `try-vulkan-middle`
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+and this project adheres to the
+[Haskell Package Versioning Policy](https://pvp.haskell.org/).
+
+## Unreleased
+
+## 0.1.0.0 - YYYY-MM-DD
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Author name here (c) 2022
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Author name here nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,1 @@
+# gpu-vulkan-middle
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/gpu-vulkan-middle.cabal b/gpu-vulkan-middle.cabal
new file mode 100644
--- /dev/null
+++ b/gpu-vulkan-middle.cabal
@@ -0,0 +1,237 @@
+cabal-version: 1.12
+
+-- This file has been generated from package.yaml by hpack version 0.37.0.
+--
+-- see: https://github.com/sol/hpack
+
+name:           gpu-vulkan-middle
+version:        0.1.0.54
+synopsis:       Medium wrapper for Vulkan API
+description:    Please see the README on GitHub at <https://github.com/YoshikuniJujo/gpu-vulkan-middle#readme>
+category:       GPU
+homepage:       https://github.com/YoshikuniJujo/gpu-vulkan-middle#readme
+bug-reports:    https://github.com/YoshikuniJujo/gpu-vulkan-middle/issues
+author:         Yoshikuni Jujo
+maintainer:     yoshikuni.jujo@gmail.com
+copyright:      2022 Yoshikuni Jujo
+license:        BSD3
+license-file:   LICENSE
+build-type:     Simple
+extra-source-files:
+    README.md
+    CHANGELOG.md
+data-files:
+    th/vkFormat.txt
+    th/vkPhysicalDeviceDescriptorIndexingFeatures.txt
+    th/vkPhysicalDeviceFeatures.txt
+    th/vkPhysicalDeviceLimits.txt
+    th/vkShaderStageFlagBits.txt
+
+source-repository head
+  type: git
+  location: https://github.com/YoshikuniJujo/gpu-vulkan-middle
+
+library
+  exposed-modules:
+      Gpu.Vulkan.AllocationCallbacks.Middle
+      Gpu.Vulkan.AllocationCallbacks.Middle.Internal
+      Gpu.Vulkan.Attachment.Enum
+      Gpu.Vulkan.Attachment.Middle
+      Gpu.Vulkan.Base.Middle.Internal
+      Gpu.Vulkan.Buffer.Enum
+      Gpu.Vulkan.Buffer.Middle
+      Gpu.Vulkan.BufferView.Middle
+      Gpu.Vulkan.ColorComponent.Enum
+      Gpu.Vulkan.Cmd.Middle
+      Gpu.Vulkan.CommandBuffer.Enum
+      Gpu.Vulkan.CommandBuffer.Middle
+      Gpu.Vulkan.CommandPool.Enum
+      Gpu.Vulkan.CommandPool.Middle
+      Gpu.Vulkan.Component.Enum
+      Gpu.Vulkan.Component.Middle
+      Gpu.Vulkan.Data.Middle
+      Gpu.Vulkan.Descriptor.Enum
+      Gpu.Vulkan.Descriptor.Middle
+      Gpu.Vulkan.DescriptorPool.Enum
+      Gpu.Vulkan.DescriptorPool.Middle
+      Gpu.Vulkan.DescriptorSet.Middle
+      Gpu.Vulkan.DescriptorSetLayout.Enum
+      Gpu.Vulkan.DescriptorSetLayout.Middle
+      Gpu.Vulkan.DescriptorSetLayout.BindingFlags.Middle
+      Gpu.Vulkan.Device.Enum
+      Gpu.Vulkan.Device.Middle
+      Gpu.Vulkan.Device.Middle.Internal
+      Gpu.Vulkan.Enum
+      Gpu.Vulkan.Exception.Enum
+      Gpu.Vulkan.Exception.Middle
+      Gpu.Vulkan.Fence.Enum
+      Gpu.Vulkan.Fence.Middle
+      Gpu.Vulkan.Fence.Middle.Internal
+      Gpu.Vulkan.Framebuffer.Enum
+      Gpu.Vulkan.Framebuffer.Middle
+      Gpu.Vulkan.Image.Enum
+      Gpu.Vulkan.Image.Middle
+      Gpu.Vulkan.Image.Middle.Internal
+      Gpu.Vulkan.ImageView.Enum
+      Gpu.Vulkan.ImageView.Middle
+      Gpu.Vulkan.Instance.Enum
+      Gpu.Vulkan.Instance.Middle
+      Gpu.Vulkan.Instance.Middle.Internal
+      Gpu.Vulkan.Memory.Enum
+      Gpu.Vulkan.Memory.Middle
+      Gpu.Vulkan.Middle
+      Gpu.Vulkan.PhysicalDevice.Enum
+      Gpu.Vulkan.PhysicalDevice.Middle
+      Gpu.Vulkan.PhysicalDevice.Middle.Internal
+      Gpu.Vulkan.PhysicalDevice.Struct
+      Gpu.Vulkan.PipelineCache.Enum
+      Gpu.Vulkan.PipelineCache.Middle
+      Gpu.Vulkan.Pipeline.ColorBlendAttachment.Middle
+      Gpu.Vulkan.Pipeline.ColorBlendState.Middle
+      Gpu.Vulkan.Pipeline.Compute.Middle
+      Gpu.Vulkan.Pipeline.DepthStencilState.Middle
+      Gpu.Vulkan.Pipeline.DynamicState.Middle
+      Gpu.Vulkan.Pipeline.Enum
+      Gpu.Vulkan.Pipeline.Graphics.Middle
+      Gpu.Vulkan.Pipeline.InputAssemblyState.Middle
+      Gpu.Vulkan.PipelineLayout.Middle
+      Gpu.Vulkan.Pipeline.MultisampleState.Middle
+      Gpu.Vulkan.Pipeline.RasterizationState.Middle
+      Gpu.Vulkan.Pipeline.ShaderStage.Enum
+      Gpu.Vulkan.Pipeline.ShaderStage.Middle
+      Gpu.Vulkan.Pipeline.TessellationState.Middle
+      Gpu.Vulkan.Pipeline.VertexInputState.Middle
+      Gpu.Vulkan.Pipeline.ViewportState.Middle
+      Gpu.Vulkan.PNext.Middle
+      Gpu.Vulkan.PNext.Middle.Internal
+      Gpu.Vulkan.PNextOld.Middle
+      Gpu.Vulkan.PNextOld.Middle.Internal
+      Gpu.Vulkan.PushConstant.Middle
+      Gpu.Vulkan.Query.Enum
+      Gpu.Vulkan.QueryPool.Middle
+      Gpu.Vulkan.Queue.Enum
+      Gpu.Vulkan.Queue.Middle
+      Gpu.Vulkan.Queue.Middle.Internal
+      Gpu.Vulkan.QueueFamily.Middle
+      Gpu.Vulkan.RenderPass.Enum
+      Gpu.Vulkan.RenderPass.Middle
+      Gpu.Vulkan.Sample.Enum
+      Gpu.Vulkan.Sample.Middle
+      Gpu.Vulkan.Sampler.Enum
+      Gpu.Vulkan.Sampler.Middle
+      Gpu.Vulkan.Semaphore.Middle
+      Gpu.Vulkan.Semaphore.Middle.Internal
+      Gpu.Vulkan.ShaderModule.Middle
+      Gpu.Vulkan.Subpass.Enum
+      Gpu.Vulkan.Subpass.Middle
+      Gpu.Vulkan.VertexInput.Enum
+      Gpu.Vulkan.VertexInput.Middle
+  other-modules:
+      Gpu.Vulkan.Attachment.Middle.Internal
+      Gpu.Vulkan.Base.Middle
+      Gpu.Vulkan.Buffer.Middle.Internal
+      Gpu.Vulkan.BufferView.Middle.Internal
+      Gpu.Vulkan.CommandBuffer.Middle.Internal
+      Gpu.Vulkan.CommandPool.Middle.Internal
+      Gpu.Vulkan.Component.Middle.Internal
+      Gpu.Vulkan.Descriptor.Middle.Internal
+      Gpu.Vulkan.DescriptorPool.Middle.Internal
+      Gpu.Vulkan.DescriptorSet.Middle.Internal
+      Gpu.Vulkan.DescriptorSetLayout.BindingFlags.Middle.Internal
+      Gpu.Vulkan.DescriptorSetLayout.Middle.Internal
+      Gpu.Vulkan.Device.Middle.Types
+      Gpu.Vulkan.Exception.Middle.Internal
+      Gpu.Vulkan.Framebuffer.Middle.Internal
+      Gpu.Vulkan.ImageView.Middle.Internal
+      Gpu.Vulkan.Memory.Middle.Internal
+      Gpu.Vulkan.Middle.Internal
+      Gpu.Vulkan.Middle.Types
+      Gpu.Vulkan.Misc.Middle.Internal
+      Gpu.Vulkan.PhysicalDevice.Struct.Th
+      Gpu.Vulkan.PhysicalDevice.Struct.ThTest
+      Gpu.Vulkan.Pipeline.ColorBlendAttachment.Middle.Internal
+      Gpu.Vulkan.Pipeline.ColorBlendState.Middle.Internal
+      Gpu.Vulkan.Pipeline.Compute.Middle.Internal
+      Gpu.Vulkan.Pipeline.DepthStencilState.Middle.Internal
+      Gpu.Vulkan.Pipeline.DynamicState.Middle.Internal
+      Gpu.Vulkan.Pipeline.Graphics.Middle.Internal
+      Gpu.Vulkan.Pipeline.InputAssemblyState.Middle.Internal
+      Gpu.Vulkan.Pipeline.MultisampleState.Middle.Internal
+      Gpu.Vulkan.Pipeline.RasterizationState.Middle.Internal
+      Gpu.Vulkan.Pipeline.ShaderStage.Middle.Internal
+      Gpu.Vulkan.Pipeline.TessellationState.Middle.Internal
+      Gpu.Vulkan.Pipeline.VertexInputState.Middle.Internal
+      Gpu.Vulkan.Pipeline.ViewportState.Middle.Internal
+      Gpu.Vulkan.PipelineCache.Middle.Internal
+      Gpu.Vulkan.PipelineLayout.Middle.Internal
+      Gpu.Vulkan.PushConstant.Middle.Internal
+      Gpu.Vulkan.QueryPool.Middle.Internal
+      Gpu.Vulkan.QueueFamily.EnumManual
+      Gpu.Vulkan.QueueFamily.Middle.Internal
+      Gpu.Vulkan.RenderPass.Middle.Internal
+      Gpu.Vulkan.Sample.Middle.Internal
+      Gpu.Vulkan.Sampler.Middle.Internal
+      Gpu.Vulkan.ShaderModule.Middle.Internal
+      Gpu.Vulkan.Specialization.Middle.Internal
+      Gpu.Vulkan.Subpass.Middle.Internal
+      Gpu.Vulkan.VertexInput.Middle.Internal
+      Paths_gpu_vulkan_middle
+  hs-source-dirs:
+      src
+  ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-export-lists -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints
+  build-depends:
+      base >=4.7 && <5
+    , bytestring <1
+    , c-enum <1
+    , containers <1
+    , data-default <1
+    , exception-hierarchy <1
+    , gpu-vulkan-core <1
+    , hetero-parameter-list <1
+    , language-spir-v <1
+    , mtl <3
+    , mtl-misc-yj <1
+    , ranged-list <1
+    , stm <3
+    , storable-hetero-list <1
+    , storable-peek-poke <1
+    , template-haskell <3
+    , text <3
+    , text-misc-yj <1
+    , typelevel-tools-yj <1
+    , union-color <1
+    , uuid <2
+  default-language: Haskell2010
+
+test-suite gpu-vulkan-middle-test
+  type: exitcode-stdio-1.0
+  main-is: Spec.hs
+  other-modules:
+      Paths_gpu_vulkan_middle
+  hs-source-dirs:
+      test
+  ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-export-lists -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints -threaded -rtsopts -with-rtsopts=-N
+  build-depends:
+      base >=4.7 && <5
+    , bytestring <1
+    , c-enum <1
+    , containers <1
+    , data-default <1
+    , exception-hierarchy <1
+    , gpu-vulkan-core <1
+    , gpu-vulkan-middle
+    , hetero-parameter-list <1
+    , language-spir-v <1
+    , mtl <3
+    , mtl-misc-yj <1
+    , ranged-list <1
+    , stm <3
+    , storable-hetero-list <1
+    , storable-peek-poke <1
+    , template-haskell <3
+    , text <3
+    , text-misc-yj <1
+    , typelevel-tools-yj <1
+    , union-color <1
+    , uuid <2
+  default-language: Haskell2010
diff --git a/src/Gpu/Vulkan/AllocationCallbacks/Middle.hs b/src/Gpu/Vulkan/AllocationCallbacks/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/AllocationCallbacks/Middle.hs
@@ -0,0 +1,24 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.AllocationCallbacks.Middle (
+
+	-- * CREATE AND DESTROY
+
+	create, destroy, Functions, FunctionsInfo(..),
+
+	-- ** Function Types
+
+	FnAllocationFunction, FnReallocationFunction, FnFreeFunction,
+	FnInternalAllocationNotification, FnInternalFreeNotification,
+
+	-- *** size and alignment
+
+	Size, Alignment,
+
+	-- * APPLY
+
+	apply, A,
+
+	) where
+
+import Gpu.Vulkan.AllocationCallbacks.Middle.Internal
diff --git a/src/Gpu/Vulkan/AllocationCallbacks/Middle/Internal.hs b/src/Gpu/Vulkan/AllocationCallbacks/Middle/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/AllocationCallbacks/Middle/Internal.hs
@@ -0,0 +1,150 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE BlockArguments, LambdaCase #-}
+{-# LANGUAGE MonoLocalBinds #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.AllocationCallbacks.Middle.Internal (
+
+	-- * CREATE AND DESTROY
+
+	create, destroy, Functions, FunctionsInfo(..),
+
+	-- ** Function Types
+
+	FnAllocationFunction, FnReallocationFunction, C.FnFreeFunction,
+	FnInternalAllocationNotification, FnInternalFreeNotification,
+
+	-- *** size and alignment
+
+	Size, Alignment,
+
+	-- * APPLY
+
+	apply, A,
+
+	-- * INTERNAL USE
+
+	mToCore
+
+	) where
+
+import Foreign.Marshal.Alloc
+import Foreign.Ptr
+import Foreign.Storable
+import Foreign.Storable.PeekPoke
+import Control.Monad
+import Data.TypeLevel.ParMaybe qualified as TPMaybe
+import Data.Word
+
+import Gpu.Vulkan.Enum
+import Gpu.Vulkan.AllocationCallbacks.Core qualified as C
+
+newtype A a = A C.A deriving Show
+
+data Functions a = Functions {
+	aPfnAllocation :: C.PfnAllocationFunction,
+	aPfnReallocation :: C.PfnReallocationFunction,
+	aPfnFree :: C.PfnFreeFunction,
+	aPfnInternalAllocation :: C.PfnInternalAllocationNotification,
+	aPfnInternalFree :: C.PfnInternalFreeNotification }
+	deriving Show
+
+apply :: Functions a -> Ptr a -> A a
+apply a p = A C.A {
+	C.aPUserData = castPtr p,
+	C.aPfnAllocation = aPfnAllocation a,
+	C.aPfnReallocation = aPfnReallocation a,
+	C.aPfnFree = aPfnFree a,
+	C.aPfnInternalAllocation = aPfnInternalAllocation a,
+	C.aPfnInternalFree = aPfnInternalFree a }
+
+create :: FunctionsInfo a -> IO (Functions a)
+create = mkCallbacksNew
+
+destroy :: Functions a -> IO ()
+destroy a = do
+	freeHaskellFunPtr allc
+	freeHaskellFunPtr rallc
+	freeHaskellFunPtr fr
+	when (iallc /= nullFunPtr) $ freeHaskellFunPtr iallc
+	when (ifr /= nullFunPtr) $ freeHaskellFunPtr ifr
+	where
+	allc = aPfnAllocation a
+	rallc = aPfnReallocation a
+	fr = aPfnFree a
+	iallc = aPfnInternalAllocation a
+	ifr = aPfnInternalFree a
+
+data FunctionsInfo a = FunctionsInfo {
+	functionsInfoFnAllocation :: FnAllocationFunction a,
+	functionsInfoFnReallocation :: FnReallocationFunction a,
+	functionsInfoFnFree :: C.FnFreeFunction a,
+	functionsInfoFnInternalAllocationFree :: Maybe (
+		FnInternalAllocationNotification a,
+		FnInternalFreeNotification a ) }
+
+type Size = Word64
+type Alignment = Word64
+
+type FnAllocationFunction a =
+	Ptr a -> Size -> Alignment -> SystemAllocationScope -> IO (Ptr ())
+
+fnAllocationFunctionToCore :: FnAllocationFunction a -> C.FnAllocationFunction a
+fnAllocationFunctionToCore f pud sz algn ascp =
+	f pud sz algn (SystemAllocationScope ascp)
+
+type FnReallocationFunction a = Ptr a ->
+	Ptr () -> Size -> Alignment -> SystemAllocationScope -> IO (Ptr ())
+
+fnReallocationFunctionToCore ::
+	FnReallocationFunction a -> C.FnReallocationFunction a
+fnReallocationFunctionToCore f pud po sz algn ascp =
+	f pud po sz algn (SystemAllocationScope ascp)
+
+type FnInternalAllocationNotification a = Ptr a ->
+	Size -> InternalAllocationType -> SystemAllocationScope -> IO ()
+
+fnInternalAllocationNotificationToCore ::
+	FnInternalAllocationNotification a ->
+	C.FnInternalAllocationNotification a
+fnInternalAllocationNotificationToCore f pud sz iatp ascp =
+	f pud sz (InternalAllocationType iatp) (SystemAllocationScope ascp)
+
+type FnInternalFreeNotification a = Ptr a ->
+	Size -> InternalAllocationType -> SystemAllocationScope -> IO ()
+
+fnInternalFreeNotificationToCore ::
+	FnInternalFreeNotification a -> C.FnInternalFreeNotification a
+fnInternalFreeNotificationToCore f pud sz iatp ascp =
+	f pud sz (InternalAllocationType iatp) (SystemAllocationScope ascp)
+
+mToCore :: TPMaybe.M A ma -> (Ptr C.A -> IO b) -> IO ()
+mToCore = TPMaybe.maybe ((() <$) . ($ NullPtr)) toCoreNew
+
+toCoreNew :: A a -> (Ptr C.A -> IO b) -> IO ()
+toCoreNew (A ac) f = () <$ alloca \p -> poke p ac >> f p
+
+mkCallbacksNew :: FunctionsInfo a -> IO (Functions a)
+mkCallbacksNew ac = do
+	pal <- C.wrapAllocationFunction $ fnAllocationFunctionToCore al
+	pral <- C.wrapReallocationFunction $ fnReallocationFunctionToCore ral
+	pfr <- C.wrapFreeFunction fr
+	(pial, pifr) <- do
+		case functionsInfoFnInternalAllocationFree ac of
+			Nothing -> pure (nullFunPtr, nullFunPtr)
+			Just (ial, ifr) -> do
+				wal <- C.wrapInternalAllocationNotification
+					$ fnInternalAllocationNotificationToCore ial
+				wfr <- C.wrapInternalFreeNotification
+					$ fnInternalFreeNotificationToCore ifr
+				pure (wal, wfr)
+	pure Functions {
+		aPfnAllocation = pal,
+		aPfnReallocation = pral,
+		aPfnFree = pfr,
+		aPfnInternalAllocation = pial,
+		aPfnInternalFree = pifr }
+	where
+	al = functionsInfoFnAllocation ac
+	ral = functionsInfoFnReallocation ac
+	fr = functionsInfoFnFree ac
diff --git a/src/Gpu/Vulkan/Attachment/Enum.hsc b/src/Gpu/Vulkan/Attachment/Enum.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Attachment/Enum.hsc
@@ -0,0 +1,47 @@
+-- This file is automatically generated by the tools/makeEnum.hs
+--	% stack runghc --cwd tools/ makeEnum
+
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-missing-export-lists -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Attachment.Enum where
+
+import Foreign.Storable
+import Foreign.C.Enum
+import Data.Bits
+import Data.Word
+
+#include <vulkan/vulkan.h>
+
+enum "DescriptionFlagBits" ''#{type VkAttachmentDescriptionFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("DescriptionFlagsZero", 0),
+	("DescriptionMayAliasBit",
+		#{const VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT}),
+	("DescriptionFlagBitsMaxEnum",
+		#{const VK_ATTACHMENT_DESCRIPTION_FLAG_BITS_MAX_ENUM}) ]
+
+enum "LoadOp" ''#{type VkAttachmentLoadOp}
+		[''Show, ''Eq, ''Storable] [
+	("LoadOpLoad", #{const VK_ATTACHMENT_LOAD_OP_LOAD}),
+	("LoadOpClear", #{const VK_ATTACHMENT_LOAD_OP_CLEAR}),
+	("LoadOpDontCare", #{const VK_ATTACHMENT_LOAD_OP_DONT_CARE}),
+	("LoadOpNoneExt", #{const VK_ATTACHMENT_LOAD_OP_NONE_EXT}),
+	("LoadOpMaxEnum", #{const VK_ATTACHMENT_LOAD_OP_MAX_ENUM}) ]
+
+enum "StoreOp" ''#{type VkAttachmentStoreOp}
+		[''Show, ''Eq, ''Storable] [
+	("StoreOpStore", #{const VK_ATTACHMENT_STORE_OP_STORE}),
+	("StoreOpDontCare",
+		#{const VK_ATTACHMENT_STORE_OP_DONT_CARE}),
+	("StoreOpNone", #{const VK_ATTACHMENT_STORE_OP_NONE}),
+	("StoreOpNoneKhr", #{const VK_ATTACHMENT_STORE_OP_NONE_KHR}),
+	("StoreOpNoneQcom",
+		#{const VK_ATTACHMENT_STORE_OP_NONE_QCOM}),
+	("StoreOpNoneExt", #{const VK_ATTACHMENT_STORE_OP_NONE_EXT}),
+	("StoreOpMaxEnum", #{const VK_ATTACHMENT_STORE_OP_MAX_ENUM}) ]
+
+type DescriptionFlags = DescriptionFlagBits
diff --git a/src/Gpu/Vulkan/Attachment/Middle.hs b/src/Gpu/Vulkan/Attachment/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Attachment/Middle.hs
@@ -0,0 +1,13 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Attachment.Middle (
+
+	-- * Reference
+
+	Reference(..), A,
+
+	-- * Description
+
+	Description(..) ) where
+
+import Gpu.Vulkan.Attachment.Middle.Internal
diff --git a/src/Gpu/Vulkan/Attachment/Middle/Internal.hsc b/src/Gpu/Vulkan/Attachment/Middle/Internal.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Attachment/Middle/Internal.hsc
@@ -0,0 +1,72 @@
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE ScopedTypeVariables, TypeApplications #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE KindSignatures, TypeOperators #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Attachment.Middle.Internal where
+
+import Foreign.Storable
+import Foreign.C.Enum
+import Data.Word
+
+import Gpu.Vulkan.Enum
+import Gpu.Vulkan.Attachment.Enum
+
+import qualified Gpu.Vulkan.Sample.Enum as Sample
+import qualified Gpu.Vulkan.Image.Enum as Image
+import qualified Gpu.Vulkan.Attachment.Core as C
+
+#include <vulkan/vulkan.h>
+
+data Description = Description {
+	descriptionFlags :: DescriptionFlags,
+	descriptionFormat :: Format,
+	descriptionSamples :: Sample.CountFlagBits,
+	descriptionLoadOp :: LoadOp,
+	descriptionStoreOp :: StoreOp,
+	descriptionStencilLoadOp :: LoadOp,
+	descriptionStencilStoreOp :: StoreOp,
+	descriptionInitialLayout :: Image.Layout,
+	descriptionFinalLayout :: Image.Layout }
+	deriving Show
+
+descriptionToCore :: Description -> C.Description
+descriptionToCore Description {
+	descriptionFlags = DescriptionFlagBits flgs,
+	descriptionFormat = Format fmt,
+	descriptionSamples = Sample.CountFlagBits smps,
+	descriptionLoadOp = LoadOp lo,
+	descriptionStoreOp = StoreOp so,
+	descriptionStencilLoadOp = LoadOp slo,
+	descriptionStencilStoreOp = StoreOp sso,
+	descriptionInitialLayout = Image.Layout il,
+	descriptionFinalLayout = Image.Layout fl
+	} = C.Description {
+		C.descriptionFlags = flgs,
+		C.descriptionFormat = fmt,
+		C.descriptionSamples = smps,
+		C.descriptionLoadOp = lo,
+		C.descriptionStoreOp = so,
+		C.descriptionStencilLoadOp = slo,
+		C.descriptionStencilStoreOp = sso,
+		C.descriptionInitialLayout = il,
+		C.descriptionFinalLayout = fl }
+
+enum "A" ''#{type uint32_t} [''Show, ''Storable, ''Num]
+	[("AUnused", #{const VK_ATTACHMENT_UNUSED})]
+
+data Reference = Reference {
+	referenceAttachment :: A,
+	referenceLayout :: Image.Layout }
+	deriving Show
+
+referenceToCore :: Reference -> C.Reference
+referenceToCore Reference {
+	referenceAttachment = A a,
+	referenceLayout = Image.Layout lyt } = C.Reference {
+		C.referenceAttachment = a,
+		C.referenceLayout = lyt }
diff --git a/src/Gpu/Vulkan/Base/Middle.hs b/src/Gpu/Vulkan/Base/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Base/Middle.hs
@@ -0,0 +1,6 @@
+{-# LANGUAGE PatternSynonyms #-}
+{-# OPTIOnS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Base.Middle (pattern NullHandle, ObjectHandle) where
+
+import Gpu.Vulkan.Base.Middle.Internal
diff --git a/src/Gpu/Vulkan/Base/Middle/Internal.hsc b/src/Gpu/Vulkan/Base/Middle/Internal.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Base/Middle/Internal.hsc
@@ -0,0 +1,41 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
+
+module Gpu.Vulkan.Base.Middle.Internal (
+
+	-- * CONVERSION BETWEEN BOOL AND BOOL32
+
+	boolToBool32, bool32ToBool,
+
+	-- * NULL HANDLE
+
+	pattern NullHandle,
+
+	-- * OBJECT HANDLE
+
+	ObjectHandle(..)
+
+	) where
+
+import Foreign.Ptr
+import Data.Word
+
+#include <vulkan/vulkan.h>
+
+boolToBool32 :: Bool -> #{type VkBool32}
+boolToBool32 False = #{const VK_FALSE}
+boolToBool32 True = #{const VK_TRUE}
+
+bool32ToBool :: #{type VkBool32} -> Bool
+bool32ToBool #{const VK_FALSE} = False
+bool32ToBool #{const VK_TRUE} = True
+bool32ToBool _ = error $
+	"Application must not pass any other values than " ++
+	"VK_TRUE or VK_FALSE into a Gpu.Vulkan implementation " ++
+	"where a VkBool32 is expected"
+
+newtype ObjectHandle = ObjectHandle #{type uint64_t} deriving Show
+
+pattern NullHandle :: Ptr a
+pattern NullHandle <- (ptrToWordPtr -> (WordPtr #{const VK_NULL_HANDLE})) where
+	NullHandle = wordPtrToPtr $ WordPtr #{const VK_NULL_HANDLE}
diff --git a/src/Gpu/Vulkan/Buffer/Enum.hsc b/src/Gpu/Vulkan/Buffer/Enum.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Buffer/Enum.hsc
@@ -0,0 +1,107 @@
+-- This file is automatically generated by the tools/makeEnum.hs
+--	% stack runghc --cwd tools/ makeEnum
+
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-missing-export-lists -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Buffer.Enum where
+
+import Foreign.Storable
+import Foreign.C.Enum
+import Data.Default
+import Data.Bits
+import Data.Word
+import Data.Default
+
+#include <vulkan/vulkan.h>
+
+enum "CreateFlagBits" ''#{type VkBufferCreateFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("CreateFlagsZero", 0),
+	("CreateSparseBindingBit",
+		#{const VK_BUFFER_CREATE_SPARSE_BINDING_BIT}),
+	("CreateSparseResidencyBit",
+		#{const VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT}),
+	("CreateSparseAliasedBit",
+		#{const VK_BUFFER_CREATE_SPARSE_ALIASED_BIT}),
+	("CreateProtectedBit", #{const VK_BUFFER_CREATE_PROTECTED_BIT}),
+	("CreateDeviceAddressCaptureReplayBit",
+		#{const VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT}),
+	("CreateDescriptorBufferCaptureReplayBitExt",
+		#{const VK_BUFFER_CREATE_DESCRIPTOR_BUFFER_CAPTURE_REPLAY_BIT_EXT}),
+	("CreateDeviceAddressCaptureReplayBitExt",
+		#{const VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_EXT}),
+	("CreateDeviceAddressCaptureReplayBitKhr",
+		#{const VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR}),
+	("CreateFlagBitsMaxEnum",
+		#{const VK_BUFFER_CREATE_FLAG_BITS_MAX_ENUM}) ]
+
+instance Default CreateFlagBits where
+	def = CreateFlagsZero
+
+enum "UsageFlagBits" ''#{type VkBufferUsageFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("UsageFlagsZero", 0),
+	("UsageTransferSrcBit",
+		#{const VK_BUFFER_USAGE_TRANSFER_SRC_BIT}),
+	("UsageTransferDstBit",
+		#{const VK_BUFFER_USAGE_TRANSFER_DST_BIT}),
+	("UsageUniformTexelBufferBit",
+		#{const VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT}),
+	("UsageStorageTexelBufferBit",
+		#{const VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT}),
+	("UsageUniformBufferBit",
+		#{const VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT}),
+	("UsageStorageBufferBit",
+		#{const VK_BUFFER_USAGE_STORAGE_BUFFER_BIT}),
+	("UsageIndexBufferBit",
+		#{const VK_BUFFER_USAGE_INDEX_BUFFER_BIT}),
+	("UsageVertexBufferBit",
+		#{const VK_BUFFER_USAGE_VERTEX_BUFFER_BIT}),
+	("UsageIndirectBufferBit",
+		#{const VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT}),
+	("UsageShaderDeviceAddressBit",
+		#{const VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT}),
+	("UsageVideoDecodeSrcBitKhr",
+		#{const VK_BUFFER_USAGE_VIDEO_DECODE_SRC_BIT_KHR}),
+	("UsageVideoDecodeDstBitKhr",
+		#{const VK_BUFFER_USAGE_VIDEO_DECODE_DST_BIT_KHR}),
+	("UsageTransformFeedbackBufferBitExt",
+		#{const VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT}),
+	("UsageTransformFeedbackCounterBufferBitExt",
+		#{const VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT}),
+	("UsageConditionalRenderingBitExt",
+		#{const VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT}),
+	("UsageAccelerationStructureBuildInputReadOnlyBitKhr",
+		#{const VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR}),
+	("UsageAccelerationStructureStorageBitKhr",
+		#{const VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR}),
+	("UsageShaderBindingTableBitKhr",
+		#{const VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR}),
+	("UsageSamplerDescriptorBufferBitExt",
+		#{const VK_BUFFER_USAGE_SAMPLER_DESCRIPTOR_BUFFER_BIT_EXT}),
+	("UsageResourceDescriptorBufferBitExt",
+		#{const VK_BUFFER_USAGE_RESOURCE_DESCRIPTOR_BUFFER_BIT_EXT}),
+	("UsagePushDescriptorsDescriptorBufferBitExt",
+		#{const VK_BUFFER_USAGE_PUSH_DESCRIPTORS_DESCRIPTOR_BUFFER_BIT_EXT}),
+	("UsageMicromapBuildInputReadOnlyBitExt",
+		#{const VK_BUFFER_USAGE_MICROMAP_BUILD_INPUT_READ_ONLY_BIT_EXT}),
+	("UsageMicromapStorageBitExt",
+		#{const VK_BUFFER_USAGE_MICROMAP_STORAGE_BIT_EXT}),
+	("UsageRayTracingBitNv",
+		#{const VK_BUFFER_USAGE_RAY_TRACING_BIT_NV}),
+	("UsageShaderDeviceAddressBitExt",
+		#{const VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_EXT}),
+	("UsageShaderDeviceAddressBitKhr",
+		#{const VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR}),
+	("UsageFlagBitsMaxEnum",
+		#{const VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM}) ]
+
+instance Default UsageFlagBits where
+	def = UsageFlagsZero
+
+type CreateFlags = CreateFlagBits
+type UsageFlags = UsageFlagBits
diff --git a/src/Gpu/Vulkan/Buffer/Middle.hs b/src/Gpu/Vulkan/Buffer/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Buffer/Middle.hs
@@ -0,0 +1,23 @@
+{-# LANGUAGE PatternSynonyms #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Buffer.Middle (
+
+	-- * CREATE AND DESTROY
+
+	create, destroy, B, CreateInfo(..),
+
+	-- * GET MEMORY REQUIREMENTS AND BIND MEMORY
+
+	getMemoryRequirements, bindMemory,
+
+	-- * COPY
+
+	Copy, pattern Copy, copySrcOffset, copyDstOffset, copySize,
+	ImageCopy(..),
+
+	-- * MEMORY BARRIER
+
+	MemoryBarrier(..) ) where
+
+import Gpu.Vulkan.Buffer.Middle.Internal
diff --git a/src/Gpu/Vulkan/Buffer/Middle/Internal.hsc b/src/Gpu/Vulkan/Buffer/Middle/Internal.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Buffer/Middle/Internal.hsc
@@ -0,0 +1,166 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE MonoLocalBinds #-}
+{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE FlexibleContexts, UndecidableInstances #-}
+{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
+{-# LANGUAGE StandaloneDeriving, GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Buffer.Middle.Internal (
+	B(..), CreateInfo(..), create, destroy,
+	bindMemory, getMemoryRequirements,
+
+	ImageCopy(..), imageCopyToCore,
+	MemoryBarrier(..), memoryBarrierToCore',
+
+	C.Copy, pattern C.Copy, C.copySrcOffset, C.copyDstOffset, C.copySize
+	) where
+
+import Foreign.Ptr
+import Foreign.Marshal.Alloc
+import Foreign.Marshal.Array
+import Foreign.Storable
+import Foreign.Storable.PeekPoke (WithPoked, withPoked, withPoked', withPtrS)
+import Control.Arrow
+import Control.Monad.Trans
+import Control.Monad.Cont
+import Data.Kind
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Data.TypeLevel.ParMaybe qualified as TPMaybe
+import Data.Word
+import Data.IORef
+
+import Gpu.Vulkan.Core
+import Gpu.Vulkan.Enum
+import Gpu.Vulkan.Exception.Middle.Internal
+import Gpu.Vulkan.Exception.Enum
+import Gpu.Vulkan.Buffer.Enum
+
+import Gpu.Vulkan.AllocationCallbacks.Middle.Internal qualified as
+	AllocationCallbacks (A, mToCore)
+import qualified Gpu.Vulkan.Device.Middle.Internal as Device
+import qualified Gpu.Vulkan.Buffer.Core as C
+import qualified Gpu.Vulkan.Memory.Middle.Internal as Memory
+import qualified Gpu.Vulkan.QueueFamily.EnumManual as QueueFamily
+import qualified Gpu.Vulkan.Image.Middle.Internal as Image
+
+#include <vulkan/vulkan.h>
+
+data CreateInfo (mn :: Maybe Type) = CreateInfo {
+	createInfoNext :: TMaybe.M mn,
+	createInfoFlags :: CreateFlags,
+	createInfoSize :: Device.Size,
+	createInfoUsage :: UsageFlags,
+	createInfoSharingMode :: SharingMode,
+	createInfoQueueFamilyIndices :: [QueueFamily.Index] }
+
+deriving instance Show (TMaybe.M mn) => Show (CreateInfo mn)
+
+createInfoToCore ::
+	WithPoked (TMaybe.M mn) => CreateInfo mn -> (Ptr C.CreateInfo -> IO a) -> IO ()
+createInfoToCore CreateInfo {
+	createInfoNext = mnxt,
+	createInfoFlags = CreateFlagBits flgs,
+	createInfoSize = Device.Size sz,
+	createInfoUsage = UsageFlagBits usg,
+	createInfoSharingMode = SharingMode sm,
+	createInfoQueueFamilyIndices =
+		length &&& (QueueFamily.unIndex <$>) -> (qfic, qfis) } f =
+	allocaArray qfic \pqfis -> do
+	pokeArray pqfis qfis
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') -> do
+		withPoked C.CreateInfo {
+				C.createInfoSType = (),
+				C.createInfoPNext = pnxt',
+				C.createInfoFlags = flgs,
+				C.createInfoSize = sz,
+				C.createInfoUsage = usg,
+				C.createInfoSharingMode = sm,
+				C.createInfoQueueFamilyIndexCount = fromIntegral qfic,
+				C.createInfoPQueueFamilyIndices = pqfis } f
+
+newtype B = B C.B deriving (Show, Eq, Storable)
+
+create :: WithPoked (TMaybe.M mn) =>
+	Device.D -> CreateInfo mn -> TPMaybe.M AllocationCallbacks.A mc -> IO B
+create (Device.D dvc) ci mac = B <$> alloca \pb -> do
+	createInfoToCore ci \pci ->
+		AllocationCallbacks.mToCore mac \pac ->
+			throwUnlessSuccess . Result =<< C.create dvc pci pac pb
+	peek pb
+
+destroy :: Device.D -> B -> TPMaybe.M AllocationCallbacks.A md -> IO ()
+destroy (Device.D dvc) (B b) mac =
+	AllocationCallbacks.mToCore mac $ C.destroy dvc b
+
+getMemoryRequirements :: Device.D -> B -> IO Memory.Requirements
+getMemoryRequirements (Device.D dvc) (B b) =
+	(Memory.requirementsFromCore <$>) . ($ pure) $ runContT do
+		pr <- ContT alloca
+		lift do	C.getMemoryRequirements dvc b pr
+			peek pr
+
+bindMemory :: Device.D -> B -> Memory.M -> Device.Size -> IO ()
+bindMemory (Device.D dvc) (B b) (Memory.M mem) (Device.Size sz) = do
+	m <- readIORef mem
+	throwUnlessSuccess . Result =<< C.bindMemory dvc b m sz
+
+data MemoryBarrier mn = MemoryBarrier {
+	memoryBarrierNext :: TMaybe.M mn,
+	memoryBarrierSrcAccessMask :: AccessFlags,
+	memoryBarrierDstAccessMask :: AccessFlags,
+	memoryBarrierSrcQueueFamilyIndex :: QueueFamily.Index,
+	memoryBarrierDstQueueFamilyIndex :: QueueFamily.Index,
+	memoryBarrierBuffer :: B,
+	memoryBarrierOffset :: Device.Size,
+	memoryBarrierSize :: Device.Size }
+
+deriving instance Show (TMaybe.M mn) => Show (MemoryBarrier mn)
+
+memoryBarrierToCore' :: WithPoked (TMaybe.M mn) =>
+	MemoryBarrier mn -> (C.MemoryBarrier -> IO a) -> IO ()
+memoryBarrierToCore' MemoryBarrier {
+	memoryBarrierNext = mnxt,
+	memoryBarrierSrcAccessMask = AccessFlagBits sam,
+	memoryBarrierDstAccessMask = AccessFlagBits dam,
+	memoryBarrierSrcQueueFamilyIndex = QueueFamily.Index sqfi,
+	memoryBarrierDstQueueFamilyIndex = QueueFamily.Index dqfi,
+	memoryBarrierBuffer = B b,
+	memoryBarrierOffset = Device.Size ofst,
+	memoryBarrierSize = Device.Size sz } f =
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+	f C.MemoryBarrier {
+		C.memoryBarrierSType = (),
+		C.memoryBarrierPNext = pnxt',
+		C.memoryBarrierSrcAccessMask = sam,
+		C.memoryBarrierDstAccessMask = dam,
+		C.memoryBarrierSrcQueueFamilyIndex = sqfi,
+		C.memoryBarrierDstQueueFamilyIndex = dqfi,
+		C.memoryBarrierBuffer = b,
+		C.memoryBarrierOffset = ofst,
+		C.memoryBarrierSize = sz }
+
+data ImageCopy = ImageCopy {
+	imageCopyBufferOffset :: Device.Size,
+	imageCopyBufferRowLength :: Word32,
+	imageCopyBufferImageHeight :: Word32,
+	imageCopyImageSubresource :: Image.SubresourceLayers,
+	imageCopyImageOffset :: Offset3d,
+	imageCopyImageExtent :: Extent3d }
+	deriving Show
+
+imageCopyToCore :: ImageCopy -> C.ImageCopy
+imageCopyToCore ImageCopy {
+	imageCopyBufferOffset = Device.Size bo,
+	imageCopyBufferRowLength = brl,
+	imageCopyBufferImageHeight = bih,
+	imageCopyImageSubresource = isr,
+	imageCopyImageOffset = io,
+	imageCopyImageExtent = ie } = C.ImageCopy {
+	C.imageCopyBufferOffset = bo,
+	C.imageCopyBufferRowLength = brl,
+	C.imageCopyBufferImageHeight = bih,
+	C.imageCopyImageSubresource = Image.subresourceLayersToCore isr,
+	C.imageCopyImageOffset = io,
+	C.imageCopyImageExtent = ie }
diff --git a/src/Gpu/Vulkan/BufferView/Middle.hs b/src/Gpu/Vulkan/BufferView/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/BufferView/Middle.hs
@@ -0,0 +1,11 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.BufferView.Middle (
+
+	-- * CREATE AND DESTROY
+
+	create, destroy, B, CreateInfo(..), CreateFlags
+
+	) where
+
+import Gpu.Vulkan.BufferView.Middle.Internal
diff --git a/src/Gpu/Vulkan/BufferView/Middle/Internal.hsc b/src/Gpu/Vulkan/BufferView/Middle/Internal.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/BufferView/Middle/Internal.hsc
@@ -0,0 +1,78 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE MonoLocalBinds #-}
+{-# LANGUAGE FlexibleContexts, UndecidableInstances #-}
+{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
+{-# LANGUAGE StandaloneDeriving, GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.BufferView.Middle.Internal (
+	B(..), CreateInfo(..), CreateFlags, create, destroy ) where
+
+import Foreign.Ptr
+import Foreign.Marshal.Alloc
+import Foreign.Storable
+import Foreign.Storable.PeekPoke
+import Foreign.C.Enum
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Data.TypeLevel.ParMaybe qualified as TPMaybe
+import Data.Word
+import Data.Bits
+
+import Gpu.Vulkan.Enum
+import Gpu.Vulkan.Exception.Middle.Internal
+import Gpu.Vulkan.Exception.Enum
+
+import Gpu.Vulkan.AllocationCallbacks.Middle.Internal
+	qualified as AllocationCallbacks
+import qualified Gpu.Vulkan.Device.Middle.Internal as Device
+import qualified Gpu.Vulkan.BufferView.Core as C
+import qualified Gpu.Vulkan.Buffer.Middle.Internal as Buffer
+
+#include <vulkan/vulkan.h>
+
+enum "CreateFlags" ''#{type VkBufferViewCreateFlags}
+	[''Show, ''Storable, ''Eq, ''Bits] [("CreateFlagsZero", 0)]
+
+data CreateInfo mn = CreateInfo {
+	createInfoNext :: TMaybe.M mn,
+	createInfoFlags :: CreateFlags,
+	createInfoBuffer :: Buffer.B,
+	createInfoFormat :: Format,
+	createInfoOffset :: Device.Size,
+	createInfoRange :: Device.Size }
+
+deriving instance Show (TMaybe.M mn) => Show (CreateInfo mn)
+
+createInfoToCore' :: WithPoked (TMaybe.M mn) => CreateInfo mn -> (Ptr C.CreateInfo -> IO a) -> IO ()
+createInfoToCore' CreateInfo {
+	createInfoNext = mnxt,
+	createInfoFlags = CreateFlags flgs,
+	createInfoBuffer = Buffer.B bf,
+	createInfoFormat = Format fmt,
+	createInfoOffset = Device.Size os,
+	createInfoRange = Device.Size rng
+	} f = withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+	withPoked C.CreateInfo {
+			C.createInfoSType = (),
+			C.createInfoPNext = pnxt',
+			C.createInfoFlags = flgs,
+			C.createInfoBuffer = bf,
+			C.createInfoFormat = fmt,
+			C.createInfoOffset = os,
+			C.createInfoRange = rng } f
+
+newtype B = B C.B deriving Show
+
+create :: WithPoked (TMaybe.M mn) =>
+	Device.D -> CreateInfo mn -> TPMaybe.M AllocationCallbacks.A mc -> IO B
+create (Device.D dvc) ci mac = B <$> alloca \pb -> do
+	createInfoToCore' ci \pci -> AllocationCallbacks.mToCore mac \pac -> do
+		r <- C.create dvc pci pac pb
+		throwUnlessSuccess $ Result r
+	peek pb
+
+destroy :: Device.D -> B -> TPMaybe.M AllocationCallbacks.A md -> IO ()
+destroy (Device.D dvc) (B b) mac =
+	AllocationCallbacks.mToCore mac $ C.destroy dvc b
diff --git a/src/Gpu/Vulkan/Cmd/Middle.hs b/src/Gpu/Vulkan/Cmd/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Cmd/Middle.hs
@@ -0,0 +1,251 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE ScopedTypeVariables, RankNTypes, TypeApplications #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Cmd.Middle (
+
+	-- * BEGIN AND END RENDER PASS
+
+	beginRenderPass, endRenderPass,
+
+	-- * DRAW AND DISPATCH
+
+	-- ** Draw
+
+	bindPipelineGraphics, bindVertexBuffers, bindIndexBuffer, draw, drawIndexed,
+
+	-- ** Dispatch
+
+	bindPipelineCompute, dispatch,
+
+	-- * PUSH CONSTANTS AND BIND DESCRIPTOR SETS
+
+	pushConstants, bindDescriptorSets,
+
+	-- * COPY BUFFERS AND IMAGES
+
+	copyBuffer, copyBufferToImage, copyImageToBuffer, blitImage,
+
+	-- * MEMORY DEPENDENCY
+
+	pipelineBarrier,
+
+	-- * QUERY
+
+	resetQueryPool, beginQuery, endQuery, writeTimestamp
+
+	) where
+
+import Foreign.Marshal.Alloc
+import Foreign.Marshal.Array
+import Foreign.Storable.PeekPoke (WithPoked)
+import Foreign.Storable.HeteroList
+import Control.Arrow
+import Control.Monad
+import Control.Monad.Trans
+import Control.Monad.Cont
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Data.HeteroParList qualified as HeteroParList
+import Data.Word
+import Data.Int
+import Data.IORef
+
+import Gpu.Vulkan.Middle.Internal
+import Gpu.Vulkan.Enum
+
+import qualified Gpu.Vulkan.CommandBuffer.Middle.Internal as CommandBuffer.M
+import qualified Gpu.Vulkan.Buffer.Middle.Internal as Buffer
+import qualified Gpu.Vulkan.Buffer.Core as Buffer.C
+import qualified Gpu.Vulkan.Device.Middle.Internal as Device
+import qualified Gpu.Vulkan.Cmd.Core as C
+
+import qualified Gpu.Vulkan.RenderPass.Middle.Internal as RenderPass
+import qualified Gpu.Vulkan.Subpass.Enum as Subpass
+import qualified Gpu.Vulkan.Pipeline.Graphics.Middle.Internal as Pipeline
+import qualified Gpu.Vulkan.Pipeline.Compute.Middle.Internal as Pipeline.Compute
+import qualified Gpu.Vulkan.Pipeline.Enum as Pipeline
+import qualified Gpu.Vulkan.PipelineLayout.Middle.Internal as Pipeline.Layout
+
+import qualified Gpu.Vulkan.DescriptorSet.Middle.Internal as Descriptor.Set
+
+import qualified Gpu.Vulkan.Image.Enum as Image
+import qualified Gpu.Vulkan.Image.Middle.Internal as Image
+import qualified Gpu.Vulkan.Buffer.Middle.Internal as Buffer.M
+import qualified Gpu.Vulkan.Memory.Middle.Internal as Memory.M
+
+import Gpu.Vulkan.Query.Enum qualified as Query
+import Gpu.Vulkan.QueryPool.Middle.Internal qualified as QueryPool
+
+beginRenderPass :: (WithPoked (TMaybe.M mn), ClearValueListToCore cts) => CommandBuffer.M.C ->
+	RenderPass.BeginInfo mn cts -> Subpass.Contents -> IO ()
+beginRenderPass (CommandBuffer.M.C _ cb) rpbi (Subpass.Contents spcnt) =
+	RenderPass.beginInfoToCore rpbi \prpbi ->
+		C.beginRenderPass cb prpbi spcnt
+
+endRenderPass :: CommandBuffer.M.C -> IO ()
+endRenderPass (CommandBuffer.M.C _ cb) = C.endRenderPass cb
+
+bindPipelineGraphics ::
+	CommandBuffer.M.C -> Pipeline.BindPoint -> Pipeline.G -> IO ()
+bindPipelineGraphics (CommandBuffer.M.C rppl cb) (Pipeline.BindPoint pbp) ppl = do
+	ppl0 <- readIORef rppl
+	ppl' <- Pipeline.gToCore ppl
+	when (ppl' /= ppl0) do
+		writeIORef rppl ppl'
+		C.bindPipeline cb pbp ppl'
+
+bindPipelineCompute ::
+	CommandBuffer.M.C -> Pipeline.BindPoint -> Pipeline.Compute.C -> IO ()
+bindPipelineCompute (CommandBuffer.M.C rppl cb) (Pipeline.BindPoint pbp) (Pipeline.Compute.C ppl) = do
+	ppl0 <- readIORef rppl
+	when (ppl /= ppl0) do
+		writeIORef rppl ppl
+		C.bindPipeline cb pbp ppl
+
+bindVertexBuffers ::
+	CommandBuffer.M.C -> Word32 -> [(Buffer.B, Device.Size)] -> IO ()
+bindVertexBuffers (CommandBuffer.M.C _ c)
+	fb ((length &&& unzip) -> (bc, (bs, os))) = ($ pure) $ runContT do
+	pb <- ContT $ allocaArray bc
+	lift . pokeArray pb $ (\(Buffer.B b) -> b) <$> bs
+	po <- ContT $ allocaArray bc
+	lift . pokeArray po $ (\(Device.Size sz) -> sz) <$> os
+	lift $ C.bindVertexBuffers c fb (fromIntegral bc) pb po
+
+bindIndexBuffer ::
+	CommandBuffer.M.C -> Buffer.B -> Device.Size -> IndexType -> IO ()
+bindIndexBuffer
+	(CommandBuffer.M.C _ cb) (Buffer.B ib) (Device.Size sz) (IndexType it) =
+	C.bindIndexBuffer cb ib sz it
+
+pushConstants :: forall as . PokableList as =>
+	CommandBuffer.M.C -> Pipeline.Layout.P ->
+	ShaderStageFlags -> Word32 -> HeteroParList.L as -> IO ()
+pushConstants (CommandBuffer.M.C _ cb) (Pipeline.Layout.P lyt)
+	(ShaderStageFlagBits ss) ost xs = ($ pure) $ runContT do
+	let	sz :: Integral n => n
+		sz = fromIntegral $ wholeSize @as
+	p <- ContT $ allocaBytes sz
+	lift do	pokeList p xs
+		C.pushConstants cb lyt ss ost sz p
+
+bindDescriptorSets ::
+	CommandBuffer.M.C -> Pipeline.BindPoint -> Pipeline.Layout.P ->
+	Word32 -> [Descriptor.Set.D] -> [Word32] -> IO ()
+bindDescriptorSets
+	(CommandBuffer.M.C _ cb) (Pipeline.BindPoint bp) (Pipeline.Layout.P lyt)
+	fs (length &&& id -> (dsc, dss))
+	(length &&& id -> (doc, dos)) = ($ pure) $ runContT do
+	pdss <- ContT $ allocaArray dsc
+	let	cdss = (\(Descriptor.Set.D s) -> s) <$> dss
+	lift $ pokeArray pdss cdss
+	pdos <- ContT $ allocaArray doc
+	lift $ pokeArray pdos dos
+	lift $ C.bindDescriptorSets
+		cb bp lyt fs (fromIntegral dsc) pdss (fromIntegral doc) pdos
+
+draw :: CommandBuffer.M.C -> Word32 -> Word32 -> Word32 -> Word32 -> IO ()
+draw (CommandBuffer.M.C _ cb) vc ic fv fi = C.draw cb vc ic fv fi
+
+drawIndexed :: CommandBuffer.M.C ->
+	Word32 -> Word32 -> Word32 -> Int32 -> Word32 -> IO ()
+drawIndexed (CommandBuffer.M.C _ cb) idxc istc fidx vo fist =
+	C.drawIndexed cb idxc istc fidx vo fist
+
+dispatch :: CommandBuffer.M.C -> Word32 -> Word32 -> Word32 -> IO ()
+dispatch (CommandBuffer.M.C _ cb) = C.dispatch cb
+
+copyBuffer ::
+	CommandBuffer.M.C -> Buffer.B -> Buffer.B -> [Buffer.C.Copy] -> IO ()
+copyBuffer (CommandBuffer.M.C _ c) (Buffer.B s) (Buffer.B d)
+	(length &&& id -> (rc, rs)) = ($ pure) $ runContT do
+	prs <- ContT $ allocaArray rc
+	lift do	pokeArray prs rs
+		C.copyBuffer c s d (fromIntegral rc) prs
+
+copyBufferToImage ::
+	CommandBuffer.M.C -> Buffer.M.B -> Image.I -> Image.Layout ->
+	[Buffer.M.ImageCopy] -> IO ()
+copyBufferToImage (CommandBuffer.M.C _ cb)
+	(Buffer.M.B sb) (Image.I rdi) (Image.Layout dil)
+	(length &&& id -> (rc, rs)) = ($ pure) $ runContT do
+	prs <- ContT $ allocaArray rc
+	lift . pokeArray prs $ Buffer.M.imageCopyToCore <$> rs
+	lift do	(_, di) <- readIORef rdi
+		C.copyBufferToImage cb sb di dil (fromIntegral rc) prs
+
+copyImageToBuffer ::
+	CommandBuffer.M.C -> Image.I -> Image.Layout -> Buffer.M.B ->
+	[Buffer.M.ImageCopy] -> IO ()
+copyImageToBuffer (CommandBuffer.M.C _ cb)
+	(Image.I rsi) (Image.Layout sil) (Buffer.M.B db)
+	(length &&& id -> (rc, rs)) = ($ pure) $ runContT do
+	prs <- ContT $ allocaArray rc
+	lift . pokeArray prs $ Buffer.M.imageCopyToCore <$> rs
+	lift do	(_, si) <- readIORef rsi
+		C.copyImageToBuffer cb si sil db (fromIntegral rc) prs
+
+pipelineBarrier :: (
+	HeteroParList.ToListWithCCpsM' WithPoked TMaybe.M ns,
+	HeteroParList.ToListWithCCpsM' WithPoked TMaybe.M ns',
+	HeteroParList.ToListWithCCpsM' WithPoked TMaybe.M ns'' ) =>
+	CommandBuffer.M.C -> Pipeline.StageFlags -> Pipeline.StageFlags ->
+	DependencyFlags ->
+	HeteroParList.PL Memory.M.Barrier ns ->
+	HeteroParList.PL Buffer.M.MemoryBarrier ns' ->
+	HeteroParList.PL Image.MemoryBarrier ns'' -> IO ()
+pipelineBarrier (CommandBuffer.M.C _ cb)
+	(Pipeline.StageFlagBits ssm) (Pipeline.StageFlagBits dsm)
+	(DependencyFlagBits dfs)
+	mbs bbs ibs =
+		HeteroParList.withListWithCCpsM' @_ @WithPoked @TMaybe.M mbs Memory.M.barrierToCore \cmbs ->
+		let	mbc = length cmbs in
+		allocaArray mbc \pmbs ->
+		pokeArray pmbs cmbs >>
+		HeteroParList.withListWithCCpsM' @_ @WithPoked @TMaybe.M bbs Buffer.M.memoryBarrierToCore' \cbbs ->
+		let	bbc = length cbbs in
+		allocaArray bbc \pbbs ->
+		pokeArray pbbs cbbs >>
+		HeteroParList.withListWithCCpsM' @_ @WithPoked @TMaybe.M ibs Image.memoryBarrierToCore \cibs ->
+		let	ibc = length cibs in
+		allocaArray ibc \pibs ->
+		pokeArray pibs cibs >>
+
+		C.pipelineBarrier cb ssm dsm dfs (fromIntegral mbc) pmbs
+			(fromIntegral bbc) pbbs (fromIntegral ibc) pibs
+
+blitImage :: CommandBuffer.M.C ->
+	Image.I -> Image.Layout -> Image.I -> Image.Layout ->
+	[Image.Blit] -> Filter -> IO ()
+blitImage (CommandBuffer.M.C _ cb)
+	(Image.I rsrc) (Image.Layout srcLyt) (Image.I rdst) (Image.Layout dstLyt)
+	(length &&& id -> (bltc, blts)) (Filter ft) = ($ pure) $ runContT do
+	pblts <- ContT $ allocaArray bltc
+	lift . pokeArray pblts $ Image.blitToCore <$> blts
+	lift do (_, src) <- readIORef rsrc
+		(_, dst) <- readIORef rdst
+		C.blitImage cb src srcLyt dst dstLyt (fromIntegral bltc) pblts ft
+
+resetQueryPool :: CommandBuffer.M.C -> QueryPool.Q -> Word32 -> Word32 -> IO ()
+resetQueryPool (CommandBuffer.M.C _ c) (QueryPool.Q q) fq qc =
+	C.resetQueryPool c q fq qc
+
+beginQuery :: CommandBuffer.M.C ->
+	QueryPool.Q -> Word32 -> Query.ControlFlags -> IO ()
+beginQuery (CommandBuffer.M.C _ c) (QueryPool.Q q) i (Query.ControlFlagBits flgs) =
+	C.beginQuery c q i flgs
+
+endQuery :: CommandBuffer.M.C -> QueryPool.Q -> Word32 -> IO ()
+endQuery (CommandBuffer.M.C _ c) (QueryPool.Q q) = C.endQuery c q
+
+writeTimestamp :: CommandBuffer.M.C -> Pipeline.StageFlagBits ->
+	QueryPool.Q -> Word32 -> IO ()
+writeTimestamp
+	(CommandBuffer.M.C _ c) (Pipeline.StageFlagBits fls) (QueryPool.Q q) i =
+	C.writeTimestamp c fls q i
diff --git a/src/Gpu/Vulkan/ColorComponent/Enum.hsc b/src/Gpu/Vulkan/ColorComponent/Enum.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/ColorComponent/Enum.hsc
@@ -0,0 +1,28 @@
+-- This file is automatically generated by the tools/makeEnum.hs
+--	% stack runghc --cwd tools/ makeEnum
+
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-missing-export-lists -fno-warn-tabs #-}
+
+module Gpu.Vulkan.ColorComponent.Enum where
+
+import Foreign.Storable
+import Foreign.C.Enum
+import Data.Bits
+import Data.Word
+
+#include <vulkan/vulkan.h>
+
+enum "FlagBits" ''#{type VkColorComponentFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("RBit", #{const VK_COLOR_COMPONENT_R_BIT}),
+	("GBit", #{const VK_COLOR_COMPONENT_G_BIT}),
+	("BBit", #{const VK_COLOR_COMPONENT_B_BIT}),
+	("ABit", #{const VK_COLOR_COMPONENT_A_BIT}),
+	("FlagBitsMaxEnum",
+		#{const VK_COLOR_COMPONENT_FLAG_BITS_MAX_ENUM}) ]
+
+type Flags = FlagBits
diff --git a/src/Gpu/Vulkan/CommandBuffer/Enum.hsc b/src/Gpu/Vulkan/CommandBuffer/Enum.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/CommandBuffer/Enum.hsc
@@ -0,0 +1,56 @@
+-- This file is automatically generated by the tools/makeEnum.hs
+--	% stack runghc --cwd tools/ makeEnum
+
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-missing-export-lists -fno-warn-tabs #-}
+
+module Gpu.Vulkan.CommandBuffer.Enum where
+
+import Foreign.Storable
+import Foreign.C.Enum
+import Data.Default
+import Data.Bits
+import Data.Word
+import Data.Default
+
+#include <vulkan/vulkan.h>
+
+enum "Level" ''#{type VkCommandBufferLevel}
+		[''Show, ''Eq, ''Storable] [
+	("LevelPrimary", #{const VK_COMMAND_BUFFER_LEVEL_PRIMARY}),
+	("LevelSecondary",
+		#{const VK_COMMAND_BUFFER_LEVEL_SECONDARY}),
+	("LevelMaxEnum",
+		#{const VK_COMMAND_BUFFER_LEVEL_MAX_ENUM}) ]
+
+enum "UsageFlagBits" ''#{type VkCommandBufferUsageFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("UsageFlagsZero", 0),
+	("UsageOneTimeSubmitBit",
+		#{const VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}),
+	("UsageRenderPassContinueBit",
+		#{const VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT}),
+	("UsageSimultaneousUseBit",
+		#{const VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT}),
+	("UsageFlagBitsMaxEnum",
+		#{const VK_COMMAND_BUFFER_USAGE_FLAG_BITS_MAX_ENUM}) ]
+
+instance Default UsageFlagBits where
+	def = UsageFlagsZero
+
+enum "ResetFlagBits" ''#{type VkCommandBufferResetFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("ResetFlagsZero", 0),
+	("ResetReleaseResourcesBit",
+		#{const VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT}),
+	("ResetFlagBitsMaxEnum",
+		#{const VK_COMMAND_BUFFER_RESET_FLAG_BITS_MAX_ENUM}) ]
+
+instance Default ResetFlagBits where
+	def = ResetFlagsZero
+
+type UsageFlags = UsageFlagBits
+type ResetFlags = ResetFlagBits
diff --git a/src/Gpu/Vulkan/CommandBuffer/Middle.hs b/src/Gpu/Vulkan/CommandBuffer/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/CommandBuffer/Middle.hs
@@ -0,0 +1,15 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.CommandBuffer.Middle (
+
+	-- * ALLOCATE AND FREE
+
+	allocateCs, freeCs, C, AllocateInfo(..),
+
+	-- * BEGIN, END AND RESET
+
+	begin, end, reset, BeginInfo(..), InheritanceInfo(..),
+
+	) where
+
+import Gpu.Vulkan.CommandBuffer.Middle.Internal
diff --git a/src/Gpu/Vulkan/CommandBuffer/Middle/Internal.hs b/src/Gpu/Vulkan/CommandBuffer/Middle/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/CommandBuffer/Middle/Internal.hs
@@ -0,0 +1,153 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUaGE ScopedTypeVariables, RankNTypes, TypeApplications #-}
+{-# LANGUAGE MonoLocalBinds #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE FlexibleContexts, FlexibleInstances, UndecidableInstances #-}
+{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.CommandBuffer.Middle.Internal (
+	C(..),
+	AllocateInfo(..), allocateCs, freeCs,
+
+	BeginInfo(..), InheritanceInfo(..), begin, end, reset
+	) where
+
+import Foreign.Ptr
+import Foreign.Marshal.Array
+import Foreign.Storable.PeekPoke (
+	WithPoked, withPoked, withPoked', withPtrS, pattern NullPtr )
+import Control.Arrow
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Data.Default
+import Data.IORef
+import Data.Word
+
+import Gpu.Vulkan.Enum
+import Gpu.Vulkan.Exception.Middle.Internal
+import Gpu.Vulkan.Exception.Enum
+import Gpu.Vulkan.CommandBuffer.Enum
+import Gpu.Vulkan.Base.Middle.Internal
+
+import qualified Gpu.Vulkan.Device.Middle.Types as Device
+import qualified Gpu.Vulkan.RenderPass.Middle.Internal as RenderPass
+import qualified Gpu.Vulkan.Framebuffer.Middle.Internal as Framebuffer
+import qualified Gpu.Vulkan.CommandPool.Middle.Internal as CommandPool
+import qualified Gpu.Vulkan.CommandBuffer.Core as C
+import qualified Gpu.Vulkan.Pipeline.Core as Pipeline.C
+
+data AllocateInfo mn = AllocateInfo {
+	allocateInfoNext :: TMaybe.M mn,
+	allocateInfoCommandPool :: CommandPool.C,
+	allocateInfoLevel :: Level,
+	allocateInfoCommandBufferCount :: Word32 }
+
+deriving instance Show (TMaybe.M mn) => Show (AllocateInfo mn)
+
+allocateInfoToCore :: WithPoked (TMaybe.M mn) =>
+	AllocateInfo mn -> (Ptr C.AllocateInfo -> IO a) -> IO ()
+allocateInfoToCore AllocateInfo {
+	allocateInfoNext = mnxt,
+	allocateInfoCommandPool = CommandPool.C cp,
+	allocateInfoLevel = Level lvl,
+	allocateInfoCommandBufferCount = cbc
+	} f = withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+	withPoked C.AllocateInfo {
+			C.allocateInfoSType = (),
+			C.allocateInfoPNext = pnxt',
+			C.allocateInfoCommandPool = cp,
+			C.allocateInfoLevel = lvl,
+			C.allocateInfoCommandBufferCount = cbc } f
+
+data C = C {
+	cPipeline :: IORef Pipeline.C.P,
+	unC :: C.C }
+
+newC :: C.C -> IO C
+newC c = C <$> newIORef nullPtr <*> pure c
+
+allocateCs :: WithPoked (TMaybe.M mn) => Device.D -> AllocateInfo mn -> IO [C]
+allocateCs (Device.D dvc) ai =  mapM newC =<<
+	allocaArray cbc \pc -> do
+	allocateInfoToCore ai \pai -> do
+		r <- C.allocateCs dvc pai pc
+		throwUnlessSuccess $ Result r
+	peekArray cbc pc
+	where cbc = fromIntegral $ allocateInfoCommandBufferCount ai
+
+data BeginInfo mn ii = BeginInfo {
+	beginInfoNext :: TMaybe.M mn,
+	beginInfoFlags :: UsageFlags,
+	beginInfoInheritanceInfo :: Maybe (InheritanceInfo ii) }
+
+instance Default (BeginInfo 'Nothing ii) where
+	def = BeginInfo {
+		beginInfoNext = TMaybe.N,
+		beginInfoFlags = UsageFlagsZero,
+		beginInfoInheritanceInfo = Nothing }
+
+beginInfoToCore :: (WithPoked (TMaybe.M mn), WithPoked (TMaybe.M ii)) =>
+	BeginInfo mn ii -> (Ptr C.BeginInfo -> IO a) -> IO ()
+beginInfoToCore BeginInfo {
+	beginInfoNext = mnxt,
+	beginInfoFlags = UsageFlagBits flgs,
+	beginInfoInheritanceInfo = mii } f =
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+	maybe ($ NullPtr) inheritanceInfoToCore mii \pii ->
+	() <$ withPoked C.BeginInfo {
+			C.beginInfoSType = (),
+			C.beginInfoPNext = pnxt',
+			C.beginInfoFlags = flgs,
+			C.beginInfoPInheritanceInfo = pii } f
+
+data InheritanceInfo mn = InheritanceInfo {
+	inheritanceInfoNext :: TMaybe.M mn,
+	inheritanceInfoRenderPass :: RenderPass.R,
+	inheritanceInfoSubpass :: Word32,
+	inheritanceInfoFramebuffer :: Framebuffer.F,
+	inheritanceInfoOcclusionQueryEnable :: Bool,
+	inheritanceInfoQueryFlags :: QueryControlFlags,
+	inheritanceInfoPipelineStatistics :: QueryPipelineStatisticFlags }
+
+inheritanceInfoToCore :: WithPoked (TMaybe.M mn) =>
+	InheritanceInfo mn -> (Ptr C.InheritanceInfo -> IO a) -> IO ()
+inheritanceInfoToCore InheritanceInfo {
+	inheritanceInfoNext = mnxt,
+	inheritanceInfoRenderPass = RenderPass.R rp,
+	inheritanceInfoSubpass = sp,
+	inheritanceInfoFramebuffer = fb,
+	inheritanceInfoOcclusionQueryEnable = oqe,
+	inheritanceInfoQueryFlags = QueryControlFlagBits qf,
+	inheritanceInfoPipelineStatistics = QueryPipelineStatisticFlagBits ps
+	} f = withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+	Framebuffer.fToCore fb >>= \fb' ->
+	withPoked C.InheritanceInfo {
+			C.inheritanceInfoSType = (),
+			C.inheritanceInfoPNext = pnxt',
+			C.inheritanceInfoRenderPass = rp,
+			C.inheritanceInfoSubpass = sp,
+			C.inheritanceInfoFramebuffer = fb',
+			C.inheritanceInfoOcclusionQueryEnable = boolToBool32 oqe,
+			C.inheritanceInfoQueryFlags = qf,
+			C.inheritanceInfoPipelineStatistics = ps } f
+
+begin :: (WithPoked (TMaybe.M mn), WithPoked (TMaybe.M ii)) => C -> BeginInfo mn ii -> IO ()
+begin (C _ c) bi =
+	beginInfoToCore bi \pbi -> throwUnlessSuccess . Result =<< C.begin c pbi
+
+end :: C -> IO ()
+end (C rppl c) = throwUnlessSuccess . Result =<< do
+	writeIORef rppl nullPtr
+	C.end c
+
+reset :: C -> ResetFlags -> IO ()
+reset (C _ c) (ResetFlagBits fs) = throwUnlessSuccess . Result =<< C.reset c fs
+
+freeCs :: Device.D -> CommandPool.C -> [C] -> IO ()
+freeCs (Device.D dvc) (CommandPool.C cp)
+	(length &&& ((\(C _ cb) -> cb) <$>) -> (cc, cs)) = allocaArray cc \pcs -> do
+		pokeArray pcs cs
+		C.freeCs dvc cp (fromIntegral cc) pcs
diff --git a/src/Gpu/Vulkan/CommandBuffer/Middle/Internal.hs-boot b/src/Gpu/Vulkan/CommandBuffer/Middle/Internal.hs-boot
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/CommandBuffer/Middle/Internal.hs-boot
@@ -0,0 +1,16 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE KindSignatures #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.CommandBuffer.Middle.Internal (
+	C(..)
+	) where
+
+import Data.IORef
+
+import qualified Gpu.Vulkan.CommandBuffer.Core as C
+import qualified Gpu.Vulkan.Pipeline.Core as Pipeline.C
+
+data C = C {
+	cPipeline :: IORef Pipeline.C.P,
+	unC :: C.C }
diff --git a/src/Gpu/Vulkan/CommandPool/Enum.hsc b/src/Gpu/Vulkan/CommandPool/Enum.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/CommandPool/Enum.hsc
@@ -0,0 +1,39 @@
+-- This file is automatically generated by the tools/makeEnum.hs
+--	% stack runghc --cwd tools/ makeEnum
+
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-missing-export-lists -fno-warn-tabs #-}
+
+module Gpu.Vulkan.CommandPool.Enum where
+
+import Foreign.Storable
+import Foreign.C.Enum
+import Data.Bits
+import Data.Word
+
+#include <vulkan/vulkan.h>
+
+enum "CreateFlagBits" ''#{type VkCommandPoolCreateFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("CreateFlagsZero", 0),
+	("CreateTransientBit",
+		#{const VK_COMMAND_POOL_CREATE_TRANSIENT_BIT}),
+	("CreateResetCommandBufferBit",
+		#{const VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT}),
+	("CreateProtectedBit",
+		#{const VK_COMMAND_POOL_CREATE_PROTECTED_BIT}),
+	("CreateFlagBitsMaxEnum",
+		#{const VK_COMMAND_POOL_CREATE_FLAG_BITS_MAX_ENUM}) ]
+
+enum "ResetFlagBits" ''#{type VkCommandPoolResetFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("ResetReleaseResourcesBit",
+		#{const VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT}),
+	("ResetFlagBitsMaxEnum",
+		#{const VK_COMMAND_POOL_RESET_FLAG_BITS_MAX_ENUM}) ]
+
+type CreateFlags = CreateFlagBits
+type ResetFlags = ResetFlagBits
diff --git a/src/Gpu/Vulkan/CommandPool/Middle.hs b/src/Gpu/Vulkan/CommandPool/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/CommandPool/Middle.hs
@@ -0,0 +1,15 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.CommandPool.Middle (
+
+	-- * CREATE AND DESTROY
+
+	create, destroy, C, CreateInfo(..),
+
+	-- * RESET
+
+	reset
+
+	) where
+
+import Gpu.Vulkan.CommandPool.Middle.Internal
diff --git a/src/Gpu/Vulkan/CommandPool/Middle/Internal.hs b/src/Gpu/Vulkan/CommandPool/Middle/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/CommandPool/Middle/Internal.hs
@@ -0,0 +1,64 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE MonoLocalBinds #-}
+{-# LANGUAGE FlexibleContexts, UndecidableInstances #-}
+{-# LANGUAGE ViewPatterns #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.CommandPool.Middle.Internal (
+	C(..), CreateInfo(..), create, destroy, reset ) where
+
+import Foreign.Ptr
+import Foreign.Marshal.Alloc
+import Foreign.Storable
+import Foreign.Storable.PeekPoke (WithPoked, withPoked, withPoked', withPtrS)
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Data.TypeLevel.ParMaybe qualified as TPMaybe
+
+import Gpu.Vulkan.Exception.Middle.Internal
+import Gpu.Vulkan.Exception.Enum
+import Gpu.Vulkan.CommandPool.Enum
+
+import Gpu.Vulkan.AllocationCallbacks.Middle.Internal
+	qualified as AllocationCallbacks
+import qualified Gpu.Vulkan.Device.Middle.Types as Device
+import qualified Gpu.Vulkan.QueueFamily.EnumManual as QueueFamily
+import qualified Gpu.Vulkan.CommandPool.Core as C
+
+data CreateInfo mn = CreateInfo {
+	createInfoNext :: TMaybe.M mn,
+	createInfoFlags :: CreateFlags,
+	createInfoQueueFamilyIndex :: QueueFamily.Index }
+
+deriving instance Show (TMaybe.M mn) => Show (CreateInfo mn)
+
+createInfoToCore :: WithPoked (TMaybe.M mn) =>
+	CreateInfo mn -> (Ptr C.CreateInfo -> IO a) -> IO ()
+createInfoToCore CreateInfo {
+	createInfoNext = mnxt,
+	createInfoFlags = CreateFlagBits flgs,
+	createInfoQueueFamilyIndex = QueueFamily.Index qfi
+	} f =
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+	withPoked C.CreateInfo {
+			C.createInfoSType = (),
+			C.createInfoPNext = pnxt',
+			C.createInfoFlags = flgs,
+			C.createInfoQueueFamilyIndex = qfi } f
+
+newtype C = C C.C deriving Show
+
+create :: WithPoked (TMaybe.M mn) =>
+	Device.D -> CreateInfo mn -> TPMaybe.M AllocationCallbacks.A mc -> IO C
+create (Device.D dvc) ci mac = C <$> alloca \pc -> do
+	createInfoToCore ci \pci -> AllocationCallbacks.mToCore mac \pac ->
+		throwUnlessSuccess . Result =<< C.create dvc pci pac pc
+	peek pc
+
+destroy :: Device.D -> C -> TPMaybe.M AllocationCallbacks.A md -> IO ()
+destroy (Device.D dvc) (C c) mac =
+	AllocationCallbacks.mToCore mac $ C.destroy dvc c
+
+reset :: Device.D -> C -> ResetFlags -> IO ()
+reset (Device.D dv) (C c) (ResetFlagBits fs) = C.reset dv c fs
diff --git a/src/Gpu/Vulkan/Component/Enum.hsc b/src/Gpu/Vulkan/Component/Enum.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Component/Enum.hsc
@@ -0,0 +1,31 @@
+-- This file is automatically generated by the tools/makeEnum.hs
+--	% stack runghc --cwd tools/ makeEnum
+
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-missing-export-lists -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Component.Enum where
+
+import Foreign.Storable
+import Foreign.C.Enum
+import Data.Word
+import Data.Default
+
+#include <vulkan/vulkan.h>
+
+enum "Swizzle" ''#{type VkComponentSwizzle}
+		[''Show, ''Eq, ''Storable] [
+	("SwizzleIdentity", #{const VK_COMPONENT_SWIZZLE_IDENTITY}),
+	("SwizzleZero", #{const VK_COMPONENT_SWIZZLE_ZERO}),
+	("SwizzleOne", #{const VK_COMPONENT_SWIZZLE_ONE}),
+	("SwizzleR", #{const VK_COMPONENT_SWIZZLE_R}),
+	("SwizzleG", #{const VK_COMPONENT_SWIZZLE_G}),
+	("SwizzleB", #{const VK_COMPONENT_SWIZZLE_B}),
+	("SwizzleA", #{const VK_COMPONENT_SWIZZLE_A}),
+	("SwizzleMaxEnum", #{const VK_COMPONENT_SWIZZLE_MAX_ENUM}) ]
+
+instance Default Swizzle where
+	def = SwizzleIdentity
diff --git a/src/Gpu/Vulkan/Component/Middle.hs b/src/Gpu/Vulkan/Component/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Component/Middle.hs
@@ -0,0 +1,11 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Component.Middle (
+
+	-- * MAPPING
+
+	Mapping(..)
+
+	) where
+
+import Gpu.Vulkan.Component.Middle.Internal
diff --git a/src/Gpu/Vulkan/Component/Middle/Internal.hs b/src/Gpu/Vulkan/Component/Middle/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Component/Middle/Internal.hs
@@ -0,0 +1,23 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Component.Middle.Internal where
+
+import Data.Default
+import Gpu.Vulkan.Component.Enum
+
+import qualified Gpu.Vulkan.Component.Core as C
+
+data Mapping = Mapping {
+	mappingR :: Swizzle, mappingG :: Swizzle,
+	mappingB :: Swizzle, mappingA :: Swizzle }
+	deriving Show
+
+instance Default Mapping where
+	def = Mapping {
+		mappingR = def, mappingG = def, mappingB = def, mappingA = def }
+
+mappingToCore :: Mapping -> C.Mapping
+mappingToCore Mapping {
+	mappingR = Swizzle r, mappingG = Swizzle g,
+	mappingB = Swizzle b, mappingA = Swizzle a } = C.Mapping {
+		C.mappingR = r, C.mappingG = g, C.mappingB = b, C.mappingA = a }
diff --git a/src/Gpu/Vulkan/Data/Middle.hsc b/src/Gpu/Vulkan/Data/Middle.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Data/Middle.hsc
@@ -0,0 +1,12 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Data.Middle {-# DEPRECATED "use maxBound instesad of uint64Max" #-} where
+
+import Data.Word
+
+#include <vulkan/vulkan.h>
+
+{-# DEPRECATED uint64Max "use maxBound :: Word64" #-}
+
+uint64Max :: #{type uint64_t}
+uint64Max = #{const UINT64_MAX}
diff --git a/src/Gpu/Vulkan/Descriptor/Enum.hsc b/src/Gpu/Vulkan/Descriptor/Enum.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Descriptor/Enum.hsc
@@ -0,0 +1,80 @@
+-- This file is automatically generated by the tools/makeEnum.hs
+--	% stack runghc --cwd tools/ makeEnum
+
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-missing-export-lists -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Descriptor.Enum where
+
+import Foreign.Storable
+import Foreign.C.Enum
+import Data.Bits
+import Data.Word
+
+#include <vulkan/vulkan.h>
+
+enum "Type" ''#{type VkDescriptorType}
+		[''Show, ''Eq, ''Storable] [
+	("TypeSampler", #{const VK_DESCRIPTOR_TYPE_SAMPLER}),
+	("TypeCombinedImageSampler",
+		#{const VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER}),
+	("TypeSampledImage",
+		#{const VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE}),
+	("TypeStorageImage",
+		#{const VK_DESCRIPTOR_TYPE_STORAGE_IMAGE}),
+	("TypeUniformTexelBuffer",
+		#{const VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER}),
+	("TypeStorageTexelBuffer",
+		#{const VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER}),
+	("TypeUniformBuffer",
+		#{const VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER}),
+	("TypeStorageBuffer",
+		#{const VK_DESCRIPTOR_TYPE_STORAGE_BUFFER}),
+	("TypeUniformBufferDynamic",
+		#{const VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC}),
+	("TypeStorageBufferDynamic",
+		#{const VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC}),
+	("TypeInputAttachment",
+		#{const VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT}),
+	("TypeInlineUniformBlock",
+		#{const VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK}),
+	("TypeAccelerationStructureKhr",
+		#{const VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR}),
+	("TypeAccelerationStructureNv",
+		#{const VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV}),
+	("TypeSampleWeightImageQcom",
+		#{const VK_DESCRIPTOR_TYPE_SAMPLE_WEIGHT_IMAGE_QCOM}),
+	("TypeBlockMatchImageQcom",
+		#{const VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM}),
+	("TypeMutableExt", #{const VK_DESCRIPTOR_TYPE_MUTABLE_EXT}),
+	("TypeInlineUniformBlockExt",
+		#{const VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT}),
+	("TypeMutableValve",
+		#{const VK_DESCRIPTOR_TYPE_MUTABLE_VALVE}),
+	("TypeMaxEnum", #{const VK_DESCRIPTOR_TYPE_MAX_ENUM}) ]
+
+enum "BindingFlagBits" ''#{type VkDescriptorBindingFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("BindingUpdateAfterBindBit",
+		#{const VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT}),
+	("BindingUpdateUnusedWhilePendingBit",
+		#{const VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT}),
+	("BindingPartiallyBoundBit",
+		#{const VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT}),
+	("BindingVariableDescriptorCountBit",
+		#{const VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT}),
+	("BindingUpdateAfterBindBitExt",
+		#{const VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT}),
+	("BindingUpdateUnusedWhilePendingBitExt",
+		#{const VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT}),
+	("BindingPartiallyBoundBitExt",
+		#{const VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT}),
+	("BindingVariableDescriptorCountBitExt",
+		#{const VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT}),
+	("BindingFlagBitsMaxEnum",
+		#{const VK_DESCRIPTOR_BINDING_FLAG_BITS_MAX_ENUM}) ]
+
+type BindingFlags = BindingFlagBits
diff --git a/src/Gpu/Vulkan/Descriptor/Middle.hs b/src/Gpu/Vulkan/Descriptor/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Descriptor/Middle.hs
@@ -0,0 +1,19 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Descriptor.Middle (
+
+	-- * EXTENSION NAME
+
+	indexingExtensionName,
+
+	-- * BUFFER INFO
+
+	BufferInfo(..),
+
+	-- * IMAGE INFO
+
+	ImageInfo(..)
+
+	) where
+
+import Gpu.Vulkan.Descriptor.Middle.Internal
diff --git a/src/Gpu/Vulkan/Descriptor/Middle/Internal.hsc b/src/Gpu/Vulkan/Descriptor/Middle/Internal.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Descriptor/Middle/Internal.hsc
@@ -0,0 +1,58 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ScopedTypeVariables, TypeApplications #-}
+{-# LANGUAGE MonoLocalBinds #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Descriptor.Middle.Internal (
+	indexingExtensionName,
+	ImageInfo(..), imageInfoToCore, BufferInfo(..), bufferInfoToCore ) where
+
+import Control.Monad.Trans
+
+import qualified Gpu.Vulkan.Device.Middle.Internal as Device
+import qualified Gpu.Vulkan.Buffer.Middle.Internal as Buffer
+import qualified Gpu.Vulkan.Image.Enum as Image
+import qualified Gpu.Vulkan.ImageView.Middle.Internal as ImageView
+import qualified Gpu.Vulkan.Sampler.Middle.Internal as Sampler
+import qualified Gpu.Vulkan.Descriptor.Core as C
+
+import Data.Text qualified as T
+
+#include <vulkan/vulkan.h>
+
+indexingExtensionName :: T.Text
+indexingExtensionName = #{const_str VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME}
+
+data BufferInfo = BufferInfo {
+	bufferInfoBuffer :: Buffer.B,
+	bufferInfoOffset :: Device.Size,
+	bufferInfoRange :: Device.Size }
+	deriving Show
+
+bufferInfoToCore :: BufferInfo -> C.BufferInfo
+bufferInfoToCore BufferInfo {
+	bufferInfoBuffer = Buffer.B b,
+	bufferInfoOffset = Device.Size os,
+	bufferInfoRange = Device.Size rg } = C.BufferInfo {
+	C.bufferInfoBuffer = b,
+	C.bufferInfoOffset = os,
+	C.bufferInfoRange = rg }
+
+data ImageInfo = ImageInfo {
+	imageInfoSampler :: Sampler.S,
+	imageInfoImageView :: ImageView.I,
+	imageInfoImageLayout :: Image.Layout }
+	deriving Show
+
+imageInfoToCore :: ImageInfo -> IO C.ImageInfo
+imageInfoToCore ImageInfo {
+	imageInfoSampler = Sampler.S s,
+	imageInfoImageView = iv,
+	imageInfoImageLayout = Image.Layout l } = do
+	iv' <- ImageView.iToCore iv
+	pure C.ImageInfo {
+		C.imageInfoSampler = s,
+		C.imageInfoImageView = iv',
+		C.imageInfoImageLayout = l }
diff --git a/src/Gpu/Vulkan/DescriptorPool/Enum.hsc b/src/Gpu/Vulkan/DescriptorPool/Enum.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/DescriptorPool/Enum.hsc
@@ -0,0 +1,35 @@
+-- This file is automatically generated by the tools/makeEnum.hs
+--	% stack runghc --cwd tools/ makeEnum
+
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-missing-export-lists -fno-warn-tabs #-}
+
+module Gpu.Vulkan.DescriptorPool.Enum where
+
+import Foreign.Storable
+import Foreign.C.Enum
+import Data.Bits
+import Data.Word
+
+#include <vulkan/vulkan.h>
+
+enum "CreateFlagBits" ''#{type VkDescriptorPoolCreateFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("CreateFlagsZero", 0),
+	("CreateFreeDescriptorSetBit",
+		#{const VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT}),
+	("CreateUpdateAfterBindBit",
+		#{const VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT}),
+	("CreateHostOnlyBitExt",
+		#{const VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_EXT}),
+	("CreateUpdateAfterBindBitExt",
+		#{const VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT}),
+	("CreateHostOnlyBitValve",
+		#{const VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_VALVE}),
+	("CreateFlagBitsMaxEnum",
+		#{const VK_DESCRIPTOR_POOL_CREATE_FLAG_BITS_MAX_ENUM}) ]
+
+type CreateFlags = CreateFlagBits
diff --git a/src/Gpu/Vulkan/DescriptorPool/Middle.hs b/src/Gpu/Vulkan/DescriptorPool/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/DescriptorPool/Middle.hs
@@ -0,0 +1,11 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.DescriptorPool.Middle (
+
+	-- * CREATE AND DESTROY
+
+	create, destroy, D, CreateInfo(..), Size(..)
+
+	) where
+
+import Gpu.Vulkan.DescriptorPool.Middle.Internal
diff --git a/src/Gpu/Vulkan/DescriptorPool/Middle/Internal.hs b/src/Gpu/Vulkan/DescriptorPool/Middle/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/DescriptorPool/Middle/Internal.hs
@@ -0,0 +1,78 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE MonoLocalBinds #-}
+{-# LANGUAGE FlexibleContexts, UndecidableInstances #-}
+{-# LANGUAGE ViewPatterns #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.DescriptorPool.Middle.Internal (
+	D(..), CreateInfo(..), Size(..), create, destroy ) where
+
+import Foreign.Ptr
+import Foreign.Marshal.Alloc
+import Foreign.Marshal.Array
+import Foreign.Storable
+import Foreign.Storable.PeekPoke (WithPoked, withPoked, withPoked', withPtrS)
+import Control.Arrow
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Data.TypeLevel.ParMaybe qualified as TPMaybe
+import Data.Word
+
+import Gpu.Vulkan.Exception.Middle.Internal
+import Gpu.Vulkan.Exception.Enum
+import Gpu.Vulkan.Descriptor.Enum
+import Gpu.Vulkan.DescriptorPool.Enum
+
+import Gpu.Vulkan.AllocationCallbacks.Middle.Internal
+	qualified as AllocationCallbacks
+import qualified Gpu.Vulkan.Device.Middle.Internal as Device
+import qualified Gpu.Vulkan.DescriptorPool.Core as C
+
+data Size = Size { sizeType :: Type, sizeDescriptorCount :: Word32 }
+	deriving Show
+
+sizeToCore :: Size -> C.Size
+sizeToCore Size { sizeType = Type tp, sizeDescriptorCount = dc } =
+	C.Size { C.sizeType = tp, C.sizeDescriptorCount = dc }
+
+data CreateInfo mn = CreateInfo {
+	createInfoNext :: TMaybe.M mn,
+	createInfoFlags :: CreateFlags,
+	createInfoMaxSets :: Word32,
+	createInfoPoolSizes :: [Size] }
+
+deriving instance Show (TMaybe.M mn) => Show (CreateInfo mn)
+
+createInfoToCore :: WithPoked (TMaybe.M mn) =>
+	CreateInfo mn -> (Ptr C.CreateInfo -> IO a) -> IO ()
+createInfoToCore CreateInfo {
+	createInfoNext = mnxt,
+	createInfoFlags = CreateFlagBits flgs,
+	createInfoMaxSets = ms,
+	createInfoPoolSizes = (length &&& (sizeToCore <$>) -> (psc, pss))
+	} f =
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+	allocaArray psc \ppss ->
+	pokeArray ppss pss >>
+	withPoked C.CreateInfo {
+			C.createInfoSType = (),
+			C.createInfoPNext = pnxt',
+			C.createInfoFlags = flgs,
+			C.createInfoMaxSets = ms,
+			C.createInfoPoolSizeCount = fromIntegral psc,
+			C.createInfoPPoolSizes = ppss } f
+
+newtype D = D C.D deriving Show
+
+create :: WithPoked (TMaybe.M mn) =>
+	Device.D -> CreateInfo mn -> TPMaybe.M AllocationCallbacks.A mc -> IO D
+create (Device.D dvc) ci mac = D <$> alloca \pp -> do
+	createInfoToCore ci \pci ->
+		AllocationCallbacks.mToCore mac \pac ->
+		throwUnlessSuccess . Result =<< C.create dvc pci pac pp
+	peek pp
+
+destroy :: Device.D -> D -> TPMaybe.M AllocationCallbacks.A md -> IO ()
+destroy (Device.D dvc) (D p) mac =
+	AllocationCallbacks.mToCore mac $ C.destroy dvc p
diff --git a/src/Gpu/Vulkan/DescriptorSet/Middle.hs b/src/Gpu/Vulkan/DescriptorSet/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/DescriptorSet/Middle.hs
@@ -0,0 +1,16 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.DescriptorSet.Middle (
+
+	-- * ALLOCATE AND FREE
+
+	allocateDs, freeDs, D, AllocateInfo(..),
+
+	-- * UPDATE
+
+	updateDs,
+	WriteListToCore, Write(..), WriteSources(..), CopyListToCore, Copy(..)
+
+	) where
+
+import Gpu.Vulkan.DescriptorSet.Middle.Internal
diff --git a/src/Gpu/Vulkan/DescriptorSet/Middle/Internal.hs b/src/Gpu/Vulkan/DescriptorSet/Middle/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/DescriptorSet/Middle/Internal.hs
@@ -0,0 +1,220 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE BlockArguments, LambdaCase, TupleSections #-}
+{-# LANGUAGE MonoLocalBinds #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE FlexibleContexts, UndecidableInstances #-}
+{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.DescriptorSet.Middle.Internal (
+	D(..), AllocateInfo(..), allocateDs, freeDs,
+	Write(..), WriteSources(..), Copy(..),
+	updateDs, WriteListToCore, CopyListToCore ) where
+
+import Foreign.Ptr
+import Foreign.Marshal.Array
+import Foreign.Storable
+import Foreign.Storable.PeekPoke (
+	WithPoked, withPoked, withPoked', withPtrS, pattern NullPtr )
+import Control.Arrow
+import Control.Monad.Trans
+import Control.Monad.Cont
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Data.List (genericLength)
+import Data.HeteroParList (pattern (:**))
+import Data.HeteroParList qualified as HeteroParList
+import Data.Word
+
+import Gpu.Vulkan.Exception.Middle.Internal
+import Gpu.Vulkan.Exception.Enum
+
+import qualified Gpu.Vulkan.Device.Middle.Internal as Device
+import qualified Gpu.Vulkan.BufferView.Middle.Internal as BufferView
+import qualified Gpu.Vulkan.Descriptor.Enum as Descriptor
+import qualified Gpu.Vulkan.Descriptor.Middle.Internal as Descriptor
+import qualified Gpu.Vulkan.DescriptorPool.Middle.Internal as Pool
+import qualified Gpu.Vulkan.DescriptorSetLayout.Middle.Internal as Layout
+import qualified Gpu.Vulkan.DescriptorSet.Core as C
+
+import qualified Gpu.Vulkan.Descriptor.Core as Descriptor.C
+import qualified Gpu.Vulkan.BufferView.Core as BufferView.C
+
+data AllocateInfo mn = AllocateInfo {
+	allocateInfoNext :: TMaybe.M mn,
+	allocateInfoDescriptorPool :: Pool.D,
+	allocateInfoSetLayouts :: [Layout.D] }
+
+deriving instance Show (TMaybe.M mn) => Show (AllocateInfo mn)
+
+allocateInfoToCore :: WithPoked (TMaybe.M mn) =>
+	AllocateInfo mn -> (C.AllocateInfo -> IO a) -> IO ()
+allocateInfoToCore AllocateInfo {
+	allocateInfoNext = mnxt,
+	allocateInfoDescriptorPool = Pool.D pl,
+	allocateInfoSetLayouts =
+		(((id &&& fromIntegral) `first`) . (length &&& id)) ->
+		((dsci, dscw), sls) } f =
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') -> do
+	psls <- allocaArray dsci \p ->
+		p <$ (pokeArray p $ (\(Layout.D l) -> l) <$> sls)
+	f C.AllocateInfo {
+		C.allocateInfoSType = (),
+		C.allocateInfoPNext = pnxt',
+		C.allocateInfoDescriptorPool = pl,
+		C.allocateInfoDescriptorSetCount = dscw,
+		C.allocateInfoPSetLayouts = psls }
+
+newtype D = D C.D deriving Show
+
+allocateDs :: WithPoked (TMaybe.M mn) => Device.D -> AllocateInfo mn -> IO [D]
+allocateDs (Device.D dvc) ai = ((D <$>) <$>) . ($ pure) $ runContT do
+	let	dsc = length $ allocateInfoSetLayouts ai
+	pss <- ContT $ allocaArray dsc
+	lift $ allocateInfoToCore ai \fai ->
+		withPoked fai \pai -> do
+			r <- C.allocateDs dvc pai pss
+			throwUnlessSuccess $ Result r
+	lift $ peekArray dsc pss
+
+freeDs :: Device.D -> Pool.D -> [D] -> IO ()
+freeDs (Device.D dvc) (Pool.D pl) ds = allocaArray ln \pds -> do
+	pokeArray pds $ (\(D d) -> d) <$> ds
+	r <- C.freeDs dvc pl ln pds
+	throwUnlessSuccess $ Result r
+	where
+	ln :: Integral n => n
+	ln = genericLength ds
+
+data Copy mn = Copy {
+	copyNext :: TMaybe.M mn,
+	copySrcSet :: D,
+	copySrcBinding :: Word32,
+	copySrcArrayElement :: Word32,
+	copyDstSet :: D,
+	copyDstBinding :: Word32,
+	copyDstArrayElement :: Word32,
+	copyDescriptorCount :: Word32 }
+
+deriving instance Show (TMaybe.M mn) => Show (Copy mn)
+
+class CopyListToCore cs where
+	copyListToCore ::
+		HeteroParList.PL Copy cs -> ([C.Copy] -> IO a) -> IO ()
+
+instance CopyListToCore '[] where
+	copyListToCore HeteroParList.Nil f = () <$ f []
+
+instance (WithPoked (TMaybe.M c), CopyListToCore cs) =>
+	CopyListToCore (c ': cs) where
+	copyListToCore (c :** cs) f =
+		copyToCore c \cc -> copyListToCore cs \ccs -> f $ cc : ccs
+
+copyToCore :: WithPoked (TMaybe.M mn) => Copy mn -> (C.Copy -> IO a) -> IO ()
+copyToCore Copy {
+	copyNext = mnxt,
+	copySrcSet = D ss,
+	copySrcBinding = sb,
+	copySrcArrayElement = sae,
+	copyDstSet = D ds,
+	copyDstBinding = db,
+	copyDstArrayElement = dae,
+	copyDescriptorCount = dc } f =
+	withPoked' mnxt \pnxt ->
+	withPtrS pnxt \(castPtr -> pnxt') -> f C.Copy {
+		C.copySType = (),
+		C.copyPNext = pnxt',
+		C.copySrcSet = ss,
+		C.copySrcBinding = sb,
+		C.copySrcArrayElement = sae,
+		C.copyDstSet = ds,
+		C.copyDstBinding = db,
+		C.copyDstArrayElement = dae,
+		C.copyDescriptorCount = dc }
+
+data Write mn = Write {
+	writeNext :: TMaybe.M mn,
+	writeDstSet :: D,
+	writeDstBinding :: Word32,
+	writeDstArrayElement :: Word32,
+	writeDescriptorType :: Descriptor.Type,
+	writeSources :: WriteSources }
+
+deriving instance Show (TMaybe.M mn) => Show (Write mn)
+
+data WriteSources
+	= WriteSourcesInNext Word32
+	| WriteSourcesImageInfo [Descriptor.ImageInfo]
+	| WriteSourcesBufferInfo [Descriptor.BufferInfo]
+	| WriteSourcesBufferView [BufferView.B]
+	deriving Show
+
+class WriteListToCore ws where
+	writeListToCore ::
+		HeteroParList.PL Write ws -> ([C.Write] -> IO a) -> IO ()
+
+instance WriteListToCore '[] where
+	writeListToCore HeteroParList.Nil f = () <$ f []
+
+instance (WithPoked (TMaybe.M w), WriteListToCore ws) => WriteListToCore (w ': ws) where
+	writeListToCore (w :** ws) f =
+		writeToCore w \cw -> writeListToCore ws \cws -> f $ cw : cws
+
+writeToCore :: WithPoked (TMaybe.M mn) => Write mn -> (C.Write -> IO a) -> IO ()
+writeToCore Write {
+	writeNext = mnxt,
+	writeDstSet = D s,
+	writeDstBinding = bdg,
+	writeDstArrayElement = ae,
+	writeDescriptorType = Descriptor.Type tp,
+	writeSources = srcs } f =
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+	writeSourcesToCore srcs \(cnt, pii, pbi, ptbv) ->
+	f C.Write {
+		C.writeSType = (),
+		C.writePNext = pnxt',
+		C.writeDstSet = s,
+		C.writeDstBinding = bdg,
+		C.writeDstArrayElement = ae,
+		C.writeDescriptorCount = cnt,
+		C.writeDescriptorType = tp,
+		C.writePImageInfo = pii,
+		C.writePBufferInfo = pbi,
+		C.writePTexelBufferView = ptbv }
+
+writeSourcesToCore :: WriteSources -> ((
+	Word32, Ptr Descriptor.C.ImageInfo,
+	Ptr Descriptor.C.BufferInfo, Ptr BufferView.C.B ) -> IO a) -> IO a
+writeSourcesToCore ws f = case ws of
+	WriteSourcesInNext c -> f (c, NullPtr, NullPtr, NullPtr)
+	WriteSourcesImageInfo (length &&& id -> (ln, iis)) ->
+		allocaArray ln \piis ->
+		Descriptor.imageInfoToCore `mapM` iis >>= \iis' ->
+		pokeArray piis iis' >>
+		f (fromIntegral ln, piis, NullPtr, NullPtr)
+	WriteSourcesBufferInfo
+		(length &&& (Descriptor.bufferInfoToCore <$>) -> (ln, bis)) ->
+		allocaArray ln \pbis ->
+		pokeArray pbis bis >>
+		f (fromIntegral ln, NullPtr, pbis, NullPtr)
+	WriteSourcesBufferView
+		(length &&& ((\(BufferView.B b) -> b) <$>) -> (ln, bvs)) ->
+		allocaArray ln \pbvs ->
+		pokeArray pbvs bvs >>
+		f (fromIntegral ln, NullPtr, NullPtr, pbvs)
+
+updateDs :: (WriteListToCore ws, CopyListToCore cs) =>
+	Device.D ->
+	HeteroParList.PL Write ws -> HeteroParList.PL Copy cs ->
+	IO ()
+updateDs (Device.D dvc) ws cs =
+	writeListToCore ws \cws ->
+	allocaAndPokeArray cws \(fromIntegral -> wc, pws) ->
+	copyListToCore cs \ccs ->
+	allocaAndPokeArray ccs \(fromIntegral -> cc, pcs) ->
+	C.updateDs dvc wc pws cc pcs
+
+allocaAndPokeArray :: Storable a => [a] -> ((Int, Ptr a) -> IO b) -> IO b
+allocaAndPokeArray (length &&& id -> (xc, xs)) f
+	= allocaArray xc \p -> pokeArray p xs >> f (xc, p)
diff --git a/src/Gpu/Vulkan/DescriptorSetLayout/BindingFlags/Middle.hs b/src/Gpu/Vulkan/DescriptorSetLayout/BindingFlags/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/DescriptorSetLayout/BindingFlags/Middle.hs
@@ -0,0 +1,5 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.DescriptorSetLayout.BindingFlags.Middle (CreateInfo(..)) where
+
+import Gpu.Vulkan.DescriptorSetLayout.BindingFlags.Middle.Internal
diff --git a/src/Gpu/Vulkan/DescriptorSetLayout/BindingFlags/Middle/Internal.hs b/src/Gpu/Vulkan/DescriptorSetLayout/BindingFlags/Middle/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/DescriptorSetLayout/BindingFlags/Middle/Internal.hs
@@ -0,0 +1,46 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE FlexibleContexts, UndecidableInstances #-}
+{-# LANGUAGE ViewPatterns #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.DescriptorSetLayout.BindingFlags.Middle.Internal (
+	CreateInfo(..) ) where
+
+import Foreign.Ptr
+import Foreign.Marshal.Alloc
+import Foreign.Marshal.Array
+import Foreign.Storable
+import Foreign.Storable.PeekPoke
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Gpu.Vulkan.Descriptor.Enum qualified as Descriptor
+import Gpu.Vulkan.DescriptorSetLayout.BindingFlags.Core qualified as C
+
+data CreateInfo mn = CreateInfo {
+	createInfoNext :: TMaybe.M mn,
+	createInfoBindingFlagsList :: [Descriptor.BindingFlags] }
+
+createInfoToCore :: WithPoked (TMaybe.M mn) =>
+	CreateInfo mn -> (C.CreateInfo -> IO a) -> IO ()
+createInfoToCore CreateInfo {
+	createInfoNext = mnxt,
+	createInfoBindingFlagsList = bfsl } f =
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+	let	bfsc = length bfsl in
+	allocaArray bfsc \pbfs ->
+	pokeArray pbfs (Descriptor.unBindingFlagBits <$> bfsl) >>
+	f C.CreateInfo {
+		C.createInfoSType = (),
+		C.createInfoPNext = pnxt',
+		C.createInfoBindingCount = fromIntegral bfsc,
+		C.createInfoPBindingFlags = pbfs }
+
+instance Sizable (CreateInfo mn) where
+	sizeOf' = sizeOf @C.CreateInfo undefined
+	alignment' = alignment @C.CreateInfo undefined
+
+instance WithPoked (TMaybe.M mn) => WithPoked (CreateInfo mn) where
+	withPoked' ci f = alloca \pcci -> do
+		createInfoToCore ci \cci -> poke pcci cci
+		f . ptrS $ castPtr pcci
diff --git a/src/Gpu/Vulkan/DescriptorSetLayout/Enum.hsc b/src/Gpu/Vulkan/DescriptorSetLayout/Enum.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/DescriptorSetLayout/Enum.hsc
@@ -0,0 +1,43 @@
+-- This file is automatically generated by the tools/makeEnum.hs
+--	% stack runghc --cwd tools/ makeEnum
+
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-missing-export-lists -fno-warn-tabs #-}
+
+module Gpu.Vulkan.DescriptorSetLayout.Enum where
+
+import Foreign.Storable
+import Foreign.C.Enum
+import Data.Word
+import Data.Bits
+import Data.Default
+
+#include <vulkan/vulkan.h>
+
+enum "CreateFlagBits" ''#{type VkDescriptorSetLayoutCreateFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("CreateFlagsZero", 0),
+	("CreateUpdateAfterBindPoolBit",
+		#{const VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT}),
+	("CreatePushDescriptorBitKhr",
+		#{const VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR}),
+	("CreateDescriptorBufferBitExt",
+		#{const VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT}),
+	("CreateEmbeddedImmutableSamplersBitExt",
+		#{const VK_DESCRIPTOR_SET_LAYOUT_CREATE_EMBEDDED_IMMUTABLE_SAMPLERS_BIT_EXT}),
+	("CreateHostOnlyPoolBitExt",
+		#{const VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_EXT}),
+	("CreateUpdateAfterBindPoolBitExt",
+		#{const VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT}),
+	("CreateHostOnlyPoolBitValve",
+		#{const VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_VALVE}),
+	("CreateFlagBitsMaxEnum",
+		#{const VK_DESCRIPTOR_SET_LAYOUT_CREATE_FLAG_BITS_MAX_ENUM}) ]
+
+instance Default CreateFlagBits where
+	def = CreateFlagsZero
+
+type CreateFlags = CreateFlagBits
diff --git a/src/Gpu/Vulkan/DescriptorSetLayout/Middle.hs b/src/Gpu/Vulkan/DescriptorSetLayout/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/DescriptorSetLayout/Middle.hs
@@ -0,0 +1,11 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.DescriptorSetLayout.Middle (
+
+	-- * CREATE AND DESTROY
+
+	create, destroy, D, CreateInfo(..), Binding(..)
+
+	) where
+
+import Gpu.Vulkan.DescriptorSetLayout.Middle.Internal
diff --git a/src/Gpu/Vulkan/DescriptorSetLayout/Middle/Internal.hs b/src/Gpu/Vulkan/DescriptorSetLayout/Middle/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/DescriptorSetLayout/Middle/Internal.hs
@@ -0,0 +1,96 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE BlockArguments, TupleSections #-}
+{-# LANGUAGE MonoLocalBinds #-}
+{-# LANGUAGE FlexibleContexts, UndecidableInstances #-}
+{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.DescriptorSetLayout.Middle.Internal (
+	D(..), CreateInfo(..), Binding(..), create, destroy ) where
+
+import Foreign.Ptr
+import Foreign.Marshal.Alloc
+import Foreign.Marshal.Array
+import Foreign.Storable
+import Foreign.Storable.PeekPoke (
+	WithPoked, withPoked, withPoked', withPtrS, pattern NullPtr )
+import Control.Arrow
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Data.TypeLevel.ParMaybe qualified as TPMaybe
+import Data.Word
+
+import Gpu.Vulkan.Enum
+import Gpu.Vulkan.Exception.Middle.Internal
+import Gpu.Vulkan.Exception.Enum
+import Gpu.Vulkan.DescriptorSetLayout.Enum
+import Gpu.Vulkan.Misc.Middle.Internal
+
+import Gpu.Vulkan.AllocationCallbacks.Middle.Internal
+	qualified as AllocationCallbacks
+import qualified Gpu.Vulkan.Device.Middle.Internal as Device
+import qualified Gpu.Vulkan.Sampler.Middle.Internal as Sampler
+import qualified Gpu.Vulkan.Descriptor.Enum as Descriptor
+import qualified Gpu.Vulkan.DescriptorSetLayout.Core as C
+
+data Binding = Binding {
+	bindingBinding :: Word32,
+	bindingDescriptorType :: Descriptor.Type,
+	bindingDescriptorCountOrImmutableSamplers :: Either Word32 [Sampler.S],
+	bindingStageFlags :: ShaderStageFlags }
+	deriving Show
+
+bindingToCore :: Binding -> (C.Binding -> IO a) -> IO a
+bindingToCore Binding {
+	bindingBinding = b,
+	bindingDescriptorType = Descriptor.Type dt,
+	bindingDescriptorCountOrImmutableSamplers =
+		either ((, []) . Left) (Right . length &&& id) -> (dc, ss),
+	bindingStageFlags = ShaderStageFlagBits sf } f = case dc of
+		Left _ -> f $ mk NullPtr
+		Right c -> allocaArray c \p -> do
+			pokeArray p $ (\(Sampler.S s) -> s) <$> ss
+			f $ mk p
+	where mk p = C.Binding {
+		C.bindingBinding = b,
+		C.bindingDescriptorType = dt,
+		C.bindingDescriptorCount = either id fromIntegral dc,
+		C.bindingStageFlags = sf,
+		C.bindingPImmutableSamplers = p }
+
+newtype D = D C.D deriving Show
+
+data CreateInfo mn = CreateInfo {
+	createInfoNext :: TMaybe.M mn,
+	createInfoFlags :: CreateFlags,
+	createInfoBindings :: [Binding] }
+
+deriving instance Show (TMaybe.M mn) => Show (CreateInfo mn)
+
+createInfoToCore ::
+	WithPoked (TMaybe.M mn) => CreateInfo mn -> (Ptr C.CreateInfo -> IO a) -> IO ()
+createInfoToCore CreateInfo {
+	createInfoNext = mnxt,
+	createInfoFlags = CreateFlagBits flgs,
+	createInfoBindings = length &&& id -> (bc, bs) } f =
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+	allocaArray bc \pbs ->
+	(bindingToCore `mapContM` bs) \cbs -> do
+		pokeArray pbs cbs
+		withPoked C.CreateInfo {
+				C.createInfoSType = (),
+				C.createInfoPNext = pnxt',
+				C.createInfoFlags = flgs,
+				C.createInfoBindingCount = fromIntegral bc,
+				C.createInfoPBindings = pbs } f
+
+create :: WithPoked (TMaybe.M mn) =>
+	Device.D -> CreateInfo mn -> TPMaybe.M AllocationCallbacks.A mc -> IO D
+create (Device.D dvc) ci mac = D <$> alloca \pl -> do
+	createInfoToCore ci \pci -> AllocationCallbacks.mToCore mac \pac ->
+		throwUnlessSuccess . Result =<< C.create dvc pci pac pl
+	peek pl
+
+destroy :: Device.D -> D -> TPMaybe.M AllocationCallbacks.A md -> IO ()
+destroy (Device.D dvc) (D l) mac =
+	AllocationCallbacks.mToCore mac \pac -> C.destroy dvc l pac
diff --git a/src/Gpu/Vulkan/Device/Enum.hsc b/src/Gpu/Vulkan/Device/Enum.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Device/Enum.hsc
@@ -0,0 +1,31 @@
+-- This file is automatically generated by the tools/makeEnum.hs
+--	% stack runghc --cwd tools/ makeEnum
+
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-missing-export-lists -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Device.Enum where
+
+import Foreign.Storable
+import Foreign.C.Enum
+import Data.Bits
+import Data.Word
+import Data.Default
+
+#include <vulkan/vulkan.h>
+
+enum "QueueCreateFlagBits" ''#{type VkDeviceQueueCreateFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("QueueCreateFlagsZero", 0),
+	("QueueCreateProtectedBit",
+		#{const VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT}),
+	("QueueCreateFlagBitsMaxEnum",
+		#{const VK_DEVICE_QUEUE_CREATE_FLAG_BITS_MAX_ENUM}) ]
+
+instance Default QueueCreateFlagBits where
+	def = QueueCreateFlagsZero
+
+type QueueCreateFlags = QueueCreateFlagBits
diff --git a/src/Gpu/Vulkan/Device/Middle.hs b/src/Gpu/Vulkan/Device/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Device/Middle.hs
@@ -0,0 +1,21 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Device.Middle (
+
+	-- * CREATE AND DESTROY
+
+	create, destroy, D,
+	CreateInfo(..), CreateFlags, CreateFlagBits,
+	QueueCreateInfo(..),
+
+	-- * GET QUEUE AND WAIT IDLE
+
+	getQueue, waitIdle,
+
+	-- * SIZE
+
+	Size
+
+	) where
+
+import Gpu.Vulkan.Device.Middle.Internal
diff --git a/src/Gpu/Vulkan/Device/Middle/Internal.hsc b/src/Gpu/Vulkan/Device/Middle/Internal.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Device/Middle/Internal.hsc
@@ -0,0 +1,172 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE RankNTypes, TypeApplications #-}
+{-# LANGUAGE GADTs, TypeFamilies #-}
+{-# LANGUAGE DataKinds, PolyKinds #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE FlexibleContexts, UndecidableInstances #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving, StandaloneDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Device.Middle.Internal (
+
+	-- * CREATE AND DESTROY
+
+	create, destroy, D(..), CreateInfo(..), CreateFlags, CreateFlagBits,
+	QueueCreateInfo(..),
+
+	-- * GET QUEUE AND WAIT IDLE
+
+	getQueue, waitIdle,
+
+	-- * SIZE
+
+	Size(..)
+
+	) where
+
+import Foreign.Ptr
+import Foreign.Marshal
+import Foreign.Storable
+import Foreign.Storable.PeekPoke (
+	WithPoked, withPoked', withPtrS, pattern NullPtr )
+import Foreign.Storable.HeteroList
+import Foreign.C.Enum
+import Control.Arrow
+import Control.Monad.Cont
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Data.TypeLevel.ParMaybe qualified as TPMaybe
+import Data.Default
+import Data.Bits
+import Data.List (genericLength)
+import Data.HeteroParList qualified as HeteroParList
+import Data.Word
+import Data.Ix
+
+import Data.Text qualified as T
+import Data.Text.Foreign.MiscYj
+
+import Gpu.Vulkan.Exception.Middle.Internal
+import Gpu.Vulkan.Exception.Enum
+import Gpu.Vulkan.Device.Enum
+
+import Gpu.Vulkan.AllocationCallbacks.Middle.Internal
+	qualified as AllocationCallbacks
+import qualified Gpu.Vulkan.PhysicalDevice.Middle.Internal as PhysicalDevice
+import qualified Gpu.Vulkan.PhysicalDevice.Struct as PhysicalDevice
+import qualified Gpu.Vulkan.Device.Core as C
+import qualified Gpu.Vulkan.Queue.Middle.Internal as Queue
+
+import qualified Gpu.Vulkan.QueueFamily.EnumManual as QueueFamily
+
+import Gpu.Vulkan.Device.Middle.Types
+
+#include <vulkan/vulkan.h>
+
+enum "CreateFlagBits" ''#{type VkDeviceCreateFlags}
+	[''Eq, ''Show, ''Storable, ''Bits] [("CreateFlagsZero", 0)]
+
+type CreateFlags = CreateFlagBits
+
+instance Default CreateFlags where def = CreateFlagsZero
+
+data CreateInfo mn qcis = CreateInfo {
+	createInfoNext :: TMaybe.M mn,
+	createInfoFlags :: CreateFlags,
+	createInfoQueueCreateInfos :: HeteroParList.PL QueueCreateInfo qcis,
+	createInfoEnabledLayerNames :: [T.Text],
+	createInfoEnabledExtensionNames :: [T.Text],
+	createInfoEnabledFeatures :: Maybe PhysicalDevice.Features }
+
+deriving instance (Show (TMaybe.M mn), Show (HeteroParList.PL QueueCreateInfo qcis)) =>
+	Show (CreateInfo mn qcis)
+
+type family Map (f :: j -> k) xs where
+	Map _f '[] = '[]
+	Map f (x ': xs) = f x ': Map f xs
+
+createInfoToCore :: (
+	WithPoked (TMaybe.M mn), HeteroParList.ToListWithCM' WithPoked TMaybe.M qcis) =>
+	CreateInfo mn qcis -> (Ptr C.CreateInfo -> IO a) -> IO ()
+createInfoToCore CreateInfo {
+	createInfoNext = mnxt,
+	createInfoFlags = CreateFlagBits flgs,
+	createInfoQueueCreateInfos = qcis,
+	createInfoEnabledLayerNames = (id &&& length) -> (elns, elnc),
+	createInfoEnabledExtensionNames = (id &&& length) -> (eens, eenc),
+	createInfoEnabledFeatures = mef } f =
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+	alloca \pci ->
+		runContT (HeteroParList.toListWithCM' @_ @_ @WithPoked @TMaybe.M (ContT . queueCreateInfoToCore) qcis) \cqcis ->
+		let	qcic = length cqcis in
+		allocaArray qcic \pcqcis ->
+		pokeArray pcqcis cqcis >>
+		textListToCStringArray elns \pcelns ->
+		textListToCStringArray eens \pceens -> do
+		let mk pef = C.CreateInfo {
+			C.createInfoSType = (),
+			C.createInfoPNext = pnxt',
+			C.createInfoFlags = flgs,
+			C.createInfoQueueCreateInfoCount = fromIntegral qcic,
+			C.createInfoPQueueCreateInfos = pcqcis,
+			C.createInfoEnabledLayerCount = fromIntegral elnc,
+			C.createInfoPpEnabledLayerNames = pcelns,
+			C.createInfoEnabledExtensionCount = fromIntegral eenc,
+			C.createInfoPpEnabledExtensionNames = pceens,
+			C.createInfoPEnabledFeatures = pef }
+		case mef of
+			Nothing -> poke pci (mk NullPtr)
+			Just ef -> alloca \p -> do
+				poke p $ PhysicalDevice.featuresToCore ef
+				poke pci (mk p)
+		() <$ f pci
+
+create :: (WithPoked (TMaybe.M mn), HeteroParList.ToListWithCM' WithPoked TMaybe.M qcis) =>
+	PhysicalDevice.P -> CreateInfo mn qcis -> TPMaybe.M AllocationCallbacks.A mc ->
+	IO D
+create (PhysicalDevice.P phdvc) ci mac = D <$> alloca \pdvc -> do
+	createInfoToCore ci \pcci ->
+		AllocationCallbacks.mToCore mac \pac -> do
+			r <- C.create phdvc pcci pac pdvc
+			throwUnlessSuccess $ Result r
+	peek pdvc
+
+destroy :: D -> TPMaybe.M AllocationCallbacks.A md -> IO ()
+destroy (D cdvc) mac = AllocationCallbacks.mToCore mac $ C.destroy cdvc
+
+getQueue :: D -> Word32 -> Word32 -> IO Queue.Q
+getQueue (D cdvc) qfi qi = Queue.Q <$> alloca \pQueue -> do
+	C.getQueue cdvc qfi qi pQueue
+	peek pQueue
+
+waitIdle :: D -> IO ()
+waitIdle (D d) = throwUnlessSuccess . Result =<< C.waitIdle d
+
+data QueueCreateInfo mn = QueueCreateInfo {
+	queueCreateInfoNext :: TMaybe.M mn,
+	queueCreateInfoFlags :: QueueCreateFlags,
+	queueCreateInfoQueueFamilyIndex :: QueueFamily.Index,
+	queueCreateInfoQueuePriorities :: [Float] }
+
+deriving instance Show (TMaybe.M mn) => Show (QueueCreateInfo mn)
+
+queueCreateInfoToCore :: WithPoked (TMaybe.M mn) =>
+	QueueCreateInfo mn -> (C.QueueCreateInfo -> IO a) -> IO ()
+queueCreateInfoToCore QueueCreateInfo {
+	queueCreateInfoNext = mnxt,
+	queueCreateInfoFlags = QueueCreateFlagBits flgs,
+	queueCreateInfoQueueFamilyIndex = QueueFamily.Index qfi,
+	queueCreateInfoQueuePriorities = qps
+	} f = allocaArray (length qps) \pqps -> do
+	pokeArray pqps qps
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+		() <$ f C.QueueCreateInfo {
+			C.queueCreateInfoSType = (),
+			C.queueCreateInfoPNext = pnxt',
+			C.queueCreateInfoFlags = flgs,
+			C.queueCreateInfoQueueFamilyIndex = qfi,
+			C.queueCreateInfoQueueCount = genericLength qps,
+			C.queueCreateInfoPQueuePriorities = pqps }
diff --git a/src/Gpu/Vulkan/Device/Middle/Types.hsc b/src/Gpu/Vulkan/Device/Middle/Types.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Device/Middle/Types.hsc
@@ -0,0 +1,20 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Device.Middle.Types where
+
+import Foreign.C.Enum
+import Data.Word
+import Data.Ix
+import Gpu.Vulkan.Device.Core qualified as C
+
+#include <vulkan/vulkan.h>
+
+newtype D = D C.D deriving Show
+
+enum "Size" ''#{type VkDeviceSize}
+		[''Show, ''Eq, ''Ord, ''Enum, ''Num, ''Real, ''Integral, ''Ix]
+	[("WholeSize", #{const VK_WHOLE_SIZE})]
diff --git a/src/Gpu/Vulkan/Enum.hsc b/src/Gpu/Vulkan/Enum.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Enum.hsc
@@ -0,0 +1,3007 @@
+-- This file is automatically generated by the tools/makeEnum.hs
+--	% stack runghc --cwd tools/ makeEnum
+
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-missing-export-lists -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Enum where
+
+import Foreign.Storable
+import Foreign.C.Enum
+import Foreign.Ptr
+import Data.Bits
+import Data.Word
+
+#include <vulkan/vulkan.h>
+
+enum "StructureType" ''#{type VkStructureType}
+		[''Show, ''Eq, ''Storable] [
+	("StructureTypeApplicationInfo",
+		#{const VK_STRUCTURE_TYPE_APPLICATION_INFO}),
+	("StructureTypeInstanceCreateInfo",
+		#{const VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO}),
+	("StructureTypeDeviceQueueCreateInfo",
+		#{const VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO}),
+	("StructureTypeDeviceCreateInfo",
+		#{const VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO}),
+	("StructureTypeSubmitInfo", #{const VK_STRUCTURE_TYPE_SUBMIT_INFO}),
+	("StructureTypeMemoryAllocateInfo",
+		#{const VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO}),
+	("StructureTypeMappedMemoryRange",
+		#{const VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE}),
+	("StructureTypeBindSparseInfo",
+		#{const VK_STRUCTURE_TYPE_BIND_SPARSE_INFO}),
+	("StructureTypeFenceCreateInfo",
+		#{const VK_STRUCTURE_TYPE_FENCE_CREATE_INFO}),
+	("StructureTypeSemaphoreCreateInfo",
+		#{const VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO}),
+	("StructureTypeEventCreateInfo",
+		#{const VK_STRUCTURE_TYPE_EVENT_CREATE_INFO}),
+	("StructureTypeQueryPoolCreateInfo",
+		#{const VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO}),
+	("StructureTypeBufferCreateInfo",
+		#{const VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO}),
+	("StructureTypeBufferViewCreateInfo",
+		#{const VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO}),
+	("StructureTypeImageCreateInfo",
+		#{const VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO}),
+	("StructureTypeImageViewCreateInfo",
+		#{const VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO}),
+	("StructureTypeShaderModuleCreateInfo",
+		#{const VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO}),
+	("StructureTypePipelineCacheCreateInfo",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO}),
+	("StructureTypePipelineShaderStageCreateInfo",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO}),
+	("StructureTypePipelineVertexInputStateCreateInfo",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO}),
+	("StructureTypePipelineInputAssemblyStateCreateInfo",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO}),
+	("StructureTypePipelineTessellationStateCreateInfo",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO}),
+	("StructureTypePipelineViewportStateCreateInfo",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO}),
+	("StructureTypePipelineRasterizationStateCreateInfo",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO}),
+	("StructureTypePipelineMultisampleStateCreateInfo",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO}),
+	("StructureTypePipelineDepthStencilStateCreateInfo",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO}),
+	("StructureTypePipelineColorBlendStateCreateInfo",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO}),
+	("StructureTypePipelineDynamicStateCreateInfo",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO}),
+	("StructureTypeGraphicsPipelineCreateInfo",
+		#{const VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO}),
+	("StructureTypeComputePipelineCreateInfo",
+		#{const VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO}),
+	("StructureTypePipelineLayoutCreateInfo",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO}),
+	("StructureTypeSamplerCreateInfo",
+		#{const VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO}),
+	("StructureTypeDescriptorSetLayoutCreateInfo",
+		#{const VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO}),
+	("StructureTypeDescriptorPoolCreateInfo",
+		#{const VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO}),
+	("StructureTypeDescriptorSetAllocateInfo",
+		#{const VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO}),
+	("StructureTypeWriteDescriptorSet",
+		#{const VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET}),
+	("StructureTypeCopyDescriptorSet",
+		#{const VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET}),
+	("StructureTypeFramebufferCreateInfo",
+		#{const VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO}),
+	("StructureTypeRenderPassCreateInfo",
+		#{const VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO}),
+	("StructureTypeCommandPoolCreateInfo",
+		#{const VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO}),
+	("StructureTypeCommandBufferAllocateInfo",
+		#{const VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO}),
+	("StructureTypeCommandBufferInheritanceInfo",
+		#{const VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO}),
+	("StructureTypeCommandBufferBeginInfo",
+		#{const VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO}),
+	("StructureTypeRenderPassBeginInfo",
+		#{const VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO}),
+	("StructureTypeBufferMemoryBarrier",
+		#{const VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER}),
+	("StructureTypeImageMemoryBarrier",
+		#{const VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER}),
+	("StructureTypeMemoryBarrier",
+		#{const VK_STRUCTURE_TYPE_MEMORY_BARRIER}),
+	("StructureTypeLoaderInstanceCreateInfo",
+		#{const VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO}),
+	("StructureTypeLoaderDeviceCreateInfo",
+		#{const VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO}),
+	("StructureTypePhysicalDeviceSubgroupProperties",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES}),
+	("StructureTypeBindBufferMemoryInfo",
+		#{const VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO}),
+	("StructureTypeBindImageMemoryInfo",
+		#{const VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO}),
+	("StructureTypePhysicalDevice16bitStorageFeatures",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES}),
+	("StructureTypeMemoryDedicatedRequirements",
+		#{const VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS}),
+	("StructureTypeMemoryDedicatedAllocateInfo",
+		#{const VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO}),
+	("StructureTypeMemoryAllocateFlagsInfo",
+		#{const VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO}),
+	("StructureTypeDeviceGroupRenderPassBeginInfo",
+		#{const VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO}),
+	("StructureTypeDeviceGroupCommandBufferBeginInfo",
+		#{const VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO}),
+	("StructureTypeDeviceGroupSubmitInfo",
+		#{const VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO}),
+	("StructureTypeDeviceGroupBindSparseInfo",
+		#{const VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO}),
+	("StructureTypeBindBufferMemoryDeviceGroupInfo",
+		#{const VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO}),
+	("StructureTypeBindImageMemoryDeviceGroupInfo",
+		#{const VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO}),
+	("StructureTypePhysicalDeviceGroupProperties",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES}),
+	("StructureTypeDeviceGroupDeviceCreateInfo",
+		#{const VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO}),
+	("StructureTypeBufferMemoryRequirementsInfo2",
+		#{const VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2}),
+	("StructureTypeImageMemoryRequirementsInfo2",
+		#{const VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2}),
+	("StructureTypeImageSparseMemoryRequirementsInfo2",
+		#{const VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2}),
+	("StructureTypeMemoryRequirements2",
+		#{const VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2}),
+	("StructureTypeSparseImageMemoryRequirements2",
+		#{const VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2}),
+	("StructureTypePhysicalDeviceFeatures2",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2}),
+	("StructureTypePhysicalDeviceProperties2",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2}),
+	("StructureTypeFormatProperties2",
+		#{const VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2}),
+	("StructureTypeImageFormatProperties2",
+		#{const VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2}),
+	("StructureTypePhysicalDeviceImageFormatInfo2",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2}),
+	("StructureTypeQueueFamilyProperties2",
+		#{const VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2}),
+	("StructureTypePhysicalDeviceMemoryProperties2",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2}),
+	("StructureTypeSparseImageFormatProperties2",
+		#{const VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2}),
+	("StructureTypePhysicalDeviceSparseImageFormatInfo2",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2}),
+	("StructureTypePhysicalDevicePointClippingProperties",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES}),
+	("StructureTypeRenderPassInputAttachmentAspectCreateInfo",
+		#{const VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO}),
+	("StructureTypeImageViewUsageCreateInfo",
+		#{const VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO}),
+	("StructureTypePipelineTessellationDomainOriginStateCreateInfo",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO}),
+	("StructureTypeRenderPassMultiviewCreateInfo",
+		#{const VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO}),
+	("StructureTypePhysicalDeviceMultiviewFeatures",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES}),
+	("StructureTypePhysicalDeviceMultiviewProperties",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES}),
+	("StructureTypePhysicalDeviceVariablePointersFeatures",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES}),
+	("StructureTypeProtectedSubmitInfo",
+		#{const VK_STRUCTURE_TYPE_PROTECTED_SUBMIT_INFO}),
+	("StructureTypePhysicalDeviceProtectedMemoryFeatures",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES}),
+	("StructureTypePhysicalDeviceProtectedMemoryProperties",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES}),
+	("StructureTypeDeviceQueueInfo2",
+		#{const VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2}),
+	("StructureTypeSamplerYcbcrConversionCreateInfo",
+		#{const VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO}),
+	("StructureTypeSamplerYcbcrConversionInfo",
+		#{const VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO}),
+	("StructureTypeBindImagePlaneMemoryInfo",
+		#{const VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO}),
+	("StructureTypeImagePlaneMemoryRequirementsInfo",
+		#{const VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO}),
+	("StructureTypePhysicalDeviceSamplerYcbcrConversionFeatures",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES}),
+	("StructureTypeSamplerYcbcrConversionImageFormatProperties",
+		#{const VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES}),
+	("StructureTypeDescriptorUpdateTemplateCreateInfo",
+		#{const VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO}),
+	("StructureTypePhysicalDeviceExternalImageFormatInfo",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO}),
+	("StructureTypeExternalImageFormatProperties",
+		#{const VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES}),
+	("StructureTypePhysicalDeviceExternalBufferInfo",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO}),
+	("StructureTypeExternalBufferProperties",
+		#{const VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES}),
+	("StructureTypePhysicalDeviceIdProperties",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES}),
+	("StructureTypeExternalMemoryBufferCreateInfo",
+		#{const VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO}),
+	("StructureTypeExternalMemoryImageCreateInfo",
+		#{const VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO}),
+	("StructureTypeExportMemoryAllocateInfo",
+		#{const VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO}),
+	("StructureTypePhysicalDeviceExternalFenceInfo",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO}),
+	("StructureTypeExternalFenceProperties",
+		#{const VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES}),
+	("StructureTypeExportFenceCreateInfo",
+		#{const VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO}),
+	("StructureTypeExportSemaphoreCreateInfo",
+		#{const VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO}),
+	("StructureTypePhysicalDeviceExternalSemaphoreInfo",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO}),
+	("StructureTypeExternalSemaphoreProperties",
+		#{const VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES}),
+	("StructureTypePhysicalDeviceMaintenance3Properties",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES}),
+	("StructureTypeDescriptorSetLayoutSupport",
+		#{const VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT}),
+	("StructureTypePhysicalDeviceShaderDrawParametersFeatures",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES}),
+	("StructureTypePhysicalDeviceVulkan11Features",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES}),
+	("StructureTypePhysicalDeviceVulkan11Properties",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES}),
+	("StructureTypePhysicalDeviceVulkan12Features",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES}),
+	("StructureTypePhysicalDeviceVulkan12Properties",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES}),
+	("StructureTypeImageFormatListCreateInfo",
+		#{const VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO}),
+	("StructureTypeAttachmentDescription2",
+		#{const VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2}),
+	("StructureTypeAttachmentReference2",
+		#{const VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2}),
+	("StructureTypeSubpassDescription2",
+		#{const VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2}),
+	("StructureTypeSubpassDependency2",
+		#{const VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2}),
+	("StructureTypeRenderPassCreateInfo2",
+		#{const VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2}),
+	("StructureTypeSubpassBeginInfo",
+		#{const VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO}),
+	("StructureTypeSubpassEndInfo",
+		#{const VK_STRUCTURE_TYPE_SUBPASS_END_INFO}),
+	("StructureTypePhysicalDevice8bitStorageFeatures",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES}),
+	("StructureTypePhysicalDeviceDriverProperties",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES}),
+	("StructureTypePhysicalDeviceShaderAtomicInt64Features",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES}),
+	("StructureTypePhysicalDeviceShaderFloat16Int8Features",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES}),
+	("StructureTypePhysicalDeviceFloatControlsProperties",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES}),
+	("StructureTypeDescriptorSetLayoutBindingFlagsCreateInfo",
+		#{const VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO}),
+	("StructureTypePhysicalDeviceDescriptorIndexingFeatures",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES}),
+	("StructureTypePhysicalDeviceDescriptorIndexingProperties",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES}),
+	("StructureTypeDescriptorSetVariableDescriptorCountAllocateInfo",
+		#{const VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO}),
+	("StructureTypeDescriptorSetVariableDescriptorCountLayoutSupport",
+		#{const VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT}),
+	("StructureTypePhysicalDeviceDepthStencilResolveProperties",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES}),
+	("StructureTypeSubpassDescriptionDepthStencilResolve",
+		#{const VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE}),
+	("StructureTypePhysicalDeviceScalarBlockLayoutFeatures",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES}),
+	("StructureTypeImageStencilUsageCreateInfo",
+		#{const VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO}),
+	("StructureTypePhysicalDeviceSamplerFilterMinmaxProperties",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES}),
+	("StructureTypeSamplerReductionModeCreateInfo",
+		#{const VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO}),
+	("StructureTypePhysicalDeviceVulkanMemoryModelFeatures",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES}),
+	("StructureTypePhysicalDeviceImagelessFramebufferFeatures",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES}),
+	("StructureTypeFramebufferAttachmentsCreateInfo",
+		#{const VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO}),
+	("StructureTypeFramebufferAttachmentImageInfo",
+		#{const VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO}),
+	("StructureTypeRenderPassAttachmentBeginInfo",
+		#{const VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO}),
+	("StructureTypePhysicalDeviceUniformBufferStandardLayoutFeatures",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES}),
+	("StructureTypePhysicalDeviceShaderSubgroupExtendedTypesFeatures",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES}),
+	("StructureTypePhysicalDeviceSeparateDepthStencilLayoutsFeatures",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES}),
+	("StructureTypeAttachmentReferenceStencilLayout",
+		#{const VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT}),
+	("StructureTypeAttachmentDescriptionStencilLayout",
+		#{const VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT}),
+	("StructureTypePhysicalDeviceHostQueryResetFeatures",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES}),
+	("StructureTypePhysicalDeviceTimelineSemaphoreFeatures",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES}),
+	("StructureTypePhysicalDeviceTimelineSemaphoreProperties",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES}),
+	("StructureTypeSemaphoreTypeCreateInfo",
+		#{const VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO}),
+	("StructureTypeTimelineSemaphoreSubmitInfo",
+		#{const VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO}),
+	("StructureTypeSemaphoreWaitInfo",
+		#{const VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO}),
+	("StructureTypeSemaphoreSignalInfo",
+		#{const VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO}),
+	("StructureTypePhysicalDeviceBufferDeviceAddressFeatures",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES}),
+	("StructureTypeBufferDeviceAddressInfo",
+		#{const VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO}),
+	("StructureTypeBufferOpaqueCaptureAddressCreateInfo",
+		#{const VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO}),
+	("StructureTypeMemoryOpaqueCaptureAddressAllocateInfo",
+		#{const VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO}),
+	("StructureTypeDeviceMemoryOpaqueCaptureAddressInfo",
+		#{const VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO}),
+	("StructureTypePhysicalDeviceVulkan13Features",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES}),
+	("StructureTypePhysicalDeviceVulkan13Properties",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_PROPERTIES}),
+	("StructureTypePipelineCreationFeedbackCreateInfo",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO}),
+	("StructureTypePhysicalDeviceShaderTerminateInvocationFeatures",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES}),
+	("StructureTypePhysicalDeviceToolProperties",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES}),
+	("StructureTypePhysicalDeviceShaderDemoteToHelperInvocationFeatures",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES}),
+	("StructureTypePhysicalDevicePrivateDataFeatures",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES}),
+	("StructureTypeDevicePrivateDataCreateInfo",
+		#{const VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO}),
+	("StructureTypePrivateDataSlotCreateInfo",
+		#{const VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO}),
+	("StructureTypePhysicalDevicePipelineCreationCacheControlFeatures",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES}),
+	("StructureTypeMemoryBarrier2",
+		#{const VK_STRUCTURE_TYPE_MEMORY_BARRIER_2}),
+	("StructureTypeBufferMemoryBarrier2",
+		#{const VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2}),
+	("StructureTypeImageMemoryBarrier2",
+		#{const VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2}),
+	("StructureTypeDependencyInfo",
+		#{const VK_STRUCTURE_TYPE_DEPENDENCY_INFO}),
+	("StructureTypeSubmitInfo2", #{const VK_STRUCTURE_TYPE_SUBMIT_INFO_2}),
+	("StructureTypeSemaphoreSubmitInfo",
+		#{const VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO}),
+	("StructureTypeCommandBufferSubmitInfo",
+		#{const VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO}),
+	("StructureTypePhysicalDeviceSynchronization2Features",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES}),
+	("StructureTypePhysicalDeviceZeroInitializeWorkgroupMemoryFeatures",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES}),
+	("StructureTypePhysicalDeviceImageRobustnessFeatures",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES}),
+	("StructureTypeCopyBufferInfo2",
+		#{const VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2}),
+	("StructureTypeCopyImageInfo2",
+		#{const VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2}),
+	("StructureTypeCopyBufferToImageInfo2",
+		#{const VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2}),
+	("StructureTypeCopyImageToBufferInfo2",
+		#{const VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2}),
+	("StructureTypeBlitImageInfo2",
+		#{const VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2}),
+	("StructureTypeResolveImageInfo2",
+		#{const VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2}),
+	("StructureTypeBufferCopy2", #{const VK_STRUCTURE_TYPE_BUFFER_COPY_2}),
+	("StructureTypeImageCopy2", #{const VK_STRUCTURE_TYPE_IMAGE_COPY_2}),
+	("StructureTypeImageBlit2", #{const VK_STRUCTURE_TYPE_IMAGE_BLIT_2}),
+	("StructureTypeBufferImageCopy2",
+		#{const VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2}),
+	("StructureTypeImageResolve2",
+		#{const VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2}),
+	("StructureTypePhysicalDeviceSubgroupSizeControlProperties",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES}),
+	("StructureTypePipelineShaderStageRequiredSubgroupSizeCreateInfo",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO}),
+	("StructureTypePhysicalDeviceSubgroupSizeControlFeatures",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES}),
+	("StructureTypePhysicalDeviceInlineUniformBlockFeatures",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES}),
+	("StructureTypePhysicalDeviceInlineUniformBlockProperties",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES}),
+	("StructureTypeWriteDescriptorSetInlineUniformBlock",
+		#{const VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK}),
+	("StructureTypeDescriptorPoolInlineUniformBlockCreateInfo",
+		#{const VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO}),
+	("StructureTypePhysicalDeviceTextureCompressionAstcHdrFeatures",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES}),
+	("StructureTypeRenderingInfo",
+		#{const VK_STRUCTURE_TYPE_RENDERING_INFO}),
+	("StructureTypeRenderingAttachmentInfo",
+		#{const VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO}),
+	("StructureTypePipelineRenderingCreateInfo",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO}),
+	("StructureTypePhysicalDeviceDynamicRenderingFeatures",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES}),
+	("StructureTypeCommandBufferInheritanceRenderingInfo",
+		#{const VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO}),
+	("StructureTypePhysicalDeviceShaderIntegerDotProductFeatures",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES}),
+	("StructureTypePhysicalDeviceShaderIntegerDotProductProperties",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES}),
+	("StructureTypePhysicalDeviceTexelBufferAlignmentProperties",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES}),
+	("StructureTypeFormatProperties3",
+		#{const VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3}),
+	("StructureTypePhysicalDeviceMaintenance4Features",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES}),
+	("StructureTypePhysicalDeviceMaintenance4Properties",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES}),
+	("StructureTypeDeviceBufferMemoryRequirements",
+		#{const VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS}),
+	("StructureTypeDeviceImageMemoryRequirements",
+		#{const VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS}),
+	("StructureTypeSwapchainCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR}),
+	("StructureTypePresentInfoKhr",
+		#{const VK_STRUCTURE_TYPE_PRESENT_INFO_KHR}),
+	("StructureTypeDeviceGroupPresentCapabilitiesKhr",
+		#{const VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR}),
+	("StructureTypeImageSwapchainCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR}),
+	("StructureTypeBindImageMemorySwapchainInfoKhr",
+		#{const VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR}),
+	("StructureTypeAcquireNextImageInfoKhr",
+		#{const VK_STRUCTURE_TYPE_ACQUIRE_NEXT_IMAGE_INFO_KHR}),
+	("StructureTypeDeviceGroupPresentInfoKhr",
+		#{const VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_INFO_KHR}),
+	("StructureTypeDeviceGroupSwapchainCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_DEVICE_GROUP_SWAPCHAIN_CREATE_INFO_KHR}),
+	("StructureTypeDisplayModeCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR}),
+	("StructureTypeDisplaySurfaceCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR}),
+	("StructureTypeDisplayPresentInfoKhr",
+		#{const VK_STRUCTURE_TYPE_DISPLAY_PRESENT_INFO_KHR}),
+	("StructureTypeXlibSurfaceCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR}),
+	("StructureTypeXcbSurfaceCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR}),
+	("StructureTypeWaylandSurfaceCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR}),
+	("StructureTypeAndroidSurfaceCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR}),
+	("StructureTypeWin32SurfaceCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR}),
+	("StructureTypeDebugReportCallbackCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT}),
+	("StructureTypePipelineRasterizationStateRasterizationOrderAmd",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD}),
+	("StructureTypeDebugMarkerObjectNameInfoExt",
+		#{const VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT}),
+	("StructureTypeDebugMarkerObjectTagInfoExt",
+		#{const VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_TAG_INFO_EXT}),
+	("StructureTypeDebugMarkerMarkerInfoExt",
+		#{const VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT}),
+	("StructureTypeVideoProfileInfoKhr",
+		#{const VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR}),
+	("StructureTypeVideoCapabilitiesKhr",
+		#{const VK_STRUCTURE_TYPE_VIDEO_CAPABILITIES_KHR}),
+	("StructureTypeVideoPictureResourceInfoKhr",
+		#{const VK_STRUCTURE_TYPE_VIDEO_PICTURE_RESOURCE_INFO_KHR}),
+	("StructureTypeVideoSessionMemoryRequirementsKhr",
+		#{const VK_STRUCTURE_TYPE_VIDEO_SESSION_MEMORY_REQUIREMENTS_KHR}),
+	("StructureTypeBindVideoSessionMemoryInfoKhr",
+		#{const VK_STRUCTURE_TYPE_BIND_VIDEO_SESSION_MEMORY_INFO_KHR}),
+	("StructureTypeVideoSessionCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_VIDEO_SESSION_CREATE_INFO_KHR}),
+	("StructureTypeVideoSessionParametersCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_VIDEO_SESSION_PARAMETERS_CREATE_INFO_KHR}),
+	("StructureTypeVideoSessionParametersUpdateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_VIDEO_SESSION_PARAMETERS_UPDATE_INFO_KHR}),
+	("StructureTypeVideoBeginCodingInfoKhr",
+		#{const VK_STRUCTURE_TYPE_VIDEO_BEGIN_CODING_INFO_KHR}),
+	("StructureTypeVideoEndCodingInfoKhr",
+		#{const VK_STRUCTURE_TYPE_VIDEO_END_CODING_INFO_KHR}),
+	("StructureTypeVideoCodingControlInfoKhr",
+		#{const VK_STRUCTURE_TYPE_VIDEO_CODING_CONTROL_INFO_KHR}),
+	("StructureTypeVideoReferenceSlotInfoKhr",
+		#{const VK_STRUCTURE_TYPE_VIDEO_REFERENCE_SLOT_INFO_KHR}),
+	("StructureTypeQueueFamilyVideoPropertiesKhr",
+		#{const VK_STRUCTURE_TYPE_QUEUE_FAMILY_VIDEO_PROPERTIES_KHR}),
+	("StructureTypeVideoProfileListInfoKhr",
+		#{const VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR}),
+	("StructureTypePhysicalDeviceVideoFormatInfoKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_FORMAT_INFO_KHR}),
+	("StructureTypeVideoFormatPropertiesKhr",
+		#{const VK_STRUCTURE_TYPE_VIDEO_FORMAT_PROPERTIES_KHR}),
+	("StructureTypeQueueFamilyQueryResultStatusPropertiesKhr",
+		#{const VK_STRUCTURE_TYPE_QUEUE_FAMILY_QUERY_RESULT_STATUS_PROPERTIES_KHR}),
+	("StructureTypeVideoDecodeInfoKhr",
+		#{const VK_STRUCTURE_TYPE_VIDEO_DECODE_INFO_KHR}),
+	("StructureTypeVideoDecodeCapabilitiesKhr",
+		#{const VK_STRUCTURE_TYPE_VIDEO_DECODE_CAPABILITIES_KHR}),
+	("StructureTypeVideoDecodeUsageInfoKhr",
+		#{const VK_STRUCTURE_TYPE_VIDEO_DECODE_USAGE_INFO_KHR}),
+	("StructureTypeDedicatedAllocationImageCreateInfoNv",
+		#{const VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV}),
+	("StructureTypeDedicatedAllocationBufferCreateInfoNv",
+		#{const VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV}),
+	("StructureTypeDedicatedAllocationMemoryAllocateInfoNv",
+		#{const VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV}),
+	("StructureTypePhysicalDeviceTransformFeedbackFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceTransformFeedbackPropertiesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT}),
+	("StructureTypePipelineRasterizationStateStreamCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_STREAM_CREATE_INFO_EXT}),
+	("StructureTypeCuModuleCreateInfoNvx",
+		#{const VK_STRUCTURE_TYPE_CU_MODULE_CREATE_INFO_NVX}),
+	("StructureTypeCuFunctionCreateInfoNvx",
+		#{const VK_STRUCTURE_TYPE_CU_FUNCTION_CREATE_INFO_NVX}),
+	("StructureTypeCuLaunchInfoNvx",
+		#{const VK_STRUCTURE_TYPE_CU_LAUNCH_INFO_NVX}),
+	("StructureTypeImageViewHandleInfoNvx",
+		#{const VK_STRUCTURE_TYPE_IMAGE_VIEW_HANDLE_INFO_NVX}),
+	("StructureTypeImageViewAddressPropertiesNvx",
+		#{const VK_STRUCTURE_TYPE_IMAGE_VIEW_ADDRESS_PROPERTIES_NVX}),
+	("StructureTypeVideoDecodeH264CapabilitiesKhr",
+		#{const VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_CAPABILITIES_KHR}),
+	("StructureTypeVideoDecodeH264PictureInfoKhr",
+		#{const VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PICTURE_INFO_KHR}),
+	("StructureTypeVideoDecodeH264ProfileInfoKhr",
+		#{const VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_INFO_KHR}),
+	("StructureTypeVideoDecodeH264SessionParametersCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_KHR}),
+	("StructureTypeVideoDecodeH264SessionParametersAddInfoKhr",
+		#{const VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_ADD_INFO_KHR}),
+	("StructureTypeVideoDecodeH264DpbSlotInfoKhr",
+		#{const VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_DPB_SLOT_INFO_KHR}),
+	("StructureTypeTextureLodGatherFormatPropertiesAmd",
+		#{const VK_STRUCTURE_TYPE_TEXTURE_LOD_GATHER_FORMAT_PROPERTIES_AMD}),
+	("StructureTypeRenderingFragmentShadingRateAttachmentInfoKhr",
+		#{const VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR}),
+	("StructureTypeRenderingFragmentDensityMapAttachmentInfoExt",
+		#{const VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_INFO_EXT}),
+	("StructureTypeAttachmentSampleCountInfoAmd",
+		#{const VK_STRUCTURE_TYPE_ATTACHMENT_SAMPLE_COUNT_INFO_AMD}),
+	("StructureTypeMultiviewPerViewAttributesInfoNvx",
+		#{const VK_STRUCTURE_TYPE_MULTIVIEW_PER_VIEW_ATTRIBUTES_INFO_NVX}),
+	("StructureTypeStreamDescriptorSurfaceCreateInfoGgp",
+		#{const VK_STRUCTURE_TYPE_STREAM_DESCRIPTOR_SURFACE_CREATE_INFO_GGP}),
+	("StructureTypePhysicalDeviceCornerSampledImageFeaturesNv",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CORNER_SAMPLED_IMAGE_FEATURES_NV}),
+	("StructureTypeExternalMemoryImageCreateInfoNv",
+		#{const VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV}),
+	("StructureTypeExportMemoryAllocateInfoNv",
+		#{const VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV}),
+	("StructureTypeImportMemoryWin32HandleInfoNv",
+		#{const VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV}),
+	("StructureTypeExportMemoryWin32HandleInfoNv",
+		#{const VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_NV}),
+	("StructureTypeWin32KeyedMutexAcquireReleaseInfoNv",
+		#{const VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV}),
+	("StructureTypeValidationFlagsExt",
+		#{const VK_STRUCTURE_TYPE_VALIDATION_FLAGS_EXT}),
+	("StructureTypeViSurfaceCreateInfoNn",
+		#{const VK_STRUCTURE_TYPE_VI_SURFACE_CREATE_INFO_NN}),
+	("StructureTypeImageViewAstcDecodeModeExt",
+		#{const VK_STRUCTURE_TYPE_IMAGE_VIEW_ASTC_DECODE_MODE_EXT}),
+	("StructureTypePhysicalDeviceAstcDecodeFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT}),
+	("StructureTypePipelineRobustnessCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_ROBUSTNESS_CREATE_INFO_EXT}),
+	("StructureTypePhysicalDevicePipelineRobustnessFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_ROBUSTNESS_FEATURES_EXT}),
+	("StructureTypePhysicalDevicePipelineRobustnessPropertiesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_ROBUSTNESS_PROPERTIES_EXT}),
+	("StructureTypeImportMemoryWin32HandleInfoKhr",
+		#{const VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR}),
+	("StructureTypeExportMemoryWin32HandleInfoKhr",
+		#{const VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR}),
+	("StructureTypeMemoryWin32HandlePropertiesKhr",
+		#{const VK_STRUCTURE_TYPE_MEMORY_WIN32_HANDLE_PROPERTIES_KHR}),
+	("StructureTypeMemoryGetWin32HandleInfoKhr",
+		#{const VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR}),
+	("StructureTypeImportMemoryFdInfoKhr",
+		#{const VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR}),
+	("StructureTypeMemoryFdPropertiesKhr",
+		#{const VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR}),
+	("StructureTypeMemoryGetFdInfoKhr",
+		#{const VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR}),
+	("StructureTypeWin32KeyedMutexAcquireReleaseInfoKhr",
+		#{const VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_KHR}),
+	("StructureTypeImportSemaphoreWin32HandleInfoKhr",
+		#{const VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR}),
+	("StructureTypeExportSemaphoreWin32HandleInfoKhr",
+		#{const VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR}),
+	("StructureTypeD3d12FenceSubmitInfoKhr",
+		#{const VK_STRUCTURE_TYPE_D3D12_FENCE_SUBMIT_INFO_KHR}),
+	("StructureTypeSemaphoreGetWin32HandleInfoKhr",
+		#{const VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR}),
+	("StructureTypeImportSemaphoreFdInfoKhr",
+		#{const VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR}),
+	("StructureTypeSemaphoreGetFdInfoKhr",
+		#{const VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR}),
+	("StructureTypePhysicalDevicePushDescriptorPropertiesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR}),
+	("StructureTypeCommandBufferInheritanceConditionalRenderingInfoExt",
+		#{const VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT}),
+	("StructureTypePhysicalDeviceConditionalRenderingFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT}),
+	("StructureTypeConditionalRenderingBeginInfoExt",
+		#{const VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT}),
+	("StructureTypePresentRegionsKhr",
+		#{const VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR}),
+	("StructureTypePipelineViewportWScalingStateCreateInfoNv",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV}),
+	("StructureTypeSurfaceCapabilities2Ext",
+		#{const VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT}),
+	("StructureTypeDisplayPowerInfoExt",
+		#{const VK_STRUCTURE_TYPE_DISPLAY_POWER_INFO_EXT}),
+	("StructureTypeDeviceEventInfoExt",
+		#{const VK_STRUCTURE_TYPE_DEVICE_EVENT_INFO_EXT}),
+	("StructureTypeDisplayEventInfoExt",
+		#{const VK_STRUCTURE_TYPE_DISPLAY_EVENT_INFO_EXT}),
+	("StructureTypeSwapchainCounterCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_SWAPCHAIN_COUNTER_CREATE_INFO_EXT}),
+	("StructureTypePresentTimesInfoGoogle",
+		#{const VK_STRUCTURE_TYPE_PRESENT_TIMES_INFO_GOOGLE}),
+	("StructureTypePhysicalDeviceMultiviewPerViewAttributesPropertiesNvx",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_ATTRIBUTES_PROPERTIES_NVX}),
+	("StructureTypePipelineViewportSwizzleStateCreateInfoNv",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SWIZZLE_STATE_CREATE_INFO_NV}),
+	("StructureTypePhysicalDeviceDiscardRectanglePropertiesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT}),
+	("StructureTypePipelineDiscardRectangleStateCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT}),
+	("StructureTypePhysicalDeviceConservativeRasterizationPropertiesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT}),
+	("StructureTypePipelineRasterizationConservativeStateCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT}),
+	("StructureTypePhysicalDeviceDepthClipEnableFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT}),
+	("StructureTypePipelineRasterizationDepthClipStateCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT}),
+	("StructureTypeHdrMetadataExt",
+		#{const VK_STRUCTURE_TYPE_HDR_METADATA_EXT}),
+	("StructureTypeSharedPresentSurfaceCapabilitiesKhr",
+		#{const VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR}),
+	("StructureTypeImportFenceWin32HandleInfoKhr",
+		#{const VK_STRUCTURE_TYPE_IMPORT_FENCE_WIN32_HANDLE_INFO_KHR}),
+	("StructureTypeExportFenceWin32HandleInfoKhr",
+		#{const VK_STRUCTURE_TYPE_EXPORT_FENCE_WIN32_HANDLE_INFO_KHR}),
+	("StructureTypeFenceGetWin32HandleInfoKhr",
+		#{const VK_STRUCTURE_TYPE_FENCE_GET_WIN32_HANDLE_INFO_KHR}),
+	("StructureTypeImportFenceFdInfoKhr",
+		#{const VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR}),
+	("StructureTypeFenceGetFdInfoKhr",
+		#{const VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR}),
+	("StructureTypePhysicalDevicePerformanceQueryFeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_FEATURES_KHR}),
+	("StructureTypePhysicalDevicePerformanceQueryPropertiesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_PROPERTIES_KHR}),
+	("StructureTypeQueryPoolPerformanceCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_CREATE_INFO_KHR}),
+	("StructureTypePerformanceQuerySubmitInfoKhr",
+		#{const VK_STRUCTURE_TYPE_PERFORMANCE_QUERY_SUBMIT_INFO_KHR}),
+	("StructureTypeAcquireProfilingLockInfoKhr",
+		#{const VK_STRUCTURE_TYPE_ACQUIRE_PROFILING_LOCK_INFO_KHR}),
+	("StructureTypePerformanceCounterKhr",
+		#{const VK_STRUCTURE_TYPE_PERFORMANCE_COUNTER_KHR}),
+	("StructureTypePerformanceCounterDescriptionKhr",
+		#{const VK_STRUCTURE_TYPE_PERFORMANCE_COUNTER_DESCRIPTION_KHR}),
+	("StructureTypePhysicalDeviceSurfaceInfo2Khr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR}),
+	("StructureTypeSurfaceCapabilities2Khr",
+		#{const VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR}),
+	("StructureTypeSurfaceFormat2Khr",
+		#{const VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR}),
+	("StructureTypeDisplayProperties2Khr",
+		#{const VK_STRUCTURE_TYPE_DISPLAY_PROPERTIES_2_KHR}),
+	("StructureTypeDisplayPlaneProperties2Khr",
+		#{const VK_STRUCTURE_TYPE_DISPLAY_PLANE_PROPERTIES_2_KHR}),
+	("StructureTypeDisplayModeProperties2Khr",
+		#{const VK_STRUCTURE_TYPE_DISPLAY_MODE_PROPERTIES_2_KHR}),
+	("StructureTypeDisplayPlaneInfo2Khr",
+		#{const VK_STRUCTURE_TYPE_DISPLAY_PLANE_INFO_2_KHR}),
+	("StructureTypeDisplayPlaneCapabilities2Khr",
+		#{const VK_STRUCTURE_TYPE_DISPLAY_PLANE_CAPABILITIES_2_KHR}),
+	("StructureTypeIosSurfaceCreateInfoMvk",
+		#{const VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK}),
+	("StructureTypeMacosSurfaceCreateInfoMvk",
+		#{const VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK}),
+	("StructureTypeDebugUtilsObjectNameInfoExt",
+		#{const VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT}),
+	("StructureTypeDebugUtilsObjectTagInfoExt",
+		#{const VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_TAG_INFO_EXT}),
+	("StructureTypeDebugUtilsLabelExt",
+		#{const VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT}),
+	("StructureTypeDebugUtilsMessengerCallbackDataExt",
+		#{const VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT}),
+	("StructureTypeDebugUtilsMessengerCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT}),
+	("StructureTypeAndroidHardwareBufferUsageAndroid",
+		#{const VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID}),
+	("StructureTypeAndroidHardwareBufferPropertiesAndroid",
+		#{const VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID}),
+	("StructureTypeAndroidHardwareBufferFormatPropertiesAndroid",
+		#{const VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID}),
+	("StructureTypeImportAndroidHardwareBufferInfoAndroid",
+		#{const VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID}),
+	("StructureTypeMemoryGetAndroidHardwareBufferInfoAndroid",
+		#{const VK_STRUCTURE_TYPE_MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID}),
+	("StructureTypeExternalFormatAndroid",
+		#{const VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID}),
+	("StructureTypeAndroidHardwareBufferFormatProperties2Android",
+		#{const VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_2_ANDROID}),
+	("StructureTypeSampleLocationsInfoExt",
+		#{const VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT}),
+	("StructureTypeRenderPassSampleLocationsBeginInfoExt",
+		#{const VK_STRUCTURE_TYPE_RENDER_PASS_SAMPLE_LOCATIONS_BEGIN_INFO_EXT}),
+	("StructureTypePipelineSampleLocationsStateCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT}),
+	("StructureTypePhysicalDeviceSampleLocationsPropertiesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT}),
+	("StructureTypeMultisamplePropertiesExt",
+		#{const VK_STRUCTURE_TYPE_MULTISAMPLE_PROPERTIES_EXT}),
+	("StructureTypePhysicalDeviceBlendOperationAdvancedFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceBlendOperationAdvancedPropertiesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT}),
+	("StructureTypePipelineColorBlendAdvancedStateCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT}),
+	("StructureTypePipelineCoverageToColorStateCreateInfoNv",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_TO_COLOR_STATE_CREATE_INFO_NV}),
+	("StructureTypeWriteDescriptorSetAccelerationStructureKhr",
+		#{const VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR}),
+	("StructureTypeAccelerationStructureBuildGeometryInfoKhr",
+		#{const VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR}),
+	("StructureTypeAccelerationStructureDeviceAddressInfoKhr",
+		#{const VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR}),
+	("StructureTypeAccelerationStructureGeometryAabbsDataKhr",
+		#{const VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_AABBS_DATA_KHR}),
+	("StructureTypeAccelerationStructureGeometryInstancesDataKhr",
+		#{const VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR}),
+	("StructureTypeAccelerationStructureGeometryTrianglesDataKhr",
+		#{const VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR}),
+	("StructureTypeAccelerationStructureGeometryKhr",
+		#{const VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR}),
+	("StructureTypeAccelerationStructureVersionInfoKhr",
+		#{const VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_VERSION_INFO_KHR}),
+	("StructureTypeCopyAccelerationStructureInfoKhr",
+		#{const VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_INFO_KHR}),
+	("StructureTypeCopyAccelerationStructureToMemoryInfoKhr",
+		#{const VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_TO_MEMORY_INFO_KHR}),
+	("StructureTypeCopyMemoryToAccelerationStructureInfoKhr",
+		#{const VK_STRUCTURE_TYPE_COPY_MEMORY_TO_ACCELERATION_STRUCTURE_INFO_KHR}),
+	("StructureTypePhysicalDeviceAccelerationStructureFeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR}),
+	("StructureTypePhysicalDeviceAccelerationStructurePropertiesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_PROPERTIES_KHR}),
+	("StructureTypeAccelerationStructureCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR}),
+	("StructureTypeAccelerationStructureBuildSizesInfoKhr",
+		#{const VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR}),
+	("StructureTypePhysicalDeviceRayTracingPipelineFeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR}),
+	("StructureTypePhysicalDeviceRayTracingPipelinePropertiesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_PROPERTIES_KHR}),
+	("StructureTypeRayTracingPipelineCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_KHR}),
+	("StructureTypeRayTracingShaderGroupCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR}),
+	("StructureTypeRayTracingPipelineInterfaceCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_INTERFACE_CREATE_INFO_KHR}),
+	("StructureTypePhysicalDeviceRayQueryFeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_QUERY_FEATURES_KHR}),
+	("StructureTypePipelineCoverageModulationStateCreateInfoNv",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_MODULATION_STATE_CREATE_INFO_NV}),
+	("StructureTypePhysicalDeviceShaderSmBuiltinsFeaturesNv",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SM_BUILTINS_FEATURES_NV}),
+	("StructureTypePhysicalDeviceShaderSmBuiltinsPropertiesNv",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SM_BUILTINS_PROPERTIES_NV}),
+	("StructureTypeDrmFormatModifierPropertiesListExt",
+		#{const VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT}),
+	("StructureTypePhysicalDeviceImageDrmFormatModifierInfoExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT}),
+	("StructureTypeImageDrmFormatModifierListCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT}),
+	("StructureTypeImageDrmFormatModifierExplicitCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT}),
+	("StructureTypeImageDrmFormatModifierPropertiesExt",
+		#{const VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT}),
+	("StructureTypeDrmFormatModifierPropertiesList2Ext",
+		#{const VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_2_EXT}),
+	("StructureTypeValidationCacheCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_VALIDATION_CACHE_CREATE_INFO_EXT}),
+	("StructureTypeShaderModuleValidationCacheCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_SHADER_MODULE_VALIDATION_CACHE_CREATE_INFO_EXT}),
+	("StructureTypePipelineViewportShadingRateImageStateCreateInfoNv",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SHADING_RATE_IMAGE_STATE_CREATE_INFO_NV}),
+	("StructureTypePhysicalDeviceShadingRateImageFeaturesNv",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_FEATURES_NV}),
+	("StructureTypePhysicalDeviceShadingRateImagePropertiesNv",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_PROPERTIES_NV}),
+	("StructureTypePipelineViewportCoarseSampleOrderStateCreateInfoNv",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_COARSE_SAMPLE_ORDER_STATE_CREATE_INFO_NV}),
+	("StructureTypeRayTracingPipelineCreateInfoNv",
+		#{const VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_NV}),
+	("StructureTypeAccelerationStructureCreateInfoNv",
+		#{const VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV}),
+	("StructureTypeGeometryNv", #{const VK_STRUCTURE_TYPE_GEOMETRY_NV}),
+	("StructureTypeGeometryTrianglesNv",
+		#{const VK_STRUCTURE_TYPE_GEOMETRY_TRIANGLES_NV}),
+	("StructureTypeGeometryAabbNv",
+		#{const VK_STRUCTURE_TYPE_GEOMETRY_AABB_NV}),
+	("StructureTypeBindAccelerationStructureMemoryInfoNv",
+		#{const VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_NV}),
+	("StructureTypeWriteDescriptorSetAccelerationStructureNv",
+		#{const VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_NV}),
+	("StructureTypeAccelerationStructureMemoryRequirementsInfoNv",
+		#{const VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV}),
+	("StructureTypePhysicalDeviceRayTracingPropertiesNv",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PROPERTIES_NV}),
+	("StructureTypeRayTracingShaderGroupCreateInfoNv",
+		#{const VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV}),
+	("StructureTypeAccelerationStructureInfoNv",
+		#{const VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV}),
+	("StructureTypePhysicalDeviceRepresentativeFragmentTestFeaturesNv",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_REPRESENTATIVE_FRAGMENT_TEST_FEATURES_NV}),
+	("StructureTypePipelineRepresentativeFragmentTestStateCreateInfoNv",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_REPRESENTATIVE_FRAGMENT_TEST_STATE_CREATE_INFO_NV}),
+	("StructureTypePhysicalDeviceImageViewImageFormatInfoExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_IMAGE_FORMAT_INFO_EXT}),
+	("StructureTypeFilterCubicImageViewImageFormatPropertiesExt",
+		#{const VK_STRUCTURE_TYPE_FILTER_CUBIC_IMAGE_VIEW_IMAGE_FORMAT_PROPERTIES_EXT}),
+	("StructureTypeImportMemoryHostPointerInfoExt",
+		#{const VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT}),
+	("StructureTypeMemoryHostPointerPropertiesExt",
+		#{const VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT}),
+	("StructureTypePhysicalDeviceExternalMemoryHostPropertiesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT}),
+	("StructureTypePhysicalDeviceShaderClockFeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR}),
+	("StructureTypePipelineCompilerControlCreateInfoAmd",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_COMPILER_CONTROL_CREATE_INFO_AMD}),
+	("StructureTypeCalibratedTimestampInfoExt",
+		#{const VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT}),
+	("StructureTypePhysicalDeviceShaderCorePropertiesAmd",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_AMD}),
+	("StructureTypeVideoDecodeH265CapabilitiesKhr",
+		#{const VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_CAPABILITIES_KHR}),
+	("StructureTypeVideoDecodeH265SessionParametersCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_PARAMETERS_CREATE_INFO_KHR}),
+	("StructureTypeVideoDecodeH265SessionParametersAddInfoKhr",
+		#{const VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_PARAMETERS_ADD_INFO_KHR}),
+	("StructureTypeVideoDecodeH265ProfileInfoKhr",
+		#{const VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_INFO_KHR}),
+	("StructureTypeVideoDecodeH265PictureInfoKhr",
+		#{const VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PICTURE_INFO_KHR}),
+	("StructureTypeVideoDecodeH265DpbSlotInfoKhr",
+		#{const VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_DPB_SLOT_INFO_KHR}),
+	("StructureTypeDeviceQueueGlobalPriorityCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_KHR}),
+	("StructureTypePhysicalDeviceGlobalPriorityQueryFeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_KHR}),
+	("StructureTypeQueueFamilyGlobalPriorityPropertiesKhr",
+		#{const VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_KHR}),
+	("StructureTypeDeviceMemoryOverallocationCreateInfoAmd",
+		#{const VK_STRUCTURE_TYPE_DEVICE_MEMORY_OVERALLOCATION_CREATE_INFO_AMD}),
+	("StructureTypePhysicalDeviceVertexAttributeDivisorPropertiesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT}),
+	("StructureTypePipelineVertexInputDivisorStateCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT}),
+	("StructureTypePhysicalDeviceVertexAttributeDivisorFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT}),
+	("StructureTypePresentFrameTokenGgp",
+		#{const VK_STRUCTURE_TYPE_PRESENT_FRAME_TOKEN_GGP}),
+	("StructureTypePhysicalDeviceComputeShaderDerivativesFeaturesNv",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV}),
+	("StructureTypePhysicalDeviceMeshShaderFeaturesNv",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV}),
+	("StructureTypePhysicalDeviceMeshShaderPropertiesNv",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_NV}),
+	("StructureTypePhysicalDeviceShaderImageFootprintFeaturesNv",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_FOOTPRINT_FEATURES_NV}),
+	("StructureTypePipelineViewportExclusiveScissorStateCreateInfoNv",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_EXCLUSIVE_SCISSOR_STATE_CREATE_INFO_NV}),
+	("StructureTypePhysicalDeviceExclusiveScissorFeaturesNv",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXCLUSIVE_SCISSOR_FEATURES_NV}),
+	("StructureTypeCheckpointDataNv",
+		#{const VK_STRUCTURE_TYPE_CHECKPOINT_DATA_NV}),
+	("StructureTypeQueueFamilyCheckpointPropertiesNv",
+		#{const VK_STRUCTURE_TYPE_QUEUE_FAMILY_CHECKPOINT_PROPERTIES_NV}),
+	("StructureTypePhysicalDeviceShaderIntegerFunctions2FeaturesIntel",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL}),
+	("StructureTypeQueryPoolPerformanceQueryCreateInfoIntel",
+		#{const VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_QUERY_CREATE_INFO_INTEL}),
+	("StructureTypeInitializePerformanceApiInfoIntel",
+		#{const VK_STRUCTURE_TYPE_INITIALIZE_PERFORMANCE_API_INFO_INTEL}),
+	("StructureTypePerformanceMarkerInfoIntel",
+		#{const VK_STRUCTURE_TYPE_PERFORMANCE_MARKER_INFO_INTEL}),
+	("StructureTypePerformanceStreamMarkerInfoIntel",
+		#{const VK_STRUCTURE_TYPE_PERFORMANCE_STREAM_MARKER_INFO_INTEL}),
+	("StructureTypePerformanceOverrideInfoIntel",
+		#{const VK_STRUCTURE_TYPE_PERFORMANCE_OVERRIDE_INFO_INTEL}),
+	("StructureTypePerformanceConfigurationAcquireInfoIntel",
+		#{const VK_STRUCTURE_TYPE_PERFORMANCE_CONFIGURATION_ACQUIRE_INFO_INTEL}),
+	("StructureTypePhysicalDevicePciBusInfoPropertiesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT}),
+	("StructureTypeDisplayNativeHdrSurfaceCapabilitiesAmd",
+		#{const VK_STRUCTURE_TYPE_DISPLAY_NATIVE_HDR_SURFACE_CAPABILITIES_AMD}),
+	("StructureTypeSwapchainDisplayNativeHdrCreateInfoAmd",
+		#{const VK_STRUCTURE_TYPE_SWAPCHAIN_DISPLAY_NATIVE_HDR_CREATE_INFO_AMD}),
+	("StructureTypeImagepipeSurfaceCreateInfoFuchsia",
+		#{const VK_STRUCTURE_TYPE_IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA}),
+	("StructureTypeMetalSurfaceCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT}),
+	("StructureTypePhysicalDeviceFragmentDensityMapFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceFragmentDensityMapPropertiesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT}),
+	("StructureTypeRenderPassFragmentDensityMapCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT}),
+	("StructureTypeFragmentShadingRateAttachmentInfoKhr",
+		#{const VK_STRUCTURE_TYPE_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR}),
+	("StructureTypePipelineFragmentShadingRateStateCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR}),
+	("StructureTypePhysicalDeviceFragmentShadingRatePropertiesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR}),
+	("StructureTypePhysicalDeviceFragmentShadingRateFeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR}),
+	("StructureTypePhysicalDeviceFragmentShadingRateKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_KHR}),
+	("StructureTypePhysicalDeviceShaderCoreProperties2Amd",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_2_AMD}),
+	("StructureTypePhysicalDeviceCoherentMemoryFeaturesAmd",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COHERENT_MEMORY_FEATURES_AMD}),
+	("StructureTypePhysicalDeviceShaderImageAtomicInt64FeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_ATOMIC_INT64_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceMemoryBudgetPropertiesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT}),
+	("StructureTypePhysicalDeviceMemoryPriorityFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT}),
+	("StructureTypeMemoryPriorityAllocateInfoExt",
+		#{const VK_STRUCTURE_TYPE_MEMORY_PRIORITY_ALLOCATE_INFO_EXT}),
+	("StructureTypeSurfaceProtectedCapabilitiesKhr",
+		#{const VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR}),
+	("StructureTypePhysicalDeviceDedicatedAllocationImageAliasingFeaturesNv",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEDICATED_ALLOCATION_IMAGE_ALIASING_FEATURES_NV}),
+	("StructureTypePhysicalDeviceBufferDeviceAddressFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT}),
+	("StructureTypeBufferDeviceAddressCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_CREATE_INFO_EXT}),
+	("StructureTypeValidationFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT}),
+	("StructureTypePhysicalDevicePresentWaitFeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_WAIT_FEATURES_KHR}),
+	("StructureTypePhysicalDeviceCooperativeMatrixFeaturesNv",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_NV}),
+	("StructureTypeCooperativeMatrixPropertiesNv",
+		#{const VK_STRUCTURE_TYPE_COOPERATIVE_MATRIX_PROPERTIES_NV}),
+	("StructureTypePhysicalDeviceCooperativeMatrixPropertiesNv",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_PROPERTIES_NV}),
+	("StructureTypePhysicalDeviceCoverageReductionModeFeaturesNv",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COVERAGE_REDUCTION_MODE_FEATURES_NV}),
+	("StructureTypePipelineCoverageReductionStateCreateInfoNv",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_REDUCTION_STATE_CREATE_INFO_NV}),
+	("StructureTypeFramebufferMixedSamplesCombinationNv",
+		#{const VK_STRUCTURE_TYPE_FRAMEBUFFER_MIXED_SAMPLES_COMBINATION_NV}),
+	("StructureTypePhysicalDeviceFragmentShaderInterlockFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceYcbcrImageArraysFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_IMAGE_ARRAYS_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceProvokingVertexFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT}),
+	("StructureTypePipelineRasterizationProvokingVertexStateCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT}),
+	("StructureTypePhysicalDeviceProvokingVertexPropertiesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_PROPERTIES_EXT}),
+	("StructureTypeSurfaceFullScreenExclusiveInfoExt",
+		#{const VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT}),
+	("StructureTypeSurfaceCapabilitiesFullScreenExclusiveExt",
+		#{const VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_FULL_SCREEN_EXCLUSIVE_EXT}),
+	("StructureTypeSurfaceFullScreenExclusiveWin32InfoExt",
+		#{const VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_WIN32_INFO_EXT}),
+	("StructureTypeHeadlessSurfaceCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT}),
+	("StructureTypePhysicalDeviceLineRasterizationFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT}),
+	("StructureTypePipelineRasterizationLineStateCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT}),
+	("StructureTypePhysicalDeviceLineRasterizationPropertiesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT}),
+	("StructureTypePhysicalDeviceShaderAtomicFloatFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceIndexTypeUint8FeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceExtendedDynamicStateFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT}),
+	("StructureTypePhysicalDevicePipelineExecutablePropertiesFeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR}),
+	("StructureTypePipelineInfoKhr",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR}),
+	("StructureTypePipelineExecutablePropertiesKhr",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_PROPERTIES_KHR}),
+	("StructureTypePipelineExecutableInfoKhr",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INFO_KHR}),
+	("StructureTypePipelineExecutableStatisticKhr",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_STATISTIC_KHR}),
+	("StructureTypePipelineExecutableInternalRepresentationKhr",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INTERNAL_REPRESENTATION_KHR}),
+	("StructureTypeMemoryMapInfoKhr",
+		#{const VK_STRUCTURE_TYPE_MEMORY_MAP_INFO_KHR}),
+	("StructureTypeMemoryUnmapInfoKhr",
+		#{const VK_STRUCTURE_TYPE_MEMORY_UNMAP_INFO_KHR}),
+	("StructureTypePhysicalDeviceShaderAtomicFloat2FeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT}),
+	("StructureTypeSurfacePresentModeExt",
+		#{const VK_STRUCTURE_TYPE_SURFACE_PRESENT_MODE_EXT}),
+	("StructureTypeSurfacePresentScalingCapabilitiesExt",
+		#{const VK_STRUCTURE_TYPE_SURFACE_PRESENT_SCALING_CAPABILITIES_EXT}),
+	("StructureTypeSurfacePresentModeCompatibilityExt",
+		#{const VK_STRUCTURE_TYPE_SURFACE_PRESENT_MODE_COMPATIBILITY_EXT}),
+	("StructureTypePhysicalDeviceSwapchainMaintenance1FeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_EXT}),
+	("StructureTypeSwapchainPresentFenceInfoExt",
+		#{const VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_FENCE_INFO_EXT}),
+	("StructureTypeSwapchainPresentModesCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_MODES_CREATE_INFO_EXT}),
+	("StructureTypeSwapchainPresentModeInfoExt",
+		#{const VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_MODE_INFO_EXT}),
+	("StructureTypeSwapchainPresentScalingCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_SCALING_CREATE_INFO_EXT}),
+	("StructureTypeReleaseSwapchainImagesInfoExt",
+		#{const VK_STRUCTURE_TYPE_RELEASE_SWAPCHAIN_IMAGES_INFO_EXT}),
+	("StructureTypePhysicalDeviceDeviceGeneratedCommandsPropertiesNv",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_PROPERTIES_NV}),
+	("StructureTypeGraphicsShaderGroupCreateInfoNv",
+		#{const VK_STRUCTURE_TYPE_GRAPHICS_SHADER_GROUP_CREATE_INFO_NV}),
+	("StructureTypeGraphicsPipelineShaderGroupsCreateInfoNv",
+		#{const VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_SHADER_GROUPS_CREATE_INFO_NV}),
+	("StructureTypeIndirectCommandsLayoutTokenNv",
+		#{const VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_TOKEN_NV}),
+	("StructureTypeIndirectCommandsLayoutCreateInfoNv",
+		#{const VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_CREATE_INFO_NV}),
+	("StructureTypeGeneratedCommandsInfoNv",
+		#{const VK_STRUCTURE_TYPE_GENERATED_COMMANDS_INFO_NV}),
+	("StructureTypeGeneratedCommandsMemoryRequirementsInfoNv",
+		#{const VK_STRUCTURE_TYPE_GENERATED_COMMANDS_MEMORY_REQUIREMENTS_INFO_NV}),
+	("StructureTypePhysicalDeviceDeviceGeneratedCommandsFeaturesNv",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_FEATURES_NV}),
+	("StructureTypePhysicalDeviceInheritedViewportScissorFeaturesNv",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INHERITED_VIEWPORT_SCISSOR_FEATURES_NV}),
+	("StructureTypeCommandBufferInheritanceViewportScissorInfoNv",
+		#{const VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_VIEWPORT_SCISSOR_INFO_NV}),
+	("StructureTypePhysicalDeviceTexelBufferAlignmentFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT}),
+	("StructureTypeCommandBufferInheritanceRenderPassTransformInfoQcom",
+		#{const VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDER_PASS_TRANSFORM_INFO_QCOM}),
+	("StructureTypeRenderPassTransformBeginInfoQcom",
+		#{const VK_STRUCTURE_TYPE_RENDER_PASS_TRANSFORM_BEGIN_INFO_QCOM}),
+	("StructureTypePhysicalDeviceDeviceMemoryReportFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_MEMORY_REPORT_FEATURES_EXT}),
+	("StructureTypeDeviceDeviceMemoryReportCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_DEVICE_DEVICE_MEMORY_REPORT_CREATE_INFO_EXT}),
+	("StructureTypeDeviceMemoryReportCallbackDataExt",
+		#{const VK_STRUCTURE_TYPE_DEVICE_MEMORY_REPORT_CALLBACK_DATA_EXT}),
+	("StructureTypePhysicalDeviceRobustness2FeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceRobustness2PropertiesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_PROPERTIES_EXT}),
+	("StructureTypeSamplerCustomBorderColorCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT}),
+	("StructureTypePhysicalDeviceCustomBorderColorPropertiesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_PROPERTIES_EXT}),
+	("StructureTypePhysicalDeviceCustomBorderColorFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT}),
+	("StructureTypePipelineLibraryCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR}),
+	("StructureTypePhysicalDevicePresentBarrierFeaturesNv",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_BARRIER_FEATURES_NV}),
+	("StructureTypeSurfaceCapabilitiesPresentBarrierNv",
+		#{const VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_PRESENT_BARRIER_NV}),
+	("StructureTypeSwapchainPresentBarrierCreateInfoNv",
+		#{const VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_BARRIER_CREATE_INFO_NV}),
+	("StructureTypePresentIdKhr",
+		#{const VK_STRUCTURE_TYPE_PRESENT_ID_KHR}),
+	("StructureTypePhysicalDevicePresentIdFeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_ID_FEATURES_KHR}),
+	("StructureTypePhysicalDeviceDiagnosticsConfigFeaturesNv",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DIAGNOSTICS_CONFIG_FEATURES_NV}),
+	("StructureTypeDeviceDiagnosticsConfigCreateInfoNv",
+		#{const VK_STRUCTURE_TYPE_DEVICE_DIAGNOSTICS_CONFIG_CREATE_INFO_NV}),
+	("StructureTypeQueryLowLatencySupportNv",
+		#{const VK_STRUCTURE_TYPE_QUERY_LOW_LATENCY_SUPPORT_NV}),
+	("StructureTypeExportMetalObjectCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_EXPORT_METAL_OBJECT_CREATE_INFO_EXT}),
+	("StructureTypeExportMetalObjectsInfoExt",
+		#{const VK_STRUCTURE_TYPE_EXPORT_METAL_OBJECTS_INFO_EXT}),
+	("StructureTypeExportMetalDeviceInfoExt",
+		#{const VK_STRUCTURE_TYPE_EXPORT_METAL_DEVICE_INFO_EXT}),
+	("StructureTypeExportMetalCommandQueueInfoExt",
+		#{const VK_STRUCTURE_TYPE_EXPORT_METAL_COMMAND_QUEUE_INFO_EXT}),
+	("StructureTypeExportMetalBufferInfoExt",
+		#{const VK_STRUCTURE_TYPE_EXPORT_METAL_BUFFER_INFO_EXT}),
+	("StructureTypeImportMetalBufferInfoExt",
+		#{const VK_STRUCTURE_TYPE_IMPORT_METAL_BUFFER_INFO_EXT}),
+	("StructureTypeExportMetalTextureInfoExt",
+		#{const VK_STRUCTURE_TYPE_EXPORT_METAL_TEXTURE_INFO_EXT}),
+	("StructureTypeImportMetalTextureInfoExt",
+		#{const VK_STRUCTURE_TYPE_IMPORT_METAL_TEXTURE_INFO_EXT}),
+	("StructureTypeExportMetalIoSurfaceInfoExt",
+		#{const VK_STRUCTURE_TYPE_EXPORT_METAL_IO_SURFACE_INFO_EXT}),
+	("StructureTypeImportMetalIoSurfaceInfoExt",
+		#{const VK_STRUCTURE_TYPE_IMPORT_METAL_IO_SURFACE_INFO_EXT}),
+	("StructureTypeExportMetalSharedEventInfoExt",
+		#{const VK_STRUCTURE_TYPE_EXPORT_METAL_SHARED_EVENT_INFO_EXT}),
+	("StructureTypeImportMetalSharedEventInfoExt",
+		#{const VK_STRUCTURE_TYPE_IMPORT_METAL_SHARED_EVENT_INFO_EXT}),
+	("StructureTypeQueueFamilyCheckpointProperties2Nv",
+		#{const VK_STRUCTURE_TYPE_QUEUE_FAMILY_CHECKPOINT_PROPERTIES_2_NV}),
+	("StructureTypeCheckpointData2Nv",
+		#{const VK_STRUCTURE_TYPE_CHECKPOINT_DATA_2_NV}),
+	("StructureTypePhysicalDeviceDescriptorBufferPropertiesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_BUFFER_PROPERTIES_EXT}),
+	("StructureTypePhysicalDeviceDescriptorBufferDensityMapPropertiesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_BUFFER_DENSITY_MAP_PROPERTIES_EXT}),
+	("StructureTypePhysicalDeviceDescriptorBufferFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_BUFFER_FEATURES_EXT}),
+	("StructureTypeDescriptorAddressInfoExt",
+		#{const VK_STRUCTURE_TYPE_DESCRIPTOR_ADDRESS_INFO_EXT}),
+	("StructureTypeDescriptorGetInfoExt",
+		#{const VK_STRUCTURE_TYPE_DESCRIPTOR_GET_INFO_EXT}),
+	("StructureTypeBufferCaptureDescriptorDataInfoExt",
+		#{const VK_STRUCTURE_TYPE_BUFFER_CAPTURE_DESCRIPTOR_DATA_INFO_EXT}),
+	("StructureTypeImageCaptureDescriptorDataInfoExt",
+		#{const VK_STRUCTURE_TYPE_IMAGE_CAPTURE_DESCRIPTOR_DATA_INFO_EXT}),
+	("StructureTypeImageViewCaptureDescriptorDataInfoExt",
+		#{const VK_STRUCTURE_TYPE_IMAGE_VIEW_CAPTURE_DESCRIPTOR_DATA_INFO_EXT}),
+	("StructureTypeSamplerCaptureDescriptorDataInfoExt",
+		#{const VK_STRUCTURE_TYPE_SAMPLER_CAPTURE_DESCRIPTOR_DATA_INFO_EXT}),
+	("StructureTypeOpaqueCaptureDescriptorDataCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_OPAQUE_CAPTURE_DESCRIPTOR_DATA_CREATE_INFO_EXT}),
+	("StructureTypeDescriptorBufferBindingInfoExt",
+		#{const VK_STRUCTURE_TYPE_DESCRIPTOR_BUFFER_BINDING_INFO_EXT}),
+	("StructureTypeDescriptorBufferBindingPushDescriptorBufferHandleExt",
+		#{const VK_STRUCTURE_TYPE_DESCRIPTOR_BUFFER_BINDING_PUSH_DESCRIPTOR_BUFFER_HANDLE_EXT}),
+	("StructureTypeAccelerationStructureCaptureDescriptorDataInfoExt",
+		#{const VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CAPTURE_DESCRIPTOR_DATA_INFO_EXT}),
+	("StructureTypePhysicalDeviceGraphicsPipelineLibraryFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceGraphicsPipelineLibraryPropertiesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_PROPERTIES_EXT}),
+	("StructureTypeGraphicsPipelineLibraryCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT}),
+	("StructureTypePhysicalDeviceShaderEarlyAndLateFragmentTestsFeaturesAmd",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_EARLY_AND_LATE_FRAGMENT_TESTS_FEATURES_AMD}),
+	("StructureTypePhysicalDeviceFragmentShaderBarycentricFeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_KHR}),
+	("StructureTypePhysicalDeviceFragmentShaderBarycentricPropertiesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_PROPERTIES_KHR}),
+	("StructureTypePhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_FEATURES_KHR}),
+	("StructureTypePhysicalDeviceFragmentShadingRateEnumsPropertiesNv",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_ENUMS_PROPERTIES_NV}),
+	("StructureTypePhysicalDeviceFragmentShadingRateEnumsFeaturesNv",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_ENUMS_FEATURES_NV}),
+	("StructureTypePipelineFragmentShadingRateEnumStateCreateInfoNv",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_ENUM_STATE_CREATE_INFO_NV}),
+	("StructureTypeAccelerationStructureGeometryMotionTrianglesDataNv",
+		#{const VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_MOTION_TRIANGLES_DATA_NV}),
+	("StructureTypePhysicalDeviceRayTracingMotionBlurFeaturesNv",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_MOTION_BLUR_FEATURES_NV}),
+	("StructureTypeAccelerationStructureMotionInfoNv",
+		#{const VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MOTION_INFO_NV}),
+	("StructureTypePhysicalDeviceMeshShaderFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceMeshShaderPropertiesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_EXT}),
+	("StructureTypePhysicalDeviceYcbcr2Plane444FormatsFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_2_PLANE_444_FORMATS_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceFragmentDensityMap2FeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceFragmentDensityMap2PropertiesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_PROPERTIES_EXT}),
+	("StructureTypeCopyCommandTransformInfoQcom",
+		#{const VK_STRUCTURE_TYPE_COPY_COMMAND_TRANSFORM_INFO_QCOM}),
+	("StructureTypePhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_FEATURES_KHR}),
+	("StructureTypePhysicalDeviceImageCompressionControlFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_FEATURES_EXT}),
+	("StructureTypeImageCompressionControlExt",
+		#{const VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT}),
+	("StructureTypeSubresourceLayout2Ext",
+		#{const VK_STRUCTURE_TYPE_SUBRESOURCE_LAYOUT_2_EXT}),
+	("StructureTypeImageSubresource2Ext",
+		#{const VK_STRUCTURE_TYPE_IMAGE_SUBRESOURCE_2_EXT}),
+	("StructureTypeImageCompressionPropertiesExt",
+		#{const VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_PROPERTIES_EXT}),
+	("StructureTypePhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_FEATURES_EXT}),
+	("StructureTypePhysicalDevice4444FormatsFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceFaultFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FAULT_FEATURES_EXT}),
+	("StructureTypeDeviceFaultCountsExt",
+		#{const VK_STRUCTURE_TYPE_DEVICE_FAULT_COUNTS_EXT}),
+	("StructureTypeDeviceFaultInfoExt",
+		#{const VK_STRUCTURE_TYPE_DEVICE_FAULT_INFO_EXT}),
+	("StructureTypePhysicalDeviceRgba10x6FormatsFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RGBA10X6_FORMATS_FEATURES_EXT}),
+	("StructureTypeDirectfbSurfaceCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_DIRECTFB_SURFACE_CREATE_INFO_EXT}),
+	("StructureTypePhysicalDeviceVertexInputDynamicStateFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_INPUT_DYNAMIC_STATE_FEATURES_EXT}),
+	("StructureTypeVertexInputBindingDescription2Ext",
+		#{const VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT}),
+	("StructureTypeVertexInputAttributeDescription2Ext",
+		#{const VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT}),
+	("StructureTypePhysicalDeviceDrmPropertiesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT}),
+	("StructureTypePhysicalDeviceAddressBindingReportFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ADDRESS_BINDING_REPORT_FEATURES_EXT}),
+	("StructureTypeDeviceAddressBindingCallbackDataExt",
+		#{const VK_STRUCTURE_TYPE_DEVICE_ADDRESS_BINDING_CALLBACK_DATA_EXT}),
+	("StructureTypePhysicalDeviceDepthClipControlFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_CONTROL_FEATURES_EXT}),
+	("StructureTypePipelineViewportDepthClipControlCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT}),
+	("StructureTypePhysicalDevicePrimitiveTopologyListRestartFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT}),
+	("StructureTypeImportMemoryZirconHandleInfoFuchsia",
+		#{const VK_STRUCTURE_TYPE_IMPORT_MEMORY_ZIRCON_HANDLE_INFO_FUCHSIA}),
+	("StructureTypeMemoryZirconHandlePropertiesFuchsia",
+		#{const VK_STRUCTURE_TYPE_MEMORY_ZIRCON_HANDLE_PROPERTIES_FUCHSIA}),
+	("StructureTypeMemoryGetZirconHandleInfoFuchsia",
+		#{const VK_STRUCTURE_TYPE_MEMORY_GET_ZIRCON_HANDLE_INFO_FUCHSIA}),
+	("StructureTypeImportSemaphoreZirconHandleInfoFuchsia",
+		#{const VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_ZIRCON_HANDLE_INFO_FUCHSIA}),
+	("StructureTypeSemaphoreGetZirconHandleInfoFuchsia",
+		#{const VK_STRUCTURE_TYPE_SEMAPHORE_GET_ZIRCON_HANDLE_INFO_FUCHSIA}),
+	("StructureTypeBufferCollectionCreateInfoFuchsia",
+		#{const VK_STRUCTURE_TYPE_BUFFER_COLLECTION_CREATE_INFO_FUCHSIA}),
+	("StructureTypeImportMemoryBufferCollectionFuchsia",
+		#{const VK_STRUCTURE_TYPE_IMPORT_MEMORY_BUFFER_COLLECTION_FUCHSIA}),
+	("StructureTypeBufferCollectionImageCreateInfoFuchsia",
+		#{const VK_STRUCTURE_TYPE_BUFFER_COLLECTION_IMAGE_CREATE_INFO_FUCHSIA}),
+	("StructureTypeBufferCollectionPropertiesFuchsia",
+		#{const VK_STRUCTURE_TYPE_BUFFER_COLLECTION_PROPERTIES_FUCHSIA}),
+	("StructureTypeBufferConstraintsInfoFuchsia",
+		#{const VK_STRUCTURE_TYPE_BUFFER_CONSTRAINTS_INFO_FUCHSIA}),
+	("StructureTypeBufferCollectionBufferCreateInfoFuchsia",
+		#{const VK_STRUCTURE_TYPE_BUFFER_COLLECTION_BUFFER_CREATE_INFO_FUCHSIA}),
+	("StructureTypeImageConstraintsInfoFuchsia",
+		#{const VK_STRUCTURE_TYPE_IMAGE_CONSTRAINTS_INFO_FUCHSIA}),
+	("StructureTypeImageFormatConstraintsInfoFuchsia",
+		#{const VK_STRUCTURE_TYPE_IMAGE_FORMAT_CONSTRAINTS_INFO_FUCHSIA}),
+	("StructureTypeSysmemColorSpaceFuchsia",
+		#{const VK_STRUCTURE_TYPE_SYSMEM_COLOR_SPACE_FUCHSIA}),
+	("StructureTypeBufferCollectionConstraintsInfoFuchsia",
+		#{const VK_STRUCTURE_TYPE_BUFFER_COLLECTION_CONSTRAINTS_INFO_FUCHSIA}),
+	("StructureTypeSubpassShadingPipelineCreateInfoHuawei",
+		#{const VK_STRUCTURE_TYPE_SUBPASS_SHADING_PIPELINE_CREATE_INFO_HUAWEI}),
+	("StructureTypePhysicalDeviceSubpassShadingFeaturesHuawei",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_SHADING_FEATURES_HUAWEI}),
+	("StructureTypePhysicalDeviceSubpassShadingPropertiesHuawei",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_SHADING_PROPERTIES_HUAWEI}),
+	("StructureTypePhysicalDeviceInvocationMaskFeaturesHuawei",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INVOCATION_MASK_FEATURES_HUAWEI}),
+	("StructureTypeMemoryGetRemoteAddressInfoNv",
+		#{const VK_STRUCTURE_TYPE_MEMORY_GET_REMOTE_ADDRESS_INFO_NV}),
+	("StructureTypePhysicalDeviceExternalMemoryRdmaFeaturesNv",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_RDMA_FEATURES_NV}),
+	("StructureTypePipelinePropertiesIdentifierExt",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_PROPERTIES_IDENTIFIER_EXT}),
+	("StructureTypePhysicalDevicePipelinePropertiesFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_PROPERTIES_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceMultisampledRenderToSingleSampledFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_FEATURES_EXT}),
+	("StructureTypeSubpassResolvePerformanceQueryExt",
+		#{const VK_STRUCTURE_TYPE_SUBPASS_RESOLVE_PERFORMANCE_QUERY_EXT}),
+	("StructureTypeMultisampledRenderToSingleSampledInfoExt",
+		#{const VK_STRUCTURE_TYPE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_INFO_EXT}),
+	("StructureTypePhysicalDeviceExtendedDynamicState2FeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT}),
+	("StructureTypeScreenSurfaceCreateInfoQnx",
+		#{const VK_STRUCTURE_TYPE_SCREEN_SURFACE_CREATE_INFO_QNX}),
+	("StructureTypePhysicalDeviceColorWriteEnableFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT}),
+	("StructureTypePipelineColorWriteCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_COLOR_WRITE_CREATE_INFO_EXT}),
+	("StructureTypePhysicalDevicePrimitivesGeneratedQueryFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVES_GENERATED_QUERY_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceRayTracingMaintenance1FeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_MAINTENANCE_1_FEATURES_KHR}),
+	("StructureTypePhysicalDeviceImageViewMinLodFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_MIN_LOD_FEATURES_EXT}),
+	("StructureTypeImageViewMinLodCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_IMAGE_VIEW_MIN_LOD_CREATE_INFO_EXT}),
+	("StructureTypePhysicalDeviceMultiDrawFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceMultiDrawPropertiesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_PROPERTIES_EXT}),
+	("StructureTypePhysicalDeviceImage2dViewOf3dFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_2D_VIEW_OF_3D_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceShaderTileImageFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TILE_IMAGE_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceShaderTileImagePropertiesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TILE_IMAGE_PROPERTIES_EXT}),
+	("StructureTypeMicromapBuildInfoExt",
+		#{const VK_STRUCTURE_TYPE_MICROMAP_BUILD_INFO_EXT}),
+	("StructureTypeMicromapVersionInfoExt",
+		#{const VK_STRUCTURE_TYPE_MICROMAP_VERSION_INFO_EXT}),
+	("StructureTypeCopyMicromapInfoExt",
+		#{const VK_STRUCTURE_TYPE_COPY_MICROMAP_INFO_EXT}),
+	("StructureTypeCopyMicromapToMemoryInfoExt",
+		#{const VK_STRUCTURE_TYPE_COPY_MICROMAP_TO_MEMORY_INFO_EXT}),
+	("StructureTypeCopyMemoryToMicromapInfoExt",
+		#{const VK_STRUCTURE_TYPE_COPY_MEMORY_TO_MICROMAP_INFO_EXT}),
+	("StructureTypePhysicalDeviceOpacityMicromapFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_OPACITY_MICROMAP_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceOpacityMicromapPropertiesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_OPACITY_MICROMAP_PROPERTIES_EXT}),
+	("StructureTypeMicromapCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_MICROMAP_CREATE_INFO_EXT}),
+	("StructureTypeMicromapBuildSizesInfoExt",
+		#{const VK_STRUCTURE_TYPE_MICROMAP_BUILD_SIZES_INFO_EXT}),
+	("StructureTypeAccelerationStructureTrianglesOpacityMicromapExt",
+		#{const VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_TRIANGLES_OPACITY_MICROMAP_EXT}),
+	("StructureTypePhysicalDeviceClusterCullingShaderFeaturesHuawei",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CLUSTER_CULLING_SHADER_FEATURES_HUAWEI}),
+	("StructureTypePhysicalDeviceClusterCullingShaderPropertiesHuawei",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CLUSTER_CULLING_SHADER_PROPERTIES_HUAWEI}),
+	("StructureTypePhysicalDeviceBorderColorSwizzleFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BORDER_COLOR_SWIZZLE_FEATURES_EXT}),
+	("StructureTypeSamplerBorderColorComponentMappingCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_SAMPLER_BORDER_COLOR_COMPONENT_MAPPING_CREATE_INFO_EXT}),
+	("StructureTypePhysicalDevicePageableDeviceLocalMemoryFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PAGEABLE_DEVICE_LOCAL_MEMORY_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceShaderCorePropertiesArm",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_ARM}),
+	("StructureTypePhysicalDeviceImageSlicedViewOf3dFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_SLICED_VIEW_OF_3D_FEATURES_EXT}),
+	("StructureTypeImageViewSlicedCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_IMAGE_VIEW_SLICED_CREATE_INFO_EXT}),
+	("StructureTypePhysicalDeviceDescriptorSetHostMappingFeaturesValve",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_SET_HOST_MAPPING_FEATURES_VALVE}),
+	("StructureTypeDescriptorSetBindingReferenceValve",
+		#{const VK_STRUCTURE_TYPE_DESCRIPTOR_SET_BINDING_REFERENCE_VALVE}),
+	("StructureTypeDescriptorSetLayoutHostMappingInfoValve",
+		#{const VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_HOST_MAPPING_INFO_VALVE}),
+	("StructureTypePhysicalDeviceDepthClampZeroOneFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLAMP_ZERO_ONE_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceNonSeamlessCubeMapFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_NON_SEAMLESS_CUBE_MAP_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceFragmentDensityMapOffsetFeaturesQcom",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_FEATURES_QCOM}),
+	("StructureTypePhysicalDeviceFragmentDensityMapOffsetPropertiesQcom",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_PROPERTIES_QCOM}),
+	("StructureTypeSubpassFragmentDensityMapOffsetEndInfoQcom",
+		#{const VK_STRUCTURE_TYPE_SUBPASS_FRAGMENT_DENSITY_MAP_OFFSET_END_INFO_QCOM}),
+	("StructureTypePhysicalDeviceCopyMemoryIndirectFeaturesNv",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COPY_MEMORY_INDIRECT_FEATURES_NV}),
+	("StructureTypePhysicalDeviceCopyMemoryIndirectPropertiesNv",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COPY_MEMORY_INDIRECT_PROPERTIES_NV}),
+	("StructureTypePhysicalDeviceMemoryDecompressionFeaturesNv",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_DECOMPRESSION_FEATURES_NV}),
+	("StructureTypePhysicalDeviceMemoryDecompressionPropertiesNv",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_DECOMPRESSION_PROPERTIES_NV}),
+	("StructureTypePhysicalDeviceLinearColorAttachmentFeaturesNv",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINEAR_COLOR_ATTACHMENT_FEATURES_NV}),
+	("StructureTypePhysicalDeviceImageCompressionControlSwapchainFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceImageProcessingFeaturesQcom",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_PROCESSING_FEATURES_QCOM}),
+	("StructureTypePhysicalDeviceImageProcessingPropertiesQcom",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_PROCESSING_PROPERTIES_QCOM}),
+	("StructureTypeImageViewSampleWeightCreateInfoQcom",
+		#{const VK_STRUCTURE_TYPE_IMAGE_VIEW_SAMPLE_WEIGHT_CREATE_INFO_QCOM}),
+	("StructureTypePhysicalDeviceExtendedDynamicState3FeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_3_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceExtendedDynamicState3PropertiesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_3_PROPERTIES_EXT}),
+	("StructureTypePhysicalDeviceSubpassMergeFeedbackFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_MERGE_FEEDBACK_FEATURES_EXT}),
+	("StructureTypeRenderPassCreationControlExt",
+		#{const VK_STRUCTURE_TYPE_RENDER_PASS_CREATION_CONTROL_EXT}),
+	("StructureTypeRenderPassCreationFeedbackCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_RENDER_PASS_CREATION_FEEDBACK_CREATE_INFO_EXT}),
+	("StructureTypeRenderPassSubpassFeedbackCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_RENDER_PASS_SUBPASS_FEEDBACK_CREATE_INFO_EXT}),
+	("StructureTypeDirectDriverLoadingInfoLunarg",
+		#{const VK_STRUCTURE_TYPE_DIRECT_DRIVER_LOADING_INFO_LUNARG}),
+	("StructureTypeDirectDriverLoadingListLunarg",
+		#{const VK_STRUCTURE_TYPE_DIRECT_DRIVER_LOADING_LIST_LUNARG}),
+	("StructureTypePhysicalDeviceShaderModuleIdentifierFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MODULE_IDENTIFIER_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceShaderModuleIdentifierPropertiesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MODULE_IDENTIFIER_PROPERTIES_EXT}),
+	("StructureTypePipelineShaderStageModuleIdentifierCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_MODULE_IDENTIFIER_CREATE_INFO_EXT}),
+	("StructureTypeShaderModuleIdentifierExt",
+		#{const VK_STRUCTURE_TYPE_SHADER_MODULE_IDENTIFIER_EXT}),
+	("StructureTypePhysicalDeviceRasterizationOrderAttachmentAccessFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceOpticalFlowFeaturesNv",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_OPTICAL_FLOW_FEATURES_NV}),
+	("StructureTypePhysicalDeviceOpticalFlowPropertiesNv",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_OPTICAL_FLOW_PROPERTIES_NV}),
+	("StructureTypeOpticalFlowImageFormatInfoNv",
+		#{const VK_STRUCTURE_TYPE_OPTICAL_FLOW_IMAGE_FORMAT_INFO_NV}),
+	("StructureTypeOpticalFlowImageFormatPropertiesNv",
+		#{const VK_STRUCTURE_TYPE_OPTICAL_FLOW_IMAGE_FORMAT_PROPERTIES_NV}),
+	("StructureTypeOpticalFlowSessionCreateInfoNv",
+		#{const VK_STRUCTURE_TYPE_OPTICAL_FLOW_SESSION_CREATE_INFO_NV}),
+	("StructureTypeOpticalFlowExecuteInfoNv",
+		#{const VK_STRUCTURE_TYPE_OPTICAL_FLOW_EXECUTE_INFO_NV}),
+	("StructureTypeOpticalFlowSessionCreatePrivateDataInfoNv",
+		#{const VK_STRUCTURE_TYPE_OPTICAL_FLOW_SESSION_CREATE_PRIVATE_DATA_INFO_NV}),
+	("StructureTypePhysicalDeviceLegacyDitheringFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LEGACY_DITHERING_FEATURES_EXT}),
+	("StructureTypePhysicalDevicePipelineProtectedAccessFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_PROTECTED_ACCESS_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceRayTracingPositionFetchFeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_POSITION_FETCH_FEATURES_KHR}),
+	("StructureTypePhysicalDeviceShaderObjectFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceShaderObjectPropertiesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_PROPERTIES_EXT}),
+	("StructureTypeShaderCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT}),
+	("StructureTypePhysicalDeviceTilePropertiesFeaturesQcom",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TILE_PROPERTIES_FEATURES_QCOM}),
+	("StructureTypeTilePropertiesQcom",
+		#{const VK_STRUCTURE_TYPE_TILE_PROPERTIES_QCOM}),
+	("StructureTypePhysicalDeviceAmigoProfilingFeaturesSec",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_AMIGO_PROFILING_FEATURES_SEC}),
+	("StructureTypeAmigoProfilingSubmitInfoSec",
+		#{const VK_STRUCTURE_TYPE_AMIGO_PROFILING_SUBMIT_INFO_SEC}),
+	("StructureTypePhysicalDeviceMultiviewPerViewViewportsFeaturesQcom",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_VIEWPORTS_FEATURES_QCOM}),
+	("StructureTypePhysicalDeviceRayTracingInvocationReorderFeaturesNv",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_INVOCATION_REORDER_FEATURES_NV}),
+	("StructureTypePhysicalDeviceRayTracingInvocationReorderPropertiesNv",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_INVOCATION_REORDER_PROPERTIES_NV}),
+	("StructureTypePhysicalDeviceMutableDescriptorTypeFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_EXT}),
+	("StructureTypeMutableDescriptorTypeCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_EXT}),
+	("StructureTypePhysicalDeviceShaderCoreBuiltinsFeaturesArm",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_BUILTINS_FEATURES_ARM}),
+	("StructureTypePhysicalDeviceShaderCoreBuiltinsPropertiesArm",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_BUILTINS_PROPERTIES_ARM}),
+	("StructureTypePhysicalDevicePipelineLibraryGroupHandlesFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_LIBRARY_GROUP_HANDLES_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceMultiviewPerViewRenderAreasFeaturesQcom",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_RENDER_AREAS_FEATURES_QCOM}),
+	("StructureTypeMultiviewPerViewRenderAreasRenderPassBeginInfoQcom",
+		#{const VK_STRUCTURE_TYPE_MULTIVIEW_PER_VIEW_RENDER_AREAS_RENDER_PASS_BEGIN_INFO_QCOM}),
+	("StructureTypePhysicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_DYNAMIC_STATE_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceVariablePointerFeatures",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES}),
+	("StructureTypePhysicalDeviceShaderDrawParameterFeatures",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES}),
+	("StructureTypeDebugReportCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT}),
+	("StructureTypeRenderingInfoKhr",
+		#{const VK_STRUCTURE_TYPE_RENDERING_INFO_KHR}),
+	("StructureTypeRenderingAttachmentInfoKhr",
+		#{const VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR}),
+	("StructureTypePipelineRenderingCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR}),
+	("StructureTypePhysicalDeviceDynamicRenderingFeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR}),
+	("StructureTypeCommandBufferInheritanceRenderingInfoKhr",
+		#{const VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR}),
+	("StructureTypeAttachmentSampleCountInfoNv",
+		#{const VK_STRUCTURE_TYPE_ATTACHMENT_SAMPLE_COUNT_INFO_NV}),
+	("StructureTypeRenderPassMultiviewCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHR}),
+	("StructureTypePhysicalDeviceMultiviewFeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR}),
+	("StructureTypePhysicalDeviceMultiviewPropertiesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR}),
+	("StructureTypePhysicalDeviceFeatures2Khr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR}),
+	("StructureTypePhysicalDeviceProperties2Khr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR}),
+	("StructureTypeFormatProperties2Khr",
+		#{const VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR}),
+	("StructureTypeImageFormatProperties2Khr",
+		#{const VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR}),
+	("StructureTypePhysicalDeviceImageFormatInfo2Khr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR}),
+	("StructureTypeQueueFamilyProperties2Khr",
+		#{const VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2_KHR}),
+	("StructureTypePhysicalDeviceMemoryProperties2Khr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2_KHR}),
+	("StructureTypeSparseImageFormatProperties2Khr",
+		#{const VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2_KHR}),
+	("StructureTypePhysicalDeviceSparseImageFormatInfo2Khr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2_KHR}),
+	("StructureTypeMemoryAllocateFlagsInfoKhr",
+		#{const VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO_KHR}),
+	("StructureTypeDeviceGroupRenderPassBeginInfoKhr",
+		#{const VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO_KHR}),
+	("StructureTypeDeviceGroupCommandBufferBeginInfoKhr",
+		#{const VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO_KHR}),
+	("StructureTypeDeviceGroupSubmitInfoKhr",
+		#{const VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO_KHR}),
+	("StructureTypeDeviceGroupBindSparseInfoKhr",
+		#{const VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO_KHR}),
+	("StructureTypeBindBufferMemoryDeviceGroupInfoKhr",
+		#{const VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO_KHR}),
+	("StructureTypeBindImageMemoryDeviceGroupInfoKhr",
+		#{const VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO_KHR}),
+	("StructureTypePhysicalDeviceTextureCompressionAstcHdrFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceGroupPropertiesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHR}),
+	("StructureTypeDeviceGroupDeviceCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO_KHR}),
+	("StructureTypePhysicalDeviceExternalImageFormatInfoKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHR}),
+	("StructureTypeExternalImageFormatPropertiesKhr",
+		#{const VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR}),
+	("StructureTypePhysicalDeviceExternalBufferInfoKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO_KHR}),
+	("StructureTypeExternalBufferPropertiesKhr",
+		#{const VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES_KHR}),
+	("StructureTypePhysicalDeviceIdPropertiesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHR}),
+	("StructureTypeExternalMemoryBufferCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR}),
+	("StructureTypeExternalMemoryImageCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR}),
+	("StructureTypeExportMemoryAllocateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR}),
+	("StructureTypePhysicalDeviceExternalSemaphoreInfoKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR}),
+	("StructureTypeExternalSemaphorePropertiesKhr",
+		#{const VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR}),
+	("StructureTypeExportSemaphoreCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR}),
+	("StructureTypePhysicalDeviceShaderFloat16Int8FeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR}),
+	("StructureTypePhysicalDeviceFloat16Int8FeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR}),
+	("StructureTypePhysicalDevice16bitStorageFeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR}),
+	("StructureTypeDescriptorUpdateTemplateCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR}),
+	("StructureTypePhysicalDeviceImagelessFramebufferFeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR}),
+	("StructureTypeFramebufferAttachmentsCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR}),
+	("StructureTypeFramebufferAttachmentImageInfoKhr",
+		#{const VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR}),
+	("StructureTypeRenderPassAttachmentBeginInfoKhr",
+		#{const VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR}),
+	("StructureTypeAttachmentDescription2Khr",
+		#{const VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR}),
+	("StructureTypeAttachmentReference2Khr",
+		#{const VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR}),
+	("StructureTypeSubpassDescription2Khr",
+		#{const VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR}),
+	("StructureTypeSubpassDependency2Khr",
+		#{const VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR}),
+	("StructureTypeRenderPassCreateInfo2Khr",
+		#{const VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR}),
+	("StructureTypeSubpassBeginInfoKhr",
+		#{const VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO_KHR}),
+	("StructureTypeSubpassEndInfoKhr",
+		#{const VK_STRUCTURE_TYPE_SUBPASS_END_INFO_KHR}),
+	("StructureTypePhysicalDeviceExternalFenceInfoKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR}),
+	("StructureTypeExternalFencePropertiesKhr",
+		#{const VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR}),
+	("StructureTypeExportFenceCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO_KHR}),
+	("StructureTypePhysicalDevicePointClippingPropertiesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES_KHR}),
+	("StructureTypeRenderPassInputAttachmentAspectCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO_KHR}),
+	("StructureTypeImageViewUsageCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR}),
+	("StructureTypePipelineTessellationDomainOriginStateCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO_KHR}),
+	("StructureTypePhysicalDeviceVariablePointersFeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES_KHR}),
+	("StructureTypePhysicalDeviceVariablePointerFeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR}),
+	("StructureTypeMemoryDedicatedRequirementsKhr",
+		#{const VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR}),
+	("StructureTypeMemoryDedicatedAllocateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR}),
+	("StructureTypePhysicalDeviceSamplerFilterMinmaxPropertiesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT}),
+	("StructureTypeSamplerReductionModeCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT}),
+	("StructureTypePhysicalDeviceInlineUniformBlockFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceInlineUniformBlockPropertiesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT}),
+	("StructureTypeWriteDescriptorSetInlineUniformBlockExt",
+		#{const VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT}),
+	("StructureTypeDescriptorPoolInlineUniformBlockCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO_EXT}),
+	("StructureTypeBufferMemoryRequirementsInfo2Khr",
+		#{const VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR}),
+	("StructureTypeImageMemoryRequirementsInfo2Khr",
+		#{const VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR}),
+	("StructureTypeImageSparseMemoryRequirementsInfo2Khr",
+		#{const VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2_KHR}),
+	("StructureTypeMemoryRequirements2Khr",
+		#{const VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR}),
+	("StructureTypeSparseImageMemoryRequirements2Khr",
+		#{const VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2_KHR}),
+	("StructureTypeImageFormatListCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR}),
+	("StructureTypeSamplerYcbcrConversionCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO_KHR}),
+	("StructureTypeSamplerYcbcrConversionInfoKhr",
+		#{const VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO_KHR}),
+	("StructureTypeBindImagePlaneMemoryInfoKhr",
+		#{const VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO_KHR}),
+	("StructureTypeImagePlaneMemoryRequirementsInfoKhr",
+		#{const VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO_KHR}),
+	("StructureTypePhysicalDeviceSamplerYcbcrConversionFeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES_KHR}),
+	("StructureTypeSamplerYcbcrConversionImageFormatPropertiesKhr",
+		#{const VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES_KHR}),
+	("StructureTypeBindBufferMemoryInfoKhr",
+		#{const VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO_KHR}),
+	("StructureTypeBindImageMemoryInfoKhr",
+		#{const VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO_KHR}),
+	("StructureTypeDescriptorSetLayoutBindingFlagsCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT}),
+	("StructureTypePhysicalDeviceDescriptorIndexingFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceDescriptorIndexingPropertiesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT}),
+	("StructureTypeDescriptorSetVariableDescriptorCountAllocateInfoExt",
+		#{const VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT}),
+	("StructureTypeDescriptorSetVariableDescriptorCountLayoutSupportExt",
+		#{const VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT}),
+	("StructureTypePhysicalDeviceMaintenance3PropertiesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES_KHR}),
+	("StructureTypeDescriptorSetLayoutSupportKhr",
+		#{const VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT_KHR}),
+	("StructureTypeDeviceQueueGlobalPriorityCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT}),
+	("StructureTypePhysicalDeviceShaderSubgroupExtendedTypesFeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES_KHR}),
+	("StructureTypePhysicalDevice8bitStorageFeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR}),
+	("StructureTypePhysicalDeviceShaderAtomicInt64FeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR}),
+	("StructureTypePipelineCreationFeedbackCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO_EXT}),
+	("StructureTypePhysicalDeviceDriverPropertiesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR}),
+	("StructureTypePhysicalDeviceFloatControlsPropertiesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR}),
+	("StructureTypePhysicalDeviceDepthStencilResolvePropertiesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR}),
+	("StructureTypeSubpassDescriptionDepthStencilResolveKhr",
+		#{const VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR}),
+	("StructureTypePhysicalDeviceFragmentShaderBarycentricFeaturesNv",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_NV}),
+	("StructureTypePhysicalDeviceTimelineSemaphoreFeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR}),
+	("StructureTypePhysicalDeviceTimelineSemaphorePropertiesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES_KHR}),
+	("StructureTypeSemaphoreTypeCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR}),
+	("StructureTypeTimelineSemaphoreSubmitInfoKhr",
+		#{const VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR}),
+	("StructureTypeSemaphoreWaitInfoKhr",
+		#{const VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO_KHR}),
+	("StructureTypeSemaphoreSignalInfoKhr",
+		#{const VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO_KHR}),
+	("StructureTypeQueryPoolCreateInfoIntel",
+		#{const VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO_INTEL}),
+	("StructureTypePhysicalDeviceVulkanMemoryModelFeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR}),
+	("StructureTypePhysicalDeviceShaderTerminateInvocationFeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES_KHR}),
+	("StructureTypePhysicalDeviceScalarBlockLayoutFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceSubgroupSizeControlPropertiesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT}),
+	("StructureTypePipelineShaderStageRequiredSubgroupSizeCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT}),
+	("StructureTypePhysicalDeviceSubgroupSizeControlFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceSeparateDepthStencilLayoutsFeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES_KHR}),
+	("StructureTypeAttachmentReferenceStencilLayoutKhr",
+		#{const VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR}),
+	("StructureTypeAttachmentDescriptionStencilLayoutKhr",
+		#{const VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT_KHR}),
+	("StructureTypePhysicalDeviceBufferAddressFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_ADDRESS_FEATURES_EXT}),
+	("StructureTypeBufferDeviceAddressInfoExt",
+		#{const VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_EXT}),
+	("StructureTypePhysicalDeviceToolPropertiesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT}),
+	("StructureTypeImageStencilUsageCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT}),
+	("StructureTypePhysicalDeviceUniformBufferStandardLayoutFeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR}),
+	("StructureTypePhysicalDeviceBufferDeviceAddressFeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR}),
+	("StructureTypeBufferDeviceAddressInfoKhr",
+		#{const VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR}),
+	("StructureTypeBufferOpaqueCaptureAddressCreateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO_KHR}),
+	("StructureTypeMemoryOpaqueCaptureAddressAllocateInfoKhr",
+		#{const VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO_KHR}),
+	("StructureTypeDeviceMemoryOpaqueCaptureAddressInfoKhr",
+		#{const VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO_KHR}),
+	("StructureTypePhysicalDeviceHostQueryResetFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceShaderDemoteToHelperInvocationFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT}),
+	("StructureTypePhysicalDeviceShaderIntegerDotProductFeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES_KHR}),
+	("StructureTypePhysicalDeviceShaderIntegerDotProductPropertiesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES_KHR}),
+	("StructureTypePhysicalDeviceTexelBufferAlignmentPropertiesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT}),
+	("StructureTypePhysicalDevicePrivateDataFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT}),
+	("StructureTypeDevicePrivateDataCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO_EXT}),
+	("StructureTypePrivateDataSlotCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO_EXT}),
+	("StructureTypePhysicalDevicePipelineCreationCacheControlFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES_EXT}),
+	("StructureTypeMemoryBarrier2Khr",
+		#{const VK_STRUCTURE_TYPE_MEMORY_BARRIER_2_KHR}),
+	("StructureTypeBufferMemoryBarrier2Khr",
+		#{const VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2_KHR}),
+	("StructureTypeImageMemoryBarrier2Khr",
+		#{const VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2_KHR}),
+	("StructureTypeDependencyInfoKhr",
+		#{const VK_STRUCTURE_TYPE_DEPENDENCY_INFO_KHR}),
+	("StructureTypeSubmitInfo2Khr",
+		#{const VK_STRUCTURE_TYPE_SUBMIT_INFO_2_KHR}),
+	("StructureTypeSemaphoreSubmitInfoKhr",
+		#{const VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO_KHR}),
+	("StructureTypeCommandBufferSubmitInfoKhr",
+		#{const VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO_KHR}),
+	("StructureTypePhysicalDeviceSynchronization2FeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES_KHR}),
+	("StructureTypePhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES_KHR}),
+	("StructureTypePhysicalDeviceImageRobustnessFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES_EXT}),
+	("StructureTypeCopyBufferInfo2Khr",
+		#{const VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2_KHR}),
+	("StructureTypeCopyImageInfo2Khr",
+		#{const VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR}),
+	("StructureTypeCopyBufferToImageInfo2Khr",
+		#{const VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR}),
+	("StructureTypeCopyImageToBufferInfo2Khr",
+		#{const VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2_KHR}),
+	("StructureTypeBlitImageInfo2Khr",
+		#{const VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR}),
+	("StructureTypeResolveImageInfo2Khr",
+		#{const VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2_KHR}),
+	("StructureTypeBufferCopy2Khr",
+		#{const VK_STRUCTURE_TYPE_BUFFER_COPY_2_KHR}),
+	("StructureTypeImageCopy2Khr",
+		#{const VK_STRUCTURE_TYPE_IMAGE_COPY_2_KHR}),
+	("StructureTypeImageBlit2Khr",
+		#{const VK_STRUCTURE_TYPE_IMAGE_BLIT_2_KHR}),
+	("StructureTypeBufferImageCopy2Khr",
+		#{const VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2_KHR}),
+	("StructureTypeImageResolve2Khr",
+		#{const VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR}),
+	("StructureTypePhysicalDeviceRasterizationOrderAttachmentAccessFeaturesArm",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_ARM}),
+	("StructureTypePhysicalDeviceMutableDescriptorTypeFeaturesValve",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_VALVE}),
+	("StructureTypeMutableDescriptorTypeCreateInfoValve",
+		#{const VK_STRUCTURE_TYPE_MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_VALVE}),
+	("StructureTypeFormatProperties3Khr",
+		#{const VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR}),
+	("StructureTypePipelineInfoExt",
+		#{const VK_STRUCTURE_TYPE_PIPELINE_INFO_EXT}),
+	("StructureTypePhysicalDeviceGlobalPriorityQueryFeaturesExt",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_EXT}),
+	("StructureTypeQueueFamilyGlobalPriorityPropertiesExt",
+		#{const VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_EXT}),
+	("StructureTypePhysicalDeviceMaintenance4FeaturesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES_KHR}),
+	("StructureTypePhysicalDeviceMaintenance4PropertiesKhr",
+		#{const VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES_KHR}),
+	("StructureTypeDeviceBufferMemoryRequirementsKhr",
+		#{const VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS_KHR}),
+	("StructureTypeDeviceImageMemoryRequirementsKhr",
+		#{const VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS_KHR}),
+	("StructureTypeShaderRequiredSubgroupSizeCreateInfoExt",
+		#{const VK_STRUCTURE_TYPE_SHADER_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT}),
+	("StructureTypeMaxEnum", #{const VK_STRUCTURE_TYPE_MAX_ENUM}) ]
+
+enum "SystemAllocationScope" ''#{type VkSystemAllocationScope}
+		[''Show, ''Eq, ''Storable] [
+	("SystemAllocationScopeCommand",
+		#{const VK_SYSTEM_ALLOCATION_SCOPE_COMMAND}),
+	("SystemAllocationScopeObject",
+		#{const VK_SYSTEM_ALLOCATION_SCOPE_OBJECT}),
+	("SystemAllocationScopeCache",
+		#{const VK_SYSTEM_ALLOCATION_SCOPE_CACHE}),
+	("SystemAllocationScopeDevice",
+		#{const VK_SYSTEM_ALLOCATION_SCOPE_DEVICE}),
+	("SystemAllocationScopeInstance",
+		#{const VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE}),
+	("SystemAllocationScopeMaxEnum",
+		#{const VK_SYSTEM_ALLOCATION_SCOPE_MAX_ENUM}) ]
+
+enum "InternalAllocationType" ''#{type VkInternalAllocationType}
+		[''Show, ''Eq, ''Storable] [
+	("InternalAllocationTypeExecutable",
+		#{const VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE}),
+	("InternalAllocationTypeMaxEnum",
+		#{const VK_INTERNAL_ALLOCATION_TYPE_MAX_ENUM}) ]
+
+enum "ObjectType" ''#{type VkObjectType}
+		[''Show, ''Eq, ''Storable] [
+	("ObjectTypeUnknown", #{const VK_OBJECT_TYPE_UNKNOWN}),
+	("ObjectTypeInstance", #{const VK_OBJECT_TYPE_INSTANCE}),
+	("ObjectTypePhysicalDevice", #{const VK_OBJECT_TYPE_PHYSICAL_DEVICE}),
+	("ObjectTypeDevice", #{const VK_OBJECT_TYPE_DEVICE}),
+	("ObjectTypeQueue", #{const VK_OBJECT_TYPE_QUEUE}),
+	("ObjectTypeSemaphore", #{const VK_OBJECT_TYPE_SEMAPHORE}),
+	("ObjectTypeCommandBuffer", #{const VK_OBJECT_TYPE_COMMAND_BUFFER}),
+	("ObjectTypeFence", #{const VK_OBJECT_TYPE_FENCE}),
+	("ObjectTypeDeviceMemory", #{const VK_OBJECT_TYPE_DEVICE_MEMORY}),
+	("ObjectTypeBuffer", #{const VK_OBJECT_TYPE_BUFFER}),
+	("ObjectTypeImage", #{const VK_OBJECT_TYPE_IMAGE}),
+	("ObjectTypeEvent", #{const VK_OBJECT_TYPE_EVENT}),
+	("ObjectTypeQueryPool", #{const VK_OBJECT_TYPE_QUERY_POOL}),
+	("ObjectTypeBufferView", #{const VK_OBJECT_TYPE_BUFFER_VIEW}),
+	("ObjectTypeImageView", #{const VK_OBJECT_TYPE_IMAGE_VIEW}),
+	("ObjectTypeShaderModule", #{const VK_OBJECT_TYPE_SHADER_MODULE}),
+	("ObjectTypePipelineCache", #{const VK_OBJECT_TYPE_PIPELINE_CACHE}),
+	("ObjectTypePipelineLayout", #{const VK_OBJECT_TYPE_PIPELINE_LAYOUT}),
+	("ObjectTypeRenderPass", #{const VK_OBJECT_TYPE_RENDER_PASS}),
+	("ObjectTypePipeline", #{const VK_OBJECT_TYPE_PIPELINE}),
+	("ObjectTypeDescriptorSetLayout",
+		#{const VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT}),
+	("ObjectTypeSampler", #{const VK_OBJECT_TYPE_SAMPLER}),
+	("ObjectTypeDescriptorPool", #{const VK_OBJECT_TYPE_DESCRIPTOR_POOL}),
+	("ObjectTypeDescriptorSet", #{const VK_OBJECT_TYPE_DESCRIPTOR_SET}),
+	("ObjectTypeFramebuffer", #{const VK_OBJECT_TYPE_FRAMEBUFFER}),
+	("ObjectTypeCommandPool", #{const VK_OBJECT_TYPE_COMMAND_POOL}),
+	("ObjectTypeSamplerYcbcrConversion",
+		#{const VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION}),
+	("ObjectTypeDescriptorUpdateTemplate",
+		#{const VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE}),
+	("ObjectTypePrivateDataSlot",
+		#{const VK_OBJECT_TYPE_PRIVATE_DATA_SLOT}),
+	("ObjectTypeSurfaceKhr", #{const VK_OBJECT_TYPE_SURFACE_KHR}),
+	("ObjectTypeSwapchainKhr", #{const VK_OBJECT_TYPE_SWAPCHAIN_KHR}),
+	("ObjectTypeDisplayKhr", #{const VK_OBJECT_TYPE_DISPLAY_KHR}),
+	("ObjectTypeDisplayModeKhr", #{const VK_OBJECT_TYPE_DISPLAY_MODE_KHR}),
+	("ObjectTypeDebugReportCallbackExt",
+		#{const VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT}),
+	("ObjectTypeVideoSessionKhr",
+		#{const VK_OBJECT_TYPE_VIDEO_SESSION_KHR}),
+	("ObjectTypeVideoSessionParametersKhr",
+		#{const VK_OBJECT_TYPE_VIDEO_SESSION_PARAMETERS_KHR}),
+	("ObjectTypeCuModuleNvx", #{const VK_OBJECT_TYPE_CU_MODULE_NVX}),
+	("ObjectTypeCuFunctionNvx", #{const VK_OBJECT_TYPE_CU_FUNCTION_NVX}),
+	("ObjectTypeDebugUtilsMessengerExt",
+		#{const VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT}),
+	("ObjectTypeAccelerationStructureKhr",
+		#{const VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR}),
+	("ObjectTypeValidationCacheExt",
+		#{const VK_OBJECT_TYPE_VALIDATION_CACHE_EXT}),
+	("ObjectTypeAccelerationStructureNv",
+		#{const VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV}),
+	("ObjectTypePerformanceConfigurationIntel",
+		#{const VK_OBJECT_TYPE_PERFORMANCE_CONFIGURATION_INTEL}),
+	("ObjectTypeDeferredOperationKhr",
+		#{const VK_OBJECT_TYPE_DEFERRED_OPERATION_KHR}),
+	("ObjectTypeIndirectCommandsLayoutNv",
+		#{const VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NV}),
+	("ObjectTypeBufferCollectionFuchsia",
+		#{const VK_OBJECT_TYPE_BUFFER_COLLECTION_FUCHSIA}),
+	("ObjectTypeMicromapExt", #{const VK_OBJECT_TYPE_MICROMAP_EXT}),
+	("ObjectTypeOpticalFlowSessionNv",
+		#{const VK_OBJECT_TYPE_OPTICAL_FLOW_SESSION_NV}),
+	("ObjectTypeShaderExt", #{const VK_OBJECT_TYPE_SHADER_EXT}),
+	("ObjectTypeDescriptorUpdateTemplateKhr",
+		#{const VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR}),
+	("ObjectTypeSamplerYcbcrConversionKhr",
+		#{const VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR}),
+	("ObjectTypePrivateDataSlotExt",
+		#{const VK_OBJECT_TYPE_PRIVATE_DATA_SLOT_EXT}),
+	("ObjectTypeMaxEnum", #{const VK_OBJECT_TYPE_MAX_ENUM}) ]
+
+enum "SharingMode" ''#{type VkSharingMode}
+		[''Show, ''Eq, ''Storable] [
+	("SharingModeExclusive", #{const VK_SHARING_MODE_EXCLUSIVE}),
+	("SharingModeConcurrent", #{const VK_SHARING_MODE_CONCURRENT}),
+	("SharingModeMaxEnum", #{const VK_SHARING_MODE_MAX_ENUM}) ]
+
+enum "PrimitiveTopology" ''#{type VkPrimitiveTopology}
+		[''Show, ''Eq, ''Storable] [
+	("PrimitiveTopologyPointList",
+		#{const VK_PRIMITIVE_TOPOLOGY_POINT_LIST}),
+	("PrimitiveTopologyLineList", #{const VK_PRIMITIVE_TOPOLOGY_LINE_LIST}),
+	("PrimitiveTopologyLineStrip",
+		#{const VK_PRIMITIVE_TOPOLOGY_LINE_STRIP}),
+	("PrimitiveTopologyTriangleList",
+		#{const VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST}),
+	("PrimitiveTopologyTriangleStrip",
+		#{const VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP}),
+	("PrimitiveTopologyTriangleFan",
+		#{const VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN}),
+	("PrimitiveTopologyLineListWithAdjacency",
+		#{const VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY}),
+	("PrimitiveTopologyLineStripWithAdjacency",
+		#{const VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY}),
+	("PrimitiveTopologyTriangleListWithAdjacency",
+		#{const VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY}),
+	("PrimitiveTopologyTriangleStripWithAdjacency",
+		#{const VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY}),
+	("PrimitiveTopologyPatchList",
+		#{const VK_PRIMITIVE_TOPOLOGY_PATCH_LIST}),
+	("PrimitiveTopologyMaxEnum", #{const VK_PRIMITIVE_TOPOLOGY_MAX_ENUM}) ]
+
+enum "PolygonMode" ''#{type VkPolygonMode}
+		[''Show, ''Eq, ''Storable] [
+	("PolygonModeFill", #{const VK_POLYGON_MODE_FILL}),
+	("PolygonModeLine", #{const VK_POLYGON_MODE_LINE}),
+	("PolygonModePoint", #{const VK_POLYGON_MODE_POINT}),
+	("PolygonModeFillRectangleNv",
+		#{const VK_POLYGON_MODE_FILL_RECTANGLE_NV}),
+	("PolygonModeMaxEnum", #{const VK_POLYGON_MODE_MAX_ENUM}) ]
+
+enum "FrontFace" ''#{type VkFrontFace}
+		[''Show, ''Eq, ''Storable] [
+	("FrontFaceCounterClockwise", #{const VK_FRONT_FACE_COUNTER_CLOCKWISE}),
+	("FrontFaceClockwise", #{const VK_FRONT_FACE_CLOCKWISE}),
+	("FrontFaceMaxEnum", #{const VK_FRONT_FACE_MAX_ENUM}) ]
+
+enum "CompareOp" ''#{type VkCompareOp}
+		[''Show, ''Eq, ''Storable] [
+	("CompareOpNever", #{const VK_COMPARE_OP_NEVER}),
+	("CompareOpLess", #{const VK_COMPARE_OP_LESS}),
+	("CompareOpEqual", #{const VK_COMPARE_OP_EQUAL}),
+	("CompareOpLessOrEqual", #{const VK_COMPARE_OP_LESS_OR_EQUAL}),
+	("CompareOpGreater", #{const VK_COMPARE_OP_GREATER}),
+	("CompareOpNotEqual", #{const VK_COMPARE_OP_NOT_EQUAL}),
+	("CompareOpGreaterOrEqual", #{const VK_COMPARE_OP_GREATER_OR_EQUAL}),
+	("CompareOpAlways", #{const VK_COMPARE_OP_ALWAYS}),
+	("CompareOpMaxEnum", #{const VK_COMPARE_OP_MAX_ENUM}) ]
+
+enum "StencilOp" ''#{type VkStencilOp}
+		[''Show, ''Eq, ''Storable] [
+	("StencilOpKeep", #{const VK_STENCIL_OP_KEEP}),
+	("StencilOpZero", #{const VK_STENCIL_OP_ZERO}),
+	("StencilOpReplace", #{const VK_STENCIL_OP_REPLACE}),
+	("StencilOpIncrementAndClamp",
+		#{const VK_STENCIL_OP_INCREMENT_AND_CLAMP}),
+	("StencilOpDecrementAndClamp",
+		#{const VK_STENCIL_OP_DECREMENT_AND_CLAMP}),
+	("StencilOpInvert", #{const VK_STENCIL_OP_INVERT}),
+	("StencilOpIncrementAndWrap",
+		#{const VK_STENCIL_OP_INCREMENT_AND_WRAP}),
+	("StencilOpDecrementAndWrap",
+		#{const VK_STENCIL_OP_DECREMENT_AND_WRAP}),
+	("StencilOpMaxEnum", #{const VK_STENCIL_OP_MAX_ENUM}) ]
+
+enum "BlendFactor" ''#{type VkBlendFactor}
+		[''Show, ''Eq, ''Storable] [
+	("BlendFactorZero", #{const VK_BLEND_FACTOR_ZERO}),
+	("BlendFactorOne", #{const VK_BLEND_FACTOR_ONE}),
+	("BlendFactorSrcColor", #{const VK_BLEND_FACTOR_SRC_COLOR}),
+	("BlendFactorOneMinusSrcColor",
+		#{const VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR}),
+	("BlendFactorDstColor", #{const VK_BLEND_FACTOR_DST_COLOR}),
+	("BlendFactorOneMinusDstColor",
+		#{const VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR}),
+	("BlendFactorSrcAlpha", #{const VK_BLEND_FACTOR_SRC_ALPHA}),
+	("BlendFactorOneMinusSrcAlpha",
+		#{const VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA}),
+	("BlendFactorDstAlpha", #{const VK_BLEND_FACTOR_DST_ALPHA}),
+	("BlendFactorOneMinusDstAlpha",
+		#{const VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA}),
+	("BlendFactorConstantColor", #{const VK_BLEND_FACTOR_CONSTANT_COLOR}),
+	("BlendFactorOneMinusConstantColor",
+		#{const VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR}),
+	("BlendFactorConstantAlpha", #{const VK_BLEND_FACTOR_CONSTANT_ALPHA}),
+	("BlendFactorOneMinusConstantAlpha",
+		#{const VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA}),
+	("BlendFactorSrcAlphaSaturate",
+		#{const VK_BLEND_FACTOR_SRC_ALPHA_SATURATE}),
+	("BlendFactorSrc1Color", #{const VK_BLEND_FACTOR_SRC1_COLOR}),
+	("BlendFactorOneMinusSrc1Color",
+		#{const VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR}),
+	("BlendFactorSrc1Alpha", #{const VK_BLEND_FACTOR_SRC1_ALPHA}),
+	("BlendFactorOneMinusSrc1Alpha",
+		#{const VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA}),
+	("BlendFactorMaxEnum", #{const VK_BLEND_FACTOR_MAX_ENUM}) ]
+
+enum "BlendOp" ''#{type VkBlendOp}
+		[''Show, ''Eq, ''Storable] [
+	("BlendOpAdd", #{const VK_BLEND_OP_ADD}),
+	("BlendOpSubtract", #{const VK_BLEND_OP_SUBTRACT}),
+	("BlendOpReverseSubtract", #{const VK_BLEND_OP_REVERSE_SUBTRACT}),
+	("BlendOpMin", #{const VK_BLEND_OP_MIN}),
+	("BlendOpMax", #{const VK_BLEND_OP_MAX}),
+	("BlendOpZeroExt", #{const VK_BLEND_OP_ZERO_EXT}),
+	("BlendOpSrcExt", #{const VK_BLEND_OP_SRC_EXT}),
+	("BlendOpDstExt", #{const VK_BLEND_OP_DST_EXT}),
+	("BlendOpSrcOverExt", #{const VK_BLEND_OP_SRC_OVER_EXT}),
+	("BlendOpDstOverExt", #{const VK_BLEND_OP_DST_OVER_EXT}),
+	("BlendOpSrcInExt", #{const VK_BLEND_OP_SRC_IN_EXT}),
+	("BlendOpDstInExt", #{const VK_BLEND_OP_DST_IN_EXT}),
+	("BlendOpSrcOutExt", #{const VK_BLEND_OP_SRC_OUT_EXT}),
+	("BlendOpDstOutExt", #{const VK_BLEND_OP_DST_OUT_EXT}),
+	("BlendOpSrcAtopExt", #{const VK_BLEND_OP_SRC_ATOP_EXT}),
+	("BlendOpDstAtopExt", #{const VK_BLEND_OP_DST_ATOP_EXT}),
+	("BlendOpXorExt", #{const VK_BLEND_OP_XOR_EXT}),
+	("BlendOpMultiplyExt", #{const VK_BLEND_OP_MULTIPLY_EXT}),
+	("BlendOpScreenExt", #{const VK_BLEND_OP_SCREEN_EXT}),
+	("BlendOpOverlayExt", #{const VK_BLEND_OP_OVERLAY_EXT}),
+	("BlendOpDarkenExt", #{const VK_BLEND_OP_DARKEN_EXT}),
+	("BlendOpLightenExt", #{const VK_BLEND_OP_LIGHTEN_EXT}),
+	("BlendOpColordodgeExt", #{const VK_BLEND_OP_COLORDODGE_EXT}),
+	("BlendOpColorburnExt", #{const VK_BLEND_OP_COLORBURN_EXT}),
+	("BlendOpHardlightExt", #{const VK_BLEND_OP_HARDLIGHT_EXT}),
+	("BlendOpSoftlightExt", #{const VK_BLEND_OP_SOFTLIGHT_EXT}),
+	("BlendOpDifferenceExt", #{const VK_BLEND_OP_DIFFERENCE_EXT}),
+	("BlendOpExclusionExt", #{const VK_BLEND_OP_EXCLUSION_EXT}),
+	("BlendOpInvertExt", #{const VK_BLEND_OP_INVERT_EXT}),
+	("BlendOpInvertRgbExt", #{const VK_BLEND_OP_INVERT_RGB_EXT}),
+	("BlendOpLineardodgeExt", #{const VK_BLEND_OP_LINEARDODGE_EXT}),
+	("BlendOpLinearburnExt", #{const VK_BLEND_OP_LINEARBURN_EXT}),
+	("BlendOpVividlightExt", #{const VK_BLEND_OP_VIVIDLIGHT_EXT}),
+	("BlendOpLinearlightExt", #{const VK_BLEND_OP_LINEARLIGHT_EXT}),
+	("BlendOpPinlightExt", #{const VK_BLEND_OP_PINLIGHT_EXT}),
+	("BlendOpHardmixExt", #{const VK_BLEND_OP_HARDMIX_EXT}),
+	("BlendOpHslHueExt", #{const VK_BLEND_OP_HSL_HUE_EXT}),
+	("BlendOpHslSaturationExt", #{const VK_BLEND_OP_HSL_SATURATION_EXT}),
+	("BlendOpHslColorExt", #{const VK_BLEND_OP_HSL_COLOR_EXT}),
+	("BlendOpHslLuminosityExt", #{const VK_BLEND_OP_HSL_LUMINOSITY_EXT}),
+	("BlendOpPlusExt", #{const VK_BLEND_OP_PLUS_EXT}),
+	("BlendOpPlusClampedExt", #{const VK_BLEND_OP_PLUS_CLAMPED_EXT}),
+	("BlendOpPlusClampedAlphaExt",
+		#{const VK_BLEND_OP_PLUS_CLAMPED_ALPHA_EXT}),
+	("BlendOpPlusDarkerExt", #{const VK_BLEND_OP_PLUS_DARKER_EXT}),
+	("BlendOpMinusExt", #{const VK_BLEND_OP_MINUS_EXT}),
+	("BlendOpMinusClampedExt", #{const VK_BLEND_OP_MINUS_CLAMPED_EXT}),
+	("BlendOpContrastExt", #{const VK_BLEND_OP_CONTRAST_EXT}),
+	("BlendOpInvertOvgExt", #{const VK_BLEND_OP_INVERT_OVG_EXT}),
+	("BlendOpRedExt", #{const VK_BLEND_OP_RED_EXT}),
+	("BlendOpGreenExt", #{const VK_BLEND_OP_GREEN_EXT}),
+	("BlendOpBlueExt", #{const VK_BLEND_OP_BLUE_EXT}),
+	("BlendOpMaxEnum", #{const VK_BLEND_OP_MAX_ENUM}) ]
+
+enum "LogicOp" ''#{type VkLogicOp}
+		[''Show, ''Eq, ''Storable] [
+	("LogicOpClear", #{const VK_LOGIC_OP_CLEAR}),
+	("LogicOpAnd", #{const VK_LOGIC_OP_AND}),
+	("LogicOpAndReverse", #{const VK_LOGIC_OP_AND_REVERSE}),
+	("LogicOpCopy", #{const VK_LOGIC_OP_COPY}),
+	("LogicOpAndInverted", #{const VK_LOGIC_OP_AND_INVERTED}),
+	("LogicOpNoOp", #{const VK_LOGIC_OP_NO_OP}),
+	("LogicOpXor", #{const VK_LOGIC_OP_XOR}),
+	("LogicOpOr", #{const VK_LOGIC_OP_OR}),
+	("LogicOpNor", #{const VK_LOGIC_OP_NOR}),
+	("LogicOpEquivalent", #{const VK_LOGIC_OP_EQUIVALENT}),
+	("LogicOpInvert", #{const VK_LOGIC_OP_INVERT}),
+	("LogicOpOrReverse", #{const VK_LOGIC_OP_OR_REVERSE}),
+	("LogicOpCopyInverted", #{const VK_LOGIC_OP_COPY_INVERTED}),
+	("LogicOpOrInverted", #{const VK_LOGIC_OP_OR_INVERTED}),
+	("LogicOpNand", #{const VK_LOGIC_OP_NAND}),
+	("LogicOpSet", #{const VK_LOGIC_OP_SET}),
+	("LogicOpMaxEnum", #{const VK_LOGIC_OP_MAX_ENUM}) ]
+
+enum "DynamicState" ''#{type VkDynamicState}
+		[''Show, ''Eq, ''Storable] [
+	("DynamicStateViewport", #{const VK_DYNAMIC_STATE_VIEWPORT}),
+	("DynamicStateScissor", #{const VK_DYNAMIC_STATE_SCISSOR}),
+	("DynamicStateLineWidth", #{const VK_DYNAMIC_STATE_LINE_WIDTH}),
+	("DynamicStateDepthBias", #{const VK_DYNAMIC_STATE_DEPTH_BIAS}),
+	("DynamicStateBlendConstants",
+		#{const VK_DYNAMIC_STATE_BLEND_CONSTANTS}),
+	("DynamicStateDepthBounds", #{const VK_DYNAMIC_STATE_DEPTH_BOUNDS}),
+	("DynamicStateStencilCompareMask",
+		#{const VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK}),
+	("DynamicStateStencilWriteMask",
+		#{const VK_DYNAMIC_STATE_STENCIL_WRITE_MASK}),
+	("DynamicStateStencilReference",
+		#{const VK_DYNAMIC_STATE_STENCIL_REFERENCE}),
+	("DynamicStateCullMode", #{const VK_DYNAMIC_STATE_CULL_MODE}),
+	("DynamicStateFrontFace", #{const VK_DYNAMIC_STATE_FRONT_FACE}),
+	("DynamicStatePrimitiveTopology",
+		#{const VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY}),
+	("DynamicStateViewportWithCount",
+		#{const VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT}),
+	("DynamicStateScissorWithCount",
+		#{const VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT}),
+	("DynamicStateVertexInputBindingStride",
+		#{const VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE}),
+	("DynamicStateDepthTestEnable",
+		#{const VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE}),
+	("DynamicStateDepthWriteEnable",
+		#{const VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE}),
+	("DynamicStateDepthCompareOp",
+		#{const VK_DYNAMIC_STATE_DEPTH_COMPARE_OP}),
+	("DynamicStateDepthBoundsTestEnable",
+		#{const VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE}),
+	("DynamicStateStencilTestEnable",
+		#{const VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE}),
+	("DynamicStateStencilOp", #{const VK_DYNAMIC_STATE_STENCIL_OP}),
+	("DynamicStateRasterizerDiscardEnable",
+		#{const VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE}),
+	("DynamicStateDepthBiasEnable",
+		#{const VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE}),
+	("DynamicStatePrimitiveRestartEnable",
+		#{const VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE}),
+	("DynamicStateViewportWScalingNv",
+		#{const VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV}),
+	("DynamicStateDiscardRectangleExt",
+		#{const VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT}),
+	("DynamicStateDiscardRectangleEnableExt",
+		#{const VK_DYNAMIC_STATE_DISCARD_RECTANGLE_ENABLE_EXT}),
+	("DynamicStateDiscardRectangleModeExt",
+		#{const VK_DYNAMIC_STATE_DISCARD_RECTANGLE_MODE_EXT}),
+	("DynamicStateSampleLocationsExt",
+		#{const VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT}),
+	("DynamicStateRayTracingPipelineStackSizeKhr",
+		#{const VK_DYNAMIC_STATE_RAY_TRACING_PIPELINE_STACK_SIZE_KHR}),
+	("DynamicStateViewportShadingRatePaletteNv",
+		#{const VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV}),
+	("DynamicStateViewportCoarseSampleOrderNv",
+		#{const VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV}),
+	("DynamicStateExclusiveScissorEnableNv",
+		#{const VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_ENABLE_NV}),
+	("DynamicStateExclusiveScissorNv",
+		#{const VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV}),
+	("DynamicStateFragmentShadingRateKhr",
+		#{const VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR}),
+	("DynamicStateLineStippleExt",
+		#{const VK_DYNAMIC_STATE_LINE_STIPPLE_EXT}),
+	("DynamicStateVertexInputExt",
+		#{const VK_DYNAMIC_STATE_VERTEX_INPUT_EXT}),
+	("DynamicStatePatchControlPointsExt",
+		#{const VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT}),
+	("DynamicStateLogicOpExt", #{const VK_DYNAMIC_STATE_LOGIC_OP_EXT}),
+	("DynamicStateColorWriteEnableExt",
+		#{const VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT}),
+	("DynamicStateTessellationDomainOriginExt",
+		#{const VK_DYNAMIC_STATE_TESSELLATION_DOMAIN_ORIGIN_EXT}),
+	("DynamicStateDepthClampEnableExt",
+		#{const VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT}),
+	("DynamicStatePolygonModeExt",
+		#{const VK_DYNAMIC_STATE_POLYGON_MODE_EXT}),
+	("DynamicStateRasterizationSamplesExt",
+		#{const VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT}),
+	("DynamicStateSampleMaskExt",
+		#{const VK_DYNAMIC_STATE_SAMPLE_MASK_EXT}),
+	("DynamicStateAlphaToCoverageEnableExt",
+		#{const VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT}),
+	("DynamicStateAlphaToOneEnableExt",
+		#{const VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT}),
+	("DynamicStateLogicOpEnableExt",
+		#{const VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT}),
+	("DynamicStateColorBlendEnableExt",
+		#{const VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT}),
+	("DynamicStateColorBlendEquationExt",
+		#{const VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT}),
+	("DynamicStateColorWriteMaskExt",
+		#{const VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT}),
+	("DynamicStateRasterizationStreamExt",
+		#{const VK_DYNAMIC_STATE_RASTERIZATION_STREAM_EXT}),
+	("DynamicStateConservativeRasterizationModeExt",
+		#{const VK_DYNAMIC_STATE_CONSERVATIVE_RASTERIZATION_MODE_EXT}),
+	("DynamicStateExtraPrimitiveOverestimationSizeExt",
+		#{const VK_DYNAMIC_STATE_EXTRA_PRIMITIVE_OVERESTIMATION_SIZE_EXT}),
+	("DynamicStateDepthClipEnableExt",
+		#{const VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT}),
+	("DynamicStateSampleLocationsEnableExt",
+		#{const VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT}),
+	("DynamicStateColorBlendAdvancedExt",
+		#{const VK_DYNAMIC_STATE_COLOR_BLEND_ADVANCED_EXT}),
+	("DynamicStateProvokingVertexModeExt",
+		#{const VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT}),
+	("DynamicStateLineRasterizationModeExt",
+		#{const VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT}),
+	("DynamicStateLineStippleEnableExt",
+		#{const VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT}),
+	("DynamicStateDepthClipNegativeOneToOneExt",
+		#{const VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT}),
+	("DynamicStateViewportWScalingEnableNv",
+		#{const VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_ENABLE_NV}),
+	("DynamicStateViewportSwizzleNv",
+		#{const VK_DYNAMIC_STATE_VIEWPORT_SWIZZLE_NV}),
+	("DynamicStateCoverageToColorEnableNv",
+		#{const VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_ENABLE_NV}),
+	("DynamicStateCoverageToColorLocationNv",
+		#{const VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_LOCATION_NV}),
+	("DynamicStateCoverageModulationModeNv",
+		#{const VK_DYNAMIC_STATE_COVERAGE_MODULATION_MODE_NV}),
+	("DynamicStateCoverageModulationTableEnableNv",
+		#{const VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_ENABLE_NV}),
+	("DynamicStateCoverageModulationTableNv",
+		#{const VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_NV}),
+	("DynamicStateShadingRateImageEnableNv",
+		#{const VK_DYNAMIC_STATE_SHADING_RATE_IMAGE_ENABLE_NV}),
+	("DynamicStateRepresentativeFragmentTestEnableNv",
+		#{const VK_DYNAMIC_STATE_REPRESENTATIVE_FRAGMENT_TEST_ENABLE_NV}),
+	("DynamicStateCoverageReductionModeNv",
+		#{const VK_DYNAMIC_STATE_COVERAGE_REDUCTION_MODE_NV}),
+	("DynamicStateAttachmentFeedbackLoopEnableExt",
+		#{const VK_DYNAMIC_STATE_ATTACHMENT_FEEDBACK_LOOP_ENABLE_EXT}),
+	("DynamicStateCullModeExt", #{const VK_DYNAMIC_STATE_CULL_MODE_EXT}),
+	("DynamicStateFrontFaceExt", #{const VK_DYNAMIC_STATE_FRONT_FACE_EXT}),
+	("DynamicStatePrimitiveTopologyExt",
+		#{const VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT}),
+	("DynamicStateViewportWithCountExt",
+		#{const VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT}),
+	("DynamicStateScissorWithCountExt",
+		#{const VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT}),
+	("DynamicStateVertexInputBindingStrideExt",
+		#{const VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT}),
+	("DynamicStateDepthTestEnableExt",
+		#{const VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT}),
+	("DynamicStateDepthWriteEnableExt",
+		#{const VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT}),
+	("DynamicStateDepthCompareOpExt",
+		#{const VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT}),
+	("DynamicStateDepthBoundsTestEnableExt",
+		#{const VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT}),
+	("DynamicStateStencilTestEnableExt",
+		#{const VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT}),
+	("DynamicStateStencilOpExt", #{const VK_DYNAMIC_STATE_STENCIL_OP_EXT}),
+	("DynamicStateRasterizerDiscardEnableExt",
+		#{const VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT}),
+	("DynamicStateDepthBiasEnableExt",
+		#{const VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT}),
+	("DynamicStatePrimitiveRestartEnableExt",
+		#{const VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT}),
+	("DynamicStateMaxEnum", #{const VK_DYNAMIC_STATE_MAX_ENUM}) ]
+
+enum "IndexType" ''#{type VkIndexType}
+		[''Show, ''Eq, ''Storable] [
+	("IndexTypeUint16", #{const VK_INDEX_TYPE_UINT16}),
+	("IndexTypeUint32", #{const VK_INDEX_TYPE_UINT32}),
+	("IndexTypeNoneKhr", #{const VK_INDEX_TYPE_NONE_KHR}),
+	("IndexTypeUint8Ext", #{const VK_INDEX_TYPE_UINT8_EXT}),
+	("IndexTypeNoneNv", #{const VK_INDEX_TYPE_NONE_NV}),
+	("IndexTypeMaxEnum", #{const VK_INDEX_TYPE_MAX_ENUM}) ]
+
+enum "Filter" ''#{type VkFilter}
+		[''Show, ''Eq, ''Storable] [
+	("FilterNearest", #{const VK_FILTER_NEAREST}),
+	("FilterLinear", #{const VK_FILTER_LINEAR}),
+	("FilterCubicExt", #{const VK_FILTER_CUBIC_EXT}),
+	("FilterCubicImg", #{const VK_FILTER_CUBIC_IMG}),
+	("FilterMaxEnum", #{const VK_FILTER_MAX_ENUM}) ]
+
+enum "BorderColor" ''#{type VkBorderColor}
+		[''Show, ''Eq, ''Storable] [
+	("BorderColorFloatTransparentBlack",
+		#{const VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK}),
+	("BorderColorIntTransparentBlack",
+		#{const VK_BORDER_COLOR_INT_TRANSPARENT_BLACK}),
+	("BorderColorFloatOpaqueBlack",
+		#{const VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK}),
+	("BorderColorIntOpaqueBlack",
+		#{const VK_BORDER_COLOR_INT_OPAQUE_BLACK}),
+	("BorderColorFloatOpaqueWhite",
+		#{const VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE}),
+	("BorderColorIntOpaqueWhite",
+		#{const VK_BORDER_COLOR_INT_OPAQUE_WHITE}),
+	("BorderColorFloatCustomExt",
+		#{const VK_BORDER_COLOR_FLOAT_CUSTOM_EXT}),
+	("BorderColorIntCustomExt", #{const VK_BORDER_COLOR_INT_CUSTOM_EXT}),
+	("BorderColorMaxEnum", #{const VK_BORDER_COLOR_MAX_ENUM}) ]
+
+enum "Format" ''#{type VkFormat}
+		[''Show, ''Eq, ''Storable] [
+	("FormatUndefined", #{const VK_FORMAT_UNDEFINED}),
+	("FormatR4g4UnormPack8", #{const VK_FORMAT_R4G4_UNORM_PACK8}),
+	("FormatR4g4b4a4UnormPack16", #{const VK_FORMAT_R4G4B4A4_UNORM_PACK16}),
+	("FormatB4g4r4a4UnormPack16", #{const VK_FORMAT_B4G4R4A4_UNORM_PACK16}),
+	("FormatR5g6b5UnormPack16", #{const VK_FORMAT_R5G6B5_UNORM_PACK16}),
+	("FormatB5g6r5UnormPack16", #{const VK_FORMAT_B5G6R5_UNORM_PACK16}),
+	("FormatR5g5b5a1UnormPack16", #{const VK_FORMAT_R5G5B5A1_UNORM_PACK16}),
+	("FormatB5g5r5a1UnormPack16", #{const VK_FORMAT_B5G5R5A1_UNORM_PACK16}),
+	("FormatA1r5g5b5UnormPack16", #{const VK_FORMAT_A1R5G5B5_UNORM_PACK16}),
+	("FormatR8Unorm", #{const VK_FORMAT_R8_UNORM}),
+	("FormatR8Snorm", #{const VK_FORMAT_R8_SNORM}),
+	("FormatR8Uscaled", #{const VK_FORMAT_R8_USCALED}),
+	("FormatR8Sscaled", #{const VK_FORMAT_R8_SSCALED}),
+	("FormatR8Uint", #{const VK_FORMAT_R8_UINT}),
+	("FormatR8Sint", #{const VK_FORMAT_R8_SINT}),
+	("FormatR8Srgb", #{const VK_FORMAT_R8_SRGB}),
+	("FormatR8g8Unorm", #{const VK_FORMAT_R8G8_UNORM}),
+	("FormatR8g8Snorm", #{const VK_FORMAT_R8G8_SNORM}),
+	("FormatR8g8Uscaled", #{const VK_FORMAT_R8G8_USCALED}),
+	("FormatR8g8Sscaled", #{const VK_FORMAT_R8G8_SSCALED}),
+	("FormatR8g8Uint", #{const VK_FORMAT_R8G8_UINT}),
+	("FormatR8g8Sint", #{const VK_FORMAT_R8G8_SINT}),
+	("FormatR8g8Srgb", #{const VK_FORMAT_R8G8_SRGB}),
+	("FormatR8g8b8Unorm", #{const VK_FORMAT_R8G8B8_UNORM}),
+	("FormatR8g8b8Snorm", #{const VK_FORMAT_R8G8B8_SNORM}),
+	("FormatR8g8b8Uscaled", #{const VK_FORMAT_R8G8B8_USCALED}),
+	("FormatR8g8b8Sscaled", #{const VK_FORMAT_R8G8B8_SSCALED}),
+	("FormatR8g8b8Uint", #{const VK_FORMAT_R8G8B8_UINT}),
+	("FormatR8g8b8Sint", #{const VK_FORMAT_R8G8B8_SINT}),
+	("FormatR8g8b8Srgb", #{const VK_FORMAT_R8G8B8_SRGB}),
+	("FormatB8g8r8Unorm", #{const VK_FORMAT_B8G8R8_UNORM}),
+	("FormatB8g8r8Snorm", #{const VK_FORMAT_B8G8R8_SNORM}),
+	("FormatB8g8r8Uscaled", #{const VK_FORMAT_B8G8R8_USCALED}),
+	("FormatB8g8r8Sscaled", #{const VK_FORMAT_B8G8R8_SSCALED}),
+	("FormatB8g8r8Uint", #{const VK_FORMAT_B8G8R8_UINT}),
+	("FormatB8g8r8Sint", #{const VK_FORMAT_B8G8R8_SINT}),
+	("FormatB8g8r8Srgb", #{const VK_FORMAT_B8G8R8_SRGB}),
+	("FormatR8g8b8a8Unorm", #{const VK_FORMAT_R8G8B8A8_UNORM}),
+	("FormatR8g8b8a8Snorm", #{const VK_FORMAT_R8G8B8A8_SNORM}),
+	("FormatR8g8b8a8Uscaled", #{const VK_FORMAT_R8G8B8A8_USCALED}),
+	("FormatR8g8b8a8Sscaled", #{const VK_FORMAT_R8G8B8A8_SSCALED}),
+	("FormatR8g8b8a8Uint", #{const VK_FORMAT_R8G8B8A8_UINT}),
+	("FormatR8g8b8a8Sint", #{const VK_FORMAT_R8G8B8A8_SINT}),
+	("FormatR8g8b8a8Srgb", #{const VK_FORMAT_R8G8B8A8_SRGB}),
+	("FormatB8g8r8a8Unorm", #{const VK_FORMAT_B8G8R8A8_UNORM}),
+	("FormatB8g8r8a8Snorm", #{const VK_FORMAT_B8G8R8A8_SNORM}),
+	("FormatB8g8r8a8Uscaled", #{const VK_FORMAT_B8G8R8A8_USCALED}),
+	("FormatB8g8r8a8Sscaled", #{const VK_FORMAT_B8G8R8A8_SSCALED}),
+	("FormatB8g8r8a8Uint", #{const VK_FORMAT_B8G8R8A8_UINT}),
+	("FormatB8g8r8a8Sint", #{const VK_FORMAT_B8G8R8A8_SINT}),
+	("FormatB8g8r8a8Srgb", #{const VK_FORMAT_B8G8R8A8_SRGB}),
+	("FormatA8b8g8r8UnormPack32", #{const VK_FORMAT_A8B8G8R8_UNORM_PACK32}),
+	("FormatA8b8g8r8SnormPack32", #{const VK_FORMAT_A8B8G8R8_SNORM_PACK32}),
+	("FormatA8b8g8r8UscaledPack32",
+		#{const VK_FORMAT_A8B8G8R8_USCALED_PACK32}),
+	("FormatA8b8g8r8SscaledPack32",
+		#{const VK_FORMAT_A8B8G8R8_SSCALED_PACK32}),
+	("FormatA8b8g8r8UintPack32", #{const VK_FORMAT_A8B8G8R8_UINT_PACK32}),
+	("FormatA8b8g8r8SintPack32", #{const VK_FORMAT_A8B8G8R8_SINT_PACK32}),
+	("FormatA8b8g8r8SrgbPack32", #{const VK_FORMAT_A8B8G8R8_SRGB_PACK32}),
+	("FormatA2r10g10b10UnormPack32",
+		#{const VK_FORMAT_A2R10G10B10_UNORM_PACK32}),
+	("FormatA2r10g10b10SnormPack32",
+		#{const VK_FORMAT_A2R10G10B10_SNORM_PACK32}),
+	("FormatA2r10g10b10UscaledPack32",
+		#{const VK_FORMAT_A2R10G10B10_USCALED_PACK32}),
+	("FormatA2r10g10b10SscaledPack32",
+		#{const VK_FORMAT_A2R10G10B10_SSCALED_PACK32}),
+	("FormatA2r10g10b10UintPack32",
+		#{const VK_FORMAT_A2R10G10B10_UINT_PACK32}),
+	("FormatA2r10g10b10SintPack32",
+		#{const VK_FORMAT_A2R10G10B10_SINT_PACK32}),
+	("FormatA2b10g10r10UnormPack32",
+		#{const VK_FORMAT_A2B10G10R10_UNORM_PACK32}),
+	("FormatA2b10g10r10SnormPack32",
+		#{const VK_FORMAT_A2B10G10R10_SNORM_PACK32}),
+	("FormatA2b10g10r10UscaledPack32",
+		#{const VK_FORMAT_A2B10G10R10_USCALED_PACK32}),
+	("FormatA2b10g10r10SscaledPack32",
+		#{const VK_FORMAT_A2B10G10R10_SSCALED_PACK32}),
+	("FormatA2b10g10r10UintPack32",
+		#{const VK_FORMAT_A2B10G10R10_UINT_PACK32}),
+	("FormatA2b10g10r10SintPack32",
+		#{const VK_FORMAT_A2B10G10R10_SINT_PACK32}),
+	("FormatR16Unorm", #{const VK_FORMAT_R16_UNORM}),
+	("FormatR16Snorm", #{const VK_FORMAT_R16_SNORM}),
+	("FormatR16Uscaled", #{const VK_FORMAT_R16_USCALED}),
+	("FormatR16Sscaled", #{const VK_FORMAT_R16_SSCALED}),
+	("FormatR16Uint", #{const VK_FORMAT_R16_UINT}),
+	("FormatR16Sint", #{const VK_FORMAT_R16_SINT}),
+	("FormatR16Sfloat", #{const VK_FORMAT_R16_SFLOAT}),
+	("FormatR16g16Unorm", #{const VK_FORMAT_R16G16_UNORM}),
+	("FormatR16g16Snorm", #{const VK_FORMAT_R16G16_SNORM}),
+	("FormatR16g16Uscaled", #{const VK_FORMAT_R16G16_USCALED}),
+	("FormatR16g16Sscaled", #{const VK_FORMAT_R16G16_SSCALED}),
+	("FormatR16g16Uint", #{const VK_FORMAT_R16G16_UINT}),
+	("FormatR16g16Sint", #{const VK_FORMAT_R16G16_SINT}),
+	("FormatR16g16Sfloat", #{const VK_FORMAT_R16G16_SFLOAT}),
+	("FormatR16g16b16Unorm", #{const VK_FORMAT_R16G16B16_UNORM}),
+	("FormatR16g16b16Snorm", #{const VK_FORMAT_R16G16B16_SNORM}),
+	("FormatR16g16b16Uscaled", #{const VK_FORMAT_R16G16B16_USCALED}),
+	("FormatR16g16b16Sscaled", #{const VK_FORMAT_R16G16B16_SSCALED}),
+	("FormatR16g16b16Uint", #{const VK_FORMAT_R16G16B16_UINT}),
+	("FormatR16g16b16Sint", #{const VK_FORMAT_R16G16B16_SINT}),
+	("FormatR16g16b16Sfloat", #{const VK_FORMAT_R16G16B16_SFLOAT}),
+	("FormatR16g16b16a16Unorm", #{const VK_FORMAT_R16G16B16A16_UNORM}),
+	("FormatR16g16b16a16Snorm", #{const VK_FORMAT_R16G16B16A16_SNORM}),
+	("FormatR16g16b16a16Uscaled", #{const VK_FORMAT_R16G16B16A16_USCALED}),
+	("FormatR16g16b16a16Sscaled", #{const VK_FORMAT_R16G16B16A16_SSCALED}),
+	("FormatR16g16b16a16Uint", #{const VK_FORMAT_R16G16B16A16_UINT}),
+	("FormatR16g16b16a16Sint", #{const VK_FORMAT_R16G16B16A16_SINT}),
+	("FormatR16g16b16a16Sfloat", #{const VK_FORMAT_R16G16B16A16_SFLOAT}),
+	("FormatR32Uint", #{const VK_FORMAT_R32_UINT}),
+	("FormatR32Sint", #{const VK_FORMAT_R32_SINT}),
+	("FormatR32Sfloat", #{const VK_FORMAT_R32_SFLOAT}),
+	("FormatR32g32Uint", #{const VK_FORMAT_R32G32_UINT}),
+	("FormatR32g32Sint", #{const VK_FORMAT_R32G32_SINT}),
+	("FormatR32g32Sfloat", #{const VK_FORMAT_R32G32_SFLOAT}),
+	("FormatR32g32b32Uint", #{const VK_FORMAT_R32G32B32_UINT}),
+	("FormatR32g32b32Sint", #{const VK_FORMAT_R32G32B32_SINT}),
+	("FormatR32g32b32Sfloat", #{const VK_FORMAT_R32G32B32_SFLOAT}),
+	("FormatR32g32b32a32Uint", #{const VK_FORMAT_R32G32B32A32_UINT}),
+	("FormatR32g32b32a32Sint", #{const VK_FORMAT_R32G32B32A32_SINT}),
+	("FormatR32g32b32a32Sfloat", #{const VK_FORMAT_R32G32B32A32_SFLOAT}),
+	("FormatR64Uint", #{const VK_FORMAT_R64_UINT}),
+	("FormatR64Sint", #{const VK_FORMAT_R64_SINT}),
+	("FormatR64Sfloat", #{const VK_FORMAT_R64_SFLOAT}),
+	("FormatR64g64Uint", #{const VK_FORMAT_R64G64_UINT}),
+	("FormatR64g64Sint", #{const VK_FORMAT_R64G64_SINT}),
+	("FormatR64g64Sfloat", #{const VK_FORMAT_R64G64_SFLOAT}),
+	("FormatR64g64b64Uint", #{const VK_FORMAT_R64G64B64_UINT}),
+	("FormatR64g64b64Sint", #{const VK_FORMAT_R64G64B64_SINT}),
+	("FormatR64g64b64Sfloat", #{const VK_FORMAT_R64G64B64_SFLOAT}),
+	("FormatR64g64b64a64Uint", #{const VK_FORMAT_R64G64B64A64_UINT}),
+	("FormatR64g64b64a64Sint", #{const VK_FORMAT_R64G64B64A64_SINT}),
+	("FormatR64g64b64a64Sfloat", #{const VK_FORMAT_R64G64B64A64_SFLOAT}),
+	("FormatB10g11r11UfloatPack32",
+		#{const VK_FORMAT_B10G11R11_UFLOAT_PACK32}),
+	("FormatE5b9g9r9UfloatPack32",
+		#{const VK_FORMAT_E5B9G9R9_UFLOAT_PACK32}),
+	("FormatD16Unorm", #{const VK_FORMAT_D16_UNORM}),
+	("FormatX8D24UnormPack32", #{const VK_FORMAT_X8_D24_UNORM_PACK32}),
+	("FormatD32Sfloat", #{const VK_FORMAT_D32_SFLOAT}),
+	("FormatS8Uint", #{const VK_FORMAT_S8_UINT}),
+	("FormatD16UnormS8Uint", #{const VK_FORMAT_D16_UNORM_S8_UINT}),
+	("FormatD24UnormS8Uint", #{const VK_FORMAT_D24_UNORM_S8_UINT}),
+	("FormatD32SfloatS8Uint", #{const VK_FORMAT_D32_SFLOAT_S8_UINT}),
+	("FormatBc1RgbUnormBlock", #{const VK_FORMAT_BC1_RGB_UNORM_BLOCK}),
+	("FormatBc1RgbSrgbBlock", #{const VK_FORMAT_BC1_RGB_SRGB_BLOCK}),
+	("FormatBc1RgbaUnormBlock", #{const VK_FORMAT_BC1_RGBA_UNORM_BLOCK}),
+	("FormatBc1RgbaSrgbBlock", #{const VK_FORMAT_BC1_RGBA_SRGB_BLOCK}),
+	("FormatBc2UnormBlock", #{const VK_FORMAT_BC2_UNORM_BLOCK}),
+	("FormatBc2SrgbBlock", #{const VK_FORMAT_BC2_SRGB_BLOCK}),
+	("FormatBc3UnormBlock", #{const VK_FORMAT_BC3_UNORM_BLOCK}),
+	("FormatBc3SrgbBlock", #{const VK_FORMAT_BC3_SRGB_BLOCK}),
+	("FormatBc4UnormBlock", #{const VK_FORMAT_BC4_UNORM_BLOCK}),
+	("FormatBc4SnormBlock", #{const VK_FORMAT_BC4_SNORM_BLOCK}),
+	("FormatBc5UnormBlock", #{const VK_FORMAT_BC5_UNORM_BLOCK}),
+	("FormatBc5SnormBlock", #{const VK_FORMAT_BC5_SNORM_BLOCK}),
+	("FormatBc6hUfloatBlock", #{const VK_FORMAT_BC6H_UFLOAT_BLOCK}),
+	("FormatBc6hSfloatBlock", #{const VK_FORMAT_BC6H_SFLOAT_BLOCK}),
+	("FormatBc7UnormBlock", #{const VK_FORMAT_BC7_UNORM_BLOCK}),
+	("FormatBc7SrgbBlock", #{const VK_FORMAT_BC7_SRGB_BLOCK}),
+	("FormatEtc2R8g8b8UnormBlock",
+		#{const VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK}),
+	("FormatEtc2R8g8b8SrgbBlock",
+		#{const VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK}),
+	("FormatEtc2R8g8b8a1UnormBlock",
+		#{const VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK}),
+	("FormatEtc2R8g8b8a1SrgbBlock",
+		#{const VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK}),
+	("FormatEtc2R8g8b8a8UnormBlock",
+		#{const VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK}),
+	("FormatEtc2R8g8b8a8SrgbBlock",
+		#{const VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK}),
+	("FormatEacR11UnormBlock", #{const VK_FORMAT_EAC_R11_UNORM_BLOCK}),
+	("FormatEacR11SnormBlock", #{const VK_FORMAT_EAC_R11_SNORM_BLOCK}),
+	("FormatEacR11g11UnormBlock",
+		#{const VK_FORMAT_EAC_R11G11_UNORM_BLOCK}),
+	("FormatEacR11g11SnormBlock",
+		#{const VK_FORMAT_EAC_R11G11_SNORM_BLOCK}),
+	("FormatAstc4x4UnormBlock", #{const VK_FORMAT_ASTC_4x4_UNORM_BLOCK}),
+	("FormatAstc4x4SrgbBlock", #{const VK_FORMAT_ASTC_4x4_SRGB_BLOCK}),
+	("FormatAstc5x4UnormBlock", #{const VK_FORMAT_ASTC_5x4_UNORM_BLOCK}),
+	("FormatAstc5x4SrgbBlock", #{const VK_FORMAT_ASTC_5x4_SRGB_BLOCK}),
+	("FormatAstc5x5UnormBlock", #{const VK_FORMAT_ASTC_5x5_UNORM_BLOCK}),
+	("FormatAstc5x5SrgbBlock", #{const VK_FORMAT_ASTC_5x5_SRGB_BLOCK}),
+	("FormatAstc6x5UnormBlock", #{const VK_FORMAT_ASTC_6x5_UNORM_BLOCK}),
+	("FormatAstc6x5SrgbBlock", #{const VK_FORMAT_ASTC_6x5_SRGB_BLOCK}),
+	("FormatAstc6x6UnormBlock", #{const VK_FORMAT_ASTC_6x6_UNORM_BLOCK}),
+	("FormatAstc6x6SrgbBlock", #{const VK_FORMAT_ASTC_6x6_SRGB_BLOCK}),
+	("FormatAstc8x5UnormBlock", #{const VK_FORMAT_ASTC_8x5_UNORM_BLOCK}),
+	("FormatAstc8x5SrgbBlock", #{const VK_FORMAT_ASTC_8x5_SRGB_BLOCK}),
+	("FormatAstc8x6UnormBlock", #{const VK_FORMAT_ASTC_8x6_UNORM_BLOCK}),
+	("FormatAstc8x6SrgbBlock", #{const VK_FORMAT_ASTC_8x6_SRGB_BLOCK}),
+	("FormatAstc8x8UnormBlock", #{const VK_FORMAT_ASTC_8x8_UNORM_BLOCK}),
+	("FormatAstc8x8SrgbBlock", #{const VK_FORMAT_ASTC_8x8_SRGB_BLOCK}),
+	("FormatAstc10x5UnormBlock", #{const VK_FORMAT_ASTC_10x5_UNORM_BLOCK}),
+	("FormatAstc10x5SrgbBlock", #{const VK_FORMAT_ASTC_10x5_SRGB_BLOCK}),
+	("FormatAstc10x6UnormBlock", #{const VK_FORMAT_ASTC_10x6_UNORM_BLOCK}),
+	("FormatAstc10x6SrgbBlock", #{const VK_FORMAT_ASTC_10x6_SRGB_BLOCK}),
+	("FormatAstc10x8UnormBlock", #{const VK_FORMAT_ASTC_10x8_UNORM_BLOCK}),
+	("FormatAstc10x8SrgbBlock", #{const VK_FORMAT_ASTC_10x8_SRGB_BLOCK}),
+	("FormatAstc10x10UnormBlock",
+		#{const VK_FORMAT_ASTC_10x10_UNORM_BLOCK}),
+	("FormatAstc10x10SrgbBlock", #{const VK_FORMAT_ASTC_10x10_SRGB_BLOCK}),
+	("FormatAstc12x10UnormBlock",
+		#{const VK_FORMAT_ASTC_12x10_UNORM_BLOCK}),
+	("FormatAstc12x10SrgbBlock", #{const VK_FORMAT_ASTC_12x10_SRGB_BLOCK}),
+	("FormatAstc12x12UnormBlock",
+		#{const VK_FORMAT_ASTC_12x12_UNORM_BLOCK}),
+	("FormatAstc12x12SrgbBlock", #{const VK_FORMAT_ASTC_12x12_SRGB_BLOCK}),
+	("FormatG8b8g8r8422Unorm", #{const VK_FORMAT_G8B8G8R8_422_UNORM}),
+	("FormatB8g8r8g8422Unorm", #{const VK_FORMAT_B8G8R8G8_422_UNORM}),
+	("FormatG8B8R83plane420Unorm",
+		#{const VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM}),
+	("FormatG8B8r82plane420Unorm",
+		#{const VK_FORMAT_G8_B8R8_2PLANE_420_UNORM}),
+	("FormatG8B8R83plane422Unorm",
+		#{const VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM}),
+	("FormatG8B8r82plane422Unorm",
+		#{const VK_FORMAT_G8_B8R8_2PLANE_422_UNORM}),
+	("FormatG8B8R83plane444Unorm",
+		#{const VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM}),
+	("FormatR10x6UnormPack16", #{const VK_FORMAT_R10X6_UNORM_PACK16}),
+	("FormatR10x6g10x6Unorm2pack16",
+		#{const VK_FORMAT_R10X6G10X6_UNORM_2PACK16}),
+	("FormatR10x6g10x6b10x6a10x6Unorm4pack16",
+		#{const VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16}),
+	("FormatG10x6b10x6g10x6r10x6422Unorm4pack16",
+		#{const VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16}),
+	("FormatB10x6g10x6r10x6g10x6422Unorm4pack16",
+		#{const VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16}),
+	("FormatG10x6B10x6R10x63plane420Unorm3pack16",
+		#{const VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16}),
+	("FormatG10x6B10x6r10x62plane420Unorm3pack16",
+		#{const VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16}),
+	("FormatG10x6B10x6R10x63plane422Unorm3pack16",
+		#{const VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16}),
+	("FormatG10x6B10x6r10x62plane422Unorm3pack16",
+		#{const VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16}),
+	("FormatG10x6B10x6R10x63plane444Unorm3pack16",
+		#{const VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16}),
+	("FormatR12x4UnormPack16", #{const VK_FORMAT_R12X4_UNORM_PACK16}),
+	("FormatR12x4g12x4Unorm2pack16",
+		#{const VK_FORMAT_R12X4G12X4_UNORM_2PACK16}),
+	("FormatR12x4g12x4b12x4a12x4Unorm4pack16",
+		#{const VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16}),
+	("FormatG12x4b12x4g12x4r12x4422Unorm4pack16",
+		#{const VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16}),
+	("FormatB12x4g12x4r12x4g12x4422Unorm4pack16",
+		#{const VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16}),
+	("FormatG12x4B12x4R12x43plane420Unorm3pack16",
+		#{const VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16}),
+	("FormatG12x4B12x4r12x42plane420Unorm3pack16",
+		#{const VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16}),
+	("FormatG12x4B12x4R12x43plane422Unorm3pack16",
+		#{const VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16}),
+	("FormatG12x4B12x4r12x42plane422Unorm3pack16",
+		#{const VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16}),
+	("FormatG12x4B12x4R12x43plane444Unorm3pack16",
+		#{const VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16}),
+	("FormatG16b16g16r16422Unorm",
+		#{const VK_FORMAT_G16B16G16R16_422_UNORM}),
+	("FormatB16g16r16g16422Unorm",
+		#{const VK_FORMAT_B16G16R16G16_422_UNORM}),
+	("FormatG16B16R163plane420Unorm",
+		#{const VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM}),
+	("FormatG16B16r162plane420Unorm",
+		#{const VK_FORMAT_G16_B16R16_2PLANE_420_UNORM}),
+	("FormatG16B16R163plane422Unorm",
+		#{const VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM}),
+	("FormatG16B16r162plane422Unorm",
+		#{const VK_FORMAT_G16_B16R16_2PLANE_422_UNORM}),
+	("FormatG16B16R163plane444Unorm",
+		#{const VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM}),
+	("FormatG8B8r82plane444Unorm",
+		#{const VK_FORMAT_G8_B8R8_2PLANE_444_UNORM}),
+	("FormatG10x6B10x6r10x62plane444Unorm3pack16",
+		#{const VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16}),
+	("FormatG12x4B12x4r12x42plane444Unorm3pack16",
+		#{const VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16}),
+	("FormatG16B16r162plane444Unorm",
+		#{const VK_FORMAT_G16_B16R16_2PLANE_444_UNORM}),
+	("FormatA4r4g4b4UnormPack16", #{const VK_FORMAT_A4R4G4B4_UNORM_PACK16}),
+	("FormatA4b4g4r4UnormPack16", #{const VK_FORMAT_A4B4G4R4_UNORM_PACK16}),
+	("FormatAstc4x4SfloatBlock", #{const VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK}),
+	("FormatAstc5x4SfloatBlock", #{const VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK}),
+	("FormatAstc5x5SfloatBlock", #{const VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK}),
+	("FormatAstc6x5SfloatBlock", #{const VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK}),
+	("FormatAstc6x6SfloatBlock", #{const VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK}),
+	("FormatAstc8x5SfloatBlock", #{const VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK}),
+	("FormatAstc8x6SfloatBlock", #{const VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK}),
+	("FormatAstc8x8SfloatBlock", #{const VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK}),
+	("FormatAstc10x5SfloatBlock",
+		#{const VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK}),
+	("FormatAstc10x6SfloatBlock",
+		#{const VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK}),
+	("FormatAstc10x8SfloatBlock",
+		#{const VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK}),
+	("FormatAstc10x10SfloatBlock",
+		#{const VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK}),
+	("FormatAstc12x10SfloatBlock",
+		#{const VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK}),
+	("FormatAstc12x12SfloatBlock",
+		#{const VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK}),
+	("FormatPvrtc12bppUnormBlockImg",
+		#{const VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG}),
+	("FormatPvrtc14bppUnormBlockImg",
+		#{const VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG}),
+	("FormatPvrtc22bppUnormBlockImg",
+		#{const VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG}),
+	("FormatPvrtc24bppUnormBlockImg",
+		#{const VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG}),
+	("FormatPvrtc12bppSrgbBlockImg",
+		#{const VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG}),
+	("FormatPvrtc14bppSrgbBlockImg",
+		#{const VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG}),
+	("FormatPvrtc22bppSrgbBlockImg",
+		#{const VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG}),
+	("FormatPvrtc24bppSrgbBlockImg",
+		#{const VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG}),
+	("FormatR16g16S105Nv", #{const VK_FORMAT_R16G16_S10_5_NV}),
+	("FormatAstc4x4SfloatBlockExt",
+		#{const VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT}),
+	("FormatAstc5x4SfloatBlockExt",
+		#{const VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK_EXT}),
+	("FormatAstc5x5SfloatBlockExt",
+		#{const VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK_EXT}),
+	("FormatAstc6x5SfloatBlockExt",
+		#{const VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK_EXT}),
+	("FormatAstc6x6SfloatBlockExt",
+		#{const VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK_EXT}),
+	("FormatAstc8x5SfloatBlockExt",
+		#{const VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK_EXT}),
+	("FormatAstc8x6SfloatBlockExt",
+		#{const VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK_EXT}),
+	("FormatAstc8x8SfloatBlockExt",
+		#{const VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK_EXT}),
+	("FormatAstc10x5SfloatBlockExt",
+		#{const VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK_EXT}),
+	("FormatAstc10x6SfloatBlockExt",
+		#{const VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK_EXT}),
+	("FormatAstc10x8SfloatBlockExt",
+		#{const VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK_EXT}),
+	("FormatAstc10x10SfloatBlockExt",
+		#{const VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK_EXT}),
+	("FormatAstc12x10SfloatBlockExt",
+		#{const VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK_EXT}),
+	("FormatAstc12x12SfloatBlockExt",
+		#{const VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK_EXT}),
+	("FormatG8b8g8r8422UnormKhr",
+		#{const VK_FORMAT_G8B8G8R8_422_UNORM_KHR}),
+	("FormatB8g8r8g8422UnormKhr",
+		#{const VK_FORMAT_B8G8R8G8_422_UNORM_KHR}),
+	("FormatG8B8R83plane420UnormKhr",
+		#{const VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR}),
+	("FormatG8B8r82plane420UnormKhr",
+		#{const VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR}),
+	("FormatG8B8R83plane422UnormKhr",
+		#{const VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR}),
+	("FormatG8B8r82plane422UnormKhr",
+		#{const VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR}),
+	("FormatG8B8R83plane444UnormKhr",
+		#{const VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM_KHR}),
+	("FormatR10x6UnormPack16Khr",
+		#{const VK_FORMAT_R10X6_UNORM_PACK16_KHR}),
+	("FormatR10x6g10x6Unorm2pack16Khr",
+		#{const VK_FORMAT_R10X6G10X6_UNORM_2PACK16_KHR}),
+	("FormatR10x6g10x6b10x6a10x6Unorm4pack16Khr",
+		#{const VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16_KHR}),
+	("FormatG10x6b10x6g10x6r10x6422Unorm4pack16Khr",
+		#{const VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16_KHR}),
+	("FormatB10x6g10x6r10x6g10x6422Unorm4pack16Khr",
+		#{const VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16_KHR}),
+	("FormatG10x6B10x6R10x63plane420Unorm3pack16Khr",
+		#{const VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_KHR}),
+	("FormatG10x6B10x6r10x62plane420Unorm3pack16Khr",
+		#{const VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_KHR}),
+	("FormatG10x6B10x6R10x63plane422Unorm3pack16Khr",
+		#{const VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16_KHR}),
+	("FormatG10x6B10x6r10x62plane422Unorm3pack16Khr",
+		#{const VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16_KHR}),
+	("FormatG10x6B10x6R10x63plane444Unorm3pack16Khr",
+		#{const VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16_KHR}),
+	("FormatR12x4UnormPack16Khr",
+		#{const VK_FORMAT_R12X4_UNORM_PACK16_KHR}),
+	("FormatR12x4g12x4Unorm2pack16Khr",
+		#{const VK_FORMAT_R12X4G12X4_UNORM_2PACK16_KHR}),
+	("FormatR12x4g12x4b12x4a12x4Unorm4pack16Khr",
+		#{const VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16_KHR}),
+	("FormatG12x4b12x4g12x4r12x4422Unorm4pack16Khr",
+		#{const VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16_KHR}),
+	("FormatB12x4g12x4r12x4g12x4422Unorm4pack16Khr",
+		#{const VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16_KHR}),
+	("FormatG12x4B12x4R12x43plane420Unorm3pack16Khr",
+		#{const VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_KHR}),
+	("FormatG12x4B12x4r12x42plane420Unorm3pack16Khr",
+		#{const VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_KHR}),
+	("FormatG12x4B12x4R12x43plane422Unorm3pack16Khr",
+		#{const VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16_KHR}),
+	("FormatG12x4B12x4r12x42plane422Unorm3pack16Khr",
+		#{const VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16_KHR}),
+	("FormatG12x4B12x4R12x43plane444Unorm3pack16Khr",
+		#{const VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16_KHR}),
+	("FormatG16b16g16r16422UnormKhr",
+		#{const VK_FORMAT_G16B16G16R16_422_UNORM_KHR}),
+	("FormatB16g16r16g16422UnormKhr",
+		#{const VK_FORMAT_B16G16R16G16_422_UNORM_KHR}),
+	("FormatG16B16R163plane420UnormKhr",
+		#{const VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM_KHR}),
+	("FormatG16B16r162plane420UnormKhr",
+		#{const VK_FORMAT_G16_B16R16_2PLANE_420_UNORM_KHR}),
+	("FormatG16B16R163plane422UnormKhr",
+		#{const VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR}),
+	("FormatG16B16r162plane422UnormKhr",
+		#{const VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR}),
+	("FormatG16B16R163plane444UnormKhr",
+		#{const VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR}),
+	("FormatG8B8r82plane444UnormExt",
+		#{const VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT}),
+	("FormatG10x6B10x6r10x62plane444Unorm3pack16Ext",
+		#{const VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT}),
+	("FormatG12x4B12x4r12x42plane444Unorm3pack16Ext",
+		#{const VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT}),
+	("FormatG16B16r162plane444UnormExt",
+		#{const VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT}),
+	("FormatA4r4g4b4UnormPack16Ext",
+		#{const VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT}),
+	("FormatA4b4g4r4UnormPack16Ext",
+		#{const VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT}),
+	("FormatMaxEnum", #{const VK_FORMAT_MAX_ENUM}) ]
+
+enum "AccessFlagBits" ''#{type VkAccessFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("AccessFlagsZero", 0),
+	("AccessIndirectCommandReadBit",
+		#{const VK_ACCESS_INDIRECT_COMMAND_READ_BIT}),
+	("AccessIndexReadBit", #{const VK_ACCESS_INDEX_READ_BIT}),
+	("AccessVertexAttributeReadBit",
+		#{const VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT}),
+	("AccessUniformReadBit", #{const VK_ACCESS_UNIFORM_READ_BIT}),
+	("AccessInputAttachmentReadBit",
+		#{const VK_ACCESS_INPUT_ATTACHMENT_READ_BIT}),
+	("AccessShaderReadBit", #{const VK_ACCESS_SHADER_READ_BIT}),
+	("AccessShaderWriteBit", #{const VK_ACCESS_SHADER_WRITE_BIT}),
+	("AccessColorAttachmentReadBit",
+		#{const VK_ACCESS_COLOR_ATTACHMENT_READ_BIT}),
+	("AccessColorAttachmentWriteBit",
+		#{const VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT}),
+	("AccessDepthStencilAttachmentReadBit",
+		#{const VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT}),
+	("AccessDepthStencilAttachmentWriteBit",
+		#{const VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT}),
+	("AccessTransferReadBit", #{const VK_ACCESS_TRANSFER_READ_BIT}),
+	("AccessTransferWriteBit", #{const VK_ACCESS_TRANSFER_WRITE_BIT}),
+	("AccessHostReadBit", #{const VK_ACCESS_HOST_READ_BIT}),
+	("AccessHostWriteBit", #{const VK_ACCESS_HOST_WRITE_BIT}),
+	("AccessMemoryReadBit", #{const VK_ACCESS_MEMORY_READ_BIT}),
+	("AccessMemoryWriteBit", #{const VK_ACCESS_MEMORY_WRITE_BIT}),
+	("AccessNone", #{const VK_ACCESS_NONE}),
+	("AccessTransformFeedbackWriteBitExt",
+		#{const VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT}),
+	("AccessTransformFeedbackCounterReadBitExt",
+		#{const VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT}),
+	("AccessTransformFeedbackCounterWriteBitExt",
+		#{const VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT}),
+	("AccessConditionalRenderingReadBitExt",
+		#{const VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT}),
+	("AccessColorAttachmentReadNoncoherentBitExt",
+		#{const VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT}),
+	("AccessAccelerationStructureReadBitKhr",
+		#{const VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR}),
+	("AccessAccelerationStructureWriteBitKhr",
+		#{const VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR}),
+	("AccessFragmentDensityMapReadBitExt",
+		#{const VK_ACCESS_FRAGMENT_DENSITY_MAP_READ_BIT_EXT}),
+	("AccessFragmentShadingRateAttachmentReadBitKhr",
+		#{const VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR}),
+	("AccessCommandPreprocessReadBitNv",
+		#{const VK_ACCESS_COMMAND_PREPROCESS_READ_BIT_NV}),
+	("AccessCommandPreprocessWriteBitNv",
+		#{const VK_ACCESS_COMMAND_PREPROCESS_WRITE_BIT_NV}),
+	("AccessShadingRateImageReadBitNv",
+		#{const VK_ACCESS_SHADING_RATE_IMAGE_READ_BIT_NV}),
+	("AccessAccelerationStructureReadBitNv",
+		#{const VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NV}),
+	("AccessAccelerationStructureWriteBitNv",
+		#{const VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_NV}),
+	("AccessNoneKhr", #{const VK_ACCESS_NONE_KHR}),
+	("AccessFlagBitsMaxEnum", #{const VK_ACCESS_FLAG_BITS_MAX_ENUM}) ]
+
+enum "DependencyFlagBits" ''#{type VkDependencyFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("DependencyFlagsZero", 0),
+	("DependencyByRegionBit", #{const VK_DEPENDENCY_BY_REGION_BIT}),
+	("DependencyDeviceGroupBit", #{const VK_DEPENDENCY_DEVICE_GROUP_BIT}),
+	("DependencyViewLocalBit", #{const VK_DEPENDENCY_VIEW_LOCAL_BIT}),
+	("DependencyFeedbackLoopBitExt",
+		#{const VK_DEPENDENCY_FEEDBACK_LOOP_BIT_EXT}),
+	("DependencyViewLocalBitKhr",
+		#{const VK_DEPENDENCY_VIEW_LOCAL_BIT_KHR}),
+	("DependencyDeviceGroupBitKhr",
+		#{const VK_DEPENDENCY_DEVICE_GROUP_BIT_KHR}),
+	("DependencyFlagBitsMaxEnum",
+		#{const VK_DEPENDENCY_FLAG_BITS_MAX_ENUM}) ]
+
+enum "QueryControlFlagBits" ''#{type VkQueryControlFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("QueryControlFlagsZero", 0),
+	("QueryControlPreciseBit", #{const VK_QUERY_CONTROL_PRECISE_BIT}),
+	("QueryControlFlagBitsMaxEnum",
+		#{const VK_QUERY_CONTROL_FLAG_BITS_MAX_ENUM}) ]
+
+enum "QueryPipelineStatisticFlagBits" ''#{type VkQueryPipelineStatisticFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("QueryPipelineStatisticFlagsZero", 0),
+	("QueryPipelineStatisticInputAssemblyVerticesBit",
+		#{const VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT}),
+	("QueryPipelineStatisticInputAssemblyPrimitivesBit",
+		#{const VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT}),
+	("QueryPipelineStatisticVertexShaderInvocationsBit",
+		#{const VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT}),
+	("QueryPipelineStatisticGeometryShaderInvocationsBit",
+		#{const VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT}),
+	("QueryPipelineStatisticGeometryShaderPrimitivesBit",
+		#{const VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT}),
+	("QueryPipelineStatisticClippingInvocationsBit",
+		#{const VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT}),
+	("QueryPipelineStatisticClippingPrimitivesBit",
+		#{const VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT}),
+	("QueryPipelineStatisticFragmentShaderInvocationsBit",
+		#{const VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT}),
+	("QueryPipelineStatisticTessellationControlShaderPatchesBit",
+		#{const VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT}),
+	("QueryPipelineStatisticTessellationEvaluationShaderInvocationsBit",
+		#{const VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT}),
+	("QueryPipelineStatisticComputeShaderInvocationsBit",
+		#{const VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT}),
+	("QueryPipelineStatisticTaskShaderInvocationsBitExt",
+		#{const VK_QUERY_PIPELINE_STATISTIC_TASK_SHADER_INVOCATIONS_BIT_EXT}),
+	("QueryPipelineStatisticMeshShaderInvocationsBitExt",
+		#{const VK_QUERY_PIPELINE_STATISTIC_MESH_SHADER_INVOCATIONS_BIT_EXT}),
+	("QueryPipelineStatisticClusterCullingShaderInvocationsBitHuawei",
+		#{const VK_QUERY_PIPELINE_STATISTIC_CLUSTER_CULLING_SHADER_INVOCATIONS_BIT_HUAWEI}),
+	("QueryPipelineStatisticFlagBitsMaxEnum",
+		#{const VK_QUERY_PIPELINE_STATISTIC_FLAG_BITS_MAX_ENUM}) ]
+
+enum "CullModeFlagBits" ''#{type VkCullModeFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("CullModeFlagsZero", 0),
+	("CullModeNone", #{const VK_CULL_MODE_NONE}),
+	("CullModeFrontBit", #{const VK_CULL_MODE_FRONT_BIT}),
+	("CullModeBackBit", #{const VK_CULL_MODE_BACK_BIT}),
+	("CullModeFrontAndBack", #{const VK_CULL_MODE_FRONT_AND_BACK}),
+	("CullModeFlagBitsMaxEnum", #{const VK_CULL_MODE_FLAG_BITS_MAX_ENUM}) ]
+
+enum "ShaderStageFlagBits" ''#{type VkShaderStageFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("ShaderStageFlagsZero", 0),
+	("ShaderStageVertexBit", #{const VK_SHADER_STAGE_VERTEX_BIT}),
+	("ShaderStageTessellationControlBit",
+		#{const VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT}),
+	("ShaderStageTessellationEvaluationBit",
+		#{const VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT}),
+	("ShaderStageGeometryBit", #{const VK_SHADER_STAGE_GEOMETRY_BIT}),
+	("ShaderStageFragmentBit", #{const VK_SHADER_STAGE_FRAGMENT_BIT}),
+	("ShaderStageComputeBit", #{const VK_SHADER_STAGE_COMPUTE_BIT}),
+	("ShaderStageAllGraphics", #{const VK_SHADER_STAGE_ALL_GRAPHICS}),
+	("ShaderStageAll", #{const VK_SHADER_STAGE_ALL}),
+	("ShaderStageRaygenBitKhr", #{const VK_SHADER_STAGE_RAYGEN_BIT_KHR}),
+	("ShaderStageAnyHitBitKhr", #{const VK_SHADER_STAGE_ANY_HIT_BIT_KHR}),
+	("ShaderStageClosestHitBitKhr",
+		#{const VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR}),
+	("ShaderStageMissBitKhr", #{const VK_SHADER_STAGE_MISS_BIT_KHR}),
+	("ShaderStageIntersectionBitKhr",
+		#{const VK_SHADER_STAGE_INTERSECTION_BIT_KHR}),
+	("ShaderStageCallableBitKhr",
+		#{const VK_SHADER_STAGE_CALLABLE_BIT_KHR}),
+	("ShaderStageTaskBitExt", #{const VK_SHADER_STAGE_TASK_BIT_EXT}),
+	("ShaderStageMeshBitExt", #{const VK_SHADER_STAGE_MESH_BIT_EXT}),
+	("ShaderStageSubpassShadingBitHuawei",
+		#{const VK_SHADER_STAGE_SUBPASS_SHADING_BIT_HUAWEI}),
+	("ShaderStageClusterCullingBitHuawei",
+		#{const VK_SHADER_STAGE_CLUSTER_CULLING_BIT_HUAWEI}),
+	("ShaderStageRaygenBitNv", #{const VK_SHADER_STAGE_RAYGEN_BIT_NV}),
+	("ShaderStageAnyHitBitNv", #{const VK_SHADER_STAGE_ANY_HIT_BIT_NV}),
+	("ShaderStageClosestHitBitNv",
+		#{const VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV}),
+	("ShaderStageMissBitNv", #{const VK_SHADER_STAGE_MISS_BIT_NV}),
+	("ShaderStageIntersectionBitNv",
+		#{const VK_SHADER_STAGE_INTERSECTION_BIT_NV}),
+	("ShaderStageCallableBitNv", #{const VK_SHADER_STAGE_CALLABLE_BIT_NV}),
+	("ShaderStageTaskBitNv", #{const VK_SHADER_STAGE_TASK_BIT_NV}),
+	("ShaderStageMeshBitNv", #{const VK_SHADER_STAGE_MESH_BIT_NV}),
+	("ShaderStageFlagBitsMaxEnum",
+		#{const VK_SHADER_STAGE_FLAG_BITS_MAX_ENUM}) ]
+
+enum "FormatFeatureFlagBits" ''#{type VkFormatFeatureFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits, ''FiniteBits] [
+	("FormatFeatureFlagsZero", 0),
+	("FormatFeatureSampledImageBit",
+		#{const VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT}),
+	("FormatFeatureStorageImageBit",
+		#{const VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT}),
+	("FormatFeatureStorageImageAtomicBit",
+		#{const VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT}),
+	("FormatFeatureUniformTexelBufferBit",
+		#{const VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT}),
+	("FormatFeatureStorageTexelBufferBit",
+		#{const VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT}),
+	("FormatFeatureStorageTexelBufferAtomicBit",
+		#{const VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT}),
+	("FormatFeatureVertexBufferBit",
+		#{const VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT}),
+	("FormatFeatureColorAttachmentBit",
+		#{const VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT}),
+	("FormatFeatureColorAttachmentBlendBit",
+		#{const VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT}),
+	("FormatFeatureDepthStencilAttachmentBit",
+		#{const VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT}),
+	("FormatFeatureBlitSrcBit", #{const VK_FORMAT_FEATURE_BLIT_SRC_BIT}),
+	("FormatFeatureBlitDstBit", #{const VK_FORMAT_FEATURE_BLIT_DST_BIT}),
+	("FormatFeatureSampledImageFilterLinearBit",
+		#{const VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT}),
+	("FormatFeatureTransferSrcBit",
+		#{const VK_FORMAT_FEATURE_TRANSFER_SRC_BIT}),
+	("FormatFeatureTransferDstBit",
+		#{const VK_FORMAT_FEATURE_TRANSFER_DST_BIT}),
+	("FormatFeatureMidpointChromaSamplesBit",
+		#{const VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT}),
+	("FormatFeatureSampledImageYcbcrConversionLinearFilterBit",
+		#{const VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT}),
+	("FormatFeatureSampledImageYcbcrConversionSeparateReconstructionFilterBit",
+		#{const VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT}),
+	("FormatFeatureSampledImageYcbcrConversionChromaReconstructionExplicitBit",
+		#{const VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT}),
+	("FormatFeatureSampledImageYcbcrConversionChromaReconstructionExplicitForceableBit",
+		#{const VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT}),
+	("FormatFeatureDisjointBit", #{const VK_FORMAT_FEATURE_DISJOINT_BIT}),
+	("FormatFeatureCositedChromaSamplesBit",
+		#{const VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT}),
+	("FormatFeatureSampledImageFilterMinmaxBit",
+		#{const VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT}),
+	("FormatFeatureVideoDecodeOutputBitKhr",
+		#{const VK_FORMAT_FEATURE_VIDEO_DECODE_OUTPUT_BIT_KHR}),
+	("FormatFeatureVideoDecodeDpbBitKhr",
+		#{const VK_FORMAT_FEATURE_VIDEO_DECODE_DPB_BIT_KHR}),
+	("FormatFeatureAccelerationStructureVertexBufferBitKhr",
+		#{const VK_FORMAT_FEATURE_ACCELERATION_STRUCTURE_VERTEX_BUFFER_BIT_KHR}),
+	("FormatFeatureSampledImageFilterCubicBitExt",
+		#{const VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT}),
+	("FormatFeatureFragmentDensityMapBitExt",
+		#{const VK_FORMAT_FEATURE_FRAGMENT_DENSITY_MAP_BIT_EXT}),
+	("FormatFeatureFragmentShadingRateAttachmentBitKhr",
+		#{const VK_FORMAT_FEATURE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR}),
+	("FormatFeatureSampledImageFilterCubicBitImg",
+		#{const VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG}),
+	("FormatFeatureTransferSrcBitKhr",
+		#{const VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR}),
+	("FormatFeatureTransferDstBitKhr",
+		#{const VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR}),
+	("FormatFeatureSampledImageFilterMinmaxBitExt",
+		#{const VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT}),
+	("FormatFeatureMidpointChromaSamplesBitKhr",
+		#{const VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT_KHR}),
+	("FormatFeatureSampledImageYcbcrConversionLinearFilterBitKhr",
+		#{const VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT_KHR}),
+	("FormatFeatureSampledImageYcbcrConversionSeparateReconstructionFilterBitKhr",
+		#{const VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT_KHR}),
+	("FormatFeatureSampledImageYcbcrConversionChromaReconstructionExplicitBitKhr",
+		#{const VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT_KHR}),
+	("FormatFeatureSampledImageYcbcrConversionChromaReconstructionExplicitForceableBitKhr",
+		#{const VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT_KHR}),
+	("FormatFeatureDisjointBitKhr",
+		#{const VK_FORMAT_FEATURE_DISJOINT_BIT_KHR}),
+	("FormatFeatureCositedChromaSamplesBitKhr",
+		#{const VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT_KHR}),
+	("FormatFeatureFlagBitsMaxEnum",
+		#{const VK_FORMAT_FEATURE_FLAG_BITS_MAX_ENUM}) ]
+
+type PtrDynamicState = Ptr DynamicState
+type AccessFlags = AccessFlagBits
+type DependencyFlags = DependencyFlagBits
+type QueryControlFlags = QueryControlFlagBits
+type QueryPipelineStatisticFlags = QueryPipelineStatisticFlagBits
+type CullModeFlags = CullModeFlagBits
+type ShaderStageFlags = ShaderStageFlagBits
+type FormatFeatureFlags = FormatFeatureFlagBits
diff --git a/src/Gpu/Vulkan/Exception/Enum.hsc b/src/Gpu/Vulkan/Exception/Enum.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Exception/Enum.hsc
@@ -0,0 +1,95 @@
+-- This file is automatically generated by the tools/makeEnum.hs
+--	% stack runghc --cwd tools/ makeEnum
+
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-missing-export-lists -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Exception.Enum where
+
+import Foreign.Storable
+import Foreign.C.Enum
+import Data.Int
+
+#include <vulkan/vulkan.h>
+
+enum "Result" ''#{type VkResult}
+		[''Show, ''Read, ''Eq, ''Enum, ''Storable] [
+	("Success", #{const VK_SUCCESS}),
+	("NotReady", #{const VK_NOT_READY}),
+	("Timeout", #{const VK_TIMEOUT}),
+	("EventSet", #{const VK_EVENT_SET}),
+	("EventReset", #{const VK_EVENT_RESET}),
+	("Incomplete", #{const VK_INCOMPLETE}),
+	("ErrorOutOfHostMemory", #{const VK_ERROR_OUT_OF_HOST_MEMORY}),
+	("ErrorOutOfDeviceMemory", #{const VK_ERROR_OUT_OF_DEVICE_MEMORY}),
+	("ErrorInitializationFailed", #{const VK_ERROR_INITIALIZATION_FAILED}),
+	("ErrorDeviceLost", #{const VK_ERROR_DEVICE_LOST}),
+	("ErrorMemoryMapFailed", #{const VK_ERROR_MEMORY_MAP_FAILED}),
+	("ErrorLayerNotPresent", #{const VK_ERROR_LAYER_NOT_PRESENT}),
+	("ErrorExtensionNotPresent", #{const VK_ERROR_EXTENSION_NOT_PRESENT}),
+	("ErrorFeatureNotPresent", #{const VK_ERROR_FEATURE_NOT_PRESENT}),
+	("ErrorIncompatibleDriver", #{const VK_ERROR_INCOMPATIBLE_DRIVER}),
+	("ErrorTooManyObjects", #{const VK_ERROR_TOO_MANY_OBJECTS}),
+	("ErrorFormatNotSupported", #{const VK_ERROR_FORMAT_NOT_SUPPORTED}),
+	("ErrorFragmentedPool", #{const VK_ERROR_FRAGMENTED_POOL}),
+	("ErrorUnknown", #{const VK_ERROR_UNKNOWN}),
+	("ErrorOutOfPoolMemory", #{const VK_ERROR_OUT_OF_POOL_MEMORY}),
+	("ErrorInvalidExternalHandle",
+		#{const VK_ERROR_INVALID_EXTERNAL_HANDLE}),
+	("ErrorFragmentation", #{const VK_ERROR_FRAGMENTATION}),
+	("ErrorInvalidOpaqueCaptureAddress",
+		#{const VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS}),
+	("PipelineCompileRequired", #{const VK_PIPELINE_COMPILE_REQUIRED}),
+	("ErrorSurfaceLostKhr", #{const VK_ERROR_SURFACE_LOST_KHR}),
+	("ErrorNativeWindowInUseKhr",
+		#{const VK_ERROR_NATIVE_WINDOW_IN_USE_KHR}),
+	("SuboptimalKhr", #{const VK_SUBOPTIMAL_KHR}),
+	("ErrorOutOfDateKhr", #{const VK_ERROR_OUT_OF_DATE_KHR}),
+	("ErrorIncompatibleDisplayKhr",
+		#{const VK_ERROR_INCOMPATIBLE_DISPLAY_KHR}),
+	("ErrorValidationFailedExt", #{const VK_ERROR_VALIDATION_FAILED_EXT}),
+	("ErrorInvalidShaderNv", #{const VK_ERROR_INVALID_SHADER_NV}),
+	("ErrorImageUsageNotSupportedKhr",
+		#{const VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR}),
+	("ErrorVideoPictureLayoutNotSupportedKhr",
+		#{const VK_ERROR_VIDEO_PICTURE_LAYOUT_NOT_SUPPORTED_KHR}),
+	("ErrorVideoProfileOperationNotSupportedKhr",
+		#{const VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR}),
+	("ErrorVideoProfileFormatNotSupportedKhr",
+		#{const VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR}),
+	("ErrorVideoProfileCodecNotSupportedKhr",
+		#{const VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR}),
+	("ErrorVideoStdVersionNotSupportedKhr",
+		#{const VK_ERROR_VIDEO_STD_VERSION_NOT_SUPPORTED_KHR}),
+	("ErrorInvalidDrmFormatModifierPlaneLayoutExt",
+		#{const VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT}),
+	("ErrorNotPermittedKhr", #{const VK_ERROR_NOT_PERMITTED_KHR}),
+	("ErrorFullScreenExclusiveModeLostExt",
+		#{const VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT}),
+	("ThreadIdleKhr", #{const VK_THREAD_IDLE_KHR}),
+	("ThreadDoneKhr", #{const VK_THREAD_DONE_KHR}),
+	("OperationDeferredKhr", #{const VK_OPERATION_DEFERRED_KHR}),
+	("OperationNotDeferredKhr", #{const VK_OPERATION_NOT_DEFERRED_KHR}),
+	("ErrorCompressionExhaustedExt",
+		#{const VK_ERROR_COMPRESSION_EXHAUSTED_EXT}),
+	("ErrorIncompatibleShaderBinaryExt",
+		#{const VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT}),
+	("ErrorOutOfPoolMemoryKhr", #{const VK_ERROR_OUT_OF_POOL_MEMORY_KHR}),
+	("ErrorInvalidExternalHandleKhr",
+		#{const VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR}),
+	("ErrorFragmentationExt", #{const VK_ERROR_FRAGMENTATION_EXT}),
+	("ErrorNotPermittedExt", #{const VK_ERROR_NOT_PERMITTED_EXT}),
+	("ErrorInvalidDeviceAddressExt",
+		#{const VK_ERROR_INVALID_DEVICE_ADDRESS_EXT}),
+	("ErrorInvalidOpaqueCaptureAddressKhr",
+		#{const VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR}),
+	("PipelineCompileRequiredExt",
+		#{const VK_PIPELINE_COMPILE_REQUIRED_EXT}),
+	("ErrorPipelineCompileRequiredExt",
+		#{const VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT}),
+	("ResultMaxEnum", #{const VK_RESULT_MAX_ENUM}) ]
+
+type PtrResult = Result
diff --git a/src/Gpu/Vulkan/Exception/Middle.hs b/src/Gpu/Vulkan/Exception/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Exception/Middle.hs
@@ -0,0 +1,15 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Exception.Middle (
+
+	-- * THROW
+
+	throwUnless, throwUnlessSuccess, throwUnlessSuccesses,
+
+	-- * MULTI RESULT
+
+	MultiResult(..)
+
+	) where
+
+import Gpu.Vulkan.Exception.Middle.Internal
diff --git a/src/Gpu/Vulkan/Exception/Middle/Internal.hsc b/src/Gpu/Vulkan/Exception/Middle/Internal.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Exception/Middle/Internal.hsc
@@ -0,0 +1,35 @@
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE ExistentialQuantification #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs -fno-warn-orphans #-}
+
+module Gpu.Vulkan.Exception.Middle.Internal where
+
+import Control.Exception
+import Control.Exception.Hierarchy
+import Data.List.NonEmpty (NonEmpty, nonEmpty)
+
+import Gpu.Vulkan.Exception.Enum
+
+data MultiResult = MultiResult (NonEmpty (Int, Result)) deriving Show
+
+exceptionHierarchy Nothing $ ExNode "E" [
+	ExType ''Result,
+	ExType ''MultiResult ]
+
+throwUnlessSuccess :: Result -> IO ()
+throwUnlessSuccess = throwUnless [Success]
+
+throwUnless :: [Result] -> Result -> IO ()
+throwUnless sccs r | r `elem` sccs = pure () | otherwise = throw r
+
+throwUnlessSuccesses :: [Result] -> IO ()
+throwUnlessSuccesses = throwUnlesses [Success]
+
+throwUnlesses :: [Result] -> [Result] -> IO ()
+throwUnlesses sccs rs = do
+	let	irs = zip [0 ..] rs
+		irs' = filter ((`notElem` sccs) . snd) irs
+	case nonEmpty irs' of
+		Nothing -> pure ()
+		Just r -> throw $ MultiResult r
diff --git a/src/Gpu/Vulkan/Fence/Enum.hsc b/src/Gpu/Vulkan/Fence/Enum.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Fence/Enum.hsc
@@ -0,0 +1,26 @@
+-- This file is automatically generated by the tools/makeEnum.hs
+--	% stack runghc --cwd tools/ makeEnum
+
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-missing-export-lists -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Fence.Enum where
+
+import Foreign.Storable
+import Foreign.C.Enum
+import Data.Bits
+import Data.Word
+
+#include <vulkan/vulkan.h>
+
+enum "CreateFlagBits" ''#{type VkFenceCreateFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("CreateFlagsZero", 0),
+	("CreateSignaledBit", #{const VK_FENCE_CREATE_SIGNALED_BIT}),
+	("CreateFlagBitsMaxEnum",
+		#{const VK_FENCE_CREATE_FLAG_BITS_MAX_ENUM}) ]
+
+type CreateFlags = CreateFlagBits
diff --git a/src/Gpu/Vulkan/Fence/Middle.hs b/src/Gpu/Vulkan/Fence/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Fence/Middle.hs
@@ -0,0 +1,15 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Fence.Middle (
+
+	-- * CREATE AND DESTROY
+
+	create, destroy, F, CreateInfo(..),
+
+	-- * RESET AND WAIT
+
+	resetFs, waitForFs
+
+	) where
+
+import Gpu.Vulkan.Fence.Middle.Internal
diff --git a/src/Gpu/Vulkan/Fence/Middle/Internal.hs b/src/Gpu/Vulkan/Fence/Middle/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Fence/Middle/Internal.hs
@@ -0,0 +1,101 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE MonoLocalBinds #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE FlexibleContexts, FlexibleInstances, UndecidableInstances #-}
+{-# LANGUAGE ViewPatterns #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Fence.Middle.Internal (
+
+	-- * CREATE AND DESTROY
+
+	create, destroy, F(..), CreateInfo(..),
+
+	-- * RESET AND WAIT
+
+	resetFs, waitForFs,
+
+	-- * INTERNAL USE
+
+	maybeFToCore
+
+	) where
+
+import Foreign.Ptr
+import Foreign.Marshal.Alloc
+import Foreign.Marshal.Array
+import Foreign.Storable
+import Foreign.Storable.PeekPoke (withPoked, withPoked', WithPoked, withPtrS)
+import Control.Arrow
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Data.TypeLevel.ParMaybe qualified as TPMaybe
+import Data.Default
+import Data.Bits
+import Data.Word
+
+import Gpu.Vulkan.Base.Middle.Internal
+import Gpu.Vulkan.Exception.Middle.Internal
+import Gpu.Vulkan.Exception.Enum
+import Gpu.Vulkan.Fence.Enum
+
+import qualified Gpu.Vulkan.AllocationCallbacks.Middle.Internal as AllocationCallbacks
+import qualified Gpu.Vulkan.Device.Middle.Types as Device
+import qualified Gpu.Vulkan.Fence.Core as C
+
+data CreateInfo mn = CreateInfo {
+	createInfoNext :: TMaybe.M mn,
+	createInfoFlags :: CreateFlags }
+
+deriving instance Show (TMaybe.M mn) => Show (CreateInfo mn)
+
+instance Default (CreateInfo 'Nothing) where
+	def = CreateInfo {
+		createInfoNext = TMaybe.N, createInfoFlags = zeroBits }
+
+createInfoToCore :: WithPoked (TMaybe.M mn) =>
+	CreateInfo mn -> (Ptr C.CreateInfo -> IO a) -> IO ()
+createInfoToCore CreateInfo {
+	createInfoNext = mnxt, createInfoFlags = CreateFlagBits flgs } f =
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+		withPoked C.CreateInfo {
+			C.createInfoSType = (),
+			C.createInfoPNext = pnxt',
+			C.createInfoFlags = flgs } f
+
+newtype F = F C.F deriving Show
+
+fToCore :: F -> C.F
+fToCore (F f) = f
+
+maybeFToCore :: Maybe F -> C.F
+maybeFToCore Nothing = NullHandle
+maybeFToCore (Just f) = fToCore f
+
+create :: WithPoked (TMaybe.M mn) =>
+	Device.D -> CreateInfo mn -> TPMaybe.M AllocationCallbacks.A mc -> IO F
+create (Device.D dvc) ci mac = F <$> alloca \pf -> do
+	createInfoToCore ci \pci ->
+		AllocationCallbacks.mToCore mac \pac -> do
+			r <- C.create dvc pci pac pf
+			throwUnlessSuccess $ Result r
+	peek pf
+
+destroy :: Device.D -> F -> TPMaybe.M AllocationCallbacks.A md -> IO ()
+destroy (Device.D dvc) (F f) mac =
+	AllocationCallbacks.mToCore mac $ C.destroy dvc f
+
+waitForFs :: Device.D -> [F] -> Bool -> Word64 -> IO ()
+waitForFs (Device.D dvc) (length &&& ((\(F f) -> f) <$>) -> (fc, fs))
+	(boolToBool32 -> wa) to = allocaArray fc \pfs -> do
+		pokeArray pfs fs
+		r <- C.waitForFs dvc (fromIntegral fc) pfs wa to
+		throwUnlessSuccess $ Result r
+
+resetFs :: Device.D -> [F] -> IO ()
+resetFs (Device.D dvc)
+	(length &&& ((\(F f) -> f) <$>) -> (fc, fs)) = allocaArray fc \pfs -> do
+		pokeArray pfs fs
+		r <- C.resetFs dvc (fromIntegral fc) pfs
+		throwUnlessSuccess $ Result r
diff --git a/src/Gpu/Vulkan/Framebuffer/Enum.hsc b/src/Gpu/Vulkan/Framebuffer/Enum.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Framebuffer/Enum.hsc
@@ -0,0 +1,29 @@
+-- This file is automatically generated by the tools/makeEnum.hs
+--	% stack runghc --cwd tools/ makeEnum
+
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-missing-export-lists -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Framebuffer.Enum where
+
+import Foreign.Storable
+import Foreign.C.Enum
+import Data.Bits
+import Data.Word
+
+#include <vulkan/vulkan.h>
+
+enum "CreateFlagBits" ''#{type VkFramebufferCreateFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("CreateFlagsZero", 0),
+	("CreateImagelessBit",
+		#{const VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT}),
+	("CreateImagelessBitKhr",
+		#{const VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR}),
+	("CreateFlagBitsMaxEnum",
+		#{const VK_FRAMEBUFFER_CREATE_FLAG_BITS_MAX_ENUM}) ]
+
+type CreateFlags = CreateFlagBits
diff --git a/src/Gpu/Vulkan/Framebuffer/Middle.hs b/src/Gpu/Vulkan/Framebuffer/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Framebuffer/Middle.hs
@@ -0,0 +1,11 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Framebuffer.Middle (
+
+	-- * CREATE AND DESTROY
+
+	create, recreate, destroy, F, CreateInfo(..)
+
+	) where
+
+import Gpu.Vulkan.Framebuffer.Middle.Internal
diff --git a/src/Gpu/Vulkan/Framebuffer/Middle/Internal.hs b/src/Gpu/Vulkan/Framebuffer/Middle/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Framebuffer/Middle/Internal.hs
@@ -0,0 +1,104 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE MonoLocalBinds #-}
+{-# LANGUAGE FlexibleContexts, UndecidableInstances #-}
+{-# LANGUAGE ViewPatterns #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Framebuffer.Middle.Internal (
+	F, CreateInfo(..), create, recreate, destroy,
+
+	fToCore ) where
+
+import Foreign.Ptr
+import Foreign.Marshal.Alloc
+import Foreign.Marshal.Array
+import Foreign.Storable
+import Foreign.Storable.PeekPoke (
+	withPoked, WithPoked, withPoked', withPtrS )
+import Control.Arrow
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Data.TypeLevel.ParMaybe qualified as TPMaybe
+import Data.Word
+import Data.IORef
+
+import Gpu.Vulkan.Exception.Middle.Internal
+import Gpu.Vulkan.Exception.Enum
+import Gpu.Vulkan.Framebuffer.Enum
+
+import Gpu.Vulkan.AllocationCallbacks.Middle.Internal
+	qualified as AllocationCallbacks
+import qualified Gpu.Vulkan.Device.Middle.Types as Device
+import {-# SOURCE #-} qualified Gpu.Vulkan.RenderPass.Middle.Internal as RenderPass
+import qualified Gpu.Vulkan.ImageView.Middle.Internal as ImageView
+import qualified Gpu.Vulkan.Framebuffer.Core as C
+
+data CreateInfo mn = CreateInfo {
+	createInfoNext :: TMaybe.M mn,
+	createInfoFlags :: CreateFlags,
+	createInfoRenderPass :: RenderPass.R,
+	createInfoAttachments :: [ImageView.I],
+	createInfoWidth :: Word32,
+	createInfoHeight :: Word32,
+	createInfoLayers :: Word32 }
+
+deriving instance Show (TMaybe.M mn) => Show (CreateInfo mn)
+
+createInfoToCore :: WithPoked (TMaybe.M mn) =>
+	CreateInfo mn -> (Ptr C.CreateInfo -> IO a) -> IO ()
+createInfoToCore CreateInfo {
+	createInfoNext = mnxt,
+	createInfoFlags = CreateFlagBits flgs,
+	createInfoRenderPass = RenderPass.R rp,
+	createInfoAttachments = length &&& id -> (ac, as),
+	createInfoWidth = w,
+	createInfoHeight = h,
+	createInfoLayers = l } f =
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+	allocaArray ac \pas -> do
+		pokeArray pas =<< ImageView.iToCore `mapM` as
+		let	ci = C.CreateInfo {
+				C.createInfoSType = (),
+				C.createInfoPNext = pnxt',
+				C.createInfoFlags = flgs,
+				C.createInfoRenderPass = rp,
+				C.createInfoAttachmentCount = fromIntegral ac,
+				C.createInfoPAttachments = pas,
+				C.createInfoWidth = w,
+				C.createInfoHeight = h,
+				C.createInfoLayers = l }
+		withPoked ci f
+
+newtype F = F (IORef C.F)
+
+fToCore :: F -> IO C.F
+fToCore (F f) = readIORef f
+
+fFromCore :: C.F -> IO F
+fFromCore f = F <$> newIORef f
+
+create :: WithPoked (TMaybe.M mn) =>
+	Device.D -> CreateInfo mn -> TPMaybe.M AllocationCallbacks.A mc -> IO F
+create (Device.D dvc) ci mac = fFromCore =<< alloca \pf -> do
+	createInfoToCore ci \pci ->
+		AllocationCallbacks.mToCore mac \pac -> do
+			throwUnlessSuccess . Result =<< C.create dvc pci pac pf
+	peek pf
+
+destroy :: Device.D -> F -> TPMaybe.M AllocationCallbacks.A md -> IO ()
+destroy (Device.D dvc) f mac = AllocationCallbacks.mToCore mac \pac -> do
+	f' <- fToCore f; C.destroy dvc f' pac
+
+recreate :: WithPoked (TMaybe.M mn) =>
+	Device.D -> CreateInfo mn -> TPMaybe.M AllocationCallbacks.A mc ->
+	TPMaybe.M AllocationCallbacks.A md -> F -> IO ()
+recreate (Device.D dvc) ci macc macd f@(F rf) =
+	fToCore f >>= \o -> alloca \pf ->
+	createInfoToCore ci \pci ->
+	AllocationCallbacks.mToCore macc \pacc ->
+	AllocationCallbacks.mToCore macd \pacd -> do
+		r <- C.create dvc pci pacc pf
+		throwUnlessSuccess $ Result r
+		writeIORef rf =<< peek pf
+		C.destroy dvc o pacd
diff --git a/src/Gpu/Vulkan/Image/Enum.hsc b/src/Gpu/Vulkan/Image/Enum.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Image/Enum.hsc
@@ -0,0 +1,220 @@
+-- This file is automatically generated by the tools/makeEnum.hs
+--	% stack runghc --cwd tools/ makeEnum
+
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-missing-export-lists -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Image.Enum where
+
+import Foreign.Storable
+import Foreign.C.Enum
+import Data.Bits
+import Data.Word
+
+#include <vulkan/vulkan.h>
+
+enum "UsageFlagBits" ''#{type VkImageUsageFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("UsageFlagsZero", 0),
+	("UsageTransferSrcBit", #{const VK_IMAGE_USAGE_TRANSFER_SRC_BIT}),
+	("UsageTransferDstBit", #{const VK_IMAGE_USAGE_TRANSFER_DST_BIT}),
+	("UsageSampledBit", #{const VK_IMAGE_USAGE_SAMPLED_BIT}),
+	("UsageStorageBit", #{const VK_IMAGE_USAGE_STORAGE_BIT}),
+	("UsageColorAttachmentBit",
+		#{const VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT}),
+	("UsageDepthStencilAttachmentBit",
+		#{const VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT}),
+	("UsageTransientAttachmentBit",
+		#{const VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT}),
+	("UsageInputAttachmentBit",
+		#{const VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT}),
+	("UsageVideoDecodeDstBitKhr",
+		#{const VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR}),
+	("UsageVideoDecodeSrcBitKhr",
+		#{const VK_IMAGE_USAGE_VIDEO_DECODE_SRC_BIT_KHR}),
+	("UsageVideoDecodeDpbBitKhr",
+		#{const VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR}),
+	("UsageFragmentDensityMapBitExt",
+		#{const VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT}),
+	("UsageFragmentShadingRateAttachmentBitKhr",
+		#{const VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR}),
+	("UsageAttachmentFeedbackLoopBitExt",
+		#{const VK_IMAGE_USAGE_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT}),
+	("UsageInvocationMaskBitHuawei",
+		#{const VK_IMAGE_USAGE_INVOCATION_MASK_BIT_HUAWEI}),
+	("UsageSampleWeightBitQcom",
+		#{const VK_IMAGE_USAGE_SAMPLE_WEIGHT_BIT_QCOM}),
+	("UsageSampleBlockMatchBitQcom",
+		#{const VK_IMAGE_USAGE_SAMPLE_BLOCK_MATCH_BIT_QCOM}),
+	("UsageShadingRateImageBitNv",
+		#{const VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV}),
+	("UsageFlagBitsMaxEnum",
+		#{const VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM}) ]
+
+enum "AspectFlagBits" ''#{type VkImageAspectFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("AspectFlagsZero", 0),
+	("AspectColorBit", #{const VK_IMAGE_ASPECT_COLOR_BIT}),
+	("AspectDepthBit", #{const VK_IMAGE_ASPECT_DEPTH_BIT}),
+	("AspectStencilBit", #{const VK_IMAGE_ASPECT_STENCIL_BIT}),
+	("AspectMetadataBit", #{const VK_IMAGE_ASPECT_METADATA_BIT}),
+	("AspectPlane0Bit", #{const VK_IMAGE_ASPECT_PLANE_0_BIT}),
+	("AspectPlane1Bit", #{const VK_IMAGE_ASPECT_PLANE_1_BIT}),
+	("AspectPlane2Bit", #{const VK_IMAGE_ASPECT_PLANE_2_BIT}),
+	("AspectNone", #{const VK_IMAGE_ASPECT_NONE}),
+	("AspectMemoryPlane0BitExt",
+		#{const VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT}),
+	("AspectMemoryPlane1BitExt",
+		#{const VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT}),
+	("AspectMemoryPlane2BitExt",
+		#{const VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT}),
+	("AspectMemoryPlane3BitExt",
+		#{const VK_IMAGE_ASPECT_MEMORY_PLANE_3_BIT_EXT}),
+	("AspectPlane0BitKhr", #{const VK_IMAGE_ASPECT_PLANE_0_BIT_KHR}),
+	("AspectPlane1BitKhr", #{const VK_IMAGE_ASPECT_PLANE_1_BIT_KHR}),
+	("AspectPlane2BitKhr", #{const VK_IMAGE_ASPECT_PLANE_2_BIT_KHR}),
+	("AspectNoneKhr", #{const VK_IMAGE_ASPECT_NONE_KHR}),
+	("AspectFlagBitsMaxEnum",
+		#{const VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM}) ]
+
+enum "Layout" ''#{type VkImageLayout}
+		[''Show, ''Eq, ''Storable] [
+	("LayoutUndefined", #{const VK_IMAGE_LAYOUT_UNDEFINED}),
+	("LayoutGeneral", #{const VK_IMAGE_LAYOUT_GENERAL}),
+	("LayoutColorAttachmentOptimal",
+		#{const VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}),
+	("LayoutDepthStencilAttachmentOptimal",
+		#{const VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}),
+	("LayoutDepthStencilReadOnlyOptimal",
+		#{const VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL}),
+	("LayoutShaderReadOnlyOptimal",
+		#{const VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL}),
+	("LayoutTransferSrcOptimal",
+		#{const VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL}),
+	("LayoutTransferDstOptimal",
+		#{const VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL}),
+	("LayoutPreinitialized", #{const VK_IMAGE_LAYOUT_PREINITIALIZED}),
+	("LayoutDepthReadOnlyStencilAttachmentOptimal",
+		#{const VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL}),
+	("LayoutDepthAttachmentStencilReadOnlyOptimal",
+		#{const VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL}),
+	("LayoutDepthAttachmentOptimal",
+		#{const VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL}),
+	("LayoutDepthReadOnlyOptimal",
+		#{const VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL}),
+	("LayoutStencilAttachmentOptimal",
+		#{const VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL}),
+	("LayoutStencilReadOnlyOptimal",
+		#{const VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL}),
+	("LayoutReadOnlyOptimal",
+		#{const VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL}),
+	("LayoutAttachmentOptimal",
+		#{const VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL}),
+	("LayoutPresentSrcKhr", #{const VK_IMAGE_LAYOUT_PRESENT_SRC_KHR}),
+	("LayoutVideoDecodeDstKhr",
+		#{const VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR}),
+	("LayoutVideoDecodeSrcKhr",
+		#{const VK_IMAGE_LAYOUT_VIDEO_DECODE_SRC_KHR}),
+	("LayoutVideoDecodeDpbKhr",
+		#{const VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR}),
+	("LayoutSharedPresentKhr",
+		#{const VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR}),
+	("LayoutFragmentDensityMapOptimalExt",
+		#{const VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT}),
+	("LayoutFragmentShadingRateAttachmentOptimalKhr",
+		#{const VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR}),
+	("LayoutAttachmentFeedbackLoopOptimalExt",
+		#{const VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT}),
+	("LayoutDepthReadOnlyStencilAttachmentOptimalKhr",
+		#{const VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR}),
+	("LayoutDepthAttachmentStencilReadOnlyOptimalKhr",
+		#{const VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR}),
+	("LayoutShadingRateOptimalNv",
+		#{const VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV}),
+	("LayoutDepthAttachmentOptimalKhr",
+		#{const VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR}),
+	("LayoutDepthReadOnlyOptimalKhr",
+		#{const VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR}),
+	("LayoutStencilAttachmentOptimalKhr",
+		#{const VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR}),
+	("LayoutStencilReadOnlyOptimalKhr",
+		#{const VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR}),
+	("LayoutReadOnlyOptimalKhr",
+		#{const VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR}),
+	("LayoutAttachmentOptimalKhr",
+		#{const VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR}),
+	("LayoutMaxEnum", #{const VK_IMAGE_LAYOUT_MAX_ENUM}) ]
+
+enum "CreateFlagBits" ''#{type VkImageCreateFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("CreateFlagsZero", 0),
+	("CreateSparseBindingBit",
+		#{const VK_IMAGE_CREATE_SPARSE_BINDING_BIT}),
+	("CreateSparseResidencyBit",
+		#{const VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT}),
+	("CreateSparseAliasedBit",
+		#{const VK_IMAGE_CREATE_SPARSE_ALIASED_BIT}),
+	("CreateMutableFormatBit",
+		#{const VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT}),
+	("CreateCubeCompatibleBit",
+		#{const VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT}),
+	("CreateAliasBit", #{const VK_IMAGE_CREATE_ALIAS_BIT}),
+	("CreateSplitInstanceBindRegionsBit",
+		#{const VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT}),
+	("Create2dArrayCompatibleBit",
+		#{const VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT}),
+	("CreateBlockTexelViewCompatibleBit",
+		#{const VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT}),
+	("CreateExtendedUsageBit",
+		#{const VK_IMAGE_CREATE_EXTENDED_USAGE_BIT}),
+	("CreateProtectedBit", #{const VK_IMAGE_CREATE_PROTECTED_BIT}),
+	("CreateDisjointBit", #{const VK_IMAGE_CREATE_DISJOINT_BIT}),
+	("CreateCornerSampledBitNv",
+		#{const VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV}),
+	("CreateSampleLocationsCompatibleDepthBitExt",
+		#{const VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT}),
+	("CreateSubsampledBitExt",
+		#{const VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT}),
+	("CreateDescriptorBufferCaptureReplayBitExt",
+		#{const VK_IMAGE_CREATE_DESCRIPTOR_BUFFER_CAPTURE_REPLAY_BIT_EXT}),
+	("CreateMultisampledRenderToSingleSampledBitExt",
+		#{const VK_IMAGE_CREATE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_BIT_EXT}),
+	("Create2dViewCompatibleBitExt",
+		#{const VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT}),
+	("CreateFragmentDensityMapOffsetBitQcom",
+		#{const VK_IMAGE_CREATE_FRAGMENT_DENSITY_MAP_OFFSET_BIT_QCOM}),
+	("CreateSplitInstanceBindRegionsBitKhr",
+		#{const VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR}),
+	("Create2dArrayCompatibleBitKhr",
+		#{const VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR}),
+	("CreateBlockTexelViewCompatibleBitKhr",
+		#{const VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_KHR}),
+	("CreateExtendedUsageBitKhr",
+		#{const VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR}),
+	("CreateDisjointBitKhr",
+		#{const VK_IMAGE_CREATE_DISJOINT_BIT_KHR}),
+	("CreateAliasBitKhr", #{const VK_IMAGE_CREATE_ALIAS_BIT_KHR}),
+	("CreateFlagBitsMaxEnum",
+		#{const VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM}) ]
+
+enum "Type" ''#{type VkImageType}
+		[''Show, ''Eq, ''Storable] [
+	("Type1d", #{const VK_IMAGE_TYPE_1D}),
+	("Type2d", #{const VK_IMAGE_TYPE_2D}),
+	("Type3d", #{const VK_IMAGE_TYPE_3D}),
+	("TypeMaxEnum", #{const VK_IMAGE_TYPE_MAX_ENUM}) ]
+
+enum "Tiling" ''#{type VkImageTiling}
+		[''Show, ''Eq, ''Storable] [
+	("TilingOptimal", #{const VK_IMAGE_TILING_OPTIMAL}),
+	("TilingLinear", #{const VK_IMAGE_TILING_LINEAR}),
+	("TilingDrmFormatModifierExt",
+		#{const VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT}),
+	("TilingMaxEnum", #{const VK_IMAGE_TILING_MAX_ENUM}) ]
+
+type UsageFlags = UsageFlagBits
+type AspectFlags = AspectFlagBits
+type CreateFlags = CreateFlagBits
diff --git a/src/Gpu/Vulkan/Image/Middle.hs b/src/Gpu/Vulkan/Image/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Image/Middle.hs
@@ -0,0 +1,28 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Image.Middle (
+
+	-- * CREATE AND DESTROY
+
+	create, recreate, recreate', destroy, I, CreateInfo(..),
+
+	-- ** Manage Multiple Image
+
+	Group, group, create', destroy', lookup,
+
+	-- * GET MEMORY REQUIREMENTS AND BIND MEMORY
+
+	getMemoryRequirements, bindMemory,
+
+	-- * MEMORY BARRIER
+
+	MemoryBarrier(..), SubresourceRange(..),
+
+	-- * BLIT
+
+	Blit(..), SubresourceLayers(..)
+
+	) where
+
+import Prelude hiding (lookup)
+import Gpu.Vulkan.Image.Middle.Internal
diff --git a/src/Gpu/Vulkan/Image/Middle/Internal.hs b/src/Gpu/Vulkan/Image/Middle/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Image/Middle/Internal.hs
@@ -0,0 +1,334 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE BlockArguments, TupleSections #-}
+{-# LANGUAGe ScopedTypeVariables, RankNTypes, TypeApplications #-}
+{-# LANGUAGE MonoLocalBinds #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE FlexibleContexts, UndecidableInstances #-}
+{-# LANGUAGE ViewPatterns #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Image.Middle.Internal (
+
+	-- * CREATE AND DESTROY
+
+	create, recreate, recreate', destroy, I(..), CreateInfo(..),
+
+	-- ** Image Group
+
+	Group, group, create', destroy', lookup,
+
+	-- * GET MEMORY REQUIREMENTS AND BIND MEMORY
+
+	getMemoryRequirements, bindMemory,
+
+	-- * MEMORY BARRIER
+
+	MemoryBarrier(..), memoryBarrierToCore,
+	SubresourceRange(..), subresourceRangeToCore,
+
+	-- * BLIT
+
+	Blit(..), blitToCore,
+	SubresourceLayers(..), subresourceLayersToCore
+
+	) where
+
+import Prelude hiding (lookup)
+import Foreign.Ptr
+import Foreign.Marshal.Alloc
+import Foreign.Marshal.Array
+import Foreign.Storable
+import Foreign.Storable.PeekPoke (withPoked, WithPoked, withPoked', withPtrS)
+import Control.Arrow
+import Control.Monad.Trans
+import Control.Monad.Cont
+import Control.Concurrent.STM
+import Control.Concurrent.STM.TSem
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Data.TypeLevel.ParMaybe qualified as TPMaybe
+import Data.Map qualified as M
+import Data.IORef
+import Data.Word
+
+import Gpu.Vulkan.Core
+import Gpu.Vulkan.Enum
+import Gpu.Vulkan.Exception.Middle.Internal
+import Gpu.Vulkan.Exception.Enum
+import Gpu.Vulkan.Image.Enum
+
+import Gpu.Vulkan.AllocationCallbacks.Middle.Internal
+	qualified as AllocationCallbacks
+import qualified Gpu.Vulkan.Device.Middle.Types as Device
+import qualified Gpu.Vulkan.Memory.Middle.Internal as Memory
+import qualified Gpu.Vulkan.Image.Core as C
+import qualified Gpu.Vulkan.Sample.Enum as Sample
+import qualified Gpu.Vulkan.QueueFamily.EnumManual as QueueFamily
+
+data SubresourceRange = SubresourceRange {
+	subresourceRangeAspectMask :: AspectFlags,
+	subresourceRangeBaseMipLevel :: Word32,
+	subresourceRangeLevelCount :: Word32,
+	subresourceRangeBaseArrayLayer :: Word32,
+	subresourceRangeLayerCount :: Word32 }
+	deriving Show
+
+subresourceRangeToCore :: SubresourceRange -> C.SubresourceRange
+subresourceRangeToCore SubresourceRange {
+	subresourceRangeAspectMask = AspectFlagBits am,
+	subresourceRangeBaseMipLevel = bmlv,
+	subresourceRangeLevelCount = lvc,
+	subresourceRangeBaseArrayLayer = baly,
+	subresourceRangeLayerCount = lyc } = C.SubresourceRange {
+		C.subresourceRangeAspectMask = am,
+		C.subresourceRangeBaseMipLevel = bmlv,
+		C.subresourceRangeLevelCount = lvc,
+		C.subresourceRangeBaseArrayLayer = baly,
+		C.subresourceRangeLayerCount = lyc }
+
+newtype I = I (IORef (Extent3d, C.I))
+
+data CreateInfo mn = CreateInfo {
+	createInfoNext :: TMaybe.M mn,
+	createInfoFlags :: CreateFlags,
+	createInfoImageType :: Type,
+	createInfoFormat :: Format,
+	createInfoExtent :: Extent3d,
+	createInfoMipLevels :: Word32,
+	createInfoArrayLayers :: Word32,
+	createInfoSamples :: Sample.CountFlagBits,
+	createInfoTiling :: Tiling,
+	createInfoUsage :: UsageFlags,
+	createInfoSharingMode :: SharingMode,
+	createInfoQueueFamilyIndices :: [Word32],
+	createInfoInitialLayout :: Layout }
+
+deriving instance Show (TMaybe.M mn) => Show (CreateInfo mn)
+
+createInfoToCore :: WithPoked (TMaybe.M mn) =>
+	CreateInfo mn -> (Ptr C.CreateInfo -> IO a) -> IO ()
+createInfoToCore CreateInfo {
+	createInfoNext = mnxt,
+	createInfoFlags = CreateFlagBits flgs,
+	createInfoImageType = Type tp,
+	createInfoFormat = Format fmt,
+	createInfoExtent = ext,
+	createInfoMipLevels = mls,
+	createInfoArrayLayers = als,
+	createInfoSamples = Sample.CountFlagBits smpls,
+	createInfoTiling = Tiling tlng,
+	createInfoUsage = UsageFlagBits usg,
+	createInfoSharingMode = SharingMode sm,
+	createInfoQueueFamilyIndices = length &&& id -> (qfic, qfis),
+	createInfoInitialLayout = Layout lyt } f =
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+	allocaArray qfic \pqfis -> do
+		pokeArray pqfis qfis
+		let	ci = C.CreateInfo {
+				C.createInfoSType = (),
+				C.createInfoPNext = pnxt',
+				C.createInfoFlags = flgs,
+				C.createInfoImageType = tp,
+				C.createInfoFormat = fmt,
+				C.createInfoExtent = ext,
+				C.createInfoMipLevels = mls,
+				C.createInfoArrayLayers = als,
+				C.createInfoSamples = smpls,
+				C.createInfoTiling = tlng,
+				C.createInfoUsage = usg,
+				C.createInfoSharingMode = sm,
+				C.createInfoQueueFamilyIndexCount = fromIntegral qfic,
+				C.createInfoPQueueFamilyIndices = pqfis,
+				C.createInfoInitialLayout = lyt }
+		withPoked ci f
+
+create :: WithPoked (TMaybe.M mn) =>
+	Device.D -> CreateInfo mn -> TPMaybe.M AllocationCallbacks.A mc -> IO I
+create (Device.D dvc) ci mac = I <$> alloca \pimg -> do
+	createInfoToCore ci \pci ->
+		AllocationCallbacks.mToCore mac \pac ->
+			throwUnlessSuccess . Result
+				=<< C.create dvc pci pac pimg
+	newIORef . (ex ,) =<< peek pimg
+	where ex = createInfoExtent ci
+
+group :: Device.D -> TPMaybe.M AllocationCallbacks.A md ->
+	(forall s . Group s k -> IO a) -> IO a
+group dvc mac f = do
+	(sem, m) <- atomically $ (,) <$> newTSem 1 <*> newTVar M.empty
+	rtn <- f $ Group sem m
+	((\i -> destroy dvc i mac) `mapM_`) =<< atomically (readTVar m)
+	pure rtn
+
+create' :: (Ord k, WithPoked (TMaybe.M mn)) => Device.D ->
+	Group sm k -> k -> CreateInfo mn ->
+	TPMaybe.M AllocationCallbacks.A mc -> IO (Either String I)
+create' (Device.D dvc) (Group sem is) k ci mac = do
+	ok <- atomically do
+		mx <- (M.lookup k) <$> readTVar is
+		case mx of
+			Nothing -> waitTSem sem >> pure True
+			Just _ -> pure False
+	if ok
+	then do	i <- I <$> alloca \pimg -> do
+			createInfoToCore ci \pci ->
+				AllocationCallbacks.mToCore mac \pac ->
+					throwUnlessSuccess . Result
+						=<< C.create dvc pci pac pimg
+			newIORef . (ex ,) =<< peek pimg
+		atomically $ modifyTVar is (M.insert k i) >> signalTSem sem
+		pure $ Right i
+	else pure . Left $ "Gpu.Vulkan.Image.create': The key already exist"
+	where ex = createInfoExtent ci
+
+data Group s k = Group TSem (TVar (M.Map k I))
+
+destroy' :: Ord k => Device.D ->
+	Group sm k -> k -> TPMaybe.M AllocationCallbacks.A mc ->
+	IO (Either String ())
+destroy' dvc (Group sem is) k mac = do
+	mi <- atomically do
+		mx <- (M.lookup k) <$> readTVar is
+		case mx of
+			Nothing -> pure Nothing
+			Just _ -> waitTSem sem >> pure mx
+	case mi of
+		Nothing -> pure $ Left "Gpu.Vulkan.Image.destroy: No such key"
+		Just i -> do
+			destroy dvc i mac
+			atomically do
+				modifyTVar is (M.delete k)
+				signalTSem sem
+				pure $ Right ()
+
+lookup :: Ord k => Group sm k -> k -> IO (Maybe I)
+lookup (Group _sem is) k = atomically $ M.lookup k <$> readTVar is
+
+recreate :: WithPoked (TMaybe.M mn) =>
+	Device.D -> CreateInfo mn ->
+	TPMaybe.M AllocationCallbacks.A mc ->
+	TPMaybe.M AllocationCallbacks.A md ->
+	I -> IO ()
+recreate d@(Device.D dvc) ci macc macd i@(I ri) = alloca \pimg ->
+	createInfoToCore ci \pci ->
+	AllocationCallbacks.mToCore macc \pacc -> do
+		r <- C.create dvc pci pacc pimg
+		throwUnlessSuccess $ Result r
+		destroy d i macd
+		writeIORef ri . (ex ,) =<< peek pimg
+	where ex = createInfoExtent ci
+
+recreate' :: WithPoked (TMaybe.M mn) =>
+	Device.D -> CreateInfo mn ->
+	TPMaybe.M AllocationCallbacks.A mc ->
+	TPMaybe.M AllocationCallbacks.A md ->
+	I -> IO a -> IO ()
+recreate' (Device.D dvc) ci macc macd (I ri) act = alloca \pimg ->
+	createInfoToCore ci \pci ->
+	AllocationCallbacks.mToCore macc \pacc -> do
+		r <- C.create dvc pci pacc pimg
+		throwUnlessSuccess $ Result r
+		(_, img) <- readIORef ri
+		writeIORef ri . (ex ,) =<< peek pimg
+		_ <- act
+		AllocationCallbacks.mToCore macd $ C.destroy dvc img
+	where ex = createInfoExtent ci
+
+getMemoryRequirements :: Device.D -> I -> IO Memory.Requirements
+getMemoryRequirements (Device.D dvc) (I ri) =
+	(Memory.requirementsFromCore <$>) . ($ pure) $ runContT do
+		pr <- ContT alloca
+		lift do	(_, i) <- readIORef ri
+			C.getMemoryRequirements dvc i pr
+			peek pr
+
+bindMemory :: Device.D -> I -> Memory.M -> Device.Size -> IO ()
+bindMemory (Device.D dvc) (I rimg) mem (Device.Size ost) = do
+	(_, img) <- readIORef rimg
+	cmem <- Memory.mToCore mem
+	r <- C.bindMemory dvc img cmem ost
+	throwUnlessSuccess $ Result r
+
+data MemoryBarrier mn = MemoryBarrier {
+	memoryBarrierNext :: TMaybe.M mn,
+	memoryBarrierSrcAccessMask :: AccessFlags,
+	memoryBarrierDstAccessMask :: AccessFlags,
+	memoryBarrierOldLayout :: Layout,
+	memoryBarrierNewLayout :: Layout,
+	memoryBarrierSrcQueueFamilyIndex :: QueueFamily.Index,
+	memoryBarrierDstQueueFamilyIndex :: QueueFamily.Index,
+	memoryBarrierImage :: I,
+	memoryBarrierSubresourceRange :: SubresourceRange }
+
+memoryBarrierToCore :: WithPoked (TMaybe.M mn) =>
+	MemoryBarrier mn -> (C.MemoryBarrier -> IO a) -> IO ()
+memoryBarrierToCore MemoryBarrier {
+	memoryBarrierNext = mnxt,
+	memoryBarrierSrcAccessMask = AccessFlagBits sam,
+	memoryBarrierDstAccessMask = AccessFlagBits dam,
+	memoryBarrierOldLayout = Layout ol,
+	memoryBarrierNewLayout = Layout nl,
+	memoryBarrierSrcQueueFamilyIndex = QueueFamily.Index sqfi,
+	memoryBarrierDstQueueFamilyIndex = QueueFamily.Index dqfi,
+	memoryBarrierImage = I rimg,
+	memoryBarrierSubresourceRange = srr } f =
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+	readIORef rimg >>= \(_, img) ->
+	f C.MemoryBarrier {
+		C.memoryBarrierSType = (),
+		C.memoryBarrierPNext = pnxt',
+		C.memoryBarrierSrcAccessMask = sam,
+		C.memoryBarrierDstAccessMask = dam,
+		C.memoryBarrierOldLayout = ol,
+		C.memoryBarrierNewLayout = nl,
+		C.memoryBarrierSrcQueueFamilyIndex = sqfi,
+		C.memoryBarrierDstQueueFamilyIndex = dqfi,
+		C.memoryBarrierImage = img,
+		C.memoryBarrierSubresourceRange = subresourceRangeToCore srr }
+
+data SubresourceLayers = SubresourceLayers {
+	subresourceLayersAspectMask :: AspectFlags,
+	subresourceLayersMipLevel :: Word32,
+	subresourceLayersBaseArrayLayer :: Word32,
+	subresourceLayersLayerCount :: Word32 }
+	deriving Show
+
+subresourceLayersToCore :: SubresourceLayers -> C.SubresourceLayers
+subresourceLayersToCore SubresourceLayers {
+	subresourceLayersAspectMask = AspectFlagBits am,
+	subresourceLayersMipLevel = ml,
+	subresourceLayersBaseArrayLayer = bal,
+	subresourceLayersLayerCount = lc } = C.SubresourceLayers {
+		C.subresourceLayersAspectMask = am,
+		C.subresourceLayersMipLevel = ml,
+		C.subresourceLayersBaseArrayLayer = bal,
+		C.subresourceLayersLayerCount = lc }
+
+destroy :: Device.D -> I -> TPMaybe.M AllocationCallbacks.A md -> IO ()
+destroy (Device.D dvc) (I rimg) mac =
+	AllocationCallbacks.mToCore mac \pac -> do
+		(_, img) <- readIORef rimg
+		C.destroy dvc img pac
+
+data Blit = Blit {
+	blitSrcSubresource :: SubresourceLayers,
+	blitSrcOffsetFrom :: Offset3d,
+	blitSrcOffsetTo :: Offset3d,
+	blitDstSubresource :: SubresourceLayers,
+	blitDstOffsetFrom :: Offset3d,
+	blitDstOffsetTo :: Offset3d }
+	deriving Show
+
+blitToCore :: Blit -> C.Blit
+blitToCore Blit {
+	blitSrcSubresource = ssr,
+	blitSrcOffsetFrom = sof,
+	blitSrcOffsetTo = sot,
+	blitDstSubresource = dsr,
+	blitDstOffsetFrom = dof,
+	blitDstOffsetTo = dot } = C.Blit {
+	C.blitSrcSubresource = subresourceLayersToCore ssr,
+	C.blitSrcOffsets = [sof, sot],
+	C.blitDstSubresource = subresourceLayersToCore dsr,
+	C.blitDstOffsets = [dof, dot] }
diff --git a/src/Gpu/Vulkan/ImageView/Enum.hsc b/src/Gpu/Vulkan/ImageView/Enum.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/ImageView/Enum.hsc
@@ -0,0 +1,42 @@
+-- This file is automatically generated by the tools/makeEnum.hs
+--	% stack runghc --cwd tools/ makeEnum
+
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-missing-export-lists -fno-warn-tabs #-}
+
+module Gpu.Vulkan.ImageView.Enum where
+
+import Foreign.Storable
+import Foreign.C.Enum
+import Data.Bits
+import Data.Word
+
+#include <vulkan/vulkan.h>
+
+enum "CreateFlagBits" ''#{type VkImageViewCreateFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("CreateFlagsZero", 0),
+	("CreateFragmentDensityMapDynamicBitExt",
+		#{const VK_IMAGE_VIEW_CREATE_FRAGMENT_DENSITY_MAP_DYNAMIC_BIT_EXT}),
+	("CreateDescriptorBufferCaptureReplayBitExt",
+		#{const VK_IMAGE_VIEW_CREATE_DESCRIPTOR_BUFFER_CAPTURE_REPLAY_BIT_EXT}),
+	("CreateFragmentDensityMapDeferredBitExt",
+		#{const VK_IMAGE_VIEW_CREATE_FRAGMENT_DENSITY_MAP_DEFERRED_BIT_EXT}),
+	("CreateFlagBitsMaxEnum",
+		#{const VK_IMAGE_VIEW_CREATE_FLAG_BITS_MAX_ENUM}) ]
+
+enum "Type" ''#{type VkImageViewType}
+		[''Show, ''Eq, ''Storable] [
+	("Type1d", #{const VK_IMAGE_VIEW_TYPE_1D}),
+	("Type2d", #{const VK_IMAGE_VIEW_TYPE_2D}),
+	("Type3d", #{const VK_IMAGE_VIEW_TYPE_3D}),
+	("TypeCube", #{const VK_IMAGE_VIEW_TYPE_CUBE}),
+	("Type1dArray", #{const VK_IMAGE_VIEW_TYPE_1D_ARRAY}),
+	("Type2dArray", #{const VK_IMAGE_VIEW_TYPE_2D_ARRAY}),
+	("TypeCubeArray", #{const VK_IMAGE_VIEW_TYPE_CUBE_ARRAY}),
+	("TypeMaxEnum", #{const VK_IMAGE_VIEW_TYPE_MAX_ENUM}) ]
+
+type CreateFlags = CreateFlagBits
diff --git a/src/Gpu/Vulkan/ImageView/Middle.hs b/src/Gpu/Vulkan/ImageView/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/ImageView/Middle.hs
@@ -0,0 +1,16 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.ImageView.Middle (
+
+	-- * CREATE AND DESTROY
+
+	create, recreate, recreate', destroy, I, CreateInfo(..),
+
+	-- ** Image Views Group
+
+	Group, group, create', destroy', lookup
+
+	) where
+
+import Prelude hiding (lookup)
+import Gpu.Vulkan.ImageView.Middle.Internal
diff --git a/src/Gpu/Vulkan/ImageView/Middle/Internal.hs b/src/Gpu/Vulkan/ImageView/Middle/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/ImageView/Middle/Internal.hs
@@ -0,0 +1,174 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE MonoLocalBinds #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE ViewPatterns #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.ImageView.Middle.Internal (
+	I, CreateInfo(..), create, recreate, recreate', destroy,
+
+	group, create', destroy', lookup, Group,
+
+	iToCore
+	) where
+
+import Prelude hiding (lookup)
+
+import Foreign.Ptr
+import Foreign.Marshal
+import Foreign.Storable
+import Foreign.Storable.PeekPoke
+import Control.Concurrent.STM
+import Control.Concurrent.STM.TSem
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Data.TypeLevel.ParMaybe qualified as TPMaybe
+import Data.Map qualified as M
+import Data.IORef
+
+import Gpu.Vulkan.Enum
+import Gpu.Vulkan.Exception.Middle.Internal
+import Gpu.Vulkan.Exception.Enum
+import Gpu.Vulkan.Component.Middle.Internal
+import Gpu.Vulkan.ImageView.Enum
+
+import Gpu.Vulkan.AllocationCallbacks.Middle.Internal
+	qualified as AllocationCallbacks
+import qualified Gpu.Vulkan.Device.Middle.Types as Device
+import qualified Gpu.Vulkan.Image.Middle.Internal as Image
+import qualified Gpu.Vulkan.ImageView.Core as C
+
+data CreateInfo mn = CreateInfo {
+	createInfoNext :: TMaybe.M mn,
+	createInfoFlags :: CreateFlags,
+	createInfoImage :: Image.I,
+	createInfoViewType :: Type,
+	createInfoFormat :: Format,
+	createInfoComponents :: Mapping,
+	createInfoSubresourceRange :: Image.SubresourceRange }
+
+createInfoToCore :: WithPoked (TMaybe.M mn) =>
+	CreateInfo mn -> (Ptr C.CreateInfo -> IO a) -> IO ()
+createInfoToCore CreateInfo {
+	createInfoNext = mnxt,
+	createInfoFlags = CreateFlagBits flgs,
+	createInfoImage = Image.I rimg,
+	createInfoViewType = Type tp,
+	createInfoFormat = Format fmt,
+	createInfoComponents = cpns,
+	createInfoSubresourceRange = srr
+	} f = withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+	readIORef rimg >>= \(_, img) -> let ci = C.CreateInfo {
+		C.createInfoSType = (),
+		C.createInfoPNext = pnxt',
+		C.createInfoFlags = flgs,
+		C.createInfoImage = img,
+		C.createInfoViewType = tp,
+		C.createInfoFormat = fmt,
+		C.createInfoComponents = mappingToCore cpns,
+		C.createInfoSubresourceRange =
+			Image.subresourceRangeToCore srr } in
+	withPoked ci f
+
+newtype I = I (IORef C.I)
+
+instance Show I where show _ = "Vk.ImageView.I"
+
+iToCore :: I -> IO C.I
+iToCore (I i) = readIORef i
+
+iFromCore :: C.I -> IO I
+iFromCore i = I <$> newIORef i
+
+create :: WithPoked (TMaybe.M mn) =>
+	Device.D -> CreateInfo mn -> TPMaybe.M AllocationCallbacks.A mc -> IO I
+create (Device.D dvc) ci mac = iFromCore =<< alloca \pView -> do
+	createInfoToCore ci \pci ->
+		AllocationCallbacks.mToCore mac \pac -> do
+			r <- C.create dvc pci pac pView
+			throwUnlessSuccess $ Result r
+	peek pView
+
+group :: Device.D -> TPMaybe.M AllocationCallbacks.A mc ->
+	(forall s . Group s k -> IO a) -> IO a
+group dvc mac f = do
+	(sem, mng) <- atomically $ (,) <$> newTSem 1 <*> newTVar M.empty
+	rtn <- f $ Group sem mng
+	((\iv -> destroy dvc iv mac) `mapM_`) =<< atomically (readTVar mng)
+	pure rtn
+
+data Group s k = Group TSem (TVar (M.Map k I))
+
+create' :: (Ord k, WithPoked (TMaybe.M mn)) =>
+	Device.D -> Group sm k -> k ->
+	CreateInfo mn -> TPMaybe.M AllocationCallbacks.A mc -> IO (Either String I)
+create' (Device.D dvc) (Group sem is) k ci mac = do
+	ok <- atomically do
+		mx <- (M.lookup k) <$> readTVar is
+		case mx of
+			Nothing -> waitTSem sem >> pure True
+			Just _ -> pure False
+	if ok
+	then do	i <- iFromCore =<< alloca \pView -> do
+			createInfoToCore ci \pci ->
+				AllocationCallbacks.mToCore mac \pac -> do
+					r <- C.create dvc pci pac pView
+					throwUnlessSuccess $ Result r
+			peek pView
+		atomically $ modifyTVar is (M.insert k i) >> signalTSem sem
+		pure $ Right i
+	else pure . Left $ "Gpu.Vulkan.ImageView.create': The key already exist"
+
+destroy' :: Ord k => Device.D ->
+	Group sm k -> k -> TPMaybe.M AllocationCallbacks.A mc -> IO (Either String ())
+destroy' dvc (Group sem is) k mac = do
+	mi <- atomically do
+		mx <- (M.lookup k) <$> readTVar is
+		case mx of
+			Nothing -> pure Nothing
+			Just _ -> waitTSem sem >> pure mx
+	case mi of
+		Nothing -> pure $ Left "Gpu.Vulkan.ImageView.destroy: No such key"
+		Just i -> do
+			destroy dvc i mac
+			atomically do
+				modifyTVar is (M.delete k)
+				signalTSem sem
+				pure $ Right ()
+
+lookup :: Ord k => Group sm k -> k -> IO (Maybe I)
+lookup (Group _sem is) k = atomically $ M.lookup k <$> readTVar is
+
+recreate :: WithPoked (TMaybe.M mn) =>
+	Device.D -> CreateInfo mn ->
+	TPMaybe.M AllocationCallbacks.A mc -> TPMaybe.M AllocationCallbacks.A md ->
+	I -> IO ()
+recreate (Device.D dvc) ci macc macd (I ri) = alloca \pView ->
+	createInfoToCore ci \pci ->
+	AllocationCallbacks.mToCore macc \pac -> do
+		r <- C.create dvc pci pac pView
+		throwUnlessSuccess $ Result r
+		io <- readIORef ri
+		AllocationCallbacks.mToCore macd $ C.destroy dvc io
+		writeIORef ri =<< peek pView
+
+recreate' :: WithPoked (TMaybe.M mn) =>
+	Device.D -> CreateInfo mn ->
+	TPMaybe.M AllocationCallbacks.A mc -> TPMaybe.M AllocationCallbacks.A md ->
+	I -> IO a -> IO ()
+recreate' (Device.D dvc) ci macc macd (I ri) act = alloca \pView ->
+	createInfoToCore ci \pci ->
+	AllocationCallbacks.mToCore macc \pac -> do
+		r <- C.create dvc pci pac pView
+		throwUnlessSuccess $ Result r
+		io <- readIORef ri
+		writeIORef ri =<< peek pView
+		rtn <- act
+		AllocationCallbacks.mToCore macd $ C.destroy dvc io
+		pure rtn
+
+destroy :: Device.D -> I -> TPMaybe.M AllocationCallbacks.A md -> IO ()
+destroy (Device.D dvc) iv mac = do
+	iv' <- iToCore iv
+	AllocationCallbacks.mToCore mac $ C.destroy dvc iv'
diff --git a/src/Gpu/Vulkan/Instance/Enum.hsc b/src/Gpu/Vulkan/Instance/Enum.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Instance/Enum.hsc
@@ -0,0 +1,19 @@
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Instance.Enum where
+
+import Foreign.Storable
+import Foreign.C.Enum
+import Data.Default
+import Data.Bits
+import Data.Word
+
+#include <vulkan/vulkan.h>
+
+enum "CreateFlags" ''#{type VkInstanceCreateFlags}
+	[''Show, ''Eq, ''Storable, ''Bits] [("CreateFlagsZero", 0)]
+
+instance Default CreateFlags where def = CreateFlagsZero
diff --git a/src/Gpu/Vulkan/Instance/Middle.hs b/src/Gpu/Vulkan/Instance/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Instance/Middle.hs
@@ -0,0 +1,15 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Instance.Middle (
+
+	-- * CREATE AND DESTROY
+
+	create, destroy, I, CreateInfo(..),
+
+	-- * ENUMERATE
+
+	enumerateLayerProperties, enumerateExtensionProperties
+
+	) where
+
+import Gpu.Vulkan.Instance.Middle.Internal
diff --git a/src/Gpu/Vulkan/Instance/Middle/Internal.hs b/src/Gpu/Vulkan/Instance/Middle/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Instance/Middle/Internal.hs
@@ -0,0 +1,125 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE MonoLocalBinds #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE FlexibleContexts, FlexibleInstances, UndecidableInstances #-}
+{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Instance.Middle.Internal (
+
+	-- * CREATE AND DESTROY
+
+	create, destroy, I(..), CreateInfo(..),
+
+	-- * ENUMERATE
+
+	enumerateLayerProperties, enumerateExtensionProperties
+
+	) where
+
+import Foreign.Ptr
+import Foreign.Marshal
+import Foreign.Storable
+import Foreign.Storable.PeekPoke (
+	WithPoked, withPoked, withPoked', withPtrS, pattern NullPtr )
+import Control.Arrow
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Data.TypeLevel.ParMaybe qualified as TPMaybe
+import Data.Default
+
+import Data.Text qualified as T
+import Data.Text.Foreign.MiscYj
+
+import Gpu.Vulkan.Middle.Internal
+import Gpu.Vulkan.Exception.Middle.Internal
+import Gpu.Vulkan.Exception.Enum
+import Gpu.Vulkan.Instance.Enum
+
+import qualified Gpu.Vulkan.Instance.Core as C
+import Gpu.Vulkan.AllocationCallbacks.Middle.Internal
+	qualified as AllocationCallbacks
+
+data CreateInfo mn a = CreateInfo {
+	createInfoNext :: TMaybe.M mn,
+	createInfoFlags :: CreateFlags,
+	createInfoApplicationInfo :: Maybe (ApplicationInfo a),
+	createInfoEnabledLayerNames :: [T.Text],
+	createInfoEnabledExtensionNames :: [T.Text] }
+
+deriving instance (Show (TMaybe.M mn), Show (TMaybe.M a)) => Show (CreateInfo mn a)
+
+instance Default (CreateInfo 'Nothing a) where
+	def = CreateInfo {
+		createInfoNext = TMaybe.N,
+		createInfoFlags = CreateFlagsZero,
+		createInfoApplicationInfo = Nothing,
+		createInfoEnabledLayerNames = [],
+		createInfoEnabledExtensionNames = [] }
+
+createInfoToCore :: (WithPoked (TMaybe.M mn), WithPoked (TMaybe.M n')) =>
+	CreateInfo mn n' -> (Ptr C.CreateInfo -> IO a) -> IO ()
+createInfoToCore CreateInfo {
+	createInfoNext = mnxt,
+	createInfoFlags = (\(CreateFlags f) -> f) -> flgs,
+	createInfoApplicationInfo = mai,
+	createInfoEnabledLayerNames =
+		(fromIntegral . length &&& id) -> (elnc, elns),
+	createInfoEnabledExtensionNames =
+		(fromIntegral . length &&& id) -> (eenc, eens) } f =
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+	textListToCStringArray elns \pelna ->
+	textListToCStringArray eens \peena ->
+	let	ci pai = C.CreateInfo {
+			C.createInfoSType = (),
+			C.createInfoPNext = pnxt',
+			C.createInfoFlags = flgs,
+			C.createInfoPApplicationInfo = pai,
+			C.createInfoEnabledLayerCount = elnc,
+			C.createInfoPpEnabledLayerNames = pelna,
+			C.createInfoEnabledExtensionCount = eenc,
+			C.createInfoPpEnabledExtensionNames = peena } in
+	case mai of
+		Nothing -> () <$ withPoked (ci NullPtr) f
+		Just ai -> applicationInfoToCore ai \pai ->
+			withPoked (ci pai) f
+
+newtype I = I C.I deriving Show
+
+create :: (WithPoked (TMaybe.M mn), WithPoked (TMaybe.M a)) =>
+	CreateInfo mn a -> TPMaybe.M AllocationCallbacks.A mc -> IO I
+create ci mac = I <$> alloca \pist -> do
+	createInfoToCore ci \pcci ->
+		AllocationCallbacks.mToCore mac \pac -> do
+			r <- C.create pcci pac pist
+			throwUnlessSuccess $ Result r
+	peek pist
+
+destroy :: I -> TPMaybe.M AllocationCallbacks.A md -> IO ()
+destroy (I cist) mac = AllocationCallbacks.mToCore mac $ C.destroy cist
+
+enumerateLayerProperties :: IO [LayerProperties]
+enumerateLayerProperties =
+	map layerPropertiesFromCore <$> alloca \pLayerCount ->
+	C.enumerateLayerProperties pLayerCount NullPtr >>= \r ->
+	throwUnlessSuccess (Result r) >>
+	peek pLayerCount >>= \(fromIntegral -> layerCount) ->
+	allocaArray layerCount \pLayerProps ->
+	C.enumerateLayerProperties pLayerCount pLayerProps >>= \r' ->
+	throwUnlessSuccess (Result r') >>
+	peekArray layerCount pLayerProps
+
+enumerateExtensionProperties :: Maybe T.Text -> IO [ExtensionProperties]
+enumerateExtensionProperties mln =
+	map extensionPropertiesFromCore <$> case mln of
+		Nothing -> go NullPtr
+		Just ln -> textToCString ln go
+	where go cln = alloca \pExtCount ->
+		C.enumerateExtensionProperties cln pExtCount NullPtr >>= \r ->
+		throwUnlessSuccess (Result r) >>
+		peek pExtCount >>= \(fromIntegral -> extCount) ->
+		allocaArray extCount \pExts ->
+		C.enumerateExtensionProperties cln pExtCount pExts >>= \r' ->
+		throwUnlessSuccess (Result r') >>
+		peekArray extCount pExts
diff --git a/src/Gpu/Vulkan/Memory/Enum.hsc b/src/Gpu/Vulkan/Memory/Enum.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Memory/Enum.hsc
@@ -0,0 +1,55 @@
+-- This file is automatically generated by the tools/makeEnum.hs
+--	% stack runghc --cwd tools/ makeEnum
+
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-missing-export-lists -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Memory.Enum where
+
+import Foreign.Storable
+import Foreign.C.Enum
+import Data.Bits
+import Data.Word
+
+#include <vulkan/vulkan.h>
+
+enum "PropertyFlagBits" ''#{type VkMemoryPropertyFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("PropertyFlagsZero", 0),
+	("PropertyDeviceLocalBit",
+		#{const VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT}),
+	("PropertyHostVisibleBit",
+		#{const VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT}),
+	("PropertyHostCoherentBit",
+		#{const VK_MEMORY_PROPERTY_HOST_COHERENT_BIT}),
+	("PropertyHostCachedBit",
+		#{const VK_MEMORY_PROPERTY_HOST_CACHED_BIT}),
+	("PropertyLazilyAllocatedBit",
+		#{const VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT}),
+	("PropertyProtectedBit",
+		#{const VK_MEMORY_PROPERTY_PROTECTED_BIT}),
+	("PropertyDeviceCoherentBitAmd",
+		#{const VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD}),
+	("PropertyDeviceUncachedBitAmd",
+		#{const VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD}),
+	("PropertyRdmaCapableBitNv",
+		#{const VK_MEMORY_PROPERTY_RDMA_CAPABLE_BIT_NV}),
+	("PropertyFlagBitsMaxEnum",
+		#{const VK_MEMORY_PROPERTY_FLAG_BITS_MAX_ENUM}) ]
+
+enum "HeapFlagBits" ''#{type VkMemoryHeapFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("HeapFlagsZero", 0),
+	("HeapDeviceLocalBit", #{const VK_MEMORY_HEAP_DEVICE_LOCAL_BIT}),
+	("HeapMultiInstanceBit",
+		#{const VK_MEMORY_HEAP_MULTI_INSTANCE_BIT}),
+	("HeapMultiInstanceBitKhr",
+		#{const VK_MEMORY_HEAP_MULTI_INSTANCE_BIT_KHR}),
+	("HeapFlagBitsMaxEnum",
+		#{const VK_MEMORY_HEAP_FLAG_BITS_MAX_ENUM}) ]
+
+type PropertyFlags = PropertyFlagBits
+type HeapFlags = HeapFlagBits
diff --git a/src/Gpu/Vulkan/Memory/Middle.hs b/src/Gpu/Vulkan/Memory/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Memory/Middle.hs
@@ -0,0 +1,26 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Memory.Middle (
+
+	-- * ALLOCATE AND FREE
+
+	allocate, reallocate, reallocate', free, M, AllocateInfo(..),
+
+	-- ** Destruction Group
+
+	Group, group, allocate', free', lookup,
+
+	-- * MAP AND UNMNAP
+
+	map, unmap, MapFlags(..),
+
+	-- * REQUIREMENTS AND BARRIER
+
+	Requirements(..), Barrier(..),
+
+	-- * MEMORY TYPE
+
+	MType(..), TypeBits, TypeIndex, elemTypeIndex ) where
+
+import Prelude hiding (map, lookup)
+import Gpu.Vulkan.Memory.Middle.Internal
diff --git a/src/Gpu/Vulkan/Memory/Middle/Internal.hsc b/src/Gpu/Vulkan/Memory/Middle/Internal.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Memory/Middle/Internal.hsc
@@ -0,0 +1,257 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE MonoLocalBinds #-}
+{-# LANGUAGE FlexibleContexts, UndecidableInstances #-}
+{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
+{-# LANGUAGE StandaloneDeriving, GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Memory.Middle.Internal (
+	M(..), mToCore, AllocateInfo(..), allocate, reallocate, reallocate', free,
+
+	group, allocate', free', lookup, Group,
+
+	MapFlags(..), map, unmap,
+
+	Requirements(..), requirementsFromCore,
+	Barrier(..), barrierToCore,
+
+	Heap, heapFromCore,
+
+	MType(..), mTypeFromCore,
+	TypeBits, TypeIndex, elemTypeIndex, typeBitsToTypeIndices
+	) where
+
+import Prelude hiding (map, lookup)
+
+import Foreign.Ptr
+import Foreign.Marshal.Alloc hiding (free)
+import Foreign.Storable
+import Foreign.Storable.PeekPoke
+import Foreign.C.Enum
+import Control.Concurrent.STM
+import Control.Concurrent.STM.TSem
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Data.TypeLevel.ParMaybe qualified as TPMaybe
+import Data.Default
+import Data.Bits
+import Data.Map qualified as M
+import Data.IORef
+import Data.Word
+
+import Gpu.Vulkan.Enum
+import Gpu.Vulkan.Exception.Middle.Internal
+import Gpu.Vulkan.Exception.Enum
+import Gpu.Vulkan.Memory.Enum
+
+import qualified Gpu.Vulkan.Device.Middle.Types as Device
+
+import qualified Gpu.Vulkan.AllocationCallbacks.Middle.Internal as AllocationCallbacks
+import qualified Gpu.Vulkan.Memory.Core as C
+
+#include <vulkan/vulkan.h>
+
+newtype M = M (IORef C.M)
+
+mToCore :: M -> IO C.M
+mToCore (M r) = readIORef r
+
+newtype TypeBits = TypeBits #{type uint32_t} deriving (Show, Eq, Bits, FiniteBits)
+
+newtype TypeIndex = TypeIndex Word32
+	deriving (Show, Eq, Ord, Enum, Num, Real, Integral)
+
+typeBitsToTypeIndices :: TypeBits -> [TypeIndex]
+typeBitsToTypeIndices bs = (fst <$>)
+	. filter snd . zip [0 ..] $ testBit bs <$> [0 .. finiteBitSize bs - 1]
+
+elemTypeIndex :: TypeIndex -> TypeBits -> Bool
+elemTypeIndex ti tbs = testBit tbs $ fromIntegral ti
+
+data Requirements = Requirements {
+	requirementsSize :: Device.Size,
+	requirementsAlignment :: Device.Size,
+	requirementsMemoryTypeBits :: TypeBits }
+	deriving Show
+
+requirementsFromCore :: C.Requirements -> Requirements
+requirementsFromCore C.Requirements {
+	C.requirementsSize = sz,
+	C.requirementsAlignment = al,
+	C.requirementsMemoryTypeBits = mtbs } = Requirements {
+	requirementsSize = Device.Size sz,
+	requirementsAlignment = Device.Size al,
+	requirementsMemoryTypeBits = TypeBits mtbs }
+
+data MType = MType {
+	mTypePropertyFlags :: PropertyFlags,
+	mTypeHeapIndex :: #{type uint32_t} }
+	deriving Show
+
+mTypeFromCore :: C.MType -> MType
+mTypeFromCore C.MType {
+	C.mTypePropertyFlags = pfs,
+	C.mTypeHeapIndex = hi } = MType {
+	mTypePropertyFlags = PropertyFlagBits pfs,
+	mTypeHeapIndex = hi }
+
+data Heap = Heap { heapSize :: Device.Size, heapFlags :: HeapFlags }
+	deriving Show
+
+heapFromCore :: C.Heap -> Heap
+heapFromCore C.Heap { C.heapSize = sz, C.heapFlags = flgs } =
+	Heap { heapSize = Device.Size sz, heapFlags = HeapFlagBits flgs }
+
+data AllocateInfo mn = AllocateInfo {
+	allocateInfoNext :: TMaybe.M mn,
+	allocateInfoAllocationSize :: Device.Size,
+	allocateInfoMemoryTypeIndex :: TypeIndex }
+
+deriving instance Show (TMaybe.M mn) => Show (AllocateInfo mn)
+
+allocateInfoToCore :: WithPoked (TMaybe.M mn) =>
+	AllocateInfo mn -> (Ptr C.AllocateInfo -> IO a) -> IO ()
+allocateInfoToCore AllocateInfo {
+	allocateInfoNext = mnxt,
+	allocateInfoAllocationSize = Device.Size sz,
+	allocateInfoMemoryTypeIndex = TypeIndex mti } f =
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+	let	ci = C.AllocateInfo {
+			C.allocateInfoSType = (),
+			C.allocateInfoPNext = pnxt',
+			C.allocateInfoAllocationSize = sz,
+			C.allocateInfoMemoryTypeIndex = mti } in
+	withPoked ci f
+
+allocate :: WithPoked (TMaybe.M mn) =>
+	Device.D -> AllocateInfo mn -> TPMaybe.M AllocationCallbacks.A ma -> IO M
+allocate (Device.D dvc) ai mac = M <$> alloca \pm -> do
+	allocateInfoToCore ai \pai ->
+		AllocationCallbacks.mToCore mac \pac -> do
+			r <- C.allocate dvc pai pac pm
+			throwUnlessSuccess $ Result r
+	newIORef =<< peek pm
+
+-- free :: Device.D -> M -> TPMaybe.M AllocationCallbacks.A mf -> IO ()
+
+group :: Device.D -> TPMaybe.M AllocationCallbacks.A mf ->
+	(forall s . Group s k -> IO a) -> IO a
+group dvc mac f = do
+	(sem, mng) <-atomically $ (,) <$> newTSem 1 <*> newTVar M.empty
+	rtn <- f $ Group sem mng
+	((\m -> free dvc m mac) `mapM_`) =<< atomically (readTVar mng)
+	pure rtn
+
+allocate' :: (Ord k, WithPoked (TMaybe.M mn)) =>
+	Device.D -> Group sm k -> k -> AllocateInfo mn ->
+	TPMaybe.M AllocationCallbacks.A ma -> IO (Either String M)
+allocate' (Device.D dvc) (Group sem ms) k ai mac = do
+	ok <- atomically do
+		mx <- (M.lookup k) <$> readTVar ms
+		case mx of
+			Nothing -> waitTSem sem >> pure True
+			Just _ -> pure False
+	if ok
+	then do	m <- M <$> alloca \pm -> do
+			allocateInfoToCore ai \pai ->
+				AllocationCallbacks.mToCore mac \pac -> do
+					r <- C.allocate dvc pai pac pm
+					throwUnlessSuccess $ Result r
+			newIORef =<< peek pm
+		atomically do
+			modifyTVar ms (M.insert k m)
+			signalTSem sem
+		pure $ Right m
+	else pure . Left $ "Gpu.Vulkan.Memory.allocate': The key already exist"
+
+data Group s k = Group TSem (TVar (M.Map k M))
+
+free' :: Ord k => Device.D ->
+	Group smng k -> k -> TPMaybe.M AllocationCallbacks.A mc ->
+	IO (Either String ())
+free' dvc (Group sem ms) k mac = do
+	mm <- atomically do
+		mx <- (M.lookup k) <$> readTVar ms
+		case mx of
+			Nothing -> pure Nothing
+			Just _ -> waitTSem sem >> pure mx
+	case mm of
+		Nothing -> pure $ Left "Gpu.Vulkan.Memory.free': No such key"
+		Just m -> do
+			free dvc m mac
+			atomically do
+				modifyTVar ms (M.delete k)
+				signalTSem sem
+				pure $ Right ()
+
+lookup :: Ord k => Group sm k -> k -> IO (Maybe M)
+lookup (Group _sem ms) k = atomically $ M.lookup k <$> readTVar ms
+
+reallocate :: WithPoked (TMaybe.M mn) =>
+	Device.D -> AllocateInfo mn ->
+	TPMaybe.M AllocationCallbacks.A ma ->
+	M -> IO ()
+reallocate d@(Device.D dvc) ai macc m@(M rm) =
+	alloca \pm -> allocateInfoToCore ai \pai ->
+	AllocationCallbacks.mToCore macc \pac -> do
+		r <- C.allocate dvc pai pac pm
+		throwUnlessSuccess $ Result r
+		free d m macc
+		writeIORef rm =<< peek pm
+
+reallocate' :: WithPoked (TMaybe.M mn) =>
+	Device.D -> AllocateInfo mn ->
+	TPMaybe.M AllocationCallbacks.A ma ->
+	M -> IO a -> IO ()
+reallocate' (Device.D dvc) ai macc (M rm) act =
+	alloca \pm -> allocateInfoToCore ai \pai ->
+	AllocationCallbacks.mToCore macc \pac -> do
+		r <- C.allocate dvc pai pac pm
+		throwUnlessSuccess $ Result r
+		mm <- readIORef rm
+		writeIORef rm =<< peek pm
+		_ <- act
+		C.free dvc mm pac
+
+free :: Device.D -> M -> TPMaybe.M AllocationCallbacks.A mf -> IO ()
+free (Device.D dvc) (M mem) mac =
+	AllocationCallbacks.mToCore mac \pac -> do
+		m <- readIORef mem
+		C.free dvc m pac
+
+enum "MapFlags" ''#{type VkMemoryMapFlags}
+	[''Eq, ''Show, ''Storable, ''Bits] [("MapFlagsZero", 0)]
+
+instance Default MapFlags where def = MapFlagsZero
+
+map :: Device.D -> M -> Device.Size -> Device.Size -> MapFlags ->
+	IO (Ptr a)
+map (Device.D dvc) (M mem)
+	(Device.Size ofst) (Device.Size sz) (MapFlags flgs) = alloca \pd ->
+	readIORef mem >>= \m ->
+	C.map dvc m ofst sz flgs pd >>= \r ->
+	throwUnlessSuccess (Result r) >>
+	peek pd
+
+unmap :: Device.D -> M -> IO ()
+unmap (Device.D dvc) (M mem) = C.unmap dvc =<< readIORef mem
+
+data Barrier mn = Barrier {
+	barrierNext :: TMaybe.M mn,
+	barrierSrcAccessMask :: AccessFlags,
+	barrierDstAccessMask :: AccessFlags }
+
+deriving instance Show (TMaybe.M mn) => Show (Barrier mn)
+
+barrierToCore :: WithPoked (TMaybe.M mn) => Barrier mn -> (C.Barrier -> IO a) -> IO ()
+barrierToCore Barrier {
+	barrierNext = mnxt,
+	barrierSrcAccessMask = AccessFlagBits sam,
+	barrierDstAccessMask = AccessFlagBits dam } f =
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') -> f C.Barrier {
+		C.barrierSType = (),
+		C.barrierPNext = pnxt',
+		C.barrierSrcAccessMask = sam,
+		C.barrierDstAccessMask = dam }
diff --git a/src/Gpu/Vulkan/Middle.hs b/src/Gpu/Vulkan/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Middle.hs
@@ -0,0 +1,73 @@
+{-# LANGUAGE PatternSynonyms #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Middle (
+
+	-- * INFO
+
+	-- ** ApplicationInfo
+
+	ApplicationInfo(..),
+	ApiVersion, makeApiVersion, apiVersion_1_0, apiVersion_1_1,
+
+	-- ** SubmitInfo
+
+	SubmitInfo(..), SubmitInfoListToCore(..),
+
+	-- * PROPERTIES
+
+	LayerProperties(..), ExtensionProperties(..), FormatProperties(..),
+
+	-- * PIPELINE VALUES
+
+	-- ** ViewPort
+
+	Viewport, pattern Viewport,
+	viewportX, viewportY, viewportWidth, viewportHeight,
+	viewportMinDepth, viewportMaxDepth,
+
+	-- ** StencilOpState
+
+	StencilOpState(..),
+
+	-- ** ClearValue
+
+	ClearValue(..),
+	ClearValueListToCore, ClearValueToCore,
+
+	-- *** ClearType
+
+	ClearType(..), ClearColorType(..),
+
+	-- *** ClearColorValue
+
+	ClearColorValueToCore,
+
+	-- *** ClearDepthStencilValue
+
+	ClearDepthStencilValue, pattern ClearDepthStencilValue,
+	clearDepthStencilValueDepth, clearDepthStencilValueStencil,
+
+	-- * RECT, OFFSET AND EXTENT
+
+	-- ** Rect
+
+	Rect2d, pattern Rect2d, rect2dExtent, rect2dOffset,
+
+	-- ** Offset
+
+	Offset2d, pattern Offset2d, offset2dX, offset2dY,
+	Offset3d, pattern Offset3d, offset3dX, offset3dY, offset3dZ,
+
+	-- ** Extent
+
+	Extent2d, pattern Extent2d, extent2dWidth, extent2dHeight,
+	Extent3d, pattern Extent3d, extent3dWidth, extent3dHeight, extent3dDepth,
+
+	-- * OTHERS
+
+	Size(..)
+
+	) where
+
+import Gpu.Vulkan.Middle.Internal
diff --git a/src/Gpu/Vulkan/Middle/Internal.hsc b/src/Gpu/Vulkan/Middle/Internal.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Middle/Internal.hsc
@@ -0,0 +1,348 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE BlockArguments, OverloadedStrings #-}
+{-# LANGUAGE ScopedTypeVariables, TypeApplications #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE KindSignatures, TypeOperators #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE FlexibleContexts, UndecidableInstances #-}
+{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
+{-# LANGUAGE StandaloneDeriving, GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Middle.Internal (
+	ApplicationInfo(..), applicationInfoToCore,
+	ApiVersion(..), makeApiVersion, apiVersion_1_0, apiVersion_1_1,
+	LayerProperties(..), layerPropertiesFromCore,
+	ExtensionProperties(..), extensionPropertiesFromCore,
+	StencilOpState(..), stencilOpStateToCore,
+	ClearValue(..), ClearValueListToCore(..),
+	ClearValueToCore, ClearColorValueToCore,
+	clearValueListToArray,
+	ClearType(..), ClearColorType(..),
+
+	C.ClearDepthStencilValue, pattern C.ClearDepthStencilValue,
+	C.clearDepthStencilValueDepth, C.clearDepthStencilValueStencil,
+
+	SubmitInfo(..), SubmitInfoListToCore(..), submitInfoToCore,
+
+	FormatProperties(..), formatPropertiesFromCore,
+
+	C.Rect2d, pattern C.Rect2d, C.rect2dExtent, C.rect2dOffset,
+
+	C.Offset2d, pattern C.Offset2d, C.offset2dX, C.offset2dY,
+	C.Offset3d, pattern C.Offset3d, C.offset3dX, C.offset3dY, C.offset3dZ,
+
+	C.Extent2d, pattern C.Extent2d, C.extent2dWidth, C.extent2dHeight,
+	C.Extent3d,
+	pattern C.Extent3d, C.extent3dWidth, C.extent3dHeight, C.extent3dDepth,
+
+	C.Viewport, pattern C.Viewport,
+	C.viewportX, C.viewportY, C.viewportWidth, C.viewportHeight,
+	C.viewportMinDepth, C.viewportMaxDepth,
+
+	Size(..)
+
+	) where
+
+import Foreign.Ptr
+import Foreign.Marshal.Alloc
+import Foreign.Marshal.Array
+import Foreign.Marshal.Utils
+import Foreign.Storable
+import Foreign.Storable.PeekPoke
+import Control.Arrow
+import Control.Monad
+import Data.Default
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Data.TypeLevel.List qualified as TL
+import Data.HeteroParList qualified as HeteroParList
+import Data.HeteroParList (pattern (:**))
+import Data.Word
+import Data.Text.Foreign.MiscYj
+import Data.Color.Internal
+
+import qualified Data.Text as T
+
+import Gpu.Vulkan.Enum
+
+import qualified Gpu.Vulkan.Core as C
+
+import qualified Gpu.Vulkan.Pipeline.Enum as Pipeline
+import qualified Gpu.Vulkan.Semaphore.Middle.Internal as Semaphore
+import {-# SOURCE #-} qualified
+	Gpu.Vulkan.CommandBuffer.Middle.Internal as CommandBuffer
+
+import Gpu.Vulkan.Middle.Types
+
+#include <vulkan/vulkan.h>
+
+data ApplicationInfo mn = ApplicationInfo {
+	applicationInfoNext :: TMaybe.M mn,
+	applicationInfoApplicationName :: T.Text,
+	applicationInfoApplicationVersion :: ApiVersion,
+	applicationInfoEngineName :: T.Text,
+	applicationInfoEngineVersion :: ApiVersion,
+	applicationInfoApiVersion :: ApiVersion }
+
+deriving instance Show (TMaybe.M mn) => Show (ApplicationInfo mn)
+
+newtype ApiVersion = ApiVersion C.ApiVersion deriving (Show, Eq, Ord, Storable)
+
+apiVersion_1_0, apiVersion_1_1 :: ApiVersion
+apiVersion_1_0 = ApiVersion C.apiVersion_1_0
+apiVersion_1_1 = ApiVersion C.apiVersion_1_1
+
+type Variant = Word8	-- 0 <= variant < 8
+type Major = Word8	-- 0 <= major < 127
+type Minor = Word16	-- 0 <= minor < 1023
+type Patch = Word16	-- 0 <= patch < 4095
+
+makeApiVersion :: Variant -> Major -> Minor -> Patch -> ApiVersion
+makeApiVersion v mj mn p = ApiVersion $ C.makeApiVersion v mj mn p
+
+applicationInfoToCore :: WithPoked (TMaybe.M mn) =>
+	ApplicationInfo mn -> (Ptr C.ApplicationInfo -> IO a) -> IO ()
+applicationInfoToCore ApplicationInfo {
+	applicationInfoNext = mnxt,
+	applicationInfoApplicationName = anm,
+	applicationInfoApplicationVersion = (\(ApiVersion v) -> v) -> appv,
+	applicationInfoEngineName = enm,
+	applicationInfoEngineVersion = (\(ApiVersion v) -> v) -> engv,
+	applicationInfoApiVersion = (\(ApiVersion v) -> v) -> apiv
+	} f = withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+	textToCString anm \canm -> textToCString enm \cenm ->
+	let	appInfo = C.ApplicationInfo {
+			C.applicationInfoSType = (),
+			C.applicationInfoPNext = pnxt',
+			C.applicationInfoPApplicationName = canm,
+			C.applicationInfoApplicationVersion = appv,
+			C.applicationInfoPEngineName = cenm,
+			C.applicationInfoEngineVersion = engv,
+			C.applicationInfoApiVersion = apiv } in
+	withPoked appInfo f
+
+data ExtensionProperties = ExtensionProperties {
+	extensionPropertiesExtensionName :: T.Text,
+	extensionPropertiesSpecVersion :: ApiVersion }
+	deriving Show
+
+extensionPropertiesFromCore :: C.ExtensionProperties -> ExtensionProperties
+extensionPropertiesFromCore C.ExtensionProperties {
+	C.extensionPropertiesExtensionName = en,
+	C.extensionPropertiesSpecVersion = sv } = ExtensionProperties {
+		extensionPropertiesExtensionName = en,
+		extensionPropertiesSpecVersion = ApiVersion sv }
+
+data LayerProperties = LayerProperties {
+	layerPropertiesLayerName :: T.Text,
+	layerPropertiesSpecVersion :: ApiVersion,
+	layerPropertiesImplementationVersion :: ApiVersion,
+	layerPropertiesDescription :: T.Text }
+	deriving Show
+
+layerPropertiesFromCore :: C.LayerProperties -> LayerProperties
+layerPropertiesFromCore C.LayerProperties {
+	C.layerPropertiesLayerName = ln,
+	C.layerPropertiesSpecVersion = sv,
+	C.layerPropertiesImplementationVersion = iv,
+	C.layerPropertiesDescription = dsc } = LayerProperties {
+	layerPropertiesLayerName = ln,
+	layerPropertiesSpecVersion = ApiVersion sv,
+	layerPropertiesImplementationVersion = ApiVersion iv,
+	layerPropertiesDescription = dsc }
+
+data StencilOpState = StencilOpState {
+	stencilOpStateFailOp :: StencilOp,
+	stencilOpStatePassOp :: StencilOp,
+	stencilOpStateDepthFailOp :: StencilOp,
+	stencilOpStateCompareOp :: CompareOp,
+	stencilOpStateCompareMask :: Word32,
+	stencilOpStateWriteMask :: Word32,
+	stencilOpStateReference :: Word32 }
+	deriving Show
+
+instance Default StencilOpState where def = stencilOpStateZero
+
+stencilOpStateZero :: StencilOpState
+stencilOpStateZero = StencilOpState {
+	stencilOpStateFailOp = StencilOpKeep,
+	stencilOpStatePassOp = StencilOpKeep,
+	stencilOpStateDepthFailOp = StencilOpKeep,
+	stencilOpStateCompareOp = CompareOpNever,
+	stencilOpStateCompareMask = 0,
+	stencilOpStateWriteMask = 0,
+	stencilOpStateReference = 0 }
+
+stencilOpStateToCore :: StencilOpState -> C.StencilOpState
+stencilOpStateToCore StencilOpState {
+	stencilOpStateFailOp = StencilOp fo,
+	stencilOpStatePassOp = StencilOp po,
+	stencilOpStateDepthFailOp = StencilOp dfo,
+	stencilOpStateCompareOp = CompareOp co,
+	stencilOpStateCompareMask = cm,
+	stencilOpStateWriteMask = wm,
+	stencilOpStateReference = rf } = C.StencilOpState {
+		C.stencilOpStateFailOp = fo,
+		C.stencilOpStatePassOp = po,
+		C.stencilOpStateDepthFailOp = dfo,
+		C.stencilOpStateCompareOp = co,
+		C.stencilOpStateCompareMask = cm,
+		C.stencilOpStateWriteMask = wm,
+		C.stencilOpStateReference = rf }
+
+data ClearValue (ct :: ClearType) where
+	ClearValueColor :: Rgba Float -> ClearValue ('ClearTypeColor cct)
+	ClearValueDepthStencil ::
+		C.ClearDepthStencilValue -> ClearValue 'ClearTypeDepthStencil
+
+class ClearColorValueToCore (cct :: ClearColorType) where
+	clearColorValueToCore ::
+		ClearValue ('ClearTypeColor cct) ->
+		(Ptr C.ClearColorValue -> IO a) -> IO a
+
+instance ClearColorValueToCore 'ClearColorTypeFloat32 where
+	clearColorValueToCore (ClearValueColor (RgbaDouble r g b a)) f =
+		allocaArray 4 \prgba -> do
+			pokeArray prgba [r, g, b, a]
+			f $ C.clearColorValueFromFloats prgba
+
+instance ClearColorValueToCore 'ClearColorTypeInt32 where
+	clearColorValueToCore (ClearValueColor (RgbaInt32 r g b a)) f =
+		allocaArray 4 \prgba -> do
+			pokeArray prgba [r, g, b, a]
+			f $ C.clearColorValueFromInts prgba
+
+instance ClearColorValueToCore 'ClearColorTypeUint32 where
+	clearColorValueToCore (ClearValueColor (RgbaWord32 r g b a)) f =
+		allocaArray 4 \prgba -> do
+			pokeArray prgba [r, g, b, a]
+			f $ C.clearColorValueFromUints prgba
+
+deriving instance Show (ClearValue ct)
+
+data ClearType = ClearTypeColor ClearColorType | ClearTypeDepthStencil
+	deriving Show
+
+data ClearColorType
+	= ClearColorTypeFloat32 | ClearColorTypeInt32 | ClearColorTypeUint32
+	deriving Show
+
+class ClearValueToCore (ct :: ClearType) where
+	clearValueToCore :: ClearValue ct -> (Ptr C.ClearValue -> IO a) -> IO a
+
+instance ClearValueToCore 'ClearTypeDepthStencil where
+	clearValueToCore (ClearValueDepthStencil cdsv) =
+		C.clearValueFromClearDepthStencilValue cdsv
+
+instance ClearColorValueToCore cct =>
+	ClearValueToCore ('ClearTypeColor cct) where
+	clearValueToCore cv@(ClearValueColor _) f =
+		clearColorValueToCore cv $ f . C.clearValueFromClearColorValue
+
+class TL.Length cts => ClearValueListToCore (cts :: [ClearType]) where
+	clearValueListToCore ::
+		HeteroParList.PL ClearValue cts ->
+		([Ptr C.ClearValue] -> IO a) -> IO a
+
+instance ClearValueListToCore '[] where clearValueListToCore HeteroParList.Nil = ($ [])
+
+instance (ClearValueToCore ct, ClearValueListToCore cts) =>
+	ClearValueListToCore (ct ': cts) where
+	clearValueListToCore (cv :** cvs) f =
+		clearValueToCore cv \ccv ->
+		clearValueListToCore cvs \ccvs -> f $ ccv : ccvs
+
+clearValueListToArray :: [Ptr C.ClearValue] -> (Ptr C.ClearValue -> IO a) -> IO a
+clearValueListToArray (length &&& id -> (pcvc, pcvl)) f =
+	allocaClearValueArray pcvc \pcva -> do
+		pokeClearValueArray pcva pcvl
+		f pcva
+
+allocaClearValueArray :: Int -> (Ptr C.ClearValue -> IO a) -> IO a
+allocaClearValueArray n = allocaBytesAligned
+	(alignedSize #{size VkClearValue} #{alignment VkClearValue} * n)
+	#{alignment VkClearValue}
+
+alignedSize :: Int -> Int -> Int
+alignedSize sz al = (sz - 1) `div` al * al + 1
+
+pokeClearValueArray :: Ptr C.ClearValue -> [Ptr C.ClearValue] -> IO ()
+pokeClearValueArray p lst = zipWithM_ pokeClearValue (clearValueArrayPtrs p) lst
+
+clearValueArrayPtrs :: Ptr C.ClearValue -> [Ptr C.ClearValue]
+clearValueArrayPtrs = iterate (
+	(`alignPtr` #{alignment VkClearValue})
+		. (`plusPtr` #{size VkClearValue}) )
+
+pokeClearValue :: Ptr C.ClearValue -> Ptr C.ClearValue -> IO ()
+pokeClearValue dst src = copyBytes dst src #{size VkClearValue}
+
+data SubmitInfo mn = SubmitInfo {
+	submitInfoNext :: TMaybe.M mn,
+	submitInfoWaitSemaphoreDstStageMasks ::
+		[(Semaphore.S, Pipeline.StageFlags)],
+	submitInfoCommandBuffers :: [CommandBuffer.C],
+	submitInfoSignalSemaphores :: [Semaphore.S] }
+
+class SubmitInfoListToCore ns where
+	submitInfoListToCore :: HeteroParList.PL SubmitInfo ns ->
+		([C.SubmitInfo] -> IO a) -> IO ()
+
+instance SubmitInfoListToCore '[] where
+	submitInfoListToCore HeteroParList.Nil f = () <$ f []
+
+instance (WithPoked (TMaybe.M n), SubmitInfoListToCore ns) =>
+	SubmitInfoListToCore (n ': ns) where
+	submitInfoListToCore (ci :** cis) f = submitInfoToCore @n ci \cci ->
+		submitInfoListToCore cis \ccis -> f $ cci : ccis
+
+submitInfoToCore :: WithPoked (TMaybe.M mn) =>
+	SubmitInfo mn -> (C.SubmitInfo -> IO a) -> IO ()
+submitInfoToCore SubmitInfo {
+	submitInfoNext = mnxt,
+	submitInfoWaitSemaphoreDstStageMasks =
+		length &&&
+		(	(Semaphore.unS <$>) ***
+			(Pipeline.unStageFlagBits <$>)) . unzip ->
+		(wsc, (wss, wdsms)),
+	submitInfoCommandBuffers = (length &&& id) . map CommandBuffer.unC -> (cbc, cbs),
+	submitInfoSignalSemaphores =
+		length &&& (Semaphore.unS <$>) -> (ssc, sss) } f =
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+	allocaArray wsc \pwss ->
+	pokeArray pwss wss >>
+	allocaArray wsc \pwdsms ->
+	pokeArray pwdsms wdsms >>
+	allocaArray cbc \pcbs ->
+	pokeArray pcbs cbs >>
+	allocaArray ssc \psss ->
+	pokeArray psss sss >>
+	f C.SubmitInfo {
+		C.submitInfoSType = (),
+		C.submitInfoPNext = pnxt',
+		C.submitInfoWaitSemaphoreCount = fromIntegral wsc,
+		C.submitInfoPWaitSemaphores = pwss,
+		C.submitInfoPWaitDstStageMask = pwdsms,
+		C.submitInfoCommandBufferCount = fromIntegral cbc,
+		C.submitInfoPCommandBuffers = pcbs,
+		C.submitInfoSignalSemaphoreCount = fromIntegral ssc,
+		C.submitInfoPSignalSemaphores = psss }
+
+data FormatProperties = FormatProperties {
+	formatPropertiesLinearTilingFeatures :: FormatFeatureFlags,
+	formatPropertiesOptimalTilingFeatures :: FormatFeatureFlags,
+	formatPropertiesBufferFeatures :: FormatFeatureFlags }
+	deriving Show
+
+formatPropertiesFromCore :: C.FormatProperties -> FormatProperties
+formatPropertiesFromCore C.FormatProperties {
+	C.formatPropertiesLinearTilingFeatures = ltfs,
+	C.formatPropertiesOptimalTilingFeatures = otfs,
+	C.formatPropertiesBufferFeatures = bfs
+	} = FormatProperties {
+		formatPropertiesLinearTilingFeatures =
+			FormatFeatureFlagBits ltfs,
+		formatPropertiesOptimalTilingFeatures =
+			FormatFeatureFlagBits otfs,
+		formatPropertiesBufferFeatures = FormatFeatureFlagBits bfs }
diff --git a/src/Gpu/Vulkan/Middle/Types.hs b/src/Gpu/Vulkan/Middle/Types.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Middle/Types.hs
@@ -0,0 +1,7 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Middle.Types where
+
+import Data.Word
+
+newtype Size = Size Word64 deriving Show
diff --git a/src/Gpu/Vulkan/Misc/Middle/Internal.hsc b/src/Gpu/Vulkan/Misc/Middle/Internal.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Misc/Middle/Internal.hsc
@@ -0,0 +1,20 @@
+{-# LANGUAGE BlockArguments, LambdaCase, TupleSections #-}
+{-# LANGUAGE MonoLocalBinds #-}
+{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
+{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Misc.Middle.Internal (
+
+	-- * Control
+
+	mapContM,
+
+	) where
+
+#include <vulkan/vulkan.h>
+
+mapContM :: Monad m => (a -> (b -> m c) -> m c) -> [a] -> ([b] -> m c) -> m c
+-- mapContM f = runContT . mapM (ContT . f)
+mapContM _ [] g = g []
+mapContM f (x : xs) g = f x \y -> mapContM f xs \ys -> g $ y : ys
diff --git a/src/Gpu/Vulkan/PNext/Middle.hs b/src/Gpu/Vulkan/PNext/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/PNext/Middle.hs
@@ -0,0 +1,11 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.PNext.Middle (
+
+	-- * FIND P NEXT CHAIN ALL
+
+	FindChainAll
+
+	) where
+
+import Gpu.Vulkan.PNext.Middle.Internal
diff --git a/src/Gpu/Vulkan/PNext/Middle/Internal.hs b/src/Gpu/Vulkan/PNext/Middle/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/PNext/Middle/Internal.hs
@@ -0,0 +1,102 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE ScopedTypeVariables, TypeApplications #-}
+{-# LANGUAGE MonoLocalBinds #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE KindSignatures, TypeOperators #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE FlexibleContexts, FlexibleInstances, UndecidableInstances #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.PNext.Middle.Internal (
+
+	-- * STRUCT COMMON
+
+	StructCommon(..), structCommonFromCore,
+
+	-- * SET AND READ CHAIN
+
+	Typeable(..), FindChainAll(..), ReadChain(..), Nextable(..)
+
+	) where
+
+import Foreign.Ptr
+import Foreign.Marshal.Alloc
+import Foreign.Storable
+import Foreign.Storable.PeekPoke
+import Data.Kind
+import Data.HeteroParList (pattern (:**))
+import Data.HeteroParList qualified as HPList
+
+import Gpu.Vulkan.Enum
+import Gpu.Vulkan.Core qualified as C
+
+import Data.TypeLevel.Maybe qualified as TMaybe
+
+-- STRUCT COMMON
+
+data StructCommon = StructCommon {
+	structCommonSType :: StructureType, structCommonPNext :: Ptr () }
+	deriving Show
+
+instance Peek StructCommon where
+	peek' p = structCommonFromCore <$> peek (castPtr p)
+
+instance Poke StructCommon where
+	poke' p = poke (castPtr p) . structCommonToCore
+
+structCommonFromCore :: C.StructCommon -> StructCommon
+structCommonFromCore C.StructCommon {
+	C.structCommonSType = stp, C.structCommonPNext = pn } = StructCommon {
+	structCommonSType = StructureType stp, structCommonPNext = pn }
+
+structCommonToCore :: StructCommon -> C.StructCommon
+structCommonToCore StructCommon {
+	structCommonSType = StructureType stp,
+	structCommonPNext = pn } = C.StructCommon {
+	C.structCommonSType = stp, C.structCommonPNext = pn }
+
+-- TYPEABLE
+
+class Peek n => Typeable n where structureType :: StructureType
+
+-- FIND PNEXT CHAIN ALL
+
+class FindChainAll ns where findChainAll :: Ptr () -> IO (HPList.PL Maybe ns)
+
+instance FindChainAll '[] where findChainAll _ = pure HPList.Nil
+
+instance (Typeable n, FindChainAll ns) => FindChainAll (n ': ns) where
+	findChainAll p = (:**) <$> findChain p <*> findChainAll p
+
+findChain :: forall n . Typeable n => Ptr () -> IO (Maybe n)
+findChain NullPtr = pure Nothing
+findChain p = peek' (castPtr p) >>= \sc ->
+	if structCommonSType sc == structureType @n
+		then Just <$> peek' (castPtr p)
+		else findChain $ structCommonPNext sc
+
+-- READ CHAIN
+
+class ReadChain mn where
+	clearedChain :: (Ptr () -> IO a) -> IO a
+	readChain :: Ptr () -> IO (TMaybe.M mn)
+
+instance ReadChain 'Nothing where
+	clearedChain = ($ nullPtr); readChain _ = pure TMaybe.N
+
+instance (Nextable n, ReadChain mnn) => ReadChain ('Just (n (mnn))) where
+	clearedChain f = clearedChain @mnn \np -> do
+		p <- callocBytes $ nextableSize @n
+		poke' p StructCommon {
+			structCommonSType = nextableType @n,
+			structCommonPNext = np }
+		f (castPtr p) <* free p
+	readChain p =
+		TMaybe.J <$> (createNextable p =<< readChain =<< nextPtr @n p)
+	
+class Nextable (n :: Maybe Type -> Type) where
+	nextableSize :: Int
+	nextableType :: StructureType; nextPtr :: Ptr () -> IO (Ptr ())
+	createNextable :: Ptr () -> TMaybe.M mn' -> IO (n mn')
diff --git a/src/Gpu/Vulkan/PNextOld/Middle.hs b/src/Gpu/Vulkan/PNextOld/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/PNextOld/Middle.hs
@@ -0,0 +1,11 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.PNextOld.Middle (
+
+	-- * FIND P NEXT CHAIN ALL
+
+	FindPNextChainAll
+
+	) where
+
+import Gpu.Vulkan.PNextOld.Middle.Internal
diff --git a/src/Gpu/Vulkan/PNextOld/Middle/Internal.hs b/src/Gpu/Vulkan/PNextOld/Middle/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/PNextOld/Middle/Internal.hs
@@ -0,0 +1,136 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE ScopedTypeVariables, TypeApplications #-}
+{-# LANGUAGE MonoLocalBinds #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE KindSignatures, TypeOperators #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE FlexibleContexts, FlexibleInstances, UndecidableInstances #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.PNextOld.Middle.Internal (
+
+	-- * STRUCT COMMON
+
+	StructCommon(..), structCommonFromCore,
+
+	-- * FIND P NEXT CHAIN ALL
+
+	FindPNextChainAll(..), Nextable(..),
+
+	FindPNextChainAll'(..), Nextable'(..),
+
+	-- * OTHERS
+
+--	ClearedChain(..)
+
+	) where
+
+import Foreign.Ptr
+import Foreign.Marshal.Alloc
+import Foreign.Storable
+import Foreign.Storable.PeekPoke
+import Data.Kind
+import Data.HeteroParList (pattern (:**))
+import Data.HeteroParList qualified as HeteroParList
+
+import Gpu.Vulkan.Enum
+import Gpu.Vulkan.Core qualified as C
+
+import Data.TypeLevel.Maybe qualified as TMaybe
+
+data StructCommon = StructCommon {
+	structCommonSType :: StructureType,
+	structCommonPNext :: Ptr () }
+	deriving Show
+
+instance Peek StructCommon where
+	peek' p = structCommonFromCore <$> peek (castPtr p)
+
+structCommonFromCore :: C.StructCommon -> StructCommon
+structCommonFromCore C.StructCommon {
+	C.structCommonSType = stp,
+	C.structCommonPNext = pn } = StructCommon {
+	structCommonSType = StructureType stp,
+	structCommonPNext = pn }
+
+instance Poke StructCommon where
+	poke' p = poke (castPtr p) . structCommonToCore
+
+structCommonToCore :: StructCommon -> C.StructCommon
+structCommonToCore StructCommon {
+	structCommonSType = StructureType stp,
+	structCommonPNext = pn } = C.StructCommon {
+	C.structCommonSType = stp,
+	C.structCommonPNext = pn }
+
+class Peek n => Nextable n where nextableType :: StructureType
+
+class FindPNextChainAll ns where
+	findPNextChainAll :: Ptr () -> IO (HeteroParList.PL Maybe ns)
+
+instance FindPNextChainAll '[] where
+	findPNextChainAll _ = pure HeteroParList.Nil
+
+instance (Nextable n, FindPNextChainAll ns) =>
+	FindPNextChainAll (n ': ns) where
+	findPNextChainAll p =
+		(:**) <$> findPNextChain p <*> findPNextChainAll p
+
+findPNextChain :: forall n . Nextable n => Ptr () -> IO (Maybe n)
+findPNextChain NullPtr = pure Nothing
+findPNextChain p = do
+	sc <- peek' $ castPtr p
+	putStrLn "findPNextChain"
+	putStrLn $ "\tthis type    : " ++ show (structCommonSType sc)
+	putStrLn $ "\tnextable type: " ++ show (nextableType @n)
+	if structCommonSType sc == nextableType @n
+	then Just <$> peek' (castPtr p)
+	else findPNextChain $ structCommonPNext sc
+
+class ClearedChain (ns :: [Type]) where
+	clearedChain :: (Ptr () -> IO a) -> IO a
+
+instance ClearedChain '[] where clearedChain = ($ nullPtr)
+
+instance (Sizable n, Nextable n, ClearedChain ns) => ClearedChain (n ': ns) where
+	clearedChain f = clearedChain @ns \p -> do
+		let	sc = StructCommon {
+				structCommonSType = nextableType @n,
+				structCommonPNext = p }
+		p' <- callocBytes (sizeOf' @n)
+		poke' p' sc
+		rslt <- f $ castPtr p'
+		free p'
+		pure rslt
+
+class FindPNextChainAll' mn where
+	clearedChain' :: (Ptr () -> IO a) -> IO a
+	findPNextChainAll' :: Ptr () -> IO (TMaybe.M mn)
+
+instance FindPNextChainAll' 'Nothing where
+	clearedChain' = ($ nullPtr)
+	findPNextChainAll' _ = pure TMaybe.N
+
+instance (Nextable' n, FindPNextChainAll' mn') =>
+	FindPNextChainAll' ('Just (n (mn'))) where
+	clearedChain' f = clearedChain' @mn' \p -> do
+		let	sc = StructCommon {
+				structCommonSType = nextableType' @n,
+				structCommonPNext = p }
+		p' <- callocBytes (nextableSize @n)
+		poke' p' sc
+		rslt <- f $ castPtr p'
+		free p'
+		pure rslt
+	findPNextChainAll' p = do
+		p' <- nextPtr @n p
+		mn' <- findPNextChainAll' p'
+		TMaybe.J <$> createNextable p mn'
+	
+class Nextable' (n :: Maybe Type -> Type) where
+	nextableSize :: Int
+	nextableType' :: StructureType
+	nextPtr :: Ptr () -> IO (Ptr ())
+	createNextable :: Ptr () -> TMaybe.M mn' -> IO (n mn')
diff --git a/src/Gpu/Vulkan/PhysicalDevice/Enum.hsc b/src/Gpu/Vulkan/PhysicalDevice/Enum.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/PhysicalDevice/Enum.hsc
@@ -0,0 +1,29 @@
+-- This file is automatically generated by the tools/makeEnum.hs
+--	% stack runghc --cwd tools/ makeEnum
+
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-missing-export-lists -fno-warn-tabs #-}
+
+module Gpu.Vulkan.PhysicalDevice.Enum where
+
+import Foreign.Storable
+import Foreign.C.Enum
+import Data.Word
+
+#include <vulkan/vulkan.h>
+
+enum "Type" ''#{type VkPhysicalDeviceType}
+		[''Show, ''Eq, ''Storable] [
+	("TypeOther", #{const VK_PHYSICAL_DEVICE_TYPE_OTHER}),
+	("TypeIntegratedGpu",
+		#{const VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU}),
+	("TypeDiscreteGpu",
+		#{const VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU}),
+	("TypeVirtualGpu",
+		#{const VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU}),
+	("TypeCpu", #{const VK_PHYSICAL_DEVICE_TYPE_CPU}),
+	("TypeMaxEnum",
+		#{const VK_PHYSICAL_DEVICE_TYPE_MAX_ENUM}) ]
diff --git a/src/Gpu/Vulkan/PhysicalDevice/Middle.hs b/src/Gpu/Vulkan/PhysicalDevice/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/PhysicalDevice/Middle.hs
@@ -0,0 +1,31 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.PhysicalDevice.Middle (
+
+	-- * ENUMERATE, PROPERTIES AND FEATURES
+
+	enumerate, P, getProperties, Properties(..), getFeatures,
+
+	-- ** Get Properties 2
+
+	getProperties2ExtensionName,
+	getFeatures2, Features2(..),
+
+	-- * OTHER PROPERTIES
+
+	enumerateExtensionProperties,
+	getQueueFamilyProperties,
+	getFormatProperties,
+	getMemoryProperties, MemoryProperties(..),
+
+	-- * OTHER FEATURES
+
+	ShaderDrawParametersFeatures(..),
+
+	-- * OTHER EXTENSIONS
+
+	maintenance3ExtensionName
+
+	) where
+
+import Gpu.Vulkan.PhysicalDevice.Middle.Internal
diff --git a/src/Gpu/Vulkan/PhysicalDevice/Middle/Internal.hsc b/src/Gpu/Vulkan/PhysicalDevice/Middle/Internal.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/PhysicalDevice/Middle/Internal.hsc
@@ -0,0 +1,266 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE BlockArguments, OverloadedStrings #-}
+{-# LANGUAGE ScopedTypeVariables, TypeApplications #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE FlexibleContexts, UndecidableInstances #-}
+{-# LANGUAGE ViewPatterns #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.PhysicalDevice.Middle.Internal (
+
+	-- * ENUMERATE, PROPERTIES AND FEATURES
+
+	enumerate, P(..), getProperties, Properties(..), getFeatures,
+
+	-- ** Get Properties 2
+
+	getProperties2ExtensionName,
+	getFeatures2, Features2(..),
+
+	-- * OTHER PROPERTIES
+
+	getQueueFamilyProperties,
+	enumerateExtensionProperties,
+	getFormatProperties,
+	getMemoryProperties, MemoryProperties(..),
+
+	-- * OTHER FEATURES
+
+	ShaderDrawParametersFeatures(..),
+
+	-- * OTHER EXTENSIONS
+
+	maintenance3ExtensionName
+
+	) where
+
+import Foreign.Ptr
+import Foreign.Marshal
+import Foreign.Storable
+import Foreign.Storable.PeekPoke
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Data.Maybe
+import Data.List.Length
+import Data.Word
+import Data.UUID
+
+import qualified Data.ByteString.Lazy as LBS
+
+import Data.Text qualified as T
+import Data.Text.Foreign.MiscYj
+
+import Gpu.Vulkan.Enum
+import Gpu.Vulkan.Middle.Internal
+import Gpu.Vulkan.Base.Middle.Internal
+import Gpu.Vulkan.Exception.Middle.Internal
+import Gpu.Vulkan.Exception.Enum
+import Gpu.Vulkan.PhysicalDevice.Enum
+import Gpu.Vulkan.PhysicalDevice.Struct
+
+import qualified Gpu.Vulkan.Instance.Middle.Internal as Instance.M
+import qualified Gpu.Vulkan.PhysicalDevice.Core as C
+import qualified Gpu.Vulkan.QueueFamily.Middle.Internal as QueueFamily
+import qualified Gpu.Vulkan.QueueFamily.EnumManual as QueueFamily
+import qualified Gpu.Vulkan.Memory.Middle.Internal as Memory.M
+
+import Gpu.Vulkan.PNext.Middle.Internal
+
+#include <vulkan/vulkan.h>
+
+newtype P = P C.P deriving Show
+
+enumerate :: Instance.M.I -> IO [P]
+enumerate (Instance.M.I ist) = map P <$> alloca \pdvcc ->
+	C.enumerate ist pdvcc NullPtr >>= \r ->
+	throwUnlessSuccess (Result r) >>
+	peek pdvcc >>= \(fromIntegral -> dvcc) ->
+	allocaArray dvcc \pdvcs ->
+	C.enumerate ist pdvcc pdvcs >>= \r' ->
+	throwUnlessSuccess (Result r') >>
+	peekArray dvcc pdvcs
+
+data Properties = Properties {
+	propertiesApiVersion :: ApiVersion,
+	propertiesDriverVersion :: Word32,
+	propertiesVendorId :: Word32,
+	propertiesDeviceId :: Word32,
+	propertiesDeviceType :: Type,
+	propertiesDeviceName :: T.Text,
+	propertiesPipelineCacheUuid :: UUID,
+	propertiesLimits :: Limits,
+	propertiesSparseProperties :: SparseProperties }
+	deriving Show
+
+propertiesFromCore :: C.Properties -> Properties
+propertiesFromCore C.Properties {
+	C.propertiesApiVersion = av,
+	C.propertiesDriverVersion = dv,
+	C.propertiesVendorId = vi,
+	C.propertiesDeviceId = di,
+	C.propertiesDeviceType = dt,
+	C.propertiesDeviceName = dn,
+	C.propertiesPipelineCacheUuid = pcu,
+	C.propertiesLimits = l,
+	C.propertiesSparseProperties = sp } = Properties {
+	propertiesApiVersion = ApiVersion av,
+	propertiesDriverVersion = dv,
+	propertiesVendorId = vi,
+	propertiesDeviceId = di,
+	propertiesDeviceType = Type dt,
+	propertiesDeviceName = dn,
+	propertiesPipelineCacheUuid = word8listToUuid pcu,
+	propertiesLimits = limitsFromCore l,
+	propertiesSparseProperties = sparsePropertiesFromCore sp }
+
+word8listToUuid :: [Word8] -> UUID
+word8listToUuid ws = fromJust . fromByteString $ LBS.pack ws
+
+data SparseProperties = SparseProperties {
+	sparsePropertiesResidencyStandard2DBlockShape :: Bool,
+	sparsePropertiesResidencyStandard2DMultisampleBlockShape :: Bool,
+	sparsePropertiesResidencyStandard3DBlockShape :: Bool,
+	sparsePropertiesResidencyAlignedMipSize :: Bool,
+	sparsePropertiesResidencyNonResidentStrict :: Bool }
+	deriving Show
+
+sparsePropertiesFromCore :: C.SparseProperties -> SparseProperties
+sparsePropertiesFromCore C.SparseProperties {
+	C.sparsePropertiesResidencyStandard2DBlockShape = crs2bs,
+	C.sparsePropertiesResidencyStandard2DMultisampleBlockShape = crs2mbs,
+	C.sparsePropertiesResidencyStandard3DBlockShape = crs3bs,
+	C.sparsePropertiesResidencyAlignedMipSize = crams,
+	C.sparsePropertiesResidencyNonResidentStrict = cnrs } =
+	SparseProperties {
+		sparsePropertiesResidencyStandard2DBlockShape = rs2bs,
+		sparsePropertiesResidencyStandard2DMultisampleBlockShape =
+			rs2mbs,
+		sparsePropertiesResidencyStandard3DBlockShape = rs3bs,
+		sparsePropertiesResidencyAlignedMipSize = rams,
+		sparsePropertiesResidencyNonResidentStrict = nrs }
+	where
+	(rs2bs :. rs2mbs :. rs3bs :. rams :. nrs :. NilL :: LengthL 5 Bool) =
+		bool32ToBool <$>
+			(crs2bs :. crs2mbs :. crs3bs :. crams :. cnrs :. NilL)
+
+getProperties :: P -> IO Properties
+getProperties (P pdvc) = propertiesFromCore <$> alloca \pppts -> do
+	C.getProperties pdvc pppts
+	peek pppts
+
+getFeatures :: P -> IO Features
+getFeatures (P pdvc) = featuresFromCore <$> alloca \pfts -> do
+	C.getFeatures pdvc pfts
+	peek pfts
+
+getFeatures2 :: forall mn . ReadChain mn => P -> IO (Features2 mn)
+getFeatures2 (P pdvc) = clearedChain @mn \pn ->
+	features2FromCore =<< alloca \pfts -> do
+		cfs <- C.getClearedFeatures
+		poke pfts $ C.Features2 {
+			C.features2SType = (),
+			C.features2PNext = pn,
+			C.features2Features = cfs }
+		C.getFeatures2 pdvc pfts
+		peek pfts
+
+data Features2 mn = Features2 {
+	features2Next :: TMaybe.M mn,
+	features2Features :: Features }
+
+deriving instance Show (TMaybe.M mn) => Show (Features2 mn)
+
+features2FromCore :: ReadChain mn => C.Features2 -> IO (Features2 mn)
+features2FromCore C.Features2 {
+	C.features2PNext = pnxt,
+	C.features2Features = ftrs } = do
+	nxts <- readChain pnxt
+	let	ftrs' = featuresFromCore ftrs
+	pure Features2 {
+		features2Next = nxts, features2Features = ftrs' }
+
+getQueueFamilyProperties :: P -> IO [(QueueFamily.Index, QueueFamily.Properties)]
+getQueueFamilyProperties (P pdvc) =
+	(QueueFamily.indices `zip`)
+		. map QueueFamily.propertiesFromCore <$> alloca \ppptc ->
+	C.getQueueFamilyProperties pdvc ppptc NullPtr >>
+	peek ppptc >>= \(fromIntegral -> pptc) ->
+	allocaArray pptc \pppts ->
+	C.getQueueFamilyProperties pdvc ppptc pppts >>
+	peekArray pptc pppts
+
+enumerateExtensionProperties ::
+	P -> Maybe T.Text -> IO [ExtensionProperties]
+enumerateExtensionProperties (P pdvc) mlnm =
+	map extensionPropertiesFromCore <$> case mlnm of
+		Nothing -> go NullPtr
+		Just lnm -> textToCString lnm go
+	where
+	go cmlnm = alloca \pExtensionCount ->
+		C.enumerateExtensionProperties
+			pdvc cmlnm pExtensionCount NullPtr >>= \r ->
+		throwUnlessSuccess (Result r) >>
+		peek pExtensionCount >>= \(fromIntegral -> extensionCount) ->
+		allocaArray extensionCount \pAvailableExtensions -> do
+			r' <- C.enumerateExtensionProperties pdvc cmlnm
+				pExtensionCount pAvailableExtensions
+			throwUnlessSuccess $ Result r'
+			peekArray extensionCount pAvailableExtensions
+
+data MemoryProperties = MemoryProperties {
+	memoryPropertiesMemoryTypes :: [(Memory.M.TypeIndex, Memory.M.MType)],
+	memoryPropertiesMemoryHeaps :: [Memory.M.Heap] }
+	deriving Show
+
+memoryPropertiesFromCore :: C.MemoryProperties -> MemoryProperties
+memoryPropertiesFromCore C.MemoryProperties {
+	C.memoryPropertiesMemoryTypeCount = fromIntegral -> mtc,
+	C.memoryPropertiesMemoryTypes = (Memory.M.mTypeFromCore <$>) -> mts,
+	C.memoryPropertiesMemoryHeapCount = fromIntegral -> mhc,
+	C.memoryPropertiesMemoryHeaps = (Memory.M.heapFromCore <$>) -> mhs } =
+	MemoryProperties {
+		memoryPropertiesMemoryTypes = [0 ..] `zip` take mtc mts,
+		memoryPropertiesMemoryHeaps = take mhc mhs }
+
+getMemoryProperties :: P -> IO MemoryProperties
+getMemoryProperties (P p) = memoryPropertiesFromCore <$> alloca \pmps -> do
+	C.getMemoryProperties p pmps
+	peek pmps
+
+getFormatProperties :: P -> Format -> IO FormatProperties
+getFormatProperties (P pdvc) (Format fmt) = formatPropertiesFromCore <$> alloca \pp -> do
+	C.getFormatProperties pdvc fmt pp
+	peek pp
+
+data ShaderDrawParametersFeatures mn = ShaderDrawParametersFeatures {
+	shaderDrawParametersFeaturesNext :: TMaybe.M mn,
+	shaderDrawParametersFeaturesShaderDrawParameters :: Bool }
+
+deriving instance Show (TMaybe.M mn) => Show (ShaderDrawParametersFeatures mn)
+
+shaderDrawParametersFeaturesToCore :: WithPoked (TMaybe.M mn) =>
+	ShaderDrawParametersFeatures mn ->
+	(Ptr C.ShaderDrawParametersFeatures -> IO a) -> IO a
+shaderDrawParametersFeaturesToCore ShaderDrawParametersFeatures {
+	shaderDrawParametersFeaturesNext = mnxt,
+	shaderDrawParametersFeaturesShaderDrawParameters = sdp } f =
+	alloca \pfs -> withPoked' mnxt \pnxt -> do
+		withPtrS pnxt \(castPtr -> pnxt') -> poke pfs
+			C.ShaderDrawParametersFeatures {
+				C.shaderDrawParametersFeaturesSType = (),
+				C.shaderDrawParametersFeaturesPNext = pnxt',
+				C.shaderDrawParametersFeaturesShaderDrawParameters =
+					boolToBool32 sdp }
+		f pfs
+
+instance WithPoked (TMaybe.M mn) => WithPoked (ShaderDrawParametersFeatures mn) where
+	withPoked' sdpfs f =
+		shaderDrawParametersFeaturesToCore sdpfs $ f . ptrS . castPtr
+
+maintenance3ExtensionName :: T.Text
+maintenance3ExtensionName = #{const_str VK_KHR_MAINTENANCE_3_EXTENSION_NAME}
+
+getProperties2ExtensionName :: T.Text
+getProperties2ExtensionName =
+	#{const_str VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}
diff --git a/src/Gpu/Vulkan/PhysicalDevice/Struct.hs b/src/Gpu/Vulkan/PhysicalDevice/Struct.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/PhysicalDevice/Struct.hs
@@ -0,0 +1,63 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE FlexibleContexts, UndecidableInstances #-}
+{-# LANGUAGE ViewPatterns #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.PhysicalDevice.Struct where
+
+import Foreign.Ptr
+import Foreign.Marshal.Alloc
+import Foreign.Storable
+import Foreign.Storable.PeekPoke
+
+import Data.Default
+import System.IO.Unsafe
+
+import Gpu.Vulkan.PhysicalDevice.Struct.Th
+import qualified Gpu.Vulkan.PhysicalDevice.Core as C
+import qualified Gpu.Vulkan.PhysicalDevice.Struct.Core as C
+
+import Gpu.Vulkan.PhysicalDevice.Struct.ThTest
+
+import Gpu.Vulkan.Enum
+import Gpu.Vulkan.PNext.Middle.Internal
+
+import Data.TypeLevel.Maybe qualified as TMaybe
+
+vkPhysicalDeviceLimits
+vkPhysicalDeviceFeatures
+
+featuresZero :: Features
+featuresZero = unsafePerformIO $ featuresFromCore <$> C.getClearedFeatures
+
+instance Default Features where def = featuresZero
+
+makeStructure "DescriptorIndexingFeatures"
+
+instance Peek DescriptorIndexingFeaturesNoNext where
+	peek' = (descriptorIndexingFeaturesFromCore <$>) . peek . castPtr
+
+instance Typeable DescriptorIndexingFeaturesNoNext where
+	structureType = StructureTypePhysicalDeviceDescriptorIndexingFeatures
+
+instance Sizable DescriptorIndexingFeaturesNoNext where
+	sizeOf' = sizeOf @C.DescriptorIndexingFeatures undefined
+	alignment' = alignment @C.DescriptorIndexingFeatures undefined
+
+instance WithPoked (TMaybe.M mn) => WithPoked (DescriptorIndexingFeatures mn) where
+	withPoked' difs f = alloca \pcdifs -> do
+		descriptorIndexingFeaturesToCore difs $ \cdifs -> poke pcdifs cdifs
+		f . ptrS $ castPtr pcdifs
+
+instance Nextable DescriptorIndexingFeatures where
+	nextableSize = sizeOf @C.DescriptorIndexingFeatures undefined
+	nextableType = StructureTypePhysicalDeviceDescriptorIndexingFeatures
+	nextPtr p = C.descriptorIndexingFeaturesPNext <$> peek (castPtr p)
+	createNextable p n =
+		descriptorIndexingFeaturesFromNoNext n .
+		descriptorIndexingFeaturesFromCore <$> peek (castPtr p)
diff --git a/src/Gpu/Vulkan/PhysicalDevice/Struct/Th.hs b/src/Gpu/Vulkan/PhysicalDevice/Struct/Th.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/PhysicalDevice/Struct/Th.hs
@@ -0,0 +1,219 @@
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.PhysicalDevice.Struct.Th (
+	vkPhysicalDeviceLimits, vkPhysicalDeviceFeatures,
+	DeviceSize(..), Size(..),
+
+
+	vkPhysicalDeviceData, vkPhysicalDeviceFromFunBody
+	) where
+
+import Language.Haskell.TH
+import Control.Arrow
+import Control.Monad
+import Data.Foldable
+import Data.Maybe
+import Data.List.Length
+import Data.Word
+import Data.Int
+import Data.Char
+
+import Gpu.Vulkan.Middle.Types
+import Gpu.Vulkan.Base.Middle.Internal
+
+import qualified Gpu.Vulkan.Sample.Enum as Sample
+
+import qualified Gpu.Vulkan.Device.Middle.Types as Device
+
+newtype DeviceSize = DeviceSize { unDeviceSize :: Word64 }
+	deriving (Show, Eq, Ord, Enum, Num, Real, Integral)
+
+vkPhysicalDeviceLimits :: DecsQ
+vkPhysicalDeviceLimits = makeData "Limits"
+
+vkPhysicalDeviceFeatures :: DecsQ
+vkPhysicalDeviceFeatures = makeData "Features"
+
+makeData :: String -> DecsQ
+makeData dtnm = (\dt sg bd tsg tbd -> [dt, sg, bd, tsg, tbd])
+	<$> vkPhysicalDeviceData dtnm
+	<*> vkPhysicalDeviceFromFunSig dtnm
+	<*> vkPhysicalDeviceFromFunBody dtnm
+	<*> vkPhysicalDeviceToFunSig dtnm
+	<*> vkPhysicalDeviceToFunBody dtnm
+
+vkPhysicalDeviceData :: String -> DecQ
+vkPhysicalDeviceData dtnm = do
+	ds <- runIO $ readStructData dtnm
+	dataD (cxt []) (mkName dtnm) [] Nothing [recC (mkName dtnm)
+		(uncurry (member dtnm) <$> ds)] [derivClause Nothing [conT ''Show]]
+
+dict :: Dict
+dict = dictGenToDict dictGen
+
+dictGenToDict :: DictGen -> Dict
+dictGenToDict = map \(tp, tfr, _to) -> (tp, tfr)
+
+dict2 :: Dict2
+dict2 = dictGenToDict2 dictGen
+
+dictGenToDict2 :: DictGen -> Dict2
+dictGenToDict2 = map \(tp, _tfr, to) -> (tp, to)
+
+type Dict = [(String, (TypeQ, Name -> ExpQ))]
+type Dict2 = [(String, (Name -> PatQ, Name -> ExpQ))]
+type DictGen = [(String, (TypeQ, Name -> ExpQ), (Name -> PatQ, Name -> ExpQ))]
+
+dictGen :: [(String, (TypeQ, Name -> ExpQ), (Name -> PatQ, Name -> ExpQ))]
+dictGen = [
+	("uint32_t", (conT ''Word32, varE), (varP, varE)),
+	("int32_t", (conT ''Int32, varE), (varP, varE)),
+	("float", (conT ''Float, varE), (varP, varE)),
+	("VkBool32", (conT ''Bool, appE (varE 'bool32ToBool) . varE),
+		(varP, appE (varE 'boolToBool32) . varE)),
+	("size_t", (conT ''Size, appE (conE 'Size) . varE),
+		(conP 'Size . (: []) . varP, varE)),
+	("VkDeviceSize", (conT ''Device.Size, appE (conE 'Device.Size) . varE),
+		(conP 'Device.Size . (: []) . varP, varE)),
+	("VkSampleCountFlags",
+		(conT ''Sample.CountFlags,
+			appE (conE 'Sample.CountFlagBits) . varE),
+		(conP 'Sample.CountFlagBits . (: []) . varP, varE)) ]
+
+noBang :: BangQ
+noBang = bang noSourceUnpackedness noSourceStrictness
+
+member :: String -> String -> FieldName -> VarBangTypeQ
+member dtnm tp_ fn = varBangType (mkName nm) $ bangType noBang tp
+	where
+	pfx = map toLower dtnm
+	(nm, tp) = getNameType pfx tp_ fn
+
+getNameType :: String -> String -> FieldName -> (String, TypeQ)
+getNameType pfx tp (Atom fn) = (pfx ++ capitalize fn, fst $ lookup' tp dict)
+getNameType pfx tp (List fn nb) = (pfx ++ capitalize fn,
+	conT ''LengthL `appT` litT (numTyLit nb) `appT` fst (lookup' tp dict))
+
+lookup' :: (Show a, Eq a) => a -> [(a, b)] -> b
+lookup' x d = case lookup x d of
+	Nothing -> error $ "no such key: " ++ show x
+	Just y -> y
+
+capitalize :: String -> String
+capitalize "" = ""
+capitalize (c : cs) = toUpper c : cs
+
+readStructData :: String -> IO [(String, FieldName)]
+readStructData dtnm = map ((id *** readName) . (separate '|')) . lines <$>
+	(readFile $ "th/vkPhysicalDevice" ++ dtnm ++ ".txt")
+
+data FieldName = Atom String | List String Integer deriving Show
+
+readName :: String -> FieldName
+readName ('A' : ' ' : nm) = Atom nm
+readName ('L' : ' ' : nmnb) = let [nm, nb] = words nmnb in List nm (read nb)
+readName _ = error "bad"
+
+separate :: Eq a => a -> [a] -> ([a], [a])
+separate c str = case span (/= c) str of
+	(pre, _ : pst) -> (pre, pst)
+	_ -> error "no separater"
+
+vkPhysicalDeviceFromFunSig :: String -> DecQ
+vkPhysicalDeviceFromFunSig dtnm = sigD (mkName $ map toLower dtnm ++ "FromCore")
+	$ (conT =<< (fromJustMsg "vkPhysicalDeviceFromFunSig" <$> lookupTypeName ("C." ++ dtnm))) `arrT` conT (mkName dtnm)
+
+vkPhysicalDeviceToFunSig :: String -> DecQ
+vkPhysicalDeviceToFunSig dtnm = sigD (mkName $ map toLower dtnm ++ "ToCore")
+	$ conT (mkName dtnm) `arrT` (conT =<< (fromJustMsg "vkPhysicalDeviceToFunSig" <$> lookupTypeName ("C." ++ dtnm)))
+
+arrT :: TypeQ -> TypeQ -> TypeQ
+arrT t1 t2 = arrowT `appT` t1 `appT` t2
+
+vkPhysicalDeviceFromFunBody :: String -> DecQ
+vkPhysicalDeviceFromFunBody dtnm = do
+	ds <- runIO $ readStructData dtnm
+	xs <- replicateM (length ds) $ newName "x"
+	let	fs = (\(tp, _) -> typeToFun tp) <$> ds
+		nvs = zip (map snd ds) xs
+		nws = zip (zip (map snd ds) xs) fs
+	funD (mkName $ map toLower dtnm ++ "FromCore") [
+		clause [(`recP` exFieldPats dtnm nvs) =<< fromJustMsg "vkPhysicalDeviceFromFunBody" <$> lookupValueName' ("C." ++ dtnm)]
+			(normalB $ recConE (mkName dtnm) (exFieldExps dtnm nws)) []
+		]
+
+vkPhysicalDeviceToFunBody :: String -> DecQ
+vkPhysicalDeviceToFunBody dtnm = do
+	ds <- runIO $ readStructData dtnm
+	xs <- replicateM (length ds) $ newName "x"
+	let	pes = (\(tp, _) -> typeToPatExp tp) <$> ds
+		nvs = zip (zip (map snd ds) xs) pes
+	funD (mkName $ map toLower dtnm ++ "ToCore") [
+		clause [(recP (mkName dtnm) $ toFieldPats dtnm nvs)]
+			(normalB $ (`recConE` toFieldExps dtnm nvs) =<< fromJustMsg "vkPhysicalDeviceToFunBody" <$> lookupValueName' ("C." ++ dtnm)) []]
+
+typeToFun :: String -> (Name -> ExpQ)
+typeToFun nm = let Just (_, f) = lookup nm dict in f
+
+exFieldPats :: String -> [(FieldName, Name)] -> [Q FieldPat]
+exFieldPats dtnm = map $ uncurry (exFieldPat1 $ map toLower dtnm)
+
+exFieldPat1 :: String -> FieldName -> Name -> Q FieldPat
+exFieldPat1 pfx fn x = do
+	let	nm = case fn of
+			Atom n -> n
+			List n _ -> n
+	n <- fromJustMsg (mkMsg pfx nm) <$> lookupValueName' ("C." ++ pfx ++ capitalize nm)
+	fieldPat n (varP x)
+	where
+	mkMsg p n = "exFieldPat1: pfx = " ++ show p ++ " nm = " ++ show n
+
+exFieldExps :: String -> [((FieldName, Name), Name -> ExpQ)] -> [Q (Name, Exp)]
+exFieldExps dtnm = map . uncurry $ uncurry (exFieldExp1 $ map toLower dtnm)
+
+listToLengthL :: ListToLengthL n => [a] -> LengthL n a
+listToLengthL xs = case splitL xs of
+	Right (ln, []) -> ln
+	_ -> error "bad"
+
+exFieldExp1 :: String -> FieldName -> Name -> (Name -> ExpQ) -> Q (Name, Exp)
+exFieldExp1 pfx (Atom nm) x f = fieldExp (mkName $ pfx ++ capitalize nm) (f x)
+exFieldExp1 pfx (List nm _) x f = do
+	y <- newName "y"
+	fieldExp (mkName $ pfx ++ capitalize nm)
+		. appE (varE 'listToLengthL) $ lam1E (varP y) (f y) .<$> varE x
+
+(.<$>) :: ExpQ -> ExpQ -> ExpQ
+f .<$> x = infixApp f (varE '(<$>)) x
+
+typeToPatExp :: String -> (Name -> PatQ, Name -> ExpQ)
+typeToPatExp = fromJustMsg "typeToPatExp" . (`lookup` dict2)
+
+toFieldPats :: String -> [((FieldName, Name), (Name -> PatQ, a))] -> [Q FieldPat]
+toFieldPats dtnm = map . uncurry $ uncurry (toFieldPat1 $ map toLower dtnm)
+
+toFieldPat1 :: String -> FieldName -> Name -> ((Name -> PatQ), a) -> Q FieldPat
+toFieldPat1 pfx (Atom nm) x (f, _) = fieldPat (mkName $ pfx ++ capitalize nm) (f x)
+toFieldPat1 pfx (List nm _) x _ = fieldPat (mkName $ pfx ++ capitalize nm) (varP x)
+
+toFieldExps :: String -> [((FieldName, Name), (Name -> PatQ, Name -> ExpQ))] -> [Q (Name, Exp)]
+toFieldExps dtnm = map . uncurry $ uncurry (toFieldExp1 $ map toLower dtnm)
+
+toFieldExp1 :: String -> FieldName -> Name -> (Name -> PatQ, Name -> ExpQ) -> Q (Name, Exp)
+toFieldExp1 pfx (Atom nm) x (_, f) = do
+	n <- fromJustMsg "toFieldExp1" <$> lookupValueName' ("C." ++ pfx ++ capitalize nm)
+	fieldExp n (f x)
+toFieldExp1 pfx (List nm _) x (pf, f) = do
+	n <- fromJustMsg "toFieldExp1" <$> lookupValueName' ("C." ++ pfx ++ capitalize nm)
+	y <- newName "y"
+	fieldExp n $ lam1E (pf y) (f y) .<$> (varE 'toList `appE` varE x)
+
+fromJustMsg :: String -> Maybe a -> a
+fromJustMsg msg Nothing = error msg
+fromJustMsg _ (Just x) = x
+
+lookupValueName' :: String -> Q (Maybe Name)
+lookupValueName' = pure . Just . mkName
diff --git a/src/Gpu/Vulkan/PhysicalDevice/Struct/ThTest.hs b/src/Gpu/Vulkan/PhysicalDevice/Struct/ThTest.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/PhysicalDevice/Struct/ThTest.hs
@@ -0,0 +1,317 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE BlockArguments, LambdaCase, TupleSections #-}
+{-# LANGUAGE FlexibleContexts, UndecidableInstances #-}
+{-# LANGUAGE ViewPatterns #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.PhysicalDevice.Struct.ThTest where
+
+import Language.Haskell.TH
+
+import Foreign.Ptr
+import Foreign.Storable.PeekPoke
+
+import Data.TypeLevel.Maybe qualified as TMaybe
+-- import Gpu.Vulkan.PhysicalDevice.Struct.Core qualified as C
+
+import Gpu.Vulkan.Base.Middle.Internal
+
+import qualified Gpu.Vulkan.Sample.Enum as Sample
+import Data.Word
+import Data.Int
+import Data.List.Length
+import Data.Char
+import Control.Arrow
+-- import Data.Maybe
+import Data.Foldable
+import Control.Monad
+
+fromJust' :: String -> Maybe a -> a
+fromJust' msg = \case Nothing -> error msg; Just x -> x
+
+makeStructure :: String -> DecsQ
+makeStructure nm = do
+	dct <- readStructData nm
+	sequence [
+		mkData nm dct, mkDataShow nm, mkDataNoNext nm dct,
+		mkFromCoreType Production nm, mkFromCoreBody Production nm dct,
+		mkToCoreType Production nm, mkToCoreBody Production nm dct,
+		mkFromNoNextType nm, mkFromNoNextBody nm dct ]
+
+mkData :: String -> DictFieldName -> DecQ
+mkData nm dct = do
+	mn <- newName "mn"
+	let	varBangTypes = getVarBangTypes "" nm dct
+	dataD (cxt [])
+		(mkName nm)
+		[plainTV mn] Nothing
+		[recC (mkName nm) $
+			(varBangType (mkName $ nm' ++ "Next")
+				(bangType noBang
+					(conT ''TMaybe.M `appT` varT mn))) :
+			(drop 2 varBangTypes)] []
+	where nm' = appHead toLower nm
+
+mkDataShow :: String -> DecQ
+mkDataShow nm = standaloneDerivD
+	(cxt [conT ''Show `appT` (conT ''TMaybe.M `appT` varT (mkName "mn"))])
+	(conT ''Show `appT` (conT (mkName nm) `appT` varT (mkName "mn")))
+
+mkDataNoNext :: String -> DictFieldName -> DecQ
+mkDataNoNext nm dct = do
+	let	varBangTypes = getVarBangTypes "NoNext" nm dct
+	dataD (cxt []) (mkName nmnnx) [] Nothing
+		[recC (mkName nmnnx) $ drop 2 varBangTypes]
+		[derivClause Nothing [conT ''Show]]
+	where nmnnx = nm ++ "NoNext"
+
+getVarBangTypes :: String -> String -> DictFieldName -> [VarBangTypeQ]
+getVarBangTypes sfx dtnm ds = uncurry (member $ dtnm ++ sfx) <$> ds
+
+mkFromCoreType :: Debug -> String -> DecQ
+mkFromCoreType dbg nm = do
+	cnm <- fromJust' "foo" <$> lookupTypeName' dbg ("C." ++ nm)
+	sigD (mkName $ nm' ++ "FromCore")
+		(conT cnm `arrT` conT (mkName $ nm ++ "NoNext"))
+	where nm' = appHead toLower nm
+
+mkFromCoreBody :: Debug -> String -> DictFieldName -> DecQ
+mkFromCoreBody dbg nm dct = do
+	let	ds = drop 2 dct
+	xs <- replicateM (length ds) $ newName "x"
+	let	fs = (\(tp, _) -> typeToFun tp) <$> ds
+		nvs = zip (map snd ds) xs
+		nws = zip (zip (map snd ds) xs) fs
+	cnm <- fromJust' "bar" <$> lookupValueName' dbg ("C." ++ nm)
+	funD (mkName $ nm' ++ "FromCore") . (: []) . ($ [])
+		. clause [mkFromCorePat cnm nvs] . normalB
+		$ recConE (mkName $ nm ++ "NoNext") (exFieldExps "NoNext" nm nws)
+	where
+	nm' = appHead toLower nm
+	mkFromCorePat cnm nvs = recP cnm $ exFieldPats dbg nm nvs
+
+mkToCoreType :: Debug -> String -> DecQ
+mkToCoreType dbg nm = do
+	mn <- newName "mn"
+	cnm <- fromJust' "baz" <$> lookupTypeName' dbg ("C." ++ nm)
+	sigD (mkName $ nm' ++ "ToCore")
+		(forallT []
+			(cxt [conT ''WithPoked `appT`
+				(conT ''TMaybe.M `appT` varT mn)])
+			(conT (mkName nm) `appT` varT mn `arrT`
+				(conT cnm `arrT` conT ''IO `appT` conT ''()) `arrT`
+				conT ''IO `appT` conT ''()))
+	where nm' = appHead toLower nm
+
+mkToCoreBody :: Debug -> String -> DictFieldName -> DecQ
+mkToCoreBody dbg nm ds = do
+	f <- newName "f"
+	cnm <- fromJust' "poooo" <$> lookupValueName' dbg ("C." ++ nm)
+	stype <- fromJust' "hogefuga" <$> lookupValueName' dbg ("C." ++ nm' ++ "SType")
+	pnext <- fromJust' "oops" <$> lookupValueName' dbg ("C." ++ nm' ++ "PNext")
+	xs <- replicateM (length ds) $ newName "x"
+	let	pes = (\(tp, _) -> typeToPatExp tp) <$> ds
+		nvs = zip (zip (map snd ds) xs) pes
+	[mnxt, pnxt, pnxt'] <- newName `mapM` ["mnxt", "pnxt", "pnxt'"]
+	funD (mkName $ nm' ++ "ToCore")
+		. (: []) . ($ []) . clause [mkToCorePat mnxt nvs, varP f] . normalB
+		$ varE 'withPoked' `appE` varE mnxt `appE`
+			lamE [varP pnxt] (
+				varE 'withPtrS `appE` varE pnxt `appE`
+				lamE [viewP (varE 'castPtr) (varP pnxt')] (
+					varE f `appE`
+					recConE cnm (
+						((stype ,) <$> conE '()) : ((pnext ,) <$> varE pnxt') :
+						toFieldExps dbg nm (drop 2 nvs) ) ) )
+	where
+	nm' = appHead toLower nm
+	mkToCorePat mnxt nvs = recP (mkName nm)
+		$ fieldPat (mkName $ nm' ++ "Next") (varP mnxt) : toFieldPats nm (drop 2 nvs)
+
+type DictFieldName = [(String, FieldName)]
+
+readStructData :: String -> Q DictFieldName
+readStructData dtnm = runIO $ map ((id *** readName) . (separate '|')) . lines <$>
+	(readFile $ "th/vkPhysicalDevice" ++ dtnm ++ ".txt")
+
+data Debug = Production | Debug deriving Show
+
+lookupValueName' :: Debug -> String -> Q (Maybe Name)
+lookupValueName' = \case
+--	Production -> lookupValueName
+	Production -> pure . Just . mkName
+	Debug -> pure . Just . mkName
+
+lookupTypeName' :: Debug -> String -> Q (Maybe Name)
+lookupTypeName' = \case
+	Production -> lookupTypeName
+	Debug -> pure . Just . mkName
+
+sample :: String
+sample = "DescriptorIndexingFeatures"
+
+newtype DeviceSize = DeviceSize { unDeviceSize :: Word64 } deriving Show
+newtype Size = Size Word64 deriving Show
+
+infixr 8 `arrT`
+
+arrT :: TypeQ -> TypeQ -> TypeQ
+t1 `arrT` t2 = arrowT `appT` t1 `appT` t2
+
+data FieldName = Atom String | List String Integer deriving Show
+
+member :: String -> String -> FieldName -> VarBangTypeQ
+member dtnm tp_ fn = varBangType (mkName nm) $ bangType noBang tp
+	where
+	pfx = appHead toLower dtnm
+	(nm, tp) = getNameType pfx tp_ fn
+
+appHead :: (a -> a) -> [a] -> [a]
+appHead f = \case [] -> []; x : xs -> f x : xs
+
+getNameType :: String -> String -> FieldName -> (String, TypeQ)
+getNameType pfx tp (Atom fn) = (pfx ++ capitalize fn, fst $ lookup' tp dict)
+getNameType pfx tp (List fn nb) = (pfx ++ capitalize fn,
+	conT ''LengthL `appT` litT (numTyLit nb) `appT` fst (lookup' tp dict))
+
+lookup' :: (Show a, Eq a) => a -> [(a, b)] -> b
+lookup' x d = case lookup x d of
+	Nothing -> error $ "no such key: " ++ show x
+	Just y -> y
+
+dict :: Dict
+dict = dictGenToDict dictGen
+
+dictGenToDict :: DictGen -> Dict
+dictGenToDict = map \(tp, tfr, _to) -> (tp, tfr)
+
+dict2 :: Dict2
+dict2 = dictGenToDict2 dictGen
+
+dictGenToDict2 :: DictGen -> Dict2
+dictGenToDict2 = map \(tp, _tfr, to) -> (tp, to)
+
+type Dict = [(String, (TypeQ, Name -> ExpQ))]
+type Dict2 = [(String, (Name -> PatQ, Name -> ExpQ))]
+type DictGen = [(String, (TypeQ, Name -> ExpQ), (Name -> PatQ, Name -> ExpQ))]
+
+dictGen :: [(String, (TypeQ, Name -> ExpQ), (Name -> PatQ, Name -> ExpQ))]
+dictGen = [
+	("uint32_t", (conT ''Word32, varE), (varP, varE)),
+	("int32_t", (conT ''Int32, varE), (varP, varE)),
+	("float", (conT ''Float, varE), (varP, varE)),
+	("VkBool32", (conT ''Bool, appE (varE 'bool32ToBool) . varE),
+		(varP, appE (varE 'boolToBool32) . varE)),
+	("size_t", (conT ''Size, appE (conE 'Size) . varE),
+		(conP 'Size . (: []) . varP, varE)),
+	("VkDeviceSize", (conT ''DeviceSize, appE (conE 'DeviceSize) . varE),
+		(conP 'DeviceSize . (: []) . varP, varE)),
+	("VkSampleCountFlags",
+		(conT ''Sample.CountFlags,
+			appE (conE 'Sample.CountFlagBits) . varE),
+		(conP 'Sample.CountFlagBits . (: []) . varP, varE)) ]
+
+capitalize :: String -> String
+capitalize "" = ""
+capitalize (c : cs) = toUpper c : cs
+
+noBang :: BangQ
+noBang = bang noSourceUnpackedness noSourceStrictness
+
+readName :: String -> FieldName
+readName ('A' : ' ' : nm) = Atom nm
+readName ('L' : ' ' : nmnb) = case words nmnb of
+	[nm, nb] -> List nm (read nb); _ -> error "bad"
+readName _ = error "bad"
+
+separate :: Eq a => a -> [a] -> ([a], [a])
+separate c str = case span (/= c) str of
+	(pre, _ : pst) -> (pre, pst)
+	_ -> error "no separater"
+
+toFieldExps :: Debug -> String -> [((FieldName, Name), (Name -> PatQ, Name -> ExpQ))] -> [Q (Name, Exp)]
+toFieldExps dbg dtnm = map . uncurry $ uncurry (toFieldExp1 dbg $ appHead toLower dtnm)
+
+toFieldExp1 :: Debug -> String -> FieldName -> Name -> (Name -> PatQ, Name -> ExpQ) -> Q (Name, Exp)
+toFieldExp1 dbg pfx (Atom nm) x (_, f) = do
+	n <- fromJust' "ukki" <$> lookupValueName' dbg ("C." ++ pfx ++ capitalize nm)
+	fieldExp n (f x)
+toFieldExp1 dbg pfx (List nm _) x (pf, f) = do
+	n <- fromJust' "sarusaru" <$> lookupValueName' dbg ("C." ++ pfx ++ capitalize nm)
+	y <- newName "y"
+	fieldExp n $ lam1E (pf y) (f y) .<$> (varE 'toList `appE` varE x)
+
+typeToFun :: String -> (Name -> ExpQ)
+typeToFun nm = case lookup nm dict of Just (_, f) -> f; Nothing -> error "bad"
+
+exFieldPats :: Debug -> String -> [(FieldName, Name)] -> [Q FieldPat]
+exFieldPats dbg dtnm = map $ uncurry (exFieldPat1 dbg $ appHead toLower dtnm)
+
+exFieldPat1 :: Debug -> String -> FieldName -> Name -> Q FieldPat
+exFieldPat1 dbg pfx fn x = do
+	let	nm = case fn of
+			Atom n -> n
+			List n _ -> n
+	n <- fromJust' ("C." ++ pfx ++ capitalize nm) <$> lookupValueName' dbg ("C." ++ pfx ++ capitalize nm)
+	fieldPat n (varP x)
+
+typeToPatExp :: String -> (Name -> PatQ, Name -> ExpQ)
+typeToPatExp = fromJust' "nande" . (`lookup` dict2)
+
+toFieldPats :: String -> [((FieldName, Name), (Name -> PatQ, a))] -> [Q FieldPat]
+toFieldPats dtnm = map . uncurry $ uncurry (toFieldPat1 $ appHead toLower dtnm)
+
+toFieldPat1 :: String -> FieldName -> Name -> ((Name -> PatQ), a) -> Q FieldPat
+toFieldPat1 pfx (Atom nm) x (f, _) = fieldPat (mkName $ pfx ++ capitalize nm) (f x)
+toFieldPat1 pfx (List nm _) x _ = fieldPat (mkName $ pfx ++ capitalize nm) (varP x)
+
+exFieldExps :: String -> String -> [((FieldName, Name), Name -> ExpQ)] -> [Q (Name, Exp)]
+exFieldExps sfx dtnm = map . uncurry $ uncurry (exFieldExp1 sfx $ appHead toLower dtnm)
+
+listToLengthL :: ListToLengthL n => [a] -> LengthL n a
+listToLengthL xs = case splitL xs of
+	Right (ln, []) -> ln
+	_ -> error "bad"
+
+exFieldExp1 :: String -> String -> FieldName -> Name -> (Name -> ExpQ) -> Q (Name, Exp)
+exFieldExp1 sfx pfx (Atom nm) x f = fieldExp (mkName $ pfx ++ sfx ++ capitalize nm) (f x)
+exFieldExp1 sfx pfx (List nm _) x f = do
+	y <- newName "y"
+	fieldExp (mkName $ pfx ++ sfx ++ capitalize nm)
+		. appE (varE 'listToLengthL) $ lam1E (varP y) (f y) .<$> varE x
+
+(.<$>) :: ExpQ -> ExpQ -> ExpQ
+f .<$> x = infixApp f (varE '(<$>)) x
+
+mkFromNoNextType :: String -> DecQ
+mkFromNoNextType nm = do
+	mn <- newName "mn"
+	sigD (mkName $ nm' ++ "FromNoNext") $
+		(conT ''TMaybe.M `appT` varT mn) `arrT`
+		conT (mkName $ nm ++ "NoNext") `arrT`
+		(conT (mkName nm) `appT` varT mn)
+	where nm' = appHead toLower nm
+
+mkFromNoNextBody :: String -> DictFieldName -> DecQ
+mkFromNoNextBody nm dct = do
+	mnxt <- newName "mnxt"
+	xs <- replicateM (length dct) $ newName "x"
+	funD (mkName $ nm' ++ "FromNoNext") . (: []) . ($ [])
+		. clause [varP mnxt, mkFromNoNextPat nm (drop 2 dct) xs] . normalB
+		. recConE (mkName nm) $
+			((mkName (nm' ++ "Next") ,) <$> varE mnxt) :
+			(<$> zip (dictFieldNameToNames $ drop 2 dct) xs) \(fnm, x) ->
+				(mkName (nm' ++ capitalize fnm) ,) <$> varE x
+	where nm' = appHead toLower nm
+
+mkFromNoNextPat :: String -> DictFieldName -> [Name] -> PatQ
+mkFromNoNextPat nm dct xs = recP (mkName $ nm ++ "NoNext")
+	$ (<$> zip (dictFieldNameToNames dct) xs) \(fnm, x) ->
+		fieldPat (mkName $ nm' ++ "NoNext" ++ capitalize fnm) (varP x)
+	where nm' = appHead toLower nm
+
+dictFieldNameToNames :: DictFieldName -> [String]
+dictFieldNameToNames = (dfntn <$>)
+	where dfntn (_, fn) = case fn of Atom n -> n; List n _ -> n
diff --git a/src/Gpu/Vulkan/Pipeline/ColorBlendAttachment/Middle.hs b/src/Gpu/Vulkan/Pipeline/ColorBlendAttachment/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Pipeline/ColorBlendAttachment/Middle.hs
@@ -0,0 +1,9 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Pipeline.ColorBlendAttachment.Middle (
+
+	-- * STATE
+
+	State(..) ) where
+
+import Gpu.Vulkan.Pipeline.ColorBlendAttachment.Middle.Internal
diff --git a/src/Gpu/Vulkan/Pipeline/ColorBlendAttachment/Middle/Internal.hs b/src/Gpu/Vulkan/Pipeline/ColorBlendAttachment/Middle/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Pipeline/ColorBlendAttachment/Middle/Internal.hs
@@ -0,0 +1,42 @@
+{-# LANGUAGE ViewPatterns #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Pipeline.ColorBlendAttachment.Middle.Internal (
+	State(..), stateToCore ) where
+
+import Gpu.Vulkan.Enum
+import Gpu.Vulkan.Base.Middle.Internal
+
+import qualified Gpu.Vulkan.ColorComponent.Enum as ColorComponent
+import qualified Gpu.Vulkan.Pipeline.ColorBlendAttachment.Core as C
+
+data State = State {
+	stateBlendEnable :: Bool,
+	stateSrcColorBlendFactor :: BlendFactor,
+	stateDstColorBlendFactor :: BlendFactor,
+	stateColorBlendOp :: BlendOp,
+	stateSrcAlphaBlendFactor :: BlendFactor,
+	stateDstAlphaBlendFactor :: BlendFactor,
+	stateAlphaBlendOp :: BlendOp,
+	stateColorWriteMask :: ColorComponent.Flags }
+	deriving Show
+
+stateToCore :: State -> C.State
+stateToCore State {
+	stateBlendEnable = boolToBool32 -> be,
+	stateSrcColorBlendFactor = BlendFactor scbf,
+	stateDstColorBlendFactor = BlendFactor dcbf,
+	stateColorBlendOp = BlendOp cbo,
+	stateSrcAlphaBlendFactor = BlendFactor sabf,
+	stateDstAlphaBlendFactor = BlendFactor dabf,
+	stateAlphaBlendOp = BlendOp abo,
+	stateColorWriteMask = ColorComponent.FlagBits cwm
+	} = C.State {
+		C.stateBlendEnable = be,
+		C.stateSrcColorBlendFactor = scbf,
+		C.stateDstColorBlendFactor = dcbf,
+		C.stateColorBlendOp = cbo,
+		C.stateSrcAlphaBlendFactor = sabf,
+		C.stateDstAlphaBlendFactor = dabf,
+		C.stateAlphaBlendOp = abo,
+		C.stateColorWriteMask = cwm }
diff --git a/src/Gpu/Vulkan/Pipeline/ColorBlendState/Middle.hs b/src/Gpu/Vulkan/Pipeline/ColorBlendState/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Pipeline/ColorBlendState/Middle.hs
@@ -0,0 +1,9 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Pipeline.ColorBlendState.Middle (
+
+	-- * CREATE INFO
+
+	CreateInfo(..), CreateFlags ) where
+
+import Gpu.Vulkan.Pipeline.ColorBlendState.Middle.Internal
diff --git a/src/Gpu/Vulkan/Pipeline/ColorBlendState/Middle/Internal.hsc b/src/Gpu/Vulkan/Pipeline/ColorBlendState/Middle/Internal.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Pipeline/ColorBlendState/Middle/Internal.hsc
@@ -0,0 +1,69 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE MonoLocalBinds #-}
+{-# LANGUAGE FlexibleContexts, UndecidableInstances #-}
+{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
+{-# LANGUAGE StandaloneDeriving, GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Pipeline.ColorBlendState.Middle.Internal (
+	CreateInfo(..), CreateFlags, createInfoToCore
+	) where
+
+import Foreign.Ptr
+import Foreign.Marshal.Array
+import Foreign.Storable
+import Foreign.Storable.PeekPoke
+import Foreign.C.Enum
+import Control.Arrow
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Data.Bits
+import Data.Word
+import Data.Color
+
+import Gpu.Vulkan.Enum
+import Gpu.Vulkan.Base.Middle.Internal
+
+import qualified Gpu.Vulkan.Pipeline.ColorBlendAttachment.Middle.Internal
+	as ColorBlendAttachment
+import qualified Gpu.Vulkan.Pipeline.ColorBlendState.Core as C
+
+#include <vulkan/vulkan.h>
+
+enum "CreateFlags" ''#{type VkPipelineColorBlendStateCreateFlags}
+	[''Show, ''Storable, ''Eq, ''Bits] [("CreateFlagsZero", 0)]
+
+data CreateInfo mn = CreateInfo {
+	createInfoNext :: TMaybe.M mn,
+	createInfoFlags :: CreateFlags,
+	createInfoLogicOpEnable :: Bool,
+	createInfoLogicOp :: LogicOp,
+	createInfoAttachments :: [ColorBlendAttachment.State],
+	createInfoBlendConstants :: Rgba Float }
+
+deriving instance Show (TMaybe.M mn) => Show (CreateInfo mn)
+
+createInfoToCore :: WithPoked (TMaybe.M mn) =>
+	CreateInfo mn -> (Ptr C.CreateInfo -> IO a) -> IO ()
+createInfoToCore CreateInfo {
+	createInfoNext = mnxt,
+	createInfoFlags = CreateFlags flgs,
+	createInfoLogicOpEnable = boolToBool32 -> loe,
+	createInfoLogicOp = LogicOp lo,
+	createInfoAttachments =
+		length &&& (ColorBlendAttachment.stateToCore <$>) -> (ac, as),
+	createInfoBlendConstants = RgbaDouble r g b a } f =
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+	allocaArray ac \pas ->
+	pokeArray pas as >>
+	let ci = C.CreateInfo {
+			C.createInfoSType = (),
+			C.createInfoPNext = pnxt',
+			C.createInfoFlags = flgs,
+			C.createInfoLogicOpEnable = loe,
+			C.createInfoLogicOp = lo,
+			C.createInfoAttachmentCount = fromIntegral ac,
+			C.createInfoPAttachments = pas,
+			C.createInfoBlendConstants = [r, g, b, a] } in
+	withPoked ci f
diff --git a/src/Gpu/Vulkan/Pipeline/Compute/Middle.hs b/src/Gpu/Vulkan/Pipeline/Compute/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Pipeline/Compute/Middle.hs
@@ -0,0 +1,9 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Pipeline.Compute.Middle (
+
+	-- * CREATE AND DESTROY
+
+	createCs, destroy, C, CreateInfo(..), CreateInfoListToCore ) where
+
+import Gpu.Vulkan.Pipeline.Compute.Middle.Internal
diff --git a/src/Gpu/Vulkan/Pipeline/Compute/Middle/Internal.hs b/src/Gpu/Vulkan/Pipeline/Compute/Middle/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Pipeline/Compute/Middle/Internal.hs
@@ -0,0 +1,114 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE ScopedTypeVariables, TypeApplications #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE FlexibleContexts, FlexibleInstances, UndecidableInstances #-}
+{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Pipeline.Compute.Middle.Internal (
+	C(..),
+
+	createCs, destroy, CreateInfo(..), CreateInfoListToCore ) where
+
+import Prelude hiding (length)
+
+import Foreign.Ptr
+import Foreign.Marshal.Array
+import Foreign.Storable.PeekPoke
+import Foreign.Storable.HeteroList
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Data.TypeLevel.ParMaybe qualified as TPMaybe
+import Data.TypeLevel.Tuple.Uncurry
+import Data.TypeLevel.List
+import qualified Data.HeteroParList as HeteroParList
+import Data.HeteroParList (pattern (:**))
+import Data.Maybe
+import Data.Int
+
+import Language.SpirV.ShaderKind
+
+import Gpu.Vulkan.Exception.Middle.Internal
+import Gpu.Vulkan.Exception.Enum
+
+import Gpu.Vulkan.AllocationCallbacks.Middle.Internal
+	qualified as AllocationCallbacks
+import qualified Gpu.Vulkan.Device.Middle.Internal as Device
+import qualified Gpu.Vulkan.Pipeline.Enum as Pipeline
+import qualified Gpu.Vulkan.Pipeline.Core as Pipeline.C
+import qualified Gpu.Vulkan.PipelineCache.Middle.Internal as Cache
+import qualified Gpu.Vulkan.Pipeline.Compute.Core as C
+import qualified Gpu.Vulkan.Pipeline.ShaderStage.Middle.Internal as ShaderStage
+import qualified Gpu.Vulkan.PipelineLayout.Middle.Internal as Pipeline.Layout
+
+data CreateInfo mn ss sivs = CreateInfo {
+	createInfoNext :: TMaybe.M mn,
+	createInfoFlags :: Pipeline.CreateFlags,
+	createInfoStage :: ShaderStage.CreateInfo ss 'GlslComputeShader sivs,
+	createInfoLayout :: Pipeline.Layout.P,
+	createInfoBasePipelineHandle :: Maybe C,
+	createInfoBasePipelineIndex :: Maybe Int32 }
+
+deriving instance (
+	Show (TMaybe.M mn), Show (ShaderStage.CreateInfo ss 'GlslComputeShader sivs) ) =>
+	Show (CreateInfo mn ss sivs)
+
+createInfoToCore ::
+	(WithPoked (TMaybe.M mn), WithPoked (TMaybe.M n1), PokableList vs) =>
+	CreateInfo mn n1 vs -> (C.CreateInfo -> IO r) -> IO ()
+createInfoToCore CreateInfo {
+	createInfoNext = mnxt,
+	createInfoFlags = Pipeline.CreateFlagBits flgs,
+	createInfoStage = stg,
+	createInfoLayout = Pipeline.Layout.P lyt,
+	createInfoBasePipelineHandle = maybe NullPtr (\(C b) -> b) -> bph,
+	createInfoBasePipelineIndex = fromMaybe (- 1) -> idx } f =
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+	ShaderStage.createInfoToCore stg \stg' ->
+	f C.CreateInfo {
+		C.createInfoSType = (),
+		C.createInfoPNext = pnxt',
+		C.createInfoFlags = flgs,
+		C.createInfoStage = stg',
+		C.createInfoLayout = lyt,
+		C.createInfoBasePipelineHandle = bph,
+		C.createInfoBasePipelineIndex = idx }
+
+class Length cias => CreateInfoListToCore cias where
+	createInfoListToCore ::
+		HeteroParList.PL (U3 CreateInfo) cias ->
+		([C.CreateInfo] -> IO r) -> IO ()
+
+instance CreateInfoListToCore '[] where
+	createInfoListToCore HeteroParList.Nil = (() <$) . ($ [])
+
+instance (
+	WithPoked (TMaybe.M mn), WithPoked (TMaybe.M ss), PokableList sivs,
+	CreateInfoListToCore cias ) =>
+	CreateInfoListToCore ('(mn, ss, sivs) ': cias) where
+	createInfoListToCore (U3 ci :** cis) f =
+		createInfoToCore ci \cci ->
+		createInfoListToCore cis \ccis -> f $ cci : ccis
+
+newtype C = C Pipeline.C.P deriving Show
+
+createCs :: forall cias mc . CreateInfoListToCore cias =>
+	Device.D -> Maybe Cache.P -> HeteroParList.PL (U3 CreateInfo) cias ->
+	TPMaybe.M AllocationCallbacks.A mc -> IO [C]
+createCs (Device.D dvc) (maybe NullPtr (\(Cache.P c) -> c) -> cch) cis mac =
+	(C <$>) <$> allocaArray ln \pps -> do
+		createInfoListToCore cis \cis' ->
+			allocaArray ln \pcis ->
+			pokeArray pcis cis' >>
+			AllocationCallbacks.mToCore mac \pac ->
+				throwUnlessSuccess . Result =<< C.createCs
+					dvc cch (fromIntegral ln) pcis pac pps
+		peekArray ln pps
+	where ln = length @_ @cias
+
+destroy :: Device.D -> C -> TPMaybe.M AllocationCallbacks.A md -> IO ()
+destroy (Device.D dvc) (C p) mac =
+	AllocationCallbacks.mToCore mac $ Pipeline.C.destroy dvc p
diff --git a/src/Gpu/Vulkan/Pipeline/DepthStencilState/Middle.hs b/src/Gpu/Vulkan/Pipeline/DepthStencilState/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Pipeline/DepthStencilState/Middle.hs
@@ -0,0 +1,9 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Pipeline.DepthStencilState.Middle (
+
+	-- * CREATE INFO
+
+	CreateInfo(..), CreateFlags(..) ) where
+
+import Gpu.Vulkan.Pipeline.DepthStencilState.Middle.Internal
diff --git a/src/Gpu/Vulkan/Pipeline/DepthStencilState/Middle/Internal.hsc b/src/Gpu/Vulkan/Pipeline/DepthStencilState/Middle/Internal.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Pipeline/DepthStencilState/Middle/Internal.hsc
@@ -0,0 +1,76 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE MonoLocalBinds #-}
+{-# LANGUAGE FlexibleContexts, UndecidableInstances #-}
+{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
+{-# LANGUAGE StandaloneDeriving, GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Pipeline.DepthStencilState.Middle.Internal (
+	CreateInfo(..), CreateFlags(..), createInfoToCore
+	) where
+
+import Foreign.Ptr
+import Foreign.Storable
+import Foreign.Storable.PeekPoke
+import Foreign.C.Enum
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Data.Bits
+import Data.Word
+
+import Gpu.Vulkan.Enum
+import Gpu.Vulkan.Middle.Internal
+import Gpu.Vulkan.Base.Middle.Internal
+
+import qualified Gpu.Vulkan.Pipeline.DepthStencilState.Core as C
+
+#include <vulkan/vulkan.h>
+
+enum "CreateFlags" ''#{type VkPipelineDepthStencilStateCreateFlags}
+	[''Show, ''Storable, ''Eq, ''Bits] [("CreateFlagsZero", 0)]
+
+data CreateInfo mn = CreateInfo {
+	createInfoNext :: TMaybe.M mn,
+	createInfoFlags :: CreateFlags,
+	createInfoDepthTestEnable :: Bool,
+	createInfoDepthWriteEnable :: Bool,
+	createInfoDepthCompareOp :: CompareOp,
+	createInfoDepthBoundsTestEnable :: Bool,
+	createInfoStencilTestEnable :: Bool,
+	createInfoFront :: StencilOpState,
+	createInfoBack :: StencilOpState,
+	createInfoMinDepthBounds :: Float,
+	createInfoMaxDepthBounds :: Float }
+
+deriving instance Show (TMaybe.M mn) => Show (CreateInfo mn)
+
+createInfoToCore :: WithPoked (TMaybe.M mn) =>
+	CreateInfo mn -> (Ptr C.CreateInfo -> IO a) -> IO ()
+createInfoToCore CreateInfo {
+	createInfoNext = mnxt,
+	createInfoFlags = CreateFlags flgs,
+	createInfoDepthTestEnable = boolToBool32 -> dte,
+	createInfoDepthWriteEnable = boolToBool32 -> dwe,
+	createInfoDepthCompareOp = CompareOp dco,
+	createInfoDepthBoundsTestEnable = boolToBool32 -> bte,
+	createInfoStencilTestEnable = boolToBool32 -> ste,
+	createInfoFront = stencilOpStateToCore -> fr,
+	createInfoBack = stencilOpStateToCore -> bk,
+	createInfoMinDepthBounds = mndb,
+	createInfoMaxDepthBounds = mxdb } f =
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+	let	ci = C.CreateInfo {
+			C.createInfoSType = (),
+			C.createInfoPNext = pnxt',
+			C.createInfoFlags = flgs,
+			C.createInfoDepthTestEnable = dte,
+			C.createInfoDepthWriteEnable = dwe,
+			C.createInfoDepthCompareOp = dco,
+			C.createInfoDepthBoundsTestEnable = bte,
+			C.createInfoStencilTestEnable = ste,
+			C.createInfoFront = fr,
+			C.createInfoBack = bk,
+			C.createInfoMinDepthBounds = mndb,
+			C.createInfoMaxDepthBounds = mxdb } in
+	withPoked ci f
diff --git a/src/Gpu/Vulkan/Pipeline/DynamicState/Middle.hs b/src/Gpu/Vulkan/Pipeline/DynamicState/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Pipeline/DynamicState/Middle.hs
@@ -0,0 +1,9 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Pipeline.DynamicState.Middle (
+
+	-- * CREATE INFO
+
+	CreateInfo(..), CreateFlags ) where
+
+import Gpu.Vulkan.Pipeline.DynamicState.Middle.Internal
diff --git a/src/Gpu/Vulkan/Pipeline/DynamicState/Middle/Internal.hsc b/src/Gpu/Vulkan/Pipeline/DynamicState/Middle/Internal.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Pipeline/DynamicState/Middle/Internal.hsc
@@ -0,0 +1,56 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE MonoLocalBinds #-}
+{-# LANGUAGE FlexibleContexts, UndecidableInstances #-}
+{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Pipeline.DynamicState.Middle.Internal (
+	CreateInfo(..), CreateFlags(..), createInfoToCore
+	) where
+
+import Foreign.Ptr
+import Foreign.Marshal.Array
+import Foreign.Storable
+import Foreign.Storable.PeekPoke
+import Foreign.C.Enum
+import Control.Arrow
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Data.Word
+
+import Gpu.Vulkan.Enum
+
+import qualified Gpu.Vulkan.Pipeline.DynamicState.Core as C
+
+#include <vulkan/vulkan.h>
+
+enum "CreateFlags" ''#{type VkPipelineDynamicStateCreateFlags}
+	[''Show, ''Storable] [("CreateFlagsZero", 0)]
+
+data CreateInfo mn = CreateInfo {
+	createInfoNext :: TMaybe.M mn,
+	createInfoFlags :: CreateFlags,
+	createInfoDynamicStates :: [DynamicState] }
+
+deriving instance Show (TMaybe.M mn) => Show (CreateInfo mn)
+
+createInfoToCore :: WithPoked (TMaybe.M mn) =>
+	CreateInfo mn -> (Ptr C.CreateInfo -> IO a) -> IO ()
+createInfoToCore CreateInfo {
+	createInfoNext = mnxt,
+	createInfoFlags = CreateFlags flgs,
+	createInfoDynamicStates = (
+		length &&&
+		((\(DynamicState ds) -> ds) <$>) ) -> (dsc, dss) } f =
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+	allocaArray dsc \pdss ->
+	pokeArray pdss dss >>
+	let	ci = C.CreateInfo {
+			C.createInfoSType = (),
+			C.createInfoPNext = pnxt',
+			C.createInfoFlags = flgs,
+			C.createInfoDynamicStateCount = fromIntegral dsc,
+			C.createInfoPDynamicStates = pdss } in
+	withPoked ci f
diff --git a/src/Gpu/Vulkan/Pipeline/Enum.hsc b/src/Gpu/Vulkan/Pipeline/Enum.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Pipeline/Enum.hsc
@@ -0,0 +1,187 @@
+-- This file is automatically generated by the tools/makeEnum.hs
+--	% stack runghc --cwd tools/ makeEnum
+
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-missing-export-lists -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Pipeline.Enum where
+
+import Foreign.Storable
+import Foreign.C.Enum
+import Data.Bits
+import Data.Word
+import Data.Default
+
+#include <vulkan/vulkan.h>
+
+enum "BindPoint" ''#{type VkPipelineBindPoint}
+		[''Show, ''Storable] [
+	("BindPointGraphics", #{const VK_PIPELINE_BIND_POINT_GRAPHICS}),
+	("BindPointCompute", #{const VK_PIPELINE_BIND_POINT_COMPUTE}),
+	("BindPointRayTracingKhr",
+		#{const VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR}),
+	("BindPointSubpassShadingHuawei",
+		#{const VK_PIPELINE_BIND_POINT_SUBPASS_SHADING_HUAWEI}),
+	("BindPointRayTracingNv",
+		#{const VK_PIPELINE_BIND_POINT_RAY_TRACING_NV}),
+	("BindPointMaxEnum", #{const VK_PIPELINE_BIND_POINT_MAX_ENUM}) ]
+
+enum "StageFlagBits" ''#{type VkPipelineStageFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("StageFlagsZero", 0),
+	("StageTopOfPipeBit",
+		#{const VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT}),
+	("StageDrawIndirectBit",
+		#{const VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT}),
+	("StageVertexInputBit",
+		#{const VK_PIPELINE_STAGE_VERTEX_INPUT_BIT}),
+	("StageVertexShaderBit",
+		#{const VK_PIPELINE_STAGE_VERTEX_SHADER_BIT}),
+	("StageTessellationControlShaderBit",
+		#{const VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT}),
+	("StageTessellationEvaluationShaderBit",
+		#{const VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT}),
+	("StageGeometryShaderBit",
+		#{const VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT}),
+	("StageFragmentShaderBit",
+		#{const VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT}),
+	("StageEarlyFragmentTestsBit",
+		#{const VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT}),
+	("StageLateFragmentTestsBit",
+		#{const VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT}),
+	("StageColorAttachmentOutputBit",
+		#{const VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}),
+	("StageComputeShaderBit",
+		#{const VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT}),
+	("StageTransferBit", #{const VK_PIPELINE_STAGE_TRANSFER_BIT}),
+	("StageBottomOfPipeBit",
+		#{const VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT}),
+	("StageHostBit", #{const VK_PIPELINE_STAGE_HOST_BIT}),
+	("StageAllGraphicsBit",
+		#{const VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT}),
+	("StageAllCommandsBit",
+		#{const VK_PIPELINE_STAGE_ALL_COMMANDS_BIT}),
+	("StageNone", #{const VK_PIPELINE_STAGE_NONE}),
+	("StageTransformFeedbackBitExt",
+		#{const VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT}),
+	("StageConditionalRenderingBitExt",
+		#{const VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT}),
+	("StageAccelerationStructureBuildBitKhr",
+		#{const VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR}),
+	("StageRayTracingShaderBitKhr",
+		#{const VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR}),
+	("StageFragmentDensityProcessBitExt",
+		#{const VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT}),
+	("StageFragmentShadingRateAttachmentBitKhr",
+		#{const VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR}),
+	("StageCommandPreprocessBitNv",
+		#{const VK_PIPELINE_STAGE_COMMAND_PREPROCESS_BIT_NV}),
+	("StageTaskShaderBitExt",
+		#{const VK_PIPELINE_STAGE_TASK_SHADER_BIT_EXT}),
+	("StageMeshShaderBitExt",
+		#{const VK_PIPELINE_STAGE_MESH_SHADER_BIT_EXT}),
+	("StageShadingRateImageBitNv",
+		#{const VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV}),
+	("StageRayTracingShaderBitNv",
+		#{const VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_NV}),
+	("StageAccelerationStructureBuildBitNv",
+		#{const VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_NV}),
+	("StageTaskShaderBitNv",
+		#{const VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV}),
+	("StageMeshShaderBitNv",
+		#{const VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV}),
+	("StageNoneKhr", #{const VK_PIPELINE_STAGE_NONE_KHR}),
+	("StageFlagBitsMaxEnum",
+		#{const VK_PIPELINE_STAGE_FLAG_BITS_MAX_ENUM}) ]
+
+instance Default StageFlagBits where
+	def = StageFlagsZero
+
+enum "CreateFlagBits" ''#{type VkPipelineCreateFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("CreateFlagsZero", 0),
+	("CreateDisableOptimizationBit",
+		#{const VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT}),
+	("CreateAllowDerivativesBit",
+		#{const VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT}),
+	("CreateDerivativeBit",
+		#{const VK_PIPELINE_CREATE_DERIVATIVE_BIT}),
+	("CreateViewIndexFromDeviceIndexBit",
+		#{const VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT}),
+	("CreateDispatchBaseBit",
+		#{const VK_PIPELINE_CREATE_DISPATCH_BASE_BIT}),
+	("CreateFailOnPipelineCompileRequiredBit",
+		#{const VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT}),
+	("CreateEarlyReturnOnFailureBit",
+		#{const VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT}),
+	("CreateRenderingFragmentShadingRateAttachmentBitKhr",
+		#{const VK_PIPELINE_CREATE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR}),
+	("CreateRenderingFragmentDensityMapAttachmentBitExt",
+		#{const VK_PIPELINE_CREATE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT}),
+	("CreateRayTracingNoNullAnyHitShadersBitKhr",
+		#{const VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_ANY_HIT_SHADERS_BIT_KHR}),
+	("CreateRayTracingNoNullClosestHitShadersBitKhr",
+		#{const VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_CLOSEST_HIT_SHADERS_BIT_KHR}),
+	("CreateRayTracingNoNullMissShadersBitKhr",
+		#{const VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_MISS_SHADERS_BIT_KHR}),
+	("CreateRayTracingNoNullIntersectionShadersBitKhr",
+		#{const VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_INTERSECTION_SHADERS_BIT_KHR}),
+	("CreateRayTracingSkipTrianglesBitKhr",
+		#{const VK_PIPELINE_CREATE_RAY_TRACING_SKIP_TRIANGLES_BIT_KHR}),
+	("CreateRayTracingSkipAabbsBitKhr",
+		#{const VK_PIPELINE_CREATE_RAY_TRACING_SKIP_AABBS_BIT_KHR}),
+	("CreateRayTracingShaderGroupHandleCaptureReplayBitKhr",
+		#{const VK_PIPELINE_CREATE_RAY_TRACING_SHADER_GROUP_HANDLE_CAPTURE_REPLAY_BIT_KHR}),
+	("CreateDeferCompileBitNv",
+		#{const VK_PIPELINE_CREATE_DEFER_COMPILE_BIT_NV}),
+	("CreateCaptureStatisticsBitKhr",
+		#{const VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR}),
+	("CreateCaptureInternalRepresentationsBitKhr",
+		#{const VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR}),
+	("CreateIndirectBindableBitNv",
+		#{const VK_PIPELINE_CREATE_INDIRECT_BINDABLE_BIT_NV}),
+	("CreateLibraryBitKhr",
+		#{const VK_PIPELINE_CREATE_LIBRARY_BIT_KHR}),
+	("CreateDescriptorBufferBitExt",
+		#{const VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT}),
+	("CreateRetainLinkTimeOptimizationInfoBitExt",
+		#{const VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT}),
+	("CreateLinkTimeOptimizationBitExt",
+		#{const VK_PIPELINE_CREATE_LINK_TIME_OPTIMIZATION_BIT_EXT}),
+	("CreateRayTracingAllowMotionBitNv",
+		#{const VK_PIPELINE_CREATE_RAY_TRACING_ALLOW_MOTION_BIT_NV}),
+	("CreateColorAttachmentFeedbackLoopBitExt",
+		#{const VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT}),
+	("CreateDepthStencilAttachmentFeedbackLoopBitExt",
+		#{const VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT}),
+	("CreateRayTracingOpacityMicromapBitExt",
+		#{const VK_PIPELINE_CREATE_RAY_TRACING_OPACITY_MICROMAP_BIT_EXT}),
+	("CreateNoProtectedAccessBitExt",
+		#{const VK_PIPELINE_CREATE_NO_PROTECTED_ACCESS_BIT_EXT}),
+	("CreateProtectedAccessOnlyBitExt",
+		#{const VK_PIPELINE_CREATE_PROTECTED_ACCESS_ONLY_BIT_EXT}),
+	("CreateDispatchBase",
+		#{const VK_PIPELINE_CREATE_DISPATCH_BASE}),
+	("RasterizationStateCreateFragmentShadingRateAttachmentBitKhr",
+		#{const VK_PIPELINE_RASTERIZATION_STATE_CREATE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR}),
+	("RasterizationStateCreateFragmentDensityMapAttachmentBitExt",
+		#{const VK_PIPELINE_RASTERIZATION_STATE_CREATE_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT}),
+	("CreateViewIndexFromDeviceIndexBitKhr",
+		#{const VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT_KHR}),
+	("CreateDispatchBaseKhr",
+		#{const VK_PIPELINE_CREATE_DISPATCH_BASE_KHR}),
+	("CreateFailOnPipelineCompileRequiredBitExt",
+		#{const VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT}),
+	("CreateEarlyReturnOnFailureBitExt",
+		#{const VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT_EXT}),
+	("CreateFlagBitsMaxEnum",
+		#{const VK_PIPELINE_CREATE_FLAG_BITS_MAX_ENUM}) ]
+
+instance Default CreateFlagBits where
+	def = CreateFlagsZero
+
+type StageFlags = StageFlagBits
+type CreateFlags = CreateFlagBits
diff --git a/src/Gpu/Vulkan/Pipeline/Graphics/Middle.hs b/src/Gpu/Vulkan/Pipeline/Graphics/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Pipeline/Graphics/Middle.hs
@@ -0,0 +1,12 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Pipeline.Graphics.Middle (
+
+	-- * CREATE AND DESTROY
+
+	createGs, recreateGs, destroyGs, G, gNull,
+	CreateInfo(..), CreateInfoListToCore
+
+	) where
+
+import Gpu.Vulkan.Pipeline.Graphics.Middle.Internal
diff --git a/src/Gpu/Vulkan/Pipeline/Graphics/Middle/Internal.hs b/src/Gpu/Vulkan/Pipeline/Graphics/Middle/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Pipeline/Graphics/Middle/Internal.hs
@@ -0,0 +1,251 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE BlockArguments, LambdaCase #-}
+{-# LANGUAGE ScopedTypeVariables, TypeApplications #-}
+{-# LANGUAGE GADTs, TypeFamilies #-}
+{-# LANGUAGE DataKinds, PolyKinds #-}
+{-# LANGUAGE KindSignatures, TypeOperators #-}
+{-# LANGUAGE MultiParamTypeClasses, AllowAmbiguousTypes #-}
+{-# LANGUAGE FlexibleContexts, FlexibleInstances #-}
+{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Pipeline.Graphics.Middle.Internal (
+	CreateInfo(..), CreateInfoListToCore,
+	createGs, recreateGs,
+
+	destroyGs,
+
+	G, gNull, gToCore,
+	) where
+
+import Prelude hiding (length)
+import Prelude qualified as P
+
+import Foreign.Ptr
+import Foreign.Marshal.Array
+import Foreign.Storable.PeekPoke
+import Control.Monad
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Data.TypeLevel.ParMaybe qualified as TPMaybe
+import Data.TypeLevel.Tuple.Uncurry
+import Data.TypeLevel.List
+import Data.IORef
+import qualified Data.HeteroParList as HeteroParList
+import Data.HeteroParList (pattern (:**))
+import Data.Word
+import Data.Int
+
+import Gpu.Vulkan.Base.Middle.Internal
+import Gpu.Vulkan.Exception.Middle.Internal
+import Gpu.Vulkan.Exception.Enum
+import Gpu.Vulkan.Pipeline.Enum
+
+import qualified Gpu.Vulkan.Pipeline.Core as Pipeline.C
+import qualified Gpu.Vulkan.Pipeline.ShaderStage.Middle.Internal as ShaderStage
+import qualified Gpu.Vulkan.Pipeline.VertexInputState.Middle.Internal as VertexInputState.M
+import Gpu.Vulkan.Pipeline.InputAssemblyState.Middle.Internal
+	qualified as InputAssemblyState
+import Gpu.Vulkan.Pipeline.TessellationState.Middle.Internal
+	qualified as TessellationState
+import qualified Gpu.Vulkan.Pipeline.ViewportState.Middle.Internal as ViewportState
+import qualified Gpu.Vulkan.Pipeline.RasterizationState.Middle.Internal as RasterizationState
+import qualified Gpu.Vulkan.Pipeline.MultisampleState.Middle.Internal as MultisampleState
+import qualified Gpu.Vulkan.Pipeline.DepthStencilState.Middle.Internal
+	as DepthStencilState
+import qualified Gpu.Vulkan.Pipeline.ColorBlendState.Middle.Internal
+	as ColorBlendState
+import qualified Gpu.Vulkan.Pipeline.DynamicState.Middle.Internal
+	as DynamicState
+import qualified Gpu.Vulkan.PipelineLayout.Middle.Internal as Layout
+import qualified Gpu.Vulkan.RenderPass.Middle.Internal as RenderPass
+import qualified Gpu.Vulkan.Pipeline.Graphics.Core as C
+
+import Gpu.Vulkan.AllocationCallbacks.Middle.Internal
+	qualified as AllocationCallbacks
+import qualified Gpu.Vulkan.Device.Middle.Internal as Device
+import qualified Gpu.Vulkan.PipelineCache.Middle.Internal as Cache
+
+data CreateInfo mn stg vis ias ts vs rs ms dss cbs ds = CreateInfo {
+	createInfoNext :: TMaybe.M mn,
+	createInfoFlags :: CreateFlags,
+	createInfoStages :: HeteroParList.PL (U3 ShaderStage.CreateInfo) stg,
+	createInfoVertexInputState :: Maybe (VertexInputState.M.CreateInfo vis),
+	createInfoInputAssemblyState ::
+		Maybe (InputAssemblyState.CreateInfo ias),
+	createInfoTessellationState :: Maybe (TessellationState.CreateInfo ts),
+	createInfoViewportState :: Maybe (ViewportState.CreateInfo vs),
+	createInfoRasterizationState ::
+		Maybe (RasterizationState.CreateInfo rs),
+	createInfoMultisampleState :: Maybe (MultisampleState.CreateInfo ms),
+	createInfoDepthStencilState :: Maybe (DepthStencilState.CreateInfo dss),
+	createInfoColorBlendState :: Maybe (ColorBlendState.CreateInfo cbs),
+	createInfoDynamicState :: Maybe (DynamicState.CreateInfo ds),
+	createInfoLayout :: Layout.P,
+	createInfoRenderPass :: RenderPass.R,
+	createInfoSubpass :: Word32,
+	createInfoBasePipelineHandle :: G,
+	createInfoBasePipelineIndex :: Int32 }
+
+createInfoToCore :: (
+	WithPoked (TMaybe.M mn),
+	ShaderStage.CreateInfoListToCore stg,
+	WithPoked (TMaybe.M n2), WithPoked (TMaybe.M n3),
+	WithPoked (TMaybe.M n4), WithPoked (TMaybe.M n5),
+	WithPoked (TMaybe.M n6), WithPoked (TMaybe.M n7),
+	WithPoked (TMaybe.M n8), WithPoked (TMaybe.M n9),
+	WithPoked (TMaybe.M n10) ) =>
+	CreateInfo mn stg n2 n3 n4 n5 n6 n7 n8 n9 n10 ->
+	(C.CreateInfo -> IO a) -> IO ()
+createInfoToCore CreateInfo {
+	createInfoNext = mnxt,
+	createInfoFlags = CreateFlagBits flgs,
+	createInfoStages = ss,
+	createInfoVertexInputState = mvist,
+	createInfoInputAssemblyState = miast,
+	createInfoTessellationState = mtst,
+	createInfoViewportState = mvst,
+	createInfoRasterizationState = mrst,
+	createInfoMultisampleState = mmst,
+	createInfoDepthStencilState = mdsst,
+	createInfoColorBlendState = mcbst,
+	createInfoDynamicState = mdst,
+	createInfoLayout = Layout.P lyt,
+	createInfoRenderPass = RenderPass.R rp,
+	createInfoSubpass = sp,
+	createInfoBasePipelineHandle = bph,
+	createInfoBasePipelineIndex = bpi } f =
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+	ShaderStage.createInfoListToCore ss \css ->
+	let sc = P.length css in
+	allocaArray sc \pss ->
+	pokeArray pss css >>
+	maybeToCore VertexInputState.M.createInfoToCore mvist \pvist ->
+	maybeToCore InputAssemblyState.createInfoToCore miast \piast ->
+	maybeToCore TessellationState.createInfoToCore mtst \ptst ->
+	maybeToCore ViewportState.createInfoToCore mvst \pvst ->
+	maybeToCore RasterizationState.createInfoToCore mrst \prst ->
+	maybeToCore MultisampleState.createInfoToCore mmst \pmst ->
+	maybeToCore DepthStencilState.createInfoToCore mdsst \pdsst ->
+	maybeToCore ColorBlendState.createInfoToCore mcbst \pcbst ->
+	maybeToCore' DynamicState.createInfoToCore mdst \pdst ->
+	gToCore bph >>= \bph' ->
+	f C.CreateInfo {
+		C.createInfoSType = (),
+		C.createInfoPNext = pnxt',
+		C.createInfoFlags = flgs,
+		C.createInfoStageCount = fromIntegral sc,
+		C.createInfoPStages = pss,
+		C.createInfoPVertexInputState = pvist,
+		C.createInfoPInputAssemblyState = piast,
+		C.createInfoPTessellationState = ptst,
+		C.createInfoPViewportState = pvst,
+		C.createInfoPRasterizationState = prst,
+		C.createInfoPMultisampleState = pmst,
+		C.createInfoPDepthStencilState = pdsst,
+		C.createInfoPColorBlendState = pcbst,
+		C.createInfoPDynamicState = pdst,
+		C.createInfoLayout = lyt,
+		C.createInfoRenderPass = rp,
+		C.createInfoSubpass = sp,
+		C.createInfoBasePipelineHandle = bph',
+		C.createInfoBasePipelineIndex = bpi }
+
+maybeToCore :: (a -> (Ptr b -> IO r) -> IO r) -> Maybe a -> (Ptr b -> IO r) -> IO r
+maybeToCore f mx g = case mx of Nothing -> g NullPtr; Just x -> f x g
+
+maybeToCore' :: (a -> (Ptr b -> IO r) -> IO ()) -> Maybe a -> (Ptr b -> IO r) -> IO ()
+maybeToCore' f mx g = case mx of Nothing -> () <$ g NullPtr; Just x -> f x g
+
+class Length cias => CreateInfoListToCore cias where
+	createInfoListToCore ::
+		HeteroParList.PL (U11 CreateInfo) cias ->
+		([C.CreateInfo] -> IO r) -> IO ()
+
+instance CreateInfoListToCore '[] where createInfoListToCore HeteroParList.Nil f = () <$ f []
+
+instance (
+	WithPoked (TMaybe.M mn), ShaderStage.CreateInfoListToCore stg,
+	WithPoked (TMaybe.M vis), WithPoked (TMaybe.M ias),
+	WithPoked (TMaybe.M ts), WithPoked (TMaybe.M vs),
+	WithPoked (TMaybe.M rs), WithPoked (TMaybe.M ms),
+	WithPoked (TMaybe.M dss), WithPoked (TMaybe.M cbs),
+	WithPoked (TMaybe.M ds), CreateInfoListToCore cias ) =>
+	CreateInfoListToCore ('(
+		mn, stg, vis, ias, ts, vs, rs, ms, dss, cbs, ds ) ': cias) where
+	createInfoListToCore (U11 ci :** cis) f =
+		createInfoToCore ci \cci ->
+		createInfoListToCore cis \ccis -> f $ cci : ccis
+
+gNull :: IO G
+gNull = G <$> newIORef NullHandle
+
+newtype G = G (IORef Pipeline.C.P)
+
+gToCore :: G -> IO Pipeline.C.P
+gToCore (G rp) = readIORef rp
+
+gFromCore :: Pipeline.C.P -> IO G
+gFromCore p = G <$> newIORef p
+
+gListFromCore :: [Pipeline.C.P] -> IO [G]
+gListFromCore [] = pure []
+gListFromCore (cp : cps) = (:) <$> gFromCore cp <*> gListFromCore cps
+
+gListToIORefs :: [G] -> [IORef Pipeline.C.P]
+gListToIORefs [] = []
+gListToIORefs (G cp : cps) = cp : gListToIORefs cps
+
+gListToCore :: [G] -> IO [Pipeline.C.P]
+gListToCore cps = readIORef `mapM` gListToIORefs cps
+
+createGs :: CreateInfoListToCore cias =>
+	Device.D -> Maybe Cache.P -> HeteroParList.PL (U11 CreateInfo) cias ->
+	TPMaybe.M AllocationCallbacks.A mc -> IO [G]
+createGs dvc mc cis mac = gListFromCore =<< createRaw dvc mc cis mac
+
+recreateGs :: CreateInfoListToCore cias =>
+	Device.D -> Maybe Cache.P ->
+	HeteroParList.PL (U11 CreateInfo) cias ->
+	TPMaybe.M AllocationCallbacks.A mc ->
+	[G] -> IO ()
+recreateGs dvc mc cis macc gs =
+	recreateRaw dvc mc cis macc $ gListToIORefs gs
+
+createRaw :: forall ss mn' . CreateInfoListToCore ss =>
+	Device.D -> Maybe Cache.P ->
+	HeteroParList.PL (U11 CreateInfo) ss ->
+	TPMaybe.M AllocationCallbacks.A mn' -> IO [Pipeline.C.P]
+createRaw (Device.D dvc) mc cis mac = let
+	cc = case mc of Nothing -> NullPtr; Just (Cache.P c) -> c
+	cic = length @_ @ss in
+	allocaArray cic \pps -> do
+		createInfoListToCore cis \ccis -> allocaArray cic \pcis ->
+			pokeArray pcis ccis >>
+			AllocationCallbacks.mToCore mac \pac -> do
+				r <- C.create dvc cc (fromIntegral cic) pcis pac pps
+				throwUnlessSuccess $ Result r
+		peekArray cic pps
+
+recreateRaw :: CreateInfoListToCore ss =>
+	Device.D -> Maybe Cache.P ->
+	HeteroParList.PL (U11 CreateInfo) ss ->
+	TPMaybe.M AllocationCallbacks.A mc ->
+	[IORef Pipeline.C.P] -> IO ()
+recreateRaw dvc mc cis macc rs = do
+	os <- readIORef `mapM` rs
+	ns <- createRaw dvc mc cis macc
+	zipWithM_ writeIORef rs ns
+	(\o -> destroyRaw dvc o macc) `mapM_` os
+
+destroyGs :: Device.D -> [G] -> TPMaybe.M AllocationCallbacks.A md -> IO ()
+destroyGs dvc gs mac = ((\g -> gFromCore g >>= \g' -> destroy dvc g' mac) `mapM_`) =<< gListToCore gs
+
+destroy :: Device.D -> G -> TPMaybe.M AllocationCallbacks.A mn -> IO ()
+destroy (Device.D dvc) g mac = gToCore g >>= \p ->
+	AllocationCallbacks.mToCore mac $ Pipeline.C.destroy dvc p
+
+destroyRaw ::
+	Device.D -> Pipeline.C.P -> TPMaybe.M AllocationCallbacks.A md -> IO ()
+destroyRaw (Device.D dvc) p macd =
+	AllocationCallbacks.mToCore macd $ Pipeline.C.destroy dvc p
diff --git a/src/Gpu/Vulkan/Pipeline/InputAssemblyState/Middle.hs b/src/Gpu/Vulkan/Pipeline/InputAssemblyState/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Pipeline/InputAssemblyState/Middle.hs
@@ -0,0 +1,9 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Pipeline.InputAssemblyState.Middle (
+
+	-- * CREATE INFO
+
+	CreateInfo(..), CreateFlags ) where
+
+import Gpu.Vulkan.Pipeline.InputAssemblyState.Middle.Internal
diff --git a/src/Gpu/Vulkan/Pipeline/InputAssemblyState/Middle/Internal.hsc b/src/Gpu/Vulkan/Pipeline/InputAssemblyState/Middle/Internal.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Pipeline/InputAssemblyState/Middle/Internal.hsc
@@ -0,0 +1,55 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE MonoLocalBinds #-}
+{-# LANGUAGE FlexibleContexts, UndecidableInstances #-}
+{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
+{-# LANGUAGE StandaloneDeriving, GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Pipeline.InputAssemblyState.Middle.Internal (
+	CreateInfo(..), CreateFlags, createInfoToCore
+	) where
+
+import Foreign.Ptr
+import Foreign.Storable
+import Foreign.Storable.PeekPoke
+import Foreign.C.Enum
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Data.Bits
+import Data.Word
+
+import Gpu.Vulkan.Base.Middle.Internal
+import Gpu.Vulkan.Enum
+
+import qualified Gpu.Vulkan.Pipeline.InputAssemblyState.Core as C
+
+#include <vulkan/vulkan.h>
+
+enum "CreateFlags" ''#{type VkPipelineInputAssemblyStateCreateFlags}
+	[''Show, ''Eq, ''Storable, ''Bits] [("CreateFlagsZero", 0)]
+
+data CreateInfo mn = CreateInfo {
+	createInfoNext :: TMaybe.M mn,
+	createInfoFlags :: CreateFlags,
+	createInfoTopology :: PrimitiveTopology,
+	createInfoPrimitiveRestartEnable :: Bool }
+
+deriving instance Show (TMaybe.M mn) => Show (CreateInfo mn)
+
+createInfoToCore :: WithPoked (TMaybe.M mn) =>
+	CreateInfo mn -> (Ptr C.CreateInfo -> IO a) -> IO ()
+createInfoToCore CreateInfo {
+	createInfoNext = mnxt,
+	createInfoFlags = CreateFlags flgs,
+	createInfoTopology = PrimitiveTopology tplg,
+	createInfoPrimitiveRestartEnable = pre } f =
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+	let	ci = C.CreateInfo {
+			C.createInfoSType = (),
+			C.createInfoPNext = pnxt',
+			C.createInfoFlags = flgs,
+			C.createInfoTopology = tplg,
+			C.createInfoPrimitiveRestartEnable =
+				boolToBool32 pre } in
+	withPoked ci f
diff --git a/src/Gpu/Vulkan/Pipeline/MultisampleState/Middle.hs b/src/Gpu/Vulkan/Pipeline/MultisampleState/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Pipeline/MultisampleState/Middle.hs
@@ -0,0 +1,9 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Pipeline.MultisampleState.Middle (
+
+	-- * CREATE INFO
+
+	CreateInfo(..), CreateFlags ) where
+
+import Gpu.Vulkan.Pipeline.MultisampleState.Middle.Internal
diff --git a/src/Gpu/Vulkan/Pipeline/MultisampleState/Middle/Internal.hsc b/src/Gpu/Vulkan/Pipeline/MultisampleState/Middle/Internal.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Pipeline/MultisampleState/Middle/Internal.hsc
@@ -0,0 +1,66 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE MonoLocalBinds #-}
+{-# LANGUAGE FlexibleContexts, UndecidableInstances #-}
+{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
+{-# LANGUAGE StandaloneDeriving, GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Pipeline.MultisampleState.Middle.Internal (
+	CreateInfo(..), CreateFlags, createInfoToCore ) where
+
+import Foreign.Ptr
+import Foreign.Storable
+import Foreign.Storable.PeekPoke
+import Foreign.C.Enum
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Data.Bits
+import Data.Word
+
+import Gpu.Vulkan.Base.Middle.Internal
+
+import Gpu.Vulkan.Sample.Middle.Internal as Sample
+import Gpu.Vulkan.Sample.Enum as Sample
+
+import qualified Gpu.Vulkan.Pipeline.MultisampleState.Core as C
+
+#include <vulkan/vulkan.h>
+
+enum "CreateFlags" ''#{type VkPipelineMultisampleStateCreateFlags}
+	[''Show, ''Eq, ''Storable, ''Bits] [("CreateFlagsZero", 0)]
+
+data CreateInfo mn = CreateInfo {
+	createInfoNext :: TMaybe.M mn,
+	createInfoFlags :: CreateFlags,
+	createInfoRasterizationSamplesAndMask :: Sample.CountAndMask,
+	createInfoSampleShadingEnable :: Bool,
+	createInfoMinSampleShading :: Float,
+	createInfoAlphaToCoverageEnable :: Bool,
+	createInfoAlphaToOneEnable :: Bool }
+
+deriving instance Show (TMaybe.M mn) => Show (CreateInfo mn)
+
+createInfoToCore :: WithPoked (TMaybe.M mn) =>
+	CreateInfo mn -> (Ptr C.CreateInfo -> IO a) -> IO ()
+createInfoToCore CreateInfo {
+	createInfoNext = mnxt,
+	createInfoFlags = CreateFlags flgs,
+	createInfoRasterizationSamplesAndMask = cm,
+	createInfoSampleShadingEnable = boolToBool32 -> sse,
+	createInfoMinSampleShading = mss,
+	createInfoAlphaToCoverageEnable = boolToBool32 -> ace,
+	createInfoAlphaToOneEnable = boolToBool32 -> aoe } f =
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+	countAndMaskToCore cm \(Sample.CountFlagBits c, m) ->
+	let ci = C.CreateInfo {
+		C.createInfoSType = (),
+		C.createInfoPNext = pnxt',
+		C.createInfoFlags = flgs,
+		C.createInfoRasterizationSamples = c,
+		C.createInfoSampleShadingEnable = sse,
+		C.createInfoMinSampleShading = mss,
+		C.createInfoPSampleMask = m,
+		C.createInfoAlphaToCoverageEnable = ace,
+		C.createInfoAlphaToOneEnable = aoe } in
+	withPoked ci f
diff --git a/src/Gpu/Vulkan/Pipeline/RasterizationState/Middle.hs b/src/Gpu/Vulkan/Pipeline/RasterizationState/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Pipeline/RasterizationState/Middle.hs
@@ -0,0 +1,9 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Pipeline.RasterizationState.Middle (
+
+	-- * CREATE INFO
+
+	CreateInfo(..), CreateFlags ) where
+
+import Gpu.Vulkan.Pipeline.RasterizationState.Middle.Internal
diff --git a/src/Gpu/Vulkan/Pipeline/RasterizationState/Middle/Internal.hsc b/src/Gpu/Vulkan/Pipeline/RasterizationState/Middle/Internal.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Pipeline/RasterizationState/Middle/Internal.hsc
@@ -0,0 +1,78 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE MonoLocalBinds #-}
+{-# LANGUAGE FlexibleContexts, UndecidableInstances #-}
+{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
+{-# LANGUAGE StandaloneDeriving, GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Pipeline.RasterizationState.Middle.Internal (
+	CreateInfo(..), CreateFlags, createInfoToCore
+	) where
+
+import Foreign.Ptr
+import Foreign.Storable
+import Foreign.Storable.PeekPoke
+import Foreign.C.Enum
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Data.Bits
+import Data.Word
+
+import Gpu.Vulkan.Base.Middle.Internal
+import Gpu.Vulkan.Enum
+
+import qualified Gpu.Vulkan.Pipeline.RasterizationState.Core as C
+
+#include <vulkan/vulkan.h>
+
+enum "CreateFlags" ''#{type VkPipelineRasterizationStateCreateFlags}
+	[''Show, ''Eq, ''Storable, ''Bits] [("CreateFlagsZero", 0)]
+
+data CreateInfo mn = CreateInfo {
+	createInfoNext :: TMaybe.M mn,
+	createInfoFlags :: CreateFlags,
+	createInfoDepthClampEnable :: Bool,
+	createInfoRasterizerDiscardEnable :: Bool,
+	createInfoPolygonMode :: PolygonMode,
+	createInfoCullMode :: CullModeFlags,
+	createInfoFrontFace :: FrontFace,
+	createInfoDepthBiasEnable :: Bool,
+	createInfoDepthBiasConstantFactor :: Float,
+	createInfoDepthBiasClamp :: Float,
+	createInfoDepthBiasSlopeFactor :: Float,
+	createInfoLineWidth :: Float }
+
+deriving instance Show (TMaybe.M mn) => Show (CreateInfo mn)
+
+createInfoToCore :: WithPoked (TMaybe.M mn) =>
+	CreateInfo mn -> (Ptr C.CreateInfo -> IO a) -> IO ()
+createInfoToCore CreateInfo {
+	createInfoNext = mnxt,
+	createInfoFlags = CreateFlags flgs,
+	createInfoDepthClampEnable = boolToBool32 -> dce,
+	createInfoRasterizerDiscardEnable = boolToBool32 -> rde,
+	createInfoPolygonMode = PolygonMode pm,
+	createInfoCullMode = CullModeFlagBits cm,
+	createInfoFrontFace = FrontFace ff,
+	createInfoDepthBiasEnable = boolToBool32 -> dbe,
+	createInfoDepthBiasConstantFactor = dbcf,
+	createInfoDepthBiasClamp = dbc,
+	createInfoDepthBiasSlopeFactor = dbsf,
+	createInfoLineWidth = lw } f =
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+	let	ci = C.CreateInfo {
+			C.createInfoSType = (),
+			C.createInfoPNext = pnxt',
+			C.createInfoFlags = flgs,
+			C.createInfoDepthClampEnable = dce,
+			C.createInfoRasterizerDiscardEnable = rde,
+			C.createInfoPolygonMode = pm,
+			C.createInfoCullMode = cm,
+			C.createInfoFrontFace = ff,
+			C.createInfoDepthBiasEnable = dbe,
+			C.createInfoDepthBiasConstantFactor = dbcf,
+			C.createInfoDepthBiasClamp = dbc,
+			C.createInfoDepthBiasSlopeFactor = dbsf,
+			C.createInfoLineWidth = lw } in
+	withPoked ci f
diff --git a/src/Gpu/Vulkan/Pipeline/ShaderStage/Enum.hsc b/src/Gpu/Vulkan/Pipeline/ShaderStage/Enum.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Pipeline/ShaderStage/Enum.hsc
@@ -0,0 +1,37 @@
+-- This file is automatically generated by the tools/makeEnum.hs
+--	% stack runghc --cwd tools/ makeEnum
+
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-missing-export-lists -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Pipeline.ShaderStage.Enum where
+
+import Foreign.Storable
+import Foreign.C.Enum
+import Data.Word
+import Data.Bits
+import Data.Default
+
+#include <vulkan/vulkan.h>
+
+enum "CreateFlagBits" ''#{type VkPipelineShaderStageCreateFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("CreateFlagsZero", 0),
+	("CreateAllowVaryingSubgroupSizeBit",
+		#{const VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT}),
+	("CreateRequireFullSubgroupsBit",
+		#{const VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT}),
+	("CreateAllowVaryingSubgroupSizeBitExt",
+		#{const VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT}),
+	("CreateRequireFullSubgroupsBitExt",
+		#{const VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT}),
+	("CreateFlagBitsMaxEnum",
+		#{const VK_PIPELINE_SHADER_STAGE_CREATE_FLAG_BITS_MAX_ENUM}) ]
+
+instance Default CreateFlagBits where
+	def = CreateFlagsZero
+
+type CreateFlags = CreateFlagBits
diff --git a/src/Gpu/Vulkan/Pipeline/ShaderStage/Middle.hs b/src/Gpu/Vulkan/Pipeline/ShaderStage/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Pipeline/ShaderStage/Middle.hs
@@ -0,0 +1,8 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Pipeline.ShaderStage.Middle (
+
+	-- * CREATE INFO
+	CreateInfo(..), CreateInfoListToCore ) where
+
+import Gpu.Vulkan.Pipeline.ShaderStage.Middle.Internal
diff --git a/src/Gpu/Vulkan/Pipeline/ShaderStage/Middle/Internal.hs b/src/Gpu/Vulkan/Pipeline/ShaderStage/Middle/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Pipeline/ShaderStage/Middle/Internal.hs
@@ -0,0 +1,82 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE ExplicitForAll #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleContexts, FlexibleInstances, UndecidableInstances #-}
+{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Pipeline.ShaderStage.Middle.Internal (
+	CreateInfo(..), createInfoToCore,
+	CreateInfoListToCore, createInfoListToCore ) where
+
+import Foreign.Ptr
+import Foreign.Storable.PeekPoke
+import Foreign.Storable.HeteroList
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Data.TypeLevel.Tuple.Uncurry
+import qualified Data.HeteroParList as HeteroParList
+import Data.HeteroParList (pattern (:**))
+
+import qualified Data.ByteString as BS
+
+import Gpu.Vulkan.Enum
+import Gpu.Vulkan.Pipeline.ShaderStage.Enum
+
+import qualified Gpu.Vulkan.ShaderModule.Middle.Internal as ShaderModule
+import qualified Gpu.Vulkan.Pipeline.ShaderStage.Core as C
+import qualified Gpu.Vulkan.Specialization.Middle.Internal as Specialization
+
+data CreateInfo mn sknd sivs = CreateInfo {
+	createInfoNext :: TMaybe.M mn,
+	createInfoFlags :: CreateFlags,
+	createInfoStage :: ShaderStageFlagBits,
+	createInfoModule :: ShaderModule.S sknd,
+	createInfoName :: BS.ByteString,
+	createInfoSpecializationInfo :: Maybe (HeteroParList.L sivs) }
+
+deriving instance (Show (TMaybe.M mn), Show (HeteroParList.L sivs)) =>
+	Show (CreateInfo mn sknd sivs)
+
+createInfoToCore ::
+	forall mn sknd sivs r . (WithPoked (TMaybe.M mn), PokableList sivs) =>
+	CreateInfo mn sknd sivs -> (C.CreateInfo -> IO r) -> IO ()
+createInfoToCore CreateInfo {
+	createInfoNext = mnxt,
+	createInfoFlags = CreateFlagBits flgs,
+	createInfoStage = ShaderStageFlagBits stg,
+	createInfoModule = ShaderModule.S mdl,
+	createInfoName = nm,
+	createInfoSpecializationInfo = mxs } f =
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+	BS.useAsCString nm \cnm ->
+	let	 ci pcsi = C.CreateInfo {
+			C.createInfoSType = (),
+			C.createInfoPNext = pnxt',
+			C.createInfoFlags = flgs,
+			C.createInfoStage = stg,
+			C.createInfoModule = mdl,
+			C.createInfoPName = cnm,
+			C.createInfoPSpecializationInfo = pcsi } in
+	case mxs of
+		Nothing -> f $ ci NullPtr
+		Just xs -> Specialization.infoToCore xs \csi ->
+			withPoked csi $ f . ci
+
+class CreateInfoListToCore cias where
+	createInfoListToCore ::
+		HeteroParList.PL (U3 CreateInfo) cias ->
+			([C.CreateInfo] -> IO r) -> IO ()
+
+instance CreateInfoListToCore '[] where
+	createInfoListToCore HeteroParList.Nil = (() <$) . ($ [])
+
+instance (WithPoked (TMaybe.M mn), PokableList sivs, CreateInfoListToCore cias) =>
+	CreateInfoListToCore ('(mn, sknd, sivs) ': cias) where
+	createInfoListToCore (U3 ci :** cis) f =
+		createInfoToCore ci \cci ->
+		createInfoListToCore cis \ccis -> f $ cci : ccis
diff --git a/src/Gpu/Vulkan/Pipeline/TessellationState/Middle.hs b/src/Gpu/Vulkan/Pipeline/TessellationState/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Pipeline/TessellationState/Middle.hs
@@ -0,0 +1,9 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Pipeline.TessellationState.Middle (
+
+	-- * CREATE INFO
+
+	CreateInfo(..) ) where
+
+import Gpu.Vulkan.Pipeline.TessellationState.Middle.Internal
diff --git a/src/Gpu/Vulkan/Pipeline/TessellationState/Middle/Internal.hsc b/src/Gpu/Vulkan/Pipeline/TessellationState/Middle/Internal.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Pipeline/TessellationState/Middle/Internal.hsc
@@ -0,0 +1,47 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE MonoLocalBinds #-}
+{-# LANGUAGE FlexibleContexts, UndecidableInstances #-}
+{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
+{-# LANGUAGE StandaloneDeriving, GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Pipeline.TessellationState.Middle.Internal where
+
+import Foreign.Ptr
+import Foreign.Storable
+import Foreign.Storable.PeekPoke
+import Foreign.C.Enum
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Data.Bits
+import Data.Word
+
+import qualified Gpu.Vulkan.Pipeline.TessellationState.Core as C
+
+#include <vulkan/vulkan.h>
+
+enum "CreateFlags" ''#{type VkPipelineTessellationStateCreateFlags}
+	[''Show, ''Eq, ''Bits, ''Storable] []
+
+data CreateInfo mn = CreateInfo {
+	createInfoNext :: TMaybe.M mn,
+	createInfoFlags :: CreateFlags,
+	createInfoPatchControlPoints :: Word32 }
+
+deriving instance Show (TMaybe.M mn) => Show (CreateInfo mn)
+
+createInfoToCore :: WithPoked (TMaybe.M mn) =>
+	CreateInfo mn -> (Ptr C.CreateInfo -> IO a) -> IO ()
+createInfoToCore CreateInfo {
+	createInfoNext = mnxt,
+	createInfoFlags = CreateFlags flgs,
+	createInfoPatchControlPoints = pcps
+	} f =
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+	let ci = C.CreateInfo {
+			C.createInfoSType = (),
+			C.createInfoPNext = pnxt',
+			C.createInfoFlags = flgs,
+			C.createInfoPatchControlPoints = pcps } in
+	withPoked ci f
diff --git a/src/Gpu/Vulkan/Pipeline/VertexInputState/Middle.hs b/src/Gpu/Vulkan/Pipeline/VertexInputState/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Pipeline/VertexInputState/Middle.hs
@@ -0,0 +1,9 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Pipeline.VertexInputState.Middle (
+
+	-- * CREATE INFO
+
+	CreateInfo(..), CreateFlags ) where
+
+import Gpu.Vulkan.Pipeline.VertexInputState.Middle.Internal
diff --git a/src/Gpu/Vulkan/Pipeline/VertexInputState/Middle/Internal.hsc b/src/Gpu/Vulkan/Pipeline/VertexInputState/Middle/Internal.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Pipeline/VertexInputState/Middle/Internal.hsc
@@ -0,0 +1,64 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE MonoLocalBinds #-}
+{-# LANGUAGE FlexibleContexts, UndecidableInstances #-}
+{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
+{-# LANGUAGE StandaloneDeriving, GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Pipeline.VertexInputState.Middle.Internal where
+
+import Foreign.Ptr
+import Foreign.Marshal.Array
+import Foreign.Storable
+import Foreign.Storable.PeekPoke
+import Foreign.C.Enum
+import Control.Arrow
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Data.Bits
+import Data.Word
+
+import qualified Gpu.Vulkan.VertexInput.Middle.Internal as VertexInput
+import qualified Gpu.Vulkan.Pipeline.VertexInputState.Core as C
+
+#include <vulkan/vulkan.h>
+
+enum "CreateFlags" ''#{type VkPipelineVertexInputStateCreateFlags}
+		[''Show, ''Storable, ''Eq, ''Bits] []
+
+data CreateInfo mn = CreateInfo {
+	createInfoNext :: TMaybe.M mn,
+	createInfoFlags :: CreateFlags,
+	createInfoVertexBindingDescriptions ::
+		[VertexInput.BindingDescription],
+	createInfoVertexAttributeDescriptions ::
+		[VertexInput.AttributeDescription] }
+
+deriving instance Show (TMaybe.M mn) => Show (CreateInfo mn)
+
+createInfoToCore :: WithPoked (TMaybe.M mn) =>
+	CreateInfo mn -> (Ptr C.CreateInfo -> IO a) -> IO ()
+createInfoToCore CreateInfo {
+	createInfoNext = mnxt,
+	createInfoFlags = CreateFlags flgs,
+	createInfoVertexBindingDescriptions =
+		((length &&& id) . (VertexInput.bindingDescriptionToCore <$>))
+			-> (vbdc, vbds),
+	createInfoVertexAttributeDescriptions =
+		((length &&& id) . (VertexInput.attributeDescriptionToCore <$>))
+			-> (vadc, vads) } f =
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+	allocaArray vbdc \pvbds ->
+	pokeArray pvbds vbds >>
+	allocaArray vadc \pvads ->
+	pokeArray pvads vads >>
+	let ci = C.CreateInfo {
+		C.createInfoSType = (),
+		C.createInfoPNext = pnxt',
+		C.createInfoFlags = flgs,
+		C.createInfoVertexBindingDescriptionCount = fromIntegral vbdc,
+		C.createInfoPVertexBindingDescriptions = pvbds,
+		C.createInfoVertexAttributeDescriptionCount = fromIntegral vadc,
+		C.createInfoPVertexAttributeDescriptions = pvads } in
+	withPoked ci f
diff --git a/src/Gpu/Vulkan/Pipeline/ViewportState/Middle.hs b/src/Gpu/Vulkan/Pipeline/ViewportState/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Pipeline/ViewportState/Middle.hs
@@ -0,0 +1,9 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Pipeline.ViewportState.Middle (
+
+	-- * CREATE INFO
+
+	CreateInfo(..), CreateFlags ) where
+
+import Gpu.Vulkan.Pipeline.ViewportState.Middle.Internal
diff --git a/src/Gpu/Vulkan/Pipeline/ViewportState/Middle/Internal.hsc b/src/Gpu/Vulkan/Pipeline/ViewportState/Middle/Internal.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Pipeline/ViewportState/Middle/Internal.hsc
@@ -0,0 +1,66 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE MonoLocalBinds #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE FlexibleContexts, FlexibleInstances, UndecidableInstances #-}
+{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
+{-# LANGUAGE StandaloneDeriving, GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Pipeline.ViewportState.Middle.Internal where
+
+import Foreign.Ptr
+import Foreign.Marshal.Array
+import Foreign.Storable
+import Foreign.Storable.PeekPoke
+import Foreign.C.Enum
+import Control.Arrow
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Data.Default
+import Data.Bits
+import Data.Word
+
+import Gpu.Vulkan.Core
+
+import qualified Gpu.Vulkan.Pipeline.ViewportState.Core as C
+
+#include <vulkan/vulkan.h>
+
+enum "CreateFlags" ''#{type VkPipelineViewportStateCreateFlags}
+	[''Show, ''Eq, ''Storable, ''Bits] []
+
+data CreateInfo mn = CreateInfo {
+	createInfoNext :: TMaybe.M mn,
+	createInfoFlags :: CreateFlags,
+	createInfoViewports :: [Viewport],
+	createInfoScissors :: [Rect2d] }
+
+deriving instance Show (TMaybe.M mn) => Show (CreateInfo mn)
+
+instance Default (CreateInfo 'Nothing) where
+	def = CreateInfo {
+		createInfoNext = TMaybe.N, createInfoFlags = zeroBits,
+		createInfoViewports = [], createInfoScissors = [] }
+
+createInfoToCore :: WithPoked (TMaybe.M mn) =>
+	CreateInfo mn -> (Ptr C.CreateInfo -> IO a) -> IO ()
+createInfoToCore CreateInfo {
+	createInfoNext = mnxt,
+	createInfoFlags = CreateFlags flgs,
+	createInfoViewports = (length &&& id) -> (vpc, vps),
+	createInfoScissors = (length &&& id) -> (scc, scs) } f =
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+	allocaArray vpc \pvps ->
+	pokeArray pvps vps >>
+	allocaArray scc \pscs ->
+	pokeArray pscs scs >>
+	let	ci = C.CreateInfo {
+			C.createInfoSType = (),
+			C.createInfoPNext = pnxt',
+			C.createInfoFlags = flgs,
+			C.createInfoViewportCount = fromIntegral vpc,
+			C.createInfoPViewports = pvps,
+			C.createInfoScissorCount = fromIntegral scc,
+			C.createInfoPScissors = pscs } in
+	withPoked ci f
diff --git a/src/Gpu/Vulkan/PipelineCache/Enum.hsc b/src/Gpu/Vulkan/PipelineCache/Enum.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/PipelineCache/Enum.hsc
@@ -0,0 +1,29 @@
+-- This file is automatically generated by the tools/makeEnum.hs
+--	% stack runghc --cwd tools/ makeEnum
+
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-missing-export-lists -fno-warn-tabs #-}
+
+module Gpu.Vulkan.PipelineCache.Enum where
+
+import Foreign.Storable
+import Foreign.C.Enum
+import Data.Bits
+import Data.Word
+
+#include <vulkan/vulkan.h>
+
+enum "CreateFlagBits" ''#{type VkPipelineCacheCreateFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("CreateFlagsZero", 0),
+	("CreateExternallySynchronizedBit",
+		#{const VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT}),
+	("CreateExternallySynchronizedBitExt",
+		#{const VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT_EXT}),
+	("CreateFlagBitsMaxEnum",
+		#{const VK_PIPELINE_CACHE_CREATE_FLAG_BITS_MAX_ENUM}) ]
+
+type CreateFlags = CreateFlagBits
diff --git a/src/Gpu/Vulkan/PipelineCache/Middle.hs b/src/Gpu/Vulkan/PipelineCache/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/PipelineCache/Middle.hs
@@ -0,0 +1,11 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.PipelineCache.Middle (
+
+	-- * CREATE AND DESTROY
+
+	create, destroy, P, CreateInfo(..), getData, Data(..),
+
+	) where
+
+import Gpu.Vulkan.PipelineCache.Middle.Internal
diff --git a/src/Gpu/Vulkan/PipelineCache/Middle/Internal.hsc b/src/Gpu/Vulkan/PipelineCache/Middle/Internal.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/PipelineCache/Middle/Internal.hsc
@@ -0,0 +1,98 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE BlockArguments, OverloadedStrings #-}
+{-# LANGUAGE ScopedTypeVariables, TypeApplications #-}
+{-# LANGUAGE MonoLocalBinds #-}
+{-# LANGUAGE FlexibleContexts, UndecidableInstances #-}
+{-# LANGUAGE ViewPatterns #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.PipelineCache.Middle.Internal (
+	P(..), CreateInfo(..), create, destroy,
+	Data(..), getData,
+	) where
+
+import Foreign.Ptr
+import Foreign.Marshal.Alloc
+import Foreign.Storable
+import Foreign.Storable.PeekPoke
+import Foreign.C.Types
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Data.TypeLevel.ParMaybe qualified as TPMaybe
+import Data.Default
+import Data.Word
+import Data.ByteString qualified as BS
+
+import Gpu.Vulkan.Exception.Middle.Internal
+import Gpu.Vulkan.Exception.Enum
+import Gpu.Vulkan.PipelineCache.Enum
+
+import Gpu.Vulkan.AllocationCallbacks.Middle.Internal
+	qualified as AllocationCallbacks
+import qualified Gpu.Vulkan.Device.Middle.Internal as Device
+import qualified Gpu.Vulkan.PipelineCache.Core as C
+
+#include <vulkan/vulkan.h>
+
+data CreateInfo mn = CreateInfo {
+	createInfoNext :: TMaybe.M mn,
+	createInfoFlags :: CreateFlags,
+	createInfoInitialData :: Data }
+
+deriving instance Show (TMaybe.M mn) => Show (CreateInfo mn)
+
+createInfoToCore :: WithPoked (TMaybe.M mn) =>
+	CreateInfo mn -> (Ptr C.CreateInfo -> IO a) -> IO ()
+createInfoToCore CreateInfo {
+	createInfoNext = mnxt,
+	createInfoFlags = CreateFlagBits flgs,
+	createInfoInitialData = d } f =
+	dataToRaw d \(DataRaw dtsz pdt) ->
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+	let	ci = C.CreateInfo {
+			C.createInfoSType = (),
+			C.createInfoPNext = pnxt',
+			C.createInfoFlags = flgs,
+			C.createInfoInitialDataSize = dtsz,
+			C.createInfoPInitialData = castPtr pdt } in
+	withPoked ci f
+
+newtype P = P C.P deriving Show
+
+create :: WithPoked (TMaybe.M mn) =>
+	Device.D -> CreateInfo mn -> TPMaybe.M AllocationCallbacks.A mc -> IO P
+create (Device.D dvc) ci mac = P <$> alloca \pc -> do
+	createInfoToCore ci \pci ->
+		AllocationCallbacks.mToCore mac \pac -> do
+			r <- C.create dvc pci pac pc
+			throwUnlessSuccess $ Result r
+	peek pc
+
+destroy :: Device.D -> P -> TPMaybe.M AllocationCallbacks.A md -> IO ()
+destroy (Device.D dvc) (P c) mac =
+	AllocationCallbacks.mToCore mac $ C.destroy dvc c
+
+getData :: Device.D -> P -> IO Data
+getData (Device.D dv) (P c) = alloca \psz -> do
+	r <- C.getData dv c psz nullPtr
+	throwUnlessSuccess $ Result r
+	sz <- peek psz
+	allocaBytes (fromIntegral sz) \pdt -> do
+		r' <- C.getData dv c psz pdt
+		throwUnlessSuccess $ Result r'
+		dataFromRaw . DataRaw sz $ castPtr pdt
+
+dataFromRaw :: DataRaw -> IO Data
+dataFromRaw (DataRaw sz pd) = Data <$> BS.packCStringLen (pd, fromIntegral sz)
+
+dataToRaw :: Data -> (DataRaw -> IO a) -> IO a
+dataToRaw (Data bs) f = BS.useAsCStringLen bs \(pd, sz) ->
+	f $ DataRaw (fromIntegral sz) pd
+
+newtype Data = Data BS.ByteString deriving (Show, Eq)
+
+data DataRaw = DataRaw #{type size_t} (Ptr CChar) deriving Show
+
+instance Default Data where def = Data ""
+
+instance Default DataRaw where def = DataRaw 0 nullPtr
diff --git a/src/Gpu/Vulkan/PipelineLayout/Middle.hs b/src/Gpu/Vulkan/PipelineLayout/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/PipelineLayout/Middle.hs
@@ -0,0 +1,9 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.PipelineLayout.Middle (
+
+	-- * CREATE AND DESTROY
+
+	create, destroy, P, CreateInfo(..), CreateFlags ) where
+
+import Gpu.Vulkan.PipelineLayout.Middle.Internal
diff --git a/src/Gpu/Vulkan/PipelineLayout/Middle/Internal.hsc b/src/Gpu/Vulkan/PipelineLayout/Middle/Internal.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/PipelineLayout/Middle/Internal.hsc
@@ -0,0 +1,91 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE MonoLocalBinds #-}
+{-# LANGUAGE FlexibleContexts, UndecidableInstances #-}
+{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
+{-# LANGUAGE StandaloneDeriving, GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.PipelineLayout.Middle.Internal (
+	P(..), CreateInfo(..), CreateFlags, create, destroy
+	) where
+
+import Foreign.Ptr
+import Foreign.Marshal.Alloc
+import Foreign.Marshal.Array
+import Foreign.Storable
+import Foreign.Storable.PeekPoke
+import Foreign.C.Enum
+import Control.Arrow
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Data.TypeLevel.ParMaybe qualified as TPMaybe
+import Data.Default
+import Data.Bits
+import Data.Word
+
+import Gpu.Vulkan.Exception.Middle.Internal
+import Gpu.Vulkan.Exception.Enum
+
+import Gpu.Vulkan.AllocationCallbacks.Middle.Internal
+	qualified as AllocationCallbacks
+import qualified Gpu.Vulkan.Device.Middle.Internal as Device
+import qualified Gpu.Vulkan.DescriptorSetLayout.Middle.Internal as DescriptorSet.Layout
+import qualified Gpu.Vulkan.PushConstant.Middle.Internal as PushConstant
+import qualified Gpu.Vulkan.PipelineLayout.Core as C
+
+#include <vulkan/vulkan.h>
+
+enum "CreateFlags" ''#{type VkPipelineLayoutCreateFlags}
+	[''Show, ''Storable, ''Eq, ''Bits] [("CreateFlagsZero", 0)]
+
+instance Default CreateFlags where def = CreateFlagsZero
+
+data CreateInfo mn = CreateInfo {
+	createInfoNext :: TMaybe.M mn,
+	createInfoFlags :: CreateFlags,
+	createInfoSetLayouts :: [DescriptorSet.Layout.D],
+	createInfoPushConstantRanges :: [PushConstant.Range] }
+
+deriving instance Show (TMaybe.M mn) => Show (CreateInfo mn)
+
+createInfoToCore :: WithPoked (TMaybe.M mn) =>
+	CreateInfo mn -> (Ptr C.CreateInfo -> IO a) -> IO ()
+createInfoToCore CreateInfo {
+	createInfoNext = mnxt,
+	createInfoFlags = CreateFlags flgs,
+	createInfoSetLayouts =
+		(length &&& ((\(DescriptorSet.Layout.D lyt) -> lyt) <$>)) ->
+			(slc, sls),
+	createInfoPushConstantRanges = (
+		length &&&
+		(PushConstant.rangeToCore <$>)) -> (pcrc, pcrs) } f =
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') -> 
+	allocaArray slc \psls ->
+	pokeArray psls sls >>
+	allocaArray pcrc \ppcrs ->
+	pokeArray ppcrs pcrs >>
+	let ci = C.CreateInfo {
+		C.createInfoSType = (),
+		C.createInfoPNext = pnxt',
+		C.createInfoFlags = flgs,
+		C.createInfoSetLayoutCount = fromIntegral slc,
+		C.createInfoPSetLayouts = psls,
+		C.createInfoPushConstantRangeCount = fromIntegral pcrc,
+		C.createInfoPPushConstantRanges = ppcrs } in
+	withPoked ci f
+
+newtype P = P C.P deriving Show
+
+create :: WithPoked (TMaybe.M mn) =>
+	Device.D -> CreateInfo mn -> TPMaybe.M AllocationCallbacks.A mc -> IO P
+create (Device.D dvc) ci mac = P <$> alloca \pl -> do
+	createInfoToCore ci \pci ->
+		AllocationCallbacks.mToCore mac \pac -> do
+			r <- C.create dvc pci pac pl
+			throwUnlessSuccess $ Result r
+	peek pl
+
+destroy :: Device.D -> P -> TPMaybe.M AllocationCallbacks.A md -> IO ()
+destroy (Device.D dvc) (P lyt) mac =
+	AllocationCallbacks.mToCore mac $ C.destroy dvc lyt
diff --git a/src/Gpu/Vulkan/PushConstant/Middle.hs b/src/Gpu/Vulkan/PushConstant/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/PushConstant/Middle.hs
@@ -0,0 +1,9 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.PushConstant.Middle (
+
+	-- * RANGE
+
+	Range(..) ) where
+
+import Gpu.Vulkan.PushConstant.Middle.Internal
diff --git a/src/Gpu/Vulkan/PushConstant/Middle/Internal.hs b/src/Gpu/Vulkan/PushConstant/Middle/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/PushConstant/Middle/Internal.hs
@@ -0,0 +1,23 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.PushConstant.Middle.Internal where
+
+import Data.Word
+
+import Gpu.Vulkan.Enum
+
+import qualified Gpu.Vulkan.PushConstant.Core as C
+
+data Range = Range {
+	rangeStageFlags :: ShaderStageFlags,
+	rangeOffset :: Word32,
+	rangeSize :: Word32 }
+	deriving Show
+
+rangeToCore :: Range -> C.Range
+rangeToCore Range {
+	rangeStageFlags = ShaderStageFlagBits sf,
+	rangeOffset = ost, rangeSize = sz
+	} = C.Range {
+		C.rangeStageFlags = sf,
+		C.rangeOffset = ost, C.rangeSize = sz }
diff --git a/src/Gpu/Vulkan/Query/Enum.hsc b/src/Gpu/Vulkan/Query/Enum.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Query/Enum.hsc
@@ -0,0 +1,106 @@
+-- This file is automatically generated by the tools/makeEnum.hs
+--	% stack runghc --cwd tools/ makeEnum
+
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-missing-export-lists -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Query.Enum where
+
+import Foreign.Storable
+import Foreign.C.Enum
+import Data.Bits
+import Data.Word
+
+#include <vulkan/vulkan.h>
+
+enum "PipelineStatisticFlagBits" ''#{type VkQueryPipelineStatisticFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("PipelineStatisticInputAssemblyVerticesBit",
+		#{const VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT}),
+	("PipelineStatisticInputAssemblyPrimitivesBit",
+		#{const VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT}),
+	("PipelineStatisticVertexShaderInvocationsBit",
+		#{const VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT}),
+	("PipelineStatisticGeometryShaderInvocationsBit",
+		#{const VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT}),
+	("PipelineStatisticGeometryShaderPrimitivesBit",
+		#{const VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT}),
+	("PipelineStatisticClippingInvocationsBit",
+		#{const VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT}),
+	("PipelineStatisticClippingPrimitivesBit",
+		#{const VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT}),
+	("PipelineStatisticFragmentShaderInvocationsBit",
+		#{const VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT}),
+	("PipelineStatisticTessellationControlShaderPatchesBit",
+		#{const VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT}),
+	("PipelineStatisticTessellationEvaluationShaderInvocationsBit",
+		#{const VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT}),
+	("PipelineStatisticComputeShaderInvocationsBit",
+		#{const VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT}),
+	("PipelineStatisticTaskShaderInvocationsBitExt",
+		#{const VK_QUERY_PIPELINE_STATISTIC_TASK_SHADER_INVOCATIONS_BIT_EXT}),
+	("PipelineStatisticMeshShaderInvocationsBitExt",
+		#{const VK_QUERY_PIPELINE_STATISTIC_MESH_SHADER_INVOCATIONS_BIT_EXT}),
+	("PipelineStatisticClusterCullingShaderInvocationsBitHuawei",
+		#{const VK_QUERY_PIPELINE_STATISTIC_CLUSTER_CULLING_SHADER_INVOCATIONS_BIT_HUAWEI}),
+	("PipelineStatisticFlagBitsMaxEnum",
+		#{const VK_QUERY_PIPELINE_STATISTIC_FLAG_BITS_MAX_ENUM}) ]
+
+enum "ControlFlagBits" ''#{type VkQueryControlFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("ControlPreciseBit", #{const VK_QUERY_CONTROL_PRECISE_BIT}),
+	("ControlFlagBitsMaxEnum",
+		#{const VK_QUERY_CONTROL_FLAG_BITS_MAX_ENUM}) ]
+
+enum "ResultFlagBits" ''#{type VkQueryResultFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("Result64Bit", #{const VK_QUERY_RESULT_64_BIT}),
+	("ResultWaitBit", #{const VK_QUERY_RESULT_WAIT_BIT}),
+	("ResultWithAvailabilityBit",
+		#{const VK_QUERY_RESULT_WITH_AVAILABILITY_BIT}),
+	("ResultPartialBit", #{const VK_QUERY_RESULT_PARTIAL_BIT}),
+	("ResultWithStatusBitKhr",
+		#{const VK_QUERY_RESULT_WITH_STATUS_BIT_KHR}),
+	("ResultFlagBitsMaxEnum",
+		#{const VK_QUERY_RESULT_FLAG_BITS_MAX_ENUM}) ]
+
+enum "Type" ''#{type VkQueryType}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("TypeOcclusion", #{const VK_QUERY_TYPE_OCCLUSION}),
+	("TypePipelineStatistics",
+		#{const VK_QUERY_TYPE_PIPELINE_STATISTICS}),
+	("TypeTimestamp", #{const VK_QUERY_TYPE_TIMESTAMP}),
+	("TypeResultStatusOnlyKhr",
+		#{const VK_QUERY_TYPE_RESULT_STATUS_ONLY_KHR}),
+	("TypeTransformFeedbackStreamExt",
+		#{const VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT}),
+	("TypePerformanceQueryKhr",
+		#{const VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR}),
+	("TypeAccelerationStructureCompactedSizeKhr",
+		#{const VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR}),
+	("TypeAccelerationStructureSerializationSizeKhr",
+		#{const VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR}),
+	("TypeAccelerationStructureCompactedSizeNv",
+		#{const VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_NV}),
+	("TypePerformanceQueryIntel",
+		#{const VK_QUERY_TYPE_PERFORMANCE_QUERY_INTEL}),
+	("TypeMeshPrimitivesGeneratedExt",
+		#{const VK_QUERY_TYPE_MESH_PRIMITIVES_GENERATED_EXT}),
+	("TypePrimitivesGeneratedExt",
+		#{const VK_QUERY_TYPE_PRIMITIVES_GENERATED_EXT}),
+	("TypeAccelerationStructureSerializationBottomLevelPointersKhr",
+		#{const VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_BOTTOM_LEVEL_POINTERS_KHR}),
+	("TypeAccelerationStructureSizeKhr",
+		#{const VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SIZE_KHR}),
+	("TypeMicromapSerializationSizeExt",
+		#{const VK_QUERY_TYPE_MICROMAP_SERIALIZATION_SIZE_EXT}),
+	("TypeMicromapCompactedSizeExt",
+		#{const VK_QUERY_TYPE_MICROMAP_COMPACTED_SIZE_EXT}),
+	("TypeMaxEnum", #{const VK_QUERY_TYPE_MAX_ENUM}) ]
+
+type PipelineStatisticFlags = PipelineStatisticFlagBits
+type ControlFlags = ControlFlagBits
+type ResultFlags = ResultFlagBits
diff --git a/src/Gpu/Vulkan/QueryPool/Middle.hs b/src/Gpu/Vulkan/QueryPool/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/QueryPool/Middle.hs
@@ -0,0 +1,16 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.QueryPool.Middle (
+
+	-- * CREATE AND DESTROY
+
+	create, destroy, Q, CreateInfo(..), CreateFlags,
+
+	-- * GET RESULTS
+
+--	reset,
+	getResults, W32W64Tools, W32W64(..), AvailabilityTools, Availability(..)
+
+	) where
+
+import Gpu.Vulkan.QueryPool.Middle.Internal
diff --git a/src/Gpu/Vulkan/QueryPool/Middle/Internal.hsc b/src/Gpu/Vulkan/QueryPool/Middle/Internal.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/QueryPool/Middle/Internal.hsc
@@ -0,0 +1,203 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE BlockArguments, LambdaCase #-}
+{-# LANGUAGE ScopedTypeVariables, TypeApplications #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE MultiParamTypeClasses, AllowAmbiguousTypes #-}
+{-# LANGUAGE FlexibleContexts, FlexibleInstances, UndecidableInstances #-}
+{-# LANGUAGE ViewPatterns #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving, StandaloneDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+ 
+module Gpu.Vulkan.QueryPool.Middle.Internal where
+
+import Foreign.Ptr
+import Foreign.Marshal.Alloc
+import Foreign.Marshal.Array
+import Foreign.Storable
+import Foreign.Storable.PeekPoke
+import Foreign.C.Enum
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Data.TypeLevel.ParMaybe qualified as TPMaybe
+import Data.Bits
+import Data.Bool
+import Data.Word
+
+import Gpu.Vulkan.Exception.Middle.Internal
+import Gpu.Vulkan.Exception.Enum
+import Gpu.Vulkan.AllocationCallbacks.Middle.Internal
+	qualified as AllocationCallbacks
+import Gpu.Vulkan.Device.Middle.Internal qualified as Device
+import Gpu.Vulkan.Query.Enum
+import Gpu.Vulkan.QueryPool.Core qualified as C
+
+#include <vulkan/vulkan.h>
+
+enum "CreateFlagBits" ''#{type VkQueryPoolCreateFlags}
+		[''Show, ''Eq, ''Storable, ''Bits] []
+
+type CreateFlags = CreateFlagBits
+
+data CreateInfo mn = CreateInfo {
+	createInfoNext :: TMaybe.M mn,
+	createInfoFlags :: CreateFlags,
+	createInfoQueryType :: Type,
+	createInfoQueryCount :: Word32,
+	createInfoPipelineStatistics :: PipelineStatisticFlags }
+
+deriving instance Show (TMaybe.M mn) => Show (CreateInfo mn)
+
+createInfoToCore :: WithPoked (TMaybe.M mn) =>
+	CreateInfo mn -> (Ptr C.CreateInfo -> IO a) -> IO ()
+createInfoToCore CreateInfo {
+	createInfoNext = mnxt,
+	createInfoFlags = CreateFlagBits flgs,
+	createInfoQueryType = Type tp,
+	createInfoQueryCount = cnt,
+	createInfoPipelineStatistics = PipelineStatisticFlagBits ps } f =
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+	withPoked C.CreateInfo {
+		C.createInfoSType = (),
+		C.createInfoPNext = pnxt',
+		C.createInfoFlags = flgs,
+		C.createInfoQueryType = tp,
+		C.createInfoQueryCount = cnt,
+		C.createInfoPipelineStatistics = ps } f
+
+newtype Q = Q C.Q deriving Show
+
+create :: WithPoked (TMaybe.M mn) =>
+	Device.D -> CreateInfo mn -> TPMaybe.M AllocationCallbacks.A mc -> IO Q
+create (Device.D dv) ci mac = Q <$> alloca \pq -> do
+	createInfoToCore ci \pci ->
+		AllocationCallbacks.mToCore mac \pac -> do
+			r <- C.create dv pci pac pq
+			throwUnlessSuccess $ Result r
+	peek pq
+
+destroy :: Device.D -> Q -> TPMaybe.M AllocationCallbacks.A md -> IO ()
+destroy (Device.D dv) (Q q) mad = AllocationCallbacks.mToCore mad \pad ->
+	C.destroy dv q pad
+
+reset :: Device.D -> Q -> Word32 -> Word32 -> IO ()
+reset (Device.D dv) (Q q) fq qc = C.reset dv q fq qc
+
+getResultsRaw :: Device.D -> Q -> Word32 -> Word32 -> ResultFlags -> IO [Word32]
+getResultsRaw (Device.D dv) (Q q) fq qc (ResultFlagBits flgs) =
+	allocaArray (qc' * 16) \pd -> do
+		r <- C.getResults dv q fq qc (qc' * 16) pd 16 flgs
+		throwUnlessSuccess $ Result r
+		peekArray (qc' * 4) $ castPtr pd
+	where
+	qc' :: Integral n => n
+	qc' = fromIntegral qc
+
+data W32W64 (w64 :: Bool) where
+	W32 :: Word32 -> W32W64 'False
+	W64 :: Word64 -> W32W64 'True
+
+deriving instance Show (W32W64 w64)
+deriving instance Eq (W32W64 w64)
+
+instance Storable (W32W64 'False) where
+	sizeOf _ = sizeOf @Word32 undefined
+	alignment _ = alignment @Word32 undefined
+	peek p = W32 <$> peek (castPtr p)
+	poke p (W32 w) = poke (castPtr p) w
+
+instance Storable (W32W64 'True) where
+	sizeOf _ = sizeOf @Word64 undefined
+	alignment _ = alignment @Word64 undefined
+	peek p = W64 <$> peek (castPtr p)
+	poke p (W64 w) = poke (castPtr p) w
+
+instance Num (W32W64 'False) where
+	W32 m + W32 n = W32 $ m + n
+	W32 m * W32 n = W32 $ m * n
+	abs (W32 n) = W32 $ abs n
+	signum (W32 n) = W32 $ signum n
+	fromInteger = W32 . fromInteger
+	negate (W32 n) = W32 $ negate n
+
+instance Num (W32W64 'True) where
+	W64 m + W64 n = W64 $ m + n
+	W64 m * W64 n = W64 $ m * n
+	abs (W64 n) = W64 $ abs n
+	signum (W64 n) = W64 $ signum n
+	fromInteger = W64 . fromInteger
+	negate (W64 n) = W64 $ negate n
+
+class W32W64Tools (w64 :: Bool) where
+	bytesOf :: Integral n => n
+	result64Bit :: ResultFlags -> ResultFlags
+
+instance W32W64Tools False where
+	bytesOf = 4
+	result64Bit = (.&. complement Result64Bit)
+
+instance W32W64Tools True where
+	bytesOf = 8
+	result64Bit = (.|. Result64Bit)
+
+getResultsW32W64 :: forall w64 . (Storable (W32W64 w64), W32W64Tools w64) =>
+	Device.D -> Q -> Word32 -> Word32 -> ResultFlags -> IO [W32W64 w64]
+getResultsW32W64
+	(Device.D dv) (Q q) fq qc (result64Bit @w64 -> ResultFlagBits flgs) =
+	allocaArray (qc' * 2) \pd -> do
+		r <- C.getResults dv q fq qc
+			(qc' * 2 * bytesOf @w64) pd (2 * bytesOf @w64) flgs
+		throwUnlessSuccess $ Result r
+		peekArray (qc' * 2) $ castPtr pd
+	where
+	qc' :: Integral n => n
+	qc' = fromIntegral qc
+
+data Availability (av :: Bool) a where
+	NonAvailability :: a -> Availability 'False a
+	Availability :: Maybe a -> Availability 'True a
+
+deriving instance Show a => Show (Availability av a)
+
+instance Functor (Availability av) where
+	fmap f = \case
+		NonAvailability x -> NonAvailability $ f x
+		Availability mx -> Availability $ f <$> mx
+
+class AvailabilityTools (av :: Bool) a where
+	numOfWords :: Integral n => n
+	resultWithAvailBit :: ResultFlags -> ResultFlags
+	mkAvailability :: [a] -> [Availability av a]
+
+instance AvailabilityTools 'False a where
+	numOfWords = 1
+	resultWithAvailBit = (.&. complement ResultWithAvailabilityBit)
+	mkAvailability = (NonAvailability <$>)
+
+instance (Eq n, Num n) => AvailabilityTools 'True n where
+	numOfWords = 2
+	resultWithAvailBit = (.|. ResultWithAvailabilityBit)
+	mkAvailability = \case
+		[] -> []
+		[_] -> error "never occur"
+		x : a : xas -> Availability
+			(bool Nothing (Just x) (a /= 0)) : mkAvailability xas
+
+getResults :: forall av w64 . (
+	Storable (W32W64 w64), W32W64Tools w64,
+	AvailabilityTools av (W32W64 w64) ) =>
+	Device.D -> Q -> Word32 -> Word32 -> ResultFlags ->
+	IO [Availability av (W32W64 w64)]
+getResults (Device.D dv) (Q q) fq qc
+	(resultWithAvailBit @av @(W32W64 w64) . result64Bit @w64 -> ResultFlagBits flgs) =
+	allocaArray (qc' * nw) \pd -> do
+		r <- C.getResults dv q fq qc
+			(qc' * nw * bytesOf @w64) pd (nw * bytesOf @w64) flgs
+		throwUnlessSuccess $ Result r
+		mkAvailability <$> peekArray (qc' * nw) (castPtr pd)
+	where
+	qc' :: Integral n => n
+	qc' = fromIntegral qc
+	nw :: Integral n => n
+	nw = numOfWords @av @(W32W64 w64)
diff --git a/src/Gpu/Vulkan/Queue/Enum.hsc b/src/Gpu/Vulkan/Queue/Enum.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Queue/Enum.hsc
@@ -0,0 +1,31 @@
+-- This file is automatically generated by the tools/makeEnum.hs
+--	% stack runghc --cwd tools/ makeEnum
+
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-missing-export-lists -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Queue.Enum where
+
+import Foreign.Storable
+import Foreign.C.Enum
+import Data.Bits
+import Data.Word
+
+#include <vulkan/vulkan.h>
+
+enum "FlagBits" ''#{type VkQueueFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits, ''FiniteBits] [
+	("FlagsZero", 0),
+	("GraphicsBit", #{const VK_QUEUE_GRAPHICS_BIT}),
+	("ComputeBit", #{const VK_QUEUE_COMPUTE_BIT}),
+	("TransferBit", #{const VK_QUEUE_TRANSFER_BIT}),
+	("SparseBindingBit", #{const VK_QUEUE_SPARSE_BINDING_BIT}),
+	("ProtectedBit", #{const VK_QUEUE_PROTECTED_BIT}),
+	("VideoDecodeBitKhr", #{const VK_QUEUE_VIDEO_DECODE_BIT_KHR}),
+	("OpticalFlowBitNv", #{const VK_QUEUE_OPTICAL_FLOW_BIT_NV}),
+	("FlagBitsMaxEnum", #{const VK_QUEUE_FLAG_BITS_MAX_ENUM}) ]
+
+type Flags = FlagBits
diff --git a/src/Gpu/Vulkan/Queue/Middle.hs b/src/Gpu/Vulkan/Queue/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Queue/Middle.hs
@@ -0,0 +1,9 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Queue.Middle (
+
+	-- * SUBMIT AND WAIT IDLE
+
+	submit, waitIdle, Q ) where
+
+import Gpu.Vulkan.Queue.Middle.Internal
diff --git a/src/Gpu/Vulkan/Queue/Middle/Internal.hs b/src/Gpu/Vulkan/Queue/Middle/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Queue/Middle/Internal.hs
@@ -0,0 +1,41 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE ScopedTypeVariables, TypeApplications #-}
+{-# LANGUAGE GADTs, TypeFamilies #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE KindSignatures, TypeOperators #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE FlexibleContexts, FlexibleInstances #-}
+{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Queue.Middle.Internal (
+
+	-- * SUBMIT AND WAIT IDLE
+
+	submit, waitIdle, Q(..)
+
+	) where
+
+import Foreign.Marshal.Array
+import Data.HeteroParList qualified as HeteroParList
+
+import Gpu.Vulkan.Middle
+import Gpu.Vulkan.Exception.Middle.Internal
+import Gpu.Vulkan.Exception.Enum
+import Gpu.Vulkan.Fence.Middle.Internal qualified as Fence.M
+import Gpu.Vulkan.Queue.Core qualified as C
+
+newtype Q = Q C.Q deriving Show
+
+submit :: SubmitInfoListToCore ns =>
+	Q -> HeteroParList.PL SubmitInfo ns -> Maybe Fence.M.F -> IO ()
+submit (Q q) sis mf = submitInfoListToCore sis \csis ->
+	let sic = length csis in allocaArray sic \psis -> do
+		pokeArray psis csis
+		r <- C.submit q (fromIntegral sic) psis
+			$ Fence.M.maybeFToCore mf
+		throwUnlessSuccess $ Result r
+
+waitIdle :: Q -> IO ()
+waitIdle (Q q) = throwUnlessSuccess . Result =<< C.waitIdle q
diff --git a/src/Gpu/Vulkan/QueueFamily/EnumManual.hsc b/src/Gpu/Vulkan/QueueFamily/EnumManual.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/QueueFamily/EnumManual.hsc
@@ -0,0 +1,19 @@
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.QueueFamily.EnumManual where
+
+import Foreign.Storable
+import Data.Word
+
+#include <vulkan/vulkan.h>
+
+import Foreign.C.Enum
+
+enum "Index" ''#{type uint32_t} [''Show, ''Eq, ''Storable, ''Enum]
+	[("Ignored", #{const VK_QUEUE_FAMILY_IGNORED})]
+
+indices :: [Index]
+indices = [Index 0 ..]
diff --git a/src/Gpu/Vulkan/QueueFamily/Middle.hs b/src/Gpu/Vulkan/QueueFamily/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/QueueFamily/Middle.hs
@@ -0,0 +1,11 @@
+{-# LANGUAGE PatternSynonyms #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.QueueFamily.Middle (
+
+	-- * PROPERTIES
+
+	Properties(..), Index(..), pattern Ignored ) where
+
+import Gpu.Vulkan.QueueFamily.EnumManual
+import Gpu.Vulkan.QueueFamily.Middle.Internal
diff --git a/src/Gpu/Vulkan/QueueFamily/Middle/Internal.hsc b/src/Gpu/Vulkan/QueueFamily/Middle/Internal.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/QueueFamily/Middle/Internal.hsc
@@ -0,0 +1,29 @@
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.QueueFamily.Middle.Internal where
+
+import Data.Word
+
+import Gpu.Vulkan.Core
+
+import qualified Gpu.Vulkan.Queue.Enum as Queue
+import qualified Gpu.Vulkan.QueueFamily.Core as C
+
+data Properties = Properties {
+	propertiesQueueFlags :: Queue.Flags,
+	propertiesQueueCount :: Word32,
+	propertiesTimestampValidBits :: Word32,
+	propertiesMinImageTransferGranularity :: Extent3d }
+	deriving Show
+
+propertiesFromCore :: C.Properties -> Properties
+propertiesFromCore C.Properties {
+	C.propertiesQueueFlags = flgs,
+	C.propertiesQueueCount = cnt,
+	C.propertiesTimestampValidBits = tvb,
+	C.propertiesMinImageTransferGranularity = mitg } = Properties {
+	propertiesQueueFlags = Queue.FlagBits flgs,
+	propertiesQueueCount = cnt,
+	propertiesTimestampValidBits = tvb,
+	propertiesMinImageTransferGranularity = mitg }
diff --git a/src/Gpu/Vulkan/RenderPass/Enum.hsc b/src/Gpu/Vulkan/RenderPass/Enum.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/RenderPass/Enum.hsc
@@ -0,0 +1,27 @@
+-- This file is automatically generated by the tools/makeEnum.hs
+--	% stack runghc --cwd tools/ makeEnum
+
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-missing-export-lists -fno-warn-tabs #-}
+
+module Gpu.Vulkan.RenderPass.Enum where
+
+import Foreign.Storable
+import Foreign.C.Enum
+import Data.Bits
+import Data.Word
+
+#include <vulkan/vulkan.h>
+
+enum "CreateFlagBits" ''#{type VkRenderPassCreateFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("CreateFlagsZero", 0),
+	("CreateTransformBitQcom",
+		#{const VK_RENDER_PASS_CREATE_TRANSFORM_BIT_QCOM}),
+	("CreateFlagBitsMaxEnum",
+		#{const VK_RENDER_PASS_CREATE_FLAG_BITS_MAX_ENUM}) ]
+
+type CreateFlags = CreateFlagBits
diff --git a/src/Gpu/Vulkan/RenderPass/Middle.hs b/src/Gpu/Vulkan/RenderPass/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/RenderPass/Middle.hs
@@ -0,0 +1,13 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.RenderPass.Middle (
+
+	-- * CREATE AND DESTROY
+
+	create, destroy, R, CreateInfo(..),
+
+	-- * BEGIN INFO
+
+	BeginInfo(..) ) where
+
+import Gpu.Vulkan.RenderPass.Middle.Internal
diff --git a/src/Gpu/Vulkan/RenderPass/Middle/Internal.hs b/src/Gpu/Vulkan/RenderPass/Middle/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/RenderPass/Middle/Internal.hs
@@ -0,0 +1,120 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE ScopedTypeVariables, TypeApplications #-}
+{-# LANGUAGE MonoLocalBinds #-}
+{-# LANGUAGE FlexibleContexts, UndecidableInstances #-}
+{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.RenderPass.Middle.Internal where
+
+import Foreign.Ptr
+import Foreign.Marshal.Alloc
+import Foreign.Marshal.Array
+import Foreign.Storable
+import Foreign.Storable.PeekPoke
+import Control.Arrow
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Data.TypeLevel.ParMaybe qualified as TPMaybe
+import Data.TypeLevel.List qualified as TL
+import qualified Data.HeteroParList as HeteroParList
+
+import Gpu.Vulkan.Middle.Internal
+import Gpu.Vulkan.Exception.Middle.Internal
+import Gpu.Vulkan.Exception.Enum
+import Gpu.Vulkan.RenderPass.Enum
+
+import Gpu.Vulkan.Misc.Middle.Internal
+
+import Gpu.Vulkan.AllocationCallbacks.Middle.Internal
+	qualified as AllocationCallbacks
+import qualified Gpu.Vulkan.Device.Middle.Types as Device
+import qualified Gpu.Vulkan.Attachment.Middle.Internal as Attachment
+import qualified Gpu.Vulkan.Subpass.Middle.Internal as Subpass
+import qualified Gpu.Vulkan.Framebuffer.Middle.Internal as Framebuffer
+import qualified Gpu.Vulkan.RenderPass.Core as C
+
+data CreateInfo mn = CreateInfo {
+	createInfoNext :: TMaybe.M mn,
+	createInfoFlags :: CreateFlags,
+	createInfoAttachments :: [Attachment.Description],
+	createInfoSubpasses :: [Subpass.Description],
+	createInfoDependencies :: [Subpass.Dependency] }
+
+deriving instance Show (TMaybe.M mn) => Show (CreateInfo mn)
+
+createInfoToCore :: WithPoked (TMaybe.M mn) =>
+	CreateInfo mn -> (Ptr C.CreateInfo -> IO r) -> IO ()
+createInfoToCore CreateInfo {
+	createInfoNext = mnxt,
+	createInfoFlags = CreateFlagBits flgs,
+	createInfoAttachments =
+		(length &&& (Attachment.descriptionToCore <$>)) -> (ac, as),
+	createInfoSubpasses = (length &&& id) -> (sc, ss),
+	createInfoDependencies =
+		(length &&& (Subpass.dependencyToCore <$>)) -> (dc, ds) } f =
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+	allocaArray ac \pas ->
+	pokeArray pas as >>
+	(Subpass.descriptionToCore `mapContM` ss) \css ->
+	allocaArray sc \pss ->
+	pokeArray pss css >>
+	allocaArray dc \pds ->
+	pokeArray pds ds >>
+	let ci = C.CreateInfo {
+		C.createInfoSType = (),
+		C.createInfoPNext = pnxt',
+		C.createInfoFlags = flgs,
+		C.createInfoAttachmentCount = fromIntegral ac,
+		C.createInfoPAttachments = pas,
+		C.createInfoSubpassCount = fromIntegral sc,
+		C.createInfoPSubpasses = pss,
+		C.createInfoDependencyCount = fromIntegral dc,
+		C.createInfoPDependencies = pds } in
+	withPoked ci f
+
+newtype R = R C.R deriving Show
+
+create :: WithPoked (TMaybe.M mn) =>
+	Device.D -> CreateInfo mn -> TPMaybe.M AllocationCallbacks.A mc -> IO R
+create (Device.D dvc) ci mac = R <$>
+	alloca \pr -> do
+		createInfoToCore ci \pci ->
+			AllocationCallbacks.mToCore mac \pac -> do
+				r <- C.create dvc pci pac pr
+				throwUnlessSuccess $ Result r
+		peek pr
+
+destroy :: Device.D -> R -> TPMaybe.M AllocationCallbacks.A md -> IO ()
+destroy (Device.D dvc) (R r) mac =
+	AllocationCallbacks.mToCore mac $ C.destroy dvc r
+
+data BeginInfo mn cts = BeginInfo {
+	beginInfoNext :: TMaybe.M mn,
+	beginInfoRenderPass :: R,
+	beginInfoFramebuffer :: Framebuffer.F,
+	beginInfoRenderArea :: Rect2d,
+	beginInfoClearValues :: HeteroParList.PL ClearValue cts }
+
+beginInfoToCore :: forall mn cts a . (WithPoked (TMaybe.M mn), ClearValueListToCore cts) =>
+	BeginInfo mn cts -> (Ptr C.BeginInfo -> IO a) -> IO ()
+beginInfoToCore BeginInfo {
+	beginInfoNext = mnxt,
+	beginInfoRenderPass = R rp,
+	beginInfoFramebuffer = fb,
+	beginInfoRenderArea = ra,
+	beginInfoClearValues = const (TL.length @_ @cts) &&& id -> (cvc, cvs)
+	} f = withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+		clearValueListToCore cvs \pcvl ->
+		clearValueListToArray pcvl \pcva -> do
+		fb' <- Framebuffer.fToCore fb
+		let	ci = C.BeginInfo {
+				C.beginInfoSType = (),
+				C.beginInfoPNext = pnxt',
+				C.beginInfoRenderPass = rp,
+				C.beginInfoFramebuffer = fb',
+				C.beginInfoRenderArea = ra,
+				C.beginInfoClearValueCount = cvc,
+				C.beginInfoPClearValues = pcva }
+		withPoked ci f
diff --git a/src/Gpu/Vulkan/RenderPass/Middle/Internal.hs-boot b/src/Gpu/Vulkan/RenderPass/Middle/Internal.hs-boot
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/RenderPass/Middle/Internal.hs-boot
@@ -0,0 +1,9 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.RenderPass.Middle.Internal where
+
+import qualified Gpu.Vulkan.RenderPass.Core as C
+
+newtype R = R C.R
+
+instance Show R
diff --git a/src/Gpu/Vulkan/Sample/Enum.hsc b/src/Gpu/Vulkan/Sample/Enum.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Sample/Enum.hsc
@@ -0,0 +1,32 @@
+-- This file is automatically generated by the tools/makeEnum.hs
+--	% stack runghc --cwd tools/ makeEnum
+
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-missing-export-lists -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Sample.Enum where
+
+import Foreign.Storable
+import Foreign.C.Enum
+import Data.Bits
+import Data.Word
+
+#include <vulkan/vulkan.h>
+
+enum "CountFlagBits" ''#{type VkSampleCountFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits, ''FiniteBits] [
+	("CountFlagsZero", 0),
+	("Count1Bit", #{const VK_SAMPLE_COUNT_1_BIT}),
+	("Count2Bit", #{const VK_SAMPLE_COUNT_2_BIT}),
+	("Count4Bit", #{const VK_SAMPLE_COUNT_4_BIT}),
+	("Count8Bit", #{const VK_SAMPLE_COUNT_8_BIT}),
+	("Count16Bit", #{const VK_SAMPLE_COUNT_16_BIT}),
+	("Count32Bit", #{const VK_SAMPLE_COUNT_32_BIT}),
+	("Count64Bit", #{const VK_SAMPLE_COUNT_64_BIT}),
+	("CountFlagBitsMaxEnum",
+		#{const VK_SAMPLE_COUNT_FLAG_BITS_MAX_ENUM}) ]
+
+type CountFlags = CountFlagBits
diff --git a/src/Gpu/Vulkan/Sample/Middle.hs b/src/Gpu/Vulkan/Sample/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Sample/Middle.hs
@@ -0,0 +1,9 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs  #-}
+
+module Gpu.Vulkan.Sample.Middle (
+
+	-- * COUNT AND MASK
+
+	CountAndMask(..) ) where
+
+import Gpu.Vulkan.Sample.Middle.Internal
diff --git a/src/Gpu/Vulkan/Sample/Middle/Internal.hsc b/src/Gpu/Vulkan/Sample/Middle/Internal.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Sample/Middle/Internal.hsc
@@ -0,0 +1,34 @@
+{-# LANGUAGE BlockArguments, LambdaCase #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Sample.Middle.Internal where
+
+import Foreign.Ptr
+import Foreign.Marshal.Array
+import Foreign.Storable.PeekPoke
+import Data.Bits
+import Data.Word
+
+import Gpu.Vulkan.Sample.Enum
+
+#include <vulkan/vulkan.h>
+
+data CountAndMask = CountAndMask CountFlagBits (Maybe Mask) deriving Show
+
+newtype Mask = Mask Integer deriving Show
+
+countAndMaskToCore ::
+	CountAndMask -> ((CountFlagBits, Ptr #{type VkSampleMask}) -> IO a) -> IO a
+countAndMaskToCore foo f = case foo of
+	CountAndMask cfb Nothing -> f (cfb, NullPtr)
+	CountAndMask cfb@(CountFlagBits c) (Just (Mask m)) ->
+		allocaArray ln \pm ->
+		pokeArray pm (integerToWord32s ln m) >>
+		f (cfb, pm)
+		where ln = fromIntegral $ (c - 1) `div` 32 + 1
+
+integerToWord32s :: Int -> Integer -> [Word32]
+integerToWord32s ln _ | ln < 1 = []
+integerToWord32s ln n =
+	fromInteger (n .&. 0xffffffff) :
+	integerToWord32s (ln - 1) (n `shiftR` 32)
diff --git a/src/Gpu/Vulkan/Sampler/Enum.hsc b/src/Gpu/Vulkan/Sampler/Enum.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Sampler/Enum.hsc
@@ -0,0 +1,57 @@
+-- This file is automatically generated by the tools/makeEnum.hs
+--	% stack runghc --cwd tools/ makeEnum
+
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-missing-export-lists -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Sampler.Enum where
+
+import Foreign.Storable
+import Foreign.C.Enum
+import Data.Bits
+import Data.Word
+
+#include <vulkan/vulkan.h>
+
+enum "CreateFlagBits" ''#{type VkSamplerCreateFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("CreateFlagsZero", 0),
+	("CreateSubsampledBitExt",
+		#{const VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT}),
+	("CreateSubsampledCoarseReconstructionBitExt",
+		#{const VK_SAMPLER_CREATE_SUBSAMPLED_COARSE_RECONSTRUCTION_BIT_EXT}),
+	("CreateDescriptorBufferCaptureReplayBitExt",
+		#{const VK_SAMPLER_CREATE_DESCRIPTOR_BUFFER_CAPTURE_REPLAY_BIT_EXT}),
+	("CreateNonSeamlessCubeMapBitExt",
+		#{const VK_SAMPLER_CREATE_NON_SEAMLESS_CUBE_MAP_BIT_EXT}),
+	("CreateImageProcessingBitQcom",
+		#{const VK_SAMPLER_CREATE_IMAGE_PROCESSING_BIT_QCOM}),
+	("CreateFlagBitsMaxEnum",
+		#{const VK_SAMPLER_CREATE_FLAG_BITS_MAX_ENUM}) ]
+
+enum "MipmapMode" ''#{type VkSamplerMipmapMode}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("MipmapModeNearest", #{const VK_SAMPLER_MIPMAP_MODE_NEAREST}),
+	("MipmapModeLinear", #{const VK_SAMPLER_MIPMAP_MODE_LINEAR}),
+	("MipmapModeMaxEnum", #{const VK_SAMPLER_MIPMAP_MODE_MAX_ENUM}) ]
+
+enum "AddressMode" ''#{type VkSamplerAddressMode}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("AddressModeRepeat", #{const VK_SAMPLER_ADDRESS_MODE_REPEAT}),
+	("AddressModeMirroredRepeat",
+		#{const VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT}),
+	("AddressModeClampToEdge",
+		#{const VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE}),
+	("AddressModeClampToBorder",
+		#{const VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER}),
+	("AddressModeMirrorClampToEdge",
+		#{const VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE}),
+	("AddressModeMirrorClampToEdgeKhr",
+		#{const VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE_KHR}),
+	("AddressModeMaxEnum",
+		#{const VK_SAMPLER_ADDRESS_MODE_MAX_ENUM}) ]
+
+type CreateFlags = CreateFlagBits
diff --git a/src/Gpu/Vulkan/Sampler/Middle.hs b/src/Gpu/Vulkan/Sampler/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Sampler/Middle.hs
@@ -0,0 +1,10 @@
+{-# LANGUAGE PatternSynonyms #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Sampler.Middle (
+
+	-- * CREATE AND DESTROY
+
+	create, destroy, S, pattern Null, CreateInfo(..) ) where
+
+import Gpu.Vulkan.Sampler.Middle.Internal
diff --git a/src/Gpu/Vulkan/Sampler/Middle/Internal.hs b/src/Gpu/Vulkan/Sampler/Middle/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Sampler/Middle/Internal.hs
@@ -0,0 +1,109 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE MonoLocalBinds #-}
+{-# LANGUAGE FlexibleContexts, UndecidableInstances #-}
+{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Sampler.Middle.Internal where
+
+import Foreign.Ptr
+import Foreign.Marshal.Alloc
+import Foreign.Storable	
+import Foreign.Storable.PeekPoke
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Data.TypeLevel.ParMaybe qualified as TPMaybe
+
+import Gpu.Vulkan.Base.Middle.Internal
+import Gpu.Vulkan.Enum
+import Gpu.Vulkan.Exception.Middle.Internal
+import Gpu.Vulkan.Exception.Enum
+import Gpu.Vulkan.Sampler.Enum
+
+import Gpu.Vulkan.AllocationCallbacks.Middle.Internal
+	qualified as AllocationCallbacks
+import qualified Gpu.Vulkan.Device.Middle.Internal as Device
+import qualified Gpu.Vulkan.Sampler.Core as C
+
+newtype S = S C.S deriving Show
+
+pattern Null :: S
+pattern Null <- S NullHandle where
+	Null = S NullHandle
+
+data CreateInfo mn = CreateInfo {
+	createInfoNext :: TMaybe.M mn,
+	createInfoFlags :: CreateFlags,
+	createInfoMagFilter :: Filter,
+	createInfoMinFilter :: Filter,
+	createInfoMipmapMode :: MipmapMode,
+	createInfoAddressModeU :: AddressMode,
+	createInfoAddressModeV :: AddressMode,
+	createInfoAddressModeW :: AddressMode,
+	createInfoMipLodBias :: Float,
+	createInfoAnisotropyEnable :: Bool,
+	createInfoMaxAnisotropy :: Float,
+	createInfoCompareEnable :: Bool,
+	createInfoCompareOp :: CompareOp,
+	createInfoMinLod :: Float,
+	createInfoMaxLod :: Float,
+	createInfoBorderColor :: BorderColor,
+	createInfoUnnormalizedCoordinates :: Bool }
+
+deriving instance Show (TMaybe.M mn) => Show (CreateInfo mn)
+
+createInfoToCore :: WithPoked (TMaybe.M mn) =>
+	CreateInfo mn -> (Ptr C.CreateInfo -> IO r) -> IO ()
+createInfoToCore CreateInfo {
+	createInfoNext = mnxt,
+	createInfoFlags = CreateFlagBits flgs,
+	createInfoMagFilter = Filter mgf,
+	createInfoMinFilter = Filter mnf,
+	createInfoMipmapMode = MipmapMode mmm,
+	createInfoAddressModeU = AddressMode amu,
+	createInfoAddressModeV = AddressMode amv,
+	createInfoAddressModeW = AddressMode amw,
+	createInfoMipLodBias = mlb,
+	createInfoAnisotropyEnable = boolToBool32 -> aie,
+	createInfoMaxAnisotropy = mai,
+	createInfoCompareEnable = boolToBool32 -> ce,
+	createInfoCompareOp = CompareOp cop,
+	createInfoMinLod = mnl,
+	createInfoMaxLod = mxl,
+	createInfoBorderColor = BorderColor bc,
+	createInfoUnnormalizedCoordinates = boolToBool32 -> unc } f =
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+	let	ci = C.CreateInfo {
+			C.createInfoSType = (),
+			C.createInfoPNext = pnxt',
+			C.createInfoFlags = flgs,
+			C.createInfoMagFilter = mgf,
+			C.createInfoMinFilter = mnf,
+			C.createInfoMipmapMode = mmm,
+			C.createInfoAddressModeU = amu,
+			C.createInfoAddressModeV = amv,
+			C.createInfoAddressModeW = amw,
+			C.createInfoMipLodBias = mlb,
+			C.createInfoAnisotropyEnable = aie,
+			C.createInfoMaxAnisotropy = mai,
+			C.createInfoCompareEnable = ce,
+			C.createInfoCompareOp = cop,
+			C.createInfoMinLod = mnl,
+			C.createInfoMaxLod = mxl,
+			C.createInfoBorderColor = bc,
+			C.createInfoUnnormalizedCoordinates = unc } in
+	withPoked ci f
+
+create :: WithPoked (TMaybe.M mn) =>
+	Device.D -> CreateInfo mn -> TPMaybe.M AllocationCallbacks.A mc -> IO S
+create (Device.D dvc) ci mac = S <$> alloca \ps -> do
+	createInfoToCore ci \pci ->
+		AllocationCallbacks.mToCore mac \pac ->
+			throwUnlessSuccess . Result
+				=<< C.create dvc pci pac ps
+	peek ps
+
+destroy :: Device.D -> S -> TPMaybe.M AllocationCallbacks.A md -> IO ()
+destroy (Device.D dvc) (S s) mac =
+	AllocationCallbacks.mToCore mac $ C.destroy dvc s
diff --git a/src/Gpu/Vulkan/Semaphore/Middle.hs b/src/Gpu/Vulkan/Semaphore/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Semaphore/Middle.hs
@@ -0,0 +1,11 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Semaphore.Middle (
+
+	-- * CREATE AND DESTROY
+
+	create, destroy, S, CreateInfo(..), CreateFlags,
+
+	) where
+
+import Gpu.Vulkan.Semaphore.Middle.Internal
diff --git a/src/Gpu/Vulkan/Semaphore/Middle/Internal.hs-boot b/src/Gpu/Vulkan/Semaphore/Middle/Internal.hs-boot
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Semaphore/Middle/Internal.hs-boot
@@ -0,0 +1,9 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Semaphore.Middle.Internal where
+
+import qualified Gpu.Vulkan.Semaphore.Core as C
+
+newtype S = S { unS :: C.S }
+
+instance Show S
diff --git a/src/Gpu/Vulkan/Semaphore/Middle/Internal.hsc b/src/Gpu/Vulkan/Semaphore/Middle/Internal.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Semaphore/Middle/Internal.hsc
@@ -0,0 +1,74 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE MonoLocalBinds #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE FlexibleContexts, FlexibleInstances, UndecidableInstances #-}
+{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
+{-# LANGUAGE StandaloneDeriving, GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Semaphore.Middle.Internal (
+
+	-- * CREATE AND DESTROY
+
+	create, destroy, S(..), CreateInfo(..), CreateFlags,
+
+	) where
+
+import Foreign.Ptr
+import Foreign.Marshal.Alloc
+import Foreign.Storable
+import Foreign.Storable.PeekPoke
+import Foreign.C.Enum
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Data.TypeLevel.ParMaybe qualified as TPMaybe
+import Data.Default
+import Data.Bits
+import Data.Word
+
+import Gpu.Vulkan.Exception.Middle.Internal
+import Gpu.Vulkan.Exception.Enum
+
+import qualified Gpu.Vulkan.AllocationCallbacks.Middle.Internal as AllocationCallbacks
+import qualified Gpu.Vulkan.Semaphore.Core as C
+
+import qualified Gpu.Vulkan.Device.Middle.Types as Device
+
+#include <vulkan/vulkan.h>
+
+enum "CreateFlags" ''#{type VkSemaphoreCreateFlags}
+	[''Show, ''Eq, ''Storable, ''Bits] [("CreateFlagsZero", 0)]
+
+data CreateInfo mn = CreateInfo {
+	createInfoNext :: TMaybe.M mn, createInfoFlags :: CreateFlags }
+
+deriving instance Show (TMaybe.M mn) => Show (CreateInfo mn)
+
+instance Default (CreateInfo 'Nothing) where
+	def = CreateInfo {
+		createInfoNext = TMaybe.N, createInfoFlags = zeroBits }
+
+createInfoToCore :: WithPoked (TMaybe.M mn) =>
+	CreateInfo mn -> (Ptr C.CreateInfo -> IO r) -> IO ()
+createInfoToCore CreateInfo {
+	createInfoNext = mnxt,
+	createInfoFlags = CreateFlags flgs } f =
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') ->
+	let ci = C.CreateInfo {
+		C.createInfoSType = (),
+		C.createInfoPNext = pnxt',
+		C.createInfoFlags = flgs } in withPoked ci f
+
+newtype S = S { unS :: C.S } deriving Show
+
+create :: WithPoked (TMaybe.M mn) =>
+	Device.D -> CreateInfo mn -> TPMaybe.M AllocationCallbacks.A mc -> IO S
+create (Device.D dvc) ci mac = S <$> alloca \ps -> do
+	createInfoToCore ci \pci -> AllocationCallbacks.mToCore mac \pac ->
+		throwUnlessSuccess . Result =<< C.create dvc pci pac ps
+	peek ps
+
+destroy :: Device.D -> S -> TPMaybe.M AllocationCallbacks.A md -> IO ()
+destroy (Device.D dvc) (S s) mac =
+	AllocationCallbacks.mToCore mac $ C.destroy dvc s
diff --git a/src/Gpu/Vulkan/ShaderModule/Middle.hs b/src/Gpu/Vulkan/ShaderModule/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/ShaderModule/Middle.hs
@@ -0,0 +1,9 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.ShaderModule.Middle (
+
+	-- * CREATE AND DESTROY
+
+	create, destroy, S, CreateInfo(..), CreateFlags, CreateFlagBits ) where
+
+import Gpu.Vulkan.ShaderModule.Middle.Internal
diff --git a/src/Gpu/Vulkan/ShaderModule/Middle/Internal.hsc b/src/Gpu/Vulkan/ShaderModule/Middle/Internal.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/ShaderModule/Middle/Internal.hsc
@@ -0,0 +1,92 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE MonoLocalBinds #-}
+{-# LANGUAGE DataKinds, KindSignatures #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE FlexibleContexts, UndecidableInstances #-}
+{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
+{-# LANGUAGE StandaloneDeriving, GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.ShaderModule.Middle.Internal where
+
+import Foreign.Ptr
+import Foreign.ForeignPtr
+import Foreign.Marshal
+import Foreign.Storable
+import Foreign.Storable.PeekPoke
+import Foreign.C.Enum
+import Data.TypeLevel.Maybe qualified as TMaybe
+import Data.TypeLevel.ParMaybe qualified as TPMaybe
+import Data.Default
+import Data.Bits
+import Data.Word
+
+import qualified Data.ByteString as BS
+import qualified Data.ByteString.Internal as BS
+
+import Language.SpirV.Internal qualified as SpirV
+import Language.SpirV.ShaderKind qualified as SpirV
+
+import Gpu.Vulkan.Exception.Middle.Internal
+import Gpu.Vulkan.Exception.Enum
+
+import Gpu.Vulkan.AllocationCallbacks.Middle.Internal
+	qualified as AllocationCallbacks
+import qualified Gpu.Vulkan.Device.Middle.Internal as Device
+import qualified Gpu.Vulkan.ShaderModule.Core as C
+
+#include <vulkan/vulkan.h>
+
+newtype S (sknd :: SpirV.ShaderKind) = S C.S deriving Show
+
+enum "CreateFlagBits" ''#{type VkShaderModuleCreateFlags}
+	[''Eq, ''Show, ''Storable, ''Bits] [("CreateFlagsZero", 0)]
+
+type CreateFlags = CreateFlagBits
+
+instance Default CreateFlags where def = CreateFlagsZero
+
+data CreateInfo mn sknd = CreateInfo {
+	createInfoNext :: TMaybe.M mn,
+	createInfoFlags :: CreateFlags,
+	createInfoCode :: SpirV.S sknd }
+
+deriving instance Show (TMaybe.M mn) => Show (CreateInfo mn sknd)
+
+createInfoToCore :: WithPoked (TMaybe.M mn) =>
+	CreateInfo mn sknd -> (Ptr C.CreateInfo -> IO r) -> IO ()
+createInfoToCore CreateInfo {
+	createInfoNext = mnxt,
+	createInfoFlags = CreateFlagBits flgs,
+	createInfoCode = cd } f =
+	withPoked' mnxt \pnxt -> withPtrS pnxt \(castPtr -> pnxt') -> do
+		(p, n) <- readFromByteString $ (\(SpirV.S spv) -> spv) cd
+		let ci = C.CreateInfo {
+			C.createInfoSType = (),
+			C.createInfoPNext = pnxt',
+			C.createInfoFlags = flgs,
+			C.createInfoCodeSize = n,
+			C.createInfoPCode = p }
+		withPoked ci f
+
+readFromByteString :: BS.ByteString -> IO (Ptr Word32, Word64)
+readFromByteString (BS.PS f o l) = do
+	p' <- mallocBytes l
+	withForeignPtr f \p -> copyBytes p' (p `plusPtr` o) l
+	pure (p', fromIntegral l)
+
+create :: WithPoked (TMaybe.M mn) =>
+	Device.D ->
+	CreateInfo mn sknd -> TPMaybe.M AllocationCallbacks.A mc -> IO (S sknd)
+create (Device.D dvc) ci mac = S <$> alloca \pm -> do
+	createInfoToCore ci \pcci ->
+		AllocationCallbacks.mToCore mac \pac -> do
+			r <- C.create dvc pcci pac pm
+			throwUnlessSuccess $ Result r
+	peek pm
+
+destroy :: Device.D -> S sknd -> TPMaybe.M AllocationCallbacks.A md -> IO ()
+destroy (Device.D dvc) (S m) mac =
+	AllocationCallbacks.mToCore mac $ C.destroy dvc m
diff --git a/src/Gpu/Vulkan/Specialization/Middle/Internal.hs b/src/Gpu/Vulkan/Specialization/Middle/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Specialization/Middle/Internal.hs
@@ -0,0 +1,54 @@
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE ScopedTypeVariables, TypeApplications #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Specialization.Middle.Internal (infoToCore) where
+
+import Foreign.Marshal.Alloc
+import Foreign.Marshal.Array
+import Foreign.Storable.HeteroList hiding (alignments)
+import qualified Data.HeteroParList as HeteroParList
+
+import qualified Gpu.Vulkan.Specialization.Core as C
+
+type Parameters = (Int, [(Int, Int, Int)], Int, Int)
+
+parameters :: [(Int, Int)] -> Parameters
+parameters szals = (
+	length szals, zip3 [0 ..] ofs (fst <$> szals), tsz, alignments szals )
+	where
+	ofs = offsets szals; szs = fst <$> szals; tsz = last ofs + last szs
+
+offsets :: [(Int, Int)] -> [Int]
+offsets = tail . (fst <$>) . scanl step (0, 0)
+
+step :: (Int, Int) -> (Int, Int) -> (Int, Int)
+step (_st, ed) (sz, al) = (st', st' + sz)
+	where st' = ((ed - 1) `div` al + 1) * al
+
+alignments :: [(Int, Int)] -> Int
+alignments = foldl lcm 1 . (snd <$>)
+
+mapEntries :: Parameters -> [C.MapEntry]
+mapEntries (_, ps, _, _) = (<$> ps) \(i, o, s) -> C.MapEntry {
+	C.mapEntryConstantId = fromIntegral i,
+	C.mapEntryOffset = fromIntegral o,
+	C.mapEntrySize = fromIntegral s }
+
+infoToCore :: forall vs a . PokableList vs =>
+	HeteroParList.L vs -> (C.Info -> IO a) -> IO a
+infoToCore xs f =
+	allocaArray n \pmes ->
+	pokeArray pmes (mapEntries ps) >>
+	allocaBytesAligned tsz tal \pd ->
+	pokeList pd xs >>
+	f C.Info {
+		C.infoMapEntryCount = fromIntegral n,
+		C.infoPMapEntries = pmes,
+		C.infoDataSize = fromIntegral tsz,
+		C.infoPData = pd }
+	where
+	szals = sizeAlignments @vs
+	ps@(n, _, tsz, tal) = parameters szals
diff --git a/src/Gpu/Vulkan/Subpass/Enum.hsc b/src/Gpu/Vulkan/Subpass/Enum.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Subpass/Enum.hsc
@@ -0,0 +1,54 @@
+-- This file is automatically generated by the tools/makeEnum.hs
+--	% stack runghc --cwd tools/ makeEnum
+
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-missing-export-lists -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Subpass.Enum where
+
+import Foreign.Storable
+import Foreign.C.Enum
+import Data.Bits
+import Data.Word
+
+#include <vulkan/vulkan.h>
+
+enum "DescriptionFlagBits" ''#{type VkSubpassDescriptionFlagBits}
+		[''Show, ''Eq, ''Storable, ''Bits] [
+	("DescriptionFlagsZero", 0),
+	("DescriptionPerViewAttributesBitNvx",
+		#{const VK_SUBPASS_DESCRIPTION_PER_VIEW_ATTRIBUTES_BIT_NVX}),
+	("DescriptionPerViewPositionXOnlyBitNvx",
+		#{const VK_SUBPASS_DESCRIPTION_PER_VIEW_POSITION_X_ONLY_BIT_NVX}),
+	("DescriptionFragmentRegionBitQcom",
+		#{const VK_SUBPASS_DESCRIPTION_FRAGMENT_REGION_BIT_QCOM}),
+	("DescriptionShaderResolveBitQcom",
+		#{const VK_SUBPASS_DESCRIPTION_SHADER_RESOLVE_BIT_QCOM}),
+	("DescriptionRasterizationOrderAttachmentColorAccessBitExt",
+		#{const VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_BIT_EXT}),
+	("DescriptionRasterizationOrderAttachmentDepthAccessBitExt",
+		#{const VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_EXT}),
+	("DescriptionRasterizationOrderAttachmentStencilAccessBitExt",
+		#{const VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_EXT}),
+	("DescriptionEnableLegacyDitheringBitExt",
+		#{const VK_SUBPASS_DESCRIPTION_ENABLE_LEGACY_DITHERING_BIT_EXT}),
+	("DescriptionRasterizationOrderAttachmentColorAccessBitArm",
+		#{const VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_BIT_ARM}),
+	("DescriptionRasterizationOrderAttachmentDepthAccessBitArm",
+		#{const VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_ARM}),
+	("DescriptionRasterizationOrderAttachmentStencilAccessBitArm",
+		#{const VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_ARM}),
+	("DescriptionFlagBitsMaxEnum",
+		#{const VK_SUBPASS_DESCRIPTION_FLAG_BITS_MAX_ENUM}) ]
+
+enum "Contents" ''#{type VkSubpassContents}
+		[''Show, ''Eq, ''Storable] [
+	("ContentsInline", #{const VK_SUBPASS_CONTENTS_INLINE}),
+	("ContentsSecondaryCommandBuffers",
+		#{const VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS}),
+	("ContentsMaxEnum", #{const VK_SUBPASS_CONTENTS_MAX_ENUM}) ]
+
+type DescriptionFlags = DescriptionFlagBits
diff --git a/src/Gpu/Vulkan/Subpass/Middle.hs b/src/Gpu/Vulkan/Subpass/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Subpass/Middle.hs
@@ -0,0 +1,14 @@
+{-# LANGUAGE PatternSynonyms #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Subpass.Middle (
+
+	-- * DESCRIPTION
+
+	Description(..),
+
+	-- * DEPENDENCY
+
+	Dependency(..), S, pattern SExternal ) where
+
+import Gpu.Vulkan.Subpass.Middle.Internal
diff --git a/src/Gpu/Vulkan/Subpass/Middle/Internal.hsc b/src/Gpu/Vulkan/Subpass/Middle/Internal.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/Subpass/Middle/Internal.hsc
@@ -0,0 +1,102 @@
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE BlockArguments, TupleSections #-}
+{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.Subpass.Middle.Internal where
+
+import Foreign.Marshal.Alloc
+import Foreign.Marshal.Array
+import Foreign.Storable
+import Foreign.Storable.PeekPoke
+import Foreign.C.Enum
+import Control.Arrow
+import Data.Word
+
+import Gpu.Vulkan.Enum
+import Gpu.Vulkan.Subpass.Enum
+
+import qualified Gpu.Vulkan.Pipeline.Enum as Pipeline
+import qualified Gpu.Vulkan.Attachment.Middle.Internal as Attachment
+import qualified Gpu.Vulkan.Subpass.Core as C
+
+#include <vulkan/vulkan.h>
+
+data Description = Description {
+	descriptionFlags :: DescriptionFlags,
+	descriptionPipelineBindPoint :: Pipeline.BindPoint,
+	descriptionInputAttachments :: [Attachment.Reference],
+	descriptionColorAndResolveAttachments :: Either
+		[Attachment.Reference]
+		[(Attachment.Reference, Attachment.Reference)],
+	descriptionDepthStencilAttachment :: Maybe Attachment.Reference,
+	descriptionPreserveAttachments :: [Word32] }
+	deriving Show
+
+descriptionToCore :: Description -> (C.Description -> IO r) -> IO r
+descriptionToCore Description {
+	descriptionFlags = DescriptionFlagBits flgs,
+	descriptionPipelineBindPoint = Pipeline.BindPoint bp,
+	descriptionInputAttachments =
+		length &&& (Attachment.referenceToCore <$>) -> (iac, ias),
+	descriptionColorAndResolveAttachments =
+		(length &&& id)
+			. either (, Nothing) ((Just `second`) . unzip) ->
+		(cac, (	(Attachment.referenceToCore <$>) -> cas,
+			((Attachment.referenceToCore <$>) <$>) -> mras)),
+	descriptionDepthStencilAttachment =
+		(Attachment.referenceToCore <$>) -> mdsa,
+	descriptionPreserveAttachments = length &&& id -> (pac, pas) } f =
+	allocaArray iac \pias ->
+	pokeArray pias ias >>
+	allocaArray cac \pcas ->
+	pokeArray pcas cas >>
+	maybe ($ NullPtr)
+		(\ras g -> allocaArray cac \p -> pokeArray p ras >> g p)
+		mras \pras ->
+	maybe ($ NullPtr)
+		(\dsa g -> alloca \p -> poke p dsa >> g p) mdsa \pdsa ->
+	allocaArray pac \ppas ->
+	pokeArray ppas pas >>
+	f C.Description {
+		C.descriptionFlags = flgs,
+		C.descriptionPipelineBindPoint = bp,
+		C.descriptionInputAttachmentCount = fromIntegral iac,
+		C.descriptionPInputAttachments = pias,
+		C.descriptionColorAttachmentCount = fromIntegral cac,
+		C.descriptionPColorAttachments = pcas,
+		C.descriptionPResolveAttachments = pras,
+		C.descriptionPDepthStencilAttachment = pdsa,
+		C.descriptionPreserveAttachmentCount = fromIntegral pac,
+		C.descriptionPPreserveAttachments = ppas }
+
+enum "S" ''#{type uint32_t} [''Show, ''Storable, ''Num]
+	[("SExternal", #{const VK_SUBPASS_EXTERNAL})]
+
+data Dependency = Dependency {
+	dependencySrcSubpass :: S,
+	dependencyDstSubpass :: S,
+	dependencySrcStageMask :: Pipeline.StageFlags,
+	dependencyDstStageMask :: Pipeline.StageFlags,
+	dependencySrcAccessMask :: AccessFlags,
+	dependencyDstAccessMask :: AccessFlags,
+	dependencyDependencyFlags :: DependencyFlags }
+	deriving Show
+
+dependencyToCore :: Dependency -> C.Dependency
+dependencyToCore Dependency {
+	dependencySrcSubpass = S ss,
+	dependencyDstSubpass = S ds,
+	dependencySrcStageMask = Pipeline.StageFlagBits ssm,
+	dependencyDstStageMask = Pipeline.StageFlagBits dsm,
+	dependencySrcAccessMask = AccessFlagBits sam,
+	dependencyDstAccessMask = AccessFlagBits dam,
+	dependencyDependencyFlags = DependencyFlagBits flgs } = C.Dependency {
+		C.dependencySrcSubpass = ss,
+		C.dependencyDstSubpass = ds,
+		C.dependencySrcStageMask = ssm,
+		C.dependencyDstStageMask = dsm,
+		C.dependencySrcAccessMask = sam,
+		C.dependencyDstAccessMask = dam,
+		C.dependencyDependencyFlags = flgs }
diff --git a/src/Gpu/Vulkan/VertexInput/Enum.hsc b/src/Gpu/Vulkan/VertexInput/Enum.hsc
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/VertexInput/Enum.hsc
@@ -0,0 +1,22 @@
+-- This file is automatically generated by the tools/makeEnum.hs
+--	% stack runghc --cwd tools/ makeEnum
+
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# OPTIONS_GHC -Wall -fno-warn-missing-export-lists -fno-warn-tabs #-}
+
+module Gpu.Vulkan.VertexInput.Enum where
+
+import Foreign.Storable
+import Foreign.C.Enum
+import Data.Word
+
+#include <vulkan/vulkan.h>
+
+enum "Rate" ''#{type VkVertexInputRate}
+		[''Show, ''Eq, ''Storable] [
+	("RateVertex", #{const VK_VERTEX_INPUT_RATE_VERTEX}),
+	("RateInstance", #{const VK_VERTEX_INPUT_RATE_INSTANCE}),
+	("RateMaxEnum", #{const VK_VERTEX_INPUT_RATE_MAX_ENUM}) ]
diff --git a/src/Gpu/Vulkan/VertexInput/Middle.hs b/src/Gpu/Vulkan/VertexInput/Middle.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/VertexInput/Middle.hs
@@ -0,0 +1,13 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.VertexInput.Middle (
+
+	-- * ATTRIBUTE DESCRIPTION
+
+	AttributeDescription(..),
+
+	-- * BINDING DESCRIPTION
+
+	BindingDescription(..) ) where
+
+import Gpu.Vulkan.VertexInput.Middle.Internal
diff --git a/src/Gpu/Vulkan/VertexInput/Middle/Internal.hs b/src/Gpu/Vulkan/VertexInput/Middle/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Gpu/Vulkan/VertexInput/Middle/Internal.hs
@@ -0,0 +1,49 @@
+{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
+
+module Gpu.Vulkan.VertexInput.Middle.Internal where
+
+import Data.Word
+
+import Gpu.Vulkan.Enum
+
+import qualified Gpu.Vulkan.VertexInput.Enum as E
+import qualified Gpu.Vulkan.VertexInput.Core as C
+
+data BindingDescription = BindingDescription {
+	bindingDescriptionBinding :: Word32,
+	bindingDescriptionStride :: Word32,
+	bindingDescriptionInputRate :: E.Rate }
+	deriving Show
+
+bindingDescriptionToCore :: BindingDescription -> C.BindingDescription
+bindingDescriptionToCore BindingDescription {
+	bindingDescriptionBinding = bd,
+	bindingDescriptionStride = st,
+	bindingDescriptionInputRate = E.Rate ir
+	} = C.BindingDescription {
+		C.bindingDescriptionBinding = bd,
+		C.bindingDescriptionStride = st,
+		C.bindingDescriptionInputRate = ir }
+
+data AttributeDescription = AttributeDescription {
+	attributeDescriptionLocation :: Word32,
+	attributeDescriptionBinding :: Word32,
+	attributeDescriptionFormat :: Format,
+	attributeDescriptionOffset :: Word32 }
+	deriving Show
+
+attributeDescriptionToCore :: AttributeDescription -> C.AttributeDescription
+attributeDescriptionToCore AttributeDescription {
+	attributeDescriptionLocation = loc,
+	attributeDescriptionBinding = bnd,
+	attributeDescriptionFormat = Format fmt,
+	attributeDescriptionOffset = oft } = C.AttributeDescription {
+		C.attributeDescriptionLocation = loc,
+		C.attributeDescriptionBinding = bnd,
+		C.attributeDescriptionFormat = fmt,
+		C.attributeDescriptionOffset = oft }
+
+succAttributeDescriptionLocation :: AttributeDescription -> AttributeDescription
+succAttributeDescriptionLocation
+	ad@AttributeDescription { attributeDescriptionLocation = loc } =
+	ad { attributeDescriptionLocation = loc + 1 }
diff --git a/test/Spec.hs b/test/Spec.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec.hs
@@ -0,0 +1,2 @@
+main :: IO ()
+main = putStrLn "Test suite not yet implemented"
diff --git a/th/vkFormat.txt b/th/vkFormat.txt
new file mode 100644
--- /dev/null
+++ b/th/vkFormat.txt
@@ -0,0 +1,303 @@
+FormatUndefined
+FormatR4g4UnormPack8
+FormatR4g4b4a4UnormPack16
+FormatB4g4r4a4UnormPack16
+FormatR5g6b5UnormPack16
+FormatB5g6r5UnormPack16
+FormatR5g5b5a1UnormPack16
+FormatB5g5r5a1UnormPack16
+FormatA1r5g5b5UnormPack16
+FormatR8Unorm
+FormatR8Snorm
+FormatR8Uscaled
+FormatR8Sscaled
+FormatR8Uint
+FormatR8Sint
+FormatR8Srgb
+FormatR8g8Unorm
+FormatR8g8Snorm
+FormatR8g8Uscaled
+FormatR8g8Sscaled
+FormatR8g8Uint
+FormatR8g8Sint
+FormatR8g8Srgb
+FormatR8g8b8Unorm
+FormatR8g8b8Snorm
+FormatR8g8b8Uscaled
+FormatR8g8b8Sscaled
+FormatR8g8b8Uint
+FormatR8g8b8Sint
+FormatR8g8b8Srgb
+FormatB8g8r8Unorm
+FormatB8g8r8Snorm
+FormatB8g8r8Uscaled
+FormatB8g8r8Sscaled
+FormatB8g8r8Uint
+FormatB8g8r8Sint
+FormatB8g8r8Srgb
+FormatR8g8b8a8Unorm
+FormatR8g8b8a8Snorm
+FormatR8g8b8a8Uscaled
+FormatR8g8b8a8Sscaled
+FormatR8g8b8a8Uint
+FormatR8g8b8a8Sint
+FormatR8g8b8a8Srgb
+FormatB8g8r8a8Unorm
+FormatB8g8r8a8Snorm
+FormatB8g8r8a8Uscaled
+FormatB8g8r8a8Sscaled
+FormatB8g8r8a8Uint
+FormatB8g8r8a8Sint
+FormatB8g8r8a8Srgb
+FormatA8b8g8r8UnormPack32
+FormatA8b8g8r8SnormPack32
+FormatA8b8g8r8UscaledPack32
+FormatA8b8g8r8SscaledPack32
+FormatA8b8g8r8UintPack32
+FormatA8b8g8r8SintPack32
+FormatA8b8g8r8SrgbPack32
+FormatA2r10g10b10UnormPack32
+FormatA2r10g10b10SnormPack32
+FormatA2r10g10b10UscaledPack32
+FormatA2r10g10b10SscaledPack32
+FormatA2r10g10b10UintPack32
+FormatA2r10g10b10SintPack32
+FormatA2b10g10r10UnormPack32
+FormatA2b10g10r10SnormPack32
+FormatA2b10g10r10UscaledPack32
+FormatA2b10g10r10SscaledPack32
+FormatA2b10g10r10UintPack32
+FormatA2b10g10r10SintPack32
+FormatR16Unorm
+FormatR16Snorm
+FormatR16Uscaled
+FormatR16Sscaled
+FormatR16Uint
+FormatR16Sint
+FormatR16Sfloat
+FormatR16g16Unorm
+FormatR16g16Snorm
+FormatR16g16Uscaled
+FormatR16g16Sscaled
+FormatR16g16Uint
+FormatR16g16Sint
+FormatR16g16Sfloat
+FormatR16g16b16Unorm
+FormatR16g16b16Snorm
+FormatR16g16b16Uscaled
+FormatR16g16b16Sscaled
+FormatR16g16b16Uint
+FormatR16g16b16Sint
+FormatR16g16b16Sfloat
+FormatR16g16b16a16Unorm
+FormatR16g16b16a16Snorm
+FormatR16g16b16a16Uscaled
+FormatR16g16b16a16Sscaled
+FormatR16g16b16a16Uint
+FormatR16g16b16a16Sint
+FormatR16g16b16a16Sfloat
+FormatR32Uint
+FormatR32Sint
+FormatR32Sfloat
+FormatR32g32Uint
+FormatR32g32Sint
+FormatR32g32Sfloat
+FormatR32g32b32Uint
+FormatR32g32b32Sint
+FormatR32g32b32Sfloat
+FormatR32g32b32a32Uint
+FormatR32g32b32a32Sint
+FormatR32g32b32a32Sfloat
+FormatR64Uint
+FormatR64Sint
+FormatR64Sfloat
+FormatR64g64Uint
+FormatR64g64Sint
+FormatR64g64Sfloat
+FormatR64g64b64Uint
+FormatR64g64b64Sint
+FormatR64g64b64Sfloat
+FormatR64g64b64a64Uint
+FormatR64g64b64a64Sint
+FormatR64g64b64a64Sfloat
+FormatB10g11r11UfloatPack32
+FormatE5b9g9r9UfloatPack32
+FormatD16Unorm
+FormatX8D24UnormPack32
+FormatD32Sfloat
+FormatS8Uint
+FormatD16UnormS8Uint
+FormatD24UnormS8Uint
+FormatD32SfloatS8Uint
+FormatBc1RgbUnormBlock
+FormatBc1RgbSrgbBlock
+FormatBc1RgbaUnormBlock
+FormatBc1RgbaSrgbBlock
+FormatBc2UnormBlock
+FormatBc2SrgbBlock
+FormatBc3UnormBlock
+FormatBc3SrgbBlock
+FormatBc4UnormBlock
+FormatBc4SnormBlock
+FormatBc5UnormBlock
+FormatBc5SnormBlock
+FormatBc6hUfloatBlock
+FormatBc6hSfloatBlock
+FormatBc7UnormBlock
+FormatBc7SrgbBlock
+FormatEtc2R8g8b8UnormBlock
+FormatEtc2R8g8b8SrgbBlock
+FormatEtc2R8g8b8a1UnormBlock
+FormatEtc2R8g8b8a1SrgbBlock
+FormatEtc2R8g8b8a8UnormBlock
+FormatEtc2R8g8b8a8SrgbBlock
+FormatEacR11UnormBlock
+FormatEacR11SnormBlock
+FormatEacR11g11UnormBlock
+FormatEacR11g11SnormBlock
+FormatAstc4x4UnormBlock
+FormatAstc4x4SrgbBlock
+FormatAstc5x4UnormBlock
+FormatAstc5x4SrgbBlock
+FormatAstc5x5UnormBlock
+FormatAstc5x5SrgbBlock
+FormatAstc6x5UnormBlock
+FormatAstc6x5SrgbBlock
+FormatAstc6x6UnormBlock
+FormatAstc6x6SrgbBlock
+FormatAstc8x5UnormBlock
+FormatAstc8x5SrgbBlock
+FormatAstc8x6UnormBlock
+FormatAstc8x6SrgbBlock
+FormatAstc8x8UnormBlock
+FormatAstc8x8SrgbBlock
+FormatAstc10x5UnormBlock
+FormatAstc10x5SrgbBlock
+FormatAstc10x6UnormBlock
+FormatAstc10x6SrgbBlock
+FormatAstc10x8UnormBlock
+FormatAstc10x8SrgbBlock
+FormatAstc10x10UnormBlock
+FormatAstc10x10SrgbBlock
+FormatAstc12x10UnormBlock
+FormatAstc12x10SrgbBlock
+FormatAstc12x12UnormBlock
+FormatAstc12x12SrgbBlock
+FormatG8b8g8r8422Unorm
+FormatB8g8r8g8422Unorm
+FormatG8B8R83plane420Unorm
+FormatG8B8r82plane420Unorm
+FormatG8B8R83plane422Unorm
+FormatG8B8r82plane422Unorm
+FormatG8B8R83plane444Unorm
+FormatR10x6UnormPack16
+FormatR10x6g10x6Unorm2pack16
+FormatR10x6g10x6b10x6a10x6Unorm4pack16
+FormatG10x6b10x6g10x6r10x6422Unorm4pack16
+FormatB10x6g10x6r10x6g10x6422Unorm4pack16
+FormatG10x6B10x6R10x63plane420Unorm3pack16
+FormatG10x6B10x6r10x62plane420Unorm3pack16
+FormatG10x6B10x6R10x63plane422Unorm3pack16
+FormatG10x6B10x6r10x62plane422Unorm3pack16
+FormatG10x6B10x6R10x63plane444Unorm3pack16
+FormatR12x4UnormPack16
+FormatR12x4g12x4Unorm2pack16
+FormatR12x4g12x4b12x4a12x4Unorm4pack16
+FormatG12x4b12x4g12x4r12x4422Unorm4pack16
+FormatB12x4g12x4r12x4g12x4422Unorm4pack16
+FormatG12x4B12x4R12x43plane420Unorm3pack16
+FormatG12x4B12x4r12x42plane420Unorm3pack16
+FormatG12x4B12x4R12x43plane422Unorm3pack16
+FormatG12x4B12x4r12x42plane422Unorm3pack16
+FormatG12x4B12x4R12x43plane444Unorm3pack16
+FormatG16b16g16r16422Unorm
+FormatB16g16r16g16422Unorm
+FormatG16B16R163plane420Unorm
+FormatG16B16r162plane420Unorm
+FormatG16B16R163plane422Unorm
+FormatG16B16r162plane422Unorm
+FormatG16B16R163plane444Unorm
+FormatG8B8r82plane444Unorm
+FormatG10x6B10x6r10x62plane444Unorm3pack16
+FormatG12x4B12x4r12x42plane444Unorm3pack16
+FormatG16B16r162plane444Unorm
+FormatA4r4g4b4UnormPack16
+FormatA4b4g4r4UnormPack16
+FormatAstc4x4SfloatBlock
+FormatAstc5x4SfloatBlock
+FormatAstc5x5SfloatBlock
+FormatAstc6x5SfloatBlock
+FormatAstc6x6SfloatBlock
+FormatAstc8x5SfloatBlock
+FormatAstc8x6SfloatBlock
+FormatAstc8x8SfloatBlock
+FormatAstc10x5SfloatBlock
+FormatAstc10x6SfloatBlock
+FormatAstc10x8SfloatBlock
+FormatAstc10x10SfloatBlock
+FormatAstc12x10SfloatBlock
+FormatAstc12x12SfloatBlock
+FormatPvrtc12bppUnormBlockImg
+FormatPvrtc14bppUnormBlockImg
+FormatPvrtc22bppUnormBlockImg
+FormatPvrtc24bppUnormBlockImg
+FormatPvrtc12bppSrgbBlockImg
+FormatPvrtc14bppSrgbBlockImg
+FormatPvrtc22bppSrgbBlockImg
+FormatPvrtc24bppSrgbBlockImg
+FormatR16g16S105Nv
+FormatAstc4x4SfloatBlockExt
+FormatAstc5x4SfloatBlockExt
+FormatAstc5x5SfloatBlockExt
+FormatAstc6x5SfloatBlockExt
+FormatAstc6x6SfloatBlockExt
+FormatAstc8x5SfloatBlockExt
+FormatAstc8x6SfloatBlockExt
+FormatAstc8x8SfloatBlockExt
+FormatAstc10x5SfloatBlockExt
+FormatAstc10x6SfloatBlockExt
+FormatAstc10x8SfloatBlockExt
+FormatAstc10x10SfloatBlockExt
+FormatAstc12x10SfloatBlockExt
+FormatAstc12x12SfloatBlockExt
+FormatG8b8g8r8422UnormKhr
+FormatB8g8r8g8422UnormKhr
+FormatG8B8R83plane420UnormKhr
+FormatG8B8r82plane420UnormKhr
+FormatG8B8R83plane422UnormKhr
+FormatG8B8r82plane422UnormKhr
+FormatG8B8R83plane444UnormKhr
+FormatR10x6UnormPack16Khr
+FormatR10x6g10x6Unorm2pack16Khr
+FormatR10x6g10x6b10x6a10x6Unorm4pack16Khr
+FormatG10x6b10x6g10x6r10x6422Unorm4pack16Khr
+FormatB10x6g10x6r10x6g10x6422Unorm4pack16Khr
+FormatG10x6B10x6R10x63plane420Unorm3pack16Khr
+FormatG10x6B10x6r10x62plane420Unorm3pack16Khr
+FormatG10x6B10x6R10x63plane422Unorm3pack16Khr
+FormatG10x6B10x6r10x62plane422Unorm3pack16Khr
+FormatG10x6B10x6R10x63plane444Unorm3pack16Khr
+FormatR12x4UnormPack16Khr
+FormatR12x4g12x4Unorm2pack16Khr
+FormatR12x4g12x4b12x4a12x4Unorm4pack16Khr
+FormatG12x4b12x4g12x4r12x4422Unorm4pack16Khr
+FormatB12x4g12x4r12x4g12x4422Unorm4pack16Khr
+FormatG12x4B12x4R12x43plane420Unorm3pack16Khr
+FormatG12x4B12x4r12x42plane420Unorm3pack16Khr
+FormatG12x4B12x4R12x43plane422Unorm3pack16Khr
+FormatG12x4B12x4r12x42plane422Unorm3pack16Khr
+FormatG12x4B12x4R12x43plane444Unorm3pack16Khr
+FormatG16b16g16r16422UnormKhr
+FormatB16g16r16g16422UnormKhr
+FormatG16B16R163plane420UnormKhr
+FormatG16B16r162plane420UnormKhr
+FormatG16B16R163plane422UnormKhr
+FormatG16B16r162plane422UnormKhr
+FormatG16B16R163plane444UnormKhr
+FormatG8B8r82plane444UnormExt
+FormatG10x6B10x6r10x62plane444Unorm3pack16Ext
+FormatG12x4B12x4r12x42plane444Unorm3pack16Ext
+FormatG16B16r162plane444UnormExt
+FormatA4r4g4b4UnormPack16Ext
+FormatA4b4g4r4UnormPack16Ext
+FormatMaxEnum
diff --git a/th/vkPhysicalDeviceDescriptorIndexingFeatures.txt b/th/vkPhysicalDeviceDescriptorIndexingFeatures.txt
new file mode 100644
--- /dev/null
+++ b/th/vkPhysicalDeviceDescriptorIndexingFeatures.txt
@@ -0,0 +1,22 @@
+VkStructureType|A sType
+void*|A pNext
+VkBool32|A shaderInputAttachmentArrayDynamicIndexing
+VkBool32|A shaderUniformTexelBufferArrayDynamicIndexing
+VkBool32|A shaderStorageTexelBufferArrayDynamicIndexing
+VkBool32|A shaderUniformBufferArrayNonUniformIndexing
+VkBool32|A shaderSampledImageArrayNonUniformIndexing
+VkBool32|A shaderStorageBufferArrayNonUniformIndexing
+VkBool32|A shaderStorageImageArrayNonUniformIndexing
+VkBool32|A shaderInputAttachmentArrayNonUniformIndexing
+VkBool32|A shaderUniformTexelBufferArrayNonUniformIndexing
+VkBool32|A shaderStorageTexelBufferArrayNonUniformIndexing
+VkBool32|A descriptorBindingUniformBufferUpdateAfterBind
+VkBool32|A descriptorBindingSampledImageUpdateAfterBind
+VkBool32|A descriptorBindingStorageImageUpdateAfterBind
+VkBool32|A descriptorBindingStorageBufferUpdateAfterBind
+VkBool32|A descriptorBindingUniformTexelBufferUpdateAfterBind
+VkBool32|A descriptorBindingStorageTexelBufferUpdateAfterBind
+VkBool32|A descriptorBindingUpdateUnusedWhilePending
+VkBool32|A descriptorBindingPartiallyBound
+VkBool32|A descriptorBindingVariableDescriptorCount
+VkBool32|A runtimeDescriptorArray
diff --git a/th/vkPhysicalDeviceFeatures.txt b/th/vkPhysicalDeviceFeatures.txt
new file mode 100644
--- /dev/null
+++ b/th/vkPhysicalDeviceFeatures.txt
@@ -0,0 +1,55 @@
+VkBool32|A robustBufferAccess
+VkBool32|A fullDrawIndexUint32
+VkBool32|A imageCubeArray
+VkBool32|A independentBlend
+VkBool32|A geometryShader
+VkBool32|A tessellationShader
+VkBool32|A sampleRateShading
+VkBool32|A dualSrcBlend
+VkBool32|A logicOp
+VkBool32|A multiDrawIndirect
+VkBool32|A drawIndirectFirstInstance
+VkBool32|A depthClamp
+VkBool32|A depthBiasClamp
+VkBool32|A fillModeNonSolid
+VkBool32|A depthBounds
+VkBool32|A wideLines
+VkBool32|A largePoints
+VkBool32|A alphaToOne
+VkBool32|A multiViewport
+VkBool32|A samplerAnisotropy
+VkBool32|A textureCompressionETC2
+VkBool32|A textureCompressionASTC_LDR
+VkBool32|A textureCompressionBC
+VkBool32|A occlusionQueryPrecise
+VkBool32|A pipelineStatisticsQuery
+VkBool32|A vertexPipelineStoresAndAtomics
+VkBool32|A fragmentStoresAndAtomics
+VkBool32|A shaderTessellationAndGeometryPointSize
+VkBool32|A shaderImageGatherExtended
+VkBool32|A shaderStorageImageExtendedFormats
+VkBool32|A shaderStorageImageMultisample
+VkBool32|A shaderStorageImageReadWithoutFormat
+VkBool32|A shaderStorageImageWriteWithoutFormat
+VkBool32|A shaderUniformBufferArrayDynamicIndexing
+VkBool32|A shaderSampledImageArrayDynamicIndexing
+VkBool32|A shaderStorageBufferArrayDynamicIndexing
+VkBool32|A shaderStorageImageArrayDynamicIndexing
+VkBool32|A shaderClipDistance
+VkBool32|A shaderCullDistance
+VkBool32|A shaderFloat64
+VkBool32|A shaderInt64
+VkBool32|A shaderInt16
+VkBool32|A shaderResourceResidency
+VkBool32|A shaderResourceMinLod
+VkBool32|A sparseBinding
+VkBool32|A sparseResidencyBuffer
+VkBool32|A sparseResidencyImage2D
+VkBool32|A sparseResidencyImage3D
+VkBool32|A sparseResidency2Samples
+VkBool32|A sparseResidency4Samples
+VkBool32|A sparseResidency8Samples
+VkBool32|A sparseResidency16Samples
+VkBool32|A sparseResidencyAliased
+VkBool32|A variableMultisampleRate
+VkBool32|A inheritedQueries
diff --git a/th/vkPhysicalDeviceLimits.txt b/th/vkPhysicalDeviceLimits.txt
new file mode 100644
--- /dev/null
+++ b/th/vkPhysicalDeviceLimits.txt
@@ -0,0 +1,106 @@
+uint32_t|A maxImageDimension1D
+uint32_t|A maxImageDimension2D
+uint32_t|A maxImageDimension3D
+uint32_t|A maxImageDimensionCube
+uint32_t|A maxImageArrayLayers
+uint32_t|A maxTexelBufferElements
+uint32_t|A maxUniformBufferRange
+uint32_t|A maxStorageBufferRange
+uint32_t|A maxPushConstantsSize
+uint32_t|A maxMemoryAllocationCount
+uint32_t|A maxSamplerAllocationCount
+VkDeviceSize|A bufferImageGranularity
+VkDeviceSize|A sparseAddressSpaceSize
+uint32_t|A maxBoundDescriptorSets
+uint32_t|A maxPerStageDescriptorSamplers
+uint32_t|A maxPerStageDescriptorUniformBuffers
+uint32_t|A maxPerStageDescriptorStorageBuffers
+uint32_t|A maxPerStageDescriptorSampledImages
+uint32_t|A maxPerStageDescriptorStorageImages
+uint32_t|A maxPerStageDescriptorInputAttachments
+uint32_t|A maxPerStageResources
+uint32_t|A maxDescriptorSetSamplers
+uint32_t|A maxDescriptorSetUniformBuffers
+uint32_t|A maxDescriptorSetUniformBuffersDynamic
+uint32_t|A maxDescriptorSetStorageBuffers
+uint32_t|A maxDescriptorSetStorageBuffersDynamic
+uint32_t|A maxDescriptorSetSampledImages
+uint32_t|A maxDescriptorSetStorageImages
+uint32_t|A maxDescriptorSetInputAttachments
+uint32_t|A maxVertexInputAttributes
+uint32_t|A maxVertexInputBindings
+uint32_t|A maxVertexInputAttributeOffset
+uint32_t|A maxVertexInputBindingStride
+uint32_t|A maxVertexOutputComponents
+uint32_t|A maxTessellationGenerationLevel
+uint32_t|A maxTessellationPatchSize
+uint32_t|A maxTessellationControlPerVertexInputComponents
+uint32_t|A maxTessellationControlPerVertexOutputComponents
+uint32_t|A maxTessellationControlPerPatchOutputComponents
+uint32_t|A maxTessellationControlTotalOutputComponents
+uint32_t|A maxTessellationEvaluationInputComponents
+uint32_t|A maxTessellationEvaluationOutputComponents
+uint32_t|A maxGeometryShaderInvocations
+uint32_t|A maxGeometryInputComponents
+uint32_t|A maxGeometryOutputComponents
+uint32_t|A maxGeometryOutputVertices
+uint32_t|A maxGeometryTotalOutputComponents
+uint32_t|A maxFragmentInputComponents
+uint32_t|A maxFragmentOutputAttachments
+uint32_t|A maxFragmentDualSrcAttachments
+uint32_t|A maxFragmentCombinedOutputResources
+uint32_t|A maxComputeSharedMemorySize
+uint32_t|L maxComputeWorkGroupCount 3
+uint32_t|A maxComputeWorkGroupInvocations
+uint32_t|L maxComputeWorkGroupSize 3
+uint32_t|A subPixelPrecisionBits
+uint32_t|A subTexelPrecisionBits
+uint32_t|A mipmapPrecisionBits
+uint32_t|A maxDrawIndexedIndexValue
+uint32_t|A maxDrawIndirectCount
+float|A maxSamplerLodBias
+float|A maxSamplerAnisotropy
+uint32_t|A maxViewports
+uint32_t|L maxViewportDimensions 2
+float|L viewportBoundsRange 2
+uint32_t|A viewportSubPixelBits
+size_t|A minMemoryMapAlignment
+VkDeviceSize|A minTexelBufferOffsetAlignment
+VkDeviceSize|A minUniformBufferOffsetAlignment
+VkDeviceSize|A minStorageBufferOffsetAlignment
+int32_t|A minTexelOffset
+uint32_t|A maxTexelOffset
+int32_t|A minTexelGatherOffset
+uint32_t|A maxTexelGatherOffset
+float|A minInterpolationOffset
+float|A maxInterpolationOffset
+uint32_t|A subPixelInterpolationOffsetBits
+uint32_t|A maxFramebufferWidth
+uint32_t|A maxFramebufferHeight
+uint32_t|A maxFramebufferLayers
+VkSampleCountFlags|A framebufferColorSampleCounts
+VkSampleCountFlags|A framebufferDepthSampleCounts
+VkSampleCountFlags|A framebufferStencilSampleCounts
+VkSampleCountFlags|A framebufferNoAttachmentsSampleCounts
+uint32_t|A maxColorAttachments
+VkSampleCountFlags|A sampledImageColorSampleCounts
+VkSampleCountFlags|A sampledImageIntegerSampleCounts
+VkSampleCountFlags|A sampledImageDepthSampleCounts
+VkSampleCountFlags|A sampledImageStencilSampleCounts
+VkSampleCountFlags|A storageImageSampleCounts
+uint32_t|A maxSampleMaskWords
+VkBool32|A timestampComputeAndGraphics
+float|A timestampPeriod
+uint32_t|A maxClipDistances
+uint32_t|A maxCullDistances
+uint32_t|A maxCombinedClipAndCullDistances
+uint32_t|A discreteQueuePriorities
+float|L pointSizeRange 2
+float|L lineWidthRange 2
+float|A pointSizeGranularity
+float|A lineWidthGranularity
+VkBool32|A strictLines
+VkBool32|A standardSampleLocations
+VkDeviceSize|A optimalBufferCopyOffsetAlignment
+VkDeviceSize|A optimalBufferCopyRowPitchAlignment
+VkDeviceSize|A nonCoherentAtomSize
diff --git a/th/vkShaderStageFlagBits.txt b/th/vkShaderStageFlagBits.txt
new file mode 100644
--- /dev/null
+++ b/th/vkShaderStageFlagBits.txt
@@ -0,0 +1,28 @@
+ShaderStageFlagsZero
+ShaderStageVertexBit
+ShaderStageTessellationControlBit
+ShaderStageTessellationEvaluationBit
+ShaderStageGeometryBit
+ShaderStageFragmentBit
+ShaderStageComputeBit
+ShaderStageAllGraphics
+ShaderStageAll
+ShaderStageRaygenBitKhr
+ShaderStageAnyHitBitKhr
+ShaderStageClosestHitBitKhr
+ShaderStageMissBitKhr
+ShaderStageIntersectionBitKhr
+ShaderStageCallableBitKhr
+ShaderStageTaskBitExt
+ShaderStageMeshBitExt
+ShaderStageSubpassShadingBitHuawei
+ShaderStageClusterCullingBitHuawei
+ShaderStageRaygenBitNv
+ShaderStageAnyHitBitNv
+ShaderStageClosestHitBitNv
+ShaderStageMissBitNv
+ShaderStageIntersectionBitNv
+ShaderStageCallableBitNv
+ShaderStageTaskBitNv
+ShaderStageMeshBitNv
+ShaderStageFlagBitsMaxEnum
