capi: expose deferred API and make order consistent.
gotta get all these ABI breaks done before release.
This commit is contained in:
parent
fa6cd87c60
commit
0eac766685
|
@ -497,12 +497,22 @@ typedef libra_error_t (*PFN_libra_gl_filter_chain_free)(libra_gl_filter_chain_t
|
||||||
#if defined(LIBRA_RUNTIME_VULKAN)
|
#if defined(LIBRA_RUNTIME_VULKAN)
|
||||||
/// Function pointer definition for
|
/// Function pointer definition for
|
||||||
///libra_vk_filter_chain_create
|
///libra_vk_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_vk_filter_chain_create)(libra_shader_preset_t *preset,
|
||||||
libra_shader_preset_t *preset,
|
struct libra_device_vk_t vulkan,
|
||||||
const struct filter_chain_vk_opt_t *options,
|
const struct filter_chain_vk_opt_t *options,
|
||||||
libra_vk_filter_chain_t *out);
|
libra_vk_filter_chain_t *out);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(LIBRA_RUNTIME_VULKAN)
|
||||||
|
/// Function pointer definition for
|
||||||
|
///libra_vk_filter_chain_create_deferred
|
||||||
|
typedef libra_error_t (*PFN_libra_vk_filter_chain_create_deferred)(libra_shader_preset_t *preset,
|
||||||
|
struct libra_device_vk_t vulkan,
|
||||||
|
VkCommandBuffer command_buffer,
|
||||||
|
const struct filter_chain_vk_opt_t *options,
|
||||||
|
libra_vk_filter_chain_t *out);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(LIBRA_RUNTIME_VULKAN)
|
#if defined(LIBRA_RUNTIME_VULKAN)
|
||||||
/// Function pointer definition for
|
/// Function pointer definition for
|
||||||
///libra_vk_filter_chain_frame
|
///libra_vk_filter_chain_frame
|
||||||
|
@ -556,11 +566,21 @@ typedef libra_error_t (*PFN_libra_vk_filter_chain_free)(libra_vk_filter_chain_t
|
||||||
/// Function pointer definition for
|
/// Function pointer definition for
|
||||||
///libra_d3d11_filter_chain_create
|
///libra_d3d11_filter_chain_create
|
||||||
typedef libra_error_t (*PFN_libra_d3d11_filter_chain_create)(libra_shader_preset_t *preset,
|
typedef libra_error_t (*PFN_libra_d3d11_filter_chain_create)(libra_shader_preset_t *preset,
|
||||||
const struct filter_chain_d3d11_opt_t *options,
|
|
||||||
ID3D11Device * device,
|
ID3D11Device * device,
|
||||||
|
const struct filter_chain_d3d11_opt_t *options,
|
||||||
libra_d3d11_filter_chain_t *out);
|
libra_d3d11_filter_chain_t *out);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(LIBRA_RUNTIME_D3D11)
|
||||||
|
/// Function pointer definition for
|
||||||
|
///libra_d3d11_filter_chain_create_deferred
|
||||||
|
typedef libra_error_t (*PFN_libra_d3d11_filter_chain_create_deferred)(libra_shader_preset_t *preset,
|
||||||
|
ID3D11Device * device,
|
||||||
|
ID3D11DeviceContext * device_context,
|
||||||
|
const struct filter_chain_d3d11_opt_t *options,
|
||||||
|
libra_d3d11_filter_chain_t *out);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(LIBRA_RUNTIME_D3D11)
|
#if defined(LIBRA_RUNTIME_D3D11)
|
||||||
/// Function pointer definition for
|
/// Function pointer definition for
|
||||||
///libra_d3d11_filter_chain_frame
|
///libra_d3d11_filter_chain_frame
|
||||||
|
@ -571,7 +591,7 @@ typedef libra_error_t (*PFN_libra_d3d11_filter_chain_frame)(libra_d3d11_filter_c
|
||||||
struct libra_viewport_t viewport,
|
struct libra_viewport_t viewport,
|
||||||
ID3D11RenderTargetView * out,
|
ID3D11RenderTargetView * out,
|
||||||
const float *mvp,
|
const float *mvp,
|
||||||
const struct frame_d3d11_opt_t *opt);
|
const struct frame_d3d11_opt_t *options);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(LIBRA_RUNTIME_D3D11)
|
#if defined(LIBRA_RUNTIME_D3D11)
|
||||||
|
@ -614,11 +634,21 @@ typedef libra_error_t (*PFN_libra_d3d11_filter_chain_free)(libra_d3d11_filter_ch
|
||||||
/// Function pointer definition for
|
/// Function pointer definition for
|
||||||
///libra_d3d12_filter_chain_create
|
///libra_d3d12_filter_chain_create
|
||||||
typedef libra_error_t (*PFN_libra_d3d12_filter_chain_create)(libra_shader_preset_t *preset,
|
typedef libra_error_t (*PFN_libra_d3d12_filter_chain_create)(libra_shader_preset_t *preset,
|
||||||
const struct filter_chain_d3d12_opt_t *opt,
|
|
||||||
ID3D12Device * device,
|
ID3D12Device * device,
|
||||||
|
const struct filter_chain_d3d12_opt_t *options,
|
||||||
libra_d3d12_filter_chain_t *out);
|
libra_d3d12_filter_chain_t *out);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(LIBRA_RUNTIME_D3D12)
|
||||||
|
/// Function pointer definition for
|
||||||
|
///libra_d3d12_filter_chain_create_deferred
|
||||||
|
typedef libra_error_t (*PFN_libra_d3d12_filter_chain_create_deferred)(libra_shader_preset_t *preset,
|
||||||
|
ID3D12Device * device,
|
||||||
|
ID3D12GraphicsCommandList * command_list,
|
||||||
|
const struct filter_chain_d3d12_opt_t *options,
|
||||||
|
libra_d3d12_filter_chain_t *out);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(LIBRA_RUNTIME_D3D12)
|
#if defined(LIBRA_RUNTIME_D3D12)
|
||||||
/// Function pointer definition for
|
/// Function pointer definition for
|
||||||
///libra_d3d12_filter_chain_frame
|
///libra_d3d12_filter_chain_frame
|
||||||
|
@ -905,12 +935,37 @@ libra_error_t libra_gl_filter_chain_free(libra_gl_filter_chain_t *chain);
|
||||||
/// - `preset` must be either null, or valid and aligned.
|
/// - `preset` must be either null, or valid and aligned.
|
||||||
/// - `options` 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.
|
/// - `out` must be aligned, but may be null, invalid, or uninitialized.
|
||||||
libra_error_t libra_vk_filter_chain_create(struct libra_device_vk_t vulkan,
|
libra_error_t libra_vk_filter_chain_create(libra_shader_preset_t *preset,
|
||||||
libra_shader_preset_t *preset,
|
struct libra_device_vk_t vulkan,
|
||||||
const struct filter_chain_vk_opt_t *options,
|
const struct filter_chain_vk_opt_t *options,
|
||||||
libra_vk_filter_chain_t *out);
|
libra_vk_filter_chain_t *out);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(LIBRA_RUNTIME_VULKAN)
|
||||||
|
/// Create the filter chain given the shader preset deferring and GPU-side initialization
|
||||||
|
/// to the caller. This function therefore requires no external synchronization of the device queue.
|
||||||
|
///
|
||||||
|
/// The shader preset is immediately invalidated and must be recreated after
|
||||||
|
/// the filter chain is created.
|
||||||
|
///
|
||||||
|
/// ## Safety:
|
||||||
|
/// - The handles provided in `vulkan` must be valid for the command buffers that
|
||||||
|
/// `libra_vk_filter_chain_frame` will write to. Namely, the VkDevice must have been
|
||||||
|
/// created with the `VK_KHR_dynamic_rendering` extension.
|
||||||
|
/// - `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.
|
||||||
|
///
|
||||||
|
/// The provided command buffer must be ready for recording and contain no prior commands.
|
||||||
|
/// The caller is responsible for ending the command buffer and immediately submitting it to a
|
||||||
|
/// graphics queue. The command buffer must be completely executed before calling `libra_vk_filter_chain_frame`.
|
||||||
|
libra_error_t libra_vk_filter_chain_create_deferred(libra_shader_preset_t *preset,
|
||||||
|
struct libra_device_vk_t vulkan,
|
||||||
|
VkCommandBuffer command_buffer,
|
||||||
|
const struct filter_chain_vk_opt_t *options,
|
||||||
|
libra_vk_filter_chain_t *out);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(LIBRA_RUNTIME_VULKAN)
|
#if defined(LIBRA_RUNTIME_VULKAN)
|
||||||
/// Records rendering commands for a frame with the given parameters for the given filter chain
|
/// Records rendering commands for a frame with the given parameters for the given filter chain
|
||||||
/// to the input command buffer.
|
/// to the input command buffer.
|
||||||
|
@ -1006,11 +1061,43 @@ libra_error_t libra_vk_filter_chain_free(libra_vk_filter_chain_t *chain);
|
||||||
/// - `device` must not be null.
|
/// - `device` must not be null.
|
||||||
/// - `out` must be aligned, but may be null, invalid, or uninitialized.
|
/// - `out` must be aligned, but may be null, invalid, or uninitialized.
|
||||||
libra_error_t libra_d3d11_filter_chain_create(libra_shader_preset_t *preset,
|
libra_error_t libra_d3d11_filter_chain_create(libra_shader_preset_t *preset,
|
||||||
const struct filter_chain_d3d11_opt_t *options,
|
|
||||||
ID3D11Device * device,
|
ID3D11Device * device,
|
||||||
|
const struct filter_chain_d3d11_opt_t *options,
|
||||||
libra_d3d11_filter_chain_t *out);
|
libra_d3d11_filter_chain_t *out);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(LIBRA_RUNTIME_D3D11)
|
||||||
|
/// Create the filter chain given the shader preset, deferring and GPU-side initialization
|
||||||
|
/// to the caller. This function is therefore requires no external synchronization of the
|
||||||
|
/// immediate context, as long as the immediate context is not used as the input context,
|
||||||
|
/// nor of the device, as long as the device is not single-threaded only.
|
||||||
|
///
|
||||||
|
/// 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.
|
||||||
|
/// - `device_context` not be null.
|
||||||
|
/// - `out` must be aligned, but may be null, invalid, or uninitialized.
|
||||||
|
///
|
||||||
|
/// The provided context must either be immediate, or immediately submitted after this function
|
||||||
|
/// returns, **before drawing frames**, or lookup textures will fail to load and the filter chain
|
||||||
|
/// will be in an invalid state.
|
||||||
|
///
|
||||||
|
/// If the context is deferred, it must be ready for command recording, and have no prior commands
|
||||||
|
/// recorded. No commands shall be recorded after, the caller must immediately call [`FinishCommandList`](https://learn.microsoft.com/en-us/windows/win32/api/d3d11/nf-d3d11-id3d11devicecontext-finishcommandlist)
|
||||||
|
/// and execute the command list on the immediate context after this function returns.
|
||||||
|
///
|
||||||
|
/// If the context is immediate, then access to the immediate context requires external synchronization.
|
||||||
|
libra_error_t libra_d3d11_filter_chain_create_deferred(libra_shader_preset_t *preset,
|
||||||
|
ID3D11Device * device,
|
||||||
|
ID3D11DeviceContext * device_context,
|
||||||
|
const struct filter_chain_d3d11_opt_t *options,
|
||||||
|
libra_d3d11_filter_chain_t *out);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(LIBRA_RUNTIME_D3D11)
|
#if defined(LIBRA_RUNTIME_D3D11)
|
||||||
/// Draw a frame with the given parameters for the given filter chain.
|
/// Draw a frame with the given parameters for the given filter chain.
|
||||||
///
|
///
|
||||||
|
@ -1039,7 +1126,7 @@ libra_error_t libra_d3d11_filter_chain_frame(libra_d3d11_filter_chain_t *chain,
|
||||||
struct libra_viewport_t viewport,
|
struct libra_viewport_t viewport,
|
||||||
ID3D11RenderTargetView * out,
|
ID3D11RenderTargetView * out,
|
||||||
const float *mvp,
|
const float *mvp,
|
||||||
const struct frame_d3d11_opt_t *opt);
|
const struct frame_d3d11_opt_t *options);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(LIBRA_RUNTIME_D3D11)
|
#if defined(LIBRA_RUNTIME_D3D11)
|
||||||
|
@ -1105,11 +1192,35 @@ libra_error_t libra_d3d11_filter_chain_free(libra_d3d11_filter_chain_t *chain);
|
||||||
/// - `device` must not be null.
|
/// - `device` must not be null.
|
||||||
/// - `out` must be aligned, but may be null, invalid, or uninitialized.
|
/// - `out` must be aligned, but may be null, invalid, or uninitialized.
|
||||||
libra_error_t libra_d3d12_filter_chain_create(libra_shader_preset_t *preset,
|
libra_error_t libra_d3d12_filter_chain_create(libra_shader_preset_t *preset,
|
||||||
const struct filter_chain_d3d12_opt_t *opt,
|
|
||||||
ID3D12Device * device,
|
ID3D12Device * device,
|
||||||
|
const struct filter_chain_d3d12_opt_t *options,
|
||||||
libra_d3d12_filter_chain_t *out);
|
libra_d3d12_filter_chain_t *out);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(LIBRA_RUNTIME_D3D12)
|
||||||
|
/// Create the filter chain given the shader preset deferring and GPU-side initialization
|
||||||
|
/// to the caller. This function therefore requires no external synchronization of the device queue.
|
||||||
|
///
|
||||||
|
/// 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.
|
||||||
|
/// - `cmd` must not be null.
|
||||||
|
///
|
||||||
|
/// The provided command list must be ready for recording and contain no prior commands.
|
||||||
|
/// The caller is responsible for ending the command list and immediately submitting it to a
|
||||||
|
/// graphics queue. The command list must be completely executed before calling `libra_d3d12_filter_chain_frame`.
|
||||||
|
libra_error_t libra_d3d12_filter_chain_create_deferred(libra_shader_preset_t *preset,
|
||||||
|
ID3D12Device * device,
|
||||||
|
ID3D12GraphicsCommandList * command_list,
|
||||||
|
const struct filter_chain_d3d12_opt_t *options,
|
||||||
|
libra_d3d12_filter_chain_t *out);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(LIBRA_RUNTIME_D3D12)
|
#if defined(LIBRA_RUNTIME_D3D12)
|
||||||
/// Records rendering commands for a frame with the given parameters for the given filter chain
|
/// Records rendering commands for a frame with the given parameters for the given filter chain
|
||||||
/// to the input command list.
|
/// to the input command list.
|
||||||
|
|
|
@ -29,12 +29,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
// Uncomment the following defines to activate runtimes.
|
// Uncomment the following defines to activate runtimes.
|
||||||
|
|
||||||
//#define LIBRA_RUNTIME_OPENGL
|
// #define LIBRA_RUNTIME_OPENGL
|
||||||
//#define LIBRA_RUNTIME_VULKAN
|
// #define LIBRA_RUNTIME_VULKAN
|
||||||
//
|
|
||||||
//#if defined(_WIN32)
|
// #if defined(_WIN32)
|
||||||
//#define LIBRA_RUNTIME_D3D11
|
// #define LIBRA_RUNTIME_D3D11
|
||||||
//#endif
|
// #define LIBRA_RUNTIME_D3D12
|
||||||
|
// #endif
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
@ -153,11 +154,18 @@ libra_error_t __librashader__noop_gl_filter_chain_get_active_pass_count(
|
||||||
|
|
||||||
#if defined(LIBRA_RUNTIME_VULKAN)
|
#if defined(LIBRA_RUNTIME_VULKAN)
|
||||||
libra_error_t __librashader__noop_vk_filter_chain_create(
|
libra_error_t __librashader__noop_vk_filter_chain_create(
|
||||||
struct libra_device_vk_t vulkan, libra_shader_preset_t *preset,
|
libra_shader_preset_t *preset, struct libra_device_vk_t vulkan,
|
||||||
const struct filter_chain_vk_opt_t *options, libra_vk_filter_chain_t *out) {
|
const struct filter_chain_vk_opt_t *options, libra_vk_filter_chain_t *out) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
libra_error_t __librashader__noop_vk_filter_chain_create_deferred(
|
||||||
|
libra_shader_preset_t *preset, struct libra_device_vk_t vulkan,
|
||||||
|
VkCommandBuffer command_buffer, 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_error_t __librashader__noop_vk_filter_chain_frame(
|
||||||
libra_vk_filter_chain_t *chain, VkCommandBuffer command_buffer,
|
libra_vk_filter_chain_t *chain, VkCommandBuffer command_buffer,
|
||||||
size_t frame_count, struct libra_source_image_vk_t image,
|
size_t frame_count, struct libra_source_image_vk_t image,
|
||||||
|
@ -194,8 +202,15 @@ libra_error_t __librashader__noop_vk_filter_chain_get_active_pass_count(
|
||||||
|
|
||||||
#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, ID3D11Device *device,
|
||||||
const struct filter_chain_d3d11_opt_t *options, ID3D11Device *device,
|
const struct filter_chain_d3d11_opt_t *options,
|
||||||
|
libra_d3d11_filter_chain_t *out) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
libra_error_t __librashader__noop_d3d11_filter_chain_create_deferred(
|
||||||
|
libra_shader_preset_t *preset, ID3D11Device *device, ID3D11DeviceContext *device_context,
|
||||||
|
const struct filter_chain_d3d11_opt_t *options,
|
||||||
libra_d3d11_filter_chain_t *out) {
|
libra_d3d11_filter_chain_t *out) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -238,8 +253,16 @@ libra_error_t __librashader__noop_d3d11_filter_chain_get_active_pass_count(
|
||||||
|
|
||||||
#if defined(LIBRA_RUNTIME_D3D12)
|
#if defined(LIBRA_RUNTIME_D3D12)
|
||||||
libra_error_t __librashader__noop_d3d12_filter_chain_create(
|
libra_error_t __librashader__noop_d3d12_filter_chain_create(
|
||||||
libra_shader_preset_t *preset,
|
libra_shader_preset_t *preset, ID3D12Device *device,
|
||||||
const struct filter_chain_d3d12_opt_t *options, ID3D12Device *device,
|
const struct filter_chain_d3d12_opt_t *options,
|
||||||
|
libra_d3d12_filter_chain_t *out) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
libra_error_t __librashader__noop_d3d12_filter_chain_create_deferred(
|
||||||
|
libra_shader_preset_t *preset, ID3D12Device *device,
|
||||||
|
ID3D12GraphicsCommandList *command_list,
|
||||||
|
const struct filter_chain_d3d12_opt_t *options,
|
||||||
libra_d3d12_filter_chain_t *out) {
|
libra_d3d12_filter_chain_t *out) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -505,6 +528,30 @@ typedef struct libra_instance_t {
|
||||||
/// - `out` must be aligned, but may be null, invalid, or uninitialized.
|
/// - `out` must be aligned, but may be null, invalid, or uninitialized.
|
||||||
PFN_libra_vk_filter_chain_create vk_filter_chain_create;
|
PFN_libra_vk_filter_chain_create vk_filter_chain_create;
|
||||||
|
|
||||||
|
/// Create the filter chain given the shader preset deferring and GPU-side
|
||||||
|
/// initialization to the caller. This function therefore requires no
|
||||||
|
/// external synchronization of the device queue.
|
||||||
|
///
|
||||||
|
/// The shader preset is immediately invalidated and must be recreated after
|
||||||
|
/// the filter chain is created.
|
||||||
|
///
|
||||||
|
/// ## Safety:
|
||||||
|
/// - The handles provided in `vulkan` must be valid for the command buffers
|
||||||
|
/// that
|
||||||
|
/// `libra_vk_filter_chain_frame` will write to. Namely, the VkDevice must
|
||||||
|
/// have been
|
||||||
|
/// created with the `VK_KHR_dynamic_rendering` extension.
|
||||||
|
/// - `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.
|
||||||
|
///
|
||||||
|
/// The provided command buffer must be ready for recording and contain no
|
||||||
|
/// prior commands. The caller is responsible for ending the command buffer
|
||||||
|
/// and immediately submitting it to a graphics queue. The command buffer
|
||||||
|
/// must be completely executed before calling
|
||||||
|
/// `libra_vk_filter_chain_frame`.
|
||||||
|
PFN_libra_vk_filter_chain_create_deferred vk_filter_chain_create_deferred;
|
||||||
|
|
||||||
/// Records rendering commands for a frame with the given parameters for the
|
/// Records rendering commands for a frame with the given parameters for the
|
||||||
/// given filter chain
|
/// given filter chain
|
||||||
/// to the input command buffer.
|
/// to the input command buffer.
|
||||||
|
@ -582,6 +629,39 @@ typedef struct libra_instance_t {
|
||||||
/// - `out` must be aligned, but may be null, invalid, or uninitialized.
|
/// - `out` must be aligned, but may be null, invalid, or uninitialized.
|
||||||
PFN_libra_d3d11_filter_chain_create d3d11_filter_chain_create;
|
PFN_libra_d3d11_filter_chain_create d3d11_filter_chain_create;
|
||||||
|
|
||||||
|
/// Create the filter chain given the shader preset, deferring and GPU-side
|
||||||
|
/// initialization
|
||||||
|
/// to the caller. This function is therefore requires no external
|
||||||
|
/// synchronization of the immediate context, as long as the immediate
|
||||||
|
/// context is not used as the input context, nor of the device, as long as
|
||||||
|
/// the device is not single-threaded only.
|
||||||
|
///
|
||||||
|
/// 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.
|
||||||
|
/// - `device_context` not be null.
|
||||||
|
/// - `out` must be aligned, but may be null, invalid, or uninitialized.
|
||||||
|
///
|
||||||
|
/// The provided context must either be immediate, or immediately submitted
|
||||||
|
/// after this function returns, **before drawing frames**, or lookup
|
||||||
|
/// textures will fail to load and the filter chain will be in an invalid
|
||||||
|
/// state.
|
||||||
|
///
|
||||||
|
/// If the context is deferred, it must be ready for command recording, and
|
||||||
|
/// have no prior commands recorded. No commands shall be recorded after,
|
||||||
|
/// the caller must immediately call
|
||||||
|
/// [`FinishCommandList`](https://learn.microsoft.com/en-us/windows/win32/api/d3d11/nf-d3d11-id3d11devicecontext-finishcommandlist)
|
||||||
|
/// and execute the command list on the immediate context after this
|
||||||
|
/// function returns.
|
||||||
|
///
|
||||||
|
/// If the context is immediate, then access to the immediate context
|
||||||
|
/// requires external synchronization.
|
||||||
|
PFN_libra_d3d11_filter_chain_create_deferred d3d11_filter_chain_create_deferred;
|
||||||
|
|
||||||
/// Draw a frame with the given parameters for the given filter chain.
|
/// Draw a frame with the given parameters for the given filter chain.
|
||||||
///
|
///
|
||||||
/// ## Safety
|
/// ## Safety
|
||||||
|
@ -652,6 +732,27 @@ typedef struct libra_instance_t {
|
||||||
/// - `out` must be aligned, but may be null, invalid, or uninitialized.
|
/// - `out` must be aligned, but may be null, invalid, or uninitialized.
|
||||||
PFN_libra_d3d12_filter_chain_create d3d12_filter_chain_create;
|
PFN_libra_d3d12_filter_chain_create d3d12_filter_chain_create;
|
||||||
|
|
||||||
|
/// Create the filter chain given the shader preset deferring and GPU-side
|
||||||
|
/// initialization
|
||||||
|
/// to the caller. This function therefore requires no external
|
||||||
|
/// synchronization of the device queue.
|
||||||
|
///
|
||||||
|
/// 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.
|
||||||
|
/// - `cmd` must not be null.
|
||||||
|
///
|
||||||
|
/// The provided command list must be ready for recording and contain no
|
||||||
|
/// prior commands. The caller is responsible for ending the command list
|
||||||
|
/// and immediately submitting it to a graphics queue. The command list must
|
||||||
|
/// be completely executed before calling `libra_d3d12_filter_chain_frame`
|
||||||
|
PFN_libra_d3d12_filter_chain_create_deferred d3d12_filter_chain_create_deferred;
|
||||||
|
|
||||||
/// Draw a frame with the given parameters for the given filter chain.
|
/// Draw a frame with the given parameters for the given filter chain.
|
||||||
///
|
///
|
||||||
/// ## Safety
|
/// ## Safety
|
||||||
|
@ -747,6 +848,7 @@ libra_instance_t __librashader_make_null_instance() {
|
||||||
|
|
||||||
#if defined(LIBRA_RUNTIME_VULKAN)
|
#if defined(LIBRA_RUNTIME_VULKAN)
|
||||||
.vk_filter_chain_create = __librashader__noop_vk_filter_chain_create,
|
.vk_filter_chain_create = __librashader__noop_vk_filter_chain_create,
|
||||||
|
.vk_filter_chain_create_deferred = __librashader__noop_vk_filter_chain_create_deferred,
|
||||||
.vk_filter_chain_frame = __librashader__noop_vk_filter_chain_frame,
|
.vk_filter_chain_frame = __librashader__noop_vk_filter_chain_frame,
|
||||||
.vk_filter_chain_free = __librashader__noop_vk_filter_chain_free,
|
.vk_filter_chain_free = __librashader__noop_vk_filter_chain_free,
|
||||||
.vk_filter_chain_get_active_pass_count =
|
.vk_filter_chain_get_active_pass_count =
|
||||||
|
@ -762,6 +864,8 @@ libra_instance_t __librashader_make_null_instance() {
|
||||||
#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,
|
||||||
|
.d3d11_filter_chain_create_deferred =
|
||||||
|
__librashader__noop_d3d11_filter_chain_create_deferred,
|
||||||
.d3d11_filter_chain_frame =
|
.d3d11_filter_chain_frame =
|
||||||
__librashader__noop_d3d11_filter_chain_frame,
|
__librashader__noop_d3d11_filter_chain_frame,
|
||||||
.d3d11_filter_chain_free = __librashader__noop_d3d11_filter_chain_free,
|
.d3d11_filter_chain_free = __librashader__noop_d3d11_filter_chain_free,
|
||||||
|
@ -778,6 +882,8 @@ libra_instance_t __librashader_make_null_instance() {
|
||||||
#if defined(LIBRA_RUNTIME_D3D12)
|
#if defined(LIBRA_RUNTIME_D3D12)
|
||||||
.d3d12_filter_chain_create =
|
.d3d12_filter_chain_create =
|
||||||
__librashader__noop_d3d12_filter_chain_create,
|
__librashader__noop_d3d12_filter_chain_create,
|
||||||
|
.d3d12_filter_chain_create_deferred =
|
||||||
|
__librashader__noop_d3d12_filter_chain_create_deferred,
|
||||||
.d3d12_filter_chain_frame =
|
.d3d12_filter_chain_frame =
|
||||||
__librashader__noop_d3d12_filter_chain_frame,
|
__librashader__noop_d3d12_filter_chain_frame,
|
||||||
.d3d12_filter_chain_free = __librashader__noop_d3d12_filter_chain_free,
|
.d3d12_filter_chain_free = __librashader__noop_d3d12_filter_chain_free,
|
||||||
|
@ -849,6 +955,7 @@ libra_instance_t librashader_load_instance() {
|
||||||
|
|
||||||
#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_create_deferred);
|
||||||
_LIBRASHADER_ASSIGN(librashader, instance, vk_filter_chain_frame);
|
_LIBRASHADER_ASSIGN(librashader, instance, vk_filter_chain_frame);
|
||||||
_LIBRASHADER_ASSIGN(librashader, instance, vk_filter_chain_free);
|
_LIBRASHADER_ASSIGN(librashader, instance, vk_filter_chain_free);
|
||||||
_LIBRASHADER_ASSIGN(librashader, instance,
|
_LIBRASHADER_ASSIGN(librashader, instance,
|
||||||
|
@ -863,6 +970,7 @@ libra_instance_t librashader_load_instance() {
|
||||||
|
|
||||||
#if defined(_WIN32) && defined(LIBRA_RUNTIME_D3D11)
|
#if defined(_WIN32) && defined(LIBRA_RUNTIME_D3D11)
|
||||||
_LIBRASHADER_ASSIGN(librashader, instance, d3d11_filter_chain_create);
|
_LIBRASHADER_ASSIGN(librashader, instance, d3d11_filter_chain_create);
|
||||||
|
_LIBRASHADER_ASSIGN(librashader, instance, d3d11_filter_chain_create_deferred);
|
||||||
_LIBRASHADER_ASSIGN(librashader, instance, d3d11_filter_chain_frame);
|
_LIBRASHADER_ASSIGN(librashader, instance, d3d11_filter_chain_frame);
|
||||||
_LIBRASHADER_ASSIGN(librashader, instance, d3d11_filter_chain_free);
|
_LIBRASHADER_ASSIGN(librashader, instance, d3d11_filter_chain_free);
|
||||||
_LIBRASHADER_ASSIGN(librashader, instance, d3d11_filter_chain_get_param);
|
_LIBRASHADER_ASSIGN(librashader, instance, d3d11_filter_chain_get_param);
|
||||||
|
@ -875,6 +983,7 @@ libra_instance_t librashader_load_instance() {
|
||||||
|
|
||||||
#if defined(_WIN32) && defined(LIBRA_RUNTIME_D3D12)
|
#if defined(_WIN32) && defined(LIBRA_RUNTIME_D3D12)
|
||||||
_LIBRASHADER_ASSIGN(librashader, instance, d3d12_filter_chain_create);
|
_LIBRASHADER_ASSIGN(librashader, instance, d3d12_filter_chain_create);
|
||||||
|
_LIBRASHADER_ASSIGN(librashader, instance, d3d12_filter_chain_create_deferred);
|
||||||
_LIBRASHADER_ASSIGN(librashader, instance, d3d12_filter_chain_frame);
|
_LIBRASHADER_ASSIGN(librashader, instance, d3d12_filter_chain_frame);
|
||||||
_LIBRASHADER_ASSIGN(librashader, instance, d3d12_filter_chain_free);
|
_LIBRASHADER_ASSIGN(librashader, instance, d3d12_filter_chain_free);
|
||||||
_LIBRASHADER_ASSIGN(librashader, instance, d3d12_filter_chain_get_param);
|
_LIBRASHADER_ASSIGN(librashader, instance, d3d12_filter_chain_get_param);
|
||||||
|
|
|
@ -115,6 +115,7 @@ include = [
|
||||||
|
|
||||||
# vulkan
|
# vulkan
|
||||||
"PFN_libra_vk_filter_chain_create",
|
"PFN_libra_vk_filter_chain_create",
|
||||||
|
"PFN_libra_vk_filter_chain_create_deferred",
|
||||||
"PFN_libra_vk_filter_chain_frame",
|
"PFN_libra_vk_filter_chain_frame",
|
||||||
"PFN_libra_vk_filter_chain_set_param",
|
"PFN_libra_vk_filter_chain_set_param",
|
||||||
"PFN_libra_vk_filter_chain_get_param",
|
"PFN_libra_vk_filter_chain_get_param",
|
||||||
|
@ -124,6 +125,7 @@ include = [
|
||||||
|
|
||||||
# d3d11
|
# d3d11
|
||||||
"PFN_libra_d3d11_filter_chain_create",
|
"PFN_libra_d3d11_filter_chain_create",
|
||||||
|
"PFN_libra_d3d11_filter_chain_create_deferred",
|
||||||
"PFN_libra_d3d11_filter_chain_frame",
|
"PFN_libra_d3d11_filter_chain_frame",
|
||||||
"PFN_libra_d3d11_filter_chain_set_param",
|
"PFN_libra_d3d11_filter_chain_set_param",
|
||||||
"PFN_libra_d3d11_filter_chain_get_param",
|
"PFN_libra_d3d11_filter_chain_get_param",
|
||||||
|
@ -132,8 +134,9 @@ include = [
|
||||||
"PFN_libra_d3d11_filter_chain_free",
|
"PFN_libra_d3d11_filter_chain_free",
|
||||||
|
|
||||||
|
|
||||||
# d3d11
|
# d3d12
|
||||||
"PFN_libra_d3d12_filter_chain_create",
|
"PFN_libra_d3d12_filter_chain_create",
|
||||||
|
"PFN_libra_d3d12_filter_chain_create_deferred",
|
||||||
"PFN_libra_d3d12_filter_chain_frame",
|
"PFN_libra_d3d12_filter_chain_frame",
|
||||||
"PFN_libra_d3d12_filter_chain_set_param",
|
"PFN_libra_d3d12_filter_chain_set_param",
|
||||||
"PFN_libra_d3d12_filter_chain_get_param",
|
"PFN_libra_d3d12_filter_chain_get_param",
|
||||||
|
|
|
@ -92,8 +92,8 @@ extern_fn! {
|
||||||
/// - `out` must be aligned, but may be null, invalid, or uninitialized.
|
/// - `out` must be aligned, but may be null, invalid, or uninitialized.
|
||||||
fn libra_d3d11_filter_chain_create(
|
fn libra_d3d11_filter_chain_create(
|
||||||
preset: *mut libra_shader_preset_t,
|
preset: *mut libra_shader_preset_t,
|
||||||
options: *const MaybeUninit<filter_chain_d3d11_opt_t>,
|
|
||||||
device: ManuallyDrop<ID3D11Device>,
|
device: ManuallyDrop<ID3D11Device>,
|
||||||
|
options: *const MaybeUninit<filter_chain_d3d11_opt_t>,
|
||||||
out: *mut MaybeUninit<libra_d3d11_filter_chain_t>
|
out: *mut MaybeUninit<libra_d3d11_filter_chain_t>
|
||||||
) {
|
) {
|
||||||
assert_non_null!(preset);
|
assert_non_null!(preset);
|
||||||
|
@ -111,8 +111,8 @@ extern_fn! {
|
||||||
|
|
||||||
let options = options.map(FromUninit::from_uninit);
|
let options = options.map(FromUninit::from_uninit);
|
||||||
let chain = librashader::runtime::d3d11::capi::FilterChainD3D11::load_from_preset(
|
let chain = librashader::runtime::d3d11::capi::FilterChainD3D11::load_from_preset(
|
||||||
&device,
|
|
||||||
*preset,
|
*preset,
|
||||||
|
&device,
|
||||||
options.as_ref(),
|
options.as_ref(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -124,6 +124,69 @@ extern_fn! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern_fn! {
|
||||||
|
/// Create the filter chain given the shader preset, deferring and GPU-side initialization
|
||||||
|
/// to the caller. This function is therefore requires no external synchronization of the
|
||||||
|
/// immediate context, as long as the immediate context is not used as the input context,
|
||||||
|
/// nor of the device, as long as the device is not single-threaded only.
|
||||||
|
///
|
||||||
|
/// 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.
|
||||||
|
/// - `device_context` not be null.
|
||||||
|
/// - `out` must be aligned, but may be null, invalid, or uninitialized.
|
||||||
|
///
|
||||||
|
/// The provided context must either be immediate, or immediately submitted after this function
|
||||||
|
/// returns, **before drawing frames**, or lookup textures will fail to load and the filter chain
|
||||||
|
/// will be in an invalid state.
|
||||||
|
///
|
||||||
|
/// If the context is deferred, it must be ready for command recording, and have no prior commands
|
||||||
|
/// recorded. No commands shall be recorded after, the caller must immediately call [`FinishCommandList`](https://learn.microsoft.com/en-us/windows/win32/api/d3d11/nf-d3d11-id3d11devicecontext-finishcommandlist)
|
||||||
|
/// and execute the command list on the immediate context after this function returns.
|
||||||
|
///
|
||||||
|
/// If the context is immediate, then access to the immediate context requires external synchronization.
|
||||||
|
fn libra_d3d11_filter_chain_create_deferred(
|
||||||
|
preset: *mut libra_shader_preset_t,
|
||||||
|
device: ManuallyDrop<ID3D11Device>,
|
||||||
|
device_context: ManuallyDrop<ID3D11DeviceContext>,
|
||||||
|
options: *const MaybeUninit<filter_chain_d3d11_opt_t>,
|
||||||
|
out: *mut MaybeUninit<libra_d3d11_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.read() })
|
||||||
|
};
|
||||||
|
|
||||||
|
let options = options.map(FromUninit::from_uninit);
|
||||||
|
let chain = unsafe {
|
||||||
|
librashader::runtime::d3d11::capi::FilterChainD3D11::load_from_preset_deferred(
|
||||||
|
*preset,
|
||||||
|
&device,
|
||||||
|
&device_context,
|
||||||
|
options.as_ref(),
|
||||||
|
)?
|
||||||
|
};
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(
|
||||||
|
chain,
|
||||||
|
)))))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This assert ensures that the bindings of Option<ManuallyDrop<ID3D11DeviceContext>> to ID3D11DeviceContext* is sound.
|
// This assert ensures that the bindings of Option<ManuallyDrop<ID3D11DeviceContext>> to ID3D11DeviceContext* is sound.
|
||||||
const _: () = assert!(
|
const _: () = assert!(
|
||||||
std::mem::size_of::<ID3D11DeviceContext>()
|
std::mem::size_of::<ID3D11DeviceContext>()
|
||||||
|
@ -162,7 +225,7 @@ extern_fn! {
|
||||||
viewport: libra_viewport_t,
|
viewport: libra_viewport_t,
|
||||||
out: ManuallyDrop<ID3D11RenderTargetView>,
|
out: ManuallyDrop<ID3D11RenderTargetView>,
|
||||||
mvp: *const f32,
|
mvp: *const f32,
|
||||||
opt: *const MaybeUninit<frame_d3d11_opt_t>
|
options: *const MaybeUninit<frame_d3d11_opt_t>
|
||||||
) mut |chain| {
|
) mut |chain| {
|
||||||
assert_some_ptr!(mut chain);
|
assert_some_ptr!(mut chain);
|
||||||
|
|
||||||
|
@ -172,10 +235,10 @@ extern_fn! {
|
||||||
Some(<&[f32; 16]>::try_from(unsafe { slice::from_raw_parts(mvp, 16) }).unwrap())
|
Some(<&[f32; 16]>::try_from(unsafe { slice::from_raw_parts(mvp, 16) }).unwrap())
|
||||||
};
|
};
|
||||||
|
|
||||||
let opt = if opt.is_null() {
|
let options = if options.is_null() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(unsafe { opt.read() })
|
Some(unsafe { options.read() })
|
||||||
};
|
};
|
||||||
|
|
||||||
let viewport = Viewport {
|
let viewport = Viewport {
|
||||||
|
@ -188,10 +251,10 @@ extern_fn! {
|
||||||
mvp,
|
mvp,
|
||||||
};
|
};
|
||||||
|
|
||||||
let opt = opt.map(FromUninit::from_uninit);
|
let options = options.map(FromUninit::from_uninit);
|
||||||
|
|
||||||
let image = image.try_into()?;
|
let image = image.try_into()?;
|
||||||
chain.frame(device_context.as_deref(), image, &viewport, frame_count, opt.as_ref())?;
|
chain.frame(device_context.as_deref(), image, &viewport, frame_count, options.as_ref())?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -113,8 +113,8 @@ extern_fn! {
|
||||||
/// - `out` must be aligned, but may be null, invalid, or uninitialized.
|
/// - `out` must be aligned, but may be null, invalid, or uninitialized.
|
||||||
fn libra_d3d12_filter_chain_create(
|
fn libra_d3d12_filter_chain_create(
|
||||||
preset: *mut libra_shader_preset_t,
|
preset: *mut libra_shader_preset_t,
|
||||||
opt: *const MaybeUninit<filter_chain_d3d12_opt_t>,
|
|
||||||
device: ManuallyDrop<ID3D12Device>,
|
device: ManuallyDrop<ID3D12Device>,
|
||||||
|
options: *const MaybeUninit<filter_chain_d3d12_opt_t>,
|
||||||
out: *mut MaybeUninit<libra_d3d12_filter_chain_t>
|
out: *mut MaybeUninit<libra_d3d12_filter_chain_t>
|
||||||
) {
|
) {
|
||||||
assert_non_null!(preset);
|
assert_non_null!(preset);
|
||||||
|
@ -124,17 +124,17 @@ extern_fn! {
|
||||||
Box::from_raw(preset.unwrap().as_ptr())
|
Box::from_raw(preset.unwrap().as_ptr())
|
||||||
};
|
};
|
||||||
|
|
||||||
let opt = if opt.is_null() {
|
let options = if options.is_null() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(unsafe { opt.read() })
|
Some(unsafe { options.read() })
|
||||||
};
|
};
|
||||||
|
|
||||||
let opt = opt.map(FromUninit::from_uninit);
|
let options = options.map(FromUninit::from_uninit);
|
||||||
let chain = librashader::runtime::d3d12::capi::FilterChainD3D12::load_from_preset(
|
let chain = librashader::runtime::d3d12::capi::FilterChainD3D12::load_from_preset(
|
||||||
&device,
|
|
||||||
*preset,
|
*preset,
|
||||||
opt.as_ref(),
|
&device,
|
||||||
|
options.as_ref(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -145,6 +145,61 @@ extern_fn! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern_fn! {
|
||||||
|
/// Create the filter chain given the shader preset deferring and GPU-side initialization
|
||||||
|
/// to the caller. This function therefore requires no external synchronization of the device queue.
|
||||||
|
///
|
||||||
|
/// 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.
|
||||||
|
/// - `cmd` must not be null.
|
||||||
|
///
|
||||||
|
/// The provided command list must be ready for recording and contain no prior commands.
|
||||||
|
/// The caller is responsible for ending the command list and immediately submitting it to a
|
||||||
|
/// graphics queue. The command list must be completely executed before calling `libra_d3d12_filter_chain_frame`.
|
||||||
|
fn libra_d3d12_filter_chain_create_deferred(
|
||||||
|
preset: *mut libra_shader_preset_t,
|
||||||
|
device: ManuallyDrop<ID3D12Device>,
|
||||||
|
command_list: ManuallyDrop<ID3D12GraphicsCommandList>,
|
||||||
|
options: *const MaybeUninit<filter_chain_d3d12_opt_t>,
|
||||||
|
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.read() })
|
||||||
|
};
|
||||||
|
|
||||||
|
let options = options.map(FromUninit::from_uninit);
|
||||||
|
let chain = unsafe {
|
||||||
|
librashader::runtime::d3d12::capi::FilterChainD3D12::load_from_preset_deferred(
|
||||||
|
*preset,
|
||||||
|
&device,
|
||||||
|
&command_list,
|
||||||
|
options.as_ref(),
|
||||||
|
)?
|
||||||
|
};
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(
|
||||||
|
chain,
|
||||||
|
)))))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extern_fn! {
|
extern_fn! {
|
||||||
/// Records rendering commands for a frame with the given parameters for the given filter chain
|
/// Records rendering commands for a frame with the given parameters for the given filter chain
|
||||||
/// to the input command list.
|
/// to the input command list.
|
||||||
|
|
|
@ -136,8 +136,8 @@ extern_fn! {
|
||||||
/// - `options` 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.
|
/// - `out` must be aligned, but may be null, invalid, or uninitialized.
|
||||||
fn libra_vk_filter_chain_create(
|
fn libra_vk_filter_chain_create(
|
||||||
vulkan: libra_device_vk_t,
|
|
||||||
preset: *mut libra_shader_preset_t,
|
preset: *mut libra_shader_preset_t,
|
||||||
|
vulkan: libra_device_vk_t,
|
||||||
options: *const MaybeUninit<filter_chain_vk_opt_t>,
|
options: *const MaybeUninit<filter_chain_vk_opt_t>,
|
||||||
out: *mut MaybeUninit<libra_vk_filter_chain_t>
|
out: *mut MaybeUninit<libra_vk_filter_chain_t>
|
||||||
) {
|
) {
|
||||||
|
@ -157,7 +157,63 @@ extern_fn! {
|
||||||
let vulkan: VulkanInstance = vulkan.into();
|
let vulkan: VulkanInstance = vulkan.into();
|
||||||
let options = options.map(FromUninit::from_uninit);
|
let options = options.map(FromUninit::from_uninit);
|
||||||
|
|
||||||
let chain = librashader::runtime::vk::capi::FilterChainVulkan::load_from_preset(vulkan, *preset, options.as_ref())?;
|
let chain = librashader::runtime::vk::capi::FilterChainVulkan::load_from_preset(*preset, vulkan, options.as_ref())?;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(
|
||||||
|
chain,
|
||||||
|
)))))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern_fn! {
|
||||||
|
/// Create the filter chain given the shader preset deferring and GPU-side initialization
|
||||||
|
/// to the caller. This function therefore requires no external synchronization of the device queue.
|
||||||
|
///
|
||||||
|
/// The shader preset is immediately invalidated and must be recreated after
|
||||||
|
/// the filter chain is created.
|
||||||
|
///
|
||||||
|
/// ## Safety:
|
||||||
|
/// - The handles provided in `vulkan` must be valid for the command buffers that
|
||||||
|
/// `libra_vk_filter_chain_frame` will write to. Namely, the VkDevice must have been
|
||||||
|
/// created with the `VK_KHR_dynamic_rendering` extension.
|
||||||
|
/// - `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.
|
||||||
|
///
|
||||||
|
/// The provided command buffer must be ready for recording and contain no prior commands.
|
||||||
|
/// The caller is responsible for ending the command buffer and immediately submitting it to a
|
||||||
|
/// graphics queue. The command buffer must be completely executed before calling `libra_vk_filter_chain_frame`.
|
||||||
|
fn libra_vk_filter_chain_create_deferred(
|
||||||
|
preset: *mut libra_shader_preset_t,
|
||||||
|
vulkan: libra_device_vk_t,
|
||||||
|
command_buffer: vk::CommandBuffer,
|
||||||
|
options: *const MaybeUninit<filter_chain_vk_opt_t>,
|
||||||
|
out: *mut MaybeUninit<libra_vk_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.read() })
|
||||||
|
};
|
||||||
|
|
||||||
|
let vulkan: VulkanInstance = vulkan.into();
|
||||||
|
let options = options.map(FromUninit::from_uninit);
|
||||||
|
|
||||||
|
let chain = unsafe {
|
||||||
|
librashader::runtime::vk::capi::FilterChainVulkan::load_from_preset_deferred(*preset,
|
||||||
|
vulkan,
|
||||||
|
command_buffer,
|
||||||
|
options.as_ref())?
|
||||||
|
};
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(
|
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(
|
||||||
|
|
|
@ -76,23 +76,23 @@ pub(crate) struct FilterCommon {
|
||||||
impl FilterChainD3D11 {
|
impl FilterChainD3D11 {
|
||||||
/// Load the shader preset at the given path into a filter chain.
|
/// Load the shader preset at the given path into a filter chain.
|
||||||
pub fn load_from_path(
|
pub fn load_from_path(
|
||||||
device: &ID3D11Device,
|
|
||||||
path: impl AsRef<Path>,
|
path: impl AsRef<Path>,
|
||||||
|
device: &ID3D11Device,
|
||||||
options: Option<&FilterChainOptionsD3D11>,
|
options: Option<&FilterChainOptionsD3D11>,
|
||||||
) -> error::Result<FilterChainD3D11> {
|
) -> error::Result<FilterChainD3D11> {
|
||||||
// load passes from preset
|
// load passes from preset
|
||||||
let preset = ShaderPreset::try_parse(path)?;
|
let preset = ShaderPreset::try_parse(path)?;
|
||||||
Self::load_from_preset(device, preset, options)
|
Self::load_from_preset(preset, device, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
||||||
pub fn load_from_preset(
|
pub fn load_from_preset(
|
||||||
device: &ID3D11Device,
|
|
||||||
preset: ShaderPreset,
|
preset: ShaderPreset,
|
||||||
|
device: &ID3D11Device,
|
||||||
options: Option<&FilterChainOptionsD3D11>,
|
options: Option<&FilterChainOptionsD3D11>,
|
||||||
) -> error::Result<FilterChainD3D11> {
|
) -> error::Result<FilterChainD3D11> {
|
||||||
let immediate_context = unsafe { device.GetImmediateContext()? };
|
let immediate_context = unsafe { device.GetImmediateContext()? };
|
||||||
unsafe { Self::load_from_preset_deferred(device, preset, &immediate_context, options) }
|
unsafe { Self::load_from_preset_deferred(preset, device, &immediate_context, options) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Load a filter chain from a pre-parsed `ShaderPreset`, deferring and GPU-side initialization
|
/// Load a filter chain from a pre-parsed `ShaderPreset`, deferring and GPU-side initialization
|
||||||
|
@ -111,8 +111,8 @@ impl FilterChainD3D11 {
|
||||||
///
|
///
|
||||||
/// If the context is immediate, then access to the immediate context requires external synchronization.
|
/// If the context is immediate, then access to the immediate context requires external synchronization.
|
||||||
pub unsafe fn load_from_preset_deferred(
|
pub unsafe fn load_from_preset_deferred(
|
||||||
device: &ID3D11Device,
|
|
||||||
preset: ShaderPreset,
|
preset: ShaderPreset,
|
||||||
|
device: &ID3D11Device,
|
||||||
ctx: &ID3D11DeviceContext,
|
ctx: &ID3D11DeviceContext,
|
||||||
options: Option<&FilterChainOptionsD3D11>,
|
options: Option<&FilterChainOptionsD3D11>,
|
||||||
) -> error::Result<FilterChainD3D11> {
|
) -> error::Result<FilterChainD3D11> {
|
||||||
|
|
|
@ -290,7 +290,7 @@ pub mod d3d11_hello_triangle {
|
||||||
image: Option<Image>,
|
image: Option<Image>,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let (dxgi_factory, device, context) = create_device()?;
|
let (dxgi_factory, device, context) = create_device()?;
|
||||||
let filter = FilterChainD3D11::load_from_path(&device, filter, filter_options).unwrap();
|
let filter = FilterChainD3D11::load_from_path(filter, &device, filter_options).unwrap();
|
||||||
let lut = if let Some(image) = image {
|
let lut = if let Some(image) = image {
|
||||||
let lut = LutTexture::new(
|
let lut = LutTexture::new(
|
||||||
&device,
|
&device,
|
||||||
|
|
|
@ -141,19 +141,19 @@ impl Drop for FrameResiduals {
|
||||||
impl FilterChainD3D12 {
|
impl FilterChainD3D12 {
|
||||||
/// Load the shader preset at the given path into a filter chain.
|
/// Load the shader preset at the given path into a filter chain.
|
||||||
pub fn load_from_path(
|
pub fn load_from_path(
|
||||||
device: &ID3D12Device,
|
|
||||||
path: impl AsRef<Path>,
|
path: impl AsRef<Path>,
|
||||||
|
device: &ID3D12Device,
|
||||||
options: Option<&FilterChainOptionsD3D12>,
|
options: Option<&FilterChainOptionsD3D12>,
|
||||||
) -> error::Result<FilterChainD3D12> {
|
) -> error::Result<FilterChainD3D12> {
|
||||||
// load passes from preset
|
// load passes from preset
|
||||||
let preset = ShaderPreset::try_parse(path)?;
|
let preset = ShaderPreset::try_parse(path)?;
|
||||||
Self::load_from_preset(device, preset, options)
|
Self::load_from_preset(preset, device, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
||||||
pub fn load_from_preset(
|
pub fn load_from_preset(
|
||||||
device: &ID3D12Device,
|
|
||||||
preset: ShaderPreset,
|
preset: ShaderPreset,
|
||||||
|
device: &ID3D12Device,
|
||||||
options: Option<&FilterChainOptionsD3D12>,
|
options: Option<&FilterChainOptionsD3D12>,
|
||||||
) -> error::Result<FilterChainD3D12> {
|
) -> error::Result<FilterChainD3D12> {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -173,7 +173,7 @@ impl FilterChainD3D12 {
|
||||||
let fence_event = CreateEventA(None, false, false, None)?;
|
let fence_event = CreateEventA(None, false, false, None)?;
|
||||||
let fence: ID3D12Fence = device.CreateFence(0, D3D12_FENCE_FLAG_NONE)?;
|
let fence: ID3D12Fence = device.CreateFence(0, D3D12_FENCE_FLAG_NONE)?;
|
||||||
|
|
||||||
let filter_chain = Self::load_from_preset_deferred(device, preset, &cmd, options)?;
|
let filter_chain = Self::load_from_preset_deferred(preset, device, &cmd, options)?;
|
||||||
|
|
||||||
cmd.Close()?;
|
cmd.Close()?;
|
||||||
queue.ExecuteCommandLists(&[cmd.cast()?]);
|
queue.ExecuteCommandLists(&[cmd.cast()?]);
|
||||||
|
@ -197,8 +197,8 @@ impl FilterChainD3D12 {
|
||||||
/// The caller is responsible for ending the command list and immediately submitting it to a
|
/// The caller is responsible for ending the command list and immediately submitting it to a
|
||||||
/// graphics queue. The command list must be completely executed before calling [`frame`](Self::frame).
|
/// graphics queue. The command list must be completely executed before calling [`frame`](Self::frame).
|
||||||
pub unsafe fn load_from_preset_deferred(
|
pub unsafe fn load_from_preset_deferred(
|
||||||
device: &ID3D12Device,
|
|
||||||
preset: ShaderPreset,
|
preset: ShaderPreset,
|
||||||
|
device: &ID3D12Device,
|
||||||
cmd: &ID3D12GraphicsCommandList,
|
cmd: &ID3D12GraphicsCommandList,
|
||||||
options: Option<&FilterChainOptionsD3D12>,
|
options: Option<&FilterChainOptionsD3D12>,
|
||||||
) -> error::Result<FilterChainD3D12> {
|
) -> error::Result<FilterChainD3D12> {
|
||||||
|
|
|
@ -287,7 +287,7 @@ pub mod d3d12_hello_triangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let filter = FilterChainD3D12::load_from_path(&device, filter, None).unwrap();
|
let filter = FilterChainD3D12::load_from_path(filter, &device, None).unwrap();
|
||||||
|
|
||||||
Ok(Sample {
|
Ok(Sample {
|
||||||
dxgi_factory,
|
dxgi_factory,
|
||||||
|
|
|
@ -220,8 +220,8 @@ impl Drop for FrameResiduals {
|
||||||
impl FilterChainVulkan {
|
impl FilterChainVulkan {
|
||||||
/// Load the shader preset at the given path into a filter chain.
|
/// Load the shader preset at the given path into a filter chain.
|
||||||
pub fn load_from_path<V, E>(
|
pub fn load_from_path<V, E>(
|
||||||
vulkan: V,
|
|
||||||
path: impl AsRef<Path>,
|
path: impl AsRef<Path>,
|
||||||
|
vulkan: V,
|
||||||
options: Option<&FilterChainOptionsVulkan>,
|
options: Option<&FilterChainOptionsVulkan>,
|
||||||
) -> error::Result<FilterChainVulkan>
|
) -> error::Result<FilterChainVulkan>
|
||||||
where
|
where
|
||||||
|
@ -230,13 +230,13 @@ impl FilterChainVulkan {
|
||||||
{
|
{
|
||||||
// load passes from preset
|
// load passes from preset
|
||||||
let preset = ShaderPreset::try_parse(path)?;
|
let preset = ShaderPreset::try_parse(path)?;
|
||||||
Self::load_from_preset(vulkan, preset, options)
|
Self::load_from_preset(preset, vulkan, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
||||||
pub fn load_from_preset<V, E>(
|
pub fn load_from_preset<V, E>(
|
||||||
vulkan: V,
|
|
||||||
preset: ShaderPreset,
|
preset: ShaderPreset,
|
||||||
|
vulkan: V,
|
||||||
options: Option<&FilterChainOptionsVulkan>,
|
options: Option<&FilterChainOptionsVulkan>,
|
||||||
) -> error::Result<FilterChainVulkan>
|
) -> error::Result<FilterChainVulkan>
|
||||||
where
|
where
|
||||||
|
@ -278,8 +278,8 @@ impl FilterChainVulkan {
|
||||||
|
|
||||||
let filter_chain = unsafe {
|
let filter_chain = unsafe {
|
||||||
Self::load_from_preset_deferred::<_, Infallible>(
|
Self::load_from_preset_deferred::<_, Infallible>(
|
||||||
vulkan,
|
|
||||||
preset,
|
preset,
|
||||||
|
vulkan,
|
||||||
command_buffer,
|
command_buffer,
|
||||||
options,
|
options,
|
||||||
)?
|
)?
|
||||||
|
@ -308,8 +308,8 @@ impl FilterChainVulkan {
|
||||||
/// The caller is responsible for ending the command buffer and immediately submitting it to a
|
/// The caller is responsible for ending the command buffer and immediately submitting it to a
|
||||||
/// graphics queue. The command buffer must be completely executed before calling [`frame`](Self::frame).
|
/// graphics queue. The command buffer must be completely executed before calling [`frame`](Self::frame).
|
||||||
pub unsafe fn load_from_preset_deferred<V, E>(
|
pub unsafe fn load_from_preset_deferred<V, E>(
|
||||||
vulkan: V,
|
|
||||||
preset: ShaderPreset,
|
preset: ShaderPreset,
|
||||||
|
vulkan: V,
|
||||||
cmd: vk::CommandBuffer,
|
cmd: vk::CommandBuffer,
|
||||||
options: Option<&FilterChainOptionsVulkan>,
|
options: Option<&FilterChainOptionsVulkan>,
|
||||||
) -> error::Result<FilterChainVulkan>
|
) -> error::Result<FilterChainVulkan>
|
||||||
|
|
|
@ -42,9 +42,9 @@ mod tests {
|
||||||
let entry = unsafe { ash::Entry::load().unwrap() };
|
let entry = unsafe { ash::Entry::load().unwrap() };
|
||||||
let base = VulkanBase::new(entry).unwrap();
|
let base = VulkanBase::new(entry).unwrap();
|
||||||
let filter = FilterChainVulkan::load_from_path(
|
let filter = FilterChainVulkan::load_from_path(
|
||||||
&base,
|
|
||||||
// "../test/slang-shaders/crt/crt-royale.slangp",
|
// "../test/slang-shaders/crt/crt-royale.slangp",
|
||||||
"../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV-GLASS.slangp",
|
"../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV-GLASS.slangp",
|
||||||
|
&base,
|
||||||
// "../test/slang-shaders/test/feedback.slancargogp",
|
// "../test/slang-shaders/test/feedback.slancargogp",
|
||||||
// "../test/basic.slangp",
|
// "../test/basic.slangp",
|
||||||
Some(&FilterChainOptionsVulkan {
|
Some(&FilterChainOptionsVulkan {
|
||||||
|
|
|
@ -74,7 +74,8 @@ int main(int, char**)
|
||||||
.force_no_mipmaps = false,
|
.force_no_mipmaps = false,
|
||||||
};
|
};
|
||||||
|
|
||||||
libra.d3d11_filter_chain_create(&preset, &opt, g_pd3dDevice, &filter_chain);
|
libra.d3d11_filter_chain_create_deferred(
|
||||||
|
&preset, g_pd3dDevice, g_pd3dDeviceContext, & opt, &filter_chain);
|
||||||
|
|
||||||
// Load Fonts
|
// Load Fonts
|
||||||
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
|
|
|
@ -71,7 +71,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
||||||
.force_no_mipmaps = false,
|
.force_no_mipmaps = false,
|
||||||
};
|
};
|
||||||
|
|
||||||
libra.d3d11_filter_chain_create(&preset, &opt, device, &filter_chain);
|
libra.d3d11_filter_chain_create(&preset, device, &opt, &filter_chain);
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
IDXGIDevice1* dxgiDevice;
|
IDXGIDevice1* dxgiDevice;
|
||||||
|
|
||||||
|
|
|
@ -141,7 +141,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/,
|
||||||
|
|
||||||
libra_d3d11_filter_chain_t filter_chain;
|
libra_d3d11_filter_chain_t filter_chain;
|
||||||
|
|
||||||
libra.d3d11_filter_chain_create(&preset, NULL, d3d11Device,
|
libra.d3d11_filter_chain_create(&preset, d3d11Device, NULL,
|
||||||
&filter_chain);
|
&filter_chain);
|
||||||
|
|
||||||
// Create Swap Chain
|
// Create Swap Chain
|
||||||
|
|
Loading…
Reference in a new issue