capi: use extern_ffi where possible

This commit is contained in:
chyyran 2023-01-13 16:05:13 -05:00
parent 946fe11c69
commit f25693815b
13 changed files with 591 additions and 902 deletions

View file

@ -44,4 +44,4 @@ features = [
optional = true optional = true
[package.metadata.cargo-post.dependencies] [package.metadata.cargo-post.dependencies]
cbindgen = "0.24.3" cbindgen = { git = "https://github.com/eqrion/cbindgen" }

View file

@ -4,7 +4,14 @@ include_guard = "__LIBRASHADER_H__"
pragma_once = true pragma_once = true
usize_is_size_t = true usize_is_size_t = true
documentation_style = "c++" 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]
parse_deps = true parse_deps = true
include = ["librashader", include = ["librashader",
@ -14,7 +21,7 @@ include = ["librashader",
"librashader-runtime-gl", "librashader-runtime-gl",
"librashader-runtime-d3d11" "librashader-runtime-d3d11"
] ]
expand = ["librashader-capi"]
[struct] [struct]
@ -25,35 +32,32 @@ prefix_with_name = true
[export] [export]
include = [ include = [
# preset # preset
"PFN_lbr_load_preset", "PFN_libra_load_preset",
"PFN_lbr_preset_free", "PFN_libra_preset_free",
"PFN_lbr_preset_set_param", "PFN_libra_preset_set_param",
"PFN_lbr_preset_get_param", "PFN_libra_preset_get_param",
"PFN_lbr_preset_print", "PFN_libra_preset_print",
"PFN_lbr_preset_get_runtime_param_names", "PFN_libra_preset_get_runtime_param_names",
# error # error
"PFN_lbr_error_errno", "PFN_libra_error_errno",
"PFN_lbr_error_print", "PFN_libra_error_print",
"PFN_lbr_error_free", "PFN_libra_error_free",
"PFN_lbr_error_write", "PFN_libra_error_write",
"PFN_lbr_error_free_string", "PFN_libra_error_free_string",
# gl # gl
"PFN_lbr_gl_init_context", "PFN_libra_gl_init_context",
"PFN_lbr_gl_filter_chain_create", "PFN_libra_gl_filter_chain_create",
"PFN_lbr_gl_filter_chain_frame", "PFN_libra_gl_filter_chain_frame",
"PFN_lbr_gl_filter_chain_free", "PFN_libra_gl_filter_chain_free",
# d3d11 # d3d11
"PFN_lbr_d3d11_filter_chain_create", "PFN_libra_d3d11_filter_chain_create",
"PFN_lbr_d3d11_filter_chain_frame", "PFN_libra_d3d11_filter_chain_frame",
"PFN_lbr_d3d11_filter_chain_free" "PFN_libra_d3d11_filter_chain_free",
] ]
#exclude = ["LibrashaderError"]
#
[export.rename] [export.rename]
"LibrashaderError" = "_libra_error" "LibrashaderError" = "_libra_error"
"ShaderPreset" = "_shader_preset" "ShaderPreset" = "_shader_preset"

View file

@ -8,32 +8,31 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#ifdef _WIN32 #ifdef _WIN32 && RUNTIME_D3D11
#include <d3d11.h> #include <d3d11.h>
#else #else
typedef void ID3D11Device;typedef void ID3D11RenderTargetView;typedef void ID3D1ShaderResourceView; typedef void ID3D11Device; typedef void ID3D11RenderTargetView; typedef void ID3D1ShaderResourceView;
#endif #endif
/// Error codes for librashader error types. /// Error codes for librashader error types.
enum LIBRA_ERRNO enum LIBRA_ERRNO
#ifdef __cplusplus #ifdef __cplusplus
: int32_t : int32_t
#endif // __cplusplus #endif // __cplusplus
{ {
LIBRA_ERRNO_UNKNOWN_ERROR = 0, LIBRA_ERRNO_UNKNOWN_ERROR = 0,
LIBRA_ERRNO_INVALID_PARAMETER = 1, LIBRA_ERRNO_INVALID_PARAMETER = 1,
LIBRA_ERRNO_INVALID_PATH = 2, LIBRA_ERRNO_INVALID_PATH = 2,
LIBRA_ERRNO_PRESET_ERROR = 3, LIBRA_ERRNO_PRESET_ERROR = 3,
LIBRA_ERRNO_PREPROCESS_ERROR = 4, LIBRA_ERRNO_PREPROCESS_ERROR = 4,
LIBRA_ERRNO_RUNTIME_ERROR = 5, LIBRA_ERRNO_RUNTIME_ERROR = 5,
}; };
#ifndef __cplusplus #ifndef __cplusplus
typedef int32_t LIBRA_ERRNO; typedef int32_t LIBRA_ERRNO;
#endif // __cplusplus #endif // __cplusplus
typedef struct _filter_chain_d3d11 _filter_chain_d3d11; /// A Direct3D 11 filter chain.
typedef struct FilterChain FilterChain;
typedef struct _filter_chain_gl _filter_chain_gl;
/// The error type for librashader. /// The error type for librashader.
typedef struct _libra_error _libra_error; typedef struct _libra_error _libra_error;
@ -44,297 +43,346 @@ typedef struct _libra_error _libra_error;
/// parameter metadata. /// parameter metadata.
typedef struct _shader_preset _shader_preset; typedef struct _shader_preset _shader_preset;
typedef struct _libra_error *libra_error_t; typedef struct _libra_error* libra_error_t;
typedef struct _shader_preset *libra_shader_preset_t; typedef struct _shader_preset* libra_shader_preset_t;
#if defined(RUNTIME_OPENGL)
/// A GL function loader that librashader needs to be initialized with. /// A GL function loader that librashader needs to be initialized with.
typedef const void *(*gl_loader_t)(const char*); typedef const void* (*gl_loader_t)(const char*);
#endif
/// Options for filter chain creation. /// Options for Direct3D11 filter chain creation.
typedef struct filter_chain_gl_opt_t { typedef struct FilterChainOptions {
/// The GLSL version. Should be at least `330`. /// Use a deferred context to record shader rendering state.
uint16_t gl_version; ///
/// Whether or not to use the Direct State Access APIs. Only available on OpenGL 4.5+. /// The deferred context will be executed on the immediate context
bool use_dsa; /// with `RenderContextState = true`.
} filter_chain_gl_opt_t; 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. /// OpenGL parameters for the source image.
typedef struct libra_source_image_gl_t { typedef struct libra_source_image_gl_t {
/// A texture GLuint to the source image. /// A texture GLuint to the source image.
uint32_t handle; uint32_t handle;
/// The format of the source image. /// The format of the source image.
uint32_t format; uint32_t format;
/// The width of the source image. /// The width of the source image.
uint32_t width; uint32_t width;
/// The height of the source image. /// The height of the source image.
uint32_t height; uint32_t height;
} libra_source_image_gl_t; } libra_source_image_gl_t;
#endif
/// Parameters for the output viewport. /// Parameters for the output viewport.
typedef struct libra_viewport_t { typedef struct libra_viewport_t {
float x; float x;
float y; float y;
uint32_t width; uint32_t width;
uint32_t height; uint32_t height;
} libra_viewport_t; } libra_viewport_t;
#if defined(RUNTIME_OPENGL)
/// OpenGL parameters for the output framebuffer. /// OpenGL parameters for the output framebuffer.
typedef struct libra_draw_framebuffer_gl_t { typedef struct libra_draw_framebuffer_gl_t {
/// A framebuffer GLuint to the output framebuffer. /// A framebuffer GLuint to the output framebuffer.
uint32_t handle; uint32_t handle;
/// A texture GLuint to the logical buffer of the output framebuffer. /// A texture GLuint to the logical buffer of the output framebuffer.
uint32_t texture; uint32_t texture;
/// The format of the output framebuffer. /// The format of the output framebuffer.
uint32_t format; uint32_t format;
} libra_draw_framebuffer_gl_t; } libra_draw_framebuffer_gl_t;
#endif
/// 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. /// Options for each Direct3D11 shader frame.
typedef struct frame_d3d11_opt_t { typedef struct FrameOptions {
/// Whether or not to clear the history buffers. /// Whether or not to clear the history buffers.
bool clear_history; bool clear_history;
/// The direction of the frame. 1 should be vertical. /// The direction of the frame. 1 should be vertical.
int32_t frame_direction; int32_t frame_direction;
} frame_d3d11_opt_t; } FrameOptions;
typedef libra_error_t (*PFN_lbr_preset_free)(libra_shader_preset_t *preset); #if defined(RUNTIME_D3D11)
typedef struct FilterChain* libra_d3d11_filter_chain_t;
#endif
typedef libra_error_t (*PFN_lbr_preset_set_param)(libra_shader_preset_t *preset, const char *name, float value); #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
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;
#endif
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_free)(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_set_param)(libra_shader_preset_t* preset,
const char* name,
float value);
typedef libra_error_t (*PFN_lbr_preset_get_runtime_param_names)(libra_shader_preset_t *preset, const char **value); typedef libra_error_t(*PFN_libra_preset_get_param)(libra_shader_preset_t* preset,
const char* name,
float* value);
typedef LIBRA_ERRNO (*PFN_lbr_error_errno)(libra_error_t error); typedef libra_error_t(*PFN_libra_preset_print)(libra_shader_preset_t* preset);
typedef int32_t (*PFN_lbr_error_print)(libra_error_t error); typedef libra_error_t(*PFN_libra_preset_get_runtime_param_names)(libra_shader_preset_t* preset,
const char** value);
typedef int32_t (*PFN_lbr_error_free)(libra_error_t *error); typedef LIBRA_ERRNO(*PFN_libra_error_errno)(libra_error_t error);
typedef int32_t (*PFN_lbr_error_write)(libra_error_t error, char **out); typedef int32_t(*PFN_libra_error_print)(libra_error_t error);
typedef int32_t (*PFN_lbr_error_free_string)(char **out); typedef int32_t(*PFN_libra_error_free)(libra_error_t* error);
typedef libra_error_t (*PFN_lbr_gl_init_context)(gl_loader_t loader); typedef int32_t(*PFN_libra_error_write)(libra_error_t error, char** out);
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 int32_t(*PFN_libra_error_free_string)(char** 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); #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_filter_chain_free)(libra_gl_filter_chain_t *chain); #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_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_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_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); #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_d3d11_filter_chain_free)(libra_d3d11_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
#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
#if defined(RUNTIME_D3D11)
typedef libra_error_t(*PFN_libra_d3d11_filter_chain_free)(libra_d3d11_filter_chain_t* chain);
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif // __cplusplus #endif // __cplusplus
/// Get the error code corresponding to this error object. /// Get the error code corresponding to this error object.
/// ///
/// ## Safety /// ## Safety
/// - `error` must be valid and initialized. /// - `error` must be valid and initialized.
LIBRA_ERRNO libra_error_errno(libra_error_t error); LIBRA_ERRNO libra_error_errno(libra_error_t error);
/// Print the error message. /// Print the error message.
/// ///
/// If `error` is null, this function does nothing and returns 1. Otherwise, this function returns 0. /// If `error` is null, this function does nothing and returns 1. Otherwise, this function returns 0.
/// ## Safety /// ## Safety
/// - `error` must be a valid and initialized instance of `libra_error_t`. /// - `error` must be a valid and initialized instance of `libra_error_t`.
int32_t libra_error_print(libra_error_t error); int32_t libra_error_print(libra_error_t error);
/// Frees any internal state kept by the 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. /// If `error` is null, this function does nothing and returns 1. Otherwise, this function returns 0.
/// The resulting error object becomes null. /// The resulting error object becomes null.
/// ## Safety /// ## Safety
/// - `error` must be null or a pointer to a valid and initialized instance of `libra_error_t`. /// - `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); int32_t libra_error_free(libra_error_t* error);
/// Writes the error message into `out` /// Writes the error message into `out`
/// ///
/// If `error` is null, this function does nothing and returns 1. Otherwise, this function returns 0. /// If `error` is null, this function does nothing and returns 1. Otherwise, this function returns 0.
/// ## Safety /// ## Safety
/// - `error` must be a valid and initialized instance of `libra_error_t`. /// - `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. /// - `out` must be a non-null pointer. The resulting string must not be modified.
int32_t libra_error_write(libra_error_t error, int32_t libra_error_write(libra_error_t error,
char **out); char** out);
/// Frees an error string previously allocated by `libra_error_write`. /// Frees an error string previously allocated by `libra_error_write`.
/// ///
/// After freeing, the pointer will be set to null. /// After freeing, the pointer will be set to null.
/// ## Safety /// ## Safety
/// - If `libra_error_write` is not null, it must point to a string previously returned by `libra_error_write`. /// - 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 /// Attempting to free anything else, including strings or objects from other librashader functions, is immediate
/// Undefined Behaviour. /// Undefined Behaviour.
int32_t libra_error_free_string(char **out); int32_t libra_error_free_string(char** out);
/// Load a preset. /// Load a preset.
/// ///
/// ## Safety /// ## Safety
/// - `filename` must be either null or a valid, aligned pointer to a string path to the shader preset. /// - `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`. /// - `out` must be either null, or an aligned pointer to an uninitialized or invalid `libra_shader_preset_t`.
/// ## Returns /// ## Returns
/// - If any parameters are null, `out` is unchanged, and this function returns `LIBRA_ERR_INVALID_PARAMETER`. /// - 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_error_t libra_preset_create(const char* filename,
libra_shader_preset_t *out); libra_shader_preset_t* out);
/// Free the preset. /// Free the preset.
/// ///
/// If `preset` is null, this function does nothing. The resulting value in `preset` then becomes /// If `preset` is null, this function does nothing. The resulting value in `preset` then becomes
/// null. /// null.
/// ///
/// ## Safety /// ## Safety
/// - `preset` must be a valid and aligned pointer to a shader preset. /// - `preset` must be a valid and aligned pointer to a shader preset.
libra_error_t libra_preset_free(libra_shader_preset_t *preset); libra_error_t libra_preset_free(libra_shader_preset_t* preset);
/// Set the value of the parameter in the preset. /// Set the value of the parameter in the preset.
/// ///
/// ## Safety /// ## Safety
/// - `preset` must be null or a valid and aligned pointer to a shader preset. /// - `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. /// - `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); 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. /// Get the value of the parameter as set in the preset.
/// ///
/// ## Safety /// ## Safety
/// - `preset` must be null or a valid and aligned pointer to a shader preset. /// - `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. /// - `name` must be null or a valid and aligned pointer to a string.
/// - `value` may be a pointer to a uninitialized `float`. /// - `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); libra_error_t libra_preset_get_param(libra_shader_preset_t* preset, const char* name, float* value);
/// Pretty print the shader preset. /// Pretty print the shader preset.
/// ///
/// ## Safety /// ## Safety
/// - `preset` must be null or a valid and aligned pointer to a shader preset. /// - `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); libra_error_t libra_preset_print(libra_shader_preset_t* preset);
/// Get a list of runtime parameter names. /// Get a list of runtime parameter names.
/// ///
/// The returned value can not currently be freed. /// The returned value can not currently be freed.
/// This function should be considered in progress. Its use is discouraged. /// 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, libra_error_t libra_preset_get_runtime_param_names(libra_shader_preset_t* preset,
const char **value); const char** value);
/// Initialize the OpenGL Context for librashader. #if defined(RUNTIME_OPENGL)
/// /// Initialize the OpenGL Context for librashader.
/// ## Safety ///
/// Attempting to create a filter chain will fail. /// ## 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. /// Reinitializing the OpenGL context with a different loader immediately invalidates previous filter
libra_error_t libra_gl_init_context(gl_loader_t loader); /// chain objects, and drawing with them causes immediate undefined behaviour.
libra_error_t libra_gl_init_context(gl_loader_t loader);
#endif
/// Create the filter chain given the shader preset. #if defined(RUNTIME_OPENGL)
/// /// Create the filter chain given the shader preset.
/// The shader preset is immediately invalidated and must be recreated after ///
/// the filter chain is created. /// 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. /// ## Safety:
/// - `options` must be either null, or valid and aligned. /// - `preset` must be either null, or valid and aligned.
/// - `out` must be aligned, but may be null, invalid, or uninitialized. /// - `options` must be either null, or valid and aligned.
libra_error_t libra_gl_filter_chain_create(libra_shader_preset_t *preset, /// - `out` must be aligned, but may be null, invalid, or uninitialized.
const struct filter_chain_gl_opt_t *options, libra_error_t libra_gl_filter_chain_create(libra_shader_preset_t* preset,
libra_gl_filter_chain_t *out); const struct FilterChainOptions* options,
libra_gl_filter_chain_t* out);
#endif
/// Draw a frame with the given parameters for the given filter chain. #if defined(RUNTIME_OPENGL)
/// /// 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 /// ## Safety
/// function will return an error. /// - `chain` may be null, invalid, but not uninitialized. If `chain` is null or invalid, this
/// - `mvp` may be null, or if it is not null, must be an aligned pointer to 16 consecutive `float` /// function will return an error.
/// values for the model view projection matrix. /// - `mvp` may be null, or if it is not null, must be an aligned pointer to 16 consecutive `float`
/// - `opt` may be null, or if it is not null, must be an aligned pointer to a valid `frame_gl_opt_t` /// values for the model view projection matrix.
/// struct. /// - `opt` may be null, or if it is not null, must be an aligned pointer to a valid `frame_gl_opt_t`
libra_error_t libra_gl_filter_chain_frame(libra_gl_filter_chain_t *chain, /// struct.
size_t frame_count, libra_error_t libra_gl_filter_chain_frame(libra_gl_filter_chain_t* chain,
struct libra_source_image_gl_t image, size_t frame_count,
struct libra_viewport_t viewport, struct libra_source_image_gl_t image,
struct libra_draw_framebuffer_gl_t out, struct libra_viewport_t viewport,
const float *mvp, struct libra_draw_framebuffer_gl_t out,
const struct frame_gl_opt_t *opt); const float* mvp,
const struct FrameOptions* opt);
#endif
/// Free a GL filter chain. #if defined(RUNTIME_OPENGL)
/// /// Free a GL filter chain.
/// The resulting value in `chain` then becomes null. ///
/// ## Safety /// The resulting value in `chain` then becomes null.
/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_gl_filter_chain_t`. /// ## Safety
libra_error_t libra_gl_filter_chain_free(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);
#endif
/// Create the filter chain given the shader preset. #if defined(RUNTIME_D3D11)
/// /// Create the filter chain given the shader preset.
/// The shader preset is immediately invalidated and must be recreated after ///
/// the filter chain is created. /// 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. /// ## Safety:
/// - `options` must be either null, or valid and aligned. /// - `preset` must be either null, or valid and aligned.
/// - `out` must be aligned, but may be null, invalid, or uninitialized. /// - `options` must be either null, or valid and aligned.
libra_error_t libra_d3d11_filter_chain_create(libra_shader_preset_t *preset, /// - `out` must be aligned, but may be null, invalid, or uninitialized.
const struct filter_chain_d3d11_opt_t *options, libra_error_t libra_d3d11_filter_chain_create(libra_shader_preset_t* preset,
const ID3D11Device *device, const struct FilterChainOptions* options,
libra_d3d11_filter_chain_t *out); const ID3D11Device* device,
libra_d3d11_filter_chain_t* out);
#endif
/// Draw a frame with the given parameters for the given filter chain. #if defined(RUNTIME_D3D11)
/// /// 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 /// ## Safety
/// function will return an error. /// - `chain` may be null, invalid, but not uninitialized. If `chain` is null or invalid, this
/// - `mvp` may be null, or if it is not null, must be an aligned pointer to 16 consecutive `float` /// function will return an error.
/// values for the model view projection matrix. /// - `mvp` may be null, or if it is not null, must be an aligned pointer to 16 consecutive `float`
/// - `opt` may be null, or if it is not null, must be an aligned pointer to a valid `frame_gl_opt_t` /// values for the model view projection matrix.
/// struct. /// - `opt` may be null, or if it is not null, must be an aligned pointer to a valid `frame_gl_opt_t`
libra_error_t libra_d3d11_filter_chain_frame(libra_d3d11_filter_chain_t *chain, /// struct.
size_t frame_count, libra_error_t libra_d3d11_filter_chain_frame(libra_d3d11_filter_chain_t* chain,
struct libra_source_image_d3d11_t image, size_t frame_count,
struct libra_viewport_t viewport, struct libra_source_image_d3d11_t image,
const ID3D11RenderTargetView *out, struct libra_viewport_t viewport,
const float *mvp, const ID3D11RenderTargetView* out,
const struct frame_d3d11_opt_t *opt); const float* mvp,
const struct FrameOptions* opt);
#endif
/// Free a D3D11 filter chain. #if defined(RUNTIME_D3D11)
/// /// Free a D3D11 filter chain.
/// The resulting value in `chain` then becomes null. ///
/// ## Safety /// The resulting value in `chain` then becomes null.
/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_d3d11_filter_chain_t`. /// ## Safety
libra_error_t libra_d3d11_filter_chain_free(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);
#endif
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"

