librashader_capi/
ctypes.rs

1//! Binding types for the librashader C API.
2use crate::error::LibrashaderError;
3use librashader::presets::context::{Orientation, VideoDriver, WildcardContext};
4use librashader::presets::ShaderPreset;
5use std::mem::MaybeUninit;
6use std::ptr::NonNull;
7
8/// A handle to a shader preset object.
9pub type libra_shader_preset_t = Option<NonNull<ShaderPreset>>;
10
11/// A handle to a preset wildcard context object.
12pub type libra_preset_ctx_t = Option<NonNull<WildcardContext>>;
13
14/// A handle to a librashader error object.
15pub type libra_error_t = Option<NonNull<LibrashaderError>>;
16
17/// An enum representing orientation for use in preset contexts.
18#[repr(u32)]
19#[derive(Debug, Copy, Clone)]
20pub enum LIBRA_PRESET_CTX_ORIENTATION {
21    /// Context parameter for vertical orientation.
22    Vertical = 0,
23    /// Context parameter for horizontal orientation.
24    Horizontal,
25}
26impl From<LIBRA_PRESET_CTX_ORIENTATION> for Orientation {
27    fn from(value: LIBRA_PRESET_CTX_ORIENTATION) -> Self {
28        match value {
29            LIBRA_PRESET_CTX_ORIENTATION::Vertical => Orientation::Vertical,
30            LIBRA_PRESET_CTX_ORIENTATION::Horizontal => Orientation::Horizontal,
31        }
32    }
33}
34
35/// An enum representing graphics runtimes (video drivers) for use in preset contexts.
36#[repr(u32)]
37#[derive(Debug, Copy, Clone)]
38pub enum LIBRA_PRESET_CTX_RUNTIME {
39    /// No runtime.
40    None = 0,
41    /// OpenGL 3.3+
42    GlCore,
43    /// Vulkan
44    Vulkan,
45    /// Direct3D 11
46    D3D11,
47    /// Direct3D 12
48    D3D12,
49    /// Metal
50    Metal,
51    /// Direct3D 9
52    D3D9_HLSL,
53}
54
55impl From<LIBRA_PRESET_CTX_RUNTIME> for VideoDriver {
56    fn from(value: LIBRA_PRESET_CTX_RUNTIME) -> Self {
57        match value {
58            LIBRA_PRESET_CTX_RUNTIME::None => VideoDriver::None,
59            LIBRA_PRESET_CTX_RUNTIME::GlCore => VideoDriver::GlCore,
60            LIBRA_PRESET_CTX_RUNTIME::Vulkan => VideoDriver::Vulkan,
61            LIBRA_PRESET_CTX_RUNTIME::D3D11 => VideoDriver::Direct3D11,
62            LIBRA_PRESET_CTX_RUNTIME::D3D12 => VideoDriver::Direct3D12,
63            LIBRA_PRESET_CTX_RUNTIME::Metal => VideoDriver::Metal,
64            LIBRA_PRESET_CTX_RUNTIME::D3D9_HLSL => VideoDriver::Direct3D9Hlsl,
65        }
66    }
67}
68
69#[cfg(feature = "runtime-opengl")]
70use librashader::runtime::gl::FilterChain as FilterChainGL;
71
72/// A handle to a OpenGL filter chain.
73#[cfg(feature = "runtime-opengl")]
74#[cfg_attr(feature = "docsrs", doc(cfg(feature = "runtime-opengl")))]
75pub type libra_gl_filter_chain_t = Option<NonNull<FilterChainGL>>;
76
77/// A handle to a Direct3D 11 filter chain.
78#[cfg(any(
79    feature = "__cbindgen_internal",
80    all(target_os = "windows", feature = "runtime-d3d11")
81))]
82use librashader::runtime::d3d11::FilterChain as FilterChainD3D11;
83
84/// A handle to a Direct3D 11 filter chain.
85#[cfg_attr(
86    feature = "docsrs",
87    doc(cfg(all(target_os = "windows", feature = "runtime-d3d11")))
88)]
89#[cfg(any(
90    feature = "__cbindgen_internal",
91    all(target_os = "windows", feature = "runtime-d3d11")
92))]
93pub type libra_d3d11_filter_chain_t = Option<NonNull<FilterChainD3D11>>;
94
95#[cfg(any(
96    feature = "__cbindgen_internal",
97    all(target_os = "windows", feature = "runtime-d3d12")
98))]
99use librashader::runtime::d3d12::FilterChain as FilterChainD3D12;
100/// A handle to a Direct3D 12 filter chain.
101#[cfg(any(
102    feature = "__cbindgen_internal",
103    all(target_os = "windows", feature = "runtime-d3d12")
104))]
105pub type libra_d3d12_filter_chain_t = Option<NonNull<FilterChainD3D12>>;
106
107/// A handle to a Direct3D 9 filter chain.
108#[cfg(any(
109    feature = "__cbindgen_internal",
110    all(target_os = "windows", feature = "runtime-d3d9")
111))]
112use librashader::runtime::d3d9::FilterChain as FilterChainD3D9;
113
114/// A handle to a Direct3D 11 filter chain.
115#[cfg_attr(
116    feature = "docsrs",
117    doc(cfg(all(target_os = "windows", feature = "runtime-d3d9")))
118)]
119#[cfg(any(
120    feature = "__cbindgen_internal",
121    all(target_os = "windows", feature = "runtime-d3d9")
122))]
123pub type libra_d3d9_filter_chain_t = Option<NonNull<FilterChainD3D9>>;
124
125#[cfg(feature = "runtime-vulkan")]
126use librashader::runtime::vk::FilterChain as FilterChainVulkan;
127/// A handle to a Vulkan filter chain.
128#[cfg(feature = "runtime-vulkan")]
129#[cfg_attr(feature = "docsrs", doc(cfg(feature = "runtime-vulkan")))]
130pub type libra_vk_filter_chain_t = Option<NonNull<FilterChainVulkan>>;
131
132#[cfg(all(target_os = "macos", feature = "runtime-metal"))]
133use librashader::runtime::mtl::FilterChain as FilterChainMetal;
134
135/// A handle to a Vulkan filter chain.
136#[cfg_attr(
137    feature = "docsrs",
138    doc(cfg(all(target_vendor = "apple", feature = "runtime-metal")))
139)]
140#[cfg(any(
141    feature = "__cbindgen_internal",
142    all(
143        target_vendor = "apple",
144        feature = "runtime-metal",
145        feature = "__cbindgen_internal_objc"
146    )
147))]
148pub type libra_mtl_filter_chain_t = Option<NonNull<FilterChainMetal>>;
149
150/// Defines the output origin for a rendered frame.
151#[repr(C)]
152pub struct libra_viewport_t {
153    /// The x offset in the viewport framebuffer to begin rendering from.
154    pub x: f32,
155    /// The y offset in the viewport framebuffer to begin rendering from.
156    pub y: f32,
157    /// The width extent of the viewport framebuffer to end rendering, relative to
158    /// the origin specified by x.
159    pub width: u32,
160    /// The height extent of the viewport framebuffer to end rendering, relative to
161    /// the origin specified by y.
162    pub height: u32,
163}
164
165pub(crate) trait FromUninit<T>
166where
167    Self: Sized,
168{
169    fn from_uninit(value: MaybeUninit<Self>) -> T;
170}
171
172macro_rules! config_set_field {
173    (@POINTER $options:ident.$field:ident <- $ptr:ident) => {
174        $options.$field = unsafe { ::std::ptr::addr_of!((*$ptr).$field).read() };
175    };
176    (@POINTER @NEGATIVE $options:ident.$field:ident <- $ptr:ident) => {
177        $options.$field = unsafe { !::std::ptr::addr_of!((*$ptr).$field).read() };
178    };
179    (@LITERAL $options:ident.$field:ident <- $value:literal) => {
180        $options.$field = $value;
181    };
182}
183
184macro_rules! config_version_set {
185    // "optimized" version for normal behaviour
186    (@ROOT $realver:ident $version:literal => [$($field:ident),+ $(,)?] ($options:ident <- $ptr:ident)) => {
187        #[allow(unused_comparisons)]
188        if $realver >= $version {
189            $($crate::ctypes::config_set_field!(@POINTER $options.$field <- $ptr);)+
190        }
191    };
192
193    // Repeater
194    (@ROOT $realver:ident $version:literal => [$($field:tt),+ $(,)?] ($options:ident <- $ptr:ident)) => {
195        $(crate::ctypes::config_version_set!(@SINGLE $realver $version => [$field] ($options <- $ptr));)+
196    };
197
198    // Allow overriding default value with a literal for older versions
199    (@SINGLE $realver:ident $version:literal => [($field:ident: $value:literal)] ($options:ident <- $ptr:ident)) => {
200        #[allow(unused_comparisons)]
201        if $realver >= $version {
202            $crate::ctypes::config_set_field!(@LITERAL $options.$field <- $value);
203        }
204    };
205
206    // Allow negation of prior variables that is version dependent.
207    (@SINGLE $realver:ident $version:literal => [(!$field:ident)] ($options:ident <- $ptr:ident)) => {
208        #[allow(unused_comparisons)]
209        if $realver >= $version {
210            $crate::ctypes::config_set_field!(@POINTER @NEGATIVE $options.$field <- $ptr);
211        }
212    };
213
214    (@SINGLE $realver:ident $version:literal => [$field:ident] ($options:ident <- $ptr:ident)) => {
215        #[allow(unused_comparisons)]
216        if $realver >= $version {
217            $crate::ctypes::config_set_field!(@POINTER $options.$field <- $ptr);
218        }
219    };
220}
221
222/// Macro to declare a configuration struct, with options to change behaviour based on
223/// API version.
224///
225/// For example following declaration does the following
226///
227/// * Declare `frames_in_flight`, `use_dynamic_rendering` for API version 0, with the following forward compatibility statements
228///     * Inverts the behaviour of `use_dynamic_rendering` compared to API version 1.
229///     * `disable_cache` is defaulted to `true` for API version 0, regardless of `Default::default`
230///        but is not declared for API 0.
231/// * Declare `use_dynamic_rendering` with normal behaviour, and `disable_cache` for API version 1.
232/// * All fields that are undeclared inherit `Default::default`
233///
234/// ```rust
235/// config_struct! {
236///     impl FilterChainOptions => filter_chain_vk_opt_t {
237///         0 => [frames_in_flight, (!use_dynamic_rendering), (disable_cache: true)];
238///         1 => [use_dynamic_rendering, disable_cache];
239///     }
240/// }
241/// ```
242macro_rules! config_struct {
243    (impl $rust:ty => $capi:ty {$($version:literal => [$($field:tt),+]);+ $(;)?}) => {
244        impl $crate::ctypes::FromUninit<$rust> for $capi {
245            fn from_uninit(value: ::std::mem::MaybeUninit<Self>) -> $rust {
246                let ptr = value.as_ptr();
247                let version = unsafe { ::std::ptr::addr_of!((*ptr).version).read() };
248
249                let mut options = <$rust>::default();
250                $(
251                    $crate::ctypes::config_version_set!(@ROOT version $version => [$($field),+] (options <- ptr));
252                )+
253                options
254            }
255        }
256    }
257}
258
259pub(crate) use config_set_field;
260pub(crate) use config_struct;
261pub(crate) use config_version_set;
262
263#[doc(hidden)]
264#[deny(deprecated)]
265#[deprecated = "Forward declarations for cbindgen, do not use."]
266mod __cbindgen_opaque_forward_declarations {
267    macro_rules! typedef_struct {
268        ($($(#[$($attrss:tt)*])* $name:ident;)*) => {
269            $($(#[$($attrss)*])*
270                #[allow(unused)]
271                #[doc(hidden)]
272                #[deny(deprecated)]
273                #[deprecated]
274                pub struct $name;
275            )*
276        };
277    }
278
279    typedef_struct! {
280        /// Opaque struct for a preset context.
281        WildcardContext;
282        /// Opaque struct for a shader preset.
283        ShaderPreset;
284        /// Opaque struct for an OpenGL filter chain.
285        FilterChainGL;
286        /// Opaque struct for a Direct3D 11 filter chain.
287        FilterChainD3D11;
288        /// Opaque struct for a Direct3D 12 filter chain.
289        FilterChainD3D12;
290        /// Opaque struct for a Direct3D 9 filter chain.
291        FilterChainD3D9;
292        /// Opaque struct for a Vulkan filter chain.
293        FilterChainVulkan;
294        /// Opaque struct for a Metal filter chain.
295        FilterChainMetal;
296    }
297}