diff --git a/Cargo.lock b/Cargo.lock index ba053f6..55840bb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1548,6 +1548,7 @@ dependencies = [ "objc2 0.5.0", "paste", "rustc-hash", + "sptr", "thiserror", "windows 0.48.0", ] diff --git a/librashader-capi/Cargo.toml b/librashader-capi/Cargo.toml index f0a14ed..9627cab 100644 --- a/librashader-capi/Cargo.toml +++ b/librashader-capi/Cargo.toml @@ -36,6 +36,7 @@ gl = { version = "0.14.0", optional = true } rustc-hash = "1.1.0" ash = { version = "0.37", optional = true } spirv_cross = { package = "librashader-spirv-cross", version = "0.25.1" } +sptr = "0.3.2" [dependencies.librashader] path = "../librashader" diff --git a/librashader-capi/src/error.rs b/librashader-capi/src/error.rs index 3300eba..bb5797d 100644 --- a/librashader-capi/src/error.rs +++ b/librashader-capi/src/error.rs @@ -206,12 +206,12 @@ impl LibrashaderError { macro_rules! assert_non_null { ($value:ident) => { - if $value.is_null() || !$value.is_aligned() { + if $value.is_null() || !$crate::ffi::ptr_is_aligned($value) { return $crate::error::LibrashaderError::InvalidParameter(stringify!($value)).export(); } }; (noexport $value:ident) => { - if $value.is_null() || !$value.is_aligned() { + if $value.is_null() || !$crate::ffi::ptr_is_aligned($value) { return Err($crate::error::LibrashaderError::InvalidParameter( stringify!($value), )); diff --git a/librashader-capi/src/ffi.rs b/librashader-capi/src/ffi.rs index 4937f19..8e2611a 100644 --- a/librashader-capi/src/ffi.rs +++ b/librashader-capi/src/ffi.rs @@ -222,5 +222,25 @@ macro_rules! extern_fn { }; } +pub fn boxed_slice_into_raw_parts(vec: Box<[T]>) -> (*mut T, usize) { + let mut me = ManuallyDrop::new(vec); + (me.as_mut_ptr(), me.len()) +} + +pub unsafe fn boxed_slice_from_raw_parts(ptr: *mut T, len: usize) -> Box<[T]> { + unsafe { Box::from_raw(std::slice::from_raw_parts_mut(ptr, len)) } +} + +#[allow(unstable_name_collisions)] +pub fn ptr_is_aligned(ptr: *const T) -> bool { + use sptr::Strict; + let align = std::mem::align_of::(); + if !align.is_power_of_two() { + panic!("is_aligned_to: align is not a power-of-two"); + } + ptr.addr() & (align - 1) == 0 +} + pub(crate) use extern_fn; pub(crate) use ffi_body; +use std::mem::ManuallyDrop; diff --git a/librashader-capi/src/lib.rs b/librashader-capi/src/lib.rs index 55c8b96..2e110ec 100644 --- a/librashader-capi/src/lib.rs +++ b/librashader-capi/src/lib.rs @@ -65,11 +65,11 @@ #![allow(non_camel_case_types)] #![feature(try_blocks)] -#![feature(pointer_is_aligned)] -#![feature(vec_into_raw_parts)] #![deny(unsafe_op_in_unsafe_fn)] #![deny(deprecated)] +extern crate alloc; + pub mod ctypes; pub mod error; mod ffi; diff --git a/librashader-capi/src/presets.rs b/librashader-capi/src/presets.rs index 60cc14f..30976b5 100644 --- a/librashader-capi/src/presets.rs +++ b/librashader-capi/src/presets.rs @@ -218,12 +218,15 @@ extern_fn! { step: param.step }) } - let (parts, len, cap) = values.into_raw_parts(); + + let values = values.into_boxed_slice(); + let (parts, len) = crate::ffi::boxed_slice_into_raw_parts(values); + unsafe { out.write(MaybeUninit::new(libra_preset_param_list_t { parameters: parts, length: len as u64, - _internal_alloc: cap as u64, + _internal_alloc: 0, })); } } @@ -251,9 +254,9 @@ extern_fn! { /// in undefined behaviour. fn libra_preset_free_runtime_params(preset: libra_preset_param_list_t) { unsafe { - let values = Vec::from_raw_parts(preset.parameters.cast_mut(), - preset.length as usize, - preset._internal_alloc as usize); + let values = + crate::ffi::boxed_slice_from_raw_parts(preset.parameters.cast_mut(), + preset.length as usize).into_vec(); for value in values { let name = CString::from_raw(value.name.cast_mut()); diff --git a/test/capi-tests/librashader-capi-tests/librashader-capi-tests/librashader-capi-tests.cpp b/test/capi-tests/librashader-capi-tests/librashader-capi-tests/librashader-capi-tests.cpp index 2d09f78..e852606 100644 --- a/test/capi-tests/librashader-capi-tests/librashader-capi-tests/librashader-capi-tests.cpp +++ b/test/capi-tests/librashader-capi-tests/librashader-capi-tests/librashader-capi-tests.cpp @@ -39,7 +39,13 @@ int main() libra_preset_param_list_t parameters; error = instance.preset_get_runtime_params(&preset, ¶meters); - libra_preset_param_t next = parameters.parameters[471]; + for (int i = 0; i < parameters.length; i++) { + libra_preset_param_t param = parameters.parameters[i]; + + printf("%s\n", param.description); + + } + instance.preset_free_runtime_params(parameters);