• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use mesa_rust_gen::*;
2 
3 use std::{mem, ptr};
4 
5 #[derive(PartialEq, Eq, Hash)]
6 pub struct PipeResource {
7     pipe: *mut pipe_resource,
8     pub is_user: bool,
9 }
10 
11 // SAFETY: pipe_resource is considered a thread safe type
12 unsafe impl Send for PipeResource {}
13 unsafe impl Sync for PipeResource {}
14 
15 /// A thread safe wrapper around [pipe_image_view]. It's purpose is to increase the reference count
16 /// on the [pipe_resource] this view belongs to.
17 #[repr(transparent)]
18 pub struct PipeImageView {
19     pub(super) pipe: pipe_image_view,
20 }
21 
22 impl PipeImageView {
new(pipe: pipe_image_view) -> Self23     fn new(pipe: pipe_image_view) -> Self {
24         unsafe { pipe_resource_reference(&mut ptr::null_mut(), pipe.resource) }
25         Self { pipe: pipe }
26     }
27 
slice_to_pipe(slice: &[PipeImageView]) -> &[pipe_image_view]28     pub fn slice_to_pipe(slice: &[PipeImageView]) -> &[pipe_image_view] {
29         // SAFETY: `PipeImageView` is a transparent wrapper around `pipe_image_view`, so transmute
30         //         on the slice is safe.
31         unsafe { mem::transmute(slice) }
32     }
33 }
34 
35 impl Drop for PipeImageView {
drop(&mut self)36     fn drop(&mut self) {
37         unsafe { pipe_resource_reference(&mut self.pipe.resource, ptr::null_mut()) }
38     }
39 }
40 
41 // SAFETY: pipe_image_view is just static data around a pipe_resource, which itself is a thread-safe
42 //         type.
43 unsafe impl Send for PipeImageView {}
44 unsafe impl Sync for PipeImageView {}
45 
46 // Image dimensions provide by application to be used in both
47 // image and sampler views when image is created from buffer
48 #[derive(PartialEq, Eq)]
49 pub struct AppImgInfo {
50     row_stride: u32,
51     width: u32,
52     height: u32,
53 }
54 
55 impl AppImgInfo {
new(row_stride: u32, width: u32, height: u32) -> AppImgInfo56     pub fn new(row_stride: u32, width: u32, height: u32) -> AppImgInfo {
57         AppImgInfo {
58             row_stride: row_stride,
59             width: width,
60             height: height,
61         }
62     }
63 }
64 
65 impl PipeResource {
new(res: *mut pipe_resource, is_user: bool) -> Option<Self>66     pub(super) fn new(res: *mut pipe_resource, is_user: bool) -> Option<Self> {
67         if res.is_null() {
68             return None;
69         }
70 
71         Some(Self {
72             pipe: res,
73             is_user: is_user,
74         })
75     }
76 
pipe(&self) -> *mut pipe_resource77     pub(super) fn pipe(&self) -> *mut pipe_resource {
78         self.pipe
79     }
80 
as_ref(&self) -> &pipe_resource81     fn as_ref(&self) -> &pipe_resource {
82         unsafe { self.pipe.as_ref().unwrap() }
83     }
84 
width(&self) -> u3285     pub fn width(&self) -> u32 {
86         unsafe { self.pipe.as_ref().unwrap().width0 }
87     }
88 
height(&self) -> u1689     pub fn height(&self) -> u16 {
90         unsafe { self.pipe.as_ref().unwrap().height0 }
91     }
92 
depth(&self) -> u1693     pub fn depth(&self) -> u16 {
94         unsafe { self.pipe.as_ref().unwrap().depth0 }
95     }
96 
array_size(&self) -> u1697     pub fn array_size(&self) -> u16 {
98         unsafe { self.pipe.as_ref().unwrap().array_size }
99     }
100 
is_buffer(&self) -> bool101     pub fn is_buffer(&self) -> bool {
102         self.as_ref().target() == pipe_texture_target::PIPE_BUFFER
103     }
104 
is_linear(&self) -> bool105     pub fn is_linear(&self) -> bool {
106         self.as_ref().bind & PIPE_BIND_LINEAR != 0
107     }
108 
is_staging(&self) -> bool109     pub fn is_staging(&self) -> bool {
110         self.as_ref().usage() & pipe_resource_usage::PIPE_USAGE_STAGING.0 != 0
111     }
112 
pipe_image_view( &self, format: pipe_format, read_write: bool, host_access: u16, app_img_info: Option<&AppImgInfo>, ) -> PipeImageView113     pub fn pipe_image_view(
114         &self,
115         format: pipe_format,
116         read_write: bool,
117         host_access: u16,
118         app_img_info: Option<&AppImgInfo>,
119     ) -> PipeImageView {
120         let pipe = PipeResource::as_ref(self);
121         let u = if let Some(app_img_info) = app_img_info {
122             pipe_image_view__bindgen_ty_1 {
123                 tex2d_from_buf: pipe_image_view__bindgen_ty_1__bindgen_ty_3 {
124                     offset: 0,
125                     row_stride: app_img_info.row_stride as u16,
126                     width: app_img_info.width as u16,
127                     height: app_img_info.height as u16,
128                 },
129             }
130         } else if self.is_buffer() {
131             pipe_image_view__bindgen_ty_1 {
132                 buf: pipe_image_view__bindgen_ty_1__bindgen_ty_2 {
133                     offset: 0,
134                     size: pipe.width0,
135                 },
136             }
137         } else {
138             let mut tex = pipe_image_view__bindgen_ty_1__bindgen_ty_1::default();
139             tex.set_level(0);
140             tex.set_first_layer(0);
141             if pipe.target() == pipe_texture_target::PIPE_TEXTURE_3D {
142                 tex.set_last_layer((pipe.depth0 - 1).into());
143             } else if pipe.array_size > 0 {
144                 tex.set_last_layer((pipe.array_size - 1).into());
145             } else {
146                 tex.set_last_layer(0);
147             }
148 
149             pipe_image_view__bindgen_ty_1 { tex: tex }
150         };
151 
152         let shader_access = if read_write {
153             PIPE_IMAGE_ACCESS_READ_WRITE
154         } else {
155             PIPE_IMAGE_ACCESS_WRITE
156         } as u16;
157 
158         let access = if app_img_info.is_some() {
159             PIPE_IMAGE_ACCESS_TEX2D_FROM_BUFFER
160         } else {
161             0
162         } as u16;
163 
164         PipeImageView::new(pipe_image_view {
165             resource: self.pipe(),
166             format: format,
167             access: access | host_access,
168             shader_access: shader_access,
169             u: u,
170         })
171     }
172 
pipe_sampler_view_template( &self, format: pipe_format, app_img_info: Option<&AppImgInfo>, ) -> pipe_sampler_view173     pub fn pipe_sampler_view_template(
174         &self,
175         format: pipe_format,
176         app_img_info: Option<&AppImgInfo>,
177     ) -> pipe_sampler_view {
178         let mut res = pipe_sampler_view::default();
179         unsafe {
180             u_sampler_view_default_template(&mut res, self.pipe, format);
181         }
182 
183         if let Some(app_img_info) = app_img_info {
184             res.u.tex2d_from_buf.offset = 0;
185             res.u.tex2d_from_buf.row_stride = app_img_info.row_stride as u16;
186             res.u.tex2d_from_buf.width = app_img_info.width as u16;
187             res.u.tex2d_from_buf.height = app_img_info.height as u16;
188 
189             res.set_is_tex2d_from_buf(true);
190         } else if res.target() == pipe_texture_target::PIPE_BUFFER {
191             res.u.buf.offset = 0;
192             res.u.buf.size = self.as_ref().width0;
193         }
194 
195         res
196     }
197 }
198 
199 impl Drop for PipeResource {
drop(&mut self)200     fn drop(&mut self) {
201         unsafe { pipe_resource_reference(&mut self.pipe, ptr::null_mut()) }
202     }
203 }
204