{"id":16344805,"url":"https://github.com/expipiplus1/vulkan","last_synced_at":"2026-03-07T19:04:02.115Z","repository":{"id":4178420,"uuid":"51958082","full_name":"expipiplus1/vulkan","owner":"expipiplus1","description":"Haskell bindings for Vulkan","archived":false,"fork":false,"pushed_at":"2024-11-22T09:34:14.000Z","size":197282,"stargazers_count":150,"open_issues_count":26,"forks_count":33,"subscribers_count":11,"default_branch":"main","last_synced_at":"2025-05-08T00:52:38.123Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://hackage.haskell.org/package/vulkan","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/expipiplus1.png","metadata":{"files":{"readme":"readme.md","changelog":"changelog.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-02-17T21:54:21.000Z","updated_at":"2025-04-26T03:26:31.000Z","dependencies_parsed_at":"2023-07-05T19:49:03.978Z","dependency_job_id":"a12ace83-b063-466e-b386-fdfa99aa35a8","html_url":"https://github.com/expipiplus1/vulkan","commit_stats":{"total_commits":1717,"total_committers":18,"mean_commits":95.38888888888889,"dds":"0.12055911473500291","last_synced_commit":"5896dcb87ebb3e0745311b7680d7e2e0e05491ef"},"previous_names":[],"tags_count":152,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/expipiplus1%2Fvulkan","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/expipiplus1%2Fvulkan/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/expipiplus1%2Fvulkan/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/expipiplus1%2Fvulkan/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/expipiplus1","download_url":"https://codeload.github.com/expipiplus1/vulkan/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254374427,"owners_count":22060611,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-11T00:29:12.426Z","updated_at":"2026-03-07T19:04:02.106Z","avatar_url":"https://github.com/expipiplus1.png","language":"Haskell","readme":"![](haskell-vulkan.png)\n\nSlightly high level Haskell bindings to the Vulkan graphics API.\n\nJoin us on Matrix at\n[#vulkan:monoid.al](https://matrix.to/#/#vulkan:monoid.al?via=monoid.al\u0026via=matrix.org\u0026via=nordgedanken.dev)\n\nThese bindings present an interface to Vulkan which looks like more idiomatic\nHaskell and which is much less verbose than the C API. Nevertheless, it retains\naccess to all the functionality. If you find something you can do in the C\nbindings but not in these high level bindings please raise an issue.\n\nPractically speaking this means:\n\n- No fiddling with `vkGetInstanceProcAddr` or\n  `vkGetDeviceProcAddr` to get function pointers, this is done automatically on\n  instance and device creation\u003csup\u003e[1](#fun-ptr)\u003c/sup\u003e.\n\n- No setting the `sType` member, this is done automatically.\n\n- No passing length/pointer pairs for arrays, `Vector` is used\n  instead\u003csup\u003e[2](#opt-vec)\u003c/sup\u003e.\n\n- No passing pointers for return values, this is done for you and multiple\n  results are returned as elements of a tuple.\n\n- No checking `VkResult` return values for failure, a `VulkanException` will be\n  thrown if a Vulkan command returns an error `VkResult`.\n\n- No manual memory management for command parameters or Vulkan structs. You'll\n  still have to manage buffer and image memory yourself however.\n\n## Package structure\n\nTypes and functions are placed into modules according to the `features` and\n`extensions` portions of the specification. As these sections only mention\nfunctions, a best guess has to be made for types. Types and constants are drawn\nin transitively according to the dependencies of the functions.\n\nIt should be sufficient to import `Vulkan.CoreXX` along with\n`Vulkan.Extensions.{whatever extensions you want}`. You might want to import\n`Vulkan.Zero` too.\n\nThese bindings are intended to be imported qualified and do not feature the\n`Vk` prefixes on commands, structures, members or constants.\n\n## Things to know\n\n- Documentation is included more or less verbatim from the Vulkan C API\n  documentation. The parameters it references might not map one-to-one with\n  what's in these bindings. It should be obvious in most cases what it's trying\n  to say. If part of the documentation is misleading or unclear with respect to\n  these Haskell bindings please open an issue and we can special case a fix.\n  - The haddock documentation can be browsed on Hackage or\n    [here](http://expipiplus1.github.io/vulkan/)\n\n- Parameters are named with the `:::` operator where it would be useful; this\n  operator simply ignores the string on the left.\n\n- There exists a `Zero` type class defined in\n  [Vulkan.Zero](src/Vulkan/Zero.hs). This is a class for initializing values\n  with all zero contents and empty arrays. It's very handy when initializing\n  structs to use something like `zero { only = _, members = _, i = _, care = _,\n  about = _ }`.\n\n- The library is compiled with `-XStrict` so expect all record members to be\n  strict (and unboxed when they're small)\n\n- Calls to Vulkan are marked as `unsafe` by default to reduce FFI overhead.\n  - This can be changed by setting the `safe-foreign-calls` flag.\n  - It means that Vulkan functions are unable to safely call Haskell code. See\n    the [Haskell\n    wiki](https://wiki.haskell.org/Foreign_Function_Interface#Unsafe_calls) for\n    more information. This is important to consider if you want to write\n    allocation or debug callbacks in Haskell.\n  - It's also means that the garbage collector will not run while these calls\n    are in progress. For some blocking functions (those which can return\n    `VK_TIMEOUT` and those with `wait` in the name) a `safe` version is also\n    provided with the `Safe` suffix.\n\n- As encouraged by the Vulkan user guide, commands are linked dynamically (with\n  the sole exception of `vkGetInstanceProcAddr`).\n  - The function pointers are attached to any dispatchable handle to save you\n    the trouble of passing them around.\n  - The function pointers are retrieved by calling `vkGetInstanceProcAddr` and\n    `vkGetDeviceProcAddr`.  These are stored in two records `InstanceCmds` and\n    `DeviceCmds` which store instance level and device level commands\n    respectively. These tables can be initialized with the `initInstanceCmds`\n    and `initDeviceCmds` found in [Vulkan.Dynamic](src/Vulkan/Dynamic.hs).\n\n- There are nice `Read` and `Show` instances for the enums and bitmasks. These\n  will, where possible, print and parse the pattern synonyms. For example one\n  can do the following:\n\n    ```haskell\n    \u003e read @COMPARE_OP \"COMPARE_OP_LESS\"\n    COMPARE_OP_LESS\n    ```\n\n- Make sure that all the functions you're going to use are not `nullPtr` in\n  `InstanceCmds` or `DeviceCmds` before calling them or the command will throw\n  an `IOException`. The `*Cmds` records can be found inside any dispatchable\n  handle.\n\n### Minor things\n\n- To prevent a name clash between the constructors of\n  `VkClearColorValue` and `VkPerformanceCounterResultKHR` the latter have had\n  `Counter` suffixed.\n\n- To prevent a name clash between the constructors of\n  `DeviceOrHostAddressKHR` and `DeviceOrHostAddressConstKHR` the latter have\n  had `Const` suffixed.\n\n## How the C types relate to Haskell types\n\nThese bindings take advantage of the meta information present in the\nspecification detailing the validity of structures and arguments.\n\n- `Vector` is used in place of pointers to arrays with associated length\n  members/parameters. When interfacing with Vulkan these bindings automatically\n  set the length member/parameter properly. If the vector is optional but the\n  length is not then the length member/parameter is preserved, but will be\n  inferred if the vector is present and the length is 0.\n\n- If a struct member or command parameters in the specification is a optional\n  pointer (it may be null) this is replaced with a `Maybe` value.\n\n- If a struct has a member which can only have one possible value (the most\n  common example is the `sType` member, then this member is elided.\n\n- C strings become `ByteString`. This is also the case for fixed length C\n  strings, the library will truncate overly long strings in this case.\n\n- Pointers to `void` accompanied by a length in bytes become `ByteString`\n\n- Shader code is represented as `ByteString`\n\n- `VkBool32` becomes `Bool`\n\n- Some Vulkan commands or structs take several arrays which must be the same\n  length. These are currently exposed as several `Vector` arguments which must\n  be the same length. If they are not the same length an exception is thrown.\n\n- Vulkan structs with bitfields have them split into their component parts in\n  the Haskell record. Then marshalling to and from C the masking *and shifting*\n  takes place automatically.\n\nIf anything is unclear please raise an issue. The marshaling to and from\nHaskell and C is automatically generated and I've not checked every single\nfunction. It's possible that there are some commands or structs which could be\nrepresented better in Haskell, if so please also raise an issue.\n\n### Vulkan errors\n\nIf a Vulkan command has the `VkResult` type as a return value, this is checked\nand a `VulkanException` is thrown if it is not a success code. If the only\nsuccess code a command can return is `VK_SUCCESS` then this is elided from the\nreturn type. If a command can return other success codes, for instance\n`VK_EVENT_SET` then the success code is exposed.\n\n### Bracketing commands\n\nThere are certain sets commands which must be called in pairs, for instance the\n`create` and `destroy` commands for using resources. In order to facilitate\nsafe use of these commands, (i.e. ensure that the corresponding `destroy`\ncommand is always called) these bindings expose similarly named commands\nprefixed with `with` (for `Create`/`Destroy` and `Allocate`/`Free` pairs) or\n`use` for (`Begin`/`End` pairs). If the command is used in command buffer\nbuilding then it is additionally prefixed with `cmd`.\n\nThese are higher order functions which take as their last argument a consumer\nfor a pair of `create` and `destroy` commands.  Values which fit this hole\ninclude `Control.Exception.bracket`, `Control.Monad.Trans.Resource.allocate`\nand `(,)`.\n\nAn example is `withInstance` which calls `createInstance` and\n`destroyInstance`. Notice how the `AllocationCallbacks` parameter is\nautomatically passed to the `createInstance` and `destroyInstance` command.\n\n```haskell\ncreateInstance\n  :: forall a m\n   . (PokeChain a, MonadIO m)\n  =\u003e InstanceCreateInfo a\n  -\u003e Maybe AllocationCallbacks\n  -\u003e m Instance\n\ndestroyInstance\n  :: forall m\n   . MonadIO m\n  =\u003e Instance\n  -\u003e Maybe AllocationCallbacks\n  -\u003e m ()\n\nwithInstance\n  :: forall a m r\n   . (PokeChain a, MonadIO m)\n  =\u003e InstanceCreateInfo a\n  -\u003e Maybe AllocationCallbacks\n  -\u003e (m Instance -\u003e (Instance -\u003e m ()) -\u003e r)\n  -\u003e r\n```\n\nExample usage:\n\n```haskell\nimport Control.Monad.Trans.Resource (runResourceT, allocate)\n-- Create an instance and print its value\nmain = runResourceT $ do\n  (instanceReleaseKey, inst) \u003c- withInstance zero Nothing allocate\n  liftIO $ print inst\n\n-- Begin a render pass, draw something and end the render pass\ndrawTriangle =\n  cmdUseRenderPass buffer renderPassBeginInfo SUBPASS_CONTENTS_INLINE bracket_\n    $ do\n        cmdBindPipeline buffer PIPELINE_BIND_POINT_GRAPHICS graphicsPipeline\n        cmdDraw buffer 3 1 0 0\n```\n\nThese pairs of commands aren't explicit in the specification, so\na list of them is maintained in the generation code, if you see something\nmissing please open an issue (these pairs are generated in `VK/Bracket.hs`).\n\n### Dual use commands\n\nCertain commands, such as `vkEnumerateDeviceLayerProperties` or\n`vkGetDisplayModePropertiesKHR`, have a dual use. If they are not given a\npointer to return an array of results then they instead return the total number\nof possible results, otherwise they return a number of results. There is an\nidiom in Vulkan which involves calling this function once with a null pointer\nto get the total number of queryable values, allocating space for querying that\nmany values and they calling the function again to get the values. These\nbindings expose commands which automatically return all the results. As an\nexample `enumeratePhysicalDevices` has the type `MonadIO m =\u003e Instance -\u003e m\n(Result, Vector PhysicalDevice)`.\n\n### Structure chains\n\nMost structures in Vulkan have a member called `pNext` which can be a pointer\nto another Vulkan structure containing additional information. In these high\nlevel bindings the head of any struct chain is parameterized over the rest of\nthe items in the chain. This allows for using *type inference* for getting\nstruct chain return values out of Vulkan, for example:\n`getPhysicalDeviceFeatures2 :: (PokeChain a, PeekChain a) =\u003e PhysicalDevice -\u003e\nIO (PysicalDeviceFeatures2 a)`; here the variable `a :: [Type]` represents the\nstructures present in the chain returned from `vkGetPhysicalDeviceFeatures2`.\n\nThere exists a GADT `SomeStruct` which captures the case of an unknown tail in\nthe struct chain. This is also used for nested chains inside structs.\n\nStruct chains inside records are represented as nested tuples: `next ::\n(Something, (SomethingElse, (AThirdThing, ())))`\n\nThere are two pattern synonyms exposed in `Vulkan.CStruct.Extends` which help\nin constructing and deconstructing struct chains.\n\n- `h ::\u0026 t` which appends the tail `t` to the struct `h`\n- `t :\u0026 ts` which constructs a struct extending tail comprising struct `t` and\n  structs `ts`. Note that you must terminate the list with `()`.\n\nFor example, to create an instance with a `debugUtilsMessenger` and the\nvalidation layer's best practices output enabled:\n\n```haskell\nmakeInst = do\n  let debugCreateInfo = _ :: DebugUtilsMessengerCreateInfoEXT\n      validationFeatures = ValidationFeaturesEXT [VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT] []\n      instanceCreateInfo = zero ::\u0026 debugCreateInfo :\u0026 validationFeatures :\u0026 ()\n  createInstance instanceCreateInfo Nothing\n```\n\nAnd to deconstruct a return value with a struct tail, for example to find out\nif a physical device supports Timeline Semaphores:\n\n```haskell\nhasTimelineSemaphores phys = do\n  _ ::\u0026 PhysicalDeviceTimelineSemaphoreFeatures hasTimelineSemaphores :\u0026 () \u003c-\n    getPhysicalDeviceFeatures2 phys\n  pure hasTimelineSemaphores\n\n-- If you don't have a MonadFail instance you'll have to avoid pattern matching\n-- using do notation because of https://gitlab.haskell.org/ghc/ghc/-/issues/15681\nhasTimelineSemaphores phys = do\n  feats \u003c- getPhysicalDeviceFeatures2 phys\n  let _ ::\u0026 PhysicalDeviceTimelineSemaphoreFeatures hasTimelineSemaphores :\u0026 ()\n       = feats\n  pure hasTimelineSemaphores\n```\n\n## Building\n\nThis package requires GHC 8.6 or higher due to the use of the\n`QuantifiedConstraints` language extension.\n\nMake sure you have initialized the `VulkanMemoryAllocator` submodule if you\nintend to build the `VulkanMemoryAllocator` package.\n\nIf you provision `libvulkan.so` (the Vulkan loader) with nix and you're not on\nNixOS, you'll have to use [NixGL](https://github.com/guibou/nixGL) to run your\nprograms. For this reason it's recommended to use the system-provided\n`libvulkan.so`.\n\nFor instructions on how to regenerate the bindings see [the readme in\n./generate-new](./generate-new/readme.md).\n\nTo build the example programs. You'll need to supply the following system\npackages:\n\n- `vulkan-loader` (for `libvulkan.so`)\n- `vulkan-headers` (for `vulkan.h`)\n- `pkg-config` and `SDL2` to build the Haskell `sdl2` package.\n- `glslang` (for the `glslangValidator` binary, to build the shaders)\n\nJonathan Merritt has made an excellent video detailing how to set up everything\nnecessary for running the examples on macOS\n[here](https://www.youtube.com/watch?v=BaBt-CNBfd0).\n\n### Building using Nix\n\nHere is some generally useful information for using the `default.nix` files in\nthis repo.\n\n`default.nix { forShell = false; }` evaluates to an attribute set with one\nattribute for each of the following packages:\n\n- `vulkan`, the main package of this repository\n- `VulkanMemoryAllocator`, bindings to VMA\n- `vulkan-utils`, a small selection of utility functions for using `vulkan`\n- `vulkan-examples`, some examples, this package is dependency-heavy\n- `generate-new`, the program to generate the source of `vulkan` and\n  `VulkanMemoryAllocator`, also quite dependency-heavy (this only build with\n  ghc 8.10).\n\nYou may want to pass your `\u003cnixpkgs\u003e` as `pkgs` to `default.nix` to avoid\nrebuilding a parallel set of haskell packages based on the pegged nixpkgs\nversion in `default.nix`. It should probably work with a wide range of\nnixpkgss, however some overrides in `default.nix` may need tweaking,\n\nAlternatively you could use the Cachix repo\nhttps://app.cachix.org/cache/vulkan-haskell which contains the latest closure\nfor the packages in this repo.\n\n`nix-build -A vulkan` is probably not terribly useful for using the library as\nit just builds the Haskell library.\n\n`nix-build -A vulkan-examples` will produce a path with several examples,\nhowever to run these on a non-NixOS platform you'll need to use the\n[`NixGL`](https://github.com/guibou/nixGL) project (or something similar) to\nrun these. This isn't something tested very often so may be a little fragile.\nI'd suggest for non-NixOS platforms compiling without using Nix (or better yet\nget reliable instructions for using `NixGL` and open a PR).\n\nThis library is currently up to date on nixpkgs master (as of\nhttps://github.com/NixOS/nixpkgs/commit/af9608d6d133ad9b6de712418db52603bbc8531c\n2020-06-23), so if you're just a consumer it might be best to just use\n`haskellPackages.vulkan` from a recent version there.\n\nFor using this repository, I have two workflows:\n\n- For building and running examples\n  - I navigate to the examples directory and use the `default.nix` expression\n    in there to provision a shell with the correct dependencies for the\n    examples.\n  - I also make a `cabal.project` containing `packages: ./`, the reason for\n    this little dance instead of just using the root's `default.nix` is so that\n    nix builds the hoogle database for the dependencies and HIE's completion\n    and indexing works much better for external dependencies instead of using a\n    multi-package project as is the root.\n  - This will override nixpkgs's `vulkan` and `VulkanMemoryAllocator` libraries\n    with the ones in the repo, as well as building `vulkan-utils`.\n\n- For modifying the generation program I navigate to the `generate-new`\n  directory and run `nix-shell ..` to use `default.nix` in the repo's root to\n  provision a shell with:\n  - The dependencies for running the generator\n  - And the dependencies for compiling the `vulkan` source it spits out.\n  - I run the generator with `ghci $(HIE_BIOS_OUTPUT=/dev/stdout ./flags.sh $(pwd)/vk/Main.hs) vk/Main.hs +RTS -N16`\n\nFor using the source in this package externally it may be easiest to do\nwhatever you do to get a haskell environment with nix and simply override the\nsource to point to this repo, the dependencies haven't changed for a while, so\nany version of nixpkgs from the last 3 months should do the trick.\n\n### Building on Windows with Cabal\n\n- Clone this repo with submodules (to get the C header in order to build VulkanMemoryAllocator)\n  - `git clone --recursive https://github.com/expipiplus1/vulkan`\n- Install GHC and Cabal\n  - I used [ghcup](https://www.haskell.org/ghcup/)\n  - Make sure that the `libstdc++` dll is in `PATH`, I had to add\n    `C:\\ghcup\\ghc\\9.2.4\\mingw\\bin` to my user `PATH` variable\n- Make sure your graphics driver has installed `vulkan-1.dll` in\n  `C:/windows/system32`\n- Install the LunarG Vulkan SDK\n  - https://vulkan.lunarg.com/sdk/home#windows\n  - Remember the installation directory, use in place of `C:/VulkanSDK/1.3.224.1` below\n  - Install the SDL2 library/header (You can run `maintenancetool` in the SDK directory to\n    install this later if you forgot)\n  - We will link against `vulkan-1.lib` from this installation\n  - We will use the `glslangValidator` from this installation.\n- Restart your shell to pick up the new `PATH` environment set up by the SDK installer\n  The Vulkan SDK installer\n- Inform Cabal about header and library locations by adding the following to\n  `cabal.project.local`, changed accodingly for your install path for the Vulkan SDK.\n  Also use a patched SDL2 which doens't use pkgconfig (a pain to install on Windows)\n\n    ```\n    package sdl2\n        extra-lib-dirs: C:/VulkanSDK/1.3.224.1/lib/\n        extra-include-dirs: C:/VulkanSDK/1.3.224.1/Include/SDL2\n        flags: -pkgconfig\n    source-repository-package\n        type: git\n        location: https://github.com/expipiplus1/sdl2\n        tag: 35f45303a0af522f10197f09e4bf52bc49b97ef4\n\n    package vulkan\n        extra-lib-dirs: C:/VulkanSDK/1.3.224.1/lib/\n\n    package vulkan-utils\n        extra-include-dirs: C:/VulkanSDK/1.3.224.1/Include/\n\n    package VulkanMemoryAllocator\n        extra-include-dirs: C:/VulkanSDK/1.3.224.1/Include/\n\n    package vulkan-examples\n        extra-prog-path: C:/VulkanSDK/1.3.224.1/bin\n    ```\n\n- Run `cabal build examples` to build the examples\n- Run `cabal run resize` to run the `resize` example.\n\n### Building on Windows with Stack\n\nStack is currently (2020-11-02) bundled with an msys2 installation which is\ntoo old to use the package repositories (see\nhttps://github.com/commercialhaskell/stack/issues/5300) so installing the\nVulkan SDK, `SDL2` and `pkg-config` is not possible with the bundled package\nmanager.\n\nNevertheless, it should be possible to use Stack by adding the following to\n`stack.yaml` (changed appropriately according to SDL2 and VulkanSDK install\nlocations) and building after following the instructions above.\n\n```yaml\nextra-lib-dirs:\n- C:/VulkanSDK/1.2.135.0/lib/\n\nextra-include-dirs:\n- C:/VulkanSDK/1.2.135.0/Include/\n- C:/VulkanSDK/1.3.224.1/Include/SDL2\n```\n\n## Examples\n\nThere exists a package to build some example programs in the\n[`examples`](./examples) directory.\n\n## Current Status\n\nAll the core Vulkan 1.0, 1.1, 1.2, and 1.3 functionality is here as well as all the\nextensions, with the exception of the video extensions listed below which are\ncurrently disabled in the generator:\n\n- `VK_KHR_video_queue`\n- `VK_KHR_video_decode_queue`\n- `VK_KHR_video_encode_queue`\n- `VK_KHR_video_decode_av1`\n- `VK_KHR_video_decode_h264`, `VK_EXT_video_decode_h264`\n- `VK_KHR_video_encode_h264`, `VK_EXT_video_encode_h264`\n- `VK_KHR_video_decode_h265`, `VK_EXT_video_decode_h265`\n- `VK_KHR_video_encode_h265`, `VK_EXT_video_encode_h265`\n- `VK_KHR_video_maintenance1`\n\nThe list is maintained in `forceDisabledExtensions` in\n[`generate-new/src/Bespoke.hs`](./generate-new/src/Bespoke.hs).\n\nThis is currently a 64 bit only library.\n\n## See also\n\nThe [VulkanMemoryAllocator\npackage](https://hackage.haskell.org/package/VulkanMemoryAllocator) (source in\nthe [VulkanMemoryAllocator directory](./VulkanMemoryAllocator)) has similarly\nstyled bindings to the [Vulkan Memory\nAllocator](https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator)\nlibrary.\n\nThe [vulkan-utils](https://hackage.haskell.org/package/vulkan-utils) (source in\nthe [utils directory](./utils)) includes a few utilities for writing programs\nusing these bindings.\n\nFor an alternative take on Haskell bindings to Vulkan see the\n[vulkan-api](https://github.com/achirkin/vulkan#readme) package. `vulkan-api`\nstores Vulkan structs in their C representation as `ByteArray#` whereas this\nlibrary allocates structs on the stack and keeps them alive for just the\nlifetime of any Vulkan command call.\n\n--------\n\n\u003ca name=\"fun-ptr\"\u003e1\u003c/a\u003e: Note that you'll still have to request any required\n  extensions for the function pointers belonging to that extension to be\n  populated. An exception will be thrown if you try to call a function pointer\n  which is null.\n\n\u003ca name=\"opt-vec\"\u003e2\u003c/a\u003e: The exception is where the spec allows the application\n  to pass `NULL` for the vector with a non-zero count. In these cases it was\n  deemed clearer to preserve the \"count\" member and allow the Haskell\n  application to pass a zero-length vector to indicate `NULL`.\n\n\u003ca name=\"sdl-load\"\u003e3\u003c/a\u003e: \u003chttps://github.com/spurious/SDL-mirror/blob/6b6170caf69b4189c9a9d14fca96e97f09bbcc41/src/video/windows/SDL_windowsvulkan.c#L50-L54\u003e\n","funding_links":[],"categories":["Bindings"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexpipiplus1%2Fvulkan","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fexpipiplus1%2Fvulkan","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexpipiplus1%2Fvulkan/lists"}