From d4d5c6ff9534d155e4472e40fb3266ae8d495a37 Mon Sep 17 00:00:00 2001 From: Natasha England-Elbro Date: Thu, 1 Feb 2024 15:05:40 +0000 Subject: [PATCH] fix: crashing citra --- citro3d/examples/cube.rs | 24 ++++++++++++++---------- citro3d/src/lib.rs | 29 ++++++++++++++++++++++------- citro3d/src/util.rs | 6 ++++++ 3 files changed, 42 insertions(+), 17 deletions(-) create mode 100644 citro3d/src/util.rs diff --git a/citro3d/examples/cube.rs b/citro3d/examples/cube.rs index 73c074c..b8ff063 100644 --- a/citro3d/examples/cube.rs +++ b/citro3d/examples/cube.rs @@ -111,7 +111,7 @@ fn main() { y: v[1], z: v[2], }, - color: Vec3::new(i as f32 % 1., i as f32 % 1., i as f32 % 1.), + color: Vec3::new(1.0, 0.7, 0.5), }) { vbo_data.push(vert); } @@ -134,6 +134,16 @@ fn main() { FVec3::new(0.0, 1.0, 0.0), CoordinateOrientation::RightHanded, ); + let indecies_a = [ + 0, 3, 1, 1, 3, 2, // triangles making up the top (+y) facing side. + 4, 5, 7, 5, 6, 7, // bottom (-y) + 8, 11, 9, 9, 11, 10, // right (+x) + 12, 13, 15, 13, 14, 15, // left (-x) + 16, 19, 17, 17, 19, 18, // back (+z) + 20, 21, 23, 21, 22, 23, // forward (-z) + ]; + let mut indecies = Vec::with_capacity_in(indecies_a.len(), ctru::linear::LinearAllocator); + indecies.extend_from_slice(&indecies_a); while apt.main_loop() { hid.scan_input(); @@ -159,18 +169,12 @@ fn main() { unsafe { instance.draw_elements( buffer::Primitive::Triangles, - DrawingIndices::U16(&[ - 0, 3, 1, 1, 3, 2, // triangles making up the top (+y) facing side. - 4, 5, 7, 5, 6, 7, // bottom (-y) - 8, 11, 9, 9, 11, 10, // right (+x) - 12, 13, 15, 13, 14, 15, // left (-x) - 16, 19, 17, 17, 19, 18, // back (+z) - 20, 21, 23, 21, 22, 23, // forward (-z) - ]), + &buf_info, + DrawingIndices::U16(&indecies), ); } - instance.draw_arrays(buffer::Primitive::Triangles, vbo_data); + //instance.draw_arrays(buffer::Primitive::Triangles, vbo_data); }; let Projections { diff --git a/citro3d/src/lib.rs b/citro3d/src/lib.rs index 133f369..88636ee 100644 --- a/citro3d/src/lib.rs +++ b/citro3d/src/lib.rs @@ -17,11 +17,13 @@ pub mod render; pub mod shader; pub mod texenv; pub mod uniform; +mod util; use std::cell::OnceCell; use std::fmt; pub use error::{Error, Result}; +use util::is_linear_ptr; use self::texenv::TexEnv; use self::uniform::Uniform; @@ -162,27 +164,40 @@ impl Instance { } /// Indexed drawing /// + /// Draws the vertices in `buf` indexed by `indices`. `indices` must be linearly allocated + /// /// # Safety /// If `indices` goes out of scope before the current frame ends it will cause a use-after-free (possibly by the GPU) + /// If `buf` does not contain all the vertices references by `indices` it will cause an invalid access by the GPU (this crashes citra) + /// + /// # Panics + /// If `indices` is not allocated in linear memory #[doc(alias = "C3D_DrawElements")] pub unsafe fn draw_elements<'a>( &mut self, primitive: buffer::Primitive, + buf: &buffer::Info, indices: impl Into>, ) { + self.set_buffer_info(buf); let indices: DrawingIndices<'a> = indices.into(); + let elements = match indices { + DrawingIndices::U16(v) => v.as_ptr() as *const _, + DrawingIndices::U8(v) => v.as_ptr() as *const _, + }; + assert!( + is_linear_ptr(elements), + "draw_elements requires linear allocated indices buffer" + ); citro3d_sys::C3D_DrawElements( primitive as ctru_sys::GPU_Primitive_t, indices.len() as i32, // flag bit for short or byte match indices { - DrawingIndices::U16(_) => 1, - DrawingIndices::U8(_) => 0, - }, - match indices { - DrawingIndices::U16(v) => v.as_ptr() as *const _, - DrawingIndices::U8(v) => v.as_ptr() as *const _, - }, + DrawingIndices::U16(_) => citro3d_sys::C3D_UNSIGNED_SHORT, + DrawingIndices::U8(_) => citro3d_sys::C3D_UNSIGNED_BYTE, + } as i32, + elements, ); } diff --git a/citro3d/src/util.rs b/citro3d/src/util.rs new file mode 100644 index 0000000..727e8a2 --- /dev/null +++ b/citro3d/src/util.rs @@ -0,0 +1,6 @@ +/// Check if pointer is in linear memory +pub fn is_linear_ptr

(p: *const P) -> bool { + let addr = p as usize; + addr >= ctru_sys::OS_FCRAM_VADDR as usize + && addr < (ctru_sys::OS_FCRAM_VADDR as usize + ctru_sys::OS_FCRAM_SIZE as usize) +}