diff --git a/ChangeLog.md b/ChangeLog.md index 209e54b..b76435a 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,5 +1,15 @@ # Changelog for dear-imgui +## [2.3.0] + +- `imgui` updated to [1.90.9]. + * Breaking: `sdlRendererRenderDrawData` now required `Renderer` arg. + * Breaking: ImplVulkan removed command buffer for `ImGui_ImplVulkan_CreateFontsTexture`. + * Breaking: ImplVulkan removed command for `ImGui_ImplVulkan_DestroyFontUploadObjects`. + + Added `ImGui_ImplVulkan_DestroyFontsTexture`, but it shouldn't be needed as it is called from impl internals. + * Breaking: ImplVulkan moved RenderPass into InitInfo structure. + + Breaking: Haskell API is now using `Either RenderPass RenderingPipelineCreateInfo` to switch between RP/dynamic rendering. + ## [2.2.1] - Added `DearImGui.SDL.Renderer` backend and `sdlrenderer` example. @@ -125,7 +135,9 @@ Initial Hackage release based on [1.83]. [2.1.3]: https://github.com/haskell-game/dear-imgui.hs/tree/v2.1.3 [2.2.0]: https://github.com/haskell-game/dear-imgui.hs/tree/v2.2.0 [2.2.1]: https://github.com/haskell-game/dear-imgui.hs/tree/v2.2.1 +[2.3.0]: https://github.com/haskell-game/dear-imgui.hs/tree/v2.3.0 +[1.90.9]: https://github.com/ocornut/imgui/releases/tag/v1.90.9 [1.89.9]: https://github.com/ocornut/imgui/releases/tag/v1.89.9 [1.87]: https://github.com/ocornut/imgui/releases/tag/v1.87 [1.86]: https://github.com/ocornut/imgui/releases/tag/v1.86 diff --git a/dear-imgui.cabal b/dear-imgui.cabal index c2e2112..6ce56d6 100644 --- a/dear-imgui.cabal +++ b/dear-imgui.cabal @@ -1,7 +1,7 @@ cabal-version: 3.0 name: dear-imgui -version: 2.2.1 +version: 2.3.0 author: Oliver Charles maintainer: ollie@ocharles.org.uk, aenor.realm@gmail.com license: BSD-3-Clause diff --git a/examples/sdl/Renderer.hs b/examples/sdl/Renderer.hs index 68e95ad..f76d5e4 100644 --- a/examples/sdl/Renderer.hs +++ b/examples/sdl/Renderer.hs @@ -109,7 +109,7 @@ mainLoop renderer = do SDL.rendererDrawColor renderer $= V4 0 0 0 255 SDL.clear renderer render - sdlRendererRenderDrawData =<< getDrawData + sdlRendererRenderDrawData renderer =<< getDrawData SDL.present renderer go refs diff --git a/examples/vulkan/Main.hs b/examples/vulkan/Main.hs index f3cc821..d9e9eef 100644 --- a/examples/vulkan/Main.hs +++ b/examples/vulkan/Main.hs @@ -391,16 +391,15 @@ app = do , device , queueFamily , queue - , pipelineCache = Vulkan.NULL_HANDLE - , descriptorPool = imGuiDescriptorPool - , subpass = 0 + , pipelineCache = Vulkan.NULL_HANDLE + , descriptorPool = imGuiDescriptorPool + , subpass = 0 , minImageCount , imageCount - , msaaSamples = Vulkan.SAMPLE_COUNT_1_BIT - , mbAllocator = Nothing - , useDynamicRendering = False - , colorAttachmentFormat = Nothing - , checkResult = \case { Vulkan.SUCCESS -> pure (); e -> throw $ Vulkan.VulkanException e } + , msaaSamples = Vulkan.SAMPLE_COUNT_1_BIT + , mbAllocator = Nothing + , rendering = Left imGuiRenderPass + , checkResult = \case { Vulkan.SUCCESS -> pure (); e -> throw $ Vulkan.VulkanException e } } logDebug "Initialising ImGui SDL2 for Vulkan" @@ -409,7 +408,7 @@ app = do ( const ImGui.SDL.sdl2Shutdown ) logDebug "Initialising ImGui for Vulkan" - ImGui.Vulkan.withVulkan initInfo imGuiRenderPass \ _ -> do + ImGui.Vulkan.withVulkan initInfo \ _ -> do logDebug "Running one-shot commands to upload ImGui textures" logDebug "Creating fence" @@ -421,7 +420,9 @@ app = do logDebug "Recording one-shot commands" beginCommandBuffer oneshotCommandBuffer - _ <- ImGui.Vulkan.vulkanCreateFontsTexture oneshotCommandBuffer + + logDebug "ImGui preparing fonts texture" + _ <- ImGui.Vulkan.vulkanCreateFontsTexture logDebug "Uploading texture" let textureSubresource = Vulkan.ImageSubresourceRange @@ -497,8 +498,6 @@ app = do waitForFences device ( WaitAll [ fence ] ) logDebug "Finished uploading font objects" - logDebug "Cleaning up one-shot commands" - ImGui.Vulkan.vulkanDestroyFontUploadObjects traverse_ ResourceT.release [ fenceKey, oneshotCommandBufferKey, stageKey ] logDebug "Adding imgui texture" diff --git a/generator/DearImGui/Generator/Parser.hs b/generator/DearImGui/Generator/Parser.hs index db7399c..b11a968 100644 --- a/generator/DearImGui/Generator/Parser.hs +++ b/generator/DearImGui/Generator/Parser.hs @@ -27,7 +27,7 @@ import Data.Bits import Data.Char ( isSpace, toLower ) import Data.Either - ( partitionEithers ) + ( rights ) import Data.Functor ( ($>) ) import Data.Int @@ -35,7 +35,7 @@ import Data.Int import Data.Maybe ( catMaybes, fromMaybe ) import Foreign.C.Types - ( CInt ) + ( CChar, CInt, CShort, CLLong, CUChar, CUShort, CUInt, CULLong ) -- template-haskell import qualified Language.Haskell.TH as TH @@ -44,7 +44,7 @@ import qualified Language.Haskell.TH as TH -- megaparsec import Text.Megaparsec ( MonadParsec(..), ShowErrorComponent(..) - , (), anySingle, customFailure, single + , (), anySingle, choice, customFailure, single ) -- parser-combinators @@ -126,13 +126,24 @@ headers = do _ <- skipManyTill anySingle ( namedSection "Dear ImGui end-user API functions" ) _ <- skipManyTill anySingle ( namedSection "Flags & Enumerations" ) - ( _defines, basicEnums ) <- partitionEithers <$> + + basicEnums <- rights <$> + manyTill + ( ( Left <$> try ignoreDefine ) + <|> ( Left <$> try cppConditional ) + <|> ( Right <$> enumeration enumNamesAndTypes ) + ) + ( namedSection "Tables API flags and structures (ImGuiTableFlags, ImGuiTableColumnFlags, ImGuiTableRowFlags, ImGuiTableBgTarget, ImGuiTableSortSpecs, ImGuiTableColumnSortSpecs)" ) + + tableEnums <- rights <$> manyTill ( ( Left <$> try ignoreDefine ) <|> ( Left <$> try cppConditional ) <|> ( Right <$> enumeration enumNamesAndTypes ) ) - ( namedSection "Helpers: Memory allocations macros, ImVector<>" ) + ( try $ many comment >> keyword "struct" >> identifier) + + _ <- skipManyTill anySingle ( namedSection "Helpers: Memory allocations macros, ImVector<>" ) _ <- skipManyTill anySingle ( namedSection "ImGuiStyle" ) @@ -158,7 +169,7 @@ headers = do let enums :: [ Enumeration () ] - enums = basicEnums <> drawingEnums <> fontEnums + enums = basicEnums <> tableEnums <> drawingEnums <> fontEnums pure ( Headers { enums } ) -------------------------------------------------------------------------------- @@ -169,6 +180,15 @@ forwardDeclarations => m ( HashMap Text Comment, HashMap Text ( TH.Name, Comment ) ) forwardDeclarations = do _ <- many comment + _scalars <- many do + try $ keyword "typedef" + signed <- try (keyword "signed" $> True) <|> (keyword "unsigned" $> False) + width <- try (keyword "int") <|> try (keyword "char") <|> try (keyword "short") <|> try (keyword "int") <|> (keyword "long" >> keyword "long") + typeName <- identifier + reservedSymbol ';' + doc <- comment + pure (typeName, (signed, width, doc)) + _ <- many comment structs <- many do keyword "struct" structName <- identifier @@ -177,6 +197,9 @@ forwardDeclarations = do pure ( structName, doc ) _ <- many comment enums <- many do + _ <- try do + _ <- many comment + cppConditional <|> pure () keyword "enum" enumName <- identifier symbol ":" @@ -197,7 +220,23 @@ forwardDeclarations = do pure ( HashMap.fromList structs, HashMap.fromList (enums <> typedefs) ) cTypeName :: MonadParsec e [Tok] m => m TH.Name -cTypeName = keyword "int" $> ''CInt +cTypeName = + choice + [ try $ (keyword "char") $> ''CChar + , try $ (keyword "signed" >> keyword "int") $> ''CInt + , try $ (keyword "unsigned" >> keyword "int") $> ''CUInt + , try $ (keyword "unsigned" >> keyword "char") $> ''CUChar + , try $ (identifier' "ImS8") $> ''CChar + , try $ (identifier' "ImU8") $> ''CUChar + , try $ (identifier' "ImS16") $> ''CShort + , try $ (identifier' "ImU16") $> ''CUShort + , try $ (identifier' "ImS32") $> ''CInt + , try $ (identifier' "ImU32") $> ''CUInt + , try $ (identifier' "ImS64") $> ''CLLong + , try $ (identifier' "ImU64") $> ''CULLong + , keyword "int" $> ''CInt + ] + "cTypeName" -------------------------------------------------------------------------------- -- Parsing enumerations. @@ -211,6 +250,7 @@ data EnumState = EnumState enumeration :: MonadParsec CustomParseError [Tok] m => HashMap Text ( TH.Name, Comment ) -> m ( Enumeration () ) enumeration enumNamesAndTypes = do + void $ many (try $ comment >> cppConditional) inlineDocs <- try do inlineDocs <- many comment keyword "enum" @@ -331,13 +371,20 @@ comment = CommentText <$> "comment" keyword :: MonadParsec e [ Tok ] m => Text -> m () -keyword kw = token ( \ case { Keyword kw' | kw == kw' -> Just (); _ -> Nothing } ) mempty +keyword = void . keyword' + +keyword' :: MonadParsec e [ Tok ] m => Text -> m Text +keyword' kw = token ( \ case { Keyword kw' | kw == kw' -> Just kw; _ -> Nothing } ) mempty ( Text.unpack kw <> " (keyword)" ) identifier :: MonadParsec e [ Tok ] m => m Text identifier = token ( \ case { Identifier i -> Just i; _ -> Nothing } ) mempty "identifier" +identifier' :: MonadParsec e [ Tok ] m => Text -> m Text +identifier' ident = token ( \ case { Identifier i | i == ident -> Just ident; _ -> Nothing } ) mempty + ( Text.unpack ident <> " (identifier)" ) + {- prefixedIdentifier :: MonadParsec e [ Tok ] m => Text -> m Text prefixedIdentifier prefix = @@ -452,7 +499,7 @@ cppDirective f = token ( \case { BeginCPP a -> f a; _ -> Nothing } ) mempty cppConditional :: MonadParsec e [Tok] m => m () cppConditional = do - void $ cppDirective ( \case { "ifdef" -> Just True; "ifndef" -> Just False; _ -> Nothing } ) + void $ cppDirective ( \case { "if" -> Just True; "ifdef" -> Just True; "ifndef" -> Just False; _ -> Nothing } ) -- assumes no nesting void $ skipManyTill anySingle ( cppDirective ( \case { "endif" -> Just (); _ -> Nothing } ) ) void $ skipManyTill anySingle ( single EndCPPLine ) diff --git a/imgui b/imgui index c6e0284..cb16be3 160000 --- a/imgui +++ b/imgui @@ -1 +1 @@ -Subproject commit c6e0284ac58b3f205c95365478888f7b53b077e2 +Subproject commit cb16be3a3fc1f9cd146ae24d52b615f8a05fa93d diff --git a/src/DearImGui/SDL/Renderer.hs b/src/DearImGui/SDL/Renderer.hs index 416c596..ffe8eb9 100644 --- a/src/DearImGui/SDL/Renderer.hs +++ b/src/DearImGui/SDL/Renderer.hs @@ -69,6 +69,6 @@ sdlRendererNewFrame = liftIO do [C.exp| void { ImGui_ImplSDLRenderer2_NewFrame(); } |] -- | Wraps @ImGui_ImplSDLRenderer2_RenderDrawData@. -sdlRendererRenderDrawData :: MonadIO m => DrawData -> m () -sdlRendererRenderDrawData (DrawData ptr) = liftIO do - [C.exp| void { ImGui_ImplSDLRenderer2_RenderDrawData((ImDrawData*) $( void* ptr )) } |] +sdlRendererRenderDrawData :: MonadIO m => Renderer -> DrawData -> m () +sdlRendererRenderDrawData (Renderer renderPtr) (DrawData ptr) = liftIO do + [C.exp| void { ImGui_ImplSDLRenderer2_RenderDrawData((ImDrawData*) $( void* ptr ), (SDL_Renderer*) $( void* renderPtr )) } |] diff --git a/src/DearImGui/Vulkan.hs b/src/DearImGui/Vulkan.hs index 8a8b9f9..369f035 100644 --- a/src/DearImGui/Vulkan.hs +++ b/src/DearImGui/Vulkan.hs @@ -17,7 +17,7 @@ module DearImGui.Vulkan , vulkanNewFrame , vulkanRenderDrawData , vulkanCreateFontsTexture - , vulkanDestroyFontUploadObjects + , vulkanDestroyFontsTexture , vulkanSetMinImageCount , vulkanAddTexture @@ -27,6 +27,8 @@ module DearImGui.Vulkan -- base import Data.Maybe ( fromMaybe ) +import Data.Either + ( isRight ) import Data.Word ( Word32 ) import Foreign.Marshal.Alloc @@ -56,6 +58,8 @@ import UnliftIO.Exception -- vulkan import qualified Vulkan +import Vulkan.Zero + ( zero ) -- DearImGui import DearImGui @@ -63,8 +67,8 @@ import DearImGui import DearImGui.Vulkan.Types ( vulkanCtx ) - C.context ( Cpp.cppCtx <> C.funCtx <> vulkanCtx ) +C.include "string.h" C.include "imgui.h" C.include "backends/imgui_impl_vulkan.h" Cpp.using "namespace ImGui" @@ -72,28 +76,27 @@ Cpp.using "namespace ImGui" data InitInfo = InitInfo - { instance' :: !Vulkan.Instance - , physicalDevice :: !Vulkan.PhysicalDevice - , device :: !Vulkan.Device - , queueFamily :: !Word32 - , queue :: !Vulkan.Queue - , pipelineCache :: !Vulkan.PipelineCache - , descriptorPool :: !Vulkan.DescriptorPool - , subpass :: !Word32 - , minImageCount :: !Word32 - , imageCount :: !Word32 - , msaaSamples :: !Vulkan.SampleCountFlagBits - , colorAttachmentFormat :: !(Maybe Vulkan.Format) - , useDynamicRendering :: !Bool - , mbAllocator :: Maybe Vulkan.AllocationCallbacks - , checkResult :: Vulkan.Result -> IO () + { instance' :: !Vulkan.Instance + , physicalDevice :: !Vulkan.PhysicalDevice + , device :: !Vulkan.Device + , queueFamily :: !Word32 + , queue :: !Vulkan.Queue + , pipelineCache :: !Vulkan.PipelineCache + , descriptorPool :: !Vulkan.DescriptorPool + , subpass :: !Word32 + , minImageCount :: !Word32 + , imageCount :: !Word32 + , msaaSamples :: !Vulkan.SampleCountFlagBits + , rendering :: Either Vulkan.RenderPass Vulkan.PipelineRenderingCreateInfo + , mbAllocator :: Maybe Vulkan.AllocationCallbacks + , checkResult :: Vulkan.Result -> IO () } -- | Wraps @ImGui_ImplVulkan_Init@ and @ImGui_ImplVulkan_Shutdown@. -withVulkan :: MonadUnliftIO m => InitInfo -> Vulkan.RenderPass -> ( Bool -> m a ) -> m a -withVulkan initInfo renderPass action = +withVulkan :: MonadUnliftIO m => InitInfo -> ( Bool -> m a ) -> m a +withVulkan initInfo action = bracket - ( vulkanInit initInfo renderPass ) + ( vulkanInit initInfo ) vulkanShutdown ( \ ( _, initResult ) -> action initResult ) @@ -101,8 +104,8 @@ withVulkan initInfo renderPass action = -- -- Use 'vulkanShutdown' to clean up on shutdown. -- Prefer using 'withVulkan' when possible, as it automatically handles cleanup. -vulkanInit :: MonadIO m => InitInfo -> Vulkan.RenderPass -> m (FunPtr (Vulkan.Result -> IO ()), Bool) -vulkanInit ( InitInfo {..} ) renderPass = do +vulkanInit :: MonadIO m => InitInfo -> m (FunPtr (Vulkan.Result -> IO ()), Bool) +vulkanInit ( InitInfo {..} ) = liftIO do let instancePtr :: Ptr Vulkan.Instance_T instancePtr = Vulkan.instanceHandle instance' @@ -117,14 +120,20 @@ vulkanInit ( InitInfo {..} ) renderPass = do Nothing -> f nullPtr Just callbacks -> alloca ( \ ptr -> poke ptr callbacks *> f ptr ) useDynamicRendering' :: Cpp.CBool - useDynamicRendering' = fromBool useDynamicRendering - colorAttachmentFormat' :: Vulkan.Format - colorAttachmentFormat' = fromMaybe Vulkan.FORMAT_UNDEFINED colorAttachmentFormat - liftIO do + useDynamicRendering' = fromBool (isRight rendering) + renderPass :: Vulkan.RenderPass + renderPass = either id (const zero) rendering + Vulkan.withCStruct (either (const zero) id rendering) \pipelineRenderingCIPtr -> do checkResultFunPtr <- $( C.mkFunPtr [t| Vulkan.Result -> IO () |] ) checkResult - initResult <- withCallbacks \ callbacksPtr -> + initResult <- withCallbacks \ callbacksPtr -> do [C.block| bool { - ImGui_ImplVulkan_InitInfo initInfo; + ImGui_ImplVulkan_InitInfo initInfo = {0,}; + + #ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING + VkPipelineRenderingCreateInfoKHR pipelineRenderingCI; + memset(&pipelineRenderingCI, 0, sizeof(VkPipelineRenderingCreateInfoKHR)); + #endif + VkInstance instance = { $( VkInstance_T* instancePtr ) }; initInfo.Instance = instance; VkPhysicalDevice physicalDevice = { $( VkPhysicalDevice_T* physicalDevicePtr ) }; @@ -142,9 +151,12 @@ vulkanInit ( InitInfo {..} ) renderPass = do initInfo.MSAASamples = $(VkSampleCountFlagBits msaaSamples); initInfo.Allocator = $(VkAllocationCallbacks* callbacksPtr); initInfo.CheckVkResultFn = $( void (*checkResultFunPtr)(VkResult) ); + initInfo.UseDynamicRendering = $(bool useDynamicRendering'); - initInfo.ColorAttachmentFormat = $(VkFormat colorAttachmentFormat'); - return ImGui_ImplVulkan_Init(&initInfo, $(VkRenderPass renderPass) ); + initInfo.RenderPass = $(VkRenderPass renderPass); + if ($(VkPipelineRenderingCreateInfo* pipelineRenderingCIPtr)) + memcpy(&initInfo.PipelineRenderingCreateInfo, $(VkPipelineRenderingCreateInfo* pipelineRenderingCIPtr), sizeof(VkPipelineRenderingCreateInfo)); + return ImGui_ImplVulkan_Init(&initInfo); }|] pure ( checkResultFunPtr, initResult /= 0 ) @@ -175,22 +187,21 @@ vulkanRenderDrawData (DrawData dataPtr) commandBuffer mbPipeline = liftIO do }|] -- | Wraps @ImGui_ImplVulkan_CreateFontsTexture@. -vulkanCreateFontsTexture :: MonadIO m => Vulkan.CommandBuffer -> m Bool -vulkanCreateFontsTexture commandBuffer = liftIO do - let - commandBufferPtr :: Ptr Vulkan.CommandBuffer_T - commandBufferPtr = Vulkan.commandBufferHandle commandBuffer +vulkanCreateFontsTexture :: MonadIO m => m Bool +vulkanCreateFontsTexture = liftIO do res <- [C.block| bool { - VkCommandBuffer commandBuffer = { $( VkCommandBuffer_T* commandBufferPtr ) }; - return ImGui_ImplVulkan_CreateFontsTexture(commandBuffer); + return ImGui_ImplVulkan_CreateFontsTexture(); }|] pure ( res /= 0 ) --- | Wraps @ImGui_ImplVulkan_DestroyFontUploadObjects@. -vulkanDestroyFontUploadObjects :: MonadIO m => m () -vulkanDestroyFontUploadObjects = liftIO do - [C.exp| void { ImGui_ImplVulkan_DestroyFontUploadObjects(); } |] +-- | You probably never need to call this, as it is called by ImGui_ImplVulkan_CreateFontsTexture() and ImGui_ImplVulkan_Shutdown(). +-- | Wraps @ImGui_ImplVulkan_DestroyFontsTexture@. +vulkanDestroyFontsTexture :: MonadIO m => m () +vulkanDestroyFontsTexture = liftIO do + [C.block| void { + return ImGui_ImplVulkan_DestroyFontsTexture(); + }|] -- | Wraps @ImGui_ImplVulkan_SetMinImageCount@. vulkanSetMinImageCount :: MonadIO m => Word32 -> m () diff --git a/src/DearImGui/Vulkan/Types.hs b/src/DearImGui/Vulkan/Types.hs index 930a1d9..dc02d98 100644 --- a/src/DearImGui/Vulkan/Types.hs +++ b/src/DearImGui/Vulkan/Types.hs @@ -19,23 +19,24 @@ import qualified Vulkan vulkanTypesTable :: C.TypesTable vulkanTypesTable = Map.fromList - [ ( C.TypeName "VkAllocationCallbacks", [t| Vulkan.AllocationCallbacks |] ) - , ( C.TypeName "VkCommandBuffer_T" , [t| Vulkan.CommandBuffer_T |] ) - , ( C.TypeName "VkDescriptorPool" , [t| Vulkan.DescriptorPool |] ) - , ( C.TypeName "VkDevice_T" , [t| Vulkan.Device_T |] ) - , ( C.TypeName "VkInstance_T" , [t| Vulkan.Instance_T |] ) - , ( C.TypeName "VkPhysicalDevice_T" , [t| Vulkan.PhysicalDevice_T |] ) - , ( C.TypeName "VkPipeline" , [t| Vulkan.Pipeline |] ) - , ( C.TypeName "VkPipelineCache" , [t| Vulkan.PipelineCache |] ) - , ( C.TypeName "VkQueue_T" , [t| Vulkan.Queue_T |] ) - , ( C.TypeName "VkRenderPass" , [t| Vulkan.RenderPass |] ) - , ( C.TypeName "VkResult" , [t| Vulkan.Result |] ) - , ( C.TypeName "VkSampleCountFlagBits", [t| Vulkan.SampleCountFlagBits |] ) - , ( C.TypeName "VkSampler" , [t| Vulkan.Sampler |] ) - , ( C.TypeName "VkImageView" , [t| Vulkan.ImageView |] ) - , ( C.TypeName "VkImageLayout" , [t| Vulkan.ImageLayout |] ) - , ( C.TypeName "VkDescriptorSet" , [t| Vulkan.DescriptorSet |] ) - , ( C.TypeName "VkFormat" , [t| Vulkan.Format |]) + [ ( C.TypeName "VkAllocationCallbacks" , [t| Vulkan.AllocationCallbacks |] ) + , ( C.TypeName "VkCommandBuffer_T" , [t| Vulkan.CommandBuffer_T |] ) + , ( C.TypeName "VkDescriptorPool" , [t| Vulkan.DescriptorPool |] ) + , ( C.TypeName "VkDevice_T" , [t| Vulkan.Device_T |] ) + , ( C.TypeName "VkInstance_T" , [t| Vulkan.Instance_T |] ) + , ( C.TypeName "VkPhysicalDevice_T" , [t| Vulkan.PhysicalDevice_T |] ) + , ( C.TypeName "VkPipeline" , [t| Vulkan.Pipeline |] ) + , ( C.TypeName "VkPipelineCache" , [t| Vulkan.PipelineCache |] ) + , ( C.TypeName "VkQueue_T" , [t| Vulkan.Queue_T |] ) + , ( C.TypeName "VkRenderPass" , [t| Vulkan.RenderPass |] ) + , ( C.TypeName "VkResult" , [t| Vulkan.Result |] ) + , ( C.TypeName "VkSampleCountFlagBits" , [t| Vulkan.SampleCountFlagBits |] ) + , ( C.TypeName "VkSampler" , [t| Vulkan.Sampler |] ) + , ( C.TypeName "VkImageView" , [t| Vulkan.ImageView |] ) + , ( C.TypeName "VkImageLayout" , [t| Vulkan.ImageLayout |] ) + , ( C.TypeName "VkDescriptorSet" , [t| Vulkan.DescriptorSet |] ) + , ( C.TypeName "VkFormat" , [t| Vulkan.Format |] ) + , ( C.TypeName "VkPipelineRenderingCreateInfo", [t| Vulkan.PipelineRenderingCreateInfo |] ) ] vulkanCtx :: C.Context