From dda00cc0486ce2f7febc62e108ee5544bf3b31f3 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Mon, 29 Jul 2024 21:02:03 +0200 Subject: [PATCH] Implement custom `Drop` for `IRVersionedCSInfo` Every `IRVersioned*Info` structure has an accompanying `IRShaderReflectionRelease*Info()` function to clean up allocated pointers inside, mostly strings. Even though `IRVersionedCSInfo` doesn't contain any pointers, it is a versioned structure that could be extended in the future with allocated objects, so we should call the existing (currently no-op) `Release` function on it prematurely. --- src/lib.rs | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 01683b0..97f5c9c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,6 +5,7 @@ use std::{ ffi::{c_char, CStr, OsStr}, fmt, mem::MaybeUninit, + ops::Deref, ptr::NonNull, sync::Arc, }; @@ -121,10 +122,7 @@ impl IRShaderReflection { } #[doc(alias = "IRShaderReflectionCopyComputeInfo")] - pub fn compute_info( - &self, - version: ffi::IRReflectionVersion, - ) -> Option { + pub fn compute_info(&self, version: ffi::IRReflectionVersion) -> Option { let mut info = MaybeUninit::uninit(); if unsafe { self.funcs.IRShaderReflectionCopyComputeInfo( @@ -133,13 +131,38 @@ impl IRShaderReflection { info.as_mut_ptr(), ) } { - Some(unsafe { info.assume_init() }) + Some(IRVersionedCSInfo { + me: unsafe { info.assume_init() }, + funcs: self.funcs.clone(), + }) } else { None } } } +pub struct IRVersionedCSInfo { + me: ffi::IRVersionedCSInfo, + funcs: Arc, +} + +impl Deref for IRVersionedCSInfo { + type Target = ffi::IRVersionedCSInfo; + + fn deref(&self) -> &Self::Target { + &self.me + } +} + +impl Drop for IRVersionedCSInfo { + fn drop(&mut self) { + assert!(unsafe { + self.funcs + .IRShaderReflectionReleaseComputeInfo(&mut self.me) + }) + } +} + pub struct IRObject { me: NonNull, funcs: Arc,