capi: publish d3d12

This commit is contained in:
chyyran 2023-02-06 02:17:30 -05:00
parent 9a898f2cba
commit 4dcbdadb4f
13 changed files with 945 additions and 320 deletions

View file

@ -37,8 +37,13 @@ The librashader C API is best used by linking statically with `librashader_ld`,
loads the librashader (`librashader.so` or `librashader.dll`) implementation in the search path.
### Building
Some downstream dependencies require some Python dependencies to build.
For Rust projects, simply add the crate to your `Cargo.toml`. Python may also be required to build some dependent libraries.
```
pip install meson ninja mako
```
For Rust projects, simply add the crate to your `Cargo.toml`.
```
cargo add librashader
@ -106,7 +111,7 @@ Please report an issue if you run into a shader that works in RetroArch, but not
* All caveats from the OpenGL 3.3+ section should be considered.
* Should work on OpenGL 4.5 but this is not guaranteed. The OpenGL 4.6 runtime may eventually switch to using `ARB_spirv_extensions` for loading shaders, and this will not be marked as a breaking change.
* The OpenGL 4.6 runtime uses Direct State Access to minimize changes to the OpenGL state. For GPUs released within the last 5 years, this may improve performance.
* Vulkan 1.3+
* Vulkan
* The Vulkan runtime uses [`VK_KHR_dynamic_rendering`](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_dynamic_rendering.html) by default.
This extension must be enabled at device creation. Explicit render passes can be used by configuring filter chain options, but may have reduced performance
compared to dynamic rendering.

View file

@ -50,6 +50,14 @@ typedef void* VkPhysicalDevice;
typedef void* VkInstance;
typedef void* VkCommandBuffer;
#endif
#if defined(_WIN32) && defined(LIBRA_RUNTIME_D3D12)
#include <d3d12.h>
#else
typedef void ID3D12GraphicsCommandList;
typedef void ID3D12Device;
typedef void ID3D12Resource;
typedef void D3D12_CPU_DESCRIPTOR_HANDLE;
#endif
/// Error codes for librashader error types.
@ -74,6 +82,9 @@ typedef int32_t LIBRA_ERRNO;
/// A Direct3D 11 filter chain.
typedef struct _filter_chain_d3d11 _filter_chain_d3d11;
/// A Direct3D 12 filter chain.
typedef struct _filter_chain_d3d12 _filter_chain_d3d12;
/// An OpenGL filter chain.
typedef struct _filter_chain_gl _filter_chain_gl;
@ -184,47 +195,11 @@ typedef struct libra_draw_framebuffer_gl_t {
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.
/// The direction of rendering.
/// -1 indicates that the frames are played in reverse order.
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;
/// Whether or not to explicitly disable mipmap
/// generation regardless of shader preset settings.
bool force_no_mipmaps;
} filter_chain_d3d11_opt_t;
#if defined(LIBRA_RUNTIME_D3D11)
/// A handle to a Direct3D11 filter chain.
typedef struct _filter_chain_d3d11 *libra_d3d11_filter_chain_t;
#endif
#if defined(LIBRA_RUNTIME_D3D11)
/// Direct3D 11 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
/// 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;
#if defined(LIBRA_RUNTIME_VULKAN)
/// Handles required to instantiate vulkan
typedef struct libra_device_vk_t {
@ -276,10 +251,89 @@ typedef struct libra_image_vk_t {
typedef struct frame_vk_opt_t {
/// Whether or not to clear the history buffers.
bool clear_history;
/// The direction of the frame. 1 should be vertical.
/// The direction of rendering.
/// -1 indicates that the frames are played in reverse order.
int32_t frame_direction;
} frame_vk_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;
/// Whether or not to explicitly disable mipmap
/// generation regardless of shader preset settings.
bool force_no_mipmaps;
} filter_chain_d3d11_opt_t;
#if defined(LIBRA_RUNTIME_D3D11)
/// A handle to a Direct3D 11 filter chain.
typedef struct _filter_chain_d3d11 *libra_d3d11_filter_chain_t;
#endif
#if defined(LIBRA_RUNTIME_D3D11)
/// Direct3D 11 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
/// 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 rendering.
/// -1 indicates that the frames are played in reverse order.
int32_t frame_direction;
} frame_d3d11_opt_t;
/// Options for Direct3D11 filter chain creation.
typedef struct filter_chain_d3d12_opt_t {
/// Force the HLSL shader pipeline. This may reduce shader compatibility.
bool force_hlsl_pipeline;
/// Whether or not to explicitly disable mipmap
/// generation for intermediate passes regardless
/// of shader preset settings.
bool force_no_mipmaps;
} filter_chain_d3d12_opt_t;
#if defined(LIBRA_RUNTIME_D3D12)
/// A handle to a Direct3D 12 filter chain.
typedef struct _filter_chain_d3d12 *libra_d3d12_filter_chain_t;
#endif
#if defined(LIBRA_RUNTIME_D3D12)
/// Direct3D 11 parameters for the source image.
typedef struct libra_source_image_d3d12_t {
/// The resource containing the image.
const ID3D12Resource * resource;
/// A CPU descriptor handle to a shader resource view of the image.
D3D12_CPU_DESCRIPTOR_HANDLE descriptor;
/// The format of the image.
DXGI_FORMAT format;
/// The width of the source image.
uint32_t width;
/// The height of the source image.
uint32_t height;
} libra_source_image_d3d12_t;
#endif
/// Options for each Direct3D11 shader frame.
typedef struct frame_d3d12_opt_t {
/// Whether or not to clear the history buffers.
bool clear_history;
/// The direction of rendering.
/// -1 indicates that the frames are played in reverse order.
int32_t frame_direction;
} frame_d3d12_opt_t;
/// Function pointer definition for
///libra_preset_create
typedef libra_error_t (*PFN_libra_preset_create)(const char *filename, libra_shader_preset_t *out);
@ -390,6 +444,64 @@ typedef libra_error_t (*PFN_libra_gl_filter_chain_get_active_pass_count)(libra_g
typedef libra_error_t (*PFN_libra_gl_filter_chain_free)(libra_gl_filter_chain_t *chain);
#endif
#if defined(LIBRA_RUNTIME_VULKAN)
/// Function pointer definition for
///libra_vk_filter_chain_create
typedef libra_error_t (*PFN_libra_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);
#endif
#if defined(LIBRA_RUNTIME_VULKAN)
/// Function pointer definition for
///libra_vk_filter_chain_frame
typedef libra_error_t (*PFN_libra_vk_filter_chain_frame)(libra_vk_filter_chain_t *chain,
VkCommandBuffer command_buffer,
size_t frame_count,
struct libra_image_vk_t image,
struct libra_viewport_t viewport,
struct libra_image_vk_t out,
const float *mvp,
const struct frame_vk_opt_t *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
typedef libra_error_t (*PFN_libra_vk_filter_chain_free)(libra_vk_filter_chain_t *chain);
#endif
#if defined(LIBRA_RUNTIME_D3D11)
/// Function pointer definition for
///libra_d3d11_filter_chain_create
@ -447,62 +559,62 @@ typedef libra_error_t (*PFN_libra_d3d11_filter_chain_get_active_pass_count)(libr
typedef libra_error_t (*PFN_libra_d3d11_filter_chain_free)(libra_d3d11_filter_chain_t *chain);
#endif
#if defined(LIBRA_RUNTIME_VULKAN)
#if defined(LIBRA_RUNTIME_D3D12)
/// Function pointer definition for
///libra_vk_filter_chain_create
typedef libra_error_t (*PFN_libra_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);
///libra_d3d12_filter_chain_create
typedef libra_error_t (*PFN_libra_d3d12_filter_chain_create)(libra_shader_preset_t *preset,
const struct filter_chain_d3d12_opt_t *options,
const ID3D12Device * device,
libra_d3d12_filter_chain_t *out);
#endif
#if defined(LIBRA_RUNTIME_VULKAN)
#if defined(LIBRA_RUNTIME_D3D12)
/// Function pointer definition for
///libra_vk_filter_chain_frame
typedef libra_error_t (*PFN_libra_vk_filter_chain_frame)(libra_vk_filter_chain_t *chain,
VkCommandBuffer command_buffer,
size_t frame_count,
struct libra_image_vk_t image,
struct libra_viewport_t viewport,
struct libra_image_vk_t out,
const float *mvp,
const struct frame_vk_opt_t *opt);
///libra_d3d12_filter_chain_frame
typedef libra_error_t (*PFN_libra_d3d12_filter_chain_frame)(libra_d3d12_filter_chain_t *chain,
const ID3D12GraphicsCommandList * command_list,
size_t frame_count,
struct libra_source_image_d3d12_t image,
struct libra_viewport_t viewport,
D3D12_CPU_DESCRIPTOR_HANDLE out,
const float *mvp,
const struct frame_d3d12_opt_t *opt);
#endif
#if defined(LIBRA_RUNTIME_VULKAN)
#if defined(LIBRA_RUNTIME_D3D12)
/// 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);
///libra_d3d12_filter_chain_set_param
typedef libra_error_t (*PFN_libra_d3d12_filter_chain_set_param)(libra_d3d12_filter_chain_t *chain,
const char *param_name,
float value);
#endif
#if defined(LIBRA_RUNTIME_VULKAN)
#if defined(LIBRA_RUNTIME_D3D12)
/// 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);
///libra_d3d12_filter_chain_get_param
typedef libra_error_t (*PFN_libra_d3d12_filter_chain_get_param)(libra_d3d12_filter_chain_t *chain,
const char *param_name,
float *out);
#endif
#if defined(LIBRA_RUNTIME_VULKAN)
#if defined(LIBRA_RUNTIME_D3D12)
/// 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);
///libra_d3d12_filter_chain_set_active_pass_count
typedef libra_error_t (*PFN_libra_d3d12_filter_chain_set_active_pass_count)(libra_d3d12_filter_chain_t *chain,
uint32_t value);
#endif
#if defined(LIBRA_RUNTIME_VULKAN)
#if defined(LIBRA_RUNTIME_D3D12)
/// 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);
///libra_d3d12_filter_chain_get_active_pass_count
typedef libra_error_t (*PFN_libra_d3d12_filter_chain_get_active_pass_count)(libra_d3d12_filter_chain_t *chain,
uint32_t *out);
#endif
#if defined(LIBRA_RUNTIME_VULKAN)
#if defined(LIBRA_RUNTIME_D3D12)
/// Function pointer definition for
///libra_vk_filter_chain_free
typedef libra_error_t (*PFN_libra_vk_filter_chain_free)(libra_vk_filter_chain_t *chain);
///libra_d3d12_filter_chain_free
typedef libra_error_t (*PFN_libra_d3d12_filter_chain_free)(libra_d3d12_filter_chain_t *chain);
#endif
#ifdef __cplusplus
@ -721,95 +833,6 @@ libra_error_t libra_gl_filter_chain_get_active_pass_count(libra_gl_filter_chain_
libra_error_t libra_gl_filter_chain_free(libra_gl_filter_chain_t *chain);
#endif
#if defined(LIBRA_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.
///
/// ## Safety:
/// - `preset` must be either null, or valid and aligned.
/// - `options` must be either null, or valid and aligned.
/// - `device` must not be null.
/// - `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);
#endif
#if defined(LIBRA_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
/// 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.
/// - `out` must not be null.
/// - `image.handle` must not be null.
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);
#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.
///
/// The resulting value in `chain` then becomes null.
/// ## Safety
/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_d3d11_filter_chain_t`.
libra_error_t libra_d3d11_filter_chain_free(libra_d3d11_filter_chain_t *chain);
#endif
#if defined(LIBRA_RUNTIME_VULKAN)
/// Create the filter chain given the shader preset.
///
@ -905,6 +928,187 @@ libra_error_t libra_vk_filter_chain_get_active_pass_count(libra_vk_filter_chain_
libra_error_t libra_vk_filter_chain_free(libra_vk_filter_chain_t *chain);
#endif
#if defined(LIBRA_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.
///
/// ## Safety:
/// - `preset` must be either null, or valid and aligned.
/// - `options` must be either null, or valid and aligned.
/// - `device` must not be null.
/// - `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);
#endif
#if defined(LIBRA_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
/// 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.
/// - `out` must not be null.
/// - `image.handle` must not be null.
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);
#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.
///
/// The resulting value in `chain` then becomes null.
/// ## Safety
/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_d3d11_filter_chain_t`.
libra_error_t libra_d3d11_filter_chain_free(libra_d3d11_filter_chain_t *chain);
#endif
#if defined(LIBRA_RUNTIME_D3D12)
/// 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.
/// - `device` must not be null.
/// - `out` must be aligned, but may be null, invalid, or uninitialized.
libra_error_t libra_d3d12_filter_chain_create(libra_shader_preset_t *preset,
const struct filter_chain_d3d12_opt_t *options,
const ID3D12Device * device,
libra_d3d12_filter_chain_t *out);
#endif
#if defined(LIBRA_RUNTIME_D3D12)
/// Records rendering commands for a frame with the given parameters for the given filter chain
/// to the input command list.
///
/// ## 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.
/// - `out` must be a descriptor handle to a render target view.
/// - `image.resource` must not be null.
/// - `command_list` must not be null.
libra_error_t libra_d3d12_filter_chain_frame(libra_d3d12_filter_chain_t *chain,
const ID3D12GraphicsCommandList * command_list,
size_t frame_count,
struct libra_source_image_d3d12_t image,
struct libra_viewport_t viewport,
D3D12_CPU_DESCRIPTOR_HANDLE out,
const float *mvp,
const struct frame_d3d12_opt_t *opt);
#endif
#if defined(LIBRA_RUNTIME_D3D12)
/// 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_d3d12_filter_chain_t`.
/// - `param_name` must be either null or a null terminated string.
libra_error_t libra_d3d12_filter_chain_set_param(libra_d3d12_filter_chain_t *chain,
const char *param_name,
float value);
#endif
#if defined(LIBRA_RUNTIME_D3D12)
/// 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_d3d12_filter_chain_t`.
/// - `param_name` must be either null or a null terminated string.
libra_error_t libra_d3d12_filter_chain_get_param(libra_d3d12_filter_chain_t *chain,
const char *param_name,
float *out);
#endif
#if defined(LIBRA_RUNTIME_D3D12)
/// 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_d3d12_filter_chain_t`.
libra_error_t libra_d3d12_filter_chain_set_active_pass_count(libra_d3d12_filter_chain_t *chain,
uint32_t value);
#endif
#if defined(LIBRA_RUNTIME_D3D12)
/// 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_d3d12_filter_chain_t`.
libra_error_t libra_d3d12_filter_chain_get_active_pass_count(libra_d3d12_filter_chain_t *chain,
uint32_t *out);
#endif
#if defined(LIBRA_RUNTIME_D3D12)
/// Free a D3D12 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_d3d12_filter_chain_t`.
libra_error_t libra_d3d12_filter_chain_free(libra_d3d12_filter_chain_t *chain);
#endif
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus

