rusticl/mesa: add thread-safe wrapper for pipe_image_views

In theory a pipe_image_view can outlive the pipe_resource it's referring
to, so we have to make sure that doesn't happen.

Signed-off-by: Karol Herbst <kherbst@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26040>
This commit is contained in:
Karol Herbst
2023-10-05 14:39:55 +02:00
committed by Marge Bot
parent 1166944124
commit 89868992ab
2 changed files with 43 additions and 10 deletions
@@ -520,7 +520,8 @@ impl PipeContext {
unsafe { self.pipe.as_ref().sampler_view_destroy.unwrap()(self.pipe.as_ptr(), view) }
}
pub fn set_shader_images(&self, images: &[pipe_image_view]) {
pub fn set_shader_images(&self, images: &[PipeImageView]) {
let images = PipeImageView::slice_to_pipe(images);
unsafe {
self.pipe.as_ref().set_shader_images.unwrap()(
self.pipe.as_ptr(),
@@ -1,6 +1,6 @@
use mesa_rust_gen::*;
use std::ptr;
use std::{mem, ptr};
#[derive(PartialEq, Eq, Hash)]
pub struct PipeResource {
@@ -12,6 +12,37 @@ pub struct PipeResource {
unsafe impl Send for PipeResource {}
unsafe impl Sync for PipeResource {}
/// A thread safe wrapper around [pipe_image_view]. It's purpose is to increase the reference count
/// on the [pipe_resource] this view belongs to.
#[repr(transparent)]
pub struct PipeImageView {
pub(super) pipe: pipe_image_view,
}
impl PipeImageView {
fn new(pipe: pipe_image_view) -> Self {
unsafe { pipe_resource_reference(&mut ptr::null_mut(), pipe.resource) }
Self { pipe: pipe }
}
pub fn slice_to_pipe(slice: &[PipeImageView]) -> &[pipe_image_view] {
// SAFETY: `PipeImageView` is a transparent wrapper around `pipe_image_view`, so transmute
// on the slice is safe.
unsafe { mem::transmute(slice) }
}
}
impl Drop for PipeImageView {
fn drop(&mut self) {
unsafe { pipe_resource_reference(&mut self.pipe.resource, ptr::null_mut()) }
}
}
// SAFETY: pipe_image_view is just static data around a pipe_resource, which itself is a thread-safe
// type.
unsafe impl Send for PipeImageView {}
unsafe impl Sync for PipeImageView {}
// Image dimensions provide by application to be used in both
// image and sampler views when image is created from buffer
#[derive(PartialEq, Eq)]
@@ -85,7 +116,8 @@ impl PipeResource {
read_write: bool,
host_access: u16,
app_img_info: Option<&AppImgInfo>,
) -> pipe_image_view {
) -> PipeImageView {
let pipe = PipeResource::as_ref(self);
let u = if let Some(app_img_info) = app_img_info {
pipe_image_view__bindgen_ty_1 {
tex2d_from_buf: pipe_image_view__bindgen_ty_1__bindgen_ty_3 {
@@ -99,17 +131,17 @@ impl PipeResource {
pipe_image_view__bindgen_ty_1 {
buf: pipe_image_view__bindgen_ty_1__bindgen_ty_2 {
offset: 0,
size: self.as_ref().width0,
size: pipe.width0,
},
}
} else {
let mut tex = pipe_image_view__bindgen_ty_1__bindgen_ty_1::default();
tex.set_level(0);
tex.set_first_layer(0);
if self.as_ref().target() == pipe_texture_target::PIPE_TEXTURE_3D {
tex.set_last_layer((self.as_ref().depth0 - 1).into());
} else if self.as_ref().array_size > 0 {
tex.set_last_layer((self.as_ref().array_size - 1).into());
if pipe.target() == pipe_texture_target::PIPE_TEXTURE_3D {
tex.set_last_layer((pipe.depth0 - 1).into());
} else if pipe.array_size > 0 {
tex.set_last_layer((pipe.array_size - 1).into());
} else {
tex.set_last_layer(0);
}
@@ -129,13 +161,13 @@ impl PipeResource {
0
} as u16;
pipe_image_view {
PipeImageView::new(pipe_image_view {
resource: self.pipe(),
format: format,
access: access | host_access,
shader_access: shader_access,
u: u,
}
})
}
pub fn pipe_sampler_view_template(