use core::ffi::c_void;
use core::fmt;
use crate::gpu_resource::InvalidHandleError;
macro_rules! define_raw_handle {
(
$(#[$attr:meta])*
$name:ident, $payload_label:expr
) => {
$(#[$attr])*
#[derive(Copy, Clone)]
#[repr(transparent)]
pub struct $name {
ptr: *mut c_void,
}
impl $name {
#[doc = concat!("Wrap a raw `", $payload_label, "` in the typed newtype, rejecting null.")]
#[doc = concat!(
"* `ptr` must be a live `", $payload_label, "` — that exact API kind, not \
merely a non-null pointer. The only check performed is the null rejection \
below; the value is otherwise stored verbatim and later handed to the bridge \
dispatcher, which calls into the owning API through it."
)]
#[doc = concat!(" `", stringify!($name), "` is `Send + Sync`, so a copy may be moved to \
and shared with the interop worker threads. Where the API forbids that — \
recording into one `id<MTLCommandBuffer>` from two threads, or a GL context \
that is current on exactly one thread — the caller must confine the value \
itself; nothing here enforces it.")]
#[inline]
pub unsafe fn try_from_raw(ptr: *mut c_void) -> Result<Self, InvalidHandleError> {
if ptr.is_null() {
return Err(InvalidHandleError::NullPointer($payload_label));
}
Ok(Self { ptr })
}
#[inline]
pub fn as_raw(&self) -> *mut c_void {
self.ptr
}
}
impl fmt::Debug for $name {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct(stringify!($name)).finish_non_exhaustive()
}
}
unsafe impl Send for $name {}
unsafe impl Sync for $name {}
};
}
define_raw_handle! {
CudaContext, "CUcontext"
}
define_raw_handle! {
CudaStreamRef, "CUstream"
}
define_raw_handle! {
ClContext, "cl_context"
}
define_raw_handle! {
ClQueueRef, "cl_command_queue"
}
define_raw_handle! {
D3D11Device, "ID3D11Device*"
}
define_raw_handle! {
D3D12Device, "ID3D12Device*"
}
define_raw_handle! {
VkInstance, "VkInstance"
}
define_raw_handle! {
VkDevice, "VkDevice"
}
define_raw_handle! {
MtlDevice, "id<MTLDevice>"
}
define_raw_handle! {
MtlCommandBufferRef, "id<MTLCommandBuffer>"
}
define_raw_handle! {
GlContextRef, "EGLContext/HGLRC/CGLContextObj"
}