capi: make function pointer types for everything

This commit is contained in:
chyyran 2022-12-05 00:06:37 -05:00
parent ebe889df2f
commit 2cce27ecb9
14 changed files with 290 additions and 252 deletions

77
Cargo.lock generated
View file

@ -213,16 +213,6 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
[[package]]
name = "ctor"
version = "0.1.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096"
dependencies = [
"quote",
"syn",
]
[[package]]
name = "cty"
version = "0.2.2"
@ -331,17 +321,6 @@ dependencies = [
"auto_ops",
]
[[package]]
name = "ghost"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb19fe8de3ea0920d282f7b77dd4227aea6b8b999b42cdf0ca41b2472b14443a"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "gif"
version = "0.11.4"
@ -462,28 +441,6 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "inventory"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0eb5160c60ba1e809707918ee329adb99d222888155835c6feedba19f6c3fd4"
dependencies = [
"ctor",
"ghost",
"inventory-impl",
]
[[package]]
name = "inventory-impl"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e41b53715c6f0c4be49510bb82dee2c1e51c8586d885abe65396e82ed518548"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "itoa"
version = "1.0.4"
@ -556,7 +513,6 @@ dependencies = [
"gl",
"librashader",
"paste",
"safer-ffi",
"thiserror",
"windows",
]
@ -697,21 +653,6 @@ dependencies = [
"autocfg",
]
[[package]]
name = "mini_paste"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2499b7bd9834270bf24cfc4dd96be59020ba6fd7f3276b772aee2de66e82b63"
dependencies = [
"mini_paste-proc_macro",
]
[[package]]
name = "mini_paste-proc_macro"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c5f1f52e39b728e73af4b454f1b29173d4544607bd395dafe1918fd149db67"
[[package]]
name = "minimal-lexical"
version = "0.2.1"
@ -1012,24 +953,6 @@ version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
[[package]]
name = "safer-ffi"
version = "0.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40c710243617290d86a49a30564d94d0b646eacf6d7b67035e20d6e8a21f1193"
dependencies = [
"inventory",
"libc",
"mini_paste",
"safer_ffi-proc_macro",
]
[[package]]
name = "safer_ffi-proc_macro"
version = "0.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc02dc034daa0944eb133b448f261ef7422ccae768e30f30ce5cdeb4ae4e506c"
[[package]]
name = "scoped_threadpool"
version = "0.1.9"

View file

@ -16,4 +16,4 @@ pub fn main() {
.expect("Unable to open file")
.write_all(string.as_bytes())
.expect("Unable to write bindings.")
}
}

View file

