capi: d3d11 capi
This commit is contained in:
parent
6ab03ecc99
commit
0e18b56752
|
@ -0,0 +1,143 @@
|
|||
use std::mem::MaybeUninit;
|
||||
use windows::Win32::Graphics::Direct3D11::{ID3D11Device, ID3D11RenderTargetView, ID3D11ShaderResourceView};
|
||||
use crate::ctypes::{libra_d3d11_filter_chain_t, libra_error_t, libra_shader_preset_t, libra_viewport_t};
|
||||
use crate::ffi::ffi_body;
|
||||
use crate::error::{assert_non_null, assert_some_ptr, LibrashaderError};
|
||||
use std::ptr::NonNull;
|
||||
use librashader::runtime::d3d11::{DxImageView, Viewport};
|
||||
use std::slice;
|
||||
|
||||
pub use librashader::runtime::d3d11::options::FilterChainOptionsD3D11;
|
||||
pub use librashader::runtime::d3d11::options::FrameOptionsD3D11;
|
||||
use librashader::Size;
|
||||
|
||||
/// OpenGL parameters for the source image.
|
||||
#[repr(C)]
|
||||
pub struct libra_source_image_d3d11_t {
|
||||
/// A shader resource view into the source image
|
||||
pub handle: *const ID3D11ShaderResourceView,
|
||||
/// The width of the source image.
|
||||
pub width: u32,
|
||||
/// The height of the source image.
|
||||
pub height: u32
|
||||
}
|
||||
|
||||
|
||||
|
||||
impl TryFrom<libra_source_image_d3d11_t> for DxImageView {
|
||||
type Error = LibrashaderError;
|
||||
|
||||
fn try_from(value: libra_source_image_d3d11_t) -> Result<Self, Self::Error> {
|
||||
let handle = value.handle;
|
||||
assert_non_null!(noexport handle);
|
||||
|
||||
Ok(DxImageView {
|
||||
handle: unsafe { (&*handle).clone() },
|
||||
size: Size::new(value.width, value.height),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Create the filter chain given the shader preset.
|
||||
///
|
||||
/// The shader preset is immediately invalidated and must be recreated after
|
||||
/// the filter chain is created.
|
||||
///
|
||||
/// ## Safety:
|
||||
/// - `preset` must be either null, or valid and aligned.
|
||||
/// - `options` must be either null, or valid and aligned.
|
||||
/// - `out` must be aligned, but may be null, invalid, or uninitialized.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn libra_d3d11_filter_chain_create(preset: *mut libra_shader_preset_t,
|
||||
options: *const FilterChainOptionsD3D11,
|
||||
device: *const ID3D11Device,
|
||||
out: *mut MaybeUninit<libra_d3d11_filter_chain_t>) -> libra_error_t {
|
||||
ffi_body!({
|
||||
assert_non_null!(preset);
|
||||
assert_non_null!(device);
|
||||
let preset = unsafe {
|
||||
let preset_ptr = &mut *preset;
|
||||
let preset = preset_ptr.take();
|
||||
Box::from_raw(preset.unwrap().as_ptr())
|
||||
};
|
||||
|
||||
let options = if options.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(unsafe { &*options })
|
||||
};
|
||||
|
||||
|
||||
let chain = librashader::runtime::d3d11::FilterChainD3D11::load_from_preset(unsafe { &*device }, *preset, options)?;
|
||||
|
||||
unsafe {
|
||||
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(chain)))))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Draw a frame with the given parameters for the given filter chain.
|
||||
///
|
||||
/// ## Safety
|
||||
/// - `chain` may be null, invalid, but not uninitialized. If `chain` is null or invalid, this
|
||||
/// function will return an error.
|
||||
/// - `mvp` may be null, or if it is not null, must be an aligned pointer to 16 consecutive `float`
|
||||
/// values for the model view projection matrix.
|
||||
/// - `opt` may be null, or if it is not null, must be an aligned pointer to a valid `frame_gl_opt_t`
|
||||
/// struct.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn libra_d3d11_filter_chain_frame(chain: *mut libra_d3d11_filter_chain_t,
|
||||
frame_count: usize,
|
||||
image: libra_source_image_d3d11_t,
|
||||
viewport: libra_viewport_t,
|
||||
out: *const ID3D11RenderTargetView,
|
||||
mvp: *const f32,
|
||||
opt: *const FrameOptionsD3D11,
|
||||
|
||||
) -> libra_error_t {
|
||||
|
||||
ffi_body!(mut |chain| {
|
||||
assert_some_ptr!(mut chain);
|
||||
assert_non_null!(out);
|
||||
|
||||
let mvp = if mvp.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(<&[f32; 16]>::try_from(unsafe { slice::from_raw_parts(mvp, 16) }).unwrap())
|
||||
};
|
||||
|
||||
let opt = if opt.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(unsafe { opt.read() })
|
||||
};
|
||||
|
||||
let viewport = Viewport {
|
||||
x: viewport.x,
|
||||
y: viewport.y,
|
||||
size: Size::new(viewport.width, viewport.height),
|
||||
output: unsafe { (&*out).clone() },
|
||||
mvp,
|
||||
};
|
||||
|
||||
let image = image.try_into()?;
|
||||
chain.frame(image, &viewport, frame_count, opt.as_ref())?;
|
||||
})
|
||||
}
|
||||
|
||||
/// Free a D3D11 filter chain.
|
||||
///
|
||||
/// The resulting value in `chain` then becomes null.
|
||||
/// ## Safety
|
||||
/// - `chain` must be either null or a valid and aligned pointer to an initialized `libra_d3d11_filter_chain_t`.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn libra_d3d11_filter_chain_free(chain: *mut libra_d3d11_filter_chain_t) -> libra_error_t {
|
||||
ffi_body!({
|
||||
assert_non_null!(chain);
|
||||
unsafe {
|
||||
let chain_ptr = &mut *chain;
|
||||
let chain = chain_ptr.take();
|
||||
drop(Box::from_raw(chain.unwrap().as_ptr()))
|
||||
};
|
||||
})
|
||||
}
|
Loading…
Reference in a new issue