{"size": 7062, "ext": "scrbl", "max_stars_repo_path": "scribblings/unsafe.scrbl", "max_stars_repo_name": "dalev/racket-vulkan", "max_stars_repo_stars_event_min_datetime": "2019-10-18T18:39:55.000Z", "max_stars_repo_stars_event_max_datetime": "2021-11-16T21:50:30.000Z", "max_issues_repo_path": "scribblings/unsafe.scrbl", "max_issues_repo_name": "dalev/racket-vulkan", "max_issues_repo_issues_event_min_datetime": "2019-10-09T21:30:23.000Z", "max_issues_repo_issues_event_max_datetime": "2022-03-02T02:22:15.000Z", "max_forks_repo_path": "scribblings/unsafe.scrbl", "max_forks_repo_name": "dalev/racket-vulkan", "max_forks_repo_forks_event_min_datetime": "2019-10-22T23:42:40.000Z", "max_forks_repo_forks_event_max_datetime": "2022-02-15T23:32:21.000Z"}
{"max_stars_count": 45, "max_issues_count": 18, "max_forks_count": 8, "avg_line_length": 40.5862068966, "max_line_length": 239, "alphanum_fraction": 0.7656471255}
#lang scribble/manual
@require[@for-label[racket/base
                    racket/contract
                    @except-in[ffi/unsafe ->]
                    ffi/unsafe/define
                    vulkan/unsafe]
                    ffi/unsafe]

@title{Unsafe Bindings}
@defmodule[vulkan/unsafe]

The unsafe module is exactly as the name implies.
@bold{Use at your own risk.}

@racketmodname[vulkan/unsafe] is just the output of @litchar{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 @racketmodname[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. @italic{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.


@section{Design Considerations}

Since @racketmodname[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 @racketmodname[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.


@section{What Did I Just Load?}

When you @racket[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:

@itemlist[
@item{All identifiers acting as C types are prefixed with an underscore. So, the C type @tt{VkInstance} is bound to the @tt{_VkInstance} identifier in Racket.}
@item{API constants and enumerants have identifiers bound to a Racket value. e.g. @tt{VK_API_VERSION_1_1}.}
@item{All Vulkan functions are provided as Racket procedures with an identifier matching the name. e.g. The @tt{vkCreateInstance} C function is a Racket procedure also named @tt{vkCreateInstance}.}
@item{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 @tt{vkCreateAndroidSurfaceKHR} on a non-Android platform, the C function will not be found.}
@item{Unions are generated with accessor procedures that wrap @racket[union-ref]. So if a union @tt{U} has a member named @tt{floats}, you can access all Racket values converted from that union using @tt{(U-floats union-val)}.}
@item{Structs are created using @racket[define-cstruct], meaning that all bindings generated from that form exist for every Vulkan structure (e.g. @tt{_VkImageCreateInfo-pointer/null}).}
]

@section{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 @racket[_Display]-- because they are meant for use in
@racket[_cpointer] or @racket[_cpointer/null].

@subsection{X + RandR}
@deftogether[(
@defthing[_VisualID ctype? #:value _ulong]
@defthing[_Window ctype? #:value _ulong]
@defthing[_RROutput ctype? #:value _ulong]
@defthing[_Display symbol? #:value 'Display]
)]{}

@subsection{Wayland}
@deftogether[(
@defthing[_wl_display symbol? #:value 'wl_display]
@defthing[_wl_surface symbol? #:value 'wl_surface]
)]{}

@subsection{Windows}
@deftogether[(
@defthing[_HANDLE ctype? #:value (_cpointer _void)]
@defthing[_HINSTANCE ctype? #:value _HANDLE]
@defthing[_HWND  ctype? #:value _HANDLE]
@defthing[_HMONITOR ctype? #:value _HANDLE]
@defthing[_DWORD ctype? #:value _ulong]
@defthing[_LPCWSTR  ctype? #:value (_cpointer _wchar)]
@defthing[_SECURITY_ATTRIBUTES symbol? #:value 'SECURITY_ATTRIBUTES]
)]{}

@subsection{XCB}
@deftogether[(
@defthing[_xcb_visualid_t  ctype? #:value _uint32]
@defthing[_xcb_window_t  ctype? #:value _uint32]
@defthing[_xcb_connection_t symbol? #:value 'xcb_connection_t]
)]{}

@subsection{Zircon (Fuchsia OS)}
@defthing[_zx_handle_t ctype? #:value _uint32]{}

@subsection{Google Games}
@deftogether[(
@defthing[_GgpStreamDescriptor ctype? #:value (_cpointer _void)]
@defthing[_GgpFrameToken ctype? #:value (_cpointer _void)]
)]{
Be warned that these values are likely incorrect, and are apparently
@hyperlink["https://github.com/KhronosGroup/Vulkan-Docs/issues/1000"]{behind
an NDA}. Even if I knew what these were, I couldn't publish them here. If
you are the rare person who happened to sign this NDA and wish to use
Racket on Google Games, you may need to use a different binding. I
leave them here as @tt{void*} in the hopes you can use them and to clarify
that they are relevant to you.
}


@section{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.

@defproc[(VK_MAKE_VERSION [major exact-nonnegative-integer?]
                          [minor exact-nonnegative-integer?]
                          [patch exact-nonnegative-integer?])
         exact-positive-integer?]{
This is a Racket variant of the @litchar{VK_MAKE_VERSION} macro from
@litchar{vulkan.h}.
}

@deftogether[(
@defthing[VK_API_VERSION_1_0 exact-positive-integer? #:value (VK_MAKE_VERSION 1 0 0)]
@defthing[VK_API_VERSION_1_1 exact-positive-integer? #:value (VK_MAKE_VERSION 1 1 0)]
)]{
Racket-specific Vulkan version values.
}

@deftogether[(
@defproc[(VK_VERSION_MAJOR [v exact-positive-integer?]) exact-positive-integer?]
@defproc[(VK_VERSION_MINOR [v exact-positive-integer?]) exact-positive-integer?]
@defproc[(VK_VERSION_PATCH [v exact-positive-integer?]) exact-positive-integer?]
)]{
Extracts version numbers from a value constructed by @racket[VK_MAKE_VERSION].
}


@section{Additional Procedures}

@defproc[(check-vkResult [v any/c] [who symbol?]) void?]{
Equivalent to @racket[(error who "failed: ~a" v)] if @racket[v] is not
a @tt{VkResult} success code.
}

@defproc[(format-vulkan-spec-version [spec-version exact-positive-integer?]) string?]{
Equivalent to:

@racketblock[
(format "~a.~a.~a"
  (VK_VERSION_MAJOR spec-version)
  (VK_VERSION_MINOR spec-version)
  (VK_VERSION_PATCH spec-version))
]
}
