Skip to content

Commit

Permalink
capi: make viewport optional, defaulting to a viewport that is the en…
Browse files Browse the repository at this point in the history
…tire size of the render target
  • Loading branch information
chyyran committed Sep 22, 2024
1 parent eb53699 commit 1e33b4c
Show file tree
Hide file tree
Showing 16 changed files with 453 additions and 187 deletions.
210 changes: 148 additions & 62 deletions include/librashader.h

Large diffs are not rendered by default.

30 changes: 15 additions & 15 deletions include/librashader_ld.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down
3 changes: 3 additions & 0 deletions librashader-capi/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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 {
Expand Down
51 changes: 37 additions & 14 deletions librashader-capi/src/runtime/d3d11/filter_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand All @@ -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| {
Expand All @@ -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);
Expand Down
59 changes: 44 additions & 15 deletions librashader-capi/src/runtime/d3d12/filter_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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| {
Expand All @@ -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()?;
Expand Down
41 changes: 31 additions & 10 deletions librashader-capi/src/runtime/d3d9/filter_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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`
Expand All @@ -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| {
Expand All @@ -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);
Expand Down
42 changes: 32 additions & 10 deletions librashader-capi/src/runtime/gl/filter_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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| {
Expand Down Expand Up @@ -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 {
Expand Down
Loading

0 comments on commit 1e33b4c

Please sign in to comment.