View file

@ -1,7 +1,7 @@
use std::{env, fs}; use std::{env, fs};
use std::fs::File; use std::fs::File;
use std::io::{BufWriter, Write}; use std::io::{BufWriter, Write};
use std::path::{Path, PathBuf}; use std::path::PathBuf;
pub fn main() { pub fn main() {
// Do not update files on docsrs // Do not update files on docsrs

View file

@ -1,6 +1,6 @@
//! The librashader error C API. (`libra_error_*`). //! The librashader error C API. (`libra_error_*`).
use std::any::Any; use std::any::Any;
use std::ffi::{c_char, CStr, CString}; use std::ffi::{c_char, CString};
use std::mem::MaybeUninit; use std::mem::MaybeUninit;
use std::ptr::NonNull; use std::ptr::NonNull;
use thiserror::Error; use thiserror::Error;
@ -42,7 +42,9 @@ pub enum LIBRA_ERRNO {
RUNTIME_ERROR = 5, 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] #[no_mangle]
/// Get the error code corresponding to this error object. /// 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() } 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] #[no_mangle]
/// Print the error message. /// Print the error message.
/// ///
@ -74,7 +76,7 @@ pub extern "C" fn libra_error_print(error: libra_error_t) -> i32 {
return 0; 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] #[no_mangle]
/// Frees any internal state kept by the error. /// 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; return 1;
} }
let mut error = unsafe { &mut *error }; let error = unsafe { &mut *error };
let error = error.take(); let error = error.take();
let Some(error) = error else { let Some(error) = error else {
return 1; return 1;
@ -97,7 +99,7 @@ pub extern "C" fn libra_error_free(error: *mut libra_error_t) -> i32 {
return 0; 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; extern "C" fn(error: libra_error_t, out: *mut MaybeUninit<*mut c_char>) -> i32;
#[no_mangle] #[no_mangle]
/// Writes the error message into `out` /// Writes the error message into `out`
@ -128,7 +130,7 @@ pub extern "C" fn libra_error_write(
return 0; 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] #[no_mangle]
/// Frees an error string previously allocated by `libra_error_write`. /// 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) => { // macro_rules! assert_some {
if $value.is_none() { // ($value:ident) => {
return $crate::error::LibrashaderError::InvalidParameter(stringify!($value)).export(); // if $value.is_none() {
} // return $crate::error::LibrashaderError::InvalidParameter(stringify!($value)).export();
}; // }
} // };
// }
macro_rules! assert_some_ptr { macro_rules! assert_some_ptr {
($value:ident) => { ($value:ident) => {
@ -221,5 +224,5 @@ macro_rules! assert_some_ptr {
use crate::ctypes::libra_error_t; use crate::ctypes::libra_error_t;
pub(crate) use assert_non_null; pub(crate) use assert_non_null;
pub(crate) use assert_some; // pub(crate) use assert_some;
pub(crate) use assert_some_ptr; pub(crate) use assert_some_ptr;

View file

@ -65,10 +65,57 @@ macro_rules! extern_fn {
#[no_mangle] #[no_mangle]
$(#[$($attrss)*])* $(#[$($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) $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; pub(crate) use extern_fn;

View file

@ -38,11 +38,12 @@
#![feature(vec_into_raw_parts)] #![feature(vec_into_raw_parts)]
#![deny(unsafe_op_in_unsafe_fn)] #![deny(unsafe_op_in_unsafe_fn)]
use std::os::raw::c_char;
pub mod ctypes; pub mod ctypes;
pub mod error; pub mod error;
mod ffi; mod ffi;
pub mod presets; pub mod presets;
#[cfg(feature = "reflect")]
pub mod reflect; pub mod reflect;
pub mod runtime; pub mod runtime;

View file

@ -1,7 +1,7 @@
//! The librashader preset C API (`libra_preset_*`). //! The librashader preset C API (`libra_preset_*`).
use crate::ctypes::{libra_error_t, libra_shader_preset_t}; use crate::ctypes::{libra_error_t, libra_shader_preset_t};
use crate::error::{assert_non_null, assert_some, assert_some_ptr, LibrashaderError}; use crate::error::{assert_non_null, assert_some_ptr, LibrashaderError};
use crate::ffi::ffi_body; use crate::ffi::{extern_fn, ffi_body};
use librashader::presets::ShaderPreset; use librashader::presets::ShaderPreset;
use std::ffi::{c_char, CStr, CString}; use std::ffi::{c_char, CStr, CString};
use std::mem::MaybeUninit; use std::mem::MaybeUninit;
@ -12,76 +12,63 @@ pub type PFN_lbr_preset_create = unsafe extern "C" fn(
out: *mut MaybeUninit<libra_shader_preset_t>, out: *mut MaybeUninit<libra_shader_preset_t>,
) -> libra_error_t; ) -> libra_error_t;
/// Load a preset. extern_fn! {
/// /// Load a preset.
/// ## Safety ///
/// - `filename` must be either null or a valid, aligned pointer to a string path to the shader preset. /// ## Safety
/// - `out` must be either null, or an aligned pointer to an uninitialized or invalid `libra_shader_preset_t`. /// - `filename` must be either null or a valid, aligned pointer to a string path to the shader preset.
/// ## Returns /// - `out` must be either null, or an aligned pointer to an uninitialized or invalid `libra_shader_preset_t`.
/// - If any parameters are null, `out` is unchanged, and this function returns `LIBRA_ERR_INVALID_PARAMETER`. /// ## Returns
#[no_mangle] /// - If any parameters are null, `out` is unchanged, and this function returns `LIBRA_ERR_INVALID_PARAMETER`.
pub unsafe extern "C" fn libra_preset_create( fn libra_preset_create(
filename: *const c_char, filename: *const c_char,
out: *mut MaybeUninit<libra_shader_preset_t>, out: *mut MaybeUninit<libra_shader_preset_t>
) -> libra_error_t { ) {
ffi_body!({
assert_non_null!(filename); assert_non_null!(filename);
assert_non_null!(out); assert_non_null!(out);
let filename = unsafe { CStr::from_ptr(filename) }; let filename = unsafe { CStr::from_ptr(filename) };
let filename = filename.to_str()?; let filename = filename.to_str()?;
println!("loading {filename}"); println!("loading {filename}");
let preset = ShaderPreset::try_parse(filename)?;
let preset = ShaderPreset::try_parse(filename)?;
unsafe { unsafe {
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new( out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(
preset, preset,
))))) )))))
} }
}) }
} }
pub type PFN_lbr_preset_free = extern_fn! {
unsafe extern "C" fn(preset: *mut libra_shader_preset_t) -> libra_error_t; /// Free the preset.
///
/// Free the preset. /// If `preset` is null, this function does nothing. The resulting value in `preset` then becomes
/// /// null.
/// 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.
/// ## Safety fn libra_preset_free(preset: *mut libra_shader_preset_t) {
/// - `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!({
assert_non_null!(preset); assert_non_null!(preset);
unsafe { unsafe {
let preset_ptr = &mut *preset; let preset_ptr = &mut *preset;
let preset = preset_ptr.take(); let preset = preset_ptr.take();
drop(Box::from_raw(preset.unwrap().as_ptr())); drop(Box::from_raw(preset.unwrap().as_ptr()));
} }
}) }
} }
pub type PFN_lbr_preset_set_param = unsafe extern "C" fn( extern_fn! {
preset: *mut libra_shader_preset_t, /// Set the value of the parameter in the preset.
name: *const c_char, ///
value: f32, /// ## Safety
) -> libra_error_t; /// - `preset` must be null or a valid and aligned pointer to a shader preset.
/// Set the value of the parameter in the preset. /// - `name` must be null or a valid and aligned pointer to a string.
/// fn libra_preset_set_param(
/// ## Safety preset: *mut libra_shader_preset_t,
/// - `preset` must be null or a valid and aligned pointer to a shader preset. name: *const c_char,
/// - `name` must be null or a valid and aligned pointer to a string. value: f32
#[no_mangle] ) |name|; mut |preset| {
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 { let name = unsafe {
CStr::from_ptr(name) 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) { if let Some(param) = preset.parameters.iter_mut().find(|c| c.name == name) {
param.value = value param.value = value
} }
}) }
} }
pub type PFN_lbr_preset_get_param = unsafe extern "C" fn( extern_fn! {
preset: *mut libra_shader_preset_t, /// Get the value of the parameter as set in the preset.
name: *const c_char, ///
value: *mut MaybeUninit<f32>, /// ## Safety
) -> libra_error_t; /// - `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.
/// Get the value of the parameter as set in the preset. /// - `value` may be a pointer to a uninitialized `float`.
/// fn libra_preset_get_param(
/// ## Safety preset: *mut libra_shader_preset_t,
/// - `preset` must be null or a valid and aligned pointer to a shader preset. name: *const c_char,
/// - `name` must be null or a valid and aligned pointer to a string. value: *mut MaybeUninit<f32>
/// - `value` may be a pointer to a uninitialized `float`. ) |name, preset| {
#[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) }; let name = unsafe { CStr::from_ptr(name) };
let name = name.to_str()?; let name = name.to_str()?;
assert_some_ptr!(preset); 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) { 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 = extern_fn! {
unsafe extern "C" fn(preset: *mut libra_shader_preset_t) -> libra_error_t; /// Pretty print the shader preset.
///
/// Pretty print the shader preset. /// ## Safety
/// /// - `preset` must be null or a valid and aligned pointer to a shader preset.
/// ## Safety fn libra_preset_print(preset: *mut libra_shader_preset_t) |preset| {
/// - `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| {
assert_some_ptr!(preset); assert_some_ptr!(preset);
println!("{:#?}", 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, preset: *mut libra_shader_preset_t,
value: MaybeUninit<*mut *const c_char>, value: MaybeUninit<*mut *const c_char>,
) -> libra_error_t; ) -> 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(); let (parts, _len, _cap) = c_strings.into_raw_parts();
value.write(parts); value.write(parts);
}) })
} }

