3 Unsafe Bindings
(require vulkan/unsafe) | package: vulkan |
The unsafe module is exactly as the name implies. Use at your own risk.
vulkan/unsafe is just the output of ravk generate unsafe. You can generate your own copy to use Vulkan bindings according to this section without a dependency on this collection.
A copy of vulkan/unsafe provides over 2200 bindings representing all supported and deprecated Vulkan structs, unions, enumerated types, constants and functions across all platforms, extensions, and published Vulkan API verions. There are few protections against misuse. Any mistakes risk undefined behavior, race conditions, and memory leaks. Do not expect clear error messages, strong validation, or concise code.
Here you will also find platform-specific code, necessary loading calls to communicate with Vulkan, and a curated list of utilities not generated from a specification.
On instantiation, this module will attempt to load the host platform’s Vulkan library. Should this fail, the module will raise an error.
3.1 Design Considerations
Since vulkan/unsafe exposes a raw API, you can easily port a C program using Vulkan to Racket. You can also use this module to write your own abstractions in terms of ffi/unsafe, or to study established Vulkan literature while using Racket.
It is possible to write cross-platform and backwards-compatible Vulkan applications with this module, but you are responsible for detecting the platform and using APIs from the correct version.
3.2 What Did I Just Load?
When you require this module, you may assume that all Vulkan identifiers defined in the specification for the core API and all extensions are provided. I cannot document every binding by hand, but I thankfully don’t have to. The translation from C to Racket is not 1-to-1, but it is close enough where you can compare the below list of translation rules against a Vulkan specification document to know what bindings are available:
All identifiers acting as C types are prefixed with an underscore. So, the C type VkInstance is bound to the _VkInstance identifier in Racket.
API constants and enumerants have identifiers bound to a Racket value. e.g. VK_API_VERSION_1_1.
All Vulkan functions are provided as Racket procedures with an identifier matching the name. e.g. The vkCreateInstance C function is a Racket procedure also named vkCreateInstance.
A Racket procedure’s presence is not a guarentee that the associated C function is available as an object in the system library. If you call vkCreateAndroidSurfaceKHR on a non-Android platform, the C function will not be found.
Unions are generated with accessor procedures that wrap union-ref. So if a union U has a member named floats, you can access all Racket values converted from that union using (U-floats union-val).
Structs are created using define-cstruct, meaning that all bindings generated from that form exist for every Vulkan structure (e.g. _VkImageCreateInfo-pointer/null).
3.3 Platform-Specific Definitions
Vulkan is itself platform-agnostic, but extensions are necessary to integrate with platforms. Some identifiers are bound to interned symbols–such as _Display– because they are meant for use in _cpointer or _cpointer/null.
3.3.1 X + RandR
value
value
value
value
3.3.2 Wayland
value
_wl_display : symbol? = 'wl_display
value
_wl_surface : symbol? = 'wl_surface
3.3.3 Windows
value
value
_HINSTANCE : ctype? = _HANDLE
value
value
value
value
value
_SECURITY_ATTRIBUTES : symbol? = 'SECURITY_ATTRIBUTES
3.3.4 XCB
value
value
value
_xcb_connection_t : symbol? = 'xcb_connection_t
3.3.5 Zircon (Fuchsia OS)
value
3.3.6 Google Games
value
value
_GgpFrameToken : ctype? = (_cpointer _void)
3.4 Spec Version Procedures
Some core Vulkan signatures are implemented as C preprocessor macros that are difficult to transform directly to Racket. Chief among them are the expressions of specification versions that are relevant for runtime and operational use. Their names are preserved as they appear in C for consistency.
procedure
(VK_MAKE_VERSION major minor patch) → exact-positive-integer?
major : exact-nonnegative-integer? minor : exact-nonnegative-integer? patch : exact-nonnegative-integer?
value
= (VK_MAKE_VERSION 1 0 0)
value
= (VK_MAKE_VERSION 1 1 0)
procedure
v : exact-positive-integer?
procedure
v : exact-positive-integer?
procedure
v : exact-positive-integer?
3.5 Additional Procedures
procedure
(check-vkResult v who) → void?
v : any/c who : symbol?
procedure
(format-vulkan-spec-version spec-version) → string?
spec-version : exact-positive-integer?
(format "~a.~a.~a" (VK_VERSION_MAJOR spec-version) (VK_VERSION_MINOR spec-version) (VK_VERSION_PATCH spec-version))