View file

@ -151,6 +151,47 @@ libra_error_t __librashader__noop_gl_filter_chain_get_active_pass_count(
}
#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) {
return NULL;
}
libra_error_t __librashader__noop_vk_filter_chain_frame(
libra_vk_filter_chain_t *chain, VkCommandBuffer command_buffer,
size_t frame_count, struct libra_image_vk_t image,
struct libra_viewport_t viewport, struct libra_image_vk_t out,
const float *mvp, const struct frame_vk_opt_t *opt) {
return NULL;
}
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
#if defined(LIBRA_RUNTIME_D3D11)
libra_error_t __librashader__noop_d3d11_filter_chain_create(
libra_shader_preset_t *preset,
@ -191,51 +232,51 @@ 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)
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) {
#if defined(LIBRA_RUNTIME_D3D12)
libra_error_t __librashader__noop_d3d12_filter_chain_create(
libra_shader_preset_t *preset,
const struct filter_chain_d3d12_opt_t *options, const ID3D12Device *device,
libra_d3d12_filter_chain_t *out) {
return NULL;
}
libra_error_t __librashader__noop_vk_filter_chain_frame(
libra_vk_filter_chain_t *chain, VkCommandBuffer command_buffer,
size_t frame_count, struct libra_image_vk_t image,
struct libra_viewport_t viewport, struct libra_image_vk_t out,
const float *mvp, const struct frame_vk_opt_t *opt) {
libra_error_t __librashader__noop_d3d12_filter_chain_frame(
libra_d3d12_filter_chain_t *chain,
const ID3D12GraphicsCommandList *command_list, size_t frame_count,
struct libra_source_image_d3d12_t image, struct libra_viewport_t viewport,
D3D12_CPU_DESCRIPTOR_HANDLE out, const float *mvp,
const struct frame_d3d12_opt_t *opt) {
return NULL;
}
libra_error_t __librashader__noop_vk_filter_chain_free(
libra_vk_filter_chain_t *chain) {
libra_error_t __librashader__noop_d3d12_filter_chain_free(
libra_d3d12_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) {
libra_error_t __librashader__noop_d3d12_filter_chain_set_param(
libra_d3d12_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) {
libra_error_t __librashader__noop_d3d12_filter_chain_get_param(
libra_d3d12_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) {
libra_error_t __librashader__noop_d3d12_filter_chain_set_active_pass_count(
libra_d3d12_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) {
libra_error_t __librashader__noop_d3d12_filter_chain_get_active_pass_count(
libra_d3d12_filter_chain_t *chain, uint32_t *out) {
return NULL;
}
#endif
typedef struct libra_instance_t {
/// Load a preset.
///
@ -446,76 +487,6 @@ typedef struct libra_instance_t {
PFN_libra_gl_filter_chain_set_param gl_filter_chain_set_param;
#endif
#if defined(LIBRA_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.
///
/// ## 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.
PFN_libra_d3d11_filter_chain_create d3d11_filter_chain_create;
/// 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.
PFN_libra_d3d11_filter_chain_frame d3d11_filter_chain_frame;
/// 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`.
PFN_libra_d3d11_filter_chain_free d3d11_filter_chain_free;
/// 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`.
PFN_libra_d3d11_filter_chain_get_active_pass_count
d3d11_filter_chain_get_active_pass_count;
/// 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`.
PFN_libra_d3d11_filter_chain_set_active_pass_count
d3d11_filter_chain_set_active_pass_count;
/// 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.
PFN_libra_d3d11_filter_chain_get_param d3d11_filter_chain_get_param;
/// 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.
PFN_libra_d3d11_filter_chain_set_param d3d11_filter_chain_set_param;
#endif
#if defined(LIBRA_RUNTIME_VULKAN)
/// Create the filter chain given the shader preset.
///
@ -597,8 +568,149 @@ typedef struct libra_instance_t {
/// - `param_name` must be either null or a null terminated string.
PFN_libra_vk_filter_chain_set_param vk_filter_chain_set_param;
#endif
#if defined(LIBRA_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.
///
/// ## 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.
PFN_libra_d3d11_filter_chain_create d3d11_filter_chain_create;
/// 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_d3d11_opt_t`
/// struct.
PFN_libra_d3d11_filter_chain_frame d3d11_filter_chain_frame;
/// 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`.
PFN_libra_d3d11_filter_chain_free d3d11_filter_chain_free;
/// 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`.
PFN_libra_d3d11_filter_chain_get_active_pass_count
d3d11_filter_chain_get_active_pass_count;
/// 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`.
PFN_libra_d3d11_filter_chain_set_active_pass_count
d3d11_filter_chain_set_active_pass_count;
/// 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.
PFN_libra_d3d11_filter_chain_get_param d3d11_filter_chain_get_param;
/// 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.
PFN_libra_d3d11_filter_chain_set_param d3d11_filter_chain_set_param;
#endif
#if defined(LIBRA_RUNTIME_D3D12)
/// 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.
PFN_libra_d3d12_filter_chain_create d3d12_filter_chain_create;
/// 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_d3d12_opt_t`
/// struct.
PFN_libra_d3d12_filter_chain_frame d3d12_filter_chain_frame;
/// 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_d3d12_filter_chain_t`.
PFN_libra_d3d12_filter_chain_free d3d12_filter_chain_free;
/// 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_d3d12_filter_chain_t`.
PFN_libra_d3d12_filter_chain_get_active_pass_count
d3d12_filter_chain_get_active_pass_count;
/// 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_d3d12_filter_chain_t`.
PFN_libra_d3d12_filter_chain_set_active_pass_count
d3d12_filter_chain_set_active_pass_count;
/// 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_d3d12_filter_chain_t`.
/// - `param_name` must be either null or a null terminated string.
PFN_libra_d3d12_filter_chain_get_param d3d12_filter_chain_get_param;
/// 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_d3d12_filter_chain_t`.
/// - `param_name` must be either null or a null terminated string.
PFN_libra_d3d12_filter_chain_set_param d3d12_filter_chain_set_param;
#endif
} libra_instance_t;
libra_instance_t __librashader_make_null_instance() {
return libra_instance_t {
.preset_create = __librashader__noop_preset_create,
@ -632,6 +744,20 @@ libra_instance_t __librashader_make_null_instance() {
__librashader__noop_gl_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
#if defined(LIBRA_RUNTIME_D3D11)
.d3d11_filter_chain_create =
__librashader__noop_d3d11_filter_chain_create,
@ -648,19 +774,21 @@ libra_instance_t __librashader_make_null_instance() {
__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
#if defined(LIBRA_RUNTIME_D3D12)
.d3d12_filter_chain_create =
__librashader__noop_d3d12_filter_chain_create,
.d3d12_filter_chain_frame =
__librashader__noop_d3d12_filter_chain_frame,
.d3d12_filter_chain_free = __librashader__noop_d3d12_filter_chain_free,
.d3d12_filter_chain_get_active_pass_count =
__librashader__noop_d3d12_filter_chain_get_active_pass_count,
.d3d12_filter_chain_set_active_pass_count =
__librashader__noop_d3d12_filter_chain_set_active_pass_count,
.d3d12_filter_chain_get_param =
__librashader__noop_d3d12_filter_chain_get_param,
.d3d12_filter_chain_set_param =
__librashader__noop_d3d12_filter_chain_set_param,
#endif
};
}
@ -718,22 +846,6 @@ libra_instance_t librashader_load_instance() {
#endif
#if defined(_WIN32) && defined(LIBRA_RUNTIME_D3D11)
_LIBRASHADER_ASSIGN(librashader, instance,
d3d11_filter_chain_create);
_LIBRASHADER_ASSIGN(librashader, instance,
d3d11_filter_chain_frame);
_LIBRASHADER_ASSIGN(librashader, instance, d3d11_filter_chain_free);
_LIBRASHADER_ASSIGN(librashader, instance,
d3d11_filter_chain_get_param);
_LIBRASHADER_ASSIGN(librashader, instance,
d3d11_filter_chain_set_param);
_LIBRASHADER_ASSIGN(librashader, instance,
d3d11_filter_chain_get_active_pass_count);
_LIBRASHADER_ASSIGN(librashader, instance,
d3d11_filter_chain_set_active_pass_count);
#endif
#if defined(LIBRA_RUNTIME_VULKAN)
_LIBRASHADER_ASSIGN(librashader, instance, vk_filter_chain_create);
_LIBRASHADER_ASSIGN(librashader, instance, vk_filter_chain_frame);
@ -748,6 +860,29 @@ libra_instance_t librashader_load_instance() {
vk_filter_chain_set_active_pass_count);
#endif
#if defined(_WIN32) && defined(LIBRA_RUNTIME_D3D11)
_LIBRASHADER_ASSIGN(librashader, instance, d3d11_filter_chain_create);
_LIBRASHADER_ASSIGN(librashader, instance, d3d11_filter_chain_frame);
_LIBRASHADER_ASSIGN(librashader, instance, d3d11_filter_chain_free);
_LIBRASHADER_ASSIGN(librashader, instance, d3d11_filter_chain_get_param);
_LIBRASHADER_ASSIGN(librashader, instance, d3d11_filter_chain_set_param);
_LIBRASHADER_ASSIGN(librashader, instance,
d3d11_filter_chain_get_active_pass_count);
_LIBRASHADER_ASSIGN(librashader, instance,
d3d11_filter_chain_set_active_pass_count);
#endif
#if defined(_WIN32) && defined(LIBRA_RUNTIME_D3D12)
_LIBRASHADER_ASSIGN(librashader, instance, d3d12_filter_chain_create);
_LIBRASHADER_ASSIGN(librashader, instance, d3d12_filter_chain_frame);
_LIBRASHADER_ASSIGN(librashader, instance, d3d12_filter_chain_free);
_LIBRASHADER_ASSIGN(librashader, instance, d3d12_filter_chain_get_param);
_LIBRASHADER_ASSIGN(librashader, instance, d3d12_filter_chain_set_param);
_LIBRASHADER_ASSIGN(librashader, instance,
d3d12_filter_chain_get_active_pass_count);
_LIBRASHADER_ASSIGN(librashader, instance,
d3d12_filter_chain_set_active_pass_count);
#endif
return instance;
}
#else

View file

@ -15,9 +15,10 @@ description = "RetroArch shaders for all."
crate-type = [ "cdylib", "staticlib" ]
[features]
default = ["runtime-opengl", "runtime-d3d11", "runtime-vulkan"]
default = ["runtime-opengl", "runtime-d3d11", "runtime-d3d12", "runtime-vulkan"]
runtime-opengl = ["gl", "librashader/gl"]
runtime-d3d11 = ["windows", "librashader/d3d11"]
runtime-d3d11 = ["windows", "librashader/d3d11", "windows/Win32_Graphics_Direct3D11"]
runtime-d3d12 = ["windows", "librashader/d3d12", "windows/Win32_Graphics_Direct3D12"]
runtime-vulkan = ["ash", "librashader/vk"]
[dependencies]
@ -31,9 +32,6 @@ spirv_cross = { package = "librashader-spirv-cross", version = "0.23" }
[target.'cfg(windows)'.dependencies.windows]
version = "0.44.0"
features = [
"Win32_Graphics_Direct3D11",
]
optional = true
[package.metadata.cargo-post.dependencies]

View file

@ -48,12 +48,21 @@ typedef void* VkPhysicalDevice;
typedef void* VkInstance;
typedef void* VkCommandBuffer;
#endif
#if defined(_WIN32) && defined(LIBRA_RUNTIME_D3D12)
#include <d3d12.h>
#else
typedef void ID3D12GraphicsCommandList;
typedef void ID3D12Device;
typedef void ID3D12Resource;
typedef void D3D12_CPU_DESCRIPTOR_HANDLE;
#endif
"""
[defines]
"feature = runtime-opengl" = "LIBRA_RUNTIME_OPENGL"
"feature = runtime-d3d11" = "LIBRA_RUNTIME_D3D11"
"feature = runtime-vulkan" = "LIBRA_RUNTIME_VULKAN"
"feature = runtime-d3d11" = "LIBRA_RUNTIME_D3D11"
"feature = runtime-d3d12" = "LIBRA_RUNTIME_D3D12"
[parse]
parse_deps = true
@ -62,8 +71,9 @@ include = ["librashader",
"librashader-preprocess",
"librashader-reflect",
"librashader-runtime-gl",
"librashader-runtime-d3d11",
"librashader-runtime-vk",
"librashader-runtime-d3d11",
"librashader-runtime-d3d12",
]
expand = ["librashader-capi"]
@ -101,6 +111,15 @@ include = [
"PFN_libra_gl_filter_chain_get_active_pass_count",
"PFN_libra_gl_filter_chain_free",
# vulkan
"PFN_libra_vk_filter_chain_create",
"PFN_libra_vk_filter_chain_frame",
"PFN_libra_vk_filter_chain_set_param",
"PFN_libra_vk_filter_chain_get_param",
"PFN_libra_vk_filter_chain_set_active_pass_count",
"PFN_libra_vk_filter_chain_get_active_pass_count",
"PFN_libra_vk_filter_chain_free",
# d3d11
"PFN_libra_d3d11_filter_chain_create",
"PFN_libra_d3d11_filter_chain_frame",
@ -110,14 +129,15 @@ include = [
"PFN_libra_d3d11_filter_chain_get_active_pass_count",
"PFN_libra_d3d11_filter_chain_free",
# vulkan
"PFN_libra_vk_filter_chain_create",
"PFN_libra_vk_filter_chain_frame",
"PFN_libra_vk_filter_chain_set_param",
"PFN_libra_vk_filter_chain_get_param",
"PFN_libra_vk_filter_chain_set_active_pass_count",
"PFN_libra_vk_filter_chain_get_active_pass_count",
"PFN_libra_vk_filter_chain_free",
# d3d11
"PFN_libra_d3d12_filter_chain_create",
"PFN_libra_d3d12_filter_chain_frame",
"PFN_libra_d3d12_filter_chain_set_param",
"PFN_libra_d3d12_filter_chain_get_param",
"PFN_libra_d3d12_filter_chain_set_active_pass_count",
"PFN_libra_d3d12_filter_chain_get_active_pass_count",
"PFN_libra_d3d12_filter_chain_free",
]
[export.rename]
@ -126,12 +146,15 @@ include = [
"FilterChainGL" = "_filter_chain_gl"
"FilterChainOptionsGL" = "filter_chain_gl_opt_t"
"FrameOptionsGL" = "frame_gl_opt_t"
"FilterChainD3D11" = "_filter_chain_d3d11"
"FilterChainOptionsD3D11" = "filter_chain_d3d11_opt_t"
"FrameOptionsD3D11" = "frame_d3d11_opt_t"
"FilterChainVulkan" = "_filter_chain_vk"
"FilterChainOptionsVulkan" = "filter_chain_vk_opt_t"
"FrameOptionsVulkan" = "frame_vk_opt_t"
"FilterChainD3D11" = "_filter_chain_d3d11"
"FilterChainOptionsD3D11" = "filter_chain_d3d11_opt_t"
"FrameOptionsD3D11" = "frame_d3d11_opt_t"
"FilterChainD3D12" = "_filter_chain_d3d12"
"FilterChainOptionsD3D12" = "filter_chain_d3d12_opt_t"
"FrameOptionsD3D12" = "frame_d3d12_opt_t"
# vulkan renames
"PhysicalDevice" = "VkPhysicalDevice"
@ -144,4 +167,9 @@ include = [
#hack to get proper pointer indirection for COM pointers
"ID3D11Device" = "const ID3D11Device *"
"ID3D11RenderTargetView" = "const ID3D11RenderTargetView *"
"ID3D11ShaderResourceView" = "const ID3D11ShaderResourceView *"
"ID3D11ShaderResourceView" = "const ID3D11ShaderResourceView *"
#hack to get proper pointer indirection for COM pointers
"ID3D12Device" = "const ID3D12Device *"
"ID3D12Resource" = "const ID3D12Resource *"
"ID3D12GraphicsCommandList" = "const ID3D12GraphicsCommandList *"

View file

@ -14,12 +14,19 @@ pub type libra_error_t = Option<NonNull<LibrashaderError>>;
#[doc(cfg(feature = "runtime-opengl"))]
pub type libra_gl_filter_chain_t = Option<NonNull<librashader::runtime::gl::capi::FilterChainGL>>;
/// A handle to a Direct3D11 filter chain.
/// A handle to a Direct3D 11 filter chain.
#[cfg(all(target_os = "windows", feature = "runtime-d3d11"))]
#[doc(cfg(all(target_os = "windows", feature = "runtime-d3d11")))]
pub type libra_d3d11_filter_chain_t =
Option<NonNull<librashader::runtime::d3d11::capi::FilterChainD3D11>>;
/// A handle to a Direct3D 12 filter chain.
#[cfg(all(target_os = "windows", feature = "runtime-d3d12"))]
#[doc(cfg(all(target_os = "windows", feature = "runtime-d3d12")))]
pub type libra_d3d12_filter_chain_t =
Option<NonNull<librashader::runtime::d3d12::capi::FilterChainD3D12>>;
/// A handle to a Vulkan filter chain.
#[cfg(feature = "runtime-vulkan")]
#[doc(cfg(feature = "runtime-vulkan"))]

View file

@ -33,6 +33,10 @@ pub enum LibrashaderError {
#[doc(cfg(all(target_os = "windows", feature = "runtime-d3d11")))]
#[error("There was an error in the D3D11 filter chain.")]
D3D11FilterError(#[from] librashader::runtime::d3d11::error::FilterChainError),
#[cfg(all(target_os = "windows", feature = "runtime-d3d12"))]
#[doc(cfg(all(target_os = "windows", feature = "runtime-d3d12")))]
#[error("There was an error in the D3D12 filter chain.")]
D3D12FilterError(#[from] librashader::runtime::d3d12::error::FilterChainError),
#[cfg(feature = "runtime-vulkan")]
#[doc(cfg(feature = "runtime-vulkan"))]
#[error("There was an error in the Vulkan filter chain.")]
@ -183,6 +187,8 @@ impl LibrashaderError {
LibrashaderError::OpenGlFilterError(_) => LIBRA_ERRNO::RUNTIME_ERROR,
#[cfg(all(target_os = "windows", feature = "runtime-d3d11"))]
LibrashaderError::D3D11FilterError(_) => LIBRA_ERRNO::RUNTIME_ERROR,
#[cfg(all(target_os = "windows", feature = "runtime-d3d12"))]
LibrashaderError::D3D12FilterError(_) => LIBRA_ERRNO::RUNTIME_ERROR,
#[cfg(feature = "runtime-vulkan")]
LibrashaderError::VulkanFilterError(_) => LIBRA_ERRNO::RUNTIME_ERROR,
}
@ -211,14 +217,6 @@ macro_rules! assert_non_null {
};
}
// macro_rules! assert_some {
// ($value:ident) => {
// if $value.is_none() {
// return $crate::error::LibrashaderError::InvalidParameter(stringify!($value)).export();
// }
// };
// }
macro_rules! assert_some_ptr {
($value:ident) => {
if $value.is_none() {

View file

@ -1,4 +1,4 @@
//! C API for the librashader OpenGL Runtime (`libra_d3d11_*`)
//! C API for the librashader D3D12 Runtime (`libra_d3d11_*`)
mod filter_chain;
pub use filter_chain::*;

View file

@ -0,0 +1,239 @@
use crate::ctypes::{libra_d3d12_filter_chain_t, libra_shader_preset_t, libra_viewport_t};
use crate::error::{assert_non_null, assert_some_ptr, LibrashaderError};
use crate::ffi::extern_fn;
use std::ffi::c_char;
use std::ffi::CStr;
use std::mem::{ManuallyDrop, MaybeUninit};
use std::ptr::NonNull;
use std::slice;
use windows::Win32::Graphics::Direct3D12::{D3D12_CPU_DESCRIPTOR_HANDLE, ID3D12Device, ID3D12GraphicsCommandList, ID3D12Resource};
use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT;
pub use librashader::runtime::d3d12::capi::options::FilterChainOptionsD3D12;
pub use librashader::runtime::d3d12::capi::options::FrameOptionsD3D12;
use librashader::runtime::{FilterChainParameters, Size, Viewport};
use librashader::runtime::d3d12::{D3D12InputImage, D3D12OutputView};
/// Direct3D 11 parameters for the source image.
#[repr(C)]
pub struct libra_source_image_d3d12_t {
/// The resource containing the image.
pub resource: ManuallyDrop<ID3D12Resource>,
/// A CPU descriptor handle to a shader resource view of the image.
pub descriptor: D3D12_CPU_DESCRIPTOR_HANDLE,
/// The format of the image.
pub format: DXGI_FORMAT,
/// The width of the source image.
pub width: u32,
/// The height of the source image.
pub height: u32,
}
impl TryFrom<libra_source_image_d3d12_t> for D3D12InputImage {
type Error = LibrashaderError;
fn try_from(value: libra_source_image_d3d12_t) -> Result<Self, Self::Error> {
let resource = value.resource.clone();
Ok(D3D12InputImage {
resource: ManuallyDrop::into_inner(resource),
descriptor: value.descriptor,
size: Size::new(value.width, value.height),
format: value.format,
})
}
}
extern_fn! {
/// Create the filter chain given the shader preset.
///
/// The shader preset is immediately invalidated and must be recreated after
/// the filter chain is created.
///
/// ## Safety:
/// - `preset` must be either null, or valid and aligned.
/// - `options` must be either null, or valid and aligned.
/// - `device` must not be null.
/// - `out` must be aligned, but may be null, invalid, or uninitialized.
fn libra_d3d12_filter_chain_create(
preset: *mut libra_shader_preset_t,
options: *const FilterChainOptionsD3D12,
device: ManuallyDrop<ID3D12Device>,
out: *mut MaybeUninit<libra_d3d12_filter_chain_t>
) {
assert_non_null!(preset);
let preset = unsafe {
let preset_ptr = &mut *preset;
let preset = preset_ptr.take();
Box::from_raw(preset.unwrap().as_ptr())
};
let options = if options.is_null() {
None
} else {
Some(unsafe { &*options })
};
let chain = librashader::runtime::d3d12::capi::FilterChainD3D12::load_from_preset(
&device,
*preset,
options,
)?;
unsafe {
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(
chain,
)))))
}
}
}
extern_fn! {
/// Records rendering commands for a frame with the given parameters for the given filter chain
/// to the input command list.
///
/// ## 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.
/// - `out` must be a descriptor handle to a render target view.
/// - `image.resource` must not be null.
/// - `command_list` must not be null.
fn libra_d3d12_filter_chain_frame(
chain: *mut libra_d3d12_filter_chain_t,
command_list: ManuallyDrop<ID3D12GraphicsCommandList>,
frame_count: usize,
image: libra_source_image_d3d12_t,
viewport: libra_viewport_t,
out: D3D12_CPU_DESCRIPTOR_HANDLE,
mvp: *const f32,
opt: *const FrameOptionsD3D12
) mut |chain| {
assert_some_ptr!(mut chain);
let mvp = if mvp.is_null() {
None
} else {
Some(<&[f32; 16]>::try_from(unsafe { slice::from_raw_parts(mvp, 16) }).unwrap())
};
let opt = if opt.is_null() {
None
} else {
Some(unsafe { opt.read() })
};
let viewport = Viewport {
x: viewport.x,
y: viewport.y,
output: unsafe { D3D12OutputView::new_from_raw(out, Size::new(viewport.width, viewport.height)) },
mvp,
};
let image = image.try_into()?;
chain.frame(&command_list, image, &viewport, frame_count, opt.as_ref())?;
}
}
extern_fn! {
/// 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_d3d12_filter_chain_t`.
/// - `param_name` must be either null or a null terminated string.
fn libra_d3d12_filter_chain_set_param(
chain: *mut libra_d3d12_filter_chain_t,
param_name: *const c_char,
value: f32
) mut |chain| {
assert_some_ptr!(mut chain);
assert_non_null!(param_name);
unsafe {
let name = CStr::from_ptr(param_name);
let name = name.to_str()?;
if chain.set_parameter(name, value).is_none() {
return LibrashaderError::UnknownShaderParameter(param_name).export()
}
}
}
}
extern_fn! {
/// 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_d3d12_filter_chain_t`.
/// - `param_name` must be either null or a null terminated string.
fn libra_d3d12_filter_chain_get_param(
chain: *mut libra_d3d12_filter_chain_t,
param_name: *const c_char,
out: *mut MaybeUninit<f32>
) mut |chain| {
assert_some_ptr!(mut chain);
assert_non_null!(param_name);
unsafe {
let name = CStr::from_ptr(param_name);
let name = name.to_str()?;
let Some(value) = chain.get_parameter(name) else {
return LibrashaderError::UnknownShaderParameter(param_name).export()
};
out.write(MaybeUninit::new(value));
}
}
}
extern_fn! {
/// 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_d3d12_filter_chain_t`.
fn libra_d3d12_filter_chain_set_active_pass_count(
chain: *mut libra_d3d12_filter_chain_t,
value: u32
) mut |chain| {
assert_some_ptr!(mut chain);
chain.set_enabled_pass_count(value as usize);
}
}
extern_fn! {
/// 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_d3d12_filter_chain_t`.
fn libra_d3d12_filter_chain_get_active_pass_count(
chain: *mut libra_d3d12_filter_chain_t,
out: *mut MaybeUninit<u32>
) mut |chain| {
assert_some_ptr!(mut chain);
unsafe {
let value = chain.get_enabled_pass_count();
out.write(MaybeUninit::new(value as u32))
}
}
}
extern_fn! {
/// Free a D3D12 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_d3d12_filter_chain_t`.
fn libra_d3d12_filter_chain_free(chain: *mut libra_d3d12_filter_chain_t) {
assert_non_null!(chain);
unsafe {
let chain_ptr = &mut *chain;
let chain = chain_ptr.take();
drop(Box::from_raw(chain.unwrap().as_ptr()))
};
}
}

View file

@ -0,0 +1,4 @@
//! C API for the librashader D3D12 Runtime (`libra_d3d12_*`)
mod filter_chain;
pub use filter_chain::*;

View file

@ -3,10 +3,14 @@
#[cfg(feature = "runtime-opengl")]
pub mod gl;
#[doc(cfg(feature = "runtime-vulkan"))]
#[cfg(feature = "runtime-vulkan")]
pub mod vk;
#[doc(cfg(all(target_os = "windows", feature = "runtime-d3d11")))]
#[cfg(all(target_os = "windows", feature = "runtime-d3d11"))]
pub mod d3d11;
#[doc(cfg(feature = "runtime-vulkan"))]
#[cfg(feature = "runtime-vulkan")]
pub mod vk;
#[doc(cfg(all(target_os = "windows", feature = "runtime-d3d12")))]
#[cfg(all(target_os = "windows", feature = "runtime-d3d12"))]
pub mod d3d12;

View file

@ -1,3 +1,5 @@
#![cfg(target_os = "windows")]
#![feature(const_trait_impl)]
#![feature(let_chains)]
#![feature(type_alias_impl_trait)]

View file

@ -14,6 +14,7 @@
#include <assert.h>
#define LIBRA_RUNTIME_D3D11
#define LIBRA_RUNTIME_D3D12
#include "../../../../include/librashader.h"
#include "../../../../include/librashader_ld.h"