1use std::rc::Rc;
2use taichi_sys::{TiImageAllocateInfo, TiImageDimension, TiImageExtent, TiFormat, TiImageUsageFlags, TI_TRUE, TiImage, ti_allocate_image, ti_free_image, TiRuntime, TI_FALSE};
3
4use crate::{get_last_error, Result, Runtime};
5
6pub struct ImageBuilder<'a> {
7 runtime: &'a Runtime,
8 allocate_info: TiImageAllocateInfo,
9}
10impl<'a> ImageBuilder<'a> {
11 pub fn new(runtime: &'a Runtime) -> Self {
12 let allocate_info = TiImageAllocateInfo {
13 dimension: TiImageDimension::D2D,
14 extent: TiImageExtent {
15 width: 1,
16 height: 1,
17 depth: 1,
18 array_layer_count: 1,
19 },
20 mip_level_count: 1,
21 format: TiFormat::Rgba8,
22 export_sharing: TI_FALSE,
23 usage: TiImageUsageFlags::SAMPLED_BIT | TiImageUsageFlags::STORAGE_BIT,
24 };
25 ImageBuilder {
26 runtime,
27 allocate_info,
28 }
29 }
30
31 pub fn dimension(&mut self, dimension: TiImageDimension) -> &mut Self {
32 self.allocate_info.dimension = dimension;
33 self
34 }
35 pub fn width(&mut self, width: usize) -> &mut Self {
36 self.allocate_info.extent.width = width as u32;
37 self
38 }
39 pub fn height(&mut self, height: usize) -> &mut Self {
40 self.allocate_info.extent.height = height as u32;
41 self
42 }
43 pub fn depth(&mut self, depth: usize) -> &mut Self {
44 self.allocate_info.extent.depth = depth as u32;
45 self
46 }
47 pub fn array_layer_count(&mut self, array_layer_count: usize) -> &mut Self {
48 self.allocate_info.extent.array_layer_count = array_layer_count as u32;
49 self
50 }
51 pub fn mip_level_count(&mut self, mip_level_count: usize) -> &mut Self {
52 self.allocate_info.mip_level_count = mip_level_count as u32;
53 self
54 }
55 pub fn format(&mut self, format: TiFormat) -> &mut Self {
56 self.allocate_info.format = format;
57 self
58 }
59 pub fn export_sharing(&mut self, export_sharing: bool) -> &mut Self {
60 self.allocate_info.export_sharing = if export_sharing { TI_TRUE } else { TI_FALSE };
61 self
62 }
63 pub fn usage(&mut self, usage: TiImageUsageFlags) -> &mut Self {
64 self.allocate_info.usage = usage;
65 self
66 }
67
68 pub fn build(&self) -> Result<Image> {
69 Image::new(self.runtime, &self.allocate_info)
70 }
71}
72
73struct Image_ {
74 runtime: Runtime,
75 image: TiImage,
76 allocate_info: TiImageAllocateInfo,
77}
78impl Image_ {
79 pub fn new(runtime: &Runtime, allocate_info: &TiImageAllocateInfo) -> Result<Self> {
80 let image = unsafe {
81 ti_allocate_image(runtime.runtime(), allocate_info)
82 };
83 get_last_error()?;
84 Ok(Image_ {
85 runtime: runtime.clone(),
86 image,
87 allocate_info: allocate_info.clone(),
88 })
89 }
90}
91impl Drop for Image_ {
92 fn drop(&mut self) {
93 unsafe {
94 ti_free_image(self.runtime.runtime(), self.image);
95 }
96 }
97}
98
99#[derive(Clone)]
100pub struct Image {
101 inner: Rc<Image_>,
102}
103impl Image {
104 pub fn new(runtime: &Runtime, allocate_info: &TiImageAllocateInfo) -> Result<Self> {
105 Ok(Image {
106 inner: Rc::new(Image_::new(runtime, allocate_info)?),
107 })
108 }
109
110 pub fn runtime(&self) -> TiRuntime {
111 self.inner.runtime.runtime()
112 }
113 pub fn image(&self) -> TiImage {
114 self.inner.image
115 }
116
117 pub fn dimension(&self) -> TiImageDimension {
118 self.inner.allocate_info.dimension
119 }
120 pub fn width(&self) -> u32 {
121 self.inner.allocate_info.extent.width
122 }
123 pub fn height(&self) -> u32 {
124 self.inner.allocate_info.extent.height
125 }
126 pub fn depth(&self) -> u32 {
127 self.inner.allocate_info.extent.depth
128 }
129 pub fn array_layer_count(&self) -> u32 {
130 self.inner.allocate_info.extent.array_layer_count
131 }
132 pub fn mip_level_count(&self) -> u32 {
133 self.inner.allocate_info.mip_level_count
134 }
135 pub fn format(&self) -> TiFormat {
136 self.inner.allocate_info.format
137 }
138 pub fn export_sharing(&self) -> bool {
139 self.inner.allocate_info.export_sharing != TI_FALSE
140 }
141 pub fn usage(&self) -> TiImageUsageFlags {
142 self.inner.allocate_info.usage
143 }
144}
145