1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2020 The ChromiumOS Authors
2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file.
4*bb4ee6a4SAndroid Build Coastguard Worker
5*bb4ee6a4SAndroid Build Coastguard Worker //! gfxstream: Handles 3D virtio-gpu hypercalls using gfxstream.
6*bb4ee6a4SAndroid Build Coastguard Worker //!
7*bb4ee6a4SAndroid Build Coastguard Worker //! External code found at <https://android.googlesource.com/device/generic/vulkan-cereal/>.
8*bb4ee6a4SAndroid Build Coastguard Worker
9*bb4ee6a4SAndroid Build Coastguard Worker #![cfg(feature = "gfxstream")]
10*bb4ee6a4SAndroid Build Coastguard Worker
11*bb4ee6a4SAndroid Build Coastguard Worker use std::convert::TryInto;
12*bb4ee6a4SAndroid Build Coastguard Worker use std::ffi::CString;
13*bb4ee6a4SAndroid Build Coastguard Worker use std::io::IoSliceMut;
14*bb4ee6a4SAndroid Build Coastguard Worker use std::mem::size_of;
15*bb4ee6a4SAndroid Build Coastguard Worker use std::os::raw::c_char;
16*bb4ee6a4SAndroid Build Coastguard Worker use std::os::raw::c_int;
17*bb4ee6a4SAndroid Build Coastguard Worker use std::os::raw::c_uint;
18*bb4ee6a4SAndroid Build Coastguard Worker use std::os::raw::c_void;
19*bb4ee6a4SAndroid Build Coastguard Worker use std::panic::catch_unwind;
20*bb4ee6a4SAndroid Build Coastguard Worker use std::process::abort;
21*bb4ee6a4SAndroid Build Coastguard Worker use std::ptr::null;
22*bb4ee6a4SAndroid Build Coastguard Worker use std::ptr::null_mut;
23*bb4ee6a4SAndroid Build Coastguard Worker use std::sync::Arc;
24*bb4ee6a4SAndroid Build Coastguard Worker
25*bb4ee6a4SAndroid Build Coastguard Worker use crate::generated::virgl_renderer_bindings::iovec;
26*bb4ee6a4SAndroid Build Coastguard Worker use crate::generated::virgl_renderer_bindings::virgl_box;
27*bb4ee6a4SAndroid Build Coastguard Worker use crate::generated::virgl_renderer_bindings::virgl_renderer_resource_create_args;
28*bb4ee6a4SAndroid Build Coastguard Worker use crate::renderer_utils::*;
29*bb4ee6a4SAndroid Build Coastguard Worker use crate::rutabaga_core::RutabagaComponent;
30*bb4ee6a4SAndroid Build Coastguard Worker use crate::rutabaga_core::RutabagaContext;
31*bb4ee6a4SAndroid Build Coastguard Worker use crate::rutabaga_core::RutabagaResource;
32*bb4ee6a4SAndroid Build Coastguard Worker use crate::rutabaga_os::FromRawDescriptor;
33*bb4ee6a4SAndroid Build Coastguard Worker use crate::rutabaga_os::IntoRawDescriptor;
34*bb4ee6a4SAndroid Build Coastguard Worker use crate::rutabaga_os::OwnedDescriptor;
35*bb4ee6a4SAndroid Build Coastguard Worker use crate::rutabaga_os::RawDescriptor;
36*bb4ee6a4SAndroid Build Coastguard Worker use crate::rutabaga_utils::*;
37*bb4ee6a4SAndroid Build Coastguard Worker
38*bb4ee6a4SAndroid Build Coastguard Worker // See `virtgpu-gfxstream-renderer.h` for definitions
39*bb4ee6a4SAndroid Build Coastguard Worker const STREAM_RENDERER_PARAM_USER_DATA: u64 = 1;
40*bb4ee6a4SAndroid Build Coastguard Worker const STREAM_RENDERER_PARAM_RENDERER_FLAGS: u64 = 2;
41*bb4ee6a4SAndroid Build Coastguard Worker const STREAM_RENDERER_PARAM_FENCE_CALLBACK: u64 = 3;
42*bb4ee6a4SAndroid Build Coastguard Worker const STREAM_RENDERER_PARAM_WIN0_WIDTH: u64 = 4;
43*bb4ee6a4SAndroid Build Coastguard Worker const STREAM_RENDERER_PARAM_WIN0_HEIGHT: u64 = 5;
44*bb4ee6a4SAndroid Build Coastguard Worker const STREAM_RENDERER_PARAM_DEBUG_CALLBACK: u64 = 6;
45*bb4ee6a4SAndroid Build Coastguard Worker const STREAM_RENDERER_PARAM_RENDERER_FEATURES: u64 = 11;
46*bb4ee6a4SAndroid Build Coastguard Worker
47*bb4ee6a4SAndroid Build Coastguard Worker #[repr(C)]
48*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Copy, Debug)]
49*bb4ee6a4SAndroid Build Coastguard Worker pub struct stream_renderer_param {
50*bb4ee6a4SAndroid Build Coastguard Worker key: u64,
51*bb4ee6a4SAndroid Build Coastguard Worker value: u64,
52*bb4ee6a4SAndroid Build Coastguard Worker }
53*bb4ee6a4SAndroid Build Coastguard Worker
54*bb4ee6a4SAndroid Build Coastguard Worker #[repr(C)]
55*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Copy, Clone, Default)]
56*bb4ee6a4SAndroid Build Coastguard Worker pub struct stream_renderer_handle {
57*bb4ee6a4SAndroid Build Coastguard Worker pub os_handle: i64,
58*bb4ee6a4SAndroid Build Coastguard Worker pub handle_type: u32,
59*bb4ee6a4SAndroid Build Coastguard Worker }
60*bb4ee6a4SAndroid Build Coastguard Worker
61*bb4ee6a4SAndroid Build Coastguard Worker #[repr(C)]
62*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Copy, Clone, Default)]
63*bb4ee6a4SAndroid Build Coastguard Worker pub struct stream_renderer_vulkan_info {
64*bb4ee6a4SAndroid Build Coastguard Worker pub memory_index: u32,
65*bb4ee6a4SAndroid Build Coastguard Worker pub device_uuid: [u8; 16],
66*bb4ee6a4SAndroid Build Coastguard Worker pub driver_uuid: [u8; 16],
67*bb4ee6a4SAndroid Build Coastguard Worker }
68*bb4ee6a4SAndroid Build Coastguard Worker
69*bb4ee6a4SAndroid Build Coastguard Worker #[repr(C)]
70*bb4ee6a4SAndroid Build Coastguard Worker pub struct stream_renderer_command {
71*bb4ee6a4SAndroid Build Coastguard Worker pub ctx_id: u32,
72*bb4ee6a4SAndroid Build Coastguard Worker pub cmd_size: u32,
73*bb4ee6a4SAndroid Build Coastguard Worker pub cmd: *const u8,
74*bb4ee6a4SAndroid Build Coastguard Worker pub num_in_fences: u32,
75*bb4ee6a4SAndroid Build Coastguard Worker pub in_fence_descriptors: *const u64,
76*bb4ee6a4SAndroid Build Coastguard Worker }
77*bb4ee6a4SAndroid Build Coastguard Worker
78*bb4ee6a4SAndroid Build Coastguard Worker #[allow(non_camel_case_types)]
79*bb4ee6a4SAndroid Build Coastguard Worker pub type stream_renderer_create_blob = ResourceCreateBlob;
80*bb4ee6a4SAndroid Build Coastguard Worker
81*bb4ee6a4SAndroid Build Coastguard Worker #[allow(non_camel_case_types)]
82*bb4ee6a4SAndroid Build Coastguard Worker pub type stream_renderer_resource_create_args = virgl_renderer_resource_create_args;
83*bb4ee6a4SAndroid Build Coastguard Worker
84*bb4ee6a4SAndroid Build Coastguard Worker #[allow(non_camel_case_types)]
85*bb4ee6a4SAndroid Build Coastguard Worker pub type stream_renderer_box = virgl_box;
86*bb4ee6a4SAndroid Build Coastguard Worker
87*bb4ee6a4SAndroid Build Coastguard Worker #[allow(non_camel_case_types)]
88*bb4ee6a4SAndroid Build Coastguard Worker pub type stream_renderer_fence = RutabagaFence;
89*bb4ee6a4SAndroid Build Coastguard Worker
90*bb4ee6a4SAndroid Build Coastguard Worker #[allow(non_camel_case_types)]
91*bb4ee6a4SAndroid Build Coastguard Worker pub type stream_renderer_debug = RutabagaDebug;
92*bb4ee6a4SAndroid Build Coastguard Worker
93*bb4ee6a4SAndroid Build Coastguard Worker extern "C" {
94*bb4ee6a4SAndroid Build Coastguard Worker // Entry point for the stream renderer.
stream_renderer_init( stream_renderer_params: *mut stream_renderer_param, num_params: u64, ) -> c_int95*bb4ee6a4SAndroid Build Coastguard Worker fn stream_renderer_init(
96*bb4ee6a4SAndroid Build Coastguard Worker stream_renderer_params: *mut stream_renderer_param,
97*bb4ee6a4SAndroid Build Coastguard Worker num_params: u64,
98*bb4ee6a4SAndroid Build Coastguard Worker ) -> c_int;
99*bb4ee6a4SAndroid Build Coastguard Worker
100*bb4ee6a4SAndroid Build Coastguard Worker // Shutdown entry point for the renderer.
stream_renderer_teardown()101*bb4ee6a4SAndroid Build Coastguard Worker fn stream_renderer_teardown();
102*bb4ee6a4SAndroid Build Coastguard Worker
103*bb4ee6a4SAndroid Build Coastguard Worker // virtio-gpu-3d ioctl functions (begin)
104*bb4ee6a4SAndroid Build Coastguard Worker
105*bb4ee6a4SAndroid Build Coastguard Worker // In gfxstream, the resource create/transfer ioctls correspond to creating buffers for API
106*bb4ee6a4SAndroid Build Coastguard Worker // forwarding and the notification of new API calls forwarded by the guest, unless they
107*bb4ee6a4SAndroid Build Coastguard Worker // correspond to minigbm resource targets (PIPE_TEXTURE_2D), in which case they create globally
108*bb4ee6a4SAndroid Build Coastguard Worker // visible shared GL textures to support gralloc.
stream_renderer_resource_create( args: *mut stream_renderer_resource_create_args, iov: *mut iovec, num_iovs: u32, ) -> c_int109*bb4ee6a4SAndroid Build Coastguard Worker fn stream_renderer_resource_create(
110*bb4ee6a4SAndroid Build Coastguard Worker args: *mut stream_renderer_resource_create_args,
111*bb4ee6a4SAndroid Build Coastguard Worker iov: *mut iovec,
112*bb4ee6a4SAndroid Build Coastguard Worker num_iovs: u32,
113*bb4ee6a4SAndroid Build Coastguard Worker ) -> c_int;
114*bb4ee6a4SAndroid Build Coastguard Worker
stream_renderer_resource_unref(res_handle: u32)115*bb4ee6a4SAndroid Build Coastguard Worker fn stream_renderer_resource_unref(res_handle: u32);
stream_renderer_context_destroy(handle: u32)116*bb4ee6a4SAndroid Build Coastguard Worker fn stream_renderer_context_destroy(handle: u32);
stream_renderer_transfer_read_iov( handle: u32, ctx_id: u32, level: u32, stride: u32, layer_stride: u32, box_: *mut stream_renderer_box, offset: u64, iov: *mut iovec, iovec_cnt: c_int, ) -> c_int117*bb4ee6a4SAndroid Build Coastguard Worker fn stream_renderer_transfer_read_iov(
118*bb4ee6a4SAndroid Build Coastguard Worker handle: u32,
119*bb4ee6a4SAndroid Build Coastguard Worker ctx_id: u32,
120*bb4ee6a4SAndroid Build Coastguard Worker level: u32,
121*bb4ee6a4SAndroid Build Coastguard Worker stride: u32,
122*bb4ee6a4SAndroid Build Coastguard Worker layer_stride: u32,
123*bb4ee6a4SAndroid Build Coastguard Worker box_: *mut stream_renderer_box,
124*bb4ee6a4SAndroid Build Coastguard Worker offset: u64,
125*bb4ee6a4SAndroid Build Coastguard Worker iov: *mut iovec,
126*bb4ee6a4SAndroid Build Coastguard Worker iovec_cnt: c_int,
127*bb4ee6a4SAndroid Build Coastguard Worker ) -> c_int;
stream_renderer_transfer_write_iov( handle: u32, ctx_id: u32, level: c_int, stride: u32, layer_stride: u32, box_: *mut stream_renderer_box, offset: u64, iovec: *mut iovec, iovec_cnt: c_uint, ) -> c_int128*bb4ee6a4SAndroid Build Coastguard Worker fn stream_renderer_transfer_write_iov(
129*bb4ee6a4SAndroid Build Coastguard Worker handle: u32,
130*bb4ee6a4SAndroid Build Coastguard Worker ctx_id: u32,
131*bb4ee6a4SAndroid Build Coastguard Worker level: c_int,
132*bb4ee6a4SAndroid Build Coastguard Worker stride: u32,
133*bb4ee6a4SAndroid Build Coastguard Worker layer_stride: u32,
134*bb4ee6a4SAndroid Build Coastguard Worker box_: *mut stream_renderer_box,
135*bb4ee6a4SAndroid Build Coastguard Worker offset: u64,
136*bb4ee6a4SAndroid Build Coastguard Worker iovec: *mut iovec,
137*bb4ee6a4SAndroid Build Coastguard Worker iovec_cnt: c_uint,
138*bb4ee6a4SAndroid Build Coastguard Worker ) -> c_int;
stream_renderer_submit_cmd(cmd: *const stream_renderer_command) -> c_int139*bb4ee6a4SAndroid Build Coastguard Worker fn stream_renderer_submit_cmd(cmd: *const stream_renderer_command) -> c_int;
stream_renderer_resource_attach_iov( res_handle: c_int, iov: *mut iovec, num_iovs: c_int, ) -> c_int140*bb4ee6a4SAndroid Build Coastguard Worker fn stream_renderer_resource_attach_iov(
141*bb4ee6a4SAndroid Build Coastguard Worker res_handle: c_int,
142*bb4ee6a4SAndroid Build Coastguard Worker iov: *mut iovec,
143*bb4ee6a4SAndroid Build Coastguard Worker num_iovs: c_int,
144*bb4ee6a4SAndroid Build Coastguard Worker ) -> c_int;
stream_renderer_resource_detach_iov( res_handle: c_int, iov: *mut *mut iovec, num_iovs: *mut c_int, )145*bb4ee6a4SAndroid Build Coastguard Worker fn stream_renderer_resource_detach_iov(
146*bb4ee6a4SAndroid Build Coastguard Worker res_handle: c_int,
147*bb4ee6a4SAndroid Build Coastguard Worker iov: *mut *mut iovec,
148*bb4ee6a4SAndroid Build Coastguard Worker num_iovs: *mut c_int,
149*bb4ee6a4SAndroid Build Coastguard Worker );
stream_renderer_create_fence(fence: *const stream_renderer_fence) -> c_int150*bb4ee6a4SAndroid Build Coastguard Worker fn stream_renderer_create_fence(fence: *const stream_renderer_fence) -> c_int;
151*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(gfxstream_unstable)]
stream_renderer_export_fence(fence_id: u64, handle: *mut stream_renderer_handle) -> c_int152*bb4ee6a4SAndroid Build Coastguard Worker fn stream_renderer_export_fence(fence_id: u64, handle: *mut stream_renderer_handle) -> c_int;
stream_renderer_ctx_attach_resource(ctx_id: c_int, res_handle: c_int)153*bb4ee6a4SAndroid Build Coastguard Worker fn stream_renderer_ctx_attach_resource(ctx_id: c_int, res_handle: c_int);
stream_renderer_ctx_detach_resource(ctx_id: c_int, res_handle: c_int)154*bb4ee6a4SAndroid Build Coastguard Worker fn stream_renderer_ctx_detach_resource(ctx_id: c_int, res_handle: c_int);
stream_renderer_get_cap_set(set: u32, max_ver: *mut u32, max_size: *mut u32)155*bb4ee6a4SAndroid Build Coastguard Worker fn stream_renderer_get_cap_set(set: u32, max_ver: *mut u32, max_size: *mut u32);
stream_renderer_fill_caps(set: u32, version: u32, caps: *mut c_void)156*bb4ee6a4SAndroid Build Coastguard Worker fn stream_renderer_fill_caps(set: u32, version: u32, caps: *mut c_void);
157*bb4ee6a4SAndroid Build Coastguard Worker
stream_renderer_flush(res_handle: u32)158*bb4ee6a4SAndroid Build Coastguard Worker fn stream_renderer_flush(res_handle: u32);
stream_renderer_create_blob( ctx_id: u32, res_handle: u32, create_blob: *const stream_renderer_create_blob, iovecs: *const iovec, num_iovs: u32, handle: *const stream_renderer_handle, ) -> c_int159*bb4ee6a4SAndroid Build Coastguard Worker fn stream_renderer_create_blob(
160*bb4ee6a4SAndroid Build Coastguard Worker ctx_id: u32,
161*bb4ee6a4SAndroid Build Coastguard Worker res_handle: u32,
162*bb4ee6a4SAndroid Build Coastguard Worker create_blob: *const stream_renderer_create_blob,
163*bb4ee6a4SAndroid Build Coastguard Worker iovecs: *const iovec,
164*bb4ee6a4SAndroid Build Coastguard Worker num_iovs: u32,
165*bb4ee6a4SAndroid Build Coastguard Worker handle: *const stream_renderer_handle,
166*bb4ee6a4SAndroid Build Coastguard Worker ) -> c_int;
167*bb4ee6a4SAndroid Build Coastguard Worker
stream_renderer_export_blob(res_handle: u32, handle: *mut stream_renderer_handle) -> c_int168*bb4ee6a4SAndroid Build Coastguard Worker fn stream_renderer_export_blob(res_handle: u32, handle: *mut stream_renderer_handle) -> c_int;
stream_renderer_resource_map( res_handle: u32, map: *mut *mut c_void, out_size: *mut u64, ) -> c_int169*bb4ee6a4SAndroid Build Coastguard Worker fn stream_renderer_resource_map(
170*bb4ee6a4SAndroid Build Coastguard Worker res_handle: u32,
171*bb4ee6a4SAndroid Build Coastguard Worker map: *mut *mut c_void,
172*bb4ee6a4SAndroid Build Coastguard Worker out_size: *mut u64,
173*bb4ee6a4SAndroid Build Coastguard Worker ) -> c_int;
stream_renderer_resource_unmap(res_handle: u32) -> c_int174*bb4ee6a4SAndroid Build Coastguard Worker fn stream_renderer_resource_unmap(res_handle: u32) -> c_int;
stream_renderer_resource_map_info(res_handle: u32, map_info: *mut u32) -> c_int175*bb4ee6a4SAndroid Build Coastguard Worker fn stream_renderer_resource_map_info(res_handle: u32, map_info: *mut u32) -> c_int;
stream_renderer_vulkan_info( res_handle: u32, vulkan_info: *mut stream_renderer_vulkan_info, ) -> c_int176*bb4ee6a4SAndroid Build Coastguard Worker fn stream_renderer_vulkan_info(
177*bb4ee6a4SAndroid Build Coastguard Worker res_handle: u32,
178*bb4ee6a4SAndroid Build Coastguard Worker vulkan_info: *mut stream_renderer_vulkan_info,
179*bb4ee6a4SAndroid Build Coastguard Worker ) -> c_int;
stream_renderer_context_create( handle: u32, nlen: u32, name: *const c_char, context_init: u32, ) -> c_int180*bb4ee6a4SAndroid Build Coastguard Worker fn stream_renderer_context_create(
181*bb4ee6a4SAndroid Build Coastguard Worker handle: u32,
182*bb4ee6a4SAndroid Build Coastguard Worker nlen: u32,
183*bb4ee6a4SAndroid Build Coastguard Worker name: *const c_char,
184*bb4ee6a4SAndroid Build Coastguard Worker context_init: u32,
185*bb4ee6a4SAndroid Build Coastguard Worker ) -> c_int;
186*bb4ee6a4SAndroid Build Coastguard Worker
187*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(gfxstream_unstable)]
stream_renderer_suspend() -> c_int188*bb4ee6a4SAndroid Build Coastguard Worker fn stream_renderer_suspend() -> c_int;
189*bb4ee6a4SAndroid Build Coastguard Worker
190*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(gfxstream_unstable)]
stream_renderer_snapshot(dir: *const c_char) -> c_int191*bb4ee6a4SAndroid Build Coastguard Worker fn stream_renderer_snapshot(dir: *const c_char) -> c_int;
192*bb4ee6a4SAndroid Build Coastguard Worker
193*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(gfxstream_unstable)]
stream_renderer_restore(dir: *const c_char) -> c_int194*bb4ee6a4SAndroid Build Coastguard Worker fn stream_renderer_restore(dir: *const c_char) -> c_int;
195*bb4ee6a4SAndroid Build Coastguard Worker
196*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(gfxstream_unstable)]
stream_renderer_resume() -> c_int197*bb4ee6a4SAndroid Build Coastguard Worker fn stream_renderer_resume() -> c_int;
198*bb4ee6a4SAndroid Build Coastguard Worker
199*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(gfxstream_unstable)]
stream_renderer_wait_sync_resource(res_handle: u32) -> c_int200*bb4ee6a4SAndroid Build Coastguard Worker fn stream_renderer_wait_sync_resource(res_handle: u32) -> c_int;
201*bb4ee6a4SAndroid Build Coastguard Worker }
202*bb4ee6a4SAndroid Build Coastguard Worker
203*bb4ee6a4SAndroid Build Coastguard Worker /// The virtio-gpu backend state tracker which supports accelerated rendering.
204*bb4ee6a4SAndroid Build Coastguard Worker pub struct Gfxstream {
205*bb4ee6a4SAndroid Build Coastguard Worker /// Cookie used by Gfxstream, should be held as long as the renderer is alive.
206*bb4ee6a4SAndroid Build Coastguard Worker _cookie: Box<RutabagaCookie>,
207*bb4ee6a4SAndroid Build Coastguard Worker }
208*bb4ee6a4SAndroid Build Coastguard Worker
209*bb4ee6a4SAndroid Build Coastguard Worker struct GfxstreamContext {
210*bb4ee6a4SAndroid Build Coastguard Worker ctx_id: u32,
211*bb4ee6a4SAndroid Build Coastguard Worker fence_handler: RutabagaFenceHandler,
212*bb4ee6a4SAndroid Build Coastguard Worker }
213*bb4ee6a4SAndroid Build Coastguard Worker
214*bb4ee6a4SAndroid Build Coastguard Worker impl GfxstreamContext {
215*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(gfxstream_unstable)]
export_fence(&self, fence_id: u64) -> RutabagaResult<RutabagaHandle>216*bb4ee6a4SAndroid Build Coastguard Worker fn export_fence(&self, fence_id: u64) -> RutabagaResult<RutabagaHandle> {
217*bb4ee6a4SAndroid Build Coastguard Worker let mut stream_handle: stream_renderer_handle = Default::default();
218*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
219*bb4ee6a4SAndroid Build Coastguard Worker // Safe because a correctly formatted stream_handle is given to gfxstream.
220*bb4ee6a4SAndroid Build Coastguard Worker let ret = unsafe { stream_renderer_export_fence(fence_id, &mut stream_handle) };
221*bb4ee6a4SAndroid Build Coastguard Worker ret_to_res(ret)?;
222*bb4ee6a4SAndroid Build Coastguard Worker
223*bb4ee6a4SAndroid Build Coastguard Worker let raw_descriptor = stream_handle.os_handle as RawDescriptor;
224*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
225*bb4ee6a4SAndroid Build Coastguard Worker // Safe because the handle was just returned by a successful gfxstream call so it must
226*bb4ee6a4SAndroid Build Coastguard Worker // be valid and owned by us.
227*bb4ee6a4SAndroid Build Coastguard Worker let handle = unsafe { OwnedDescriptor::from_raw_descriptor(raw_descriptor) };
228*bb4ee6a4SAndroid Build Coastguard Worker
229*bb4ee6a4SAndroid Build Coastguard Worker Ok(RutabagaHandle {
230*bb4ee6a4SAndroid Build Coastguard Worker os_handle: handle,
231*bb4ee6a4SAndroid Build Coastguard Worker handle_type: stream_handle.handle_type,
232*bb4ee6a4SAndroid Build Coastguard Worker })
233*bb4ee6a4SAndroid Build Coastguard Worker }
234*bb4ee6a4SAndroid Build Coastguard Worker
235*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(not(gfxstream_unstable))]
export_fence(&self, _fence_id: u64) -> RutabagaResult<RutabagaHandle>236*bb4ee6a4SAndroid Build Coastguard Worker fn export_fence(&self, _fence_id: u64) -> RutabagaResult<RutabagaHandle> {
237*bb4ee6a4SAndroid Build Coastguard Worker Err(RutabagaError::Unsupported)
238*bb4ee6a4SAndroid Build Coastguard Worker }
239*bb4ee6a4SAndroid Build Coastguard Worker }
240*bb4ee6a4SAndroid Build Coastguard Worker
241*bb4ee6a4SAndroid Build Coastguard Worker impl RutabagaContext for GfxstreamContext {
submit_cmd( &mut self, commands: &mut [u8], _fence_ids: &[u64], _shareable_fences: Vec<RutabagaHandle>, ) -> RutabagaResult<()>242*bb4ee6a4SAndroid Build Coastguard Worker fn submit_cmd(
243*bb4ee6a4SAndroid Build Coastguard Worker &mut self,
244*bb4ee6a4SAndroid Build Coastguard Worker commands: &mut [u8],
245*bb4ee6a4SAndroid Build Coastguard Worker _fence_ids: &[u64],
246*bb4ee6a4SAndroid Build Coastguard Worker _shareable_fences: Vec<RutabagaHandle>,
247*bb4ee6a4SAndroid Build Coastguard Worker ) -> RutabagaResult<()> {
248*bb4ee6a4SAndroid Build Coastguard Worker if commands.len() % size_of::<u32>() != 0 {
249*bb4ee6a4SAndroid Build Coastguard Worker return Err(RutabagaError::InvalidCommandSize(commands.len()));
250*bb4ee6a4SAndroid Build Coastguard Worker }
251*bb4ee6a4SAndroid Build Coastguard Worker
252*bb4ee6a4SAndroid Build Coastguard Worker // TODO(b/315870313): Add safety comment
253*bb4ee6a4SAndroid Build Coastguard Worker #[allow(clippy::undocumented_unsafe_blocks)]
254*bb4ee6a4SAndroid Build Coastguard Worker let ret = unsafe {
255*bb4ee6a4SAndroid Build Coastguard Worker let cmd = stream_renderer_command {
256*bb4ee6a4SAndroid Build Coastguard Worker ctx_id: self.ctx_id,
257*bb4ee6a4SAndroid Build Coastguard Worker cmd_size: commands.len().try_into()?,
258*bb4ee6a4SAndroid Build Coastguard Worker cmd: commands.as_mut_ptr(),
259*bb4ee6a4SAndroid Build Coastguard Worker num_in_fences: 0,
260*bb4ee6a4SAndroid Build Coastguard Worker in_fence_descriptors: null(),
261*bb4ee6a4SAndroid Build Coastguard Worker };
262*bb4ee6a4SAndroid Build Coastguard Worker
263*bb4ee6a4SAndroid Build Coastguard Worker stream_renderer_submit_cmd(&cmd as *const stream_renderer_command)
264*bb4ee6a4SAndroid Build Coastguard Worker };
265*bb4ee6a4SAndroid Build Coastguard Worker ret_to_res(ret)
266*bb4ee6a4SAndroid Build Coastguard Worker }
267*bb4ee6a4SAndroid Build Coastguard Worker
attach(&mut self, resource: &mut RutabagaResource)268*bb4ee6a4SAndroid Build Coastguard Worker fn attach(&mut self, resource: &mut RutabagaResource) {
269*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
270*bb4ee6a4SAndroid Build Coastguard Worker // The context id and resource id must be valid because the respective instances ensure
271*bb4ee6a4SAndroid Build Coastguard Worker // their lifetime.
272*bb4ee6a4SAndroid Build Coastguard Worker unsafe {
273*bb4ee6a4SAndroid Build Coastguard Worker stream_renderer_ctx_attach_resource(self.ctx_id as i32, resource.resource_id as i32);
274*bb4ee6a4SAndroid Build Coastguard Worker }
275*bb4ee6a4SAndroid Build Coastguard Worker }
276*bb4ee6a4SAndroid Build Coastguard Worker
detach(&mut self, resource: &RutabagaResource)277*bb4ee6a4SAndroid Build Coastguard Worker fn detach(&mut self, resource: &RutabagaResource) {
278*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
279*bb4ee6a4SAndroid Build Coastguard Worker // The context id and resource id must be valid because the respective instances ensure
280*bb4ee6a4SAndroid Build Coastguard Worker // their lifetime.
281*bb4ee6a4SAndroid Build Coastguard Worker unsafe {
282*bb4ee6a4SAndroid Build Coastguard Worker stream_renderer_ctx_detach_resource(self.ctx_id as i32, resource.resource_id as i32);
283*bb4ee6a4SAndroid Build Coastguard Worker }
284*bb4ee6a4SAndroid Build Coastguard Worker }
285*bb4ee6a4SAndroid Build Coastguard Worker
component_type(&self) -> RutabagaComponentType286*bb4ee6a4SAndroid Build Coastguard Worker fn component_type(&self) -> RutabagaComponentType {
287*bb4ee6a4SAndroid Build Coastguard Worker RutabagaComponentType::Gfxstream
288*bb4ee6a4SAndroid Build Coastguard Worker }
289*bb4ee6a4SAndroid Build Coastguard Worker
context_create_fence( &mut self, fence: RutabagaFence, ) -> RutabagaResult<Option<RutabagaHandle>>290*bb4ee6a4SAndroid Build Coastguard Worker fn context_create_fence(
291*bb4ee6a4SAndroid Build Coastguard Worker &mut self,
292*bb4ee6a4SAndroid Build Coastguard Worker fence: RutabagaFence,
293*bb4ee6a4SAndroid Build Coastguard Worker ) -> RutabagaResult<Option<RutabagaHandle>> {
294*bb4ee6a4SAndroid Build Coastguard Worker if fence.ring_idx as u32 == 1 {
295*bb4ee6a4SAndroid Build Coastguard Worker self.fence_handler.call(fence);
296*bb4ee6a4SAndroid Build Coastguard Worker return Ok(None);
297*bb4ee6a4SAndroid Build Coastguard Worker }
298*bb4ee6a4SAndroid Build Coastguard Worker
299*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
300*bb4ee6a4SAndroid Build Coastguard Worker // Safe because RutabagaFences and stream_renderer_fence are ABI identical
301*bb4ee6a4SAndroid Build Coastguard Worker let ret = unsafe { stream_renderer_create_fence(&fence as *const stream_renderer_fence) };
302*bb4ee6a4SAndroid Build Coastguard Worker ret_to_res(ret)?;
303*bb4ee6a4SAndroid Build Coastguard Worker
304*bb4ee6a4SAndroid Build Coastguard Worker let mut hnd: Option<RutabagaHandle> = None;
305*bb4ee6a4SAndroid Build Coastguard Worker if fence.flags & RUTABAGA_FLAG_FENCE_HOST_SHAREABLE != 0 {
306*bb4ee6a4SAndroid Build Coastguard Worker hnd = Some(self.export_fence(fence.fence_id)?);
307*bb4ee6a4SAndroid Build Coastguard Worker }
308*bb4ee6a4SAndroid Build Coastguard Worker
309*bb4ee6a4SAndroid Build Coastguard Worker Ok(hnd)
310*bb4ee6a4SAndroid Build Coastguard Worker }
311*bb4ee6a4SAndroid Build Coastguard Worker }
312*bb4ee6a4SAndroid Build Coastguard Worker
313*bb4ee6a4SAndroid Build Coastguard Worker impl Drop for GfxstreamContext {
drop(&mut self)314*bb4ee6a4SAndroid Build Coastguard Worker fn drop(&mut self) {
315*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
316*bb4ee6a4SAndroid Build Coastguard Worker // The context is safe to destroy because nothing else can be referencing it.
317*bb4ee6a4SAndroid Build Coastguard Worker unsafe {
318*bb4ee6a4SAndroid Build Coastguard Worker stream_renderer_context_destroy(self.ctx_id);
319*bb4ee6a4SAndroid Build Coastguard Worker }
320*bb4ee6a4SAndroid Build Coastguard Worker }
321*bb4ee6a4SAndroid Build Coastguard Worker }
322*bb4ee6a4SAndroid Build Coastguard Worker
write_context_fence(cookie: *mut c_void, fence: *const RutabagaFence)323*bb4ee6a4SAndroid Build Coastguard Worker extern "C" fn write_context_fence(cookie: *mut c_void, fence: *const RutabagaFence) {
324*bb4ee6a4SAndroid Build Coastguard Worker catch_unwind(|| {
325*bb4ee6a4SAndroid Build Coastguard Worker assert!(!cookie.is_null());
326*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
327*bb4ee6a4SAndroid Build Coastguard Worker // We trust gfxstream not give a dangling pointer
328*bb4ee6a4SAndroid Build Coastguard Worker let cookie = unsafe { &*(cookie as *mut RutabagaCookie) };
329*bb4ee6a4SAndroid Build Coastguard Worker if let Some(handler) = &cookie.fence_handler {
330*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
331*bb4ee6a4SAndroid Build Coastguard Worker // We trust gfxstream not give a dangling pointer
332*bb4ee6a4SAndroid Build Coastguard Worker unsafe { handler.call(*fence) };
333*bb4ee6a4SAndroid Build Coastguard Worker }
334*bb4ee6a4SAndroid Build Coastguard Worker })
335*bb4ee6a4SAndroid Build Coastguard Worker .unwrap_or_else(|_| abort())
336*bb4ee6a4SAndroid Build Coastguard Worker }
337*bb4ee6a4SAndroid Build Coastguard Worker
gfxstream_debug_callback(cookie: *mut c_void, debug: *const stream_renderer_debug)338*bb4ee6a4SAndroid Build Coastguard Worker extern "C" fn gfxstream_debug_callback(cookie: *mut c_void, debug: *const stream_renderer_debug) {
339*bb4ee6a4SAndroid Build Coastguard Worker catch_unwind(|| {
340*bb4ee6a4SAndroid Build Coastguard Worker assert!(!cookie.is_null());
341*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
342*bb4ee6a4SAndroid Build Coastguard Worker // We trust gfxstream not give a dangling pointer
343*bb4ee6a4SAndroid Build Coastguard Worker let cookie = unsafe { &*(cookie as *mut RutabagaCookie) };
344*bb4ee6a4SAndroid Build Coastguard Worker if let Some(handler) = &cookie.debug_handler {
345*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
346*bb4ee6a4SAndroid Build Coastguard Worker // We trust gfxstream not give a dangling pointer
347*bb4ee6a4SAndroid Build Coastguard Worker unsafe { handler.call(*debug) };
348*bb4ee6a4SAndroid Build Coastguard Worker }
349*bb4ee6a4SAndroid Build Coastguard Worker })
350*bb4ee6a4SAndroid Build Coastguard Worker .unwrap_or_else(|_| abort())
351*bb4ee6a4SAndroid Build Coastguard Worker }
352*bb4ee6a4SAndroid Build Coastguard Worker
353*bb4ee6a4SAndroid Build Coastguard Worker impl Gfxstream {
init( display_width: u32, display_height: u32, gfxstream_flags: GfxstreamFlags, gfxstream_features: Option<String>, fence_handler: RutabagaFenceHandler, debug_handler: Option<RutabagaDebugHandler>, ) -> RutabagaResult<Box<dyn RutabagaComponent>>354*bb4ee6a4SAndroid Build Coastguard Worker pub fn init(
355*bb4ee6a4SAndroid Build Coastguard Worker display_width: u32,
356*bb4ee6a4SAndroid Build Coastguard Worker display_height: u32,
357*bb4ee6a4SAndroid Build Coastguard Worker gfxstream_flags: GfxstreamFlags,
358*bb4ee6a4SAndroid Build Coastguard Worker gfxstream_features: Option<String>,
359*bb4ee6a4SAndroid Build Coastguard Worker fence_handler: RutabagaFenceHandler,
360*bb4ee6a4SAndroid Build Coastguard Worker debug_handler: Option<RutabagaDebugHandler>,
361*bb4ee6a4SAndroid Build Coastguard Worker ) -> RutabagaResult<Box<dyn RutabagaComponent>> {
362*bb4ee6a4SAndroid Build Coastguard Worker let use_debug = debug_handler.is_some();
363*bb4ee6a4SAndroid Build Coastguard Worker let mut cookie = Box::new(RutabagaCookie {
364*bb4ee6a4SAndroid Build Coastguard Worker render_server_fd: None,
365*bb4ee6a4SAndroid Build Coastguard Worker fence_handler: Some(fence_handler),
366*bb4ee6a4SAndroid Build Coastguard Worker debug_handler,
367*bb4ee6a4SAndroid Build Coastguard Worker });
368*bb4ee6a4SAndroid Build Coastguard Worker
369*bb4ee6a4SAndroid Build Coastguard Worker let mut stream_renderer_params = Vec::from([
370*bb4ee6a4SAndroid Build Coastguard Worker stream_renderer_param {
371*bb4ee6a4SAndroid Build Coastguard Worker key: STREAM_RENDERER_PARAM_USER_DATA,
372*bb4ee6a4SAndroid Build Coastguard Worker // Safe as cookie outlives the stream renderer (stream_renderer_teardown called
373*bb4ee6a4SAndroid Build Coastguard Worker // at Gfxstream Drop)
374*bb4ee6a4SAndroid Build Coastguard Worker value: &mut *cookie as *mut RutabagaCookie as u64,
375*bb4ee6a4SAndroid Build Coastguard Worker },
376*bb4ee6a4SAndroid Build Coastguard Worker stream_renderer_param {
377*bb4ee6a4SAndroid Build Coastguard Worker key: STREAM_RENDERER_PARAM_RENDERER_FLAGS,
378*bb4ee6a4SAndroid Build Coastguard Worker value: gfxstream_flags.into(),
379*bb4ee6a4SAndroid Build Coastguard Worker },
380*bb4ee6a4SAndroid Build Coastguard Worker stream_renderer_param {
381*bb4ee6a4SAndroid Build Coastguard Worker key: STREAM_RENDERER_PARAM_FENCE_CALLBACK,
382*bb4ee6a4SAndroid Build Coastguard Worker value: write_context_fence as usize as u64,
383*bb4ee6a4SAndroid Build Coastguard Worker },
384*bb4ee6a4SAndroid Build Coastguard Worker stream_renderer_param {
385*bb4ee6a4SAndroid Build Coastguard Worker key: STREAM_RENDERER_PARAM_WIN0_WIDTH,
386*bb4ee6a4SAndroid Build Coastguard Worker value: display_width as u64,
387*bb4ee6a4SAndroid Build Coastguard Worker },
388*bb4ee6a4SAndroid Build Coastguard Worker stream_renderer_param {
389*bb4ee6a4SAndroid Build Coastguard Worker key: STREAM_RENDERER_PARAM_WIN0_HEIGHT,
390*bb4ee6a4SAndroid Build Coastguard Worker value: display_height as u64,
391*bb4ee6a4SAndroid Build Coastguard Worker },
392*bb4ee6a4SAndroid Build Coastguard Worker ]);
393*bb4ee6a4SAndroid Build Coastguard Worker
394*bb4ee6a4SAndroid Build Coastguard Worker if use_debug {
395*bb4ee6a4SAndroid Build Coastguard Worker stream_renderer_params.push(stream_renderer_param {
396*bb4ee6a4SAndroid Build Coastguard Worker key: STREAM_RENDERER_PARAM_DEBUG_CALLBACK,
397*bb4ee6a4SAndroid Build Coastguard Worker value: gfxstream_debug_callback as usize as u64,
398*bb4ee6a4SAndroid Build Coastguard Worker });
399*bb4ee6a4SAndroid Build Coastguard Worker }
400*bb4ee6a4SAndroid Build Coastguard Worker
401*bb4ee6a4SAndroid Build Coastguard Worker let features_cstr = gfxstream_features.map(|f| CString::new(f).unwrap());
402*bb4ee6a4SAndroid Build Coastguard Worker if let Some(features_cstr) = &features_cstr {
403*bb4ee6a4SAndroid Build Coastguard Worker stream_renderer_params.push(stream_renderer_param {
404*bb4ee6a4SAndroid Build Coastguard Worker key: STREAM_RENDERER_PARAM_RENDERER_FEATURES,
405*bb4ee6a4SAndroid Build Coastguard Worker value: features_cstr.as_ptr() as u64,
406*bb4ee6a4SAndroid Build Coastguard Worker });
407*bb4ee6a4SAndroid Build Coastguard Worker }
408*bb4ee6a4SAndroid Build Coastguard Worker
409*bb4ee6a4SAndroid Build Coastguard Worker // TODO(b/315870313): Add safety comment
410*bb4ee6a4SAndroid Build Coastguard Worker #[allow(clippy::undocumented_unsafe_blocks)]
411*bb4ee6a4SAndroid Build Coastguard Worker unsafe {
412*bb4ee6a4SAndroid Build Coastguard Worker ret_to_res(stream_renderer_init(
413*bb4ee6a4SAndroid Build Coastguard Worker stream_renderer_params.as_mut_ptr(),
414*bb4ee6a4SAndroid Build Coastguard Worker stream_renderer_params.len() as u64,
415*bb4ee6a4SAndroid Build Coastguard Worker ))?;
416*bb4ee6a4SAndroid Build Coastguard Worker }
417*bb4ee6a4SAndroid Build Coastguard Worker
418*bb4ee6a4SAndroid Build Coastguard Worker Ok(Box::new(Gfxstream { _cookie: cookie }))
419*bb4ee6a4SAndroid Build Coastguard Worker }
420*bb4ee6a4SAndroid Build Coastguard Worker
map_info(&self, resource_id: u32) -> RutabagaResult<u32>421*bb4ee6a4SAndroid Build Coastguard Worker fn map_info(&self, resource_id: u32) -> RutabagaResult<u32> {
422*bb4ee6a4SAndroid Build Coastguard Worker let mut map_info = 0;
423*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
424*bb4ee6a4SAndroid Build Coastguard Worker // Safe because `map_info` is a local stack variable owned by us.
425*bb4ee6a4SAndroid Build Coastguard Worker let ret = unsafe { stream_renderer_resource_map_info(resource_id, &mut map_info) };
426*bb4ee6a4SAndroid Build Coastguard Worker ret_to_res(ret)?;
427*bb4ee6a4SAndroid Build Coastguard Worker
428*bb4ee6a4SAndroid Build Coastguard Worker Ok(map_info | RUTABAGA_MAP_ACCESS_RW)
429*bb4ee6a4SAndroid Build Coastguard Worker }
430*bb4ee6a4SAndroid Build Coastguard Worker
vulkan_info(&self, resource_id: u32) -> RutabagaResult<VulkanInfo>431*bb4ee6a4SAndroid Build Coastguard Worker fn vulkan_info(&self, resource_id: u32) -> RutabagaResult<VulkanInfo> {
432*bb4ee6a4SAndroid Build Coastguard Worker let mut vulkan_info: stream_renderer_vulkan_info = Default::default();
433*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
434*bb4ee6a4SAndroid Build Coastguard Worker // Safe because `vulkan_info` is a local stack variable owned by us.
435*bb4ee6a4SAndroid Build Coastguard Worker let ret = unsafe { stream_renderer_vulkan_info(resource_id, &mut vulkan_info) };
436*bb4ee6a4SAndroid Build Coastguard Worker ret_to_res(ret)?;
437*bb4ee6a4SAndroid Build Coastguard Worker
438*bb4ee6a4SAndroid Build Coastguard Worker Ok(VulkanInfo {
439*bb4ee6a4SAndroid Build Coastguard Worker memory_idx: vulkan_info.memory_index,
440*bb4ee6a4SAndroid Build Coastguard Worker device_id: DeviceId {
441*bb4ee6a4SAndroid Build Coastguard Worker device_uuid: vulkan_info.device_uuid,
442*bb4ee6a4SAndroid Build Coastguard Worker driver_uuid: vulkan_info.driver_uuid,
443*bb4ee6a4SAndroid Build Coastguard Worker },
444*bb4ee6a4SAndroid Build Coastguard Worker })
445*bb4ee6a4SAndroid Build Coastguard Worker }
446*bb4ee6a4SAndroid Build Coastguard Worker
export_blob(&self, resource_id: u32) -> RutabagaResult<Arc<RutabagaHandle>>447*bb4ee6a4SAndroid Build Coastguard Worker fn export_blob(&self, resource_id: u32) -> RutabagaResult<Arc<RutabagaHandle>> {
448*bb4ee6a4SAndroid Build Coastguard Worker let mut stream_handle: stream_renderer_handle = Default::default();
449*bb4ee6a4SAndroid Build Coastguard Worker // TODO(b/315870313): Add safety comment
450*bb4ee6a4SAndroid Build Coastguard Worker #[allow(clippy::undocumented_unsafe_blocks)]
451*bb4ee6a4SAndroid Build Coastguard Worker let ret = unsafe { stream_renderer_export_blob(resource_id, &mut stream_handle) };
452*bb4ee6a4SAndroid Build Coastguard Worker ret_to_res(ret)?;
453*bb4ee6a4SAndroid Build Coastguard Worker
454*bb4ee6a4SAndroid Build Coastguard Worker let raw_descriptor = stream_handle.os_handle as RawDescriptor;
455*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
456*bb4ee6a4SAndroid Build Coastguard Worker // Safe because the handle was just returned by a successful gfxstream call so it must be
457*bb4ee6a4SAndroid Build Coastguard Worker // valid and owned by us.
458*bb4ee6a4SAndroid Build Coastguard Worker let handle = unsafe { OwnedDescriptor::from_raw_descriptor(raw_descriptor) };
459*bb4ee6a4SAndroid Build Coastguard Worker
460*bb4ee6a4SAndroid Build Coastguard Worker Ok(Arc::new(RutabagaHandle {
461*bb4ee6a4SAndroid Build Coastguard Worker os_handle: handle,
462*bb4ee6a4SAndroid Build Coastguard Worker handle_type: stream_handle.handle_type,
463*bb4ee6a4SAndroid Build Coastguard Worker }))
464*bb4ee6a4SAndroid Build Coastguard Worker }
465*bb4ee6a4SAndroid Build Coastguard Worker }
466*bb4ee6a4SAndroid Build Coastguard Worker
467*bb4ee6a4SAndroid Build Coastguard Worker impl Drop for Gfxstream {
drop(&mut self)468*bb4ee6a4SAndroid Build Coastguard Worker fn drop(&mut self) {
469*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: Safe because Gfxstream was successfully initialized.
470*bb4ee6a4SAndroid Build Coastguard Worker unsafe {
471*bb4ee6a4SAndroid Build Coastguard Worker stream_renderer_teardown();
472*bb4ee6a4SAndroid Build Coastguard Worker }
473*bb4ee6a4SAndroid Build Coastguard Worker }
474*bb4ee6a4SAndroid Build Coastguard Worker }
475*bb4ee6a4SAndroid Build Coastguard Worker
476*bb4ee6a4SAndroid Build Coastguard Worker impl RutabagaComponent for Gfxstream {
get_capset_info(&self, capset_id: u32) -> (u32, u32)477*bb4ee6a4SAndroid Build Coastguard Worker fn get_capset_info(&self, capset_id: u32) -> (u32, u32) {
478*bb4ee6a4SAndroid Build Coastguard Worker let mut version = 0;
479*bb4ee6a4SAndroid Build Coastguard Worker let mut size = 0;
480*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
481*bb4ee6a4SAndroid Build Coastguard Worker // Safe because gfxstream is initialized by now and properly size stack variables are
482*bb4ee6a4SAndroid Build Coastguard Worker // used for the pointers.
483*bb4ee6a4SAndroid Build Coastguard Worker unsafe {
484*bb4ee6a4SAndroid Build Coastguard Worker stream_renderer_get_cap_set(capset_id, &mut version, &mut size);
485*bb4ee6a4SAndroid Build Coastguard Worker }
486*bb4ee6a4SAndroid Build Coastguard Worker (version, size)
487*bb4ee6a4SAndroid Build Coastguard Worker }
488*bb4ee6a4SAndroid Build Coastguard Worker
get_capset(&self, capset_id: u32, version: u32) -> Vec<u8>489*bb4ee6a4SAndroid Build Coastguard Worker fn get_capset(&self, capset_id: u32, version: u32) -> Vec<u8> {
490*bb4ee6a4SAndroid Build Coastguard Worker let (_, max_size) = self.get_capset_info(capset_id);
491*bb4ee6a4SAndroid Build Coastguard Worker let mut buf = vec![0u8; max_size as usize];
492*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
493*bb4ee6a4SAndroid Build Coastguard Worker // Safe because gfxstream is initialized by now and the given buffer is sized properly
494*bb4ee6a4SAndroid Build Coastguard Worker // for the given cap id/version.
495*bb4ee6a4SAndroid Build Coastguard Worker unsafe {
496*bb4ee6a4SAndroid Build Coastguard Worker stream_renderer_fill_caps(capset_id, version, buf.as_mut_ptr() as *mut c_void);
497*bb4ee6a4SAndroid Build Coastguard Worker }
498*bb4ee6a4SAndroid Build Coastguard Worker
499*bb4ee6a4SAndroid Build Coastguard Worker buf
500*bb4ee6a4SAndroid Build Coastguard Worker }
501*bb4ee6a4SAndroid Build Coastguard Worker
create_fence(&mut self, fence: RutabagaFence) -> RutabagaResult<()>502*bb4ee6a4SAndroid Build Coastguard Worker fn create_fence(&mut self, fence: RutabagaFence) -> RutabagaResult<()> {
503*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
504*bb4ee6a4SAndroid Build Coastguard Worker // Safe because RutabagaFences and stream_renderer_fence are ABI identical
505*bb4ee6a4SAndroid Build Coastguard Worker let ret = unsafe { stream_renderer_create_fence(&fence as *const stream_renderer_fence) };
506*bb4ee6a4SAndroid Build Coastguard Worker ret_to_res(ret)
507*bb4ee6a4SAndroid Build Coastguard Worker }
508*bb4ee6a4SAndroid Build Coastguard Worker
create_3d( &self, resource_id: u32, resource_create_3d: ResourceCreate3D, ) -> RutabagaResult<RutabagaResource>509*bb4ee6a4SAndroid Build Coastguard Worker fn create_3d(
510*bb4ee6a4SAndroid Build Coastguard Worker &self,
511*bb4ee6a4SAndroid Build Coastguard Worker resource_id: u32,
512*bb4ee6a4SAndroid Build Coastguard Worker resource_create_3d: ResourceCreate3D,
513*bb4ee6a4SAndroid Build Coastguard Worker ) -> RutabagaResult<RutabagaResource> {
514*bb4ee6a4SAndroid Build Coastguard Worker let mut args = virgl_renderer_resource_create_args {
515*bb4ee6a4SAndroid Build Coastguard Worker handle: resource_id,
516*bb4ee6a4SAndroid Build Coastguard Worker target: resource_create_3d.target,
517*bb4ee6a4SAndroid Build Coastguard Worker format: resource_create_3d.format,
518*bb4ee6a4SAndroid Build Coastguard Worker bind: resource_create_3d.bind,
519*bb4ee6a4SAndroid Build Coastguard Worker width: resource_create_3d.width,
520*bb4ee6a4SAndroid Build Coastguard Worker height: resource_create_3d.height,
521*bb4ee6a4SAndroid Build Coastguard Worker depth: resource_create_3d.depth,
522*bb4ee6a4SAndroid Build Coastguard Worker array_size: resource_create_3d.array_size,
523*bb4ee6a4SAndroid Build Coastguard Worker last_level: resource_create_3d.last_level,
524*bb4ee6a4SAndroid Build Coastguard Worker nr_samples: resource_create_3d.nr_samples,
525*bb4ee6a4SAndroid Build Coastguard Worker flags: resource_create_3d.flags,
526*bb4ee6a4SAndroid Build Coastguard Worker };
527*bb4ee6a4SAndroid Build Coastguard Worker
528*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
529*bb4ee6a4SAndroid Build Coastguard Worker // Safe because gfxstream is initialized by now, and the return value is checked before
530*bb4ee6a4SAndroid Build Coastguard Worker // returning a new resource. The backing buffers are not supplied with this call.
531*bb4ee6a4SAndroid Build Coastguard Worker let ret = unsafe { stream_renderer_resource_create(&mut args, null_mut(), 0) };
532*bb4ee6a4SAndroid Build Coastguard Worker ret_to_res(ret)?;
533*bb4ee6a4SAndroid Build Coastguard Worker
534*bb4ee6a4SAndroid Build Coastguard Worker Ok(RutabagaResource {
535*bb4ee6a4SAndroid Build Coastguard Worker resource_id,
536*bb4ee6a4SAndroid Build Coastguard Worker handle: None,
537*bb4ee6a4SAndroid Build Coastguard Worker blob: false,
538*bb4ee6a4SAndroid Build Coastguard Worker blob_mem: 0,
539*bb4ee6a4SAndroid Build Coastguard Worker blob_flags: 0,
540*bb4ee6a4SAndroid Build Coastguard Worker map_info: None,
541*bb4ee6a4SAndroid Build Coastguard Worker info_2d: None,
542*bb4ee6a4SAndroid Build Coastguard Worker info_3d: None,
543*bb4ee6a4SAndroid Build Coastguard Worker vulkan_info: None,
544*bb4ee6a4SAndroid Build Coastguard Worker backing_iovecs: None,
545*bb4ee6a4SAndroid Build Coastguard Worker component_mask: 1 << (RutabagaComponentType::Gfxstream as u8),
546*bb4ee6a4SAndroid Build Coastguard Worker size: 0,
547*bb4ee6a4SAndroid Build Coastguard Worker mapping: None,
548*bb4ee6a4SAndroid Build Coastguard Worker })
549*bb4ee6a4SAndroid Build Coastguard Worker }
550*bb4ee6a4SAndroid Build Coastguard Worker
attach_backing( &self, resource_id: u32, vecs: &mut Vec<RutabagaIovec>, ) -> RutabagaResult<()>551*bb4ee6a4SAndroid Build Coastguard Worker fn attach_backing(
552*bb4ee6a4SAndroid Build Coastguard Worker &self,
553*bb4ee6a4SAndroid Build Coastguard Worker resource_id: u32,
554*bb4ee6a4SAndroid Build Coastguard Worker vecs: &mut Vec<RutabagaIovec>,
555*bb4ee6a4SAndroid Build Coastguard Worker ) -> RutabagaResult<()> {
556*bb4ee6a4SAndroid Build Coastguard Worker // TODO(b/315870313): Add safety comment
557*bb4ee6a4SAndroid Build Coastguard Worker #[allow(clippy::undocumented_unsafe_blocks)]
558*bb4ee6a4SAndroid Build Coastguard Worker let ret = unsafe {
559*bb4ee6a4SAndroid Build Coastguard Worker stream_renderer_resource_attach_iov(
560*bb4ee6a4SAndroid Build Coastguard Worker resource_id as i32,
561*bb4ee6a4SAndroid Build Coastguard Worker vecs.as_mut_ptr() as *mut iovec,
562*bb4ee6a4SAndroid Build Coastguard Worker vecs.len() as i32,
563*bb4ee6a4SAndroid Build Coastguard Worker )
564*bb4ee6a4SAndroid Build Coastguard Worker };
565*bb4ee6a4SAndroid Build Coastguard Worker ret_to_res(ret)
566*bb4ee6a4SAndroid Build Coastguard Worker }
567*bb4ee6a4SAndroid Build Coastguard Worker
detach_backing(&self, resource_id: u32)568*bb4ee6a4SAndroid Build Coastguard Worker fn detach_backing(&self, resource_id: u32) {
569*bb4ee6a4SAndroid Build Coastguard Worker // TODO(b/315870313): Add safety comment
570*bb4ee6a4SAndroid Build Coastguard Worker #[allow(clippy::undocumented_unsafe_blocks)]
571*bb4ee6a4SAndroid Build Coastguard Worker unsafe {
572*bb4ee6a4SAndroid Build Coastguard Worker stream_renderer_resource_detach_iov(
573*bb4ee6a4SAndroid Build Coastguard Worker resource_id as i32,
574*bb4ee6a4SAndroid Build Coastguard Worker std::ptr::null_mut(),
575*bb4ee6a4SAndroid Build Coastguard Worker std::ptr::null_mut(),
576*bb4ee6a4SAndroid Build Coastguard Worker );
577*bb4ee6a4SAndroid Build Coastguard Worker }
578*bb4ee6a4SAndroid Build Coastguard Worker }
579*bb4ee6a4SAndroid Build Coastguard Worker
unref_resource(&self, resource_id: u32)580*bb4ee6a4SAndroid Build Coastguard Worker fn unref_resource(&self, resource_id: u32) {
581*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
582*bb4ee6a4SAndroid Build Coastguard Worker // The resource is safe to unreference destroy because no user of these bindings can still
583*bb4ee6a4SAndroid Build Coastguard Worker // be holding a reference.
584*bb4ee6a4SAndroid Build Coastguard Worker unsafe {
585*bb4ee6a4SAndroid Build Coastguard Worker stream_renderer_resource_unref(resource_id);
586*bb4ee6a4SAndroid Build Coastguard Worker }
587*bb4ee6a4SAndroid Build Coastguard Worker }
588*bb4ee6a4SAndroid Build Coastguard Worker
transfer_write( &self, ctx_id: u32, resource: &mut RutabagaResource, transfer: Transfer3D, ) -> RutabagaResult<()>589*bb4ee6a4SAndroid Build Coastguard Worker fn transfer_write(
590*bb4ee6a4SAndroid Build Coastguard Worker &self,
591*bb4ee6a4SAndroid Build Coastguard Worker ctx_id: u32,
592*bb4ee6a4SAndroid Build Coastguard Worker resource: &mut RutabagaResource,
593*bb4ee6a4SAndroid Build Coastguard Worker transfer: Transfer3D,
594*bb4ee6a4SAndroid Build Coastguard Worker ) -> RutabagaResult<()> {
595*bb4ee6a4SAndroid Build Coastguard Worker if transfer.is_empty() {
596*bb4ee6a4SAndroid Build Coastguard Worker return Ok(());
597*bb4ee6a4SAndroid Build Coastguard Worker }
598*bb4ee6a4SAndroid Build Coastguard Worker
599*bb4ee6a4SAndroid Build Coastguard Worker let mut transfer_box = VirglBox {
600*bb4ee6a4SAndroid Build Coastguard Worker x: transfer.x,
601*bb4ee6a4SAndroid Build Coastguard Worker y: transfer.y,
602*bb4ee6a4SAndroid Build Coastguard Worker z: transfer.z,
603*bb4ee6a4SAndroid Build Coastguard Worker w: transfer.w,
604*bb4ee6a4SAndroid Build Coastguard Worker h: transfer.h,
605*bb4ee6a4SAndroid Build Coastguard Worker d: transfer.d,
606*bb4ee6a4SAndroid Build Coastguard Worker };
607*bb4ee6a4SAndroid Build Coastguard Worker
608*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
609*bb4ee6a4SAndroid Build Coastguard Worker // Safe because only stack variables of the appropriate type are used.
610*bb4ee6a4SAndroid Build Coastguard Worker let ret = unsafe {
611*bb4ee6a4SAndroid Build Coastguard Worker stream_renderer_transfer_write_iov(
612*bb4ee6a4SAndroid Build Coastguard Worker resource.resource_id,
613*bb4ee6a4SAndroid Build Coastguard Worker ctx_id,
614*bb4ee6a4SAndroid Build Coastguard Worker transfer.level as i32,
615*bb4ee6a4SAndroid Build Coastguard Worker transfer.stride,
616*bb4ee6a4SAndroid Build Coastguard Worker transfer.layer_stride,
617*bb4ee6a4SAndroid Build Coastguard Worker &mut transfer_box as *mut VirglBox as *mut stream_renderer_box,
618*bb4ee6a4SAndroid Build Coastguard Worker transfer.offset,
619*bb4ee6a4SAndroid Build Coastguard Worker null_mut(),
620*bb4ee6a4SAndroid Build Coastguard Worker 0,
621*bb4ee6a4SAndroid Build Coastguard Worker )
622*bb4ee6a4SAndroid Build Coastguard Worker };
623*bb4ee6a4SAndroid Build Coastguard Worker ret_to_res(ret)
624*bb4ee6a4SAndroid Build Coastguard Worker }
625*bb4ee6a4SAndroid Build Coastguard Worker
transfer_read( &self, ctx_id: u32, resource: &mut RutabagaResource, transfer: Transfer3D, buf: Option<IoSliceMut>, ) -> RutabagaResult<()>626*bb4ee6a4SAndroid Build Coastguard Worker fn transfer_read(
627*bb4ee6a4SAndroid Build Coastguard Worker &self,
628*bb4ee6a4SAndroid Build Coastguard Worker ctx_id: u32,
629*bb4ee6a4SAndroid Build Coastguard Worker resource: &mut RutabagaResource,
630*bb4ee6a4SAndroid Build Coastguard Worker transfer: Transfer3D,
631*bb4ee6a4SAndroid Build Coastguard Worker buf: Option<IoSliceMut>,
632*bb4ee6a4SAndroid Build Coastguard Worker ) -> RutabagaResult<()> {
633*bb4ee6a4SAndroid Build Coastguard Worker if transfer.is_empty() {
634*bb4ee6a4SAndroid Build Coastguard Worker return Ok(());
635*bb4ee6a4SAndroid Build Coastguard Worker }
636*bb4ee6a4SAndroid Build Coastguard Worker
637*bb4ee6a4SAndroid Build Coastguard Worker let mut transfer_box = VirglBox {
638*bb4ee6a4SAndroid Build Coastguard Worker x: transfer.x,
639*bb4ee6a4SAndroid Build Coastguard Worker y: transfer.y,
640*bb4ee6a4SAndroid Build Coastguard Worker z: transfer.z,
641*bb4ee6a4SAndroid Build Coastguard Worker w: transfer.w,
642*bb4ee6a4SAndroid Build Coastguard Worker h: transfer.h,
643*bb4ee6a4SAndroid Build Coastguard Worker d: transfer.d,
644*bb4ee6a4SAndroid Build Coastguard Worker };
645*bb4ee6a4SAndroid Build Coastguard Worker
646*bb4ee6a4SAndroid Build Coastguard Worker let mut iov = RutabagaIovec {
647*bb4ee6a4SAndroid Build Coastguard Worker base: null_mut(),
648*bb4ee6a4SAndroid Build Coastguard Worker len: 0,
649*bb4ee6a4SAndroid Build Coastguard Worker };
650*bb4ee6a4SAndroid Build Coastguard Worker
651*bb4ee6a4SAndroid Build Coastguard Worker let (iovecs, num_iovecs) = match buf {
652*bb4ee6a4SAndroid Build Coastguard Worker Some(mut buf) => {
653*bb4ee6a4SAndroid Build Coastguard Worker iov.base = buf.as_mut_ptr() as *mut c_void;
654*bb4ee6a4SAndroid Build Coastguard Worker iov.len = buf.len();
655*bb4ee6a4SAndroid Build Coastguard Worker (&mut iov as *mut RutabagaIovec as *mut iovec, 1)
656*bb4ee6a4SAndroid Build Coastguard Worker }
657*bb4ee6a4SAndroid Build Coastguard Worker None => (null_mut(), 0),
658*bb4ee6a4SAndroid Build Coastguard Worker };
659*bb4ee6a4SAndroid Build Coastguard Worker
660*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
661*bb4ee6a4SAndroid Build Coastguard Worker // Safe because only stack variables of the appropriate type are used.
662*bb4ee6a4SAndroid Build Coastguard Worker let ret = unsafe {
663*bb4ee6a4SAndroid Build Coastguard Worker stream_renderer_transfer_read_iov(
664*bb4ee6a4SAndroid Build Coastguard Worker resource.resource_id,
665*bb4ee6a4SAndroid Build Coastguard Worker ctx_id,
666*bb4ee6a4SAndroid Build Coastguard Worker transfer.level,
667*bb4ee6a4SAndroid Build Coastguard Worker transfer.stride,
668*bb4ee6a4SAndroid Build Coastguard Worker transfer.layer_stride,
669*bb4ee6a4SAndroid Build Coastguard Worker &mut transfer_box as *mut VirglBox as *mut stream_renderer_box,
670*bb4ee6a4SAndroid Build Coastguard Worker transfer.offset,
671*bb4ee6a4SAndroid Build Coastguard Worker iovecs,
672*bb4ee6a4SAndroid Build Coastguard Worker num_iovecs,
673*bb4ee6a4SAndroid Build Coastguard Worker )
674*bb4ee6a4SAndroid Build Coastguard Worker };
675*bb4ee6a4SAndroid Build Coastguard Worker ret_to_res(ret)
676*bb4ee6a4SAndroid Build Coastguard Worker }
677*bb4ee6a4SAndroid Build Coastguard Worker
resource_flush(&self, resource: &mut RutabagaResource) -> RutabagaResult<()>678*bb4ee6a4SAndroid Build Coastguard Worker fn resource_flush(&self, resource: &mut RutabagaResource) -> RutabagaResult<()> {
679*bb4ee6a4SAndroid Build Coastguard Worker // TODO(b/315870313): Add safety comment
680*bb4ee6a4SAndroid Build Coastguard Worker #[allow(clippy::undocumented_unsafe_blocks)]
681*bb4ee6a4SAndroid Build Coastguard Worker unsafe {
682*bb4ee6a4SAndroid Build Coastguard Worker stream_renderer_flush(resource.resource_id);
683*bb4ee6a4SAndroid Build Coastguard Worker }
684*bb4ee6a4SAndroid Build Coastguard Worker Ok(())
685*bb4ee6a4SAndroid Build Coastguard Worker }
686*bb4ee6a4SAndroid Build Coastguard Worker
create_blob( &mut self, ctx_id: u32, resource_id: u32, resource_create_blob: ResourceCreateBlob, mut iovec_opt: Option<Vec<RutabagaIovec>>, handle_opt: Option<RutabagaHandle>, ) -> RutabagaResult<RutabagaResource>687*bb4ee6a4SAndroid Build Coastguard Worker fn create_blob(
688*bb4ee6a4SAndroid Build Coastguard Worker &mut self,
689*bb4ee6a4SAndroid Build Coastguard Worker ctx_id: u32,
690*bb4ee6a4SAndroid Build Coastguard Worker resource_id: u32,
691*bb4ee6a4SAndroid Build Coastguard Worker resource_create_blob: ResourceCreateBlob,
692*bb4ee6a4SAndroid Build Coastguard Worker mut iovec_opt: Option<Vec<RutabagaIovec>>,
693*bb4ee6a4SAndroid Build Coastguard Worker handle_opt: Option<RutabagaHandle>,
694*bb4ee6a4SAndroid Build Coastguard Worker ) -> RutabagaResult<RutabagaResource> {
695*bb4ee6a4SAndroid Build Coastguard Worker let mut iovec_ptr = null_mut();
696*bb4ee6a4SAndroid Build Coastguard Worker let mut num_iovecs = 0;
697*bb4ee6a4SAndroid Build Coastguard Worker if let Some(ref mut iovecs) = iovec_opt {
698*bb4ee6a4SAndroid Build Coastguard Worker iovec_ptr = iovecs.as_mut_ptr();
699*bb4ee6a4SAndroid Build Coastguard Worker num_iovecs = iovecs.len() as u32;
700*bb4ee6a4SAndroid Build Coastguard Worker }
701*bb4ee6a4SAndroid Build Coastguard Worker
702*bb4ee6a4SAndroid Build Coastguard Worker let mut handle_ptr = null();
703*bb4ee6a4SAndroid Build Coastguard Worker let mut stream_handle: stream_renderer_handle = Default::default();
704*bb4ee6a4SAndroid Build Coastguard Worker if let Some(handle) = handle_opt {
705*bb4ee6a4SAndroid Build Coastguard Worker stream_handle.handle_type = handle.handle_type;
706*bb4ee6a4SAndroid Build Coastguard Worker stream_handle.os_handle = handle.os_handle.into_raw_descriptor() as i64;
707*bb4ee6a4SAndroid Build Coastguard Worker handle_ptr = &stream_handle;
708*bb4ee6a4SAndroid Build Coastguard Worker }
709*bb4ee6a4SAndroid Build Coastguard Worker
710*bb4ee6a4SAndroid Build Coastguard Worker // TODO(b/315870313): Add safety comment
711*bb4ee6a4SAndroid Build Coastguard Worker #[allow(clippy::undocumented_unsafe_blocks)]
712*bb4ee6a4SAndroid Build Coastguard Worker let ret = unsafe {
713*bb4ee6a4SAndroid Build Coastguard Worker stream_renderer_create_blob(
714*bb4ee6a4SAndroid Build Coastguard Worker ctx_id,
715*bb4ee6a4SAndroid Build Coastguard Worker resource_id,
716*bb4ee6a4SAndroid Build Coastguard Worker &resource_create_blob as *const stream_renderer_create_blob,
717*bb4ee6a4SAndroid Build Coastguard Worker iovec_ptr as *const iovec,
718*bb4ee6a4SAndroid Build Coastguard Worker num_iovecs,
719*bb4ee6a4SAndroid Build Coastguard Worker handle_ptr,
720*bb4ee6a4SAndroid Build Coastguard Worker )
721*bb4ee6a4SAndroid Build Coastguard Worker };
722*bb4ee6a4SAndroid Build Coastguard Worker
723*bb4ee6a4SAndroid Build Coastguard Worker ret_to_res(ret)?;
724*bb4ee6a4SAndroid Build Coastguard Worker
725*bb4ee6a4SAndroid Build Coastguard Worker Ok(RutabagaResource {
726*bb4ee6a4SAndroid Build Coastguard Worker resource_id,
727*bb4ee6a4SAndroid Build Coastguard Worker handle: self.export_blob(resource_id).ok(),
728*bb4ee6a4SAndroid Build Coastguard Worker blob: true,
729*bb4ee6a4SAndroid Build Coastguard Worker blob_mem: resource_create_blob.blob_mem,
730*bb4ee6a4SAndroid Build Coastguard Worker blob_flags: resource_create_blob.blob_flags,
731*bb4ee6a4SAndroid Build Coastguard Worker map_info: self.map_info(resource_id).ok(),
732*bb4ee6a4SAndroid Build Coastguard Worker info_2d: None,
733*bb4ee6a4SAndroid Build Coastguard Worker info_3d: None,
734*bb4ee6a4SAndroid Build Coastguard Worker vulkan_info: self.vulkan_info(resource_id).ok(),
735*bb4ee6a4SAndroid Build Coastguard Worker backing_iovecs: iovec_opt,
736*bb4ee6a4SAndroid Build Coastguard Worker component_mask: 1 << (RutabagaComponentType::Gfxstream as u8),
737*bb4ee6a4SAndroid Build Coastguard Worker size: resource_create_blob.size,
738*bb4ee6a4SAndroid Build Coastguard Worker mapping: None,
739*bb4ee6a4SAndroid Build Coastguard Worker })
740*bb4ee6a4SAndroid Build Coastguard Worker }
741*bb4ee6a4SAndroid Build Coastguard Worker
map(&self, resource_id: u32) -> RutabagaResult<RutabagaMapping>742*bb4ee6a4SAndroid Build Coastguard Worker fn map(&self, resource_id: u32) -> RutabagaResult<RutabagaMapping> {
743*bb4ee6a4SAndroid Build Coastguard Worker let mut map: *mut c_void = null_mut();
744*bb4ee6a4SAndroid Build Coastguard Worker let mut size: u64 = 0;
745*bb4ee6a4SAndroid Build Coastguard Worker
746*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
747*bb4ee6a4SAndroid Build Coastguard Worker // Safe because the Stream renderer wraps and validates use of vkMapMemory.
748*bb4ee6a4SAndroid Build Coastguard Worker let ret = unsafe { stream_renderer_resource_map(resource_id, &mut map, &mut size) };
749*bb4ee6a4SAndroid Build Coastguard Worker if ret != 0 {
750*bb4ee6a4SAndroid Build Coastguard Worker return Err(RutabagaError::MappingFailed(ret));
751*bb4ee6a4SAndroid Build Coastguard Worker }
752*bb4ee6a4SAndroid Build Coastguard Worker Ok(RutabagaMapping {
753*bb4ee6a4SAndroid Build Coastguard Worker ptr: map as u64,
754*bb4ee6a4SAndroid Build Coastguard Worker size,
755*bb4ee6a4SAndroid Build Coastguard Worker })
756*bb4ee6a4SAndroid Build Coastguard Worker }
757*bb4ee6a4SAndroid Build Coastguard Worker
unmap(&self, resource_id: u32) -> RutabagaResult<()>758*bb4ee6a4SAndroid Build Coastguard Worker fn unmap(&self, resource_id: u32) -> RutabagaResult<()> {
759*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
760*bb4ee6a4SAndroid Build Coastguard Worker // Safe because the Stream renderer wraps and validates use of vkMapMemory.
761*bb4ee6a4SAndroid Build Coastguard Worker let ret = unsafe { stream_renderer_resource_unmap(resource_id) };
762*bb4ee6a4SAndroid Build Coastguard Worker ret_to_res(ret)
763*bb4ee6a4SAndroid Build Coastguard Worker }
764*bb4ee6a4SAndroid Build Coastguard Worker
create_context( &self, ctx_id: u32, context_init: u32, context_name: Option<&str>, fence_handler: RutabagaFenceHandler, ) -> RutabagaResult<Box<dyn RutabagaContext>>765*bb4ee6a4SAndroid Build Coastguard Worker fn create_context(
766*bb4ee6a4SAndroid Build Coastguard Worker &self,
767*bb4ee6a4SAndroid Build Coastguard Worker ctx_id: u32,
768*bb4ee6a4SAndroid Build Coastguard Worker context_init: u32,
769*bb4ee6a4SAndroid Build Coastguard Worker context_name: Option<&str>,
770*bb4ee6a4SAndroid Build Coastguard Worker fence_handler: RutabagaFenceHandler,
771*bb4ee6a4SAndroid Build Coastguard Worker ) -> RutabagaResult<Box<dyn RutabagaContext>> {
772*bb4ee6a4SAndroid Build Coastguard Worker let mut name: &str = "gpu_renderer";
773*bb4ee6a4SAndroid Build Coastguard Worker if let Some(name_string) = context_name.filter(|s| !s.is_empty()) {
774*bb4ee6a4SAndroid Build Coastguard Worker name = name_string;
775*bb4ee6a4SAndroid Build Coastguard Worker }
776*bb4ee6a4SAndroid Build Coastguard Worker
777*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
778*bb4ee6a4SAndroid Build Coastguard Worker // Safe because gfxstream is initialized by now and the context name is statically
779*bb4ee6a4SAndroid Build Coastguard Worker // allocated. The return value is checked before returning a new context.
780*bb4ee6a4SAndroid Build Coastguard Worker let ret = unsafe {
781*bb4ee6a4SAndroid Build Coastguard Worker stream_renderer_context_create(
782*bb4ee6a4SAndroid Build Coastguard Worker ctx_id,
783*bb4ee6a4SAndroid Build Coastguard Worker name.len() as u32,
784*bb4ee6a4SAndroid Build Coastguard Worker name.as_ptr() as *const c_char,
785*bb4ee6a4SAndroid Build Coastguard Worker context_init,
786*bb4ee6a4SAndroid Build Coastguard Worker )
787*bb4ee6a4SAndroid Build Coastguard Worker };
788*bb4ee6a4SAndroid Build Coastguard Worker ret_to_res(ret)?;
789*bb4ee6a4SAndroid Build Coastguard Worker Ok(Box::new(GfxstreamContext {
790*bb4ee6a4SAndroid Build Coastguard Worker ctx_id,
791*bb4ee6a4SAndroid Build Coastguard Worker fence_handler,
792*bb4ee6a4SAndroid Build Coastguard Worker }))
793*bb4ee6a4SAndroid Build Coastguard Worker }
794*bb4ee6a4SAndroid Build Coastguard Worker
795*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(gfxstream_unstable)]
suspend(&self) -> RutabagaResult<()>796*bb4ee6a4SAndroid Build Coastguard Worker fn suspend(&self) -> RutabagaResult<()> {
797*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
798*bb4ee6a4SAndroid Build Coastguard Worker // Safe because gfxstream is initialized by now.
799*bb4ee6a4SAndroid Build Coastguard Worker let ret = unsafe { stream_renderer_suspend() };
800*bb4ee6a4SAndroid Build Coastguard Worker ret_to_res(ret)?;
801*bb4ee6a4SAndroid Build Coastguard Worker Ok(())
802*bb4ee6a4SAndroid Build Coastguard Worker }
803*bb4ee6a4SAndroid Build Coastguard Worker
804*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(gfxstream_unstable)]
snapshot(&self, directory: &str) -> RutabagaResult<()>805*bb4ee6a4SAndroid Build Coastguard Worker fn snapshot(&self, directory: &str) -> RutabagaResult<()> {
806*bb4ee6a4SAndroid Build Coastguard Worker let cstring = CString::new(directory)?;
807*bb4ee6a4SAndroid Build Coastguard Worker
808*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
809*bb4ee6a4SAndroid Build Coastguard Worker // Safe because directory string is valid
810*bb4ee6a4SAndroid Build Coastguard Worker let ret = unsafe { stream_renderer_snapshot(cstring.as_ptr() as *const c_char) };
811*bb4ee6a4SAndroid Build Coastguard Worker ret_to_res(ret)?;
812*bb4ee6a4SAndroid Build Coastguard Worker
813*bb4ee6a4SAndroid Build Coastguard Worker Ok(())
814*bb4ee6a4SAndroid Build Coastguard Worker }
815*bb4ee6a4SAndroid Build Coastguard Worker
816*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(gfxstream_unstable)]
restore(&self, directory: &str) -> RutabagaResult<()>817*bb4ee6a4SAndroid Build Coastguard Worker fn restore(&self, directory: &str) -> RutabagaResult<()> {
818*bb4ee6a4SAndroid Build Coastguard Worker let cstring = CString::new(directory)?;
819*bb4ee6a4SAndroid Build Coastguard Worker
820*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
821*bb4ee6a4SAndroid Build Coastguard Worker // Safe because directory string is valid
822*bb4ee6a4SAndroid Build Coastguard Worker let ret = unsafe { stream_renderer_restore(cstring.as_ptr() as *const c_char) };
823*bb4ee6a4SAndroid Build Coastguard Worker ret_to_res(ret)?;
824*bb4ee6a4SAndroid Build Coastguard Worker Ok(())
825*bb4ee6a4SAndroid Build Coastguard Worker }
826*bb4ee6a4SAndroid Build Coastguard Worker
827*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(gfxstream_unstable)]
resume(&self) -> RutabagaResult<()>828*bb4ee6a4SAndroid Build Coastguard Worker fn resume(&self) -> RutabagaResult<()> {
829*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
830*bb4ee6a4SAndroid Build Coastguard Worker // Safe because gfxstream is initialized by now.
831*bb4ee6a4SAndroid Build Coastguard Worker let ret = unsafe { stream_renderer_resume() };
832*bb4ee6a4SAndroid Build Coastguard Worker ret_to_res(ret)?;
833*bb4ee6a4SAndroid Build Coastguard Worker Ok(())
834*bb4ee6a4SAndroid Build Coastguard Worker }
835*bb4ee6a4SAndroid Build Coastguard Worker
836*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(gfxstream_unstable)]
wait_sync(&self, resource: &RutabagaResource) -> RutabagaResult<()>837*bb4ee6a4SAndroid Build Coastguard Worker fn wait_sync(&self, resource: &RutabagaResource) -> RutabagaResult<()> {
838*bb4ee6a4SAndroid Build Coastguard Worker let ret = unsafe { stream_renderer_wait_sync_resource(resource.resource_id) };
839*bb4ee6a4SAndroid Build Coastguard Worker ret_to_res(ret)?;
840*bb4ee6a4SAndroid Build Coastguard Worker Ok(())
841*bb4ee6a4SAndroid Build Coastguard Worker }
842*bb4ee6a4SAndroid Build Coastguard Worker }
843