use crate::device::OidnDevice;
use crate::error::Error;
use crate::sys;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum BufferStorage {
Undefined = 0,
Host = 1,
Device = 2,
Managed = 3,
}
impl From<sys::OIDNStorage> for BufferStorage {
fn from(s: sys::OIDNStorage) -> Self {
match s {
sys::OIDNStorage::Undefined => BufferStorage::Undefined,
sys::OIDNStorage::Host => BufferStorage::Host,
sys::OIDNStorage::Device => BufferStorage::Device,
sys::OIDNStorage::Managed => BufferStorage::Managed,
}
}
}
impl From<BufferStorage> for sys::OIDNStorage {
fn from(s: BufferStorage) -> sys::OIDNStorage {
match s {
BufferStorage::Undefined => sys::OIDNStorage::Undefined,
BufferStorage::Host => sys::OIDNStorage::Host,
BufferStorage::Device => sys::OIDNStorage::Device,
BufferStorage::Managed => sys::OIDNStorage::Managed,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum ExternalMemoryTypeFlag {
None = 0,
OpaqueFD = 1 << 0,
DmaBuf = 1 << 1,
OpaqueWin32 = 1 << 2,
OpaqueWin32KMT = 1 << 3,
D3D11Texture = 1 << 4,
D3D11TextureKMT = 1 << 5,
D3D11Resource = 1 << 6,
D3D11ResourceKMT = 1 << 7,
D3D12Heap = 1 << 8,
D3D12Resource = 1 << 9,
}
impl From<ExternalMemoryTypeFlag> for sys::OIDNExternalMemoryTypeFlag {
fn from(f: ExternalMemoryTypeFlag) -> sys::OIDNExternalMemoryTypeFlag {
unsafe { std::mem::transmute(f as u32) }
}
}
pub struct OidnBuffer {
pub(crate) raw: sys::OIDNBuffer,
_device: std::marker::PhantomData<OidnDevice>,
}
impl std::fmt::Debug for OidnBuffer {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("OidnBuffer")
.field("size", &self.size())
.field("storage", &self.storage())
.finish_non_exhaustive()
}
}
impl OidnBuffer {
pub fn new(device: &OidnDevice, byte_size: usize) -> Result<Self, Error> {
let raw = unsafe { sys::oidnNewBuffer(device.raw(), byte_size) };
if raw.is_null() {
return Err(device.take_error().unwrap_or(Error::OutOfMemory));
}
Ok(Self {
raw,
_device: std::marker::PhantomData,
})
}
pub fn new_with_storage(
device: &OidnDevice,
byte_size: usize,
storage: BufferStorage,
) -> Result<Self, Error> {
let raw = unsafe {
sys::oidnNewBufferWithStorage(device.raw(), byte_size, storage.into())
};
if raw.is_null() {
return Err(device.take_error().unwrap_or(Error::OutOfMemory));
}
Ok(Self {
raw,
_device: std::marker::PhantomData,
})
}
pub unsafe fn new_shared(device: &OidnDevice, dev_ptr: *mut std::ffi::c_void, byte_size: usize) -> Result<Self, Error> {
let raw = sys::oidnNewSharedBuffer(device.raw(), dev_ptr, byte_size);
if raw.is_null() {
return Err(device.take_error().unwrap_or(Error::OutOfMemory));
}
Ok(Self {
raw,
_device: std::marker::PhantomData,
})
}
pub fn new_shared_from_fd(
device: &OidnDevice,
fd_type: ExternalMemoryTypeFlag,
fd: i32,
byte_size: usize,
) -> Result<Self, Error> {
let raw = unsafe {
sys::oidnNewSharedBufferFromFD(device.raw(), fd_type.into(), fd, byte_size)
};
if raw.is_null() {
return Err(device.take_error().unwrap_or(Error::OutOfMemory));
}
Ok(Self {
raw,
_device: std::marker::PhantomData,
})
}
pub unsafe fn new_shared_from_win32_handle(
device: &OidnDevice,
handle_type: ExternalMemoryTypeFlag,
handle: *mut std::ffi::c_void,
name: *const std::ffi::c_void,
byte_size: usize,
) -> Result<Self, Error> {
let raw = sys::oidnNewSharedBufferFromWin32Handle(
device.raw(),
handle_type.into(),
handle,
name,
byte_size,
);
if raw.is_null() {
return Err(device.take_error().unwrap_or(Error::OutOfMemory));
}
Ok(Self {
raw,
_device: std::marker::PhantomData,
})
}
pub unsafe fn new_shared_from_metal(
device: &OidnDevice,
metal_buffer: *mut std::ffi::c_void,
) -> Result<Self, Error> {
let raw = sys::oidnNewSharedBufferFromMetal(device.raw(), metal_buffer);
if raw.is_null() {
return Err(device.take_error().unwrap_or(Error::OutOfMemory));
}
Ok(Self {
raw,
_device: std::marker::PhantomData,
})
}
pub fn size(&self) -> usize {
unsafe { sys::oidnGetBufferSize(self.raw) }
}
pub fn storage(&self) -> BufferStorage {
unsafe { sys::oidnGetBufferStorage(self.raw) }.into()
}
pub fn data(&self) -> *mut std::ffi::c_void {
unsafe { sys::oidnGetBufferData(self.raw) }
}
pub unsafe fn read(&self, byte_offset: usize, byte_size: usize, dst: *mut std::ffi::c_void) {
sys::oidnReadBuffer(self.raw, byte_offset, byte_size, dst);
}
pub unsafe fn read_async(&self, byte_offset: usize, byte_size: usize, dst: *mut std::ffi::c_void) {
sys::oidnReadBufferAsync(self.raw, byte_offset, byte_size, dst);
}
pub unsafe fn write(&self, byte_offset: usize, byte_size: usize, src: *const std::ffi::c_void) {
sys::oidnWriteBuffer(self.raw, byte_offset, byte_size, src);
}
pub unsafe fn write_async(&self, byte_offset: usize, byte_size: usize, src: *const std::ffi::c_void) {
sys::oidnWriteBufferAsync(self.raw, byte_offset, byte_size, src);
}
pub fn retain(&self) {
unsafe { sys::oidnRetainBuffer(self.raw) };
}
pub(crate) fn raw(&self) -> sys::OIDNBuffer {
self.raw
}
}
impl Drop for OidnBuffer {
fn drop(&mut self) {
unsafe { sys::oidnReleaseBuffer(self.raw) }
}
}
unsafe impl Send for OidnBuffer {}
unsafe impl Sync for OidnBuffer {}