xref: /aosp_15_r20/external/mesa3d/src/etnaviv/isa/util.rs (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker // Copyright © 2024 Igalia S.L.
2*61046927SAndroid Build Coastguard Worker // SPDX-License-Identifier: MIT
3*61046927SAndroid Build Coastguard Worker 
4*61046927SAndroid Build Coastguard Worker use isa_bindings::*;
5*61046927SAndroid Build Coastguard Worker use std::ffi::CString;
6*61046927SAndroid Build Coastguard Worker use std::mem::ManuallyDrop;
7*61046927SAndroid Build Coastguard Worker use std::ptr;
8*61046927SAndroid Build Coastguard Worker 
9*61046927SAndroid Build Coastguard Worker pub trait EtnaAsmResultExt {
set_error(&mut self, error_message: &str)10*61046927SAndroid Build Coastguard Worker     fn set_error(&mut self, error_message: &str);
dealloc_error(&mut self)11*61046927SAndroid Build Coastguard Worker     fn dealloc_error(&mut self);
12*61046927SAndroid Build Coastguard Worker 
append_instruction(&mut self, new_inst: etna_inst)13*61046927SAndroid Build Coastguard Worker     fn append_instruction(&mut self, new_inst: etna_inst);
dealloc_instructions(&mut self)14*61046927SAndroid Build Coastguard Worker     fn dealloc_instructions(&mut self);
15*61046927SAndroid Build Coastguard Worker }
16*61046927SAndroid Build Coastguard Worker 
17*61046927SAndroid Build Coastguard Worker impl EtnaAsmResultExt for etna_asm_result {
set_error(&mut self, error_message: &str)18*61046927SAndroid Build Coastguard Worker     fn set_error(&mut self, error_message: &str) {
19*61046927SAndroid Build Coastguard Worker         self.dealloc_error();
20*61046927SAndroid Build Coastguard Worker 
21*61046927SAndroid Build Coastguard Worker         self.error = CString::new(error_message)
22*61046927SAndroid Build Coastguard Worker             .expect("CString::new failed")
23*61046927SAndroid Build Coastguard Worker             .into_raw();
24*61046927SAndroid Build Coastguard Worker     }
25*61046927SAndroid Build Coastguard Worker 
dealloc_error(&mut self)26*61046927SAndroid Build Coastguard Worker     fn dealloc_error(&mut self) {
27*61046927SAndroid Build Coastguard Worker         if !self.error.is_null() {
28*61046927SAndroid Build Coastguard Worker             // SAFETY: Previously obtained from CString::into_raw in set_error
29*61046927SAndroid Build Coastguard Worker             let _ = unsafe { CString::from_raw(self.error) };
30*61046927SAndroid Build Coastguard Worker             self.error = ptr::null_mut();
31*61046927SAndroid Build Coastguard Worker         }
32*61046927SAndroid Build Coastguard Worker     }
33*61046927SAndroid Build Coastguard Worker 
append_instruction(&mut self, new_inst: etna_inst)34*61046927SAndroid Build Coastguard Worker     fn append_instruction(&mut self, new_inst: etna_inst) {
35*61046927SAndroid Build Coastguard Worker         let mut instrs = if self.instr.is_null() {
36*61046927SAndroid Build Coastguard Worker             Vec::new()
37*61046927SAndroid Build Coastguard Worker         } else {
38*61046927SAndroid Build Coastguard Worker             // SAFETY: These values come from a previous call to `append_instruction` where we turned a Vec into raw parts
39*61046927SAndroid Build Coastguard Worker             unsafe { Vec::from_raw_parts(self.instr, self.num_instr, self.capacity_instr) }
40*61046927SAndroid Build Coastguard Worker         };
41*61046927SAndroid Build Coastguard Worker 
42*61046927SAndroid Build Coastguard Worker         instrs.push(new_inst);
43*61046927SAndroid Build Coastguard Worker 
44*61046927SAndroid Build Coastguard Worker         // This is Vec::into_raw_parts, which is still unstable
45*61046927SAndroid Build Coastguard Worker         let mut md_vec = ManuallyDrop::new(instrs);
46*61046927SAndroid Build Coastguard Worker         self.num_instr = md_vec.len();
47*61046927SAndroid Build Coastguard Worker         self.capacity_instr = md_vec.capacity();
48*61046927SAndroid Build Coastguard Worker         self.instr = md_vec.as_mut_ptr();
49*61046927SAndroid Build Coastguard Worker     }
50*61046927SAndroid Build Coastguard Worker 
dealloc_instructions(&mut self)51*61046927SAndroid Build Coastguard Worker     fn dealloc_instructions(&mut self) {
52*61046927SAndroid Build Coastguard Worker         if !self.instr.is_null() {
53*61046927SAndroid Build Coastguard Worker             // SAFETY: These values come from a previous call to `append_instruction` where we turned a Vec into raw parts
54*61046927SAndroid Build Coastguard Worker             let _ = unsafe { Vec::from_raw_parts(self.instr, self.num_instr, self.capacity_instr) };
55*61046927SAndroid Build Coastguard Worker             (self.instr, self.num_instr, self.capacity_instr) = (ptr::null_mut(), 0, 0);
56*61046927SAndroid Build Coastguard Worker         }
57*61046927SAndroid Build Coastguard Worker     }
58*61046927SAndroid Build Coastguard Worker }
59