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. loads the librashader (`librashader.so` or `librashader.dll`) implementation in the search path.
### Building ### 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 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. * 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. * 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. * 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. * 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 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. compared to dynamic rendering.

View file

@ -50,6 +50,14 @@ typedef void* VkPhysicalDevice;
typedef void* VkInstance; typedef void* VkInstance;
typedef void* VkCommandBuffer; typedef void* VkCommandBuffer;
#endif #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. /// Error codes for librashader error types.
@ -74,6 +82,9 @@ typedef int32_t LIBRA_ERRNO;
/// A Direct3D 11 filter chain. /// A Direct3D 11 filter chain.
typedef struct _filter_chain_d3d11 _filter_chain_d3d11; 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. /// An OpenGL filter chain.
typedef struct _filter_chain_gl _filter_chain_gl; 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 { typedef struct frame_gl_opt_t {
/// Whether or not to clear the history buffers. /// Whether or not to clear the history buffers.
bool clear_history; bool clear_history;
/// The direction of the frame. 1 should be vertical. /// The direction of rendering.
/// -1 indicates that the frames are played in reverse order.
int32_t frame_direction; int32_t frame_direction;
} frame_gl_opt_t; } 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) #if defined(LIBRA_RUNTIME_VULKAN)
/// Handles required to instantiate vulkan /// Handles required to instantiate vulkan
typedef struct libra_device_vk_t { typedef struct libra_device_vk_t {
@ -276,10 +251,89 @@ typedef struct libra_image_vk_t {
typedef struct frame_vk_opt_t { typedef struct frame_vk_opt_t {
/// Whether or not to clear the history buffers. /// Whether or not to clear the history buffers.
bool clear_history; bool clear_history;
/// The direction of the frame. 1 should be vertical. /// The direction of rendering.
/// -1 indicates that the frames are played in reverse order.
int32_t frame_direction; int32_t frame_direction;
} frame_vk_opt_t; } 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 /// Function pointer definition for
///libra_preset_create ///libra_preset_create
typedef libra_error_t (*PFN_libra_preset_create)(const char *filename, libra_shader_preset_t *out); 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); typedef libra_error_t (*PFN_libra_gl_filter_chain_free)(libra_gl_filter_chain_t *chain);
#endif #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) #if defined(LIBRA_RUNTIME_D3D11)
/// Function pointer definition for /// Function pointer definition for
///libra_d3d11_filter_chain_create ///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); typedef libra_error_t (*PFN_libra_d3d11_filter_chain_free)(libra_d3d11_filter_chain_t *chain);
#endif #endif
#if defined(LIBRA_RUNTIME_VULKAN) #if defined(LIBRA_RUNTIME_D3D12)
/// Function pointer definition for /// Function pointer definition for
///libra_vk_filter_chain_create ///libra_d3d12_filter_chain_create
typedef libra_error_t (*PFN_libra_vk_filter_chain_create)(struct libra_device_vk_t vulkan, typedef libra_error_t (*PFN_libra_d3d12_filter_chain_create)(libra_shader_preset_t *preset,
libra_shader_preset_t *preset, const struct filter_chain_d3d12_opt_t *options,
const struct filter_chain_vk_opt_t *options, const ID3D12Device * device,
libra_vk_filter_chain_t *out); libra_d3d12_filter_chain_t *out);
#endif #endif
#if defined(LIBRA_RUNTIME_VULKAN) #if defined(LIBRA_RUNTIME_D3D12)
/// Function pointer definition for /// Function pointer definition for
///libra_vk_filter_chain_frame ///libra_d3d12_filter_chain_frame
typedef libra_error_t (*PFN_libra_vk_filter_chain_frame)(libra_vk_filter_chain_t *chain, typedef libra_error_t (*PFN_libra_d3d12_filter_chain_frame)(libra_d3d12_filter_chain_t *chain,
VkCommandBuffer command_buffer, const ID3D12GraphicsCommandList * command_list,
size_t frame_count, size_t frame_count,
struct libra_image_vk_t image, struct libra_source_image_d3d12_t image,
struct libra_viewport_t viewport, struct libra_viewport_t viewport,
struct libra_image_vk_t out, D3D12_CPU_DESCRIPTOR_HANDLE out,
const float *mvp, const float *mvp,
const struct frame_vk_opt_t *opt); const struct frame_d3d12_opt_t *opt);
#endif #endif
#if defined(LIBRA_RUNTIME_VULKAN) #if defined(LIBRA_RUNTIME_D3D12)
/// Function pointer definition for /// Function pointer definition for
///libra_vk_filter_chain_set_param ///libra_d3d12_filter_chain_set_param
typedef libra_error_t (*PFN_libra_vk_filter_chain_set_param)(libra_vk_filter_chain_t *chain, typedef libra_error_t (*PFN_libra_d3d12_filter_chain_set_param)(libra_d3d12_filter_chain_t *chain,
const char *param_name, const char *param_name,
float value); float value);
#endif #endif
#if defined(LIBRA_RUNTIME_VULKAN) #if defined(LIBRA_RUNTIME_D3D12)
/// Function pointer definition for /// Function pointer definition for
///libra_vk_filter_chain_get_param ///libra_d3d12_filter_chain_get_param
typedef libra_error_t (*PFN_libra_vk_filter_chain_get_param)(libra_vk_filter_chain_t *chain, typedef libra_error_t (*PFN_libra_d3d12_filter_chain_get_param)(libra_d3d12_filter_chain_t *chain,
const char *param_name, const char *param_name,
float *out); float *out);
#endif #endif
#if defined(LIBRA_RUNTIME_VULKAN) #if defined(LIBRA_RUNTIME_D3D12)
/// Function pointer definition for /// Function pointer definition for
///libra_vk_filter_chain_set_active_pass_count ///libra_d3d12_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, typedef libra_error_t (*PFN_libra_d3d12_filter_chain_set_active_pass_count)(libra_d3d12_filter_chain_t *chain,
uint32_t value); uint32_t value);
#endif #endif
#if defined(LIBRA_RUNTIME_VULKAN) #if defined(LIBRA_RUNTIME_D3D12)
/// Function pointer definition for /// Function pointer definition for
///libra_vk_filter_chain_get_active_pass_count ///libra_d3d12_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, typedef libra_error_t (*PFN_libra_d3d12_filter_chain_get_active_pass_count)(libra_d3d12_filter_chain_t *chain,
uint32_t *out); uint32_t *out);
#endif #endif
#if defined(LIBRA_RUNTIME_VULKAN) #if defined(LIBRA_RUNTIME_D3D12)
/// Function pointer definition for /// Function pointer definition for
///libra_vk_filter_chain_free ///libra_d3d12_filter_chain_free
typedef libra_error_t (*PFN_libra_vk_filter_chain_free)(libra_vk_filter_chain_t *chain); typedef libra_error_t (*PFN_libra_d3d12_filter_chain_free)(libra_d3d12_filter_chain_t *chain);
#endif #endif
#ifdef __cplusplus #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); libra_error_t libra_gl_filter_chain_free(libra_gl_filter_chain_t *chain);
#endif #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) #if defined(LIBRA_RUNTIME_VULKAN)
/// Create the filter chain given the shader preset. /// 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); libra_error_t libra_vk_filter_chain_free(libra_vk_filter_chain_t *chain);
#endif #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 #ifdef __cplusplus
} // extern "C" } // extern "C"
#endif // __cplusplus #endif // __cplusplus

