capi: d3d11 capi
This commit is contained in:
parent
6ab03ecc99
commit
0e18b56752
1 changed files with 143 additions and 0 deletions
|
@ -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…
Add table
Reference in a new issue