@ -4,7 +4,7 @@ include_guard = "__LIBRASHADER_H__"
pragma_once = true
usize_is_size_t = true
documentation_style = "c++"
header = "#ifdef _WIN32\n#include <d3d11.h>\n#else\ntypedef void ID3D11Device;typedef void ID3D11RenderTargetView;typedef void ID3D1ShaderResourceView;\n#endif"
after_includes = "#ifdef _WIN32\n#include <d3d11.h>\n#else\ntypedef void ID3D11Device;typedef void ID3D11RenderTargetView;typedef void ID3D1ShaderResourceView;\n#endif"
[parse]
parse_deps = true
include = ["librashader",
@ -33,7 +33,22 @@ include = [
"PFN_lbr_preset_get_runtime_param_names",
# error
"PFN_lbr_error_code",
"PFN_lbr_error_errno",
"PFN_lbr_error_print",
"PFN_lbr_error_free",
"PFN_lbr_error_write",
"PFN_lbr_error_free_string",
# gl
"PFN_lbr_gl_init_context",
"PFN_lbr_gl_filter_chain_create",
"PFN_lbr_gl_filter_chain_frame",
"PFN_lbr_gl_filter_chain_free",
# d3d11
"PFN_lbr_d3d11_filter_chain_create",
"PFN_lbr_d3d11_filter_chain_frame",
"PFN_lbr_d3d11_filter_chain_free"
]

View file

@ -1,9 +1,3 @@
#ifdef _WIN32
#include <d3d11.h>
#else
typedef void ID3D11Device;typedef void ID3D11RenderTargetView;typedef void ID3D1ShaderResourceView;
#endif
#ifndef __LIBRASHADER_H__
#define __LIBRASHADER_H__
@ -14,6 +8,11 @@ typedef void ID3D11Device;typedef void ID3D11RenderTargetView;typedef void ID3D1
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#ifdef _WIN32
#include <d3d11.h>
#else
typedef void ID3D11Device;typedef void ID3D11RenderTargetView;typedef void ID3D1ShaderResourceView;
#endif
/// Error codes for librashader error types.
enum LIBRA_ERRNO
@ -129,20 +128,83 @@ typedef struct frame_d3d11_opt_t {
int32_t frame_direction;
} frame_d3d11_opt_t;
typedef libra_error_t (*PFN_lbr_preset_free)(libra_shader_preset_t*);
typedef libra_error_t (*PFN_lbr_preset_free)(libra_shader_preset_t *preset);
typedef libra_error_t (*PFN_lbr_preset_set_param)(libra_shader_preset_t*, const char*, float);
typedef libra_error_t (*PFN_lbr_preset_set_param)(libra_shader_preset_t *preset, const char *name, float value);
typedef libra_error_t (*PFN_lbr_preset_get_param)(libra_shader_preset_t*, const char*, float*);
typedef libra_error_t (*PFN_lbr_preset_get_param)(libra_shader_preset_t *preset, const char *name, float *value);
typedef libra_error_t (*PFN_lbr_preset_print)(libra_shader_preset_t*);
typedef libra_error_t (*PFN_lbr_preset_print)(libra_shader_preset_t *preset);
typedef libra_error_t (*PFN_lbr_preset_get_runtime_param_names)(libra_shader_preset_t*, float*);
typedef libra_error_t (*PFN_lbr_preset_get_runtime_param_names)(libra_shader_preset_t *preset, const char **value);
typedef LIBRA_ERRNO (*PFN_lbr_error_errno)(libra_error_t error);
typedef int32_t (*PFN_lbr_error_print)(libra_error_t error);
typedef int32_t (*PFN_lbr_error_free)(libra_error_t *error);
typedef int32_t (*PFN_lbr_error_write)(libra_error_t error, char **out);
typedef int32_t (*PFN_lbr_error_free_string)(char **out);
typedef libra_error_t (*PFN_lbr_gl_init_context)(gl_loader_t loader);
typedef libra_error_t (*PFN_lbr_gl_filter_chain_create)(libra_shader_preset_t *preset, const struct filter_chain_gl_opt_t *options, libra_gl_filter_chain_t *out);
typedef libra_error_t (*PFN_lbr_gl_filter_chain_frame)(libra_gl_filter_chain_t *chain, size_t frame_count, struct libra_source_image_gl_t image, struct libra_viewport_t viewport, struct libra_draw_framebuffer_gl_t out, const float *mvp, const struct frame_gl_opt_t *opt);
typedef libra_error_t (*PFN_lbr_gl_filter_chain_free)(libra_gl_filter_chain_t *chain);
typedef libra_error_t (*PFN_lbr_d3d11_filter_chain_create)(libra_shader_preset_t *preset, const struct filter_chain_d3d11_opt_t *options, const ID3D11Device *device, libra_d3d11_filter_chain_t *out);
typedef libra_error_t (*PFN_lbr_d3d11_filter_chain_frame)(libra_d3d11_filter_chain_t *chain, size_t frame_count, struct libra_source_image_d3d11_t image, struct libra_viewport_t viewport, const ID3D11RenderTargetView *out, const float *mvp, const struct frame_d3d11_opt_t *opt);
typedef libra_error_t (*PFN_lbr_d3d11_filter_chain_free)(libra_d3d11_filter_chain_t *chain);
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
/// Get the error code corresponding to this error object.
///
/// ## Safety
/// - `error` must be valid and initialized.
LIBRA_ERRNO libra_error_errno(libra_error_t error);
/// Print the error message.
///
/// If `error` is null, this function does nothing and returns 1. Otherwise, this function returns 0.
/// ## Safety
/// - `error` must be a valid and initialized instance of `libra_error_t`.
int32_t libra_error_print(libra_error_t error);
/// Frees any internal state kept by the error.
///
/// If `error` is null, this function does nothing and returns 1. Otherwise, this function returns 0.
/// The resulting error object becomes null.
/// ## Safety
/// - `error` must be null or a pointer to a valid and initialized instance of `libra_error_t`.
int32_t libra_error_free(libra_error_t *error);
/// Writes the error message into `out`
///
/// If `error` is null, this function does nothing and returns 1. Otherwise, this function returns 0.
/// ## Safety
/// - `error` must be a valid and initialized instance of `libra_error_t`.
/// - `out` must be a non-null pointer. The resulting string must not be modified.
int32_t libra_error_write(libra_error_t error,
char **out);
/// Frees an error string previously allocated by `libra_error_write`.
///
/// After freeing, the pointer will be set to null.
/// ## Safety
/// - If `libra_error_write` is not null, it must point to a string previously returned by `libra_error_write`.
/// Attempting to free anything else, including strings or objects from other librashader functions, is immediate
/// Undefined Behaviour.
int32_t libra_error_free_string(char **out);
/// Load a preset.
///
/// ## Safety
@ -274,45 +336,6 @@ libra_error_t libra_d3d11_filter_chain_frame(libra_d3d11_filter_chain_t *chain,
/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_d3d11_filter_chain_t`.
libra_error_t libra_d3d11_filter_chain_free(libra_d3d11_filter_chain_t *chain);
/// Get the error code corresponding to this error object.
///
/// ## Safety
/// - `error` must be valid and initialized.
LIBRA_ERRNO libra_error_errno(libra_error_t error);
/// Print the error message.
///
/// If `error` is null, this function does nothing and returns 1. Otherwise, this function returns 0.
/// ## Safety
/// - `error` must be a valid and initialized instance of `libra_error_t`.
int32_t libra_error_print(libra_error_t error);
/// Frees any internal state kept by the error.
///
/// If `error` is null, this function does nothing and returns 1. Otherwise, this function returns 0.
/// The resulting error object becomes null.
/// ## Safety
/// - `error` must be null or a pointer to a valid and initialized instance of `libra_error_t`.
int32_t libra_error_free(libra_error_t *error);
/// Writes the error message into `out`
///
/// If `error` is null, this function does nothing and returns 1. Otherwise, this function returns 0.
/// ## Safety
/// - `error` must be a valid and initialized instance of `libra_error_t`.
/// - `out` must be a non-null pointer. The resulting string must not be modified.
int32_t libra_error_write(libra_error_t error,
char **out);
/// Frees an error string previously allocated by `libra_error_write`.
///
/// After freeing, the pointer will be set to null.
/// ## Safety
/// - If `libra_error_write` is not null, it must point to a string previously returned by `libra_error_write`.
/// Attempting to free anything else, including strings or objects from other librashader functions, is immediate
/// Undefined Behaviour.
int32_t libra_error_free_string(char **out);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus

View file

@ -1,7 +1,7 @@
//! Binding types for the librashader C API.
use std::ptr::NonNull;
use librashader::presets::ShaderPreset;
use crate::error::LibrashaderError;
use librashader::presets::ShaderPreset;
use std::ptr::NonNull;
pub type libra_shader_preset_t = Option<NonNull<ShaderPreset>>;
pub type libra_error_t = Option<NonNull<LibrashaderError>>;
@ -10,7 +10,8 @@ pub type libra_error_t = Option<NonNull<LibrashaderError>>;
pub type libra_gl_filter_chain_t = Option<NonNull<librashader::runtime::gl::FilterChainGL>>;
#[cfg(feature = "runtime-d3d11")]
pub type libra_d3d11_filter_chain_t = Option<NonNull<librashader::runtime::d3d11::FilterChainD3D11>>;
pub type libra_d3d11_filter_chain_t =
Option<NonNull<librashader::runtime::d3d11::FilterChainD3D11>>;
/// Parameters for the output viewport.
#[repr(C)]
@ -19,4 +20,4 @@ pub struct libra_viewport_t {
pub y: f32,
pub width: u32,
pub height: u32,
}
}

View file

@ -25,7 +25,6 @@ pub enum LibrashaderError {
#[cfg(feature = "runtime-d3d11")]
#[error("There was an error in the D3D11 filter chain.")]
D3D11FilterError(#[from] librashader::runtime::d3d11::error::FilterChainError),
}
/// Error codes for librashader error types.
@ -39,8 +38,7 @@ pub enum LIBRA_ERRNO {
RUNTIME_ERROR = 5,
}
pub type PFN_lbr_error_errno = extern "C" fn (libra_error_t) -> LIBRA_ERRNO;
pub type PFN_lbr_error_errno = extern "C" fn(error: libra_error_t) -> LIBRA_ERRNO;
#[no_mangle]
/// Get the error code corresponding to this error object.
///
@ -51,12 +49,10 @@ pub extern "C" fn libra_error_errno(error: libra_error_t) -> LIBRA_ERRNO {
return LIBRA_ERRNO::UNKNOWN_ERROR
};
unsafe {
error.as_ref().get_code()
}
unsafe { error.as_ref().get_code() }
}
pub type PFN_lbr_error_print = extern "C" fn (libra_error_t) -> i32;
pub type PFN_lbr_error_print = extern "C" fn(error: libra_error_t) -> i32;
#[no_mangle]
/// Print the error message.
///
@ -74,7 +70,7 @@ pub extern "C" fn libra_error_print(error: libra_error_t) -> i32 {
return 0;
}
pub type PFN_lbr_error_free = extern "C" fn (*mut libra_error_t) -> i32;
pub type PFN_lbr_error_free = extern "C" fn(error: *mut libra_error_t) -> i32;
#[no_mangle]
/// Frees any internal state kept by the error.
///
@ -93,12 +89,12 @@ pub extern "C" fn libra_error_free(error: *mut libra_error_t) -> i32 {
return 1;
};
unsafe {
drop(Box::from_raw(error.as_ptr()))
}
unsafe { drop(Box::from_raw(error.as_ptr())) }
return 0;
}
pub type PFN_lbr_error_write =
extern "C" fn(error: libra_error_t, out: *mut MaybeUninit<*mut c_char>) -> i32;
#[no_mangle]
/// Writes the error message into `out`
///
@ -106,7 +102,10 @@ pub extern "C" fn libra_error_free(error: *mut libra_error_t) -> i32 {
/// ## Safety
/// - `error` must be a valid and initialized instance of `libra_error_t`.
/// - `out` must be a non-null pointer. The resulting string must not be modified.
pub extern "C" fn libra_error_write(error: libra_error_t, out: *mut MaybeUninit<*mut c_char>) -> i32 {
pub extern "C" fn libra_error_write(
error: libra_error_t,
out: *mut MaybeUninit<*mut c_char>,
) -> i32 {
let Some(error) = error else {
return 1
};
@ -125,6 +124,7 @@ pub extern "C" fn libra_error_write(error: libra_error_t, out: *mut MaybeUninit<
return 0;
}
pub type PFN_lbr_error_free_string = extern "C" fn(out: *mut *mut c_char) -> i32;
#[no_mangle]
/// Frees an error string previously allocated by `libra_error_write`.
///
@ -157,8 +157,7 @@ impl LibrashaderError {
#[cfg(feature = "runtime-opengl")]
LibrashaderError::OpenGlFilterError(_) => LIBRA_ERRNO::RUNTIME_ERROR,
#[cfg(feature = "runtime-d3d11")]
LibrashaderError::D3D11FilterError(_) => LIBRA_ERRNO::RUNTIME_ERROR
LibrashaderError::D3D11FilterError(_) => LIBRA_ERRNO::RUNTIME_ERROR,
}
}
pub(crate) const fn ok() -> libra_error_t {
@ -177,41 +176,43 @@ impl LibrashaderError {
macro_rules! assert_non_null {
($value:ident) => {
if $value.is_null() {
return $crate::error::LibrashaderError::InvalidParameter(stringify!($value)).export()
return $crate::error::LibrashaderError::InvalidParameter(stringify!($value)).export();
}
};
(noexport $value:ident) => {
if $value.is_null() {
return Err($crate::error::LibrashaderError::InvalidParameter(stringify!($value)))
return Err($crate::error::LibrashaderError::InvalidParameter(
stringify!($value),
));
}
}
};
}
macro_rules! assert_some {
($value:ident) => {
if $value.is_none() {
return $crate::error::LibrashaderError::InvalidParameter(stringify!($value)).export()
return $crate::error::LibrashaderError::InvalidParameter(stringify!($value)).export();
}
}
};
}
macro_rules! assert_some_ptr {
($value:ident) => {
if $value.is_none() {
return $crate::error::LibrashaderError::InvalidParameter(stringify!($value)).export()
return $crate::error::LibrashaderError::InvalidParameter(stringify!($value)).export();
}
let $value = unsafe { $value.as_ref().unwrap().as_ref() };
};
(mut $value:ident) => {
if $value.is_none() {
return $crate::error::LibrashaderError::InvalidParameter(stringify!($value)).export()
return $crate::error::LibrashaderError::InvalidParameter(stringify!($value)).export();
}
let $value = unsafe { $value.as_mut().unwrap().as_mut() };
}
};
}
use crate::ctypes::libra_error_t;
pub(crate) use assert_non_null;
pub(crate) use assert_some;
pub(crate) use assert_some_ptr;
use crate::ctypes::libra_error_t;

View file

@ -1,4 +1,3 @@
macro_rules! ffi_body {
($body:block) => {
{
@ -58,7 +57,6 @@ macro_rules! ffi_body {
}
}
macro_rules! extern_fn {
($(#[$($attrss:tt)*])* fn $func_name:ident ($($arg_name:ident : $arg_ty:ty),*) $body:block) => {
paste::paste! {
@ -74,4 +72,4 @@ macro_rules! extern_fn {
}
pub(crate) use extern_fn;
pub(crate) use ffi_body;
pub(crate) use ffi_body;

View file

@ -40,8 +40,8 @@
use std::os::raw::c_char;
pub mod ctypes;
pub mod error;
mod ffi;
pub mod presets;
pub mod runtime;
pub mod error;
pub mod ctypes;
mod ffi;

View file

@ -1,13 +1,16 @@
//! The librashader preset C API (`libra_preset_*`).
use std::ffi::{c_char, CStr, CString};
use std::mem::{MaybeUninit};
use librashader::presets::ShaderPreset;
use crate::ffi::ffi_body;
use crate::ctypes::{libra_error_t, libra_shader_preset_t};
use crate::error::{assert_non_null, assert_some, assert_some_ptr, LibrashaderError};
use crate::ffi::ffi_body;
use librashader::presets::ShaderPreset;
use std::ffi::{c_char, CStr, CString};
use std::mem::MaybeUninit;
use std::ptr::NonNull;
pub type PFN_lbr_preset_create = unsafe extern "C" fn (*const c_char, *mut MaybeUninit<libra_shader_preset_t>) -> libra_error_t;
pub type PFN_lbr_preset_create = unsafe extern "C" fn(
filename: *const c_char,
out: *mut MaybeUninit<libra_shader_preset_t>,
) -> libra_error_t;
/// Load a preset.
///
@ -17,14 +20,15 @@ pub type PFN_lbr_preset_create = unsafe extern "C" fn (*const c_char, *mut Maybe
/// ## Returns
/// - If any parameters are null, `out` is unchanged, and this function returns `LIBRA_ERR_INVALID_PARAMETER`.
#[no_mangle]
pub unsafe extern "C" fn libra_preset_create(filename: *const c_char, out: *mut MaybeUninit<libra_shader_preset_t>) -> libra_error_t {
pub unsafe extern "C" fn libra_preset_create(
filename: *const c_char,
out: *mut MaybeUninit<libra_shader_preset_t>,
) -> libra_error_t {
ffi_body!({
assert_non_null!(filename);
assert_non_null!(out);
let filename = unsafe {
CStr::from_ptr(filename)
};
let filename = unsafe { CStr::from_ptr(filename) };
let filename = filename.to_str()?;
@ -32,12 +36,15 @@ pub unsafe extern "C" fn libra_preset_create(filename: *const c_char, out: *mut
let preset = ShaderPreset::try_parse(filename)?;
unsafe {
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(preset)))))
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(
preset,
)))))
}
})
}
pub type PFN_lbr_preset_free = unsafe extern "C" fn (*mut libra_shader_preset_t) -> libra_error_t;
pub type PFN_lbr_preset_free =
unsafe extern "C" fn(preset: *mut libra_shader_preset_t) -> libra_error_t;
/// Free the preset.
///
@ -58,15 +65,22 @@ pub unsafe extern "C" fn libra_preset_free(preset: *mut libra_shader_preset_t) -
})
}
pub type PFN_lbr_preset_set_param = unsafe extern "C" fn (*mut libra_shader_preset_t, *const c_char, f32) -> libra_error_t;
pub type PFN_lbr_preset_set_param = unsafe extern "C" fn(
preset: *mut libra_shader_preset_t,
name: *const c_char,
value: f32,
) -> libra_error_t;
/// Set the value of the parameter in the preset.
///
/// ## Safety
/// - `preset` must be null or a valid and aligned pointer to a shader preset.
/// - `name` must be null or a valid and aligned pointer to a string.
#[no_mangle]
pub unsafe extern "C" fn libra_preset_set_param(preset: *mut libra_shader_preset_t,
name: *const c_char, value: f32) -> libra_error_t {
pub unsafe extern "C" fn libra_preset_set_param(
preset: *mut libra_shader_preset_t,
name: *const c_char,
value: f32,
) -> libra_error_t {
ffi_body!(|name|; mut |preset| {
let name = unsafe {
CStr::from_ptr(name)
@ -81,7 +95,11 @@ pub unsafe extern "C" fn libra_preset_set_param(preset: *mut libra_shader_preset
})
}
pub type PFN_lbr_preset_get_param = unsafe extern "C" fn (*mut libra_shader_preset_t, *const c_char, *mut MaybeUninit<f32>) -> libra_error_t;
pub type PFN_lbr_preset_get_param = unsafe extern "C" fn(
preset: *mut libra_shader_preset_t,
name: *const c_char,
value: *mut MaybeUninit<f32>,
) -> libra_error_t;
/// Get the value of the parameter as set in the preset.
///
@ -90,12 +108,13 @@ pub type PFN_lbr_preset_get_param = unsafe extern "C" fn (*mut libra_shader_pres
/// - `name` must be null or a valid and aligned pointer to a string.
/// - `value` may be a pointer to a uninitialized `float`.
#[no_mangle]
pub unsafe extern "C" fn libra_preset_get_param(preset: *mut libra_shader_preset_t,
name: *const c_char, value: *mut MaybeUninit<f32>) -> libra_error_t {
ffi_body!(|name, preset | {
let name = unsafe {
CStr::from_ptr(name)
};
pub unsafe extern "C" fn libra_preset_get_param(
preset: *mut libra_shader_preset_t,
name: *const c_char,
value: *mut MaybeUninit<f32>,
) -> libra_error_t {
ffi_body!(|name, preset| {
let name = unsafe { CStr::from_ptr(name) };
let name = name.to_str()?;
assert_some_ptr!(preset);
@ -103,14 +122,13 @@ pub unsafe extern "C" fn libra_preset_get_param(preset: *mut libra_shader_preset
assert_non_null!(value);
if let Some(param) = preset.parameters.iter().find(|c| c.name == name) {
unsafe {
value.write(MaybeUninit::new(param.value))
}
unsafe { value.write(MaybeUninit::new(param.value)) }
}
})
}
pub type PFN_lbr_preset_print = unsafe extern "C" fn (*mut libra_shader_preset_t) -> libra_error_t;
pub type PFN_lbr_preset_print =
unsafe extern "C" fn(preset: *mut libra_shader_preset_t) -> libra_error_t;
/// Pretty print the shader preset.
///
@ -124,22 +142,28 @@ pub unsafe extern "C" fn libra_preset_print(preset: *mut libra_shader_preset_t)
})
}
pub type PFN_lbr_preset_get_runtime_param_names = unsafe extern "C" fn (*mut libra_shader_preset_t, *mut MaybeUninit<f32>) -> libra_error_t;
pub type PFN_lbr_preset_get_runtime_param_names = unsafe extern "C" fn(
preset: *mut libra_shader_preset_t,
value: MaybeUninit<*mut *const c_char>,
) -> libra_error_t;
/// Get a list of runtime parameter names.
///
/// The returned value can not currently be freed.
/// This function should be considered in progress. Its use is discouraged.
#[no_mangle]
pub unsafe extern "C" fn libra_preset_get_runtime_param_names(preset: *mut libra_shader_preset_t, mut value: MaybeUninit<*mut *const c_char>) -> libra_error_t {
ffi_body!(|preset | {
pub unsafe extern "C" fn libra_preset_get_runtime_param_names(
preset: *mut libra_shader_preset_t,
mut value: MaybeUninit<*mut *const c_char>,
) -> libra_error_t {
ffi_body!(|preset| {
assert_some_ptr!(preset);
let iter = librashader::presets::get_parameter_meta(preset)?;
let mut c_strings = Vec::new();
for param in iter {
let c_string = CString::new(param.id).map_err(|err| LibrashaderError::UnknownError(Box::new(err)))?;
let c_string = CString::new(param.id)
.map_err(|err| LibrashaderError::UnknownError(Box::new(err)))?;
c_strings.push(c_string.into_raw().cast_const());
}

View file

@ -1,11 +1,15 @@
use std::mem::MaybeUninit;
use windows::Win32::Graphics::Direct3D11::{ID3D11Device, ID3D11RenderTargetView, ID3D11ShaderResourceView};
use crate::ctypes::{libra_d3d11_filter_chain_t, libra_error_t, libra_shader_preset_t, libra_viewport_t};
use crate::ffi::ffi_body;
use crate::ctypes::{
libra_d3d11_filter_chain_t, libra_error_t, libra_shader_preset_t, libra_viewport_t,
};
use crate::error::{assert_non_null, assert_some_ptr, LibrashaderError};
use std::ptr::NonNull;
use crate::ffi::ffi_body;
use librashader::runtime::d3d11::{DxImageView, Viewport};
use std::mem::MaybeUninit;
use std::ptr::NonNull;
use std::slice;
use windows::Win32::Graphics::Direct3D11::{
ID3D11Device, ID3D11RenderTargetView, ID3D11ShaderResourceView,
};
pub use librashader::runtime::d3d11::options::FilterChainOptionsD3D11;
pub use librashader::runtime::d3d11::options::FrameOptionsD3D11;
@ -19,11 +23,9 @@ pub struct libra_source_image_d3d11_t {
/// The width of the source image.
pub width: u32,
/// The height of the source image.
pub height: u32
pub height: u32,
}
impl TryFrom<libra_source_image_d3d11_t> for DxImageView {
type Error = LibrashaderError;
@ -38,6 +40,12 @@ impl TryFrom<libra_source_image_d3d11_t> for DxImageView {
}
}
pub type PFN_lbr_d3d11_filter_chain_create = unsafe extern "C" fn(
preset: *mut libra_shader_preset_t,
options: *const FilterChainOptionsD3D11,
device: *const ID3D11Device,
out: *mut MaybeUninit<libra_d3d11_filter_chain_t>,
) -> libra_error_t;
/// Create the filter chain given the shader preset.
///
/// The shader preset is immediately invalidated and must be recreated after
@ -48,14 +56,16 @@ impl TryFrom<libra_source_image_d3d11_t> for DxImageView {
/// - `options` must be either null, or valid and aligned.
/// - `out` must be aligned, but may be null, invalid, or uninitialized.
#[no_mangle]
pub unsafe extern "C" fn libra_d3d11_filter_chain_create(preset: *mut libra_shader_preset_t,
options: *const FilterChainOptionsD3D11,
device: *const ID3D11Device,
out: *mut MaybeUninit<libra_d3d11_filter_chain_t>) -> libra_error_t {
pub unsafe extern "C" fn libra_d3d11_filter_chain_create(
preset: *mut libra_shader_preset_t,
options: *const FilterChainOptionsD3D11,
device: *const ID3D11Device,
out: *mut MaybeUninit<libra_d3d11_filter_chain_t>,
) -> libra_error_t {
ffi_body!({
assert_non_null!(preset);
assert_non_null!(device);
let preset = unsafe {
let preset = unsafe {
let preset_ptr = &mut *preset;
let preset = preset_ptr.take();
Box::from_raw(preset.unwrap().as_ptr())
@ -67,15 +77,30 @@ pub unsafe extern "C" fn libra_d3d11_filter_chain_create(preset: *mut libra_shad
Some(unsafe { &*options })
};
let chain = librashader::runtime::d3d11::FilterChainD3D11::load_from_preset(unsafe { &*device }, *preset, options)?;
let chain = librashader::runtime::d3d11::FilterChainD3D11::load_from_preset(
unsafe { &*device },
*preset,
options,
)?;
unsafe {
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(chain)))))
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(
chain,
)))))
}
})
}
pub type PFN_lbr_d3d11_filter_chain_frame = unsafe extern "C" fn(
chain: *mut libra_d3d11_filter_chain_t,
frame_count: usize,
image: libra_source_image_d3d11_t,
viewport: libra_viewport_t,
out: *const ID3D11RenderTargetView,
mvp: *const f32,
opt: *const FrameOptionsD3D11,
) -> libra_error_t;
/// Draw a frame with the given parameters for the given filter chain.
///
/// ## Safety
@ -86,16 +111,15 @@ pub unsafe extern "C" fn libra_d3d11_filter_chain_create(preset: *mut libra_shad
/// - `opt` may be null, or if it is not null, must be an aligned pointer to a valid `frame_gl_opt_t`
/// struct.
#[no_mangle]
pub unsafe extern "C" fn libra_d3d11_filter_chain_frame(chain: *mut libra_d3d11_filter_chain_t,
frame_count: usize,
image: libra_source_image_d3d11_t,
viewport: libra_viewport_t,
out: *const ID3D11RenderTargetView,
mvp: *const f32,
opt: *const FrameOptionsD3D11,
pub unsafe extern "C" fn libra_d3d11_filter_chain_frame(
chain: *mut libra_d3d11_filter_chain_t,
frame_count: usize,
image: libra_source_image_d3d11_t,
viewport: libra_viewport_t,
out: *const ID3D11RenderTargetView,
mvp: *const f32,
opt: *const FrameOptionsD3D11,
) -> libra_error_t {
ffi_body!(mut |chain| {
assert_some_ptr!(mut chain);
assert_non_null!(out);
@ -125,13 +149,18 @@ pub unsafe extern "C" fn libra_d3d11_filter_chain_frame(chain: *mut libra_d3d11_
})
}
pub type PFN_lbr_d3d11_filter_chain_free = unsafe extern "C" fn(
chain: *mut libra_d3d11_filter_chain_t,
) -> libra_error_t;
/// Free a D3D11 filter chain.
///
/// The resulting value in `chain` then becomes null.
/// ## Safety
/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_d3d11_filter_chain_t`.
#[no_mangle]
pub unsafe extern "C" fn libra_d3d11_filter_chain_free(chain: *mut libra_d3d11_filter_chain_t) -> libra_error_t {
pub unsafe extern "C" fn libra_d3d11_filter_chain_free(
chain: *mut libra_d3d11_filter_chain_t,
) -> libra_error_t {
ffi_body!({
assert_non_null!(chain);
unsafe {
@ -140,4 +169,4 @@ pub unsafe extern "C" fn libra_d3d11_filter_chain_free(chain: *mut libra_d3d11_f
drop(Box::from_raw(chain.unwrap().as_ptr()))
};
})
}
}

View file

@ -1,4 +1,4 @@
//! C API for the librashader OpenGL Runtime (`libra_d3d11_*`)
mod filter_chain;
pub use filter_chain::*;
pub use filter_chain::*;

View file

@ -1,20 +1,23 @@
use std::ffi::{c_char, c_void, CString};
use std::mem::MaybeUninit;
use crate::ctypes::{libra_error_t, libra_gl_filter_chain_t, libra_shader_preset_t, libra_viewport_t};
use crate::ctypes::{
libra_error_t, libra_gl_filter_chain_t, libra_shader_preset_t, libra_viewport_t,
};
use crate::error::{assert_non_null, assert_some_ptr, LibrashaderError};
use crate::ffi::ffi_body;
use librashader::runtime::gl::{GLImage, Viewport};
use librashader::runtime::FilterChain;
use std::ffi::{c_char, c_void, CString};
use std::mem::MaybeUninit;
use std::ptr::NonNull;
use std::slice;
use librashader::runtime::FilterChain;
use librashader::runtime::gl::{GLImage, Viewport};
pub use librashader::runtime::gl::options::FilterChainOptionsGL;
pub use librashader::runtime::gl::options::FrameOptionsGL;
use librashader::Size;
/// A GL function loader that librashader needs to be initialized with.
pub type gl_loader_t = unsafe extern "C" fn (*const c_char) -> *const c_void;
pub type gl_loader_t = unsafe extern "C" fn(*const c_char) -> *const c_void;
pub type PFN_lbr_gl_init_context = unsafe extern "C" fn(loader: gl_loader_t) -> libra_error_t;
/// Initialize the OpenGL Context for librashader.
///
/// ## Safety
@ -24,16 +27,19 @@ pub type gl_loader_t = unsafe extern "C" fn (*const c_char) -> *const c_void;
/// chain objects, and drawing with them causes immediate undefined behaviour.
#[no_mangle]
pub unsafe extern "C" fn libra_gl_init_context(loader: gl_loader_t) -> libra_error_t {
gl::load_with(|s| {
unsafe {
let proc_name = CString::new(s).unwrap_unchecked();
loader(proc_name.as_ptr())
}
gl::load_with(|s| unsafe {
let proc_name = CString::new(s).unwrap_unchecked();
loader(proc_name.as_ptr())
});
LibrashaderError::ok()
}
pub type PFN_lbr_gl_filter_chain_create = unsafe extern "C" fn(
preset: *mut libra_shader_preset_t,
options: *const FilterChainOptionsGL,
out: *mut MaybeUninit<libra_gl_filter_chain_t>,
) -> libra_error_t;
/// Create the filter chain given the shader preset.
///
/// The shader preset is immediately invalidated and must be recreated after
@ -44,12 +50,14 @@ pub unsafe extern "C" fn libra_gl_init_context(loader: gl_loader_t) -> libra_err
/// - `options` must be either null, or valid and aligned.
/// - `out` must be aligned, but may be null, invalid, or uninitialized.
#[no_mangle]
pub unsafe extern "C" fn libra_gl_filter_chain_create(preset: *mut libra_shader_preset_t,
options: *const FilterChainOptionsGL,
out: *mut MaybeUninit<libra_gl_filter_chain_t>) -> libra_error_t {
pub unsafe extern "C" fn libra_gl_filter_chain_create(
preset: *mut libra_shader_preset_t,
options: *const FilterChainOptionsGL,
out: *mut MaybeUninit<libra_gl_filter_chain_t>,
) -> libra_error_t {
ffi_body!({
assert_non_null!(preset);
let preset = unsafe {
let preset = unsafe {
let preset_ptr = &mut *preset;
let preset = preset_ptr.take();
Box::from_raw(preset.unwrap().as_ptr())
@ -61,11 +69,12 @@ pub unsafe extern "C" fn libra_gl_filter_chain_create(preset: *mut libra_shader_
Some(unsafe { &*options })
};
let chain = librashader::runtime::gl::FilterChainGL::load_from_preset(*preset, options)?;
unsafe {
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(chain)))))
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(
chain,
)))))
}
})
}
@ -80,7 +89,7 @@ pub struct libra_source_image_gl_t {
/// The width of the source image.
pub width: u32,
/// The height of the source image.
pub height: u32
pub height: u32,
}
/// OpenGL parameters for the output framebuffer.
@ -100,11 +109,21 @@ impl From<libra_source_image_gl_t> for GLImage {
handle: value.handle,
format: value.format,
size: Size::new(value.width, value.height),
padded_size: Size::default()
padded_size: Size::default(),
}
}
}
pub type PFN_lbr_gl_filter_chain_frame = unsafe extern "C" fn(
chain: *mut libra_gl_filter_chain_t,
frame_count: usize,
image: libra_source_image_gl_t,
viewport: libra_viewport_t,
out: libra_draw_framebuffer_gl_t,
mvp: *const f32,
opt: *const FrameOptionsGL,
) -> libra_error_t;
/// Draw a frame with the given parameters for the given filter chain.
///
/// ## Safety
@ -115,14 +134,14 @@ impl From<libra_source_image_gl_t> for GLImage {
/// - `opt` may be null, or if it is not null, must be an aligned pointer to a valid `frame_gl_opt_t`
/// struct.
#[no_mangle]
pub unsafe extern "C" fn libra_gl_filter_chain_frame(chain: *mut libra_gl_filter_chain_t,
frame_count: usize,
image: libra_source_image_gl_t,
viewport: libra_viewport_t,
out: libra_draw_framebuffer_gl_t,
mvp: *const f32,
opt: *const FrameOptionsGL,
pub unsafe extern "C" fn libra_gl_filter_chain_frame(
chain: *mut libra_gl_filter_chain_t,
frame_count: usize,
image: libra_source_image_gl_t,
viewport: libra_viewport_t,
out: libra_draw_framebuffer_gl_t,
mvp: *const f32,
opt: *const FrameOptionsGL,
) -> libra_error_t {
ffi_body!(mut |chain| {
assert_some_ptr!(mut chain);
@ -150,6 +169,9 @@ pub unsafe extern "C" fn libra_gl_filter_chain_frame(chain: *mut libra_gl_filter
})
}
pub type PFN_lbr_gl_filter_chain_free = unsafe extern "C" fn(
chain: *mut libra_gl_filter_chain_t,
)-> libra_error_t;
/// Free a GL filter chain.
///
@ -157,7 +179,9 @@ pub unsafe extern "C" fn libra_gl_filter_chain_frame(chain: *mut libra_gl_filter
/// ## Safety
/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_gl_filter_chain_t`.
#[no_mangle]
pub unsafe extern "C" fn libra_gl_filter_chain_free(chain: *mut libra_gl_filter_chain_t) -> libra_error_t {
pub unsafe extern "C" fn libra_gl_filter_chain_free(
chain: *mut libra_gl_filter_chain_t,
) -> libra_error_t {
ffi_body!({
assert_non_null!(chain);
unsafe {
@ -166,4 +190,4 @@ pub unsafe extern "C" fn libra_gl_filter_chain_free(chain: *mut libra_gl_filter_
drop(Box::from_raw(chain.unwrap().as_ptr()))
};
})
}
}

View file

@ -1,4 +1,4 @@
//! C API for the librashader OpenGL Runtime (`libra_gl_*`)
mod filter_chain;
pub use filter_chain::*;
pub use filter_chain::*;

View file

@ -3,4 +3,4 @@
pub mod gl;
#[cfg(feature = "runtime-d3d11")]
pub mod d3d11;
pub mod d3d11;