View file

@ -151,6 +151,47 @@ libra_error_t __librashader__noop_gl_filter_chain_get_active_pass_count(
} }
#endif #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) #if defined(LIBRA_RUNTIME_D3D11)
libra_error_t __librashader__noop_d3d11_filter_chain_create( libra_error_t __librashader__noop_d3d11_filter_chain_create(
libra_shader_preset_t *preset, 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) { libra_d3d11_filter_chain_t *chain, uint32_t *out) {
return NULL; return NULL;
} }
#endif #endif
#if defined(LIBRA_RUNTIME_VULKAN)
libra_error_t __librashader__noop_vk_filter_chain_create( #if defined(LIBRA_RUNTIME_D3D12)
struct libra_device_vk_t vulkan, libra_shader_preset_t *preset, libra_error_t __librashader__noop_d3d12_filter_chain_create(
const struct filter_chain_vk_opt_t *options, libra_vk_filter_chain_t *out) { libra_shader_preset_t *preset,
const struct filter_chain_d3d12_opt_t *options, const ID3D12Device *device,
libra_d3d12_filter_chain_t *out) {
return NULL; return NULL;
} }
libra_error_t __librashader__noop_vk_filter_chain_frame( libra_error_t __librashader__noop_d3d12_filter_chain_frame(
libra_vk_filter_chain_t *chain, VkCommandBuffer command_buffer, libra_d3d12_filter_chain_t *chain,
size_t frame_count, struct libra_image_vk_t image, const ID3D12GraphicsCommandList *command_list, size_t frame_count,
struct libra_viewport_t viewport, struct libra_image_vk_t out, struct libra_source_image_d3d12_t image, struct libra_viewport_t viewport,
const float *mvp, const struct frame_vk_opt_t *opt) { D3D12_CPU_DESCRIPTOR_HANDLE out, const float *mvp,
const struct frame_d3d12_opt_t *opt) {
return NULL; return NULL;
} }
libra_error_t __librashader__noop_vk_filter_chain_free( libra_error_t __librashader__noop_d3d12_filter_chain_free(
libra_vk_filter_chain_t *chain) { libra_d3d12_filter_chain_t *chain) {
return NULL; return NULL;
} }
libra_error_t __librashader__noop_vk_filter_chain_set_param( libra_error_t __librashader__noop_d3d12_filter_chain_set_param(
libra_vk_filter_chain_t *chain, const char *param_name, float value) { libra_d3d12_filter_chain_t *chain, const char *param_name, float value) {
return NULL; return NULL;
} }
libra_error_t __librashader__noop_vk_filter_chain_get_param( libra_error_t __librashader__noop_d3d12_filter_chain_get_param(
libra_vk_filter_chain_t *chain, const char *param_name, float *out) { libra_d3d12_filter_chain_t *chain, const char *param_name, float *out) {
return NULL; return NULL;
} }
libra_error_t __librashader__noop_vk_filter_chain_set_active_pass_count( libra_error_t __librashader__noop_d3d12_filter_chain_set_active_pass_count(
libra_vk_filter_chain_t *chain, uint32_t value) { libra_d3d12_filter_chain_t *chain, uint32_t value) {
return NULL; return NULL;
} }
libra_error_t __librashader__noop_vk_filter_chain_get_active_pass_count( libra_error_t __librashader__noop_d3d12_filter_chain_get_active_pass_count(
libra_vk_filter_chain_t *chain, uint32_t *out) { libra_d3d12_filter_chain_t *chain, uint32_t *out) {
return NULL; return NULL;
} }
#endif #endif
typedef struct libra_instance_t { typedef struct libra_instance_t {
/// Load a preset. /// Load a preset.
/// ///
@ -446,76 +487,6 @@ typedef struct libra_instance_t {
PFN_libra_gl_filter_chain_set_param gl_filter_chain_set_param; PFN_libra_gl_filter_chain_set_param gl_filter_chain_set_param;
#endif #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) #if defined(LIBRA_RUNTIME_VULKAN)
/// Create the filter chain given the shader preset. /// 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. /// - `param_name` must be either null or a null terminated string.
PFN_libra_vk_filter_chain_set_param vk_filter_chain_set_param; PFN_libra_vk_filter_chain_set_param vk_filter_chain_set_param;
#endif #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;
libra_instance_t __librashader_make_null_instance() { libra_instance_t __librashader_make_null_instance() {
return libra_instance_t { return libra_instance_t {
.preset_create = __librashader__noop_preset_create, .preset_create = __librashader__noop_preset_create,
@ -632,6 +744,20 @@ libra_instance_t __librashader_make_null_instance() {
__librashader__noop_gl_filter_chain_set_param, __librashader__noop_gl_filter_chain_set_param,
#endif #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) #if defined(LIBRA_RUNTIME_D3D11)
.d3d11_filter_chain_create = .d3d11_filter_chain_create =
__librashader__noop_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, __librashader__noop_d3d11_filter_chain_set_param,
#endif #endif
#if defined(LIBRA_RUNTIME_VULKAN) #if defined(LIBRA_RUNTIME_D3D12)
.vk_filter_chain_create = __librashader__noop_vk_filter_chain_create, .d3d12_filter_chain_create =
.vk_filter_chain_frame = __librashader__noop_vk_filter_chain_frame, __librashader__noop_d3d12_filter_chain_create,
.vk_filter_chain_free = __librashader__noop_vk_filter_chain_free, .d3d12_filter_chain_frame =
.vk_filter_chain_get_active_pass_count = __librashader__noop_d3d12_filter_chain_frame,
__librashader__noop_vk_filter_chain_get_active_pass_count, .d3d12_filter_chain_free = __librashader__noop_d3d12_filter_chain_free,
.vk_filter_chain_set_active_pass_count = .d3d12_filter_chain_get_active_pass_count =
__librashader__noop_vk_filter_chain_set_active_pass_count, __librashader__noop_d3d12_filter_chain_get_active_pass_count,
.vk_filter_chain_get_param = .d3d12_filter_chain_set_active_pass_count =
__librashader__noop_vk_filter_chain_get_param, __librashader__noop_d3d12_filter_chain_set_active_pass_count,
.vk_filter_chain_set_param = .d3d12_filter_chain_get_param =
__librashader__noop_vk_filter_chain_set_param, __librashader__noop_d3d12_filter_chain_get_param,
#endif .d3d12_filter_chain_set_param =
__librashader__noop_d3d12_filter_chain_set_param,
#endif
}; };
} }
@ -718,22 +846,6 @@ libra_instance_t librashader_load_instance() {
#endif #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) #if defined(LIBRA_RUNTIME_VULKAN)
_LIBRASHADER_ASSIGN(librashader, instance, vk_filter_chain_create); _LIBRASHADER_ASSIGN(librashader, instance, vk_filter_chain_create);
_LIBRASHADER_ASSIGN(librashader, instance, vk_filter_chain_frame); _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); vk_filter_chain_set_active_pass_count);
#endif #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; return instance;
} }
#else #else

View file

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

View file

@ -48,12 +48,21 @@ typedef void* VkPhysicalDevice;
typedef void* VkInstance; typedef void* VkInstance;
typedef void* VkCommandBuffer; typedef void* VkCommandBuffer;
#endif #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] [defines]
"feature = runtime-opengl" = "LIBRA_RUNTIME_OPENGL" "feature = runtime-opengl" = "LIBRA_RUNTIME_OPENGL"
"feature = runtime-d3d11" = "LIBRA_RUNTIME_D3D11"
"feature = runtime-vulkan" = "LIBRA_RUNTIME_VULKAN" "feature = runtime-vulkan" = "LIBRA_RUNTIME_VULKAN"
"feature = runtime-d3d11" = "LIBRA_RUNTIME_D3D11"
"feature = runtime-d3d12" = "LIBRA_RUNTIME_D3D12"
[parse] [parse]
parse_deps = true parse_deps = true
@ -62,8 +71,9 @@ include = ["librashader",
"librashader-preprocess", "librashader-preprocess",
"librashader-reflect", "librashader-reflect",
"librashader-runtime-gl", "librashader-runtime-gl",
"librashader-runtime-d3d11",
"librashader-runtime-vk", "librashader-runtime-vk",
"librashader-runtime-d3d11",
"librashader-runtime-d3d12",
] ]
expand = ["librashader-capi"] expand = ["librashader-capi"]
@ -101,6 +111,15 @@ include = [
"PFN_libra_gl_filter_chain_get_active_pass_count", "PFN_libra_gl_filter_chain_get_active_pass_count",
"PFN_libra_gl_filter_chain_free", "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 # d3d11
"PFN_libra_d3d11_filter_chain_create", "PFN_libra_d3d11_filter_chain_create",
"PFN_libra_d3d11_filter_chain_frame", "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_get_active_pass_count",
"PFN_libra_d3d11_filter_chain_free", "PFN_libra_d3d11_filter_chain_free",
# vulkan
"PFN_libra_vk_filter_chain_create", # d3d11
"PFN_libra_vk_filter_chain_frame", "PFN_libra_d3d12_filter_chain_create",
"PFN_libra_vk_filter_chain_set_param", "PFN_libra_d3d12_filter_chain_frame",
"PFN_libra_vk_filter_chain_get_param", "PFN_libra_d3d12_filter_chain_set_param",
"PFN_libra_vk_filter_chain_set_active_pass_count", "PFN_libra_d3d12_filter_chain_get_param",
"PFN_libra_vk_filter_chain_get_active_pass_count", "PFN_libra_d3d12_filter_chain_set_active_pass_count",
"PFN_libra_vk_filter_chain_free", "PFN_libra_d3d12_filter_chain_get_active_pass_count",
"PFN_libra_d3d12_filter_chain_free",
] ]
[export.rename] [export.rename]
@ -126,12 +146,15 @@ include = [
"FilterChainGL" = "_filter_chain_gl" "FilterChainGL" = "_filter_chain_gl"
"FilterChainOptionsGL" = "filter_chain_gl_opt_t" "FilterChainOptionsGL" = "filter_chain_gl_opt_t"
"FrameOptionsGL" = "frame_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" "FilterChainVulkan" = "_filter_chain_vk"
"FilterChainOptionsVulkan" = "filter_chain_vk_opt_t" "FilterChainOptionsVulkan" = "filter_chain_vk_opt_t"
"FrameOptionsVulkan" = "frame_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 # vulkan renames
"PhysicalDevice" = "VkPhysicalDevice" "PhysicalDevice" = "VkPhysicalDevice"
@ -144,4 +167,9 @@ include = [
#hack to get proper pointer indirection for COM pointers #hack to get proper pointer indirection for COM pointers
"ID3D11Device" = "const ID3D11Device *" "ID3D11Device" = "const ID3D11Device *"
"ID3D11RenderTargetView" = "const ID3D11RenderTargetView *" "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"))] #[doc(cfg(feature = "runtime-opengl"))]
pub type libra_gl_filter_chain_t = Option<NonNull<librashader::runtime::gl::capi::FilterChainGL>>; 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"))] #[cfg(all(target_os = "windows", feature = "runtime-d3d11"))]
#[doc(cfg(all(target_os = "windows", feature = "runtime-d3d11")))] #[doc(cfg(all(target_os = "windows", feature = "runtime-d3d11")))]
pub type libra_d3d11_filter_chain_t = pub type libra_d3d11_filter_chain_t =
Option<NonNull<librashader::runtime::d3d11::capi::FilterChainD3D11>>; 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. /// A handle to a Vulkan filter chain.
#[cfg(feature = "runtime-vulkan")] #[cfg(feature = "runtime-vulkan")]
#[doc(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")))] #[doc(cfg(all(target_os = "windows", feature = "runtime-d3d11")))]
#[error("There was an error in the D3D11 filter chain.")] #[error("There was an error in the D3D11 filter chain.")]
D3D11FilterError(#[from] librashader::runtime::d3d11::error::FilterChainError), 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")] #[cfg(feature = "runtime-vulkan")]
#[doc(cfg(feature = "runtime-vulkan"))] #[doc(cfg(feature = "runtime-vulkan"))]
#[error("There was an error in the Vulkan filter chain.")] #[error("There was an error in the Vulkan filter chain.")]
@ -183,6 +187,8 @@ impl LibrashaderError {
LibrashaderError::OpenGlFilterError(_) => LIBRA_ERRNO::RUNTIME_ERROR, LibrashaderError::OpenGlFilterError(_) => LIBRA_ERRNO::RUNTIME_ERROR,
#[cfg(all(target_os = "windows", feature = "runtime-d3d11"))] #[cfg(all(target_os = "windows", feature = "runtime-d3d11"))]
LibrashaderError::D3D11FilterError(_) => LIBRA_ERRNO::RUNTIME_ERROR, LibrashaderError::D3D11FilterError(_) => LIBRA_ERRNO::RUNTIME_ERROR,
#[cfg(all(target_os = "windows", feature = "runtime-d3d12"))]
LibrashaderError::D3D12FilterError(_) => LIBRA_ERRNO::RUNTIME_ERROR,
#[cfg(feature = "runtime-vulkan")] #[cfg(feature = "runtime-vulkan")]
LibrashaderError::VulkanFilterError(_) => LIBRA_ERRNO::RUNTIME_ERROR, 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 { macro_rules! assert_some_ptr {
($value:ident) => { ($value:ident) => {
if $value.is_none() { 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; mod filter_chain;
pub use 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")] #[cfg(feature = "runtime-opengl")]
pub mod gl; pub mod gl;
#[doc(cfg(feature = "runtime-vulkan"))]
#[cfg(feature = "runtime-vulkan")]
pub mod vk;
#[doc(cfg(all(target_os = "windows", feature = "runtime-d3d11")))] #[doc(cfg(all(target_os = "windows", feature = "runtime-d3d11")))]
#[cfg(all(target_os = "windows", feature = "runtime-d3d11"))] #[cfg(all(target_os = "windows", feature = "runtime-d3d11"))]
pub mod d3d11; pub mod d3d11;
#[doc(cfg(feature = "runtime-vulkan"))] #[doc(cfg(all(target_os = "windows", feature = "runtime-d3d12")))]
#[cfg(feature = "runtime-vulkan")] #[cfg(all(target_os = "windows", feature = "runtime-d3d12"))]
pub mod vk; pub mod d3d12;

View file

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

View file

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