View file

@ -12,7 +12,6 @@ use librashader::reflect::{
}; };
use librashader::{FilterMode, WrapMode}; use librashader::{FilterMode, WrapMode};
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use std::error::Error;
pub(crate) struct LookupTexture { pub(crate) struct LookupTexture {
wrap_mode: WrapMode, wrap_mode: WrapMode,

View file

@ -1,8 +1,8 @@
use crate::ctypes::{ 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::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 librashader::runtime::d3d11::{D3D11InputView, D3D11OutputView};
use std::mem::MaybeUninit; use std::mem::MaybeUninit;
use std::ptr::NonNull; use std::ptr::NonNull;
@ -41,29 +41,22 @@ impl TryFrom<libra_source_image_d3d11_t> for D3D11InputView {
} }
} }
pub type PFN_lbr_d3d11_filter_chain_create = unsafe extern "C" fn( extern_fn! {
preset: *mut libra_shader_preset_t, /// Create the filter chain given the shader preset.
options: *const FilterChainOptions, ///
device: *const ID3D11Device, /// The shader preset is immediately invalidated and must be recreated after
out: *mut MaybeUninit<libra_d3d11_filter_chain_t>, /// the filter chain is created.
) -> libra_error_t; ///
/// Create the filter chain given the shader preset. /// ## Safety:
/// /// - `preset` must be either null, or valid and aligned.
/// The shader preset is immediately invalidated and must be recreated after /// - `options` must be either null, or valid and aligned.
/// the filter chain is created. /// - `out` must be aligned, but may be null, invalid, or uninitialized.
/// fn libra_d3d11_filter_chain_create(
/// ## Safety: preset: *mut libra_shader_preset_t,
/// - `preset` must be either null, or valid and aligned. options: *const FilterChainOptions,
/// - `options` must be either null, or valid and aligned. device: *const ID3D11Device,
/// - `out` must be aligned, but may be null, invalid, or uninitialized. out: *mut MaybeUninit<libra_d3d11_filter_chain_t>
#[no_mangle] ) {
pub unsafe extern "C" 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!({
assert_non_null!(preset); assert_non_null!(preset);
assert_non_null!(device); assert_non_null!(device);
let preset = unsafe { let preset = unsafe {
@ -89,39 +82,28 @@ pub unsafe extern "C" fn libra_d3d11_filter_chain_create(
chain, chain,
))))) )))))
} }
}) }
} }
pub type PFN_lbr_d3d11_filter_chain_frame = unsafe extern "C" fn( extern_fn! {
chain: *mut libra_d3d11_filter_chain_t, /// Draw a frame with the given parameters for the given filter chain.
frame_count: usize, ///
image: libra_source_image_d3d11_t, /// ## Safety
viewport: libra_viewport_t, /// - `chain` may be null, invalid, but not uninitialized. If `chain` is null or invalid, this
out: *const ID3D11RenderTargetView, /// function will return an error.
mvp: *const f32, /// - `mvp` may be null, or if it is not null, must be an aligned pointer to 16 consecutive `float`
opt: *const FrameOptions, /// values for the model view projection matrix.
) -> libra_error_t; /// - `opt` may be null, or if it is not null, must be an aligned pointer to a valid `frame_gl_opt_t`
/// struct.
/// Draw a frame with the given parameters for the given filter chain. fn libra_d3d11_filter_chain_frame(
/// chain: *mut libra_d3d11_filter_chain_t,
/// ## Safety frame_count: usize,
/// - `chain` may be null, invalid, but not uninitialized. If `chain` is null or invalid, this image: libra_source_image_d3d11_t,
/// function will return an error. viewport: libra_viewport_t,
/// - `mvp` may be null, or if it is not null, must be an aligned pointer to 16 consecutive `float` out: *const ID3D11RenderTargetView,
/// values for the model view projection matrix. mvp: *const f32,
/// - `opt` may be null, or if it is not null, must be an aligned pointer to a valid `frame_gl_opt_t` opt: *const FrameOptions
/// struct. ) mut |chain| {
#[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 FrameOptions,
) -> libra_error_t {
ffi_body!(mut |chain| {
assert_some_ptr!(mut chain); assert_some_ptr!(mut chain);
assert_non_null!(out); assert_non_null!(out);
@ -149,26 +131,21 @@ pub unsafe extern "C" fn libra_d3d11_filter_chain_frame(
let image = image.try_into()?; let image = image.try_into()?;
chain.frame(image, &viewport, frame_count, opt.as_ref())?; chain.frame(image, &viewport, frame_count, opt.as_ref())?;
}) }
} }
pub type PFN_lbr_d3d11_filter_chain_free = extern_fn! {
unsafe extern "C" fn(chain: *mut libra_d3d11_filter_chain_t) -> libra_error_t; /// Free a D3D11 filter chain.
/// Free a D3D11 filter chain. ///
/// /// The resulting value in `chain` then becomes null.
/// The resulting value in `chain` then becomes null. /// ## Safety
/// ## Safety /// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_d3d11_filter_chain_t`.
/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_d3d11_filter_chain_t`. fn libra_d3d11_filter_chain_free(chain: *mut 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!({
assert_non_null!(chain); assert_non_null!(chain);
unsafe { unsafe {
let chain_ptr = &mut *chain; let chain_ptr = &mut *chain;
let chain = chain_ptr.take(); let chain = chain_ptr.take();
drop(Box::from_raw(chain.unwrap().as_ptr())) drop(Box::from_raw(chain.unwrap().as_ptr()))
}; };
}) }
} }

View file

@ -1,8 +1,8 @@
use crate::ctypes::{ 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::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 librashader::runtime::gl::{Framebuffer, GLImage};
use std::ffi::{c_char, c_void, CString}; use std::ffi::{c_char, c_void, CString};
use std::mem::MaybeUninit; use std::mem::MaybeUninit;
@ -13,72 +13,9 @@ pub use librashader::runtime::gl::options::FilterChainOptions;
pub use librashader::runtime::gl::options::FrameOptions; pub use librashader::runtime::gl::options::FrameOptions;
use librashader::runtime::{Size, Viewport}; use librashader::runtime::{Size, Viewport};
/// A GL function loader that librashader needs to be initialized with. /// 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
/// 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. /// OpenGL parameters for the source image.
#[repr(C)] #[repr(C)]
pub struct libra_source_image_gl_t { pub struct libra_source_image_gl_t {
@ -114,51 +51,93 @@ impl From<libra_source_image_gl_t> for GLImage {
} }
} }
pub type PFN_lbr_gl_filter_chain_frame = unsafe extern "C" fn( extern_fn! {
chain: *mut libra_gl_filter_chain_t, /// Initialize the OpenGL Context for librashader.
frame_count: usize, ///
image: libra_source_image_gl_t, /// ## Safety
viewport: libra_viewport_t, /// Attempting to create a filter chain will fail.
out: libra_draw_framebuffer_gl_t, ///
mvp: *const f32, /// Reinitializing the OpenGL context with a different loader immediately invalidates previous filter
opt: *const FrameOptions, /// chain objects, and drawing with them causes immediate undefined behaviour.
) -> libra_error_t; 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())
});
/// Draw a frame with the given parameters for the given filter chain. LibrashaderError::ok()
/// }
/// ## Safety }
/// - `chain` may be null, invalid, but not uninitialized. If `chain` is null or invalid, this
/// function will return an error. extern_fn! {
/// - `mvp` may be null, or if it is not null, must be an aligned pointer to 16 consecutive `float` /// Create the filter chain given the shader preset.
/// 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` /// The shader preset is immediately invalidated and must be recreated after
/// struct. /// the filter chain is created.
#[no_mangle] ///
pub unsafe extern "C" fn libra_gl_filter_chain_frame( /// ## Safety:
chain: *mut libra_gl_filter_chain_t, /// - `preset` must be either null, or valid and aligned.
frame_count: usize, /// - `options` must be either null, or valid and aligned.
image: libra_source_image_gl_t, /// - `out` must be aligned, but may be null, invalid, or uninitialized.
viewport: libra_viewport_t, fn libra_gl_filter_chain_create(
out: libra_draw_framebuffer_gl_t, preset: *mut libra_shader_preset_t,
mvp: *const f32, options: *const FilterChainOptions,
opt: *const FrameOptions, out: *mut MaybeUninit<libra_gl_filter_chain_t>
) -> libra_error_t { ) {
ffi_body!(mut |chain| { 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
/// - `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.
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
) mut |chain| {
assert_some_ptr!(mut chain); assert_some_ptr!(mut chain);
let image: GLImage = image.into(); let image: GLImage = image.into();
let mvp = if mvp.is_null() { let mvp = if mvp.is_null() {
None None
} else { } else {
Some(<&[f32; 16]>::try_from(unsafe { slice::from_raw_parts(mvp, 16) }).unwrap()) Some(<&[f32; 16]>::try_from(unsafe { slice::from_raw_parts(mvp, 16) }).unwrap())
}; };
let opt = if opt.is_null() { let opt = if opt.is_null() {
None None
} else { } else {
Some(unsafe { opt.read() }) Some(unsafe { opt.read() })
}; };
let framebuffer = Framebuffer::new_from_raw(out.texture, out.handle, out.format, Size::new(viewport.width, viewport.height), 1); let framebuffer = Framebuffer::new_from_raw(out.texture, out.handle, out.format, Size::new(viewport.width, viewport.height), 1);
let viewport = Viewport { let viewport = Viewport {
x: viewport.x, x: viewport.x,
@ -167,27 +146,23 @@ pub unsafe extern "C" fn libra_gl_filter_chain_frame(
mvp, mvp,
}; };
chain.frame(&image, &viewport, frame_count, opt.as_ref())?; chain.frame(&image, &viewport, frame_count, opt.as_ref())?;
}) }
} }
pub type PFN_lbr_gl_filter_chain_free = extern_fn! {
unsafe extern "C" fn(chain: *mut libra_gl_filter_chain_t) -> libra_error_t; /// Free a GL filter chain.
///
/// Free a GL filter chain. /// The resulting value in `chain` then becomes null.
/// /// ## Safety
/// The resulting value in `chain` then becomes null. /// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_gl_filter_chain_t`.
/// ## Safety fn libra_gl_filter_chain_free(
/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_gl_filter_chain_t`. chain: *mut 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!({
assert_non_null!(chain); assert_non_null!(chain);
unsafe { unsafe {
let chain_ptr = &mut *chain; let chain_ptr = &mut *chain;
let chain = chain_ptr.take(); let chain = chain_ptr.take();
drop(Box::from_raw(chain.unwrap().as_ptr())) drop(Box::from_raw(chain.unwrap().as_ptr()))
}; };
}) }
} }

View file

@ -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__ */

View file

@ -4,13 +4,14 @@
#include <iostream> #include <iostream>
#include <filesystem> #include <filesystem>
#include "librashader.h" #define LIBRA_RUNTIME_OPENGL
#include "../../../../librashader-capi/librashader.h"
int main() int main()
{ {
std::cout << "Hello World!\n"; std::cout << "Hello World!\n";
std::cout << std::filesystem::current_path() << std::endl; std::cout << std::filesystem::current_path() << std::endl;
libra_shader_preset_t preset; 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) { if (error != NULL) {
std::cout << "error happened\n"; std::cout << "error happened\n";
} }