From 054c365ee11f48085ab41a5d7f4abdc3c62d187a Mon Sep 17 00:00:00 2001 From: chyyran <ronny@ronnychan.ca> Date: Sat, 14 Jan 2023 01:53:39 -0500 Subject: [PATCH] ld: define out what isn't needed --- README.md | 4 +--- include/README.md | 13 +++++++++++ include/librashader_ld.h | 47 ++++++++++++++++++++++++++++++++++++++-- 3 files changed, 59 insertions(+), 5 deletions(-) create mode 100644 include/README.md diff --git a/README.md b/README.md index 31d4ba8..7eef124 100644 --- a/README.md +++ b/README.md @@ -27,13 +27,11 @@ of DirectX and OpenGL, as well as Metal, are not supported (but pull-requests ar ✔ = Render API is supported — 🚧 = Support is in progress — ❌ Render API is not supported ## Usage -🚧 *`librashader_ld` is WIP* 🚧 - librashader provides both a Rust API under the `librashader` crate, and a C API. Both APIs are first-class, fully supported. The librashader C API is best used by linking statically with `librashader_ld`, which implements a loader that dynamically loads the librashader (`librashader.so` or `librashader.dll`) implementation in the search path. You may also link against -`librashader_capi` directly with [`librashader.h`](https://github.com/SnowflakePowered/librashader/blob/master/include/librashader.h). +`librashader_capi` directly at compile time with [`librashader.h`](https://github.com/SnowflakePowered/librashader/blob/master/include/librashader.h). The C API currently does not expose the [shader reflection API](https://docs.rs/librashader/latest/librashader/reflect/index.html). Work is in progress to expose this to C. In the meanwhile, if you wish to implement a custom runtime for librashader, it will have to be done diff --git a/include/README.md b/include/README.md new file mode 100644 index 0000000..56f2f0f --- /dev/null +++ b/include/README.md @@ -0,0 +1,13 @@ +# librashader C headers + +The librashader C headers are unlike the implementations, explicitly licensed under the MIT license. + +They are provided for easy integration of librashader in a multi-target C or C++ project that may not have +the necessary hardware or APIs available required for all supported runtimes. + +`librashader.h` can be depended upon to link with `librashader.dll` or `librashader.so` if you wish to link +with librashader. + +An easier alternative is to use the `librashader_ld.h` header library to load function pointers +from any `librashader.dll` or `librashader.so` implementation in the search path. You should customize this +header file to remove support for any runtimes you do not need. \ No newline at end of file diff --git a/include/librashader_ld.h b/include/librashader_ld.h index 926113e..6c71207 100644 --- a/include/librashader_ld.h +++ b/include/librashader_ld.h @@ -35,6 +35,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #elif defined(__linux__) #include <dlfcn.h> #endif + #include "librashader.h" LIBRA_ERRNO __librashader__noop_error_errno(libra_error_t error) { @@ -79,6 +80,7 @@ libra_error_t __librashader__noop_preset_get_runtime_param_names( return NULL; } +#if defined(LIBRA_RUNTIME_OPENGL) libra_error_t __librashader__noop_gl_init_context(libra_gl_loader_t loader) { return NULL; } @@ -101,7 +103,9 @@ libra_error_t __librashader__noop_gl_filter_chain_free( libra_gl_filter_chain_t *chain) { return NULL; } +#endif +#if defined(LIBRA_RUNTIME_D3D11) libra_error_t __librashader__noop_d3d11_filter_chain_create( libra_shader_preset_t *preset, const struct filter_chain_d3d11_opt_t *options, const ID3D11Device *device, @@ -121,7 +125,9 @@ libra_error_t __librashader__noop_d3d11_filter_chain_free( libra_d3d11_filter_chain_t *chain) { return NULL; } +#endif +#if defined(LIBRA_RUNTIME_VULKAN) libra_error_t __librashader__noop_vk_filter_chain_create( struct libra_device_vk_t vulkan, libra_shader_preset_t *preset, const struct filter_chain_vk_opt_t *options, libra_vk_filter_chain_t *out) { @@ -140,6 +146,7 @@ libra_error_t __librashader__noop_vk_filter_chain_free( libra_vk_filter_chain_t *chain) { return NULL; } +#endif typedef struct libra_instance_t { PFN_libra_preset_create preset_create; @@ -155,18 +162,24 @@ typedef struct libra_instance_t { PFN_libra_error_write error_write; PFN_libra_error_free_string error_free_string; +#if defined(LIBRA_RUNTIME_OPENGL) PFN_libra_gl_init_context gl_init_context; 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; +#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; +#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; +#endif } libra_instance_t; libra_instance_t __librashader_make_null_instance() { @@ -185,24 +198,42 @@ libra_instance_t __librashader_make_null_instance() { .error_write = __librashader__noop_error_write, .error_free_string = __librashader__noop_error_free_string, +#if defined(LIBRA_RUNTIME_OPENGL) .gl_init_context = __librashader__noop_gl_init_context, .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, +#endif +#if defined(LIBRA_RUNTIME_D3D11) .d3d11_filter_chain_create = __librashader__noop_d3d11_filter_chain_create, .d3d11_filter_chain_frame = __librashader__noop_d3d11_filter_chain_frame, .d3d11_filter_chain_free = __librashader__noop_d3d11_filter_chain_free, +#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, +#endif }; } - +/// Load an instance of librashader in the OS-dependent search path of the +/// current directory. +/// +/// `librashader_load_instance` loads from `librashader.dll` on Windows, +/// or `librashader.so` on Linux. +/// +/// If no librashader implementation is found, the returned `libra_instance_t` +/// will have all function pointers set to no-op functions. +/// +/// If any symbol fails to load, the function will be set to a no-op function. +/// +/// \return An `libra_instance_t` struct with loaded function pointers. +libra_instance_t librashader_load_instance(); #if defined(_WIN32) #define _LIBRASHADER_ASSIGN_FARPROC(HMOD, INSTANCE, NAME) \ @@ -233,18 +264,24 @@ libra_instance_t librashader_load_instance() { _LIBRASHADER_ASSIGN_FARPROC(librashader, instance, error_write); _LIBRASHADER_ASSIGN_FARPROC(librashader, instance, error_free_string); +#if defined(LIBRA_RUNTIME_OPENGL) _LIBRASHADER_ASSIGN_FARPROC(librashader, instance, gl_init_context); _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); +#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_free); +#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); +#endif return instance; } @@ -277,19 +314,25 @@ libra_instance_t librashader_load_instance() { _LIBRASHADER_ASSIGN_DLSYM(librashader, instance, error_write); _LIBRASHADER_ASSIGN_DLSYM(librashader, instance, error_free_string); +#if defined(LIBRA_RUNTIME_OPENGL) _LIBRASHADER_ASSIGN_DLSYM(librashader, instance, gl_init_context); _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); +#endif + // Not sure why you would want this +#if defined(LIBRA_RUNTIME_D3D11) _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); +#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); - +#endif return instance; } #else