use crate::Device;
use hmll_sys::{hmll_free_buffer, hmll_iobuf};
use std::ops;
use std::os::raw::c_void;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Range {
pub start: usize,
pub end: usize,
}
impl Range {
#[inline(always)]
pub const fn new(start: usize, end: usize) -> Self {
Self { start, end }
}
#[inline(always)]
pub const fn len(&self) -> usize {
self.end.saturating_sub(self.start)
}
#[inline(always)]
pub const fn is_empty(&self) -> bool {
self.start >= self.end
}
#[inline(always)]
pub(crate) fn to_raw(self) -> hmll_sys::hmll_range {
hmll_sys::hmll_range {
start: self.start,
end: self.end,
}
}
#[allow(unused)]
#[inline(always)]
pub(crate) const fn from_raw(range: hmll_sys::hmll_range) -> Self {
Self {
start: range.start,
end: range.end,
}
}
}
impl From<ops::Range<usize>> for Range {
#[inline(always)]
fn from(range: ops::Range<usize>) -> Self {
Self {
start: range.start,
end: range.end,
}
}
}
impl From<Range> for ops::Range<usize> {
#[inline(always)]
fn from(range: Range) -> Self {
range.start..range.end
}
}
#[derive(Debug)]
pub struct Buffer {
ptr: *mut u8,
size: usize,
device: Device,
#[allow(dead_code)]
owned: bool,
}
impl Buffer {
#[inline(always)]
pub(crate) unsafe fn from_raw_parts(
ptr: *mut u8,
size: usize,
device: Device,
owned: bool,
) -> Self {
Self {
ptr,
size,
device,
owned,
}
}
#[inline]
pub fn as_slice(&self) -> Option<&[u8]> {
if self.device == Device::Cpu && !self.ptr.is_null() {
unsafe { Some(std::slice::from_raw_parts(self.ptr, self.size)) }
} else {
None
}
}
#[inline(always)]
pub const fn len(&self) -> usize {
self.size
}
#[inline(always)]
pub const fn is_empty(&self) -> bool {
self.size == 0
}
#[inline(always)]
pub const fn device(&self) -> Device {
self.device
}
#[inline(always)]
pub const fn as_ptr(&self) -> *const u8 {
self.ptr as *const u8
}
#[inline(always)]
pub fn as_mut_ptr(&mut self) -> *mut u8 {
self.ptr
}
#[inline]
pub fn to_vec(&self) -> Vec<u8> {
self.as_slice()
.expect("Cannot convert GPU buffer to Vec")
.to_vec()
}
}
unsafe impl Send for Buffer {}
unsafe impl Sync for Buffer {}
impl Drop for Buffer {
fn drop(&mut self) {
if !self.ptr.is_null() {
let mut buf = hmll_iobuf {
size: self.size,
ptr: self.ptr.cast::<c_void>(),
device: self.device.to_raw(),
};
unsafe { hmll_free_buffer(&mut buf as *mut hmll_iobuf) };
self.ptr = std::ptr::null_mut();
self.size = 0;
}
}
}