capi: make viewport optional, defaulting to a viewport that is the entire size of the render target

This commit is contained in:
chyyran 2024-08-21 00:14:42 -04:00 committed by Ronny Chan
parent eb53699590
commit 1e33b4cc03
16 changed files with 453 additions and 187 deletions

View file

@ -207,20 +207,6 @@ typedef struct libra_source_image_gl_t {
} libra_source_image_gl_t;
#endif
/// Defines the output origin for a rendered frame.
typedef struct libra_viewport_t {
/// The x offset in the viewport framebuffer to begin rendering from.
float x;
/// The y offset in the viewport framebuffer to begin rendering from.
float y;
/// The width extent of the viewport framebuffer to end rendering, relative to
/// the origin specified by x.
uint32_t width;
/// The height extent of the viewport framebuffer to end rendering, relative to
/// the origin specified by y.
uint32_t height;
} libra_viewport_t;
#if defined(LIBRA_RUNTIME_OPENGL)
/// OpenGL parameters for the output framebuffer.
typedef struct libra_output_framebuffer_gl_t {
@ -237,6 +223,20 @@ typedef struct libra_output_framebuffer_gl_t {
} libra_output_framebuffer_gl_t;
#endif
/// Defines the output origin for a rendered frame.
typedef struct libra_viewport_t {
/// The x offset in the viewport framebuffer to begin rendering from.
float x;
/// The y offset in the viewport framebuffer to begin rendering from.
float y;
/// The width extent of the viewport framebuffer to end rendering, relative to
/// the origin specified by x.
uint32_t width;
/// The height extent of the viewport framebuffer to end rendering, relative to
/// the origin specified by y.
uint32_t height;
} libra_viewport_t;
#if defined(LIBRA_RUNTIME_OPENGL)
/// Options for each OpenGL shader frame.
typedef struct frame_gl_opt_t {
@ -298,31 +298,17 @@ typedef struct _filter_chain_vk *libra_vk_filter_chain_t;
#endif
#if defined(LIBRA_RUNTIME_VULKAN)
/// Vulkan parameters for the source image.
typedef struct libra_source_image_vk_t {
/// A raw `VkImage` handle to the source image.
/// Vulkan parameters for an image.
typedef struct libra_image_vk_t {
/// A raw `VkImage` handle.
VkImage handle;
/// The `VkFormat` of the source image.
/// The `VkFormat` of the `VkImage`.
VkFormat format;
/// The width of the source image.
/// The width of the `VkImage`.
uint32_t width;
/// The height of the source image.
/// The height of the `VkImage`.
uint32_t height;
} libra_source_image_vk_t;
#endif
#if defined(LIBRA_RUNTIME_VULKAN)
/// Vulkan parameters for the output image.
typedef struct libra_output_image_vk_t {
/// A raw `VkImage` handle to the output image.
VkImage handle;
/// The `VkFormat` of the output image.
VkFormat format;
/// The width of the output image.
uint32_t width;
/// The height of the output image.
uint32_t height;
} libra_output_image_vk_t;
} libra_image_vk_t;
#endif
#if defined(LIBRA_RUNTIME_VULKAN)
@ -654,8 +640,8 @@ typedef libra_error_t (*PFN_libra_gl_filter_chain_create)(libra_shader_preset_t
typedef libra_error_t (*PFN_libra_gl_filter_chain_frame)(libra_gl_filter_chain_t *chain,
size_t frame_count,
struct libra_source_image_gl_t image,
struct libra_viewport_t viewport,
struct libra_output_framebuffer_gl_t out,
const struct libra_viewport_t *viewport,
const float *mvp,
const struct frame_gl_opt_t *opt);
#endif
@ -721,9 +707,9 @@ typedef libra_error_t (*PFN_libra_vk_filter_chain_create_deferred)(libra_shader_
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_source_image_vk_t image,
struct libra_viewport_t viewport,
struct libra_output_image_vk_t out,
struct libra_image_vk_t image,
struct libra_image_vk_t out,
const struct libra_viewport_t *viewport,
const float *mvp,
const struct frame_vk_opt_t *opt);
#endif
@ -790,8 +776,8 @@ typedef libra_error_t (*PFN_libra_d3d11_filter_chain_frame)(libra_d3d11_filter_c
ID3D11DeviceContext * device_context,
size_t frame_count,
ID3D11ShaderResourceView * image,
struct libra_viewport_t viewport,
ID3D11RenderTargetView * out,
const struct libra_viewport_t *viewport,
const float *mvp,
const struct frame_d3d11_opt_t *options);
#endif
@ -847,8 +833,8 @@ typedef libra_error_t (*PFN_libra_d3d9_filter_chain_create)(libra_shader_preset_
typedef libra_error_t (*PFN_libra_d3d9_filter_chain_frame)(libra_d3d9_filter_chain_t *chain,
size_t frame_count,
IDirect3DTexture9 * image,
struct libra_viewport_t viewport,
IDirect3DSurface9 * out,
const struct libra_viewport_t *viewport,
const float *mvp,
const struct frame_d3d9_opt_t *options);
#endif
@ -915,8 +901,8 @@ typedef libra_error_t (*PFN_libra_d3d12_filter_chain_frame)(libra_d3d12_filter_c
ID3D12GraphicsCommandList * command_list,
size_t frame_count,
struct libra_source_image_d3d12_t image,
struct libra_viewport_t viewport,
struct libra_output_image_d3d12_t out,
const struct libra_viewport_t *viewport,
const float *mvp,
const struct frame_d3d12_opt_t *options);
#endif
@ -983,8 +969,8 @@ typedef libra_error_t (*PFN_libra_mtl_filter_chain_frame)(libra_mtl_filter_chain
id<MTLCommandBuffer> command_buffer,
size_t frame_count,
id<MTLTexture> image,
struct libra_viewport_t viewport,
id<MTLTexture> output,
const struct libra_viewport_t *viewport,
const float *mvp,
const struct frame_mtl_opt_t *opt);
#endif
@ -1207,6 +1193,23 @@ libra_error_t libra_gl_filter_chain_create(libra_shader_preset_t *preset,
#if defined(LIBRA_RUNTIME_OPENGL)
/// Draw a frame with the given parameters for the given filter chain.
///
/// ## Parameters
///
/// - `chain` is a handle to the filter chain.
/// - `frame_count` is the number of frames passed to the shader
/// - `image` is a `libra_source_image_gl_t`, containing the name of a Texture, format, and size information to
/// to an image that will serve as the source image for the frame.
/// - `out` is a `libra_output_framebuffer_gl_t`, containing the name of a Framebuffer, the name of a Texture, format,
/// and size information for the render target of the frame.
///
/// - `viewport` is a pointer to a `libra_viewport_t` that specifies the area onto which scissor and viewport
/// will be applied to the render target. It may be null, in which case a default viewport spanning the
/// entire render target will be used.
/// - `mvp` is a pointer to an array of 16 `float` values to specify the model view projection matrix to
/// be passed to the shader.
/// - `options` is a pointer to options for the frame. Valid options are dependent on the `LIBRASHADER_API_VERSION`
/// passed in. It may be null, in which case default options for the filter chain are used.
///
/// ## Safety
/// - `chain` may be null, invalid, but not uninitialized. If `chain` is null or invalid, this
/// function will return an error.
@ -1221,8 +1224,8 @@ libra_error_t libra_gl_filter_chain_create(libra_shader_preset_t *preset,
libra_error_t libra_gl_filter_chain_frame(libra_gl_filter_chain_t *chain,
size_t frame_count,
struct libra_source_image_gl_t image,
struct libra_viewport_t viewport,
struct libra_output_framebuffer_gl_t out,
const struct libra_viewport_t *viewport,
const float *mvp,
const struct frame_gl_opt_t *opt);
#endif
@ -1326,13 +1329,31 @@ libra_error_t libra_vk_filter_chain_create_deferred(libra_shader_preset_t *prese
/// Records rendering commands for a frame with the given parameters for the given filter chain
/// to the input command buffer.
///
/// * The input image must be in the `VK_SHADER_READ_ONLY_OPTIMAL` layout.
/// * The output image must be in `VK_COLOR_ATTACHMENT_OPTIMAL` layout.
///
/// librashader **will not** create a pipeline barrier for the final pass. The output image will
/// remain in `VK_COLOR_ATTACHMENT_OPTIMAL` after all shader passes. The caller must transition
/// librashader **will not** create a pipeline barrier for the final pass. The output image must be
/// in `VK_COLOR_ATTACHMENT_OPTIMAL`, and will remain so after all shader passes. The caller must transition
/// the output image to the final layout.
///
/// ## Parameters
///
/// - `chain` is a handle to the filter chain.
/// - `command_buffer` is a `VkCommandBuffer` handle to record draw commands to.
/// The provided command buffer must be ready for recording and contain no prior commands
/// - `frame_count` is the number of frames passed to the shader
/// - `image` is a `libra_image_vk_t`, containing a `VkImage` handle, it's format and size information,
/// to an image that will serve as the source image for the frame. The input image must be in
/// the `VK_SHADER_READ_ONLY_OPTIMAL` layout.
/// - `out` is a `libra_image_vk_t`, containing a `VkImage` handle, it's format and size information,
/// for the render target of the frame. The output image must be in `VK_COLOR_ATTACHMENT_OPTIMAL` layout.
/// The output image will remain in `VK_COLOR_ATTACHMENT_OPTIMAL` after all shader passes.
///
/// - `viewport` is a pointer to a `libra_viewport_t` that specifies the area onto which scissor and viewport
/// will be applied to the render target. It may be null, in which case a default viewport spanning the
/// entire render target will be used.
/// - `mvp` is a pointer to an array of 16 `float` values to specify the model view projection matrix to
/// be passed to the shader.
/// - `options` is a pointer to options for the frame. Valid options are dependent on the `LIBRASHADER_API_VERSION`
/// passed in. It may be null, in which case default options for the filter chain are used.
///
/// ## Safety
/// - `libra_vk_filter_chain_frame` **must not be called within a RenderPass**.
/// - `command_buffer` must be a valid handle to a `VkCommandBuffer` that is ready for recording.
@ -1347,9 +1368,9 @@ libra_error_t libra_vk_filter_chain_create_deferred(libra_shader_preset_t *prese
libra_error_t libra_vk_filter_chain_frame(libra_vk_filter_chain_t *chain,
VkCommandBuffer command_buffer,
size_t frame_count,
struct libra_source_image_vk_t image,
struct libra_viewport_t viewport,
struct libra_output_image_vk_t out,
struct libra_image_vk_t image,
struct libra_image_vk_t out,
const struct libra_viewport_t *viewport,
const float *mvp,
const struct frame_vk_opt_t *opt);
#endif
@ -1457,9 +1478,26 @@ libra_error_t libra_d3d11_filter_chain_create_deferred(libra_shader_preset_t *pr
#if (defined(_WIN32) && defined(LIBRA_RUNTIME_D3D11))
/// Draw a frame with the given parameters for the given filter chain.
///
/// If `device_context` is null, then commands are recorded onto the immediate context. Otherwise,
/// it will record commands onto the provided context. If the context is deferred, librashader
/// will not finalize command lists. The context must otherwise be associated with the `ID3D11Device`
/// ## Parameters
///
/// - `chain` is a handle to the filter chain.
/// - `device_context` is the ID3D11DeviceContext used to record draw commands to.
/// If `device_context` is null, then commands are recorded onto the immediate context. Otherwise,
/// it will record commands onto the provided context. If the context is deferred, librashader
/// will not finalize command lists. The context must otherwise be associated with the `ID3D11Device`
/// the filter chain was created with.
///
/// - `frame_count` is the number of frames passed to the shader
/// - `image` is a pointer to a `ID3D11ShaderResourceView` that will serve as the source image for the frame.
/// - `out` is a pointer to a `ID3D11RenderTargetView` that will serve as the render target for the frame.
///
/// - `viewport` is a pointer to a `libra_viewport_t` that specifies the area onto which scissor and viewport
/// will be applied to the render target. It may be null, in which case a default viewport spanning the
/// entire render target will be used.
/// - `mvp` is a pointer to an array of 16 `float` values to specify the model view projection matrix to
/// be passed to the shader.
/// - `options` is a pointer to options for the frame. Valid options are dependent on the `LIBRASHADER_API_VERSION`
/// passed in. It may be null, in which case default options for the filter chain are used.
///
/// ## Safety
/// - `chain` may be null, invalid, but not uninitialized. If `chain` is null or invalid, this
@ -1479,8 +1517,8 @@ libra_error_t libra_d3d11_filter_chain_frame(libra_d3d11_filter_chain_t *chain,
ID3D11DeviceContext * device_context,
size_t frame_count,
ID3D11ShaderResourceView * image,
struct libra_viewport_t viewport,
ID3D11RenderTargetView * out,
const struct libra_viewport_t *viewport,
const float *mvp,
const struct frame_d3d11_opt_t *options);
#endif
@ -1556,10 +1594,24 @@ libra_error_t libra_d3d9_filter_chain_create(libra_shader_preset_t *preset,
#if (defined(_WIN32) && defined(LIBRA_RUNTIME_D3D9))
/// Draw a frame with the given parameters for the given filter chain.
///
/// ## Parameters
/// - `chain` is a handle to the filter chain.
/// - `frame_count` is the number of frames passed to the shader
/// - `image` is a pointer to a `IDirect3DTexture9` that will serve as the source image for the frame.
/// - `out` is a pointer to a `IDirect3DSurface9` that will serve as the render target for the frame.
///
/// - `viewport` is a pointer to a `libra_viewport_t` that specifies the area onto which scissor and viewport
/// will be applied to the render target. It may be null, in which case a default viewport spanning the
/// entire render target will be used.
/// - `mvp` is a pointer to an array of 16 `float` values to specify the model view projection matrix to
/// be passed to the shader.
/// - `options` is a pointer to options for the frame. Valid options are dependent on the `LIBRASHADER_API_VERSION`
/// passed in. It may be null, in which case default options for the filter chain are used.
///
/// ## Safety
/// - `chain` may be null, invalid, but not uninitialized. If `chain` is null or invalid, this
/// function will return an error.
/// - `viewport` may be null, or if it is not null, must be an aligned pointer to an instance of `libra_viewport_t`.
/// - `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_d3d9_opt_t`
@ -1571,8 +1623,8 @@ libra_error_t libra_d3d9_filter_chain_create(libra_shader_preset_t *preset,
libra_error_t libra_d3d9_filter_chain_frame(libra_d3d9_filter_chain_t *chain,
size_t frame_count,
IDirect3DTexture9 * image,
struct libra_viewport_t viewport,
IDirect3DSurface9 * out,
const struct libra_viewport_t *viewport,
const float *mvp,
const struct frame_d3d9_opt_t *options);
#endif
@ -1673,13 +1725,31 @@ libra_error_t libra_d3d12_filter_chain_create_deferred(libra_shader_preset_t *pr
/// Records rendering commands for a frame with the given parameters for the given filter chain
/// to the input command list.
///
/// * The input image must be in the `D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE` resource state.
/// * The output image must be in `D3D12_RESOURCE_STATE_RENDER_TARGET` resource state.
///
/// librashader **will not** create a resource barrier for the final pass. The output image will
/// remain in `D3D12_RESOURCE_STATE_RENDER_TARGET` after all shader passes. The caller must transition
/// the output image to the final resource state.
///
/// ## Parameters
///
/// - `chain` is a handle to the filter chain.
/// - `command_list` is a `ID3D12GraphicsCommandList` to record draw commands to.
/// The provided command list must be open and associated with the `ID3D12Device` this filter chain was created with.
/// - `frame_count` is the number of frames passed to the shader
/// - `image` is a `libra_source_image_d3d12_t`, containing a `ID3D12Resource` pointer and CPU descriptor
/// to an image that will serve as the source image for the frame. The input image must be in the
/// `D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE` resource state or equivalent barrier layout.
/// - `out` is a `libra_output_image_d3d12_t`, containing a CPU descriptor handle, format, and size information
/// for the render target of the frame. The output image must be in
/// `D3D12_RESOURCE_STATE_RENDER_TARGET` resource state or equivalent barrier layout.
///
/// - `viewport` is a pointer to a `libra_viewport_t` that specifies the area onto which scissor and viewport
/// will be applied to the render target. It may be null, in which case a default viewport spanning the
/// entire render target will be used.
/// - `mvp` is a pointer to an array of 16 `float` values to specify the model view projection matrix to
/// be passed to the shader.
/// - `options` is a pointer to options for the frame. Valid options are dependent on the `LIBRASHADER_API_VERSION`
/// passed in. It may be null, in which case default options for the filter chain are used.
///
/// ## Safety
/// - `chain` may be null, invalid, but not uninitialized. If `chain` is null or invalid, this
/// function will return an error.
@ -1697,8 +1767,8 @@ libra_error_t libra_d3d12_filter_chain_frame(libra_d3d12_filter_chain_t *chain,
ID3D12GraphicsCommandList * command_list,
size_t frame_count,
struct libra_source_image_d3d12_t image,
struct libra_viewport_t viewport,
struct libra_output_image_d3d12_t out,
const struct libra_viewport_t *viewport,
const float *mvp,
const struct frame_d3d12_opt_t *options);
#endif
@ -1802,6 +1872,22 @@ libra_error_t libra_mtl_filter_chain_create_deferred(libra_shader_preset_t *pres
#if (defined(__APPLE__) && defined(LIBRA_RUNTIME_METAL) && defined(__OBJC__))
/// Records rendering commands for a frame with the given parameters for the given filter chain
/// to the input command buffer.
/// ## Parameters
///
/// - `chain` is a handle to the filter chain.
/// - `command_buffer` is a `MTLCommandBuffer` handle to record draw commands to.
/// The provided command buffer must be ready for encoding and contain no prior commands
/// - `frame_count` is the number of frames passed to the shader
/// - `image` is a `id<MTLTexture>` that will serve as the source image for the frame.
/// - `out` is a `id<MTLTexture>` that is the render target of the frame.
///
/// - `viewport` is a pointer to a `libra_viewport_t` that specifies the area onto which scissor and viewport
/// will be applied to the render target. It may be null, in which case a default viewport spanning the
/// entire render target will be used.
/// - `mvp` is a pointer to an array of 16 `float` values to specify the model view projection matrix to
/// be passed to the shader.
/// - `options` is a pointer to options for the frame. Valid options are dependent on the `LIBRASHADER_API_VERSION`
/// passed in. It may be null, in which case default options for the filter chain are used.
///
/// ## Safety
/// - `command_buffer` must be a valid reference to a `MTLCommandBuffer` that is not already encoding.
@ -1817,8 +1903,8 @@ libra_error_t libra_mtl_filter_chain_frame(libra_mtl_filter_chain_t *chain,
id<MTLCommandBuffer> command_buffer,
size_t frame_count,
id<MTLTexture> image,
struct libra_viewport_t viewport,
id<MTLTexture> output,
const struct libra_viewport_t *viewport,
const float *mvp,
const struct frame_mtl_opt_t *opt);
#endif

View file

@ -204,8 +204,8 @@ libra_error_t __librashader__noop_gl_filter_chain_create(
libra_error_t __librashader__noop_gl_filter_chain_frame(
libra_gl_filter_chain_t *chain, size_t frame_count,
struct libra_source_image_gl_t image, struct libra_viewport_t viewport,
struct libra_output_framebuffer_gl_t out, const float *mvp,
struct libra_source_image_gl_t image, struct libra_output_framebuffer_gl_t out,
const struct libra_viewport_t *viewport, const float *mvp,
const struct frame_gl_opt_t *opt) {
return NULL;
}
@ -254,9 +254,9 @@ libra_error_t __librashader__noop_vk_filter_chain_create_deferred(
libra_error_t __librashader__noop_vk_filter_chain_frame(
libra_vk_filter_chain_t *chain, VkCommandBuffer command_buffer,
size_t frame_count, struct libra_source_image_vk_t image,
struct libra_viewport_t viewport, struct libra_output_image_vk_t out,
const float *mvp, const struct frame_vk_opt_t *opt) {
size_t frame_count, struct libra_image_vk_t image, struct libra_image_vk_t out,
const struct libra_viewport_t *viewport, const float *mvp,
const struct frame_vk_opt_t *opt) {
return NULL;
}
@ -306,9 +306,9 @@ libra_error_t __librashader__noop_d3d11_filter_chain_create_deferred(
libra_error_t __librashader__noop_d3d11_filter_chain_frame(
libra_d3d11_filter_chain_t *chain, ID3D11DeviceContext *device_context,
size_t frame_count, ID3D11ShaderResourceView *image,
struct libra_viewport_t viewport, ID3D11RenderTargetView *out,
const float *mvp, const struct frame_d3d11_opt_t *opt) {
size_t frame_count, ID3D11ShaderResourceView *image, ID3D11RenderTargetView *out,
const struct libra_viewport_t *viewport, const float *mvp,
const struct frame_d3d11_opt_t *opt) {
return NULL;
}
@ -358,9 +358,9 @@ libra_error_t __librashader__noop_d3d12_filter_chain_create_deferred(
libra_error_t __librashader__noop_d3d12_filter_chain_frame(
libra_d3d12_filter_chain_t *chain, ID3D12GraphicsCommandList *command_list,
size_t frame_count, struct libra_source_image_d3d12_t image,
struct libra_viewport_t viewport, struct libra_output_image_d3d12_t out,
const float *mvp, const struct frame_d3d12_opt_t *opt) {
size_t frame_count, struct libra_source_image_d3d12_t image, struct libra_output_image_d3d12_t out,
const struct libra_viewport_t *viewport, const float *mvp,
const struct frame_d3d12_opt_t *opt) {
return NULL;
}
@ -401,8 +401,8 @@ libra_error_t __librashader__noop_d3d9_filter_chain_create(
libra_error_t __librashader__noop_d3d9_filter_chain_frame(
libra_d3d9_filter_chain_t *chain, size_t frame_count,
IDirect3DTexture9 *image, struct libra_viewport_t viewport,
IDirect3DSurface9 * out, const float *mvp,
IDirect3DTexture9 *image, IDirect3DSurface9 * out,
const struct libra_viewport_t *viewport, const float *mvp,
const struct frame_d3d9_opt_t *opt) {
return NULL;
}
@ -453,8 +453,8 @@ libra_error_t __librashader__noop_mtl_filter_chain_create_deferred(
libra_error_t __librashader__noop_mtl_filter_chain_frame(
libra_mtl_filter_chain_t *chain, id<MTLCommandBuffer> command_buffer,
size_t frame_count, id<MTLTexture> image, struct libra_viewport_t viewport,
id<MTLTexture> output, const float *mvp,
size_t frame_count, id<MTLTexture> image, id<MTLTexture> output,
const struct libra_viewport_t *viewport, const float *mvp,
const struct frame_mtl_opt_t *opt) {
return NULL;
}

View file

@ -89,6 +89,8 @@ pub enum LibrashaderError {
#[cfg(all(target_vendor = "apple", feature = "runtime-metal"))]
#[error("There was an error in the Metal filter chain.")]
MetalFilterError(#[from] librashader::runtime::mtl::error::FilterChainError),
#[error("This error is not reachable")]
Infallible(#[from] std::convert::Infallible),
}
/// Error codes for librashader error types.
@ -254,6 +256,7 @@ impl LibrashaderError {
LibrashaderError::VulkanFilterError(_) => LIBRA_ERRNO::RUNTIME_ERROR,
#[cfg(all(target_vendor = "apple", feature = "runtime-metal"))]
LibrashaderError::MetalFilterError(_) => LIBRA_ERRNO::RUNTIME_ERROR,
LibrashaderError::Infallible(_) => LIBRA_ERRNO::UNKNOWN_ERROR,
}
}
pub(crate) const fn ok() -> libra_error_t {

View file

@ -15,6 +15,7 @@ use windows::Win32::Graphics::Direct3D11::{
};
use crate::LIBRASHADER_API_VERSION;
use librashader::runtime::d3d11::error::FilterChainError;
use librashader::runtime::{FilterChainParameters, Size, Viewport};
/// Options for Direct3D 11 filter chain creation.
@ -178,10 +179,26 @@ const _: () = assert!(
extern_fn! {
/// Draw a frame with the given parameters for the given filter chain.
///
/// If `device_context` is null, then commands are recorded onto the immediate context. Otherwise,
/// it will record commands onto the provided context. If the context is deferred, librashader
/// will not finalize command lists. The context must otherwise be associated with the `ID3D11Device`
// the filter chain was created with.
/// ## Parameters
///
/// - `chain` is a handle to the filter chain.
/// - `device_context` is the ID3D11DeviceContext used to record draw commands to.
/// If `device_context` is null, then commands are recorded onto the immediate context. Otherwise,
/// it will record commands onto the provided context. If the context is deferred, librashader
/// will not finalize command lists. The context must otherwise be associated with the `ID3D11Device`
/// the filter chain was created with.
///
/// - `frame_count` is the number of frames passed to the shader
/// - `image` is a pointer to a `ID3D11ShaderResourceView` that will serve as the source image for the frame.
/// - `out` is a pointer to a `ID3D11RenderTargetView` that will serve as the render target for the frame.
///
/// - `viewport` is a pointer to a `libra_viewport_t` that specifies the area onto which scissor and viewport
/// will be applied to the render target. It may be null, in which case a default viewport spanning the
/// entire render target will be used.
/// - `mvp` is a pointer to an array of 16 `float` values to specify the model view projection matrix to
/// be passed to the shader.
/// - `options` is a pointer to options for the frame. Valid options are dependent on the `LIBRASHADER_API_VERSION`
/// passed in. It may be null, in which case default options for the filter chain are used.
///
/// ## Safety
/// - `chain` may be null, invalid, but not uninitialized. If `chain` is null or invalid, this
@ -204,8 +221,8 @@ extern_fn! {
device_context: Option<ManuallyDrop<ID3D11DeviceContext>>,
frame_count: usize,
image: ManuallyDrop<ID3D11ShaderResourceView>,
viewport: libra_viewport_t,
out: ManuallyDrop<ID3D11RenderTargetView>,
viewport: *const libra_viewport_t,
mvp: *const f32,
options: *const MaybeUninit<frame_d3d11_opt_t>
) mut |chain| {
@ -223,15 +240,21 @@ extern_fn! {
Some(unsafe { options.read() })
};
let viewport = Viewport {
x: viewport.x,
y: viewport.y,
output: ManuallyDrop::into_inner(out.clone()),
size: Size {
height: viewport.height,
width: viewport.width
},
mvp,
let viewport = if viewport.is_null() {
Viewport::new_render_target_sized_origin(ManuallyDrop::into_inner(out.clone()), mvp)
.map_err(|e| LibrashaderError::D3D11FilterError(FilterChainError::Direct3DError(e)))?
} else {
let viewport = unsafe { viewport.read() };
Viewport {
x: viewport.x,
y: viewport.y,
output: ManuallyDrop::into_inner(out.clone()),
size: Size {
height: viewport.height,
width: viewport.width
},
mvp,
}
};
let options = options.map(FromUninit::from_uninit);

View file

@ -208,13 +208,31 @@ extern_fn! {
/// Records rendering commands for a frame with the given parameters for the given filter chain
/// to the input command list.
///
/// * The input image must be in the `D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE` resource state.
/// * The output image must be in `D3D12_RESOURCE_STATE_RENDER_TARGET` resource state.
///
/// librashader **will not** create a resource barrier for the final pass. The output image will
/// remain in `D3D12_RESOURCE_STATE_RENDER_TARGET` after all shader passes. The caller must transition
/// the output image to the final resource state.
///
/// ## Parameters
///
/// - `chain` is a handle to the filter chain.
/// - `command_list` is a `ID3D12GraphicsCommandList` to record draw commands to.
/// The provided command list must be open and associated with the `ID3D12Device` this filter chain was created with.
/// - `frame_count` is the number of frames passed to the shader
/// - `image` is a `libra_source_image_d3d12_t`, containing a `ID3D12Resource` pointer and CPU descriptor
/// to an image that will serve as the source image for the frame. The input image must be in the
/// `D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE` resource state or equivalent barrier layout.
/// - `out` is a `libra_output_image_d3d12_t`, containing a CPU descriptor handle, format, and size information
/// for the render target of the frame. The output image must be in
/// `D3D12_RESOURCE_STATE_RENDER_TARGET` resource state or equivalent barrier layout.
///
/// - `viewport` is a pointer to a `libra_viewport_t` that specifies the area onto which scissor and viewport
/// will be applied to the render target. It may be null, in which case a default viewport spanning the
/// entire render target will be used.
/// - `mvp` is a pointer to an array of 16 `float` values to specify the model view projection matrix to
/// be passed to the shader.
/// - `options` is a pointer to options for the frame. Valid options are dependent on the `LIBRASHADER_API_VERSION`
/// passed in. It may be null, in which case default options for the filter chain are used.
///
/// ## Safety
/// - `chain` may be null, invalid, but not uninitialized. If `chain` is null or invalid, this
/// function will return an error.
@ -233,8 +251,8 @@ extern_fn! {
command_list: ManuallyDrop<ID3D12GraphicsCommandList>,
frame_count: usize,
image: libra_source_image_d3d12_t,
viewport: libra_viewport_t,
out: libra_output_image_d3d12_t,
viewport: *const libra_viewport_t,
mvp: *const f32,
options: *const MaybeUninit<frame_d3d12_opt_t>
) mut |chain| {
@ -253,17 +271,28 @@ extern_fn! {
};
let options = options.map(FromUninit::from_uninit);
let viewport = Viewport {
x: viewport.x,
y: viewport.y,
size: Size {
height: viewport.height,
width: viewport.width
},
output: unsafe {
D3D12OutputView::new_from_raw(out.descriptor,
Size::new(out.width, out.height), out.format) },
mvp,
let output = unsafe {
D3D12OutputView::new_from_raw(
out.descriptor,
Size::new(out.width, out.height),
out.format)
};
let viewport = if viewport.is_null() {
Viewport::new_render_target_sized_origin(output, mvp)?
} else {
let viewport = unsafe { viewport.read() };
Viewport {
x: viewport.x,
y: viewport.y,
output,
size: Size {
height: viewport.height,
width: viewport.width
},
mvp,
}
};
let image = image.try_into()?;

View file

@ -12,6 +12,7 @@ use std::slice;
use windows::Win32::Graphics::Direct3D9::{IDirect3DDevice9, IDirect3DSurface9, IDirect3DTexture9};
use crate::LIBRASHADER_API_VERSION;
use librashader::runtime::d3d9::error::FilterChainError;
use librashader::runtime::{FilterChainParameters, Size, Viewport};
/// Options for Direct3D 11 filter chain creation.
@ -108,10 +109,24 @@ extern_fn! {
extern_fn! {
/// Draw a frame with the given parameters for the given filter chain.
///
/// ## Parameters
/// - `chain` is a handle to the filter chain.
/// - `frame_count` is the number of frames passed to the shader
/// - `image` is a pointer to a `IDirect3DTexture9` that will serve as the source image for the frame.
/// - `out` is a pointer to a `IDirect3DSurface9` that will serve as the render target for the frame.
///
/// - `viewport` is a pointer to a `libra_viewport_t` that specifies the area onto which scissor and viewport
/// will be applied to the render target. It may be null, in which case a default viewport spanning the
/// entire render target will be used.
/// - `mvp` is a pointer to an array of 16 `float` values to specify the model view projection matrix to
/// be passed to the shader.
/// - `options` is a pointer to options for the frame. Valid options are dependent on the `LIBRASHADER_API_VERSION`
/// passed in. It may be null, in which case default options for the filter chain are used.
///
/// ## Safety
/// - `chain` may be null, invalid, but not uninitialized. If `chain` is null or invalid, this
/// function will return an error.
/// - `viewport` may be null, or if it is not null, must be an aligned pointer to an instance of `libra_viewport_t`.
/// - `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_d3d9_opt_t`
@ -124,8 +139,8 @@ extern_fn! {
chain: *mut libra_d3d9_filter_chain_t,
frame_count: usize,
image: ManuallyDrop<IDirect3DTexture9>,
viewport: libra_viewport_t,
out: ManuallyDrop<IDirect3DSurface9>,
viewport: *const libra_viewport_t,
mvp: *const f32,
options: *const MaybeUninit<frame_d3d9_opt_t>
) mut |chain| {
@ -143,15 +158,21 @@ extern_fn! {
Some(unsafe { options.read() })
};
let viewport = Viewport {
x: viewport.x,
y: viewport.y,
output: ManuallyDrop::into_inner(out.clone()),
size: Size {
height: viewport.height,
width: viewport.width
},
mvp,
let viewport = if viewport.is_null() {
Viewport::new_render_target_sized_origin(ManuallyDrop::into_inner(out.clone()), mvp)
.map_err(|e| LibrashaderError::D3D9FilterError(FilterChainError::Direct3DError(e)))?
} else {
let viewport = unsafe { viewport.read() };
Viewport {
x: viewport.x,
y: viewport.y,
output: ManuallyDrop::into_inner(out.clone()),
size: Size {
height: viewport.height,
width: viewport.width
},
mvp,
}
};
let options = options.map(FromUninit::from_uninit);

View file

@ -162,6 +162,23 @@ extern_fn! {
extern_fn! {
/// Draw a frame with the given parameters for the given filter chain.
///
/// ## Parameters
///
/// - `chain` is a handle to the filter chain.
/// - `frame_count` is the number of frames passed to the shader
/// - `image` is a `libra_source_image_gl_t`, containing the name of a Texture, format, and size information to
/// to an image that will serve as the source image for the frame.
/// - `out` is a `libra_output_framebuffer_gl_t`, containing the name of a Framebuffer, the name of a Texture, format,
/// and size information for the render target of the frame.
///
/// - `viewport` is a pointer to a `libra_viewport_t` that specifies the area onto which scissor and viewport
/// will be applied to the render target. It may be null, in which case a default viewport spanning the
/// entire render target will be used.
/// - `mvp` is a pointer to an array of 16 `float` values to specify the model view projection matrix to
/// be passed to the shader.
/// - `options` is a pointer to options for the frame. Valid options are dependent on the `LIBRASHADER_API_VERSION`
/// passed in. It may be null, in which case default options for the filter chain are used.
///
/// ## Safety
/// - `chain` may be null, invalid, but not uninitialized. If `chain` is null or invalid, this
/// function will return an error.
@ -177,8 +194,8 @@ extern_fn! {
chain: *mut libra_gl_filter_chain_t,
frame_count: usize,
image: libra_source_image_gl_t,
viewport: libra_viewport_t,
out: libra_output_framebuffer_gl_t,
viewport: *const libra_viewport_t,
mvp: *const f32,
opt: *const MaybeUninit<frame_gl_opt_t>,
) mut |chain| {
@ -209,15 +226,20 @@ extern_fn! {
let framebuffer = GLFramebuffer::new_from_raw(Arc::clone(chain.get_context()),
texture, fbo, out.format, Size::new(out.width, out.height), 1);
let viewport = Viewport {
x: viewport.x,
y: viewport.y,
output: &framebuffer,
size: Size {
height: viewport.height,
width: viewport.width
},
mvp,
let viewport = if viewport.is_null() {
Viewport::new_render_target_sized_origin(&framebuffer, mvp)?
} else {
let viewport = unsafe { viewport.read() };
Viewport {
x: viewport.x,
y: viewport.y,
output: &framebuffer,
size: Size {
height: viewport.height,
width: viewport.width
},
mvp,
}
};
unsafe {

View file

@ -173,6 +173,22 @@ extern_fn! {
extern_fn! {
/// Records rendering commands for a frame with the given parameters for the given filter chain
/// to the input command buffer.
/// ## Parameters
///
/// - `chain` is a handle to the filter chain.
/// - `command_buffer` is a `MTLCommandBuffer` handle to record draw commands to.
/// The provided command buffer must be ready for encoding and contain no prior commands
/// - `frame_count` is the number of frames passed to the shader
/// - `image` is a `id<MTLTexture>` that will serve as the source image for the frame.
/// - `out` is a `id<MTLTexture>` that is the render target of the frame.
///
/// - `viewport` is a pointer to a `libra_viewport_t` that specifies the area onto which scissor and viewport
/// will be applied to the render target. It may be null, in which case a default viewport spanning the
/// entire render target will be used.
/// - `mvp` is a pointer to an array of 16 `float` values to specify the model view projection matrix to
/// be passed to the shader.
/// - `options` is a pointer to options for the frame. Valid options are dependent on the `LIBRASHADER_API_VERSION`
/// passed in. It may be null, in which case default options for the filter chain are used.
///
/// ## Safety
/// - `command_buffer` must be a valid reference to a `MTLCommandBuffer` that is not already encoding.
@ -189,8 +205,8 @@ extern_fn! {
command_buffer: PMTLCommandBuffer,
frame_count: usize,
image: PMTLTexture,
viewport: libra_viewport_t,
output: PMTLTexture,
viewport: *const libra_viewport_t,
mvp: *const f32,
opt: *const MaybeUninit<frame_mtl_opt_t>
) |command_buffer, image, output|; mut |chain| {
@ -207,15 +223,21 @@ extern_fn! {
Some(unsafe { opt.read() })
};
let opt = opt.map(FromUninit::from_uninit);
let viewport = Viewport {
x: viewport.x,
y: viewport.y,
size: Size {
height: viewport.height,
width: viewport.width
},
output,
mvp,
let viewport = if viewport.is_null() {
Viewport::new_render_target_sized_origin(output, mvp)?
} else {
let viewport = unsafe { viewport.read() };
Viewport {
x: viewport.x,
y: viewport.y,
output,
size: Size {
height: viewport.height,
width: viewport.width
},
mvp,
}
};
chain.frame(&image, &viewport, command_buffer, frame_count, opt.as_ref())?;

View file

@ -24,29 +24,16 @@ pub use ash::vk::PFN_vkGetInstanceProcAddr;
pub type libra_PFN_vkGetInstanceProcAddr =
unsafe extern "system" fn(instance: *mut c_void, p_name: *const c_char);
/// Vulkan parameters for the source image.
/// Vulkan parameters for an image.
#[repr(C)]
pub struct libra_source_image_vk_t {
/// A raw `VkImage` handle to the source image.
pub struct libra_image_vk_t {
/// A raw `VkImage` handle.
pub handle: vk::Image,
/// The `VkFormat` of the source image.
/// The `VkFormat` of the `VkImage`.
pub format: vk::Format,
/// The width of the source image.
/// The width of the `VkImage`.
pub width: u32,
/// The height of the source image.
pub height: u32,
}
/// Vulkan parameters for the output image.
#[repr(C)]
pub struct libra_output_image_vk_t {
/// A raw `VkImage` handle to the output image.
pub handle: vk::Image,
/// The `VkFormat` of the output image.
pub format: vk::Format,
/// The width of the output image.
pub width: u32,
/// The height of the output image.
/// The height of the `VkImage`.
pub height: u32,
}
@ -66,8 +53,8 @@ pub struct libra_device_vk_t {
pub entry: vk::PFN_vkGetInstanceProcAddr,
}
impl From<libra_source_image_vk_t> for VulkanImage {
fn from(value: libra_source_image_vk_t) -> Self {
impl From<libra_image_vk_t> for VulkanImage {
fn from(value: libra_image_vk_t) -> Self {
VulkanImage {
size: Size::new(value.width, value.height),
image: value.handle,
@ -240,13 +227,31 @@ extern_fn! {
/// Records rendering commands for a frame with the given parameters for the given filter chain
/// to the input command buffer.
///
/// * The input image must be in the `VK_SHADER_READ_ONLY_OPTIMAL` layout.
/// * The output image must be in `VK_COLOR_ATTACHMENT_OPTIMAL` layout.
///
/// librashader **will not** create a pipeline barrier for the final pass. The output image will
/// remain in `VK_COLOR_ATTACHMENT_OPTIMAL` after all shader passes. The caller must transition
/// librashader **will not** create a pipeline barrier for the final pass. The output image must be
/// in `VK_COLOR_ATTACHMENT_OPTIMAL`, and will remain so after all shader passes. The caller must transition
/// the output image to the final layout.
///
/// ## Parameters
///
/// - `chain` is a handle to the filter chain.
/// - `command_buffer` is a `VkCommandBuffer` handle to record draw commands to.
/// The provided command buffer must be ready for recording and contain no prior commands
/// - `frame_count` is the number of frames passed to the shader
/// - `image` is a `libra_image_vk_t`, containing a `VkImage` handle, it's format and size information,
/// to an image that will serve as the source image for the frame. The input image must be in
/// the `VK_SHADER_READ_ONLY_OPTIMAL` layout.
/// - `out` is a `libra_image_vk_t`, containing a `VkImage` handle, it's format and size information,
/// for the render target of the frame. The output image must be in `VK_COLOR_ATTACHMENT_OPTIMAL` layout.
/// The output image will remain in `VK_COLOR_ATTACHMENT_OPTIMAL` after all shader passes.
///
/// - `viewport` is a pointer to a `libra_viewport_t` that specifies the area onto which scissor and viewport
/// will be applied to the render target. It may be null, in which case a default viewport spanning the
/// entire render target will be used.
/// - `mvp` is a pointer to an array of 16 `float` values to specify the model view projection matrix to
/// be passed to the shader.
/// - `options` is a pointer to options for the frame. Valid options are dependent on the `LIBRASHADER_API_VERSION`
/// passed in. It may be null, in which case default options for the filter chain are used.
///
/// ## Safety
/// - `libra_vk_filter_chain_frame` **must not be called within a RenderPass**.
/// - `command_buffer` must be a valid handle to a `VkCommandBuffer` that is ready for recording.
@ -262,9 +267,9 @@ extern_fn! {
chain: *mut libra_vk_filter_chain_t,
command_buffer: vk::CommandBuffer,
frame_count: usize,
image: libra_source_image_vk_t,
viewport: libra_viewport_t,
out: libra_output_image_vk_t,
image: libra_image_vk_t,
out: libra_image_vk_t,
viewport: *const libra_viewport_t,
mvp: *const f32,
opt: *const MaybeUninit<frame_vk_opt_t>
) mut |chain| {
@ -286,15 +291,21 @@ extern_fn! {
Some(unsafe { opt.read() })
};
let opt = opt.map(FromUninit::from_uninit);
let viewport = Viewport {
x: viewport.x,
y: viewport.y,
size: Size {
height: viewport.height,
width: viewport.width
},
output,
mvp,
let viewport = if viewport.is_null() {
Viewport::new_render_target_sized_origin(output, mvp)?
} else {
let viewport = unsafe { viewport.read() };
Viewport {
x: viewport.x,
y: viewport.y,
output,
size: Size {
height: viewport.height,
width: viewport.width
},
mvp,
}
};
unsafe {

View file

@ -201,47 +201,46 @@ impl<T> Size<T> {
}
}
impl<T: Sub<Output=T>> Sub for Size<T> {
impl<T: Sub<Output = T>> Sub for Size<T> {
type Output = Size<T>;
fn sub(self, rhs: Self) -> Self::Output {
Self {
width: self.width - rhs.width,
height: self.height - rhs.height
height: self.height - rhs.height,
}
}
}
impl<T: Sub<T, Output=T> + Copy> Sub<T> for Size<T> {
impl<T: Sub<T, Output = T> + Copy> Sub<T> for Size<T> {
type Output = Size<T>;
fn sub(self, rhs: T) -> Self::Output {
Self {
width: self.width - rhs,
height: self.height - rhs
height: self.height - rhs,
}
}
}
impl<T: Add<Output=T>> Add for Size<T> {
impl<T: Add<Output = T>> Add for Size<T> {
type Output = Size<T>;
fn add(self, rhs: Self) -> Self::Output {
Self {
width: self.width + rhs.width,
height: self.height + rhs.height
height: self.height + rhs.height,
}
}
}
impl<T: Add<T, Output=T> + Copy> Add<T> for Size<T> {
impl<T: Add<T, Output = T> + Copy> Add<T> for Size<T> {
type Output = Size<T>;
fn add(self, rhs: T) -> Self::Output {
Self {
width: self.width + rhs,
height: self.height + rhs
height: self.height + rhs,
}
}
}

View file

@ -107,3 +107,16 @@ impl GetSize<u32> for ProtocolObject<dyn MTLTexture> {
})
}
}
impl GetSize<u32> for &ProtocolObject<dyn MTLTexture> {
type Error = std::convert::Infallible;
fn size(&self) -> Result<Size<u32>, Self::Error> {
let height = self.height();
let width = self.width();
Ok(Size {
height: height as u32,
width: width as u32,
})
}
}

View file

@ -1,4 +1,4 @@
use crate::Size;
use crate::{GetSize, Size};
/// The rendering output of a filter chain.
///
@ -23,3 +23,24 @@ pub struct Viewport<'a, T> {
/// by x and y.
pub size: Size<u32>,
}
impl<'a, T: GetSize<u32>> Viewport<'a, T> {
/// Create a new viewport from an output that can be sized.
///
/// This will create a viewport that spans the entire output texture,
/// which will give correct results in the general case.
#[inline(always)]
pub fn new_render_target_sized_origin(
output: T,
mvp: Option<&'a [f32; 16]>,
) -> Result<Viewport<'a, T>, T::Error> {
let size = output.size()?;
Ok(Self {
x: 0.0,
y: 0.0,
mvp,
output,
size,
})
}
}

View file

@ -1,7 +1,7 @@
use windows::Win32::Foundation::RECT;
use crate::filter_chain::FilterCommon;
use crate::options::FrameOptionsD3D11;
use crate::texture::InputTexture;
use windows::Win32::Foundation::RECT;
use librashader_common::map::FastHashMap;
use librashader_common::{ImageFormat, Size, Viewport};

View file

@ -136,3 +136,11 @@ impl GetSize<u32> for GLFramebuffer {
Ok(self.size)
}
}
impl GetSize<u32> for &GLFramebuffer {
type Error = std::convert::Infallible;
fn size(&self) -> std::result::Result<Size<u32>, Self::Error> {
Ok(self.size)
}
}

View file

@ -208,7 +208,7 @@ impl MetalGraphicsPipeline {
x: output.x as usize,
y: output.y as usize,
width: output.size.width as usize,
height: output.size.height as usize
height: output.size.height as usize,
});
rpass.setViewport(MTLViewport {

View file

@ -7,7 +7,7 @@ use parking_lot::Mutex;
use std::sync::Arc;
use crate::error::FilterChainError;
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
use librashader_common::{FilterMode, GetSize, ImageFormat, Size, WrapMode};
use librashader_presets::Scale2D;
use librashader_runtime::scaling::{MipmapSize, ScaleFramebuffer, ViewportSize};
@ -535,3 +535,11 @@ impl ScaleFramebuffer for OwnedImage {
)
}
}
impl GetSize<u32> for VulkanImage {
type Error = std::convert::Infallible;
fn size(&self) -> Result<Size<u32>, Self::Error> {
Ok(self.size)
}
}