From b928a8068dd810cb9021117858ffc77a2dd809f4 Mon Sep 17 00:00:00 2001 From: chyyran Date: Sat, 3 Dec 2022 18:56:57 -0500 Subject: [PATCH] capi: finish basic gl capi --- .idea/src.iml | 3 + librashader-capi/cbindgen.toml | 6 +- librashader-capi/librashader.h | 39 ++++++++++-- librashader-capi/src/ctypes.rs | 8 +++ librashader-capi/src/runtime/gl.rs | 62 ++++++++++++++++++- .../src/filter_chain/filter_impl.rs | 11 +++- .../src/filter_chain/mod.rs | 17 ++++- librashader-runtime-gl/src/lib.rs | 1 + 8 files changed, 134 insertions(+), 13 deletions(-) diff --git a/.idea/src.iml b/.idea/src.iml index bb57c00..6fdd171 100644 --- a/.idea/src.iml +++ b/.idea/src.iml @@ -15,6 +15,9 @@ + + + diff --git a/librashader-capi/cbindgen.toml b/librashader-capi/cbindgen.toml index ff08f9d..8096adc 100644 --- a/librashader-capi/cbindgen.toml +++ b/librashader-capi/cbindgen.toml @@ -28,7 +28,7 @@ include = [ "PFN_lbr_preset_get_param", "PFN_lbr_preset_print", "PFN_lbr_preset_get_runtime_param_names", - "GLFilterChain" + "FilterChain" ] @@ -37,5 +37,5 @@ include = [ [export.rename] "LibrashaderError" = "_libra_error" "ShaderPreset" = "_shader_preset" -"GLFilterChain" = "_filter_chain_gl" -"GLFilterChainOptions" = "filter_chain_gl_opt_t" +"FilterChainGL" = "_filter_chain_gl" +"FilterChainOptionsGL" = "filter_chain_gl_opt_t" diff --git a/librashader-capi/librashader.h b/librashader-capi/librashader.h index 71f866a..13f6653 100644 --- a/librashader-capi/librashader.h +++ b/librashader-capi/librashader.h @@ -9,7 +9,7 @@ #include #include -typedef struct FilterChain FilterChain; +typedef struct _filter_chain_gl _filter_chain_gl; typedef struct _libra_error _libra_error; @@ -27,12 +27,34 @@ typedef struct _shader_preset *libra_shader_preset_t; typedef const void *(*gl_loader_t)(const char*); -typedef struct FilterChainOptions { +typedef struct filter_chain_gl_opt_t { uint16_t gl_version; bool use_dsa; -} FilterChainOptions; +} filter_chain_gl_opt_t; -typedef struct FilterChain *libra_gl_filter_chain_t; +typedef struct _filter_chain_gl *libra_gl_filter_chain_t; + +typedef struct libra_source_image_gl_t { + uint32_t handle; + uint32_t format; + uint32_t width; + uint32_t height; +} libra_source_image_gl_t; + +typedef struct libra_viewport_t { + float x; + float y; + uint32_t width; + uint32_t height; +} libra_viewport_t; + +typedef struct libra_draw_framebuffer_gl_t { + uint32_t handle; + uint32_t texture; + uint32_t format; + uint32_t width; + uint32_t height; +} libra_draw_framebuffer_gl_t; /** * Load a preset. @@ -106,9 +128,16 @@ libra_error_t libra_gl_init_context(gl_loader_t loader); * - `out` may be either null or uninitialized, but must be aligned. */ libra_error_t libra_gl_create_filter_chain(libra_shader_preset_t *preset, - const struct FilterChainOptions *options, + const struct filter_chain_gl_opt_t *options, libra_gl_filter_chain_t *out); +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_draw_framebuffer_gl_t out, + const float *mvp); + #ifdef __cplusplus } // extern "C" #endif // __cplusplus diff --git a/librashader-capi/src/ctypes.rs b/librashader-capi/src/ctypes.rs index 1668566..485f60c 100644 --- a/librashader-capi/src/ctypes.rs +++ b/librashader-capi/src/ctypes.rs @@ -7,3 +7,11 @@ pub type libra_error_t = *const LibrashaderError; // #[cfg(feature = "runtime-opengl")] pub type libra_gl_filter_chain_t = ManuallyDrop>>; + +#[repr(C)] +pub struct libra_viewport_t { + pub x: f32, + pub y: f32, + pub width: u32, + pub height: u32, +} \ No newline at end of file diff --git a/librashader-capi/src/runtime/gl.rs b/librashader-capi/src/runtime/gl.rs index 42febd4..cffb0b1 100644 --- a/librashader-capi/src/runtime/gl.rs +++ b/librashader-capi/src/runtime/gl.rs @@ -1,11 +1,14 @@ use std::ffi::{c_char, c_void, CString}; use std::mem::MaybeUninit; -use crate::ctypes::{libra_error_t, libra_gl_filter_chain_t, libra_shader_preset_t}; +use crate::ctypes::{libra_error_t, libra_gl_filter_chain_t, libra_shader_preset_t, libra_viewport_t}; use crate::error::{assert_non_null, assert_some, LibrashaderError}; use crate::ffi::ffi_body; use std::mem::ManuallyDrop; +use librashader::runtime::FilterChain; +use librashader::runtime::gl::{Framebuffer, GLImage, Viewport}; pub use librashader::runtime::gl::options::FilterChainOptionsGL; +use librashader::Size; pub type gl_loader_t = unsafe extern "C" fn (*const c_char) -> *const c_void; /// Initialize the OpenGL Context for librashader. @@ -58,4 +61,59 @@ pub unsafe extern "C" fn libra_gl_create_filter_chain(preset: *mut libra_shader_ out.write(MaybeUninit::new(ManuallyDrop::new(Some(Box::new(chain))))) } }) -} \ No newline at end of file +} + +#[repr(C)] +pub struct libra_source_image_gl_t { + pub handle: u32, + pub format: u32, + pub width: u32, + pub height: u32 +} + +#[repr(C)] +pub struct libra_draw_framebuffer_gl_t { + pub handle: u32, + pub texture: u32, + pub format: u32, + pub width: u32, + pub height: u32 +} + +impl From for GLImage { + fn from(value: libra_source_image_gl_t) -> Self { + GLImage { + handle: value.handle, + format: value.format, + size: Size::new(value.width, value.height), + padded_size: Size::default() + } + } +} + +#[no_mangle] +pub unsafe extern "C" fn libra_gl_filter_chain_frame(chain: *mut libra_gl_filter_chain_t, + frame_count: usize, + image: libra_source_image_gl_t, + viewport: libra_viewport_t, + out: libra_draw_framebuffer_gl_t, + mvp: *const f32, + +) -> libra_error_t { + + ffi_body!(mut |chain| { + assert_some!(chain); + let chain = chain.as_mut().unwrap(); + + let image: GLImage = image.into(); + let viewport = Viewport { + x: viewport.x, + y: viewport.y, + output: &chain.create_framebuffer_raw(out.texture, out.handle, out.format, Size::new(out.width, out.height), 1), + mvp: None, + }; + chain.frame(&image, &viewport, frame_count, None)?; + }) +} + + diff --git a/librashader-runtime-gl/src/filter_chain/filter_impl.rs b/librashader-runtime-gl/src/filter_chain/filter_impl.rs index e864a2d..7abe17c 100644 --- a/librashader-runtime-gl/src/filter_chain/filter_impl.rs +++ b/librashader-runtime-gl/src/filter_chain/filter_impl.rs @@ -7,8 +7,8 @@ use librashader_reflect::back::cross::{CrossGlslContext, GlslVersion}; use librashader_reflect::back::targets::GLSL; use librashader_reflect::front::shaderc::GlslangCompilation; use spirv_cross::spirv::Decoration; -use gl::types::{GLint, GLuint}; -use librashader_common::{FilterMode, WrapMode}; +use gl::types::{GLenum, GLint, GLuint}; +use librashader_common::{FilterMode, Size, WrapMode}; use std::collections::VecDeque; use librashader_reflect::reflect::ReflectShader; use crate::{error, GLImage, util, Viewport}; @@ -84,6 +84,13 @@ type ShaderPassMeta = ( ); impl FilterChainImpl { + pub(crate) fn create_framebuffer_raw(&self, texture: GLuint, + handle: GLuint, + format: GLenum, + size: Size, + miplevels: u32,) -> Framebuffer { + T::FramebufferInterface::new_from_raw(texture, handle, format, size, miplevels) + } /// Load a filter chain from a pre-parsed `ShaderPreset`. pub(crate) fn load_from_preset( preset: ShaderPreset, diff --git a/librashader-runtime-gl/src/filter_chain/mod.rs b/librashader-runtime-gl/src/filter_chain/mod.rs index d3ee991..0e1b56f 100644 --- a/librashader-runtime-gl/src/filter_chain/mod.rs +++ b/librashader-runtime-gl/src/filter_chain/mod.rs @@ -1,9 +1,10 @@ use std::path::Path; +use gl::types::{GLenum, GLuint}; use librashader_presets::ShaderPreset; use crate::filter_chain::filter_impl::FilterChainImpl; use crate::filter_chain::inner::FilterChainDispatch; -use crate::{GLImage, Viewport}; +use crate::{Framebuffer, GLImage, Viewport}; use crate::error::{Result, FilterChainError}; use crate::options::{FilterChainOptionsGL, FrameOptionsGL}; @@ -12,12 +13,26 @@ mod inner; mod parameters; pub(crate) use filter_impl::FilterCommon; +use librashader_common::Size; pub struct FilterChainGL { pub(in crate::filter_chain) filter: FilterChainDispatch, } impl FilterChainGL { + pub fn create_framebuffer_raw(&self, texture: GLuint, + handle: GLuint, + format: GLenum, + size: Size, + miplevels: u32,) -> Framebuffer { + + match &self.filter { + FilterChainDispatch::DirectStateAccess(p) => { + p.create_framebuffer_raw(texture, handle, format, size, miplevels) + } + FilterChainDispatch::Compatibility(p) => p.create_framebuffer_raw(texture, handle, format, size, miplevels), + } + } pub fn load_from_preset( preset: ShaderPreset, options: Option<&FilterChainOptionsGL>, diff --git a/librashader-runtime-gl/src/lib.rs b/librashader-runtime-gl/src/lib.rs index a4698c4..9678426 100644 --- a/librashader-runtime-gl/src/lib.rs +++ b/librashader-runtime-gl/src/lib.rs @@ -20,6 +20,7 @@ mod viewport; pub use filter_chain::FilterChainGL; pub use framebuffer::GLImage; pub use viewport::Viewport; +pub use crate::gl::Framebuffer; #[cfg(test)] mod tests {