capi: get rid of safer_ffi
This commit is contained in:
parent
0e18b56752
commit
ebe889df2f
|
@ -19,14 +19,12 @@ crate-type = [ "cdylib", "staticlib", "lib" ]
|
|||
default = ["runtime-opengl", "runtime-d3d11"]
|
||||
runtime-opengl = ["gl", "librashader/gl"]
|
||||
runtime-d3d11 = ["windows", "librashader/d3d11"]
|
||||
headers = ["safer-ffi/headers"]
|
||||
|
||||
[dependencies]
|
||||
librashader = { path = "../librashader", version = "0.1.0-alpha.2" }
|
||||
thiserror = "1.0.37"
|
||||
paste = "1.0.9"
|
||||
gl = { version = "0.14.0", optional = true }
|
||||
safer-ffi = { version = "0.0.10", repository = "https://github.com/getditto/safer_ffi" }
|
||||
|
||||
[dependencies.windows]
|
||||
version = "0.43.0"
|
||||
|
|
|
@ -4,13 +4,15 @@ 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"
|
||||
[parse]
|
||||
parse_deps = true
|
||||
include = ["librashader",
|
||||
"librashader-presets",
|
||||
"librashader-preprocess",
|
||||
"librashader-reflect",
|
||||
"librashader-runtime-gl"
|
||||
"librashader-runtime-gl",
|
||||
"librashader-runtime-d3d11"
|
||||
]
|
||||
|
||||
|
||||
|
@ -43,3 +45,6 @@ include = [
|
|||
"FilterChainGL" = "_filter_chain_gl"
|
||||
"FilterChainOptionsGL" = "filter_chain_gl_opt_t"
|
||||
"FrameOptionsGL" = "frame_gl_opt_t"
|
||||
"FilterChainD3D11" = "_filter_chain_d3d11"
|
||||
"FilterChainOptionsD3D11" = "filter_chain_d3d11_opt_t"
|
||||
"FrameOptionsD3D11" = "frame_d3d11_opt_t"
|
|
@ -1,3 +0,0 @@
|
|||
fn main() -> ::std::io::Result<()> {
|
||||
::librashader_capi::generate_headers()
|
||||
}
|
|
@ -1,3 +1,9 @@
|
|||
#ifdef _WIN32
|
||||
#include <d3d11.h>
|
||||
#else
|
||||
typedef void ID3D11Device;typedef void ID3D11RenderTargetView;typedef void ID3D1ShaderResourceView;
|
||||
#endif
|
||||
|
||||
#ifndef __LIBRASHADER_H__
|
||||
#define __LIBRASHADER_H__
|
||||
|
||||
|
@ -26,6 +32,8 @@ enum LIBRA_ERRNO
|
|||
typedef int32_t LIBRA_ERRNO;
|
||||
#endif // __cplusplus
|
||||
|
||||
typedef struct _filter_chain_d3d11 _filter_chain_d3d11;
|
||||
|
||||
typedef struct _filter_chain_gl _filter_chain_gl;
|
||||
|
||||
/// The error type for librashader.
|
||||
|
@ -44,8 +52,11 @@ typedef struct _shader_preset *libra_shader_preset_t;
|
|||
/// A GL function loader that librashader needs to be initialized with.
|
||||
typedef const void *(*gl_loader_t)(const char*);
|
||||
|
||||
/// Options for filter chain creation.
|
||||
typedef struct filter_chain_gl_opt_t {
|
||||
/// The GLSL version. Should be at least `330`.
|
||||
uint16_t gl_version;
|
||||
/// Whether or not to use the Direct State Access APIs. Only available on OpenGL 4.5+.
|
||||
bool use_dsa;
|
||||
} filter_chain_gl_opt_t;
|
||||
|
||||
|
@ -81,11 +92,43 @@ typedef struct libra_draw_framebuffer_gl_t {
|
|||
uint32_t format;
|
||||
} libra_draw_framebuffer_gl_t;
|
||||
|
||||
/// Options for each OpenGL shader frame.
|
||||
typedef struct frame_gl_opt_t {
|
||||
/// Whether or not to clear the history buffers.
|
||||
bool clear_history;
|
||||
/// The direction of the frame. 1 should be vertical.
|
||||
int32_t frame_direction;
|
||||
} frame_gl_opt_t;
|
||||
|
||||
/// Options for Direct3D11 filter chain creation.
|
||||
typedef struct filter_chain_d3d11_opt_t {
|
||||
/// Use a deferred context to record shader rendering state.
|
||||
///
|
||||
/// The deferred context will be executed on the immediate context
|
||||
/// with `RenderContextState = true`.
|
||||
bool use_deferred_context;
|
||||
} filter_chain_d3d11_opt_t;
|
||||
|
||||
typedef struct _filter_chain_d3d11 *libra_d3d11_filter_chain_t;
|
||||
|
||||
/// OpenGL parameters for the source image.
|
||||
typedef struct libra_source_image_d3d11_t {
|
||||
/// A shader resource view into the source image
|
||||
const ID3D11ShaderResourceView *handle;
|
||||
/// The width of the source image.
|
||||
uint32_t width;
|
||||
/// The height of the source image.
|
||||
uint32_t height;
|
||||
} libra_source_image_d3d11_t;
|
||||
|
||||
/// Options for each Direct3D11 shader frame.
|
||||
typedef struct frame_d3d11_opt_t {
|
||||
/// Whether or not to clear the history buffers.
|
||||
bool clear_history;
|
||||
/// The direction of the frame. 1 should be vertical.
|
||||
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_set_param)(libra_shader_preset_t*, const char*, float);
|
||||
|
@ -114,20 +157,36 @@ libra_error_t libra_preset_create(const char *filename,
|
|||
///
|
||||
/// If `preset` is null, this function does nothing. The resulting value in `preset` then becomes
|
||||
/// null.
|
||||
///
|
||||
/// ## Safety
|
||||
/// - `preset` must be a valid and aligned pointer to a shader preset.
|
||||
libra_error_t libra_preset_free(libra_shader_preset_t *preset);
|
||||
|
||||
/// 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.
|
||||
libra_error_t libra_preset_set_param(libra_shader_preset_t *preset, const char *name, float value);
|
||||
|
||||
/// Get the value of the parameter as set 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.
|
||||
/// - `value` may be a pointer to a uninitialized `float`.
|
||||
libra_error_t libra_preset_get_param(libra_shader_preset_t *preset, const char *name, float *value);
|
||||
|
||||
/// Pretty print the shader preset.
|
||||
///
|
||||
/// ## Safety
|
||||
/// - `preset` must be null or a valid and aligned pointer to a shader preset.
|
||||
libra_error_t libra_preset_print(libra_shader_preset_t *preset);
|
||||
|
||||
/// 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.
|
||||
libra_error_t libra_preset_get_runtime_param_names(libra_shader_preset_t *preset,
|
||||
const char **value);
|
||||
|
||||
|
@ -177,6 +236,44 @@ libra_error_t libra_gl_filter_chain_frame(libra_gl_filter_chain_t *chain,
|
|||
/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_gl_filter_chain_t`.
|
||||
libra_error_t libra_gl_filter_chain_free(libra_gl_filter_chain_t *chain);
|
||||
|
||||
/// Create the filter chain given the shader preset.
|
||||
///
|
||||
/// The shader preset is immediately invalidated and must be recreated after
|
||||
/// the filter chain is created.
|
||||
///
|
||||
/// ## Safety:
|
||||
/// - `preset` must be either null, or valid and aligned.
|
||||
/// - `options` must be either null, or valid and aligned.
|
||||
/// - `out` must be aligned, but may be null, invalid, or uninitialized.
|
||||
libra_error_t libra_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);
|
||||
|
||||
/// Draw a frame with the given parameters for the given filter chain.
|
||||
///
|
||||
/// ## Safety
|
||||
/// - `chain` may be null, invalid, but not uninitialized. If `chain` is null or invalid, this
|
||||
/// function will return an error.
|
||||
/// - `mvp` may be null, or if it is not null, must be an aligned pointer to 16 consecutive `float`
|
||||
/// values for the model view projection matrix.
|
||||
/// - `opt` may be null, or if it is not null, must be an aligned pointer to a valid `frame_gl_opt_t`
|
||||
/// struct.
|
||||
libra_error_t libra_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);
|
||||
|
||||
/// 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`.
|
||||
libra_error_t libra_d3d11_filter_chain_free(libra_d3d11_filter_chain_t *chain);
|
||||
|
||||
/// Get the error code corresponding to this error object.
|
||||
///
|
||||
/// ## Safety
|
||||
|
|
|
@ -22,6 +22,9 @@ pub enum LibrashaderError {
|
|||
#[cfg(feature = "runtime-opengl")]
|
||||
#[error("There was an error in the OpenGL filter chain.")]
|
||||
OpenGlFilterError(#[from] librashader::runtime::gl::error::FilterChainError),
|
||||
#[cfg(feature = "runtime-d3d11")]
|
||||
#[error("There was an error in the D3D11 filter chain.")]
|
||||
D3D11FilterError(#[from] librashader::runtime::d3d11::error::FilterChainError),
|
||||
|
||||
}
|
||||
|
||||
|
@ -151,7 +154,11 @@ impl LibrashaderError {
|
|||
LibrashaderError::InvalidPath(_) => LIBRA_ERRNO::INVALID_PATH,
|
||||
LibrashaderError::PresetError(_) => LIBRA_ERRNO::PRESET_ERROR,
|
||||
LibrashaderError::PreprocessError(_) => LIBRA_ERRNO::PREPROCESS_ERROR,
|
||||
LibrashaderError::OpenGlFilterError(_) => LIBRA_ERRNO::RUNTIME_ERROR
|
||||
#[cfg(feature = "runtime-opengl")]
|
||||
LibrashaderError::OpenGlFilterError(_) => LIBRA_ERRNO::RUNTIME_ERROR,
|
||||
#[cfg(feature = "runtime-d3d11")]
|
||||
LibrashaderError::D3D11FilterError(_) => LIBRA_ERRNO::RUNTIME_ERROR
|
||||
|
||||
}
|
||||
}
|
||||
pub(crate) const fn ok() -> libra_error_t {
|
||||
|
@ -172,6 +179,11 @@ macro_rules! assert_non_null {
|
|||
if $value.is_null() {
|
||||
return $crate::error::LibrashaderError::InvalidParameter(stringify!($value)).export()
|
||||
}
|
||||
};
|
||||
(noexport $value:ident) => {
|
||||
if $value.is_null() {
|
||||
return Err($crate::error::LibrashaderError::InvalidParameter(stringify!($value)))
|
||||
}
|
||||
}
|
||||
}
|
||||
macro_rules! assert_some {
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
//!
|
||||
//! Once an object is freed, the input pointer is always set to null. Attempting to free an object that was not
|
||||
//! allocated from `librashader` or trying to free an object with a wrong `free` function results in
|
||||
//! immediate **undefined behaviour**.
|
||||
//! **immediate undefined behaviour**.
|
||||
//!
|
||||
//! In general, all functions will accept null pointers for all parameters. However, passing a null pointer
|
||||
//! into any function that requires a non-null pointer will result in the function returning an error with code `INVALID_PARAMETER`.
|
||||
|
@ -19,6 +19,15 @@
|
|||
//! All types that begin with an underscore, such as `_libra_error` or `_shader_preset` are handles that
|
||||
//! can not be constructed validly, and should always be used with pointer indirection via the corresponding `_t` types.
|
||||
//!
|
||||
//! All functions have safety invariants labeled `## Safety` that must be upheld. Failure to uphold these invariants
|
||||
//! will result in **immediate undefined behaviour**. Generally speaking, all pointers passed to functions must be
|
||||
//! **aligned** regardless of whether or not they are null.
|
||||
//!
|
||||
//! ## Booleans
|
||||
//! Some option structs take `bool` values.
|
||||
//! Any booleans passed to librashader **must have a bit pattern equivalent to either `1` or `0`**. Any other value will cause
|
||||
//! **immediate undefined behaviour**.
|
||||
//!
|
||||
//! ## Errors
|
||||
//! The librashader C API provides a robust, reflective error system. Every function returns a `libra_error_t`, which is either
|
||||
//! a null pointer, or a handle to an opaque allocated error object. If the returned error is null, then the function was successful.
|
||||
|
@ -36,11 +45,3 @@ pub mod runtime;
|
|||
pub mod error;
|
||||
pub mod ctypes;
|
||||
mod ffi;
|
||||
|
||||
#[doc(hide)]
|
||||
#[cfg(feature = "headers")] // c.f. the `Cargo.toml` section
|
||||
pub fn generate_headers() -> ::std::io::Result<()> {
|
||||
::safer_ffi::headers::builder()
|
||||
.to_file("librashader.h")?
|
||||
.generate()
|
||||
}
|
|
@ -7,32 +7,6 @@ use crate::ctypes::{libra_error_t, libra_shader_preset_t};
|
|||
use crate::error::{assert_non_null, assert_some, assert_some_ptr, LibrashaderError};
|
||||
use std::ptr::NonNull;
|
||||
|
||||
// use safer_ffi::prelude::*;
|
||||
// use safer_ffi::ffi_export;
|
||||
// use safer_ffi::char_p::char_p_ref as CStrRef;
|
||||
|
||||
// extern_fn! {
|
||||
// /// SAFETY:
|
||||
// /// - filename is aligned and valid for reads.
|
||||
// fn load_preset(filename: *const c_char, out: *mut MaybeUninit<shader_preset_t>) {
|
||||
// assert_non_null!(filename, "filename");
|
||||
// assert_non_null!(out, "out");
|
||||
//
|
||||
// let filename = unsafe {
|
||||
// CStr::from_ptr(filename)
|
||||
// };
|
||||
//
|
||||
// let filename = filename.to_str()?;
|
||||
//
|
||||
// println!("loading {filename}");
|
||||
// let preset = ShaderPreset::try_parse(filename)?;
|
||||
//
|
||||
// unsafe {
|
||||
// out.write(MaybeUninit::new(ManuallyDrop::new(Box::new(preset))))
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
pub type PFN_lbr_preset_create = unsafe extern "C" fn (*const c_char, *mut MaybeUninit<libra_shader_preset_t>) -> libra_error_t;
|
||||
|
||||
/// Load a preset.
|
||||
|
@ -69,6 +43,9 @@ pub type PFN_lbr_preset_free = unsafe extern "C" fn (*mut libra_shader_preset_t)
|
|||
///
|
||||
/// If `preset` is null, this function does nothing. The resulting value in `preset` then becomes
|
||||
/// null.
|
||||
///
|
||||
/// ## Safety
|
||||
/// - `preset` must be a valid and aligned pointer to a shader preset.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn libra_preset_free(preset: *mut libra_shader_preset_t) -> libra_error_t {
|
||||
ffi_body!({
|
||||
|
@ -83,6 +60,10 @@ 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;
|
||||
/// 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 {
|
||||
|
@ -103,6 +84,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;
|
||||
|
||||
/// Get the value of the parameter as set 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.
|
||||
/// - `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 {
|
||||
|
@ -114,6 +100,8 @@ pub unsafe extern "C" fn libra_preset_get_param(preset: *mut libra_shader_preset
|
|||
let name = name.to_str()?;
|
||||
assert_some_ptr!(preset);
|
||||
|
||||
assert_non_null!(value);
|
||||
|
||||
if let Some(param) = preset.parameters.iter().find(|c| c.name == name) {
|
||||
unsafe {
|
||||
value.write(MaybeUninit::new(param.value))
|
||||
|
@ -125,6 +113,9 @@ pub unsafe extern "C" fn libra_preset_get_param(preset: *mut libra_shader_preset
|
|||
pub type PFN_lbr_preset_print = unsafe extern "C" fn (*mut libra_shader_preset_t) -> libra_error_t;
|
||||
|
||||
/// Pretty print the shader preset.
|
||||
///
|
||||
/// ## Safety
|
||||
/// - `preset` must be null or a valid and aligned pointer to a shader preset.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn libra_preset_print(preset: *mut libra_shader_preset_t) -> libra_error_t {
|
||||
ffi_body!(|preset| {
|
||||
|
@ -139,6 +130,7 @@ pub type PFN_lbr_preset_get_runtime_param_names = unsafe extern "C" fn (*mut lib
|
|||
/// 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 | {
|
||||
|
|
Loading…
Reference in a new issue