diff --git a/include/librashader.h b/include/librashader.h index 68088b7..4d3e41d 100644 --- a/include/librashader.h +++ b/include/librashader.h @@ -50,10 +50,12 @@ enum LIBRA_ERRNO { LIBRA_ERRNO_UNKNOWN_ERROR = 0, LIBRA_ERRNO_INVALID_PARAMETER = 1, - LIBRA_ERRNO_INVALID_PATH = 2, + LIBRA_ERRNO_INVALID_STRING = 2, LIBRA_ERRNO_PRESET_ERROR = 3, LIBRA_ERRNO_PREPROCESS_ERROR = 4, - LIBRA_ERRNO_RUNTIME_ERROR = 5, + LIBRA_ERRNO_SHADER_PARAMETER_ERROR = 5, + LIBRA_ERRNO_REFLECT_ERROR = 6, + LIBRA_ERRNO_RUNTIME_ERROR = 7, }; #ifndef __cplusplus typedef int32_t LIBRA_ERRNO; @@ -83,6 +85,33 @@ typedef struct _libra_error *libra_error_t; /// A handle to a shader preset object. typedef struct _shader_preset *libra_shader_preset_t; +/// A preset parameter. +typedef struct libra_preset_param_t { + /// The name of the parameter + const char *name; + /// The description of the parameter. + const char *description; + /// The initial value the parameter is set to. + float initial; + /// The minimum value that the parameter can be set to. + float minimum; + /// The maximum value that the parameter can be set to. + float maximum; + /// The step by which this parameter can be incremented or decremented. + float step; +} libra_preset_param_t; + +/// A list of preset parameters. +typedef struct libra_preset_parameter_list_t { + /// A pointer to the parameter + const struct libra_preset_param_t *parameters; + /// The number of parameters in the list + uint64_t length; + /// For internal use only. + /// Changing this causes immediate undefined behaviour on freeing this parameter list. + uint64_t _internal_alloc; +} libra_preset_parameter_list_t; + #if defined(LIBRA_RUNTIME_OPENGL) /// A GL function loader that librashader needs to be initialized with. typedef const void *(*libra_gl_loader_t)(const char*); @@ -262,10 +291,6 @@ typedef libra_error_t (*PFN_libra_preset_get_param)(libra_shader_preset_t *prese ///libra_preset_print typedef libra_error_t (*PFN_libra_preset_print)(libra_shader_preset_t *preset); -/// Function pointer definition for libra_preset_get_runtime_param_names -typedef libra_error_t (*PFN_libra_preset_get_runtime_param_names)(libra_shader_preset_t *preset, - const char **value); - /// Function pointer definition for libra_error_errno typedef LIBRA_ERRNO (*PFN_libra_error_errno)(libra_error_t error); @@ -307,6 +332,36 @@ typedef libra_error_t (*PFN_libra_gl_filter_chain_frame)(libra_gl_filter_chain_t const struct frame_gl_opt_t *opt); #endif +#if defined(LIBRA_RUNTIME_OPENGL) +/// Function pointer definition for +///libra_gl_filter_chain_set_param +typedef libra_error_t (*PFN_libra_gl_filter_chain_set_param)(libra_gl_filter_chain_t *chain, + const char *param_name, + float value); +#endif + +#if defined(LIBRA_RUNTIME_OPENGL) +/// Function pointer definition for +///libra_gl_filter_chain_get_param +typedef libra_error_t (*PFN_libra_gl_filter_chain_get_param)(libra_gl_filter_chain_t *chain, + const char *param_name, + float *out); +#endif + +#if defined(LIBRA_RUNTIME_OPENGL) +/// Function pointer definition for +///libra_gl_filter_chain_set_active_pass_count +typedef libra_error_t (*PFN_libra_gl_filter_chain_set_active_pass_count)(libra_gl_filter_chain_t *chain, + uint32_t value); +#endif + +#if defined(LIBRA_RUNTIME_OPENGL) +/// Function pointer definition for +///libra_gl_filter_chain_get_active_pass_count +typedef libra_error_t (*PFN_libra_gl_filter_chain_get_active_pass_count)(libra_gl_filter_chain_t *chain, + uint32_t *out); +#endif + #if defined(LIBRA_RUNTIME_OPENGL) /// Function pointer definition for ///libra_gl_filter_chain_free @@ -334,6 +389,36 @@ typedef libra_error_t (*PFN_libra_d3d11_filter_chain_frame)(libra_d3d11_filter_c const struct frame_vk_opt_t *opt); #endif +#if defined(LIBRA_RUNTIME_D3D11) +/// Function pointer definition for +///libra_d3d11_filter_chain_set_param +typedef libra_error_t (*PFN_libra_d3d11_filter_chain_set_param)(libra_d3d11_filter_chain_t *chain, + const char *param_name, + float value); +#endif + +#if defined(LIBRA_RUNTIME_D3D11) +/// Function pointer definition for +///libra_d3d11_filter_chain_get_param +typedef libra_error_t (*PFN_libra_d3d11_filter_chain_get_param)(libra_d3d11_filter_chain_t *chain, + const char *param_name, + float *out); +#endif + +#if defined(LIBRA_RUNTIME_D3D11) +/// Function pointer definition for +///libra_d3d11_filter_chain_set_active_pass_count +typedef libra_error_t (*PFN_libra_d3d11_filter_chain_set_active_pass_count)(libra_d3d11_filter_chain_t *chain, + uint32_t value); +#endif + +#if defined(LIBRA_RUNTIME_D3D11) +/// Function pointer definition for +///libra_d3d11_filter_chain_get_active_pass_count +typedef libra_error_t (*PFN_libra_d3d11_filter_chain_get_active_pass_count)(libra_d3d11_filter_chain_t *chain, + uint32_t *out); +#endif + #if defined(LIBRA_RUNTIME_D3D11) /// Function pointer definition for ///libra_d3d11_filter_chain_free @@ -362,6 +447,36 @@ typedef libra_error_t (*PFN_libra_vk_filter_chain_frame)(libra_vk_filter_chain_t const struct FrameOptionsVulkan *opt); #endif +#if defined(LIBRA_RUNTIME_VULKAN) +/// Function pointer definition for +///libra_vk_filter_chain_set_param +typedef libra_error_t (*PFN_libra_vk_filter_chain_set_param)(libra_vk_filter_chain_t *chain, + const char *param_name, + float value); +#endif + +#if defined(LIBRA_RUNTIME_VULKAN) +/// Function pointer definition for +///libra_vk_filter_chain_get_param +typedef libra_error_t (*PFN_libra_vk_filter_chain_get_param)(libra_vk_filter_chain_t *chain, + const char *param_name, + float *out); +#endif + +#if defined(LIBRA_RUNTIME_VULKAN) +/// Function pointer definition for +///libra_vk_filter_chain_set_active_pass_count +typedef libra_error_t (*PFN_libra_vk_filter_chain_set_active_pass_count)(libra_vk_filter_chain_t *chain, + uint32_t value); +#endif + +#if defined(LIBRA_RUNTIME_VULKAN) +/// Function pointer definition for +///libra_vk_filter_chain_get_active_pass_count +typedef libra_error_t (*PFN_libra_vk_filter_chain_get_active_pass_count)(libra_vk_filter_chain_t *chain, + uint32_t *out); +#endif + #if defined(LIBRA_RUNTIME_VULKAN) /// Function pointer definition for ///libra_vk_filter_chain_free @@ -453,11 +568,11 @@ 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 work in progress. Its use is discouraged. -/// Removal of this function is exempted from semantic versioning. -libra_error_t libra_preset_get_runtime_param_names(libra_shader_preset_t *preset, - const char **value); +/// ## Safety +/// - `preset` must be null or a valid and aligned pointer to a shader preset. +/// - `out` must be an aligned pointer to a `libra_preset_parameter_list_t`. +libra_error_t libra_preset_get_runtime_parameters(libra_shader_preset_t *preset, + struct libra_preset_parameter_list_t *out); #if defined(LIBRA_RUNTIME_OPENGL) /// Initialize the OpenGL Context for librashader. @@ -504,6 +619,48 @@ libra_error_t libra_gl_filter_chain_frame(libra_gl_filter_chain_t *chain, const struct frame_gl_opt_t *opt); #endif +#if defined(LIBRA_RUNTIME_OPENGL) +/// Sets a parameter for the filter chain. +/// +/// If the parameter does not exist, returns an error. +/// ## Safety +/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_gl_filter_chain_t`. +/// - `param_name` must be either null or a null terminated string. +libra_error_t libra_gl_filter_chain_set_param(libra_gl_filter_chain_t *chain, + const char *param_name, + float value); +#endif + +#if defined(LIBRA_RUNTIME_OPENGL) +/// Gets a parameter for the filter chain. +/// +/// If the parameter does not exist, returns an error. +/// ## Safety +/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_gl_filter_chain_t`. +/// - `param_name` must be either null or a null terminated string. +libra_error_t libra_gl_filter_chain_get_param(libra_gl_filter_chain_t *chain, + const char *param_name, + float *out); +#endif + +#if defined(LIBRA_RUNTIME_OPENGL) +/// Sets the number of active passes for this chain. +/// +/// ## 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_set_active_pass_count(libra_gl_filter_chain_t *chain, + uint32_t value); +#endif + +#if defined(LIBRA_RUNTIME_OPENGL) +/// Gets the number of active passes for this chain. +/// +/// ## 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_get_active_pass_count(libra_gl_filter_chain_t *chain, + uint32_t *out); +#endif + #if defined(LIBRA_RUNTIME_OPENGL) /// Free a GL filter chain. /// @@ -548,6 +705,48 @@ libra_error_t libra_d3d11_filter_chain_frame(libra_d3d11_filter_chain_t *chain, const struct frame_vk_opt_t *opt); #endif +#if defined(LIBRA_RUNTIME_D3D11) +/// Sets a parameter for the filter chain. +/// +/// If the parameter does not exist, returns an error. +/// ## Safety +/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_d3d11_filter_chain_t`. +/// - `param_name` must be either null or a null terminated string. +libra_error_t libra_d3d11_filter_chain_set_param(libra_d3d11_filter_chain_t *chain, + const char *param_name, + float value); +#endif + +#if defined(LIBRA_RUNTIME_D3D11) +/// Gets a parameter for the filter chain. +/// +/// If the parameter does not exist, returns an error. +/// ## Safety +/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_d3d11_filter_chain_t`. +/// - `param_name` must be either null or a null terminated string. +libra_error_t libra_d3d11_filter_chain_get_param(libra_d3d11_filter_chain_t *chain, + const char *param_name, + float *out); +#endif + +#if defined(LIBRA_RUNTIME_D3D11) +/// Sets the number of active passes for this chain. +/// +/// ## 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_set_active_pass_count(libra_d3d11_filter_chain_t *chain, + uint32_t value); +#endif + +#if defined(LIBRA_RUNTIME_D3D11) +/// Gets the number of active passes for this chain. +/// +/// ## 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_get_active_pass_count(libra_d3d11_filter_chain_t *chain, + uint32_t *out); +#endif + #if defined(LIBRA_RUNTIME_D3D11) /// Free a D3D11 filter chain. /// @@ -589,7 +788,7 @@ libra_error_t libra_vk_filter_chain_create(struct libra_device_vk_t vulkan, /// 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` +/// - `opt` may be null, or if it is not null, must be an aligned pointer to a valid `frame_vk_opt_t` /// struct. libra_error_t libra_vk_filter_chain_frame(libra_vk_filter_chain_t *chain, VkCommandBuffer command_buffer, @@ -602,11 +801,53 @@ libra_error_t libra_vk_filter_chain_frame(libra_vk_filter_chain_t *chain, #endif #if defined(LIBRA_RUNTIME_VULKAN) -/// Free a GL filter chain. +/// Sets a parameter for the filter chain. +/// +/// If the parameter does not exist, returns an error. +/// ## Safety +/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_vk_filter_chain_t`. +/// - `param_name` must be either null or a null terminated string. +libra_error_t libra_vk_filter_chain_set_param(libra_vk_filter_chain_t *chain, + const char *param_name, + float value); +#endif + +#if defined(LIBRA_RUNTIME_VULKAN) +/// Gets a parameter for the filter chain. +/// +/// If the parameter does not exist, returns an error. +/// ## Safety +/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_vk_filter_chain_t`. +/// - `param_name` must be either null or a null terminated string. +libra_error_t libra_vk_filter_chain_get_param(libra_vk_filter_chain_t *chain, + const char *param_name, + float *out); +#endif + +#if defined(LIBRA_RUNTIME_VULKAN) +/// Sets the number of active passes for this chain. +/// +/// ## Safety +/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_vk_filter_chain_t`. +libra_error_t libra_vk_filter_chain_set_active_pass_count(libra_vk_filter_chain_t *chain, + uint32_t value); +#endif + +#if defined(LIBRA_RUNTIME_VULKAN) +/// Gets the number of active passes for this chain. +/// +/// ## Safety +/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_vk_filter_chain_t`. +libra_error_t libra_vk_filter_chain_get_active_pass_count(libra_vk_filter_chain_t *chain, + uint32_t *out); +#endif + +#if defined(LIBRA_RUNTIME_VULKAN) +/// Free a Vulkan 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`. +/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_vk_filter_chain_t`. libra_error_t libra_vk_filter_chain_free(libra_vk_filter_chain_t *chain); #endif diff --git a/include/librashader_ld.h b/include/librashader_ld.h index 0124f8b..b5dd275 100644 --- a/include/librashader_ld.h +++ b/include/librashader_ld.h @@ -75,11 +75,6 @@ libra_error_t __librashader__noop_preset_print(libra_shader_preset_t *preset) { return NULL; } -libra_error_t __librashader__noop_preset_get_runtime_param_names( - libra_shader_preset_t *preset, const char **value) { - return NULL; -} - #if defined(LIBRA_RUNTIME_OPENGL) libra_error_t __librashader__noop_gl_init_context(libra_gl_loader_t loader) { return NULL; @@ -103,6 +98,26 @@ libra_error_t __librashader__noop_gl_filter_chain_free( libra_gl_filter_chain_t *chain) { return NULL; } + +libra_error_t __librashader__noop_gl_filter_chain_set_param( + libra_gl_filter_chain_t *chain, const char *param_name, float value) { + return NULL; +} + +libra_error_t __librashader__noop_gl_filter_chain_get_param( + libra_gl_filter_chain_t *chain, const char *param_name, float *out) { + return NULL; +} + +libra_error_t __librashader__noop_gl_filter_chain_set_active_pass_count( + libra_gl_filter_chain_t *chain, uint32_t value) { + return NULL; +} + +libra_error_t __librashader__noop_gl_filter_chain_get_active_pass_count( + libra_gl_filter_chain_t *chain, uint32_t *out) { + return NULL; +} #endif #if defined(LIBRA_RUNTIME_D3D11) @@ -125,6 +140,27 @@ libra_error_t __librashader__noop_d3d11_filter_chain_free( libra_d3d11_filter_chain_t *chain) { return NULL; } + +libra_error_t __librashader__noop_d3d11_filter_chain_set_param( + libra_d3d11_filter_chain_t *chain, const char *param_name, float value) { + return NULL; +} + +libra_error_t __librashader__noop_d3d11_filter_chain_get_param( + libra_d3d11_filter_chain_t *chain, const char *param_name, float *out) { + return NULL; +} + +libra_error_t __librashader__noop_d3d11_filter_chain_set_active_pass_count( + libra_d3d11_filter_chain_t *chain, uint32_t value) { + return NULL; +} + +libra_error_t __librashader__noop_d3d11_filter_chain_get_active_pass_count( + libra_d3d11_filter_chain_t *chain, uint32_t *out) { + return NULL; +} + #endif #if defined(LIBRA_RUNTIME_VULKAN) @@ -146,6 +182,27 @@ libra_error_t __librashader__noop_vk_filter_chain_free( libra_vk_filter_chain_t *chain) { return NULL; } + +libra_error_t __librashader__noop_vk_filter_chain_set_param( + libra_vk_filter_chain_t *chain, const char *param_name, float value) { + return NULL; +} + +libra_error_t __librashader__noop_vk_filter_chain_get_param( + libra_vk_filter_chain_t *chain, const char *param_name, float *out) { + return NULL; +} + +libra_error_t __librashader__noop_vk_filter_chain_set_active_pass_count( + libra_vk_filter_chain_t *chain, uint32_t value) { + return NULL; +} + +libra_error_t __librashader__noop_vk_filter_chain_get_active_pass_count( + libra_vk_filter_chain_t *chain, uint32_t *out) { + return NULL; +} + #endif typedef struct libra_instance_t { @@ -154,7 +211,6 @@ typedef struct libra_instance_t { PFN_libra_preset_set_param preset_set_param; PFN_libra_preset_get_param preset_get_param; PFN_libra_preset_print preset_print; - PFN_libra_preset_get_runtime_param_names preset_get_runtime_param_names; PFN_libra_error_errno error_errno; PFN_libra_error_print error_print; @@ -167,30 +223,46 @@ typedef struct libra_instance_t { PFN_libra_gl_filter_chain_create gl_filter_chain_create; PFN_libra_gl_filter_chain_frame gl_filter_chain_frame; PFN_libra_gl_filter_chain_free gl_filter_chain_free; + PFN_libra_gl_filter_chain_get_active_pass_count + gl_filter_chain_get_active_pass_count; + PFN_libra_gl_filter_chain_set_active_pass_count + gl_filter_chain_set_active_pass_count; + PFN_libra_gl_filter_chain_get_param gl_filter_chain_get_param; + PFN_libra_gl_filter_chain_set_param gl_filter_chain_set_param; #endif #if defined(LIBRA_RUNTIME_VULKAN) PFN_libra_d3d11_filter_chain_create d3d11_filter_chain_create; PFN_libra_d3d11_filter_chain_frame d3d11_filter_chain_frame; PFN_libra_d3d11_filter_chain_free d3d11_filter_chain_free; + PFN_libra_d3d11_filter_chain_get_active_pass_count + d3d11_filter_chain_get_active_pass_count; + PFN_libra_d3d11_filter_chain_set_active_pass_count + d3d11_filter_chain_set_active_pass_count; + PFN_libra_d3d11_filter_chain_get_param d3d11_filter_chain_get_param; + PFN_libra_d3d11_filter_chain_set_param d3d11_filter_chain_set_param; #endif #if defined(LIBRA_RUNTIME_VULKAN) PFN_libra_vk_filter_chain_create vk_filter_chain_create; PFN_libra_vk_filter_chain_frame vk_filter_chain_frame; PFN_libra_vk_filter_chain_free vk_filter_chain_free; + PFN_libra_vk_filter_chain_get_active_pass_count + vk_filter_chain_get_active_pass_count; + PFN_libra_vk_filter_chain_set_active_pass_count + vk_filter_chain_set_active_pass_count; + PFN_libra_vk_filter_chain_get_param vk_filter_chain_get_param; + PFN_libra_vk_filter_chain_set_param vk_filter_chain_set_param; #endif } libra_instance_t; libra_instance_t __librashader_make_null_instance() { - return libra_instance_t{ + return libra_instance_t { .preset_create = __librashader__noop_preset_create, .preset_free = __librashader__noop_preset_free, .preset_set_param = __librashader__noop_preset_set_param, .preset_get_param = __librashader__noop_preset_get_param, .preset_print = __librashader__noop_preset_print, - .preset_get_runtime_param_names = - __librashader__noop_preset_get_runtime_param_names, .error_errno = __librashader__noop_error_errno, .error_print = __librashader__noop_error_print, @@ -203,6 +275,14 @@ libra_instance_t __librashader_make_null_instance() { .gl_filter_chain_create = __librashader__noop_gl_filter_chain_create, .gl_filter_chain_frame = __librashader__noop_gl_filter_chain_frame, .gl_filter_chain_free = __librashader__noop_gl_filter_chain_free, + .gl_filter_chain_get_active_pass_count = + __librashader__noop_gl_filter_chain_get_active_pass_count, + .gl_filter_chain_set_active_pass_count = + __librashader__noop_gl_filter_chain_set_active_pass_count, + .gl_filter_chain_get_param = + __librashader__noop_gl_filter_chain_get_param, + .gl_filter_chain_set_param = + __librashader__noop_gl_filter_chain_set_param, #endif #if defined(LIBRA_RUNTIME_D3D11) @@ -211,12 +291,28 @@ libra_instance_t __librashader_make_null_instance() { .d3d11_filter_chain_frame = __librashader__noop_d3d11_filter_chain_frame, .d3d11_filter_chain_free = __librashader__noop_d3d11_filter_chain_free, + .d3d11_filter_chain_get_active_pass_count = + __librashader__noop_d3d11_filter_chain_get_active_pass_count, + .d3d11_filter_chain_set_active_pass_count = + __librashader__noop_d3d11_filter_chain_set_active_pass_count, + .d3d11_filter_chain_get_param = + __librashader__noop_d3d11_filter_chain_get_param, + .d3d11_filter_chain_set_param = + __librashader__noop_d3d11_filter_chain_set_param, #endif #if defined(LIBRA_RUNTIME_VULKAN) .vk_filter_chain_create = __librashader__noop_vk_filter_chain_create, .vk_filter_chain_frame = __librashader__noop_vk_filter_chain_frame, .vk_filter_chain_free = __librashader__noop_vk_filter_chain_free, + .vk_filter_chain_get_active_pass_count = + __librashader__noop_vk_filter_chain_get_active_pass_count, + .vk_filter_chain_set_active_pass_count = + __librashader__noop_vk_filter_chain_set_active_pass_count, + .vk_filter_chain_get_param = + __librashader__noop_vk_filter_chain_get_param, + .vk_filter_chain_set_param = + __librashader__noop_vk_filter_chain_set_param, #endif }; } @@ -236,7 +332,7 @@ libra_instance_t __librashader_make_null_instance() { libra_instance_t librashader_load_instance(); #if defined(_WIN32) -#define _LIBRASHADER_ASSIGN_FARPROC(HMOD, INSTANCE, NAME) \ +#define _LIBRASHADER_ASSIGN_FARPROC(HMOD, INSTANCE, NAME) \ { \ FARPROC address = GetProcAddress(HMOD, "libra_" #NAME); \ if (address != NULL) { \ @@ -256,7 +352,6 @@ libra_instance_t librashader_load_instance() { _LIBRASHADER_ASSIGN_FARPROC(librashader, instance, preset_set_param); _LIBRASHADER_ASSIGN_FARPROC(librashader, instance, preset_get_param); _LIBRASHADER_ASSIGN_FARPROC(librashader, instance, preset_print); - _LIBRASHADER_ASSIGN_FARPROC(librashader, instance, preset_get_runtime_param_names); _LIBRASHADER_ASSIGN_FARPROC(librashader, instance, error_errno); _LIBRASHADER_ASSIGN_FARPROC(librashader, instance, error_print); @@ -269,33 +364,60 @@ libra_instance_t librashader_load_instance() { _LIBRASHADER_ASSIGN_FARPROC(librashader, instance, gl_filter_chain_create); _LIBRASHADER_ASSIGN_FARPROC(librashader, instance, gl_filter_chain_frame); _LIBRASHADER_ASSIGN_FARPROC(librashader, instance, gl_filter_chain_free); + _LIBRASHADER_ASSIGN_FARPROC(librashader, instance, + gl_filter_chain_get_param); + _LIBRASHADER_ASSIGN_FARPROC(librashader, instance, + gl_filter_chain_set_param); + _LIBRASHADER_ASSIGN_FARPROC(librashader, instance, + gl_filter_chain_get_active_pass_count); + _LIBRASHADER_ASSIGN_FARPROC(librashader, instance, + gl_filter_chain_set_active_pass_count); + #endif #if defined(LIBRA_RUNTIME_D3D11) - _LIBRASHADER_ASSIGN_FARPROC(librashader, instance, d3d11_filter_chain_create); - _LIBRASHADER_ASSIGN_FARPROC(librashader, instance, d3d11_filter_chain_frame); + _LIBRASHADER_ASSIGN_FARPROC(librashader, instance, + d3d11_filter_chain_create); + _LIBRASHADER_ASSIGN_FARPROC(librashader, instance, + d3d11_filter_chain_frame); _LIBRASHADER_ASSIGN_FARPROC(librashader, instance, d3d11_filter_chain_free); + _LIBRASHADER_ASSIGN_FARPROC(librashader, instance, + d3d11_filter_chain_get_param); + _LIBRASHADER_ASSIGN_FARPROC(librashader, instance, + d3d11_filter_chain_set_param); + _LIBRASHADER_ASSIGN_FARPROC(librashader, instance, + d3d11_filter_chain_get_active_pass_count); + _LIBRASHADER_ASSIGN_FARPROC(librashader, instance, + d3d11_filter_chain_set_active_pass_count); #endif #if defined(LIBRA_RUNTIME_VULKAN) _LIBRASHADER_ASSIGN_FARPROC(librashader, instance, vk_filter_chain_create); _LIBRASHADER_ASSIGN_FARPROC(librashader, instance, vk_filter_chain_frame); _LIBRASHADER_ASSIGN_FARPROC(librashader, instance, vk_filter_chain_free); + _LIBRASHADER_ASSIGN_FARPROC(librashader, instance, + vk_filter_chain_get_param); + _LIBRASHADER_ASSIGN_FARPROC(librashader, instance, + vk_filter_chain_set_param); + _LIBRASHADER_ASSIGN_FARPROC(librashader, instance, + vk_filter_chain_get_active_pass_count); + _LIBRASHADER_ASSIGN_FARPROC(librashader, instance, + vk_filter_chain_set_active_pass_count); #endif return instance; } #elif defined(__linux__) -#define _LIBRASHADER_ASSIGN_DLSYM(HMOD, INSTANCE, NAME) \ - { \ - void* address = dlsym(HMOD, "libra_" #NAME); \ - if (address != NULL) { \ - (INSTANCE).NAME = (PFN_libra_##NAME)address; \ - } \ +#define _LIBRASHADER_ASSIGN_DLSYM(HMOD, INSTANCE, NAME) \ + { \ + void *address = dlsym(HMOD, "libra_" #NAME); \ + if (address != NULL) { \ + (INSTANCE).NAME = (PFN_libra_##NAME)address; \ + } \ } libra_instance_t librashader_load_instance() { - void* librashader = dlopen(L"librashader.so", RTLD_LAZY); + void *librashader = dlopen(L"librashader.so", RTLD_LAZY); libra_instance_t instance = __librashader_make_null_instance(); if (librashader == NULL) { return instance; @@ -306,7 +428,6 @@ libra_instance_t librashader_load_instance() { _LIBRASHADER_ASSIGN_DLSYM(librashader, instance, preset_set_param); _LIBRASHADER_ASSIGN_DLSYM(librashader, instance, preset_get_param); _LIBRASHADER_ASSIGN_DLSYM(librashader, instance, preset_print); - _LIBRASHADER_ASSIGN_DLSYM(librashader, instance, preset_get_runtime_param_names); _LIBRASHADER_ASSIGN_DLSYM(librashader, instance, error_errno); _LIBRASHADER_ASSIGN_DLSYM(librashader, instance, error_print); @@ -319,6 +440,12 @@ libra_instance_t librashader_load_instance() { _LIBRASHADER_ASSIGN_DLSYM(librashader, instance, gl_filter_chain_create); _LIBRASHADER_ASSIGN_DLSYM(librashader, instance, gl_filter_chain_frame); _LIBRASHADER_ASSIGN_DLSYM(librashader, instance, gl_filter_chain_free); + _LIBRASHADER_ASSIGN_DLSYM(librashader, instance, gl_filter_chain_get_param); + _LIBRASHADER_ASSIGN_DLSYM(librashader, instance, gl_filter_chain_set_param); + _LIBRASHADER_ASSIGN_DLSYM(librashader, instance, + gl_filter_chain_get_active_pass_count); + _LIBRASHADER_ASSIGN_DLSYM(librashader, instance, + gl_filter_chain_set_active_pass_count); #endif // Not sure why you would want this @@ -326,12 +453,27 @@ libra_instance_t librashader_load_instance() { _LIBRASHADER_ASSIGN_DLSYM(librashader, instance, d3d11_filter_chain_create); _LIBRASHADER_ASSIGN_DLSYM(librashader, instance, d3d11_filter_chain_frame); _LIBRASHADER_ASSIGN_DLSYM(librashader, instance, d3d11_filter_chain_free); + _LIBRASHADER_ASSIGN_DLSYM(librashader, instance, + d3d11_filter_chain_get_param); + _LIBRASHADER_ASSIGN_DLSYM(librashader, instance, + d3d11_filter_chain_set_param); + _LIBRASHADER_ASSIGN_DLSYM(librashader, instance, + d3d11_filter_chain_get_active_pass_count); + _LIBRASHADER_ASSIGN_DLSYM(librashader, instance, + d3d11_filter_chain_set_active_pass_count); + #endif #if defined(LIBRA_RUNTIME_VULKAN) _LIBRASHADER_ASSIGN_DLSYM(librashader, instance, vk_filter_chain_create); _LIBRASHADER_ASSIGN_DLSYM(librashader, instance, vk_filter_chain_frame); _LIBRASHADER_ASSIGN_DLSYM(librashader, instance, vk_filter_chain_free); + _LIBRASHADER_ASSIGN_DLSYM(librashader, instance, vk_filter_chain_get_param); + _LIBRASHADER_ASSIGN_DLSYM(librashader, instance, vk_filter_chain_set_param); + _LIBRASHADER_ASSIGN_DLSYM(librashader, instance, + vk_filter_chain_get_active_pass_count); + _LIBRASHADER_ASSIGN_DLSYM(librashader, instance, + vk_filter_chain_set_active_pass_count); #endif return instance; } diff --git a/librashader-capi/src/error.rs b/librashader-capi/src/error.rs index a3ebe8e..75e51a7 100644 --- a/librashader-capi/src/error.rs +++ b/librashader-capi/src/error.rs @@ -3,7 +3,6 @@ use std::any::Any; use std::ffi::{c_char, CString}; use std::mem::MaybeUninit; use std::ptr::NonNull; -use std::str::Utf8Error; use thiserror::Error; /// The error type for librashader. diff --git a/librashader-capi/src/presets.rs b/librashader-capi/src/presets.rs index 5ebc4dd..2bf58d3 100644 --- a/librashader-capi/src/presets.rs +++ b/librashader-capi/src/presets.rs @@ -1,12 +1,41 @@ //! The librashader preset C API (`libra_preset_*`). -use crate::ctypes::{libra_error_t, libra_shader_preset_t}; +use crate::ctypes::{libra_shader_preset_t}; use crate::error::{assert_non_null, assert_some_ptr, LibrashaderError}; -use crate::ffi::{extern_fn, ffi_body}; +use crate::ffi::extern_fn; use librashader::presets::ShaderPreset; use std::ffi::{c_char, CStr, CString}; use std::mem::MaybeUninit; use std::ptr::NonNull; +/// A list of preset parameters. +#[repr(C)] +pub struct libra_preset_parameter_list_t { + /// A pointer to the parameter + pub parameters: *const libra_preset_param_t, + /// The number of parameters in the list + pub length: u64, + /// For internal use only. + /// Changing this causes immediate undefined behaviour on freeing this parameter list. + pub _internal_alloc: u64, +} + +/// A preset parameter. +#[repr(C)] +pub struct libra_preset_param_t { + /// The name of the parameter + pub name: *const c_char, + /// The description of the parameter. + pub description: *const c_char, + /// The initial value the parameter is set to. + pub initial: f32, + /// The minimum value that the parameter can be set to. + pub minimum: f32, + /// The maximum value that the parameter can be set to. + pub maximum: f32, + /// The step by which this parameter can be incremented or decremented. + pub step: f32, +} + extern_fn! { /// Load a preset. /// @@ -92,7 +121,6 @@ extern_fn! { let name = unsafe { CStr::from_ptr(name) }; let name = name.to_str()?; assert_some_ptr!(preset); - assert_non_null!(value); if let Some(param) = preset.parameters.iter().find(|c| c.name == name) { @@ -112,38 +140,68 @@ extern_fn! { } } -// can't use extern_fn! for this because of the mut. -/// Function pointer definition for libra_preset_get_runtime_param_names -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>, - size: *mut MaybeUninit<*const u64>, -) -> libra_error_t; - -/// Get a list of runtime parameter names. -/// -/// The caller must provide a sufficiently sized buffer. -/// ## Safety -/// - `preset` must be null or a valid and aligned pointer to a shader preset. -#[no_mangle] -pub unsafe extern "C" fn libra_preset_get_runtime_param_names( - preset: *mut libra_shader_preset_t, - mut value: MaybeUninit<*mut *const c_char>, - mut size: *mut MaybeUninit, -) -> libra_error_t { - ffi_body!(|preset| { +extern_fn! { + /// Get a list of runtime parameter names. + /// + /// ## Safety + /// - `preset` must be null or a valid and aligned pointer to a shader preset. + /// - `out` must be an aligned pointer to a `libra_preset_parameter_list_t`. + fn libra_preset_get_runtime_parameters( + preset: *mut libra_shader_preset_t, + out: *mut MaybeUninit + ) |preset| { assert_some_ptr!(preset); + assert_non_null!(out); let iter = librashader::presets::get_parameter_meta(preset)?; - let mut c_strings = Vec::new(); + let mut values = Vec::new(); for param in iter { - let c_string = CString::new(param.id) - .map_err(|err| LibrashaderError::UnknownError(Box::new(err)))?; - c_strings.push(c_string.into_raw().cast_const()); + let name = CString::new(param.id) + .map_err(|err| LibrashaderError::UnknownError(Box::new(err)))?; + let description = CString::new(param.description) + .map_err(|err| LibrashaderError::UnknownError(Box::new(err)))?; + values.push(libra_preset_param_t { + name: name.into_raw().cast_const(), + description: description.into_raw().cast_const(), + initial: param.initial, + minimum: param.minimum, + maximum: param.maximum, + step: param.step + }) } - - let (parts, _len, _cap) = c_strings.into_raw_parts(); - - value.write(parts); - }) + let (parts, len, cap) = values.into_raw_parts(); + unsafe { + out.write(MaybeUninit::new(libra_preset_parameter_list_t { + parameters: parts, + length: len as u64, + _internal_alloc: cap as u64, + })); + } + } } + +// /// Get a list of runtime parameter names. +// /// +// /// The caller must provide a sufficiently sized buffer. +// /// If `value` is null, then size will be written to with the size of the buffer required +// /// to get the parameter names. +// /// ## Safety +// /// - `preset` must be null or a valid and aligned pointer to a shader preset. +// #[no_mangle] +// pub unsafe extern "C" fn libra_preset_free_runtime_param_names( +// value: MaybeUninit<*mut *const c_char>, +// ) -> libra_error_t { +// ffi_body!(|value| { +// let iter = librashader::presets::get_parameter_meta(preset)?; +// let mut c_strings = Vec::new(); +// for param in iter { +// let c_string = CString::new(param.id) +// .map_err(|err| LibrashaderError::UnknownError(Box::new(err)))?; +// c_strings.push(c_string.into_raw().cast_const()); +// } +// +// let (parts, _len, _cap) = c_strings.into_raw_parts(); +// +// value.write(parts); +// }) +// } diff --git a/librashader-capi/src/runtime/d3d11/filter_chain.rs b/librashader-capi/src/runtime/d3d11/filter_chain.rs index 50b9693..eaf27d8 100644 --- a/librashader-capi/src/runtime/d3d11/filter_chain.rs +++ b/librashader-capi/src/runtime/d3d11/filter_chain.rs @@ -198,9 +198,7 @@ extern_fn! { value: u32 ) mut |chain| { assert_some_ptr!(mut chain); - unsafe { - chain.set_enabled_pass_count(value as usize); - } + chain.set_enabled_pass_count(value as usize); } } diff --git a/librashader-capi/src/runtime/gl/filter_chain.rs b/librashader-capi/src/runtime/gl/filter_chain.rs index 3a9a382..117a201 100644 --- a/librashader-capi/src/runtime/gl/filter_chain.rs +++ b/librashader-capi/src/runtime/gl/filter_chain.rs @@ -213,9 +213,7 @@ extern_fn! { value: u32 ) mut |chain| { assert_some_ptr!(mut chain); - unsafe { - chain.set_enabled_pass_count(value as usize); - } + chain.set_enabled_pass_count(value as usize); } } @@ -229,8 +227,8 @@ extern_fn! { out: *mut MaybeUninit ) mut |chain| { assert_some_ptr!(mut chain); + let value = chain.get_enabled_pass_count(); unsafe { - let value = chain.get_enabled_pass_count(); out.write(MaybeUninit::new(value as u32)) } } diff --git a/librashader-capi/src/runtime/vk/filter_chain.rs b/librashader-capi/src/runtime/vk/filter_chain.rs index 5f70446..721f1f2 100644 --- a/librashader-capi/src/runtime/vk/filter_chain.rs +++ b/librashader-capi/src/runtime/vk/filter_chain.rs @@ -228,9 +228,7 @@ extern_fn! { value: u32 ) mut |chain| { assert_some_ptr!(mut chain); - unsafe { - chain.set_enabled_pass_count(value as usize); - } + chain.set_enabled_pass_count(value as usize); } } @@ -244,8 +242,8 @@ extern_fn! { out: *mut MaybeUninit ) mut |chain| { assert_some_ptr!(mut chain); + let value = chain.get_enabled_pass_count(); unsafe { - let value = chain.get_enabled_pass_count(); out.write(MaybeUninit::new(value as u32)) } }