1use crate::device::OidnDevice;
6use crate::error::Error;
7use crate::sys;
8
9#[derive(Clone, Copy, Debug, PartialEq, Eq)]
11#[repr(u32)]
12pub enum BufferStorage {
13 Undefined = 0,
14 Host = 1,
16 Device = 2,
18 Managed = 3,
20}
21
22impl From<sys::OIDNStorage> for BufferStorage {
23 fn from(s: sys::OIDNStorage) -> Self {
24 match s {
25 sys::OIDNStorage::Undefined => BufferStorage::Undefined,
26 sys::OIDNStorage::Host => BufferStorage::Host,
27 sys::OIDNStorage::Device => BufferStorage::Device,
28 sys::OIDNStorage::Managed => BufferStorage::Managed,
29 }
30 }
31}
32
33impl From<BufferStorage> for sys::OIDNStorage {
34 fn from(s: BufferStorage) -> sys::OIDNStorage {
35 match s {
36 BufferStorage::Undefined => sys::OIDNStorage::Undefined,
37 BufferStorage::Host => sys::OIDNStorage::Host,
38 BufferStorage::Device => sys::OIDNStorage::Device,
39 BufferStorage::Managed => sys::OIDNStorage::Managed,
40 }
41 }
42}
43
44#[derive(Clone, Copy, Debug, PartialEq, Eq)]
46#[repr(u32)]
47pub enum ExternalMemoryTypeFlag {
48 None = 0,
49 OpaqueFD = 1 << 0,
50 DmaBuf = 1 << 1,
51 OpaqueWin32 = 1 << 2,
52 OpaqueWin32KMT = 1 << 3,
53 D3D11Texture = 1 << 4,
54 D3D11TextureKMT = 1 << 5,
55 D3D11Resource = 1 << 6,
56 D3D11ResourceKMT = 1 << 7,
57 D3D12Heap = 1 << 8,
58 D3D12Resource = 1 << 9,
59}
60
61impl From<ExternalMemoryTypeFlag> for sys::OIDNExternalMemoryTypeFlag {
62 fn from(f: ExternalMemoryTypeFlag) -> sys::OIDNExternalMemoryTypeFlag {
63 unsafe { std::mem::transmute(f as u32) }
64 }
65}
66
67pub struct OidnBuffer {
69 pub(crate) raw: sys::OIDNBuffer,
70 _device: std::marker::PhantomData<OidnDevice>,
71}
72
73impl std::fmt::Debug for OidnBuffer {
74 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
75 f.debug_struct("OidnBuffer")
76 .field("size", &self.size())
77 .field("storage", &self.storage())
78 .finish_non_exhaustive()
79 }
80}
81
82impl OidnBuffer {
83 pub fn new(device: &OidnDevice, byte_size: usize) -> Result<Self, Error> {
89 let raw = unsafe { sys::oidnNewBuffer(device.raw(), byte_size) };
90 if raw.is_null() {
91 return Err(device.take_error().unwrap_or(Error::OutOfMemory));
92 }
93 Ok(Self {
94 raw,
95 _device: std::marker::PhantomData,
96 })
97 }
98
99 pub fn new_with_storage(
105 device: &OidnDevice,
106 byte_size: usize,
107 storage: BufferStorage,
108 ) -> Result<Self, Error> {
109 let raw = unsafe {
110 sys::oidnNewBufferWithStorage(device.raw(), byte_size, storage.into())
111 };
112 if raw.is_null() {
113 return Err(device.take_error().unwrap_or(Error::OutOfMemory));
114 }
115 Ok(Self {
116 raw,
117 _device: std::marker::PhantomData,
118 })
119 }
120
121 pub unsafe fn new_shared(device: &OidnDevice, dev_ptr: *mut std::ffi::c_void, byte_size: usize) -> Result<Self, Error> {
132 let raw = sys::oidnNewSharedBuffer(device.raw(), dev_ptr, byte_size);
133 if raw.is_null() {
134 return Err(device.take_error().unwrap_or(Error::OutOfMemory));
135 }
136 Ok(Self {
137 raw,
138 _device: std::marker::PhantomData,
139 })
140 }
141
142 pub fn new_shared_from_fd(
148 device: &OidnDevice,
149 fd_type: ExternalMemoryTypeFlag,
150 fd: i32,
151 byte_size: usize,
152 ) -> Result<Self, Error> {
153 let raw = unsafe {
154 sys::oidnNewSharedBufferFromFD(device.raw(), fd_type.into(), fd, byte_size)
155 };
156 if raw.is_null() {
157 return Err(device.take_error().unwrap_or(Error::OutOfMemory));
158 }
159 Ok(Self {
160 raw,
161 _device: std::marker::PhantomData,
162 })
163 }
164
165 pub unsafe fn new_shared_from_win32_handle(
176 device: &OidnDevice,
177 handle_type: ExternalMemoryTypeFlag,
178 handle: *mut std::ffi::c_void,
179 name: *const std::ffi::c_void,
180 byte_size: usize,
181 ) -> Result<Self, Error> {
182 let raw = sys::oidnNewSharedBufferFromWin32Handle(
183 device.raw(),
184 handle_type.into(),
185 handle,
186 name,
187 byte_size,
188 );
189 if raw.is_null() {
190 return Err(device.take_error().unwrap_or(Error::OutOfMemory));
191 }
192 Ok(Self {
193 raw,
194 _device: std::marker::PhantomData,
195 })
196 }
197
198 pub unsafe fn new_shared_from_metal(
208 device: &OidnDevice,
209 metal_buffer: *mut std::ffi::c_void,
210 ) -> Result<Self, Error> {
211 let raw = sys::oidnNewSharedBufferFromMetal(device.raw(), metal_buffer);
212 if raw.is_null() {
213 return Err(device.take_error().unwrap_or(Error::OutOfMemory));
214 }
215 Ok(Self {
216 raw,
217 _device: std::marker::PhantomData,
218 })
219 }
220
221 pub fn size(&self) -> usize {
223 unsafe { sys::oidnGetBufferSize(self.raw) }
224 }
225
226 pub fn storage(&self) -> BufferStorage {
228 unsafe { sys::oidnGetBufferStorage(self.raw) }.into()
229 }
230
231 pub fn data(&self) -> *mut std::ffi::c_void {
233 unsafe { sys::oidnGetBufferData(self.raw) }
234 }
235
236 pub unsafe fn read(&self, byte_offset: usize, byte_size: usize, dst: *mut std::ffi::c_void) {
241 sys::oidnReadBuffer(self.raw, byte_offset, byte_size, dst);
242 }
243
244 pub unsafe fn read_async(&self, byte_offset: usize, byte_size: usize, dst: *mut std::ffi::c_void) {
249 sys::oidnReadBufferAsync(self.raw, byte_offset, byte_size, dst);
250 }
251
252 pub unsafe fn write(&self, byte_offset: usize, byte_size: usize, src: *const std::ffi::c_void) {
257 sys::oidnWriteBuffer(self.raw, byte_offset, byte_size, src);
258 }
259
260 pub unsafe fn write_async(&self, byte_offset: usize, byte_size: usize, src: *const std::ffi::c_void) {
265 sys::oidnWriteBufferAsync(self.raw, byte_offset, byte_size, src);
266 }
267
268 pub fn retain(&self) {
270 unsafe { sys::oidnRetainBuffer(self.raw) };
271 }
272
273 pub(crate) fn raw(&self) -> sys::OIDNBuffer {
274 self.raw
275 }
276}
277
278impl Drop for OidnBuffer {
279 fn drop(&mut self) {
280 unsafe { sys::oidnReleaseBuffer(self.raw) }
281 }
282}
283
284unsafe impl Send for OidnBuffer {}
285unsafe impl Sync for OidnBuffer {}