librashader_capi/
lib.rs

1#![forbid(missing_docs)]
2//! The C API for [librashader](https://docs.rs/librashader/).
3//!
4//! The librashader C API is designed to be loaded dynamically via `librashader_ld.h`, but static usage is also
5//! possible by linking against `librashader.h` as well as any static libraries used by `librashader`.
6//!
7//! ## Usage
8//! ⚠ Rust consumers should use [librashader](https://docs.rs/librashader/) directly instead. ⚠
9//!
10//! The librashader C API is designed to be easy to use and safe. Most objects are only accessible behind an opaque pointer.
11//! Every allocated object can be freed with a corresponding `free` function **for that specific object type**.
12//!
13//! Once an object is freed, the input pointer is always set to null. Attempting to free an object that was not
14//! allocated from `librashader` or trying to free an object with a wrong `free` function results in
15//! **immediate undefined behaviour**.
16//!
17//! In general, all functions will accept null pointers for all parameters. However, passing a null pointer
18//! into any function that requires a non-null pointer will result in the function returning an error with code `INVALID_PARAMETER`.
19//!
20//! All types that begin with an underscore, such as `_libra_error` or `_shader_preset` are handles that
21//! can not be constructed validly, and should always be used with pointer indirection via the corresponding `_t` types.
22//!
23//! All functions have safety invariants labeled `## Safety` that must be upheld. Failure to uphold these invariants
24//! will result in **immediate undefined behaviour**. Generally speaking, all pointers passed to functions must be
25//! **aligned** regardless of whether or not they are null.
26//!
27//! ## Booleans
28//! Some option structs take `bool` values.
29//! Any booleans passed to librashader **must have a bit pattern equivalent to either `1` or `0`**. Any other value will cause
30//! **immediate undefined behaviour**. Using `_Bool` from `stdbool.h` should maintain this invariant.
31//!
32//! ## Errors
33//! The librashader C API provides a robust, reflective error system. Every function returns a `libra_error_t`, which is either
34//! a null pointer, or a handle to an opaque allocated error object. If the returned error is null, then the function was successful.
35//! Otherwise, error information can be accessed via the `libra_error_` set of APIs. If an error indeed occurs, it may be freed by
36//! `libra_error_free`.
37//!
38//! It is **highly recommended** to check for errors after every call to a librashader API like in the following example.
39//!
40//! ```c
41//! libra_preset_t preset;
42//! libra_error_t error = libra.preset_create(
43//!         "slang-shaders/crt/crt-lottes.slangp", &preset);
44//! if (error != NULL) {
45//!    libra.error_print(error);
46//!    libra.error_free(&error);
47//!    exit(1);
48//! }
49//! ```
50//!
51//! There is a case to be made for skipping error checking for `*_filter_chain_frame` due to performance reasons,
52//! but only if you are certain that the safety invariants are upheld on each call. Failure to check for errors
53//! may result in **undefined behaviour** stemming from failure to uphold safety invariants.
54//!
55//! ## Thread safety
56//!
57//! Except for the metal runtime, it is in general, **safe** to create a filter chain instance from a different thread,
58//! but drawing filter passes must be synchronized externally. The exception to filter chain creation are in OpenGL,
59//! where creating the filter chain instance is safe **if and only if** the thread local OpenGL context is initialized
60//! to the same context as the drawing thread, and in Direct3D 11, where filter chain creation is unsafe
61//! if the `ID3D11Device` was created with `D3D11_CREATE_DEVICE_SINGLETHREADED`. Metal is entirely thread unsafe.
62//!
63//! Setting and retrieving filter parameters from any thread, regardless of the lack of other thread safety-guarantees
64//! of the runtime, is always thread safe.
65//!
66//! You must ensure that only thread has access to a created filter pass **before** you call `*_frame`. `*_frame` may only be
67//! called from one thread at a time.
68#![cfg_attr(feature = "docsrs", feature(doc_cfg))]
69#![allow(non_camel_case_types)]
70#![deny(unsafe_op_in_unsafe_fn)]
71#![deny(deprecated)]
72
73extern crate alloc;
74
75pub mod ctypes;
76pub mod error;
77mod ffi;
78pub mod presets;
79
80#[cfg(feature = "reflect-unstable")]
81#[doc(hidden)]
82pub mod reflect;
83
84pub mod runtime;
85pub mod version;
86pub mod wildcard;
87
88pub use version::LIBRASHADER_ABI_VERSION;
89pub use version::LIBRASHADER_API_VERSION;
90
91#[allow(dead_code)]
92const fn assert_thread_safe<T: Send + Sync>() {}