capi: use extern_ffi where possible
This commit is contained in:
parent
946fe11c69
commit
f25693815b
13 changed files with 591 additions and 902 deletions
|
@ -44,4 +44,4 @@ features = [
|
|||
optional = true
|
||||
|
||||
[package.metadata.cargo-post.dependencies]
|
||||
cbindgen = "0.24.3"
|
||||
cbindgen = { git = "https://github.com/eqrion/cbindgen" }
|
||||
|
|
|
@ -4,7 +4,14 @@ include_guard = "__LIBRASHADER_H__"
|
|||
pragma_once = true
|
||||
usize_is_size_t = true
|
||||
documentation_style = "c++"
|
||||
after_includes = "#ifdef _WIN32\n#include <d3d11.h>\n#else\ntypedef void ID3D11Device;typedef void ID3D11RenderTargetView;typedef void ID3D1ShaderResourceView;\n#endif"
|
||||
after_includes = "#ifdef _WIN32 && RUNTIME_D3D11 \n#include <d3d11.h>\n#else\ntypedef void ID3D11Device;typedef void ID3D11RenderTargetView;typedef void ID3D1ShaderResourceView;\n#endif"
|
||||
|
||||
|
||||
|
||||
[defines]
|
||||
"feature = runtime-opengl" = "LIBRA_RUNTIME_OPENGL"
|
||||
"feature = runtime-d3d11" = "LIBRA_RUNTIME_D3D11"
|
||||
|
||||
[parse]
|
||||
parse_deps = true
|
||||
include = ["librashader",
|
||||
|
@ -14,7 +21,7 @@ include = ["librashader",
|
|||
"librashader-runtime-gl",
|
||||
"librashader-runtime-d3d11"
|
||||
]
|
||||
|
||||
expand = ["librashader-capi"]
|
||||
|
||||
[struct]
|
||||
|
||||
|
@ -25,35 +32,32 @@ prefix_with_name = true
|
|||
[export]
|
||||
include = [
|
||||
# preset
|
||||
"PFN_lbr_load_preset",
|
||||
"PFN_lbr_preset_free",
|
||||
"PFN_lbr_preset_set_param",
|
||||
"PFN_lbr_preset_get_param",
|
||||
"PFN_lbr_preset_print",
|
||||
"PFN_lbr_preset_get_runtime_param_names",
|
||||
"PFN_libra_load_preset",
|
||||
"PFN_libra_preset_free",
|
||||
"PFN_libra_preset_set_param",
|
||||
"PFN_libra_preset_get_param",
|
||||
"PFN_libra_preset_print",
|
||||
"PFN_libra_preset_get_runtime_param_names",
|
||||
|
||||
# error
|
||||
"PFN_lbr_error_errno",
|
||||
"PFN_lbr_error_print",
|
||||
"PFN_lbr_error_free",
|
||||
"PFN_lbr_error_write",
|
||||
"PFN_lbr_error_free_string",
|
||||
"PFN_libra_error_errno",
|
||||
"PFN_libra_error_print",
|
||||
"PFN_libra_error_free",
|
||||
"PFN_libra_error_write",
|
||||
"PFN_libra_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",
|
||||
"PFN_libra_gl_init_context",
|
||||
"PFN_libra_gl_filter_chain_create",
|
||||
"PFN_libra_gl_filter_chain_frame",
|
||||
"PFN_libra_gl_filter_chain_free",
|
||||
|
||||
# d3d11
|
||||
"PFN_lbr_d3d11_filter_chain_create",
|
||||
"PFN_lbr_d3d11_filter_chain_frame",
|
||||
"PFN_lbr_d3d11_filter_chain_free"
|
||||
|
||||
"PFN_libra_d3d11_filter_chain_create",
|
||||
"PFN_libra_d3d11_filter_chain_frame",
|
||||
"PFN_libra_d3d11_filter_chain_free",
|
||||
]
|
||||
|
||||
#exclude = ["LibrashaderError"]
|
||||
#
|
||||
[export.rename]
|
||||
"LibrashaderError" = "_libra_error"
|
||||
"ShaderPreset" = "_shader_preset"
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef _WIN32
|
||||
#ifdef _WIN32 && RUNTIME_D3D11
|
||||
#include <d3d11.h>
|
||||
#else
|
||||
typedef void ID3D11Device; typedef void ID3D11RenderTargetView; typedef void ID3D1ShaderResourceView;
|
||||
|
@ -31,9 +31,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;
|
||||
/// A Direct3D 11 filter chain.
|
||||
typedef struct FilterChain FilterChain;
|
||||
|
||||
/// The error type for librashader.
|
||||
typedef struct _libra_error _libra_error;
|
||||
|
@ -48,19 +47,28 @@ typedef struct _libra_error *libra_error_t;
|
|||
|
||||
typedef struct _shader_preset* libra_shader_preset_t;
|
||||
|
||||
#if defined(RUNTIME_OPENGL)
|
||||
/// A GL function loader that librashader needs to be initialized with.
|
||||
typedef const void* (*gl_loader_t)(const char*);
|
||||
#endif
|
||||
|
||||
/// 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;
|
||||
/// Options for Direct3D11 filter chain creation.
|
||||
typedef struct FilterChainOptions {
|
||||
/// 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;
|
||||
/// Whether or not to explicitly disable mipmap
|
||||
/// generation regardless of shader preset settings.
|
||||
bool force_no_mipmaps;
|
||||
} FilterChainOptions;
|
||||
|
||||
typedef struct _filter_chain_gl *libra_gl_filter_chain_t;
|
||||
#if defined(RUNTIME_OPENGL)
|
||||
typedef struct FilterChain* libra_gl_filter_chain_t;
|
||||
#endif
|
||||
|
||||
#if defined(RUNTIME_OPENGL)
|
||||
/// OpenGL parameters for the source image.
|
||||
typedef struct libra_source_image_gl_t {
|
||||
/// A texture GLuint to the source image.
|
||||
|
@ -72,6 +80,7 @@ typedef struct libra_source_image_gl_t {
|
|||
/// The height of the source image.
|
||||
uint32_t height;
|
||||
} libra_source_image_gl_t;
|
||||
#endif
|
||||
|
||||
/// Parameters for the output viewport.
|
||||
typedef struct libra_viewport_t {
|
||||
|
@ -81,6 +90,7 @@ typedef struct libra_viewport_t {
|
|||
uint32_t height;
|
||||
} libra_viewport_t;
|
||||
|
||||
#if defined(RUNTIME_OPENGL)
|
||||
/// OpenGL parameters for the output framebuffer.
|
||||
typedef struct libra_draw_framebuffer_gl_t {
|
||||
/// A framebuffer GLuint to the output framebuffer.
|
||||
|
@ -90,26 +100,21 @@ typedef struct libra_draw_framebuffer_gl_t {
|
|||
/// The format of the output framebuffer.
|
||||
uint32_t format;
|
||||
} libra_draw_framebuffer_gl_t;
|
||||
#endif
|
||||
|
||||
/// Options for each OpenGL shader frame.
|
||||
typedef struct frame_gl_opt_t {
|
||||
/// Options for each Direct3D11 shader frame.
|
||||
typedef struct FrameOptions {
|
||||
/// 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;
|
||||
} FrameOptions;
|
||||
|
||||
/// 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;
|
||||
#if defined(RUNTIME_D3D11)
|
||||
typedef struct FilterChain* libra_d3d11_filter_chain_t;
|
||||
#endif
|
||||
|
||||
#if defined(RUNTIME_D3D11)
|
||||
/// OpenGL parameters for the source image.
|
||||
typedef struct libra_source_image_d3d11_t {
|
||||
/// A shader resource view into the source image
|
||||
|
@ -119,48 +124,77 @@ typedef struct libra_source_image_d3d11_t {
|
|||
/// The height of the source image.
|
||||
uint32_t height;
|
||||
} libra_source_image_d3d11_t;
|
||||
#endif
|
||||
|
||||
/// 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_libra_preset_free)(libra_shader_preset_t* preset);
|
||||
|
||||
typedef libra_error_t (*PFN_lbr_preset_free)(libra_shader_preset_t *preset);
|
||||
typedef libra_error_t(*PFN_libra_preset_set_param)(libra_shader_preset_t* preset,
|
||||
const char* name,
|
||||
float value);
|
||||
|
||||
typedef libra_error_t (*PFN_lbr_preset_set_param)(libra_shader_preset_t *preset, const char *name, float value);
|
||||
typedef libra_error_t(*PFN_libra_preset_get_param)(libra_shader_preset_t* preset,
|
||||
const char* name,
|
||||
float* value);
|
||||
|
||||
typedef libra_error_t (*PFN_lbr_preset_get_param)(libra_shader_preset_t *preset, const char *name, float *value);
|
||||
typedef libra_error_t(*PFN_libra_preset_print)(libra_shader_preset_t* preset);
|
||||
|
||||
typedef libra_error_t (*PFN_lbr_preset_print)(libra_shader_preset_t *preset);
|
||||
typedef libra_error_t(*PFN_libra_preset_get_runtime_param_names)(libra_shader_preset_t* preset,
|
||||
const char** value);
|
||||
|
||||
typedef libra_error_t (*PFN_lbr_preset_get_runtime_param_names)(libra_shader_preset_t *preset, const char **value);
|
||||
typedef LIBRA_ERRNO(*PFN_libra_error_errno)(libra_error_t error);
|
||||
|
||||
typedef LIBRA_ERRNO (*PFN_lbr_error_errno)(libra_error_t error);
|
||||
typedef int32_t(*PFN_libra_error_print)(libra_error_t error);
|
||||
|
||||
typedef int32_t (*PFN_lbr_error_print)(libra_error_t error);
|
||||
typedef int32_t(*PFN_libra_error_free)(libra_error_t* error);
|
||||
|
||||
typedef int32_t (*PFN_lbr_error_free)(libra_error_t *error);
|
||||
typedef int32_t(*PFN_libra_error_write)(libra_error_t error, char** out);
|
||||
|
||||
typedef int32_t (*PFN_lbr_error_write)(libra_error_t error, char **out);
|
||||
typedef int32_t(*PFN_libra_error_free_string)(char** out);
|
||||
|
||||
typedef int32_t (*PFN_lbr_error_free_string)(char **out);
|
||||
#if defined(RUNTIME_OPENGL)
|
||||
typedef libra_error_t(*PFN_libra_gl_init_context)(gl_loader_t loader);
|
||||
#endif
|
||||
|
||||
typedef libra_error_t (*PFN_lbr_gl_init_context)(gl_loader_t loader);
|
||||
#if defined(RUNTIME_OPENGL)
|
||||
typedef libra_error_t(*PFN_libra_gl_filter_chain_create)(libra_shader_preset_t* preset,
|
||||
const struct FilterChainOptions* options,
|
||||
libra_gl_filter_chain_t* out);
|
||||
#endif
|
||||
|
||||
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);
|
||||
#if defined(RUNTIME_OPENGL)
|
||||
typedef libra_error_t(*PFN_libra_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 FrameOptions* opt);
|
||||
#endif
|
||||
|
||||
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);
|
||||
#if defined(RUNTIME_OPENGL)
|
||||
typedef libra_error_t(*PFN_libra_gl_filter_chain_free)(libra_gl_filter_chain_t* chain);
|
||||
#endif
|
||||
|
||||
typedef libra_error_t (*PFN_lbr_gl_filter_chain_free)(libra_gl_filter_chain_t *chain);
|
||||
#if defined(RUNTIME_D3D11)
|
||||
typedef libra_error_t(*PFN_libra_d3d11_filter_chain_create)(libra_shader_preset_t* preset,
|
||||
const struct FilterChainOptions* options,
|
||||
const ID3D11Device* device,
|
||||
libra_d3d11_filter_chain_t* out);
|
||||
#endif
|
||||
|
||||
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);
|
||||
#if defined(RUNTIME_D3D11)
|
||||
typedef libra_error_t(*PFN_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 FrameOptions* opt);
|
||||
#endif
|
||||
|
||||
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);
|
||||
#if defined(RUNTIME_D3D11)
|
||||
typedef libra_error_t(*PFN_libra_d3d11_filter_chain_free)(libra_d3d11_filter_chain_t* chain);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -252,6 +286,7 @@ libra_error_t libra_preset_print(libra_shader_preset_t *preset);
|
|||
libra_error_t libra_preset_get_runtime_param_names(libra_shader_preset_t* preset,
|
||||
const char** value);
|
||||
|
||||
#if defined(RUNTIME_OPENGL)
|
||||
/// Initialize the OpenGL Context for librashader.
|
||||
///
|
||||
/// ## Safety
|
||||
|
@ -260,7 +295,9 @@ libra_error_t libra_preset_get_runtime_param_names(libra_shader_preset_t *preset
|
|||
/// Reinitializing the OpenGL context with a different loader immediately invalidates previous filter
|
||||
/// chain objects, and drawing with them causes immediate undefined behaviour.
|
||||
libra_error_t libra_gl_init_context(gl_loader_t loader);
|
||||
#endif
|
||||
|
||||
#if defined(RUNTIME_OPENGL)
|
||||
/// Create the filter chain given the shader preset.
|
||||
///
|
||||
/// The shader preset is immediately invalidated and must be recreated after
|
||||
|
@ -271,9 +308,11 @@ libra_error_t libra_gl_init_context(gl_loader_t loader);
|
|||
/// - `options` must be either null, or valid and aligned.
|
||||
/// - `out` must be aligned, but may be null, invalid, or uninitialized.
|
||||
libra_error_t libra_gl_filter_chain_create(libra_shader_preset_t* preset,
|
||||
const struct filter_chain_gl_opt_t *options,
|
||||
const struct FilterChainOptions* options,
|
||||
libra_gl_filter_chain_t* out);
|
||||
#endif
|
||||
|
||||
#if defined(RUNTIME_OPENGL)
|
||||
/// Draw a frame with the given parameters for the given filter chain.
|
||||
///
|
||||
/// ## Safety
|
||||
|
@ -289,15 +328,19 @@ libra_error_t libra_gl_filter_chain_frame(libra_gl_filter_chain_t *chain,
|
|||
struct libra_viewport_t viewport,
|
||||
struct libra_draw_framebuffer_gl_t out,
|
||||
const float* mvp,
|
||||
const struct frame_gl_opt_t *opt);
|
||||
const struct FrameOptions* opt);
|
||||
#endif
|
||||
|
||||
#if defined(RUNTIME_OPENGL)
|
||||
/// Free a GL 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_gl_filter_chain_t`.
|
||||
libra_error_t libra_gl_filter_chain_free(libra_gl_filter_chain_t* chain);
|
||||
#endif
|
||||
|
||||
#if defined(RUNTIME_D3D11)
|
||||
/// Create the filter chain given the shader preset.
|
||||
///
|
||||
/// The shader preset is immediately invalidated and must be recreated after
|
||||
|
@ -308,10 +351,12 @@ libra_error_t libra_gl_filter_chain_free(libra_gl_filter_chain_t *chain);
|
|||
/// - `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 struct FilterChainOptions* options,
|
||||
const ID3D11Device* device,
|
||||
libra_d3d11_filter_chain_t* out);
|
||||
#endif
|
||||
|
||||
#if defined(RUNTIME_D3D11)
|
||||
/// Draw a frame with the given parameters for the given filter chain.
|
||||
///
|
||||
/// ## Safety
|
||||
|
@ -327,14 +372,17 @@ libra_error_t libra_d3d11_filter_chain_frame(libra_d3d11_filter_chain_t *chain,
|
|||
struct libra_viewport_t viewport,
|
||||
const ID3D11RenderTargetView* out,
|
||||
const float* mvp,
|
||||
const struct frame_d3d11_opt_t *opt);
|
||||
const struct FrameOptions* opt);
|
||||
#endif
|
||||
|
||||
#if defined(RUNTIME_D3D11)
|
||||
/// 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);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::{env, fs};
|
||||
use std::fs::File;
|
||||
use std::io::{BufWriter, Write};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub fn main() {
|
||||
// Do not update files on docsrs
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! The librashader error C API. (`libra_error_*`).
|
||||
use std::any::Any;
|
||||
use std::ffi::{c_char, CStr, CString};
|
||||
use std::ffi::{c_char, CString};
|
||||
use std::mem::MaybeUninit;
|
||||
use std::ptr::NonNull;
|
||||
use thiserror::Error;
|
||||
|
@ -42,7 +42,9 @@ pub enum LIBRA_ERRNO {
|
|||
RUNTIME_ERROR = 5,
|
||||
}
|
||||
|
||||
pub type PFN_lbr_error_errno = extern "C" fn(error: libra_error_t) -> LIBRA_ERRNO;
|
||||
// Nothing here can use extern_fn because they are lower level than libra_error_t.
|
||||
|
||||
pub type PFN_libra_error_errno = extern "C" fn(error: libra_error_t) -> LIBRA_ERRNO;
|
||||
#[no_mangle]
|
||||
/// Get the error code corresponding to this error object.
|
||||
///
|
||||
|
@ -56,7 +58,7 @@ pub extern "C" fn libra_error_errno(error: libra_error_t) -> LIBRA_ERRNO {
|
|||
unsafe { error.as_ref().get_code() }
|
||||
}
|
||||
|
||||
pub type PFN_lbr_error_print = extern "C" fn(error: libra_error_t) -> i32;
|
||||
pub type PFN_libra_error_print = extern "C" fn(error: libra_error_t) -> i32;
|
||||
#[no_mangle]
|
||||
/// Print the error message.
|
||||
///
|
||||
|
@ -74,7 +76,7 @@ pub extern "C" fn libra_error_print(error: libra_error_t) -> i32 {
|
|||
return 0;
|
||||
}
|
||||
|
||||
pub type PFN_lbr_error_free = extern "C" fn(error: *mut libra_error_t) -> i32;
|
||||
pub type PFN_libra_error_free = extern "C" fn(error: *mut libra_error_t) -> i32;
|
||||
#[no_mangle]
|
||||
/// Frees any internal state kept by the error.
|
||||
///
|
||||
|
@ -87,7 +89,7 @@ pub extern "C" fn libra_error_free(error: *mut libra_error_t) -> i32 {
|
|||
return 1;
|
||||
}
|
||||
|
||||
let mut error = unsafe { &mut *error };
|
||||
let error = unsafe { &mut *error };
|
||||
let error = error.take();
|
||||
let Some(error) = error else {
|
||||
return 1;
|
||||
|
@ -97,7 +99,7 @@ pub extern "C" fn libra_error_free(error: *mut libra_error_t) -> i32 {
|
|||
return 0;
|
||||
}
|
||||
|
||||
pub type PFN_lbr_error_write =
|
||||
pub type PFN_libra_error_write =
|
||||
extern "C" fn(error: libra_error_t, out: *mut MaybeUninit<*mut c_char>) -> i32;
|
||||
#[no_mangle]
|
||||
/// Writes the error message into `out`
|
||||
|
@ -128,7 +130,7 @@ pub extern "C" fn libra_error_write(
|
|||
return 0;
|
||||
}
|
||||
|
||||
pub type PFN_lbr_error_free_string = extern "C" fn(out: *mut *mut c_char) -> i32;
|
||||
pub type PFN_libra_error_free_string = extern "C" fn(out: *mut *mut c_char) -> i32;
|
||||
#[no_mangle]
|
||||
/// Frees an error string previously allocated by `libra_error_write`.
|
||||
///
|
||||
|
@ -194,13 +196,14 @@ macro_rules! assert_non_null {
|
|||
}
|
||||
};
|
||||
}
|
||||
macro_rules! assert_some {
|
||||
($value:ident) => {
|
||||
if $value.is_none() {
|
||||
return $crate::error::LibrashaderError::InvalidParameter(stringify!($value)).export();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// macro_rules! assert_some {
|
||||
// ($value:ident) => {
|
||||
// if $value.is_none() {
|
||||
// return $crate::error::LibrashaderError::InvalidParameter(stringify!($value)).export();
|
||||
// }
|
||||
// };
|
||||
// }
|
||||
|
||||
macro_rules! assert_some_ptr {
|
||||
($value:ident) => {
|
||||
|
@ -221,5 +224,5 @@ macro_rules! assert_some_ptr {
|
|||
|
||||
use crate::ctypes::libra_error_t;
|
||||
pub(crate) use assert_non_null;
|
||||
pub(crate) use assert_some;
|
||||
// pub(crate) use assert_some;
|
||||
pub(crate) use assert_some_ptr;
|
||||
|
|
|
@ -65,10 +65,57 @@ macro_rules! extern_fn {
|
|||
|
||||
#[no_mangle]
|
||||
$(#[$($attrss)*])*
|
||||
fn $func_name($($arg_name: $arg_ty,)*) -> $crate::ctypes::libra_error_t {
|
||||
pub extern "C" fn $func_name($($arg_name: $arg_ty,)*) -> $crate::ctypes::libra_error_t {
|
||||
$crate::ffi::ffi_body!($body)
|
||||
}
|
||||
};
|
||||
|
||||
($(#[$($attrss:tt)*])* raw fn $func_name:ident ($($arg_name:ident : $arg_ty:ty),*) $body:block) => {
|
||||
paste::paste! {
|
||||
pub type [<PFN_ $func_name>] = unsafe extern "C" fn($($arg_name: $arg_ty,)*) -> $crate::ctypes::libra_error_t;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
$(#[$($attrss)*])*
|
||||
pub extern "C" fn $func_name($($arg_name: $arg_ty,)*) -> $crate::ctypes::libra_error_t {
|
||||
$body
|
||||
}
|
||||
};
|
||||
|
||||
($(#[$($attrss:tt)*])* fn $func_name:ident ($($arg_name:ident : $arg_ty:ty),*) |$($ref_capture:ident),*|; mut |$($mut_capture:ident),*| $body:block) => {
|
||||
paste::paste! {
|
||||
pub type [<PFN_ $func_name>] = unsafe extern "C" fn($($arg_name: $arg_ty,)*) -> $crate::ctypes::libra_error_t;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
$(#[$($attrss)*])*
|
||||
pub extern "C" fn $func_name($($arg_name: $arg_ty,)*) -> $crate::ctypes::libra_error_t {
|
||||
$crate::ffi::ffi_body!(|$($ref_capture),*|; mut |$($mut_capture),*| $body)
|
||||
}
|
||||
};
|
||||
|
||||
($(#[$($attrss:tt)*])* fn $func_name:ident ($($arg_name:ident : $arg_ty:ty),*) mut |$($mut_capture:ident),*| $body:block) => {
|
||||
paste::paste! {
|
||||
pub type [<PFN_ $func_name>] = unsafe extern "C" fn($($arg_name: $arg_ty,)*) -> $crate::ctypes::libra_error_t;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
$(#[$($attrss)*])*
|
||||
pub extern "C" fn $func_name($($arg_name: $arg_ty,)*) -> $crate::ctypes::libra_error_t {
|
||||
$crate::ffi::ffi_body!(mut |$($mut_capture),*| $body)
|
||||
}
|
||||
};
|
||||
($(#[$($attrss:tt)*])* fn $func_name:ident ($($arg_name:ident : $arg_ty:ty),*) |$($ref_capture:ident),*| $body:block) => {
|
||||
paste::paste! {
|
||||
pub type [<PFN_ $func_name>] = unsafe extern "C" fn($($arg_name: $arg_ty,)*) -> $crate::ctypes::libra_error_t;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
$(#[$($attrss)*])*
|
||||
pub extern "C" fn $func_name($($arg_name: $arg_ty,)*) -> $crate::ctypes::libra_error_t {
|
||||
$crate::ffi::ffi_body!(|$($ref_capture),*| $body)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub(crate) use extern_fn;
|
||||
|
|
|
@ -38,11 +38,12 @@
|
|||
#![feature(vec_into_raw_parts)]
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
|
||||
use std::os::raw::c_char;
|
||||
|
||||
pub mod ctypes;
|
||||
pub mod error;
|
||||
mod ffi;
|
||||
pub mod presets;
|
||||
|
||||
#[cfg(feature = "reflect")]
|
||||
pub mod reflect;
|
||||
|
||||
pub mod runtime;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! The librashader preset C API (`libra_preset_*`).
|
||||
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 crate::error::{assert_non_null, assert_some_ptr, LibrashaderError};
|
||||
use crate::ffi::{extern_fn, ffi_body};
|
||||
use librashader::presets::ShaderPreset;
|
||||
use std::ffi::{c_char, CStr, CString};
|
||||
use std::mem::MaybeUninit;
|
||||
|
@ -12,6 +12,7 @@ pub type PFN_lbr_preset_create = unsafe extern "C" fn(
|
|||
out: *mut MaybeUninit<libra_shader_preset_t>,
|
||||
) -> libra_error_t;
|
||||
|
||||
extern_fn! {
|
||||
/// Load a preset.
|
||||
///
|
||||
/// ## Safety
|
||||
|
@ -19,33 +20,27 @@ pub type PFN_lbr_preset_create = unsafe extern "C" fn(
|
|||
/// - `out` must be either null, or an aligned pointer to an uninitialized or invalid `libra_shader_preset_t`.
|
||||
/// ## 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(
|
||||
fn libra_preset_create(
|
||||
filename: *const c_char,
|
||||
out: *mut MaybeUninit<libra_shader_preset_t>,
|
||||
) -> libra_error_t {
|
||||
ffi_body!({
|
||||
out: *mut MaybeUninit<libra_shader_preset_t>
|
||||
) {
|
||||
assert_non_null!(filename);
|
||||
assert_non_null!(out);
|
||||
|
||||
let filename = unsafe { CStr::from_ptr(filename) };
|
||||
|
||||
let filename = filename.to_str()?;
|
||||
|
||||
println!("loading {filename}");
|
||||
let preset = ShaderPreset::try_parse(filename)?;
|
||||
|
||||
let preset = ShaderPreset::try_parse(filename)?;
|
||||
unsafe {
|
||||
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(
|
||||
preset,
|
||||
)))))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub type PFN_lbr_preset_free =
|
||||
unsafe extern "C" fn(preset: *mut libra_shader_preset_t) -> libra_error_t;
|
||||
|
||||
extern_fn! {
|
||||
/// Free the preset.
|
||||
///
|
||||
/// If `preset` is null, this function does nothing. The resulting value in `preset` then becomes
|
||||
|
@ -53,35 +48,27 @@ pub type PFN_lbr_preset_free =
|
|||
///
|
||||
/// ## 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!({
|
||||
fn libra_preset_free(preset: *mut libra_shader_preset_t) {
|
||||
assert_non_null!(preset);
|
||||
unsafe {
|
||||
let preset_ptr = &mut *preset;
|
||||
let preset = preset_ptr.take();
|
||||
drop(Box::from_raw(preset.unwrap().as_ptr()));
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
extern_fn! {
|
||||
/// 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(
|
||||
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| {
|
||||
value: f32
|
||||
) |name|; mut |preset| {
|
||||
let name = unsafe {
|
||||
CStr::from_ptr(name)
|
||||
};
|
||||
|
@ -92,30 +79,22 @@ pub unsafe extern "C" fn libra_preset_set_param(
|
|||
if let Some(param) = preset.parameters.iter_mut().find(|c| c.name == name) {
|
||||
param.value = value
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
extern_fn! {
|
||||
/// 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(
|
||||
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| {
|
||||
value: *mut MaybeUninit<f32>
|
||||
) |name, preset| {
|
||||
let name = unsafe { CStr::from_ptr(name) };
|
||||
|
||||
let name = name.to_str()?;
|
||||
assert_some_ptr!(preset);
|
||||
|
||||
|
@ -124,25 +103,22 @@ pub unsafe extern "C" fn libra_preset_get_param(
|
|||
if let Some(param) = preset.parameters.iter().find(|c| c.name == name) {
|
||||
unsafe { value.write(MaybeUninit::new(param.value)) }
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub type PFN_lbr_preset_print =
|
||||
unsafe extern "C" fn(preset: *mut libra_shader_preset_t) -> libra_error_t;
|
||||
|
||||
extern_fn! {
|
||||
/// 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| {
|
||||
fn libra_preset_print(preset: *mut libra_shader_preset_t) |preset| {
|
||||
assert_some_ptr!(preset);
|
||||
println!("{:#?}", preset);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub type PFN_lbr_preset_get_runtime_param_names = unsafe extern "C" fn(
|
||||
// can't use extern_fn! for this because of the mut.
|
||||
pub type PFN_libra_preset_get_runtime_param_names = unsafe extern "C" fn(
|
||||
preset: *mut libra_shader_preset_t,
|
||||
value: MaybeUninit<*mut *const c_char>,
|
||||
) -> libra_error_t;
|
||||
|
@ -168,6 +144,7 @@ pub unsafe extern "C" fn libra_preset_get_runtime_param_names(
|
|||
}
|
||||
|
||||
let (parts, _len, _cap) = c_strings.into_raw_parts();
|
||||
|
||||
value.write(parts);
|
||||
})
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@ use librashader::reflect::{
|
|||
};
|
||||
use librashader::{FilterMode, WrapMode};
|
||||
use rustc_hash::FxHashMap;
|
||||
use std::error::Error;
|
||||
|
||||
pub(crate) struct LookupTexture {
|
||||
wrap_mode: WrapMode,
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use crate::ctypes::{
|
||||
libra_d3d11_filter_chain_t, libra_error_t, libra_shader_preset_t, libra_viewport_t,
|
||||
libra_d3d11_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 crate::ffi::extern_fn;
|
||||
use librashader::runtime::d3d11::{D3D11InputView, D3D11OutputView};
|
||||
use std::mem::MaybeUninit;
|
||||
use std::ptr::NonNull;
|
||||
|
@ -41,12 +41,7 @@ impl TryFrom<libra_source_image_d3d11_t> for D3D11InputView {
|
|||
}
|
||||
}
|
||||
|
||||
pub type PFN_lbr_d3d11_filter_chain_create = unsafe extern "C" fn(
|
||||
preset: *mut libra_shader_preset_t,
|
||||
options: *const FilterChainOptions,
|
||||
device: *const ID3D11Device,
|
||||
out: *mut MaybeUninit<libra_d3d11_filter_chain_t>,
|
||||
) -> libra_error_t;
|
||||
extern_fn! {
|
||||
/// Create the filter chain given the shader preset.
|
||||
///
|
||||
/// The shader preset is immediately invalidated and must be recreated after
|
||||
|
@ -56,14 +51,12 @@ pub type PFN_lbr_d3d11_filter_chain_create = unsafe extern "C" fn(
|
|||
/// - `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.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn libra_d3d11_filter_chain_create(
|
||||
fn libra_d3d11_filter_chain_create(
|
||||
preset: *mut libra_shader_preset_t,
|
||||
options: *const FilterChainOptions,
|
||||
device: *const ID3D11Device,
|
||||
out: *mut MaybeUninit<libra_d3d11_filter_chain_t>,
|
||||
) -> libra_error_t {
|
||||
ffi_body!({
|
||||
out: *mut MaybeUninit<libra_d3d11_filter_chain_t>
|
||||
) {
|
||||
assert_non_null!(preset);
|
||||
assert_non_null!(device);
|
||||
let preset = unsafe {
|
||||
|
@ -89,19 +82,10 @@ pub unsafe extern "C" fn libra_d3d11_filter_chain_create(
|
|||
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 FrameOptions,
|
||||
) -> libra_error_t;
|
||||
|
||||
extern_fn! {
|
||||
/// Draw a frame with the given parameters for the given filter chain.
|
||||
///
|
||||
/// ## Safety
|
||||
|
@ -111,17 +95,15 @@ pub type PFN_lbr_d3d11_filter_chain_frame = unsafe extern "C" fn(
|
|||
/// 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.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn libra_d3d11_filter_chain_frame(
|
||||
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 FrameOptions,
|
||||
) -> libra_error_t {
|
||||
ffi_body!(mut |chain| {
|
||||
opt: *const FrameOptions
|
||||
) mut |chain| {
|
||||
assert_some_ptr!(mut chain);
|
||||
assert_non_null!(out);
|
||||
|
||||
|
@ -149,26 +131,21 @@ pub unsafe extern "C" fn libra_d3d11_filter_chain_frame(
|
|||
|
||||
let image = image.try_into()?;
|
||||
chain.frame(image, &viewport, frame_count, opt.as_ref())?;
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub type PFN_lbr_d3d11_filter_chain_free =
|
||||
unsafe extern "C" fn(chain: *mut libra_d3d11_filter_chain_t) -> libra_error_t;
|
||||
extern_fn! {
|
||||
/// 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 {
|
||||
ffi_body!({
|
||||
fn libra_d3d11_filter_chain_free(chain: *mut libra_d3d11_filter_chain_t) {
|
||||
assert_non_null!(chain);
|
||||
unsafe {
|
||||
let chain_ptr = &mut *chain;
|
||||
let chain = chain_ptr.take();
|
||||
drop(Box::from_raw(chain.unwrap().as_ptr()))
|
||||
};
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use crate::ctypes::{
|
||||
libra_error_t, libra_gl_filter_chain_t, libra_shader_preset_t, libra_viewport_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 crate::ffi::extern_fn;
|
||||
use librashader::runtime::gl::{Framebuffer, GLImage};
|
||||
use std::ffi::{c_char, c_void, CString};
|
||||
use std::mem::MaybeUninit;
|
||||
|
@ -13,72 +13,9 @@ pub use librashader::runtime::gl::options::FilterChainOptions;
|
|||
pub use librashader::runtime::gl::options::FrameOptions;
|
||||
use librashader::runtime::{Size, Viewport};
|
||||
|
||||
|
||||
/// 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 PFN_lbr_gl_init_context = unsafe extern "C" fn(loader: gl_loader_t) -> libra_error_t;
|
||||
/// Initialize the OpenGL Context for librashader.
|
||||
///
|
||||
/// ## Safety
|
||||
/// Attempting to create a filter chain will fail.
|
||||
///
|
||||
/// Reinitializing the OpenGL context with a different loader immediately invalidates previous filter
|
||||
/// 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())
|
||||
});
|
||||
|
||||
LibrashaderError::ok()
|
||||
}
|
||||
|
||||
pub type PFN_lbr_gl_filter_chain_create = unsafe extern "C" fn(
|
||||
preset: *mut libra_shader_preset_t,
|
||||
options: *const FilterChainOptions,
|
||||
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
|
||||
/// 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.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn libra_gl_filter_chain_create(
|
||||
preset: *mut libra_shader_preset_t,
|
||||
options: *const FilterChainOptions,
|
||||
out: *mut MaybeUninit<libra_gl_filter_chain_t>,
|
||||
) -> libra_error_t {
|
||||
ffi_body!({
|
||||
assert_non_null!(preset);
|
||||
let preset = unsafe {
|
||||
let preset_ptr = &mut *preset;
|
||||
let preset = preset_ptr.take();
|
||||
Box::from_raw(preset.unwrap().as_ptr())
|
||||
};
|
||||
|
||||
let options = if options.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(unsafe { &*options })
|
||||
};
|
||||
|
||||
let chain = librashader::runtime::gl::FilterChain::load_from_preset(*preset, options)?;
|
||||
|
||||
unsafe {
|
||||
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(
|
||||
chain,
|
||||
)))))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// OpenGL parameters for the source image.
|
||||
#[repr(C)]
|
||||
pub struct libra_source_image_gl_t {
|
||||
|
@ -114,16 +51,63 @@ impl From<libra_source_image_gl_t> for GLImage {
|
|||
}
|
||||
}
|
||||
|
||||
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 FrameOptions,
|
||||
) -> libra_error_t;
|
||||
extern_fn! {
|
||||
/// Initialize the OpenGL Context for librashader.
|
||||
///
|
||||
/// ## Safety
|
||||
/// Attempting to create a filter chain will fail.
|
||||
///
|
||||
/// Reinitializing the OpenGL context with a different loader immediately invalidates previous filter
|
||||
/// chain objects, and drawing with them causes immediate undefined behaviour.
|
||||
raw fn libra_gl_init_context(loader: gl_loader_t) {
|
||||
gl::load_with(|s| unsafe {
|
||||
let proc_name = CString::new(s).unwrap_unchecked();
|
||||
loader(proc_name.as_ptr())
|
||||
});
|
||||
|
||||
LibrashaderError::ok()
|
||||
}
|
||||
}
|
||||
|
||||
extern_fn! {
|
||||
/// 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.
|
||||
fn libra_gl_filter_chain_create(
|
||||
preset: *mut libra_shader_preset_t,
|
||||
options: *const FilterChainOptions,
|
||||
out: *mut MaybeUninit<libra_gl_filter_chain_t>
|
||||
) {
|
||||
assert_non_null!(preset);
|
||||
let preset = unsafe {
|
||||
let preset_ptr = &mut *preset;
|
||||
let preset = preset_ptr.take();
|
||||
Box::from_raw(preset.unwrap().as_ptr())
|
||||
};
|
||||
|
||||
let options = if options.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(unsafe { &*options })
|
||||
};
|
||||
|
||||
let chain = librashader::runtime::gl::FilterChain::load_from_preset(*preset, options)?;
|
||||
|
||||
unsafe {
|
||||
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(
|
||||
chain,
|
||||
)))))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern_fn! {
|
||||
/// Draw a frame with the given parameters for the given filter chain.
|
||||
///
|
||||
/// ## Safety
|
||||
|
@ -133,32 +117,27 @@ pub type PFN_lbr_gl_filter_chain_frame = unsafe extern "C" fn(
|
|||
/// 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.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn libra_gl_filter_chain_frame(
|
||||
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 FrameOptions,
|
||||
) -> libra_error_t {
|
||||
ffi_body!(mut |chain| {
|
||||
opt: *const FrameOptions
|
||||
) mut |chain| {
|
||||
assert_some_ptr!(mut chain);
|
||||
|
||||
let image: GLImage = image.into();
|
||||
let mvp = if mvp.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(<&[f32; 16]>::try_from(unsafe { slice::from_raw_parts(mvp, 16) }).unwrap())
|
||||
};
|
||||
|
||||
let opt = if opt.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(unsafe { opt.read() })
|
||||
};
|
||||
|
||||
let framebuffer = Framebuffer::new_from_raw(out.texture, out.handle, out.format, Size::new(viewport.width, viewport.height), 1);
|
||||
let viewport = Viewport {
|
||||
x: viewport.x,
|
||||
|
@ -167,27 +146,23 @@ pub unsafe extern "C" fn libra_gl_filter_chain_frame(
|
|||
mvp,
|
||||
};
|
||||
chain.frame(&image, &viewport, frame_count, opt.as_ref())?;
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub type PFN_lbr_gl_filter_chain_free =
|
||||
unsafe extern "C" fn(chain: *mut libra_gl_filter_chain_t) -> libra_error_t;
|
||||
|
||||
extern_fn! {
|
||||
/// Free a GL 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_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 {
|
||||
ffi_body!({
|
||||
fn libra_gl_filter_chain_free(
|
||||
chain: *mut libra_gl_filter_chain_t
|
||||
) {
|
||||
assert_non_null!(chain);
|
||||
unsafe {
|
||||
let chain_ptr = &mut *chain;
|
||||
let chain = chain_ptr.take();
|
||||
drop(Box::from_raw(chain.unwrap().as_ptr()))
|
||||
};
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,343 +0,0 @@
|
|||
#ifndef __LIBRASHADER_H__
|
||||
#define __LIBRASHADER_H__
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#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
|
||||
#ifdef __cplusplus
|
||||
: int32_t
|
||||
#endif // __cplusplus
|
||||
{
|
||||
LIBRA_ERRNO_UNKNOWN_ERROR = 0,
|
||||
LIBRA_ERRNO_INVALID_PARAMETER = 1,
|
||||
LIBRA_ERRNO_INVALID_PATH = 2,
|
||||
LIBRA_ERRNO_PRESET_ERROR = 3,
|
||||
LIBRA_ERRNO_PREPROCESS_ERROR = 4,
|
||||
LIBRA_ERRNO_RUNTIME_ERROR = 5,
|
||||
};
|
||||
#ifndef __cplusplus
|
||||
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.
|
||||
typedef struct _libra_error _libra_error;
|
||||
|
||||
/// A shader preset including all specified parameters, textures, and paths to specified shaders.
|
||||
///
|
||||
/// A shader preset can be used to create a filter chain runtime instance, or reflected to get
|
||||
/// parameter metadata.
|
||||
typedef struct _shader_preset _shader_preset;
|
||||
|
||||
typedef struct _libra_error *libra_error_t;
|
||||
|
||||
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;
|
||||
|
||||
typedef struct _filter_chain_gl *libra_gl_filter_chain_t;
|
||||
|
||||
/// OpenGL parameters for the source image.
|
||||
typedef struct libra_source_image_gl_t {
|
||||
/// A texture GLuint to the source image.
|
||||
uint32_t handle;
|
||||
/// The format of the source image.
|
||||
uint32_t format;
|
||||
/// The width of the source image.
|
||||
uint32_t width;
|
||||
/// The height of the source image.
|
||||
uint32_t height;
|
||||
} libra_source_image_gl_t;
|
||||
|
||||
/// Parameters for the output viewport.
|
||||
typedef struct libra_viewport_t {
|
||||
float x;
|
||||
float y;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
} libra_viewport_t;
|
||||
|
||||
/// OpenGL parameters for the output framebuffer.
|
||||
typedef struct libra_draw_framebuffer_gl_t {
|
||||
/// A framebuffer GLuint to the output framebuffer.
|
||||
uint32_t handle;
|
||||
/// A texture GLuint to the logical buffer of the output framebuffer.
|
||||
uint32_t texture;
|
||||
/// The format of the output framebuffer.
|
||||
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 *preset);
|
||||
|
||||
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 *preset, const char *name, float *value);
|
||||
|
||||
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 *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
|
||||
/// - `filename` must be either null or a valid, aligned pointer to a string path to the shader preset.
|
||||
/// - `out` must be either null, or an aligned pointer to an uninitialized or invalid `libra_shader_preset_t`.
|
||||
/// ## Returns
|
||||
/// - If any parameters are null, `out` is unchanged, and this function returns `LIBRA_ERR_INVALID_PARAMETER`.
|
||||
libra_error_t libra_preset_create(const char *filename,
|
||||
libra_shader_preset_t *out);
|
||||
|
||||
/// Free the preset.
|
||||
///
|
||||
/// 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);
|
||||
|
||||
/// Initialize the OpenGL Context for librashader.
|
||||
///
|
||||
/// ## Safety
|
||||
/// Attempting to create a filter chain will fail.
|
||||
///
|
||||
/// Reinitializing the OpenGL context with a different loader immediately invalidates previous filter
|
||||
/// chain objects, and drawing with them causes immediate undefined behaviour.
|
||||
libra_error_t libra_gl_init_context(gl_loader_t loader);
|
||||
|
||||
/// 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_gl_filter_chain_create(libra_shader_preset_t *preset,
|
||||
const struct filter_chain_gl_opt_t *options,
|
||||
libra_gl_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_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);
|
||||
|
||||
/// Free a GL 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_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);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif /* __LIBRASHADER_H__ */
|
|
@ -4,13 +4,14 @@
|
|||
#include <iostream>
|
||||
#include <filesystem>
|
||||
|
||||
#include "librashader.h"
|
||||
#define LIBRA_RUNTIME_OPENGL
|
||||
#include "../../../../librashader-capi/librashader.h"
|
||||
int main()
|
||||
{
|
||||
std::cout << "Hello World!\n";
|
||||
std::cout << std::filesystem::current_path() << std::endl;
|
||||
libra_shader_preset_t preset;
|
||||
auto error = libra_load_preset("../../../slang-shaders/border/gameboy-player/gameboy-player-crt-royale.slangp", &preset);
|
||||
auto error = libra_preset_create("../../../slang-shaders/border/gameboy-player/gameboy-player-crt-royale.slangp", &preset);
|
||||
if (error != NULL) {
|
||||
std::cout << "error happened\n";
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue