diff --git a/slang-sys/src/lib.rs b/slang-sys/src/lib.rs index ef9c70f..383795c 100644 --- a/slang-sys/src/lib.rs +++ b/slang-sys/src/lib.rs @@ -6,6 +6,13 @@ use std::ffi::{c_char, c_int, c_void}; // Based on Slang version 2024.14.3 +#[repr(C)] +pub struct ICastableVtable { + pub _base: ISlangUnknown__bindgen_vtable, + + pub castAs: unsafe extern "C" fn(*mut c_void, guid: *const SlangUUID) -> *mut c_void, +} + #[repr(C)] pub struct IBlobVtable { pub _base: ISlangUnknown__bindgen_vtable, @@ -72,6 +79,13 @@ pub struct ISessionVtable { pub loadModuleFromSourceString: unsafe extern "C" fn(*mut c_void, moduleName: *const c_char, path: *const c_char, string: *const c_char, outDiagnostics: *mut *mut ISlangBlob) -> *mut slang_IModule, } +#[repr(C)] +pub struct IMetadataVtable { + pub _base: ICastableVtable, + + pub isParameterLocationUsed: unsafe extern "C" fn(*mut c_void, category: SlangParameterCategory, spaceIndex: SlangUInt, registerIndex: SlangUInt, outUsed: *mut bool) -> SlangResult, +} + #[repr(C)] pub struct IComponentTypeVtable { pub _base: ISlangUnknown__bindgen_vtable, diff --git a/src/lib.rs b/src/lib.rs index 91a194a..5b2f6a8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,8 +10,8 @@ pub use sys::{ slang_TargetDesc as TargetDesc, SlangCompileTarget as CompileTarget, SlangDebugInfoLevel as DebugInfoLevel, SlangFloatingPointMode as FloatingPointMode, SlangLineDirectiveMode as LineDirectiveMode, SlangMatrixLayoutMode as MatrixLayoutMode, - SlangOptimizationLevel as OptimizationLevel, SlangSourceLanguage as SourceLanguage, - SlangStage as Stage, SlangUUID as UUID, + SlangOptimizationLevel as OptimizationLevel, SlangParameterCategory as ParameterCategory, + SlangSourceLanguage as SourceLanguage, SlangStage as Stage, SlangUUID as UUID, }; macro_rules! vcall { @@ -45,6 +45,10 @@ impl std::fmt::Debug for Error { pub type Result = std::result::Result; +pub(crate) fn succeeded(result: sys::SlangResult) -> bool { + result >= 0 +} + fn result_from_blob(code: sys::SlangResult, blob: *mut sys::slang_IBlob) -> Result<()> { if code < 0 { Err(Error::Blob(Blob(IUnknown( @@ -257,6 +261,36 @@ impl Session { } } +#[repr(transparent)] +#[derive(Clone)] +pub struct Metadata(IUnknown); + +unsafe impl Interface for Metadata { + type Vtable = sys::IMetadataVtable; + const IID: UUID = uuid( + 0x8044a8a3, + 0xddc0, + 0x4b7f, + [0xaf, 0x8e, 0x2, 0x6e, 0x90, 0x5d, 0x73, 0x32], + ); +} + +impl Metadata { + pub fn is_parameter_location_used( + &self, + category: ParameterCategory, + space_index: u64, + register_index: u64, + ) -> Option { + let mut used = false; + let res = vcall!( + self, + isParameterLocationUsed(category, space_index, register_index, &mut used) + ); + succeeded(res).then(|| used) + } +} + #[repr(transparent)] #[derive(Clone)] pub struct ComponentType(IUnknown); @@ -316,6 +350,49 @@ impl ComponentType { ))) } + pub fn target_metadata(&self, target_index: i64) -> Result { + let mut metadata = null_mut(); + let mut diagnostics = null_mut(); + + result_from_blob( + vcall!( + self, + getTargetMetadata(target_index, &mut metadata, &mut diagnostics) + ), + diagnostics, + )?; + + Ok(Metadata(IUnknown( + std::ptr::NonNull::new(metadata as *mut _).unwrap(), + ))) + } + + pub fn entry_point_metadata( + &self, + entry_point_index: i64, + target_index: i64, + ) -> Result { + let mut metadata = null_mut(); + let mut diagnostics = null_mut(); + + result_from_blob( + vcall!( + self, + getEntryPointMetadata( + entry_point_index, + target_index, + &mut metadata, + &mut diagnostics + ) + ), + diagnostics, + )?; + + Ok(Metadata(IUnknown( + std::ptr::NonNull::new(metadata as *mut _).unwrap(), + ))) + } + #[deprecated = "Use `entry_point_code` instead"] pub fn get_entry_point_code(&self, index: i64, target: i64) -> Result { self.entry_point_code(index, target) diff --git a/src/reflection/user_attribute.rs b/src/reflection/user_attribute.rs index 0acbdd8..5f31e9f 100644 --- a/src/reflection/user_attribute.rs +++ b/src/reflection/user_attribute.rs @@ -1,10 +1,6 @@ use super::{rcall, Type}; use slang_sys as sys; -fn succeeded(result: sys::SlangResult) -> bool { - result >= 0 -} - #[repr(transparent)] pub struct UserAttribute(sys::SlangReflectionUserAttribute); @@ -28,7 +24,7 @@ impl UserAttribute { self, index, &mut out )); - succeeded(result).then(|| out) + crate::succeeded(result).then(|| out) } pub fn argument_value_float(&self, index: u32) -> Option { @@ -37,7 +33,7 @@ impl UserAttribute { self, index, &mut out )); - succeeded(result).then(|| out) + crate::succeeded(result).then(|| out) } pub fn argument_value_string(&self, index: u32) -> Option<&str> {