summaryrefslogtreecommitdiff
path: root/src/gallium/frontends/rusticl/mesa/pipe/transfer.rs
blob: f662d70c36f5ce431ad75181b589ddc6595c0ac4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
use crate::pipe::context::*;

use mesa_rust_gen::*;

use std::ops::Deref;
use std::os::raw::c_void;
use std::ptr;

pub struct PipeTransfer {
    pipe: *mut pipe_transfer,
    res: *mut pipe_resource,
    ptr: *mut c_void,
    is_buffer: bool,
}

pub struct GuardedPipeTransfer<'a> {
    inner: PipeTransfer,
    ctx: &'a PipeContext,
}

impl<'a> Deref for GuardedPipeTransfer<'a> {
    type Target = PipeTransfer;

    fn deref(&self) -> &Self::Target {
        &self.inner
    }
}

impl<'a> Drop for GuardedPipeTransfer<'a> {
    fn drop(&mut self) {
        if self.is_buffer {
            self.ctx.buffer_unmap(self.inner.pipe);
        } else {
            self.ctx.texture_unmap(self.inner.pipe);
        }
        unsafe { pipe_resource_reference(&mut self.inner.res, ptr::null_mut()) };
    }
}

impl PipeTransfer {
    pub(super) fn new(is_buffer: bool, pipe: *mut pipe_transfer, ptr: *mut c_void) -> Self {
        let mut res: *mut pipe_resource = ptr::null_mut();
        unsafe { pipe_resource_reference(&mut res, (*pipe).resource) }

        Self {
            pipe: pipe,
            res: res,
            ptr: ptr,
            is_buffer: is_buffer,
        }
    }

    pub fn ptr(&self) -> *mut c_void {
        self.ptr
    }

    pub fn row_pitch(&self) -> u32 {
        unsafe { (*self.pipe).stride }
    }

    pub fn slice_pitch(&self) -> u32 {
        unsafe { (*self.pipe).layer_stride }
    }

    pub fn bx(&self) -> &pipe_box {
        unsafe { &(*self.pipe).box_ }
    }

    pub fn with_ctx(self, ctx: &PipeContext) -> GuardedPipeTransfer {
        GuardedPipeTransfer {
            inner: self,
            ctx: ctx,
        }
    }
}

// use set_ctx before operating on the PipeTransfer inside a block where it gets droped
impl Drop for PipeTransfer {
    fn drop(&mut self) {
        assert_eq!(ptr::null_mut(), self.res);
    }
}